@justanarthur/modo-ui 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 (172) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSE.beui +21 -0
  3. package/LICENSE.fluid-functionalism +21 -0
  4. package/LICENSE.motion-primitives +21 -0
  5. package/LICENSE.sileo +21 -0
  6. package/README.md +608 -2
  7. package/dist/base.css +994 -0
  8. package/dist/blocks/sidebar-app/index.d.ts +34 -0
  9. package/dist/blocks/sidebar-app/index.js +34 -0
  10. package/dist/components/badge/index.d.ts +59 -0
  11. package/dist/components/badge/index.js +18 -0
  12. package/dist/components/button/index.d.ts +59 -0
  13. package/dist/components/button/index.js +16 -0
  14. package/dist/components/card/index.d.ts +141 -0
  15. package/dist/components/card/index.js +44 -0
  16. package/dist/components/inputs/checkbox-group/index.d.ts +50 -0
  17. package/dist/components/inputs/checkbox-group/index.js +23 -0
  18. package/dist/components/inputs/color-picker/index.d.ts +137 -0
  19. package/dist/components/inputs/color-picker/index.js +37 -0
  20. package/dist/components/inputs/combobox/index.d.ts +161 -0
  21. package/dist/components/inputs/combobox/index.js +41 -0
  22. package/dist/components/inputs/date-time/calendar/index.d.ts +45 -0
  23. package/dist/components/inputs/date-time/calendar/index.js +20 -0
  24. package/dist/components/inputs/date-time/date-picker/index.d.ts +82 -0
  25. package/dist/components/inputs/date-time/date-picker/index.js +34 -0
  26. package/dist/components/inputs/date-time/date-range-picker/index.d.ts +64 -0
  27. package/dist/components/inputs/date-time/date-range-picker/index.js +33 -0
  28. package/dist/components/inputs/date-time/duration-picker/index.d.ts +57 -0
  29. package/dist/components/inputs/date-time/duration-picker/index.js +33 -0
  30. package/dist/components/inputs/date-time/month-picker/index.d.ts +57 -0
  31. package/dist/components/inputs/date-time/month-picker/index.js +32 -0
  32. package/dist/components/inputs/date-time/time-picker/index.d.ts +59 -0
  33. package/dist/components/inputs/date-time/time-picker/index.js +33 -0
  34. package/dist/components/inputs/input/index.d.ts +84 -0
  35. package/dist/components/inputs/input/index.js +20 -0
  36. package/dist/components/inputs/input-copy/index.d.ts +44 -0
  37. package/dist/components/inputs/input-copy/index.js +18 -0
  38. package/dist/components/inputs/input-message/index.d.ts +125 -0
  39. package/dist/components/inputs/input-message/index.js +27 -0
  40. package/dist/components/inputs/radio-group/index.d.ts +58 -0
  41. package/dist/components/inputs/radio-group/index.js +22 -0
  42. package/dist/components/inputs/search/index.d.ts +83 -0
  43. package/dist/components/inputs/search/index.js +28 -0
  44. package/dist/components/inputs/select/index.d.ts +105 -0
  45. package/dist/components/inputs/select/index.js +37 -0
  46. package/dist/components/inputs/slider/index.d.ts +108 -0
  47. package/dist/components/inputs/slider/index.js +16 -0
  48. package/dist/components/inputs/switch/index.d.ts +43 -0
  49. package/dist/components/inputs/switch/index.js +16 -0
  50. package/dist/components/navigation/accordion/index.d.ts +117 -0
  51. package/dist/components/navigation/accordion/index.js +30 -0
  52. package/dist/components/navigation/sidebar/index.d.ts +388 -0
  53. package/dist/components/navigation/sidebar/index.js +101 -0
  54. package/dist/components/navigation/tabs/index.d.ts +70 -0
  55. package/dist/components/navigation/tabs/index.js +25 -0
  56. package/dist/components/navigation/tabs-subtle/index.d.ts +73 -0
  57. package/dist/components/navigation/tabs-subtle/index.js +23 -0
  58. package/dist/components/overlays/alert-dialog/index.d.ts +67 -0
  59. package/dist/components/overlays/alert-dialog/index.js +24 -0
  60. package/dist/components/overlays/command/index.d.ts +121 -0
  61. package/dist/components/overlays/command/index.js +39 -0
  62. package/dist/components/overlays/context-menu/index.d.ts +97 -0
  63. package/dist/components/overlays/context-menu/index.js +32 -0
  64. package/dist/components/overlays/dialog/index.d.ts +130 -0
  65. package/dist/components/overlays/dialog/index.js +39 -0
  66. package/dist/components/overlays/dropdown/index.d.ts +222 -0
  67. package/dist/components/overlays/dropdown/index.js +47 -0
  68. package/dist/components/overlays/popover/index.d.ts +87 -0
  69. package/dist/components/overlays/popover/index.js +28 -0
  70. package/dist/components/overlays/preview-card/index.d.ts +75 -0
  71. package/dist/components/overlays/preview-card/index.js +21 -0
  72. package/dist/components/overlays/sheet/index.d.ts +67 -0
  73. package/dist/components/overlays/sheet/index.js +26 -0
  74. package/dist/components/overlays/toast/index.d.ts +107 -0
  75. package/dist/components/overlays/toast/index.js +23 -0
  76. package/dist/components/overlays/tooltip/index.d.ts +75 -0
  77. package/dist/components/overlays/tooltip/index.js +19 -0
  78. package/dist/components/table/index.d.ts +44 -0
  79. package/dist/components/table/index.js +28 -0
  80. package/dist/components/thinking-indicator/index.d.ts +32 -0
  81. package/dist/components/thinking-indicator/index.js +15 -0
  82. package/dist/index.d.ts +3926 -0
  83. package/dist/index.js +513 -0
  84. package/dist/preset.d.ts +104 -0
  85. package/dist/preset.js +124 -0
  86. package/dist/primitives/code/index.d.ts +23 -0
  87. package/dist/primitives/code/index.js +12 -0
  88. package/dist/primitives/craft/index.d.ts +31 -0
  89. package/dist/primitives/craft/index.js +13 -0
  90. package/dist/primitives/fluid-hover/index.d.ts +233 -0
  91. package/dist/primitives/fluid-hover/index.js +27 -0
  92. package/dist/primitives/morph/index.d.ts +127 -0
  93. package/dist/primitives/morph/index.js +21 -0
  94. package/dist/primitives/motion/index.d.ts +115 -0
  95. package/dist/primitives/motion/index.js +20 -0
  96. package/dist/primitives/scroll-area/index.d.ts +41 -0
  97. package/dist/primitives/scroll-area/index.js +13 -0
  98. package/dist/primitives/sizes/index.d.ts +128 -0
  99. package/dist/primitives/sizes/index.js +22 -0
  100. package/dist/primitives/surface/index.d.ts +69 -0
  101. package/dist/primitives/surface/index.js +18 -0
  102. package/dist/shared/components-0f0as45n.js +17 -0
  103. package/dist/shared/components-40j34hdb.js +986 -0
  104. package/dist/shared/components-4hh0gm0v.js +292 -0
  105. package/dist/shared/components-4xxddc44.js +15 -0
  106. package/dist/shared/components-4xxtggzp.js +110 -0
  107. package/dist/shared/components-54nf2x99.js +293 -0
  108. package/dist/shared/components-5pkcfprd.js +232 -0
  109. package/dist/shared/components-5vxtcp88.js +9 -0
  110. package/dist/shared/components-5zry9te1.js +152 -0
  111. package/dist/shared/components-61ckf42z.js +220 -0
  112. package/dist/shared/components-6hzwfmfd.js +58 -0
  113. package/dist/shared/components-6phwsry6.js +361 -0
  114. package/dist/shared/components-6t6nr33r.js +86 -0
  115. package/dist/shared/components-6y1th6k4.js +111 -0
  116. package/dist/shared/components-74c20v2f.js +32 -0
  117. package/dist/shared/components-7cqq1sqy.js +193 -0
  118. package/dist/shared/components-7gv95yfy.js +496 -0
  119. package/dist/shared/components-7nww01w4.js +375 -0
  120. package/dist/shared/components-7zp99w5d.js +62 -0
  121. package/dist/shared/components-8hk9ve3r.js +1200 -0
  122. package/dist/shared/components-8hzbsfbd.js +123 -0
  123. package/dist/shared/components-9p8s8n5q.js +171 -0
  124. package/dist/shared/components-aaq3yk4f.js +304 -0
  125. package/dist/shared/components-bf2d9k02.js +484 -0
  126. package/dist/shared/components-bkvb6nem.js +63 -0
  127. package/dist/shared/components-brnzrp2t.js +262 -0
  128. package/dist/shared/components-csxz9f52.js +42 -0
  129. package/dist/shared/components-de8xsm9y.js +22 -0
  130. package/dist/shared/components-dg0w8g5p.js +26 -0
  131. package/dist/shared/components-dphg9gjr.js +42 -0
  132. package/dist/shared/components-e46kf6cp.js +298 -0
  133. package/dist/shared/components-ed7cmssr.js +105 -0
  134. package/dist/shared/components-ess3ch6w.js +137 -0
  135. package/dist/shared/components-gjfrycb5.js +984 -0
  136. package/dist/shared/components-gndm6am4.js +128 -0
  137. package/dist/shared/components-hjkrv00c.js +191 -0
  138. package/dist/shared/components-hzfp4tjb.js +270 -0
  139. package/dist/shared/components-j65qt1mq.js +719 -0
  140. package/dist/shared/components-jw16snbn.js +19 -0
  141. package/dist/shared/components-jxgznftn.js +146 -0
  142. package/dist/shared/components-kf2ehztc.js +216 -0
  143. package/dist/shared/components-kpbcms10.js +9 -0
  144. package/dist/shared/components-m5br529r.js +141 -0
  145. package/dist/shared/components-nn6xezy2.js +1828 -0
  146. package/dist/shared/components-nnnd2xef.js +9 -0
  147. package/dist/shared/components-p2vmyfe1.js +345 -0
  148. package/dist/shared/components-peg09pzs.js +79 -0
  149. package/dist/shared/components-r22vtgqc.js +45 -0
  150. package/dist/shared/components-r2gke5p6.js +1759 -0
  151. package/dist/shared/components-r43mqnd6.js +160 -0
  152. package/dist/shared/components-r4jt6hgd.js +58 -0
  153. package/dist/shared/components-rc63qsy6.js +159 -0
  154. package/dist/shared/components-s3yfvfkr.js +149 -0
  155. package/dist/shared/components-s5pkbjx1.js +445 -0
  156. package/dist/shared/components-tad5h7ta.js +346 -0
  157. package/dist/shared/components-taxmgbnh.js +120 -0
  158. package/dist/shared/components-tm88ghva.js +215 -0
  159. package/dist/shared/components-v7es8aan.js +144 -0
  160. package/dist/shared/components-vb033rns.js +28 -0
  161. package/dist/shared/components-vc1k7yv2.js +30 -0
  162. package/dist/shared/components-vktws5r6.js +667 -0
  163. package/dist/shared/components-x2xyckd5.js +198 -0
  164. package/dist/shared/components-x3rz4cyn.js +61 -0
  165. package/dist/shared/components-xszag63d.js +141 -0
  166. package/dist/shared/components-y3cqdrgy.js +291 -0
  167. package/dist/shared/components-zvb11ker.js +288 -0
  168. package/dist/shared/components-zx2hr57f.js +124 -0
  169. package/dist/styles.css +1949 -0
  170. package/dist/tailwind.css +219 -0
  171. package/dist/tokens.css +345 -0
  172. package/package.json +102 -3
