@allxsmith/bestax-bulma 5.32.0 → 5.33.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.
Files changed (33) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/Avatars.js +4 -21
  4. package/dist/esm/components/Avatars.js.map +1 -1
  5. package/dist/esm/components/Collapses.js +1 -20
  6. package/dist/esm/components/Collapses.js.map +1 -1
  7. package/dist/esm/elements/Kbd.js +86 -0
  8. package/dist/esm/elements/Kbd.js.map +1 -0
  9. package/dist/esm/helpers/flattenChildren.js +35 -0
  10. package/dist/esm/helpers/flattenChildren.js.map +1 -0
  11. package/dist/extras.css +1 -1
  12. package/dist/extras.css.map +1 -1
  13. package/dist/index.cjs +177 -108
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.esm.js +1 -0
  16. package/dist/index.esm.js.map +1 -1
  17. package/dist/types/elements/Kbd.d.ts +100 -0
  18. package/dist/types/helpers/flattenChildren.d.ts +16 -0
  19. package/dist/types/index.d.ts +1 -0
  20. package/dist/types-cjs/elements/Kbd.d.ts +100 -0
  21. package/dist/types-cjs/helpers/flattenChildren.d.ts +16 -0
  22. package/dist/types-cjs/index.d.ts +1 -0
  23. package/dist/versions/bestax-no-dark-mode.css +1 -1
  24. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  25. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  26. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  27. package/dist/versions/bestax-no-helpers.css +1 -1
  28. package/dist/versions/bestax-no-helpers.css.map +1 -1
  29. package/dist/versions/bestax-prefixed.css +1 -1
  30. package/dist/versions/bestax-prefixed.css.map +1 -1
  31. package/package.json +1 -1
  32. package/src/scss/elements/_index.scss +1 -0
  33. package/src/scss/elements/_kbd.scss +86 -0
@@ -6,6 +6,7 @@ import { withSubComponents } from '../helpers/withSubComponents.js';
6
6
  import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
7
7
  import { Collapse } from './Collapse.js';
8
8
  import { CollapsesItemContext } from './collapsesContext.js';
9
+ import { flattenChildren } from '../helpers/flattenChildren.js';
9
10
 
10
11
  /** Either mode's value as the list of open indexes. */
