@fragments-sdk/ui 0.8.0 → 0.8.2

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 (128) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +2 -0
  3. package/fragments.json +1 -1
  4. package/package.json +21 -2
  5. package/src/assets/fragments-logo.tsx +37 -0
  6. package/src/assets/fragments_logo.svg +1 -0
  7. package/src/assets/fragments_logo_text.svg +1 -0
  8. package/src/blocks/AccountSettings.block.ts +1 -1
  9. package/src/blocks/ActivityFeed.block.ts +7 -7
  10. package/src/blocks/ChatInterface.block.ts +36 -80
  11. package/src/blocks/DashboardLayout.block.ts +85 -66
  12. package/src/blocks/DashboardPage.block.ts +297 -0
  13. package/src/blocks/EmptyState.block.ts +5 -3
  14. package/src/blocks/FeatureGrid.block.ts +1 -1
  15. package/src/blocks/LoginForm.block.ts +21 -26
  16. package/src/blocks/PricingComparison.block.ts +1 -1
  17. package/src/blocks/ShoppingCart.block.ts +2 -2
  18. package/src/components/Accordion/Accordion.fragment.tsx +2 -2
  19. package/src/components/Alert/Alert.fragment.tsx +2 -2
  20. package/src/components/AppShell/AppShell.fragment.tsx +2 -2
  21. package/src/components/Avatar/Avatar.fragment.tsx +2 -2
  22. package/src/components/Badge/Badge.fragment.tsx +2 -2
  23. package/src/components/Box/Box.fragment.tsx +2 -2
  24. package/src/components/Breadcrumbs/Breadcrumbs.fragment.tsx +2 -2
  25. package/src/components/Button/Button.fragment.tsx +2 -2
  26. package/src/components/ButtonGroup/ButtonGroup.fragment.tsx +2 -2
  27. package/src/components/Card/Card.fragment.tsx +2 -2
  28. package/src/components/Chart/Chart.fragment.tsx +2 -2
  29. package/src/components/Checkbox/Checkbox.fragment.tsx +2 -2
  30. package/src/components/Chip/Chip.fragment.tsx +2 -2
  31. package/src/components/CodeBlock/CodeBlock.fragment.tsx +2 -2
  32. package/src/components/CodeBlock/CodeBlock.module.scss +10 -52
  33. package/src/components/CodeBlock/index.tsx +13 -24
  34. package/src/components/Collapsible/Collapsible.fragment.tsx +2 -2
  35. package/src/components/ColorPicker/ColorPicker.fragment.tsx +2 -2
  36. package/src/components/Combobox/Combobox.fragment.tsx +2 -2
  37. package/src/components/ConversationList/ConversationList.fragment.tsx +2 -2
  38. package/src/components/DatePicker/DatePicker.fragment.tsx +2 -2
  39. package/src/components/Dialog/Dialog.fragment.tsx +2 -2
  40. package/src/components/EmptyState/EmptyState.fragment.tsx +2 -2
  41. package/src/components/Field/Field.fragment.tsx +2 -2
  42. package/src/components/Fieldset/Fieldset.fragment.tsx +2 -2
  43. package/src/components/Form/Form.fragment.tsx +2 -2
  44. package/src/components/Grid/Grid.fragment.tsx +2 -2
  45. package/src/components/Header/Header.fragment.tsx +2 -2
  46. package/src/components/Icon/Icon.fragment.tsx +2 -2
  47. package/src/components/Image/Image.fragment.tsx +2 -2
  48. package/src/components/Input/Input.fragment.tsx +2 -2
  49. package/src/components/Input/Input.test.tsx +35 -0
  50. package/src/components/Input/index.tsx +47 -2
  51. package/src/components/Link/Link.fragment.tsx +2 -2
  52. package/src/components/List/List.fragment.tsx +2 -2
  53. package/src/components/Listbox/Listbox.fragment.tsx +2 -2
  54. package/src/components/Loading/Loading.fragment.tsx +2 -2
  55. package/src/components/Markdown/Markdown.fragment.tsx +2 -2
  56. package/src/components/Markdown/Markdown.module.scss +5 -0
  57. package/src/components/Menu/Menu.fragment.tsx +2 -2
  58. package/src/components/Menu/Menu.module.scss +2 -0
  59. package/src/components/Message/Message.fragment.tsx +2 -2
  60. package/src/components/Popover/Popover.fragment.tsx +2 -2
  61. package/src/components/Progress/Progress.fragment.tsx +2 -2
  62. package/src/components/Prompt/Prompt.fragment.tsx +2 -2
  63. package/src/components/RadioGroup/RadioGroup.fragment.tsx +2 -2
  64. package/src/components/ScrollArea/ScrollArea.fragment.tsx +2 -2
  65. package/src/components/Select/Select.fragment.tsx +2 -2
  66. package/src/components/Separator/Separator.fragment.tsx +2 -2
  67. package/src/components/Sidebar/Sidebar.fragment.tsx +2 -2
  68. package/src/components/Sidebar/Sidebar.module.scss +1 -5
  69. package/src/components/Skeleton/Skeleton.fragment.tsx +2 -2
  70. package/src/components/Slider/Slider.fragment.tsx +2 -2
  71. package/src/components/Stack/Stack.fragment.tsx +2 -2
  72. package/src/components/Table/Table.fragment.tsx +3 -3
  73. package/src/components/Table/index.tsx +43 -5
  74. package/src/components/TableOfContents/TableOfContents.fragment.tsx +2 -2
  75. package/src/components/TableOfContents/TableOfContents.module.scss +0 -5
  76. package/src/components/TableOfContents/index.tsx +6 -1
  77. package/src/components/Tabs/Tabs.fragment.tsx +2 -2
  78. package/src/components/Text/Text.fragment.tsx +2 -2
  79. package/src/components/Text/Text.module.scss +6 -0
  80. package/src/components/Text/Text.test.tsx +5 -0
  81. package/src/components/Text/index.tsx +3 -0
  82. package/src/components/Textarea/Textarea.fragment.tsx +2 -2
  83. package/src/components/Theme/Theme.fragment.tsx +2 -2
  84. package/src/components/Theme/ThemeToggle.module.scss +1 -1
  85. package/src/components/Theme/index.tsx +1 -1
  86. package/src/components/ThinkingIndicator/ThinkingIndicator.fragment.tsx +2 -2
  87. package/src/components/Toast/Toast.fragment.tsx +2 -2
  88. package/src/components/Toggle/Toggle.fragment.tsx +2 -2
  89. package/src/components/ToggleGroup/ToggleGroup.fragment.tsx +37 -5
  90. package/src/components/Tooltip/Tooltip.fragment.tsx +2 -2
  91. package/src/components/VisuallyHidden/VisuallyHidden.fragment.tsx +2 -2
  92. package/src/index.ts +3 -0
  93. package/src/tokens/_derive.scss +32 -8
  94. package/src/tokens/_mixins.scss +9 -0
  95. package/src/tokens/_variables.scss +4 -4
  96. package/src/blocks/AIChat.block.ts +0 -266
  97. package/src/blocks/AppShell.block.ts +0 -175
  98. package/src/blocks/CTABanner.block.ts +0 -24
  99. package/src/blocks/CardGrid.block.ts +0 -22
  100. package/src/blocks/CodeExamples.block.ts +0 -66
  101. package/src/blocks/ConfirmDialog.block.ts +0 -19
  102. package/src/blocks/ConversationWithHistory.block.ts +0 -45
  103. package/src/blocks/DashboardNav.block.ts +0 -183
  104. package/src/blocks/ForgotPassword.block.ts +0 -26
  105. package/src/blocks/FormLayout.block.ts +0 -31
  106. package/src/blocks/InsetDashboardLayout.block.ts +0 -79
  107. package/src/blocks/MetricDashboard.block.ts +0 -38
  108. package/src/blocks/NewsletterSignup.block.ts +0 -26
  109. package/src/blocks/NotificationList.block.ts +0 -39
  110. package/src/blocks/NotificationPreferences.block.ts +0 -40
  111. package/src/blocks/OrderSummary.block.ts +0 -52
  112. package/src/blocks/ProfileEditForm.block.ts +0 -51
  113. package/src/blocks/SearchResults.block.ts +0 -39
  114. package/src/blocks/SettingsPage.block.ts +0 -58
  115. package/src/blocks/StreamingMessage.block.ts +0 -24
  116. package/src/blocks/TestimonialCard.block.ts +0 -27
  117. package/src/blocks/UserProfileCard.block.ts +0 -29
  118. package/src/recipes/AIChat.recipe.ts +0 -266
  119. package/src/recipes/AppShell.recipe.ts +0 -175
  120. package/src/recipes/CardGrid.recipe.ts +0 -22
  121. package/src/recipes/ChatInterface.recipe.ts +0 -87
  122. package/src/recipes/CodeExamples.recipe.ts +0 -66
  123. package/src/recipes/ConfirmDialog.recipe.ts +0 -19
  124. package/src/recipes/DashboardLayout.recipe.ts +0 -73
  125. package/src/recipes/DashboardNav.recipe.ts +0 -183
  126. package/src/recipes/FormLayout.recipe.ts +0 -31
  127. package/src/recipes/LoginForm.recipe.ts +0 -33
  128. package/src/recipes/SettingsPage.recipe.ts +0 -58
