@vendure/dashboard 3.5.0-minor-202510031341 → 3.5.0-minor-202510161257
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugin/dashboard.plugin.js +1 -1
- package/dist/plugin/default-page.html +1 -1
- package/dist/vite/utils/ast-utils.spec.js +3 -3
- package/dist/vite/utils/tsconfig-utils.js +2 -1
- package/dist/vite/vite-plugin-hmr.d.ts +8 -0
- package/dist/vite/vite-plugin-hmr.js +34 -0
- package/dist/vite/vite-plugin-theme.js +6 -6
- package/dist/vite/vite-plugin-transform-index.js +6 -1
- package/dist/vite/vite-plugin-vendure-dashboard.d.ts +31 -4
- package/dist/vite/vite-plugin-vendure-dashboard.js +89 -34
- package/package.json +18 -5
- package/src/app/app-providers.tsx +4 -1
- package/src/app/common/map-faceted-filter-fields.ts +21 -0
- package/src/app/main.tsx +3 -1
- package/src/app/routes/_authenticated/_administrators/administrators.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_administrators/administrators.tsx +13 -3
- package/src/app/routes/_authenticated/_administrators/administrators_.$id.tsx +6 -13
- package/src/app/routes/_authenticated/_administrators/components/role-permissions-display.tsx +1 -1
- package/src/app/routes/_authenticated/_assets/assets.tsx +17 -1
- package/src/app/routes/_authenticated/_collections/collections.graphql.ts +1 -0
- package/src/app/routes/_authenticated/_collections/collections.tsx +5 -0
- package/src/app/routes/_authenticated/_collections/components/collection-bulk-actions.tsx +0 -1
- package/src/app/routes/_authenticated/_customers/customers.tsx +9 -5
- package/src/app/routes/_authenticated/_facets/components/facet-bulk-actions.tsx +0 -6
- package/src/app/routes/_authenticated/_facets/components/facet-value-bulk-actions.tsx +16 -0
- package/src/app/routes/_authenticated/_facets/components/facet-values-table.tsx +43 -12
- package/src/app/routes/_authenticated/_facets/facets_.$facetId.values_.$id.tsx +14 -5
- package/src/app/routes/_authenticated/_global-settings/global-settings.tsx +4 -8
- package/src/app/routes/_authenticated/_global-settings/utils/global-languages.ts +268 -0
- package/src/app/routes/_authenticated/_orders/components/edit-order-table.tsx +117 -92
- package/src/app/routes/_authenticated/_orders/components/order-address.tsx +15 -15
- package/src/app/routes/_authenticated/_orders/components/order-detail-shared.tsx +5 -5
- package/src/app/routes/_authenticated/_orders/components/order-modification-summary.tsx +2 -1
- package/src/app/routes/_authenticated/_orders/components/order-table-totals.tsx +26 -27
- package/src/app/routes/_authenticated/_orders/components/order-table.tsx +5 -3
- package/src/app/routes/_authenticated/_orders/components/state-transition-control.tsx +6 -9
- package/src/app/routes/_authenticated/_orders/orders.graphql.ts +17 -1
- package/src/app/routes/_authenticated/_orders/orders_.$id_.modify.tsx +48 -281
- package/src/app/routes/_authenticated/_orders/orders_.draft.$id.tsx +59 -40
- package/src/app/routes/_authenticated/_orders/utils/order-utils.ts +73 -0
- package/src/app/routes/_authenticated/_orders/utils/use-modify-order.ts +312 -0
- package/src/app/routes/_authenticated/_payment-methods/payment-methods.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_payment-methods/payment-methods.tsx +4 -0
- package/src/app/routes/_authenticated/_product-variants/components/add-currency-dropdown.tsx +49 -0
- package/src/app/routes/_authenticated/_product-variants/components/add-stock-location-dropdown.tsx +56 -0
- package/src/app/routes/_authenticated/_product-variants/product-variants.graphql.ts +12 -0
- package/src/app/routes/_authenticated/_product-variants/product-variants_.$id.tsx +178 -50
- package/src/app/routes/_authenticated/_products/components/product-bulk-actions.tsx +0 -6
- package/src/app/routes/_authenticated/_products/components/product-variants-table.tsx +0 -11
- package/src/app/routes/_authenticated/_products/products.tsx +6 -2
- package/src/app/routes/_authenticated/_products/products_.$productId.option-groups.$productOptionGroupId.options_.$id.tsx +4 -8
- package/src/app/routes/_authenticated/_promotions/components/promotion-bulk-actions.tsx +0 -10
- package/src/app/routes/_authenticated/_promotions/promotions.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_promotions/promotions.tsx +12 -0
- package/src/app/routes/_authenticated/_promotions/promotions_.$id.tsx +3 -10
- package/src/app/routes/_authenticated/_sellers/sellers.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods.tsx +4 -0
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods_.$id.tsx +4 -10
- package/src/app/routes/_authenticated/_stock-locations/stock-locations.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_tax-categories/tax-categories.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_tax-rates/tax-rates.tsx +9 -0
- package/src/app/routes/_authenticated/_tax-rates/tax-rates_.$id.tsx +1 -0
- package/src/app/routes/_authenticated/_zones/zones.graphql.ts +2 -2
- package/src/app/routes/login.tsx +2 -2
- package/src/i18n/locales/ar.po +420 -289
- package/src/i18n/locales/cs.po +420 -289
- package/src/i18n/locales/de.po +420 -289
- package/src/i18n/locales/en.po +420 -289
- package/src/i18n/locales/es.po +420 -289
- package/src/i18n/locales/fa.po +420 -289
- package/src/i18n/locales/fr.po +468 -337
- package/src/i18n/locales/he.po +420 -289
- package/src/i18n/locales/hr.po +420 -289
- package/src/i18n/locales/it.po +420 -289
- package/src/i18n/locales/ja.po +420 -289
- package/src/i18n/locales/nb.po +420 -289
- package/src/i18n/locales/ne.po +420 -289
- package/src/i18n/locales/pl.po +420 -289
- package/src/i18n/locales/pt_BR.po +420 -289
- package/src/i18n/locales/pt_PT.po +420 -289
- package/src/i18n/locales/ru.po +420 -289
- package/src/i18n/locales/sv.po +420 -289
- package/src/i18n/locales/tr.po +420 -289
- package/src/i18n/locales/uk.po +420 -289
- package/src/i18n/locales/zh_Hans.po +420 -289
- package/src/i18n/locales/zh_Hant.po +420 -289
- package/src/lib/components/data-input/affixed-input.stories.tsx +93 -0
- package/src/lib/components/data-input/affixed-input.tsx +5 -2
- package/src/lib/components/data-input/boolean-input.stories.tsx +102 -0
- package/src/lib/components/data-input/checkbox-input.stories.tsx +61 -0
- package/src/lib/components/data-input/customer-group-input.tsx +0 -1
- package/src/lib/components/data-input/datetime-input.stories.tsx +62 -0
- package/src/lib/components/data-input/datetime-input.tsx +27 -13
- package/src/lib/components/data-input/default-relation-input.tsx +18 -12
- package/src/lib/components/data-input/money-input.stories.tsx +88 -0
- package/src/lib/components/data-input/money-input.tsx +7 -11
- package/src/lib/components/data-input/number-input.stories.tsx +103 -0
- package/src/lib/components/data-input/number-input.tsx +16 -5
- package/src/lib/components/data-input/password-input.stories.tsx +65 -0
- package/src/lib/components/data-input/rich-text-input.stories.tsx +92 -0
- package/src/lib/components/data-input/slug-input.stories.tsx +232 -0
- package/src/lib/components/data-input/slug-input.tsx +9 -10
- package/src/lib/components/data-input/text-input.stories.tsx +52 -0
- package/src/lib/components/data-input/textarea-input.stories.tsx +55 -0
- package/src/lib/components/data-table/add-filter-menu.tsx +6 -1
- package/src/lib/components/data-table/column-header-wrapper.tsx +106 -0
- package/src/lib/components/data-table/data-table-bulk-action-item.tsx +11 -9
- package/src/lib/components/data-table/data-table-bulk-actions.tsx +4 -4
- package/src/lib/components/data-table/data-table-column-header.tsx +17 -14
- package/src/lib/components/data-table/data-table-faceted-filter.tsx +33 -11
- package/src/lib/components/data-table/data-table-filter-badge-editable.tsx +35 -0
- package/src/lib/components/data-table/data-table-filter-badge.tsx +28 -14
- package/src/lib/components/data-table/data-table-filter-dialog.tsx +28 -8
- package/src/lib/components/data-table/data-table-pagination.tsx +23 -7
- package/src/lib/components/data-table/data-table.stories.tsx +249 -0
- package/src/lib/components/data-table/data-table.tsx +39 -11
- package/src/lib/components/data-table/filters/data-table-datetime-filter.tsx +79 -34
- package/src/lib/components/data-table/use-generated-columns.tsx +55 -27
- package/src/lib/components/layout/generated-breadcrumbs.tsx +4 -12
- package/src/lib/components/layout/nav-user.tsx +19 -13
- package/src/lib/components/login/login-form.tsx +39 -123
- package/src/lib/components/shared/alerts.tsx +29 -17
- package/src/lib/components/shared/asset/asset-bulk-actions.tsx +3 -3
- package/src/lib/components/shared/asset/asset-gallery.stories.tsx +76 -0
- package/src/lib/components/shared/asset/asset-gallery.tsx +147 -113
- package/src/lib/components/shared/asset/asset-picker-dialog.stories.tsx +58 -0
- package/src/lib/components/shared/configurable-operation-input.tsx +1 -1
- package/src/lib/components/shared/customer-group-selector.tsx +5 -2
- package/src/lib/components/shared/detail-page-button.stories.tsx +52 -0
- package/src/lib/components/shared/facet-value-selector.stories.tsx +48 -0
- package/src/lib/components/shared/facet-value-selector.tsx +130 -34
- package/src/lib/components/shared/paginated-list-data-table.stories.tsx +212 -0
- package/src/lib/components/shared/paginated-list-data-table.tsx +12 -12
- package/src/lib/components/shared/permission-guard.stories.tsx +46 -0
- package/src/lib/components/shared/remove-from-channel-bulk-action.tsx +2 -0
- package/src/lib/components/shared/rich-text-editor/responsive-toolbar.tsx +8 -4
- package/src/lib/components/shared/rich-text-editor/rich-text-editor.tsx +1 -0
- package/src/lib/components/shared/table-cell/order-table-cell-components.tsx +40 -0
- package/src/lib/components/shared/vendure-image.stories.tsx +167 -0
- package/src/lib/components/shared/vendure-image.tsx +6 -7
- package/src/lib/components/ui/accordion.stories.tsx +33 -0
- package/src/lib/components/ui/alert-dialog.stories.tsx +48 -0
- package/src/lib/components/ui/alert.stories.tsx +35 -0
- package/src/lib/components/ui/aspect-ratio.stories.tsx +28 -0
- package/src/lib/components/ui/badge.stories.tsx +28 -0
- package/src/lib/components/ui/breadcrumb.stories.tsx +41 -0
- package/src/lib/components/ui/button.stories.tsx +38 -0
- package/src/lib/components/ui/calendar.stories.tsx +22 -0
- package/src/lib/components/ui/card.stories.tsx +28 -0
- package/src/lib/components/ui/carousel.stories.tsx +34 -0
- package/src/lib/components/ui/checkbox.stories.tsx +31 -0
- package/src/lib/components/ui/collapsible.stories.tsx +39 -0
- package/src/lib/components/ui/command.stories.tsx +44 -0
- package/src/lib/components/ui/context-menu.stories.tsx +38 -0
- package/src/lib/components/ui/dialog.stories.tsx +52 -0
- package/src/lib/components/ui/drawer.stories.tsx +50 -0
- package/src/lib/components/ui/dropdown-menu.stories.tsx +41 -0
- package/src/lib/components/ui/hover-card.stories.tsx +38 -0
- package/src/lib/components/ui/input-group.tsx +148 -0
- package/src/lib/components/ui/input-otp.stories.tsx +30 -0
- package/src/lib/components/ui/input.stories.tsx +38 -0
- package/src/lib/components/ui/label.stories.tsx +24 -0
- package/src/lib/components/ui/menubar.stories.tsx +53 -0
- package/src/lib/components/ui/navigation-menu.stories.tsx +54 -0
- package/src/lib/components/ui/pagination.stories.tsx +51 -0
- package/src/lib/components/ui/password-input.stories.tsx +32 -0
- package/src/lib/components/ui/password-input.tsx +33 -0
- package/src/lib/components/ui/popover.stories.tsx +33 -0
- package/src/lib/components/ui/progress.stories.tsx +27 -0
- package/src/lib/components/ui/radio-group.stories.tsx +34 -0
- package/src/lib/components/ui/resizable.stories.tsx +32 -0
- package/src/lib/components/ui/scroll-area.stories.tsx +31 -0
- package/src/lib/components/ui/select.stories.tsx +36 -0
- package/src/lib/components/ui/separator.stories.tsx +35 -0
- package/src/lib/components/ui/sheet.stories.tsx +50 -0
- package/src/lib/components/ui/sidebar-context.ts +16 -0
- package/src/lib/components/ui/sidebar.tsx +2 -13
- package/src/lib/components/ui/skeleton.stories.tsx +26 -0
- package/src/lib/components/ui/slider.stories.tsx +37 -0
- package/src/lib/components/ui/switch.stories.tsx +31 -0
- package/src/lib/components/ui/table.stories.tsx +52 -0
- package/src/lib/components/ui/tabs.stories.tsx +29 -0
- package/src/lib/components/ui/textarea.stories.tsx +32 -0
- package/src/lib/components/ui/toggle-group.stories.tsx +31 -0
- package/src/lib/components/ui/toggle.stories.tsx +39 -0
- package/src/lib/components/ui/tooltip.stories.tsx +30 -0
- package/src/lib/components/ui/tooltip.tsx +2 -2
- package/src/lib/framework/alert/alert-extensions.tsx +0 -11
- package/src/lib/framework/alert/alert-item.tsx +14 -19
- package/src/lib/framework/alert/alerts-indicator.tsx +14 -15
- package/src/lib/framework/alert/search-index-buffer-alert/search-index-buffer-alert.ts +41 -0
- package/src/lib/framework/component-registry/component-registry.tsx +3 -14
- package/src/lib/framework/dashboard-widget/base-widget.tsx +18 -9
- package/src/lib/framework/dashboard-widget/latest-orders-widget/index.tsx +0 -2
- package/src/lib/framework/dashboard-widget/widget-filters-context.tsx +12 -11
- package/src/lib/framework/defaults.ts +9 -13
- package/src/lib/framework/extension-api/input-component-extensions.tsx +6 -1
- package/src/lib/framework/extension-api/logic/alerts.ts +3 -2
- package/src/lib/framework/extension-api/types/alerts.ts +12 -6
- package/src/lib/framework/extension-api/types/data-table.ts +5 -2
- package/src/lib/framework/extension-api/types/layout.ts +41 -1
- package/src/lib/framework/extension-api/types/login.ts +0 -21
- package/src/lib/framework/form-engine/value-transformers.ts +8 -1
- package/src/lib/framework/layout-engine/custom-form-page.stories.tsx +344 -0
- package/src/lib/framework/layout-engine/page-layout.tsx +69 -57
- package/src/lib/framework/layout-engine/page.stories.tsx +275 -0
- package/src/lib/framework/nav-menu/nav-menu-extensions.ts +32 -19
- package/src/lib/framework/page/detail-page.stories.tsx +151 -0
- package/src/lib/framework/page/detail-page.tsx +12 -15
- package/src/lib/framework/page/list-page.stories.tsx +217 -0
- package/src/lib/framework/page/list-page.tsx +8 -1
- package/src/lib/graphql/api.ts +18 -1
- package/src/lib/graphql/graphql-env.d.ts +1 -1
- package/src/lib/hooks/use-alerts.ts +84 -0
- package/src/lib/hooks/use-floating-bulk-actions.ts +2 -3
- package/src/lib/index.ts +12 -5
- package/src/lib/providers/alerts-provider.tsx +60 -0
- package/src/lib/providers/channel-provider.tsx +1 -0
- package/src/lib/providers/theme-provider.tsx +6 -3
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Button } from './button.js';
|
|
4
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './collapsible.js';
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: 'UI/Collapsible',
|
|
8
|
+
component: Collapsible,
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: 'centered',
|
|
11
|
+
},
|
|
12
|
+
tags: ['autodocs'],
|
|
13
|
+
} satisfies Meta<typeof Collapsible>;
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
16
|
+
type Story = StoryObj<typeof meta>;
|
|
17
|
+
|
|
18
|
+
export const Playground: Story = {
|
|
19
|
+
render: () => {
|
|
20
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
21
|
+
return (
|
|
22
|
+
<Collapsible open={isOpen} onOpenChange={setIsOpen} className="w-[350px] space-y-2">
|
|
23
|
+
<div className="flex items-center justify-between space-x-4 px-4">
|
|
24
|
+
<h4 className="text-sm font-semibold">@peduarte starred 3 repositories</h4>
|
|
25
|
+
<CollapsibleTrigger asChild>
|
|
26
|
+
<Button variant="ghost" size="sm">
|
|
27
|
+
{isOpen ? 'Hide' : 'Show'}
|
|
28
|
+
</Button>
|
|
29
|
+
</CollapsibleTrigger>
|
|
30
|
+
</div>
|
|
31
|
+
<div className="rounded-md border px-4 py-3 font-mono text-sm">@radix-ui/primitives</div>
|
|
32
|
+
<CollapsibleContent className="space-y-2">
|
|
33
|
+
<div className="rounded-md border px-4 py-3 font-mono text-sm">@radix-ui/colors</div>
|
|
34
|
+
<div className="rounded-md border px-4 py-3 font-mono text-sm">@stitches/react</div>
|
|
35
|
+
</CollapsibleContent>
|
|
36
|
+
</Collapsible>
|
|
37
|
+
);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import {
|
|
3
|
+
Command,
|
|
4
|
+
CommandEmpty,
|
|
5
|
+
CommandGroup,
|
|
6
|
+
CommandInput,
|
|
7
|
+
CommandItem,
|
|
8
|
+
CommandList,
|
|
9
|
+
CommandSeparator,
|
|
10
|
+
} from './command.js';
|
|
11
|
+
|
|
12
|
+
const meta = {
|
|
13
|
+
title: 'UI/Command',
|
|
14
|
+
component: Command,
|
|
15
|
+
parameters: {
|
|
16
|
+
layout: 'centered',
|
|
17
|
+
},
|
|
18
|
+
tags: ['autodocs'],
|
|
19
|
+
} satisfies Meta<typeof Command>;
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
22
|
+
type Story = StoryObj<typeof meta>;
|
|
23
|
+
|
|
24
|
+
export const Playground: Story = {
|
|
25
|
+
render: () => (
|
|
26
|
+
<Command className="rounded-lg border shadow-md w-[400px]">
|
|
27
|
+
<CommandInput placeholder="Type a command or search..." />
|
|
28
|
+
<CommandList>
|
|
29
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
30
|
+
<CommandGroup heading="Suggestions">
|
|
31
|
+
<CommandItem>Calendar</CommandItem>
|
|
32
|
+
<CommandItem>Search Emoji</CommandItem>
|
|
33
|
+
<CommandItem>Calculator</CommandItem>
|
|
34
|
+
</CommandGroup>
|
|
35
|
+
<CommandSeparator />
|
|
36
|
+
<CommandGroup heading="Settings">
|
|
37
|
+
<CommandItem>Profile</CommandItem>
|
|
38
|
+
<CommandItem>Billing</CommandItem>
|
|
39
|
+
<CommandItem>Settings</CommandItem>
|
|
40
|
+
</CommandGroup>
|
|
41
|
+
</CommandList>
|
|
42
|
+
</Command>
|
|
43
|
+
),
|
|
44
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import {
|
|
3
|
+
ContextMenu,
|
|
4
|
+
ContextMenuContent,
|
|
5
|
+
ContextMenuItem,
|
|
6
|
+
ContextMenuSeparator,
|
|
7
|
+
ContextMenuTrigger,
|
|
8
|
+
} from './context-menu.js';
|
|
9
|
+
|
|
10
|
+
const meta = {
|
|
11
|
+
title: 'UI/Context Menu',
|
|
12
|
+
component: ContextMenu,
|
|
13
|
+
parameters: {
|
|
14
|
+
layout: 'centered',
|
|
15
|
+
},
|
|
16
|
+
tags: ['autodocs'],
|
|
17
|
+
} satisfies Meta<typeof ContextMenu>;
|
|
18
|
+
|
|
19
|
+
export default meta;
|
|
20
|
+
type Story = StoryObj<typeof meta>;
|
|
21
|
+
|
|
22
|
+
export const Playground: Story = {
|
|
23
|
+
render: () => (
|
|
24
|
+
<ContextMenu>
|
|
25
|
+
<ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
|
|
26
|
+
Right click here
|
|
27
|
+
</ContextMenuTrigger>
|
|
28
|
+
<ContextMenuContent>
|
|
29
|
+
<ContextMenuItem>Back</ContextMenuItem>
|
|
30
|
+
<ContextMenuItem>Forward</ContextMenuItem>
|
|
31
|
+
<ContextMenuItem>Reload</ContextMenuItem>
|
|
32
|
+
<ContextMenuSeparator />
|
|
33
|
+
<ContextMenuItem>Save Page As...</ContextMenuItem>
|
|
34
|
+
<ContextMenuItem>Print...</ContextMenuItem>
|
|
35
|
+
</ContextMenuContent>
|
|
36
|
+
</ContextMenu>
|
|
37
|
+
),
|
|
38
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Button } from './button.js';
|
|
4
|
+
import {
|
|
5
|
+
Dialog,
|
|
6
|
+
DialogContent,
|
|
7
|
+
DialogDescription,
|
|
8
|
+
DialogFooter,
|
|
9
|
+
DialogHeader,
|
|
10
|
+
DialogTitle,
|
|
11
|
+
DialogTrigger,
|
|
12
|
+
} from './dialog.js';
|
|
13
|
+
|
|
14
|
+
const meta = {
|
|
15
|
+
title: 'UI/Dialog',
|
|
16
|
+
component: Dialog,
|
|
17
|
+
parameters: {
|
|
18
|
+
layout: 'centered',
|
|
19
|
+
},
|
|
20
|
+
tags: ['autodocs'],
|
|
21
|
+
} satisfies Meta<typeof Dialog>;
|
|
22
|
+
|
|
23
|
+
export default meta;
|
|
24
|
+
type Story = StoryObj<typeof meta>;
|
|
25
|
+
|
|
26
|
+
export const Playground: Story = {
|
|
27
|
+
render: () => {
|
|
28
|
+
const [open, setOpen] = useState(false);
|
|
29
|
+
return (
|
|
30
|
+
<Dialog open={open} onOpenChange={setOpen}>
|
|
31
|
+
<DialogTrigger asChild>
|
|
32
|
+
<Button>Open Dialog</Button>
|
|
33
|
+
</DialogTrigger>
|
|
34
|
+
<DialogContent>
|
|
35
|
+
<DialogHeader>
|
|
36
|
+
<DialogTitle>Dialog Title</DialogTitle>
|
|
37
|
+
<DialogDescription>
|
|
38
|
+
This is a dialog description. You can add any content here.
|
|
39
|
+
</DialogDescription>
|
|
40
|
+
</DialogHeader>
|
|
41
|
+
<div className="py-4">Dialog content goes here</div>
|
|
42
|
+
<DialogFooter>
|
|
43
|
+
<Button variant="outline" onClick={() => setOpen(false)}>
|
|
44
|
+
Cancel
|
|
45
|
+
</Button>
|
|
46
|
+
<Button onClick={() => setOpen(false)}>Confirm</Button>
|
|
47
|
+
</DialogFooter>
|
|
48
|
+
</DialogContent>
|
|
49
|
+
</Dialog>
|
|
50
|
+
);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Button } from './button.js';
|
|
4
|
+
import {
|
|
5
|
+
Drawer,
|
|
6
|
+
DrawerClose,
|
|
7
|
+
DrawerContent,
|
|
8
|
+
DrawerDescription,
|
|
9
|
+
DrawerFooter,
|
|
10
|
+
DrawerHeader,
|
|
11
|
+
DrawerTitle,
|
|
12
|
+
DrawerTrigger,
|
|
13
|
+
} from './drawer.js';
|
|
14
|
+
|
|
15
|
+
const meta = {
|
|
16
|
+
title: 'UI/Drawer',
|
|
17
|
+
component: Drawer,
|
|
18
|
+
parameters: {
|
|
19
|
+
layout: 'centered',
|
|
20
|
+
},
|
|
21
|
+
tags: ['autodocs'],
|
|
22
|
+
} satisfies Meta<typeof Drawer>;
|
|
23
|
+
|
|
24
|
+
export default meta;
|
|
25
|
+
type Story = StoryObj<typeof meta>;
|
|
26
|
+
|
|
27
|
+
export const Playground: Story = {
|
|
28
|
+
render: () => (
|
|
29
|
+
<Drawer>
|
|
30
|
+
<DrawerTrigger asChild>
|
|
31
|
+
<Button>Open Drawer</Button>
|
|
32
|
+
</DrawerTrigger>
|
|
33
|
+
<DrawerContent>
|
|
34
|
+
<DrawerHeader>
|
|
35
|
+
<DrawerTitle>Drawer Title</DrawerTitle>
|
|
36
|
+
<DrawerDescription>This is a drawer description</DrawerDescription>
|
|
37
|
+
</DrawerHeader>
|
|
38
|
+
<div className="p-4">
|
|
39
|
+
<p>Drawer content goes here</p>
|
|
40
|
+
</div>
|
|
41
|
+
<DrawerFooter>
|
|
42
|
+
<Button>Submit</Button>
|
|
43
|
+
<DrawerClose asChild>
|
|
44
|
+
<Button variant="outline">Cancel</Button>
|
|
45
|
+
</DrawerClose>
|
|
46
|
+
</DrawerFooter>
|
|
47
|
+
</DrawerContent>
|
|
48
|
+
</Drawer>
|
|
49
|
+
),
|
|
50
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Button } from './button.js';
|
|
3
|
+
import {
|
|
4
|
+
DropdownMenu,
|
|
5
|
+
DropdownMenuContent,
|
|
6
|
+
DropdownMenuItem,
|
|
7
|
+
DropdownMenuLabel,
|
|
8
|
+
DropdownMenuSeparator,
|
|
9
|
+
DropdownMenuTrigger,
|
|
10
|
+
} from './dropdown-menu.js';
|
|
11
|
+
|
|
12
|
+
const meta = {
|
|
13
|
+
title: 'UI/Dropdown Menu',
|
|
14
|
+
component: DropdownMenu,
|
|
15
|
+
parameters: {
|
|
16
|
+
layout: 'centered',
|
|
17
|
+
},
|
|
18
|
+
tags: ['autodocs'],
|
|
19
|
+
} satisfies Meta<typeof DropdownMenu>;
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
22
|
+
type Story = StoryObj<typeof meta>;
|
|
23
|
+
|
|
24
|
+
export const Playground: Story = {
|
|
25
|
+
render: () => (
|
|
26
|
+
<DropdownMenu>
|
|
27
|
+
<DropdownMenuTrigger asChild>
|
|
28
|
+
<Button>Open Menu</Button>
|
|
29
|
+
</DropdownMenuTrigger>
|
|
30
|
+
<DropdownMenuContent>
|
|
31
|
+
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
|
32
|
+
<DropdownMenuSeparator />
|
|
33
|
+
<DropdownMenuItem>Profile</DropdownMenuItem>
|
|
34
|
+
<DropdownMenuItem>Settings</DropdownMenuItem>
|
|
35
|
+
<DropdownMenuItem>Team</DropdownMenuItem>
|
|
36
|
+
<DropdownMenuSeparator />
|
|
37
|
+
<DropdownMenuItem>Log out</DropdownMenuItem>
|
|
38
|
+
</DropdownMenuContent>
|
|
39
|
+
</DropdownMenu>
|
|
40
|
+
),
|
|
41
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Button } from './button.js';
|
|
3
|
+
import { HoverCard, HoverCardContent, HoverCardTrigger } from './hover-card.js';
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'UI/Hover Card',
|
|
7
|
+
component: HoverCard,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
tags: ['autodocs'],
|
|
12
|
+
} satisfies Meta<typeof HoverCard>;
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
type Story = StoryObj<typeof meta>;
|
|
16
|
+
|
|
17
|
+
export const Playground: Story = {
|
|
18
|
+
render: () => (
|
|
19
|
+
<HoverCard>
|
|
20
|
+
<HoverCardTrigger asChild>
|
|
21
|
+
<Button variant="link">@username</Button>
|
|
22
|
+
</HoverCardTrigger>
|
|
23
|
+
<HoverCardContent className="w-80">
|
|
24
|
+
<div className="flex justify-between space-x-4">
|
|
25
|
+
<div className="space-y-1">
|
|
26
|
+
<h4 className="text-sm font-semibold">@username</h4>
|
|
27
|
+
<p className="text-sm">
|
|
28
|
+
The React Framework – created and maintained by @vercel.
|
|
29
|
+
</p>
|
|
30
|
+
<div className="flex items-center pt-2">
|
|
31
|
+
<span className="text-xs text-muted-foreground">Joined December 2021</span>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</HoverCardContent>
|
|
36
|
+
</HoverCard>
|
|
37
|
+
),
|
|
38
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
import { Button } from '@/vdb/components/ui/button.js';
|
|
5
|
+
import { Input } from '@/vdb/components/ui/input.js';
|
|
6
|
+
import { Textarea } from '@/vdb/components/ui/textarea.js';
|
|
7
|
+
import { cn } from '@/vdb/lib/utils.js';
|
|
8
|
+
|
|
9
|
+
function InputGroup({ className, ...props }: React.ComponentProps<'div'>) {
|
|
10
|
+
return (
|
|
11
|
+
<div
|
|
12
|
+
data-slot="input-group"
|
|
13
|
+
role="group"
|
|
14
|
+
className={cn(
|
|
15
|
+
'group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none',
|
|
16
|
+
'h-9 has-[>textarea]:h-auto',
|
|
17
|
+
|
|
18
|
+
// Variants based on alignment.
|
|
19
|
+
'has-[>[data-align=inline-start]]:[&>input]:pl-2',
|
|
20
|
+
'has-[>[data-align=inline-end]]:[&>input]:pr-2',
|
|
21
|
+
'has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3',
|
|
22
|
+
'has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3',
|
|
23
|
+
|
|
24
|
+
// Focus state.
|
|
25
|
+
'has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]',
|
|
26
|
+
|
|
27
|
+
// Error state.
|
|
28
|
+
'has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40',
|
|
29
|
+
|
|
30
|
+
className,
|
|
31
|
+
)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const inputGroupAddonVariants = cva(
|
|
38
|
+
"text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50",
|
|
39
|
+
{
|
|
40
|
+
variants: {
|
|
41
|
+
align: {
|
|
42
|
+
'inline-start': 'order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]',
|
|
43
|
+
'inline-end': 'order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]',
|
|
44
|
+
'block-start':
|
|
45
|
+
'order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5',
|
|
46
|
+
'block-end':
|
|
47
|
+
'order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
defaultVariants: {
|
|
51
|
+
align: 'inline-start',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
function InputGroupAddon({
|
|
57
|
+
className,
|
|
58
|
+
align = 'inline-start',
|
|
59
|
+
...props
|
|
60
|
+
}: React.ComponentProps<'div'> & VariantProps<typeof inputGroupAddonVariants>) {
|
|
61
|
+
return (
|
|
62
|
+
<div
|
|
63
|
+
role="group"
|
|
64
|
+
data-slot="input-group-addon"
|
|
65
|
+
data-align={align}
|
|
66
|
+
className={cn(inputGroupAddonVariants({ align }), className)}
|
|
67
|
+
onClick={e => {
|
|
68
|
+
if ((e.target as HTMLElement).closest('button')) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
e.currentTarget.parentElement?.querySelector('input')?.focus();
|
|
72
|
+
}}
|
|
73
|
+
{...props}
|
|
74
|
+
/>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const inputGroupButtonVariants = cva('text-sm shadow-none flex gap-2 items-center', {
|
|
79
|
+
variants: {
|
|
80
|
+
size: {
|
|
81
|
+
xs: "h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2",
|
|
82
|
+
sm: 'h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5',
|
|
83
|
+
'icon-xs': 'size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0',
|
|
84
|
+
'icon-sm': 'size-8 p-0 has-[>svg]:p-0',
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
defaultVariants: {
|
|
88
|
+
size: 'xs',
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
function InputGroupButton({
|
|
93
|
+
className,
|
|
94
|
+
type = 'button',
|
|
95
|
+
variant = 'ghost',
|
|
96
|
+
size = 'xs',
|
|
97
|
+
...props
|
|
98
|
+
}: Omit<React.ComponentProps<typeof Button>, 'size'> & VariantProps<typeof inputGroupButtonVariants>) {
|
|
99
|
+
return (
|
|
100
|
+
<Button
|
|
101
|
+
type={type}
|
|
102
|
+
data-size={size}
|
|
103
|
+
variant={variant}
|
|
104
|
+
className={cn(inputGroupButtonVariants({ size }), className)}
|
|
105
|
+
{...props}
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function InputGroupText({ className, ...props }: React.ComponentProps<'span'>) {
|
|
111
|
+
return (
|
|
112
|
+
<span
|
|
113
|
+
className={cn(
|
|
114
|
+
"text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
|
|
115
|
+
className,
|
|
116
|
+
)}
|
|
117
|
+
{...props}
|
|
118
|
+
/>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function InputGroupInput({ className, ...props }: React.ComponentProps<'input'>) {
|
|
123
|
+
return (
|
|
124
|
+
<Input
|
|
125
|
+
data-slot="input-group-control"
|
|
126
|
+
className={cn(
|
|
127
|
+
'flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent',
|
|
128
|
+
className,
|
|
129
|
+
)}
|
|
130
|
+
{...props}
|
|
131
|
+
/>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function InputGroupTextarea({ className, ...props }: React.ComponentProps<'textarea'>) {
|
|
136
|
+
return (
|
|
137
|
+
<Textarea
|
|
138
|
+
data-slot="input-group-control"
|
|
139
|
+
className={cn(
|
|
140
|
+
'flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent',
|
|
141
|
+
className,
|
|
142
|
+
)}
|
|
143
|
+
{...props}
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { REGEXP_ONLY_DIGITS_AND_CHARS } from 'input-otp';
|
|
3
|
+
import { InputOTP, InputOTPGroup, InputOTPSlot } from './input-otp.js';
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'UI/Input OTP',
|
|
7
|
+
component: InputOTP,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
tags: ['autodocs'],
|
|
12
|
+
} satisfies Meta<typeof InputOTP>;
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
type Story = StoryObj<typeof meta>;
|
|
16
|
+
|
|
17
|
+
export const Playground: Story = {
|
|
18
|
+
render: () => (
|
|
19
|
+
<InputOTP maxLength={6} pattern={REGEXP_ONLY_DIGITS_AND_CHARS}>
|
|
20
|
+
<InputOTPGroup>
|
|
21
|
+
<InputOTPSlot index={0} />
|
|
22
|
+
<InputOTPSlot index={1} />
|
|
23
|
+
<InputOTPSlot index={2} />
|
|
24
|
+
<InputOTPSlot index={3} />
|
|
25
|
+
<InputOTPSlot index={4} />
|
|
26
|
+
<InputOTPSlot index={5} />
|
|
27
|
+
</InputOTPGroup>
|
|
28
|
+
</InputOTP>
|
|
29
|
+
),
|
|
30
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Input } from './input.js';
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'UI/Input',
|
|
6
|
+
component: Input,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: 'centered',
|
|
9
|
+
},
|
|
10
|
+
tags: ['autodocs'],
|
|
11
|
+
argTypes: {
|
|
12
|
+
type: {
|
|
13
|
+
control: 'select',
|
|
14
|
+
options: ['text', 'email', 'password', 'number', 'tel', 'url'],
|
|
15
|
+
description: 'Input type',
|
|
16
|
+
},
|
|
17
|
+
placeholder: {
|
|
18
|
+
control: 'text',
|
|
19
|
+
description: 'Placeholder text',
|
|
20
|
+
},
|
|
21
|
+
disabled: {
|
|
22
|
+
control: 'boolean',
|
|
23
|
+
description: 'Whether the input is disabled',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
} satisfies Meta<typeof Input>;
|
|
27
|
+
|
|
28
|
+
export default meta;
|
|
29
|
+
type Story = StoryObj<typeof meta>;
|
|
30
|
+
|
|
31
|
+
export const Playground: Story = {
|
|
32
|
+
args: {
|
|
33
|
+
type: 'text',
|
|
34
|
+
placeholder: 'Enter text...',
|
|
35
|
+
disabled: false,
|
|
36
|
+
},
|
|
37
|
+
render: args => <Input {...args} className="w-[300px]" />,
|
|
38
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Checkbox } from './checkbox.js';
|
|
3
|
+
import { Label } from './label.js';
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'UI/Label',
|
|
7
|
+
component: Label,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
tags: ['autodocs'],
|
|
12
|
+
} satisfies Meta<typeof Label>;
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
type Story = StoryObj<typeof meta>;
|
|
16
|
+
|
|
17
|
+
export const Playground: Story = {
|
|
18
|
+
render: () => (
|
|
19
|
+
<div className="flex items-center space-x-2">
|
|
20
|
+
<Checkbox id="terms" />
|
|
21
|
+
<Label htmlFor="terms">Accept terms and conditions</Label>
|
|
22
|
+
</div>
|
|
23
|
+
),
|
|
24
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import {
|
|
3
|
+
Menubar,
|
|
4
|
+
MenubarContent,
|
|
5
|
+
MenubarItem,
|
|
6
|
+
MenubarMenu,
|
|
7
|
+
MenubarSeparator,
|
|
8
|
+
MenubarTrigger,
|
|
9
|
+
} from './menubar.js';
|
|
10
|
+
|
|
11
|
+
const meta = {
|
|
12
|
+
title: 'UI/Menubar',
|
|
13
|
+
component: Menubar,
|
|
14
|
+
parameters: {
|
|
15
|
+
layout: 'centered',
|
|
16
|
+
},
|
|
17
|
+
tags: ['autodocs'],
|
|
18
|
+
} satisfies Meta<typeof Menubar>;
|
|
19
|
+
|
|
20
|
+
export default meta;
|
|
21
|
+
type Story = StoryObj<typeof meta>;
|
|
22
|
+
|
|
23
|
+
export const Playground: Story = {
|
|
24
|
+
render: () => (
|
|
25
|
+
<Menubar>
|
|
26
|
+
<MenubarMenu>
|
|
27
|
+
<MenubarTrigger>File</MenubarTrigger>
|
|
28
|
+
<MenubarContent>
|
|
29
|
+
<MenubarItem>New Tab</MenubarItem>
|
|
30
|
+
<MenubarItem>New Window</MenubarItem>
|
|
31
|
+
<MenubarSeparator />
|
|
32
|
+
<MenubarItem>Share</MenubarItem>
|
|
33
|
+
<MenubarSeparator />
|
|
34
|
+
<MenubarItem>Print</MenubarItem>
|
|
35
|
+
</MenubarContent>
|
|
36
|
+
</MenubarMenu>
|
|
37
|
+
<MenubarMenu>
|
|
38
|
+
<MenubarTrigger>Edit</MenubarTrigger>
|
|
39
|
+
<MenubarContent>
|
|
40
|
+
<MenubarItem>Undo</MenubarItem>
|
|
41
|
+
<MenubarItem>Redo</MenubarItem>
|
|
42
|
+
</MenubarContent>
|
|
43
|
+
</MenubarMenu>
|
|
44
|
+
<MenubarMenu>
|
|
45
|
+
<MenubarTrigger>View</MenubarTrigger>
|
|
46
|
+
<MenubarContent>
|
|
47
|
+
<MenubarItem>Zoom In</MenubarItem>
|
|
48
|
+
<MenubarItem>Zoom Out</MenubarItem>
|
|
49
|
+
</MenubarContent>
|
|
50
|
+
</MenubarMenu>
|
|
51
|
+
</Menubar>
|
|
52
|
+
),
|
|
53
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import {
|
|
3
|
+
NavigationMenu,
|
|
4
|
+
NavigationMenuContent,
|
|
5
|
+
NavigationMenuItem,
|
|
6
|
+
NavigationMenuLink,
|
|
7
|
+
NavigationMenuList,
|
|
8
|
+
NavigationMenuTrigger,
|
|
9
|
+
} from './navigation-menu.js';
|
|
10
|
+
|
|
11
|
+
const meta = {
|
|
12
|
+
title: 'UI/Navigation Menu',
|
|
13
|
+
component: NavigationMenu,
|
|
14
|
+
parameters: {
|
|
15
|
+
layout: 'centered',
|
|
16
|
+
},
|
|
17
|
+
tags: ['autodocs'],
|
|
18
|
+
} satisfies Meta<typeof NavigationMenu>;
|
|
19
|
+
|
|
20
|
+
export default meta;
|
|
21
|
+
type Story = StoryObj<typeof meta>;
|
|
22
|
+
|
|
23
|
+
export const Playground: Story = {
|
|
24
|
+
render: () => (
|
|
25
|
+
<NavigationMenu>
|
|
26
|
+
<NavigationMenuList>
|
|
27
|
+
<NavigationMenuItem>
|
|
28
|
+
<NavigationMenuTrigger>Getting started</NavigationMenuTrigger>
|
|
29
|
+
<NavigationMenuContent>
|
|
30
|
+
<div className="grid gap-3 p-6 w-[400px]">
|
|
31
|
+
<NavigationMenuLink className="block p-3 rounded-md hover:bg-accent">
|
|
32
|
+
<div className="font-medium">Introduction</div>
|
|
33
|
+
<div className="text-sm text-muted-foreground">
|
|
34
|
+
Re-usable components built using Radix UI and Tailwind CSS.
|
|
35
|
+
</div>
|
|
36
|
+
</NavigationMenuLink>
|
|
37
|
+
<NavigationMenuLink className="block p-3 rounded-md hover:bg-accent">
|
|
38
|
+
<div className="font-medium">Installation</div>
|
|
39
|
+
<div className="text-sm text-muted-foreground">
|
|
40
|
+
How to install dependencies and structure your app.
|
|
41
|
+
</div>
|
|
42
|
+
</NavigationMenuLink>
|
|
43
|
+
</div>
|
|
44
|
+
</NavigationMenuContent>
|
|
45
|
+
</NavigationMenuItem>
|
|
46
|
+
<NavigationMenuItem>
|
|
47
|
+
<NavigationMenuLink href="/docs" className="px-4 py-2">
|
|
48
|
+
Documentation
|
|
49
|
+
</NavigationMenuLink>
|
|
50
|
+
</NavigationMenuItem>
|
|
51
|
+
</NavigationMenuList>
|
|
52
|
+
</NavigationMenu>
|
|
53
|
+
),
|
|
54
|
+
};
|