@tuuject/koi-react 0.0.0-stage → 0.1.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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -2
  3. package/dist/alert/Alert.d.ts +13 -0
  4. package/dist/alert/Alert.js +16 -0
  5. package/dist/avatar/Avatar.d.ts +7 -0
  6. package/dist/avatar/Avatar.js +10 -0
  7. package/dist/badge/Badge.d.ts +7 -0
  8. package/dist/badge/Badge.js +8 -0
  9. package/dist/button/Button.d.ts +22 -0
  10. package/dist/button/Button.js +28 -0
  11. package/dist/card/Card.d.ts +9 -0
  12. package/dist/card/Card.js +8 -0
  13. package/dist/chat-bubble/ChatBubble.d.ts +7 -0
  14. package/dist/chat-bubble/ChatBubble.js +7 -0
  15. package/dist/checkbox/Checkbox.d.ts +18 -0
  16. package/dist/checkbox/Checkbox.js +25 -0
  17. package/dist/dialog/Dialog.d.ts +13 -0
  18. package/dist/dialog/Dialog.js +38 -0
  19. package/dist/divider/Divider.d.ts +6 -0
  20. package/dist/divider/Divider.js +17 -0
  21. package/dist/field/Field.d.ts +14 -0
  22. package/dist/field/Field.js +19 -0
  23. package/dist/field/context.d.ts +5 -0
  24. package/dist/field/context.js +2 -0
  25. package/dist/icons.d.ts +26 -0
  26. package/dist/icons.js +46 -0
  27. package/dist/index.d.ts +31 -0
  28. package/dist/index.js +30 -0
  29. package/dist/input/Input.d.ts +9 -0
  30. package/dist/input/Input.js +15 -0
  31. package/dist/link/Link.d.ts +11 -0
  32. package/dist/link/Link.js +17 -0
  33. package/dist/pagination/Pagination.d.ts +7 -0
  34. package/dist/pagination/Pagination.js +26 -0
  35. package/dist/panda/buildinfo.json +10442 -0
  36. package/dist/panda/lib.json +18 -0
  37. package/dist/panda/preset.mjs +3907 -0
  38. package/dist/progress/Progress.d.ts +7 -0
  39. package/dist/progress/Progress.js +17 -0
  40. package/dist/prose/Prose.d.ts +10 -0
  41. package/dist/prose/Prose.js +10 -0
  42. package/dist/radio-group/RadioGroup.d.ts +15 -0
  43. package/dist/radio-group/RadioGroup.js +26 -0
  44. package/dist/select/Select.d.ts +11 -0
  45. package/dist/select/Select.js +21 -0
  46. package/dist/select/SelectPanel.d.ts +24 -0
  47. package/dist/select/SelectPanel.js +105 -0
  48. package/dist/shape.d.ts +16 -0
  49. package/dist/shape.js +17 -0
  50. package/dist/skeleton/Skeleton.d.ts +8 -0
  51. package/dist/skeleton/Skeleton.js +8 -0
  52. package/dist/spinner/Spinner.d.ts +7 -0
  53. package/dist/spinner/Spinner.js +13 -0
  54. package/dist/switch/Switch.d.ts +22 -0
  55. package/dist/switch/Switch.js +23 -0
  56. package/dist/table/DataTable.d.ts +12 -0
  57. package/dist/table/DataTable.js +12 -0
  58. package/dist/table/Table.d.ts +38 -0
  59. package/dist/table/Table.js +45 -0
  60. package/dist/tabs/Tabs.d.ts +11 -0
  61. package/dist/tabs/Tabs.js +20 -0
  62. package/dist/tag/Tag.d.ts +6 -0
  63. package/dist/tag/Tag.js +15 -0
  64. package/dist/textarea/Textarea.d.ts +9 -0
  65. package/dist/textarea/Textarea.js +14 -0
  66. package/dist/toast/Toast.d.ts +23 -0
  67. package/dist/toast/Toast.js +80 -0
  68. package/dist/tooltip/Tooltip.d.ts +9 -0
  69. package/dist/tooltip/Tooltip.js +29 -0
  70. package/dist/types.d.ts +11 -0
  71. package/dist/types.js +1 -0
  72. package/package.json +218 -3
  73. package/styled-system/css/conditions.d.ts +7 -0
  74. package/styled-system/css/conditions.js +32 -0
  75. package/styled-system/css/css.d.ts +22 -0
  76. package/styled-system/css/css.js +63 -0
  77. package/styled-system/css/cva.d.ts +5 -0
  78. package/styled-system/css/cva.js +51 -0
  79. package/styled-system/css/cx.d.ts +6 -0
  80. package/styled-system/css/cx.js +16 -0
  81. package/styled-system/css/first-that-works.d.ts +22 -0
  82. package/styled-system/css/first-that-works.js +1 -0
  83. package/styled-system/css/index.d.ts +8 -0
  84. package/styled-system/css/index.js +8 -0
  85. package/styled-system/css/keyframes.d.ts +5 -0
  86. package/styled-system/css/keyframes.js +8 -0
  87. package/styled-system/css/position-try.d.ts +5 -0
  88. package/styled-system/css/position-try.js +11 -0
  89. package/styled-system/css/sva.d.ts +3 -0
  90. package/styled-system/css/sva.js +49 -0
  91. package/styled-system/css/view-transition.d.ts +7 -0
  92. package/styled-system/css/view-transition.js +18 -0
  93. package/styled-system/helpers.d.ts +67 -0
  94. package/styled-system/helpers.js +624 -0
  95. package/styled-system/jsx/aspect-ratio.d.ts +7 -0
  96. package/styled-system/jsx/aspect-ratio.js +11 -0
  97. package/styled-system/jsx/bleed.d.ts +7 -0
  98. package/styled-system/jsx/bleed.js +11 -0
  99. package/styled-system/jsx/box.d.ts +7 -0
  100. package/styled-system/jsx/box.js +11 -0
  101. package/styled-system/jsx/center.d.ts +7 -0
  102. package/styled-system/jsx/center.js +11 -0
  103. package/styled-system/jsx/circle.d.ts +7 -0
  104. package/styled-system/jsx/circle.js +11 -0
  105. package/styled-system/jsx/container.d.ts +7 -0
  106. package/styled-system/jsx/container.js +11 -0
  107. package/styled-system/jsx/cq.d.ts +7 -0
  108. package/styled-system/jsx/cq.js +11 -0
  109. package/styled-system/jsx/create-recipe-context.d.ts +32 -0
  110. package/styled-system/jsx/create-recipe-context.js +38 -0
  111. package/styled-system/jsx/create-slot-recipe-context.d.ts +48 -0
  112. package/styled-system/jsx/create-slot-recipe-context.js +116 -0
  113. package/styled-system/jsx/divider.d.ts +7 -0
  114. package/styled-system/jsx/divider.js +11 -0
  115. package/styled-system/jsx/factory.d.ts +3 -0
  116. package/styled-system/jsx/factory.js +91 -0
  117. package/styled-system/jsx/flex.d.ts +7 -0
  118. package/styled-system/jsx/flex.js +11 -0
  119. package/styled-system/jsx/float.d.ts +7 -0
  120. package/styled-system/jsx/float.js +11 -0
  121. package/styled-system/jsx/grid-item.d.ts +7 -0
  122. package/styled-system/jsx/grid-item.js +11 -0
  123. package/styled-system/jsx/grid.d.ts +7 -0
  124. package/styled-system/jsx/grid.js +11 -0
  125. package/styled-system/jsx/helper.d.ts +34 -0
  126. package/styled-system/jsx/helper.js +83 -0
  127. package/styled-system/jsx/hstack.d.ts +7 -0
  128. package/styled-system/jsx/hstack.js +11 -0
  129. package/styled-system/jsx/index.d.ts +25 -0
  130. package/styled-system/jsx/index.js +24 -0
  131. package/styled-system/jsx/is-valid-prop.d.ts +7 -0
  132. package/styled-system/jsx/is-valid-prop.js +12 -0
  133. package/styled-system/jsx/link-overlay.d.ts +7 -0
  134. package/styled-system/jsx/link-overlay.js +11 -0
  135. package/styled-system/jsx/spacer.d.ts +7 -0
  136. package/styled-system/jsx/spacer.js +11 -0
  137. package/styled-system/jsx/square.d.ts +7 -0
  138. package/styled-system/jsx/square.js +11 -0
  139. package/styled-system/jsx/stack.d.ts +7 -0
  140. package/styled-system/jsx/stack.js +11 -0
  141. package/styled-system/jsx/visually-hidden.d.ts +7 -0
  142. package/styled-system/jsx/visually-hidden.js +11 -0
  143. package/styled-system/jsx/vstack.d.ts +7 -0
  144. package/styled-system/jsx/vstack.js +11 -0
  145. package/styled-system/jsx/wrap.d.ts +7 -0
  146. package/styled-system/jsx/wrap.js +11 -0
  147. package/styled-system/patterns/aspect-ratio.d.ts +19 -0
  148. package/styled-system/patterns/aspect-ratio.js +37 -0
  149. package/styled-system/patterns/bleed.d.ts +20 -0
  150. package/styled-system/patterns/bleed.js +30 -0
  151. package/styled-system/patterns/box.d.ts +17 -0
  152. package/styled-system/patterns/box.js +16 -0
  153. package/styled-system/patterns/center.d.ts +19 -0
  154. package/styled-system/patterns/center.js +22 -0
  155. package/styled-system/patterns/circle.d.ts +19 -0
  156. package/styled-system/patterns/circle.js +26 -0
  157. package/styled-system/patterns/container.d.ts +17 -0
  158. package/styled-system/patterns/container.js +26 -0
  159. package/styled-system/patterns/cq.d.ts +21 -0
  160. package/styled-system/patterns/cq.js +24 -0
  161. package/styled-system/patterns/divider.d.ts +22 -0
  162. package/styled-system/patterns/divider.js +31 -0
  163. package/styled-system/patterns/flex.d.ts +25 -0
  164. package/styled-system/patterns/flex.js +27 -0
  165. package/styled-system/patterns/float.d.ts +23 -0
  166. package/styled-system/patterns/float.js +84 -0
  167. package/styled-system/patterns/grid-item.d.ts +24 -0
  168. package/styled-system/patterns/grid-item.js +26 -0
  169. package/styled-system/patterns/grid.d.ts +24 -0
  170. package/styled-system/patterns/grid.js +30 -0
  171. package/styled-system/patterns/hstack.d.ts +20 -0
  172. package/styled-system/patterns/hstack.js +27 -0
  173. package/styled-system/patterns/index.d.ts +20 -0
  174. package/styled-system/patterns/index.js +20 -0
  175. package/styled-system/patterns/link-overlay.d.ts +17 -0
  176. package/styled-system/patterns/link-overlay.js +25 -0
  177. package/styled-system/patterns/runtime.js +25 -0
  178. package/styled-system/patterns/spacer.d.ts +20 -0
  179. package/styled-system/patterns/spacer.js +26 -0
  180. package/styled-system/patterns/square.d.ts +19 -0
  181. package/styled-system/patterns/square.js +25 -0
  182. package/styled-system/patterns/stack.d.ts +22 -0
  183. package/styled-system/patterns/stack.js +30 -0
  184. package/styled-system/patterns/visually-hidden.d.ts +17 -0
  185. package/styled-system/patterns/visually-hidden.js +19 -0
  186. package/styled-system/patterns/vstack.d.ts +20 -0
  187. package/styled-system/patterns/vstack.js +27 -0
  188. package/styled-system/patterns/wrap.d.ts +23 -0
  189. package/styled-system/patterns/wrap.js +26 -0
  190. package/styled-system/recipes/alert.d.ts +19 -0
  191. package/styled-system/recipes/alert.js +5 -0
  192. package/styled-system/recipes/avatar.d.ts +19 -0
  193. package/styled-system/recipes/avatar.js +5 -0
  194. package/styled-system/recipes/badge.d.ts +18 -0
  195. package/styled-system/recipes/badge.js +5 -0
  196. package/styled-system/recipes/button.d.ts +20 -0
  197. package/styled-system/recipes/button.js +5 -0
  198. package/styled-system/recipes/card.d.ts +19 -0
  199. package/styled-system/recipes/card.js +5 -0
  200. package/styled-system/recipes/chat-bubble.d.ts +16 -0
  201. package/styled-system/recipes/chat-bubble.js +5 -0
  202. package/styled-system/recipes/checkbox.d.ts +16 -0
  203. package/styled-system/recipes/checkbox.js +5 -0
  204. package/styled-system/recipes/dialog.d.ts +18 -0
  205. package/styled-system/recipes/dialog.js +5 -0
  206. package/styled-system/recipes/field.d.ts +16 -0
  207. package/styled-system/recipes/field.js +5 -0
  208. package/styled-system/recipes/index.d.ts +27 -0
  209. package/styled-system/recipes/index.js +27 -0
  210. package/styled-system/recipes/input.d.ts +18 -0
  211. package/styled-system/recipes/input.js +5 -0
  212. package/styled-system/recipes/link.d.ts +18 -0
  213. package/styled-system/recipes/link.js +5 -0
  214. package/styled-system/recipes/pagination.d.ts +19 -0
  215. package/styled-system/recipes/pagination.js +5 -0
  216. package/styled-system/recipes/progress.d.ts +18 -0
  217. package/styled-system/recipes/progress.js +5 -0
  218. package/styled-system/recipes/prose.d.ts +16 -0
  219. package/styled-system/recipes/prose.js +5 -0
  220. package/styled-system/recipes/radio-group.d.ts +18 -0
  221. package/styled-system/recipes/radio-group.js +5 -0
  222. package/styled-system/recipes/runtime.js +133 -0
  223. package/styled-system/recipes/select-panel.d.ts +18 -0
  224. package/styled-system/recipes/select-panel.js +5 -0
  225. package/styled-system/recipes/select.d.ts +18 -0
  226. package/styled-system/recipes/select.js +5 -0
  227. package/styled-system/recipes/separator.d.ts +16 -0
  228. package/styled-system/recipes/separator.js +5 -0
  229. package/styled-system/recipes/skeleton.d.ts +14 -0
  230. package/styled-system/recipes/skeleton.js +5 -0
  231. package/styled-system/recipes/spinner.d.ts +16 -0
  232. package/styled-system/recipes/spinner.js +5 -0
  233. package/styled-system/recipes/switch-recipe.d.ts +16 -0
  234. package/styled-system/recipes/switch-recipe.js +5 -0
  235. package/styled-system/recipes/table.d.ts +20 -0
  236. package/styled-system/recipes/table.js +5 -0
  237. package/styled-system/recipes/tabs.d.ts +18 -0
  238. package/styled-system/recipes/tabs.js +5 -0
  239. package/styled-system/recipes/tag.d.ts +18 -0
  240. package/styled-system/recipes/tag.js +5 -0
  241. package/styled-system/recipes/textarea.d.ts +14 -0
  242. package/styled-system/recipes/textarea.js +5 -0
  243. package/styled-system/recipes/toast.d.ts +20 -0
  244. package/styled-system/recipes/toast.js +5 -0
  245. package/styled-system/recipes/tooltip.d.ts +16 -0
  246. package/styled-system/recipes/tooltip.js +5 -0
  247. package/styled-system/tokens/index.d.ts +8 -0
  248. package/styled-system/tokens/index.js +18 -0
  249. package/styled-system/types/index.d.ts +5 -0
  250. package/styled-system/types/jsx.d.ts +80 -0
  251. package/styled-system/types/pattern.d.ts +26 -0
  252. package/styled-system/types/recipe.d.ts +77 -0
  253. package/styled-system/types/system.d.ts +1645 -0
  254. package/styled-system/types/tokens.d.ts +47 -0
