diff --git a/src/core/components/menu/__workshop__/index.ts b/src/core/components/menu/__workshop__/index.ts index 2b6e0c513..75f5b0e08 100644 --- a/src/core/components/menu/__workshop__/index.ts +++ b/src/core/components/menu/__workshop__/index.ts @@ -20,6 +20,11 @@ export default defineScope({ title: 'Custom MenuItem', component: lazy(() => import('./customMenuItem')), }, + { + name: 'label', + title: 'Label', + component: lazy(() => import('./label')), + }, { name: 'groups', title: 'Groups', diff --git a/src/core/components/menu/__workshop__/label.tsx b/src/core/components/menu/__workshop__/label.tsx new file mode 100644 index 000000000..cb4f71ec5 --- /dev/null +++ b/src/core/components/menu/__workshop__/label.tsx @@ -0,0 +1,49 @@ +import { + Button, + Card, + Container, + Flex, + Menu, + MenuButton, + MenuDivider, + MenuItem, + MenuLabel, + Stack, +} from '@sanity/ui' +import {useSelect} from '@sanity/ui-workshop' + +import {WORKSHOP_CARD_TONE_OPTIONS} from '../../../__workshop__/constants' + +export default function MenuLabelStory() { + const layoutTone = useSelect('Layout tone', WORKSHOP_CARD_TONE_OPTIONS, 'default', 'Props') + + return ( + + + + + + } + id="label-example" + menu={ + + + + + + + + + + + } + /> + + + + + + + ) +} diff --git a/src/core/components/menu/index.ts b/src/core/components/menu/index.ts index 81a61acb1..31f1c25c8 100644 --- a/src/core/components/menu/index.ts +++ b/src/core/components/menu/index.ts @@ -3,3 +3,4 @@ export * from './menuButton' export * from './menuDivider' export * from './menuGroup' export * from './menuItem' +export * from './menuLabel' diff --git a/src/core/components/menu/menuLabel.tsx b/src/core/components/menu/menuLabel.tsx new file mode 100644 index 000000000..40f57deb3 --- /dev/null +++ b/src/core/components/menu/menuLabel.tsx @@ -0,0 +1,60 @@ +import {forwardRef} from 'react' + +import {Box, Label} from '../../primitives' +import {ResponsivePaddingProps} from '../../primitives/types' + +/** + * @public + */ +export interface MenuLabelProps extends ResponsivePaddingProps { + fontSize?: number | number[] + text?: React.ReactNode +} + +/** + * The `MenuLabel` component is a non-interactive label for menus. + * + * @public + */ +export const MenuLabel = forwardRef(function MenuLabel( + props: MenuLabelProps & Omit, 'as' | 'height'>, + forwardedRef: React.ForwardedRef, +) { + const { + children, + fontSize = 1, + padding, + paddingX = 3, + paddingY, + paddingTop = 3, + paddingRight, + paddingBottom = 1, + paddingLeft, + text, + ...restProps + } = props + + return ( + + {text && ( + + )} + {children} + + ) +}) +MenuLabel.displayName = 'ForwardRef(MenuLabel)' diff --git a/stories/components/MenuLabel.stories.tsx b/stories/components/MenuLabel.stories.tsx new file mode 100644 index 000000000..042838b69 --- /dev/null +++ b/stories/components/MenuLabel.stories.tsx @@ -0,0 +1,119 @@ +import type {Meta, StoryFn, StoryObj} from '@storybook/react' + +import { + Menu, + MenuButton, + MenuDivider, + MenuGroup, + MenuItem, + MenuLabel, +} from '../../src/core/components' +import {Button, Card, Container} from '../../src/core/primitives' +import {LayerProvider} from '../../src/core/utils' +import {getSpaceControls} from '../controls' + +const meta: Meta = { + args: { + text: 'Menu label', + }, + argTypes: { + padding: getSpaceControls(), + paddingX: getSpaceControls(), + paddingY: getSpaceControls(), + paddingBottom: getSpaceControls(), + paddingLeft: getSpaceControls(), + paddingRight: getSpaceControls(), + paddingTop: getSpaceControls(), + }, + component: MenuLabel, + decorators: [ + (Story): React.JSX.Element => ( + + + + + + + + + + ), + ], + tags: ['autodocs'], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: (props) => { + return + }, +} + +export const WithMultipleItems: Story = { + render: (props) => { + return ( + <> + + + + + + + + + + ) + }, +} + +export const WithNestedMenu: Story = { + render: (props) => { + return ( + <> + + + + + + + + + ) + }, +} + +export const WithMenuButton: Story = { + decorators: [ + (Story: StoryFn): React.JSX.Element => ( + + + + {/* @ts-expect-error fix later */} + + + + + ), + ], + render: (props) => { + return ( + <> + + + + + + + + } + button={