@nexub/mcp 2.7.0 → 2.9.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.
Files changed (103) hide show
  1. package/dist/skill/references/components/accordion.md +40 -45
  2. package/dist/skill/references/components/activity-feed.md +13 -12
  3. package/dist/skill/references/components/alert-dialog.md +26 -22
  4. package/dist/skill/references/components/alert.md +26 -8
  5. package/dist/skill/references/components/amount.md +15 -3
  6. package/dist/skill/references/components/auth-card.md +22 -11
  7. package/dist/skill/references/components/autocomplete.md +42 -21
  8. package/dist/skill/references/components/avatar-group.md +13 -6
  9. package/dist/skill/references/components/avatar.md +31 -10
  10. package/dist/skill/references/components/badge.md +37 -16
  11. package/dist/skill/references/components/banner.md +18 -7
  12. package/dist/skill/references/components/bento-grid.md +33 -11
  13. package/dist/skill/references/components/box.md +21 -9
  14. package/dist/skill/references/components/breadcrumb.md +32 -34
  15. package/dist/skill/references/components/button-group.md +32 -14
  16. package/dist/skill/references/components/button.md +57 -32
  17. package/dist/skill/references/components/callout.md +10 -2
  18. package/dist/skill/references/components/card.md +54 -22
  19. package/dist/skill/references/components/checkbox-card.md +23 -8
  20. package/dist/skill/references/components/checkbox.md +32 -19
  21. package/dist/skill/references/components/chip.md +22 -10
  22. package/dist/skill/references/components/citation.md +18 -10
  23. package/dist/skill/references/components/code-inline.md +20 -2
  24. package/dist/skill/references/components/collapsible.md +38 -33
  25. package/dist/skill/references/components/combobox.md +18 -16
  26. package/dist/skill/references/components/conversation.md +23 -11
  27. package/dist/skill/references/components/data-table.md +40 -36
  28. package/dist/skill/references/components/date-picker.md +21 -17
  29. package/dist/skill/references/components/date-range-picker.md +11 -5
  30. package/dist/skill/references/components/dialog.md +26 -22
  31. package/dist/skill/references/components/drawer.md +66 -44
  32. package/dist/skill/references/components/empty-state.md +40 -50
  33. package/dist/skill/references/components/error-state.md +22 -10
  34. package/dist/skill/references/components/error-summary.md +20 -14
  35. package/dist/skill/references/components/eyebrow-chip.md +15 -5
  36. package/dist/skill/references/components/filter-bar.md +18 -14
  37. package/dist/skill/references/components/filter-chip.md +12 -5
  38. package/dist/skill/references/components/flex.md +31 -15
  39. package/dist/skill/references/components/form-field.md +11 -5
  40. package/dist/skill/references/components/gradient-divider.md +5 -1
  41. package/dist/skill/references/components/grid.md +22 -14
  42. package/dist/skill/references/components/heading.md +30 -14
  43. package/dist/skill/references/components/helper-text.md +17 -7
  44. package/dist/skill/references/components/hover-card.md +21 -12
  45. package/dist/skill/references/components/icon-button.md +19 -17
  46. package/dist/skill/references/components/info-list.md +15 -6
  47. package/dist/skill/references/components/input.md +32 -12
  48. package/dist/skill/references/components/kbd.md +21 -19
  49. package/dist/skill/references/components/label.md +20 -6
  50. package/dist/skill/references/components/link.md +21 -7
  51. package/dist/skill/references/components/list-detail.md +27 -6
  52. package/dist/skill/references/components/media-card.md +55 -16
  53. package/dist/skill/references/components/message-bubble.md +30 -13
  54. package/dist/skill/references/components/money-input.md +10 -2
  55. package/dist/skill/references/components/motion-collapse.md +22 -22
  56. package/dist/skill/references/components/motion-fade.md +19 -15
  57. package/dist/skill/references/components/motion-scale.md +13 -20
  58. package/dist/skill/references/components/motion-slide.md +13 -25
  59. package/dist/skill/references/components/navigation-rail.md +14 -5
  60. package/dist/skill/references/components/notification-item.md +10 -6
  61. package/dist/skill/references/components/number-input.md +10 -2
  62. package/dist/skill/references/components/number-ticker.md +27 -6
  63. package/dist/skill/references/components/pagination.md +11 -20
  64. package/dist/skill/references/components/password-input.md +13 -2
  65. package/dist/skill/references/components/plan-card.md +17 -9
  66. package/dist/skill/references/components/popover.md +31 -21
  67. package/dist/skill/references/components/progress.md +22 -8
  68. package/dist/skill/references/components/prompt-input.md +57 -29
  69. package/dist/skill/references/components/radio-card.md +41 -22
  70. package/dist/skill/references/components/radio-group.md +32 -28
  71. package/dist/skill/references/components/rating.md +23 -7
  72. package/dist/skill/references/components/scroll-area.md +30 -29
  73. package/dist/skill/references/components/search-input.md +5 -1
  74. package/dist/skill/references/components/segmented-control.md +26 -19
  75. package/dist/skill/references/components/select.md +16 -8
  76. package/dist/skill/references/components/separator.md +16 -6
  77. package/dist/skill/references/components/settings-section.md +19 -10
  78. package/dist/skill/references/components/sheet.md +25 -22
  79. package/dist/skill/references/components/skeleton.md +29 -12
  80. package/dist/skill/references/components/slider.md +10 -2
  81. package/dist/skill/references/components/spinner.md +17 -8
  82. package/dist/skill/references/components/split-button.md +26 -15
  83. package/dist/skill/references/components/stack.md +22 -10
  84. package/dist/skill/references/components/stat-card.md +34 -15
  85. package/dist/skill/references/components/status-pill.md +18 -12
  86. package/dist/skill/references/components/step-indicator.md +10 -9
  87. package/dist/skill/references/components/streaming-text.md +21 -12
  88. package/dist/skill/references/components/switch.md +10 -9
  89. package/dist/skill/references/components/table.md +66 -60
  90. package/dist/skill/references/components/tabs.md +24 -16
  91. package/dist/skill/references/components/tag.md +13 -5
  92. package/dist/skill/references/components/text-gradient.md +14 -5
  93. package/dist/skill/references/components/text.md +29 -12
  94. package/dist/skill/references/components/textarea.md +21 -7
  95. package/dist/skill/references/components/thinking-indicator.md +16 -4
  96. package/dist/skill/references/components/toast.md +41 -64
  97. package/dist/skill/references/components/toggle-group.md +22 -10
  98. package/dist/skill/references/components/toggle.md +15 -5
  99. package/dist/skill/references/components/tooltip.md +22 -9
  100. package/dist/skill/references/components/user-card.md +9 -5
  101. package/dist/skill/references/components.md +1 -1
  102. package/dist/skill/references/tokens.md +1 -1
  103. package/package.json +1 -1
