@devalok/shilp-sutra 0.39.0 → 0.40.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 (218) hide show
  1. package/AGENTS.md +151 -0
  2. package/MIGRATION.md +137 -0
  3. package/README.md +3 -0
  4. package/dist/_chunks/badge-group.js +75 -74
  5. package/dist/_chunks/badge-group.js.map +1 -1
  6. package/dist/_chunks/chart-container.js +50 -0
  7. package/dist/_chunks/chart-container.js.map +1 -0
  8. package/dist/_chunks/chat.js +231 -223
  9. package/dist/_chunks/chat.js.map +1 -1
  10. package/dist/_chunks/colors.js +30 -0
  11. package/dist/_chunks/colors.js.map +1 -0
  12. package/dist/_chunks/emoji-data.js +45 -0
  13. package/dist/_chunks/emoji-data.js.map +1 -0
  14. package/dist/_chunks/grid-lines.js +72 -0
  15. package/dist/_chunks/grid-lines.js.map +1 -0
  16. package/dist/_chunks/mention-suggestion.js +31 -259
  17. package/dist/_chunks/mention-suggestion.js.map +1 -1
  18. package/dist/_chunks/normalize-icon.js +18 -0
  19. package/dist/_chunks/normalize-icon.js.map +1 -0
  20. package/dist/_chunks/oauth-button.js +227 -0
  21. package/dist/_chunks/oauth-button.js.map +1 -0
  22. package/dist/_chunks/primitives.js +107 -107
  23. package/dist/_chunks/primitives.js.map +1 -1
  24. package/dist/_chunks/{text.js → success.js} +24 -61
  25. package/dist/_chunks/success.js.map +1 -0
  26. package/dist/_chunks/tiptap.js +1952 -1949
  27. package/dist/_chunks/tiptap.js.map +1 -1
  28. package/dist/_chunks/tooltip.js +58 -0
  29. package/dist/_chunks/tooltip.js.map +1 -0
  30. package/dist/_chunks/tree-view.js +101 -96
  31. package/dist/_chunks/tree-view.js.map +1 -1
  32. package/dist/ai/ai-command-provider.d.ts +3 -2
  33. package/dist/ai/ai-command-provider.d.ts.map +1 -1
  34. package/dist/ai/ai-command-provider.js.map +1 -1
  35. package/dist/ai/block-renderer.js +11 -9
  36. package/dist/ai/block-renderer.js.map +1 -1
  37. package/dist/ai/blocks/error.js +31 -0
  38. package/dist/ai/blocks/error.js.map +1 -0
  39. package/dist/ai/blocks/index.d.ts +0 -2
  40. package/dist/ai/blocks/index.d.ts.map +1 -1
  41. package/dist/ai/blocks/index.js +2 -2
  42. package/dist/ai/blocks/text.js +19 -0
  43. package/dist/ai/blocks/text.js.map +1 -0
  44. package/dist/ai/command-bar.d.ts.map +1 -1
  45. package/dist/ai/command-bar.js +192 -187
  46. package/dist/ai/command-bar.js.map +1 -1
  47. package/dist/ai/conversation.d.ts +2 -1
  48. package/dist/ai/conversation.d.ts.map +1 -1
  49. package/dist/ai/conversation.js +88 -83
  50. package/dist/ai/conversation.js.map +1 -1
  51. package/dist/ai/index.d.ts +0 -4
  52. package/dist/ai/index.d.ts.map +1 -1
  53. package/dist/ai/index.js +45 -46
  54. package/dist/ai/index.js.map +1 -1
  55. package/dist/composed/activity-feed.d.ts +2 -1
  56. package/dist/composed/activity-feed.d.ts.map +1 -1
  57. package/dist/composed/activity-feed.js.map +1 -1
  58. package/dist/composed/bulk-action-bar.d.ts +2 -2
  59. package/dist/composed/bulk-action-bar.d.ts.map +1 -1
  60. package/dist/composed/bulk-action-bar.js +11 -11
  61. package/dist/composed/bulk-action-bar.js.map +1 -1
  62. package/dist/composed/command-palette.d.ts +2 -1
  63. package/dist/composed/command-palette.d.ts.map +1 -1
  64. package/dist/composed/command-palette.js +103 -98
  65. package/dist/composed/command-palette.js.map +1 -1
  66. package/dist/composed/date-picker/index.js +747 -3
  67. package/dist/composed/date-picker/index.js.map +1 -0
  68. package/dist/composed/empty-state.d.ts +3 -3
  69. package/dist/composed/empty-state.d.ts.map +1 -1
  70. package/dist/composed/empty-state.js +40 -31
  71. package/dist/composed/empty-state.js.map +1 -1
  72. package/dist/composed/extensions/emoji-node.js +81 -0
  73. package/dist/composed/extensions/emoji-node.js.map +1 -0
  74. package/dist/composed/extensions/emoji-suggestion.js +117 -0
  75. package/dist/composed/extensions/emoji-suggestion.js.map +1 -0
  76. package/dist/composed/file-preview.js +498 -2
  77. package/dist/{_chunks → composed}/file-preview.js.map +1 -1
  78. package/dist/composed/index.d.ts +0 -15
  79. package/dist/composed/index.d.ts.map +1 -1
  80. package/dist/composed/index.js +16 -24
  81. package/dist/composed/rich-chat-input.js +2073 -2
  82. package/dist/{_chunks → composed}/rich-chat-input.js.map +1 -1
  83. package/dist/composed/rich-text-editor.js +64 -61
  84. package/dist/composed/rich-text-editor.js.map +1 -1
  85. package/dist/composed/status-badge.d.ts +3 -2
  86. package/dist/composed/status-badge.d.ts.map +1 -1
  87. package/dist/composed/status-badge.js +58 -53
  88. package/dist/composed/status-badge.js.map +1 -1
  89. package/dist/shell/app-command-palette.d.ts +2 -1
  90. package/dist/shell/app-command-palette.d.ts.map +1 -1
  91. package/dist/shell/app-command-palette.js.map +1 -1
  92. package/dist/shell/bottom-navbar.d.ts +3 -1
  93. package/dist/shell/bottom-navbar.d.ts.map +1 -1
  94. package/dist/shell/bottom-navbar.js +90 -82
  95. package/dist/shell/bottom-navbar.js.map +1 -1
  96. package/dist/shell/command-registry.d.ts +2 -1
  97. package/dist/shell/command-registry.d.ts.map +1 -1
  98. package/dist/shell/command-registry.js.map +1 -1
  99. package/dist/shell/sidebar.d.ts +7 -4
  100. package/dist/shell/sidebar.d.ts.map +1 -1
  101. package/dist/shell/sidebar.js +143 -129
  102. package/dist/shell/sidebar.js.map +1 -1
  103. package/dist/shell/top-bar.d.ts +4 -3
  104. package/dist/shell/top-bar.d.ts.map +1 -1
  105. package/dist/shell/top-bar.js +114 -106
  106. package/dist/shell/top-bar.js.map +1 -1
  107. package/dist/ui/badge.d.ts +3 -2
  108. package/dist/ui/badge.d.ts.map +1 -1
  109. package/dist/ui/button.d.ts +3 -2
  110. package/dist/ui/button.d.ts.map +1 -1
  111. package/dist/ui/button.js +54 -53
  112. package/dist/ui/button.js.map +1 -1
  113. package/dist/ui/charts/area-chart.js +177 -0
  114. package/dist/ui/charts/area-chart.js.map +1 -0
  115. package/dist/ui/charts/bar-chart.js +127 -0
  116. package/dist/ui/charts/bar-chart.js.map +1 -0
  117. package/dist/ui/charts/chart-container.js +3 -0
  118. package/dist/ui/charts/gauge-chart.js +72 -0
  119. package/dist/ui/charts/gauge-chart.js.map +1 -0
  120. package/dist/ui/charts/index.js +10 -1035
  121. package/dist/ui/charts/line-chart.js +135 -0
  122. package/dist/ui/charts/line-chart.js.map +1 -0
  123. package/dist/ui/charts/pie-chart.js +111 -0
  124. package/dist/ui/charts/pie-chart.js.map +1 -0
  125. package/dist/ui/charts/radar-chart.js +170 -0
  126. package/dist/ui/charts/radar-chart.js.map +1 -0
  127. package/dist/ui/charts/sparkline.js +119 -0
  128. package/dist/ui/charts/sparkline.js.map +1 -0
  129. package/dist/ui/chat/message.d.ts +3 -3
  130. package/dist/ui/chat/message.d.ts.map +1 -1
  131. package/dist/ui/chat/system-message.d.ts +2 -1
  132. package/dist/ui/chat/system-message.d.ts.map +1 -1
  133. package/dist/ui/combobox.d.ts +2 -1
  134. package/dist/ui/combobox.d.ts.map +1 -1
  135. package/dist/ui/combobox.js +97 -92
  136. package/dist/ui/combobox.js.map +1 -1
  137. package/dist/ui/container.d.ts +6 -1
  138. package/dist/ui/container.d.ts.map +1 -1
  139. package/dist/ui/container.js +2 -1
  140. package/dist/ui/container.js.map +1 -1
  141. package/dist/ui/icon-button.d.ts +9 -2
  142. package/dist/ui/icon-button.d.ts.map +1 -1
  143. package/dist/ui/icon-button.js +14 -13
  144. package/dist/ui/icon-button.js.map +1 -1
  145. package/dist/ui/index.d.ts +1 -3
  146. package/dist/ui/index.d.ts.map +1 -1
  147. package/dist/ui/index.js +31 -33
  148. package/dist/ui/index.js.map +1 -1
  149. package/dist/ui/lib/icon-input.d.ts +42 -0
  150. package/dist/ui/lib/icon-input.d.ts.map +1 -0
  151. package/dist/ui/lib/normalize-icon.d.ts +39 -0
  152. package/dist/ui/lib/normalize-icon.d.ts.map +1 -0
  153. package/dist/ui/oauth-button/index.d.ts +3 -0
  154. package/dist/ui/oauth-button/index.d.ts.map +1 -0
  155. package/dist/ui/oauth-button/index.js +3 -0
  156. package/dist/ui/oauth-button/oauth-button.d.ts +208 -0
  157. package/dist/ui/oauth-button/oauth-button.d.ts.map +1 -0
  158. package/dist/ui/progress.js +1 -1
  159. package/dist/ui/segmented-control.d.ts +3 -4
  160. package/dist/ui/segmented-control.d.ts.map +1 -1
  161. package/dist/ui/segmented-control.js +53 -45
  162. package/dist/ui/segmented-control.js.map +1 -1
  163. package/dist/ui/stack.d.ts +6 -1
  164. package/dist/ui/stack.d.ts.map +1 -1
  165. package/dist/ui/stack.js +2 -1
  166. package/dist/ui/stack.js.map +1 -1
  167. package/dist/ui/stat-card.d.ts +2 -3
  168. package/dist/ui/stat-card.d.ts.map +1 -1
  169. package/dist/ui/stat-card.js +117 -115
  170. package/dist/ui/stat-card.js.map +1 -1
  171. package/dist/ui/stepper.d.ts +2 -1
  172. package/dist/ui/stepper.d.ts.map +1 -1
  173. package/dist/ui/stepper.js +74 -69
  174. package/dist/ui/stepper.js.map +1 -1
  175. package/dist/ui/text.d.ts +7 -2
  176. package/dist/ui/text.d.ts.map +1 -1
  177. package/dist/ui/text.js +2 -1
  178. package/dist/ui/text.js.map +1 -1
  179. package/dist/ui/toaster.d.ts +11 -2
  180. package/dist/ui/toaster.d.ts.map +1 -1
  181. package/dist/ui/toaster.js.map +1 -1
  182. package/dist/ui/tooltip.js +12 -12
  183. package/dist/ui/tree-view/tree-item.d.ts +3 -2
  184. package/dist/ui/tree-view/tree-item.d.ts.map +1 -1
  185. package/dist/ui/tree-view/use-tree.d.ts +2 -1
  186. package/dist/ui/tree-view/use-tree.d.ts.map +1 -1
  187. package/docs/components/ui/oauth-button.md +86 -0
  188. package/docs/recipes/customize-brand.md +15 -0
  189. package/docs/recipes/index.md +5 -1
  190. package/docs/recipes/install-astro.md +15 -0
  191. package/docs/recipes/install-next-app-router.md +21 -5
  192. package/docs/recipes/install-next-pages.md +2 -0
  193. package/docs/recipes/install-remix.md +15 -0
  194. package/docs/recipes/install-tanstack-start.md +15 -0
  195. package/docs/recipes/install-vite.md +15 -0
  196. package/docs/recipes/troubleshoot.md +22 -0
  197. package/llms-full.txt +87 -1
  198. package/llms-quick.txt +247 -0
  199. package/llms.txt +107 -2
  200. package/package.json +79 -2
  201. package/scripts/welcome.mjs +219 -0
  202. package/skill/SKILL.md +22 -3
  203. package/skill/references/components-full.md +87 -1
  204. package/skill/references/components.md +107 -2
  205. package/skill/references/customize-brand.md +15 -0
  206. package/skill/references/setup-astro.md +15 -0
  207. package/skill/references/setup-next-app-router.md +21 -5
  208. package/skill/references/setup-next-pages.md +2 -0
  209. package/skill/references/setup-remix.md +15 -0
  210. package/skill/references/setup-tanstack-start.md +15 -0
  211. package/skill/references/setup-vite.md +15 -0
  212. package/skill/references/troubleshoot.md +22 -0
  213. package/dist/_chunks/date-picker.js +0 -748
  214. package/dist/_chunks/date-picker.js.map +0 -1
  215. package/dist/_chunks/file-preview.js +0 -499
  216. package/dist/_chunks/rich-chat-input.js +0 -2071
  217. package/dist/_chunks/text.js.map +0 -1
  218. package/dist/ui/charts/index.js.map +0 -1