@@ -0,0 +1,23 @@
1
+ import { type ToastApi, type ToastOwnProps, type ToastProviderOwnProps } from '@tuuject/koi-core';
2
+ import { type ToastSlot } from '@tuuject/koi-react/styled-system/recipes';
3
+ import { type HTMLAttributes } from 'react';
4
+ import type { SlotClassNames } from '../types.js';
5
+ export type { ToastOptions, ToastTone } from '@tuuject/koi-core';
6
+ export interface ToastProps extends ToastOwnProps, Omit<HTMLAttributes<HTMLDivElement>, keyof ToastOwnProps> {
7
+ classNames?: SlotClassNames<Exclude<ToastSlot, 'viewport'>>;
8
+ }
9
+ export interface ToastProviderProps extends ToastProviderOwnProps {
10
+ }
11
+ /**
12
+ * A toast on its own, outside ToastProvider (the provider renders the same thing). Error is role="alert", the
13
+ * other tones role="status".
14
+ */
15
+ export declare function Toast({ tone, title, description, action, onClose, className, classNames, ...rest }: ToastProps): import("react").JSX.Element;
16
+ /**
17
+ * Wrap the app once; then call `useToast().toast({...})` anywhere inside. Base UI's toast manager does the timing
18
+ * (paused while the stack is hovered or focused, or the window is in the background), swipe-to-dismiss, F6 to
19
+ * reach the toasts from the keyboard, and the screen reader announcements.
20
+ */
21
+ export declare function ToastProvider({ children, position }: ToastProviderProps): import("react").JSX.Element;
22
+ /** `toast(options)` shows one and returns its id; `dismiss(id)` closes it. Only inside ToastProvider. */
23
+ export declare function useToast(): ToastApi;
@@ -0,0 +1,80 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Toast as BaseToast } from '@base-ui/react/toast';
3
+ import { strings, TOAST_DURATION, TOAST_LIMIT, } from '@tuuject/koi-core';
4
+ import { cx } from '@tuuject/koi-react/styled-system/css';
5
+ import { toast as toastRecipe } from '@tuuject/koi-react/styled-system/recipes';
6
+ import { createContext, useContext, useEffect, useMemo, useRef } from 'react';
7
+ import { CloseIcon, ErrorIcon, InfoIcon, SuccessIcon, WarningIcon } from '../icons.js';
8
+ const toneIcon = { info: InfoIcon, success: SuccessIcon, warning: WarningIcon, error: ErrorIcon };
9
+ /**
10
+ * A toast on its own, outside ToastProvider (the provider renders the same thing). Error is role="alert", the
11
+ * other tones role="status".
12
+ */
13
+ export function Toast({ tone = 'info', title, description, action, onClose, className, classNames, ...rest }) {
14
+ const s = toastRecipe({ tone, closable: !!onClose });
15
+ const Icon = toneIcon[tone] ?? InfoIcon;
16
+ return (_jsxs("div", { role: tone === 'error' ? 'alert' : 'status', ...rest, className: cx(s.root, className), children: [_jsx("span", { className: cx(s.icon, classNames?.icon), children: _jsx(Icon, {}) }), _jsxs("div", { className: cx(s.content, classNames?.content), children: [title ? _jsx("p", { className: cx(s.title, classNames?.title), children: title }) : null, description ? _jsx("p", { className: cx(s.description, classNames?.description), children: description }) : null] }), action ? _jsx("div", { className: cx(s.action, classNames?.action), children: action }) : null, onClose ? (_jsx("button", { type: "button", className: cx(s.close, classNames?.close), "aria-label": strings.close, title: strings.close, onClick: onClose, children: _jsx(CloseIcon, {}) })) : null] }));
17
+ }
18
+ const ToastContext = createContext(null);
19
+ /**
20
+ * Wrap the app once; then call `useToast().toast({...})` anywhere inside. Base UI's toast manager does the timing
21
+ * (paused while the stack is hovered or focused, or the window is in the background), swipe-to-dismiss, F6 to
22
+ * reach the toasts from the keyboard, and the screen reader announcements.
23
+ */
24
+ export function ToastProvider({ children, position = 'bottom' }) {
25
+ const s = toastRecipe({ position });
26
+ return (_jsxs(BaseToast.Provider, { limit: TOAST_LIMIT, timeout: TOAST_DURATION, children: [_jsx(ToastApiProvider, { children: children }), _jsx(BaseToast.Portal, { children: _jsx(BaseToast.Viewport, { "aria-label": strings.notifications, className: s.viewport, children: _jsx(ToastList, { position: position }) }) })] }));
27
+ }
28
+ // Talks to Base UI's store through the hook rather than a createToastManager() instance: the instance only hears
29
+ // calls once the provider has subscribed in its effect, which runs after the children's, so a toast() fired from a
30
+ // child's mount effect would be lost.
31
+ function ToastApiProvider({ children }) {
32
+ const { add, close } = BaseToast.useToastManager();
33
+ const seq = useRef(0);
34
+ const api = useMemo(() => ({
35
+ toast({ tone = 'info', title, description, action, duration }) {
36
+ const id = ++seq.current;
37
+ add({
38
+ id: String(id),
39
+ type: tone,
40
+ title,
41
+ description,
42
+ timeout: duration,
43
+ // Errors are announced right away (legacy: role="alert"); the rest wait their turn.
44
+ priority: tone === 'error' ? 'high' : 'low',
45
+ data: { action },
46
+ });
47
+ return id;
48
+ },
49
+ dismiss(id) {
50
+ close(String(id));
51
+ },
52
+ }), [add, close]);
53
+ return _jsx(ToastContext.Provider, { value: api, children: children });
54
+ }
55
+ function ToastList({ position }) {
56
+ const { toasts, close } = BaseToast.useToastManager();
57
+ // At most 4 at once, and the oldest goes for good (legacy). Base UI only marks the extras `limited` and brings
58
+ // them back when a newer one closes, so close them.
59
+ useEffect(() => {
60
+ for (const t of toasts) {
61
+ if (t.limited && t.transitionStatus !== 'ending') {
62
+ close(t.id);
63
+ }
64
+ }
65
+ }, [toasts, close]);
66
+ return toasts.map((t) => {
67
+ const tone = (t.type ?? 'info');
68
+ const s = toastRecipe({ tone, closable: true, position });
69
+ const Icon = toneIcon[tone] ?? InfoIcon;
70
+ return (_jsxs(BaseToast.Root, { toast: t, swipeDirection: [position === 'top' ? 'up' : 'down', 'left', 'right'], className: s.root, children: [_jsx("span", { className: s.icon, children: _jsx(Icon, {}) }), _jsxs("div", { className: s.content, children: [_jsx(BaseToast.Title, { className: s.title, render: _jsx("p", {}) }), _jsx(BaseToast.Description, { className: s.description })] }), t.data?.action ? _jsx("div", { className: s.action, children: t.data.action }) : null, _jsx(BaseToast.Close, { className: s.close, "aria-label": strings.close, title: strings.close, children: _jsx(CloseIcon, {}) })] }, t.id));
71
+ });
72
+ }
73
+ /** `toast(options)` shows one and returns its id; `dismiss(id)` closes it. Only inside ToastProvider. */
74
+ export function useToast() {
75
+ const api = useContext(ToastContext);
76
+ if (!api) {
77
+ throw new Error('useToast must be used inside <ToastProvider>');
78
+ }
79
+ return api;
80
+ }
@@ -0,0 +1,9 @@
1
+ import type { TooltipOwnProps } from '@tuuject/koi-core';
2
+ export type { TooltipSide } from '@tuuject/koi-core';
3
+ export interface TooltipProps extends TooltipOwnProps<Event> {
4
+ }
5
+ /**
6
+ * Inverted bubble naming or explaining its child, on hover and keyboard focus. Base UI handles the delays, focus,
7
+ * Esc, the portal and positioning (8px from the trigger, flipping near the viewport edge).
8
+ */
9
+ export declare function Tooltip({ content, children, side, open, defaultOpen, onOpenChange, delay, closeDelay, disabled, }: TooltipProps): import("react").JSX.Element;
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Tooltip as BaseTooltip } from '@base-ui/react/tooltip';
3
+ import { tooltip } from '@tuuject/koi-react/styled-system/recipes';
4
+ import { components } from '@tuuject/koi-tokens/dimensions';
5
+ import { Children, cloneElement, useId, useState } from 'react';
6
+ /**
7
+ * Inverted bubble naming or explaining its child, on hover and keyboard focus. Base UI handles the delays, focus,
8
+ * Esc, the portal and positioning (8px from the trigger, flipping near the viewport edge).
9
+ */
10
+ export function Tooltip({ content, children, side = 'top', open, defaultOpen, onOpenChange, delay = 0, closeDelay = 0, disabled, }) {
11
+ const s = tooltip();
12
+ const autoId = useId();
13
+ const popupId = `${autoId}tooltip`;
14
+ const child = Children.only(children);
15
+ const triggerId = child.props.id ?? `${autoId}trigger`;
16
+ // Base UI doesn't describe the trigger by the popup; the spec wants aria-describedby while it's shown.
17
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen ?? false);
18
+ const shown = open ?? uncontrolledOpen;
19
+ // Skip it when the tooltip only repeats the trigger's name (IconButton label="关闭" + content="关闭"), or it's read twice.
20
+ const repeatsName = typeof content === 'string' && (child.props['aria-label'] === content || child.props.label === content);
21
+ const describedBy = [child.props['aria-describedby'], shown && !repeatsName ? popupId : undefined].filter(Boolean).join(' ') ||
22
+ undefined;
23
+ // title: undefined drops the native tooltip (IconButton sets one from its label), so the two don't stack.
24
+ const trigger = cloneElement(child, { 'aria-describedby': describedBy, title: undefined });
25
+ return (_jsxs(BaseTooltip.Root, { open: open, defaultOpen: defaultOpen, triggerId: open === undefined ? undefined : triggerId, defaultTriggerId: defaultOpen ? triggerId : undefined, disabled: disabled, onOpenChange: (next, details) => {
26
+ setUncontrolledOpen(next);
27
+ onOpenChange?.(next, details);
28
+ }, children: [_jsx(BaseTooltip.Trigger, { id: triggerId, delay: delay, closeDelay: closeDelay, render: trigger }), _jsx(BaseTooltip.Portal, { children: _jsx(BaseTooltip.Positioner, { side: side, sideOffset: components.tooltip.offset, className: s.positioner, children: _jsx(BaseTooltip.Popup, { id: popupId, role: "tooltip", className: s.popup, children: content }) }) })] }));
29
+ }
@@ -0,0 +1,11 @@
1
+ import type { ChangeDetails as CoreChangeDetails } from '@tuuject/koi-core';
2
+ /**
3
+ * The second argument of Koi's change callbacks on the web: `ChangeDetails` from @tuuject/koi-core with a DOM `Event`.
4
+ * Base UI's own details object already satisfies it, so it's passed straight through (agent-doc/headless.md, rule 5).
5
+ */
6
+ export type ChangeDetails = CoreChangeDetails<Event>;
7
+ /**
8
+ * Extra classes for a component's inner elements, keyed by its recipe's slot names (`CardSlot`, …), so
9
+ * consumers can restyle parts that `className` can't reach. The root keeps `className`.
10
+ */
11
+ export type SlotClassNames<Slot extends string> = Partial<Record<Exclude<Slot, 'root'>, string>>;
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,221 @@
1
1
  {
2
2
  "name": "@tuuject/koi-react",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Koi components for React web: Base UI for behavior, Panda CSS v2 for styling.",
6
+ "sideEffects": false,
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ },
12
+ "./styled-system/*": "./styled-system/*/index.js",
13
+ "./alert": {
14
+ "types": "./dist/alert/Alert.d.ts",
15
+ "default": "./dist/alert/Alert.js"
16
+ },
17
+ "./avatar": {
18
+ "types": "./dist/avatar/Avatar.d.ts",
19
+ "default": "./dist/avatar/Avatar.js"
20
+ },
21
+ "./badge": {
22
+ "types": "./dist/badge/Badge.d.ts",
23
+ "default": "./dist/badge/Badge.js"
24
+ },
25
+ "./button": {
26
+ "types": "./dist/button/Button.d.ts",
27
+ "default": "./dist/button/Button.js"
28
+ },
29
+ "./card": {
30
+ "types": "./dist/card/Card.d.ts",
31
+ "default": "./dist/card/Card.js"
32
+ },
33
+ "./chat-bubble": {
34
+ "types": "./dist/chat-bubble/ChatBubble.d.ts",
35
+ "default": "./dist/chat-bubble/ChatBubble.js"
36
+ },
37
+ "./checkbox": {
38
+ "types": "./dist/checkbox/Checkbox.d.ts",
39
+ "default": "./dist/checkbox/Checkbox.js"
40
+ },
41
+ "./dialog": {
42
+ "types": "./dist/dialog/Dialog.d.ts",
43
+ "default": "./dist/dialog/Dialog.js"
44
+ },
45
+ "./divider": {
46
+ "types": "./dist/divider/Divider.d.ts",
47
+ "default": "./dist/divider/Divider.js"
48
+ },
49
+ "./field": {
50
+ "types": "./dist/field/Field.d.ts",
51
+ "default": "./dist/field/Field.js"
52
+ },
53
+ "./icons": {
54
+ "types": "./dist/icons.d.ts",
55
+ "default": "./dist/icons.js"
56
+ },
57
+ "./input": {
58
+ "types": "./dist/input/Input.d.ts",
59
+ "default": "./dist/input/Input.js"
60
+ },
61
+ "./link": {
62
+ "types": "./dist/link/Link.d.ts",
63
+ "default": "./dist/link/Link.js"
64
+ },
65
+ "./pagination": {
66
+ "types": "./dist/pagination/Pagination.d.ts",
67
+ "default": "./dist/pagination/Pagination.js"
68
+ },
69
+ "./progress": {
70
+ "types": "./dist/progress/Progress.d.ts",
71
+ "default": "./dist/progress/Progress.js"
72
+ },
73
+ "./prose": {
74
+ "types": "./dist/prose/Prose.d.ts",
75
+ "default": "./dist/prose/Prose.js"
76
+ },
77
+ "./radio-group": {
78
+ "types": "./dist/radio-group/RadioGroup.d.ts",
79
+ "default": "./dist/radio-group/RadioGroup.js"
80
+ },
81
+ "./select": {
82
+ "types": "./dist/select/Select.d.ts",
83
+ "default": "./dist/select/Select.js"
84
+ },
85
+ "./select-panel": {
86
+ "types": "./dist/select/SelectPanel.d.ts",
87
+ "default": "./dist/select/SelectPanel.js"
88
+ },
89
+ "./shape": {
90
+ "types": "./dist/shape.d.ts",
91
+ "default": "./dist/shape.js"
92
+ },
93
+ "./skeleton": {
94
+ "types": "./dist/skeleton/Skeleton.d.ts",
95
+ "default": "./dist/skeleton/Skeleton.js"
96
+ },
97
+ "./spinner": {
98
+ "types": "./dist/spinner/Spinner.d.ts",
99
+ "default": "./dist/spinner/Spinner.js"
100
+ },
101
+ "./switch": {
102
+ "types": "./dist/switch/Switch.d.ts",
103
+ "default": "./dist/switch/Switch.js"
104
+ },
105
+ "./table": {
106
+ "types": "./dist/table/Table.d.ts",
107
+ "default": "./dist/table/Table.js"
108
+ },
109
+ "./data-table": {
110
+ "types": "./dist/table/DataTable.d.ts",
111
+ "default": "./dist/table/DataTable.js"
112
+ },
113
+ "./tabs": {
114
+ "types": "./dist/tabs/Tabs.d.ts",
115
+ "default": "./dist/tabs/Tabs.js"
116
+ },
117
+ "./tag": {
118
+ "types": "./dist/tag/Tag.d.ts",
119
+ "default": "./dist/tag/Tag.js"
120
+ },
121
+ "./textarea": {
122
+ "types": "./dist/textarea/Textarea.d.ts",
123
+ "default": "./dist/textarea/Textarea.js"
124
+ },
125
+ "./toast": {
126
+ "types": "./dist/toast/Toast.d.ts",
127
+ "default": "./dist/toast/Toast.js"
128
+ },
129
+ "./tooltip": {
130
+ "types": "./dist/tooltip/Tooltip.d.ts",
131
+ "default": "./dist/tooltip/Tooltip.js"
132
+ },
133
+ "./package.json": "./package.json",
134
+ "./panda/*": "./dist/panda/*",
135
+ "./css": {
136
+ "types": "./styled-system/css/index.d.ts",
137
+ "default": "./styled-system/css/index.js"
138
+ },
139
+ "./css/*": {
140
+ "types": "./styled-system/css/*.d.ts",
141
+ "default": "./styled-system/css/*.js"
142
+ },
143
+ "./recipes": {
144
+ "types": "./styled-system/recipes/index.d.ts",
145
+ "default": "./styled-system/recipes/index.js"
146
+ },
147
+ "./recipes/*": {
148
+ "types": "./styled-system/recipes/*.d.ts",
149
+ "default": "./styled-system/recipes/*.js"
150
+ },
151
+ "./patterns": {
152
+ "types": "./styled-system/patterns/index.d.ts",
153
+ "default": "./styled-system/patterns/index.js"
154
+ },
155
+ "./patterns/*": {
156
+ "types": "./styled-system/patterns/*.d.ts",
157
+ "default": "./styled-system/patterns/*.js"
158
+ },
159
+ "./jsx": {
160
+ "types": "./styled-system/jsx/index.d.ts",
161
+ "default": "./styled-system/jsx/index.js"
162
+ },
163
+ "./jsx/*": {
164
+ "types": "./styled-system/jsx/*.d.ts",
165
+ "default": "./styled-system/jsx/*.js"
166
+ },
167
+ "./tokens": {
168
+ "types": "./styled-system/tokens/index.d.ts",
169
+ "default": "./styled-system/tokens/index.js"
170
+ },
171
+ "./helpers": {
172
+ "types": "./styled-system/helpers.d.ts",
173
+ "default": "./styled-system/helpers.js"
174
+ },
175
+ "./types": {
176
+ "types": "./styled-system/types/index.d.ts"
177
+ }
178
+ },
179
+ "files": [
180
+ "dist",
181
+ "styled-system"
182
+ ],
183
+ "publishConfig": {
184
+ "access": "public"
185
+ },
186
+ "dependencies": {
187
+ "@base-ui/react": "^1.8.0",
188
+ "@iconify-icons/fa7-solid": "^2.0.0",
189
+ "@tuuject/koi-tokens": "0.1.0",
190
+ "@tuuject/koi-core": "0.1.0"
191
+ },
192
+ "peerDependencies": {
193
+ "@pandacss/dev": "~2.1.2",
194
+ "react": "^19.0.0",
195
+ "react-dom": "^19.0.0"
196
+ },
197
+ "peerDependenciesMeta": {
198
+ "@pandacss/dev": {
199
+ "optional": true
200
+ }
201
+ },
202
+ "devDependencies": {
203
+ "@types/react": "^19.3.0",
204
+ "@types/react-dom": "^19.3.0",
205
+ "react": "^19.3.0",
206
+ "react-dom": "^19.3.0",
207
+ "typescript": "^7.0.2"
208
+ },
209
+ "repository": {
210
+ "type": "git",
211
+ "url": "git+https://github.com/tuuject/design.git",
212
+ "directory": "packages/react"
213
+ },
214
+ "homepage": "https://github.com/tuuject/design#readme",
215
+ "license": "MIT",
216
+ "scripts": {
217
+ "build": "panda codegen --clean && tsc -p tsconfig.build.json && pnpm run lib",
218
+ "lib": "panda lib --files './**/*.js' && node ../../scripts/sync-publish-exports.mjs .",
219
+ "typecheck": "tsc -p tsconfig.json"
220
+ }
6
221
  }
