@estiva-app/ui 0.7.0 → 0.9.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 (63) hide show
  1. package/README.md +23 -6
  2. package/dist/Button.d.ts +12 -5
  3. package/dist/Button.d.ts.map +1 -1
  4. package/dist/Checkbox.d.ts +19 -5
  5. package/dist/Checkbox.d.ts.map +1 -1
  6. package/dist/IconButton.d.ts +9 -2
  7. package/dist/IconButton.d.ts.map +1 -1
  8. package/dist/PersonTrigger.d.ts +2 -1
  9. package/dist/PersonTrigger.d.ts.map +1 -1
  10. package/dist/Tabs.d.ts +4 -1
  11. package/dist/Tabs.d.ts.map +1 -1
  12. package/dist/cn.d.ts +10 -1
  13. package/dist/cn.d.ts.map +1 -1
  14. package/dist/index.js +353 -326
  15. package/dist/index.js.map +4 -4
  16. package/package.json +17 -3
  17. package/src/AppShell.stories.tsx +7 -1
  18. package/src/AppShell.tsx +1 -1
  19. package/src/Avatar.stories.tsx +3 -1
  20. package/src/Banner.stories.tsx +6 -1
  21. package/src/Banner.tsx +2 -2
  22. package/src/Breadcrumb.stories.tsx +3 -0
  23. package/src/Button.mdx +17 -3
  24. package/src/Button.stories.tsx +4 -1
  25. package/src/Button.test.tsx +119 -0
  26. package/src/Button.tsx +37 -23
  27. package/src/Checkbox.mdx +17 -6
  28. package/src/Checkbox.stories.tsx +10 -5
  29. package/src/Checkbox.test.tsx +73 -0
  30. package/src/Checkbox.tsx +52 -25
  31. package/src/Chip.stories.tsx +4 -0
  32. package/src/Chip.tsx +5 -5
  33. package/src/ChipInput.stories.tsx +4 -0
  34. package/src/DialogShell.tsx +1 -1
  35. package/src/EditableText.stories.tsx +6 -1
  36. package/src/IconButton.mdx +12 -1
  37. package/src/IconButton.stories.tsx +9 -4
  38. package/src/IconButton.test.tsx +102 -0
  39. package/src/IconButton.tsx +30 -17
  40. package/src/IdentityMenu.stories.tsx +5 -1
  41. package/src/Kbd.tsx +2 -2
  42. package/src/NavItem.stories.tsx +3 -0
  43. package/src/Person.stories.tsx +3 -0
  44. package/src/PersonTrigger.mdx +9 -1
  45. package/src/PersonTrigger.stories.tsx +3 -0
  46. package/src/PersonTrigger.test.tsx +52 -0
  47. package/src/PersonTrigger.tsx +8 -9
  48. package/src/Select.stories.tsx +7 -2
  49. package/src/Sidebar.stories.tsx +6 -0
  50. package/src/Tabs.mdx +13 -4
  51. package/src/Tabs.test.tsx +117 -0
  52. package/src/Tabs.tsx +45 -34
  53. package/src/Toast.tsx +8 -8
  54. package/src/TopBar.stories.tsx +7 -1
  55. package/src/cn.test.ts +20 -1
  56. package/src/cn.ts +18 -2
  57. package/stories/Choosing.mdx +101 -0
  58. package/stories/DesignTokens.mdx +10 -0
  59. package/stories/GettingStarted.mdx +108 -0
  60. package/stories/Introduction.mdx +36 -0
  61. package/stories/TokensPage.tsx +297 -0
  62. package/tailwind-preset.js +22 -0
  63. package/tokens.css +56 -0
package/README.md CHANGED
@@ -15,6 +15,13 @@ every Estiva app — Peek, Ship, and whatever comes next.
15
15
  - Primitives — arriving one at a time (see Storybook). Each has stories that
16
16
  need no app data; if a story needs a fixture, the component is not a
17
17
  primitive and does not belong here.
