@neynar/ui 0.3.0 → 0.4.0
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/.llm/accordion-content.llm.md +67 -0
- package/.llm/accordion-item.llm.md +61 -0
- package/.llm/accordion-trigger.llm.md +69 -0
- package/.llm/accordion.llm.md +88 -0
- package/.llm/alert-description.llm.md +78 -0
- package/.llm/alert-dialog-action.llm.md +51 -0
- package/.llm/alert-dialog-cancel.llm.md +48 -0
- package/.llm/alert-dialog-content.llm.md +88 -0
- package/.llm/alert-dialog-description.llm.md +53 -0
- package/.llm/alert-dialog-footer.llm.md +41 -0
- package/.llm/alert-dialog-header.llm.md +39 -0
- package/.llm/alert-dialog-overlay.llm.md +44 -0
- package/.llm/alert-dialog-portal.llm.md +41 -0
- package/.llm/alert-dialog-title.llm.md +46 -0
- package/.llm/alert-dialog-trigger.llm.md +40 -0
- package/.llm/alert-dialog.llm.md +80 -0
- package/.llm/alert-title.llm.md +48 -0
- package/.llm/alert.llm.md +92 -0
- package/.llm/aspect-ratio.llm.md +41 -0
- package/.llm/avatar-fallback.llm.md +41 -0
- package/.llm/avatar-image.llm.md +48 -0
- package/.llm/avatar.llm.md +35 -0
- package/.llm/badge.llm.md +117 -0
- package/.llm/blockquote.llm.md +55 -0
- package/.llm/body-text-large.llm.md +49 -0
- package/.llm/body-text-small.llm.md +49 -0
- package/.llm/body-text.llm.md +52 -0
- package/.llm/breadcrumb-ellipsis.llm.md +73 -0
- package/.llm/breadcrumb-item.llm.md +53 -0
- package/.llm/breadcrumb-link.llm.md +84 -0
- package/.llm/breadcrumb-list.llm.md +54 -0
- package/.llm/breadcrumb-page.llm.md +52 -0
- package/.llm/breadcrumb-separator.llm.md +60 -0
- package/.llm/breadcrumb.llm.md +110 -0
- package/.llm/button-group-separator.llm.md +53 -0
- package/.llm/button-group-text.llm.md +56 -0
- package/.llm/button-group.llm.md +81 -0
- package/.llm/button.llm.md +281 -0
- package/.llm/calendar-day-button.llm.md +57 -0
- package/.llm/calendar.llm.md +340 -0
- package/.llm/caption.llm.md +48 -0
- package/.llm/card-action.llm.md +64 -0
- package/.llm/card-content.llm.md +48 -0
- package/.llm/card-description.llm.md +46 -0
- package/.llm/card-footer.llm.md +56 -0
- package/.llm/card-header.llm.md +53 -0
- package/.llm/card-title.llm.md +43 -0
- package/.llm/card.llm.md +100 -0
- package/.llm/carousel-content.llm.md +77 -0
- package/.llm/carousel-item.llm.md +96 -0
- package/.llm/carousel-next.llm.md +95 -0
- package/.llm/carousel-previous.llm.md +95 -0
- package/.llm/carousel.llm.md +211 -0
- package/.llm/chart-config.llm.md +71 -0
- package/.llm/chart-container.llm.md +148 -0
- package/.llm/chart-legend-content.llm.md +85 -0
- package/.llm/chart-legend.llm.md +144 -0
- package/.llm/chart-style.llm.md +28 -0
- package/.llm/chart-tooltip-content.llm.md +149 -0
- package/.llm/chart-tooltip.llm.md +184 -0
- package/.llm/checkbox.llm.md +100 -0
- package/.llm/cn.llm.md +46 -0
- package/.llm/code.llm.md +45 -0
- package/.llm/collapsible-content.llm.md +109 -0
- package/.llm/collapsible-trigger.llm.md +75 -0
- package/.llm/collapsible.llm.md +109 -0
- package/.llm/combobox-option.llm.md +53 -0
- package/.llm/combobox.llm.md +208 -0
- package/.llm/command-dialog.llm.md +112 -0
- package/.llm/command-empty.llm.md +63 -0
- package/.llm/command-group.llm.md +83 -0
- package/.llm/command-input.llm.md +82 -0
- package/.llm/command-item.llm.md +97 -0
- package/.llm/command-list.llm.md +53 -0
- package/.llm/command-loading.llm.md +48 -0
- package/.llm/command-separator.llm.md +44 -0
- package/.llm/command-shortcut.llm.md +63 -0
- package/.llm/command.llm.md +147 -0
- package/.llm/container.llm.md +236 -0
- package/.llm/context-menu-checkbox-item.llm.md +97 -0
- package/.llm/context-menu-content.llm.md +91 -0
- package/.llm/context-menu-group.llm.md +61 -0
- package/.llm/context-menu-item.llm.md +94 -0
- package/.llm/context-menu-label.llm.md +60 -0
- package/.llm/context-menu-portal.llm.md +49 -0
- package/.llm/context-menu-radio-group.llm.md +66 -0
- package/.llm/context-menu-radio-item.llm.md +76 -0
- package/.llm/context-menu-separator.llm.md +51 -0
- package/.llm/context-menu-shortcut.llm.md +57 -0
- package/.llm/context-menu-sub-content.llm.md +90 -0
- package/.llm/context-menu-sub-trigger.llm.md +73 -0
- package/.llm/context-menu-sub.llm.md +61 -0
- package/.llm/context-menu-trigger.llm.md +53 -0
- package/.llm/context-menu.llm.md +103 -0
- package/.llm/date-picker.llm.md +90 -0
- package/.llm/dialog-close.llm.md +61 -0
- package/.llm/dialog-content.llm.md +128 -0
- package/.llm/dialog-description.llm.md +44 -0
- package/.llm/dialog-footer.llm.md +38 -0
- package/.llm/dialog-header.llm.md +40 -0
- package/.llm/dialog-overlay.llm.md +57 -0
- package/.llm/dialog-portal.llm.md +47 -0
- package/.llm/dialog-title.llm.md +41 -0
- package/.llm/dialog-trigger.llm.md +51 -0
- package/.llm/dialog.llm.md +113 -0
- package/.llm/drawer-close.llm.md +53 -0
- package/.llm/drawer-content.llm.md +58 -0
- package/.llm/drawer-description.llm.md +54 -0
- package/.llm/drawer-footer.llm.md +67 -0
- package/.llm/drawer-header.llm.md +60 -0
- package/.llm/drawer-overlay.llm.md +40 -0
- package/.llm/drawer-portal.llm.md +42 -0
- package/.llm/drawer-title.llm.md +51 -0
- package/.llm/drawer-trigger.llm.md +44 -0
- package/.llm/drawer.llm.md +194 -0
- package/.llm/dropdown-menu-checkbox-item.llm.md +111 -0
- package/.llm/dropdown-menu-content.llm.md +109 -0
- package/.llm/dropdown-menu-group.llm.md +38 -0
- package/.llm/dropdown-menu-item.llm.md +94 -0
- package/.llm/dropdown-menu-label.llm.md +66 -0
- package/.llm/dropdown-menu-portal.llm.md +32 -0
- package/.llm/dropdown-menu-radio-group.llm.md +73 -0
- package/.llm/dropdown-menu-radio-item.llm.md +92 -0
- package/.llm/dropdown-menu-separator.llm.md +55 -0
- package/.llm/dropdown-menu-shortcut.llm.md +74 -0
- package/.llm/dropdown-menu-sub-content.llm.md +80 -0
- package/.llm/dropdown-menu-sub-trigger.llm.md +84 -0
- package/.llm/dropdown-menu-sub.llm.md +74 -0
- package/.llm/dropdown-menu-trigger.llm.md +48 -0
- package/.llm/dropdown-menu.llm.md +120 -0
- package/.llm/empty-content.llm.md +103 -0
- package/.llm/empty-description.llm.md +70 -0
- package/.llm/empty-header.llm.md +64 -0
- package/.llm/empty-media.llm.md +81 -0
- package/.llm/empty-state.llm.md +174 -0
- package/.llm/empty-title.llm.md +54 -0
- package/.llm/empty.llm.md +158 -0
- package/.llm/field-content.llm.md +28 -0
- package/.llm/field-description.llm.md +28 -0
- package/.llm/field-error.llm.md +41 -0
- package/.llm/field-group.llm.md +84 -0
- package/.llm/field-label.llm.md +28 -0
- package/.llm/field-legend.llm.md +77 -0
- package/.llm/field-separator.llm.md +35 -0
- package/.llm/field-set.llm.md +80 -0
- package/.llm/field-title.llm.md +28 -0
- package/.llm/field.llm.md +35 -0
- package/.llm/hover-card-content.llm.md +167 -0
- package/.llm/hover-card-trigger.llm.md +65 -0
- package/.llm/hover-card.llm.md +121 -0
- package/.llm/input-group-addon.llm.md +91 -0
- package/.llm/input-group-button.llm.md +120 -0
- package/.llm/input-group-input.llm.md +145 -0
- package/.llm/input-group-text.llm.md +75 -0
- package/.llm/input-group-textarea.llm.md +157 -0
- package/.llm/input-group.llm.md +108 -0
- package/.llm/input.llm.md +319 -0
- package/.llm/item-actions.llm.md +77 -0
- package/.llm/item-content.llm.md +73 -0
- package/.llm/item-description.llm.md +61 -0
- package/.llm/item-footer.llm.md +68 -0
- package/.llm/item-group.llm.md +73 -0
- package/.llm/item-header.llm.md +66 -0
- package/.llm/item-media.llm.md +75 -0
- package/.llm/item-separator.llm.md +80 -0
- package/.llm/item-title.llm.md +59 -0
- package/.llm/item.llm.md +115 -0
- package/.llm/kbd-group.llm.md +71 -0
- package/.llm/kbd.llm.md +71 -0
- package/.llm/label.llm.md +145 -0
- package/.llm/menubar-checkbox-item.llm.md +66 -0
- package/.llm/menubar-content.llm.md +128 -0
- package/.llm/menubar-group.llm.md +40 -0
- package/.llm/menubar-item.llm.md +62 -0
- package/.llm/menubar-label.llm.md +40 -0
- package/.llm/menubar-menu.llm.md +32 -0
- package/.llm/menubar-portal.llm.md +38 -0
- package/.llm/menubar-radio-group.llm.md +39 -0
- package/.llm/menubar-radio-item.llm.md +59 -0
- package/.llm/menubar-separator.llm.md +35 -0
- package/.llm/menubar-shortcut.llm.md +37 -0
- package/.llm/menubar-sub-content.llm.md +127 -0
- package/.llm/menubar-sub-trigger.llm.md +51 -0
- package/.llm/menubar-sub.llm.md +53 -0
- package/.llm/menubar-trigger.llm.md +37 -0
- package/.llm/menubar.llm.md +115 -0
- package/.llm/navigation-menu-content.llm.md +116 -0
- package/.llm/navigation-menu-indicator.llm.md +68 -0
- package/.llm/navigation-menu-item.llm.md +62 -0
- package/.llm/navigation-menu-link.llm.md +109 -0
- package/.llm/navigation-menu-list.llm.md +52 -0
- package/.llm/navigation-menu-trigger-style.llm.md +22 -0
- package/.llm/navigation-menu-trigger.llm.md +57 -0
- package/.llm/navigation-menu-viewport.llm.md +51 -0
- package/.llm/navigation-menu.llm.md +184 -0
- package/.llm/overline.llm.md +51 -0
- package/.llm/page-title.llm.md +52 -0
- package/.llm/pagination-content.llm.md +60 -0
- package/.llm/pagination-ellipsis.llm.md +107 -0
- package/.llm/pagination-item.llm.md +59 -0
- package/.llm/pagination-link.llm.md +150 -0
- package/.llm/pagination-next.llm.md +115 -0
- package/.llm/pagination-previous.llm.md +115 -0
- package/.llm/pagination.llm.md +190 -0
- package/.llm/popover-anchor.llm.md +53 -0
- package/.llm/popover-content.llm.md +109 -0
- package/.llm/popover-trigger.llm.md +54 -0
- package/.llm/popover.llm.md +116 -0
- package/.llm/progress.llm.md +76 -0
- package/.llm/radio-group-indicator.llm.md +28 -0
- package/.llm/radio-group-item.llm.md +40 -0
- package/.llm/radio-group.llm.md +76 -0
- package/.llm/resizable-handle.llm.md +156 -0
- package/.llm/resizable-panel-group.llm.md +149 -0
- package/.llm/resizable-panel.llm.md +157 -0
- package/.llm/scroll-area-corner.llm.md +41 -0
- package/.llm/scroll-area-thumb.llm.md +39 -0
- package/.llm/scroll-area-viewport.llm.md +60 -0
- package/.llm/scroll-area.llm.md +125 -0
- package/.llm/scroll-bar.llm.md +78 -0
- package/.llm/sdk-items-registry.json +2984 -0
- package/.llm/section-title.llm.md +48 -0
- package/.llm/select-content.llm.md +139 -0
- package/.llm/select-group.llm.md +60 -0
- package/.llm/select-item.llm.md +75 -0
- package/.llm/select-label.llm.md +62 -0
- package/.llm/select-scroll-down-button.llm.md +45 -0
- package/.llm/select-scroll-up-button.llm.md +45 -0
- package/.llm/select-separator.llm.md +59 -0
- package/.llm/select-trigger.llm.md +66 -0
- package/.llm/select-value.llm.md +67 -0
- package/.llm/select.llm.md +159 -0
- package/.llm/separator.llm.md +129 -0
- package/.llm/sheet-close.llm.md +49 -0
- package/.llm/sheet-content.llm.md +115 -0
- package/.llm/sheet-description.llm.md +62 -0
- package/.llm/sheet-footer.llm.md +64 -0
- package/.llm/sheet-header.llm.md +52 -0
- package/.llm/sheet-title.llm.md +53 -0
- package/.llm/sheet-trigger.llm.md +46 -0
- package/.llm/sheet.llm.md +126 -0
- package/.llm/sidebar-content.llm.md +63 -0
- package/.llm/sidebar-footer.llm.md +50 -0
- package/.llm/sidebar-group-action.llm.md +60 -0
- package/.llm/sidebar-group-content.llm.md +64 -0
- package/.llm/sidebar-group-label.llm.md +53 -0
- package/.llm/sidebar-group.llm.md +56 -0
- package/.llm/sidebar-header.llm.md +67 -0
- package/.llm/sidebar-input.llm.md +50 -0
- package/.llm/sidebar-inset.llm.md +52 -0
- package/.llm/sidebar-menu-action.llm.md +84 -0
- package/.llm/sidebar-menu-badge.llm.md +60 -0
- package/.llm/sidebar-menu-button.llm.md +103 -0
- package/.llm/sidebar-menu-item.llm.md +75 -0
- package/.llm/sidebar-menu-skeleton.llm.md +76 -0
- package/.llm/sidebar-menu-sub-button.llm.md +85 -0
- package/.llm/sidebar-menu-sub-item.llm.md +54 -0
- package/.llm/sidebar-menu-sub.llm.md +74 -0
- package/.llm/sidebar-menu.llm.md +65 -0
- package/.llm/sidebar-provider.llm.md +79 -0
- package/.llm/sidebar-rail.llm.md +34 -0
- package/.llm/sidebar-separator.llm.md +57 -0
- package/.llm/sidebar-trigger.llm.md +49 -0
- package/.llm/sidebar.llm.md +129 -0
- package/.llm/skeleton.llm.md +134 -0
- package/.llm/slider.llm.md +173 -0
- package/.llm/spinner.llm.md +182 -0
- package/.llm/stack.llm.md +28 -0
- package/.llm/subsection-title.llm.md +46 -0
- package/.llm/switch.llm.md +76 -0
- package/.llm/table-body.llm.md +36 -0
- package/.llm/table-caption.llm.md +48 -0
- package/.llm/table-cell.llm.md +53 -0
- package/.llm/table-footer.llm.md +41 -0
- package/.llm/table-head.llm.md +69 -0
- package/.llm/table-header.llm.md +41 -0
- package/.llm/table-row.llm.md +42 -0
- package/.llm/table.llm.md +123 -0
- package/.llm/tabs-content.llm.md +47 -0
- package/.llm/tabs-list.llm.md +41 -0
- package/.llm/tabs-trigger.llm.md +47 -0
- package/.llm/tabs.llm.md +71 -0
- package/.llm/text-field.llm.md +327 -0
- package/.llm/textarea.llm.md +311 -0
- package/.llm/theme-preference.llm.md +25 -0
- package/.llm/theme-toggle.llm.md +57 -0
- package/.llm/theme.llm.md +14 -0
- package/.llm/toaster.llm.md +193 -0
- package/.llm/toggle-group-item.llm.md +59 -0
- package/.llm/toggle-group.llm.md +101 -0
- package/.llm/toggle.llm.md +40 -0
- package/.llm/tooltip-content.llm.md +185 -0
- package/.llm/tooltip-provider.llm.md +68 -0
- package/.llm/tooltip-trigger.llm.md +70 -0
- package/.llm/tooltip.llm.md +129 -0
- package/.llm/use-carousel.llm.md +55 -0
- package/.llm/use-command-state.llm.md +32 -0
- package/.llm/use-is-mobile.llm.md +73 -0
- package/.llm/use-sidebar.llm.md +61 -0
- package/dist/components/ui/scroll-area.d.ts +5 -5
- package/dist/components/ui/scroll-area.d.ts.map +1 -1
- package/dist/components/ui/stack.d.ts.map +1 -1
- package/dist/components/ui/stories/scroll-area.stories.d.ts +1 -1
- package/dist/components/ui/stories/typography.stories.d.ts +8 -108
- package/dist/components/ui/stories/typography.stories.d.ts.map +1 -1
- package/dist/components/ui/theme-toggle.d.ts +0 -3
- package/dist/components/ui/theme-toggle.d.ts.map +1 -1
- package/dist/components/ui/theme.d.ts.map +1 -1
- package/dist/components/ui/typography.d.ts +211 -474
- package/dist/components/ui/typography.d.ts.map +1 -1
- package/dist/index.js +5160 -9875
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/components/ui/stack.tsx +3 -1
- package/src/components/ui/stories/typography.stories.tsx +261 -1512
- package/src/components/ui/theme-toggle.tsx +1 -3
- package/src/components/ui/theme.tsx +6 -1
- package/src/components/ui/typography.tsx +416 -1136
- package/src/styles/globals.css +57 -106
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# DropdownMenu
|
|
2
|
+
|
|
3
|
+
**Type**: component
|
|
4
|
+
|
|
5
|
+
A versatile dropdown menu component built on Radix UI primitives Dropdown menus display a list of actions or options that a user can choose from. They're typically triggered by a button and appear as a floating panel with full keyboard navigation support, submenus, and various interactive item types. Built on Radix UI's DropdownMenu primitive with enhanced styling and type safety. Follows the WAI-ARIA Menu Button pattern for accessibility compliance.
|
|
6
|
+
|
|
7
|
+
## JSX Usage
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
import { DropdownMenu } from '@neynar/ui';
|
|
11
|
+
|
|
12
|
+
<DropdownMenu
|
|
13
|
+
defaultOpen={true}
|
|
14
|
+
open={true}
|
|
15
|
+
onOpenChange={handleOpenChange}
|
|
16
|
+
modal={true}
|
|
17
|
+
dir={value}
|
|
18
|
+
>
|
|
19
|
+
{/* Your content here */}
|
|
20
|
+
</DropdownMenu>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Component Props
|
|
24
|
+
|
|
25
|
+
### defaultOpen
|
|
26
|
+
- **Type**: `boolean`
|
|
27
|
+
- **Required**: No
|
|
28
|
+
- **Description**: Whether the dropdown is initially open (uncontrolled mode)
|
|
29
|
+
|
|
30
|
+
### open
|
|
31
|
+
- **Type**: `boolean`
|
|
32
|
+
- **Required**: No
|
|
33
|
+
- **Description**: Whether the dropdown is open (controlled mode)
|
|
34
|
+
|
|
35
|
+
### onOpenChange
|
|
36
|
+
- **Type**: `(open: boolean) => void`
|
|
37
|
+
- **Required**: No
|
|
38
|
+
- **Description**: Callback fired when the open state changes
|
|
39
|
+
|
|
40
|
+
### modal
|
|
41
|
+
- **Type**: `boolean`
|
|
42
|
+
- **Required**: No
|
|
43
|
+
- **Description**: Whether the dropdown should be modal (blocks interaction with outside elements)
|
|
44
|
+
|
|
45
|
+
### dir
|
|
46
|
+
- **Type**: `"ltr" | "rtl"`
|
|
47
|
+
- **Required**: No
|
|
48
|
+
- **Description**: The reading direction of the dropdown menu
|
|
49
|
+
|
|
50
|
+
### children
|
|
51
|
+
- **Type**: `React.ReactNode`
|
|
52
|
+
- **Required**: No
|
|
53
|
+
- **Description**: No description available
|
|
54
|
+
|
|
55
|
+
## Examples
|
|
56
|
+
|
|
57
|
+
### Example 1
|
|
58
|
+
```tsx
|
|
59
|
+
// Basic dropdown menu
|
|
60
|
+
<DropdownMenu>
|
|
61
|
+
<DropdownMenuTrigger asChild>
|
|
62
|
+
<Button variant="outline">Options</Button>
|
|
63
|
+
</DropdownMenuTrigger>
|
|
64
|
+
<DropdownMenuContent>
|
|
65
|
+
<DropdownMenuItem>Profile</DropdownMenuItem>
|
|
66
|
+
<DropdownMenuItem>Settings</DropdownMenuItem>
|
|
67
|
+
<DropdownMenuSeparator />
|
|
68
|
+
<DropdownMenuItem>Logout</DropdownMenuItem>
|
|
69
|
+
</DropdownMenuContent>
|
|
70
|
+
</DropdownMenu>
|
|
71
|
+
```
|
|
72
|
+
### Example 2
|
|
73
|
+
```tsx
|
|
74
|
+
// Controlled dropdown with alignment
|
|
75
|
+
const [open, setOpen] = useState(false);
|
|
76
|
+
<DropdownMenu open={open} onOpenChange={setOpen}>
|
|
77
|
+
<DropdownMenuTrigger asChild>
|
|
78
|
+
<Button variant="ghost" size="icon">
|
|
79
|
+
<MoreHorizontal />
|
|
80
|
+
</Button>
|
|
81
|
+
</DropdownMenuTrigger>
|
|
82
|
+
<DropdownMenuContent align="end">
|
|
83
|
+
<DropdownMenuItem>Edit</DropdownMenuItem>
|
|
84
|
+
<DropdownMenuItem>Duplicate</DropdownMenuItem>
|
|
85
|
+
<DropdownMenuSeparator />
|
|
86
|
+
<DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>
|
|
87
|
+
</DropdownMenuContent>
|
|
88
|
+
</DropdownMenu>
|
|
89
|
+
```
|
|
90
|
+
### Example 3
|
|
91
|
+
```tsx
|
|
92
|
+
// Complex menu with checkboxes, radio groups, and submenus
|
|
93
|
+
const [showPanel, setShowPanel] = useState(true);
|
|
94
|
+
const [position, setPosition] = useState("top");
|
|
95
|
+
<DropdownMenu>
|
|
96
|
+
<DropdownMenuTrigger asChild>
|
|
97
|
+
<Button>Advanced Menu</Button>
|
|
98
|
+
</DropdownMenuTrigger>
|
|
99
|
+
<DropdownMenuContent className="w-56">
|
|
100
|
+
<DropdownMenuLabel>View Options</DropdownMenuLabel>
|
|
101
|
+
<DropdownMenuSeparator />
|
|
102
|
+
<DropdownMenuCheckboxItem checked={showPanel} onCheckedChange={setShowPanel}>
|
|
103
|
+
Show Panel
|
|
104
|
+
</DropdownMenuCheckboxItem>
|
|
105
|
+
<DropdownMenuSeparator />
|
|
106
|
+
<DropdownMenuRadioGroup value={position} onValueChange={setPosition}>
|
|
107
|
+
<DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
|
|
108
|
+
<DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
|
|
109
|
+
</DropdownMenuRadioGroup>
|
|
110
|
+
<DropdownMenuSeparator />
|
|
111
|
+
<DropdownMenuSub>
|
|
112
|
+
<DropdownMenuSubTrigger>Share</DropdownMenuSubTrigger>
|
|
113
|
+
<DropdownMenuSubContent>
|
|
114
|
+
<DropdownMenuItem>Email</DropdownMenuItem>
|
|
115
|
+
<DropdownMenuItem>Copy Link</DropdownMenuItem>
|
|
116
|
+
</DropdownMenuSubContent>
|
|
117
|
+
</DropdownMenuSub>
|
|
118
|
+
</DropdownMenuContent>
|
|
119
|
+
</DropdownMenu>
|
|
120
|
+
```
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# EmptyContent
|
|
2
|
+
|
|
3
|
+
**Type**: component
|
|
4
|
+
|
|
5
|
+
EmptyContent - Additional content area for buttons, actions, or secondary information A flexible container for additional content within an empty state, typically used for action buttons, links, or secondary information. Provides consistent width constraints, gap spacing, and alignment for optimal layout of calls-to-action and supplementary content. ## Features - Maximum width of 24rem (384px) for visual balance - Minimum width of 0 to prevent overflow issues - Flex column layout with 1rem (16px) gap between children - Center-aligned items for button grouping - Small text size (text-sm) for secondary content - Text balance for improved multi-line typography - Full width within constraints (w-full) ## Common Use Cases - Primary and secondary action buttons - Button groups with multiple actions - Secondary links or navigation - Additional context or instructions - Step indicators or progress information ## Layout Patterns - Single button: automatically centered - Multiple buttons: stack vertically with gap spacing - Button groups: use flex-row with gap within content - Text content: maintains readability with text-balance
|
|
6
|
+
|
|
7
|
+
## JSX Usage
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
import { EmptyContent } from '@neynar/ui';
|
|
11
|
+
|
|
12
|
+
<EmptyContent
|
|
13
|
+
className="value"
|
|
14
|
+
>
|
|
15
|
+
{/* Your content here */}
|
|
16
|
+
</EmptyContent>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Component Props
|
|
20
|
+
|
|
21
|
+
### className
|
|
22
|
+
- **Type**: `string`
|
|
23
|
+
- **Required**: No
|
|
24
|
+
- **Description**: No description available
|
|
25
|
+
|
|
26
|
+
### children
|
|
27
|
+
- **Type**: `React.ReactNode`
|
|
28
|
+
- **Required**: No
|
|
29
|
+
- **Description**: No description available
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+
### Example 1
|
|
34
|
+
```tsx
|
|
35
|
+
// Single action button
|
|
36
|
+
import { Button } from './button';
|
|
37
|
+
<EmptyContent>
|
|
38
|
+
<Button onClick={handleCreate}>Create new project</Button>
|
|
39
|
+
</EmptyContent>
|
|
40
|
+
```
|
|
41
|
+
### Example 2
|
|
42
|
+
```tsx
|
|
43
|
+
// Multiple vertically stacked buttons
|
|
44
|
+
import { Button } from './button';
|
|
45
|
+
<EmptyContent>
|
|
46
|
+
<Button onClick={handleCreate}>Create project</Button>
|
|
47
|
+
<Button variant="outline" onClick={handleImport}>Import project</Button>
|
|
48
|
+
</EmptyContent>
|
|
49
|
+
```
|
|
50
|
+
### Example 3
|
|
51
|
+
```tsx
|
|
52
|
+
// Horizontal button group
|
|
53
|
+
import { Button } from './button';
|
|
54
|
+
import { Plus, Upload } from 'lucide-react';
|
|
55
|
+
<EmptyContent>
|
|
56
|
+
<div className="flex gap-2">
|
|
57
|
+
<Button onClick={handleCreate}>
|
|
58
|
+
<Plus className="w-4 h-4 mr-2" />
|
|
59
|
+
Create
|
|
60
|
+
</Button>
|
|
61
|
+
<Button variant="outline" onClick={handleUpload}>
|
|
62
|
+
<Upload className="w-4 h-4 mr-2" />
|
|
63
|
+
Upload
|
|
64
|
+
</Button>
|
|
65
|
+
</div>
|
|
66
|
+
</EmptyContent>
|
|
67
|
+
```
|
|
68
|
+
### Example 4
|
|
69
|
+
```tsx
|
|
70
|
+
// Button with additional text
|
|
71
|
+
import { Button } from './button';
|
|
72
|
+
<EmptyContent>
|
|
73
|
+
<Button onClick={handleInvite}>Invite team members</Button>
|
|
74
|
+
<p className="text-xs text-muted-foreground">
|
|
75
|
+
or <a href="/import" className="underline">import from CSV</a>
|
|
76
|
+
</p>
|
|
77
|
+
</EmptyContent>
|
|
78
|
+
```
|
|
79
|
+
### Example 5
|
|
80
|
+
```tsx
|
|
81
|
+
// Secondary links only
|
|
82
|
+
<EmptyContent>
|
|
83
|
+
<a href="/docs" className="text-sm underline underline-offset-4">
|
|
84
|
+
View documentation
|
|
85
|
+
</a>
|
|
86
|
+
<a href="/examples" className="text-sm underline underline-offset-4">
|
|
87
|
+
Browse examples
|
|
88
|
+
</a>
|
|
89
|
+
</EmptyContent>
|
|
90
|
+
```
|
|
91
|
+
### Example 6
|
|
92
|
+
```tsx
|
|
93
|
+
// Custom styled content area
|
|
94
|
+
import { Button } from './button';
|
|
95
|
+
<EmptyContent className="max-w-md gap-2">
|
|
96
|
+
<Button className="w-full" onClick={handleAction}>
|
|
97
|
+
Full width button
|
|
98
|
+
</Button>
|
|
99
|
+
<p className="text-center">
|
|
100
|
+
Tighter gap and wider max width
|
|
101
|
+
</p>
|
|
102
|
+
</EmptyContent>
|
|
103
|
+
```
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# EmptyDescription
|
|
2
|
+
|
|
3
|
+
**Type**: component
|
|
4
|
+
|
|
5
|
+
EmptyDescription - Descriptive text with link styling for empty states Provides supplementary information, guidance, or context below the empty state title. Automatically styles inline links with underlines and hover effects, making it easy to include helpful links or documentation references within the description text. ## Features - Muted foreground color for visual hierarchy below title - Small text size (text-sm) with relaxed line height for readability - Automatic link styling with underlines and offset - Hover state for links changes color to primary - Supports rich content including paragraphs and inline elements - Center-aligned text within empty state layout ## Link Styling - Default: underline with 4px offset, muted-foreground color - Hover: primary color while maintaining underline - Provides clear visual affordance for interactive elements ## Best Practices - Provide helpful context or next steps - Keep descriptions concise (1-2 sentences) - Include actionable guidance when possible - Use links to documentation, help, or related features - Avoid overwhelming users with too much information
|
|
6
|
+
|
|
7
|
+
## JSX Usage
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
import { EmptyDescription } from '@neynar/ui';
|
|
11
|
+
|
|
12
|
+
<EmptyDescription
|
|
13
|
+
className="value"
|
|
14
|
+
>
|
|
15
|
+
{/* Your content here */}
|
|
16
|
+
</EmptyDescription>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Component Props
|
|
20
|
+
|
|
21
|
+
### className
|
|
22
|
+
- **Type**: `string`
|
|
23
|
+
- **Required**: No
|
|
24
|
+
- **Description**: No description available
|
|
25
|
+
|
|
26
|
+
### children
|
|
27
|
+
- **Type**: `React.ReactNode`
|
|
28
|
+
- **Required**: No
|
|
29
|
+
- **Description**: No description available
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+
### Example 1
|
|
34
|
+
```tsx
|
|
35
|
+
// Simple description text
|
|
36
|
+
<EmptyDescription>
|
|
37
|
+
Try adjusting your search or filters to find what you're looking for.
|
|
38
|
+
</EmptyDescription>
|
|
39
|
+
```
|
|
40
|
+
### Example 2
|
|
41
|
+
```tsx
|
|
42
|
+
// Description with inline link
|
|
43
|
+
<EmptyDescription>
|
|
44
|
+
Get started by <a href="/docs/setup">reading our setup guide</a> or
|
|
45
|
+
watching the tutorial video.
|
|
46
|
+
</EmptyDescription>
|
|
47
|
+
```
|
|
48
|
+
### Example 3
|
|
49
|
+
```tsx
|
|
50
|
+
// Multi-line description
|
|
51
|
+
<EmptyDescription>
|
|
52
|
+
Your inbox is empty. New messages and notifications will appear here
|
|
53
|
+
when you receive them.
|
|
54
|
+
</EmptyDescription>
|
|
55
|
+
```
|
|
56
|
+
### Example 4
|
|
57
|
+
```tsx
|
|
58
|
+
// Description with multiple links
|
|
59
|
+
<EmptyDescription>
|
|
60
|
+
Need help? Check out our <a href="/docs">documentation</a> or
|
|
61
|
+
<a href="/support">contact support</a>.
|
|
62
|
+
</EmptyDescription>
|
|
63
|
+
```
|
|
64
|
+
### Example 5
|
|
65
|
+
```tsx
|
|
66
|
+
// Custom styled description
|
|
67
|
+
<EmptyDescription className="text-base text-foreground max-w-md">
|
|
68
|
+
Override default styling for custom appearance and width.
|
|
69
|
+
</EmptyDescription>
|
|
70
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# EmptyHeader
|
|
2
|
+
|
|
3
|
+
**Type**: component
|
|
4
|
+
|
|
5
|
+
EmptyHeader - Groups media and title elements with constrained width A container component that groups the EmptyMedia and EmptyTitle elements together, applying a maximum width constraint (max-w-sm / 24rem) for optimal visual hierarchy and readability. Typically used to create a cohesive header unit within the empty state. ## Features - Maximum width of 24rem (384px) for visual balance - Flex column layout with 0.5rem (8px) gap between children - Center-aligned items and text - Maintains semantic grouping for screen readers ## Usage Patterns - Group EmptyMedia and EmptyTitle together - Create visual separation from description and content - Constrain width of title for better readability - Optional - components can be used without header grouping
|
|
6
|
+
|
|
7
|
+
## JSX Usage
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
import { EmptyHeader } from '@neynar/ui';
|
|
11
|
+
|
|
12
|
+
<EmptyHeader
|
|
13
|
+
className="value"
|
|
14
|
+
>
|
|
15
|
+
{/* Your content here */}
|
|
16
|
+
</EmptyHeader>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Component Props
|
|
20
|
+
|
|
21
|
+
### className
|
|
22
|
+
- **Type**: `string`
|
|
23
|
+
- **Required**: No
|
|
24
|
+
- **Description**: No description available
|
|
25
|
+
|
|
26
|
+
### children
|
|
27
|
+
- **Type**: `React.ReactNode`
|
|
28
|
+
- **Required**: No
|
|
29
|
+
- **Description**: No description available
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+
### Example 1
|
|
34
|
+
```tsx
|
|
35
|
+
// Standard header with icon and title
|
|
36
|
+
import { Package } from 'lucide-react';
|
|
37
|
+
<EmptyHeader>
|
|
38
|
+
<EmptyMedia variant="icon">
|
|
39
|
+
<Package />
|
|
40
|
+
</EmptyMedia>
|
|
41
|
+
<EmptyTitle>No packages found</EmptyTitle>
|
|
42
|
+
</EmptyHeader>
|
|
43
|
+
```
|
|
44
|
+
### Example 2
|
|
45
|
+
```tsx
|
|
46
|
+
// Header with large illustration
|
|
47
|
+
import { Rocket } from 'lucide-react';
|
|
48
|
+
<EmptyHeader>
|
|
49
|
+
<EmptyMedia>
|
|
50
|
+
<Rocket className="w-20 h-20 text-primary" />
|
|
51
|
+
</EmptyMedia>
|
|
52
|
+
<EmptyTitle>Ready to launch!</EmptyTitle>
|
|
53
|
+
</EmptyHeader>
|
|
54
|
+
```
|
|
55
|
+
### Example 3
|
|
56
|
+
```tsx
|
|
57
|
+
// Custom styled header
|
|
58
|
+
<EmptyHeader className="max-w-md gap-4">
|
|
59
|
+
<EmptyMedia variant="icon">
|
|
60
|
+
<Star />
|
|
61
|
+
</EmptyMedia>
|
|
62
|
+
<EmptyTitle>Custom spacing and width</EmptyTitle>
|
|
63
|
+
</EmptyHeader>
|
|
64
|
+
```
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# EmptyMedia
|
|
2
|
+
|
|
3
|
+
**Type**: component
|
|
4
|
+
|
|
5
|
+
EmptyMedia - Icon or illustration display component with styling variants Displays icons, illustrations, or other visual elements in an empty state. Offers two variants: a transparent default for custom-sized graphics and an "icon" variant with consistent sizing and background styling. Automatically handles SVG pointer events and shrinking behavior. ## Variants ### default - Transparent background (bg-transparent) - No size constraints - use for custom-sized illustrations - Full control over icon/illustration dimensions - Best for large decorative graphics (48px+) ### icon - Muted background (bg-muted) with rounded corners (rounded-lg) - Fixed 40px × 40px container (size-10) - Automatically sizes child SVGs to 24px (size-6) unless explicitly sized - Text color set to foreground for proper contrast - Best for standard icon sizes (16-24px) - Provides visual emphasis through background contrast ## Features - SVG pointer events disabled to prevent interaction issues - Shrink prevention for consistent sizing - Bottom margin (mb-2 / 8px) for spacing from subsequent elements - Flex layout with centered content - Compatible with all icon libraries (lucide-react, heroicons, etc.)
|
|
6
|
+
|
|
7
|
+
## JSX Usage
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
import { EmptyMedia } from '@neynar/ui';
|
|
11
|
+
|
|
12
|
+
<EmptyMedia
|
|
13
|
+
variant={value}
|
|
14
|
+
className="value"
|
|
15
|
+
>
|
|
16
|
+
{/* Your content here */}
|
|
17
|
+
</EmptyMedia>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Component Props
|
|
21
|
+
|
|
22
|
+
### variant
|
|
23
|
+
- **Type**: `"default" | "icon"`
|
|
24
|
+
- **Required**: No
|
|
25
|
+
- **Description**: No description available
|
|
26
|
+
|
|
27
|
+
### className
|
|
28
|
+
- **Type**: `string`
|
|
29
|
+
- **Required**: No
|
|
30
|
+
- **Description**: No description available
|
|
31
|
+
|
|
32
|
+
### children
|
|
33
|
+
- **Type**: `React.ReactNode`
|
|
34
|
+
- **Required**: No
|
|
35
|
+
- **Description**: No description available
|
|
36
|
+
|
|
37
|
+
## Examples
|
|
38
|
+
|
|
39
|
+
### Example 1
|
|
40
|
+
```tsx
|
|
41
|
+
// Standard icon variant with auto-sizing
|
|
42
|
+
import { Inbox } from 'lucide-react';
|
|
43
|
+
<EmptyMedia variant="icon">
|
|
44
|
+
<Inbox />
|
|
45
|
+
</EmptyMedia>
|
|
46
|
+
```
|
|
47
|
+
### Example 2
|
|
48
|
+
```tsx
|
|
49
|
+
// Default variant with custom-sized illustration
|
|
50
|
+
import { Package } from 'lucide-react';
|
|
51
|
+
<EmptyMedia>
|
|
52
|
+
<Package className="w-16 h-16 text-primary" />
|
|
53
|
+
</EmptyMedia>
|
|
54
|
+
```
|
|
55
|
+
### Example 3
|
|
56
|
+
```tsx
|
|
57
|
+
// Icon variant with explicitly sized SVG (overrides auto-sizing)
|
|
58
|
+
import { Search } from 'lucide-react';
|
|
59
|
+
<EmptyMedia variant="icon">
|
|
60
|
+
<Search className="size-5" />
|
|
61
|
+
</EmptyMedia>
|
|
62
|
+
```
|
|
63
|
+
### Example 4
|
|
64
|
+
```tsx
|
|
65
|
+
// Custom styled media container
|
|
66
|
+
import { Sparkles } from 'lucide-react';
|
|
67
|
+
<EmptyMedia className="bg-primary/10 rounded-full p-4">
|
|
68
|
+
<Sparkles className="w-8 h-8 text-primary" />
|
|
69
|
+
</EmptyMedia>
|
|
70
|
+
```
|
|
71
|
+
### Example 5
|
|
72
|
+
```tsx
|
|
73
|
+
// Multiple icons or complex graphics
|
|
74
|
+
import { Users, Plus } from 'lucide-react';
|
|
75
|
+
<EmptyMedia>
|
|
76
|
+
<div className="relative">
|
|
77
|
+
<Users className="w-12 h-12 text-muted-foreground" />
|
|
78
|
+
<Plus className="w-6 h-6 text-primary absolute -bottom-1 -right-1" />
|
|
79
|
+
</div>
|
|
80
|
+
</EmptyMedia>
|
|
81
|
+
```
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# EmptyState
|
|
2
|
+
|
|
3
|
+
**Type**: component
|
|
4
|
+
|
|
5
|
+
EmptyState - Displays empty or no-data states with consistent UX patterns A comprehensive component for handling empty states across applications. Provides a standardized way to communicate when content is unavailable, data is missing, or initial setup is required. Built with accessibility-first principles and follows established empty state design patterns to guide users toward resolution. **Common Use Cases:** - Search results with no matches - Empty lists, tables, or dashboards - Inbox or notification centers with no items - Data visualization with no data - Onboarding states for new users - Error recovery scenarios **Component Structure:** The component follows a top-down visual hierarchy: Icon → Title → Description → Action. All elements except the title are optional, allowing for flexible implementation across different contexts while maintaining visual consistency.
|
|
6
|
+
|
|
7
|
+
## JSX Usage
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
import { EmptyState } from '@neynar/ui';
|
|
11
|
+
|
|
12
|
+
<EmptyState
|
|
13
|
+
title="value"
|
|
14
|
+
description="value"
|
|
15
|
+
icon={value}
|
|
16
|
+
action={() => {}}
|
|
17
|
+
className="value"
|
|
18
|
+
>
|
|
19
|
+
{/* Your content here */}
|
|
20
|
+
</EmptyState>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Component Props
|
|
24
|
+
|
|
25
|
+
### title
|
|
26
|
+
- **Type**: `string`
|
|
27
|
+
- **Required**: Yes
|
|
28
|
+
- **Description**: No description available
|
|
29
|
+
|
|
30
|
+
### description
|
|
31
|
+
- **Type**: `string`
|
|
32
|
+
- **Required**: No
|
|
33
|
+
- **Description**: No description available
|
|
34
|
+
|
|
35
|
+
### icon
|
|
36
|
+
- **Type**: `React.ReactNode`
|
|
37
|
+
- **Required**: No
|
|
38
|
+
- **Description**: No description available
|
|
39
|
+
|
|
40
|
+
### action
|
|
41
|
+
- **Type**: `{
|
|
42
|
+
/**
|
|
43
|
+
* Text label for the action button
|
|
44
|
+
*
|
|
45
|
+
* Should be specific and action-oriented rather than generic.
|
|
46
|
+
* @example "Create your first post", "Import data", "Try again"
|
|
47
|
+
*/
|
|
48
|
+
label: string;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Click handler function executed when the action button is pressed
|
|
52
|
+
*
|
|
53
|
+
* Called when the user activates the button via click or keyboard interaction.
|
|
54
|
+
* Should handle the primary action to resolve the empty state.
|
|
55
|
+
*/
|
|
56
|
+
onClick: () => void;
|
|
57
|
+
}`
|
|
58
|
+
- **Required**: No
|
|
59
|
+
- **Description**: No description available
|
|
60
|
+
|
|
61
|
+
### className
|
|
62
|
+
- **Type**: `string`
|
|
63
|
+
- **Required**: No
|
|
64
|
+
- **Description**: No description available
|
|
65
|
+
|
|
66
|
+
### children
|
|
67
|
+
- **Type**: `React.ReactNode`
|
|
68
|
+
- **Required**: No
|
|
69
|
+
- **Description**: No description available
|
|
70
|
+
|
|
71
|
+
## Examples
|
|
72
|
+
|
|
73
|
+
### Example 1
|
|
74
|
+
```tsx
|
|
75
|
+
// Minimal empty state with just title
|
|
76
|
+
<EmptyState title="No notifications" />
|
|
77
|
+
```
|
|
78
|
+
### Example 2
|
|
79
|
+
```tsx
|
|
80
|
+
// Search results empty state
|
|
81
|
+
import { Search } from 'lucide-react';
|
|
82
|
+
<EmptyState
|
|
83
|
+
icon={<Search className="w-12 h-12" />}
|
|
84
|
+
title="No results found"
|
|
85
|
+
description="Try adjusting your search terms or filters"
|
|
86
|
+
action={{
|
|
87
|
+
label: "Clear filters",
|
|
88
|
+
onClick: () => resetFilters()
|
|
89
|
+
}}
|
|
90
|
+
/>
|
|
91
|
+
```
|
|
92
|
+
### Example 3
|
|
93
|
+
```tsx
|
|
94
|
+
// Inbox empty state with call-to-action
|
|
95
|
+
import { Inbox, Plus } from 'lucide-react';
|
|
96
|
+
<EmptyState
|
|
97
|
+
icon={<Inbox className="w-16 h-16" />}
|
|
98
|
+
title="Your inbox is empty"
|
|
99
|
+
description="New messages and notifications will appear here"
|
|
100
|
+
action={{
|
|
101
|
+
label: "Compose message",
|
|
102
|
+
onClick: () => openComposer()
|
|
103
|
+
}}
|
|
104
|
+
/>
|
|
105
|
+
```
|
|
106
|
+
### Example 4
|
|
107
|
+
```tsx
|
|
108
|
+
// Data dashboard empty state with custom styling
|
|
109
|
+
import { BarChart3, TrendingUp } from 'lucide-react';
|
|
110
|
+
<EmptyState
|
|
111
|
+
className="min-h-[400px] bg-gradient-to-br from-muted/20 to-muted/10 rounded-lg border border-dashed border-muted-foreground/20"
|
|
112
|
+
icon={<BarChart3 className="w-14 h-14 opacity-60" />}
|
|
113
|
+
title="No analytics data"
|
|
114
|
+
description="Connect your data source or import historical data to view insights"
|
|
115
|
+
action={{
|
|
116
|
+
label: "Connect data source",
|
|
117
|
+
onClick: () => showDataSourceModal()
|
|
118
|
+
}}
|
|
119
|
+
/>
|
|
120
|
+
```
|
|
121
|
+
### Example 5
|
|
122
|
+
```tsx
|
|
123
|
+
// File manager empty state
|
|
124
|
+
import { FolderOpen, Upload } from 'lucide-react';
|
|
125
|
+
<EmptyState
|
|
126
|
+
icon={<FolderOpen className="w-12 h-12" />}
|
|
127
|
+
title="This folder is empty"
|
|
128
|
+
description="Drag and drop files here or use the upload button"
|
|
129
|
+
action={{
|
|
130
|
+
label: "Upload files",
|
|
131
|
+
onClick: () => triggerFileUpload()
|
|
132
|
+
}}
|
|
133
|
+
/>
|
|
134
|
+
```
|
|
135
|
+
### Example 6
|
|
136
|
+
```tsx
|
|
137
|
+
// Error recovery empty state
|
|
138
|
+
import { AlertTriangle, RefreshCw } from 'lucide-react';
|
|
139
|
+
<EmptyState
|
|
140
|
+
icon={<AlertTriangle className="w-12 h-12 text-destructive" />}
|
|
141
|
+
title="Failed to load data"
|
|
142
|
+
description="There was a problem loading your content. Please try again."
|
|
143
|
+
action={{
|
|
144
|
+
label: "Retry",
|
|
145
|
+
onClick: () => refetchData()
|
|
146
|
+
}}
|
|
147
|
+
/>
|
|
148
|
+
```
|
|
149
|
+
### Example 7
|
|
150
|
+
```tsx
|
|
151
|
+
// Team members empty state with multiple actions
|
|
152
|
+
import { Users, UserPlus, Mail } from 'lucide-react';
|
|
153
|
+
function TeamEmptyState() {
|
|
154
|
+
return (
|
|
155
|
+
<div className="space-y-4">
|
|
156
|
+
<EmptyState
|
|
157
|
+
icon={<Users className="w-16 h-16" />}
|
|
158
|
+
title="No team members yet"
|
|
159
|
+
description="Invite colleagues to collaborate on projects"
|
|
160
|
+
action={{
|
|
161
|
+
label: "Invite members",
|
|
162
|
+
onClick: () => openInviteModal()
|
|
163
|
+
}}
|
|
164
|
+
/>
|
|
165
|
+
<div className="flex justify-center gap-2">
|
|
166
|
+
<Button variant="outline" size="sm" onClick={() => importFromCsv()}>
|
|
167
|
+
<Mail className="w-4 h-4 mr-2" />
|
|
168
|
+
Import from CSV
|
|
169
|
+
</Button>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
```
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# EmptyTitle
|
|
2
|
+
|
|
3
|
+
**Type**: component
|
|
4
|
+
|
|
5
|
+
EmptyTitle - Prominent heading text for empty state messages Displays the primary heading or title for an empty state, styled with medium font weight and tight character spacing for visual hierarchy. Typically describes what is missing or the current state in a concise, user-friendly way. ## Features - Large text size (text-lg / 1.125rem / 18px) - Medium font weight (font-medium / 500) for emphasis - Tight character spacing (tracking-tight / -0.025em) for readability - Foreground color for maximum contrast - Center-aligned within empty state layout ## Best Practices - Keep titles short and descriptive (2-6 words) - Focus on the current state rather than what's wrong - Use positive language when possible - Be specific rather than generic ("No projects" vs "Empty") - Avoid technical jargon or error codes
|
|
6
|
+
|
|
7
|
+
## JSX Usage
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
import { EmptyTitle } from '@neynar/ui';
|
|
11
|
+
|
|
12
|
+
<EmptyTitle
|
|
13
|
+
className="value"
|
|
14
|
+
>
|
|
15
|
+
{/* Your content here */}
|
|
16
|
+
</EmptyTitle>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Component Props
|
|
20
|
+
|
|
21
|
+
### className
|
|
22
|
+
- **Type**: `string`
|
|
23
|
+
- **Required**: No
|
|
24
|
+
- **Description**: No description available
|
|
25
|
+
|
|
26
|
+
### children
|
|
27
|
+
- **Type**: `React.ReactNode`
|
|
28
|
+
- **Required**: No
|
|
29
|
+
- **Description**: No description available
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+
### Example 1
|
|
34
|
+
```tsx
|
|
35
|
+
// Simple descriptive title
|
|
36
|
+
<EmptyTitle>No results found</EmptyTitle>
|
|
37
|
+
```
|
|
38
|
+
### Example 2
|
|
39
|
+
```tsx
|
|
40
|
+
// Positive framing for empty inbox
|
|
41
|
+
<EmptyTitle>You're all caught up!</EmptyTitle>
|
|
42
|
+
```
|
|
43
|
+
### Example 3
|
|
44
|
+
```tsx
|
|
45
|
+
// Specific empty list title
|
|
46
|
+
<EmptyTitle>No team members yet</EmptyTitle>
|
|
47
|
+
```
|
|
48
|
+
### Example 4
|
|
49
|
+
```tsx
|
|
50
|
+
// Custom styled title
|
|
51
|
+
<EmptyTitle className="text-xl font-semibold text-primary">
|
|
52
|
+
Welcome to your dashboard
|
|
53
|
+
</EmptyTitle>
|
|
54
|
+
```
|