@kanso-labs/kanso-ui 0.34.0 → 0.34.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/collection/text.js +17 -0
  2. package/dist/collection/text.js.map +1 -0
  3. package/dist/components/avatar/index.js +49 -34
  4. package/dist/components/avatar/index.js.map +1 -1
  5. package/dist/components/chip-group/index.js +1 -3
  6. package/dist/components/chip-group/index.js.map +1 -1
  7. package/dist/components/color-picker/index.d.ts +2 -2
  8. package/dist/components/color-picker/index.js.map +1 -1
  9. package/dist/components/combo-box/index.js +112 -77
  10. package/dist/components/combo-box/index.js.map +1 -1
  11. package/dist/components/disclosure/index.js +35 -29
  12. package/dist/components/disclosure/index.js.map +1 -1
  13. package/dist/components/link/index.js.map +1 -1
  14. package/dist/components/list/index.d.ts +1 -1
  15. package/dist/components/list/index.js +70 -50
  16. package/dist/components/list/index.js.map +1 -1
  17. package/dist/components/list-box/index.d.ts +1 -1
  18. package/dist/components/list-box/index.js +72 -88
  19. package/dist/components/list-box/index.js.map +1 -1
  20. package/dist/components/menu/index.d.ts +4 -3
  21. package/dist/components/menu/index.js +57 -69
  22. package/dist/components/menu/index.js.map +1 -1
  23. package/dist/components/meter/index.d.ts +3 -2
  24. package/dist/components/meter/index.js.map +1 -1
  25. package/dist/components/navigation-tree/index.d.ts +1 -1
  26. package/dist/components/navigation-tree/index.js +62 -76
  27. package/dist/components/navigation-tree/index.js.map +1 -1
  28. package/dist/components/product-icon/index.js +49 -34
  29. package/dist/components/product-icon/index.js.map +1 -1
  30. package/dist/components/token-field/index.js +4 -2
  31. package/dist/components/token-field/index.js.map +1 -1
  32. package/dist/components/tree/index.d.ts +1 -1
  33. package/dist/components/tree/index.js +74 -52
  34. package/dist/components/tree/index.js.map +1 -1
  35. package/dist/hooks/useImageLoadingStatus.js +14 -7
  36. package/dist/hooks/useImageLoadingStatus.js.map +1 -1
  37. package/dist/hooks/useRipple.js +209 -216
  38. package/dist/hooks/useRipple.js.map +1 -1
  39. package/dist/styles/overlay.js +1 -0
  40. package/dist/styles/overlay.js.map +1 -1
  41. package/dist/styles.css +4 -0
  42. package/package.json +2 -2
@@ -2,6 +2,7 @@ import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
2
  import { mergeStatefulStyles, mergeStyles } from "../../styles/merge.js";
3
3
  import { ChevronEndGlyph } from "../../glyphs/index.js";
4
4
  import { focus } from "../../styles/focus.js";
5
+ import { useRipple } from "../../hooks/useRipple.js";
5
6
  import Checkbox from "../checkbox/index.js";
6
7
  import { CollectionLoadMore } from "../../collection/index.js";
7
8
  import { collectionStyles, rowItemStyles } from "../../collection/styles.js";
@@ -46,15 +47,15 @@ function chevronFor(state) {
46
47
  }[!!state.isExpanded << 0] })
47
48
  });
48
49
  }
49
- function itemContent(headline, leading, supporting, trailing, selectLabel) {
50
- return (state) => /* @__PURE__ */ jsx(RowContent, {
50
+ function itemContent(headline, leading, supporting, trailing, selectLabel, ripple) {
51
+ return (state) => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(RowContent, {
51
52
  isDisabled: state.isDisabled,
52
53
  isSelected: state.isSelected,
53
54
  leading: leadingFor(state, leading, selectLabel),
54
55
  supporting,
55
56
  trailing,
56
57
  children: headline
57
- });
58
+ }), state.isDisabled ? null : ripple] });
58
59
  }
59
60
  /**
60
61
  * The caret, the selection checkbox, then whatever the row was given. Its
@@ -106,13 +107,13 @@ function Tree$1(t0) {
106
107
  let t2;
107
108
  let t3;
108
109
  if ($[0] !== t0) {
109
- const { selectLabel: t4, ...props$3 } = t0;
110
+ const { selectLabel: t4, ...props$1 } = t0;
110
111
  const selectLabel = t4 === void 0 ? "Select" : t4;
111
112
  T1 = SelectLabelContext;
112
113
  t3 = selectLabel;
113
114
  T0 = Tree;
114
- t1 = props$3;
115
- t2 = mergeStatefulStyles(props(collectionStyles.container), props$3);
115
+ t1 = props$1;
116
+ t2 = mergeStatefulStyles(props(collectionStyles.container), props$1);
116
117
  $[0] = t0;
117
118
  $[1] = T0;
118
119
  $[2] = T1;
@@ -183,51 +184,72 @@ function TreeHeader$1(t0) {
183
184
  * taken from a plain-string headline when it is not given.
184
185
  */