18
+ - Behaviour comes from [Base UI](https://base-ui.com) (`@base-ui/react`, a
19
+ dependency installed with the package): keyboard, focus, roles, forms.
20
+ The components move onto it one stage at a time; `Tabs`, `Checkbox`,
21
+ `Button`, `IconButton` and `PersonTrigger` are on it (2026-09-07), the
22
+ rest follow the plan in `K:\Estiva\migration docs\PLAN.md`, whose §16
23
+ lists every component, its Base UI part, and what it gains. Nothing
24
+ changes how a component looks.
18
25
 
19
26
  ## Using it
20
27
 
@@ -74,6 +81,11 @@ permission. A library people are afraid to deviate from becomes a tax.
74
81
  If the colour you need has no token, the token is missing: add it here, in
75
82
  every theme, rather than reaching for hex in an app.
76
83
 
84
+ A transparent colour is a token too. A wash, an outline, a glow or the scrim
85
+ lives in `tokens.css`, not in an opacity modifier on another token:
86
+ `bg-bg-inset/40` compiles to nothing, because the tokens are plain `var()`
87
+ values.
88
+
77
89
  ### The tailwind-merge pitfall — retired for `cn()` users
78
90
 
79
91
  Stock `tailwind-merge` **silently drops** a custom text-size class
@@ -98,9 +110,10 @@ the last two; a hover-opened one owes all five.
98
110
  ### Only offer actions that can succeed
99
111
 
100
112
  An action appears only where it works. A control that cannot succeed right
101
- now is disabled *with its reason* (a tooltip), and a control someone may
102
- never use is absent, not disabled. Primitives expose what that needs: a
103
- `disabled` that can explain itself, never a button that fails.
113
+ now is disabled *with its reason*, and a control someone may never use is
114
+ absent, not disabled. `Button` and `IconButton` carry it as
115
+ `disabledReason="Sign in first"`: disabled, still reachable by Tab, the
116
+ reason shown as a tooltip. Never a button that fails.
104
117
 
105
118
  ## Themes
106
119
 
@@ -119,9 +132,13 @@ stay in Peek's own `.signal` block.
119
132
 
120
133
  ```
121
134
  npm install
122
- npm test # every theme defines every token the preset names, and no other
135
+ npm test # tokens (every theme defines every token the preset names, and no other), cn(), and each component's page claims
136
+ npm run lint # the token contract: no class Tailwind does not generate, no ramp, no raw colour
137
+ npm run typecheck
123
138
  npm run storybook # http://localhost:6008 — Design Tokens, and each primitive, in signal and ship
124
139
  ```
125
140
 
126
- Extracting a primitive from Peek must not change how Peek renders:
127
- screenshot-compare before and after, in Peek's own Storybook.
141
+ A change must not change how an app renders: screenshot-compare before and
142
+ after, in both themes here and in the apps' own Storybooks. `CLAUDE.md` has
143
+ the whole contract: what a component, a story, a page and a port are held
144
+ to, and how a change is proved.
package/dist/Button.d.ts CHANGED
@@ -4,16 +4,20 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react';
4
4
  * adopt: a `destructive` variant — the muted button in the error colour, for
5
5
  * "Delete project" and its kind; a destructive action is a button like any
6
6
  * other, not a dotted link — and `type="button"` by default, so a button
7
- * inside a form submits it only when asked to.
7
+ * inside a form submits it only when asked to. On Base UI's Button since
8
+ * stage 2 of the migration (2026-09-07).
8
9
  *
9
10
  * Three variants and two sizes: 32px default / 24px small, 6px radius, 500
10
- * weight. Sizes are spelled as arbitrary values for the reason the README
11
- * records: tailwind-merge drops a custom `text-{size}` that is followed by a
12
- * `text-{colour}`.
11
+ * weight. The sizes are the `btn-default` and `btn-small` type tokens.
13
12
  *
14
13
  * The primary reads in `text-inverse` on the accent — a theme decides what
15
14
  * that is (dark on Peek's light accents, light on Ship's dark one). Under
16
15
  * Signal it is also semibold, as Peek has it.