@@ -0,0 +1,208 @@
1
+ "use client";
2
+ import { ButtonProps } from '../button';
3
+ import { IconInput } from '../lib/icon-input';
4
+ import * as React from 'react';
5
+ export type OAuthProvider = 'google' | 'apple' | 'github' | 'microsoft' | 'x' | 'linkedin' | 'facebook' | 'discord' | 'slack' | 'gitlab' | 'sso' | 'email' | 'passkey';
6
+ export type OAuthIntent = 'continue' | 'signin' | 'signup';
7
+ /**
8
+ * Visual treatment — 1:1 with Button's variant axis. OAuthButton is a thin
9
+ * wrapper over Button, so every variant renders pixel-for-pixel identical
10
+ * to a regular Button at the same variant + size. Brand identity lives in
11
+ * the glyph (override via `icon` for a brand-multicolour SVG), not the
12
+ * button surface.
13
+ *
14
+ * - `solid` (default) | `soft` | `outline` | `ghost`
15
+ */
16
+ export type OAuthVariant = 'solid' | 'soft' | 'outline' | 'ghost';
17
+ /** @deprecated Use `OAuthVariant`. brand/dark map to solid; outline passes through. */
18
+ export type OAuthAppearance = 'brand' | 'outline' | 'dark';
19
+ /**
20
+ * Props for `OAuthButton` — a brand-aware sign-in button for OAuth providers.
21
+ *
22
+ * Composes on top of `<Button>`, inheriting `size`, `loading`, `onClickAsync`,
23
+ * `fullWidth`, and async state machinery. The provider's icon, label, and
24
+ * brand-coloured styling are derived from the `provider` prop.
25
+ *
26
+ * **Provider** (required): includes 10 social providers + 3 generic
27
+ * identifiers (`sso` enterprise, `email` magic-link, `passkey` WebAuthn).
28
+ *
29
+ * **Intent**: drives the verb in the label.
30
+ * - `continue` (default) — "Continue with Google" — works on login and signup.
31
+ * - `signin` — "Sign in with Google".
32
+ * - `signup` — "Sign up with Google".
33
+ *
34
+ * **Appearance**: visual treatment.
35
+ * - `brand` (default) — provider's brand background colour.
36
+ * - `outline` — DS-neutral outline with monochrome glyph. Best for uniform rows.
37
+ * - `dark` — unified Apple-style across all providers for visual consistency.
38
+ *
39
+ * **icon**: override the default Tabler glyph (e.g. drop in the provider's
40
+ * official multicolour SVG downloaded from their brand page).
41
+ *
42
+ * **iconOnly**: render a square icon button. Provider name kept in `aria-label`.
43
+ *
44
+ * **lastUsed**: shows a small "Last used" pill above the button — high-converting
45
+ * UX hint. Consumer tracks which provider the user picked previously.
46
+ *
47
+ * **helperText**: optional reassurance copy rendered below the button.
48
+ *
49
+ * @example
50
+ * <OAuthButton provider="google" intent="continue" fullWidth onClickAsync={signInWithGoogle} />
51
+ *
52
+ * @example
53
+ * // True brand-multicolour glyph:
54
+ * <OAuthButton provider="google" icon={<GoogleGSvg />} />
55
+ *
56
+ * @example
57
+ * <OAuthGroup>
58
+ * <OAuthButton provider="google" appearance="dark" />
59
+ * <OAuthButton provider="apple" appearance="dark" />
60
+ * <OAuthButton provider="github" appearance="dark" />
61
+ * </OAuthGroup>
62
+ */
63
+ export interface OAuthButtonProps extends Omit<ButtonProps, 'variant' | 'color' | 'startIcon' | 'endIcon' | 'shape' | 'children'> {
64
+ /** OAuth provider this button represents */
65
+ provider: OAuthProvider;
66
+ /** Verb in the default label. Default: `continue` */
67
+ intent?: OAuthIntent;
68
+ /**
69
+ * Visual treatment. Default: `solid`. Mirrors Button's variant axis with
70
+ * an extra `dark` for row coherence across providers.
71
+ */
72
+ variant?: OAuthVariant;
73
+ /** @deprecated Use `variant`. `appearance="brand"` maps to `variant="solid"`. */
74
+ appearance?: OAuthAppearance;
75
+ /** Override the default glyph (e.g. brand-multicolour SVG). Accepts any `IconInput`. */
76
+ icon?: IconInput;
77
+ /** Render a compact icon-only button (provider name kept in aria-label) */
78
+ iconOnly?: boolean;
79
+ /**
80
+ * Short label — renders just the provider name ("Google") instead of the
81
+ * full "Continue with Google". Use under an explicit "Or sign in with"
82
+ * divider where the verb is already established. aria-label still gets the
83
+ * full long form for screen readers.
84
+ */
85
+ compact?: boolean;
86
+ /**
87
+ * Show "Last used" hint — a small pill anchored to the top-right corner of
88
+ * the button (sits ON the corner, half outside the button bounds).
89
+ */
90
+ lastUsed?: boolean;
91
+ /**
92
+ * Customise the "Last used" badge. Pass a ReactNode to replace the entire
93
+ * pill (use this for custom copy, icons, or styling), or a render fn that
94
+ * receives the default props for tweaks. Only rendered when `lastUsed` is
95
+ * also set so the wrapper / aria augmentation logic stays consistent.
96
+ *
97
+ * @example
98
+ * <OAuthButton provider="google" lastUsed lastUsedSlot={<MyBadge />} />
99
+ */
100
+ lastUsedSlot?: React.ReactNode | ((defaults: {
101
+ label: string;
102
+ }) => React.ReactNode);
103
+ /** Override the visible badge label text. Default: "Last used". */
104
+ lastUsedLabel?: string;
105
+ /** Reassurance copy rendered below the button */
106
+ helperText?: React.ReactNode;
107
+ /** Override the default label entirely (i18n / custom copy) */
108
+ children?: React.ReactNode;
109
+ }
110
+ declare const OAuthButton: React.ForwardRefExoticComponent<OAuthButtonProps & React.RefAttributes<HTMLButtonElement>>;
111
+ export { OAuthButton };
112
+ export interface OAuthGroupProps extends React.HTMLAttributes<HTMLDivElement> {
113
+ /** Layout. `vertical` (default) stacks full-width buttons. */
114
+ orientation?: 'vertical' | 'horizontal';
115
+ /** Gap token between buttons. Default: `ds-03` */
116
+ gap?: 'ds-02' | 'ds-03' | 'ds-04';
117
+ /** Stretch children to fill width (vertical only). Default: true */
118
+ fullWidth?: boolean;
119
+ /**
120
+ * Move any child with `lastUsed` to position 0. Stripe-style ordering — the
121
+ * provider the user picked last time becomes the top option, which gives a
122
+ * stronger conversion lift than a "Last used" badge does on its own.
123
+ * Default: false (preserve source order).
124
+ */
125
+ reorderLastUsedFirst?: boolean;
126
+ }
127
+ /**
128
+ * Stacked layout wrapper for OAuth buttons with consistent spacing. Defaults to
129
+ * vertical, full-width children — the dominant sign-in pattern. For an icon-only
130
+ * row, set `orientation="horizontal"` and use `<OAuthButton iconOnly />`.
131
+ */
132
+ declare const OAuthGroup: React.ForwardRefExoticComponent<OAuthGroupProps & React.RefAttributes<HTMLDivElement>>;
133
+ export { OAuthGroup };
134
+ export interface OAuthDividerProps extends React.HTMLAttributes<HTMLDivElement> {
135
+ /** Text between the rules. Default: "or" */
136
+ label?: React.ReactNode;
137
+ }
138
+ declare const OAuthDivider: React.ForwardRefExoticComponent<OAuthDividerProps & React.RefAttributes<HTMLDivElement>>;
139
+ export { OAuthDivider };
140
+ export interface OAuthConnectionRowProps extends React.HTMLAttributes<HTMLDivElement> {
141
+ provider: OAuthProvider;
142
+ /** Optional account identifier shown next to the provider name (e.g. email) */
143
+ accountLabel?: React.ReactNode;
144
+ /** Whether the provider is currently linked */
145
+ connected: boolean;
146
+ /** Click handler for the connect/disconnect action */
147
+ onAction?: (e: React.MouseEvent<HTMLButtonElement>) => void;
148
+ /** Promise-returning click handler — uses Button's async state machine */
149
+ onActionAsync?: (e: React.MouseEvent<HTMLButtonElement>) => Promise<void>;
150
+ /** Override the action label */
151
+ actionLabel?: React.ReactNode;
152
+ /** Disable the action button */
153
+ disabled?: boolean;
154
+ /** Override the default glyph. Accepts any `IconInput`. */
155
+ icon?: IconInput;
156
+ }
157
+ /**
158
+ * Settings-page row representing a linked OAuth provider. Different surface
159
+ * from sign-in: this is an existing connection the user can disconnect or
160
+ * (re-)connect. Renders glyph + provider name + optional account label + a
161
+ * connect/disconnect button.
162
+ */
163
+ declare const OAuthConnectionRow: React.ForwardRefExoticComponent<OAuthConnectionRowProps & React.RefAttributes<HTMLDivElement>>;
164
+ export { OAuthConnectionRow };
165
+ export interface OAuthGlyphProps extends Omit<React.SVGAttributes<SVGElement>, 'children'> {
166
+ provider: OAuthProvider;
167
+ /** Glyph pixel size. Default 18. */
168
+ size?: number;
169
+ }
170
+ /**
171
+ * Render just the provider glyph — useful when building a custom OAuth
172
+ * trigger (e.g. an icon-button inside a Tooltip, or a provider chip on a
173
+ * profile card). Defaults to the Tabler glyph; the icon prop on
174
+ * `OAuthButton` is the right escape hatch for the brand multi-colour mark.
175
+ */
176
+ declare const OAuthGlyph: React.ForwardRefExoticComponent<OAuthGlyphProps & React.RefAttributes<SVGSVGElement>>;
177
+ export { OAuthGlyph };
178
+ /**
179
+ * Resolve the visible label for a provider × intent combo. Useful when
180
+ * rendering OAuth UIs outside of `OAuthButton` (e.g. a Confirm dialog
181
+ * "Disconnect from Google?" title).
182
+ */
183
+ export declare function getOAuthLabel(provider: OAuthProvider, intent?: OAuthIntent, compact?: boolean): string;
184
+ /** Display name for a provider, ready for sentence interpolation. */
185
+ export declare function getOAuthName(provider: OAuthProvider): string;
186
+ /**
187
+ * Namespaced API — drop-in alternative to importing each piece separately.
188
+ *
189
+ * @example
190
+ * import { OAuth } from '@devalok/shilp-sutra/ui/oauth-button'
191
+ *
192
+ * <OAuth.Group reorderLastUsedFirst>
193
+ * <OAuth.Button provider="google" lastUsed />
194
+ * <OAuth.Button provider="passkey" />
195
+ * <OAuth.Divider />
196
+ * <OAuth.Button provider="sso" variant="ghost" />
197
+ * </OAuth.Group>
198
+ */
199
+ export declare const OAuth: {
200
+ readonly Button: React.ForwardRefExoticComponent<OAuthButtonProps & React.RefAttributes<HTMLButtonElement>>;
201
+ readonly Group: React.ForwardRefExoticComponent<OAuthGroupProps & React.RefAttributes<HTMLDivElement>>;
202
+ readonly Divider: React.ForwardRefExoticComponent<OAuthDividerProps & React.RefAttributes<HTMLDivElement>>;
203
+ readonly ConnectionRow: React.ForwardRefExoticComponent<OAuthConnectionRowProps & React.RefAttributes<HTMLDivElement>>;
204
+ readonly Glyph: React.ForwardRefExoticComponent<OAuthGlyphProps & React.RefAttributes<SVGSVGElement>>;
205
+ readonly getLabel: typeof getOAuthLabel;
206
+ readonly getName: typeof getOAuthName;
207
+ };
208
+ //# sourceMappingURL=oauth-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-button.d.ts","sourceRoot":"","sources":["../../../src/ui/oauth-button/oauth-button.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAMlD,MAAM,MAAM,aAAa,GACrB,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,WAAW,GACX,GAAG,GACH,UAAU,GACV,UAAU,GACV,SAAS,GACT,OAAO,GACP,QAAQ,GACR,KAAK,GACL,OAAO,GACP,SAAS,CAAA;AAEb,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE1D;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;AAEjE,uFAAuF;AACvF,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AA6G1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,WAAW,gBACf,SAAQ,IAAI,CACV,WAAW,EACX,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CACrE;IACD,4CAA4C;IAC5C,QAAQ,EAAE,aAAa,CAAA;IACvB,qDAAqD;IACrD,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,iFAAiF;IACjF,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,wFAAwF;IACxF,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,KAAK,CAAC,SAAS,CAAC,CAAA;IACnF,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B;AAED,QAAA,MAAM,WAAW,4FAmGhB,CAAA;AAGD,OAAO,EAAE,WAAW,EAAE,CAAA;AAItB,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC3E,8DAA8D;IAC9D,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,CAAA;IACvC,kDAAkD;IAClD,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;IACjC,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED;;;;GAIG;AACH,QAAA,MAAM,UAAU,wFAmDf,CAAA;AAGD,OAAO,EAAE,UAAU,EAAE,CAAA;AAIrB,MAAM,WAAW,iBAAkB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC7E,4CAA4C;IAC5C,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACxB;AAED,QAAA,MAAM,YAAY,0FAcjB,CAAA;AAGD,OAAO,EAAE,YAAY,EAAE,CAAA;AAIvB,MAAM,WAAW,uBAAwB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACnF,QAAQ,EAAE,aAAa,CAAA;IACvB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC9B,+CAA+C;IAC/C,SAAS,EAAE,OAAO,CAAA;IAClB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAA;IAC3D,0EAA0E;IAC1E,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACzE,gCAAgC;IAChC,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAED;;;;;GAKG;AACH,QAAA,MAAM,kBAAkB,gGAyDvB,CAAA;AAGD,OAAO,EAAE,kBAAkB,EAAE,CAAA;AAI7B,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxF,QAAQ,EAAE,aAAa,CAAA;IACvB,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;GAKG;AACH,QAAA,MAAM,UAAU,uFASf,CAAA;AAGD,OAAO,EAAE,UAAU,EAAE,CAAA;AAIrB;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,GAAE,WAAwB,EAAE,OAAO,UAAQ,GAAG,MAAM,CAEhH;AAED,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAE5D;AAID;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,KAAK;;;;;;;;CAQR,CAAA"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { F as e, P as t } from "../_chunks/primitives.js";
2
+ import { A as e, k as t } from "../_chunks/primitives.js";
3
3
  import { springs as n } from "./lib/motion.js";