@@ -2,72 +2,91 @@ import { defineBlock } from '@fragments/core';
2
2
 
3
3
  export default defineBlock({
4
4
  name: 'Dashboard Layout',
5
- description: 'Dashboard grid with a featured full-width card and smaller metric cards below',
6
- category: 'layout',
7
- components: ['Grid', 'Card', 'Badge', 'Separator'],
8
- tags: ['dashboard', 'layout', 'metrics', 'widgets', 'overview'],
5
+ description:
6
+ 'Full application shell with sidebar navigation, header, and metrics grid',
7
+ category: 'dashboard',
8
+ components: [
9
+ 'AppShell',
10
+ 'Header',
11
+ 'Sidebar',
12
+ 'Stack',
13
+ 'Grid',
14
+ 'Card',
15
+ 'Text',
16
+ 'Badge',
17
+ 'Input',
18
+ 'ThemeToggle',
19
+ 'Avatar',
20
+ ],
21
+ tags: ['dashboard', 'layout', 'sidebar', 'app-shell', 'navigation'],
9
22
  code: `
10
- <Grid columns={4} gap="lg">
11
- <Grid.Item colSpan="full">
12
- <Card>
13
- <Card.Header>
14
- <Card.Title>Overview</Card.Title>
15
- <Card.Description>Key metrics for this period</Card.Description>
16
- </Card.Header>
17
- <Card.Body>{summaryContent}</Card.Body>
18
- </Card>
19
- </Grid.Item>
20
- <Card variant="outlined">
21
- <Card.Header>
22
- <Card.Title>Users</Card.Title>
23
- </Card.Header>
24
- <Card.Body>
25
- <Badge variant="success">{stats.users}</Badge>
26
- </Card.Body>
27
- </Card>
28
- <Card variant="outlined">
29
- <Card.Header>
30
- <Card.Title>Revenue</Card.Title>
31
- </Card.Header>
32
- <Card.Body>
33
- <Badge variant="info">{stats.revenue}</Badge>
34
- </Card.Body>
35
- </Card>
36
- <Card variant="outlined">
37
- <Card.Header>
38
- <Card.Title>Orders</Card.Title>
39
- </Card.Header>
40
- <Card.Body>
41
- <Badge variant="warning">{stats.orders}</Badge>
42
- </Card.Body>
43
- </Card>
44
- <Card variant="outlined">
45
- <Card.Header>
46
- <Card.Title>Errors</Card.Title>
47
- </Card.Header>
48
- <Card.Body>
49
- <Badge variant="danger">{stats.errors}</Badge>
50
- </Card.Body>
51
- </Card>
52
- <Grid.Item colSpan="full">
53
- <Separator spacing="md" />
54
- </Grid.Item>
55
- <Grid.Item colSpan={2}>
56
- <Card>
57
- <Card.Header>
58
- <Card.Title>Recent Activity</Card.Title>
59
- </Card.Header>
60
- <Card.Body>{activityList}</Card.Body>
61
- </Card>
62
- </Grid.Item>
63
- <Grid.Item colSpan={2}>
64
- <Card>
65
- <Card.Header>
66
- <Card.Title>Notifications</Card.Title>
67
- </Card.Header>
68
- <Card.Body>{notificationList}</Card.Body>
69
- </Card>
70
- </Grid.Item>
71
- </Grid>
23
+ const navItems = [
24
+ { label: 'Dashboard', active: true },
25
+ { label: 'Analytics', active: false },
26
+ { label: 'Projects', active: false },
27
+ { label: 'Settings', active: false },
28
+ ];
29
+
30
+ const metrics = [
31
+ { label: 'Total Users', value: '12,847', change: '+12%' },
32
+ { label: 'Revenue', value: '$48,352', change: '+8%' },
33
+ { label: 'Active Projects', value: '23', change: '+3' },
34
+ ];
35
+
36
+ <AppShell layout="inset">
37
+ <AppShell.Header>
38
+ <Header>
39
+ <Header.Trigger />
40
+ <Header.Search>
41
+ <Input placeholder="Search..." style={{ width: '240px' }} />
42
+ </Header.Search>
43
+ <Header.Spacer />
44
+ <Header.Actions>
45
+ <ThemeToggle size="sm" />
46
+ <Avatar size="sm" initials="JD" />
47
+ </Header.Actions>
48
+ </Header>
49
+ </AppShell.Header>
50
+ <AppShell.Sidebar width="220px" collapsible="offcanvas">
51
+ <Sidebar.Header>
52
+ <Text weight="semibold" size="lg">Acme Inc</Text>
53
+ </Sidebar.Header>
54
+ <Sidebar.Nav>
55
+ <Sidebar.Section label="Main">
56
+ {navItems.map((item) => (
57
+ <Sidebar.Item key={item.label} active={item.active}>
58
+ {item.label}
59
+ </Sidebar.Item>
60
+ ))}
61
+ </Sidebar.Section>
62
+ </Sidebar.Nav>
63
+ <Sidebar.Footer>
64
+ <Text size="sm" color="tertiary">v2.0.0</Text>
65
+ </Sidebar.Footer>
66
+ </AppShell.Sidebar>
67
+ <AppShell.Main padding="lg">
68
+ <Stack gap="lg">
69
+ <Stack gap="xs">
70
+ <Text size="xl" weight="semibold">Dashboard</Text>
71
+ <Text color="tertiary">Welcome back! Here's an overview of your metrics.</Text>
72
+ </Stack>
73
+ <Grid columns={{ base: 1, md: 3 }} gap="md">
74
+ {metrics.map((metric) => (
75
+ <Card key={metric.label}>
76
+ <Card.Body>
77
+ <Stack gap="sm">
78
+ <Text size="sm" color="tertiary">{metric.label}</Text>
79
+ <Stack direction="row" justify="between" align="baseline">
80
+ <Text size="2xl" weight="semibold">{metric.value}</Text>
81
+ <Badge variant="success">{metric.change}</Badge>
82
+ </Stack>
83
+ </Stack>
84
+ </Card.Body>
85
+ </Card>
86
+ ))}
87
+ </Grid>
88
+ </Stack>
89
+ </AppShell.Main>
90
+ </AppShell>
72
91
  `.trim(),
73
92
  });