@@ -0,0 +1,7 @@
1
+ export declare const breakpointKeys: string[];
2
+
3
+ export declare function isCondition(v: string): boolean;
4
+
5
+ export declare function finalizeConditions(paths: string[]): string[];
6
+
7
+ export declare function sortConditions(paths: string[]): string[];
@@ -0,0 +1,32 @@
1
+ import { withoutSpace } from '../helpers';
2
+
3
+ const conditions = /* @__PURE__ */ new Set(/* @__PURE__ */ "_active,_after,_anyPointerCoarse,_anyPointerFine,_anyPointerNone,_atValue,_autofill,_backdrop,_before,_checked,_closed,_complete,_current,_currentPage,_currentStep,_dark,_default,_disabled,_dragging,_empty,_enabled,_even,_expanded,_file,_first,_firstLetter,_firstLine,_firstOfType,_focus,_focusVisible,_focusWithin,_fontChill,_fullscreen,_grabbed,_groupActive,_groupChecked,_groupDisabled,_groupExpanded,_groupFocus,_groupFocusVisible,_groupFocusWithin,_groupHover,_groupInvalid,_hidden,_highContrast,_highlighted,_horizontal,_hover,_icon,_inRange,_incomplete,_indeterminate,_inert,_invalid,_invertedColors,_landscape,_last,_lastOfType,_lessContrast,_light,_loading,_ltr,_marker,_moreContrast,_motionReduce,_motionSafe,_noscript,_now,_odd,_only,_onlyOfType,_open,_optional,_osDark,_osLight,_outOfRange,_overValue,_paletteRose,_peerActive,_peerChecked,_peerDisabled,_peerExpanded,_peerFocus,_peerFocusVisible,_peerFocusWithin,_peerHover,_peerInvalid,_peerPlaceholderShown,_placeholder,_placeholderShown,_pointerCoarse,_pointerFine,_pointerNone,_portrait,_pressed,_print,_rangeEnd,_rangeStart,_readOnly,_readWrite,_required,_rtl,_scrollbar,_scrollbarThumb,_scrollbarTrack,_selected,_selection,_starting,_target,_today,_topmost,_unavailable,_underValue,_userInvalid,_userValid,_valid,_vertical,_visited,base,md,mdDown,mdOnly".split(','))
4
+ const conditionRe = /^@|&/
5
+ const underscoreRe = /^_/
6
+ const selectorRe = /&|@/
7
+
8
+ export const breakpointKeys = ["base","md"]
9
+
10
+ export function isCondition(v) {
11
+ return conditions.has(v) || conditionRe.test(v)
12
+ }
13
+
14
+ export function finalizeConditions(paths) {
15
+ return paths.map((p) => {
16
+ if (conditions.has(p)) {
17
+ return p.replace(underscoreRe, '')
18
+ }
19
+ if (selectorRe.test(p)) {
20
+ return `[${withoutSpace(p.trim())}]`
21
+ }
22
+ return p
23
+ })
24
+ }
25
+
26
+ export function sortConditions(paths) {
27
+ return [...paths].sort((a, b) => {
28
+ const aa = isCondition(a)
29
+ const bb = isCondition(b)
30
+ return aa && !bb ? 1 : !aa && bb ? -1 : 0
31
+ })
32
+ }
@@ -0,0 +1,22 @@
1
+ import type { SystemStyleObject } from '../types/system';
2
+
3
+ type Styles = SystemStyleObject | undefined | null | false
4
+ type StyleList = Styles | StyleList[]
5
+
6
+ interface CssRawFunction {
7
+ (styles: Styles): SystemStyleObject
8
+ (styles: StyleList[]): SystemStyleObject
9
+ (...styles: StyleList[]): SystemStyleObject
10
+ (styles: Styles): SystemStyleObject
11
+ }
12
+
13
+ interface CssFunction {
14
+ (styles: Styles): string
15
+ (styles: StyleList[]): string
16
+ (...styles: StyleList[]): string
17
+ (styles: Styles): string
18
+
19
+ raw: CssRawFunction
20
+ }
21
+
22
+ export declare const css: CssFunction;
@@ -0,0 +1,63 @@
1
+ import { createAssignCss, createMergeCss, createSerializeCss, createSerializeCssArgs, hypenateProperty, isObject, withoutSpace } from '../helpers';
2
+ import { breakpointKeys, finalizeConditions, sortConditions } from './conditions';
3
+
4
+ const utilities = "WebkitTextFillColor:wktf-c,accentColor:ac-c,alignContent:ac,alignItems:ai,alignSelf:as,animation:anim,animationComposition:anim-comp,animationDelay:anim-dly,animationDirection:anim-dir,animationDuration:anim-dur,animationFillMode:anim-fm,animationIterationCount:anim-ic,animationName:anim-n,animationPlayState:anim-ps,animationRange:anim-r,animationRangeEnd:anim-re,animationRangeStart:anim-rs,animationState:anim-s,animationTimeline:anim-tl,animationTimingFunction:anim-tmf,appearance:ap,aspectRatio:asp,backdropBlur:bkdp-blur,backdropBrightness:bkdp-brightness,backdropContrast:bkdp-contrast,backdropFilter:bkdp,backdropGrayscale:bkdp-grayscale,backdropHueRotate:bkdp-hue-rotate,backdropInvert:bkdp-invert,backdropOpacity:bkdp-opacity,backdropSaturate:bkdp-saturate,backdropSepia:bkdp-sepia,backfaceVisibility:bfv,background:bg/1,backgroundAttachment:bg-a/bgAttachment,backgroundBlendMode:bg-bm/bgBlendMode,backgroundClip:bg-cp/bgClip,backgroundColor:bg-c/bgColor,backgroundConic:bg-conic/bgConic,backgroundGradient:bg-grad/bgGradient,backgroundImage:bg-i/bgImage,backgroundLinear:bg-linear/bgLinear,backgroundOrigin:bg-o/bgOrigin,backgroundPosition:bg-p/bgPosition,backgroundPositionX:bg-p-x/bgPositionX,backgroundPositionY:bg-p-y/bgPositionY,backgroundRadial:bg-radial/bgRadial,backgroundRepeat:bg-r/bgRepeat,backgroundSize:bg-s/bgSize,blockSize:h-bs,border:bd,borderBlock:bd-y/borderY,borderBlockColor:bd-y-c/borderYColor,borderBlockEnd:bd-be,borderBlockEndColor:bd-be-c,borderBlockEndWidth:bd-be-w,borderBlockStart:bd-bs,borderBlockStartColor:bd-bs-c,borderBlockStartWidth:bd-bs-w,borderBlockWidth:bd-y-w/borderYWidth,borderBottom:bd-b,borderBottomColor:bd-b-c,borderBottomLeftRadius:bdr-bl/roundedBottomLeft,borderBottomRadius:bdr-b/roundedBottom,borderBottomRightRadius:bdr-br/roundedBottomRight,borderBottomWidth:bd-b-w,borderCollapse:bd-cl,borderColor:bd-c,borderEndEndRadius:bdr-ee/roundedEndEnd,borderEndRadius:bdr-e/roundedEnd,borderEndStartRadius:bdr-es/roundedEndStart,borderInline:bd-x/borderX,borderInlineColor:bd-x-c/borderXColor,borderInlineEnd:bd-e/borderEnd,borderInlineEndColor:bd-e-c/borderEndColor,borderInlineEndWidth:bd-e-w/borderEndWidth,borderInlineStart:bd-s/borderStart,borderInlineStartColor:bd-s-c/borderStartColor,borderInlineStartWidth:bd-s-w/borderStartWidth,borderInlineWidth:bd-x-w/borderXWidth,borderLeft:bd-l,borderLeftColor:bd-l-c,borderLeftRadius:bdr-l/roundedLeft,borderLeftWidth:bd-l-w,borderRadius:bdr/rounded,borderRight:bd-r,borderRightColor:bd-r-c,borderRightRadius:bdr-r/roundedRight,borderRightWidth:bd-r-w,borderSpacing:bd-sp,borderSpacingX:bd-sx,borderSpacingY:bd-sy,borderStartEndRadius:bdr-se/roundedStartEnd,borderStartRadius:bdr-s/roundedStart,borderStartStartRadius:bdr-ss/roundedStartStart,borderTop:bd-t,borderTopColor:bd-t-c,borderTopLeftRadius:bdr-tl/roundedTopLeft,borderTopRadius:bdr-t/roundedTop,borderTopRightRadius:bdr-tr/roundedTopRight,borderTopWidth:bd-t-w,borderWidth:bd-w,boxDecorationBreak:bx-db,boxShadow:bx-sh/shadow,boxShadowColor:bx-sh-c/shadowColor,boxSize:size,boxSizing:bx-s,caretColor:ca-c,clipPath:cp-path,color:c,columnGap:cg,container:cq,containerName:cq-n,containerType:cq-t,display:d,divideColor:dvd-c,divideStyle:dvd-s,divideX:dvd-x,divideY:dvd-y,flexBasis:flex-b,flexDirection:flex-d/flexDir,flexGrow:flex-g,flexShrink:flex-sh,focusRingColor:focus-ring-c,focusRingOffset:focus-ring-o,focusRingStyle:focus-ring-s,focusRingWidth:focus-ring-w,focusVisibleRing:focus-v-ring,fontFamily:ff,fontFeatureSettings:ff-s,fontKerning:fk,fontPalette:fp,fontSize:fs,fontSizeAdjust:fs-a,fontSmoothing:fsmt,fontVariant:fv,fontVariantAlternates:fv-alt,fontVariantCaps:fv-caps,fontVariantNumeric:fv-num,fontVariationSettings:fv-s,fontWeight:fw,gradientFrom:grad-from,gradientFromPosition:grad-from-pos,gradientTo:grad-to,gradientToPosition:grad-to-pos,gradientVia:grad-via,gradientViaPosition:grad-via-pos,gridAutoColumns:grid-ac,gridAutoFlow:grid-af,gridAutoRows:grid-ar,gridColumn:grid-c,gridColumnEnd:grid-ce,gridColumnGap:grid-cg,gridColumnStart:grid-cs,gridGap:grid-g,gridRow:grid-r,gridRowGap:grid-rg,gridTemplateColumns:grid-tc,gridTemplateRows:grid-tr,height:h/1,hideBelow:show,hideFrom:hide,hyphens:hy,inlineSize:w-is,insetBlock:inset-y/insetY,insetBlockEnd:inset-be,insetBlockStart:inset-bs,insetInline:inset-x/insetX,insetInlineEnd:inset-e/end/insetEnd,insetInlineStart:inset-s/insetStart/start,justifyContent:jc,letterSpacing:ls,lineClamp:lc,lineHeight:lh,listStyle:li-s,listStyleImage:li-img,listStylePosition:li-pos,listStyleType:li-t,margin:m/1,marginBlock:my/marginY/1,marginBlockEnd:mbe,marginBlockStart:mbs,marginBottom:mb/1,marginInline:mx/marginX/1,marginInlineEnd:me/marginEnd/1,marginInlineStart:ms/marginStart/1,marginLeft:ml/1,marginRight:mr/1,marginTop:mt/1,mask:msk,maskBottomFrom:msk-b-from,maskBottomFromColor:msk-b-from-c,maskBottomTo:msk-b-to,maskBottomToColor:msk-b-to-c,maskClip:msk-cp,maskComposite:msk-cmp,maskConic:msk-conic,maskConicFrom:msk-conic-from,maskConicFromColor:msk-conic-from-c,maskConicTo:msk-conic-to,maskConicToColor:msk-conic-to-c,maskImage:msk-i,maskLeftFrom:msk-l-from,maskLeftFromColor:msk-l-from-c,maskLeftTo:msk-l-to,maskLeftToColor:msk-l-to-c,maskLinear:msk-linear,maskLinearFrom:msk-linear-from,maskLinearFromColor:msk-linear-from-c,maskLinearTo:msk-linear-to,maskLinearToColor:msk-linear-to-c,maskMode:msk-md,maskOrigin:msk-o,maskPosition:msk-p,maskRadial:msk-radial,maskRadialAt:msk-radial-at,maskRadialFrom:msk-radial-from,maskRadialFromColor:msk-radial-from-c,maskRadialShape:msk-radial-shape,maskRadialSize:msk-radial-sz,maskRadialTo:msk-radial-to,maskRadialToColor:msk-radial-to-c,maskRepeat:msk-r,maskRightFrom:msk-r-from,maskRightFromColor:msk-r-from-c,maskRightTo:msk-r-to,maskRightToColor:msk-r-to-c,maskSize:msk-s,maskTopFrom:msk-t-from,maskTopFromColor:msk-t-from-c,maskTopTo:msk-t-to,maskTopToColor:msk-t-to-c,maskType:msk-t,maskXFrom:msk-x-from,maskXFromColor:msk-x-from-c,maskXTo:msk-x-to,maskXToColor:msk-x-to-c,maskYFrom:msk-y-from,maskYFromColor:msk-y-from-c,maskYTo:msk-y-to,maskYToColor:msk-y-to-c,maxBlockSize:max-b,maxHeight:max-h/maxH,maxInlineSize:max-w-is,maxWidth:max-w/maxW,minBlockSize:min-h-bs,minHeight:min-h/minH,minInlineSize:min-w-is,minWidth:min-w/minW,mixBlendMode:mix-bm,objectFit:obj-f,objectPosition:obj-p,opacity:op,outline:ring/1,outlineColor:ring-c/ringColor,outlineOffset:ring-o/ringOffset,outlineWidth:ring-w/ringWidth,overflow:ov,overflowAnchor:ov-a,overflowBlock:ov-b,overflowClipBox:ovcp-bx,overflowClipMargin:ovcp-m,overflowInline:ov-i,overflowWrap:ov-wrap,overflowX:ov-x,overflowY:ov-y,overscrollBehavior:ovs-b,overscrollBehaviorBlock:ovs-bb,overscrollBehaviorInline:ovs-bi,overscrollBehaviorX:ovs-bx,overscrollBehaviorY:ovs-by,padding:p/1,paddingBlock:py/paddingY/1,paddingBlockEnd:pbe,paddingBlockStart:pbs,paddingBottom:pb/1,paddingInline:px/paddingX/1,paddingInlineEnd:pe/paddingEnd/1,paddingInlineStart:ps/paddingStart/1,paddingLeft:pl/1,paddingRight:pr/1,paddingTop:pt/1,position:pos/1,rowGap:rg,scrollBehavior:scr-bhv,scrollMargin:scr-m,scrollMarginBlock:scr-my/scrollMarginY,scrollMarginBlockEnd:scr-mbe,scrollMarginBlockStart:scr-mbt,scrollMarginBottom:scr-mb,scrollMarginInline:scr-mx/scrollMarginX,scrollMarginInlineEnd:scr-me,scrollMarginInlineStart:scr-ms,scrollMarginLeft:scr-ml,scrollMarginRight:scr-mr,scrollMarginTop:scr-mt,scrollPadding:scr-p,scrollPaddingBlock:scr-py/scrollPaddingY,scrollPaddingBlockEnd:scr-pbe,scrollPaddingBlockStart:scr-pbs,scrollPaddingBottom:scr-pb,scrollPaddingInline:scr-px/scrollPaddingX,scrollPaddingInlineEnd:scr-pe,scrollPaddingInlineStart:scr-ps,scrollPaddingLeft:scr-pl,scrollPaddingRight:scr-pr,scrollPaddingTop:scr-pt,scrollSnapAlign:scr-sa,scrollSnapCoordinate:scrs-c,scrollSnapDestination:scrs-d,scrollSnapMargin:scrs-m,scrollSnapMarginBottom:scrs-mb,scrollSnapMarginLeft:scrs-ml,scrollSnapMarginRight:scrs-mr,scrollSnapMarginTop:scrs-mt,scrollSnapPointsX:scrs-px,scrollSnapPointsY:scrs-py,scrollSnapStop:scrs-s,scrollSnapStrictness:scrs-strt,scrollSnapType:scrs-t,scrollSnapTypeX:scrs-tx,scrollSnapTypeY:scrs-ty,scrollTimeline:scrtl,scrollTimelineAxis:scrtl-a,scrollTimelineName:scrtl-n,scrollbar:scr-bar,scrollbarColor:scr-bar-c,scrollbarGutter:scr-bar-g,scrollbarThumb:scr-bar-th,scrollbarTrack:scr-bar-tk,scrollbarWidth:scr-bar-w,spaceX:sx,spaceY:sy,srOnly:sr,stroke:stk,strokeDasharray:stk-dsh,strokeDashoffset:stk-do,strokeLinecap:stk-lc,strokeLinejoin:stk-lj,strokeMiterlimit:stk-ml,strokeOpacity:stk-op,strokeWidth:stk-w,tableLayout:tbl,textAlign:ta,textDecoration:td,textDecorationColor:td-c,textDecorationStyle:td-s,textDecorationThickness:td-t,textEmphasisColor:te-c,textGradient:txt-grad,textIndent:ti,textOverflow:tov,textShadow:tsh,textShadowColor:tsh-c/textShadowColor,textSizeAdjust:txt-adj,textStyle:textStyle,textTransform:tt,textUnderlineOffset:tu-o,textWrap:tw,touchAction:tch-a,transform:trf,transformBox:trf-b,transformOrigin:trf-o,transformStyle:trf-s,transition:trs,transitionDelay:trs-dly,transitionDuration:trs-dur,transitionProperty:trs-prop,transitionTimingFunction:trs-tmf,translateX:/x,translateY:/y,translateZ:/z,truncate:trunc,userSelect:us,verticalAlign:va,visibility:vis,width:w/1,wordBreak:wb,zIndex:z"
5
+
6
+ function createCssContext() {
7
+ const classNameByProp = new Map()
8
+ const shorthands = new Map()
9
+ if (utilities) {
10
+ utilities.split(",").forEach((utility) => {
11
+ const [prop, meta] = utility.split(":")
12
+ const [className, ...shorthandList] = meta.split("/")
13
+ if (className) classNameByProp.set(prop, className)
14
+ shorthandList.forEach((shorthand) => {
15
+ const key = shorthand === "1" ? className : shorthand
16
+ shorthands.set(key, prop)
17
+ })
18
+ })
19
+ }
20
+
21
+ const resolveShorthand = (prop) => shorthands.get(prop) || prop
22
+
23
+ return {
24
+ hash: false,
25
+ conditions: {
26
+ shift: sortConditions,
27
+ finalize: finalizeConditions,
28
+ breakpoints: { keys: breakpointKeys },
29
+ },
30
+ utility: {
31
+ prefix: null,
32
+ hasShorthand: true,
33
+ toHash(path, hashFn) {
34
+ return hashFn(path.join(":"))
35
+ },
36
+ transform(prop, value) {
37
+ const key = resolveShorthand(prop)
38
+ const propKey = classNameByProp.get(key) || hypenateProperty(key)
39
+ return { className: `${propKey}_${withoutSpace(value)}` }
40
+ },
41
+ resolveShorthand,
42
+ },
43
+ }
44
+ }
45
+
46
+ const cssContext = /* @__PURE__ */ createCssContext()
47
+ const serializeCss = /* @__PURE__ */ createSerializeCss(cssContext)
48
+ export const mergeCss = /* @__PURE__ */ createMergeCss(cssContext)
49
+ const serializeCssArgs = /* @__PURE__ */ createSerializeCssArgs(serializeCss, mergeCss)
50
+
51
+ export const css = /* @__PURE__ */ Object.assign(
52
+ function css(...styles) {
53
+ if (styles.length === 1 && isObject(styles[0])) return serializeCss(styles[0])
54
+ return serializeCssArgs(...styles)
55
+ },
56
+ {
57
+ raw: function cssRaw(...styles) {
58
+ return mergeCss(...styles)
59
+ },
60
+ },
61
+ )
62
+
63
+ export const assignCss = /* @__PURE__ */ createAssignCss(cssContext)
@@ -0,0 +1,5 @@
1
+ import type { RecipeCreatorFn } from '../types/recipe';
2
+
3
+ export declare const cva: RecipeCreatorFn;
4
+
5
+ export { RecipeVariant, RecipeVariantProps } from '../types/recipe';
@@ -0,0 +1,51 @@
1
+ import { getCompoundVariantCss, memo, mergeProps, splitProps, toVariantMap, uniq, withDefaults } from '../helpers';
2
+ import { css, mergeCss } from './css';
3
+
4
+ export const cva = (config) => {
5
+ const defaults = (c) => ({ base: {}, variants: {}, defaultVariants: {}, compoundVariants: [], ...c })
6
+ const { base, variants, defaultVariants, compoundVariants } = defaults(config)
7
+
8
+ const getVariantProps = (props) => withDefaults(defaultVariants, props)
9
+
10
+ const resolve = (props = {}) => {
11
+ const computed = getVariantProps(props)
12
+ const styles = [base]
13
+ for (const key in computed) {
14
+ const value = computed[key]
15
+ if (variants[key]?.[value]) styles.push(variants[key][value])
16
+ }
17
+ styles.push(getCompoundVariantCss(compoundVariants, computed))
18
+ return mergeCss(...styles)
19
+ }
20
+
21
+ const variantKeys = Object.keys(variants)
22
+ const variantMap = toVariantMap(variants)
23
+ const resolveMemo = memo(resolve)
24
+
25
+ const merge = (other) => {
26
+ const override = defaults(other.config)
27
+ const keys = uniq(other.variantKeys, variantKeys)
28
+ return cva({
29
+ base: mergeCss(base, override.base),
30
+ variants: Object.fromEntries(keys.map((key) => [key, mergeCss(variants[key], override.variants[key])])),
31
+ defaultVariants: mergeProps(defaultVariants, override.defaultVariants),
32
+ compoundVariants: [...compoundVariants, ...override.compoundVariants],
33
+ })
34
+ }
35
+
36
+ return Object.assign(memo(function cvaFn(props) {
37
+ return css(resolve(props))
38
+ }), {
39
+ __cva__: true,
40
+ variantMap,
41
+ variantKeys,
42
+ raw: resolve,
43
+ __memoizedRaw__: resolveMemo,
44
+ config,
45
+ merge,
46
+ splitVariantProps(props) {
47
+ return splitProps(props, variantKeys)
48
+ },
49
+ getVariantProps,
50
+ })
51
+ }
@@ -0,0 +1,6 @@
1
+ type Argument = string | boolean | null | undefined;
2
+
3
+ /**
4
+ * Conditionally join classNames into a single string
5
+ */
6
+ export declare function cx(...args: Argument[]): string;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Conditionally join classNames into a single string
3
+ */
4
+ export function cx(...args) {
5
+ let str = '',
6
+ i = 0,
7
+ arg
8
+
9
+ for (; i < arguments.length; ) {
10
+ if ((arg = arguments[i++]) && typeof arg === 'string') {
11
+ str && (str += ' ')
12
+ str += arg
13
+ }
14
+ }
15
+ return str
16
+ }
@@ -0,0 +1,22 @@
1
+ export type FirstThatWorksMember = string | number;
2
+
3
+ export type FirstThatWorksMemberOf<T> = Extract<T, FirstThatWorksMember>;
4
+
5
+ export type FirstThatWorksFn = <
6
+ T = FirstThatWorksMember,
7
+ A extends FirstThatWorksMemberOf<T> = FirstThatWorksMemberOf<T>,
8
+ B extends FirstThatWorksMemberOf<T> = FirstThatWorksMemberOf<T>,
9
+ C extends FirstThatWorksMemberOf<T> = never,
10
+ D extends FirstThatWorksMemberOf<T> = never,
11
+ E extends FirstThatWorksMemberOf<T> = never,
12
+ F extends FirstThatWorksMemberOf<T> = never,
13
+ >(
14
+ first: A,
15
+ second: B,
16
+ third?: C,
17
+ fourth?: D,
18
+ fifth?: E,
19
+ sixth?: F,
20
+ ) => T extends FirstThatWorksMember ? A | B | C | D | E | F : FirstThatWorksMemberOf<T>;
21
+
22
+ export declare const firstThatWorks: FirstThatWorksFn;
@@ -0,0 +1 @@
1
+ export const firstThatWorks = (...values) => `firstThatWorks(${values.join(', ')})`
@@ -0,0 +1,8 @@
1
+ export * from './css';
2
+ export * from './cva';
3
+ export * from './cx';
4
+ export * from './sva';
5
+ export * from './view-transition';
6
+ export * from './position-try';
7
+ export * from './keyframes';
8
+ export * from './first-that-works';