185
186
  function TreeItem$1(t0) {
186
- const $ = c(18);
187
- const { children, headline, leading, supporting, textValue, trailing, ...props } = t0;
187
+ const $ = c(26);
188
+ const { children, headline, leading, onContextMenu, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, supporting, textValue, trailing, ...props } = t0;
188
189
  const selectLabel = useContext(SelectLabelContext);
189
- const T0 = TreeItem;
190
190
  let t1;
191
- if ($[0] !== headline || $[1] !== textValue) {
192
- t1 = textValueFor(textValue, headline);
193
- $[0] = headline;
194
- $[1] = textValue;
195
- $[2] = t1;
196
- } else t1 = $[2];
197
- const t2 = mergeStatefulStyles(rowItemStyles(supporting, void 0, styles.indent), props);
198
- let t3;
199
- if ($[3] !== headline || $[4] !== leading || $[5] !== selectLabel || $[6] !== supporting || $[7] !== trailing) {
200
- t3 = itemContent(headline, leading, supporting, trailing, selectLabel);
201
- $[3] = headline;
202
- $[4] = leading;
203
- $[5] = selectLabel;
204
- $[6] = supporting;
205
- $[7] = trailing;
206
- $[8] = t3;
207
- } else t3 = $[8];
208
- let t4;
209
- if ($[9] !== t3) {
210
- t4 = /* @__PURE__ */ jsx(TreeItemContent, { children: t3 });
211
- $[9] = t3;
212
- $[10] = t4;
213
- } else t4 = $[10];
191
+ if ($[0] !== onContextMenu || $[1] !== onPointerCancel || $[2] !== onPointerDown || $[3] !== onPointerLeave || $[4] !== onPointerUp) {
192
+ t1 = {
193
+ onContextMenu,
194
+ onPointerCancel,
195
+ onPointerDown,
196
+ onPointerLeave,
197
+ onPointerUp
198
+ };
199
+ $[0] = onContextMenu;
200
+ $[1] = onPointerCancel;
201
+ $[2] = onPointerDown;
202
+ $[3] = onPointerLeave;
203
+ $[4] = onPointerUp;
204
+ $[5] = t1;
205
+ } else t1 = $[5];
206
+ const ripple = useRipple(true, t1, true);
207
+ const T0 = TreeItem;
208
+ let t2;
209
+ if ($[6] !== headline || $[7] !== textValue) {
210
+ t2 = textValueFor(textValue, headline);
211
+ $[6] = headline;
212
+ $[7] = textValue;
213
+ $[8] = t2;
214
+ } else t2 = $[8];
215
+ const t3 = ripple.handlers;
216
+ const t4 = mergeStatefulStyles(rowItemStyles(supporting, void 0, styles.indent), props);
214
217
  let t5;
215
- if ($[11] !== T0 || $[12] !== children || $[13] !== props || $[14] !== t1 || $[15] !== t2 || $[16] !== t4) {
216
- t5 = /* @__PURE__ */ jsxs(T0, {
217
- textValue: t1,
218
+ if ($[9] !== headline || $[10] !== leading || $[11] !== ripple.surface || $[12] !== selectLabel || $[13] !== supporting || $[14] !== trailing) {
219
+ t5 = itemContent(headline, leading, supporting, trailing, selectLabel, ripple.surface);
220
+ $[9] = headline;
221
+ $[10] = leading;
222
+ $[11] = ripple.surface;
223
+ $[12] = selectLabel;
224
+ $[13] = supporting;
225
+ $[14] = trailing;
226
+ $[15] = t5;
227
+ } else t5 = $[15];
228
+ let t6;
229
+ if ($[16] !== t5) {
230
+ t6 = /* @__PURE__ */ jsx(TreeItemContent, { children: t5 });
231
+ $[16] = t5;
232
+ $[17] = t6;
233
+ } else t6 = $[17];
234
+ let t7;
235
+ if ($[18] !== T0 || $[19] !== children || $[20] !== props || $[21] !== ripple.handlers || $[22] !== t2 || $[23] !== t4 || $[24] !== t6) {
236
+ t7 = /* @__PURE__ */ jsxs(T0, {
237
+ textValue: t2,
238
+ ...t3,
218
239
  ...props,
219
- ...t2,
220
- children: [t4, children]
240
+ ...t4,
241
+ children: [t6, children]
221
242
  });
222
- $[11] = T0;
223
- $[12] = children;
224
- $[13] = props;
225
- $[14] = t1;
226
- $[15] = t2;
227
- $[16] = t4;
228
- $[17] = t5;
229
- } else t5 = $[17];
230
- return t5;
243
+ $[18] = T0;
244
+ $[19] = children;
245
+ $[20] = props;
246
+ $[21] = ripple.handlers;
247
+ $[22] = t2;
248
+ $[23] = t4;
249
+ $[24] = t6;
250
+ $[25] = t7;
251
+ } else t7 = $[25];
252
+ return t7;
231
253
  }
232
254
  /**
233
255
  * The row the tree shows while it is fetching more. React Aria calls
@@ -241,11 +263,11 @@ function TreeLoadMore(t0) {
241
263
  let t1;
242
264
  let t2;
243
265
  if ($[0] !== t0) {
244
- const { label: t3, ...props$1 } = t0;
266
+ const { label: t3, ...props$2 } = t0;
245
267
  label = t3 === void 0 ? "Loading more" : t3;
246
268
  T0 = TreeLoadMoreItem;
247
- t1 = props$1;
248
- t2 = mergeStatefulStyles(props(collectionStyles.loading), props$1);
269
+ t1 = props$2;
270
+ t2 = mergeStatefulStyles(props(collectionStyles.loading), props$2);
249
271
  $[0] = t0;
250
272
  $[1] = T0;
251
273
  $[2] = label;
@@ -292,12 +314,12 @@ function TreeSection$1(t0) {
292
314
  let t1;
293
315
  let t2;
294
316
  if ($[0] !== t0) {
295
- const { children: t3, header: t4, ...props$2 } = t0;
317
+ const { children: t3, header: t4, ...props$3 } = t0;
296
318
  children = t3;
297
319
  header = t4;
298
320
  T0 = TreeSection;
299
- t1 = props$2;
300
- t2 = mergeStyles(props(collectionStyles.section), props$2);
321
+ t1 = props$3;
322
+ t2 = mergeStyles(props(collectionStyles.section), props$3);
301
323
  $[0] = t0;
302
324
  $[1] = T0;
303
325
  $[2] = children;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["ReactNode","TreeItemProps","RACTreeItemProps","TreeLoadMoreItemProps","RACTreeLoadMoreItemProps","TreeProps","RACTreeProps","TreeItemRenderProps","stylex","createContext","useContext","Button","RACButton","Tree","RACTree","TreeHeader","RACTreeHeader","TreeItem","RACTreeItem","TreeItemContent","RACTreeItemContent","TreeLoadMoreItem","RACTreeLoadMoreItem","TreeSection","RACTreeSection","CollectionLoadMore","collectionStyles","rowItemStyles","ChevronEndGlyph","RowContent","focus","mergeStatefulStyles","mergeStyles","colors","motion","radii","spacing","Checkbox","RACTreeSectionProps","Parameters","T","SelectLabelContext","styles","chevron","kGNEyG","kWkggS","kaIpWk","kMzoRj","kB7OPa","kMwMTN","kkrTdU","k1xSpc","kmuXW","kjj79g","kmVPX3","$$css","indent","kZCmMZ","TreeHeaderProps","children","Omit","TreeItemText","className","leading","style","supporting","trailing","headline","textValue","TreeLoadMoreProps","label","selectLabel","TreeSectionProps","header","chevronClassName","props","ring","chevronFor","state","hasChildItems","isExpanded","itemContent","isDisabled","isSelected","leadingFor","selects","selectionBehavior","selectionMode","textValueFor","undefined","t0","$","_c","T0","T1","t1","t2","t3","t4","container","t5","Symbol","for","TreeLoadMore","loading","section","Item","LoadMore","Section"],"sources":["../../../src/components/tree/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { TreeItemProps as RACTreeItemProps, TreeLoadMoreItemProps as RACTreeLoadMoreItemProps, TreeProps as RACTreeProps, TreeItemRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { createContext, useContext } from 'react';\nimport { Button as RACButton, Tree as RACTree, TreeHeader as RACTreeHeader, TreeItem as RACTreeItem, TreeItemContent as RACTreeItemContent, TreeLoadMoreItem as RACTreeLoadMoreItem, TreeSection as RACTreeSection } from 'react-aria-components';\nimport { CollectionLoadMore } from '../../collection';\nimport { collectionStyles, rowItemStyles } from '../../collection/styles';\nimport { ChevronEndGlyph } from '../../glyphs';\nimport { RowContent } from '../../row';\nimport { focus } from '../../styles/focus';\nimport { mergeStatefulStyles, mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, spacing } from '../../tokens/design.tokens.stylex';\nimport Checkbox from '../checkbox';\n\n// A list whose rows nest. Each row is the row every list here draws —\n// `src/row`, shared with ListItem, ListBox, List and Disclosure — so its\n// 56dp floor, body-large headline, body-medium supporting line, state layers\n// and disabled treatment are that module's, and a tree beside a list cannot\n// drift from it.\n//\n// The lists page gives no nesting: it draws one flat list. So the two things\n// a tree adds beyond that row are the library's own, and both are written\n// here with their reasons. The rest — the row, the selection colours, the\n// checkbox — is the page's, through the shared module.\n//\n// Four things are this component's own.\n//\n// **A level indents by one chevron's width.** React Aria puts the depth on\n// each row as a custom property, so the inset is one `calc` against the\n// row's own inline padding rather than a style per level. 24dp is the size\n// the menus page gives that glyph, which makes a level of nesting exactly as\n// wide as the caret that opens it.\n//\n// **The caret is a button, and React Aria names it.** A `slot=\"chevron\"`\n// button is what expands and collapses; React Aria labels it Expand or\n// Collapse and composes that with the row, so nothing here names it. It is\n// drawn only on a row that has children, since a caret on a leaf says the\n// row opens when it does not.\n//\n// **A selecting tree draws a checkbox, before whatever the row was given.**\n// Same rule as List: React Aria reports the mode on each row, so a tree that\n// toggles draws one without the call site repeating it, and it always sits\n// in the same place so a column of rows reads down.\n//\n// **`TreeItemContent` has no class to style.** React Aria renders it as a\n// `display: contents` gridcell with nothing on it, so the row's own layout\n// is drawn by what goes inside rather than by that wrapper.\n\n// `TreeSection`'s props are not re-exported from the package index, only its\n// component is — so the type is taken off the component rather than imported\n// by a name that is not there to import.\ntype RACTreeSectionProps<T> = Parameters<typeof RACTreeSection<T>>[0];\n\n// What each row's selection checkbox is called. A context rather than a prop\n// on the row, since it is the tree's decision and repeating it per row is\n// how the two drift.\nconst SelectLabelContext = createContext('Select');\nconst styles = {\n chevron: {\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xjbqb8w\",\n kaIpWk: \"x1dkaolv\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kMwMTN: \"x1w5n3ug\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x78zum5\",\n kmuXW: \"x2lah0s\",\n kjj79g: \"xl56j7k\",\n kmVPX3: \"x1717udv\",\n $$css: true\n },\n indent: {\n kZCmMZ: \"x1187sqy\",\n $$css: true\n }\n};\ntype TreeHeaderProps = {\n /** The section's heading. */\n children?: ReactNode;\n};\ntype TreeItemProps<T extends object = object> = Omit<RACTreeItemProps<T>, 'children' | 'className' | 'style' | 'textValue'> & TreeItemText & {\n /** The rows nested under this one, as further `Tree.Item` entries. */\n children?: ReactNode;\n /** A function may compute the class from the row's render state. */\n className?: RACTreeItemProps<T>['className'];\n /** Content before the headline: an avatar, an icon. */\n leading?: ReactNode;\n /** A function may compute the style from the row's render state. */\n style?: RACTreeItemProps<T>['style'];\n /** A second line under the headline, in the muted role. */\n supporting?: ReactNode;\n /** Content after the headline, such as a count or a control. */\n trailing?: ReactNode;\n};\n\n// What the row is worth as text, which React Aria requires: a tree row wraps\n// its headline in elements, so it cannot read one off the children the way a\n// plain-string child would give it. A string headline is taken as the value,\n// which is the common case; anything else has to say what it is worth, and\n// this is what makes the compiler ask rather than leaving a row unnamed.\ntype TreeItemText = {\n /** The row's headline — the one thing it is mostly about. */\n headline: string;\n /** What typeahead matches the row on. Defaults to the headline. */\n textValue?: string;\n} | {\n /** The row's headline, as something other than a plain string. */\n headline?: ReactNode;\n /** What typeahead matches the row on, and what names it. */\n textValue: string;\n};\ntype TreeLoadMoreProps = Omit<RACTreeLoadMoreItemProps, 'children'> & {\n /**\n * What the row says while it is loading. Read by a screen reader; the ring\n * itself carries no text.\n * @default 'Loading more'\n */\n label?: string;\n};\ntype TreeProps<T extends object = object> = Omit<RACTreeProps<T>, 'className' | 'style'> & {\n /** A function may compute the class from the tree's render state. */\n className?: RACTreeProps<T>['className'];\n /**\n * What each row's selection checkbox is called, for a screen reader. The\n * row's own text is what names the row; this names the box inside it.\n * @default 'Select'\n */\n selectLabel?: string;\n /** A function may compute the style from the tree's render state. */\n style?: RACTreeProps<T>['style'];\n};\ntype TreeSectionProps<T extends object = object> = Omit<RACTreeSectionProps<T>, 'children'> & {\n /**\n * The rows in the section. A section built from data puts React Aria's\n * `Collection` in here rather than a render function, since the header is\n * an element beside them.\n */\n children?: ReactNode;\n /**\n * The section's heading, rendered through React Aria's header so the\n * section is named by it. A section without one is a group with no name.\n */\n header?: ReactNode;\n};\n\n// The button itself never turns — the glyph inside it does, so the press\n// target stays a square whichever way the row is pointing.\nfunction chevronClassName() {\n return stylex.props(styles.chevron, focus.ring).className ?? '';\n}\n\n// The caret, or the space it would have taken. Written as a call rather than\n// inline at the prop, which is what react-perf's no-new-function-as-prop and\n// jsx-no-jsx-as-prop are after; the React Compiler memoises the result on\n// its inputs.\n//\n// A leaf gets the space rather than nothing, so its headline lines up with\n// the headline of a sibling that opens.\nfunction chevronFor(state: TreeItemRenderProps): ReactNode {\n if (!state.hasChildItems) {\n return <span className=\"xxk0z11 x2lah0s xvy4d1p\" />;\n }\n return <RACButton className={chevronClassName} slot=\"chevron\">\n <ChevronEndGlyph {...{\n 0: {\n className: \"x12w9bfk xxk0z11 xvy4d1p x19axjrm x1c071of xkzkux9 x11xpdln xpc4ca7\"\n },\n 1: {\n className: \"x12w9bfk xxk0z11 xvy4d1p xkzkux9 x11xpdln xpc4ca7 x1y10d4b x1iffjtl\"\n }\n }[!!state.isExpanded << 0]} />\n </RACButton>;\n}\n\n// What a row draws, from React Aria's render state. The caret comes first,\n// then the selection checkbox, then whatever the row was given — one order,\n// always, which is what keeps a column of rows reading down.\nfunction itemContent(headline: ReactNode, leading: ReactNode, supporting: ReactNode, trailing: ReactNode, selectLabel: string) {\n return (state: TreeItemRenderProps): ReactNode => <RowContent isDisabled={state.isDisabled} isSelected={state.isSelected} leading={leadingFor(state, leading, selectLabel)} supporting={supporting} trailing={trailing}>\n {headline}\n </RowContent>;\n}\n\n// StyleX cannot target `[data-selected]` on the element it is styling, so a\n// row's state comes from the render state React Aria hands its className.\n// The order matters: `disabled` is applied last so it wins over both the\n// interactive and the selected branches, and StyleX replaces a property\n// whole, so it takes their hover states with it.\n//\n// A supporting line moves the row from the page's one-line container height\n// to its two-line one, which is a floor rather than something the row's own\n// box arrives at — see `twoLine` in `src/row/styles.ts`. Taken as an\n// argument rather than read from the render state, since React Aria reports\n// what a row is doing and not what it holds; the row is built by a call for\n// the same reason `itemContent` is.\n/**\n * The caret, the selection checkbox, then whatever the row was given. Its\n * return type is written out rather than inferred: `ReactNode` is a union\n * that includes a promise, and a function inferred as returning one has to\n * be `async`.\n */\nfunction leadingFor(state: TreeItemRenderProps, leading: ReactNode, selectLabel: string): ReactNode {\n const selects = state.selectionBehavior === 'toggle' && state.selectionMode !== 'none';\n return <>\n {chevronFor(state)}\n {selects ? <Checkbox aria-label={selectLabel} slot=\"selection\" /> : null}\n {leading}\n </>;\n}\n\n// What React Aria matches typeahead on, and what names the row. `TreeItemText`\n// makes one of the two a string, so the last branch is unreachable through the\n// public type — it is there because destructuring the two apart is what loses\n// the narrowing, not because a row can arrive without either.\nfunction textValueFor(textValue: string | undefined, headline: ReactNode) {\n if (textValue !== undefined) {\n return textValue;\n }\n return typeof headline === 'string' ? headline : '';\n}\n\n/**\n * A list whose rows nest. Which rows are open is React Aria's: pass\n * `expandedKeys` with `onExpandedChange` to control it, or\n * `defaultExpandedKeys` to let it keep its own. Selection is React Aria's\n * too — set `selectionMode` to `single` or `multiple`.\n *\n * ```tsx\n * <Tree aria-label=\"Label\">\n * <Tree.Item headline=\"First item\" id=\"first\">\n * <Tree.Item headline=\"Second item\" id=\"second\" />\n * </Tree.Item>\n * </Tree>\n * ```\n *\n * Each row is the row every list here draws, indented by its depth, with a\n * caret on the rows that have children. Name the tree with `aria-label` or\n * `aria-labelledby` — nothing here labels it for you.\n *\n * The call site's `className` and `style` land on the container, which is\n * the element a layout positions.\n */\nfunction Tree<T extends object>({\n selectLabel = 'Select',\n ...props\n}: TreeProps<T>) {\n return <SelectLabelContext value={selectLabel}>\n <RACTree<T> {...props} {...mergeStatefulStyles(stylex.props(collectionStyles.container), props)} />\n </SelectLabelContext>;\n}\n\n/**\n * A named group of rows. `header` names it, and is what a screen reader\n * reads before the rows inside.\n */\nfunction TreeHeader({\n children\n}: TreeHeaderProps) {\n return <RACTreeHeader {...stylex.props(collectionStyles.header)}>\n {children}\n </RACTreeHeader>;\n}\n\n/**\n * One row, and the rows under it. Its slots are the row's: `leading`, the\n * `headline`, `supporting` under it, and `trailing`. Give every row an `id`\n * — that is the key selection and expansion are reported by.\n *\n * Rows nested as `children` are what make it a branch; a row with none is a\n * leaf and draws no caret. `textValue` is what typeahead matches on, and is\n * taken from a plain-string headline when it is not given.\n */\nfunction TreeItem<T extends object = object>({\n children,\n headline,\n leading,\n supporting,\n textValue,\n trailing,\n ...props\n}: TreeItemProps<T>) {\n const selectLabel = useContext(SelectLabelContext);\n return <RACTreeItem<T> textValue={textValueFor(textValue, headline)} {...props} {...mergeStatefulStyles(\n // No overline: a tree row takes the list variant's metrics because it\n // looks like a list row, but it follows its own page, and that page\n // gives a headline and a supporting line. The three-line item belongs\n // to the lists page, which `List.Item` and `ListBox.Item` draw.\n rowItemStyles(supporting, undefined, styles.indent), props)}>\n <RACTreeItemContent>\n {itemContent(headline, leading, supporting, trailing, selectLabel)}\n </RACTreeItemContent>\n {children}\n </RACTreeItem>;\n}\n\n/**\n * The row the tree shows while it is fetching more. React Aria calls\n * `onLoadMore` when this comes into view, and draws it only while\n * `isLoading`.\n */\nfunction TreeLoadMore({\n label = 'Loading more',\n ...props\n}: TreeLoadMoreProps) {\n return <RACTreeLoadMoreItem {...props} {...mergeStatefulStyles(stylex.props(collectionStyles.loading), props)}>\n <CollectionLoadMore label={label} size=\"24px\" />\n </RACTreeLoadMoreItem>;\n}\n\n/**\n * A named group of rows, with its heading above them.\n */\nfunction TreeSection<T extends object = object>({\n children,\n header,\n ...props\n}: TreeSectionProps<T>) {\n return <RACTreeSection<T> {...props} {...mergeStyles(stylex.props(collectionStyles.section), props)}>\n {header === undefined ? null : <TreeHeader>{header}</TreeHeader>}\n {children}\n </RACTreeSection>;\n}\nTree.Item = TreeItem;\nTree.LoadMore = TreeLoadMore;\nTree.Section = TreeSection;\nexport type { TreeHeaderProps, TreeItemProps, TreeLoadMoreProps, TreeProps, TreeSectionProps };\nexport default Tree;"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["ReactNode","TreeItemProps","RACTreeItemProps","TreeLoadMoreItemProps","RACTreeLoadMoreItemProps","TreeProps","RACTreeProps","TreeItemRenderProps","stylex","createContext","useContext","Button","RACButton","Tree","RACTree","TreeHeader","RACTreeHeader","TreeItem","RACTreeItem","TreeItemContent","RACTreeItemContent","TreeLoadMoreItem","RACTreeLoadMoreItem","TreeSection","RACTreeSection","CollectionLoadMore","collectionStyles","rowItemStyles","ChevronEndGlyph","useRipple","RowContent","focus","mergeStatefulStyles","mergeStyles","colors","motion","radii","spacing","Checkbox","RACTreeSectionProps","Parameters","T","SelectLabelContext","styles","chevron","kGNEyG","kWkggS","kaIpWk","kMzoRj","kB7OPa","kMwMTN","kkrTdU","k1xSpc","kmuXW","kjj79g","kmVPX3","$$css","indent","kZCmMZ","TreeHeaderProps","children","Omit","TreeItemText","className","leading","style","supporting","trailing","headline","textValue","TreeLoadMoreProps","label","selectLabel","TreeSectionProps","header","chevronClassName","props","ring","chevronFor","state","hasChildItems","isExpanded","itemContent","ripple","isDisabled","isSelected","leadingFor","selects","selectionBehavior","selectionMode","textValueFor","undefined","t0","$","_c","T0","T1","t1","t2","t3","t4","container","t5","Symbol","for","onContextMenu","onPointerCancel","onPointerDown","onPointerLeave","onPointerUp","handlers","surface","t6","t7","TreeLoadMore","loading","section","Item","LoadMore","Section"],"sources":["../../../src/components/tree/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { TreeItemProps as RACTreeItemProps, TreeLoadMoreItemProps as RACTreeLoadMoreItemProps, TreeProps as RACTreeProps, TreeItemRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { createContext, useContext } from 'react';\nimport { Button as RACButton, Tree as RACTree, TreeHeader as RACTreeHeader, TreeItem as RACTreeItem, TreeItemContent as RACTreeItemContent, TreeLoadMoreItem as RACTreeLoadMoreItem, TreeSection as RACTreeSection } from 'react-aria-components';\nimport { CollectionLoadMore } from '../../collection';\nimport { collectionStyles, rowItemStyles } from '../../collection/styles';\nimport { ChevronEndGlyph } from '../../glyphs';\nimport { useRipple } from '../../hooks/useRipple';\nimport { RowContent } from '../../row';\nimport { focus } from '../../styles/focus';\nimport { mergeStatefulStyles, mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, spacing } from '../../tokens/design.tokens.stylex';\nimport Checkbox from '../checkbox';\n\n// A list whose rows nest. Each row is the row every list here draws —\n// `src/row`, shared with ListItem, ListBox, List and Disclosure — so its\n// 56dp floor, body-large headline, body-medium supporting line, state layers\n// and disabled treatment are that module's, and a tree beside a list cannot\n// drift from it.\n//\n// The lists page gives no nesting: it draws one flat list. So the two things\n// a tree adds beyond that row are the library's own, and both are written\n// here with their reasons. The rest — the row, the selection colours, the\n// checkbox — is the page's, through the shared module.\n//\n// Four things are this component's own.\n//\n// **A level indents by one chevron's width.** React Aria puts the depth on\n// each row as a custom property, so the inset is one `calc` against the\n// row's own inline padding rather than a style per level. 24dp is the size\n// the menus page gives that glyph, which makes a level of nesting exactly as\n// wide as the caret that opens it.\n//\n// **The caret is a button, and React Aria names it.** A `slot=\"chevron\"`\n// button is what expands and collapses; React Aria labels it Expand or\n// Collapse and composes that with the row, so nothing here names it. It is\n// drawn only on a row that has children, since a caret on a leaf says the\n// row opens when it does not.\n//\n// **A selecting tree draws a checkbox, before whatever the row was given.**\n// Same rule as List: React Aria reports the mode on each row, so a tree that\n// toggles draws one without the call site repeating it, and it always sits\n// in the same place so a column of rows reads down.\n//\n// **`TreeItemContent` has no class to style.** React Aria renders it as a\n// `display: contents` gridcell with nothing on it, so the row's own layout\n// is drawn by what goes inside rather than by that wrapper.\n\n// `TreeSection`'s props are not re-exported from the package index, only its\n// component is — so the type is taken off the component rather than imported\n// by a name that is not there to import.\ntype RACTreeSectionProps<T> = Parameters<typeof RACTreeSection<T>>[0];\n\n// What each row's selection checkbox is called. A context rather than a prop\n// on the row, since it is the tree's decision and repeating it per row is\n// how the two drift.\nconst SelectLabelContext = createContext('Select');\nconst styles = {\n chevron: {\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xjbqb8w\",\n kaIpWk: \"x1dkaolv\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kMwMTN: \"x1w5n3ug\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x78zum5\",\n kmuXW: \"x2lah0s\",\n kjj79g: \"xl56j7k\",\n kmVPX3: \"x1717udv\",\n $$css: true\n },\n indent: {\n kZCmMZ: \"x1187sqy\",\n $$css: true\n }\n};\ntype TreeHeaderProps = {\n /** The section's heading. */\n children?: ReactNode;\n};\ntype TreeItemProps<T extends object = object> = Omit<RACTreeItemProps<T>, 'children' | 'className' | 'style' | 'textValue'> & TreeItemText & {\n /** The rows nested under this one, as further `Tree.Item` entries. */\n children?: ReactNode;\n /** A function may compute the class from the row's render state. */\n className?: RACTreeItemProps<T>['className'];\n /** Content before the headline: an avatar, an icon. */\n leading?: ReactNode;\n /** A function may compute the style from the row's render state. */\n style?: RACTreeItemProps<T>['style'];\n /** A second line under the headline, in the muted role. */\n supporting?: ReactNode;\n /** Content after the headline, such as a count or a control. */\n trailing?: ReactNode;\n};\n\n// What the row is worth as text, which React Aria requires: a tree row wraps\n// its headline in elements, so it cannot read one off the children the way a\n// plain-string child would give it. A string headline is taken as the value,\n// which is the common case; anything else has to say what it is worth, and\n// this is what makes the compiler ask rather than leaving a row unnamed.\ntype TreeItemText = {\n /** The row's headline — the one thing it is mostly about. */\n headline: string;\n /** What typeahead matches the row on. Defaults to the headline. */\n textValue?: string;\n} | {\n /** The row's headline, as something other than a plain string. */\n headline?: ReactNode;\n /** What typeahead matches the row on, and what names it. */\n textValue: string;\n};\ntype TreeLoadMoreProps = Omit<RACTreeLoadMoreItemProps, 'children'> & {\n /**\n * What the row says while it is loading. Read by a screen reader; the ring\n * itself carries no text.\n * @default 'Loading more'\n */\n label?: string;\n};\ntype TreeProps<T extends object = object> = Omit<RACTreeProps<T>, 'className' | 'style'> & {\n /** A function may compute the class from the tree's render state. */\n className?: RACTreeProps<T>['className'];\n /**\n * What each row's selection checkbox is called, for a screen reader. The\n * row's own text is what names the row; this names the box inside it.\n * @default 'Select'\n */\n selectLabel?: string;\n /** A function may compute the style from the tree's render state. */\n style?: RACTreeProps<T>['style'];\n};\ntype TreeSectionProps<T extends object = object> = Omit<RACTreeSectionProps<T>, 'children'> & {\n /**\n * The rows in the section. A section built from data puts React Aria's\n * `Collection` in here rather than a render function, since the header is\n * an element beside them.\n */\n children?: ReactNode;\n /**\n * The section's heading, rendered through React Aria's header so the\n * section is named by it. A section without one is a group with no name.\n */\n header?: ReactNode;\n};\n\n// The button itself never turns — the glyph inside it does, so the press\n// target stays a square whichever way the row is pointing.\nfunction chevronClassName() {\n return stylex.props(styles.chevron, focus.ring).className ?? '';\n}\n\n// The caret, or the space it would have taken. Written as a call rather than\n// inline at the prop, which is what react-perf's no-new-function-as-prop and\n// jsx-no-jsx-as-prop are after; the React Compiler memoises the result on\n// its inputs.\n//\n// A leaf gets the space rather than nothing, so its headline lines up with\n// the headline of a sibling that opens.\nfunction chevronFor(state: TreeItemRenderProps): ReactNode {\n if (!state.hasChildItems) {\n return <span className=\"xxk0z11 x2lah0s xvy4d1p\" />;\n }\n return <RACButton className={chevronClassName} slot=\"chevron\">\n <ChevronEndGlyph {...{\n 0: {\n className: \"x12w9bfk xxk0z11 xvy4d1p x19axjrm x1c071of xkzkux9 x11xpdln xpc4ca7\"\n },\n 1: {\n className: \"x12w9bfk xxk0z11 xvy4d1p xkzkux9 x11xpdln xpc4ca7 x1y10d4b x1iffjtl\"\n }\n }[!!state.isExpanded << 0]} />\n </RACButton>;\n}\n\n// What a row draws, from React Aria's render state. The caret comes first,\n// then the selection checkbox, then whatever the row was given — one order,\n// always, which is what keeps a column of rows reading down.\nfunction itemContent(headline: ReactNode, leading: ReactNode, supporting: ReactNode, trailing: ReactNode, selectLabel: string, ripple: ReactNode) {\n return (state: TreeItemRenderProps): ReactNode => <>\n <RowContent isDisabled={state.isDisabled} isSelected={state.isSelected} leading={leadingFor(state, leading, selectLabel)} supporting={supporting} trailing={trailing}>\n {headline}\n </RowContent>\n {state.isDisabled ? null : ripple}\n </>;\n}\n\n// StyleX cannot target `[data-selected]` on the element it is styling, so a\n// row's state comes from the render state React Aria hands its className.\n// The order matters: `disabled` is applied last so it wins over both the\n// interactive and the selected branches, and StyleX replaces a property\n// whole, so it takes their hover states with it.\n//\n// A supporting line moves the row from the page's one-line container height\n// to its two-line one, which is a floor rather than something the row's own\n// box arrives at — see `twoLine` in `src/row/styles.ts`. Taken as an\n// argument rather than read from the render state, since React Aria reports\n// what a row is doing and not what it holds; the row is built by a call for\n// the same reason `itemContent` is.\n/**\n * The caret, the selection checkbox, then whatever the row was given. Its\n * return type is written out rather than inferred: `ReactNode` is a union\n * that includes a promise, and a function inferred as returning one has to\n * be `async`.\n */\nfunction leadingFor(state: TreeItemRenderProps, leading: ReactNode, selectLabel: string): ReactNode {\n const selects = state.selectionBehavior === 'toggle' && state.selectionMode !== 'none';\n return <>\n {chevronFor(state)}\n {selects ? <Checkbox aria-label={selectLabel} slot=\"selection\" /> : null}\n {leading}\n </>;\n}\n\n// What React Aria matches typeahead on, and what names the row. `TreeItemText`\n// makes one of the two a string, so the last branch is unreachable through the\n// public type — it is there because destructuring the two apart is what loses\n// the narrowing, not because a row can arrive without either.\nfunction textValueFor(textValue: string | undefined, headline: ReactNode) {\n if (textValue !== undefined) {\n return textValue;\n }\n return typeof headline === 'string' ? headline : '';\n}\n\n/**\n * A list whose rows nest. Which rows are open is React Aria's: pass\n * `expandedKeys` with `onExpandedChange` to control it, or\n * `defaultExpandedKeys` to let it keep its own. Selection is React Aria's\n * too — set `selectionMode` to `single` or `multiple`.\n *\n * ```tsx\n * <Tree aria-label=\"Label\">\n * <Tree.Item headline=\"First item\" id=\"first\">\n * <Tree.Item headline=\"Second item\" id=\"second\" />\n * </Tree.Item>\n * </Tree>\n * ```\n *\n * Each row is the row every list here draws, indented by its depth, with a\n * caret on the rows that have children. Name the tree with `aria-label` or\n * `aria-labelledby` — nothing here labels it for you.\n *\n * The call site's `className` and `style` land on the container, which is\n * the element a layout positions.\n */\nfunction Tree<T extends object>({\n selectLabel = 'Select',\n ...props\n}: TreeProps<T>) {\n return <SelectLabelContext value={selectLabel}>\n <RACTree<T> {...props} {...mergeStatefulStyles(stylex.props(collectionStyles.container), props)} />\n </SelectLabelContext>;\n}\n\n/**\n * A named group of rows. `header` names it, and is what a screen reader\n * reads before the rows inside.\n */\nfunction TreeHeader({\n children\n}: TreeHeaderProps) {\n return <RACTreeHeader {...stylex.props(collectionStyles.header)}>\n {children}\n </RACTreeHeader>;\n}\n\n/**\n * One row, and the rows under it. Its slots are the row's: `leading`, the\n * `headline`, `supporting` under it, and `trailing`. Give every row an `id`\n * — that is the key selection and expansion are reported by.\n *\n * Rows nested as `children` are what make it a branch; a row with none is a\n * leaf and draws no caret. `textValue` is what typeahead matches on, and is\n * taken from a plain-string headline when it is not given.\n */\nfunction TreeItem<T extends object = object>({\n children,\n headline,\n leading,\n onContextMenu,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp,\n supporting,\n textValue,\n trailing,\n ...props\n}: TreeItemProps<T>) {\n const selectLabel = useContext(SelectLabelContext);\n // The press ripple List's rows draw — see ListItem there.\n const ripple = useRipple<HTMLDivElement>(true, {\n onContextMenu,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp\n }, true);\n return <RACTreeItem<T> textValue={textValueFor(textValue, headline)} {...ripple.handlers} {...props} {...mergeStatefulStyles(\n // No overline: a tree row takes the list variant's metrics because it\n // looks like a list row, but it follows its own page, and that page\n // gives a headline and a supporting line. The three-line item belongs\n // to the lists page, which `List.Item` and `ListBox.Item` draw.\n rowItemStyles(supporting, undefined, styles.indent), props)}>\n <RACTreeItemContent>\n {itemContent(headline, leading, supporting, trailing, selectLabel, ripple.surface)}\n </RACTreeItemContent>\n {children}\n </RACTreeItem>;\n}\n\n/**\n * The row the tree shows while it is fetching more. React Aria calls\n * `onLoadMore` when this comes into view, and draws it only while\n * `isLoading`.\n */\nfunction TreeLoadMore({\n label = 'Loading more',\n ...props\n}: TreeLoadMoreProps) {\n return <RACTreeLoadMoreItem {...props} {...mergeStatefulStyles(stylex.props(collectionStyles.loading), props)}>\n <CollectionLoadMore label={label} size=\"24px\" />\n </RACTreeLoadMoreItem>;\n}\n\n/**\n * A named group of rows, with its heading above them.\n */\nfunction TreeSection<T extends object = object>({\n children,\n header,\n ...props\n}: TreeSectionProps<T>) {\n return <RACTreeSection<T> {...props} {...mergeStyles(stylex.props(collectionStyles.section), props)}>\n {header === undefined ? null : <TreeHeader>{header}</TreeHeader>}\n {children}\n </RACTreeSection>;\n}\nTree.Item = TreeItem;\nTree.LoadMore = TreeLoadMore;\nTree.Section = TreeSection;\nexport type { TreeHeaderProps, TreeItemProps, TreeLoadMoreProps, TreeProps, TreeSectionProps };\nexport default Tree;"],"mappings":"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"}
@@ -20,19 +20,26 @@ function useImageLoadingStatus(src) {
20
20
  if ($[0] !== src) {
21
21
  t0 = () => {
22
22
  if (src === void 0) return;
23
- let mounted = true;
24
- const settle = (status) => () => {
25
- if (mounted) setSettled({
23
+ const onLoad = () => {
24
+ setSettled({
26
25
  src,
27
- status
26
+ status: "loaded"
27
+ });
28
+ };
29
+ const onError = () => {
30
+ setSettled({
31
+ src,
32
+ status: "error"
28
33
  });
29
34
  };
30
35
  const image = new window.Image();
31
- image.addEventListener("load", settle("loaded"), { once: true });
32
- image.addEventListener("error", settle("error"), { once: true });
36
+ image.addEventListener("load", onLoad, { once: true });
37
+ image.addEventListener("error", onError, { once: true });
33
38
  image.src = src;
34
39
  return () => {
35
- mounted = false;
40
+ image.removeEventListener("load", onLoad);
41
+ image.removeEventListener("error", onError);
42
+ image.removeAttribute("src");
36
43
  };
37
44
  };
38
45
  t1 = [src];
@@ -1 +1 @@
1
- {"version":3,"file":"useImageLoadingStatus.js","names":["useEffect","useState","ImageLoadingStatus","Settled","src","status","useImageLoadingStatus","$","_c","settled","setSettled","t0","t1","undefined","mounted","settle","image","window","Image","addEventListener","once"],"sources":["../../src/hooks/useImageLoadingStatus.ts"],"sourcesContent":["import { useEffect, useState } from 'react'\n\ntype ImageLoadingStatus = 'error' | 'loaded' | 'loading'\n\ninterface Settled {\n src: string\n status: 'error' | 'loaded'\n}\n\n/**\n * Whether an image at `src` can be shown yet. It is loaded off-screen first,\n * so a component can keep its fallback in place until the picture is ready\n * and bring the fallback back if the picture fails — an `<img>` swapped in\n * as soon as `src` is known would show the browser's broken-image glyph in\n * between.\n *\n * No `src` counts as a failure, since the outcome is the same: the fallback\n * shows. What settled is remembered against the `src` it settled for, so a\n * change of `src` reads as loading again rather than as the old outcome.\n */\nfunction useImageLoadingStatus(src: string | undefined): ImageLoadingStatus {\n const [settled, setSettled] = useState<null | Settled>(null)\n\n useEffect(() => {\n if (src === undefined) {\n return undefined\n }\n\n let mounted = true\n const settle = (status: Settled['status']) => () => {\n if (mounted) {\n setSettled({ src, status })\n }\n }\n\n const image = new window.Image()\n image.addEventListener('load', settle('loaded'), { once: true })\n image.addEventListener('error', settle('error'), { once: true })\n image.src = src\n\n return () => {\n mounted = false\n }\n }, [src])\n\n if (src === undefined) {\n return 'error'\n }\n return settled?.src === src ? settled.status : 'loading'\n}\n\nexport type { ImageLoadingStatus }\n\nexport { useImageLoadingStatus }\n"],"mappings":";;;;;;;;;;;;;;AAoBA,SAAAM,sBAAAF,KAAA;CAAA,MAAAG,IAAAC,EAAA,CAAA;CACE,MAAA,CAAAC,SAAAC,cAA8BT,SAAyB,IAAI;CAAC,IAAAU;CAAA,IAAAC;CAAA,IAAAL,EAAA,OAAAH,KAAA;EAElDO,WAAA;GACR,IAAIP,QAAQS,KAAAA,GAAS;GAIrB,IAAAC,UAAc;GACd,MAAAC,UAAeV,iBAA+B;IAC5C,IAAIS,SACFJ,WAAW;KAAAN;KAAAC;IAAc,CAAC;GAC3B;GAGH,MAAAW,QAAc,IAAIC,OAAMC,MAAO;GAC/BF,MAAKG,iBAAkB,QAAQJ,OAAO,QAAQ,GAAG,EAAAK,MAAQ,KAAK,CAAC;GAC/DJ,MAAKG,iBAAkB,SAASJ,OAAO,OAAO,GAAG,EAAAK,MAAQ,KAAK,CAAC;GAC/DJ,MAAKZ,MAAOA;GAAH,aAEF;IACLU,UAAUA;GAAH;EACR;EACAF,KAAA,CAACR,GAAG;EAACG,EAAA,KAAAH;EAAAG,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;CAAA,OAAA;EAAAD,KAAAJ,EAAA;EAAAK,KAAAL,EAAA;CAAA;CApBRP,UAAUW,IAoBPC,EAAK;CAER,IAAIR,QAAQS,KAAAA,GAAS,OACZ;CACR,OACMJ,SAAOL,QAAUA,MAAMK,QAAOJ,SAA9B;AAAiD"}
1
+ {"version":3,"file":"useImageLoadingStatus.js","names":["useEffect","useState","ImageLoadingStatus","Settled","src","status","useImageLoadingStatus","$","_c","settled","setSettled","t0","t1","undefined","onLoad","onError","image","window","Image","addEventListener","once","removeEventListener","removeAttribute"],"sources":["../../src/hooks/useImageLoadingStatus.ts"],"sourcesContent":["import { useEffect, useState } from 'react'\n\ntype ImageLoadingStatus = 'error' | 'loaded' | 'loading'\n\ninterface Settled {\n src: string\n status: 'error' | 'loaded'\n}\n\n/**\n * Whether an image at `src` can be shown yet. It is loaded off-screen first,\n * so a component can keep its fallback in place until the picture is ready\n * and bring the fallback back if the picture fails — an `<img>` swapped in\n * as soon as `src` is known would show the browser's broken-image glyph in\n * between.\n *\n * No `src` counts as a failure, since the outcome is the same: the fallback\n * shows. What settled is remembered against the `src` it settled for, so a\n * change of `src` reads as loading again rather than as the old outcome.\n */\nfunction useImageLoadingStatus(src: string | undefined): ImageLoadingStatus {\n const [settled, setSettled] = useState<null | Settled>(null)\n\n useEffect(() => {\n if (src === undefined) {\n return undefined\n }\n\n const onLoad = () => {\n setSettled({ src, status: 'loaded' })\n }\n const onError = () => {\n setSettled({ src, status: 'error' })\n }\n\n const image = new window.Image()\n image.addEventListener('load', onLoad, { once: true })\n image.addEventListener('error', onError, { once: true })\n image.src = src\n\n // A load `src` has moved on from, or one the component went before, is\n // stopped rather than left to run. Taking the listeners off is what keeps\n // it from reporting an outcome nobody asked for, and lets the image go\n // once nothing else holds it; removing its source aborts the fetch. That\n // is the source removed rather than set empty, which would also abort it\n // but queue an `error` event on the way.\n return () => {\n image.removeEventListener('load', onLoad)\n image.removeEventListener('error', onError)\n image.removeAttribute('src')\n }\n }, [src])\n\n if (src === undefined) {\n return 'error'\n }\n return settled?.src === src ? settled.status : 'loading'\n}\n\nexport type { ImageLoadingStatus }\n\nexport { useImageLoadingStatus }\n"],"mappings":";;;;;;;;;;;;;;AAoBA,SAAAM,sBAAAF,KAAA;CAAA,MAAAG,IAAAC,EAAA,CAAA;CACE,MAAA,CAAAC,SAAAC,cAA8BT,SAAyB,IAAI;CAAC,IAAAU;CAAA,IAAAC;CAAA,IAAAL,EAAA,OAAAH,KAAA;EAElDO,WAAA;GACR,IAAIP,QAAQS,KAAAA,GAAS;GAIrB,MAAAC,eAAe;IACbJ,WAAW;KAAAN;KAAAC,QAAe;IAAS,CAAC;GAAC;GAEvC,MAAAU,gBAAgB;IACdL,WAAW;KAAAN;KAAAC,QAAe;IAAQ,CAAC;GAAC;GAGtC,MAAAW,QAAc,IAAIC,OAAMC,MAAO;GAC/BF,MAAKG,iBAAkB,QAAQL,QAAQ,EAAAM,MAAQ,KAAK,CAAC;GACrDJ,MAAKG,iBAAkB,SAASJ,SAAS,EAAAK,MAAQ,KAAK,CAAC;GACvDJ,MAAKZ,MAAOA;GAAH,aAQF;IACLY,MAAKK,oBAAqB,QAAQP,MAAM;IACxCE,MAAKK,oBAAqB,SAASN,OAAO;IAC1CC,MAAKM,gBAAiB,KAAK;GAAC;EAC7B;EACAV,KAAA,CAACR,GAAG;EAACG,EAAA,KAAAH;EAAAG,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;CAAA,OAAA;EAAAD,KAAAJ,EAAA;EAAAK,KAAAL,EAAA;CAAA;CA5BRP,UAAUW,IA4BPC,EAAK;CAER,IAAIR,QAAQS,KAAAA,GAAS,OACZ;CACR,OACMJ,SAAOL,QAAUA,MAAMK,QAAOJ,SAA9B;AAAiD"}