@astryxdesign/core 0.1.7 → 0.1.8-canary.c5fa19b
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/CHANGELOG.md +65 -0
- package/README.md +30 -19
- package/dist/Avatar/Avatar.d.ts +10 -5
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +12 -8
- package/dist/Avatar/AvatarSizeContext.d.ts +1 -1
- package/dist/Avatar/AvatarSizeContext.js +1 -1
- package/dist/Avatar/AvatarStatusDot.d.ts +2 -2
- package/dist/Avatar/AvatarStatusDot.js +2 -2
- package/dist/AvatarGroup/AvatarGroup.d.ts +2 -2
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroup.js +2 -2
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +16 -14
- package/dist/Carousel/Carousel.d.ts +3 -2
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +32 -2
- package/dist/Chat/ChatMessage.d.ts +1 -1
- package/dist/Chat/ChatMessage.d.ts.map +1 -1
- package/dist/Chat/ChatMessage.js +1 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +10 -4
- package/dist/Collapsible/Collapsible.d.ts +11 -1
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +36 -4
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +4 -3
- package/dist/ContextMenu/index.d.ts +3 -0
- package/dist/ContextMenu/index.d.ts.map +1 -1
- package/dist/ContextMenu/index.js +7 -1
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +8 -4
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +89 -0
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -0
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +170 -0
- package/dist/DropdownMenu/DropdownMenuContext.d.ts +17 -1
- package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuContext.js +18 -0
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +69 -0
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -0
- package/dist/DropdownMenu/DropdownMenuRadioGroup.js +70 -0
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +69 -0
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -0
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +178 -0
- package/dist/DropdownMenu/index.d.ts +5 -1
- package/dist/DropdownMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/index.js +10 -1
- package/dist/DropdownMenu/menuItemRoles.d.ts +13 -0
- package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -0
- package/dist/DropdownMenu/menuItemRoles.js +15 -0
- package/dist/Icon/Icon.d.ts +43 -13
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +62 -27
- package/dist/Outline/Outline.d.ts +69 -3
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +129 -26
- package/dist/Outline/useScrollSpy.d.ts +27 -7
- package/dist/Outline/useScrollSpy.d.ts.map +1 -1
- package/dist/Outline/useScrollSpy.js +202 -70
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +2 -2
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +2 -0
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +1 -1
- package/dist/Table/Table.d.ts +1 -1
- package/dist/Table/Table.js +1 -1
- package/dist/Table/index.d.ts +2 -0
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +1 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +24 -2
- package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +18 -7
- package/dist/Table/plugins/tree/index.d.ts +5 -0
- package/dist/Table/plugins/tree/index.d.ts.map +1 -0
- package/dist/Table/plugins/tree/index.js +4 -0
- package/dist/Table/plugins/tree/useTableTreeData.d.ts +38 -0
- package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -0
- package/dist/Table/plugins/tree/useTableTreeData.js +358 -0
- package/dist/Table/plugins/tree/useTableTreeState.d.ts +51 -0
- package/dist/Table/plugins/tree/useTableTreeState.d.ts.map +1 -0
- package/dist/Table/plugins/tree/useTableTreeState.js +175 -0
- package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +6 -3
- package/dist/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar/Toolbar.js +8 -1
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +5 -14
- package/dist/astryx.css +24 -4
- package/dist/astryx.umd.js +54 -54
- package/dist/astryx.umd.js.map +4 -4
- package/dist/theme/Theme.js +1 -1
- package/dist/theme/defineTheme.d.ts +1 -1
- package/dist/theme/defineTheme.js +1 -1
- package/dist/theme/hct.d.ts +0 -1
- package/dist/theme/hct.d.ts.map +1 -1
- package/dist/theme/hct.js +0 -3
- package/docs.mjs +32 -461
- package/locales/en.json +200 -172
- package/locales/pseudo.json +21 -0
- package/package.json +3 -1
- package/scripts/postinstall.mjs +93 -0
- package/src/Avatar/Avatar.doc.mjs +6 -6
- package/src/Avatar/Avatar.tsx +16 -11
- package/src/Avatar/AvatarSizeContext.ts +1 -1
- package/src/Avatar/AvatarStatusDot.tsx +2 -2
- package/src/AvatarGroup/AvatarGroup.doc.mjs +1 -1
- package/src/AvatarGroup/AvatarGroup.test.tsx +17 -3
- package/src/AvatarGroup/AvatarGroup.tsx +3 -3
- package/src/AvatarGroup/AvatarGroupOverflow.doc.mjs +4 -4
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +21 -5
- package/src/Carousel/Carousel.doc.mjs +1 -0
- package/src/Carousel/Carousel.test.tsx +96 -1
- package/src/Carousel/Carousel.tsx +29 -2
- package/src/Chat/Chat.doc.mjs +1 -1
- package/src/Chat/ChatMessage.tsx +4 -2
- package/src/CheckboxInput/CheckboxInput.doc.mjs +1 -1
- package/src/Citation/Citation.test.tsx +51 -0
- package/src/Citation/Citation.tsx +8 -2
- package/src/Collapsible/Collapsible.doc.mjs +7 -0
- package/src/Collapsible/Collapsible.test.tsx +80 -0
- package/src/Collapsible/Collapsible.tsx +58 -5
- package/src/ContextMenu/ContextMenu.test.tsx +75 -1
- package/src/ContextMenu/ContextMenu.tsx +10 -5
- package/src/ContextMenu/index.ts +15 -0
- package/src/DropdownMenu/DropdownMenu.doc.mjs +23 -0
- package/src/DropdownMenu/DropdownMenu.tsx +11 -6
- package/src/DropdownMenu/DropdownMenuCheckboxItem.doc.mjs +95 -0
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +237 -0
- package/src/DropdownMenu/DropdownMenuContext.tsx +29 -1
- package/src/DropdownMenu/DropdownMenuItem.doc.mjs +7 -1
- package/src/DropdownMenu/DropdownMenuRadioGroup.doc.mjs +80 -0
- package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +119 -0
- package/src/DropdownMenu/DropdownMenuRadioItem.doc.mjs +80 -0
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +232 -0
- package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +163 -0
- package/src/DropdownMenu/index.ts +23 -3
- package/src/DropdownMenu/menuItemRoles.ts +22 -0
- package/src/Field/Field.doc.mjs +1 -1
- package/src/Field/FieldLabel.doc.mjs +1 -1
- package/src/Icon/Icon.doc.mjs +12 -0
- package/src/Icon/Icon.test.tsx +142 -0
- package/src/Icon/Icon.tsx +98 -30
- package/src/Item/Item.doc.mjs +1 -1
- package/src/NumberInput/NumberInput.doc.mjs +2 -2
- package/src/Outline/Outline.doc.mjs +123 -3
- package/src/Outline/Outline.test.tsx +735 -0
- package/src/Outline/Outline.tsx +184 -33
- package/src/Outline/useScrollSpy.ts +248 -72
- package/src/Selector/SelectorOption.doc.mjs +1 -1
- package/src/SideNav/SideNavItem.doc.mjs +2 -2
- package/src/Switch/Switch.doc.mjs +1 -1
- package/src/TabList/Tab.tsx +5 -1
- package/src/TabList/TabList.doc.mjs +3 -3
- package/src/TabList/TabList.test.tsx +66 -0
- package/src/TabList/TabList.tsx +8 -0
- package/src/TabList/TabMenu.tsx +4 -1
- package/src/Table/Table.doc.mjs +2 -0
- package/src/Table/Table.tsx +1 -1
- package/src/Table/index.ts +7 -0
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +90 -1
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +37 -5
- package/src/Table/plugins/sortable/useTableSortable.test.tsx +95 -9
- package/src/Table/plugins/sortable/useTableSortable.tsx +23 -7
- package/src/Table/plugins/tree/index.ts +12 -0
- package/src/Table/plugins/tree/useTableTreeData-perf.test.tsx +163 -0
- package/src/Table/plugins/tree/useTableTreeData.test.tsx +594 -0
- package/src/Table/plugins/tree/useTableTreeData.tsx +495 -0
- package/src/Table/plugins/tree/useTableTreeState.test.tsx +636 -0
- package/src/Table/plugins/tree/useTableTreeState.tsx +253 -0
- package/src/Table/useBaseTablePlugins.ts +6 -2
- package/src/Table/useTableTreeData.doc.mjs +75 -0
- package/src/Table/useTableTreeState.doc.mjs +98 -0
- package/src/TextArea/TextArea.doc.mjs +1 -1
- package/src/TextInput/TextInput.doc.mjs +1 -1
- package/src/Toolbar/Toolbar.tsx +10 -3
- package/src/TreeList/TreeList.test.tsx +32 -1
- package/src/TreeList/TreeListItem.tsx +19 -10
- package/src/docs-script.test.mjs +18 -13
- package/src/postinstall.test.mjs +71 -0
- package/src/theme/Theme.doc.mjs +4 -4
- package/src/theme/Theme.tsx +1 -1
- package/src/theme/defineTheme.ts +1 -1
- package/src/theme/hct.ts +0 -4
- package/dist/TreeList/treeListItem.markers.stylex.d.ts +0 -16
- package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +0 -1
- package/dist/TreeList/treeListItem.markers.stylex.js +0 -22
- package/src/TreeList/treeListItem.markers.stylex.ts +0 -20
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file DropdownMenuRadioGroup.tsx
|
|
7
|
+
* @output DropdownMenuRadioGroup — a single-select group of menu items.
|
|
8
|
+
* @position Sub-component; wraps DropdownMenuRadioItem inside a DropdownMenu.
|
|
9
|
+
*
|
|
10
|
+
* Owns single-selection state (value/onChange) for its child
|
|
11
|
+
* DropdownMenuRadioItems and exposes it via context. Renders role="group" with
|
|
12
|
+
* an accessible name so the radios are announced as a set. Keyboard navigation
|
|
13
|
+
* comes from the parent DropdownMenu's useListFocus, which matches
|
|
14
|
+
* menuitemradio rows.
|
|
15
|
+
*/
|
|
16
|
+
import { useMemo } from 'react';
|
|
17
|
+
import * as stylex from '@stylexjs/stylex';
|
|
18
|
+
import "../theme/tokens.stylex.js";
|
|
19
|
+
import { spacingVars } from "../theme/tokens.stylex.js";
|
|
20
|
+
import { mergeProps } from "../utils/index.js";
|
|
21
|
+
import { DropdownMenuRadioGroupContext } from "./DropdownMenuContext.js";
|
|
22
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
23
|
+
/**
|
|
24
|
+
* A single-select group of radio menu items (role="group" of menuitemradio).
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```
|
|
28
|
+
* * import {
|
|
29
|
+
* DropdownMenuRadioGroup,
|
|
30
|
+
* DropdownMenuRadioItem,
|
|
31
|
+
* } from '@astryxdesign/core/DropdownMenu';
|
|
32
|
+
*
|
|
33
|
+
* <DropdownMenu button={{label: 'Sort'}}>
|
|
34
|
+
* <DropdownMenuRadioGroup value={sort} onChange={setSort} aria-label="Sort by">
|
|
35
|
+
* <DropdownMenuRadioItem value="newest" label="Newest" />
|
|
36
|
+
* <DropdownMenuRadioItem value="oldest" label="Oldest" />
|
|
37
|
+
* </DropdownMenuRadioGroup>
|
|
38
|
+
* </DropdownMenu>
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function DropdownMenuRadioGroup({
|
|
42
|
+
value,
|
|
43
|
+
onChange,
|
|
44
|
+
hasCloseOnSelect = true,
|
|
45
|
+
children,
|
|
46
|
+
className,
|
|
47
|
+
style,
|
|
48
|
+
...rest
|
|
49
|
+
}) {
|
|
50
|
+
const contextValue = useMemo(() => ({
|
|
51
|
+
value,
|
|
52
|
+
onChange,
|
|
53
|
+
hasCloseOnSelect
|
|
54
|
+
}), [value, onChange, hasCloseOnSelect]);
|
|
55
|
+
return /*#__PURE__*/_jsx("div", {
|
|
56
|
+
...rest,
|
|
57
|
+
role: "group",
|
|
58
|
+
...mergeProps({
|
|
59
|
+
className: "x78zum5 xdt5ytf x1lsbc85"
|
|
60
|
+
}, {
|
|
61
|
+
className,
|
|
62
|
+
style
|
|
63
|
+
}),
|
|
64
|
+
children: /*#__PURE__*/_jsx(DropdownMenuRadioGroupContext, {
|
|
65
|
+
value: contextValue,
|
|
66
|
+
children: children
|
|
67
|
+
})
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
DropdownMenuRadioGroup.displayName = 'DropdownMenuRadioGroup';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file DropdownMenuRadioItem.tsx
|
|
3
|
+
* @input React, stylex, Item + Icon + DropdownMenu context + tokens from core
|
|
4
|
+
* @output DropdownMenuRadioItem — a single option in a radio group.
|
|
5
|
+
* @position Sub-component; must be used inside a DropdownMenuRadioGroup.
|
|
6
|
+
*
|
|
7
|
+
* A menu item representing one option in a single-select group
|
|
8
|
+
* (role="menuitemradio"). The row owns the role and aria-checked; there is no
|
|
9
|
+
* nested native <input> (per the WAI-ARIA menuitemradio pattern). Selection
|
|
10
|
+
* state + onChange come from DropdownMenuRadioGroupContext. Keyboard nav +
|
|
11
|
+
* Enter/Space activation come from the parent DropdownMenu.
|
|
12
|
+
*
|
|
13
|
+
* The round radio visual (circle + center dot) is decorative (aria-hidden) —
|
|
14
|
+
* the row owns the checked state. Its size is derived from the menu's item size
|
|
15
|
+
* and it swaps to the inline-end of the row on coarse-pointer (touch) devices
|
|
16
|
+
* via CSS `order`. The dot is a shaped element, not an icon (a filled circle
|
|
17
|
+
* has no registry glyph).
|
|
18
|
+
*/
|
|
19
|
+
import { type ReactNode } from 'react';
|
|
20
|
+
import { type IconType } from '../Icon';
|
|
21
|
+
import type { BaseProps } from '../BaseProps';
|
|
22
|
+
export interface DropdownMenuRadioItemProps extends Omit<BaseProps, 'role' | 'aria-checked' | 'tabIndex'> {
|
|
23
|
+
/**
|
|
24
|
+
* The value this item represents within its group. The group's `value`
|
|
25
|
+
* matches against this to determine the checked state.
|
|
26
|
+
*/
|
|
27
|
+
value: string;
|
|
28
|
+
/**
|
|
29
|
+
* Primary label text identifying the option.
|
|
30
|
+
*/
|
|
31
|
+
label: ReactNode;
|
|
32
|
+
/**
|
|
33
|
+
* Secondary description text displayed below the label.
|
|
34
|
+
*/
|
|
35
|
+
description?: ReactNode;
|
|
36
|
+
/**
|
|
37
|
+
* Icon to display before the label. Accepts a semantic icon name (see
|
|
38
|
+
* `npx astryx docs icons`) or a rendered node.
|
|
39
|
+
*/
|
|
40
|
+
icon?: ReactNode | IconType;
|
|
41
|
+
/**
|
|
42
|
+
* Whether this individual radio item is disabled. Disabled items stay
|
|
43
|
+
* focusable (via `aria-disabled`) so they remain discoverable by keyboard
|
|
44
|
+
* and assistive technology, but selection is blocked.
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
isDisabled?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Content to render after the label and description, such as a badge or
|
|
50
|
+
* metadata.
|
|
51
|
+
*/
|
|
52
|
+
endContent?: ReactNode;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A single option in a DropdownMenuRadioGroup (role="menuitemradio").
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```
|
|
59
|
+
* <DropdownMenuRadioGroup value={sort} onChange={setSort} aria-label="Sort by">
|
|
60
|
+
* <DropdownMenuRadioItem value="newest" label="Newest" />
|
|
61
|
+
* <DropdownMenuRadioItem value="oldest" label="Oldest" icon="clock" />
|
|
62
|
+
* </DropdownMenuRadioGroup>
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare function DropdownMenuRadioItem({ value, label, description, icon, isDisabled, endContent, xstyle, className, style, ...rest }: DropdownMenuRadioItemProps): import("react").JSX.Element;
|
|
66
|
+
export declare namespace DropdownMenuRadioItem {
|
|
67
|
+
var displayName: string;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=DropdownMenuRadioItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DropdownMenuRadioItem.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuRadioItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAc,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAElD,OAAO,EAAiB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAWtD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAsE5C,MAAM,WAAW,0BAA2B,SAAQ,IAAI,CACtD,SAAS,EACT,MAAM,GAAG,cAAc,GAAG,UAAU,CACrC;IACC;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IACjB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,KAAK,EACL,WAAW,EACX,IAAI,EACJ,UAAkB,EAClB,UAAU,EACV,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EACR,EAAE,0BAA0B,+BAiE5B;yBA5Ee,qBAAqB"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file DropdownMenuRadioItem.tsx
|
|
7
|
+
* @input React, stylex, Item + Icon + DropdownMenu context + tokens from core
|
|
8
|
+
* @output DropdownMenuRadioItem — a single option in a radio group.
|
|
9
|
+
* @position Sub-component; must be used inside a DropdownMenuRadioGroup.
|
|
10
|
+
*
|
|
11
|
+
* A menu item representing one option in a single-select group
|
|
12
|
+
* (role="menuitemradio"). The row owns the role and aria-checked; there is no
|
|
13
|
+
* nested native <input> (per the WAI-ARIA menuitemradio pattern). Selection
|
|
14
|
+
* state + onChange come from DropdownMenuRadioGroupContext. Keyboard nav +
|
|
15
|
+
* Enter/Space activation come from the parent DropdownMenu.
|
|
16
|
+
*
|
|
17
|
+
* The round radio visual (circle + center dot) is decorative (aria-hidden) —
|
|
18
|
+
* the row owns the checked state. Its size is derived from the menu's item size
|
|
19
|
+
* and it swaps to the inline-end of the row on coarse-pointer (touch) devices
|
|
20
|
+
* via CSS `order`. The dot is a shaped element, not an icon (a filled circle
|
|
21
|
+
* has no registry glyph).
|
|
22
|
+
*/
|
|
23
|
+
import { useCallback } from 'react';
|
|
24
|
+
import * as stylex from '@stylexjs/stylex';
|
|
25
|
+
import { renderIconSlot } from "../Icon/index.js";
|
|
26
|
+
import { Item } from "../Item/index.js";
|
|
27
|
+
import { useDropdownMenuContext } from "./DropdownMenuContext.js";
|
|
28
|
+
import "../theme/tokens.stylex.js";
|
|
29
|
+
import { colorVars, spacingVars, durationVars, easeVars, borderVars } from "../theme/tokens.stylex.js";
|
|
30
|
+
import { mergeProps, themeProps } from "../utils/index.js";
|
|
31
|
+
import { useDropdownMenuRadioGroupContext } from "./DropdownMenuContext.js";
|
|
32
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
33
|
+
const styles = {
|
|
34
|
+
root: {
|
|
35
|
+
kzqmXN: "xh8yej3",
|
|
36
|
+
kaIpWk: "x1ws5lxm",
|
|
37
|
+
kMwMTN: "x1tgivj0",
|
|
38
|
+
kWkggS: "xjbqb8w x1c52tdz x1uwx2nv",
|
|
39
|
+
kkrTdU: "x1ypdohk",
|
|
40
|
+
kI3sdo: "x1a2a7pz",
|
|
41
|
+
$$css: true
|
|
42
|
+
},
|
|
43
|
+
disabled: {
|
|
44
|
+
kSiTet: "xbyyjgo",
|
|
45
|
+
kkrTdU: "x1h6gzvc",
|
|
46
|
+
$$css: true
|
|
47
|
+
},
|
|
48
|
+
circle: {
|
|
49
|
+
k1xSpc: "x78zum5",
|
|
50
|
+
kGNEyG: "x6s0dn4",
|
|
51
|
+
kjj79g: "xl56j7k",
|
|
52
|
+
kmuXW: "x2lah0s",
|
|
53
|
+
kB7OPa: "x9f619",
|
|
54
|
+
kMzoRj: "x1litavf",
|
|
55
|
+
ksu8eU: "x1y0btm7",
|
|
56
|
+
kaIpWk: "x16rqkct",
|
|
57
|
+
k1ekBW: "xts7igz",
|
|
58
|
+
kIyJzY: "xuedmi6 x12w9bfk",
|
|
59
|
+
kAMwcw: "xlr8y92",
|
|
60
|
+
kayTVb: "x1g77sc7 xozvky",
|
|
61
|
+
keTefX: "x1lziwak x1jymrmb",
|
|
62
|
+
$$css: true
|
|
63
|
+
},
|
|
64
|
+
unchecked: {
|
|
65
|
+
kVAM5u: "xvy26l8",
|
|
66
|
+
kWkggS: "x10xzikg",
|
|
67
|
+
$$css: true
|
|
68
|
+
},
|
|
69
|
+
checked: {
|
|
70
|
+
kVAM5u: "xad5do",
|
|
71
|
+
kWkggS: "x1ewilqj",
|
|
72
|
+
$$css: true
|
|
73
|
+
},
|
|
74
|
+
dot: {
|
|
75
|
+
kaIpWk: "x16rqkct",
|
|
76
|
+
kWkggS: "x1azo05",
|
|
77
|
+
$$css: true
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const circleSizeStyles = {
|
|
81
|
+
sm: {
|
|
82
|
+
kzqmXN: "x1xp8n7a",
|
|
83
|
+
kZKoxP: "xmix8c7",
|
|
84
|
+
$$css: true
|
|
85
|
+
},
|
|
86
|
+
md: {
|
|
87
|
+
kzqmXN: "x17z2i9w",
|
|
88
|
+
kZKoxP: "x17rw0jw",
|
|
89
|
+
$$css: true
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const dotSizeStyles = {
|
|
93
|
+
sm: {
|
|
94
|
+
kzqmXN: "x1v4s8kt",
|
|
95
|
+
kZKoxP: "xols6we",
|
|
96
|
+
$$css: true
|
|
97
|
+
},
|
|
98
|
+
md: {
|
|
99
|
+
kzqmXN: "x1xc55vz",
|
|
100
|
+
kZKoxP: "xdk7pt",
|
|
101
|
+
$$css: true
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* A single option in a DropdownMenuRadioGroup (role="menuitemradio").
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```
|
|
109
|
+
* <DropdownMenuRadioGroup value={sort} onChange={setSort} aria-label="Sort by">
|
|
110
|
+
* <DropdownMenuRadioItem value="newest" label="Newest" />
|
|
111
|
+
* <DropdownMenuRadioItem value="oldest" label="Oldest" icon="clock" />
|
|
112
|
+
* </DropdownMenuRadioGroup>
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export function DropdownMenuRadioItem({
|
|
116
|
+
value,
|
|
117
|
+
label,
|
|
118
|
+
description,
|
|
119
|
+
icon,
|
|
120
|
+
isDisabled = false,
|
|
121
|
+
endContent,
|
|
122
|
+
xstyle,
|
|
123
|
+
className,
|
|
124
|
+
style,
|
|
125
|
+
...rest
|
|
126
|
+
}) {
|
|
127
|
+
const menuCtx = useDropdownMenuContext();
|
|
128
|
+
const groupCtx = useDropdownMenuRadioGroupContext();
|
|
129
|
+
if (!groupCtx) {
|
|
130
|
+
throw new Error('DropdownMenuRadioItem must be used within a DropdownMenuRadioGroup');
|
|
131
|
+
}
|
|
132
|
+
const menuSize = menuCtx?.menuSize ?? 'md';
|
|
133
|
+
const controlSize = menuSize === 'sm' ? 'sm' : 'md';
|
|
134
|
+
const isChecked = groupCtx.value === value;
|
|
135
|
+
const handleClick = useCallback(() => {
|
|
136
|
+
if (isDisabled) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
groupCtx.onChange(value);
|
|
140
|
+
if (groupCtx.hasCloseOnSelect) {
|
|
141
|
+
menuCtx?.closeMenu();
|
|
142
|
+
}
|
|
143
|
+
}, [isDisabled, groupCtx, value, menuCtx]);
|
|
144
|
+
return /*#__PURE__*/_jsx(Item, {
|
|
145
|
+
...rest,
|
|
146
|
+
role: "menuitemradio",
|
|
147
|
+
"aria-checked": isChecked,
|
|
148
|
+
tabIndex: isDisabled ? undefined : -1,
|
|
149
|
+
marker: /*#__PURE__*/_jsx("span", {
|
|
150
|
+
"aria-hidden": "true",
|
|
151
|
+
...mergeProps(themeProps('dropdown-menu-radio', {
|
|
152
|
+
size: controlSize,
|
|
153
|
+
checked: isChecked ? 'checked' : null,
|
|
154
|
+
disabled: isDisabled ? 'disabled' : null
|
|
155
|
+
}), stylex.props(styles.circle, circleSizeStyles[controlSize], isChecked ? styles.checked : styles.unchecked)),
|
|
156
|
+
children: isChecked && /*#__PURE__*/_jsx("span", {
|
|
157
|
+
...stylex.props(styles.dot, dotSizeStyles[controlSize])
|
|
158
|
+
})
|
|
159
|
+
}),
|
|
160
|
+
startContent: icon ? renderIconSlot(icon, {
|
|
161
|
+
size: 'sm',
|
|
162
|
+
color: 'secondary'
|
|
163
|
+
}) : undefined,
|
|
164
|
+
label: label,
|
|
165
|
+
description: description,
|
|
166
|
+
endContent: endContent,
|
|
167
|
+
onClick: handleClick,
|
|
168
|
+
isDisabled: isDisabled,
|
|
169
|
+
xstyle: [styles.root, isDisabled && styles.disabled, xstyle],
|
|
170
|
+
...mergeProps(themeProps('dropdown-menu-item', {
|
|
171
|
+
size: menuSize
|
|
172
|
+
}), {
|
|
173
|
+
className,
|
|
174
|
+
style
|
|
175
|
+
})
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
DropdownMenuRadioItem.displayName = 'DropdownMenuRadioItem';
|
|
@@ -4,5 +4,9 @@
|
|
|
4
4
|
* @position Public API entry point
|
|
5
5
|
*/
|
|
6
6
|
export { DropdownMenu, type DropdownMenuProps, type DropdownMenuButtonProps, type DropdownMenuItemData, type DropdownMenuDivider, type DropdownMenuSection, type DropdownMenuOption, } from './DropdownMenu';
|
|
7
|
-
export { DropdownMenuItem, type DropdownMenuItemProps
|
|
7
|
+
export { DropdownMenuItem, type DropdownMenuItemProps } from './DropdownMenuItem';
|
|
8
|
+
export { DropdownMenuCheckboxItem, type DropdownMenuCheckboxItemProps, } from './DropdownMenuCheckboxItem';
|
|
9
|
+
export { DropdownMenuRadioGroup, type DropdownMenuRadioGroupProps, } from './DropdownMenuRadioGroup';
|
|
10
|
+
export { DropdownMenuRadioItem, type DropdownMenuRadioItemProps, } from './DropdownMenuRadioItem';
|
|
11
|
+
export { DropdownMenuContext, useDropdownMenuContext, type DropdownMenuContextValue, type DropdownMenuSize, } from './DropdownMenuContext';
|
|
8
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/index.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/index.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAC,gBAAgB,EAAE,KAAK,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AAGhF,OAAO,EACL,wBAAwB,EACxB,KAAK,6BAA6B,GACnC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,sBAAsB,EACtB,KAAK,2BAA2B,GACjC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,GAChC,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC"}
|
|
@@ -8,4 +8,13 @@
|
|
|
8
8
|
* @position Public API entry point
|
|
9
9
|
*/
|
|
10
10
|
export { DropdownMenu } from "./DropdownMenu.js";
|
|
11
|
-
export { DropdownMenuItem } from "./DropdownMenuItem.js";
|
|
11
|
+
export { DropdownMenuItem } from "./DropdownMenuItem.js";
|
|
12
|
+
|
|
13
|
+
// Selectable items — checkbox (independent) and radio (single-select group).
|
|
14
|
+
export { DropdownMenuCheckboxItem } from "./DropdownMenuCheckboxItem.js";
|
|
15
|
+
export { DropdownMenuRadioGroup } from "./DropdownMenuRadioGroup.js";
|
|
16
|
+
export { DropdownMenuRadioItem } from "./DropdownMenuRadioItem.js";
|
|
17
|
+
|
|
18
|
+
// Menu-coordination context — public so consumers can build custom menu items
|
|
19
|
+
// that read the menu size / close the menu.
|
|
20
|
+
export { DropdownMenuContext, useDropdownMenuContext } from "./DropdownMenuContext.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file menuItemRoles.ts
|
|
3
|
+
* @output Shared menu-item role set + focus selector.
|
|
4
|
+
* @position Internal; used by DropdownMenu and ContextMenu so their
|
|
5
|
+
* roving-focus, typeahead, and Enter/Space activation stay in sync.
|
|
6
|
+
*
|
|
7
|
+
* Includes the selectable items (menuitemradio/menuitemcheckbox) alongside
|
|
8
|
+
* plain menuitem so checkbox/radio rows are reachable by arrow keys, typeahead,
|
|
9
|
+
* and Enter/Space — not just role="menuitem".
|
|
10
|
+
*/
|
|
11
|
+
export declare const MENU_ITEM_ROLES: ReadonlySet<string>;
|
|
12
|
+
export declare const MENU_ITEM_SELECTOR: string;
|
|
13
|
+
//# sourceMappingURL=menuItemRoles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menuItemRoles.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/menuItemRoles.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAI9C,CAAC;AAEH,eAAO,MAAM,kBAAkB,EAAE,MAErB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file menuItemRoles.ts
|
|
5
|
+
* @output Shared menu-item role set + focus selector.
|
|
6
|
+
* @position Internal; used by DropdownMenu and ContextMenu so their
|
|
7
|
+
* roving-focus, typeahead, and Enter/Space activation stay in sync.
|
|
8
|
+
*
|
|
9
|
+
* Includes the selectable items (menuitemradio/menuitemcheckbox) alongside
|
|
10
|
+
* plain menuitem so checkbox/radio rows are reachable by arrow keys, typeahead,
|
|
11
|
+
* and Enter/Space — not just role="menuitem".
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export const MENU_ITEM_ROLES = new Set(['menuitem', 'menuitemradio', 'menuitemcheckbox']);
|
|
15
|
+
export const MENU_ITEM_SELECTOR = [...MENU_ITEM_ROLES].map(role => `[role="${role}"]:not([aria-disabled="true"])`).join(',');
|
package/dist/Icon/Icon.d.ts
CHANGED
|
@@ -82,23 +82,28 @@ declare const colorStyles: Readonly<{
|
|
|
82
82
|
/**
|
|
83
83
|
* Size styles for direct SVG icon components.
|
|
84
84
|
* Uses width/height only — SVG components handle their own viewBox scaling.
|
|
85
|
+
*
|
|
86
|
+
* Sizes are expressed in `rem` (relative to the root font-size) so icons scale
|
|
87
|
+
* in step with text when the document font-size changes, matching the rest of
|
|
88
|
+
* the design system's rem-based type scale. Values are the px-equivalents at a
|
|
89
|
+
* 16px root: 12px → 0.75rem, 16px → 1rem, 20px → 1.25rem, 24px → 1.5rem.
|
|
85
90
|
*/
|
|
86
91
|
declare const sizeStyles: Readonly<{
|
|
87
92
|
readonly xsm: Readonly<{
|
|
88
|
-
readonly width: stylex.StyleXClassNameFor<"width",
|
|
89
|
-
readonly height: stylex.StyleXClassNameFor<"height",
|
|
93
|
+
readonly width: stylex.StyleXClassNameFor<"width", "0.75rem">;
|
|
94
|
+
readonly height: stylex.StyleXClassNameFor<"height", "0.75rem">;
|
|
90
95
|
}>;
|
|
91
96
|
readonly sm: Readonly<{
|
|
92
|
-
readonly width: stylex.StyleXClassNameFor<"width",
|
|
93
|
-
readonly height: stylex.StyleXClassNameFor<"height",
|
|
97
|
+
readonly width: stylex.StyleXClassNameFor<"width", "1rem">;
|
|
98
|
+
readonly height: stylex.StyleXClassNameFor<"height", "1rem">;
|
|
94
99
|
}>;
|
|
95
100
|
readonly md: Readonly<{
|
|
96
|
-
readonly width: stylex.StyleXClassNameFor<"width",
|
|
97
|
-
readonly height: stylex.StyleXClassNameFor<"height",
|
|
101
|
+
readonly width: stylex.StyleXClassNameFor<"width", "1.25rem">;
|
|
102
|
+
readonly height: stylex.StyleXClassNameFor<"height", "1.25rem">;
|
|
98
103
|
}>;
|
|
99
104
|
readonly lg: Readonly<{
|
|
100
|
-
readonly width: stylex.StyleXClassNameFor<"width",
|
|
101
|
-
readonly height: stylex.StyleXClassNameFor<"height",
|
|
105
|
+
readonly width: stylex.StyleXClassNameFor<"width", "1.5rem">;
|
|
106
|
+
readonly height: stylex.StyleXClassNameFor<"height", "1.5rem">;
|
|
102
107
|
}>;
|
|
103
108
|
}>;
|
|
104
109
|
export type IconColor = keyof typeof colorStyles;
|
|
@@ -128,13 +133,38 @@ export interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'ref' | 'color'
|
|
|
128
133
|
color?: IconColor;
|
|
129
134
|
/**
|
|
130
135
|
* The size of the icon.
|
|
131
|
-
* - 'xsm': 12px
|
|
132
|
-
* - 'sm': 16px
|
|
133
|
-
* - 'md': 20px
|
|
134
|
-
* - 'lg': 24px
|
|
136
|
+
* - 'xsm': 0.75rem (12px at a 16px root)
|
|
137
|
+
* - 'sm': 1rem (16px at a 16px root)
|
|
138
|
+
* - 'md': 1.25rem (20px at a 16px root)
|
|
139
|
+
* - 'lg': 1.5rem (24px at a 16px root)
|
|
135
140
|
* @default 'md'
|
|
136
141
|
*/
|
|
137
142
|
size?: IconSize;
|
|
143
|
+
/**
|
|
144
|
+
* Accessible name for the icon. Set this only when the icon is MEANINGFUL on
|
|
145
|
+
* its own — a standalone status glyph or an icon-only indicator with no
|
|
146
|
+
* adjacent text conveying the same information. Providing it exposes the icon
|
|
147
|
+
* to assistive tech as `role="img"` with this string as the accessible name
|
|
148
|
+
* (via `aria-label`) and drops the default `aria-hidden="true"`.
|
|
149
|
+
*
|
|
150
|
+
* Omit it (the default) for decorative icons — the common case, e.g. an icon
|
|
151
|
+
* beside a text label — and the icon stays hidden from assistive tech
|
|
152
|
+
* (`aria-hidden="true"`). An empty string (`''`) is treated the same as
|
|
153
|
+
* omitting it (decorative), since an empty accessible name is meaningless.
|
|
154
|
+
*
|
|
155
|
+
* Don't set `label` when an interactive parent (Button, IconButton, link)
|
|
156
|
+
* already names the control — that produces a duplicate announcement.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```
|
|
160
|
+
* // Meaningful, standalone icon
|
|
161
|
+
* <Icon icon="success" label="Completed" />
|
|
162
|
+
*
|
|
163
|
+
* // Decorative icon (default) — omit label
|
|
164
|
+
* <Icon icon="search" />
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
label?: string;
|
|
138
168
|
}
|
|
139
169
|
/**
|
|
140
170
|
* Renders an icon from the icon registry or a custom SVG component.
|
|
@@ -144,7 +174,7 @@ export interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'ref' | 'color'
|
|
|
144
174
|
* <Icon icon="close" size="md" color="primary" />
|
|
145
175
|
* ```
|
|
146
176
|
*/
|
|
147
|
-
export declare function Icon({ icon, color, size, ref, ...props }: IconProps): React.JSX.Element;
|
|
177
|
+
export declare function Icon({ icon, color, size, label, ref, ...props }: IconProps): React.JSX.Element;
|
|
148
178
|
export declare namespace Icon {
|
|
149
179
|
var displayName: string;
|
|
150
180
|
}
|
package/dist/Icon/Icon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../src/Icon/Icon.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC/D,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAG3C,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAqBnD,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2Df,CAAC;AAEH
|
|
1
|
+
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../src/Icon/Icon.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC/D,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAG3C,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAqBnD,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2Df,CAAC;AAEH;;;;;;;;GAQG;AACH,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;EAiBd,CAAC;AAyCH,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAC;AACjD,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,UAAU,CAAC;AAE/C;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;AAE9D;;;GAGG;AACH,MAAM,WAAW,SAAU,SAAQ,IAAI,CACrC,QAAQ,CAAC,aAAa,CAAC,EACvB,KAAK,GAAG,OAAO,CAChB;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC/B;;;;OAIG;IACH,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAyBD;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,EACnB,IAAI,EACJ,KAAiB,EACjB,IAAW,EACX,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,SAAS,qBAkCX;yBAzCe,IAAI;;;AA4FpB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,KAAK,CAAC,SAAS,GAAG,QAAQ,EAChC,KAAK,CAAC,EAAE;IAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAC,GAC3C,KAAK,CAAC,SAAS,CAYjB"}
|
package/dist/Icon/Icon.js
CHANGED
|
@@ -128,26 +128,31 @@ const colorStyles = {
|
|
|
128
128
|
/**
|
|
129
129
|
* Size styles for direct SVG icon components.
|
|
130
130
|
* Uses width/height only — SVG components handle their own viewBox scaling.
|
|
131
|
+
*
|
|
132
|
+
* Sizes are expressed in `rem` (relative to the root font-size) so icons scale
|
|
133
|
+
* in step with text when the document font-size changes, matching the rest of
|
|
134
|
+
* the design system's rem-based type scale. Values are the px-equivalents at a
|
|
135
|
+
* 16px root: 12px → 0.75rem, 16px → 1rem, 20px → 1.25rem, 24px → 1.5rem.
|
|
131
136
|
*/
|
|
132
137
|
const sizeStyles = {
|
|
133
138
|
xsm: {
|
|
134
|
-
kzqmXN: "
|
|
135
|
-
kZKoxP: "
|
|
139
|
+
kzqmXN: "x1jw3ynk",
|
|
140
|
+
kZKoxP: "xvle69y",
|
|
136
141
|
$$css: true
|
|
137
142
|
},
|
|
138
143
|
sm: {
|
|
139
|
-
kzqmXN: "
|
|
140
|
-
kZKoxP: "
|
|
144
|
+
kzqmXN: "xcdlrvm",
|
|
145
|
+
kZKoxP: "x1l36t39",
|
|
141
146
|
$$css: true
|
|
142
147
|
},
|
|
143
148
|
md: {
|
|
144
|
-
kzqmXN: "
|
|
145
|
-
kZKoxP: "
|
|
149
|
+
kzqmXN: "xwqq7k2",
|
|
150
|
+
kZKoxP: "xmll18r",
|
|
146
151
|
$$css: true
|
|
147
152
|
},
|
|
148
153
|
lg: {
|
|
149
|
-
kzqmXN: "
|
|
150
|
-
kZKoxP: "
|
|
154
|
+
kzqmXN: "xp8d6y2",
|
|
155
|
+
kZKoxP: "xam5rvr",
|
|
151
156
|
$$css: true
|
|
152
157
|
}
|
|
153
158
|
};
|
|
@@ -155,30 +160,33 @@ const sizeStyles = {
|
|
|
155
160
|
/**
|
|
156
161
|
* Size styles for string-based (registry) icons.
|
|
157
162
|
* Includes fontSize so that 1em-based icons from the registry scale correctly.
|
|
163
|
+
*
|
|
164
|
+
* Expressed in `rem` for the same reason as {@link sizeStyles} — icons track the
|
|
165
|
+
* root font-size instead of being locked to absolute pixels.
|
|
158
166
|
*/
|
|
159
167
|
const spanSizeStyles = {
|
|
160
168
|
xsm: {
|
|
161
|
-
kzqmXN: "
|
|
162
|
-
kZKoxP: "
|
|
163
|
-
kGuDYH: "
|
|
169
|
+
kzqmXN: "x1jw3ynk",
|
|
170
|
+
kZKoxP: "xvle69y",
|
|
171
|
+
kGuDYH: "xboafo0",
|
|
164
172
|
$$css: true
|
|
165
173
|
},
|
|
166
174
|
sm: {
|
|
167
|
-
kzqmXN: "
|
|
168
|
-
kZKoxP: "
|
|
169
|
-
kGuDYH: "
|
|
175
|
+
kzqmXN: "xcdlrvm",
|
|
176
|
+
kZKoxP: "x1l36t39",
|
|
177
|
+
kGuDYH: "x1jchvi3",
|
|
170
178
|
$$css: true
|
|
171
179
|
},
|
|
172
180
|
md: {
|
|
173
|
-
kzqmXN: "
|
|
174
|
-
kZKoxP: "
|
|
175
|
-
kGuDYH: "
|
|
181
|
+
kzqmXN: "xwqq7k2",
|
|
182
|
+
kZKoxP: "xmll18r",
|
|
183
|
+
kGuDYH: "x1603h9y",
|
|
176
184
|
$$css: true
|
|
177
185
|
},
|
|
178
186
|
lg: {
|
|
179
|
-
kzqmXN: "
|
|
180
|
-
kZKoxP: "
|
|
181
|
-
kGuDYH: "
|
|
187
|
+
kzqmXN: "xp8d6y2",
|
|
188
|
+
kZKoxP: "xam5rvr",
|
|
189
|
+
kGuDYH: "xngnso2",
|
|
182
190
|
$$css: true
|
|
183
191
|
}
|
|
184
192
|
};
|
|
@@ -197,6 +205,26 @@ const spanSizeStyles = {
|
|
|
197
205
|
* Extends SVGProps to allow passing additional SVG attributes (used when icon is a component).
|
|
198
206
|
*/
|
|
199
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Derives the ARIA attributes for an icon from its `label` prop.
|
|
210
|
+
*
|
|
211
|
+
* - Non-empty `label` → meaningful image: `role="img"` + `aria-label`, and no
|
|
212
|
+
* `aria-hidden` (an `aria-hidden` element is removed from the accessibility
|
|
213
|
+
* tree, so its accessible name would be ignored).
|
|
214
|
+
* - Omitted or empty `label` → decorative default: `aria-hidden="true"`.
|
|
215
|
+
*
|
|
216
|
+
* The result is spread BEFORE `{...props}` in both render modes so an explicit
|
|
217
|
+
* `aria-hidden` / `role` / `aria-label` from the consumer always wins.
|
|
218
|
+
*/
|
|
219
|
+
function getIconA11yProps(label) {
|
|
220
|
+
return label != null && label !== '' ? {
|
|
221
|
+
role: 'img',
|
|
222
|
+
'aria-label': label
|
|
223
|
+
} : {
|
|
224
|
+
'aria-hidden': 'true'
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
200
228
|
// =============================================================================
|
|
201
229
|
// Component
|
|
202
230
|
// =============================================================================
|
|
@@ -213,15 +241,21 @@ export function Icon({
|
|
|
213
241
|
icon,
|
|
214
242
|
color = 'inherit',
|
|
215
243
|
size = 'md',
|
|
244
|
+
label,
|
|
216
245
|
ref,
|
|
217
246
|
...props
|
|
218
247
|
}) {
|
|
248
|
+
// Derive ARIA from `label`: decorative (aria-hidden) by default, or a
|
|
249
|
+
// meaningful image (role="img" + aria-label) when `label` is non-empty.
|
|
250
|
+
const a11yProps = getIconA11yProps(label);
|
|
251
|
+
|
|
219
252
|
// String mode: resolve from icon registry, wrap in styled span
|
|
220
253
|
if (typeof icon === 'string') {
|
|
221
254
|
return /*#__PURE__*/_jsx(IconFromRegistry, {
|
|
222
255
|
name: icon,
|
|
223
256
|
color: color,
|
|
224
257
|
size: size,
|
|
258
|
+
a11yProps: a11yProps,
|
|
225
259
|
spanProps: props
|
|
226
260
|
});
|
|
227
261
|
}
|
|
@@ -229,8 +263,12 @@ export function Icon({
|
|
|
229
263
|
// Component mode: render SVG component directly with ref forwarding
|
|
230
264
|
const IconComponent = icon;
|
|
231
265
|
return /*#__PURE__*/_jsx(IconComponent, {
|
|
232
|
-
ref: ref
|
|
233
|
-
|
|
266
|
+
ref: ref
|
|
267
|
+
// Derived a11y (decorative default or meaningful `label`) is spread
|
|
268
|
+
// BEFORE {...props} so an explicit aria-hidden/role/aria-label from the
|
|
269
|
+
// consumer still wins as an escape hatch.
|
|
270
|
+
,
|
|
271
|
+
...a11yProps,
|
|
234
272
|
...mergeProps(themeProps('icon', {
|
|
235
273
|
size,
|
|
236
274
|
color
|
|
@@ -255,6 +293,7 @@ function IconFromRegistry({
|
|
|
255
293
|
name,
|
|
256
294
|
color,
|
|
257
295
|
size,
|
|
296
|
+
a11yProps,
|
|
258
297
|
spanProps
|
|
259
298
|
}) {
|
|
260
299
|
const resolvedIcon = getIcon(name);
|
|
@@ -262,11 +301,7 @@ function IconFromRegistry({
|
|
|
262
301
|
return null;
|
|
263
302
|
}
|
|
264
303
|
return /*#__PURE__*/_jsx("span", {
|
|
265
|
-
|
|
266
|
-
// can override it (e.g. `aria-hidden={false}` + `role="img"` +
|
|
267
|
-
// `aria-label`) to expose a meaningful standalone icon. This matches
|
|
268
|
-
// component-mode Icon, which already sets aria-hidden before its spread.
|
|
269
|
-
"aria-hidden": "true",
|
|
304
|
+
...a11yProps,
|
|
270
305
|
...spanProps,
|
|
271
306
|
...mergeProps(themeProps('icon', {
|
|
272
307
|
size,
|