@@ -0,0 +1,297 @@
1
+ import { defineBlock } from '@fragments/core';
2
+
3
+ export default defineBlock({
4
+ name: 'Dashboard Page',
5
+ description:
6
+ 'Full dashboard page with sidebar navigation, stats cards, revenue chart, transactions table, and activity feed',
7
+ category: 'kitchen-sink',
8
+ components: [
9
+ 'AppShell',
10
+ 'Header',
11
+ 'Sidebar',
12
+ 'Grid',
13
+ 'Card',
14
+ 'Stack',
15
+ 'Text',
16
+ 'Badge',
17
+ 'Icon',
18
+ 'Avatar',
19
+ 'Input',
20
+ 'Button',
21
+ 'Separator',
22
+ 'Table',
23
+ 'ChartContainer',
24
+ 'ChartTooltip',
25
+ 'Breadcrumbs',
26
+ 'ThemeToggle',
27
+ 'Progress',
28
+ 'Tabs',
29
+ ],
30
+ tags: [
31
+ 'dashboard',
32
+ 'full-page',
33
+ 'kitchen-sink',
34
+ 'chart',
35
+ 'table',
36
+ 'sidebar',
37
+ 'stats',
38
+ 'metrics',
39
+ 'analytics',
40
+ ],
41
+ code: `
42
+ import { AreaChart, Area, XAxis } from 'recharts';
43
+ import {
44
+ TrendUp, TrendDown, Bell, SquaresFour, ChartBar,
45
+ FileText, GearSix, Users, UserCircle, CreditCard,
46
+ Bank, Lightning, Wallet, CheckCircle, Clock, XCircle,
47
+ ArrowClockwise, DownloadSimple,
48
+ } from '@phosphor-icons/react';
49
+
50
+ // ── Stats data ──────────────────────────────────────────────
51
+ const stats = [
52
+ { label: 'Total Revenue', value: '$45,231', change: '+20.1%', up: true },
53
+ { label: 'Active Users', value: '2,350', change: '+12.5%', up: true },
54
+ { label: 'Sessions', value: '12,543', change: '-3.2%', up: false },
55
+ { label: 'Growth Rate', value: '4.5%', change: '+0.8%', up: true },
56
+ ];
57
+
58
+ // ── Chart data ──────────────────────────────────────────────
59
+ const revenueData = [
60
+ { month: 'Sep', revenue: 3200 },
61
+ { month: 'Oct', revenue: 4100 },
62
+ { month: 'Nov', revenue: 3800 },
63
+ { month: 'Dec', revenue: 5200 },
64
+ { month: 'Jan', revenue: 4800 },
65
+ { month: 'Feb', revenue: 6100 },
66
+ ];
67
+
68
+ const chartConfig = {
69
+ revenue: { label: 'Revenue', color: 'var(--fui-color-accent)' },
70
+ };
71
+
72
+ // ── Table data ──────────────────────────────────────────────
73
+ const methodIcons = { card: CreditCard, bank: Bank, crypto: Lightning, wallet: Wallet };
74
+ const methodLabels = { card: 'Card', bank: 'Bank', crypto: 'Crypto', wallet: 'Wallet' };
75
+ const statusConfig = {
76
+ completed: { variant: 'success', icon: CheckCircle, label: 'Completed' },
77
+ pending: { variant: 'warning', icon: Clock, label: 'Pending' },
78
+ failed: { variant: 'error', icon: XCircle, label: 'Failed' },
79
+ refunded: { variant: 'info', icon: ArrowClockwise, label: 'Refunded' },
80
+ };
81
+
82
+ const transactions = [
83
+ { id: '1', customer: 'Alice Chen', method: 'card', amount: '$1,250.00', status: 'completed', date: 'Feb 3' },
84
+ { id: '2', customer: 'Bob Park', method: 'bank', amount: '$890.00', status: 'pending', date: 'Feb 2' },
85
+ { id: '3', customer: 'Clara Liu', method: 'crypto', amount: '$2,100.00', status: 'completed', date: 'Feb 1' },
86
+ { id: '4', customer: 'David Kim', method: 'wallet', amount: '$450.00', status: 'failed', date: 'Jan 31' },
87
+ { id: '5', customer: 'Eva Santos', method: 'card', amount: '$3,200.00', status: 'completed', date: 'Jan 30' },
88
+ ];
89
+
90
+ const columns = createColumns([
91
+ {
92
+ key: 'customer',
93
+ header: 'Customer',
94
+ cell: (row) => (
95
+ <Stack direction="row" gap="sm" align="center">
96
+ <Icon icon={UserCircle} size="sm" />
97
+ <Text size="sm" weight="medium">{row.customer}</Text>
98
+ </Stack>
99
+ ),
100
+ },
101
+ {
102
+ key: 'method',
103
+ header: 'Method',
104
+ cell: (row) => (
105
+ <Stack direction="row" gap="xs" align="center">
106
+ <Icon icon={methodIcons[row.method]} size="xs" />
107
+ <Text size="sm" color="secondary">{methodLabels[row.method]}</Text>
108
+ </Stack>
109
+ ),
110
+ },
111
+ {
112
+ key: 'amount',
113
+ header: 'Amount',
114
+ cell: (row) => <Text size="sm" weight="medium" font="mono">{row.amount}</Text>,
115
+ },
116
+ {
117
+ key: 'status',
118
+ header: 'Status',
119
+ cell: (row) => {
120
+ const cfg = statusConfig[row.status];
121
+ return (
122
+ <Badge variant={cfg.variant} size="sm" icon={<Icon icon={cfg.icon} size="xs" />}>
123
+ {cfg.label}
124
+ </Badge>
125
+ );
126
+ },
127
+ },
128
+ { key: 'date', header: 'Date' },
129
+ ]);
130
+
131
+ // ── Activity data ───────────────────────────────────────────
132
+ const activities = [
133
+ { id: 1, user: 'Alice Chen', action: 'completed a purchase', time: '2 min ago', initials: 'AC' },
134
+ { id: 2, user: 'Bob Park', action: 'submitted a support ticket', time: '15 min ago', initials: 'BP' },
135
+ { id: 3, user: 'Clara Liu', action: 'upgraded to Pro plan', time: '1 hour ago', initials: 'CL' },
136
+ { id: 4, user: 'David Kim', action: 'left a review', time: '3 hours ago', initials: 'DK' },
137
+ ];
138
+
139
+ // ── Layout ──────────────────────────────────────────────────
140
+
141
+ <AppShell layout="sidebar-inset">
142
+ <AppShell.Header>
143
+ <Header>
144
+ <Header.Trigger />
145
+ <Header.Nav>
146
+ <Breadcrumbs>
147
+ <Breadcrumbs.Item>Dashboard</Breadcrumbs.Item>
148
+ <Breadcrumbs.Item>Overview</Breadcrumbs.Item>
149
+ </Breadcrumbs>
150
+ </Header.Nav>
151
+ <Header.Spacer />
152
+ <Header.Search>
153
+ <Input placeholder="Search..." size="sm" style={{ width: 200 }} />
154
+ </Header.Search>
155
+ <Header.Actions>
156
+ <Button variant="ghost" size="sm" icon aria-label="Notifications">
157
+ <Icon icon={Bell} />
158
+ </Button>
159
+ <ThemeToggle size="sm" />
160
+ <Avatar size="sm" initials="JD" />
161
+ </Header.Actions>
162
+ </Header>
163
+ </AppShell.Header>
164
+
165
+ <AppShell.Sidebar width="220px" collapsible="icon">
166
+ <Sidebar.Header>
167
+ <Text weight="semibold" size="lg">Acme Inc</Text>
168
+ </Sidebar.Header>
169
+ <Sidebar.Nav>
170
+ <Sidebar.Section label="Main">
171
+ <Sidebar.Item icon={<Icon icon={SquaresFour} />} active>Dashboard</Sidebar.Item>
172
+ <Sidebar.Item icon={<Icon icon={ChartBar} />}>Analytics</Sidebar.Item>
173
+ <Sidebar.Item icon={<Icon icon={Users} />}>Customers</Sidebar.Item>
174
+ <Sidebar.Item icon={<Icon icon={FileText} />}>Reports</Sidebar.Item>
175
+ </Sidebar.Section>
176
+ <Sidebar.Section label="System">
177
+ <Sidebar.Item icon={<Icon icon={GearSix} />}>Settings</Sidebar.Item>
178
+ </Sidebar.Section>
179
+ </Sidebar.Nav>
180
+ <Sidebar.Footer>
181
+ <Sidebar.CollapseToggle />
182
+ </Sidebar.Footer>
183
+ </AppShell.Sidebar>
184
+
185
+ <AppShell.Main padding="lg">
186
+ <Stack gap="lg">
187
+ {/* Page header */}
188
+ <Stack direction="row" justify="between" align="end">
189
+ <Stack gap="xs">
190
+ <Text size="xl" weight="semibold">Dashboard</Text>
191
+ <Text color="secondary">Welcome back! Here's an overview of your metrics.</Text>
192
+ </Stack>
193
+ <Button variant="primary" size="sm">
194
+ <Icon icon={DownloadSimple} size="sm" /> Export
195
+ </Button>
196
+ </Stack>
197
+
198
+ {/* Stats cards */}
199
+ <Grid columns={{ base: 1, sm: 2, lg: 4 }} gap="md">
200
+ {stats.map((stat) => (
201
+ <Card key={stat.label}>
202
+ <Card.Body>
203
+ <Stack gap="xs">
204
+ <Text size="sm" color="secondary">{stat.label}</Text>
205
+ <Text size="2xl" weight="semibold">{stat.value}</Text>
206
+ <Badge
207
+ variant={stat.up ? 'success' : 'warning'}
208
+ size="sm"
209
+ icon={<Icon icon={stat.up ? TrendUp : TrendDown} size="xs" />}
210
+ >
211
+ {stat.change}
212
+ </Badge>
213
+ </Stack>
214
+ </Card.Body>
215
+ </Card>
216
+ ))}
217
+ </Grid>
218
+
219
+ {/* Chart + Activity feed row */}
220
+ <Grid columns={{ base: 1, lg: 3 }} gap="md">
221
+ <Grid.Item colSpan={2}>
222
+ <Card style={{ height: '100%' }}>
223
+ <Card.Header>
224
+ <Stack direction="row" justify="between" align="center">
225
+ <Card.Title>Revenue</Card.Title>
226
+ <Text size="sm" color="secondary">Last 6 months</Text>
227
+ </Stack>
228
+ </Card.Header>
229
+ <Card.Body>
230
+ <div style={{ height: 220 }}>
231
+ <ChartContainer config={chartConfig}>
232
+ <AreaChart data={revenueData} margin={{ top: 5, right: 5, bottom: 0, left: -20 }}>
233
+ <XAxis dataKey="month" tickLine={false} axisLine={false} />
234
+ <Area
235
+ type="monotone"
236
+ dataKey="revenue"
237
+ stroke="var(--fui-color-accent)"
238
+ fill="var(--fui-color-accent)"
239
+ fillOpacity={0.15}
240
+ strokeWidth={2}
241
+ />
242
+ <ChartTooltip />
243
+ </AreaChart>
244
+ </ChartContainer>
245
+ </div>
246
+ </Card.Body>
247
+ </Card>
248
+ </Grid.Item>
249
+
250
+ <Card>
251
+ <Card.Header>
252
+ <Card.Title>Recent Activity</Card.Title>
253
+ </Card.Header>
254
+ <Card.Body>
255
+ <Stack gap="md">
256
+ {activities.map((a) => (
257
+ <Stack key={a.id} direction="row" gap="sm" align="center">
258
+ <Avatar size="sm" initials={a.initials} />
259
+ <Stack gap="xs" style={{ flex: 1 }}>
260
+ <Text size="sm">
261
+ <Text size="sm" weight="semibold">{a.user}</Text> {a.action}
262
+ </Text>
263
+ <Text size="xs" color="tertiary">{a.time}</Text>
264
+ </Stack>
265
+ </Stack>
266
+ ))}
267
+ </Stack>
268
+ </Card.Body>
269
+ </Card>
270
+ </Grid>
271
+
272
+ {/* Transactions table */}
273
+ <Card>
274
+ <Card.Header>
275
+ <Stack direction="row" justify="between" align="center">
276
+ <Stack direction="row" gap="sm" align="center">
277
+ <Card.Title>Recent Transactions</Card.Title>
278
+ <Badge variant="outline" size="sm">5 total</Badge>
279
+ </Stack>
280
+ <Button variant="ghost" size="sm" icon aria-label="Download">
281
+ <Icon icon={DownloadSimple} size="sm" />
282
+ </Button>
283
+ </Stack>
284
+ </Card.Header>
285
+ <Table
286
+ columns={columns}
287
+ data={transactions}
288
+ size="sm"
289
+ caption="Recent transactions"
290
+ captionHidden
291
+ />
292
+ </Card>
293
+ </Stack>
294
+ </AppShell.Main>
295
+ </AppShell>
296
+ `.trim(),
297
+ });
@@ -2,14 +2,16 @@ import { defineBlock } from '@fragments/core';
2
2
 