@@ -20,49 +20,54 @@ Toggle visibility of content with smooth animation.
20
20
  ## Example: Default
21
21
 
22
22
  ```tsx
23
- <Collapsible.Root>
24
- <Collapsible.Trigger asChild>
25
- <Button variant="outline">Toggle details</Button>
26
- </Collapsible.Trigger>
27
- <Collapsible.Content>
28
- <div style={{ paddingTop: '12px', color: 'var(--color-text-secondary)' }}>
29
- Hidden content revealed on toggle.
30
- </div>
31
- </Collapsible.Content>
32
- </Collapsible.Root>
23
+ import * as React from 'react';
24
+ import { Collapsible, Button } from '@nexub/react';
25
+
26
+ export default function Example() {
27
+ const [open, setOpen] = React.useState(false);
28
+ return (
29
+ <Collapsible.Root open={open} onOpenChange={setOpen}>
30
+ <Collapsible.Trigger asChild>
31
+ <Button variant="outline">{open ? 'Hide details' : 'Show details'}</Button>
32
+ </Collapsible.Trigger>
33
+ <Collapsible.Content>
34
+ <div className="pt-3 text-[var(--color-on-surface-variant)] text-body-sm">
35
+ Hidden content revealed on toggle. This section can hold any content.
36
+ </div>
37
+ </Collapsible.Content>
38
+ </Collapsible.Root>
39
+ );
40
+ }
33
41
  ```
