@arbor-education/design-system.components 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/pull_request_template.md +4 -3
- package/CHANGELOG.md +10 -0
- package/CONTRIBUTING.md +1 -0
- package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.d.ts +2 -2
- package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.d.ts.map +1 -1
- package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.js +0 -1
- package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.js.map +1 -1
- package/dist/components/formField/inputs/time/TimeInput.d.ts +1 -1
- package/dist/components/formField/inputs/time/TimeInput.stories.d.ts +1 -1
- package/dist/components/icon/Icon.d.ts.map +1 -1
- package/dist/components/icon/Icon.js +18 -3
- package/dist/components/icon/Icon.js.map +1 -1
- package/dist/components/icon/Icon.stories.d.ts +4 -2
- package/dist/components/icon/Icon.stories.d.ts.map +1 -1
- package/dist/components/icon/Icon.stories.js +150 -102
- package/dist/components/icon/Icon.stories.js.map +1 -1
- package/dist/components/icon/Icon.test.js +146 -6
- package/dist/components/icon/Icon.test.js.map +1 -1
- package/dist/components/icon/LucideIcon.d.ts +17 -0
- package/dist/components/icon/LucideIcon.d.ts.map +1 -0
- package/dist/components/icon/LucideIcon.js +73 -0
- package/dist/components/icon/LucideIcon.js.map +1 -0
- package/dist/components/icon/allowedIcons.d.ts +44 -108
- package/dist/components/icon/allowedIcons.d.ts.map +1 -1
- package/dist/components/icon/allowedIcons.js +52 -112
- package/dist/components/icon/allowedIcons.js.map +1 -1
- package/dist/components/icon/types.d.ts +5 -4
- package/dist/components/icon/types.d.ts.map +1 -1
- package/dist/components/tabs/Tabs.d.ts +1 -1
- package/dist/components/tabs/Tabs.stories.d.ts +1 -1
- package/dist/components/tabs/Tabs.stories.js +1 -1
- package/dist/components/tabs/Tabs.stories.js.map +1 -1
- package/dist/components/tabs/TabsItem.d.ts +2 -2
- package/dist/components/tabs/TabsItem.d.ts.map +1 -1
- package/dist/components/tabs/TabsItem.stories.d.ts +5 -5
- package/dist/components/tabs/TabsItem.stories.d.ts.map +1 -1
- package/dist/components/tabs/TabsItem.stories.js +7 -4
- package/dist/components/tabs/TabsItem.stories.js.map +1 -1
- package/package.json +1 -1
- package/src/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.tsx +2 -2
- package/src/components/icon/Icon.stories.tsx +224 -119
- package/src/components/icon/Icon.test.tsx +178 -6
- package/src/components/icon/Icon.tsx +25 -3
- package/src/components/icon/LucideIcon.tsx +94 -0
- package/src/components/icon/allowedIcons.tsx +67 -207
- package/src/components/icon/lucideDynamic.d.ts +13 -0
- package/src/components/icon/types.ts +5 -4
- package/src/components/tabs/Tabs.stories.tsx +1 -1
- package/src/components/tabs/TabsItem.stories.tsx +8 -4
- package/src/components/tabs/TabsItem.tsx +2 -2
|
@@ -21,12 +21,13 @@
|
|
|
21
21
|
<!-- Step-by-step testing instructions. Include any browser-specific or environment-specific notes.
|
|
22
22
|
Chromatic will post a Storybook link automatically — no need to include one here. -->
|
|
23
23
|
|
|
24
|
-
1.
|
|
25
|
-
2.
|
|
26
|
-
3.
|
|
24
|
+
1.
|
|
25
|
+
2.
|
|
26
|
+
3.
|
|
27
27
|
|
|
28
28
|
## Checklist
|
|
29
29
|
|
|
30
|
+
- [ ] This contribution has been discussed with the design system team in the [contribution process Slack channel](https://arbor-education.slack.com/archives/C0BJU1K3HH9)
|
|
30
31
|
- [ ] This PR does **one thing** — the title does not contain "and" or "also"
|
|
31
32
|
- [ ] The meaningful code diff is under 400 lines (or a justification is written in "Notes for code owners")
|
|
32
33
|
- [ ] `yarn check-types` passes with no errors
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#252](https://github.com/arbor-education/design-system.components/pull/252) [`9247537`](https://github.com/arbor-education/design-system.components/commit/9247537f0297ad464e0e4d059b186ba10db6d0d6) Thanks [@Alex-DN-SP](https://github.com/Alex-DN-SP)! - MIS-73878 Allow all lucide icons in DS Icon component
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#251](https://github.com/arbor-education/design-system.components/pull/251) [`a084aa2`](https://github.com/arbor-education/design-system.components/commit/a084aa29dd18c4fa4ccb8300087140330d66ed49) Thanks [@rickbairstow](https://github.com/rickbairstow)! - MIS-74535 Updates PR template
|
|
12
|
+
|
|
3
13
|
## 3.1.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
package/CONTRIBUTING.md
CHANGED
|
@@ -110,6 +110,7 @@ Each commit should tell part of the story. A reviewer should be able to follow y
|
|
|
110
110
|
|
|
111
111
|
Run through this checklist yourself before requesting review:
|
|
112
112
|
|
|
113
|
+
- [ ] This contribution has been discussed with the design system team in the [contribution process Slack channel](https://arbor-education.slack.com/archives/C0BJU1K3HH9)
|
|
113
114
|
- [ ] My branch name includes the Jira ticket number (e.g. `feature/MIS-12345-add-button-variant`)
|
|
114
115
|
- [ ] My PR does **one thing**. The title does not contain "and" or "also"
|
|
115
116
|
- [ ] The diff is under 400 lines of meaningful code (or I have written a justification)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { IconName } from '../../../../../icon/allowedIcons.js';
|
|
2
2
|
export type SelectDropdownItemBaseProps = {
|
|
3
3
|
value: string;
|
|
4
4
|
selected?: boolean;
|
|
@@ -7,7 +7,7 @@ export type SelectDropdownItemBaseProps = {
|
|
|
7
7
|
export type SelectDropdownItemProps = {
|
|
8
8
|
value: string;
|
|
9
9
|
label?: string;
|
|
10
|
-
icon?:
|
|
10
|
+
icon?: IconName;
|
|
11
11
|
header?: string;
|
|
12
12
|
group?: string;
|
|
13
13
|
closeAfterSelection?: boolean;
|
package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectDropdownItem.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"SelectDropdownItem.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAK7D,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;AAEzC,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,GAAG,2BAA2B,CAAC;AAEhC,eAAO,MAAM,kBAAkB,GAAI,OAAO,uBAAuB,gCAyBhE,CAAC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { allowedIcons } from '../../../../../icon/allowedIcons.js';
|
|
3
2
|
import { Icon } from '../../../../../icon/Icon.js';
|
|
4
3
|
import { Dropdown } from '../../../../../dropdown/Dropdown.js';
|
|
5
4
|
import classNames from 'classnames';
|
package/dist/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectDropdownItem.js","sourceRoot":"","sources":["../../../../../../../src/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"SelectDropdownItem.js","sourceRoot":"","sources":["../../../../../../../src/components/formField/inputs/selectDropdown/items/item/SelectDropdownItem.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,UAAU,MAAM,YAAY,CAAC;AAiBpC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAA8B,EAAE,EAAE;IACnE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,GAAG,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE,GAAG,KAAK,CAAC;IAEjG,MAAM,OAAO,GAAG,UAAU,CAAC,0BAA0B,EAAE;QACrD,qCAAqC,EAAE,MAAM;KAC9C,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,QAAQ,CAAC,UAAU,IAClB,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,EAC1C,mBAAmB,EAAE,mBAAmB,aAEvC,IAAI,IAAI,CACP,eAAM,SAAS,EAAC,+BAA+B,YAC7C,KAAC,IAAI,IAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,GAAI,GACzB,CACR,EACD,eAAK,SAAS,EAAC,gCAAgC,aAC5C,MAAM,IAAI,aAAI,SAAS,EAAC,iCAAiC,YAAE,MAAM,GAAM,EACxE,eAAM,SAAS,EAAC,kCAAkC,YAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAQ,IAC7E,IACc,CACvB,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -22,7 +22,7 @@ export declare const TimeInput: import("react").ForwardRefExoticComponent<{
|
|
|
22
22
|
onValueChange?: (value: string) => void;
|
|
23
23
|
searchType?: ComboboxSearchType;
|
|
24
24
|
highlightStringMatches?: boolean;
|
|
25
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, "
|
|
25
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size" | "defaultValue" | "value"> & {
|
|
26
26
|
value?: TimeValue | "";
|
|
27
27
|
defaultValue?: TimeValue | "";
|
|
28
28
|
} & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -10,7 +10,7 @@ declare const meta: {
|
|
|
10
10
|
onValueChange?: (value: string) => void;
|
|
11
11
|
searchType?: import("../../../combobox/types.js").ComboboxSearchType;
|
|
12
12
|
highlightStringMatches?: boolean;
|
|
13
|
-
} & Omit<import("react").InputHTMLAttributes<HTMLInputElement>, "
|
|
13
|
+
} & Omit<import("react").InputHTMLAttributes<HTMLInputElement>, "type" | "size" | "defaultValue" | "value"> & {
|
|
14
14
|
value?: TimeValue | "";
|
|
15
15
|
defaultValue?: TimeValue | "";
|
|
16
16
|
} & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../../src/components/icon/Icon.tsx"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../../src/components/icon/Icon.tsx"],"names":[],"mappings":"AACA,OAAO,EAA4B,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE5E,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE5D,KAAK,SAAS,GAAG;IACf,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAwBF,eAAO,MAAM,IAAI,GAAI,OAAO,SAAS,gCAYpC,CAAC;AAEF,yBAAiB,IAAI,CAAC;IACpB,KAAY,KAAK,GAAG,SAAS,CAAC;IAC9B,KAAY,IAAI,GAAG,QAAQ,CAAC;IAC5B,KAAY,IAAI,GAAG,QAAQ,CAAC;IAC5B,KAAY,WAAW,GAAG,eAAe,CAAC;CAC3C"}
|
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import classNames from 'classnames';
|
|
3
|
-
import {
|
|
3
|
+
import { customIcons, iconAliases } from './allowedIcons.js';
|
|
4
|
+
import { LucideIcon } from './LucideIcon.js';
|
|
5
|
+
const isCustomIconName = (name) => Object.prototype.hasOwnProperty.call(customIcons, name);
|
|
6
|
+
const isAliasedIconName = (name) => Object.prototype.hasOwnProperty.call(iconAliases, name);
|
|
7
|
+
const resolveLucideName = (name) => isAliasedIconName(name) ? iconAliases[name] : name;
|
|
8
|
+
/**
|
|
9
|
+
* Arbor's custom icons and aliases are resolved before the Lucide set, so an Arbor name always wins
|
|
10
|
+
* over the Lucide icon it shadows.
|
|
11
|
+
*/
|
|
12
|
+
const IconGlyph = (props) => {
|
|
13
|
+
const { name, ...glyphProps } = props;
|
|
14
|
+
if (isCustomIconName(name)) {
|
|
15
|
+
const CustomIcon = customIcons[name];
|
|
16
|
+
return _jsx(CustomIcon, { ...glyphProps });
|
|
17
|
+
}
|
|
18
|
+
return _jsx(LucideIcon, { name: resolveLucideName(name), ...glyphProps });
|
|
19
|
+
};
|
|
4
20
|
export const Icon = (props) => {
|
|
5
21
|
const { size = 16, color = 'currentColor', name, screenReaderText, className } = props;
|
|
6
|
-
const Component = allowedIcons[name];
|
|
7
22
|
const classes = classNames(className, `ds-icon ds-icon-${name}`);
|
|
8
|
-
return (_jsxs(_Fragment, { children: [_jsx(
|
|
23
|
+
return (_jsxs(_Fragment, { children: [_jsx(IconGlyph, { name: name, size: size, color: color, className: classes, role: "img", "aria-hidden": true }), !!screenReaderText && (_jsx("span", { className: "sr-only", children: screenReaderText }))] }));
|
|
9
24
|
};
|
|
10
25
|
//# sourceMappingURL=Icon.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.js","sourceRoot":"","sources":["../../../src/components/icon/Icon.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"Icon.js","sourceRoot":"","sources":["../../../src/components/icon/Icon.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAiB,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAuB,MAAM,iBAAiB,CAAC;AAWlE,MAAM,gBAAgB,GAAG,CAAC,IAAc,EAAoC,EAAE,CAC5E,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AAE1D,MAAM,iBAAiB,GAAG,CAAC,IAAc,EAAoC,EAAE,CAC7E,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AAE1D,MAAM,iBAAiB,GAAG,CAAC,IAAiD,EAAkB,EAAE,CAC9F,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAErD;;;GAGG;AACH,MAAM,SAAS,GAAG,CAAC,KAA2C,EAAE,EAAE;IAChE,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,CAAC;IACtC,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACrC,OAAO,KAAC,UAAU,OAAK,UAAU,GAAI,CAAC;IACxC,CAAC;IACD,OAAO,KAAC,UAAU,IAAC,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAM,UAAU,GAAI,CAAC;AACvE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,KAAgB,EAAE,EAAE;IACvC,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG,cAAc,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IACvF,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,EAAE,mBAAmB,IAAI,EAAE,CAAC,CAAC;IACjE,OAAO,CACL,8BAEE,KAAC,SAAS,IAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAC,KAAK,wBAAe,EAC7F,CAAC,CAAC,gBAAgB,IAAI,CACrB,eAAM,SAAS,EAAC,SAAS,YAAE,gBAAgB,GAAQ,CACpD,IACA,CACJ,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { StoryObj } from '@storybook/react-vite';
|
|
2
2
|
import { Icon } from './Icon.js';
|
|
3
|
+
import { type IconName } from './allowedIcons.js';
|
|
3
4
|
declare function IconDocsPage(): import("react").JSX.Element;
|
|
4
5
|
declare const meta: {
|
|
5
6
|
title: string;
|
|
@@ -7,7 +8,7 @@ declare const meta: {
|
|
|
7
8
|
size?: import("./types.js").IconSize;
|
|
8
9
|
color?: string;
|
|
9
10
|
screenReaderText?: string;
|
|
10
|
-
name:
|
|
11
|
+
name: IconName;
|
|
11
12
|
className?: string;
|
|
12
13
|
}) => import("react").JSX.Element;
|
|
13
14
|
parameters: {
|
|
@@ -20,7 +21,7 @@ declare const meta: {
|
|
|
20
21
|
argTypes: {
|
|
21
22
|
name: {
|
|
22
23
|
control: "select";
|
|
23
|
-
options:
|
|
24
|
+
options: IconName[];
|
|
24
25
|
description: string;
|
|
25
26
|
table: {
|
|
26
27
|
type: {
|
|
@@ -91,4 +92,5 @@ export declare const CustomSolidVariants: Story;
|
|
|
91
92
|
export declare const InButtonContext: Story;
|
|
92
93
|
export declare const InStatusIndicatorContext: Story;
|
|
93
94
|
export declare const InEmptyStateContext: Story;
|
|
95
|
+
export declare const IconSearch: Story;
|
|
94
96
|
//# sourceMappingURL=Icon.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.stories.d.ts","sourceRoot":"","sources":["../../../src/components/icon/Icon.stories.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Icon.stories.d.ts","sourceRoot":"","sources":["../../../src/components/icon/Icon.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAW5D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAuN7D,iBAAS,YAAY,gCAsBpB;AA8FD,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwFmB,CAAC;AAE9B,eAAe,IAAI,CAAC;AAGpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AA4oBnC,eAAO,MAAM,OAAO,EAAE,KASrB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAgDtB,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,KAiDrC,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAmD7B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KA+C7B,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,KA6CpC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAoDjC,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAkD7B,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,KA+CtC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAmDjC,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KASxB,CAAC"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState } from 'react';
|
|
2
3
|
import { Controls, Heading as DocHeading, Markdown, Primary as DocPrimary, Stories, Subtitle, Title, } from '@storybook/addon-docs/blocks';
|
|
3
4
|
import { Button } from '../button/Button.js';
|
|
4
5
|
import { Icon } from './Icon.js';
|
|
5
|
-
import {
|
|
6
|
+
import { iconNames } from './allowedIcons.js';
|
|
6
7
|
import { iconSizes } from './types.js';
|
|
7
8
|
// ---------------------------------------------------------------------------
|
|
8
9
|
// Docs page content
|
|
@@ -177,7 +178,7 @@ const DEVELOPER_NOTES = [
|
|
|
177
178
|
'- **Status icons** — must be paired with visible text where possible (WCAG 1.4.1: use of colour).',
|
|
178
179
|
' Do not rely on icon colour alone to communicate success, warning, or error.',
|
|
179
180
|
'- **Icon-only interactions** — must have accessible label + tooltip on hover/focus.',
|
|
180
|
-
'- **Avoid `title` attributes** — Lucide SVGs sometimes include `<title>` elements; Arbor\'s `
|
|
181
|
+
'- **Avoid `title` attributes** — Lucide SVGs sometimes include `<title>` elements; Arbor\'s `Icon`',
|
|
181
182
|
' wrapper suppresses these via `aria-hidden`. Do not rely on SVG `title` for accessible names.',
|
|
182
183
|
'- **"Opens in new tab"** — communicate this in text (`<span class="sr-only">opens in new tab</span>`),',
|
|
183
184
|
' not only via the `external-link` icon.',
|
|
@@ -195,7 +196,7 @@ const DEVELOPER_NOTES = [
|
|
|
195
196
|
'| Type | Description |',
|
|
196
197
|
'|---|---|',
|
|
197
198
|
'| `Icon.Props` | Full props interface |',
|
|
198
|
-
'| `Icon.Name` | Union of
|
|
199
|
+
'| `Icon.Name` | Union of every valid name: the whole Lucide set, plus Arbor aliases and custom icons |',
|
|
199
200
|
'| `Icon.Size` | `12 \\| 16 \\| 24` |',
|
|
200
201
|
'| `Icon.CustomProps` | Props for custom SVG icons |',
|
|
201
202
|
].join('\n');
|
|
@@ -204,10 +205,95 @@ const RELATED_COMPONENTS = [
|
|
|
204
205
|
'',
|
|
205
206
|
'[Button](?path=/docs/components-button--docs) · [Banner](?path=/docs/components-banner--docs) · [Badge](?path=/docs/components-badge--docs) · [Dot](?path=/docs/components-dot--docs) · [Tag](?path=/docs/components-tag--docs)',
|
|
206
207
|
].join('\n');
|
|
208
|
+
const CATALOGUE_INTRO = [
|
|
209
|
+
'The Arbor-curated names are grouped below. Every [Lucide](https://lucide.dev/icons) icon name is',
|
|
210
|
+
'also valid — use the **Icon search** story above to find one by name.',
|
|
211
|
+
].join('\n');
|
|
207
212
|
const PROPS_INTRO = 'The preview below is wired to the **Controls** panel — tweak any prop to see the story update in real time.';
|
|
208
213
|
function IconDocsPage() {
|
|
209
|
-
return (_jsxs(_Fragment, { children: [_jsx(Title, {}), _jsx(Subtitle, {}), _jsx(Markdown, { children: DESCRIPTION_INTRO }), _jsx(DocHeading, { children: "Interactive example" }), _jsx(Markdown, { children: PROPS_INTRO }), _jsx(DocPrimary, {}), _jsx(Controls, {}), _jsx(DocHeading, { children: "Usage guidance" }), _jsx(Markdown, { children: USAGE_GUIDANCE }), _jsx(DocHeading, { children: "Developer notes" }), _jsx(Markdown, { children: DEVELOPER_NOTES }), _jsx(DocHeading, { children: "Examples" }), _jsx(Stories, { title: "" }), _jsx(DocHeading, { children: "Icon catalogue" }), _jsx(IconGalleryTemplate, {}), _jsx(Markdown, { children: RELATED_COMPONENTS })] }));
|
|
214
|
+
return (_jsxs(_Fragment, { children: [_jsx(Title, {}), _jsx(Subtitle, {}), _jsx(Markdown, { children: DESCRIPTION_INTRO }), _jsx(DocHeading, { children: "Interactive example" }), _jsx(Markdown, { children: PROPS_INTRO }), _jsx(DocPrimary, {}), _jsx(Controls, {}), _jsx(DocHeading, { children: "Usage guidance" }), _jsx(Markdown, { children: USAGE_GUIDANCE }), _jsx(DocHeading, { children: "Developer notes" }), _jsx(Markdown, { children: DEVELOPER_NOTES }), _jsx(DocHeading, { children: "Examples" }), _jsx(Stories, { title: "" }), _jsx(DocHeading, { children: "Icon catalogue" }), _jsx(Markdown, { children: CATALOGUE_INTRO }), _jsx(IconGalleryTemplate, {}), _jsx(Markdown, { children: RELATED_COMPONENTS })] }));
|
|
210
215
|
}
|
|
216
|
+
const ICON_CATEGORIES = [
|
|
217
|
+
{
|
|
218
|
+
heading: 'Navigation',
|
|
219
|
+
icons: [
|
|
220
|
+
'arrow-up', 'arrow-down', 'arrow-left', 'arrow-right',
|
|
221
|
+
'arrow-right-from-line', 'arrow-up-right',
|
|
222
|
+
'chevron-up', 'chevron-down', 'chevron-left', 'chevron-right',
|
|
223
|
+
'chevrons-left', 'chevrons-right',
|
|
224
|
+
'corner-down-left', 'menu',
|
|
225
|
+
'ellipsis', 'ellipsis-vertical', '3-dot', 'grab',
|
|
226
|
+
],
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
heading: 'Actions',
|
|
230
|
+
icons: [
|
|
231
|
+
'pencil', 'trash', 'save', 'copy', 'download', 'upload',
|
|
232
|
+
'share', 'send', 'redo', 'undo', 'plus', 'minus',
|
|
233
|
+
'circle-plus', 'iteration-ccw', 'switch-camera',
|
|
234
|
+
],
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
heading: 'Status / severity',
|
|
238
|
+
icons: [
|
|
239
|
+
'info', 'circle-alert', 'triangle-alert',
|
|
240
|
+
'circle-check', 'circle-check-big', 'circle-x',
|
|
241
|
+
'circle-help', 'check', 'check-solid', 'x', 'x-solid',
|
|
242
|
+
],
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
heading: 'Content / media',
|
|
246
|
+
icons: [
|
|
247
|
+
'file', 'files', 'clipboard', 'clipboard-list',
|
|
248
|
+
'book-open', 'camera', 'mic', 'paperclip',
|
|
249
|
+
'sheet', 'table',
|
|
250
|
+
'sparkles', 'party-popper', 'lightbulb',
|
|
251
|
+
'favourite-outline', 'favourite-filled',
|
|
252
|
+
],
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
heading: 'Charts / data',
|
|
256
|
+
icons: [
|
|
257
|
+
'chart-column-increasing', 'chart-spline',
|
|
258
|
+
'trending-up', 'trending-down',
|
|
259
|
+
'percent', 'circle-percent',
|
|
260
|
+
'sorting', 'funnel', 'sliders-horizontal', 'list-filter-plus',
|
|
261
|
+
],
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
heading: 'People / org',
|
|
265
|
+
icons: [
|
|
266
|
+
'user', 'guardians', 'group', 'staff', 'graduation-cap',
|
|
267
|
+
],
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
heading: 'System / state',
|
|
271
|
+
icons: [
|
|
272
|
+
'eye', 'eye-off', 'lock', 'lock-open', 'loader',
|
|
273
|
+
'pin', 'flag', 'house', 'history', 'clock-3', 'date',
|
|
274
|
+
'settings', 'expand', 'shrink', 'link', 'external-link',
|
|
275
|
+
'log-out', 'search', 'mail', 'phone', 'smartphone',
|
|
276
|
+
'monitor', 'projector', 'archive',
|
|
277
|
+
],
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
heading: 'Other / misc',
|
|
281
|
+
icons: [
|
|
282
|
+
'dot', 'layout-list', 'list', 'grid-3x3',
|
|
283
|
+
'paint-bucket', 'message-square-more',
|
|
284
|
+
],
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
heading: 'Custom / brand',
|
|
288
|
+
icons: ['ask-arbor', 'google'],
|
|
289
|
+
},
|
|
290
|
+
];
|
|
291
|
+
/**
|
|
292
|
+
* The Arbor-curated names, used for the Controls select. The `name` prop accepts every Lucide icon
|
|
293
|
+
* too, but ~1,900 options in a dropdown is not a usable control — use the Icon search story to
|
|
294
|
+
* explore the full set.
|
|
295
|
+
*/
|
|
296
|
+
const CURATED_ICON_NAMES = ICON_CATEGORIES.flatMap(category => category.icons);
|
|
211
297
|
// ---------------------------------------------------------------------------
|
|
212
298
|
// Meta
|
|
213
299
|
// ---------------------------------------------------------------------------
|
|
@@ -224,12 +310,12 @@ const meta = {
|
|
|
224
310
|
argTypes: {
|
|
225
311
|
name: {
|
|
226
312
|
control: 'select',
|
|
227
|
-
options:
|
|
313
|
+
options: CURATED_ICON_NAMES,
|
|
228
314
|
description: [
|
|
229
315
|
'Kebab-case key identifying the icon to render. Required.',
|
|
230
|
-
'
|
|
231
|
-
'
|
|
232
|
-
'
|
|
316
|
+
'Every [Lucide](https://lucide.dev) icon name is valid, plus Arbor\'s own aliases and custom',
|
|
317
|
+
'icons — TypeScript errors on any unknown value. The dropdown below lists the Arbor-curated',
|
|
318
|
+
'names only; use the **Icon search** story to browse the full set.',
|
|
233
319
|
'Commonly used: `pencil` (edit), `trash` (delete), `plus` (add), `x` (close/remove),',
|
|
234
320
|
'`check` (confirm), `3-dot` (more actions), `chevron-down` (expand), `triangle-alert` (warning).',
|
|
235
321
|
].join(' '),
|
|
@@ -440,81 +526,29 @@ const CustomSolidVariantsTemplate = () => (_jsxs("div", { style: {
|
|
|
440
526
|
flexDirection: 'column',
|
|
441
527
|
gap: 'var(--spacing-large)',
|
|
442
528
|
}, children: [_jsx("p", { className: "ds-text", style: { margin: 0, color: 'var(--color-grey-600)' }, children: "Favourite/bookmark active state" }), _jsxs("div", { style: { display: 'flex', gap: 'var(--spacing-xlarge)', alignItems: 'center' }, children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'var(--spacing-small)' }, children: [_jsx(Icon, { name: "favourite-outline", size: 24 }), _jsx("span", { className: "ds-text", style: { color: 'var(--color-grey-600)' }, children: "favourite-outline" })] }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'var(--spacing-small)' }, children: [_jsx(Icon, { name: "favourite-filled", size: 24, color: "var(--color-brand-600)" }), _jsx("span", { className: "ds-text", style: { color: 'var(--color-grey-600)' }, children: "favourite-filled" })] })] })] })] }));
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
'info', 'circle-alert', 'triangle-alert',
|
|
467
|
-
'circle-check', 'circle-check-big', 'circle-x',
|
|
468
|
-
'circle-help', 'check', 'check-solid', 'x', 'x-solid',
|
|
469
|
-
],
|
|
470
|
-
},
|
|
471
|
-
{
|
|
472
|
-
heading: 'Content / media',
|
|
473
|
-
icons: [
|
|
474
|
-
'file', 'files', 'clipboard', 'clipboard-list',
|
|
475
|
-
'book-open', 'camera', 'mic', 'paperclip',
|
|
476
|
-
'sheet', 'table',
|
|
477
|
-
'sparkles', 'party-popper', 'lightbulb',
|
|
478
|
-
'favourite-outline', 'favourite-filled',
|
|
479
|
-
],
|
|
480
|
-
},
|
|
481
|
-
{
|
|
482
|
-
heading: 'Charts / data',
|
|
483
|
-
icons: [
|
|
484
|
-
'chart-column-increasing', 'chart-spline',
|
|
485
|
-
'trending-up', 'trending-down',
|
|
486
|
-
'percent', 'circle-percent',
|
|
487
|
-
'sorting', 'funnel', 'sliders-horizontal', 'list-filter-plus',
|
|
488
|
-
],
|
|
489
|
-
},
|
|
490
|
-
{
|
|
491
|
-
heading: 'People / org',
|
|
492
|
-
icons: [
|
|
493
|
-
'user', 'guardians', 'group', 'staff', 'graduation-cap',
|
|
494
|
-
],
|
|
495
|
-
},
|
|
496
|
-
{
|
|
497
|
-
heading: 'System / state',
|
|
498
|
-
icons: [
|
|
499
|
-
'eye', 'eye-off', 'lock', 'lock-open', 'loader',
|
|
500
|
-
'pin', 'flag', 'house', 'history', 'clock-3', 'date',
|
|
501
|
-
'settings', 'expand', 'shrink', 'link', 'external-link',
|
|
502
|
-
'log-out', 'search', 'mail', 'phone', 'smartphone',
|
|
503
|
-
'monitor', 'projector', 'archive',
|
|
504
|
-
],
|
|
505
|
-
},
|
|
506
|
-
{
|
|
507
|
-
heading: 'Other / misc',
|
|
508
|
-
icons: [
|
|
509
|
-
'dot', 'layout-list', 'list', 'grid-3x3',
|
|
510
|
-
'paint-bucket', 'message-square-more',
|
|
511
|
-
],
|
|
512
|
-
},
|
|
513
|
-
{
|
|
514
|
-
heading: 'Custom / brand',
|
|
515
|
-
icons: ['ask-arbor', 'google'],
|
|
516
|
-
},
|
|
517
|
-
];
|
|
529
|
+
// ---------------------------------------------------------------------------
|
|
530
|
+
// IconGallery — all icons grouped by semantic category
|
|
531
|
+
// ---------------------------------------------------------------------------
|
|
532
|
+
const ICON_CARD_GRID_STYLE = {
|
|
533
|
+
display: 'grid',
|
|
534
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(7rem, 1fr))',
|
|
535
|
+
gap: 'var(--spacing-small)',
|
|
536
|
+
};
|
|
537
|
+
const IconCard = ({ name }) => (_jsxs("div", { style: {
|
|
538
|
+
display: 'flex',
|
|
539
|
+
flexDirection: 'column',
|
|
540
|
+
alignItems: 'center',
|
|
541
|
+
gap: 'var(--spacing-xsmall)',
|
|
542
|
+
padding: 'var(--spacing-medium)',
|
|
543
|
+
borderRadius: 'var(--border-radius-small)',
|
|
544
|
+
border: '1px solid var(--color-grey-200)',
|
|
545
|
+
background: 'var(--color-grey-100)',
|
|
546
|
+
}, children: [_jsx(Icon, { name: name, size: 16 }), _jsx("span", { className: "ds-text", style: {
|
|
547
|
+
color: 'var(--color-grey-600)',
|
|
548
|
+
wordBreak: 'break-word',
|
|
549
|
+
textAlign: 'center',
|
|
550
|
+
fontSize: 'var(--font-size-1-11)',
|
|
551
|
+
}, children: name })] }));
|
|
518
552
|
const IconGalleryTemplate = () => (_jsx("div", { style: {
|
|
519
553
|
padding: 'var(--spacing-xlarge)',
|
|
520
554
|
width: '100%',
|
|
@@ -523,25 +557,32 @@ const IconGalleryTemplate = () => (_jsx("div", { style: {
|
|
|
523
557
|
margin: '0 0 var(--spacing-large) 0',
|
|
524
558
|
color: 'var(--color-grey-600)',
|
|
525
559
|
fontWeight: 'var(--font-weight-semi-bold)',
|
|
526
|
-
}, children: category.heading }), _jsx("div", { style: {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
560
|
+
}, children: category.heading }), _jsx("div", { style: ICON_CARD_GRID_STYLE, children: category.icons.map(name => (_jsx(IconCard, { name: name }, name))) })] }, category.heading))) }));
|
|
561
|
+
// ---------------------------------------------------------------------------
|
|
562
|
+
// IconSearch — search the whole Lucide set without rendering ~1,900 SVGs at once
|
|
563
|
+
// ---------------------------------------------------------------------------
|
|
564
|
+
const SEARCH_RESULT_LIMIT = 120;
|
|
565
|
+
const IconSearchTemplate = () => {
|
|
566
|
+
const [query, setQuery] = useState('');
|
|
567
|
+
const searchTerm = query.trim().toLowerCase();
|
|
568
|
+
const matches = useMemo(() => (searchTerm
|
|
569
|
+
? iconNames.filter(name => name.includes(searchTerm))
|
|
570
|
+
: CURATED_ICON_NAMES), [searchTerm]);
|
|
571
|
+
const visible = matches.slice(0, SEARCH_RESULT_LIMIT);
|
|
572
|
+
return (_jsxs("div", { style: { padding: 'var(--spacing-xlarge)', width: '100%', maxWidth: '900px' }, children: [_jsxs("label", { className: "ds-text", htmlFor: "ds-icon-search", style: {
|
|
573
|
+
display: 'block',
|
|
574
|
+
marginBottom: 'var(--spacing-xsmall)',
|
|
575
|
+
fontWeight: 'var(--font-weight-semi-bold)',
|
|
576
|
+
}, children: ["Search", ' ', iconNames.length, ' ', "icon names"] }), _jsx("input", { id: "ds-icon-search", type: "search", value: query, onChange: event => setQuery(event.target.value), placeholder: "e.g. calendar, arrow, user", style: {
|
|
577
|
+
width: '100%',
|
|
578
|
+
padding: 'var(--spacing-small)',
|
|
579
|
+
marginBottom: 'var(--spacing-small)',
|
|
580
|
+
borderRadius: 'var(--border-radius-small)',
|
|
581
|
+
border: '1px solid var(--color-grey-300)',
|
|
582
|
+
} }), _jsx("p", { className: "ds-text", style: { margin: '0 0 var(--spacing-large) 0', color: 'var(--color-grey-600)' }, children: searchTerm
|
|
583
|
+
? `${matches.length} match${matches.length === 1 ? '' : 'es'}${matches.length > visible.length ? ` — showing the first ${visible.length}` : ''}`
|
|
584
|
+
: `Showing the ${visible.length} Arbor-curated names — type to search the full set.` }), _jsx("div", { style: ICON_CARD_GRID_STYLE, children: visible.map(name => (_jsx(IconCard, { name: name }, name))) }), searchTerm && matches.length === 0 && (_jsxs("p", { className: "ds-text", style: { margin: 0, color: 'var(--color-grey-600)' }, children: ["No icon name contains \u201C", searchTerm, "\u201D. Browse the full set at", ' ', _jsx("a", { href: "https://lucide.dev/icons", target: "_blank", rel: "noreferrer", children: "lucide.dev/icons" }), "."] }))] }));
|
|
585
|
+
};
|
|
545
586
|
const InButtonContextTemplate = () => (_jsxs("div", { style: {
|
|
546
587
|
padding: 'var(--spacing-xlarge)',
|
|
547
588
|
display: 'flex',
|
|
@@ -994,4 +1035,11 @@ export default InEmptyStateContextExample;
|
|
|
994
1035
|
'Do not use `size={24}` in list items, table cells, or button icons — reserve it for',
|
|
995
1036
|
'full-area statements like this one.',
|
|
996
1037
|
].join(' '));
|
|
1038
|
+
export const IconSearch = withDescription({
|
|
1039
|
+
render: () => _jsx(IconSearchTemplate, {}),
|
|
1040
|
+
parameters: { layout: 'fullscreen' },
|
|
1041
|
+
}, [
|
|
1042
|
+
'Every Lucide icon name is a valid `name`, which is far too many to render at once — search',
|
|
1043
|
+
'instead. Icons load on demand, so only the ones you actually render are downloaded.',
|
|
1044
|
+
].join(' '));
|
|
997
1045
|
//# sourceMappingURL=Icon.stories.js.map
|