4
4
  import { t as r } from "../_chunks/vendor-utils.js";
5
5
  import { cn as i } from "./lib/utils.js";
@@ -1,14 +1,13 @@
1
1
  "use client";
2
+ import { IconInput } from './lib/icon-input';
2
3
  import * as React from 'react';
3
4
  export type SegmentedControlSize = 'sm' | 'md' | 'lg';
4
5
  export type SegmentedControlVariant = 'default' | 'solid';
5
6
  export interface SegmentedControlOption {
6
7
  id: string;
7
8
  text: string;
8
- /** Optional icon component rendered before the text label. */
9
- icon?: React.ComponentType<{
10
- className?: string;
11
- }>;
9
+ /** Optional icon rendered before the text label. Accepts any `IconInput`. */
10
+ icon?: IconInput;
12
11
  }
13
12
  export interface SegmentedControlProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {
14
13
  size?: SegmentedControlSize;
@@ -1 +1 @@
1
- {"version":3,"file":"segmented-control.d.ts","sourceRoot":"","sources":["../../src/ui/segmented-control.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AACrD,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,OAAO,CAAA;AAEzD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,8DAA8D;IAC9D,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACnD;AAED,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IACnG,IAAI,CAAC,EAAE,oBAAoB,CAAA;IAC3B,OAAO,CAAC,EAAE,uBAAuB,CAAA;IACjC,OAAO,EAAE,sBAAsB,EAAE,CAAA;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AA6BD,QAAA,MAAM,gBAAgB,8FA+HrB,CAAA;AAKD,OAAO,EAAE,gBAAgB,EAAE,CAAA"}
1
+ {"version":3,"file":"segmented-control.d.ts","sourceRoot":"","sources":["../../src/ui/segmented-control.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAMjD,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AACrD,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,OAAO,CAAA;AAEzD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,6EAA6E;IAC7E,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAED,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IACnG,IAAI,CAAC,EAAE,oBAAoB,CAAA;IAC3B,OAAO,CAAC,EAAE,uBAAuB,CAAA;IACjC,OAAO,EAAE,sBAAsB,EAAE,CAAA;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AA6BD,QAAA,MAAM,gBAAgB,8FAkIrB,CAAA;AAKD,OAAO,EAAE,gBAAgB,EAAE,CAAA"}
@@ -1,10 +1,12 @@
1
1
  "use client";
2
- import { cn as e } from "./lib/utils.js";
3
- import * as t from "react";
4
- import { jsx as n, jsxs as r } from "react/jsx-runtime";
5
- import { LayoutGroup as i, motion as a } from "framer-motion";
2
+ import { IconProvider as e } from "./icon-context.js";
3
+ import { cn as t } from "./lib/utils.js";
4
+ import { t as n } from "../_chunks/normalize-icon.js";
5
+ import * as r from "react";
6
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
+ import { LayoutGroup as o, motion as s } from "framer-motion";
6
8
  //#region src/ui/segmented-control.tsx
7
- var o = {
9
+ var c = {
8
10
  sm: {
9
11
  button: "h-7 px-ds-04 text-ds-sm",
10
12
  icon: "h-3.5 w-3.5"
@@ -17,78 +19,84 @@ var o = {
17
19
  button: "h-10 px-ds-06 text-ds-md",
18
20
  icon: "h-4 w-4"
19
21
  }
20
- }, s = {
22
+ }, l = {
21
23
  default: "bg-surface-overlay shadow-raised",
22
24
  solid: "bg-accent-9"
23
- }, c = {
25
+ }, u = {
24
26
  default: "text-surface-fg",
25
27
  solid: "text-accent-fg"
26
- }, l = {
28
+ }, d = {
27
29
  type: "spring",
28
30
  stiffness: 400,
29
31
  damping: 30
30
- }, u = t.forwardRef(function({ size: u = "md", variant: d = "default", options: f, selectedId: p, onSelect: m, disabled: h = !1, className: g, ..._ }, v) {
31
- let y = t.useId(), b = t.useRef(null), x = t.useCallback((e) => {
32
- b.current = e, typeof v == "function" ? v(e) : v && (v.current = e);
33
- }, [v]), S = (e) => {
34
- if (h) return;
35
- let t = f.findIndex((e) => e.id === p), n = t;
32
+ }, f = r.forwardRef(function({ size: f = "md", variant: p = "default", options: m, selectedId: h, onSelect: g, disabled: _ = !1, className: v, ...y }, b) {
33
+ let x = r.useId(), S = r.useRef(null), C = r.useCallback((e) => {
34
+ S.current = e, typeof b == "function" ? b(e) : b && (b.current = e);
35
+ }, [b]), w = (e) => {
36
+ if (_) return;
37
+ let t = m.findIndex((e) => e.id === h), n = t;
36
38
  switch (e.key) {
37
39
  case "ArrowLeft":
38
- e.preventDefault(), n = t > 0 ? t - 1 : f.length - 1;
40
+ e.preventDefault(), n = t > 0 ? t - 1 : m.length - 1;
39
41
  break;
40
42
  case "ArrowRight":
41
- e.preventDefault(), n = t < f.length - 1 ? t + 1 : 0;
43
+ e.preventDefault(), n = t < m.length - 1 ? t + 1 : 0;
42
44
  break;
43
45
  case "Home":
44
46
  e.preventDefault(), n = 0;
45
47
  break;
46
48
  case "End":
47
- e.preventDefault(), n = f.length - 1;
49
+ e.preventDefault(), n = m.length - 1;
48
50
  break;
49
51
  default: return;
50
52
  }
51
- m(f[n].id), requestAnimationFrame(() => {
52
- (b.current?.querySelectorAll("[role=\"tab\"]"))?.[n]?.focus();
53
+ g(m[n].id), requestAnimationFrame(() => {
54
+ (S.current?.querySelectorAll("[role=\"tab\"]"))?.[n]?.focus();
53
55
  });
54
- }, { button: C, icon: w } = o[u];
55
- return /* @__PURE__ */ n("div", {
56
- ref: x,
56
+ }, { button: T, icon: E } = c[f];
57
+ return /* @__PURE__ */ i("div", {
58
+ ref: C,
57
59
  role: "tablist",
58
60
  tabIndex: -1,
59
- "aria-label": _["aria-label"] ?? "Segmented control",
60
- onKeyDown: S,
61
- className: e("inline-flex p-[3px] rounded-pill", "bg-surface-raised-hover border border-surface-border-subtle shadow-inset", h && "opacity-action-disabled pointer-events-none", g),
62
- ..._,
63
- children: /* @__PURE__ */ n(i, {
64
- id: y,
65
- children: f.map((t) => {
66
- let i = t.id === p, o = t.icon;
67
- return /* @__PURE__ */ r("button", {
61
+ "aria-label": y["aria-label"] ?? "Segmented control",
62
+ onKeyDown: w,
63
+ className: t("inline-flex p-[3px] rounded-pill", "bg-surface-raised-hover border border-surface-border-subtle shadow-inset", _ && "opacity-action-disabled pointer-events-none", v),
64
+ ...y,
65
+ children: /* @__PURE__ */ i(o, {
66
+ id: x,
67
+ children: m.map((r) => {
68
+ let o = r.id === h;
69
+ return /* @__PURE__ */ a("button", {
68
70
  type: "button",
69
71
  role: "tab",
70
- "aria-selected": i,
71
- tabIndex: i ? 0 : -1,
72
- disabled: h,
73
- onClick: () => m(t.id),
74
- className: e("relative inline-flex items-center justify-center gap-ds-02 rounded-pill", "font-medium transition-colors duration-fast-02 ease-productive-standard", "outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2", C, i ? c[d] : "text-surface-fg-muted hover:text-surface-fg"),
72
+ "aria-selected": o,
73
+ tabIndex: o ? 0 : -1,
74
+ disabled: _,
75
+ onClick: () => g(r.id),
76
+ className: t("relative inline-flex items-center justify-center gap-ds-02 rounded-pill", "font-medium transition-colors duration-fast-02 ease-productive-standard", "outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2", T, o ? u[p] : "text-surface-fg-muted hover:text-surface-fg"),
75
77
  children: [
76
- i && /* @__PURE__ */ n(a.span, {
78
+ o && /* @__PURE__ */ i(s.span, {
77
79
  layoutId: "segment-pill",
78
- className: e("absolute inset-0 rounded-pill pointer-events-none", s[d]),
79
- transition: l
80
+ className: t("absolute inset-0 rounded-pill pointer-events-none", l[p]),
81
+ transition: d
82
+ }),
83
+ r.icon && /* @__PURE__ */ i("span", {
84
+ className: t("relative z-[1] shrink-0 inline-flex items-center justify-center", E),
85
+ children: /* @__PURE__ */ i(e, {
86
+ size: f === "lg" ? "sm" : "xs",
87
+ children: n(r.icon)
88
+ })
80
89
  }),
81
- o && /* @__PURE__ */ n(o, { className: e("relative z-[1] shrink-0", w) }),
82
- /* @__PURE__ */ n("span", {
90
+ /* @__PURE__ */ i("span", {
83
91
  className: "relative z-[1]",
84
- children: t.text
92
+ children: r.text
85
93
  })
86
94
  ]
87
- }, t.id);
95
+ }, r.id);
88
96
  })
89
97
  })
90
98
  });
91
99
  });
92
- u.displayName = "SegmentedControl";
100
+ f.displayName = "SegmentedControl";
93
101
  //#endregion
94
- export { u as SegmentedControl };
102
+ export { f as SegmentedControl };
@@ -1 +1 @@
1
- {"version":3,"file":"segmented-control.js","names":[],"sources":["../../src/ui/segmented-control.tsx"],"sourcesContent":["'use client'\n\nimport { LayoutGroup,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { cn } from './lib/utils'\n\n/* ── Types ─────────────────────────────────────────────────── */\n\nexport type SegmentedControlSize = 'sm' | 'md' | 'lg'\nexport type SegmentedControlVariant = 'default' | 'solid'\n\nexport interface SegmentedControlOption {\n id: string\n text: string\n /** Optional icon component rendered before the text label. */\n icon?: React.ComponentType<{ className?: string }>\n}\n\nexport interface SegmentedControlProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n size?: SegmentedControlSize\n variant?: SegmentedControlVariant\n options: SegmentedControlOption[]\n selectedId: string\n onSelect: (id: string) => void\n disabled?: boolean\n}\n\n/* ── Size config ───────────────────────────────────────────── */\n\nconst sizeConfig = {\n sm: { button: 'h-7 px-ds-04 text-ds-sm', icon: 'h-3.5 w-3.5' },\n md: { button: 'h-8 px-ds-05 text-ds-md', icon: 'h-4 w-4' },\n lg: { button: 'h-10 px-ds-06 text-ds-md', icon: 'h-4 w-4' },\n} as const\n\n/* ── Pill styles per variant ───────────────────────────────── */\n\nconst pillStyles = {\n default: 'bg-surface-overlay shadow-raised',\n solid: 'bg-accent-9',\n} as const\n\nconst selectedTextStyles = {\n default: 'text-surface-fg',\n solid: 'text-accent-fg',\n} as const\n\n/* ── Spring config (snappy, minimal overshoot) ─────────────── */\n/* Intentionally softer than springs.snappy (500/30/0.5) for pill slide feel */\n\nconst pillSpring = { type: 'spring' as const, stiffness: 400, damping: 30 }\n\n/* ── SegmentedControl ──────────────────────────────────────── */\n\nconst SegmentedControl = React.forwardRef<HTMLDivElement, SegmentedControlProps>(\n function SegmentedControl(\n {\n size = 'md',\n variant = 'default',\n options,\n selectedId,\n onSelect,\n disabled = false,\n className,\n ...props\n },\n ref,\n ) {\n const instanceId = React.useId()\n const tablistRef = React.useRef<HTMLDivElement | null>(null)\n\n // Compose refs\n const mergedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n tablistRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n },\n [ref],\n )\n\n // Keyboard navigation\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return\n\n const currentIndex = options.findIndex((o) => o.id === selectedId)\n let nextIndex = currentIndex\n\n switch (e.key) {\n case 'ArrowLeft':\n e.preventDefault()\n nextIndex = currentIndex > 0 ? currentIndex - 1 : options.length - 1\n break\n case 'ArrowRight':\n e.preventDefault()\n nextIndex = currentIndex < options.length - 1 ? currentIndex + 1 : 0\n break\n case 'Home':\n e.preventDefault()\n nextIndex = 0\n break\n case 'End':\n e.preventDefault()\n nextIndex = options.length - 1\n break\n default:\n return\n }\n\n onSelect(options[nextIndex].id)\n requestAnimationFrame(() => {\n const buttons = tablistRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"tab\"]')\n buttons?.[nextIndex]?.focus()\n })\n }\n\n const { button: buttonSize, icon: iconSize } = sizeConfig[size]\n\n return (\n <div\n ref={mergedRef}\n role=\"tablist\"\n tabIndex={-1}\n aria-label={props['aria-label'] ?? 'Segmented control'}\n onKeyDown={handleKeyDown}\n className={cn(\n 'inline-flex p-[3px] rounded-pill',\n 'bg-surface-raised-hover border border-surface-border-subtle shadow-inset',\n disabled && 'opacity-action-disabled pointer-events-none',\n className,\n )}\n {...props}\n >\n <LayoutGroup id={instanceId}>\n {options.map((option) => {\n const isSelected = option.id === selectedId\n const OptionIcon = option.icon\n\n return (\n <button\n key={option.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={isSelected}\n tabIndex={isSelected ? 0 : -1}\n disabled={disabled}\n onClick={() => onSelect(option.id)}\n className={cn(\n 'relative inline-flex items-center justify-center gap-ds-02 rounded-pill',\n 'font-medium transition-colors duration-fast-02 ease-productive-standard',\n 'outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2',\n buttonSize,\n isSelected\n ? selectedTextStyles[variant]\n : 'text-surface-fg-muted hover:text-surface-fg',\n )}\n >\n {/* Sliding pill indicator */}\n {isSelected && (\n <motion.span\n layoutId=\"segment-pill\"\n className={cn(\n 'absolute inset-0 rounded-pill pointer-events-none',\n pillStyles[variant],\n )}\n transition={pillSpring}\n />\n )}\n\n {/* Content (above pill via z-index) */}\n {OptionIcon && (\n <OptionIcon className={cn('relative z-[1] shrink-0', iconSize)} />\n )}\n <span className=\"relative z-[1]\">{option.text}</span>\n </button>\n )\n })}\n </LayoutGroup>\n </div>\n )\n },\n)\nSegmentedControl.displayName = 'SegmentedControl'\n\n/* ── Exports ───────────────────────────────────────────────── */\n\nexport { SegmentedControl }\n"],"mappings":";;;;;;AA8BA,IAAM,IAAa;CACjB,IAAI;EAAE,QAAQ;EAA2B,MAAM;EAAe;CAC9D,IAAI;EAAE,QAAQ;EAA2B,MAAM;EAAW;CAC1D,IAAI;EAAE,QAAQ;EAA4B,MAAM;EAAW;CAC5D,EAIK,IAAa;CACjB,SAAS;CACT,OAAO;CACR,EAEK,IAAqB;CACzB,SAAS;CACT,OAAO;CACR,EAKK,IAAa;CAAE,MAAM;CAAmB,WAAW;CAAK,SAAS;CAAI,EAIrE,IAAmB,EAAM,WAC7B,SACE,EACE,UAAO,MACP,aAAU,WACV,YACA,eACA,aACA,cAAW,IACX,cACA,GAAG,KAEL,GACA;CACA,IAAM,IAAa,EAAM,OAAO,EAC1B,IAAa,EAAM,OAA8B,KAAK,EAGtD,IAAY,EAAM,aACrB,MAAgC;AAE/B,EADA,EAAW,UAAU,GACjB,OAAO,KAAQ,aAAY,EAAI,EAAK,GAC/B,MAAM,EAAsD,UAAU;IAEjF,CAAC,EAAI,CACN,EAGK,KAAiB,MAA2C;AAChE,MAAI,EAAU;EAEd,IAAM,IAAe,EAAQ,WAAW,MAAM,EAAE,OAAO,EAAW,EAC9D,IAAY;AAEhB,UAAQ,EAAE,KAAV;GACE,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY,IAAe,IAAI,IAAe,IAAI,EAAQ,SAAS;AACnE;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY,IAAe,EAAQ,SAAS,IAAI,IAAe,IAAI;AACnE;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY;AACZ;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY,EAAQ,SAAS;AAC7B;GACF,QACE;;AAIJ,EADA,EAAS,EAAQ,GAAW,GAAG,EAC/B,4BAA4B;AAE1B,IADgB,EAAW,SAAS,iBAAoC,iBAAe,IAC7E,IAAY,OAAO;IAC7B;IAGE,EAAE,QAAQ,GAAY,MAAM,MAAa,EAAW;AAE1D,QACE,kBAAC,OAAD;EACE,KAAK;EACL,MAAK;EACL,UAAU;EACV,cAAY,EAAM,iBAAiB;EACnC,WAAW;EACX,WAAW,EACT,oCACA,4EACA,KAAY,+CACZ,EACD;EACD,GAAI;YAEJ,kBAAC,GAAD;GAAa,IAAI;aACd,EAAQ,KAAK,MAAW;IACvB,IAAM,IAAa,EAAO,OAAO,GAC3B,IAAa,EAAO;AAE1B,WACE,kBAAC,UAAD;KAEE,MAAK;KACL,MAAK;KACL,iBAAe;KACf,UAAU,IAAa,IAAI;KACjB;KACV,eAAe,EAAS,EAAO,GAAG;KAClC,WAAW,EACT,2EACA,2EACA,+FACA,GACA,IACI,EAAmB,KACnB,8CACL;eAhBH;MAmBG,KACC,kBAAC,EAAO,MAAR;OACE,UAAS;OACT,WAAW,EACT,qDACA,EAAW,GACZ;OACD,YAAY;OACZ,CAAA;MAIH,KACC,kBAAC,GAAD,EAAY,WAAW,EAAG,2BAA2B,EAAS,EAAI,CAAA;MAEpE,kBAAC,QAAD;OAAM,WAAU;iBAAkB,EAAO;OAAY,CAAA;MAC9C;OAlCF,EAAO,GAkCL;KAEX;GACU,CAAA;EACV,CAAA;EAGX;AACD,EAAiB,cAAc"}
1
+ {"version":3,"file":"segmented-control.js","names":[],"sources":["../../src/ui/segmented-control.tsx"],"sourcesContent":["'use client'\n\nimport { LayoutGroup,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { IconProvider } from './icon-context'\nimport type { IconInput } from './lib/icon-input'\nimport { normalizeIcon } from './lib/normalize-icon'\nimport { cn } from './lib/utils'\n\n/* ── Types ─────────────────────────────────────────────────── */\n\nexport type SegmentedControlSize = 'sm' | 'md' | 'lg'\nexport type SegmentedControlVariant = 'default' | 'solid'\n\nexport interface SegmentedControlOption {\n id: string\n text: string\n /** Optional icon rendered before the text label. Accepts any `IconInput`. */\n icon?: IconInput\n}\n\nexport interface SegmentedControlProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n size?: SegmentedControlSize\n variant?: SegmentedControlVariant\n options: SegmentedControlOption[]\n selectedId: string\n onSelect: (id: string) => void\n disabled?: boolean\n}\n\n/* ── Size config ───────────────────────────────────────────── */\n\nconst sizeConfig = {\n sm: { button: 'h-7 px-ds-04 text-ds-sm', icon: 'h-3.5 w-3.5' },\n md: { button: 'h-8 px-ds-05 text-ds-md', icon: 'h-4 w-4' },\n lg: { button: 'h-10 px-ds-06 text-ds-md', icon: 'h-4 w-4' },\n} as const\n\n/* ── Pill styles per variant ───────────────────────────────── */\n\nconst pillStyles = {\n default: 'bg-surface-overlay shadow-raised',\n solid: 'bg-accent-9',\n} as const\n\nconst selectedTextStyles = {\n default: 'text-surface-fg',\n solid: 'text-accent-fg',\n} as const\n\n/* ── Spring config (snappy, minimal overshoot) ─────────────── */\n/* Intentionally softer than springs.snappy (500/30/0.5) for pill slide feel */\n\nconst pillSpring = { type: 'spring' as const, stiffness: 400, damping: 30 }\n\n/* ── SegmentedControl ──────────────────────────────────────── */\n\nconst SegmentedControl = React.forwardRef<HTMLDivElement, SegmentedControlProps>(\n function SegmentedControl(\n {\n size = 'md',\n variant = 'default',\n options,\n selectedId,\n onSelect,\n disabled = false,\n className,\n ...props\n },\n ref,\n ) {\n const instanceId = React.useId()\n const tablistRef = React.useRef<HTMLDivElement | null>(null)\n\n // Compose refs\n const mergedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n tablistRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n },\n [ref],\n )\n\n // Keyboard navigation\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return\n\n const currentIndex = options.findIndex((o) => o.id === selectedId)\n let nextIndex = currentIndex\n\n switch (e.key) {\n case 'ArrowLeft':\n e.preventDefault()\n nextIndex = currentIndex > 0 ? currentIndex - 1 : options.length - 1\n break\n case 'ArrowRight':\n e.preventDefault()\n nextIndex = currentIndex < options.length - 1 ? currentIndex + 1 : 0\n break\n case 'Home':\n e.preventDefault()\n nextIndex = 0\n break\n case 'End':\n e.preventDefault()\n nextIndex = options.length - 1\n break\n default:\n return\n }\n\n onSelect(options[nextIndex].id)\n requestAnimationFrame(() => {\n const buttons = tablistRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"tab\"]')\n buttons?.[nextIndex]?.focus()\n })\n }\n\n const { button: buttonSize, icon: iconSize } = sizeConfig[size]\n\n return (\n <div\n ref={mergedRef}\n role=\"tablist\"\n tabIndex={-1}\n aria-label={props['aria-label'] ?? 'Segmented control'}\n onKeyDown={handleKeyDown}\n className={cn(\n 'inline-flex p-[3px] rounded-pill',\n 'bg-surface-raised-hover border border-surface-border-subtle shadow-inset',\n disabled && 'opacity-action-disabled pointer-events-none',\n className,\n )}\n {...props}\n >\n <LayoutGroup id={instanceId}>\n {options.map((option) => {\n const isSelected = option.id === selectedId\n\n return (\n <button\n key={option.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={isSelected}\n tabIndex={isSelected ? 0 : -1}\n disabled={disabled}\n onClick={() => onSelect(option.id)}\n className={cn(\n 'relative inline-flex items-center justify-center gap-ds-02 rounded-pill',\n 'font-medium transition-colors duration-fast-02 ease-productive-standard',\n 'outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2',\n buttonSize,\n isSelected\n ? selectedTextStyles[variant]\n : 'text-surface-fg-muted hover:text-surface-fg',\n )}\n >\n {/* Sliding pill indicator */}\n {isSelected && (\n <motion.span\n layoutId=\"segment-pill\"\n className={cn(\n 'absolute inset-0 rounded-pill pointer-events-none',\n pillStyles[variant],\n )}\n transition={pillSpring}\n />\n )}\n\n {/* Content (above pill via z-index) */}\n {option.icon && (\n <span className={cn('relative z-[1] shrink-0 inline-flex items-center justify-center', iconSize)}>\n <IconProvider size={size === 'lg' ? 'sm' : 'xs'}>\n {normalizeIcon(option.icon)}\n </IconProvider>\n </span>\n )}\n <span className=\"relative z-[1]\">{option.text}</span>\n </button>\n )\n })}\n </LayoutGroup>\n </div>\n )\n },\n)\nSegmentedControl.displayName = 'SegmentedControl'\n\n/* ── Exports ───────────────────────────────────────────────── */\n\nexport { SegmentedControl }\n"],"mappings":";;;;;;;;AAiCA,IAAM,IAAa;CACjB,IAAI;EAAE,QAAQ;EAA2B,MAAM;EAAe;CAC9D,IAAI;EAAE,QAAQ;EAA2B,MAAM;EAAW;CAC1D,IAAI;EAAE,QAAQ;EAA4B,MAAM;EAAW;CAC5D,EAIK,IAAa;CACjB,SAAS;CACT,OAAO;CACR,EAEK,IAAqB;CACzB,SAAS;CACT,OAAO;CACR,EAKK,IAAa;CAAE,MAAM;CAAmB,WAAW;CAAK,SAAS;CAAI,EAIrE,IAAmB,EAAM,WAC7B,SACE,EACE,UAAO,MACP,aAAU,WACV,YACA,eACA,aACA,cAAW,IACX,cACA,GAAG,KAEL,GACA;CACA,IAAM,IAAa,EAAM,OAAO,EAC1B,IAAa,EAAM,OAA8B,KAAK,EAGtD,IAAY,EAAM,aACrB,MAAgC;AAE/B,EADA,EAAW,UAAU,GACjB,OAAO,KAAQ,aAAY,EAAI,EAAK,GAC/B,MAAM,EAAsD,UAAU;IAEjF,CAAC,EAAI,CACN,EAGK,KAAiB,MAA2C;AAChE,MAAI,EAAU;EAEd,IAAM,IAAe,EAAQ,WAAW,MAAM,EAAE,OAAO,EAAW,EAC9D,IAAY;AAEhB,UAAQ,EAAE,KAAV;GACE,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY,IAAe,IAAI,IAAe,IAAI,EAAQ,SAAS;AACnE;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY,IAAe,EAAQ,SAAS,IAAI,IAAe,IAAI;AACnE;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY;AACZ;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,IAAY,EAAQ,SAAS;AAC7B;GACF,QACE;;AAIJ,EADA,EAAS,EAAQ,GAAW,GAAG,EAC/B,4BAA4B;AAE1B,IADgB,EAAW,SAAS,iBAAoC,iBAAe,IAC7E,IAAY,OAAO;IAC7B;IAGE,EAAE,QAAQ,GAAY,MAAM,MAAa,EAAW;AAE1D,QACE,kBAAC,OAAD;EACE,KAAK;EACL,MAAK;EACL,UAAU;EACV,cAAY,EAAM,iBAAiB;EACnC,WAAW;EACX,WAAW,EACT,oCACA,4EACA,KAAY,+CACZ,EACD;EACD,GAAI;YAEJ,kBAAC,GAAD;GAAa,IAAI;aACd,EAAQ,KAAK,MAAW;IACvB,IAAM,IAAa,EAAO,OAAO;AAEjC,WACE,kBAAC,UAAD;KAEE,MAAK;KACL,MAAK;KACL,iBAAe;KACf,UAAU,IAAa,IAAI;KACjB;KACV,eAAe,EAAS,EAAO,GAAG;KAClC,WAAW,EACT,2EACA,2EACA,+FACA,GACA,IACI,EAAmB,KACnB,8CACL;eAhBH;MAmBG,KACC,kBAAC,EAAO,MAAR;OACE,UAAS;OACT,WAAW,EACT,qDACA,EAAW,GACZ;OACD,YAAY;OACZ,CAAA;MAIH,EAAO,QACN,kBAAC,QAAD;OAAM,WAAW,EAAG,mEAAmE,EAAS;iBAC9F,kBAAC,GAAD;QAAc,MAAM,MAAS,OAAO,OAAO;kBACxC,EAAc,EAAO,KAAK;QACd,CAAA;OACV,CAAA;MAET,kBAAC,QAAD;OAAM,WAAU;iBAAkB,EAAO;OAAY,CAAA;MAC9C;OAtCF,EAAO,GAsCL;KAEX;GACU,CAAA;EACV,CAAA;EAGX;AACD,EAAiB,cAAc"}
@@ -10,6 +10,11 @@ type StackProps<T extends React.ElementType = 'div'> = {
10
10
  className?: string;
11
11
  children?: React.ReactNode;
12
12
  } & Omit<React.ComponentPropsWithRef<T>, 'as' | 'className' | 'children'>;
13
- declare const Stack: React.ForwardRefExoticComponent<Omit<StackProps<"div">, "ref"> & React.RefAttributes<HTMLElement>>;
13
+ type StackComponent = (<T extends React.ElementType = 'div'>(props: StackProps<T> & {
14
+ ref?: React.ComponentPropsWithRef<T>['ref'];
15
+ }) => React.ReactElement | null) & {
16
+ displayName?: string;
17
+ };
18
+ declare const Stack: StackComponent;
14
19
  export { type SpacingToken, Stack, type StackProps };
15
20
  //# sourceMappingURL=stack.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../src/ui/stack.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,KAAK,YAAY,GACb,OAAO,GACP,OAAO,GACP,QAAQ,GACR,OAAO,GACP,OAAO,GACP,OAAO,GACP,QAAQ,GACR,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,CAAA;AAEX,KAAK,UAAU,CAAC,CAAC,SAAS,KAAK,CAAC,WAAW,GAAG,KAAK,IAAI;IACrD,EAAE,CAAC,EAAE,CAAC,CAAA;IACN,SAAS,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,KAAK,GAAG,QAAQ,CAAA;IACxD,GAAG,CAAC,EAAE,YAAY,GAAG,MAAM,CAAA;IAC3B,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,GAAG,UAAU,CAAA;IAC3D,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;IACtE,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,WAAW,GAAG,UAAU,CAAC,CAAA;AAmDzE,QAAA,MAAM,KAAK,oGAqBV,CAAA;AAGD,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,CAAA"}
1
+ {"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../src/ui/stack.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,KAAK,YAAY,GACb,OAAO,GACP,OAAO,GACP,QAAQ,GACR,OAAO,GACP,OAAO,GACP,OAAO,GACP,QAAQ,GACR,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,CAAA;AAEX,KAAK,UAAU,CAAC,CAAC,SAAS,KAAK,CAAC,WAAW,GAAG,KAAK,IAAI;IACrD,EAAE,CAAC,EAAE,CAAC,CAAA;IACN,SAAS,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,KAAK,GAAG,QAAQ,CAAA;IACxD,GAAG,CAAC,EAAE,YAAY,GAAG,MAAM,CAAA;IAC3B,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,GAAG,UAAU,CAAA;IAC3D,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;IACtE,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,WAAW,GAAG,UAAU,CAAC,CAAA;AAsDzE,KAAK,cAAc,GAAG,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,WAAW,GAAG,KAAK,EACzD,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;CAAE,KACnE,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AA0B1D,QAAA,MAAM,KAAK,EAA2B,cAAc,CAAA;AAEpD,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,CAAA"}
package/dist/ui/stack.js CHANGED
@@ -53,5 +53,6 @@ var n = {
53
53
  }, f);
54
54
  });
55
55
  a.displayName = "Stack";
56
+ var o = a;
56
57
  //#endregion
57
- export { a as Stack };
58
+ export { o as Stack };
@@ -1 +1 @@
1
- {"version":3,"file":"stack.js","names":[],"sources":["../../src/ui/stack.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\n\nimport { cn } from './lib/utils'\n\ntype SpacingToken =\n | 'ds-01'\n | 'ds-02'\n | 'ds-02b'\n | 'ds-03'\n | 'ds-04'\n | 'ds-05'\n | 'ds-05b'\n | 'ds-06'\n | 'ds-07'\n | 'ds-08'\n | 'ds-09'\n | 'ds-10'\n | 'ds-11'\n | 'ds-12'\n | 'ds-13'\n\ntype StackProps<T extends React.ElementType = 'div'> = {\n as?: T\n direction?: 'vertical' | 'horizontal' | 'row' | 'column'\n gap?: SpacingToken | number\n align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline'\n justify?: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'\n wrap?: boolean\n className?: string\n children?: React.ReactNode\n} & Omit<React.ComponentPropsWithRef<T>, 'as' | 'className' | 'children'>\n\nconst alignMap = {\n start: 'items-start',\n center: 'items-center',\n end: 'items-end',\n stretch: 'items-stretch',\n baseline: 'items-baseline',\n} as const\n\nconst justifyMap = {\n start: 'justify-start',\n center: 'justify-center',\n end: 'justify-end',\n between: 'justify-between',\n around: 'justify-around',\n evenly: 'justify-evenly',\n} as const\n\nconst gapMap: Record<string, string> = {\n '0': 'gap-0',\n '1': 'gap-ds-01',\n '2': 'gap-ds-02',\n '3': 'gap-ds-03',\n '4': 'gap-ds-04',\n '5': 'gap-ds-05',\n '6': 'gap-ds-06',\n '7': 'gap-ds-07',\n '8': 'gap-ds-08',\n '9': 'gap-ds-09',\n '10': 'gap-ds-10',\n '11': 'gap-ds-11',\n '12': 'gap-ds-12',\n '13': 'gap-ds-13',\n 'ds-01': 'gap-ds-01',\n 'ds-02': 'gap-ds-02',\n 'ds-02b': 'gap-ds-02b',\n 'ds-03': 'gap-ds-03',\n 'ds-04': 'gap-ds-04',\n 'ds-05': 'gap-ds-05',\n 'ds-05b': 'gap-ds-05b',\n 'ds-06': 'gap-ds-06',\n 'ds-07': 'gap-ds-07',\n 'ds-08': 'gap-ds-08',\n 'ds-09': 'gap-ds-09',\n 'ds-10': 'gap-ds-10',\n 'ds-11': 'gap-ds-11',\n 'ds-12': 'gap-ds-12',\n 'ds-13': 'gap-ds-13',\n} as const\n\nconst Stack = React.forwardRef<HTMLElement, StackProps>(\n ({ as, direction = 'vertical', gap, align, justify, wrap, className, children, ...props }, ref) => {\n const Component = as || 'div'\n return React.createElement(\n Component,\n {\n ref,\n className: cn(\n 'flex',\n (direction === 'vertical' || direction === 'column') ? 'flex-col' : 'flex-row',\n gap != null && gapMap[String(gap)],\n align && alignMap[align],\n justify && justifyMap[justify],\n wrap && 'flex-wrap',\n className,\n ),\n ...props,\n },\n children,\n )\n },\n)\nStack.displayName = 'Stack'\n\nexport { type SpacingToken, Stack, type StackProps }\n"],"mappings":";;;AAiCA,IAAM,IAAW;CACf,OAAO;CACP,QAAQ;CACR,KAAK;CACL,SAAS;CACT,UAAU;CACX,EAEK,IAAa;CACjB,OAAO;CACP,QAAQ;CACR,KAAK;CACL,SAAS;CACT,QAAQ;CACR,QAAQ;CACT,EAEK,IAAiC;CACrC,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,IAAM;CACN,IAAM;CACN,IAAM;CACN,IAAM;CACN,SAAS;CACT,SAAS;CACT,UAAU;CACV,SAAS;CACT,SAAS;CACT,SAAS;CACT,UAAU;CACV,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACV,EAEK,IAAQ,EAAM,YACjB,EAAE,OAAI,eAAY,YAAY,QAAK,UAAO,YAAS,SAAM,cAAW,aAAU,GAAG,KAAS,MAAQ;CACjG,IAAM,IAAY,KAAM;AACxB,QAAO,EAAM,cACX,GACA;EACE;EACA,WAAW,EACT,QACC,MAAc,cAAc,MAAc,WAAY,aAAa,YACpE,KAAO,QAAQ,EAAO,OAAO,EAAI,GACjC,KAAS,EAAS,IAClB,KAAW,EAAW,IACtB,KAAQ,aACR,EACD;EACD,GAAG;EACJ,EACD,EACD;EAEJ;AACD,EAAM,cAAc"}
1
+ {"version":3,"file":"stack.js","names":[],"sources":["../../src/ui/stack.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\n\nimport { cn } from './lib/utils'\n\ntype SpacingToken =\n | 'ds-01'\n | 'ds-02'\n | 'ds-02b'\n | 'ds-03'\n | 'ds-04'\n | 'ds-05'\n | 'ds-05b'\n | 'ds-06'\n | 'ds-07'\n | 'ds-08'\n | 'ds-09'\n | 'ds-10'\n | 'ds-11'\n | 'ds-12'\n | 'ds-13'\n\ntype StackProps<T extends React.ElementType = 'div'> = {\n as?: T\n direction?: 'vertical' | 'horizontal' | 'row' | 'column'\n gap?: SpacingToken | number\n align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline'\n justify?: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'\n wrap?: boolean\n className?: string\n children?: React.ReactNode\n} & Omit<React.ComponentPropsWithRef<T>, 'as' | 'className' | 'children'>\n\nconst alignMap = {\n start: 'items-start',\n center: 'items-center',\n end: 'items-end',\n stretch: 'items-stretch',\n baseline: 'items-baseline',\n} as const\n\nconst justifyMap = {\n start: 'justify-start',\n center: 'justify-center',\n end: 'justify-end',\n between: 'justify-between',\n around: 'justify-around',\n evenly: 'justify-evenly',\n} as const\n\nconst gapMap: Record<string, string> = {\n '0': 'gap-0',\n '1': 'gap-ds-01',\n '2': 'gap-ds-02',\n '3': 'gap-ds-03',\n '4': 'gap-ds-04',\n '5': 'gap-ds-05',\n '6': 'gap-ds-06',\n '7': 'gap-ds-07',\n '8': 'gap-ds-08',\n '9': 'gap-ds-09',\n '10': 'gap-ds-10',\n '11': 'gap-ds-11',\n '12': 'gap-ds-12',\n '13': 'gap-ds-13',\n 'ds-01': 'gap-ds-01',\n 'ds-02': 'gap-ds-02',\n 'ds-02b': 'gap-ds-02b',\n 'ds-03': 'gap-ds-03',\n 'ds-04': 'gap-ds-04',\n 'ds-05': 'gap-ds-05',\n 'ds-05b': 'gap-ds-05b',\n 'ds-06': 'gap-ds-06',\n 'ds-07': 'gap-ds-07',\n 'ds-08': 'gap-ds-08',\n 'ds-09': 'gap-ds-09',\n 'ds-10': 'gap-ds-10',\n 'ds-11': 'gap-ds-11',\n 'ds-12': 'gap-ds-12',\n 'ds-13': 'gap-ds-13',\n} as const\n\n// Polymorphic component type — preserves T across the call site so element-\n// specific props (e.g. `<Stack as=\"ul\">` accepting `<ul>` props) typecheck.\n// Standard polymorphic-component pattern; see text.tsx for the same shape.\ntype StackComponent = (<T extends React.ElementType = 'div'>(\n props: StackProps<T> & { ref?: React.ComponentPropsWithRef<T>['ref'] },\n) => React.ReactElement | null) & { displayName?: string }\n\nconst StackImpl = React.forwardRef<HTMLElement, StackProps>(\n ({ as, direction = 'vertical', gap, align, justify, wrap, className, children, ...props }, ref) => {\n const Component = as || 'div'\n return React.createElement(\n Component,\n {\n ref,\n className: cn(\n 'flex',\n (direction === 'vertical' || direction === 'column') ? 'flex-col' : 'flex-row',\n gap != null && gapMap[String(gap)],\n align && alignMap[align],\n justify && justifyMap[justify],\n wrap && 'flex-wrap',\n className,\n ),\n ...props,\n },\n children,\n )\n },\n)\nStackImpl.displayName = 'Stack'\n\nconst Stack = StackImpl as unknown as StackComponent\n\nexport { type SpacingToken, Stack, type StackProps }\n"],"mappings":";;;AAiCA,IAAM,IAAW;CACf,OAAO;CACP,QAAQ;CACR,KAAK;CACL,SAAS;CACT,UAAU;CACX,EAEK,IAAa;CACjB,OAAO;CACP,QAAQ;CACR,KAAK;CACL,SAAS;CACT,QAAQ;CACR,QAAQ;CACT,EAEK,IAAiC;CACrC,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,GAAK;CACL,IAAM;CACN,IAAM;CACN,IAAM;CACN,IAAM;CACN,SAAS;CACT,SAAS;CACT,UAAU;CACV,SAAS;CACT,SAAS;CACT,SAAS;CACT,UAAU;CACV,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACV,EASK,IAAY,EAAM,YACrB,EAAE,OAAI,eAAY,YAAY,QAAK,UAAO,YAAS,SAAM,cAAW,aAAU,GAAG,KAAS,MAAQ;CACjG,IAAM,IAAY,KAAM;AACxB,QAAO,EAAM,cACX,GACA;EACE;EACA,WAAW,EACT,QACC,MAAc,cAAc,MAAc,WAAY,aAAa,YACpE,KAAO,QAAQ,EAAO,OAAO,EAAI,GACjC,KAAS,EAAS,IAClB,KAAW,EAAW,IACtB,KAAQ,aACR,EACD;EACD,GAAG;EACJ,EACD,EACD;EAEJ;AACD,EAAU,cAAc;AAExB,IAAM,IAAQ"}
@@ -1,4 +1,5 @@
1
1
  "use client";
2
+ import { IconInput } from './lib/icon-input';
2
3
  import * as React from 'react';
3
4
  /**
4
5
  * Props for StatCard — a dashboard metric tile displaying a label, a large numeric value,
@@ -54,9 +55,7 @@ export interface StatCardProps extends React.HTMLAttributes<HTMLDivElement> {
54
55
  value: string;
55
56
  direction: 'up' | 'down' | 'neutral';
56
57
  };
57
- icon?: React.ReactNode | React.ComponentType<{
58
- className?: string;
59
- }>;
58
+ icon?: IconInput;
60
59
  loading?: boolean;
61
60
  /** Comparison period label shown after delta, e.g. "vs last month" */
62
61
  comparisonLabel?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"stat-card.d.ts","sourceRoot":"","sources":["../../src/ui/stat-card.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAO9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,WAAW,aAAc,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACzE,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE;QACN,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAA;KACrC,CAAA;IACD,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,sEAAsE;IACtE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,kDAAkD;IAClD,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;IAC7D,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB;AAuGD,QAAA,MAAM,QAAQ,sFA0Nb,CAAA;AAID,OAAO,EAAE,QAAQ,EAAE,CAAA"}
1
+ {"version":3,"file":"stat-card.d.ts","sourceRoot":"","sources":["../../src/ui/stat-card.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAMjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,WAAW,aAAc,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACzE,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE;QACN,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAA;KACrC,CAAA;IACD,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,sEAAsE;IACtE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,kDAAkD;IAClD,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;IAC7D,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB;AAuGD,QAAA,MAAM,QAAQ,sFAwNb,CAAA;AAID,OAAO,EAAE,QAAQ,EAAE,CAAA"}