11
12
  function toIndexes(value) {
@@ -13,26 +14,6 @@ function toIndexes(value) {
13
14
  return value;
14
15
  return typeof value === 'number' ? [value] : [];
15
16
  }
16
- /**
17
- * Flattens Fragment children (recursively) so each item inside one gets its
18
- * own index rather than sharing the fragment's. Children.toArray keys restart
19
- * at ".0" inside each fragment, so those children are re-keyed with the
20
- * fragment's own key as a prefix, the way Avatars does it.
21
- */
22
- function flattenChildren(children, keyPrefix = '') {
23
- return React.Children.toArray(children).flatMap(child => {
24
- if (!React.isValidElement(child))
25
- return [child];
26
- if (child.type === React.Fragment) {
27
- return flattenChildren(child.props.children, keyPrefix + child.key);
28
- }
29
- return [
30
- keyPrefix
31
- ? React.cloneElement(child, { key: keyPrefix + child.key })
32
- : child,
33
- ];
34
- });
35
- }
36
17
  /**
37
18
  * The `Collapses` component groups `Collapse` items into an accordion that keeps one item open at a time, or any number with `multiple`.
38
19
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Collapses.js","sources":["../../../src/components/Collapses.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { Collapse } from './Collapse';\nimport { CollapsesItemContext } from './collapsesContext';\n\n/**\n * Props shared by both modes of the Collapses component.\n */\ninterface CollapsesBaseProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'color' | 'defaultValue' | 'onChange'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Joins the items into one block, with no gap between them and only the outer corners rounded. The joins show on `bordered` items. */\n seamless?: boolean;\n /** Additional CSS classes to apply. */\n className?: string;\n /** The `Collapse` items. Each child element is one item, indexed from 0 in order, with the children of a fragment counted one by one. A child that sets its own `open` keeps it: the group leaves that item alone. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for Collapses in single mode, the accordion: opening one item closes the others.\n */\nexport interface CollapsesSingleProps extends CollapsesBaseProps {\n /**\n * Lets items open independently. Without it, opening one item closes the others.\n * @defaultValue false\n */\n multiple?: false;\n /** Controlled open items: the index of the open item, or `null` for none. With `multiple`, an array of indexes. An index is a position among the children, so rendering an item conditionally or reordering them moves the open state onto a neighbour: render every item and hide one with `visibility=\"hidden\"`, or keep `value` in step yourself. */\n value?: number | null;\n /** Open items for uncontrolled use, as an index or `null` (the default, none open). With `multiple`, an array of indexes, empty by default. Indexes are positions among the children, as for `value`. */\n defaultValue?: number | null;\n /** Called with the new open items each time a trigger asks for a change, whether or not `value` is set: an index or `null`, or with `multiple` an array of indexes in ascending order. Indexes are positions among the children, as for `value`. */\n onChange?: (value: number | null) => void;\n}\n\n/**\n * Props for Collapses with `multiple`: items open and close independently.\n */\nexport interface CollapsesMultipleProps extends CollapsesBaseProps {\n /**\n * Lets items open independently. Without it, opening one item closes the others.\n * @defaultValue false\n */\n multiple: true;\n /** Controlled open items: the index of the open item, or `null` for none. With `multiple`, an array of indexes. An index is a position among the children, so rendering an item conditionally or reordering them moves the open state onto a neighbour: render every item and hide one with `visibility=\"hidden\"`, or keep `value` in step yourself. */\n value?: number[];\n /** Open items for uncontrolled use, as an index or `null` (the default, none open). With `multiple`, an array of indexes, empty by default. Indexes are positions among the children, as for `value`. */\n defaultValue?: number[];\n /** Called with the new open items each time a trigger asks for a change, whether or not `value` is set: an index or `null`, or with `multiple` an array of indexes in ascending order. Indexes are positions among the children, as for `value`. */\n onChange?: (value: number[]) => void;\n}\n\n/**\n * Props for the Collapses component, a discriminated union on `multiple`: the open items are an index (or `null`) in single mode and an array of indexes with `multiple`.\n */\nexport type CollapsesProps = CollapsesSingleProps | CollapsesMultipleProps;\n\n/** Either mode's value as the list of open indexes. */\nfunction toIndexes(value: number | number[] | null | undefined): number[] {\n if (Array.isArray(value)) return value;\n return typeof value === 'number' ? [value] : [];\n}\n\n/**\n * Flattens Fragment children (recursively) so each item inside one gets its\n * own index rather than sharing the fragment's. Children.toArray keys restart\n * at \".0\" inside each fragment, so those children are re-keyed with the\n * fragment's own key as a prefix, the way Avatars does it.\n */\nfunction flattenChildren(\n children: React.ReactNode,\n keyPrefix = ''\n): React.ReactNode[] {\n return React.Children.toArray(children).flatMap(child => {\n if (!React.isValidElement(child)) return [child];\n if (child.type === React.Fragment) {\n return flattenChildren(\n (child.props as { children?: React.ReactNode }).children,\n keyPrefix + child.key\n );\n }\n return [\n keyPrefix\n ? React.cloneElement(child, { key: keyPrefix + child.key })\n : child,\n ];\n });\n}\n\n/**\n * The `Collapses` component groups `Collapse` items into an accordion that keeps one item open at a time, or any number with `multiple`.\n *\n * @function\n * @param {CollapsesProps} props - Props for the Collapses component.\n * @returns {JSX.Element} The rendered group.\n *\n * @example\n * // Accordion: one item open at a time, the first to start with\n * <Collapses defaultValue={0}>\n * <Collapse bordered trigger={<strong>Shipping</strong>}>…</Collapse>\n * <Collapse bordered trigger={<strong>Returns</strong>}>…</Collapse>\n * </Collapses>\n *\n * @example\n * // Controlled, with items that open independently\n * const [open, setOpen] = useState<number[]>([]);\n * <Collapses multiple value={open} onChange={setOpen}>…</Collapses>\n */\nconst CollapsesComponent: React.FC<CollapsesProps> = ({\n multiple = false,\n value,\n defaultValue,\n onChange,\n seamless = false,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });\n\n // Controlled vs uncontrolled, as in Tabs. State is held as a list of open\n // indexes in both modes; `multiple` only decides how a change is computed\n // and which shape `onChange` receives.\n const isControlled = value !== undefined;\n const [internalOpen, setInternalOpen] = useState(() =>\n toIndexes(defaultValue)\n );\n const openIndexes = isControlled ? toIndexes(value) : internalOpen;\n\n // Each mode types `onChange` for its own shape, and the value built below\n // always matches `multiple`, the union's discriminant.\n const reportChange = onChange as\n ((next: number | number[] | null) => void) | undefined;\n\n const setItemOpen = (index: number, open: boolean) => {\n const others = openIndexes.filter(i => i !== index);\n // Single mode keeps at most one item open, so opening one drops the rest.\n // Ascending order, whatever order the items were opened in, so the value\n // reads and compares the same way however the user got there.\n const next = (\n open ? (multiple ? [...others, index] : [index]) : others\n ).sort((a, b) => a - b);\n if (!isControlled) setInternalOpen(next);\n reportChange?.(multiple ? next : (next[0] ?? null));\n };\n\n const groupClasses = usePrefixedClassNames('collapses', {\n 'is-seamless': seamless,\n });\n const combinedClasses = classNames(\n groupClasses,\n bulmaHelperClasses,\n className\n );\n\n const items: React.ReactNode[] = [];\n let index = 0;\n for (const child of flattenChildren(children)) {\n if (!React.isValidElement(child)) {\n items.push(child);\n continue;\n }\n const itemIndex = index;\n index += 1;\n items.push(\n <CollapsesItemContext.Provider\n key={child.key}\n value={{\n open: openIndexes.includes(itemIndex),\n setOpen: open => setItemOpen(itemIndex, open),\n }}\n >\n {child}\n </CollapsesItemContext.Provider>\n );\n }\n\n return (\n <div className={combinedClasses} {...rest}>\n {items}\n </div>\n );\n};\n\nexport const Collapses = withSubComponents(\n CollapsesComponent,\n { Collapse },\n 'Collapses'\n);\n\nexport default Collapses;\n"],"names":["_jsx"],"mappings":";;;;;;;;;AAgEA;AACA,SAAS,SAAS,CAAC,KAA2C,EAAA;AAC5D,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,KAAK;AACtC,IAAA,OAAO,OAAO,KAAK,KAAK,QAAQ,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE;AACjD;AAEA;;;;;AAKG;AACH,SAAS,eAAe,CACtB,QAAyB,EACzB,SAAS,GAAG,EAAE,EAAA;AAEd,IAAA,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,IAAG;AACtD,QAAA,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,KAAK,CAAC;QAChD,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,QAAQ,EAAE;AACjC,YAAA,OAAO,eAAe,CACnB,KAAK,CAAC,KAAwC,CAAC,QAAQ,EACxD,SAAS,GAAG,KAAK,CAAC,GAAG,CACtB;QACH;QACA,OAAO;YACL;AACE,kBAAE,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,EAAE;AAC1D,kBAAE,KAAK;SACV;AACH,IAAA,CAAC,CAAC;AACJ;AAEA;;;;;;;;;;;;;;;;;;AAkBG;AACH,MAAM,kBAAkB,GAA6B,CAAC,EACpD,QAAQ,GAAG,KAAK,EAChB,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;;;;AAKlE,IAAA,MAAM,YAAY,GAAG,KAAK,KAAK,SAAS;AACxC,IAAA,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,MAC/C,SAAS,CAAC,YAAY,CAAC,CACxB;AACD,IAAA,MAAM,WAAW,GAAG,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,YAAY;;;IAIlE,MAAM,YAAY,GAAG,QACmC;AAExD,IAAA,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,IAAa,KAAI;AACnD,QAAA,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC;;;;QAInD,MAAM,IAAI,GAAG,CACX,IAAI,IAAI,QAAQ,GAAG,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,EACzD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACvB,QAAA,IAAI,CAAC,YAAY;YAAE,eAAe,CAAC,IAAI,CAAC;AACxC,QAAA,YAAY,GAAG,QAAQ,GAAG,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;AACrD,IAAA,CAAC;AAED,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,WAAW,EAAE;AACtD,QAAA,aAAa,EAAE,QAAQ;AACxB,KAAA,CAAC;IACF,MAAM,eAAe,GAAG,UAAU,CAChC,YAAY,EACZ,kBAAkB,EAClB,SAAS,CACV;IAED,MAAM,KAAK,GAAsB,EAAE;IACnC,IAAI,KAAK,GAAG,CAAC;IACb,KAAK,MAAM,KAAK,IAAI,eAAe,CAAC,QAAQ,CAAC,EAAE;QAC7C,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE;AAChC,YAAA,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;YACjB;QACF;QACA,MAAM,SAAS,GAAG,KAAK;QACvB,KAAK,IAAI,CAAC;QACV,KAAK,CAAC,IAAI,CACRA,GAAA,CAAC,oBAAoB,CAAC,QAAQ,EAAA,EAE5B,KAAK,EAAE;AACL,gBAAA,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACrC,OAAO,EAAE,IAAI,IAAI,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC;AAC9C,aAAA,EAAA,QAAA,EAEA,KAAK,EAAA,EAND,KAAK,CAAC,GAAG,CAOgB,CACjC;IACH;IAEA,QACEA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,eAAe,EAAA,GAAM,IAAI,EAAA,QAAA,EACtC,KAAK,EAAA,CACF;AAEV,CAAC;AAEM,MAAM,SAAS,GAAG,iBAAiB,CACxC,kBAAkB,EAClB,EAAE,QAAQ,EAAE,EACZ,WAAW;;"}
1
+ {"version":3,"file":"Collapses.js","sources":["../../../src/components/Collapses.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { Collapse } from './Collapse';\nimport { CollapsesItemContext } from './collapsesContext';\nimport { flattenChildren } from '../helpers/flattenChildren';\n\n/**\n * Props shared by both modes of the Collapses component.\n */\ninterface CollapsesBaseProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'color' | 'defaultValue' | 'onChange'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Joins the items into one block, with no gap between them and only the outer corners rounded. The joins show on `bordered` items. */\n seamless?: boolean;\n /** Additional CSS classes to apply. */\n className?: string;\n /** The `Collapse` items. Each child element is one item, indexed from 0 in order, with the children of a fragment counted one by one. A child that sets its own `open` keeps it: the group leaves that item alone. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for Collapses in single mode, the accordion: opening one item closes the others.\n */\nexport interface CollapsesSingleProps extends CollapsesBaseProps {\n /**\n * Lets items open independently. Without it, opening one item closes the others.\n * @defaultValue false\n */\n multiple?: false;\n /** Controlled open items: the index of the open item, or `null` for none. With `multiple`, an array of indexes. An index is a position among the children, so rendering an item conditionally or reordering them moves the open state onto a neighbour: render every item and hide one with `visibility=\"hidden\"`, or keep `value` in step yourself. */\n value?: number | null;\n /** Open items for uncontrolled use, as an index or `null` (the default, none open). With `multiple`, an array of indexes, empty by default. Indexes are positions among the children, as for `value`. */\n defaultValue?: number | null;\n /** Called with the new open items each time a trigger asks for a change, whether or not `value` is set: an index or `null`, or with `multiple` an array of indexes in ascending order. Indexes are positions among the children, as for `value`. */\n onChange?: (value: number | null) => void;\n}\n\n/**\n * Props for Collapses with `multiple`: items open and close independently.\n */\nexport interface CollapsesMultipleProps extends CollapsesBaseProps {\n /**\n * Lets items open independently. Without it, opening one item closes the others.\n * @defaultValue false\n */\n multiple: true;\n /** Controlled open items: the index of the open item, or `null` for none. With `multiple`, an array of indexes. An index is a position among the children, so rendering an item conditionally or reordering them moves the open state onto a neighbour: render every item and hide one with `visibility=\"hidden\"`, or keep `value` in step yourself. */\n value?: number[];\n /** Open items for uncontrolled use, as an index or `null` (the default, none open). With `multiple`, an array of indexes, empty by default. Indexes are positions among the children, as for `value`. */\n defaultValue?: number[];\n /** Called with the new open items each time a trigger asks for a change, whether or not `value` is set: an index or `null`, or with `multiple` an array of indexes in ascending order. Indexes are positions among the children, as for `value`. */\n onChange?: (value: number[]) => void;\n}\n\n/**\n * Props for the Collapses component, a discriminated union on `multiple`: the open items are an index (or `null`) in single mode and an array of indexes with `multiple`.\n */\nexport type CollapsesProps = CollapsesSingleProps | CollapsesMultipleProps;\n\n/** Either mode's value as the list of open indexes. */\nfunction toIndexes(value: number | number[] | null | undefined): number[] {\n if (Array.isArray(value)) return value;\n return typeof value === 'number' ? [value] : [];\n}\n\n/**\n * The `Collapses` component groups `Collapse` items into an accordion that keeps one item open at a time, or any number with `multiple`.\n *\n * @function\n * @param {CollapsesProps} props - Props for the Collapses component.\n * @returns {JSX.Element} The rendered group.\n *\n * @example\n * // Accordion: one item open at a time, the first to start with\n * <Collapses defaultValue={0}>\n * <Collapse bordered trigger={<strong>Shipping</strong>}>…</Collapse>\n * <Collapse bordered trigger={<strong>Returns</strong>}>…</Collapse>\n * </Collapses>\n *\n * @example\n * // Controlled, with items that open independently\n * const [open, setOpen] = useState<number[]>([]);\n * <Collapses multiple value={open} onChange={setOpen}>…</Collapses>\n */\nconst CollapsesComponent: React.FC<CollapsesProps> = ({\n multiple = false,\n value,\n defaultValue,\n onChange,\n seamless = false,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });\n\n // Controlled vs uncontrolled, as in Tabs. State is held as a list of open\n // indexes in both modes; `multiple` only decides how a change is computed\n // and which shape `onChange` receives.\n const isControlled = value !== undefined;\n const [internalOpen, setInternalOpen] = useState(() =>\n toIndexes(defaultValue)\n );\n const openIndexes = isControlled ? toIndexes(value) : internalOpen;\n\n // Each mode types `onChange` for its own shape, and the value built below\n // always matches `multiple`, the union's discriminant.\n const reportChange = onChange as\n ((next: number | number[] | null) => void) | undefined;\n\n const setItemOpen = (index: number, open: boolean) => {\n const others = openIndexes.filter(i => i !== index);\n // Single mode keeps at most one item open, so opening one drops the rest.\n // Ascending order, whatever order the items were opened in, so the value\n // reads and compares the same way however the user got there.\n const next = (\n open ? (multiple ? [...others, index] : [index]) : others\n ).sort((a, b) => a - b);\n if (!isControlled) setInternalOpen(next);\n reportChange?.(multiple ? next : (next[0] ?? null));\n };\n\n const groupClasses = usePrefixedClassNames('collapses', {\n 'is-seamless': seamless,\n });\n const combinedClasses = classNames(\n groupClasses,\n bulmaHelperClasses,\n className\n );\n\n const items: React.ReactNode[] = [];\n let index = 0;\n for (const child of flattenChildren(children)) {\n if (!React.isValidElement(child)) {\n items.push(child);\n continue;\n }\n const itemIndex = index;\n index += 1;\n items.push(\n <CollapsesItemContext.Provider\n key={child.key}\n value={{\n open: openIndexes.includes(itemIndex),\n setOpen: open => setItemOpen(itemIndex, open),\n }}\n >\n {child}\n </CollapsesItemContext.Provider>\n );\n }\n\n return (\n <div className={combinedClasses} {...rest}>\n {items}\n </div>\n );\n};\n\nexport const Collapses = withSubComponents(\n CollapsesComponent,\n { Collapse },\n 'Collapses'\n);\n\nexport default Collapses;\n"],"names":["_jsx"],"mappings":";;;;;;;;;;AAiEA;AACA,SAAS,SAAS,CAAC,KAA2C,EAAA;AAC5D,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,KAAK;AACtC,IAAA,OAAO,OAAO,KAAK,KAAK,QAAQ,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE;AACjD;AAEA;;;;;;;;;;;;;;;;;;AAkBG;AACH,MAAM,kBAAkB,GAA6B,CAAC,EACpD,QAAQ,GAAG,KAAK,EAChB,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;;;;AAKlE,IAAA,MAAM,YAAY,GAAG,KAAK,KAAK,SAAS;AACxC,IAAA,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,MAC/C,SAAS,CAAC,YAAY,CAAC,CACxB;AACD,IAAA,MAAM,WAAW,GAAG,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,YAAY;;;IAIlE,MAAM,YAAY,GAAG,QACmC;AAExD,IAAA,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,IAAa,KAAI;AACnD,QAAA,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC;;;;QAInD,MAAM,IAAI,GAAG,CACX,IAAI,IAAI,QAAQ,GAAG,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,EACzD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACvB,QAAA,IAAI,CAAC,YAAY;YAAE,eAAe,CAAC,IAAI,CAAC;AACxC,QAAA,YAAY,GAAG,QAAQ,GAAG,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;AACrD,IAAA,CAAC;AAED,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,WAAW,EAAE;AACtD,QAAA,aAAa,EAAE,QAAQ;AACxB,KAAA,CAAC;IACF,MAAM,eAAe,GAAG,UAAU,CAChC,YAAY,EACZ,kBAAkB,EAClB,SAAS,CACV;IAED,MAAM,KAAK,GAAsB,EAAE;IACnC,IAAI,KAAK,GAAG,CAAC;IACb,KAAK,MAAM,KAAK,IAAI,eAAe,CAAC,QAAQ,CAAC,EAAE;QAC7C,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE;AAChC,YAAA,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;YACjB;QACF;QACA,MAAM,SAAS,GAAG,KAAK;QACvB,KAAK,IAAI,CAAC;QACV,KAAK,CAAC,IAAI,CACRA,GAAA,CAAC,oBAAoB,CAAC,QAAQ,EAAA,EAE5B,KAAK,EAAE;AACL,gBAAA,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACrC,OAAO,EAAE,IAAI,IAAI,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC;AAC9C,aAAA,EAAA,QAAA,EAEA,KAAK,EAAA,EAND,KAAK,CAAC,GAAG,CAOgB,CACjC;IACH;IAEA,QACEA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,eAAe,EAAA,GAAM,IAAI,EAAA,QAAA,EACtC,KAAK,EAAA,CACF;AAEV,CAAC;AAEM,MAAM,SAAS,GAAG,iBAAiB,CACxC,kBAAkB,EAClB,EAAE,QAAQ,EAAE,EACZ,WAAW;;"}
@@ -0,0 +1,86 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import React, { forwardRef } from 'react';
4
+ import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
5
+ import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
6
+ import { flattenChildren } from '../helpers/flattenChildren.js';
7
+ import { visuallyHidden } from '../helpers/statusRegion.js';
8
+ import { withSubComponents } from '../helpers/withSubComponents.js';
9
+
10
+ /**
11
+ * Keys pressed together or one after another, in the outer `<kbd>` HTML gives a combination, with the separator between each pair as text.
12
+ *
13
+ * It doesn't wrap in the middle and isn't drawn as a key itself. It sets no
14
+ * font size, so the keys in it are the size of a key on its own.
15
+ *
16
+ * @function
17
+ * @param {KbdGroupProps} props - Props for Kbd.Group.
18
+ * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the outer `<kbd>`.
19
+ * @returns {JSX.Element} The rendered combination.
20
+ *
21
+ * @example
22
+ * <Kbd.Group>
23
+ * <Kbd>Ctrl</Kbd>
24
+ * <Kbd>Shift</Kbd>
25
+ * <Kbd>P</Kbd>
26
+ * </Kbd.Group>
27
+ *
28
+ * @example
29
+ * <Kbd.Group separator="then">
30
+ * <Kbd>G</Kbd>
31
+ * <Kbd>I</Kbd>
32
+ * </Kbd.Group>
33
+ */
34
+ const KbdGroup = forwardRef(({ className, textColor, separator = '+', children, ...props }, ref) => {
35
+ const { bulmaHelperClasses, rest } = useBulmaClasses({
36
+ color: textColor,
37
+ ...props,
38
+ });
39
+ const groupClass = usePrefixedClassNames('kbd-group');
40
+ const separatorClass = usePrefixedClassNames('kbd-separator');
41
+ // Null, undefined and booleans drop out, and Fragments are opened up, so
42
+ // an empty Fragment leaves no separator behind and the keys in one are
43
+ // separated like the rest. The spaces are part of the text, so a screen
44
+ // reader reads "Ctrl plus S" rather than one run-together word, whatever
45
+ // the CSS does.
46
+ const keys = flattenChildren(children);
47
+ return (jsx("kbd", { ref: ref, className: classNames(groupClass, bulmaHelperClasses, className), ...rest, children: keys.map((key, index) => (jsxs(React.Fragment, { children: [index > 0 && (jsx("span", { className: separatorClass, children: ` ${separator} ` })), key] }, React.isValidElement(key) && key.key != null ? key.key : index))) }));
48
+ });
49
+ KbdGroup.displayName = 'Kbd.Group';
50
+ /**
51
+ * The `Kbd` component renders a `<kbd>` drawn as a keycap, for a key the reader presses.
52
+ *
53
+ * It only shows the key: it doesn't listen for it. The key takes its colors
54
+ * from the text it sits in, and its size in `em`, so it fits a paragraph, a
55
+ * title or a filled button as it is, and `textSize` sizes it outright. For a
56
+ * combination or a sequence, put the keys in a `Kbd.Group`. What tells
57
+ * assistive tech a control has a shortcut is `aria-keyshortcuts` on that
58
+ * control, with `Kbd` as the hint people see next to it.
59
+ *
60
+ * @function
61
+ * @param {KbdProps} props - Props for the Kbd component.
62
+ * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the `<kbd>`.
63
+ * @returns {JSX.Element} The rendered key.
64
+ *
65
+ * @example
66
+ * <Kbd>Esc</Kbd>
67
+ *
68
+ * @example
69
+ * <Kbd label="Command">⌘</Kbd>
70
+ */
71
+ const KbdRoot = forwardRef(({ className, textColor, bgColor, label, children, ...props }, ref) => {
72
+ const { bulmaHelperClasses, rest } = useBulmaClasses({
73
+ color: textColor,
74
+ backgroundColor: bgColor,
75
+ ...props,
76
+ });
77
+ const kbdClass = usePrefixedClassNames('kbd');
78
+ // The name is text rather than an aria-label, which ARIA in HTML
79
+ // prohibits on kbd. Its styles are inline, so it stays hidden in a
80
+ // modular build that leaves out Bulma's helper classes.
81
+ return (jsx("kbd", { ref: ref, className: classNames(kbdClass, bulmaHelperClasses, className), ...rest, children: label ? (jsxs(Fragment, { children: [jsx("span", { "aria-hidden": "true", children: children }), jsx("span", { style: visuallyHidden, children: label })] })) : (children) }));
82
+ });
83
+ const Kbd = withSubComponents(KbdRoot, { Group: KbdGroup }, 'Kbd');
84
+
85
+ export { Kbd, KbdGroup };
86
+ //# sourceMappingURL=Kbd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Kbd.js","sources":["../../../src/elements/Kbd.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { flattenChildren } from '../helpers/flattenChildren';\nimport { visuallyHidden } from '../helpers/statusRegion';\nimport { withSubComponents } from '../helpers/withSubComponents';\n\n/**\n * Props for the Kbd component. The helper props, the other attributes and\n * the `ref` land on the `<kbd>`.\n *\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the `<kbd>`.\n */\nexport interface KbdProps\n extends\n Omit<React.HTMLAttributes<HTMLElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * The key as it's printed on the keyboard: a word (`Ctrl`, `Esc`), a\n * letter, or a symbol (`⌘`).\n */\n children?: React.ReactNode;\n /**\n * What a screen reader says in place of a symbol, in your app's language:\n * `label=\"Command\"` on `⌘`. The symbol is hidden from assistive tech with\n * `aria-hidden`, and the label is read in its place, from text that's\n * visually hidden. Use it for a glyph that isn't a word, such as `⌘`, `⌥`,\n * `⇧`, `⌃` or `⏎`, and leave it off a key written as a word. Copying the\n * key copies the label along with the glyph. Don't reach for `aria-label`\n * instead: ARIA in HTML prohibits naming a `<kbd>`, so nothing obliges a\n * screen reader to read it.\n */\n label?: string;\n /**\n * Text color helper. The key's edge and fill are mixed from its text\n * color, so they follow it.\n */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Background color helper. It replaces the key's faint fill, and the text\n * still follows the text around it, which turns light in dark mode, so pair\n * it with a `textColor` that reads on that color in both schemes, such as\n * `textColor=\"black\"` on `bgColor=\"warning\"`.\n */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n}\n\n/**\n * Props for Kbd.Group, keys pressed together or one after another. The\n * group renders the outer `<kbd>` of a combination, and the helper props,\n * the other attributes and the `ref` land on it.\n *\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the outer `<kbd>`.\n */\nexport interface KbdGroupProps\n extends\n Omit<React.HTMLAttributes<HTMLElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * The keys, a `Kbd` each, in the order they're pressed. The group renders\n * the outer `<kbd>` around them, so it doesn't go inside a `Kbd` of its\n * own, and it puts the separator between them, so don't type one: a `+`\n * of your own doubles up. A `null` or `false` child, or an empty Fragment,\n * gets no separator, and the keys in a Fragment are separated like the\n * rest. A component that renders nothing still gets one, since the group\n * can't see what a child renders, so write a conditional key inline\n * (`{isMac && <Kbd label=\"Command\">⌘</Kbd>}`), not in a component of its\n * own.\n */\n children?: React.ReactNode;\n /**\n * What goes between the keys, shown and read aloud, with a space either\n * side. Use `'then'` for a sequence pressed one key after another. It's a\n * string because a screen reader has to read it.\n */\n separator?: string;\n /** Text color helper. The keys and separators inside follow it. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n}\n\n/**\n * Keys pressed together or one after another, in the outer `<kbd>` HTML gives a combination, with the separator between each pair as text.\n *\n * It doesn't wrap in the middle and isn't drawn as a key itself. It sets no\n * font size, so the keys in it are the size of a key on its own.\n *\n * @function\n * @param {KbdGroupProps} props - Props for Kbd.Group.\n * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the outer `<kbd>`.\n * @returns {JSX.Element} The rendered combination.\n *\n * @example\n * <Kbd.Group>\n * <Kbd>Ctrl</Kbd>\n * <Kbd>Shift</Kbd>\n * <Kbd>P</Kbd>\n * </Kbd.Group>\n *\n * @example\n * <Kbd.Group separator=\"then\">\n * <Kbd>G</Kbd>\n * <Kbd>I</Kbd>\n * </Kbd.Group>\n */\nexport const KbdGroup = forwardRef<HTMLElement, KbdGroupProps>(\n ({ className, textColor, separator = '+', children, ...props }, ref) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n ...props,\n });\n const groupClass = usePrefixedClassNames('kbd-group');\n const separatorClass = usePrefixedClassNames('kbd-separator');\n\n // Null, undefined and booleans drop out, and Fragments are opened up, so\n // an empty Fragment leaves no separator behind and the keys in one are\n // separated like the rest. The spaces are part of the text, so a screen\n // reader reads \"Ctrl plus S\" rather than one run-together word, whatever\n // the CSS does.\n const keys = flattenChildren(children);\n\n return (\n <kbd\n ref={ref}\n className={classNames(groupClass, bulmaHelperClasses, className)}\n {...rest}\n >\n {keys.map((key, index) => (\n // Each wrapper takes its child's own React key, so a child that\n // moves keeps its node. Text has none, so it goes by its place.\n <React.Fragment\n key={React.isValidElement(key) && key.key != null ? key.key : index}\n >\n {index > 0 && (\n <span className={separatorClass}>{` ${separator} `}</span>\n )}\n {key}\n </React.Fragment>\n ))}\n </kbd>\n );\n }\n);\n\nKbdGroup.displayName = 'Kbd.Group';\n\n/**\n * The `Kbd` component renders a `<kbd>` drawn as a keycap, for a key the reader presses.\n *\n * It only shows the key: it doesn't listen for it. The key takes its colors\n * from the text it sits in, and its size in `em`, so it fits a paragraph, a\n * title or a filled button as it is, and `textSize` sizes it outright. For a\n * combination or a sequence, put the keys in a `Kbd.Group`. What tells\n * assistive tech a control has a shortcut is `aria-keyshortcuts` on that\n * control, with `Kbd` as the hint people see next to it.\n *\n * @function\n * @param {KbdProps} props - Props for the Kbd component.\n * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the `<kbd>`.\n * @returns {JSX.Element} The rendered key.\n *\n * @example\n * <Kbd>Esc</Kbd>\n *\n * @example\n * <Kbd label=\"Command\">⌘</Kbd>\n */\nconst KbdRoot = forwardRef<HTMLElement, KbdProps>(\n ({ className, textColor, bgColor, label, children, ...props }, ref) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n const kbdClass = usePrefixedClassNames('kbd');\n\n // The name is text rather than an aria-label, which ARIA in HTML\n // prohibits on kbd. Its styles are inline, so it stays hidden in a\n // modular build that leaves out Bulma's helper classes.\n return (\n <kbd\n ref={ref}\n className={classNames(kbdClass, bulmaHelperClasses, className)}\n {...rest}\n >\n {label ? (\n <>\n <span aria-hidden=\"true\">{children}</span>\n <span style={visuallyHidden}>{label}</span>\n </>\n ) : (\n children\n )}\n </kbd>\n );\n }\n);\n\nexport const Kbd = withSubComponents(KbdRoot, { Group: KbdGroup }, 'Kbd');\n\nexport default Kbd;\n"],"names":["_jsx","_jsxs"],"mappings":";;;;;;;;;AAwFA;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AACI,MAAM,QAAQ,GAAG,UAAU,CAChC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,KAAI;AACrE,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;AACnD,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,GAAG,KAAK;AACT,KAAA,CAAC;AACF,IAAA,MAAM,UAAU,GAAG,qBAAqB,CAAC,WAAW,CAAC;AACrD,IAAA,MAAM,cAAc,GAAG,qBAAqB,CAAC,eAAe,CAAC;;;;;;AAO7D,IAAA,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC;AAEtC,IAAA,QACEA,GAAA,CAAA,KAAA,EAAA,EACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CAAC,UAAU,EAAE,kBAAkB,EAAE,SAAS,CAAC,KAC5D,IAAI,EAAA,QAAA,EAEP,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,MAGnBC,KAAC,KAAK,CAAC,QAAQ,EAAA,EAAA,QAAA,EAAA,CAGZ,KAAK,GAAG,CAAC,KACRD,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,cAAc,EAAA,QAAA,EAAG,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,CAAG,EAAA,CAAQ,CAC3D,EACA,GAAG,CAAA,EAAA,EALC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,IAAI,GAAG,GAAG,CAAC,GAAG,GAAG,KAAK,CAMpD,CAClB,CAAC,EAAA,CACE;AAEV,CAAC;AAGH,QAAQ,CAAC,WAAW,GAAG,WAAW;AAElC;;;;;;;;;;;;;;;;;;;;AAoBG;AACH,MAAM,OAAO,GAAG,UAAU,CACxB,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,KAAI;AACpE,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;AACnD,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,eAAe,EAAE,OAAO;AACxB,QAAA,GAAG,KAAK;AACT,KAAA,CAAC;AACF,IAAA,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC;;;;IAK7C,QACEA,aACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CAAC,QAAQ,EAAE,kBAAkB,EAAE,SAAS,CAAC,EAAA,GAC1D,IAAI,EAAA,QAAA,EAEP,KAAK,IACJC,4BACED,GAAA,CAAA,MAAA,EAAA,EAAA,aAAA,EAAkB,MAAM,YAAE,QAAQ,EAAA,CAAQ,EAC1CA,GAAA,CAAA,MAAA,EAAA,EAAM,KAAK,EAAE,cAAc,EAAA,QAAA,EAAG,KAAK,GAAQ,CAAA,EAAA,CAC1C,KAEH,QAAQ,CACT,EAAA,CACG;AAEV,CAAC,CACF;AAEM,MAAM,GAAG,GAAG,iBAAiB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK;;"}
@@ -0,0 +1,35 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ import React from 'react';
3
+
4
+ // INTERNAL: deliberately not exported from src/index.ts.
5
+ /**
6
+ * A component's children as a flat list, with each Fragment opened up
7
+ * (recursively) so the items inside one count one by one rather than as the
8
+ * Fragment. `Children.toArray` already drops `null`, `undefined` and
9
+ * booleans and flattens arrays, but it keeps a Fragment whole, so an empty
10
+ * one would still count as an item and two items in one would count as one.
11
+ *
12
+ * `Children.toArray` keys restart at ".0" inside each Fragment, so the items
13
+ * in one are re-keyed with the Fragment's own key as a prefix. Otherwise an
14
+ * item in a Fragment and a sibling outside it could share a key.
15
+ *
16
+ * Text and numbers pass through as they are, so a caller that wants only
17
+ * elements filters with `React.isValidElement`.
18
+ */
19
+ function flattenChildren(children, keyPrefix = '') {
20
+ return React.Children.toArray(children).flatMap(child => {
21
+ if (!React.isValidElement(child))
22
+ return [child];
23
+ if (child.type === React.Fragment) {
24
+ return flattenChildren(child.props.children, keyPrefix + child.key);
25
+ }
26
+ return [
27
+ keyPrefix
28
+ ? React.cloneElement(child, { key: keyPrefix + child.key })
29
+ : child,
30
+ ];
31
+ });
32
+ }
33
+
34
+ export { flattenChildren };
35
+ //# sourceMappingURL=flattenChildren.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flattenChildren.js","sources":["../../../src/helpers/flattenChildren.ts"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts.\nimport React from 'react';\n\n/**\n * A component's children as a flat list, with each Fragment opened up\n * (recursively) so the items inside one count one by one rather than as the\n * Fragment. `Children.toArray` already drops `null`, `undefined` and\n * booleans and flattens arrays, but it keeps a Fragment whole, so an empty\n * one would still count as an item and two items in one would count as one.\n *\n * `Children.toArray` keys restart at \".0\" inside each Fragment, so the items\n * in one are re-keyed with the Fragment's own key as a prefix. Otherwise an\n * item in a Fragment and a sibling outside it could share a key.\n *\n * Text and numbers pass through as they are, so a caller that wants only\n * elements filters with `React.isValidElement`.\n */\nexport function flattenChildren(\n children: React.ReactNode,\n keyPrefix = ''\n): React.ReactNode[] {\n return React.Children.toArray(children).flatMap(child => {\n if (!React.isValidElement(child)) return [child];\n if (child.type === React.Fragment) {\n return flattenChildren(\n (child.props as { children?: React.ReactNode }).children,\n keyPrefix + child.key\n );\n }\n return [\n keyPrefix\n ? React.cloneElement(child, { key: keyPrefix + child.key })\n : child,\n ];\n });\n}\n"],"names":[],"mappings":";;;AAAA;AAGA;;;;;;;;;;;;;AAaG;SACa,eAAe,CAC7B,QAAyB,EACzB,SAAS,GAAG,EAAE,EAAA;AAEd,IAAA,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,IAAG;AACtD,QAAA,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,KAAK,CAAC;QAChD,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,QAAQ,EAAE;AACjC,YAAA,OAAO,eAAe,CACnB,KAAK,CAAC,KAAwC,CAAC,QAAQ,EACxD,SAAS,GAAG,KAAK,CAAC,GAAG,CACtB;QACH;QACA,OAAO;YACL;AACE,kBAAE,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,EAAE;AAC1D,kBAAE,KAAK;SACV;AACH,IAAA,CAAC,CAAC;AACJ;;"}