34
42
 
35
43
  ## Example: Controlled
36
44
 
37
45
  ```tsx
38
- function ControlledExample() {
39
- const [open, setOpen] = React.useState(false);
46
+ import * as React from 'react';
47
+ import { Collapsible, Button, Switch, Label } from '@nexub/react';
48
+
49
+ export default function Example() {
50
+ const [open2, setOpen2] = React.useState(false);
40
51
  return (
41
- <Collapsible.Root open={open} onOpenChange={setOpen}>
42
- <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
43
- <span style={{ fontWeight: 500 }}>Advanced settings</span>
52
+ <Collapsible.Root open={open2} onOpenChange={setOpen2}>
53
+ <div className="flex items-center gap-2">
54
+ <span className="font-medium text-[var(--color-on-surface)] text-body-sm">Advanced settings</span>
44
55
  <Collapsible.Trigger asChild>
45
- <IconButton
46
- aria-label={open ? 'Collapse' : 'Expand'}
47
- variant="ghost"
48
- size="sm"
49
- />
56
+ <Button variant="ghost" size="sm">{open2 ? 'Collapse' : 'Expand'}</Button>
50
57
  </Collapsible.Trigger>
51
58
  </div>
52
59
  <Collapsible.Content>
53
- <div style={{ paddingTop: '12px', display: 'flex', flexDirection: 'column', gap: '12px' }}>
54
- <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
55
- <Switch id="notif" />
56
- <Label htmlFor="notif">Enable notifications</Label>
57
- </div>
58
- <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
59
- <Switch id="autosave" />
60
- <Label htmlFor="autosave">Auto-save drafts</Label>
61
- </div>
62
- <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
63
- <Switch id="tooltips" />
64
- <Label htmlFor="tooltips">Show tooltips</Label>
65
- </div>
60
+ <div className="pt-3 flex flex-col gap-3">
61
+ {[
62
+ { id: 'notif', label: 'Enable notifications' },
63
+ { id: 'autosave', label: 'Auto-save drafts' },
64
+ { id: 'tooltips', label: 'Show tooltips' },
65
+ ].map(({ id, label }) => (
66
+ <div key={id} className="flex items-center gap-2">
67
+ <Switch id={id} />
68
+ <Label htmlFor={id}>{label}</Label>
69
+ </div>
70
+ ))}
66
71
  </div>
67
72
  </Collapsible.Content>
68
73
  </Collapsible.Root>
@@ -21,20 +21,22 @@ Command-palette style searchable dropdown built on cmdk.
21
21
  ## Example: Default
22
22
 
23
23
  ```tsx
