Menu items can also show content when selected. As opposed to menu items, content doesn't have any standard in which it is displayed. You're free to display any React element you want. We however recommend to mostly keep the content for reading purposes and not for interaction. It's better to keep interaction in the menus for consistency and to support all features users expect such as searching capabilities.
Lets add some simple content to our items:
import React from "react";
import {
createSettings,
createSettingsFolder,
createStandardMenuItem,
createStandardSearchPatternMatcher,
declare,
searchAction,
} from "@launchmenu/core";
const info = {
name: "HelloWorld",
description: "A minimal example applet",
version: "0.0.0",
icon: "applets" as const,
tags: ["cool"],
};
const settings = createSettings({
version: "0.0.0",
settings: () => createSettingsFolder({...info, children: {}}),
});
const helloWorldPattern = createStandardSearchPatternMatcher({
name: "Hello world",
matcher: /^world: /,
});
const items = [
createStandardMenuItem({
name: "Hello world",
onExecute: () => alert("Hello!"),
content: <div>Hello people!</div>,
searchPattern: helloWorldPattern,
}),
createStandardMenuItem({
name: "Bye world",
onExecute: () => alert("Bye!"),
content: <div>Bye people!</div>,
searchPattern: helloWorldPattern,
}),
];
export default declare({
info,
settings,
async search(query, hook) {
return {
children: searchAction.get(items),
};
},
});
Now when you select one of these items, the content section should automatically open up and show your content.
Your content supplied to createStandardMenuItem
is also wrapped in a component that allows the user to scroll up and down using the page up and down button on their keyboard when the content overflows.
We have several options for the format in which we pass the content. We will learn more about this in the next section about UILayers and menus. But here's a quick summary of all options:
{close: true}
view
: The React element or component as described abovetransparent
: Whether this view is transparent, and should thus also show the content behind ittransitions
: The transition components to be used when switching from one component to another.LaunchMenu comes with a theming system that can be used in your content to make sure consistent colors, spacings, and other properties are used. The most convenient way to use this system is to use our Box
React component. This component has a large range of css properties that can be directly set as React props, which will then automatically apply the correct value as configured in the theme.
import React, {FC} from "react";
import {
Box,
createSettings,
createSettingsFolder,
createStandardMenuItem,
createStandardSearchPatternMatcher,
declare,
searchAction,
} from "@launchmenu/core";
const info = {
name: "HelloWorld",
description: "A minimal example applet",
version: "0.0.0",
icon: "applets" as const,
tags: ["cool"],
};
const settings = createSettings({
version: "0.0.0",
settings: () => createSettingsFolder({...info, children: {}}),
});
const helloWorldPattern = createStandardSearchPatternMatcher({
name: "Hello world",
matcher: /^world: /,
});
const Content: FC<{text: string}> = ({text}) => {
return <Box color="primary">{text} people!</Box>;
};
const items = [
createStandardMenuItem({
name: "Hello world",
onExecute: () => alert("Hello!"),
content: <Content text="Hello" />,
searchPattern: helloWorldPattern,
}),
createStandardMenuItem({
name: "Bye world",
onExecute: () => alert("Bye!"),
content: <Content text="Bye" />,
searchPattern: helloWorldPattern,
}),
];
export default declare({
info,
settings,
async search(query, hook) {
return {
children: searchAction.get(items),
};
},
});
Note that here we see one of our first TypeScript type declarations: Content: FC<{text: string}>
.
In TypeScript you use the :type
notation to declare the type of variable that proceeds it. In this case we're saying that Content
is a "Functional Component" or FC
for short. We can however have many types of functional components, each allowing for different props. This is why FC
takes a generic type argument, which is similar to a function argument but on the level of types. In this case we specify {text: string}
as the generic type argument. This declares that this component takes 1 prop, namely a text
prop of type string
. If we were to have another numeric spacing
prop, we could have specified: Content: FC<{text: string, spacing: number}>
.
This Box
component also uses Emotion's CSS prop object to allow for inline CSS including selectors. Note that the css
prop isn't supported for all react components, only custom ones like Box
.
const Content: FC<{text: string}> = ({text}) => {
return (
<Box color="primary" css={{height: 200}}>
{text} people!
</Box>
);
};
We additionally also supply a useTheme
React hook that can be used to obtain the theme in your components.
import {useTheme} from "@laucnmenu/core";
const Content: FC<{text: string}> = ({text}) => {
const theme = useTheme();
return <div style={{color: theme.color.primary}}>{text} people!</div>;
};