package/dist/preset.js ADDED
@@ -0,0 +1,124 @@
1
+ // preset.ts
2
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ var TYPE_ROLES = ["display", "title", "subtitle", "body", "caption", "micro"];
6
+ var WEIGHTS = ["normal", "medium", "semibold", "bold"];
7
+ var TIERS = ["fast", "moderate", "slow"];
8
+ var RADII = ["box", "glyph"];
9
+ var theme = {
10
+ font: {
11
+ sans: "'Inter Variable', ui-sans-serif, system-ui, sans-serif",
12
+ mono: "ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, monospace"
13
+ },
14
+ colors: {
15
+ background: "var(--background)",
16
+ foreground: "var(--foreground)",
17
+ card: { DEFAULT: "var(--card)", foreground: "var(--card-foreground)" },
18
+ muted: { DEFAULT: "var(--muted)", foreground: "var(--muted-foreground)" },
19
+ accent: {
20
+ DEFAULT: "var(--accent)",
21
+ foreground: "var(--accent-foreground)",
22
+ hover: "var(--accent-hover)"
23
+ },
24
+ brand: { DEFAULT: "var(--brand)", hover: "var(--brand-hover)" },
25
+ "focus-ring": "var(--focus-ring)",
26
+ overlay: "rgb(var(--overlay))",
27
+ selected: "var(--selected)",
28
+ thumb: "var(--thumb)",
29
+ picker: { edge: "var(--picker-edge)", ring: "var(--picker-ring)" },
30
+ control: "var(--control-border)",
31
+ scrim: "var(--scrim)",
32
+ status: {
33
+ success: "var(--status-success)",
34
+ loading: "var(--status-loading)",
35
+ error: "var(--status-error)",
36
+ warning: "var(--status-warning)",
37
+ info: "var(--status-info)",
38
+ action: "var(--status-action)"
39
+ },
40
+ border: "var(--border)",
41
+ ring: "var(--ring)",
42
+ input: "var(--input)",
43
+ destructive: { DEFAULT: "var(--destructive)", light: "var(--destructive-light)" },
44
+ hover: "var(--hover)",
45
+ active: "var(--active)",
46
+ syntax: {
47
+ keyword: "var(--syntax-keyword)",
48
+ string: "var(--syntax-string)",
49
+ class: "var(--syntax-class)",
50
+ entity: "var(--syntax-entity)",
51
+ property: "var(--syntax-property)",
52
+ comment: "var(--syntax-comment)",
53
+ identifier: "var(--syntax-identifier)",
54
+ jsx: "var(--syntax-jsx)",
55
+ sign: "var(--syntax-sign)"
56
+ },
57
+ surface: {
58
+ 1: "var(--surface-1)",
59
+ 2: "var(--surface-2)",
60
+ 3: "var(--surface-3)",
61
+ 4: "var(--surface-4)",
62
+ 5: "var(--surface-5)",
63
+ 6: "var(--surface-6)",
64
+ 7: "var(--surface-7)",
65
+ 8: "var(--surface-8)"
66
+ }
67
+ },
68
+ property: {
69
+ "stroke-width": "stroke-width",
70
+ "font-variation-settings": "font-variation-settings"
71
+ },
72
+ shadow: {
73
+ "surface-1": "var(--shadow-1)",
74
+ "surface-2": "var(--shadow-2)",
75
+ "surface-3": "var(--shadow-3)",
76
+ "surface-4": "var(--shadow-4)",
77
+ "surface-5": "var(--shadow-5)",
78
+ "surface-6": "var(--shadow-6)",
79
+ "surface-7": "var(--shadow-7)",
80
+ "surface-8": "var(--shadow-8)",
81
+ thumb: "var(--shadow-thumb)",
82
+ "picker-thumb": "var(--shadow-picker-thumb)",
83
+ "picker-cursor": "var(--shadow-picker-cursor)",
84
+ swatch: "var(--shadow-swatch)",
85
+ "swatch-hover": "var(--shadow-swatch-hover)",
86
+ "swatch-selected": "var(--shadow-swatch-selected)"
87
+ },
88
+ dropShadow: {
89
+ "picker-cursor": "var(--drop-shadow-picker-cursor)"
90
+ }
91
+ };
92
+ var utilities = Object.fromEntries([
93
+ ...TYPE_ROLES.flatMap((role) => ["", "-compact"].map((step) => [
94
+ `text-${role}${step}`,
95
+ { "font-size": `var(--text-${role}${step})`, "line-height": `var(--leading-${role})` }
96
+ ])),
97
+ ...WEIGHTS.map((weight) => [`weight-${weight}`, { "font-variation-settings": `var(--weight-${weight})` }]),
98
+ ...TIERS.flatMap((tier) => ["", "-exit"].flatMap((step) => [
99
+ [
100
+ `duration-${tier}${step}`,
101
+ { "--un-duration": `var(--duration-${tier}${step})`, "transition-duration": `var(--duration-${tier}${step})` }
102
+ ],
103
+ [`delay-${tier}${step}`, { "transition-delay": `var(--duration-${tier}${step})` }]
104
+ ])),
105
+ ...RADII.map((radius) => [`rounded-${radius}`, { "border-radius": `var(--radius-${radius})` }])
106
+ ]);
107
+ var dist = dirname(fileURLToPath(import.meta.url));
108
+ var COMPONENT_DIRS = ["shared", "primitives", "components", "blocks"];
109
+ function modoUiContent() {
110
+ return COMPONENT_DIRS.map((dir) => join(dist, dir)).filter((dir) => existsSync(dir)).flatMap((dir) => readdirSync(dir, { recursive: true, encoding: "utf8" }).filter((file) => file.endsWith(".js")).map((file) => readFileSync(join(dir, file), "utf8"))).join(`
111
+ `);
112
+ }
113
+ function presetModoUi() {
114
+ return { name: "@justanarthur/modo-ui", theme, rules: Object.entries(utilities) };
115
+ }
116
+ var preset_default = presetModoUi;
117
+ export {
118
+ utilities,
119
+ theme,
120
+ presetModoUi,
121
+ modoUiContent,
122
+ preset_default as default,
123
+ COMPONENT_DIRS
124
+ };
@@ -0,0 +1,23 @@
1
+ import { JSX as JSX_1kxb } from "react";
2
+ type Element_12xgc = JSX_1kxb["Element"];
3
+ /**
4
+ * Source code in the theme's syntax colors, one surface step above whatever
5
+ * it sits on.
6
+ *
7
+ * sugar-high tokenizes; each token type takes a `--syntax-*` token from
8
+ * tokens/colors.css, so code follows light and dark like everything else.
9
+ * Long lines scroll sideways under a fading edge instead of wrapping. It is
10
+ * also the docs chrome's Code slot: every example's source and every fenced
11
+ * block on these pages renders through it.
12
+ *
13
+ * @example {@include ./examples.mdx}
14
+ */
15
+ declare function Code({ children, language, className }: {
16
+ /** The source to show; surrounding blank lines are trimmed. */
17
+ children: string;
18
+ /** Fence name, alias or extension (`tsx`, `css`, `sh`, …). Unknown names render as plain text. Defaults to `'tsx'`. */
19
+ language?: string;
20
+ /** Extra classes for the frame. */
21
+ className?: string;
22
+ }): Element_12xgc;
23
+ export { Code as default, Code };
@@ -0,0 +1,12 @@
1
+ import {
2
+ Code
3
+ } from "../../shared/components-bkvb6nem.js";
4
+ import"../../shared/components-ed7cmssr.js";
5
+ import"../../shared/components-csxz9f52.js";
6
+ import"../../shared/components-7zp99w5d.js";
7
+ import"../../shared/components-0f0as45n.js";
8
+ import"../../shared/components-kpbcms10.js";
9
+ export {
10
+ Code as default,
11
+ Code
12
+ };
@@ -0,0 +1,31 @@
1
+ import { ReactNode } from "react";
2
+ import { JSX as JSX_1kxb } from "react";
3
+ interface CraftProps {
4
+ /** The naive version: the same interface with the detail missing. */
5
+ bad: ReactNode;
6
+ /** The system's version, with the detail in place. */
7
+ good: ReactNode;
8
+ /** What goes wrong on the bad side, in one line. */
9
+ badNote?: string;
10
+ /** What the good side does instead, in one line. */
11
+ goodNote?: string;
12
+ /** Classes for the root grid. */
13
+ className?: string;
14
+ }
15
+ type Element_12xgc = JSX_1kxb["Element"];
16
+ /**
17
+ * The details that make an interface feel finished, each one shown without
18
+ * and with it.
19
+ *
20
+ * Every pair below isolates one rule of the system: the bad side is the
21
+ * version most component libraries ship, the good side is this design
22
+ * system's own item. Try both: press, hover between rows, click and then tab,
23
+ * open and close. The rules themselves are on the Motion, FluidHover,
24
+ * Morph, Elevated and SizeProvider pages; this one is where they can be felt.
25
+ * `Craft` is the frame: the two versions side by side, each with a one-line
26
+ * verdict, stacked on narrow screens.
27
+ *
28
+ * @example {@include ./examples.mdx}
29
+ */
30
+ declare function Craft({ bad, good, badNote, goodNote, className }: CraftProps): Element_12xgc;
31
+ export { Craft as default, CraftProps };
@@ -0,0 +1,13 @@
1
+ import {
2
+ Craft
3
+ } from "../../shared/components-6hzwfmfd.js";
4
+ import"../../shared/components-9p8s8n5q.js";
5
+ import"../../shared/components-7zp99w5d.js";
6
+ import"../../shared/components-nnnd2xef.js";
7
+ import"../../shared/components-vc1k7yv2.js";
8
+ import"../../shared/components-x3rz4cyn.js";
9
+ import"../../shared/components-0f0as45n.js";
10
+ import"../../shared/components-kpbcms10.js";
11
+ export {
12
+ Craft as default
13
+ };
@@ -0,0 +1,233 @@
1
+ import { ForwardRefExoticComponent, HTMLAttributes, ReactNode, RefAttributes } from "react";
2
+ import { Transition } from "motion/react";
3
+ import { Dispatch, MutableRefObject, RefObject, SetStateAction } from "react";
4
+ interface ItemRect {
5
+ top: number;
6
+ height: number;
7
+ left: number;
8
+ width: number;
9
+ }
10
+ interface UseFluidHoverOptions {
11
+ /**
12
+ * Which direction to resolve the nearest item along.
13
+ * "y" — vertical lists (default): closest by top/height
14
+ * "x" — horizontal strips: closest by left/width
15
+ * "xy" — 2-D grids: closest card across both rows AND columns,
16
+ * measured by Euclidean distance to each item's center
17
+ */
18
+ axis?: "x" | "y" | "xy";
19
+ /**
20
+ * Makes an item invisible to hit-testing without unregistering it — for
21
+ * rows that stay mounted while clipped away (a collapsed sub-tree).
22
+ * Unregistering would invalidate every measurement; a skipped item keeps
23
+ * the set stable. Consulted per mouse move, so keep it cheap.
24
+ */
25
+ isItemDisabled?: (element: HTMLElement) => boolean;
26
+ /**
27
+ * Whether a click that lands between items (a gap, the padding, past the
28
+ * last row) is routed to the highlighted item, so what is lit is what a
29
+ * click hits. On by default: in a menu or a list the highlight is a
30
+ * promise about the click. Pass `false` where empty space should stay
31
+ * inert (rows with destructive actions, generous whitespace), or
32
+ * `{ maxDistance }` to route only clicks within that many pixels of the
33
+ * highlighted item's edge.
34
+ */
35
+ gapClick?: boolean | {
36
+ maxDistance?: number;
37
+ };
38
+ }
39
+ interface UseFluidHoverReturn {
40
+ activeIndex: number | null;
41
+ setActiveIndex: Dispatch<SetStateAction<number | null>>;
42
+ itemRects: ItemRect[];
43
+ /**
44
+ * True once every registered item has been measured and no remeasure is
45
+ * pending, i.e. `itemRects` describes the current item set. Gate absolutely
46
+ * positioned overlays on it: an overlay that mounts against a rect a later
47
+ * pass still corrects animates from the wrong place to the right one, which
48
+ * reads as the highlight sliding in from another row.
49
+ */
50
+ isMeasured: boolean;
51
+ sessionRef: MutableRefObject<number>;
52
+ handlers: {
53
+ onMouseMove: (e: React.MouseEvent) => void;
54
+ onMouseEnter: () => void;
55
+ onMouseLeave: () => void;
56
+ /**
57
+ * Routes a click that lands between items (a gap, the padding, past the
58
+ * last row) to the highlighted item, so the highlight and the click agree:
59
+ * what is lit is what a click hits. A click inside an item is left to the
60
+ * item. Disabled items (`isItemDisabled`) are never activated.
61
+ */
62
+ onClick: (e: React.MouseEvent) => void;
63
+ };
64
+ registerItem: (index: number, element: HTMLElement | null) => void;
65
+ /**
66
+ * Invalidates the published rects and runs the hook's coalesced measurement
67
+ * pass again, holding `isMeasured` false until it settles. Reach for it when
68
+ * the rects may be wrong and showing an overlay against them would misplace
69
+ * it: a popup that stays mounted between opens keeps its items registered,
70
+ * so nothing else would notice that its rects were taken while it was
71
+ * hidden. Registration, item resize, and container resize already trigger
72
+ * a pass; do not call this on `children` changes.
73
+ */
74
+ remeasure: () => void;
75
+ /**
76
+ * Re-reads the rects synchronously, keeping `isMeasured` as it is. Only for
77
+ * layout that moves the rows under a visible overlay frame by frame (the
78
+ * accordion re-measures inside its height animation). Everything else
79
+ * wants `remeasure`, or nothing.
80
+ */
81
+ measureItems: () => void;
82
+ }
83
+ declare function useFluidHover<T extends HTMLElement>(containerRef: RefObject<T | null>, options?: UseFluidHoverOptions): UseFluidHoverReturn;
84
+ /**
85
+ * Registers an item's element with its list for as long as it is mounted.
86
+ * The one way rows join a list: pass the hook's `registerItem` (or the copy
87
+ * a context hands down), the row's index, and its ref. Either may be
88
+ * missing for a row rendered outside a list (a standalone card, an accordion
89
+ * item that is not grouped); then nothing is registered.
90
+ */
91
+ declare function useRegisterFluidHoverItem(registerItem: ((index: number, element: HTMLElement | null) => void) | undefined, index: number | undefined, ref: RefObject<HTMLElement | null>): void;
92
+ import { JSX as JSX_1kxb } from "react";
93
+ /** What the highlight reads off the hook: the highlighted index, the
94
+ * measured rects, whether they are current, and the pointer session. */
95
+ type FluidHoverSource = Pick<UseFluidHoverReturn, "activeIndex" | "itemRects" | "isMeasured" | "sessionRef">;
96
+ interface HighlightFromHook {
97
+ /** The hook's return value. The highlight sits on
98
+ * `itemRects[activeIndex]` once `isMeasured`, and re-keys on the session. */
99
+ hover: FluidHoverSource;
100
+ /** Keep the list's state but show nothing (a closed popup, hover switched
101
+ * off). Runs the exit fade. */
102
+ hidden?: boolean;
103
+ rect?: never;
104
+ session?: never;
105
+ }
106
+ interface HighlightFromRect {
107
+ /** For lists that resolve their own rect (the sidebar's unified scope):
108
+ * the rect to sit on, in the container's coordinate space. `null` hides
109
+ * the highlight (it fades out on `spring.fast.exit`). */
110
+ rect: ItemRect | null;
111
+ /** `sessionRef.current` from `useFluidHover`. It increments when the
112
+ * cursor enters the container, which re-keys the highlight so it fades in
113
+ * at `from ?? rect` instead of sliding over from wherever it was last. */
114
+ session: number;
115
+ hover?: never;
116
+ hidden?: never;
117
+ }
118
+ type FluidHoverHighlightProps = (HighlightFromHook | HighlightFromRect) & {
119
+ /** Where a fresh session fades in from. A dropdown passes its checked row,
120
+ * a nav menu its active route. Defaults to the rect itself. */
121
+ from?: ItemRect | null;
122
+ /** Radius, z-index, anything else. Merged onto
123
+ * `absolute bg-hover pointer-events-none`. */
124
+ className?: string;
125
+ /** The positional spring. Defaults to `spring.fast`. Pass `false` to snap
126
+ * to the new rect with no travel (a layout reflow that moved the rows
127
+ * underneath, not a hover change). The opacity fade is always 0.08s. */
128
+ transition?: Transition | false;
129
+ };
130
+ type Element_12xgc = JSX_1kxb["Element"];
131
+ declare function FluidHoverHighlight(props: FluidHoverHighlightProps): Element_12xgc;
132
+ type FluidHoverAxis = "x" | "y" | "xy";
133
+ interface FluidHoverItemProps extends HTMLAttributes<HTMLButtonElement> {
134
+ /** Position in the list. Assigned automatically to direct children of `FluidHover`; pass it by hand for rows rendered inside a wrapper of your own. */
135
+ index?: number;
136
+ /** Skips the row: never lit, never the target of a gap click. It stays registered, so its neighbours keep their indices. Defaults to `false`. */
137
+ disabled?: boolean;
138
+ /** The row's content — a label, or an icon plus text, or (on `xy`) a title over a description. */
139
+ children?: ReactNode;
140
+ /** Classes for the row, merged over the per-axis defaults. */
141
+ className?: string;
142
+ }
143
+ /**
144
+ * One row of a fluid hover list: a real button, focusable and activatable from
145
+ * the keyboard, announced by its label. It registers itself with the
146
+ * surrounding `FluidHover` for as long as it is mounted; outside one it is
147
+ * just a button.
148
+ */
149
+ declare const FluidHoverItem: ForwardRefExoticComponent<FluidHoverItemProps & RefAttributes<HTMLButtonElement>>;
150
+ interface FluidHoverProps extends HTMLAttributes<HTMLDivElement> {
151
+ /** Which way the list runs: `'y'` for lists, `'x'` for strips, `'xy'` for grids. Defaults to `'y'`, or `'xy'` when `columns` is above 1. */
152
+ axis?: FluidHoverAxis;
153
+ /** Grid columns. Above 1 the container becomes a grid and resolves the nearest item across rows and columns. Defaults to `1`, or `2` when `axis` is `'xy'`. */
154
+ columns?: number;
155
+ /** Shorthand rows: one `FluidHover.Item` per string, indexed in order. Omit it and pass `FluidHover.Item` children instead. */
156
+ items?: string[];
157
+ /** Renders the content of a shorthand row. Defaults to the string itself. */
158
+ renderItem?: (item: string, index: number) => ReactNode;
159
+ /** Rows to skip: never lit, never the target of a gap click. They stay registered, so their neighbours keep their indices. */
160
+ disabledIndices?: number[];
161
+ /** Whether a click that lands between rows goes to the lit one, so what is lit is what a click hits. `false` leaves empty space inert; `{ maxDistance }` routes only clicks within that many pixels of the lit row. Defaults to `true`. */
162
+ gapClick?: boolean | {
163
+ maxDistance?: number;
164
+ };
165
+ /** Classes for the highlight itself — radius and z-index. Merged over `absolute bg-hover` and the shape system's radius. */
166
+ highlightClassName?: string;
167
+ /** Classes for the list container. Padding here is part of the list: a click in it still lands on the lit row. */
168
+ className?: string;
169
+ /** `FluidHover.Item` rows, when `items` is not enough. Direct Item children are indexed in order. */
170
+ children?: ReactNode;
171
+ }
172
+ type FluidHoverComponent = ForwardRefExoticComponent<FluidHoverProps & RefAttributes<HTMLDivElement>> & {
173
+ Item: typeof FluidHoverItem;
174
+ };
175
+ /**
176
+ * Hover that never blinks and always follows your cursor to the nearest item.
177
+ *
178
+ * One rule, no dead zones: an item the pointer is inside wins, and otherwise
179
+ * the item whose center is nearest does — so a cursor in a gap, in the
180
+ * padding, or past the last row still lands on something, and a click there
181
+ * lands on what is lit (`gapClick`). One list is one FluidHover: it owns the
182
+ * container's mouse handlers, hands every row its index, and draws the single
183
+ * highlight that melts between the measured rectangles, stretching toward the
184
+ * next row and letting go (the liquid indicators in Morph).
185
+ *
186
+ * Three axes, one feel. `y` is for lists — menus, tables, radio rows — and
187
+ * measures the vertical center; `x` is for strips — tabs, segmented controls —
188
+ * and measures the horizontal one; `xy` is for card grids, where the nearest
189
+ * card is the shortest straight line to a center across both rows and columns.
190
+ * Pass `columns` and the container becomes that grid and picks `xy` on its own.
191
+ *
192
+ * Split a list at the divider. Rows that are alternatives to each other share
193
+ * one list — children ride with their parent — and the highlight never crosses
194
+ * into a different kind of thing: that is a second FluidHover. A disabled row
195
+ * is skipped rather than unregistered (`disabledIndices`, or `disabled` on the
196
+ * row), so the rows around it keep their indices and their measurements.
197
+ *
198
+ * It costs 1 transform and 1 loop per move: the pick is one pass
199
+ * over cached rectangles per animation frame, with no DOM reads per row, and
200
+ * the highlight travels on a transform. While it melts, a shrinking blob and
201
+ * the goo filter join it, and both are gone once it settles, so a resting
202
+ * highlight is filtered by nothing. Reduced motion is honoured on its own,
203
+ * read straight off the OS media query with no MotionConfig wrapper needed:
204
+ * the highlight still fades in on the nearest row, it just stops travelling
205
+ * between rows.
206
+ *
207
+ * Use it when everything in the list can be clicked (a menu, a list, tabs, a
208
+ * grid of links), when the items sit close together, and when they stay where
209
+ * they are while you look at them. Skip it when a wrong click would hurt, when
210
+ * only some of the cards can be clicked, when there is a lot of empty space
211
+ * around the items, or when rows change place as you scroll.
212
+ *
213
+ * Statics: FluidHover.Item — one row, rendered as a real button (focusable,
214
+ * activatable from the keyboard, announced by its label); the hook only lights
215
+ * it, it never moves focus.
216
+ *
217
+ * For a list this container cannot express, the machinery is re-exported
218
+ * unchanged. `useFluidHover(containerRef, { axis, isItemDisabled, gapClick })`
219
+ * returns `{ handlers, registerItem, activeIndex, setActiveIndex, itemRects,
220
+ * isMeasured, remeasure, sessionRef }`: spread `handlers` on the container,
221
+ * give each row `useRegisterFluidHoverItem(registerItem, index, ref)`, light a
222
+ * row yourself with `setActiveIndex` for keyboard focus, and call `remeasure`
223
+ * when the rects may be stale (a popup opening on rows that never unmounted).
224
+ * `FluidHoverHighlight` then draws the fill: `hover` is the hook's return
225
+ * value, `hidden` keeps the state but shows nothing, `from` is where a fresh
226
+ * entry fades in (a dropdown passes its checked row), `className` carries
227
+ * radius and z-index, and `transition` is the travel — `false` snaps into
228
+ * place after a reflow instead of sliding.
229
+ *
230
+ * @example {@include ./examples.mdx}
231
+ */
232
+ declare const FluidHover: FluidHoverComponent;
233
+ export { useRegisterFluidHoverItem, useFluidHover, FluidHover as default, UseFluidHoverReturn, UseFluidHoverOptions, ItemRect, FluidHoverProps, FluidHoverItemProps, FluidHoverItem, FluidHoverHighlightProps, FluidHoverHighlight, FluidHoverAxis, FluidHover };
@@ -0,0 +1,27 @@
1
+ import {
2
+ FluidHover,
3
+ FluidHoverItem,
4
+ fluid_hover_default
5
+ } from "../../shared/components-ess3ch6w.js";
6
+ import {
7
+ FluidHoverHighlight
8
+ } from "../../shared/components-r22vtgqc.js";
9
+ import {
10
+ useFluidHover,
11
+ useRegisterFluidHoverItem
12
+ } from "../../shared/components-e46kf6cp.js";
13
+ import"../../shared/components-7zp99w5d.js";
14
+ import"../../shared/components-kf2ehztc.js";
15
+ import"../../shared/components-7nww01w4.js";
16
+ import"../../shared/components-nnnd2xef.js";
17
+ import"../../shared/components-vc1k7yv2.js";
18
+ import"../../shared/components-0f0as45n.js";
19
+ import"../../shared/components-kpbcms10.js";
20
+ export {
21
+ useRegisterFluidHoverItem,
22
+ useFluidHover,
23
+ fluid_hover_default as default,
24
+ FluidHoverItem,
25
+ FluidHoverHighlight,
26
+ FluidHover
27
+ };
@@ -0,0 +1,127 @@
1
+ import { ReactNode as ReactNode2 } from "react";
2
+ import { ReactNode } from "react";
3
+ import { JSX as JSX_1kxb } from "react";
4
+ interface MorphPartProps {
5
+ /** Pairs the part in the trigger with its twin in the overlay; unique within one overlay. */
6
+ id: string;
7
+ /** Classes for the part's box. */
8
+ className?: string;
9
+ /** The part's content: an image, a title. */
10
+ children?: ReactNode;
11
+ }
12
+ type Element_12xgc = JSX_1kxb["Element"];
13
+ declare function MorphPart({ id, className, children }: MorphPartProps): Element_12xgc;
14
+ import { JSX as JSX_1kxb2 } from "react";
15
+ interface MorphProps {
16
+ /** Where the panel grows from: the pressed `'trigger'`, the press `'pointer'` (a circle; keyboard opens use the trigger's center), the panel's own `'center'`, or a viewport edge (`'top'`, `'right'`, `'bottom'`, `'left'`). Defaults to `'trigger'`. */
17
+ from?: "trigger" | "pointer" | "center" | "top" | "right" | "bottom" | "left";
18
+ /** How it gets there: `'goo'` grows the surface with a liquid neck to its source, `'morph'` grows it without one, `'slide'` moves the finished panel in, `'fade'` only fades (what every effect becomes under reduced motion). Defaults to `'goo'`. */
19
+ effect?: "goo" | "morph" | "slide" | "fade";
20
+ /** Spring tier of a plain morph, slide or fade, which closes on the tier's faster exit tween; goo runs on its own `spring.goo`. Defaults to `'slow'`. */
21
+ tier?: "moderate" | "slow";
22
+ /** Hide the trigger while the panel is open, so the trigger reads as becoming the panel. Defaults to `false`. */
23
+ hideSource?: boolean;
24
+ /** Controlled open state. Pair with `onOpenChange`. */
25
+ open?: boolean;
26
+ /** Uncontrolled initial open state, toggled by the built-in trigger. Defaults to `false`. */
27
+ defaultOpen?: boolean;
28
+ /** Called with the next open state when the trigger is pressed. */
29
+ onOpenChange?: (open: boolean) => void;
30
+ /** Label of the built-in trigger. Defaults to `'Open'`. */
31
+ label?: string;
32
+ /** Extra classes for the stage (trigger + panel). */
33
+ className?: string;
34
+ /** The panel's content. */
35
+ children?: ReactNode2;
36
+ }
37
+ type Element_12xgc2 = JSX_1kxb2["Element"];
38
+ /**
39
+ * Overlays grow out of whatever opened them. One progress value on a spring
40
+ * tier carries the surface from its source to its own box, and every
41
+ * morphing overlay in this system runs on that one engine.
42
+ *
43
+ * The overlay's popup keeps its final size the whole time, so Base UI's
44
+ * positioning, collision flipping and focus handling never see the animation.
45
+ * Inside it, three layers move: the surface's background and its shadow (the
46
+ * `Elevated` level, as `SURFACE_BG` / `SURFACE_SHADOW`), the goo layer that
47
+ * melts the surface into its source, and the content, revealed by a clip
48
+ * from the same rect. The surface moves its real box rather than being
49
+ * clipped, so its shadow is never cut off and nothing scales.
50
+ *
51
+ * ## Options
52
+ *
53
+ * Every morphing overlay takes the same `from`, `effect` and `hideSource`
54
+ * options, and a spring `tier` for the effects other than goo (see Motion).
55
+ *
56
+ * - `from` — where the surface grows from. `'trigger'` is the trigger that
57
+ * was pressed; it is measured again on close, and when it has gone or
58
+ * scrolled away the surface grows from its `'center'` instead.
59
+ * `'pointer'` is the press point, `'center'` the panel's own center, and an
60
+ * edge (`'top'`, `'right'`, `'bottom'`, `'left'`) the side of the viewport.
61
+ * Components also take a ref to any element, such as a card that
62
+ * expands.
63
+ * - `effect` — `'goo'` (the default) grows the surface with a liquid neck to
64
+ * its source, like two drops of water merging; `'morph'` grows it without
65
+ * one; `'slide'` moves the finished panel in; `'fade'` only fades.
66
+ * - `hideSource` — hides the source while open, so it reads as turning into
67
+ * the overlay. Focus can still return to it. With `effect="morph"` an
68
+ * anchored overlay also opens in place: the panel lays over its trigger,
69
+ * corner to corner, instead of beside it, so the trigger's own box is where
70
+ * it starts and where it shrinks back to.
71
+ *
72
+ * ## Motion
73
+ *
74
+ * Goo runs on its own tier, `spring.goo`: it lands in about 200ms with a
75
+ * little bounce and springs back in about as long, slow enough for the neck
76
+ * to stretch. Its blur eases away over the last stretch, so the neck pinches
77
+ * off as the surface lands, and while it melts a hairline in the shadow's
78
+ * color follows the liquid shape, so a surface the color of the page still
79
+ * shows it; the surface's own shadow takes over as it lets go. The other
80
+ * effects open on a spring tier (`slow` by default) and close on that tier's
81
+ * faster exit tween, like every other animation here (see Motion).
82
+ * Reduced motion, the OS setting or a `MotionConfig` asking for it, turns every
83
+ * effect into a fade.
84
+ *
85
+ * ## Liquid indicators
86
+ *
87
+ * The same goo moves everything that travels between items: the active tab
88
+ * of Tabs and TabsSubtle, the Switch thumb, RadioGroup's selection and the
89
+ * fluid hover highlight of every list (Select, Dropdown, Combobox, Card,
90
+ * Accordion, FluidHover). The indicator springs to its new item and leaves
91
+ * a blob behind. The blob lingers for a third of the spring, then follows
92
+ * to the back of the new item while it shrinks, so the two melt into one
93
+ * stretched drop that lets go. A long move tears it into a drop and a
94
+ * droplet that catches up and is absorbed.
95
+ *
96
+ * Merged selections (CheckboxGroup, a multiple Dropdown) melt the same way:
97
+ * a checked row grows out of its center and flows into its checked
98
+ * neighbours, and an unchecked one pinches off and shrinks away.
99
+ *
100
+ * - The goo filter runs only while a blob is alive; at rest an indicator is
101
+ * one plain element.
102
+ * - The melted shape is filled with the indicator's own token, so
103
+ * translucent fills such as `bg-hover` and `bg-active` melt like opaque
104
+ * surfaces. Shadows are drawn again beneath the goo while it moves.
105
+ * - A short move or a resize in place springs without a blob, and a square
106
+ * indicator, with no radius to melt, only slides.
107
+ * - Reduced motion snaps the indicator into place.
108
+ *
109
+ * ## Shared parts
110
+ *
111
+ * `Morph.Part` pairs an element in the trigger with its twin in the overlay
112
+ * (same `id`), so the part flies from one to the other while the surface
113
+ * morphs, and back on close: a card's image or title moving into a Dialog.
114
+ *
115
+ * ## The `Morph` stage
116
+ *
117
+ * `Morph` itself is a docs stage, not a building block: a trigger and a small
118
+ * panel below it that plays one `from` × `effect` pair.
119
+ *
120
+ * Statics:
121
+ * - `Morph.Part` — a shared part (`id`, `className`), for overlays that scope
122
+ * parts (Dialog).
123
+ *
124
+ * @example {@include ./examples.mdx}
125
+ */
126
+ declare function Morph({ from, effect, tier, hideSource, open, defaultOpen, onOpenChange, label, className, children }: MorphProps): Element_12xgc2;
127
+ export { Morph as default, MorphProps, MorphPart, Morph };
@@ -0,0 +1,21 @@
1
+ import {
2
+ Morph
3
+ } from "../../shared/components-6t6nr33r.js";
4
+ import"../../shared/components-5pkcfprd.js";
5
+ import"../../shared/components-csxz9f52.js";
6
+ import {
7
+ MorphPart
8
+ } from "../../shared/components-jxgznftn.js";
9
+ import"../../shared/components-7zp99w5d.js";
10
+ import"../../shared/components-dg0w8g5p.js";
11
+ import"../../shared/components-7nww01w4.js";
12
+ import"../../shared/components-nnnd2xef.js";
13
+ import"../../shared/components-vc1k7yv2.js";
14
+ import"../../shared/components-x3rz4cyn.js";
15
+ import"../../shared/components-0f0as45n.js";
16
+ import"../../shared/components-kpbcms10.js";
17
+ export {
18
+ Morph as default,
19
+ MorphPart,
20
+ Morph
21
+ };