24
- <Combobox.Root>
25
- <Combobox.Input placeholder="Search..." />
26
- <Combobox.List>
27
- <Combobox.Empty>No results found.</Combobox.Empty>
28
- <Combobox.Group heading="Frameworks">
29
- <Combobox.Item value="react">React</Combobox.Item>
30
- <Combobox.Item value="vue">Vue</Combobox.Item>
31
- <Combobox.Item value="svelte">Svelte</Combobox.Item>
32
- </Combobox.Group>
33
- <Combobox.Separator />
34
- <Combobox.Group heading="Languages">
35
- <Combobox.Item value="typescript">TypeScript</Combobox.Item>
36
- <Combobox.Item value="rust">Rust</Combobox.Item>
37
- </Combobox.Group>
38
- </Combobox.List>
39
- </Combobox.Root>
24
+ import { Combobox } from '@nexub/react';
25
+
26
+ export default function Example() {
27
+ return (
28
+ <Combobox.Root className="w-[260px]">
29
+ <Combobox.Input placeholder="Search…" />
30
+ <Combobox.List>
31
+ <Combobox.Empty>No results found.</Combobox.Empty>
32
+ <Combobox.Group heading="Frameworks">
33
+ <Combobox.Item value="react">React</Combobox.Item>
34
+ <Combobox.Item value="vue">Vue</Combobox.Item>
35
+ <Combobox.Item value="angular">Angular</Combobox.Item>
36
+ <Combobox.Item value="svelte">Svelte</Combobox.Item>
37
+ </Combobox.Group>
38
+ </Combobox.List>
39
+ </Combobox.Root>
40
+ );
41
+ }
40
42
  ```
@@ -30,15 +30,27 @@ Chat layout: a scrolling message list that follows new content, with a sticky co
30
30
  Send a message: it shows Thinking, then streams a cited reply. Stop or Escape ends the reply early.
31
31
 
32
32
  ```tsx
33
- type Message = { id: number; from: 'user' | 'assistant'; text: string };
33
+ import * as React from 'react';
34
+ import { type PromptInputStatus, PromptInput, MessageBubble, ThinkingIndicator, StreamingText, Citation, type CitationSource } from '@nexub/react';
35
+ import { Conversation } from '@nexub/patterns';
34
36
 
35
- const REPLY = 'Air-source heat pumps work in most homes and run at roughly the cost of gas.';
36
- const SOURCE = { title: 'Choosing a heat pump', url: 'https://example.com/guides/heat-pumps' };
37
+ const CITATION_SOURCES: CitationSource[] = [
38
+ { title: 'Choosing a heat pump', url: 'https://example.com/guides/heat-pumps', snippet: 'Air-source pumps suit most homes with a garden or outside wall.' },
39
+ { title: 'Grants for home heating', url: 'https://example.org/grants', domain: 'example.org' },
40
+ { title: 'Running costs compared', url: 'https://example.net/costs' },
41
+ ];
37
42
 
