@mitcsutt/kiln-ui 0.3.0 → 0.4.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 (100) hide show
  1. package/dist/components/actions/Button/Button.module.js.map +1 -1
  2. package/dist/components/actions/ToggleChip/ToggleChip.d.ts +5 -0
  3. package/dist/components/actions/ToggleChip/ToggleChip.js +10 -6
  4. package/dist/components/actions/ToggleChip/ToggleChip.js.map +1 -1
  5. package/dist/components/actions/ToggleChip/chip.module.js +4 -3
  6. package/dist/components/actions/ToggleChip/chip.module.js.map +1 -1
  7. package/dist/components/display/AvatarGroup/AvatarGroup.d.ts +2 -2
  8. package/dist/components/display/AvatarGroup/AvatarGroup.js +1 -1
  9. package/dist/components/display/AvatarGroup/AvatarGroup.js.map +1 -1
  10. package/dist/components/display/Card/Card.d.ts +7 -4
  11. package/dist/components/display/Card/Card.js +8 -7
  12. package/dist/components/display/Card/Card.js.map +1 -1
  13. package/dist/components/display/Card/Card.module.js.map +1 -1
  14. package/dist/components/display/List/List.d.ts +10 -5
  15. package/dist/components/display/List/List.js +49 -40
  16. package/dist/components/display/List/List.js.map +1 -1
  17. package/dist/components/display/List/List.module.js.map +1 -1
  18. package/dist/components/display/Marquee/Marquee.js +1 -1
  19. package/dist/components/display/Marquee/Marquee.js.map +1 -1
  20. package/dist/components/display/Media/Media.d.ts +13 -0
  21. package/dist/components/display/Media/Media.js +23 -19
  22. package/dist/components/display/Media/Media.js.map +1 -1
  23. package/dist/components/display/Media/Media.module.js.map +1 -1
  24. package/dist/components/display/Media/index.d.ts +1 -1
  25. package/dist/components/display/Stat/Stat.module.js.map +1 -1
  26. package/dist/components/display/Table/Table.d.ts +6 -1
  27. package/dist/components/display/Table/Table.js +6 -4
  28. package/dist/components/display/Table/Table.js.map +1 -1
  29. package/dist/components/display/Table/Table.module.js.map +1 -1
  30. package/dist/components/display/Tag/Tag.d.ts +3 -0
  31. package/dist/components/display/Tag/Tag.js +11 -10
  32. package/dist/components/display/Tag/Tag.js.map +1 -1
  33. package/dist/components/display/Tag/Tag.module.js.map +1 -1
  34. package/dist/components/display/Tag/index.d.ts +1 -1
  35. package/dist/components/feedback/Flash/Flash.d.ts +47 -0
  36. package/dist/components/feedback/Flash/Flash.js +36 -0
  37. package/dist/components/feedback/Flash/Flash.js.map +1 -0
  38. package/dist/components/feedback/Flash/Flash.module.js +10 -0
  39. package/dist/components/feedback/Flash/Flash.module.js.map +1 -0
  40. package/dist/components/feedback/Flash/index.d.ts +2 -0
  41. package/dist/components/feedback/RelativeTime/RelativeTime.d.ts +7 -0
  42. package/dist/components/feedback/RelativeTime/RelativeTime.js +11 -11
  43. package/dist/components/feedback/RelativeTime/RelativeTime.js.map +1 -1
  44. package/dist/components/feedback/StatusDot/StatusDot.d.ts +1 -1
  45. package/dist/components/feedback/StatusDot/StatusDot.js.map +1 -1
  46. package/dist/components/inputs/ChoiceCards/ChoiceCards.js +9 -9
  47. package/dist/components/inputs/Combobox/Combobox.js +5 -5
  48. package/dist/components/inputs/PasswordInput/PasswordInput.js +4 -4
  49. package/dist/components/layout/AppShell/AppShell.d.ts +4 -1
  50. package/dist/components/layout/AppShell/AppShell.js +58 -44
  51. package/dist/components/layout/AppShell/AppShell.js.map +1 -1
  52. package/dist/components/layout/AppShell/AppShell.module.js.map +1 -1
  53. package/dist/components/layout/Box/Box.d.ts +6 -3
  54. package/dist/components/layout/Box/Box.js.map +1 -1
  55. package/dist/components/layout/Box/Box.module.js.map +1 -1
  56. package/dist/components/layout/Divider/Divider.d.ts +7 -1
  57. package/dist/components/layout/Divider/Divider.js +18 -20
  58. package/dist/components/layout/Divider/Divider.js.map +1 -1
  59. package/dist/components/layout/Section/Section.d.ts +8 -6
  60. package/dist/components/layout/Section/Section.js.map +1 -1
  61. package/dist/components/layout/Section/Section.module.js.map +1 -1
  62. package/dist/components/navigation/Accordion/Accordion.d.ts +6 -1
  63. package/dist/components/navigation/Accordion/Accordion.js +19 -11
  64. package/dist/components/navigation/Accordion/Accordion.js.map +1 -1
  65. package/dist/components/navigation/Accordion/Accordion.module.js +7 -6
  66. package/dist/components/navigation/Accordion/Accordion.module.js.map +1 -1
  67. package/dist/components/navigation/NavLinks/NavLinks.d.ts +4 -1
  68. package/dist/components/navigation/NavLinks/NavLinks.js.map +1 -1
  69. package/dist/components/navigation/NavLinks/NavLinks.module.js.map +1 -1
  70. package/dist/components/overlays/Tooltip/Tooltip.d.ts +23 -0
  71. package/dist/components/overlays/Tooltip/Tooltip.js +77 -31
  72. package/dist/components/overlays/Tooltip/Tooltip.js.map +1 -1
  73. package/dist/components/typography/Numeral/Numeral.d.ts +26 -2
  74. package/dist/components/typography/Numeral/Numeral.js +25 -21
  75. package/dist/components/typography/Numeral/Numeral.js.map +1 -1
  76. package/dist/components/typography/Numeral/Numeral.module.js +4 -3
  77. package/dist/components/typography/Numeral/Numeral.module.js.map +1 -1
  78. package/dist/components/typography/Text/Text.d.ts +5 -2
  79. package/dist/components/typography/Text/Text.js.map +1 -1
  80. package/dist/components/typography/Text/Text.module.js.map +1 -1
  81. package/dist/icons/Icon.js +1 -0
  82. package/dist/icons/Icon.js.map +1 -1
  83. package/dist/icons/icons.d.ts +12 -0
  84. package/dist/icons/icons.js +63 -13
  85. package/dist/icons/icons.js.map +1 -1
  86. package/dist/index.d.ts +16 -23
  87. package/dist/index.js +113 -112
  88. package/dist/styles.css +1 -1
  89. package/dist/themes/fiesta.css +1 -1
  90. package/dist/utils/tokens.d.ts +2 -0
  91. package/dist/utils/tokens.js.map +1 -1
  92. package/package.json +2 -2
  93. package/skills/custom-theme/SKILL.md +1 -1
  94. package/skills/design-rules/SKILL.md +7 -4
  95. package/skills/layout-composition/references/app-shell.md +2 -2
  96. package/skills/layout-composition/references/box.md +1 -1
  97. package/skills/layout-composition/references/divider.md +30 -1
  98. package/skills/layout-composition/references/section.md +23 -2
  99. package/skills/setup-and-theming/SKILL.md +3 -3
  100. package/skills/setup-and-theming/references/fiesta.md +1 -1
@@ -3,33 +3,31 @@ import { mergeStyles as t } from "../../../utils/responsive.js";
3
3
  import { space as n } from "../../../utils/tokens.js";
4
4
  import { visibilityClass as r } from "../../../utils/visibility.js";
5
5
  import i from "./Divider.module.js";
6
- import { forwardRef as a, useId as o } from "react";
7
- import { jsx as s } from "react/jsx-runtime";
6
+ import { forwardRef as a } from "react";
7
+ import { jsx as o } from "react/jsx-runtime";
8
8
  //#region src/components/layout/Divider/Divider.tsx
