@usefragments/ui 1.0.2 → 1.1.1
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/README.md +16 -16
- package/dist/assets/fragments-wordmark.cjs +30 -0
- package/dist/assets/fragments-wordmark.d.ts +13 -0
- package/dist/assets/fragments-wordmark.d.ts.map +1 -0
- package/dist/assets/fragments-wordmark.js +30 -0
- package/dist/assets/ui.css +3173 -3108
- package/dist/components/Accordion/Accordion.module.scss.cjs +8 -8
- package/dist/components/Accordion/Accordion.module.scss.js +8 -8
- package/dist/components/Accordion/index.cjs +22 -10
- package/dist/components/Accordion/index.d.ts.map +1 -1
- package/dist/components/Accordion/index.js +22 -10
- package/dist/components/Alert/Alert.module.scss.cjs +13 -13
- package/dist/components/Alert/Alert.module.scss.js +13 -13
- package/dist/components/AppShell/AppShell.module.scss.cjs +22 -10
- package/dist/components/AppShell/AppShell.module.scss.js +22 -10
- package/dist/components/AppShell/index.cjs +1 -1
- package/dist/components/AppShell/index.js +1 -1
- package/dist/components/Avatar/Avatar.module.scss.cjs +13 -13
- package/dist/components/Avatar/Avatar.module.scss.js +13 -13
- package/dist/components/Badge/Badge.module.scss.cjs +16 -16
- package/dist/components/Badge/Badge.module.scss.js +16 -16
- package/dist/components/BentoGrid/BentoGrid.module.scss.cjs +14 -14
- package/dist/components/BentoGrid/BentoGrid.module.scss.js +14 -14
- package/dist/components/Box/Box.module.scss.cjs +152 -152
- package/dist/components/Box/Box.module.scss.js +152 -152
- package/dist/components/Breadcrumbs/Breadcrumbs.module.scss.cjs +8 -8
- package/dist/components/Breadcrumbs/Breadcrumbs.module.scss.js +8 -8
- package/dist/components/Button/Button.module.scss.cjs +13 -13
- package/dist/components/Button/Button.module.scss.js +13 -13
- package/dist/components/Card/Card.module.scss.cjs +17 -17
- package/dist/components/Card/Card.module.scss.js +17 -17
- package/dist/components/Card/index.d.ts +3 -3
- package/dist/components/Card/index.d.ts.map +1 -1
- package/dist/components/Chart/Chart.module.scss.cjs +15 -15
- package/dist/components/Chart/Chart.module.scss.js +15 -15
- package/dist/components/Checkbox/Checkbox.module.scss.cjs +11 -11
- package/dist/components/Checkbox/Checkbox.module.scss.js +11 -11
- package/dist/components/Chip/Chip.module.scss.cjs +15 -15
- package/dist/components/Chip/Chip.module.scss.js +15 -15
- package/dist/components/CodeBlock/CodeBlock.module.scss.cjs +21 -21
- package/dist/components/CodeBlock/CodeBlock.module.scss.js +21 -21
- package/dist/components/Collapsible/Collapsible.module.scss.cjs +10 -10
- package/dist/components/Collapsible/Collapsible.module.scss.js +10 -10
- package/dist/components/ColorPicker/ColorPicker.module.scss.cjs +14 -14
- package/dist/components/ColorPicker/ColorPicker.module.scss.js +14 -14
- package/dist/components/Combobox/Combobox.module.scss.cjs +23 -23
- package/dist/components/Combobox/Combobox.module.scss.js +23 -23
- package/dist/components/Command/Command.module.scss.cjs +11 -11
- package/dist/components/Command/Command.module.scss.js +11 -11
- package/dist/components/ConversationList/ConversationList.module.scss.cjs +10 -10
- package/dist/components/ConversationList/ConversationList.module.scss.js +10 -10
- package/dist/components/DataTable/DataTable.module.scss.cjs +34 -34
- package/dist/components/DataTable/DataTable.module.scss.js +34 -34
- package/dist/components/DataTable/index.d.ts +3 -1
- package/dist/components/DataTable/index.d.ts.map +1 -1
- package/dist/components/DatePicker/DatePicker.module.scss.cjs +33 -33
- package/dist/components/DatePicker/DatePicker.module.scss.js +33 -33
- package/dist/components/DatePicker/index.d.ts +1 -1
- package/dist/components/DatePicker/index.d.ts.map +1 -1
- package/dist/components/Dialog/Dialog.module.scss.cjs +14 -14
- package/dist/components/Dialog/Dialog.module.scss.js +14 -14
- package/dist/components/Drawer/Drawer.module.scss.cjs +28 -28
- package/dist/components/Drawer/Drawer.module.scss.js +28 -28
- package/dist/components/Drawer/index.cjs +20 -3
- package/dist/components/Drawer/index.d.ts.map +1 -1
- package/dist/components/Drawer/index.js +20 -3
- package/dist/components/Editor/Editor.module.scss.cjs +17 -17
- package/dist/components/Editor/Editor.module.scss.js +17 -17
- package/dist/components/EmptyState/EmptyState.module.scss.cjs +8 -8
- package/dist/components/EmptyState/EmptyState.module.scss.js +8 -8
- package/dist/components/Field/Field.module.scss.cjs +4 -4
- package/dist/components/Field/Field.module.scss.js +4 -4
- package/dist/components/Field/index.cjs +10 -9
- package/dist/components/Field/index.d.ts +7 -7
- package/dist/components/Field/index.d.ts.map +1 -1
- package/dist/components/Field/index.js +10 -9
- package/dist/components/Fieldset/Fieldset.module.scss.cjs +3 -3
- package/dist/components/Fieldset/Fieldset.module.scss.js +3 -3
- package/dist/components/Header/Header.module.scss.cjs +44 -29
- package/dist/components/Header/Header.module.scss.js +44 -29
- package/dist/components/Header/index.cjs +56 -3
- package/dist/components/Header/index.d.ts +25 -3
- package/dist/components/Header/index.d.ts.map +1 -1
- package/dist/components/Header/index.js +56 -3
- package/dist/components/Icon/Icon.module.scss.cjs +8 -8
- package/dist/components/Icon/Icon.module.scss.js +8 -8
- package/dist/components/IconButton/IconButton.module.scss.cjs +8 -8
- package/dist/components/IconButton/IconButton.module.scss.js +8 -8
- package/dist/components/Image/Image.module.scss.cjs +27 -27
- package/dist/components/Image/Image.module.scss.js +27 -27
- package/dist/components/Input/Input.module.scss.cjs +19 -19
- package/dist/components/Input/Input.module.scss.js +19 -19
- package/dist/components/Link/Link.module.scss.cjs +10 -10
- package/dist/components/Link/Link.module.scss.js +10 -10
- package/dist/components/List/List.module.scss.cjs +19 -19
- package/dist/components/List/List.module.scss.js +19 -19
- package/dist/components/Listbox/Listbox.module.scss.cjs +8 -8
- package/dist/components/Listbox/Listbox.module.scss.js +8 -8
- package/dist/components/Loading/Loading.module.scss.cjs +30 -30
- package/dist/components/Loading/Loading.module.scss.js +30 -30
- package/dist/components/Markdown/Markdown.module.scss.cjs +1 -1
- package/dist/components/Markdown/Markdown.module.scss.js +1 -1
- package/dist/components/Menu/Menu.module.scss.cjs +14 -14
- package/dist/components/Menu/Menu.module.scss.js +14 -14
- package/dist/components/Message/Message.module.scss.cjs +18 -18
- package/dist/components/Message/Message.module.scss.js +18 -18
- package/dist/components/NavigationMenu/NavigationMenu.module.scss.cjs +28 -28
- package/dist/components/NavigationMenu/NavigationMenu.module.scss.js +28 -28
- package/dist/components/Pagination/Pagination.module.scss.cjs +7 -7
- package/dist/components/Pagination/Pagination.module.scss.js +7 -7
- package/dist/components/Popover/Popover.module.scss.cjs +10 -10
- package/dist/components/Popover/Popover.module.scss.js +10 -10
- package/dist/components/Popover/index.cjs +27 -2
- package/dist/components/Popover/index.d.ts.map +1 -1
- package/dist/components/Popover/index.js +27 -2
- package/dist/components/Progress/Progress.module.scss.cjs +25 -25
- package/dist/components/Progress/Progress.module.scss.js +25 -25
- package/dist/components/Prompt/Prompt.module.scss.cjs +18 -18
- package/dist/components/Prompt/Prompt.module.scss.js +18 -18
- package/dist/components/RadioGroup/RadioGroup.module.scss.cjs +17 -17
- package/dist/components/RadioGroup/RadioGroup.module.scss.js +17 -17
- package/dist/components/RadioGroup/index.cjs +2 -0
- package/dist/components/RadioGroup/index.d.ts +2 -0
- package/dist/components/RadioGroup/index.d.ts.map +1 -1
- package/dist/components/RadioGroup/index.js +2 -0
- package/dist/components/ScrollArea/ScrollArea.module.scss.cjs +10 -10
- package/dist/components/ScrollArea/ScrollArea.module.scss.js +10 -10
- package/dist/components/Select/Select.module.scss.cjs +17 -17
- package/dist/components/Select/Select.module.scss.js +17 -17
- package/dist/components/Separator/Separator.module.scss.cjs +10 -10
- package/dist/components/Separator/Separator.module.scss.js +10 -10
- package/dist/components/Sidebar/Sidebar.module.scss.cjs +42 -42
- package/dist/components/Sidebar/Sidebar.module.scss.js +42 -42
- package/dist/components/Skeleton/Skeleton.module.scss.cjs +38 -38
- package/dist/components/Skeleton/Skeleton.module.scss.js +38 -38
- package/dist/components/Slider/Slider.module.scss.cjs +12 -12
- package/dist/components/Slider/Slider.module.scss.js +12 -12
- package/dist/components/Table/Table.module.scss.cjs +18 -18
- package/dist/components/Table/Table.module.scss.js +18 -18
- package/dist/components/TableOfContents/TableOfContents.module.scss.cjs +15 -15
- package/dist/components/TableOfContents/TableOfContents.module.scss.js +15 -15
- package/dist/components/Tabs/Tabs.module.scss.cjs +12 -12
- package/dist/components/Tabs/Tabs.module.scss.js +12 -12
- package/dist/components/Text/Text.module.scss.cjs +51 -51
- package/dist/components/Text/Text.module.scss.js +51 -51
- package/dist/components/Textarea/Textarea.module.scss.cjs +23 -23
- package/dist/components/Textarea/Textarea.module.scss.js +23 -23
- package/dist/components/Theme/ThemeToggle.module.scss.cjs +6 -6
- package/dist/components/Theme/ThemeToggle.module.scss.js +6 -6
- package/dist/components/ThinkingIndicator/ThinkingIndicator.module.scss.cjs +13 -13
- package/dist/components/ThinkingIndicator/ThinkingIndicator.module.scss.js +13 -13
- package/dist/components/Toast/Toast.module.scss.cjs +21 -21
- package/dist/components/Toast/Toast.module.scss.js +21 -21
- package/dist/components/Toggle/Toggle.module.scss.cjs +13 -13
- package/dist/components/Toggle/Toggle.module.scss.js +13 -13
- package/dist/components/ToggleGroup/ToggleGroup.module.scss.cjs +17 -17
- package/dist/components/ToggleGroup/ToggleGroup.module.scss.js +17 -17
- package/dist/components/Tooltip/Tooltip.module.scss.cjs +3 -3
- package/dist/components/Tooltip/Tooltip.module.scss.js +3 -3
- package/dist/data-table.cjs +58 -41
- package/dist/data-table.js +59 -41
- package/dist/datepicker.cjs +32 -72
- package/dist/datepicker.js +32 -72
- package/dist/index.cjs +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/fragments.json +1 -1
- package/package.json +4 -8
- package/src/assets/fragments-wordmark.tsx +47 -0
- package/src/components/Accordion/index.tsx +13 -3
- package/src/components/Alert/Alert.module.scss +15 -2
- package/src/components/AppShell/AppShell.module.scss +73 -15
- package/src/components/AppShell/index.tsx +1 -1
- package/src/components/Button/Button.module.scss +19 -20
- package/src/components/Card/Card.module.scss +3 -3
- package/src/components/Card/index.tsx +3 -3
- package/src/components/CodeBlock/CodeBlock.module.scss +2 -7
- package/src/components/Combobox/Combobox.module.scss +3 -2
- package/src/components/DataTable/DataTable.contract.json +16 -23
- package/src/components/DataTable/index.tsx +25 -4
- package/src/components/DatePicker/index.tsx +32 -84
- package/src/components/Drawer/index.tsx +38 -12
- package/src/components/Field/index.tsx +35 -35
- package/src/components/Header/Header.contract.json +41 -1
- package/src/components/Header/Header.module.scss +40 -0
- package/src/components/Header/index.tsx +88 -2
- package/src/components/IconButton/IconButton.contract.json +120 -0
- package/src/components/Listbox/Listbox.module.scss +5 -4
- package/src/components/Menu/Menu.module.scss +8 -10
- package/src/components/Popover/index.tsx +34 -2
- package/src/components/RadioGroup/RadioGroup.contract.json +13 -27
- package/src/components/RadioGroup/index.tsx +4 -0
- package/src/components/Select/Select.module.scss +13 -12
- package/src/components/TableOfContents/TableOfContents.module.scss +10 -1
- package/src/components/Toast/Toast.module.scss +15 -2
- package/src/components/ToggleGroup/ToggleGroup.module.scss +4 -1
- package/src/index.ts +1 -0
- package/src/styles/globals.scss +13 -10
- package/src/tokens/_component-properties.scss +25 -0
- package/src/tokens/_computed.scss +22 -4
- package/src/tokens/_derive.scss +55 -6
- package/src/tokens/_palettes.scss +24 -0
- package/src/tokens/_seeds.scss +20 -12
- package/src/tokens/_variables.scss +110 -63
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usefragments/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Customizable UI components built on Base UI headless primitives",
|
|
6
6
|
"author": "Conan McNicholl",
|
|
@@ -155,13 +155,9 @@
|
|
|
155
155
|
"remark-gfm": ">=4.0.0",
|
|
156
156
|
"shiki": ">=1.0.0"
|
|
157
157
|
},
|
|
158
|
-
"scarfSettings": {
|
|
159
|
-
"defaultOptIn": true
|
|
160
|
-
},
|
|
161
158
|
"dependencies": {
|
|
162
|
-
"@base-ui/react": "
|
|
163
|
-
"@phosphor-icons/react": "^2.1.10"
|
|
164
|
-
"@scarf/scarf": "^1.4.0"
|
|
159
|
+
"@base-ui/react": "1.6.0",
|
|
160
|
+
"@phosphor-icons/react": "^2.1.10"
|
|
165
161
|
},
|
|
166
162
|
"devDependencies": {
|
|
167
163
|
"@storybook/addon-a11y": "^8",
|
|
@@ -194,7 +190,7 @@
|
|
|
194
190
|
"vite": "^6.0.0",
|
|
195
191
|
"vitest": "^2.1.8",
|
|
196
192
|
"vitest-axe": "^0.1.0",
|
|
197
|
-
"@usefragments/core": "1.
|
|
193
|
+
"@usefragments/core": "1.2.0"
|
|
198
194
|
},
|
|
199
195
|
"files": [
|
|
200
196
|
"src",
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
// Baked from the brand lockup artwork (star + wordmark), trimmed to content and
|
|
4
|
+
// stored as a monochrome alpha mask so it can be filled with currentColor. That
|
|
5
|
+
// keeps the lockup themeable — it renders in the current text color, matching
|
|
6
|
+
// the light and dark brand versions from a single asset.
|
|
7
|
+
const WORDMARK_MASK =
|
|
8
|
+
"data:image/png;base64,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";
|
|
9
|
+
|
|
10
|
+
/** Aspect ratio (width / height) of the trimmed lockup. */
|
|
11
|
+
const WORDMARK_ASPECT = 4.000;
|
|
12
|
+
|
|
13
|
+
export interface FragmentsWordmarkProps {
|
|
14
|
+
/** Rendered height in px; width follows the lockup aspect ratio. */
|
|
15
|
+
height?: number;
|
|
16
|
+
/** Optional className */
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The Fragments logo lockup — star + wordmark as one image. Use this anywhere
|
|
22
|
+
* the brand is shown with its name, instead of the icon beside a text label.
|
|
23
|
+
* Themeable: the artwork is a CSS mask filled with currentColor.
|
|
24
|
+
*/
|
|
25
|
+
export function FragmentsWordmark({ height = 20, className }: FragmentsWordmarkProps) {
|
|
26
|
+
return (
|
|
27
|
+
<span
|
|
28
|
+
role="img"
|
|
29
|
+
aria-label="Fragments"
|
|
30
|
+
className={className}
|
|
31
|
+
style={{
|
|
32
|
+
display: "inline-block",
|
|
33
|
+
height,
|
|
34
|
+
width: height * WORDMARK_ASPECT,
|
|
35
|
+
backgroundColor: "currentColor",
|
|
36
|
+
maskImage: `url("${WORDMARK_MASK}")`,
|
|
37
|
+
WebkitMaskImage: `url("${WORDMARK_MASK}")`,
|
|
38
|
+
maskRepeat: "no-repeat",
|
|
39
|
+
WebkitMaskRepeat: "no-repeat",
|
|
40
|
+
maskSize: "contain",
|
|
41
|
+
WebkitMaskSize: "contain",
|
|
42
|
+
maskPosition: "left center",
|
|
43
|
+
WebkitMaskPosition: "left center",
|
|
44
|
+
}}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -184,7 +184,7 @@ function AccordionItem({
|
|
|
184
184
|
className,
|
|
185
185
|
...htmlProps
|
|
186
186
|
}: AccordionItemProps) {
|
|
187
|
-
const { openItems } = useAccordionContext();
|
|
187
|
+
const { openItems, toggle } = useAccordionContext();
|
|
188
188
|
const isOpen = openItems.includes(value);
|
|
189
189
|
const baseId = React.useId();
|
|
190
190
|
const triggerId = `accordion-trigger-${baseId}`;
|
|
@@ -201,7 +201,17 @@ function AccordionItem({
|
|
|
201
201
|
|
|
202
202
|
return (
|
|
203
203
|
<AccordionItemContext.Provider value={{ value, isOpen, disabled, triggerId, contentId }}>
|
|
204
|
-
<BaseCollapsible.Root
|
|
204
|
+
<BaseCollapsible.Root
|
|
205
|
+
open={isOpen}
|
|
206
|
+
disabled={disabled}
|
|
207
|
+
onOpenChange={(nextOpen, eventDetails) => {
|
|
208
|
+
// Trigger presses stay in AccordionTrigger so its public onClick can cancel them.
|
|
209
|
+
// Base owns the browser-only beforematch event used by hiddenUntilFound panels.
|
|
210
|
+
if (eventDetails.event.type === "beforematch" && nextOpen !== isOpen) {
|
|
211
|
+
toggle(value);
|
|
212
|
+
}
|
|
213
|
+
}}
|
|
214
|
+
>
|
|
205
215
|
<div
|
|
206
216
|
{...htmlProps}
|
|
207
217
|
className={classes}
|
|
@@ -285,7 +295,7 @@ function AccordionContent({
|
|
|
285
295
|
data-state={isOpen ? "open" : "closed"}
|
|
286
296
|
role="region"
|
|
287
297
|
aria-labelledby={triggerId}
|
|
288
|
-
keepMounted={keepMounted}
|
|
298
|
+
keepMounted={keepMounted || hiddenUntilFound}
|
|
289
299
|
hiddenUntilFound={hiddenUntilFound}
|
|
290
300
|
>
|
|
291
301
|
<div className={styles.contentInner}>{children}</div>
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
.alert {
|
|
5
5
|
display: flex;
|
|
6
|
-
|
|
6
|
+
// Single-line alerts (icon + one line, no title) read best vertically
|
|
7
|
+
// centered. Multi-line alerts top-align instead — see `:has(.title)` below.
|
|
8
|
+
align-items: center;
|
|
7
9
|
gap: var(--fui-space-3, $fui-space-3);
|
|
8
10
|
padding: var(--fui-space-2, $fui-space-2) var(--fui-space-3, $fui-space-3);
|
|
9
11
|
border-radius: var(--fui-radius-lg, $fui-radius-lg);
|
|
@@ -12,6 +14,12 @@
|
|
|
12
14
|
line-height: var(--fui-line-height-normal, $fui-line-height-normal);
|
|
13
15
|
}
|
|
14
16
|
|
|
17
|
+
// With a title (title + description), the block is multi-line: top-align so
|
|
18
|
+
// the icon and close sit with the first line rather than the block's centre.
|
|
19
|
+
.alert:has(.title) {
|
|
20
|
+
align-items: flex-start;
|
|
21
|
+
}
|
|
22
|
+
|
|
15
23
|
// Severity variants
|
|
16
24
|
.info {
|
|
17
25
|
background: var(--fui-color-info-bg, $fui-color-info-bg);
|
|
@@ -47,10 +55,15 @@
|
|
|
47
55
|
font-size: var(--fui-font-size-xs, $fui-font-size-xs);
|
|
48
56
|
font-weight: var(--fui-font-weight-semibold, $fui-font-weight-semibold);
|
|
49
57
|
flex-shrink: 0;
|
|
50
|
-
margin-top: var(--fui-space-px, $fui-space-px);
|
|
51
58
|
color: var(--fui-text-inverse, $fui-text-inverse);
|
|
52
59
|
}
|
|
53
60
|
|
|
61
|
+
// Only nudge the icon down to meet the first text line when the alert is
|
|
62
|
+
// multi-line; centered single-line alerts need no offset.
|
|
63
|
+
.alert:has(.title) .icon {
|
|
64
|
+
margin-top: var(--fui-space-px, $fui-space-px);
|
|
65
|
+
}
|
|
66
|
+
|
|
54
67
|
.info .icon {
|
|
55
68
|
background-color: var(--fui-color-info-text, $fui-color-info-text);
|
|
56
69
|
}
|
|
@@ -72,7 +72,10 @@
|
|
|
72
72
|
grid-area: header;
|
|
73
73
|
position: sticky;
|
|
74
74
|
top: 0;
|
|
75
|
-
height: var(
|
|
75
|
+
height: var(
|
|
76
|
+
--appshell-header-height,
|
|
77
|
+
var(--fui-appshell-header-height, $fui-appshell-header-height)
|
|
78
|
+
);
|
|
76
79
|
z-index: var(--fui-header-z-index, $fui-header-z-index);
|
|
77
80
|
background-color: inherit;
|
|
78
81
|
|
|
@@ -88,9 +91,22 @@
|
|
|
88
91
|
.sidebar {
|
|
89
92
|
grid-area: sidebar;
|
|
90
93
|
position: sticky;
|
|
91
|
-
top: var(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
top: var(
|
|
95
|
+
--appshell-header-height,
|
|
96
|
+
var(--fui-appshell-header-height, $fui-appshell-header-height)
|
|
97
|
+
);
|
|
98
|
+
height: calc(
|
|
99
|
+
100vh - var(
|
|
100
|
+
--appshell-header-height,
|
|
101
|
+
var(--fui-appshell-header-height, $fui-appshell-header-height)
|
|
102
|
+
)
|
|
103
|
+
);
|
|
104
|
+
height: calc(
|
|
105
|
+
100dvh - var(
|
|
106
|
+
--appshell-header-height,
|
|
107
|
+
var(--fui-appshell-header-height, $fui-appshell-header-height)
|
|
108
|
+
)
|
|
109
|
+
);
|
|
94
110
|
z-index: 30;
|
|
95
111
|
overflow: hidden;
|
|
96
112
|
background-color: inherit;
|
|
@@ -171,9 +187,8 @@
|
|
|
171
187
|
border: 1px solid var(--fui-border, $fui-border);
|
|
172
188
|
border-radius: var(--fui-radius-xl, $fui-radius-xl);
|
|
173
189
|
background-color: var(--fui-app-main-bg, var(--fui-main-bg, #{$fui-main-bg}));
|
|
174
|
-
box-shadow:
|
|
175
|
-
|
|
176
|
-
color-mix(in srgb, var(--fui-text-primary, #{$fui-text-primary}) 5%, transparent);
|
|
190
|
+
box-shadow: inset 0 1px 0
|
|
191
|
+
color-mix(in srgb, var(--fui-text-primary, #{$fui-text-primary}) 5%, transparent);
|
|
177
192
|
overflow: hidden auto;
|
|
178
193
|
|
|
179
194
|
@include below-md {
|
|
@@ -185,6 +200,25 @@
|
|
|
185
200
|
}
|
|
186
201
|
}
|
|
187
202
|
|
|
203
|
+
// Canonical spacing scale (shared with Card/Box/Stack/Grid): sm=2 md=3 lg=4.
|
|
204
|
+
// Keep these compound rules after `.mainFloating`: the explicit padding prop
|
|
205
|
+
// owns the content inset even when the floating surface supplies its default.
|
|
206
|
+
.main.paddingNone {
|
|
207
|
+
padding: 0;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.main.paddingSm {
|
|
211
|
+
padding: var(--fui-space-2, $fui-space-2);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.main.paddingMd {
|
|
215
|
+
padding: var(--fui-space-3, $fui-space-3);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.main.paddingLg {
|
|
219
|
+
padding: var(--fui-space-4, $fui-space-4);
|
|
220
|
+
}
|
|
221
|
+
|
|
188
222
|
// ============================================
|
|
189
223
|
// Aside (Right Panel)
|
|
190
224
|
// ============================================
|
|
@@ -192,9 +226,22 @@
|
|
|
192
226
|
.aside {
|
|
193
227
|
grid-area: aside;
|
|
194
228
|
position: sticky;
|
|
195
|
-
top: var(
|
|
196
|
-
|
|
197
|
-
|
|
229
|
+
top: var(
|
|
230
|
+
--appshell-header-height,
|
|
231
|
+
var(--fui-appshell-header-height, $fui-appshell-header-height)
|
|
232
|
+
);
|
|
233
|
+
height: calc(
|
|
234
|
+
100vh - var(
|
|
235
|
+
--appshell-header-height,
|
|
236
|
+
var(--fui-appshell-header-height, $fui-appshell-header-height)
|
|
237
|
+
)
|
|
238
|
+
);
|
|
239
|
+
height: calc(
|
|
240
|
+
100dvh - var(
|
|
241
|
+
--appshell-header-height,
|
|
242
|
+
var(--fui-appshell-header-height, $fui-appshell-header-height)
|
|
243
|
+
)
|
|
244
|
+
);
|
|
198
245
|
width: var(--aside-width, 280px);
|
|
199
246
|
min-height: 0; // Allow shrinking in grid
|
|
200
247
|
z-index: 30;
|
|
@@ -216,16 +263,27 @@
|
|
|
216
263
|
// Override the explicit width so the aside fills its grid cell
|
|
217
264
|
// and the margin creates visible inset space from the viewport edge.
|
|
218
265
|
width: auto;
|
|
219
|
-
height: calc(
|
|
220
|
-
|
|
266
|
+
height: calc(
|
|
267
|
+
100vh - var(
|
|
268
|
+
--appshell-header-height,
|
|
269
|
+
var(--fui-appshell-header-height, $fui-appshell-header-height)
|
|
270
|
+
) - var(--fui-space-1, $fui-space-1) *
|
|
271
|
+
2
|
|
272
|
+
);
|
|
273
|
+
height: calc(
|
|
274
|
+
100dvh - var(
|
|
275
|
+
--appshell-header-height,
|
|
276
|
+
var(--fui-appshell-header-height, $fui-appshell-header-height)
|
|
277
|
+
) - var(--fui-space-1, $fui-space-1) *
|
|
278
|
+
2
|
|
279
|
+
);
|
|
221
280
|
margin: var(--fui-space-1, $fui-space-1) var(--fui-space-1, $fui-space-1)
|
|
222
281
|
var(--fui-space-1, $fui-space-1) 0;
|
|
223
282
|
border: 1px solid var(--fui-border, $fui-border);
|
|
224
283
|
border-radius: var(--fui-radius-xl, $fui-radius-xl);
|
|
225
284
|
background-color: var(--fui-panel-bg, inherit);
|
|
226
|
-
box-shadow:
|
|
227
|
-
|
|
228
|
-
color-mix(in srgb, var(--fui-text-primary, #{$fui-text-primary}) 5%, transparent);
|
|
285
|
+
box-shadow: inset 0 1px 0
|
|
286
|
+
color-mix(in srgb, var(--fui-text-primary, #{$fui-text-primary}) 5%, transparent);
|
|
229
287
|
overflow: hidden;
|
|
230
288
|
|
|
231
289
|
@include below-md {
|
|
@@ -448,7 +448,7 @@ function AppShellMain({
|
|
|
448
448
|
|
|
449
449
|
const classes = [
|
|
450
450
|
styles.main,
|
|
451
|
-
|
|
451
|
+
styles[`padding${padding.charAt(0).toUpperCase() + padding.slice(1)}`],
|
|
452
452
|
resolvedVariant === "floating" && styles.mainFloating,
|
|
453
453
|
className,
|
|
454
454
|
]
|
|
@@ -29,6 +29,14 @@
|
|
|
29
29
|
white-space: nowrap;
|
|
30
30
|
user-select: none;
|
|
31
31
|
|
|
32
|
+
// A composed link — `Button asChild` cloning an <a>, or an anchor rendered
|
|
33
|
+
// as a child — must wear the button's own foreground, never the global
|
|
34
|
+
// naked-link accent color (which would collide, e.g. accent-on-accent).
|
|
35
|
+
a {
|
|
36
|
+
color: inherit;
|
|
37
|
+
text-decoration: none;
|
|
38
|
+
}
|
|
39
|
+
|
|
32
40
|
&:hover:not(:disabled):not([data-disabled]) {
|
|
33
41
|
border-color: var(--_button-border-hover);
|
|
34
42
|
background: var(--_button-bg-hover);
|
|
@@ -173,22 +181,17 @@
|
|
|
173
181
|
}
|
|
174
182
|
|
|
175
183
|
.danger {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
--_button-bg-hover: linear-gradient(
|
|
183
|
-
to bottom,
|
|
184
|
-
color-mix(in srgb, var(--fui-color-danger, #{$fui-color-danger}) 76%, white 24%) 0%,
|
|
185
|
-
color-mix(in srgb, var(--fui-color-danger, #{$fui-color-danger}) 94%, black 6%) 52%,
|
|
186
|
-
color-mix(in srgb, var(--fui-color-danger, #{$fui-color-danger}) 78%, black 22%) 100%
|
|
184
|
+
// Flat danger fill — no gradient. Hover/active darken the solid colour.
|
|
185
|
+
--_button-bg: var(--fui-color-danger, #{$fui-color-danger});
|
|
186
|
+
--_button-bg-hover: color-mix(
|
|
187
|
+
in srgb,
|
|
188
|
+
var(--fui-color-danger, #{$fui-color-danger}) 88%,
|
|
189
|
+
black 12%
|
|
187
190
|
);
|
|
188
|
-
--_button-bg-active:
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
191
|
+
--_button-bg-active: color-mix(
|
|
192
|
+
in srgb,
|
|
193
|
+
var(--fui-color-danger, #{$fui-color-danger}) 80%,
|
|
194
|
+
black 20%
|
|
192
195
|
);
|
|
193
196
|
--_button-border: color-mix(
|
|
194
197
|
in srgb,
|
|
@@ -213,11 +216,7 @@
|
|
|
213
216
|
--_button-border: var(--fui-button-neutral-border);
|
|
214
217
|
--_button-border-hover: var(--fui-button-neutral-border-hover);
|
|
215
218
|
--_button-color: var(--fui-button-neutral-color, var(--fui-text-primary, #{$fui-text-primary}));
|
|
216
|
-
--_button-shadow:
|
|
217
|
-
light-dark(
|
|
218
|
-
color-mix(in srgb, white 72%, transparent),
|
|
219
|
-
color-mix(in srgb, white 5%, transparent)
|
|
220
|
-
);
|
|
219
|
+
--_button-shadow: var(--fui-button-outlined-shadow, #{$fui-button-outlined-shadow});
|
|
221
220
|
--_button-shadow-hover: var(--fui-button-neutral-shadow);
|
|
222
221
|
--_button-shadow-active: var(--fui-button-neutral-shadow-active);
|
|
223
222
|
}
|
|
@@ -129,15 +129,15 @@
|
|
|
129
129
|
margin-bottom: var(--fui-space-2, $fui-space-2);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
// Full-bleed panel-header
|
|
133
|
-
// hairline bottom divider. No trailing margin — it sits flush above the
|
|
132
|
+
// Full-bleed panel-header region with a 40px minimum height, canonical inset,
|
|
133
|
+
// and a hairline bottom divider. No trailing margin — it sits flush above the
|
|
134
134
|
// panel body, which manages its own padding. Use inside `variant="panel"`.
|
|
135
135
|
.headerDivided {
|
|
136
136
|
display: flex;
|
|
137
137
|
align-items: center;
|
|
138
138
|
gap: var(--fui-space-1, $fui-space-1);
|
|
139
139
|
min-height: 2.857rem; // 40px
|
|
140
|
-
padding:
|
|
140
|
+
padding: var(--fui-space-2, $fui-space-2);
|
|
141
141
|
margin-bottom: 0;
|
|
142
142
|
border-bottom: 1px solid var(--fui-border, $fui-border);
|
|
143
143
|
}
|
|
@@ -34,9 +34,9 @@ export interface CardProps extends Omit<React.HTMLAttributes<HTMLElement>, "chil
|
|
|
34
34
|
|
|
35
35
|
export interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
36
36
|
children: React.ReactNode;
|
|
37
|
-
/** Renders the header as a divided
|
|
38
|
-
* hairline bottom border, no trailing margin. Used with
|
|
39
|
-
* for dashboard-style panel headers. */
|
|
37
|
+
/** Renders the header as a divided region with a minimum height, canonical
|
|
38
|
+
* inset, hairline bottom border, and no trailing margin. Used with
|
|
39
|
+
* `variant="panel"` for dashboard-style panel headers. */
|
|
40
40
|
divided?: boolean;
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
@use "../../tokens/mixins" as *;
|
|
3
3
|
|
|
4
4
|
// Local component tokens (code blocks always dark — no light variant).
|
|
5
|
-
//
|
|
5
|
+
// Background and selection stay global so apps can theme CodeBlock and
|
|
6
|
+
// Markdown consistently without replacing either component.
|
|
6
7
|
$fui-code-text: #e2e2e5 !default;
|
|
7
8
|
$fui-code-text-muted: #8a8a9a !default;
|
|
8
9
|
$fui-code-border: rgba(255, 255, 255, 0.06) !default;
|
|
@@ -11,12 +12,6 @@ $fui-code-tab-text-active: #e2e2e5 !default;
|
|
|
11
12
|
$fui-code-copy-bg: rgba(255, 255, 255, 0.06) !default;
|
|
12
13
|
$fui-code-copy-bg-hover: rgba(255, 255, 255, 0.12) !default;
|
|
13
14
|
$fui-code-highlight-bg: rgba(255, 255, 255, 0.06) !default;
|
|
14
|
-
// Selection tint derived from the primary action blue instead of semantic state colors.
|
|
15
|
-
$fui-code-selection-bg: color-mix(
|
|
16
|
-
in srgb,
|
|
17
|
-
var(--fui-button-primary-base, #0a84ff) 30%,
|
|
18
|
-
transparent
|
|
19
|
-
) !default;
|
|
20
15
|
$fui-code-scrollbar-track: transparent !default;
|
|
21
16
|
$fui-code-scrollbar-thumb: rgba(255, 255, 255, 0.1) !default;
|
|
22
17
|
$fui-code-scrollbar-thumb-hover: rgba(255, 255, 255, 0.2) !default;
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
border-color: var(--fui-form-group-border, $fui-border);
|
|
198
198
|
|
|
199
199
|
// Item height derived from text-base font + vertical padding
|
|
200
|
-
--
|
|
200
|
+
--_combobox-item-h: calc(
|
|
201
201
|
var(--fui-font-size-sm, #{$fui-font-size-sm}) *
|
|
202
202
|
var(--fui-line-height-normal, #{$fui-line-height-normal}) +
|
|
203
203
|
var(--fui-space-2, #{$fui-space-2}) * 2
|
|
@@ -207,7 +207,8 @@
|
|
|
207
207
|
// Show N items + half-peek scroll hint (default 4.5 items)
|
|
208
208
|
// !important needed to override Base UI's inline max-height: 100%
|
|
209
209
|
max-height: calc(
|
|
210
|
-
var(--
|
|
210
|
+
var(--_combobox-item-h) * var(--fui-select-max-items, 4.5) +
|
|
211
|
+
var(--fui-space-1, #{$fui-space-1}) * 2
|
|
211
212
|
) !important;
|
|
212
213
|
overflow-y: auto !important;
|
|
213
214
|
|
|
@@ -3,14 +3,7 @@
|
|
|
3
3
|
"name": "DataTable",
|
|
4
4
|
"description": "Data table with sorting, selection, and column management. Powered by TanStack Table.",
|
|
5
5
|
"category": "display",
|
|
6
|
-
"tags": [
|
|
7
|
-
"table",
|
|
8
|
-
"data",
|
|
9
|
-
"grid",
|
|
10
|
-
"list",
|
|
11
|
-
"sorting",
|
|
12
|
-
"tanstack"
|
|
13
|
-
],
|
|
6
|
+
"tags": ["table", "data", "grid", "list", "sorting", "tanstack"],
|
|
14
7
|
"status": "stable",
|
|
15
8
|
"sourcePath": "src/components/DataTable/index.tsx",
|
|
16
9
|
"exportName": "DataTable",
|
|
@@ -26,6 +19,7 @@
|
|
|
26
19
|
"rowSelection: object",
|
|
27
20
|
"onRowSelectionChange: function",
|
|
28
21
|
"onRowClick: function",
|
|
22
|
+
"getRowProps: function",
|
|
29
23
|
"getSubRows: function",
|
|
30
24
|
"expanded: union",
|
|
31
25
|
"onExpandedChange: function",
|
|
@@ -97,6 +91,11 @@
|
|
|
97
91
|
"description": "Handler for row clicks/keyboard activation. Called as (row, event)",
|
|
98
92
|
"required": false
|
|
99
93
|
},
|
|
94
|
+
"getRowProps": {
|
|
95
|
+
"type": "function",
|
|
96
|
+
"description": "Returns row-level HTML, ARIA, data, class, and event props for each rendered data row",
|
|
97
|
+
"required": false
|
|
98
|
+
},
|
|
100
99
|
"getSubRows": {
|
|
101
100
|
"type": "function",
|
|
102
101
|
"description": "Extract sub-rows for expandable tree tables",
|
|
@@ -123,10 +122,7 @@
|
|
|
123
122
|
"description": "Table density",
|
|
124
123
|
"default": "md",
|
|
125
124
|
"required": false,
|
|
126
|
-
"values": [
|
|
127
|
-
"sm",
|
|
128
|
-
"md"
|
|
129
|
-
]
|
|
125
|
+
"values": ["sm", "md"]
|
|
130
126
|
},
|
|
131
127
|
"caption": {
|
|
132
128
|
"type": "string",
|
|
@@ -181,13 +177,15 @@
|
|
|
181
177
|
"Use consistent alignment (numbers right, text left)",
|
|
182
178
|
"Provide meaningful empty states",
|
|
183
179
|
"Consider mobile responsiveness",
|
|
184
|
-
"Use showCheckbox for bulk selection workflows"
|
|
180
|
+
"Use showCheckbox for bulk selection workflows",
|
|
181
|
+
"Use getRowProps to provide an accessible name and intentional semantics for clickable rows"
|
|
185
182
|
],
|
|
186
183
|
"accessibility": [
|
|
187
184
|
"Proper table semantics with headers",
|
|
188
185
|
"Sortable columns are keyboard accessible",
|
|
189
186
|
"Row selection checkboxes include aria-labels",
|
|
190
|
-
"Expand/collapse buttons have aria-expanded state"
|
|
187
|
+
"Expand/collapse buttons have aria-expanded state",
|
|
188
|
+
"Clickable rows expose an accessible action label through getRowProps"
|
|
191
189
|
]
|
|
192
190
|
},
|
|
193
191
|
"examples": [
|
|
@@ -224,7 +222,7 @@
|
|
|
224
222
|
{
|
|
225
223
|
"name": "Clickable Rows",
|
|
226
224
|
"description": "Rows respond to click and keyboard activation",
|
|
227
|
-
"code": "<DataTable\n columns={endpointColumns}\n data={sampleEndpoints}\n onRowClick={(row) => alert(`${row.method} ${row.path}`)}\n size=\"sm\"\n aria-label=\"API endpoints\"\n/>"
|
|
225
|
+
"code": "<DataTable\n columns={endpointColumns}\n data={sampleEndpoints}\n getRowProps={(row) => ({\n role: 'button',\n 'aria-label': `Open ${row.method} ${row.path}`,\n })}\n onRowClick={(row) => alert(`${row.method} ${row.path}`)}\n size=\"sm\"\n aria-label=\"API endpoints\"\n/>"
|
|
228
226
|
},
|
|
229
227
|
{
|
|
230
228
|
"name": "Striped",
|
|
@@ -273,22 +271,17 @@
|
|
|
273
271
|
"showCheckbox: boolean - add checkbox column",
|
|
274
272
|
"getSubRows: (row) => T[] - enable expandable rows",
|
|
275
273
|
"onRowClick: (row, event) => void - row activation handler with event access",
|
|
274
|
+
"getRowProps: (row) => HTMLAttributes<HTMLTableRowElement> - row-level ARIA, role, data, class, and event props",
|
|
276
275
|
"size: sm|md - table density",
|
|
277
276
|
"striped: boolean - alternating row backgrounds",
|
|
278
277
|
"bordered: boolean - bordered container",
|
|
279
278
|
"wrapperClassName / wrapperProps - style and configure the outer wrapper div"
|
|
280
279
|
],
|
|
281
|
-
"a11yRules": [
|
|
282
|
-
"A11Y_TABLE_HEADERS",
|
|
283
|
-
"A11Y_TABLE_SORT"
|
|
284
|
-
]
|
|
280
|
+
"a11yRules": ["A11Y_TABLE_HEADERS", "A11Y_TABLE_SORT"]
|
|
285
281
|
},
|
|
286
282
|
"ai": {
|
|
287
283
|
"compositionPattern": "simple",
|
|
288
|
-
"subComponents": [
|
|
289
|
-
"Root",
|
|
290
|
-
"Columns"
|
|
291
|
-
],
|
|
284
|
+
"subComponents": ["Root", "Columns"],
|
|
292
285
|
"commonPatterns": [
|
|
293
286
|
"<DataTable columns={createColumns([{key:\"name\",header:\"Name\"},{key:\"status\",header:\"Status\"}])} data={[{name:\"Item 1\",status:\"Active\"}]} />"
|
|
294
287
|
]
|
|
@@ -82,6 +82,8 @@ export interface DataTableProps<T> extends Omit<React.HTMLAttributes<HTMLTableEl
|
|
|
82
82
|
onRowSelectionChange?: OnChangeFn<RowSelectionState>;
|
|
83
83
|
/** Row click handler */
|
|
84
84
|
onRowClick?: (row: T, event: DataTableRowClickEvent) => void;
|
|
85
|
+
/** Props applied to each rendered data row. Use this for row-level ARIA labels, roles, and data attributes. */
|
|
86
|
+
getRowProps?: (row: T) => React.HTMLAttributes<HTMLTableRowElement>;
|
|
85
87
|
/** Extract sub-rows from a row for expandable tree tables */
|
|
86
88
|
getSubRows?: (row: T) => T[] | undefined;
|
|
87
89
|
/** Controlled expanded state */
|
|
@@ -143,7 +145,11 @@ function isInteractiveTarget(target: EventTarget | null, currentTarget: HTMLTabl
|
|
|
143
145
|
'button, a, input, select, textarea, [role="button"], [role="link"], [role="checkbox"], [role="switch"]'
|
|
144
146
|
);
|
|
145
147
|
|
|
146
|
-
return Boolean(
|
|
148
|
+
return Boolean(
|
|
149
|
+
interactiveElement &&
|
|
150
|
+
interactiveElement !== currentTarget &&
|
|
151
|
+
currentTarget.contains(interactiveElement)
|
|
152
|
+
);
|
|
147
153
|
}
|
|
148
154
|
|
|
149
155
|
function DataTableRoot<T>({
|
|
@@ -158,6 +164,7 @@ function DataTableRoot<T>({
|
|
|
158
164
|
rowSelection: controlledRowSelection,
|
|
159
165
|
onRowSelectionChange,
|
|
160
166
|
onRowClick,
|
|
167
|
+
getRowProps,
|
|
161
168
|
getSubRows,
|
|
162
169
|
expanded: controlledExpanded,
|
|
163
170
|
onExpandedChange,
|
|
@@ -411,13 +418,25 @@ function DataTableRoot<T>({
|
|
|
411
418
|
const isSelected = selectable ? row.getIsSelected() : false;
|
|
412
419
|
const depth: number = row.depth ?? 0;
|
|
413
420
|
const canExpand = hasSubRows && row.getCanExpand();
|
|
421
|
+
const resolvedRowProps = getRowProps?.(row.original) ?? {};
|
|
422
|
+
const {
|
|
423
|
+
className: rowClassName,
|
|
424
|
+
onClick: rowOnClick,
|
|
425
|
+
onKeyDown: rowOnKeyDown,
|
|
426
|
+
tabIndex: rowTabIndex,
|
|
427
|
+
...rowHtmlProps
|
|
428
|
+
} = resolvedRowProps;
|
|
414
429
|
const handleRowClick = (event: React.MouseEvent<HTMLTableRowElement>) => {
|
|
430
|
+
rowOnClick?.(event);
|
|
431
|
+
if (event.defaultPrevented) return;
|
|
415
432
|
if (!onRowClick) return;
|
|
416
433
|
if (isInteractiveTarget(event.target, event.currentTarget)) return;
|
|
417
434
|
onRowClick(row.original, event);
|
|
418
435
|
};
|
|
419
436
|
|
|
420
437
|
const handleRowKeyDown = (event: React.KeyboardEvent<HTMLTableRowElement>) => {
|
|
438
|
+
rowOnKeyDown?.(event);
|
|
439
|
+
if (event.defaultPrevented) return;
|
|
421
440
|
if (!onRowClick) return;
|
|
422
441
|
if (isInteractiveTarget(event.target, event.currentTarget)) return;
|
|
423
442
|
if (event.key === "Enter" || event.key === " ") {
|
|
@@ -428,18 +447,20 @@ function DataTableRoot<T>({
|
|
|
428
447
|
|
|
429
448
|
return (
|
|
430
449
|
<tr
|
|
450
|
+
{...rowHtmlProps}
|
|
431
451
|
key={row.id}
|
|
432
452
|
className={[
|
|
433
453
|
styles.row,
|
|
434
454
|
isClickable && styles.clickable,
|
|
435
455
|
isSelected && styles.selected,
|
|
436
456
|
depth > 0 && styles.subRow,
|
|
457
|
+
rowClassName,
|
|
437
458
|
]
|
|
438
459
|
.filter(Boolean)
|
|
439
460
|
.join(" ")}
|
|
440
|
-
onClick={isClickable ? handleRowClick : undefined}
|
|
441
|
-
onKeyDown={isClickable ? handleRowKeyDown : undefined}
|
|
442
|
-
tabIndex={isClickable ? 0 : undefined}
|
|
461
|
+
onClick={isClickable || rowOnClick ? handleRowClick : undefined}
|
|
462
|
+
onKeyDown={isClickable || rowOnKeyDown ? handleRowKeyDown : undefined}
|
|
463
|
+
tabIndex={rowTabIndex ?? (isClickable ? 0 : undefined)}
|
|
443
464
|
data-selected={isSelected || undefined}
|
|
444
465
|
data-depth={depth > 0 ? depth : undefined}
|
|
445
466
|
>
|