38
- function Chat() {
39
- const [messages, setMessages] = React.useState<Message[]>([]);
40
- const [status, setStatus] = React.useState<'idle' | 'submitting' | 'streaming'>('idle');
41
- const timer = React.useRef<ReturnType<typeof setTimeout>>();
43
+ type ChatMessage = { id: number; from: 'user' | 'assistant'; text: string };
44
+
45
+ const CHAT_REPLY = 'Air-source heat pumps work in most homes and run at roughly the cost of gas.';
46
+
47
+ const CHAT_SOURCE = CITATION_SOURCES[0]!;
48
+
49
+ export default function Example() {
50
+ const [messages, setMessages] = React.useState<ChatMessage[]>([]);
51
+ const [status, setStatus] = React.useState<PromptInputStatus>('idle');
52
+ const timer = React.useRef<ReturnType<typeof setTimeout>>(undefined);
53
+ React.useEffect(() => () => clearTimeout(timer.current), []);
42
54
 
43
55
  function send(text: string) {
44
56
  const id = Date.now();
@@ -51,8 +63,8 @@ function Chat() {
51
63
  }
52
64
 
53
65
  function stream(id: number, length: number) {
54
- setMessages((m) => m.map((msg) => (msg.id === id ? { ...msg, text: REPLY.slice(0, length) } : msg)));
55
- if (length >= REPLY.length) return setStatus('idle');
66
+ setMessages((m) => m.map((msg) => (msg.id === id ? { ...msg, text: CHAT_REPLY.slice(0, length) } : msg)));
67
+ if (length >= CHAT_REPLY.length) return setStatus('idle');
56
68
  timer.current = setTimeout(() => stream(id, length + 4), 50);
57
69
  }
58
70
 
@@ -65,7 +77,7 @@ function Chat() {
65
77
 
66
78
  return (
67
79
  <Conversation
68
- style={{ height: 420 }}
80
+ className="h-[420px] w-full"
69
81
  composer={<PromptInput placeholder="Ask about heat pumps" status={status} onSubmit={send} onStop={stop} />}
70
82
  >
71
83
  {messages.map((msg) =>
@@ -78,7 +90,7 @@ function Chat() {
78
90
  ) : (
79
91
  <>
80
92
  <StreamingText as="span" text={msg.text} streaming={status === 'streaming' && msg === last} />
81
- {msg.text === REPLY && <Citation index={1} source={SOURCE} />}
93
+ {msg.text === CHAT_REPLY && <Citation index={1} source={CHAT_SOURCE} />}
82
94
  </>
83
95
  )}
84
96
  </MessageBubble>
@@ -24,47 +24,51 @@ Feature-rich data table with sorting and row selection powered by TanStack Table
24
24
  ## Example: Default
25
25
 
26
26
  ```tsx
27
- const columns = [
28
- { accessorKey: 'name', header: 'Name' },
29
- { accessorKey: 'role', header: 'Role' },
30
- { accessorKey: 'status', header: 'Status' },
31
- { accessorKey: 'joined', header: 'Joined' },
32
- ];
27
+ import { DataTable } from '@nexub/react';
33
28
 
34
- const data = [
35
- { name: 'Alice Johnson', role: 'Admin', status: 'Active', joined: '2024-01-10' },
36
- { name: 'Bob Martinez', role: 'Editor', status: 'Pending', joined: '2024-03-22' },
37
- { name: 'Carol Smith', role: 'Viewer', status: 'Inactive', joined: '2024-06-05' },
38
- { name: 'David Lee', role: 'Editor', status: 'Active', joined: '2024-09-17' },
39
- { name: 'Eva Chen', role: 'Admin', status: 'Active', joined: '2025-01-03' },
40
- ];
41
-
42
- <DataTable columns={columns} data={data} />
29
+ export default function Example() {
30
+ const data = [
31
+ { name: 'Alice Brown', email: 'alice@example.com', plan: 'Pro', status: 'Active' },
32
+ { name: 'Bob Carter', email: 'bob@example.com', plan: 'Free', status: 'Pending' },
33
+ { name: 'Carol Davis', email: 'carol@example.com', plan: 'Pro', status: 'Inactive' },
34
+ { name: 'Dave Evans', email: 'dave@example.com', plan: 'Enterprise', status: 'Active' },
35
+ ];
36
+ const columns = [
37
+ { accessorKey: 'name', header: 'Name' },
38
+ { accessorKey: 'email', header: 'Email' },
39
+ { accessorKey: 'plan', header: 'Plan' },
40
+ { accessorKey: 'status', header: 'Status' },
41
+ ];
42
+ return (
43
+ <div className="w-full max-w-[600px]">
44
+ <DataTable columns={columns} data={data} />
45
+ </div>
46
+ );
47
+ }
43
48
  ```
44
49
 
45
50
  ## Example: With sorting
46
51
 
47
52
  ```tsx
48
- const columns = [
49
- { accessorKey: 'name', header: 'Name', enableSorting: true },
50
- { accessorKey: 'role', header: 'Role', enableSorting: true },
51
- { accessorKey: 'status', header: 'Status', enableSorting: true },
52
- { accessorKey: 'joined', header: 'Joined', enableSorting: true },
53
- ];
54
-
55
- const data = [
56
- { name: 'Alice Johnson', role: 'Admin', status: 'Active', joined: '2024-01-10' },
57
- { name: 'Bob Martinez', role: 'Editor', status: 'Pending', joined: '2024-03-22' },
58
- { name: 'Carol Smith', role: 'Viewer', status: 'Inactive', joined: '2024-06-05' },
59
- { name: 'David Lee', role: 'Editor', status: 'Active', joined: '2024-09-17' },
60
- { name: 'Eva Chen', role: 'Admin', status: 'Active', joined: '2025-01-03' },
61
- ];
53
+ import { DataTable } from '@nexub/react';
62
54
 
63
- <DataTable
64
- columns={columns}
65
- data={data}
66
- enableSorting
67
- enableRowSelection
68
- pagination={{ pageSize: 5, pageIndex: 0 }}
69
- />
55
+ export default function Example() {
56
+ const data = [
57
+ { name: 'Alice Brown', email: 'alice@example.com', plan: 'Pro', status: 'Active' },
58
+ { name: 'Bob Carter', email: 'bob@example.com', plan: 'Free', status: 'Pending' },
59
+ { name: 'Carol Davis', email: 'carol@example.com', plan: 'Pro', status: 'Inactive' },
60
+ { name: 'Dave Evans', email: 'dave@example.com', plan: 'Enterprise', status: 'Active' },
61
+ ];
62
+ const columns = [
63
+ { accessorKey: 'name', header: 'Name' },
64
+ { accessorKey: 'email', header: 'Email' },
65
+ { accessorKey: 'plan', header: 'Plan' },
66
+ { accessorKey: 'status', header: 'Status' },
67
+ ];
68
+ return (
69
+ <div className="w-full max-w-[600px]">
70
+ <DataTable columns={columns} data={data} enableSorting />
71
+ </div>
72
+ );
73
+ }
70
74
  ```
@@ -25,32 +25,36 @@ Calendar date picker with text input.
25
25
  ## Example: Default
26
26
 
27
27
  ```tsx
28
- <DatePicker placeholder="Select a date…" />
28
+ import { DatePicker } from '@nexub/react';
29
+
30
+ export default function Example() {
31
+ return <DatePicker placeholder="Select a date…" />;
32
+ }
29
33
  ```
30
34
 
31
35
  ## Example: With value
32
36
 
33
37
  ```tsx
34
- function ControlledDatePicker() {
35
- const [date, setDate] = React.useState(new Date('2026-01-15'));
36
- return (
37
- <DatePicker
38
- aria-label="Appointment date"
39
- value={date}
40
- onChange={setDate}
41
- placeholder="Select a date…"
42
- />
43
- );
38
+ import { DatePicker } from '@nexub/react';
39
+
40
+ export default function Example() {
41
+ return <DatePicker value={new Date('2026-01-15')} onChange={() => {}} />;
44
42
  }
45
43
  ```
46
44
 
47
45
  ## Example: With constraints
48
46
 
49
47
  ```tsx
50
- <DatePicker
51
- aria-label="Schedule for"
52
- placeholder="Select a future date…"
53
- minDate={new Date()}
54
- maxDate={new Date(Date.now() + 90 * 24 * 60 * 60 * 1000)}
55
- />
48
+ import { DatePicker } from '@nexub/react';
49
+
50
+ export default function Example() {
51
+ return (
52
+ <DatePicker
53
+ aria-label="Schedule for"
54
+ placeholder="Select a future date…"
55
+ minDate={new Date()}
56
+ maxDate={new Date(Date.now() + 90 * 24 * 60 * 60 * 1000)}
57
+ />
58
+ );
59
+ }
56
60
  ```
@@ -25,22 +25,28 @@ Dual-calendar date range selector.
25
25
  ## Example: Default
26
26
 
27
27
  ```tsx
28
- <DateRangePicker placeholder="Select date range…" />
28
+ import { DateRangePicker } from '@nexub/react';
29
+
30
+ export default function Example() {
31
+ return <DateRangePicker placeholder="Select date range…" />;
32
+ }
29
33
  ```
30
34
 
31
35
  ## Example: Controlled
32
36
 
33
37
  ```tsx
34
- function ControlledDateRangePicker() {
35
- const [range, setRange] = React.useState({
38
+ import * as React from 'react';
39
+ import { DateRangePicker } from '@nexub/react';
40
+
41
+ export default function Example() {
42
+ const [range, setRange] = React.useState<{ from: Date | undefined; to: Date | undefined }>({
36
43
  from: new Date('2026-04-01'),
37
44
  to: new Date('2026-04-14'),
38
45
  });
39
46
  return (
40
47
  <DateRangePicker
41
- aria-label="Booking period"
42
48
  value={range}
43
- onChange={setRange}
49
+ onChange={(r) => setRange({ from: r?.from, to: r?.to })}
44
50
  placeholder="Select date range…"
45
51
  />
46
52
  );
@@ -32,26 +32,30 @@ Modal dialog built on Radix UI. Fully accessible with focus trapping and ARIA ro
32
32
  ## Example: Default
33
33
 
34
34
  ```tsx
35
- <Dialog.Root>
36
- <Dialog.Trigger asChild>
37
- <Button>Open Dialog</Button>
38
- </Dialog.Trigger>
39
- <Dialog.Portal>
40
- <Dialog.Overlay />
41
- <Dialog.Content>
42
- <Dialog.Header>
43
- <Dialog.Title>Edit profile</Dialog.Title>
44
- <Dialog.Description>
45
- Make changes to your profile here.
46
- </Dialog.Description>
47
- </Dialog.Header>
48
- <Dialog.Footer>
49
- <Dialog.Close asChild>
50
- <Button variant="outline">Cancel</Button>
51
- </Dialog.Close>
52
- <Button>Save changes</Button>
53
- </Dialog.Footer>
54
- </Dialog.Content>
55
- </Dialog.Portal>
56
- </Dialog.Root>
35
+ import * as React from 'react';
36
+ import { Button, Dialog } from '@nexub/react';
37
+
38
+ export default function Example() {
39
+ const [open, setOpen] = React.useState(false);
40
+ return (
41
+ <>
42
+ <Button variant="primary" onClick={() => setOpen(true)}>Open Dialog</Button>
43
+ <Dialog.Root open={open} onOpenChange={setOpen}>
44
+ <Dialog.Portal>
45
+ <Dialog.Overlay />
46
+ <Dialog.Content size="sm">
47
+ <Dialog.Title>Confirm action</Dialog.Title>
48
+ <Dialog.Description className="mt-2 mb-6">
49
+ Are you sure you want to continue? This action cannot be undone.
50
+ </Dialog.Description>
51
+ <div className="flex gap-2 justify-end">
52
+ <Dialog.Close asChild><Button variant="outline">Cancel</Button></Dialog.Close>
53
+ <Button variant="primary" onClick={() => setOpen(false)}>Confirm</Button>
54
+ </div>
55
+ </Dialog.Content>
56
+ </Dialog.Portal>
57
+ </Dialog.Root>
58
+ </>
59
+ );
60
+ }
57
61
  ```
@@ -27,53 +27,75 @@ Slide-in panel from any edge of the screen.
27
27
  ## Example: Default
28
28
 
29
29
  ```tsx
30
- <Drawer.Root>
31
- <Drawer.Trigger asChild>
32
- <Button variant="outline">Open drawer</Button>
33
- </Drawer.Trigger>
34
- <Drawer.Portal>
35
- <Drawer.Overlay />
36
- <Drawer.Content side="right">
37
- <Drawer.Header>
38
- <Drawer.Title>Edit profile</Drawer.Title>
39
- <Drawer.Description>Make changes to your profile settings.</Drawer.Description>
40
- </Drawer.Header>
41
- <div style={{ padding: '16px', flex: 1 }}>
42
- <Text size="body-sm" tone="secondary">Drawer body content goes here.</Text>
43
- </div>
44
- <Drawer.Footer>
45
- <Drawer.Close asChild>
46
- <Button variant="outline">Cancel</Button>
47
- </Drawer.Close>
48
- <Button variant="primary">Save changes</Button>
49
- </Drawer.Footer>
50
- </Drawer.Content>
51
- </Drawer.Portal>
52
- </Drawer.Root>
30
+ import * as React from 'react';
31
+ import { Button, Drawer, Label, Input } from '@nexub/react';
32
+
33
+ export default function Example() {
34
+ const [open, setOpen] = React.useState(false);
35
+ return (
36
+ <>
37
+ <Button variant="outline" onClick={() => setOpen(true)}>Open Drawer</Button>
38
+ <Drawer.Root open={open} onOpenChange={setOpen}>
39
+ <Drawer.Portal>
40
+ <Drawer.Overlay />
41
+ <Drawer.Content side="right">
42
+ <Drawer.Header>
43
+ <Drawer.Title>Edit profile</Drawer.Title>
44
+ <Drawer.Description>Update your profile details.</Drawer.Description>
45
+ </Drawer.Header>
46
+ <div className="p-4 flex-1 overflow-y-auto">
47
+ <div className="flex flex-col gap-3 items-start">
48
+ <div className="flex flex-col gap-1 items-start">
49
+ <Label htmlFor="d-name">Name</Label>
50
+ <Input id="d-name" placeholder="Jane Smith" />
51
+ </div>
52
+ <div className="flex flex-col gap-1 items-start">
53
+ <Label htmlFor="d-email">Email</Label>
54
+ <Input id="d-email" type="email" placeholder="jane@example.com" />
55
+ </div>
56
+ </div>
57
+ </div>
58
+ <Drawer.Footer>
59
+ <div className="flex gap-2 justify-end">
60
+ <Drawer.Close asChild><Button variant="outline">Cancel</Button></Drawer.Close>
61
+ <Button variant="primary">Save changes</Button>
62
+ </div>
63
+ </Drawer.Footer>
64
+ </Drawer.Content>
65
+ </Drawer.Portal>
66
+ </Drawer.Root>
67
+ </>
68
+ );
69
+ }
53
70
  ```
54
71
 
55
72
  ## Example: Bottom sheet
56
73
 
57
74
  ```tsx
58
- <Drawer.Root>
59
- <Drawer.Trigger asChild>
60
- <Button variant="outline">Open bottom sheet</Button>
61
- </Drawer.Trigger>
62
- <Drawer.Portal>
63
- <Drawer.Overlay />
64
- <Drawer.Content side="bottom">
65
- <Drawer.Header>
66
- <Drawer.Title>Share</Drawer.Title>
67
- </Drawer.Header>
68
- <div style={{ padding: '16px' }}>
69
- <Text size="body-sm">Choose how you would like to share this item.</Text>
70
- </div>
71
- <Drawer.Footer>
72
- <Drawer.Close asChild>
73
- <Button variant="outline" fullWidth>Cancel</Button>
74
- </Drawer.Close>
75
- </Drawer.Footer>
76
- </Drawer.Content>
77
- </Drawer.Portal>
78
- </Drawer.Root>
75
+ import * as React from 'react';
76
+ import { Button, Drawer } from '@nexub/react';
77
+
78
+ export default function Example() {
79
+ const [open, setOpen] = React.useState(false);
80
+ return (
81
+ <>
82
+ <Button variant="outline" onClick={() => setOpen(true)}>Open Bottom Sheet</Button>
83
+ <Drawer.Root open={open} onOpenChange={setOpen}>
84
+ <Drawer.Portal>
85
+ <Drawer.Overlay />
86
+ <Drawer.Content side="bottom">
87
+ <Drawer.Header>
88
+ <Drawer.Title>Share to</Drawer.Title>
89
+ </Drawer.Header>
90
+ <div className="p-4 flex gap-3 flex-wrap">
91
+ {['Twitter', 'LinkedIn', 'Slack', 'Email'].map((s) => (
92
+ <Button key={s} variant="outline" size="sm">{s}</Button>
93
+ ))}
94
+ </div>
95
+ </Drawer.Content>
96
+ </Drawer.Portal>
97
+ </Drawer.Root>
98
+ </>
99
+ );
100
+ }
79
101
  ```