9
- var c = a(function({ orientation: a = "horizontal", strong: c = !1, label: l, labelPosition: u = "start", spacing: d, decorative: f = !1, hideBelow: p, hideAbove: m, className: h, style: g, ..._ }, v) {
10
- let y = o(), b = l != null && l !== !1 && a === "horizontal";
11
- return /* @__PURE__ */ s("div", {
12
- ref: v,
9
+ var s = a(function({ orientation: a = "horizontal", strong: s = !1, label: c, labelPosition: l = "start", spacing: u, decorative: d = !1, hideBelow: f, hideAbove: p, className: m, style: h, ...g }, _) {
10
+ let v = c != null && c !== !1 && a === "horizontal";
11
+ return /* @__PURE__ */ o("div", {
12
+ ref: _,
13
13
  className: e(i.divider, r({
14
- hideBelow: p,
15
- hideAbove: m
16
- }), h),
17
- role: f ? "none" : "separator",
18
- "aria-orientation": !f && a === "vertical" ? "vertical" : void 0,
19
- "aria-labelledby": !f && b ? y : void 0,
14
+ hideBelow: f,
15
+ hideAbove: p
16
+ }), m),
17
+ role: d || v ? "none" : "separator",
18
+ "aria-orientation": !d && a === "vertical" ? "vertical" : void 0,
20
19
  "data-orientation": a,
21
- "data-strong": c || void 0,
22
- "data-label-position": b ? u : void 0,
23
- style: t(d === void 0 ? void 0 : { "--divider-spacing": n(d) }, g),
24
- ..._,
25
- children: b ? /* @__PURE__ */ s("span", {
26
- id: y,
20
+ "data-strong": s || void 0,
21
+ "data-label-position": v ? l : void 0,
22
+ style: t(u === void 0 ? void 0 : { "--divider-spacing": n(u) }, h),
23
+ ...g,
24
+ children: v ? /* @__PURE__ */ o("div", {
27
25
  className: i.label,
28
- children: l
26
+ children: c
29
27
  }) : null
30
28
  });
31
29
  });
32
30
  //#endregion
33
- export { c as Divider };
31
+ export { s as Divider };
34
32
 
35
33
  //# sourceMappingURL=Divider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Divider.js","names":["styles","Divider_module_default","Divider","forwardRef","rest","labelId","useId","hasLabel","label","orientation","cx","visibilityClass","className","decorative","strong","labelPosition","mergeStyles","spacing","space","style"],"sources":["../../../../src/components/layout/Divider/Divider.tsx"],"sourcesContent":["import { forwardRef, useId, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles } from '#utils/responsive'\nimport { space, type Space } from '#utils/tokens'\nimport styles from './Divider.module.css'\nimport { visibilityClass, type VisibilityProps } from '#utils/visibility'\n\nexport type DividerOrientation = 'horizontal' | 'vertical'\n\nexport interface DividerProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'children'>, VisibilityProps {\n /** Default `horizontal`. A vertical rule stretches to its flex/grid row. */\n orientation?: DividerOrientation\n /** Heavier rule in `--color-line-strong` at `--border-width-strong`. */\n strong?: boolean\n /** Text set into a horizontal rule, e.g. \"Earlier this week\". It also names the separator. */\n label?: ReactNode\n /** Where the label sits. Default `start` (left-aligned by default); `center` for a lone break. */\n labelPosition?: 'start' | 'center'\n /** Margin on both sides of the rule (block axis if horizontal, inline if vertical). */\n spacing?: Space\n /**\n * Purely visual: hide it from assistive tech. Use when the rule only repeats a\n * boundary that headings or landmarks already convey.\n */\n decorative?: boolean\n}\n\n/**\n * A hairline rule between groups of content, optionally labelled, horizontal or vertical.\n *\n * @remarks\n * `Divider` separates groups. For a rule between every item of a list, use `Stack dividers`\n * instead, which spaces the rules for you.\n *\n * @privateRemarks\n * A hairline rule between groups of content. Prefer `Stack dividers` for rules\n * between every item of a list.\n *\n * <Divider label=\"Earlier this week\" spacing={6} />\n */\nexport const Divider = forwardRef<HTMLDivElement, DividerProps>(function Divider(\n {\n orientation = 'horizontal',\n strong = false,\n label,\n labelPosition = 'start',\n spacing,\n decorative = false,\n hideBelow,\n hideAbove,\n className,\n style,\n ...rest\n },\n ref,\n) {\n const labelId = useId()\n const hasLabel =\n label !== undefined && label !== null && label !== false && orientation === 'horizontal'\n return (\n <div\n ref={ref}\n className={cx(styles.divider, visibilityClass({ hideBelow, hideAbove }), className)}\n role={decorative ? 'none' : 'separator'}\n aria-orientation={!decorative && orientation === 'vertical' ? 'vertical' : undefined}\n aria-labelledby={!decorative && hasLabel ? labelId : undefined}\n data-orientation={orientation}\n data-strong={strong || undefined}\n data-label-position={hasLabel ? labelPosition : undefined}\n style={mergeStyles(\n spacing === undefined\n ? undefined\n : ({ '--divider-spacing': space(spacing) } as CSSProperties),\n style,\n )}\n {...rest}\n >\n {hasLabel ? (\n <span id={labelId} className={styles.label}>\n {label}\n </span>\n ) : null}\n </div>\n )\n})\n"],"mappings":";;;;;;;;AAyCA,IAAaE,IAAUC,EAAyC,SAC9D,EACE,iBAAc,cACd,YAAS,IACT,UACA,mBAAgB,SAChB,YACA,gBAAa,IACb,cACA,cACA,cACA,UACA,GAAGC,KAEL,GACA;CACA,IAAMC,IAAUC,EAAM,GAChBC,IACJC,KAAiC,QAAQA,MAAU,MAASC,MAAgB;CAC9E,OACE,kBAAC,OAAD;EACO;EACL,WAAWC,EAAGV,EAAO,SAASW,EAAgB;GAAE;GAAW;EAAU,CAAC,GAAGC,CAAS;EAClF,MAAMC,IAAa,SAAS;EAC5B,oBAAkB,CAACA,KAAcJ,MAAgB,aAAa,aAAa,KAAA;EAC3E,mBAAiB,CAACI,KAAcN,IAAWF,IAAU,KAAA;EACrD,oBAAkBI;EAClB,eAAaK,KAAU,KAAA;EACvB,uBAAqBP,IAAWQ,IAAgB,KAAA;EAChD,OAAOC,EACLC,MAAY,KAAA,IACR,KAAA,IACC,EAAE,qBAAqBC,EAAMD,CAAO,EAAE,GAC3CE,CACF;EACA,GAAIf;EAEH,UAAAG,IACC,kBAAC,QAAD;GAAM,IAAIF;GAAS,WAAWL,EAAO;GAClC,UAAAQ;EACG,CAAA,IACJ;CACD,CAAA;AAET,CAAC"}
1
+ {"version":3,"file":"Divider.js","names":["styles","Divider_module_default","Divider","forwardRef","rest","hasLabel","label","orientation","cx","visibilityClass","className","decorative","strong","labelPosition","mergeStyles","spacing","space","style"],"sources":["../../../../src/components/layout/Divider/Divider.tsx"],"sourcesContent":["import { forwardRef, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles } from '#utils/responsive'\nimport { space, type Space } from '#utils/tokens'\nimport styles from './Divider.module.css'\nimport { visibilityClass, type VisibilityProps } from '#utils/visibility'\n\nexport type DividerOrientation = 'horizontal' | 'vertical'\n\nexport interface DividerProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'children'>, VisibilityProps {\n /** Default `horizontal`. A vertical rule stretches to its flex/grid row. */\n orientation?: DividerOrientation\n /** Heavier rule in `--color-line-strong` at `--border-width-strong`. */\n strong?: boolean\n /**\n * Content set into a horizontal rule, e.g. \"Earlier this week\". It's real content, read like\n * any text, and may be a block (a `Stack` of lines); the rules either side are decorative.\n */\n label?: ReactNode\n /** Where the label sits. Default `start` (left-aligned by default); `center` for a lone break. */\n labelPosition?: 'start' | 'center'\n /** Margin on both sides of the rule (block axis if horizontal, inline if vertical). */\n spacing?: Space\n /**\n * Purely visual: hide it from assistive tech. Use when the rule only repeats a\n * boundary that headings or landmarks already convey.\n */\n decorative?: boolean\n}\n\n/**\n * A hairline rule between groups of content, optionally labelled, horizontal or vertical.\n *\n * @remarks\n * `Divider` separates groups. For a rule between every item of a list, use `Stack dividers`\n * instead, which spaces the rules for you.\n *\n * A labelled divider is a band rather than a separator: its label is content that screen readers\n * read in place, and the rules either side of it are decorative.\n *\n * @privateRemarks\n * A hairline rule between groups of content. Prefer `Stack dividers` for rules\n * between every item of a list.\n *\n * <Divider label=\"Earlier this week\" spacing={6} />\n */\nexport const Divider = forwardRef<HTMLDivElement, DividerProps>(function Divider(\n {\n orientation = 'horizontal',\n strong = false,\n label,\n labelPosition = 'start',\n spacing,\n decorative = false,\n hideBelow,\n hideAbove,\n className,\n style,\n ...rest\n },\n ref,\n) {\n const hasLabel =\n label !== undefined && label !== null && label !== false && orientation === 'horizontal'\n return (\n <div\n ref={ref}\n className={cx(styles.divider, visibilityClass({ hideBelow, hideAbove }), className)}\n // A labelled band's label is content, which a separator's children can't be.\n role={decorative || hasLabel ? 'none' : 'separator'}\n aria-orientation={!decorative && orientation === 'vertical' ? 'vertical' : undefined}\n data-orientation={orientation}\n data-strong={strong || undefined}\n data-label-position={hasLabel ? labelPosition : undefined}\n style={mergeStyles(\n spacing === undefined\n ? undefined\n : ({ '--divider-spacing': space(spacing) } as CSSProperties),\n style,\n )}\n {...rest}\n >\n {hasLabel ? <div className={styles.label}>{label}</div> : null}\n </div>\n )\n})\n"],"mappings":";;;;;;;;AA+CA,IAAaE,IAAUC,EAAyC,SAC9D,EACE,iBAAc,cACd,YAAS,IACT,UACA,mBAAgB,SAChB,YACA,gBAAa,IACb,cACA,cACA,cACA,UACA,GAAGC,KAEL,GACA;CACA,IAAMC,IACJC,KAAiC,QAAQA,MAAU,MAASC,MAAgB;CAC9E,OACE,kBAAC,OAAD;EACO;EACL,WAAWC,EAAGR,EAAO,SAASS,EAAgB;GAAE;GAAW;EAAU,CAAC,GAAGC,CAAS;EAElF,MAAMC,KAAcN,IAAW,SAAS;EACxC,oBAAkB,CAACM,KAAcJ,MAAgB,aAAa,aAAa,KAAA;EAC3E,oBAAkBA;EAClB,eAAaK,KAAU,KAAA;EACvB,uBAAqBP,IAAWQ,IAAgB,KAAA;EAChD,OAAOC,EACLC,MAAY,KAAA,IACR,KAAA,IACC,EAAE,qBAAqBC,EAAMD,CAAO,EAAE,GAC3CE,CACF;EACA,GAAIb;EAEH,UAAAC,IAAW,kBAAC,OAAD;GAAK,WAAWL,EAAO;GAAQ,UAAAM;EAAW,CAAA,IAAI;CACvD,CAAA;AAET,CAAC"}
@@ -1,9 +1,9 @@
1
1
  import { type HTMLAttributes } from 'react';
2
2
  import { type Responsive } from '../../../utils/responsive.js';
3
- import { type Space } from '../../../utils/tokens.js';
3
+ import { type Space, type CategoryColor } from '../../../utils/tokens.js';
4
4
  import { type VisibilityProps } from '../../../utils/visibility.js';
5
5
  export type SectionElement = 'section' | 'div' | 'article' | 'aside' | 'header' | 'footer';
6
- export type SectionSurface = 'canvas' | 'surface' | 'sunken' | 'inverse' | 'accent';
6
+ export type SectionSurface = 'canvas' | 'surface' | 'sunken' | 'inverse' | 'accent' | `cat-${CategoryColor}`;
7
7
  export type SectionDivider = 'top' | 'bottom' | 'both';
8
8
  export interface SectionProps extends HTMLAttributes<HTMLElement>, VisibilityProps {
9
9
  /**
@@ -12,8 +12,9 @@ export interface SectionProps extends HTMLAttributes<HTMLElement>, VisibilityPro
12
12
  */
13
13
  space?: Responsive<Space>;
14
14
  /**
15
- * Full-bleed band colour. Omit to stay transparent on the canvas. `inverse` and
16
- * `accent` re-point the ink, line and focus colours so children stay legible.
15
+ * Full-bleed band colour. Omit to stay transparent on the canvas. `inverse`, `accent` and
16
+ * the categorical `cat-1` to `cat-8` re-point the ink, line and focus colours so children
17
+ * stay legible.
17
18
  */
18
19
  surface?: SectionSurface;
19
20
  /** A hairline across the full bleed at the top, bottom or both edges. */
@@ -31,8 +32,9 @@ export interface SectionProps extends HTMLAttributes<HTMLElement>, VisibilityPro
31
32
  *
32
33
  * ## Surfaces and bands
33
34
  *
34
- * `surface` is `canvas`, `surface`, `sunken`, `inverse` or `accent`. On `inverse` and `accent`,
35
- * the colour roles flip for everything inside, so text, links, focus rings and buttons stay
35
+ * `surface` is `canvas`, `surface`, `sunken`, `inverse`, `accent`, or a categorical `cat-1` to
36
+ * `cat-8` (a band in one person's or team's colour, matching their `Tag`). On `inverse`, `accent`
37
+ * and the categorical bands, the colour roles flip for everything inside, so text, links, focus rings and buttons stay
36
38
  * legible with no extra props. `divider` adds a rule at the `top`, `bottom` or `both`.
37
39
  *
38
40
  * @privateRemarks
@@ -1 +1 @@
1
- {"version":3,"file":"Section.js","names":["styles","Section_module_default","Section","forwardRef","spaceProp","Comp","rest","cx","visibilityClass","className","surface","divider","mergeStyles","responsiveVars","space","style"],"sources":["../../../../src/components/layout/Section/Section.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes } from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles, responsiveVars, type Responsive } from '#utils/responsive'\nimport { space, type Space } from '#utils/tokens'\nimport styles from './Section.module.css'\nimport { visibilityClass, type VisibilityProps } from '#utils/visibility'\n\nexport type SectionElement = 'section' | 'div' | 'article' | 'aside' | 'header' | 'footer'\nexport type SectionSurface = 'canvas' | 'surface' | 'sunken' | 'inverse' | 'accent'\nexport type SectionDivider = 'top' | 'bottom' | 'both'\n\nexport interface SectionProps extends HTMLAttributes<HTMLElement>, VisibilityProps {\n /**\n * Block padding (top and bottom), as a step on the space scale. Responsive.\n * Vary it: adjacent sections should not share the same step. Default `8`.\n */\n space?: Responsive<Space>\n /**\n * Full-bleed band colour. Omit to stay transparent on the canvas. `inverse` and\n * `accent` re-point the ink, line and focus colours so children stay legible.\n */\n surface?: SectionSurface\n /** A hairline across the full bleed at the top, bottom or both edges. */\n divider?: SectionDivider\n as?: SectionElement\n}\n\n/**\n * A full-bleed band of vertical space, with an optional surface and rules. Put a Container inside\n * it for width.\n *\n * @remarks\n * `Section` is how a page gets its rhythm: each band pads itself top and bottom with a step from\n * the space scale, and can paint a surface across the full width. Width is the `Container`'s job,\n * so a section is almost always `Section` then `Container`.\n *\n * ## Surfaces and bands\n *\n * `surface` is `canvas`, `surface`, `sunken`, `inverse` or `accent`. On `inverse` and `accent`,\n * the colour roles flip for everything inside, so text, links, focus rings and buttons stay\n * legible with no extra props. `divider` adds a rule at the `top`, `bottom` or `both`.\n *\n * @privateRemarks\n * A full-bleed band of vertical rhythm. Put a `Container` inside for width.\n *\n * <Section space={{ base: 7, md: 9 }} surface=\"sunken\" divider=\"both\">\n * <Container>…</Container>\n * </Section>\n */\nexport const Section = forwardRef<HTMLElement, SectionProps>(function Section(\n {\n space: spaceProp,\n surface,\n divider,\n as: Comp = 'section',\n hideBelow,\n hideAbove,\n className,\n style,\n ...rest\n },\n ref,\n) {\n return (\n <Comp\n // @ts-expect-error — polymorphic ref across a union of intrinsic elements is safe here\n ref={ref}\n className={cx(styles.section, visibilityClass({ hideBelow, hideAbove }), className)}\n data-surface={surface}\n data-divider={divider}\n style={mergeStyles(responsiveVars('section-space', spaceProp, space), style)}\n {...rest}\n />\n )\n})\n"],"mappings":";;;;;;;;AAiDA,IAAaE,IAAUC,EAAsC,SAC3D,EACE,OAAOC,GACP,YACA,YACA,IAAIC,IAAO,WACX,cACA,cACA,cACA,UACA,GAAGC,KAEL,GACA;CACA,OACE,kBAACD,GAAD;EAEO;EACL,WAAWE,EAAGP,EAAO,SAASQ,EAAgB;GAAE;GAAW;EAAU,CAAC,GAAGC,CAAS;EAClF,gBAAcC;EACd,gBAAcC;EACd,OAAOC,EAAYC,EAAe,iBAAiBT,GAAWU,CAAK,GAAGC,CAAK;EAC3E,GAAIT;CACL,CAAA;AAEL,CAAC"}
1
+ {"version":3,"file":"Section.js","names":["styles","Section_module_default","Section","forwardRef","spaceProp","Comp","rest","cx","visibilityClass","className","surface","divider","mergeStyles","responsiveVars","space","style"],"sources":["../../../../src/components/layout/Section/Section.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes } from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles, responsiveVars, type Responsive } from '#utils/responsive'\nimport { space, type Space, type CategoryColor } from '#utils/tokens'\nimport styles from './Section.module.css'\nimport { visibilityClass, type VisibilityProps } from '#utils/visibility'\n\nexport type SectionElement = 'section' | 'div' | 'article' | 'aside' | 'header' | 'footer'\nexport type SectionSurface =\n 'canvas' | 'surface' | 'sunken' | 'inverse' | 'accent' | `cat-${CategoryColor}`\nexport type SectionDivider = 'top' | 'bottom' | 'both'\n\nexport interface SectionProps extends HTMLAttributes<HTMLElement>, VisibilityProps {\n /**\n * Block padding (top and bottom), as a step on the space scale. Responsive.\n * Vary it: adjacent sections should not share the same step. Default `8`.\n */\n space?: Responsive<Space>\n /**\n * Full-bleed band colour. Omit to stay transparent on the canvas. `inverse`, `accent` and\n * the categorical `cat-1` to `cat-8` re-point the ink, line and focus colours so children\n * stay legible.\n */\n surface?: SectionSurface\n /** A hairline across the full bleed at the top, bottom or both edges. */\n divider?: SectionDivider\n as?: SectionElement\n}\n\n/**\n * A full-bleed band of vertical space, with an optional surface and rules. Put a Container inside\n * it for width.\n *\n * @remarks\n * `Section` is how a page gets its rhythm: each band pads itself top and bottom with a step from\n * the space scale, and can paint a surface across the full width. Width is the `Container`'s job,\n * so a section is almost always `Section` then `Container`.\n *\n * ## Surfaces and bands\n *\n * `surface` is `canvas`, `surface`, `sunken`, `inverse`, `accent`, or a categorical `cat-1` to\n * `cat-8` (a band in one person's or team's colour, matching their `Tag`). On `inverse`, `accent`\n * and the categorical bands, the colour roles flip for everything inside, so text, links, focus rings and buttons stay\n * legible with no extra props. `divider` adds a rule at the `top`, `bottom` or `both`.\n *\n * @privateRemarks\n * A full-bleed band of vertical rhythm. Put a `Container` inside for width.\n *\n * <Section space={{ base: 7, md: 9 }} surface=\"sunken\" divider=\"both\">\n * <Container>…</Container>\n * </Section>\n */\nexport const Section = forwardRef<HTMLElement, SectionProps>(function Section(\n {\n space: spaceProp,\n surface,\n divider,\n as: Comp = 'section',\n hideBelow,\n hideAbove,\n className,\n style,\n ...rest\n },\n ref,\n) {\n return (\n <Comp\n // @ts-expect-error — polymorphic ref across a union of intrinsic elements is safe here\n ref={ref}\n className={cx(styles.section, visibilityClass({ hideBelow, hideAbove }), className)}\n data-surface={surface}\n data-divider={divider}\n style={mergeStyles(responsiveVars('section-space', spaceProp, space), style)}\n {...rest}\n />\n )\n})\n"],"mappings":";;;;;;;;AAoDA,IAAaE,IAAUC,EAAsC,SAC3D,EACE,OAAOC,GACP,YACA,YACA,IAAIC,IAAO,WACX,cACA,cACA,cACA,UACA,GAAGC,KAEL,GACA;CACA,OACE,kBAACD,GAAD;EAEO;EACL,WAAWE,EAAGP,EAAO,SAASQ,EAAgB;GAAE;GAAW;EAAU,CAAC,GAAGC,CAAS;EAClF,gBAAcC;EACd,gBAAcC;EACd,OAAOC,EAAYC,EAAe,iBAAiBT,GAAWU,CAAK,GAAGC,CAAK;EAC3E,GAAIT;CACL,CAAA;AAEL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Section.module.js","names":["section","Section_module_default"],"sources":["../../../../src/components/layout/Section/Section.module.css"],"sourcesContent":["/*\n * Responsive pattern: see layout/Stack/Stack.module.css.\n *\n * Component tokens:\n * --section-fill / --section-on (read-only) the band's fill and ink on inverse/accent\n * --section-space-default block padding when `space` is unset (default var(--space-8))\n * --section-divider-color hairline colour for `divider` (default var(--color-line))\n */\n.section {\n --_space: var(--section-space-base, var(--section-space-default, var(--space-8)));\n --_rule: var(--border-width) solid var(--section-divider-color, var(--color-line));\n\n display: block;\n position: relative;\n min-inline-size: 0;\n padding-block: var(--_space);\n}\n\n@media (min-width: 40em) {\n .section {\n --_space: var(--section-space-sm, var(--section-space-default, var(--space-8)));\n }\n}\n@media (min-width: 48em) {\n .section {\n --_space: var(--section-space-md, var(--section-space-default, var(--space-8)));\n }\n}\n@media (min-width: 64em) {\n .section {\n --_space: var(--section-space-lg, var(--section-space-default, var(--space-8)));\n }\n}\n@media (min-width: 80em) {\n .section {\n --_space: var(--section-space-xl, var(--section-space-default, var(--space-8)));\n }\n}\n\n.section[data-divider='top'],\n.section[data-divider='both'] {\n border-block-start: var(--_rule);\n}\n.section[data-divider='bottom'],\n.section[data-divider='both'] {\n border-block-end: var(--_rule);\n}\n\n/* Surfaces */\n.section[data-surface='canvas'] {\n background-color: var(--color-canvas);\n background-image: var(--canvas-image);\n background-size: var(--canvas-image-size);\n color: var(--color-ink);\n}\n.section[data-surface='surface'] {\n background-color: var(--color-surface);\n color: var(--color-ink);\n}\n.section[data-surface='sunken'] {\n background-color: var(--color-surface-sunken);\n color: var(--color-ink);\n}\n\n/*\n * Inverse and accent bands re-point the colour roles for every descendant, so text,\n * hairlines, focus rings and nested controls (an outline or solid Button) stay legible\n * without per-child props. Mixes are taken against the band's own fill.\n *\n * Swapping a pair (e.g. ink <-> ink-inverse) can't happen on one element — it would be\n * a var() cycle — so the band publishes its fill/ink as --section-fill/--section-on and\n * the swapped roles are set on its children.\n */\n.section[data-surface='inverse'] {\n --section-fill: var(--color-surface-inverse);\n --section-on: var(--color-ink-inverse);\n}\n.section[data-surface='accent'] {\n --section-fill: var(--color-accent);\n --section-on: var(--color-accent-ink);\n}\n.section:is([data-surface='inverse'], [data-surface='accent']) {\n --color-ink: var(--section-on);\n --color-ink-muted: color-mix(in oklab, var(--section-on) 76%, var(--section-fill));\n --color-ink-subtle: color-mix(in oklab, var(--section-on) 60%, var(--section-fill));\n --color-line: color-mix(in oklab, var(--section-on) 22%, var(--section-fill));\n --color-line-strong: color-mix(in oklab, var(--section-on) 45%, var(--section-fill));\n --color-canvas: var(--section-fill);\n --color-surface: color-mix(in oklab, var(--section-on) 7%, var(--section-fill));\n --color-surface-sunken: color-mix(in oklab, var(--section-on) 12%, var(--section-fill));\n --color-surface-raised: color-mix(in oklab, var(--section-on) 4%, var(--section-fill));\n --color-focus: var(--section-on);\n --color-accent-text: var(--section-on);\n --canvas-image: none;\n\n background-color: var(--section-fill);\n color: var(--section-on);\n}\n/* An accent fill only clears AA against its own ink (~4.5-5:1), so there is no headroom\n for muted/subtle steps there: secondary text uses the full band ink, and nested\n surfaces stay the band fill (edges come from the line tokens) so text on them keeps AA. */\n.section[data-surface='accent'] {\n --color-ink-muted: var(--section-on);\n --color-ink-subtle: var(--section-on);\n --color-surface: var(--section-fill);\n --color-surface-sunken: var(--section-fill);\n --color-surface-raised: var(--section-fill);\n}\n.section[data-surface='inverse'] > * {\n --color-surface-inverse: var(--section-on);\n --color-ink-inverse: var(--section-fill);\n}\n/* On an accent band the accent itself becomes the band's ink, so a primary action still stands out. */\n.section[data-surface='accent'] > * {\n --color-accent: var(--section-on);\n --color-accent-hover: color-mix(in oklab, var(--section-on) 82%, var(--section-fill));\n --color-accent-ink: var(--section-fill);\n --color-accent-soft: color-mix(in oklab, var(--section-on) 12%, var(--section-fill));\n}\n\n/* `hidden` wins over the display above (author CSS otherwise beats the UA [hidden] rule). */\n.section[hidden] {\n display: none;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Section.module.js","names":["section","Section_module_default"],"sources":["../../../../src/components/layout/Section/Section.module.css"],"sourcesContent":["/*\n * Responsive pattern: see layout/Stack/Stack.module.css.\n *\n * Component tokens:\n * --section-fill / --section-on (read-only) the band's fill and ink on inverse/accent\n * --section-space-default block padding when `space` is unset (default var(--space-8))\n * --section-divider-color hairline colour for `divider` (default var(--color-line))\n */\n.section {\n --_space: var(--section-space-base, var(--section-space-default, var(--space-8)));\n --_rule: var(--border-width) solid var(--section-divider-color, var(--color-line));\n\n display: block;\n position: relative;\n min-inline-size: 0;\n padding-block: var(--_space);\n}\n\n@media (min-width: 40em) {\n .section {\n --_space: var(--section-space-sm, var(--section-space-default, var(--space-8)));\n }\n}\n@media (min-width: 48em) {\n .section {\n --_space: var(--section-space-md, var(--section-space-default, var(--space-8)));\n }\n}\n@media (min-width: 64em) {\n .section {\n --_space: var(--section-space-lg, var(--section-space-default, var(--space-8)));\n }\n}\n@media (min-width: 80em) {\n .section {\n --_space: var(--section-space-xl, var(--section-space-default, var(--space-8)));\n }\n}\n\n.section[data-divider='top'],\n.section[data-divider='both'] {\n border-block-start: var(--_rule);\n}\n.section[data-divider='bottom'],\n.section[data-divider='both'] {\n border-block-end: var(--_rule);\n}\n\n/* Surfaces */\n.section[data-surface='canvas'] {\n background-color: var(--color-canvas);\n background-image: var(--canvas-image);\n background-size: var(--canvas-image-size);\n color: var(--color-ink);\n}\n.section[data-surface='surface'] {\n background-color: var(--color-surface);\n color: var(--color-ink);\n}\n.section[data-surface='sunken'] {\n background-color: var(--color-surface-sunken);\n color: var(--color-ink);\n}\n\n/*\n * Inverse and accent bands re-point the colour roles for every descendant, so text,\n * hairlines, focus rings and nested controls (an outline or solid Button) stay legible\n * without per-child props. Mixes are taken against the band's own fill.\n *\n * Swapping a pair (e.g. ink <-> ink-inverse) can't happen on one element — it would be\n * a var() cycle — so the band publishes its fill/ink as --section-fill/--section-on and\n * the swapped roles are set on its children.\n */\n.section[data-surface='inverse'] {\n --section-fill: var(--color-surface-inverse);\n --section-on: var(--color-ink-inverse);\n}\n.section[data-surface='accent'] {\n --section-fill: var(--color-accent);\n --section-on: var(--color-accent-ink);\n}\n.section[data-surface='cat-1'] {\n --section-fill: var(--color-cat-1);\n}\n.section[data-surface='cat-2'] {\n --section-fill: var(--color-cat-2);\n}\n.section[data-surface='cat-3'] {\n --section-fill: var(--color-cat-3);\n}\n.section[data-surface='cat-4'] {\n --section-fill: var(--color-cat-4);\n}\n.section[data-surface='cat-5'] {\n --section-fill: var(--color-cat-5);\n}\n.section[data-surface='cat-6'] {\n --section-fill: var(--color-cat-6);\n}\n.section[data-surface='cat-7'] {\n --section-fill: var(--color-cat-7);\n}\n.section[data-surface='cat-8'] {\n --section-fill: var(--color-cat-8);\n}\n.section[data-surface^='cat-'] {\n --section-on: var(--color-cat-ink);\n}\n.section:is([data-surface='inverse'], [data-surface='accent'], [data-surface^='cat-']) {\n --color-ink: var(--section-on);\n --color-ink-muted: color-mix(in oklab, var(--section-on) 76%, var(--section-fill));\n --color-ink-subtle: color-mix(in oklab, var(--section-on) 60%, var(--section-fill));\n --color-line: color-mix(in oklab, var(--section-on) 22%, var(--section-fill));\n --color-line-strong: color-mix(in oklab, var(--section-on) 45%, var(--section-fill));\n --color-canvas: var(--section-fill);\n --color-surface: color-mix(in oklab, var(--section-on) 7%, var(--section-fill));\n --color-surface-sunken: color-mix(in oklab, var(--section-on) 12%, var(--section-fill));\n --color-surface-raised: color-mix(in oklab, var(--section-on) 4%, var(--section-fill));\n --color-focus: var(--section-on);\n --color-accent-text: var(--section-on);\n --canvas-image: none;\n\n background-color: var(--section-fill);\n color: var(--section-on);\n}\n/* An accent or categorical fill only clears AA against its own ink, so there is no headroom\n for muted/subtle steps there: secondary text uses the full band ink, and nested\n surfaces stay the band fill (edges come from the line tokens) so text on them keeps AA. */\n.section:is([data-surface='accent'], [data-surface^='cat-']) {\n --color-ink-muted: var(--section-on);\n --color-ink-subtle: var(--section-on);\n --color-surface: var(--section-fill);\n --color-surface-sunken: var(--section-fill);\n --color-surface-raised: var(--section-fill);\n}\n.section[data-surface='inverse'] > * {\n --color-surface-inverse: var(--section-on);\n --color-ink-inverse: var(--section-fill);\n}\n/* On an accent band the accent itself becomes the band's ink, so a primary action still stands out. */\n.section[data-surface='accent'] > * {\n --color-accent: var(--section-on);\n --color-accent-hover: color-mix(in oklab, var(--section-on) 82%, var(--section-fill));\n --color-accent-ink: var(--section-fill);\n --color-accent-soft: color-mix(in oklab, var(--section-on) 12%, var(--section-fill));\n}\n\n/* `hidden` wins over the display above (author CSS otherwise beats the UA [hidden] rule). */\n.section[hidden] {\n display: none;\n}\n"],"mappings":""}
@@ -1,4 +1,4 @@
1
- import { type ComponentPropsWithoutRef } from 'react';
1
+ import { type ComponentPropsWithoutRef, type ReactNode } from 'react';
2
2
  import { Accordion as AccordionPrimitive } from 'radix-ui';
3
3
  export type AccordionVariant = 'divided' | 'contained';
4
4
  export type AccordionSize = 'sm' | 'md';
@@ -13,6 +13,11 @@ export type AccordionItemProps = ComponentPropsWithoutRef<typeof AccordionPrimit
13
13
  export interface AccordionTriggerProps extends ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger> {
14
14
  /** Heading level wrapping the trigger, for the document outline. Default 3. */
15
15
  level?: 2 | 3 | 4 | 5 | 6;
16
+ /**
17
+ * A figure or badge at the end of the trigger, just before the chevron, like a score beside
18
+ * a match. Keep it phrasing content (`Numeral`, `Badge`, `Text`): it's inside a button.
19
+ */
20
+ trailing?: ReactNode;
16
21
  }
17
22
  export type AccordionContentProps = ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>;
18
23
  /**
@@ -27,21 +27,29 @@ var u = i("md"), d = a(function({ variant: t = "divided", size: n = "md", classN
27
27
  className: e(r.item, t),
28
28
  ...n
29
29
  });
30
- }), p = a(function({ level: i = 3, className: a, children: d, ...f }, p) {
31
- let m = o(u), h = n(i);
30
+ }), p = a(function({ level: i = 3, trailing: a, className: d, children: f, ...p }, m) {
31
+ let h = o(u), g = n(i);
32
32
  return /* @__PURE__ */ s(l.Header, {
33
33
  asChild: !0,
34
- children: /* @__PURE__ */ s(h, {
34
+ children: /* @__PURE__ */ s(g, {
35
35
  className: r.header,
36
36
  children: /* @__PURE__ */ c(l.Trigger, {
37
- ref: p,
38
- className: e(r.trigger, a),
39
- "data-size": m,
40
- ...f,
41
- children: [/* @__PURE__ */ s("span", {
42
- className: r.triggerLabel,
43
- children: d
44
- }), /* @__PURE__ */ s(t, { className: r.chevron })]
37
+ ref: m,
38
+ className: e(r.trigger, d),
39
+ "data-size": h,
40
+ "data-trailing": a !== void 0 || void 0,
41
+ ...p,
42
+ children: [
43
+ /* @__PURE__ */ s("span", {
44
+ className: r.triggerLabel,
45
+ children: f
46
+ }),
47
+ a === void 0 ? null : /* @__PURE__ */ s("span", {
48
+ className: r.triggerTrailing,
49
+ children: a
50
+ }),
51
+ /* @__PURE__ */ s(t, { className: r.chevron })
52
+ ]
45
53
  })
46
54
  })
47
55
  });
@@ -1 +1 @@
1
- {"version":3,"file":"Accordion.js","names":["Accordion","AccordionPrimitive","styles","Accordion_module_default","SizeContext","createContext","AccordionRoot","forwardRef","rest","props","size","Accordion","cx","className","variant","AccordionItem","AccordionTrigger","useContext","Heading","headingTag","level","ChevronDownIcon","AccordionContent","Accordion$1"],"sources":["../../../../src/components/navigation/Accordion/Accordion.tsx"],"sourcesContent":["import { createContext, forwardRef, useContext, type ComponentPropsWithoutRef } from 'react'\nimport { Accordion as AccordionPrimitive } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport { ChevronDownIcon } from '#icons'\nimport styles from './Accordion.module.css'\nimport { headingTag } from '#utils/heading'\n\nexport type AccordionVariant = 'divided' | 'contained'\nexport type AccordionSize = 'sm' | 'md'\n\ninterface AccordionOwnProps {\n /** `divided` (default): hairlines between items, no box. `contained`: a bordered surface. */\n variant?: AccordionVariant\n /** `sm` for inline notes (\"Why is this invoice overdue?\"); `md` for FAQs and sections. */\n size?: AccordionSize\n}\n\nexport type AccordionProps = (\n AccordionPrimitive.AccordionSingleProps | AccordionPrimitive.AccordionMultipleProps\n) &\n AccordionOwnProps\n\nconst SizeContext = createContext<AccordionSize>('md')\n\nconst AccordionRoot = forwardRef<HTMLDivElement, AccordionProps>(function Accordion(\n { variant = 'divided', size = 'md', className, ...rest },\n ref,\n) {\n const props = rest.type === 'single' ? { collapsible: true, ...rest } : rest // single items can close by default\n return (\n <SizeContext.Provider value={size}>\n <AccordionPrimitive.Root\n ref={ref}\n className={cx(styles.root, className)}\n data-variant={variant}\n data-size={size}\n {...props}\n />\n </SizeContext.Provider>\n )\n})\n\nexport type AccordionItemProps = ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>\n\nconst AccordionItem = forwardRef<HTMLDivElement, AccordionItemProps>(function AccordionItem(\n { className, ...rest },\n ref,\n) {\n return <AccordionPrimitive.Item ref={ref} className={cx(styles.item, className)} {...rest} />\n})\n\nexport interface AccordionTriggerProps extends ComponentPropsWithoutRef<\n typeof AccordionPrimitive.Trigger\n> {\n /** Heading level wrapping the trigger, for the document outline. Default 3. */\n level?: 2 | 3 | 4 | 5 | 6\n}\n\nconst AccordionTrigger = forwardRef<HTMLButtonElement, AccordionTriggerProps>(\n function AccordionTrigger({ level = 3, className, children, ...rest }, ref) {\n const size = useContext(SizeContext)\n const Heading = headingTag(level)\n return (\n <AccordionPrimitive.Header asChild>\n <Heading className={styles.header}>\n <AccordionPrimitive.Trigger\n ref={ref}\n className={cx(styles.trigger, className)}\n data-size={size}\n {...rest}\n >\n <span className={styles.triggerLabel}>{children}</span>\n <ChevronDownIcon className={styles.chevron} />\n </AccordionPrimitive.Trigger>\n </Heading>\n </AccordionPrimitive.Header>\n )\n },\n)\n\nexport type AccordionContentProps = ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>\n\nconst AccordionContent = forwardRef<HTMLDivElement, AccordionContentProps>(\n function AccordionContent({ className, children, ...rest }, ref) {\n const size = useContext(SizeContext)\n return (\n <AccordionPrimitive.Content\n ref={ref}\n className={cx(styles.content, className)}\n data-size={size}\n {...rest}\n >\n <div className={styles.contentInner}>{children}</div>\n </AccordionPrimitive.Content>\n )\n },\n)\n\n/**\n * Expandable sections with a turning chevron. Also Kiln's disclosure, for a single \"why?\" note.\n *\n * @remarks\n * `Accordion` stacks sections whose content expands under their heading. It's Radix Accordion\n * underneath, so triggers are buttons inside headings, and arrow keys move between them.\n *\n * @privateRemarks\n * Radix Accordion: expandable sections with a rotating chevron and a height animation.\n * Also the library's disclosure: use one `type=\"single\"` item for an inline \"why?\" note.\n * Single accordions are `collapsible` unless you pass `collapsible={false}`.\n *\n * <Accordion type=\"single\">\n * <Accordion.Item value=\"scoring\">\n * <Accordion.Trigger>How scoring works</Accordion.Trigger>\n * <Accordion.Content>…</Accordion.Content>\n * </Accordion.Item>\n * </Accordion>\n */\nexport const Accordion = Object.assign(AccordionRoot, {\n Item: AccordionItem,\n Trigger: AccordionTrigger,\n Content: AccordionContent,\n})\n"],"mappings":";;;;;;;;AAsBA,IAAMI,IAAcC,EAA6B,IAAI,GAE/CC,IAAgBC,EAA2C,SAC/D,EAAE,aAAU,WAAW,UAAO,MAAM,cAAW,GAAGC,KAClD,GACA;CACA,IAAMC,IAAQD,EAAK,SAAS,WAAW;EAAE,aAAa;EAAM,GAAGA;CAAK,IAAIA;CACxE,OACE,kBAACJ,EAAY,UAAb;EAAsB,OAAOM;EAC3B,UAAA,kBAACT,EAAmB,MAApB;GACO;GACL,WAAWW,EAAGV,EAAO,MAAMW,CAAS;GACpC,gBAAcC;GACd,aAAWJ;GACX,GAAID;EACL,CAAA;CACmB,CAAA;AAE1B,CAAC,GAIKM,IAAgBR,EAA+C,SACnE,EAAE,cAAW,GAAGC,KAChB,GACA;CACA,OAAO,kBAACP,EAAmB,MAApB;EAA8B;EAAK,WAAWW,EAAGV,EAAO,MAAMW,CAAS;EAAG,GAAIL;CAAO,CAAA;AAC9F,CAAC,GASKQ,IAAmBT,EACvB,SAA0B,EAAE,WAAQ,GAAG,cAAW,aAAU,GAAGC,KAAQ,GAAK;CAC1E,IAAME,IAAOO,EAAWb,CAAW,GAC7Bc,IAAUC,EAAWC,CAAK;CAChC,OACE,kBAACnB,EAAmB,QAApB;EAA2B,SAAA;EACzB,UAAA,kBAACiB,GAAD;GAAS,WAAWhB,EAAO;GACzB,UAAA,kBAACD,EAAmB,SAApB;IACO;IACL,WAAWW,EAAGV,EAAO,SAASW,CAAS;IACvC,aAAWH;IACX,GAAIF;IAJN,UAAA,CAME,kBAAC,QAAD;KAAM,WAAWN,EAAO;KAAe;IAAe,CAAA,GACtD,kBAACmB,GAAD,EAAiB,WAAWnB,EAAO,QAAU,CAAA,CACnB;;EACrB,CAAA;CACgB,CAAA;AAE/B,CACF,GAIMoB,IAAmBf,EACvB,SAA0B,EAAE,cAAW,aAAU,GAAGC,KAAQ,GAAK;CAC/D,IAAME,IAAOO,EAAWb,CAAW;CACnC,OACE,kBAACH,EAAmB,SAApB;EACO;EACL,WAAWW,EAAGV,EAAO,SAASW,CAAS;EACvC,aAAWH;EACX,GAAIF;EAEJ,UAAA,kBAAC,OAAD;GAAK,WAAWN,EAAO;GAAe;EAAc,CAAA;CAC1B,CAAA;AAEhC,CACF,GAqBaF,IAAY,OAAO,OAAOM,GAAe;CACpD,MAAMS;CACN,SAASC;CACT,SAASM;AACX,CAAC"}
1
+ {"version":3,"file":"Accordion.js","names":["Accordion","AccordionPrimitive","styles","Accordion_module_default","SizeContext","createContext","AccordionRoot","forwardRef","rest","props","size","Accordion","cx","className","variant","AccordionItem","AccordionTrigger","useContext","Heading","headingTag","level","trailing","ChevronDownIcon","AccordionContent","Accordion$1"],"sources":["../../../../src/components/navigation/Accordion/Accordion.tsx"],"sourcesContent":["import {\n createContext,\n forwardRef,\n useContext,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\nimport { Accordion as AccordionPrimitive } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport { ChevronDownIcon } from '#icons'\nimport styles from './Accordion.module.css'\nimport { headingTag } from '#utils/heading'\n\nexport type AccordionVariant = 'divided' | 'contained'\nexport type AccordionSize = 'sm' | 'md'\n\ninterface AccordionOwnProps {\n /** `divided` (default): hairlines between items, no box. `contained`: a bordered surface. */\n variant?: AccordionVariant\n /** `sm` for inline notes (\"Why is this invoice overdue?\"); `md` for FAQs and sections. */\n size?: AccordionSize\n}\n\nexport type AccordionProps = (\n AccordionPrimitive.AccordionSingleProps | AccordionPrimitive.AccordionMultipleProps\n) &\n AccordionOwnProps\n\nconst SizeContext = createContext<AccordionSize>('md')\n\nconst AccordionRoot = forwardRef<HTMLDivElement, AccordionProps>(function Accordion(\n { variant = 'divided', size = 'md', className, ...rest },\n ref,\n) {\n const props = rest.type === 'single' ? { collapsible: true, ...rest } : rest // single items can close by default\n return (\n <SizeContext.Provider value={size}>\n <AccordionPrimitive.Root\n ref={ref}\n className={cx(styles.root, className)}\n data-variant={variant}\n data-size={size}\n {...props}\n />\n </SizeContext.Provider>\n )\n})\n\nexport type AccordionItemProps = ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>\n\nconst AccordionItem = forwardRef<HTMLDivElement, AccordionItemProps>(function AccordionItem(\n { className, ...rest },\n ref,\n) {\n return <AccordionPrimitive.Item ref={ref} className={cx(styles.item, className)} {...rest} />\n})\n\nexport interface AccordionTriggerProps extends ComponentPropsWithoutRef<\n typeof AccordionPrimitive.Trigger\n> {\n /** Heading level wrapping the trigger, for the document outline. Default 3. */\n level?: 2 | 3 | 4 | 5 | 6\n /**\n * A figure or badge at the end of the trigger, just before the chevron, like a score beside\n * a match. Keep it phrasing content (`Numeral`, `Badge`, `Text`): it's inside a button.\n */\n trailing?: ReactNode\n}\n\nconst AccordionTrigger = forwardRef<HTMLButtonElement, AccordionTriggerProps>(\n function AccordionTrigger({ level = 3, trailing, className, children, ...rest }, ref) {\n const size = useContext(SizeContext)\n const Heading = headingTag(level)\n return (\n <AccordionPrimitive.Header asChild>\n <Heading className={styles.header}>\n <AccordionPrimitive.Trigger\n ref={ref}\n className={cx(styles.trigger, className)}\n data-size={size}\n data-trailing={trailing !== undefined || undefined}\n {...rest}\n >\n <span className={styles.triggerLabel}>{children}</span>\n {trailing !== undefined ? (\n <span className={styles.triggerTrailing}>{trailing}</span>\n ) : null}\n <ChevronDownIcon className={styles.chevron} />\n </AccordionPrimitive.Trigger>\n </Heading>\n </AccordionPrimitive.Header>\n )\n },\n)\n\nexport type AccordionContentProps = ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>\n\nconst AccordionContent = forwardRef<HTMLDivElement, AccordionContentProps>(\n function AccordionContent({ className, children, ...rest }, ref) {\n const size = useContext(SizeContext)\n return (\n <AccordionPrimitive.Content\n ref={ref}\n className={cx(styles.content, className)}\n data-size={size}\n {...rest}\n >\n <div className={styles.contentInner}>{children}</div>\n </AccordionPrimitive.Content>\n )\n },\n)\n\n/**\n * Expandable sections with a turning chevron. Also Kiln's disclosure, for a single \"why?\" note.\n *\n * @remarks\n * `Accordion` stacks sections whose content expands under their heading. It's Radix Accordion\n * underneath, so triggers are buttons inside headings, and arrow keys move between them.\n *\n * @privateRemarks\n * Radix Accordion: expandable sections with a rotating chevron and a height animation.\n * Also the library's disclosure: use one `type=\"single\"` item for an inline \"why?\" note.\n * Single accordions are `collapsible` unless you pass `collapsible={false}`.\n *\n * <Accordion type=\"single\">\n * <Accordion.Item value=\"scoring\">\n * <Accordion.Trigger>How scoring works</Accordion.Trigger>\n * <Accordion.Content>…</Accordion.Content>\n * </Accordion.Item>\n * </Accordion>\n */\nexport const Accordion = Object.assign(AccordionRoot, {\n Item: AccordionItem,\n Trigger: AccordionTrigger,\n Content: AccordionContent,\n})\n"],"mappings":";;;;;;;;AA4BA,IAAMI,IAAcC,EAA6B,IAAI,GAE/CC,IAAgBC,EAA2C,SAC/D,EAAE,aAAU,WAAW,UAAO,MAAM,cAAW,GAAGC,KAClD,GACA;CACA,IAAMC,IAAQD,EAAK,SAAS,WAAW;EAAE,aAAa;EAAM,GAAGA;CAAK,IAAIA;CACxE,OACE,kBAACJ,EAAY,UAAb;EAAsB,OAAOM;EAC3B,UAAA,kBAACT,EAAmB,MAApB;GACO;GACL,WAAWW,EAAGV,EAAO,MAAMW,CAAS;GACpC,gBAAcC;GACd,aAAWJ;GACX,GAAID;EACL,CAAA;CACmB,CAAA;AAE1B,CAAC,GAIKM,IAAgBR,EAA+C,SACnE,EAAE,cAAW,GAAGC,KAChB,GACA;CACA,OAAO,kBAACP,EAAmB,MAApB;EAA8B;EAAK,WAAWW,EAAGV,EAAO,MAAMW,CAAS;EAAG,GAAIL;CAAO,CAAA;AAC9F,CAAC,GAcKQ,IAAmBT,EACvB,SAA0B,EAAE,WAAQ,GAAG,aAAU,cAAW,aAAU,GAAGC,KAAQ,GAAK;CACpF,IAAME,IAAOO,EAAWb,CAAW,GAC7Bc,IAAUC,EAAWC,CAAK;CAChC,OACE,kBAACnB,EAAmB,QAApB;EAA2B,SAAA;EACzB,UAAA,kBAACiB,GAAD;GAAS,WAAWhB,EAAO;GACzB,UAAA,kBAACD,EAAmB,SAApB;IACO;IACL,WAAWW,EAAGV,EAAO,SAASW,CAAS;IACvC,aAAWH;IACX,iBAAeW,MAAa,KAAA,KAAa,KAAA;IACzC,GAAIb;IALN,UAAA;KAOE,kBAAC,QAAD;MAAM,WAAWN,EAAO;MAAe;KAAe,CAAA;KACrDmB,MAAa,KAAA,IAEV,OADF,kBAAC,QAAD;MAAM,WAAWnB,EAAO;MAAkB,UAAAmB;KAAe,CAAA;KAE3D,kBAACC,GAAD,EAAiB,WAAWpB,EAAO,QAAU,CAAA;IACnB;;EACrB,CAAA;CACgB,CAAA;AAE/B,CACF,GAIMqB,IAAmBhB,EACvB,SAA0B,EAAE,cAAW,aAAU,GAAGC,KAAQ,GAAK;CAC/D,IAAME,IAAOO,EAAWb,CAAW;CACnC,OACE,kBAACH,EAAmB,SAApB;EACO;EACL,WAAWW,EAAGV,EAAO,SAASW,CAAS;EACvC,aAAWH;EACX,GAAIF;EAEJ,UAAA,kBAAC,OAAD;GAAK,WAAWN,EAAO;GAAe;EAAc,CAAA;CAC1B,CAAA;AAEhC,CACF,GAqBaF,IAAY,OAAO,OAAOM,GAAe;CACpD,MAAMS;CACN,SAASC;CACT,SAASO;AACX,CAAC"}
@@ -1,17 +1,18 @@
1
1
  //#region src/components/navigation/Accordion/Accordion.module.css
2
- var e = "kiln-Accordion__root", t = "kiln-Accordion__item", n = "kiln-Accordion__header", r = "kiln-Accordion__trigger", i = "kiln-Accordion__chevron", a = "kiln-Accordion__triggerLabel", o = "kiln-Accordion__content", s = "kiln-Accordion__open", c = "kiln-Accordion__close", l = "kiln-Accordion__contentInner", u = {
2
+ var e = "kiln-Accordion__root", t = "kiln-Accordion__item", n = "kiln-Accordion__header", r = "kiln-Accordion__trigger", i = "kiln-Accordion__chevron", a = "kiln-Accordion__triggerLabel", o = "kiln-Accordion__triggerTrailing", s = "kiln-Accordion__content", c = "kiln-Accordion__open", l = "kiln-Accordion__close", u = "kiln-Accordion__contentInner", d = {
3
3
  root: e,
4
4
  item: t,
5
5
  header: n,
6
6
  trigger: r,
7
7
  chevron: i,
8
8
  triggerLabel: a,
9
- content: o,
10
- open: s,
11
- close: c,
12
- contentInner: l
9
+ triggerTrailing: o,
10
+ content: s,
11
+ open: c,
12
+ close: l,
13
+ contentInner: u
13
14
  };
14
15
  //#endregion
15
- export { i as chevron, c as close, o as content, l as contentInner, u as default, n as header, t as item, s as open, e as root, r as trigger, a as triggerLabel };
16
+ export { i as chevron, l as close, s as content, u as contentInner, d as default, n as header, t as item, c as open, e as root, r as trigger, a as triggerLabel, o as triggerTrailing };
16
17
 
17
18
  //# sourceMappingURL=Accordion.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Accordion.module.js","names":["root","item","header","trigger","chevron","triggerLabel","content","open","close","contentInner","Accordion_module_default"],"sources":["../../../../src/components/navigation/Accordion/Accordion.module.css"],"sourcesContent":["/*\n * Component tokens:\n * --accordion-radius contained variant, default var(--radius-surface)\n * --accordion-bg contained variant, default var(--color-surface)\n * --accordion-shadow contained variant, default var(--shadow-surface)\n */\n.root {\n --_px: 0px;\n\n min-inline-size: 0;\n}\n\n.root[data-variant='contained'] {\n --_px: var(--space-4);\n\n overflow: hidden;\n border: var(--border-width) solid var(--color-line-strong);\n border-radius: var(--accordion-radius, var(--radius-surface));\n background: var(--accordion-bg, var(--color-surface));\n box-shadow: var(--accordion-shadow, var(--shadow-surface));\n}\n\n.item + .item {\n border-block-start: var(--border-width) solid var(--color-line);\n}\n\n.header {\n all: unset;\n display: flex;\n}\n\n.trigger {\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-4);\n min-block-size: max(2.75rem, var(--control-lg));\n padding-block: var(--space-3);\n padding-inline: var(--_px);\n border: 0;\n background: transparent;\n color: var(--color-ink);\n font-family: var(--font-text);\n font-size: var(--text-md);\n font-weight: var(--label-weight);\n letter-spacing: var(--label-tracking);\n text-transform: var(--label-transform);\n line-height: var(--leading-snug);\n text-align: start;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition:\n color var(--dur-1) var(--ease-out),\n background-color var(--dur-1) var(--ease-out);\n}\n.trigger[data-size='sm'] {\n /* Small = an inline note: the chevron follows the label instead of hugging the far edge. */\n justify-content: flex-start;\n gap: var(--space-2);\n min-block-size: max(2.75rem, var(--control-sm));\n padding-block: var(--space-2);\n font-size: var(--text-sm);\n}\n\n@media (hover: hover) {\n .trigger:hover:not(:disabled) .chevron {\n color: var(--color-ink);\n }\n .root[data-variant='contained'] .trigger:hover:not(:disabled) {\n background: var(--color-surface-sunken);\n }\n}\n\n.trigger:focus-visible {\n outline: 2px solid var(--color-focus);\n outline-offset: -2px;\n border-radius: var(--radius-field);\n}\n\n.trigger:disabled {\n cursor: not-allowed;\n opacity: 0.45;\n}\n\n.triggerLabel {\n min-inline-size: 0;\n}\n\n.chevron {\n flex: none;\n font-size: 1.25rem;\n color: var(--color-ink-subtle);\n transition:\n rotate var(--dur-2) var(--ease-spring),\n color var(--dur-1) var(--ease-out);\n}\n.trigger[data-size='sm'] .chevron {\n font-size: 1rem;\n}\n.trigger[data-state='open'] .chevron {\n rotate: 180deg;\n color: var(--color-ink);\n}\n\n/* ── Content: height animates to Radix's measured value ─────────────────── */\n.content {\n overflow: hidden;\n color: var(--color-ink-muted);\n font-size: var(--text-sm);\n line-height: var(--leading-body);\n}\n.content[data-state='open'] {\n animation: open var(--dur-3) var(--ease-out);\n}\n.content[data-state='closed'] {\n animation: close var(--dur-2) var(--ease-out);\n}\n.contentInner {\n padding-block-end: var(--space-4);\n padding-inline: var(--_px);\n padding-inline-end: calc(var(--_px) + 1.25rem + var(--space-4));\n}\n.content[data-size='sm'] .contentInner {\n padding-block-end: var(--space-3);\n padding-inline-end: var(--_px);\n}\n\n@keyframes open {\n from {\n block-size: 0;\n }\n to {\n block-size: var(--radix-accordion-content-height);\n }\n}\n@keyframes close {\n from {\n block-size: var(--radix-accordion-content-height);\n }\n to {\n block-size: 0;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .content[data-state='open'],\n .content[data-state='closed'] {\n animation: none;\n }\n .chevron {\n transition: none;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Accordion.module.js","names":["root","item","header","trigger","chevron","triggerLabel","triggerTrailing","content","open","close","contentInner","Accordion_module_default"],"sources":["../../../../src/components/navigation/Accordion/Accordion.module.css"],"sourcesContent":["/*\n * Component tokens:\n * --accordion-radius contained variant, default var(--radius-surface)\n * --accordion-bg contained variant, default var(--color-surface)\n * --accordion-shadow contained variant, default var(--shadow-surface)\n */\n.root {\n --_px: 0px;\n\n min-inline-size: 0;\n}\n\n.root[data-variant='contained'] {\n --_px: var(--space-4);\n\n overflow: hidden;\n border: var(--border-width) solid var(--color-line-strong);\n border-radius: var(--accordion-radius, var(--radius-surface));\n background: var(--accordion-bg, var(--color-surface));\n box-shadow: var(--accordion-shadow, var(--shadow-surface));\n}\n\n.item + .item {\n border-block-start: var(--border-width) solid var(--color-line);\n}\n\n.header {\n all: unset;\n display: flex;\n}\n\n.trigger {\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-4);\n min-block-size: max(2.75rem, var(--control-lg));\n padding-block: var(--space-3);\n padding-inline: var(--_px);\n border: 0;\n background: transparent;\n color: var(--color-ink);\n font-family: var(--font-text);\n font-size: var(--text-md);\n font-weight: var(--label-weight);\n letter-spacing: var(--label-tracking);\n text-transform: var(--label-transform);\n line-height: var(--leading-snug);\n text-align: start;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition:\n color var(--dur-1) var(--ease-out),\n background-color var(--dur-1) var(--ease-out);\n}\n.trigger[data-size='sm'] {\n /* Small = an inline note: the chevron follows the label instead of hugging the far edge. */\n justify-content: flex-start;\n gap: var(--space-2);\n min-block-size: max(2.75rem, var(--control-sm));\n padding-block: var(--space-2);\n font-size: var(--text-sm);\n}\n\n@media (hover: hover) {\n .trigger:hover:not(:disabled) .chevron {\n color: var(--color-ink);\n }\n .root[data-variant='contained'] .trigger:hover:not(:disabled) {\n background: var(--color-surface-sunken);\n }\n}\n\n.trigger:focus-visible {\n outline: 2px solid var(--color-focus);\n outline-offset: -2px;\n border-radius: var(--radius-field);\n}\n\n.trigger:disabled {\n cursor: not-allowed;\n opacity: 0.45;\n}\n\n/* The label fills the trigger, so its content can spread to the chevron or `trailing`. */\n.triggerLabel {\n flex: 1 1 auto;\n min-inline-size: 0;\n}\n.trigger[data-size='sm'] .triggerLabel {\n flex: 0 1 auto;\n}\n/* With a trailing figure, even a small trigger's label fills, so the figures in a list line up. */\n.trigger[data-size='sm'][data-trailing] .triggerLabel {\n flex: 1 1 auto;\n}\n.triggerTrailing {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: var(--space-2);\n font-variant-numeric: tabular-nums lining-nums;\n}\n\n.chevron {\n flex: none;\n font-size: 1.25rem;\n color: var(--color-ink-subtle);\n transition:\n rotate var(--dur-2) var(--ease-spring),\n color var(--dur-1) var(--ease-out);\n}\n.trigger[data-size='sm'] .chevron {\n font-size: 1rem;\n}\n.trigger[data-state='open'] .chevron {\n rotate: 180deg;\n color: var(--color-ink);\n}\n\n/* ── Content: height animates to Radix's measured value ─────────────────── */\n.content {\n overflow: hidden;\n color: var(--color-ink-muted);\n font-size: var(--text-sm);\n line-height: var(--leading-body);\n}\n.content[data-state='open'] {\n animation: open var(--dur-3) var(--ease-out);\n}\n.content[data-state='closed'] {\n animation: close var(--dur-2) var(--ease-out);\n}\n.contentInner {\n padding-block-end: var(--space-4);\n padding-inline: var(--_px);\n padding-inline-end: calc(var(--_px) + 1.25rem + var(--space-4));\n}\n.content[data-size='sm'] .contentInner {\n padding-block-end: var(--space-3);\n padding-inline-end: var(--_px);\n}\n\n@keyframes open {\n from {\n block-size: 0;\n }\n to {\n block-size: var(--radix-accordion-content-height);\n }\n}\n@keyframes close {\n from {\n block-size: var(--radix-accordion-content-height);\n }\n to {\n block-size: 0;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .content[data-state='open'],\n .content[data-state='closed'] {\n animation: none;\n }\n .chevron {\n transition: none;\n }\n}\n"],"mappings":""}
@@ -13,7 +13,10 @@ export interface NavLinksProps extends HTMLAttributes<HTMLElement>, VisibilityPr
13
13
  * vertical (vertical items are already a full control tall).
14
14
  */
15
15
  gap?: Space;
16
- /** `md` (default) for page headers; `sm` for dense toolbars, footers and sub-navs. */
16
+ /**
17
+ * `md` (default), body-size labels for page headers; `sm`, one step smaller, for sidebars,
18
+ * dense toolbars, footers and sub-navs. Neither drops to the caption steps.
19
+ */
17
20
  size?: NavLinksSize;
18
21
  }
19
22
  export interface NavLinksItemProps extends AnchorHTMLAttributes<HTMLAnchorElement>, VisibilityProps {
@@ -1 +1 @@
1
- {"version":3,"file":"NavLinks.js","names":["styles","NavLinks_module_default","NavLinksContext","createContext","NavLinksRoot","forwardRef","rest","label","cx","visibilityClass","className","orientation","size","gap","space","NavLinksItem","useContext","Comp","asChild","Slot","active","NavLinks"],"sources":["../../../../src/components/navigation/NavLinks/NavLinks.tsx"],"sourcesContent":["import {\n createContext,\n forwardRef,\n useContext,\n type AnchorHTMLAttributes,\n type CSSProperties,\n type HTMLAttributes,\n} from 'react'\nimport { Slot } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport { space, type Space } from '#utils/tokens'\nimport { visibilityClass, type VisibilityProps } from '#utils/visibility'\nimport styles from './NavLinks.module.css'\n\nexport type NavLinksOrientation = 'horizontal' | 'vertical'\nexport type NavLinksSize = 'sm' | 'md'\n\nexport interface NavLinksProps extends HTMLAttributes<HTMLElement>, VisibilityProps {\n /** Names the landmark. Required when a page has more than one nav. Default \"Main\". */\n label?: string\n /** `horizontal` (default) for headers; `vertical` for sidebars and footers. */\n orientation?: NavLinksOrientation\n /**\n * Space between links, as a step on the space scale. Default `5` horizontal, `0`\n * vertical (vertical items are already a full control tall).\n */\n gap?: Space\n /** `md` (default) for page headers; `sm` for dense toolbars, footers and sub-navs. */\n size?: NavLinksSize\n}\n\ninterface NavLinksContextValue {\n orientation: NavLinksOrientation\n size: NavLinksSize\n}\n\nconst NavLinksContext = createContext<NavLinksContextValue>({\n orientation: 'horizontal',\n size: 'md',\n})\n\nconst NavLinksRoot = forwardRef<HTMLElement, NavLinksProps>(function NavLinks(\n {\n label = 'Main',\n orientation = 'horizontal',\n gap,\n size = 'md',\n hideBelow,\n hideAbove,\n className,\n children,\n ...rest\n },\n ref,\n) {\n return (\n <NavLinksContext.Provider value={{ orientation, size }}>\n <nav\n ref={ref}\n aria-label={label}\n className={cx(styles.nav, visibilityClass({ hideBelow, hideAbove }), className)}\n data-orientation={orientation}\n data-size={size}\n {...rest}\n >\n <ul\n className={styles.list}\n role=\"list\"\n style={gap === undefined ? undefined : ({ '--_gap': space(gap) } as CSSProperties)}\n >\n {children}\n </ul>\n </nav>\n </NavLinksContext.Provider>\n )\n})\n\nexport interface NavLinksItemProps\n extends AnchorHTMLAttributes<HTMLAnchorElement>, VisibilityProps {\n /** The current page. Sets `aria-current=\"page\"` and draws the marker. */\n active?: boolean\n /** Render the single child (e.g. a router `<Link>`) instead of an `<a>`. */\n asChild?: boolean\n}\n\n/**\n * One link. For router links: `<NavLinks.Item asChild active={isActive}><Link to=\"/work\">Work</Link></NavLinks.Item>`.\n * `hideBelow`/`hideAbove` hide the whole list item (e.g. a secondary link on phones).\n */\nconst NavLinksItem = forwardRef<HTMLAnchorElement, NavLinksItemProps>(function NavLinksItem(\n { active = false, asChild = false, hideBelow, hideAbove, className, ...rest },\n ref,\n) {\n const { orientation, size } = useContext(NavLinksContext)\n const Comp = asChild ? Slot.Root : 'a'\n return (\n <li className={cx(styles.item, visibilityClass({ hideBelow, hideAbove }))}>\n <Comp\n ref={ref}\n className={cx(styles.link, className)}\n data-orientation={orientation}\n data-size={size}\n data-active={active || undefined}\n aria-current={active ? 'page' : undefined}\n {...rest}\n />\n </li>\n )\n})\n\n/**\n * A labelled navigation landmark with a list of links. Horizontal for headers, vertical for\n * sidebars.\n *\n * @remarks\n * `NavLinks` is a `<nav>` with a list of links. The current page is marked with a short accent bar\n * under the label (horizontal) or an accent dot beside it (vertical), and gets\n * `aria-current=\"page\"`. These docs' header and sidebar are `NavLinks`.\n *\n * @privateRemarks\n * Site / app navigation: a labelled `<nav>` with a list of links. The current page is\n * marked with a short accent bar under the label (horizontal) or an accent dot beside\n * it (vertical) — a mark, not a glowing pill.\n */\nexport const NavLinks = Object.assign(NavLinksRoot, { Item: NavLinksItem })\n"],"mappings":";;;;;;;;AAoCA,IAAME,IAAkBC,EAAoC;CAC1D,aAAa;CACb,MAAM;AACR,CAAC,GAEKC,IAAeC,EAAuC,SAC1D,EACE,WAAQ,QACR,iBAAc,cACd,QACA,UAAO,MACP,cACA,cACA,cACA,aACA,GAAGC,KAEL,GACA;CACA,OACE,kBAACJ,EAAgB,UAAjB;EAA0B,OAAO;GAAE;GAAa;EAAK;EACnD,UAAA,kBAAC,OAAD;GACO;GACL,cAAYK;GACZ,WAAWC,EAAGR,EAAO,KAAKS,EAAgB;IAAE;IAAW;GAAU,CAAC,GAAGC,CAAS;GAC9E,oBAAkBC;GAClB,aAAWC;GACX,GAAIN;GAEJ,UAAA,kBAAC,MAAD;IACE,WAAWN,EAAO;IAClB,MAAK;IACL,OAAOa,MAAQ,KAAA,IAAY,KAAA,IAAa,EAAE,UAAUC,EAAMD,CAAG,EAAE;IAE9D;GACC,CAAA;EACD,CAAA;CACmB,CAAA;AAE9B,CAAC,GAcKE,IAAeV,EAAiD,SACpE,EAAE,YAAS,IAAO,aAAU,IAAO,cAAW,cAAW,cAAW,GAAGC,KACvE,GACA;CACA,IAAM,EAAE,gBAAa,YAASU,EAAWd,CAAe,GAClDe,IAAOC,IAAUC,EAAK,OAAO;CACnC,OACE,kBAAC,MAAD;EAAI,WAAWX,EAAGR,EAAO,MAAMS,EAAgB;GAAE;GAAW;EAAU,CAAC,CAAC;EACtE,UAAA,kBAACQ,GAAD;GACO;GACL,WAAWT,EAAGR,EAAO,MAAMU,CAAS;GACpC,oBAAkBC;GAClB,aAAWC;GACX,eAAaQ,KAAU,KAAA;GACvB,gBAAcA,IAAS,SAAS,KAAA;GAChC,GAAId;EACL,CAAA;CACC,CAAA;AAER,CAAC,GAgBYe,IAAW,OAAO,OAAOjB,GAAc,EAAE,MAAMW,EAAa,CAAC"}
1
+ {"version":3,"file":"NavLinks.js","names":["styles","NavLinks_module_default","NavLinksContext","createContext","NavLinksRoot","forwardRef","rest","label","cx","visibilityClass","className","orientation","size","gap","space","NavLinksItem","useContext","Comp","asChild","Slot","active","NavLinks"],"sources":["../../../../src/components/navigation/NavLinks/NavLinks.tsx"],"sourcesContent":["import {\n createContext,\n forwardRef,\n useContext,\n type AnchorHTMLAttributes,\n type CSSProperties,\n type HTMLAttributes,\n} from 'react'\nimport { Slot } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport { space, type Space } from '#utils/tokens'\nimport { visibilityClass, type VisibilityProps } from '#utils/visibility'\nimport styles from './NavLinks.module.css'\n\nexport type NavLinksOrientation = 'horizontal' | 'vertical'\nexport type NavLinksSize = 'sm' | 'md'\n\nexport interface NavLinksProps extends HTMLAttributes<HTMLElement>, VisibilityProps {\n /** Names the landmark. Required when a page has more than one nav. Default \"Main\". */\n label?: string\n /** `horizontal` (default) for headers; `vertical` for sidebars and footers. */\n orientation?: NavLinksOrientation\n /**\n * Space between links, as a step on the space scale. Default `5` horizontal, `0`\n * vertical (vertical items are already a full control tall).\n */\n gap?: Space\n /**\n * `md` (default), body-size labels for page headers; `sm`, one step smaller, for sidebars,\n * dense toolbars, footers and sub-navs. Neither drops to the caption steps.\n */\n size?: NavLinksSize\n}\n\ninterface NavLinksContextValue {\n orientation: NavLinksOrientation\n size: NavLinksSize\n}\n\nconst NavLinksContext = createContext<NavLinksContextValue>({\n orientation: 'horizontal',\n size: 'md',\n})\n\nconst NavLinksRoot = forwardRef<HTMLElement, NavLinksProps>(function NavLinks(\n {\n label = 'Main',\n orientation = 'horizontal',\n gap,\n size = 'md',\n hideBelow,\n hideAbove,\n className,\n children,\n ...rest\n },\n ref,\n) {\n return (\n <NavLinksContext.Provider value={{ orientation, size }}>\n <nav\n ref={ref}\n aria-label={label}\n className={cx(styles.nav, visibilityClass({ hideBelow, hideAbove }), className)}\n data-orientation={orientation}\n data-size={size}\n {...rest}\n >\n <ul\n className={styles.list}\n role=\"list\"\n style={gap === undefined ? undefined : ({ '--_gap': space(gap) } as CSSProperties)}\n >\n {children}\n </ul>\n </nav>\n </NavLinksContext.Provider>\n )\n})\n\nexport interface NavLinksItemProps\n extends AnchorHTMLAttributes<HTMLAnchorElement>, VisibilityProps {\n /** The current page. Sets `aria-current=\"page\"` and draws the marker. */\n active?: boolean\n /** Render the single child (e.g. a router `<Link>`) instead of an `<a>`. */\n asChild?: boolean\n}\n\n/**\n * One link. For router links: `<NavLinks.Item asChild active={isActive}><Link to=\"/work\">Work</Link></NavLinks.Item>`.\n * `hideBelow`/`hideAbove` hide the whole list item (e.g. a secondary link on phones).\n */\nconst NavLinksItem = forwardRef<HTMLAnchorElement, NavLinksItemProps>(function NavLinksItem(\n { active = false, asChild = false, hideBelow, hideAbove, className, ...rest },\n ref,\n) {\n const { orientation, size } = useContext(NavLinksContext)\n const Comp = asChild ? Slot.Root : 'a'\n return (\n <li className={cx(styles.item, visibilityClass({ hideBelow, hideAbove }))}>\n <Comp\n ref={ref}\n className={cx(styles.link, className)}\n data-orientation={orientation}\n data-size={size}\n data-active={active || undefined}\n aria-current={active ? 'page' : undefined}\n {...rest}\n />\n </li>\n )\n})\n\n/**\n * A labelled navigation landmark with a list of links. Horizontal for headers, vertical for\n * sidebars.\n *\n * @remarks\n * `NavLinks` is a `<nav>` with a list of links. The current page is marked with a short accent bar\n * under the label (horizontal) or an accent dot beside it (vertical), and gets\n * `aria-current=\"page\"`. These docs' header and sidebar are `NavLinks`.\n *\n * @privateRemarks\n * Site / app navigation: a labelled `<nav>` with a list of links. The current page is\n * marked with a short accent bar under the label (horizontal) or an accent dot beside\n * it (vertical) — a mark, not a glowing pill.\n */\nexport const NavLinks = Object.assign(NavLinksRoot, { Item: NavLinksItem })\n"],"mappings":";;;;;;;;AAuCA,IAAME,IAAkBC,EAAoC;CAC1D,aAAa;CACb,MAAM;AACR,CAAC,GAEKC,IAAeC,EAAuC,SAC1D,EACE,WAAQ,QACR,iBAAc,cACd,QACA,UAAO,MACP,cACA,cACA,cACA,aACA,GAAGC,KAEL,GACA;CACA,OACE,kBAACJ,EAAgB,UAAjB;EAA0B,OAAO;GAAE;GAAa;EAAK;EACnD,UAAA,kBAAC,OAAD;GACO;GACL,cAAYK;GACZ,WAAWC,EAAGR,EAAO,KAAKS,EAAgB;IAAE;IAAW;GAAU,CAAC,GAAGC,CAAS;GAC9E,oBAAkBC;GAClB,aAAWC;GACX,GAAIN;GAEJ,UAAA,kBAAC,MAAD;IACE,WAAWN,EAAO;IAClB,MAAK;IACL,OAAOa,MAAQ,KAAA,IAAY,KAAA,IAAa,EAAE,UAAUC,EAAMD,CAAG,EAAE;IAE9D;GACC,CAAA;EACD,CAAA;CACmB,CAAA;AAE9B,CAAC,GAcKE,IAAeV,EAAiD,SACpE,EAAE,YAAS,IAAO,aAAU,IAAO,cAAW,cAAW,cAAW,GAAGC,KACvE,GACA;CACA,IAAM,EAAE,gBAAa,YAASU,EAAWd,CAAe,GAClDe,IAAOC,IAAUC,EAAK,OAAO;CACnC,OACE,kBAAC,MAAD;EAAI,WAAWX,EAAGR,EAAO,MAAMS,EAAgB;GAAE;GAAW;EAAU,CAAC,CAAC;EACtE,UAAA,kBAACQ,GAAD;GACO;GACL,WAAWT,EAAGR,EAAO,MAAMU,CAAS;GACpC,oBAAkBC;GAClB,aAAWC;GACX,eAAaQ,KAAU,KAAA;GACvB,gBAAcA,IAAS,SAAS,KAAA;GAChC,GAAId;EACL,CAAA;CACC,CAAA;AAER,CAAC,GAgBYe,IAAW,OAAO,OAAOjB,GAAc,EAAE,MAAMW,EAAa,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"NavLinks.module.js","names":["nav","list","item","link","NavLinks_module_default"],"sources":["../../../../src/components/navigation/NavLinks/NavLinks.module.css"],"sourcesContent":["/*\n * Component tokens:\n * --navlinks-marker current-page marker colour, default var(--color-accent)\n * --navlinks-gap space between links, default var(--space-5) horizontal / 0 vertical\n * (the `gap` prop wins over it)\n */\n.nav {\n min-inline-size: 0;\n}\n\n.list {\n /* Defined here so an ancestor's --_gap can never leak in; the `gap` prop overrides inline. */\n --_gap: var(--navlinks-gap, var(--space-5));\n\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n column-gap: var(--_gap);\n row-gap: var(--space-1);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.nav[data-orientation='vertical'] .list {\n --_gap: var(--navlinks-gap, 0px);\n flex-direction: column;\n flex-wrap: nowrap;\n align-items: stretch;\n gap: var(--_gap);\n}\n\n.item {\n display: flex;\n margin: 0;\n padding: 0;\n}\n\n.link {\n --_marker: var(--navlinks-marker, var(--color-accent));\n\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: 0.5em;\n min-block-size: var(--control-md);\n padding: 0;\n color: var(--color-ink-muted);\n font-family: var(--font-text);\n font-size: var(--text-sm);\n font-weight: var(--label-weight);\n letter-spacing: var(--label-tracking);\n text-transform: var(--label-transform);\n line-height: 1.2;\n text-decoration: none;\n white-space: nowrap;\n -webkit-tap-highlight-color: transparent;\n transition: color var(--dur-1) var(--ease-out);\n}\n\n@media (hover: hover) {\n .link:hover {\n color: var(--color-ink);\n }\n}\n\n.link[data-active] {\n color: var(--color-ink);\n}\n\n.link[data-size='sm'] {\n min-block-size: var(--control-sm);\n font-size: var(--text-xs);\n}\n\n.link:focus-visible {\n outline: 2px solid var(--color-focus);\n outline-offset: 2px;\n border-radius: 2px;\n}\n\n/* Horizontal: a bar under the label, the width of the word, sitting a little below it. */\n.link[data-orientation='horizontal']::after {\n content: '';\n position: absolute;\n inset-inline: 0;\n inset-block-end: calc(50% - 0.6lh - var(--space-2));\n block-size: max(2px, var(--border-width-strong));\n border-radius: 1px;\n background: var(--_marker);\n scale: 0 1;\n transform-origin: left;\n transition: scale var(--dur-2) var(--ease-spring);\n}\n.link[data-orientation='horizontal'][data-active]::after {\n scale: 1 1;\n}\n\n/* Vertical: a dot in a reserved gutter, so labels never shift. */\n.link[data-orientation='vertical'] {\n inline-size: 100%;\n padding-inline-start: var(--space-4);\n}\n.link[data-orientation='vertical'][data-size='sm'] {\n padding-inline-start: var(--space-3);\n}\n.link[data-orientation='vertical']::before {\n content: '';\n position: absolute;\n inset-inline-start: 0;\n inset-block-start: 50%;\n inline-size: 0.375rem;\n block-size: 0.375rem;\n margin-block-start: -0.1875rem;\n border-radius: 50%;\n background: var(--_marker);\n scale: 0;\n transition: scale var(--dur-2) var(--ease-spring);\n}\n.link[data-orientation='vertical'][data-active]::before {\n scale: 1;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .link::before,\n .link::after {\n transition: none;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"NavLinks.module.js","names":["nav","list","item","link","NavLinks_module_default"],"sources":["../../../../src/components/navigation/NavLinks/NavLinks.module.css"],"sourcesContent":["/*\n * Component tokens:\n * --navlinks-marker current-page marker colour, default var(--color-accent)\n * --navlinks-gap space between links, default var(--space-5) horizontal / 0 vertical\n * (the `gap` prop wins over it)\n */\n.nav {\n min-inline-size: 0;\n}\n\n.list {\n /* Defined here so an ancestor's --_gap can never leak in; the `gap` prop overrides inline. */\n --_gap: var(--navlinks-gap, var(--space-5));\n\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n column-gap: var(--_gap);\n row-gap: var(--space-1);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.nav[data-orientation='vertical'] .list {\n --_gap: var(--navlinks-gap, 0px);\n flex-direction: column;\n flex-wrap: nowrap;\n align-items: stretch;\n gap: var(--_gap);\n}\n\n.item {\n display: flex;\n margin: 0;\n padding: 0;\n}\n\n.link {\n --_marker: var(--navlinks-marker, var(--color-accent));\n\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: 0.5em;\n min-block-size: var(--control-md);\n padding: 0;\n color: var(--color-ink-muted);\n font-family: var(--font-text);\n /* Body size: people read and scan nav labels, so they never drop to the caption steps. */\n font-size: var(--text-md);\n font-weight: var(--label-weight);\n letter-spacing: var(--label-tracking);\n text-transform: var(--label-transform);\n line-height: 1.2;\n text-decoration: none;\n white-space: nowrap;\n -webkit-tap-highlight-color: transparent;\n transition: color var(--dur-1) var(--ease-out);\n}\n\n@media (hover: hover) {\n .link:hover {\n color: var(--color-ink);\n }\n}\n\n.link[data-active] {\n color: var(--color-ink);\n}\n\n.link[data-size='sm'] {\n min-block-size: var(--control-sm);\n font-size: var(--text-sm);\n}\n\n.link:focus-visible {\n outline: 2px solid var(--color-focus);\n outline-offset: 2px;\n border-radius: 2px;\n}\n\n/* Horizontal: a bar under the label, the width of the word, sitting a little below it. */\n.link[data-orientation='horizontal']::after {\n content: '';\n position: absolute;\n inset-inline: 0;\n inset-block-end: calc(50% - 0.6lh - var(--space-2));\n block-size: max(2px, var(--border-width-strong));\n border-radius: 1px;\n background: var(--_marker);\n scale: 0 1;\n transform-origin: left;\n transition: scale var(--dur-2) var(--ease-spring);\n}\n.link[data-orientation='horizontal'][data-active]::after {\n scale: 1 1;\n}\n\n/* Vertical: a dot in a reserved gutter, so labels never shift. */\n.link[data-orientation='vertical'] {\n inline-size: 100%;\n padding-inline-start: var(--space-4);\n}\n.link[data-orientation='vertical'][data-size='sm'] {\n padding-inline-start: var(--space-3);\n}\n.link[data-orientation='vertical']::before {\n content: '';\n position: absolute;\n inset-inline-start: 0;\n inset-block-start: 50%;\n inline-size: 0.375rem;\n block-size: 0.375rem;\n margin-block-start: -0.1875rem;\n border-radius: 50%;\n background: var(--_marker);\n scale: 0;\n transition: scale var(--dur-2) var(--ease-spring);\n}\n.link[data-orientation='vertical'][data-active]::before {\n scale: 1;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .link::before,\n .link::after {\n transition: none;\n }\n}\n"],"mappings":""}
@@ -7,6 +7,7 @@ export type TooltipProviderProps = ComponentPropsWithoutRef<typeof TooltipPrimit
7
7
  */
8
8
  export declare function TooltipProvider({ delayDuration, skipDelayDuration, ...rest }: TooltipProviderProps): import("react").JSX.Element;
9
9
  export type TooltipSide = 'top' | 'right' | 'bottom' | 'left';
10
+ export type TooltipTouch = 'none' | 'longpress';
10
11
  export type TooltipAlign = 'start' | 'center' | 'end';
11
12
  export interface TooltipProps extends Omit<ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>, 'content' | 'side' | 'align' | 'children'> {
12
13
  /** The hint. Short — a label or one sentence. It's announced as the trigger's description. */
@@ -20,6 +21,12 @@ export interface TooltipProps extends Omit<ComponentPropsWithoutRef<typeof Toolt
20
21
  align?: TooltipAlign;
21
22
  /** Hover delay before opening, in ms. Keyboard focus opens immediately. */
22
23
  delay?: number;
24
+ /**
25
+ * What a touch does. Hover and focus don't exist on a phone, so by default (`none`) a touch
26
+ * never opens a tooltip. `longpress` opens it when the trigger is held for half a second, and
27
+ * swallows the tap that follows, so the press doesn't also act. A tap elsewhere closes it.
28
+ */
29
+ touch?: TooltipTouch;
23
30
  open?: boolean;
24
31
  defaultOpen?: boolean;
25
32
  onOpenChange?: (open: boolean) => void;
@@ -34,6 +41,22 @@ export interface TooltipProps extends Omit<ComponentPropsWithoutRef<typeof Toolt
34
41
  * so an `overflow: hidden` parent never clips it. Keep it to a few words, and never put anything
35
42
  * interactive in it: use a {@link Popover | Popover} for that.
36
43
  *
44
+ * ## On touch screens
45
+ *
46
+ * A phone has no hover, so a tooltip never opens on a tap. With `touch="longpress"` it opens
47
+ * when the trigger is held for half a second, and the tap that ends the press is swallowed, so
48
+ * holding a button to see who reacted doesn't also press it. Don't hide anything essential in a
49
+ * tooltip: a long press is easy to miss.
50
+ *
51
+ * ## On disabled triggers
52
+ *
53
+ * A disabled button gets no pointer or focus events, so a tooltip on it could never open. When
54
+ * the trigger is `disabled`, `Tooltip` marks it `aria-disabled` instead and blocks its clicks
55
+ * and key presses, so it still looks and announces as disabled, but hover, focus and long press
56
+ * reach it and the reason it's disabled ("You've used all three reactions") reaches every
57
+ * reader. It's the same element either way, so a trigger that's disabled while a request is
58
+ * pending keeps keyboard focus.
59
+ *
37
60
  * @privateRemarks
38
61
  * A small label that appears on hover and on keyboard focus. Portalled, so it's never
39
62
  * clipped by an `overflow: hidden` card. Not for anything interactive — use `Popover`.
@@ -1,64 +1,110 @@
1
1
  import { cx as e } from "../../../utils/cx.js";
2
2
  import { PortalAnchorContext as t, composeRefs as n, usePortalAnchorRef as r, usePortalTheme as i } from "../usePortalTheme.js";
3
3
  import a from "./Tooltip.module.js";
4
- import { createContext as o, forwardRef as s, useContext as c } from "react";
5
- import { jsx as l, jsxs as u } from "react/jsx-runtime";
6
- import { Tooltip as d } from "radix-ui";
4
+ import { cloneElement as o, createContext as s, forwardRef as c, isValidElement as l, useContext as u, useEffect as d, useRef as f, useState as p } from "react";
5
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
6
+ import { Tooltip as g } from "radix-ui";
7
7
  //#region src/components/overlays/Tooltip/Tooltip.tsx
8
- var f = o(!1);
9
- function p({ delayDuration: e = 500, skipDelayDuration: t = 300, ...n }) {
10
- return /* @__PURE__ */ l(f.Provider, {
8
+ var _ = s(!1);
9
+ function v({ delayDuration: e = 500, skipDelayDuration: t = 300, ...n }) {
10
+ return /* @__PURE__ */ m(_.Provider, {
11
11
  value: !0,
12
- children: /* @__PURE__ */ l(d.Provider, {
12
+ children: /* @__PURE__ */ m(g.Provider, {
13
13
  delayDuration: e,
14
14
  skipDelayDuration: t,
15
15
  ...n
16
16
  })
17
17
  });
18
18
  }
19
- var m = s(function({ container: t, className: n, children: r, ...o }, s) {
19
+ var y = 500, b = 10, x = 1e3, S = c(function({ container: t, className: n, children: r, ...o }, s) {
20
20
  let c = i(t);
21
- return /* @__PURE__ */ u(d.Content, {
21
+ return /* @__PURE__ */ h(g.Content, {
22
22
  ref: s,
23
23
  className: e(a.content, n),
24
24
  collisionPadding: 8,
25
25
  ...c,
26
26
  ...o,
27
- children: [r, /* @__PURE__ */ l(d.Arrow, {
27
+ children: [r, /* @__PURE__ */ m(g.Arrow, {
28
28
  className: a.arrow,
29
29
  width: 10,
30
30
  height: 5
31
31
  })]
32
32
  });
33
- }), h = s(function({ content: e, children: i, side: a = "top", align: o = "center", delay: s, open: h, defaultOpen: g, onOpenChange: _, container: v, sideOffset: y = 6, ...b }, x) {
34
- let S = c(f), C = r(), w = /* @__PURE__ */ l(t.Provider, {
35
- value: C,
36
- children: /* @__PURE__ */ u(d.Root, {
37
- delayDuration: s,
38
- open: h,
39
- defaultOpen: g,
40
- onOpenChange: _,
41
- children: [/* @__PURE__ */ l(d.Trigger, {
33
+ }), C = c(function({ content: e, children: i, side: a = "top", align: s = "center", delay: c, touch: d = "none", open: f, defaultOpen: y, onOpenChange: b, container: x, sideOffset: C = 6, ...T }, E) {
34
+ let D = u(_), O = r(), [k, A] = p(y ?? !1), j = f ?? k, M = (e) => {
35
+ f === void 0 && A(e), b?.(e);
36
+ }, N = w(d === "longpress", () => {
37
+ M(!0);
38
+ }), P = l(i) && i.props.disabled === !0, F = P ? o(i, {
39
+ disabled: !1,
40
+ "aria-disabled": !0
41
+ }) : i, I = P ? {
42
+ onClickCapture: (e) => {
43
+ e.preventDefault(), e.stopPropagation();
44
+ },
45
+ onKeyDownCapture: (e) => {
46
+ (e.key === "Enter" || e.key === " ") && (e.preventDefault(), e.stopPropagation());
47
+ }
48
+ } : {}, L = /* @__PURE__ */ m(t.Provider, {
49
+ value: O,
50
+ children: /* @__PURE__ */ h(g.Root, {
51
+ delayDuration: c,
52
+ open: j,
53
+ onOpenChange: M,
54
+ children: [/* @__PURE__ */ m(g.Trigger, {
42
55
  asChild: !0,
43
- ref: n(C),
44
- children: i
45
- }), /* @__PURE__ */ l(d.Portal, {
46
- container: v,
47
- children: /* @__PURE__ */ l(m, {
48
- ref: x,
49
- container: v,
56
+ ref: n(O),
57
+ ...N,
58
+ ...I,
59
+ children: F
60
+ }), /* @__PURE__ */ m(g.Portal, {
61
+ container: x,
62
+ children: /* @__PURE__ */ m(S, {
63
+ ref: E,
64
+ container: x,
50
65
  side: a,
51
- align: o,
52
- sideOffset: y,
53
- ...b,
66
+ align: s,
67
+ sideOffset: C,
68
+ ...T,
54
69
  children: e
55
70
  })
56
71
  })]
57
72
  })
58
73
  });
59
- return S ? w : /* @__PURE__ */ l(p, { children: w });
74
+ return D ? L : /* @__PURE__ */ m(v, { children: L });
60
75
  });
76
+ function w(e, t) {
77
+ let n = f(void 0), r = f(null), i = f(!1), a = f(void 0), o = () => {
78
+ clearTimeout(n.current), r.current = null;
79
+ };
80
+ if (d(() => o, []), !e) return {};
81
+ let s = (e) => {
82
+ o(), i.current && (a.current = e.timeStamp);
83
+ }, c = (e) => {
84
+ if (!i.current) return;
85
+ let t = a.current;
86
+ t !== void 0 && (i.current = !1, e.timeStamp - t > x) || (e.preventDefault(), e.stopPropagation());
87
+ };
88
+ return {
89
+ onPointerDown: (e) => {
90
+ i.current = !1, a.current = void 0, e.pointerType === "touch" && (r.current = {
91
+ x: e.clientX,
92
+ y: e.clientY
93
+ }, clearTimeout(n.current), n.current = setTimeout(() => {
94
+ i.current = !0, r.current = null, t();
95
+ }, y));
96
+ },
97
+ onPointerMove: (e) => {
98
+ let t = r.current;
99
+ t && Math.hypot(e.clientX - t.x, e.clientY - t.y) > b && o();
100
+ },
101
+ onPointerUp: s,
102
+ onPointerCancel: s,
103
+ onClickCapture: c,
104
+ onContextMenu: c
105
+ };
106
+ }
61
107
  //#endregion
62
- export { h as Tooltip, p as TooltipProvider };
108
+ export { C as Tooltip, v as TooltipProvider };
63
109
 
64
110
  //# sourceMappingURL=Tooltip.js.map