3
3
  export default defineBlock({
4
4
  name: 'Empty State',
5
- description: 'Placeholder when no content or data exists',
5
+ description: 'Placeholder with icon, message, and action when no content exists',
6
6
  category: 'dashboard',
7
7
  components: ['EmptyState', 'Button'],
8
- tags: ['empty', 'placeholder', 'zero-state', 'dashboard'],
8
+ tags: ['empty', 'placeholder', 'zero-state', 'no-data'],
9
9
  code: `
10
10
  <EmptyState>
11
11
  <EmptyState.Icon>
12
- <InboxIcon />
12
+ <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
13
+ <path d="M21 8v13H3V8M1 3h22v5H1zM10 12h4" />
14
+ </svg>
13
15
  </EmptyState.Icon>
14
16
  <EmptyState.Title>No items yet</EmptyState.Title>
15
17
  <EmptyState.Description>Get started by creating your first item.</EmptyState.Description>
@@ -19,7 +19,7 @@ const features = [
19
19
  <Card key={feature.title}>
20
20
  <Card.Body>
21
21
  <Stack gap="md">
22
- <Icon icon={feature.icon} size="lg" color="accent" />
22
+ <Icon icon={feature.icon} size="lg" variant="accent" />
23
23
  <Stack gap="xs">
24
24
  <Text weight="semibold">{feature.title}</Text>
25
25
  <Text size="sm" color="tertiary">{feature.description}</Text>
@@ -2,32 +2,27 @@ import { defineBlock } from '@fragments/core';
2
2
 
3
3
  export default defineBlock({
4
4
  name: 'Login Form',
5
- description: 'Email/password authentication form with validation states',
6
- category: 'forms',
7
- components: ['Input', 'Button', 'Alert'],
8
- tags: ['auth', 'login', 'form'],
5
+ description: 'Email/password authentication form with card layout and footer links',
6
+ category: 'authentication',
7
+ components: ['Card', 'Stack', 'Input', 'Button', 'Text', 'Link'],
8
+ tags: ['auth', 'login', 'signin', 'form'],
9
9
  code: `
10
- <Input
11
- label="Email"
12
- type="email"
13
- placeholder="you@example.com"
14
- error={Boolean(errors.email)}
15
- helperText={errors.email}
16
- />
17
- <Input
18
- label="Password"
19
- type="password"
20
- error={Boolean(errors.password)}
21
- helperText={errors.password}
22
- />
23
- <Button type="submit" variant="primary">Sign in</Button>
24
- {error && (
25
- <Alert severity="error">
26
- <Alert.Icon />
27
- <Alert.Body>
28
- <Alert.Content>{error}</Alert.Content>
29
- </Alert.Body>
30
- </Alert>
31
- )}
10
+ <Card variant="elevated">
11
+ <Card.Header>
12
+ <Card.Title>Sign In</Card.Title>
13
+ <Card.Description>Welcome back! Please enter your details.</Card.Description>
14
+ </Card.Header>
15
+ <Card.Body>
16
+ <Stack gap="md">
17
+ <Input label="Email" type="email" placeholder="Enter your email" />
18
+ <Input label="Password" type="password" placeholder="Enter your password" />
19
+ <Link href="#" variant="subtle"><Text size="sm">Forgot password?</Text></Link>
20
+ <Button variant="primary" fullWidth>Sign In</Button>
21
+ </Stack>
22
+ </Card.Body>
23
+ <Card.Footer>
24
+ <Text size="sm" color="tertiary">Don't have an account? <Link href="#">Sign up</Link></Text>
25
+ </Card.Footer>
26
+ </Card>
32
27
  `.trim(),
33
28
  });
@@ -13,7 +13,7 @@ const tiers = [
13
13
  { name: 'Enterprise', price: '$99', period: '/month', description: 'For large organizations', features: ['Everything in Pro', 'Custom integrations', 'Dedicated support', 'SLA guarantee'], ctaText: 'Contact Sales' },
14
14
  ];
15
15
 
16
- <Grid columns={3} gap="lg">
16
+ <Grid columns={{ base: 1, lg: 3 }} gap="lg">
17
17
  {tiers.map((tier) => (
18
18
  <Card key={tier.name}>
19
19
  <Card.Header>
@@ -21,8 +21,8 @@ const items = [
21
21
  </Card.Header>
22
22
  <Card.Body>
23
23
  <Stack gap="md">
24
- {items.map((item, index) => (
25
- <Stack key={index} direction="row" gap="md" align="center">
24
+ {items.map((item) => (
25
+ <Stack key={item.name} direction="row" gap="md" align="center">
26
26
  <Image src={item.image} alt={item.name} width={64} height={64} rounded="md" />
27
27
  <Stack gap="xs" style={{ flex: 1 }}>
28
28
  <Text weight="semibold">{item.name}</Text>
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import { defineSegment } from '@fragments/core';
2
+ import { defineFragment } from '@fragments/core';
3
3
  import { Accordion } from '.';
4
4
 
5
- export default defineSegment({
5
+ export default defineFragment({
6
6
  component: Accordion,
7
7
 
8
8
  meta: {
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import { defineSegment } from '@fragments/core';
2
+ import { defineFragment } from '@fragments/core';
3
3
  import { Alert } from '.';
4
4
 
5
- export default defineSegment({
5
+ export default defineFragment({
6
6
  component: Alert,
7
7
 
8
8
  meta: {
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { defineSegment } from '@fragments/core';
2
+ import { defineFragment } from '@fragments/core';
3
3
  import { AppShell } from '.';
4
4
  import { Header } from '../Header';
5
5
  import { Sidebar } from '../Sidebar';
@@ -38,7 +38,7 @@ function SearchIcon() {
38
38
  );
39
39
  }
40
40
 
41
- export default defineSegment({
41
+ export default defineFragment({
42
42
  component: AppShell,
43
43
 
44
44
  meta: {
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import { defineSegment } from '@fragments/core';
2
+ import { defineFragment } from '@fragments/core';
3
3
  import { Avatar } from '.';
4
4
 
5
- export default defineSegment({
5
+ export default defineFragment({
6
6
  component: Avatar,
7
7
 
8
8
  meta: {
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import { defineSegment } from '@fragments/core';
2
+ import { defineFragment } from '@fragments/core';
3
3
  import { Badge } from '.';
4
4
 
5
- export default defineSegment({
5
+ export default defineFragment({
6
6
  component: Badge,
7
7
 
8
8
  meta: {
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import { defineSegment } from '@fragments/core';
2
+ import { defineFragment } from '@fragments/core';
3
3
  import { Box } from '.';
4
4
 
5
- export default defineSegment({
5
+ export default defineFragment({
6
6
  component: Box,
7
7
 
8
8
  meta: {
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import { defineSegment } from '@fragments/core';
2
+ import { defineFragment } from '@fragments/core';
3
3
  import { Breadcrumbs } from '.';
4
4
 
5
- export default defineSegment({
5
+ export default defineFragment({
6
6
  component: Breadcrumbs,
7
7
 
8
8
  meta: {