16
+ *
17
+ * `disabledReason` is the package's own rule, "only offer actions that can
18
+ * succeed", done once: the button is disabled, stays reachable by keyboard
19
+ * (Base UI's `focusableWhenDisabled`), and shows the reason as a tooltip on
20
+ * hover. Ship wrote that wrapper by hand six times.
17
21
  */
18
22
  export type ButtonVariant = 'primary' | 'outlined' | 'muted' | 'destructive';
19
23
  export type ButtonSize = 'default' | 'small';
@@ -22,7 +26,10 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
22
26
  size?: ButtonSize;
23
27
  /** 16px, stroke 1.5 on the default size; 14px on small. */
24
28
  leadingIcon?: ReactNode;
29
+ /** Why the action cannot succeed right now. Disables the button, keeps it
30
+ * reachable by keyboard, and shows the reason as a tooltip on hover. */
31
+ disabledReason?: string;
25
32
  children: ReactNode;
26
33
  }
27
- export declare function Button({ variant, size, leadingIcon, className, children, disabled, type, ...props }: ButtonProps): import("react").JSX.Element;
34
+ export declare function Button({ variant, size, leadingIcon, className, children, disabled, disabledReason, type, ...props }: ButtonProps): import("react").JSX.Element;
28
35
  //# sourceMappingURL=Button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../src/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAG5D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,aAAa,CAAA;AAC5E,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,OAAO,CAAA;AAE5C,MAAM,WAAW,WAAY,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC1E,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,MAAM,CAAC,EACrB,OAAiB,EACjB,IAAgB,EAChB,WAAW,EACX,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,IAAe,EACf,GAAG,KAAK,EACT,EAAE,WAAW,+BA2Bb"}
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../src/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAK5D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,aAAa,CAAA;AAC5E,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,OAAO,CAAA;AAE5C,MAAM,WAAW,WAAY,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC1E,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB;6EACyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,MAAM,CAAC,EACrB,OAAiB,EACjB,IAAgB,EAChB,WAAW,EACX,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,IAAe,EACf,GAAG,KAAK,EACT,EAAE,WAAW,+BA+Bb"}
@@ -1,11 +1,25 @@
1
1
  /**
2
2
  * A 16px square that fills with the accent when checked — Peek's Checkbox
3
- * (2026-09-01), verbatim.
3
+ * (2026-09-01), verbatim; on Base UI Checkbox since stage 1 of the migration
4
+ * (2026-09-06).
4
5
  *
5
- * Controlled only; parents own the state. Rendered as a button with the
6
- * checkbox role so it works standalone or inside clickable rows: a caller
7
- * that toggles on the row's own click passes no `onChange`, and the square
8
- * goes inert rather than stealing the click.
6
+ * Controlled only; parents own the state. Two renderings, one class list:
7
+ *
8
+ * - With `onChange` it is the control, as Base UI renders it: a
9
+ * `<span role="checkbox">` with a hidden `<input>` beside it. Space
10
+ * toggles, Enter does not, and its click never reaches the row around it.
11
+ * - Without `onChange` it is a picture of the state, for a row that toggles
12
+ * on its own click. It is hidden from assistive technology and takes no
13
+ * focus, so the row is one control and says the state itself
14
+ * (`aria-pressed`, or `aria-selected` on an option). Two focusable controls
15
+ * nested in one another is what axe's `nested-interactive` rule rejects.
16
+ *
17
+ * The tick is always in the box, hidden when unchecked. A box that is empty
18
+ * in one state and holds an icon in the other hangs on a line of text
19
+ * differently in each, and moved 1px on every click (Katerina, 2026-09-07:
20
+ * "it should be fixed"). With the tick always there, Base UI's `<span>` and
21
+ * the `<button>` this used to be land on the same pixel, measured. In a flex
22
+ * row nothing ever moved.
9
23
  */
10
24
  export interface CheckboxProps {
11
25
  checked: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../src/Checkbox.tsx"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAgB,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,+BAyBlG"}
