@fragments-sdk/ui 0.8.5 → 0.8.7
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/fragments.json +1 -1
- package/package.json +2 -2
- package/src/blocks/AccountSettings.block.ts +1 -1
- package/src/blocks/ActivityFeed.block.ts +1 -1
- package/src/blocks/ChatInterface.block.ts +1 -1
- package/src/blocks/ChatMessages.block.ts +1 -1
- package/src/blocks/CheckoutForm.block.ts +1 -1
- package/src/blocks/ContactForm.block.ts +1 -1
- package/src/blocks/DashboardLayout.block.ts +1 -1
- package/src/blocks/DashboardPage.block.ts +1 -1
- package/src/blocks/DataTable.block.ts +1 -1
- package/src/blocks/EmptyState.block.ts +1 -1
- package/src/blocks/FAQSection.block.ts +1 -1
- package/src/blocks/FeatureGrid.block.ts +1 -1
- package/src/blocks/HeroSection.block.ts +1 -1
- package/src/blocks/LoginForm.block.ts +1 -1
- package/src/blocks/NavigationHeader.block.ts +1 -1
- package/src/blocks/PricingComparison.block.ts +1 -1
- package/src/blocks/ProductCard.block.ts +1 -1
- package/src/blocks/RegistrationForm.block.ts +1 -1
- package/src/blocks/SettingsPanel.block.ts +1 -1
- package/src/blocks/ShoppingCart.block.ts +1 -1
- package/src/blocks/StatsCard.block.ts +1 -1
- package/src/blocks/ThinkingStates.block.ts +1 -1
- package/src/components/Accordion/Accordion.fragment.tsx +1 -1
- package/src/components/Alert/Alert.fragment.tsx +1 -1
- package/src/components/AppShell/AppShell.fragment.tsx +11 -11
- package/src/components/Avatar/Avatar.fragment.tsx +1 -1
- package/src/components/Avatar/index.tsx +9 -1
- package/src/components/Badge/Badge.fragment.tsx +1 -1
- package/src/components/Box/Box.fragment.tsx +1 -1
- package/src/components/Breadcrumbs/Breadcrumbs.fragment.tsx +1 -1
- package/src/components/Button/Button.fragment.tsx +1 -1
- package/src/components/ButtonGroup/ButtonGroup.fragment.tsx +1 -1
- package/src/components/Card/Card.fragment.tsx +1 -1
- package/src/components/Chart/Chart.fragment.tsx +1 -1
- package/src/components/Checkbox/Checkbox.fragment.tsx +1 -1
- package/src/components/Chip/Chip.fragment.tsx +1 -1
- package/src/components/Chip/index.tsx +2 -0
- package/src/components/CodeBlock/CodeBlock.fragment.tsx +1 -1
- package/src/components/Collapsible/Collapsible.fragment.tsx +1 -1
- package/src/components/ColorPicker/ColorPicker.fragment.tsx +1 -1
- package/src/components/ColorPicker/index.tsx +2 -0
- package/src/components/Combobox/Combobox.fragment.tsx +1 -1
- package/src/components/Combobox/index.tsx +2 -0
- package/src/components/ConversationList/ConversationList.fragment.tsx +1 -1
- package/src/components/DatePicker/DatePicker.fragment.tsx +10 -9
- package/src/components/DatePicker/index.tsx +2 -0
- package/src/components/Dialog/Dialog.fragment.tsx +1 -1
- package/src/components/EmptyState/EmptyState.fragment.tsx +1 -1
- package/src/components/Field/Field.fragment.tsx +1 -1
- package/src/components/Fieldset/Fieldset.fragment.tsx +1 -1
- package/src/components/Form/Form.fragment.tsx +1 -1
- package/src/components/Grid/Grid.fragment.tsx +1 -1
- package/src/components/Header/Header.fragment.tsx +1 -1
- package/src/components/Icon/Icon.fragment.tsx +1 -1
- package/src/components/Image/Image.fragment.tsx +1 -1
- package/src/components/Image/index.tsx +10 -0
- package/src/components/Input/Input.fragment.tsx +1 -1
- package/src/components/Input/index.tsx +2 -0
- package/src/components/Link/Link.fragment.tsx +1 -1
- package/src/components/List/List.fragment.tsx +1 -1
- package/src/components/Listbox/Listbox.fragment.tsx +1 -1
- package/src/components/Listbox/index.tsx +6 -1
- package/src/components/Loading/Loading.fragment.tsx +1 -1
- package/src/components/Markdown/Markdown.fragment.tsx +1 -1
- package/src/components/Menu/Menu.fragment.tsx +55 -5
- package/src/components/Menu/Menu.module.scss +21 -10
- package/src/components/Menu/Menu.test.tsx +126 -3
- package/src/components/Menu/index.tsx +85 -11
- package/src/components/Message/Message.fragment.tsx +1 -1
- package/src/components/Message/Message.module.scss +2 -1
- package/src/components/NavigationMenu/NavigationMenu.fragment.tsx +1 -1
- package/src/components/NavigationMenu/index.tsx +1 -0
- package/src/components/Popover/Popover.fragment.tsx +1 -1
- package/src/components/Progress/Progress.fragment.tsx +1 -1
- package/src/components/Prompt/Prompt.fragment.tsx +1 -1
- package/src/components/RadioGroup/RadioGroup.fragment.tsx +1 -1
- package/src/components/ScrollArea/ScrollArea.fragment.tsx +1 -1
- package/src/components/ScrollArea/index.tsx +2 -0
- package/src/components/Select/Select.fragment.tsx +1 -1
- package/src/components/Select/index.tsx +2 -0
- package/src/components/Separator/Separator.fragment.tsx +1 -1
- package/src/components/Sidebar/Sidebar.fragment.tsx +2 -2
- package/src/components/Sidebar/index.tsx +2 -0
- package/src/components/Skeleton/Skeleton.fragment.tsx +1 -1
- package/src/components/Slider/Slider.fragment.tsx +1 -1
- package/src/components/Slider/index.tsx +2 -0
- package/src/components/Stack/Stack.fragment.tsx +1 -1
- package/src/components/Table/Table.fragment.tsx +1 -1
- package/src/components/Table/index.tsx +2 -0
- package/src/components/TableOfContents/TableOfContents.fragment.tsx +1 -1
- package/src/components/Tabs/Tabs.fragment.tsx +1 -1
- package/src/components/Text/Text.fragment.tsx +1 -1
- package/src/components/Textarea/Textarea.fragment.tsx +1 -1
- package/src/components/Theme/Theme.fragment.tsx +1 -1
- package/src/components/ThinkingIndicator/ThinkingIndicator.fragment.tsx +1 -1
- package/src/components/Toast/Toast.fragment.tsx +1 -1
- package/src/components/Toast/index.tsx +2 -0
- package/src/components/Toggle/Toggle.fragment.tsx +1 -1
- package/src/components/ToggleGroup/ToggleGroup.fragment.tsx +1 -1
- package/src/components/Tooltip/Tooltip.fragment.tsx +1 -1
- package/src/components/VisuallyHidden/VisuallyHidden.fragment.tsx +1 -1
- package/src/styles/globals.scss +65 -7
- package/src/tokens/_computed.scss +1 -1
- package/src/tokens/_density.scss +1 -1
- package/src/tokens/_derive.scss +1 -1
- package/src/tokens/_index.scss +1 -1
- package/src/tokens/_mixins.scss +1 -1
- package/src/tokens/_palettes.scss +1 -1
- package/src/tokens/_radius.scss +1 -1
- package/src/tokens/_seeds.scss +1 -1
- package/src/tokens/_variables.scss +2 -2
- package/src/utils/a11y.tsx +2 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fragments-sdk/ui",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Customizable UI components built on Base UI headless primitives",
|
|
6
6
|
"author": "Conan McNicholl",
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
"@tanstack/react-table": "^8.21.3",
|
|
114
114
|
"vitest": "^2.1.8",
|
|
115
115
|
"vitest-axe": "^0.1.0",
|
|
116
|
-
"@fragments-sdk/cli": "0.7.
|
|
116
|
+
"@fragments-sdk/cli": "0.7.10"
|
|
117
117
|
},
|
|
118
118
|
"files": [
|
|
119
119
|
"src",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ChartBar, Gear, House, MagnifyingGlass } from '@phosphor-icons/react';
|
|
3
|
-
import { defineFragment } from '@fragments/core';
|
|
3
|
+
import { defineFragment } from '@fragments-sdk/cli/core';
|
|
4
4
|
import { AppShell } from '.';
|
|
5
5
|
import { Box } from '../Box';
|
|
6
6
|
import { Header } from '../Header';
|
|
@@ -85,7 +85,7 @@ import { Stack } from '@/components/Stack';
|
|
|
85
85
|
import { Text } from '@/components/Text';
|
|
86
86
|
import { ThemeToggle } from '@/components/Theme';
|
|
87
87
|
|
|
88
|
-
<Box
|
|
88
|
+
<Box minHeight="100vh" overflow="hidden" border rounded="md">
|
|
89
89
|
<AppShell layout="default">
|
|
90
90
|
<AppShell.Header>
|
|
91
91
|
<Header>
|
|
@@ -123,7 +123,7 @@ import { ThemeToggle } from '@/components/Theme';
|
|
|
123
123
|
</AppShell>
|
|
124
124
|
</Box>`,
|
|
125
125
|
render: () => (
|
|
126
|
-
<Box
|
|
126
|
+
<Box minHeight="100vh" overflow="hidden" border rounded="md">
|
|
127
127
|
<AppShell layout="default">
|
|
128
128
|
<AppShell.Header>
|
|
129
129
|
<Header>
|
|
@@ -175,7 +175,7 @@ import { Stack } from '@/components/Stack';
|
|
|
175
175
|
import { Text } from '@/components/Text';
|
|
176
176
|
import { ThemeToggle } from '@/components/Theme';
|
|
177
177
|
|
|
178
|
-
<Box
|
|
178
|
+
<Box minHeight="100vh" overflow="hidden" border rounded="md">
|
|
179
179
|
<AppShell layout="sidebar">
|
|
180
180
|
<AppShell.Header>
|
|
181
181
|
<Header>
|
|
@@ -220,7 +220,7 @@ import { ThemeToggle } from '@/components/Theme';
|
|
|
220
220
|
</AppShell>
|
|
221
221
|
</Box>`,
|
|
222
222
|
render: () => (
|
|
223
|
-
<Box
|
|
223
|
+
<Box minHeight="100vh" overflow="hidden" border rounded="md">
|
|
224
224
|
<AppShell layout="sidebar">
|
|
225
225
|
<AppShell.Header>
|
|
226
226
|
<Header>
|
|
@@ -279,7 +279,7 @@ import { Stack } from '@/components/Stack';
|
|
|
279
279
|
import { Text } from '@/components/Text';
|
|
280
280
|
import { ThemeToggle } from '@/components/Theme';
|
|
281
281
|
|
|
282
|
-
<Box
|
|
282
|
+
<Box minHeight="100vh" overflow="hidden" border rounded="md">
|
|
283
283
|
<AppShell layout="default">
|
|
284
284
|
<AppShell.Header>
|
|
285
285
|
<Header>
|
|
@@ -320,7 +320,7 @@ import { ThemeToggle } from '@/components/Theme';
|
|
|
320
320
|
</AppShell>
|
|
321
321
|
</Box>`,
|
|
322
322
|
render: () => (
|
|
323
|
-
<Box
|
|
323
|
+
<Box minHeight="100vh" overflow="hidden" border rounded="md">
|
|
324
324
|
<AppShell layout="default">
|
|
325
325
|
<AppShell.Header>
|
|
326
326
|
<Header>
|
|
@@ -374,7 +374,7 @@ import { Sidebar } from '@/components/Sidebar';
|
|
|
374
374
|
import { Text } from '@/components/Text';
|
|
375
375
|
import { ThemeToggle } from '@/components/Theme';
|
|
376
376
|
|
|
377
|
-
<Box
|
|
377
|
+
<Box minHeight="100vh" overflow="hidden" border rounded="md">
|
|
378
378
|
<AppShell layout="sidebar">
|
|
379
379
|
<AppShell.Header>
|
|
380
380
|
<Header>
|
|
@@ -410,7 +410,7 @@ import { ThemeToggle } from '@/components/Theme';
|
|
|
410
410
|
</AppShell>
|
|
411
411
|
</Box>`,
|
|
412
412
|
render: () => (
|
|
413
|
-
<Box
|
|
413
|
+
<Box minHeight="100vh" overflow="hidden" border rounded="md">
|
|
414
414
|
<AppShell layout="sidebar">
|
|
415
415
|
<AppShell.Header>
|
|
416
416
|
<Header>
|
|
@@ -460,7 +460,7 @@ import { Stack } from '@/components/Stack';
|
|
|
460
460
|
import { Text } from '@/components/Text';
|
|
461
461
|
import { ThemeToggle } from '@/components/Theme';
|
|
462
462
|
|
|
463
|
-
<Box
|
|
463
|
+
<Box minHeight="100vh" overflow="hidden" border rounded="md">
|
|
464
464
|
<AppShell layout="sidebar-floating">
|
|
465
465
|
<AppShell.Header>
|
|
466
466
|
<Header>
|
|
@@ -505,7 +505,7 @@ import { ThemeToggle } from '@/components/Theme';
|
|
|
505
505
|
</AppShell>
|
|
506
506
|
</Box>`,
|
|
507
507
|
render: () => (
|
|
508
|
-
<Box
|
|
508
|
+
<Box minHeight="100vh" overflow="hidden" border rounded="md">
|
|
509
509
|
<AppShell layout="sidebar-floating">
|
|
510
510
|
<AppShell.Header>
|
|
511
511
|
<Header>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
1
3
|
import * as React from 'react';
|
|
2
4
|
import styles from './Avatar.module.scss';
|
|
3
5
|
// Import globals to ensure CSS variables are defined
|
|
@@ -109,11 +111,16 @@ const AvatarBase = React.forwardRef<HTMLDivElement, AvatarProps>(
|
|
|
109
111
|
},
|
|
110
112
|
ref
|
|
111
113
|
) {
|
|
114
|
+
const imgRef = React.useRef<HTMLImageElement>(null);
|
|
112
115
|
const [imageError, setImageError] = React.useState(false);
|
|
113
116
|
|
|
114
|
-
// Reset error state when src changes
|
|
117
|
+
// Reset error state when src changes; check if already-loaded image failed
|
|
115
118
|
React.useEffect(() => {
|
|
116
119
|
setImageError(false);
|
|
120
|
+
const img = imgRef.current;
|
|
121
|
+
if (img && img.complete && img.naturalWidth === 0) {
|
|
122
|
+
setImageError(true);
|
|
123
|
+
}
|
|
117
124
|
}, [src]);
|
|
118
125
|
|
|
119
126
|
const showFallback = !src || imageError;
|
|
@@ -150,6 +157,7 @@ const AvatarBase = React.forwardRef<HTMLDivElement, AvatarProps>(
|
|
|
150
157
|
>
|
|
151
158
|
{!showFallback && (
|
|
152
159
|
<img
|
|
160
|
+
ref={imgRef}
|
|
153
161
|
src={src}
|
|
154
162
|
alt={alt}
|
|
155
163
|
className={styles.image}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
|
-
import { defineFragment } from '@fragments/core';
|
|
2
|
+
import { defineFragment } from '@fragments-sdk/cli/core';
|
|
3
3
|
import { DatePicker } from '.';
|
|
4
4
|
import type { DateRange } from '.';
|
|
5
5
|
import { subDays } from 'date-fns';
|
|
@@ -87,17 +87,18 @@ export default defineFragment({
|
|
|
87
87
|
required: true,
|
|
88
88
|
},
|
|
89
89
|
mode: {
|
|
90
|
-
type:
|
|
90
|
+
type: 'enum',
|
|
91
|
+
values: ['single', 'range'],
|
|
91
92
|
description: 'Selection mode',
|
|
92
93
|
default: "'single'",
|
|
93
94
|
},
|
|
94
95
|
selected: {
|
|
95
|
-
type: '
|
|
96
|
-
description: 'Controlled date (single mode)',
|
|
96
|
+
type: 'custom',
|
|
97
|
+
description: 'Controlled date (single mode). Type: Date | null',
|
|
97
98
|
},
|
|
98
99
|
selectedRange: {
|
|
99
|
-
type: '
|
|
100
|
-
description: 'Controlled range (range mode)',
|
|
100
|
+
type: 'custom',
|
|
101
|
+
description: 'Controlled range (range mode). Type: DateRange | null',
|
|
101
102
|
},
|
|
102
103
|
onSelect: {
|
|
103
104
|
type: 'function',
|
|
@@ -118,8 +119,8 @@ export default defineFragment({
|
|
|
118
119
|
default: 'false',
|
|
119
120
|
},
|
|
120
121
|
disabledDates: {
|
|
121
|
-
type: '
|
|
122
|
-
description: 'Dates to disable (react-day-picker Matcher)',
|
|
122
|
+
type: 'custom',
|
|
123
|
+
description: 'Dates to disable (react-day-picker Matcher | Matcher[])',
|
|
123
124
|
},
|
|
124
125
|
placeholder: {
|
|
125
126
|
type: 'string',
|
|
@@ -130,7 +131,7 @@ export default defineFragment({
|
|
|
130
131
|
relations: [
|
|
131
132
|
{ component: 'Select', relationship: 'alternative', note: 'Use Select for choosing from a list of options' },
|
|
132
133
|
{ component: 'Input', relationship: 'sibling', note: 'Use Input for free-form text date entry' },
|
|
133
|
-
{ component: 'Popover', relationship: '
|
|
134
|
+
{ component: 'Popover', relationship: 'composition', note: 'DatePicker uses Popover for the calendar dropdown' },
|
|
134
135
|
],
|
|
135
136
|
|
|
136
137
|
contract: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { defineFragment } from '@fragments/core';
|
|
2
|
+
import { defineFragment } from '@fragments-sdk/cli/core';
|
|
3
3
|
import { Header } from '.';
|
|
4
4
|
import { NavigationMenu } from '../NavigationMenu';
|
|
5
5
|
import { ThemeToggle, ThemeProvider } from '../Theme';
|
|
@@ -43,8 +43,17 @@ const ImageRoot = React.forwardRef<HTMLDivElement, ImageProps>(
|
|
|
43
43
|
},
|
|
44
44
|
ref
|
|
45
45
|
) {
|
|
46
|
+
const imgRef = React.useRef<HTMLImageElement>(null);
|
|
46
47
|
const [status, setStatus] = React.useState<'loading' | 'loaded' | 'error'>('loading');
|
|
47
48
|
|
|
49
|
+
// Handle images that are already cached/loaded before hydration
|
|
50
|
+
React.useEffect(() => {
|
|
51
|
+
const img = imgRef.current;
|
|
52
|
+
if (img && img.complete) {
|
|
53
|
+
setStatus(img.naturalWidth > 0 ? 'loaded' : 'error');
|
|
54
|
+
}
|
|
55
|
+
}, [src]);
|
|
56
|
+
|
|
48
57
|
const handleLoad = () => setStatus('loaded');
|
|
49
58
|
const handleError = () => setStatus('error');
|
|
50
59
|
|
|
@@ -80,6 +89,7 @@ const ImageRoot = React.forwardRef<HTMLDivElement, ImageProps>(
|
|
|
80
89
|
<div className={styles.fallback}>{fallback}</div>
|
|
81
90
|
)}
|
|
82
91
|
<img
|
|
92
|
+
ref={imgRef}
|
|
83
93
|
src={src}
|
|
84
94
|
alt={alt}
|
|
85
95
|
className={imgClasses}
|