1
+ {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../src/Checkbox.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAeD,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAgB,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,+BAwBlG"}
@@ -3,7 +3,11 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react';
3
3
  * Peek's IconButton (2026-08-28), verbatim: a square 4px-padded button
4
4
  * around a 16px icon, 8px radius, three variants, an optional tooltip that
5
5
  * portals above or below. Plus `type="button"` by default (Ship's addition),
6
- * so it never submits a form by accident.
6
+ * so it never submits a form by accident. On Base UI's Button since stage 2
7
+ * of the migration (2026-09-07).
8
+ *
9
+ * `disabledReason` disables it, keeps it reachable by keyboard, and shows
10
+ * the reason in place of the tooltip — see Button.
7
11
  */
8
12
  export type IconButtonVariant = 'muted' | 'outlined' | 'primary';
9
13
  export interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
@@ -13,8 +17,11 @@ export interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>
13
17
  * whose only other affordance is a keyboard shortcut. */
14
18
  tooltipShortcut?: string;
15
19
  tooltipPlacement?: 'top' | 'bottom';
20
+ /** Why the action cannot succeed right now. Disables the button, keeps it
21
+ * reachable by keyboard, and shows the reason as the tooltip. */
22
+ disabledReason?: string;
16
23
  /** The icon: 16px, stroke 1.5. */
17
24
  children: ReactNode;
18
25
  }
19
- export declare function IconButton({ variant, className, children, disabled, tooltip, tooltipShortcut, tooltipPlacement, type, ...props }: IconButtonProps): import("react").JSX.Element;
26
+ export declare function IconButton({ variant, className, children, disabled, disabledReason, tooltip, tooltipShortcut, tooltipPlacement, type, ...props }: IconButtonProps): import("react").JSX.Element;
20
27
  //# sourceMappingURL=IconButton.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IconButton.d.ts","sourceRoot":"","sources":["../src/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAI5D;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAA;AAEhE,MAAM,WAAW,eAAgB,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC9E,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;8DAC0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;IACnC,kCAAkC;IAClC,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAiB,EACjB,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,IAAe,EACf,GAAG,KAAK,EACT,EAAE,eAAe,+BA8BjB"}
1
+ {"version":3,"file":"IconButton.d.ts","sourceRoot":"","sources":["../src/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAK5D;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAA;AAEhE,MAAM,WAAW,eAAgB,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC9E,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;8DAC0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;IACnC;sEACkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kCAAkC;IAClC,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAiB,EACjB,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,IAAe,EACf,GAAG,KAAK,EACT,EAAE,eAAe,+BAkCjB"}
@@ -1,7 +1,8 @@
1
1
  import type { ComponentPropsWithRef } from 'react';
2
2
  import { type PersonProps } from './Person';
3
3
  /**
4
- * The person, as the button that opens the account menu.
4
+ * The person, as the button that opens the account menu. On Base UI's Button
5
+ * since stage 2 of the migration (2026-09-07).
5
6
  *
6
7
  * Two shapes, one component (Katerina, 2026-09-01):
7
8
  *
@@ -1 +1 @@
1
- {"version":3,"file":"PersonTrigger.d.ts","sourceRoot":"","sources":["../src/PersonTrigger.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAA;AAIlD,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AAEnD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,kBACf,SAAQ,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,EACpC,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IACnD,mFAAmF;IACnF,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,+FAA+F;IAC/F,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAY,EAAE,OAAe,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,+BAiCtI"}
1
+ {"version":3,"file":"PersonTrigger.d.ts","sourceRoot":"","sources":["../src/PersonTrigger.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAA;AAKlD,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AAEnD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBACf,SAAQ,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,EACpC,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IACnD,mFAAmF;IACnF,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,+FAA+F;IAC/F,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAY,EAAE,OAAe,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,+BA8BtI"}
package/dist/Tabs.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import type { ReactNode } from 'react';
2
2
  /**
3
3
  * A row of tabs. Ship's Tabs (2026-09-01), which was Peek's TopicTabs with
4
- * the topic-specific ids taken out.
4
+ * the topic-specific ids taken out; on Base UI Tabs since stage 1 of the
5
+ * migration (2026-09-06), which is where the keyboard comes from: one Tab
6
+ * stop for the row, arrow keys between the tabs.
5
7
  *
6
8
  * A selected tab is a neutral fill (bg-active), not the accent tint —
7
9
  * Katerina's ruling (2026-08-27), extended to every app (2026-09-01). Two
@@ -28,6 +30,7 @@ export interface TabsProps<T extends string> {
28
30
  onChange: (id: T) => void;
29
31
  /** `default` 14px; `small` 12px, the denser geometry. */
30
32
  size?: 'default' | 'small';
33
+ /** Lands on the outer box, around the row. */
31
34
  className?: string;
32
35
  }
33
36
  export declare function Tabs<T extends string>({ tabs, active, onChange, size, className }: TabsProps<T>): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../src/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,MAAM,CAAC,CAAC,SAAS,MAAM;IACtC,EAAE,EAAE,CAAC,CAAA;IACL,KAAK,EAAE,MAAM,CAAA;IACb,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wBAAwB;IACxB,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAED,MAAM,WAAW,SAAS,CAAC,CAAC,SAAS,MAAM;IACzC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;IACjB,MAAM,EAAE,CAAC,CAAA;IACT,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,CAAA;IACzB,yDAAyD;IACzD,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAgB,EAAE,SAAS,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,+BAoC3G"}
1
+ {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../src/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,MAAM,CAAC,CAAC,SAAS,MAAM;IACtC,EAAE,EAAE,CAAC,CAAA;IACL,KAAK,EAAE,MAAM,CAAA;IACb,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wBAAwB;IACxB,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAED,MAAM,WAAW,SAAS,CAAC,CAAC,SAAS,MAAM;IACzC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;IACjB,MAAM,EAAE,CAAC,CAAA;IACT,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,CAAA;IACzB,yDAAyD;IACzD,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;IAC1B,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAgB,EAAE,SAAS,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,+BA2C3G"}
package/dist/cn.d.ts CHANGED
@@ -14,7 +14,16 @@ import { type ClassValue } from 'clsx';
14
14
  * imported here without dragging them into the browser bundle).
15
15
  */
16
16
  declare const FONT_SIZE_TOKENS: string[];
17
+ /**
18
+ * The preset's box-shadow and drop-shadow keys, for the same reason: stock
19
+ * tailwind-merge files an unknown `shadow-x` under shadow-COLOUR, so
20
+ * `shadow-focus-ring` beside `shadow-glow-warning` lost one of them, and
21
+ * `shadow-glow-warning` beside `shadow-md` kept both (measured 2026-09-06).
22
+ * `cn.test.ts` pins these to the preset too.
23
+ */
24
+ declare const BOX_SHADOW_TOKENS: string[];
25
+ declare const DROP_SHADOW_TOKENS: string[];
17
26
  /** Merge class names, last-one-wins on conflicting Tailwind utilities. */
18
27
  export declare function cn(...inputs: ClassValue[]): string;
19
- export { FONT_SIZE_TOKENS as _fontSizeTokens };
28
+ export { FONT_SIZE_TOKENS as _fontSizeTokens, BOX_SHADOW_TOKENS as _boxShadowTokens, DROP_SHADOW_TOKENS as _dropShadowTokens };
20
29
  //# sourceMappingURL=cn.d.ts.map
package/dist/cn.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cn.d.ts","sourceRoot":"","sources":["../src/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAG5C;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,gBAAgB,UAIrB,CAAA;AAMD,0EAA0E;AAC1E,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC;AAED,OAAO,EAAE,gBAAgB,IAAI,eAAe,EAAE,CAAA"}
1
+ {"version":3,"file":"cn.d.ts","sourceRoot":"","sources":["../src/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAG5C;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,gBAAgB,UAIrB,CAAA;AAED;;;;;;GAMG;AACH,QAAA,MAAM,iBAAiB,UAAsE,CAAA;AAC7F,QAAA,MAAM,kBAAkB,UAAkC,CAAA;AAY1D,0EAA0E;AAC1E,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC;AAED,OAAO,EAAE,gBAAgB,IAAI,eAAe,EAAE,iBAAiB,IAAI,gBAAgB,EAAE,kBAAkB,IAAI,iBAAiB,EAAE,CAAA"}