@justanarthur/modo-ui 0.0.0-stage → 0.2.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 (171) 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 +31 -0
  10. package/dist/components/badge/index.d.ts +59 -0
  11. package/dist/components/badge/index.js +16 -0
  12. package/dist/components/button/index.d.ts +59 -0
  13. package/dist/components/button/index.js +14 -0
  14. package/dist/components/card/index.d.ts +141 -0
  15. package/dist/components/card/index.js +42 -0
  16. package/dist/components/inputs/checkbox-group/index.d.ts +50 -0
  17. package/dist/components/inputs/checkbox-group/index.js +21 -0
  18. package/dist/components/inputs/color-picker/index.d.ts +137 -0
  19. package/dist/components/inputs/color-picker/index.js +35 -0
  20. package/dist/components/inputs/combobox/index.d.ts +161 -0
  21. package/dist/components/inputs/combobox/index.js +38 -0
  22. package/dist/components/inputs/date-time/calendar/index.d.ts +45 -0
  23. package/dist/components/inputs/date-time/calendar/index.js +18 -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 +32 -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 +31 -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 +31 -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 +30 -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 +31 -0
  34. package/dist/components/inputs/input/index.d.ts +84 -0
  35. package/dist/components/inputs/input/index.js +19 -0
  36. package/dist/components/inputs/input-copy/index.d.ts +44 -0
  37. package/dist/components/inputs/input-copy/index.js +16 -0
  38. package/dist/components/inputs/input-message/index.d.ts +125 -0
  39. package/dist/components/inputs/input-message/index.js +25 -0
  40. package/dist/components/inputs/radio-group/index.d.ts +58 -0
  41. package/dist/components/inputs/radio-group/index.js +20 -0
  42. package/dist/components/inputs/search/index.d.ts +83 -0
  43. package/dist/components/inputs/search/index.js +25 -0
  44. package/dist/components/inputs/select/index.d.ts +105 -0
  45. package/dist/components/inputs/select/index.js +34 -0
  46. package/dist/components/inputs/slider/index.d.ts +108 -0
  47. package/dist/components/inputs/slider/index.js +14 -0
  48. package/dist/components/inputs/switch/index.d.ts +43 -0
  49. package/dist/components/inputs/switch/index.js +14 -0
  50. package/dist/components/navigation/accordion/index.d.ts +117 -0
  51. package/dist/components/navigation/accordion/index.js +28 -0
  52. package/dist/components/navigation/sidebar/index.d.ts +388 -0
  53. package/dist/components/navigation/sidebar/index.js +99 -0
  54. package/dist/components/navigation/tabs/index.d.ts +70 -0
  55. package/dist/components/navigation/tabs/index.js +23 -0
  56. package/dist/components/navigation/tabs-subtle/index.d.ts +73 -0
  57. package/dist/components/navigation/tabs-subtle/index.js +21 -0
  58. package/dist/components/overlays/alert-dialog/index.d.ts +67 -0
  59. package/dist/components/overlays/alert-dialog/index.js +22 -0
  60. package/dist/components/overlays/command/index.d.ts +121 -0
  61. package/dist/components/overlays/command/index.js +36 -0
  62. package/dist/components/overlays/context-menu/index.d.ts +97 -0
  63. package/dist/components/overlays/context-menu/index.js +29 -0
  64. package/dist/components/overlays/dialog/index.d.ts +130 -0
  65. package/dist/components/overlays/dialog/index.js +37 -0
  66. package/dist/components/overlays/dropdown/index.d.ts +222 -0
  67. package/dist/components/overlays/dropdown/index.js +44 -0
  68. package/dist/components/overlays/popover/index.d.ts +87 -0
  69. package/dist/components/overlays/popover/index.js +26 -0
  70. package/dist/components/overlays/preview-card/index.d.ts +75 -0
  71. package/dist/components/overlays/preview-card/index.js +19 -0
  72. package/dist/components/overlays/sheet/index.d.ts +67 -0
  73. package/dist/components/overlays/sheet/index.js +24 -0
  74. package/dist/components/overlays/toast/index.d.ts +107 -0
  75. package/dist/components/overlays/toast/index.js +21 -0
  76. package/dist/components/overlays/tooltip/index.d.ts +75 -0
  77. package/dist/components/overlays/tooltip/index.js +17 -0
  78. package/dist/components/table/index.d.ts +44 -0
  79. package/dist/components/table/index.js +26 -0
  80. package/dist/components/thinking-indicator/index.d.ts +32 -0
  81. package/dist/components/thinking-indicator/index.js +13 -0
  82. package/dist/index.d.ts +3926 -0
  83. package/dist/index.js +511 -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 +11 -0
  88. package/dist/primitives/craft/index.d.ts +31 -0
  89. package/dist/primitives/craft/index.js +11 -0
  90. package/dist/primitives/fluid-hover/index.d.ts +233 -0
  91. package/dist/primitives/fluid-hover/index.js +25 -0
  92. package/dist/primitives/morph/index.d.ts +127 -0
  93. package/dist/primitives/morph/index.js +19 -0
  94. package/dist/primitives/motion/index.d.ts +115 -0
  95. package/dist/primitives/motion/index.js +19 -0
  96. package/dist/primitives/scroll-area/index.d.ts +41 -0
  97. package/dist/primitives/scroll-area/index.js +12 -0
  98. package/dist/primitives/sizes/index.d.ts +128 -0
  99. package/dist/primitives/sizes/index.js +21 -0
  100. package/dist/primitives/surface/index.d.ts +69 -0
  101. package/dist/primitives/surface/index.js +17 -0
  102. package/dist/shared/components-0ke6xada.js +123 -0
  103. package/dist/shared/components-0q0sqfh4.js +146 -0
  104. package/dist/shared/components-0sn7ypjw.js +61 -0
  105. package/dist/shared/components-1j9791sn.js +345 -0
  106. package/dist/shared/components-1rfwbyyc.js +361 -0
  107. package/dist/shared/components-1v7rxytx.js +30 -0
  108. package/dist/shared/components-1xekx2hx.js +215 -0
  109. package/dist/shared/components-39jq9va1.js +86 -0
  110. package/dist/shared/components-3gae8nta.js +719 -0
  111. package/dist/shared/components-3k8xpnpq.js +1759 -0
  112. package/dist/shared/components-3ky44908.js +9 -0
  113. package/dist/shared/components-3mkepka5.js +111 -0
  114. package/dist/shared/components-3wk0w46f.js +667 -0
  115. package/dist/shared/components-4cnjmgex.js +124 -0
  116. package/dist/shared/components-59efxjd9.js +298 -0
  117. package/dist/shared/components-5xc2j8jz.js +159 -0
  118. package/dist/shared/components-62ybc7t2.js +496 -0
  119. package/dist/shared/components-66mv71kx.js +262 -0
  120. package/dist/shared/components-7ans7ce5.js +120 -0
  121. package/dist/shared/components-7btqt08d.js +270 -0
  122. package/dist/shared/components-7r3etddy.js +171 -0
  123. package/dist/shared/components-7x9kawxv.js +152 -0
  124. package/dist/shared/components-8fpr3s4p.js +292 -0
  125. package/dist/shared/components-9jvzzvt1.js +198 -0
  126. package/dist/shared/components-apdwtweq.js +484 -0
  127. package/dist/shared/components-asr5pg50.js +191 -0
  128. package/dist/shared/components-b2wyq2cq.js +232 -0
  129. package/dist/shared/components-c6s6b43g.js +15 -0
  130. package/dist/shared/components-ca2c898n.js +1828 -0
  131. package/dist/shared/components-cbxjn9p8.js +141 -0
  132. package/dist/shared/components-chacnk61.js +216 -0
  133. package/dist/shared/components-cv16mryv.js +62 -0
  134. package/dist/shared/components-ez65vtbq.js +110 -0
  135. package/dist/shared/components-ezxhrmer.js +17 -0
  136. package/dist/shared/components-gc5vtq2f.js +149 -0
  137. package/dist/shared/components-gf5s6ap9.js +42 -0
  138. package/dist/shared/components-gvr9w41t.js +193 -0
  139. package/dist/shared/components-h2dpcwgc.js +137 -0
  140. package/dist/shared/components-hawvy2qz.js +105 -0
  141. package/dist/shared/components-hqeq3w9q.js +375 -0
  142. package/dist/shared/components-jjw69c4c.js +28 -0
  143. package/dist/shared/components-jwst3vtj.js +346 -0
  144. package/dist/shared/components-kvr7f9hy.js +45 -0
  145. package/dist/shared/components-men63rwj.js +9 -0
  146. package/dist/shared/components-mhd39z7x.js +22 -0
  147. package/dist/shared/components-n7mjr357.js +26 -0
  148. package/dist/shared/components-ng72k97e.js +128 -0
  149. package/dist/shared/components-nh8tma1n.js +986 -0
  150. package/dist/shared/components-njzgqdwy.js +445 -0
  151. package/dist/shared/components-ny774h8p.js +293 -0
  152. package/dist/shared/components-q4daerx0.js +58 -0
  153. package/dist/shared/components-q5xj5c16.js +79 -0
  154. package/dist/shared/components-rr7a6ja9.js +160 -0
  155. package/dist/shared/components-s2bz1xpk.js +63 -0
  156. package/dist/shared/components-tqvarbfv.js +288 -0
  157. package/dist/shared/components-v6xp325t.js +304 -0
  158. package/dist/shared/components-v7wtz8hk.js +144 -0
  159. package/dist/shared/components-vc7vq5nz.js +32 -0
  160. package/dist/shared/components-vfbhxf5r.js +58 -0
  161. package/dist/shared/components-vynjtrk6.js +19 -0
  162. package/dist/shared/components-wvp1m52g.js +1200 -0
  163. package/dist/shared/components-yh3kwdhr.js +981 -0
  164. package/dist/shared/components-ytb2tefr.js +291 -0
  165. package/dist/shared/components-zfnmn5d4.js +220 -0
  166. package/dist/shared/components-zrkzcayz.js +141 -0
  167. package/dist/shared/components-zx6b6yby.js +42 -0
  168. package/dist/styles.css +1949 -0
  169. package/dist/tailwind.css +219 -0
  170. package/dist/tokens.css +345 -0
  171. package/package.json +103 -4
@@ -0,0 +1,146 @@
1
+ import {
2
+ useReduceMotion
3
+ } from "./components-men63rwj.js";
4
+ import {
5
+ GOO_MATRIX
6
+ } from "./components-hqeq3w9q.js";
7
+ import {
8
+ cn2
9
+ } from "./components-ezxhrmer.js";
10
+ import {
11
+ spring2
12
+ } from "./components-1v7rxytx.js";
13
+
14
+ // lib/morph-part.tsx
15
+ import { motion } from "motion/react";
16
+ import { createContext, useContext } from "react";
17
+ import { jsx } from "react/jsx-runtime";
18
+ var MorphPartScope = createContext(null);
19
+ var MorphPartInOverlay = createContext(false);
20
+ var { exit: _exit, ...enter } = spring2.slow;
21
+ function MorphPart2({ id, className, children }) {
22
+ const scope = useContext(MorphPartScope);
23
+ const inOverlay = useContext(MorphPartInOverlay);
24
+ const reduced = useReduceMotion();
25
+ const layoutId = scope && !reduced && (scope.open || !inOverlay) ? `${scope.id}-${id}` : undefined;
26
+ return /* @__PURE__ */ jsx(motion.div, {
27
+ layoutId,
28
+ transition: enter,
29
+ className,
30
+ children
31
+ });
32
+ }
33
+
34
+ // lib/morph-layers.tsx
35
+ import { jsx as jsx2, jsxs, Fragment } from "react/jsx-runtime";
36
+ function GooFilter({ id, blur, blurRef, outlineRef }) {
37
+ return /* @__PURE__ */ jsx2("svg", {
38
+ "aria-hidden": true,
39
+ className: "absolute size-0",
40
+ children: /* @__PURE__ */ jsxs("filter", {
41
+ id,
42
+ x: "-50%",
43
+ y: "-50%",
44
+ width: "200%",
45
+ height: "200%",
46
+ colorInterpolationFilters: "sRGB",
47
+ children: [
48
+ /* @__PURE__ */ jsx2("feGaussianBlur", {
49
+ ref: blurRef,
50
+ in: "SourceGraphic",
51
+ stdDeviation: blur,
52
+ result: "blur"
53
+ }),
54
+ /* @__PURE__ */ jsx2("feColorMatrix", {
55
+ in: "blur",
56
+ mode: "matrix",
57
+ values: GOO_MATRIX,
58
+ result: "goo"
59
+ }),
60
+ /* @__PURE__ */ jsx2("feComposite", {
61
+ in: "SourceGraphic",
62
+ in2: "goo",
63
+ operator: "atop",
64
+ result: "body"
65
+ }),
66
+ outlineRef && /* @__PURE__ */ jsxs(Fragment, {
67
+ children: [
68
+ /* @__PURE__ */ jsx2("feMorphology", {
69
+ in: "goo",
70
+ operator: "dilate",
71
+ radius: 1,
72
+ result: "grown"
73
+ }),
74
+ /* @__PURE__ */ jsx2("feFlood", {
75
+ ref: outlineRef,
76
+ className: "[flood-color:var(--shadow-color)]"
77
+ }),
78
+ /* @__PURE__ */ jsx2("feComposite", {
79
+ in2: "grown",
80
+ operator: "in",
81
+ result: "outline"
82
+ }),
83
+ /* @__PURE__ */ jsxs("feMerge", {
84
+ children: [
85
+ /* @__PURE__ */ jsx2("feMergeNode", {
86
+ in: "outline"
87
+ }),
88
+ /* @__PURE__ */ jsx2("feMergeNode", {
89
+ in: "body"
90
+ })
91
+ ]
92
+ })
93
+ ]
94
+ })
95
+ ]
96
+ })
97
+ });
98
+ }
99
+ function MorphSurface({ morph, bg, shadow, radius, className, children }) {
100
+ const { refs, gooId, effect } = morph;
101
+ return /* @__PURE__ */ jsxs(Fragment, {
102
+ children: [
103
+ effect === "goo" && /* @__PURE__ */ jsx2(GooFilter, {
104
+ id: gooId,
105
+ blurRef: refs.blur,
106
+ outlineRef: refs.outline
107
+ }),
108
+ (effect === "goo" || effect === "morph") && /* @__PURE__ */ jsxs("div", {
109
+ ref: refs.shapes,
110
+ "aria-hidden": true,
111
+ className: "pointer-events-none absolute hidden",
112
+ style: effect === "goo" ? { filter: `url(#${gooId})` } : undefined,
113
+ children: [
114
+ effect === "goo" && /* @__PURE__ */ jsx2("div", {
115
+ ref: refs.copy,
116
+ className: cn2("absolute", bg)
117
+ }),
118
+ /* @__PURE__ */ jsx2("div", {
119
+ ref: refs.shape,
120
+ className: cn2("absolute", bg)
121
+ })
122
+ ]
123
+ }),
124
+ /* @__PURE__ */ jsx2("div", {
125
+ ref: refs.bg,
126
+ "aria-hidden": true,
127
+ className: cn2("pointer-events-none absolute inset-0", bg, radius)
128
+ }),
129
+ shadow && /* @__PURE__ */ jsx2("div", {
130
+ ref: refs.shadow,
131
+ "aria-hidden": true,
132
+ className: cn2("pointer-events-none absolute inset-0", shadow, radius)
133
+ }),
134
+ /* @__PURE__ */ jsx2("div", {
135
+ ref: refs.content,
136
+ className: cn2("relative", className),
137
+ children: /* @__PURE__ */ jsx2(MorphPartInOverlay.Provider, {
138
+ value: true,
139
+ children
140
+ })
141
+ })
142
+ ]
143
+ });
144
+ }
145
+
146
+ export { MorphPartScope, MorphPart2, GooFilter, MorphSurface };
@@ -0,0 +1,61 @@
1
+ // lib/size-context.tsx
2
+ import { createContext, useContext } from "react";
3
+ var sizeMap2 = {
4
+ default: {
5
+ variant: "default",
6
+ control: "h-9",
7
+ controlHeight: 36,
8
+ segmentItem: "h-7",
9
+ segmentPad: "p-1",
10
+ text: "text-body",
11
+ px: "px-3",
12
+ itemPx: "px-2",
13
+ gap: "gap-2",
14
+ icon: 16
15
+ },
16
+ compact: {
17
+ variant: "compact",
18
+ control: "h-7",
19
+ controlHeight: 28,
20
+ segmentItem: "h-6",
21
+ segmentPad: "p-0.5",
22
+ text: "text-body-compact",
23
+ px: "px-2.5",
24
+ itemPx: "px-1.5",
25
+ gap: "gap-1",
26
+ icon: 14
27
+ }
28
+ };
29
+ var typeScale2 = {
30
+ display: { default: 28, compact: 24 },
31
+ title: { default: 16, compact: 15 },
32
+ subtitle: { default: 14, compact: 13 },
33
+ body: { default: 13, compact: 12 },
34
+ caption: { default: 12, compact: 11 }
35
+ };
36
+ function useTypeScale2(override) {
37
+ const variant = useSizeVariant2(override);
38
+ return {
39
+ display: typeScale2.display[variant],
40
+ title: typeScale2.title[variant],
41
+ subtitle: typeScale2.subtitle[variant],
42
+ body: typeScale2.body[variant],
43
+ caption: typeScale2.caption[variant]
44
+ };
45
+ }
46
+ var SizeContext = createContext(null);
47
+ function useSizeVariant2(override) {
48
+ const ctx = useContext(SizeContext);
49
+ return override ?? ctx?.size ?? "default";
50
+ }
51
+ function useSize2(override) {
52
+ return sizeMap2[useSizeVariant2(override)];
53
+ }
54
+ function useSizeContext2() {
55
+ const ctx = useContext(SizeContext);
56
+ if (!ctx)
57
+ throw new Error("useSizeContext must be used within a SizeProvider");
58
+ return ctx;
59
+ }
60
+
61
+ export { sizeMap2, typeScale2, useTypeScale2, SizeContext, useSizeVariant2, useSize2, useSizeContext2 };
@@ -0,0 +1,345 @@
1
+ import {
2
+ useIcon
3
+ } from "./components-zrkzcayz.js";
4
+ import {
5
+ useReduceMotion
6
+ } from "./components-men63rwj.js";
7
+ import {
8
+ GooFilter
9
+ } from "./components-0q0sqfh4.js";
10
+ import {
11
+ GOO_BLUR_RATIO
12
+ } from "./components-hqeq3w9q.js";
13
+ import {
14
+ cn2
15
+ } from "./components-ezxhrmer.js";
16
+ import {
17
+ useShape
18
+ } from "./components-cv16mryv.js";
19
+ import {
20
+ useSize2
21
+ } from "./components-0sn7ypjw.js";
22
+ import {
23
+ Tooltip2
24
+ } from "./components-ng72k97e.js";
25
+ import {
26
+ spring2
27
+ } from "./components-1v7rxytx.js";
28
+
29
+ // components/inputs/input-copy/index.tsx
30
+ import { AnimatePresence, animate, motion, useMotionValue } from "motion/react";
31
+ import {
32
+ forwardRef,
33
+ useCallback,
34
+ useEffect,
35
+ useId,
36
+ useLayoutEffect,
37
+ useRef,
38
+ useState
39
+ } from "react";
40
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
41
+ var GLYPH = 14;
42
+ var DISC = 20;
43
+ var UNIT = GLYPH / 24;
44
+ var sheet = (at) => ({ x: at * UNIT, y: at * UNIT, w: 14 * UNIT, h: 14 * UNIT, r: 2 * UNIT });
45
+ var BACK = sheet(2);
46
+ var FRONT = sheet(8);
47
+ var DISC_RECT = { x: (GLYPH - DISC) / 2, y: (GLYPH - DISC) / 2, w: DISC, h: DISC, r: DISC / 2 };
48
+ var BLUR = DISC / 2 * GOO_BLUR_RATIO;
49
+ var LAYER = { at: DISC_RECT.x - BLUR * 3, size: DISC + BLUR * 6 };
50
+ var TONE_BG = { copied: "bg-status-success", error: "bg-status-error" };
51
+ var TONE_TEXT = { copied: "text-status-success", error: "text-status-error" };
52
+ var CHECK_STROKE = {
53
+ icon: "[&_svg]:stroke-[1.5] [&_svg]:transition-[stroke-width] [&_svg]:duration-fast group-hover:[&_svg]:stroke-[2]",
54
+ button: "[&_svg]:stroke-[2]"
55
+ };
56
+ var { exit: _exit, ...enter } = spring2.slow;
57
+ function placeSheet(el, a, b, p) {
58
+ if (!el)
59
+ return;
60
+ const lerp = (from, to) => from + (to - from) * p;
61
+ const w = Math.max(0, lerp(a.w, b.w));
62
+ const h = Math.max(0, lerp(a.h, b.h));
63
+ el.style.left = `${lerp(a.x, b.x) - LAYER.at}px`;
64
+ el.style.top = `${lerp(a.y, b.y) - LAYER.at}px`;
65
+ el.style.width = `${w}px`;
66
+ el.style.height = `${h}px`;
67
+ el.style.borderRadius = `${Math.min(Math.max(0, lerp(a.r, b.r)), w / 2, h / 2)}px`;
68
+ }
69
+ function CopyDisc({ status }) {
70
+ const layer = useRef(null);
71
+ const back = useRef(null);
72
+ const front = useRef(null);
73
+ const progress = useMotionValue(0);
74
+ const reduced = useReduceMotion();
75
+ const gooId = `copy-goo-${useId().replace(/:/g, "")}`;
76
+ const tone = useRef("copied");
77
+ const on = status !== "idle";
78
+ if (on)
79
+ tone.current = status;
80
+ useLayoutEffect(() => {
81
+ if (!on && progress.get() === 0)
82
+ return;
83
+ const render = (p) => {
84
+ if (layer.current)
85
+ layer.current.style.visibility = p > 0 ? "visible" : "hidden";
86
+ placeSheet(back.current, BACK, DISC_RECT, p);
87
+ placeSheet(front.current, FRONT, DISC_RECT, p);
88
+ };
89
+ const target = on ? 1 : 0;
90
+ if (reduced) {
91
+ progress.jump(target);
92
+ return render(target);
93
+ }
94
+ const controls = animate(progress, target, { ...on ? enter : spring2.slow.exit, onUpdate: render });
95
+ return () => controls.stop();
96
+ }, [on, reduced]);
97
+ return /* @__PURE__ */ jsxs("span", {
98
+ "aria-hidden": true,
99
+ className: "pointer-events-none absolute",
100
+ style: { left: LAYER.at, top: LAYER.at, width: LAYER.size, height: LAYER.size },
101
+ children: [
102
+ /* @__PURE__ */ jsx(GooFilter, {
103
+ id: gooId,
104
+ blur: BLUR
105
+ }),
106
+ /* @__PURE__ */ jsxs("span", {
107
+ ref: layer,
108
+ className: "invisible absolute inset-0 opacity-16",
109
+ style: { filter: `url(#${gooId})` },
110
+ children: [
111
+ /* @__PURE__ */ jsx("span", {
112
+ ref: back,
113
+ className: cn2("absolute", TONE_BG[tone.current])
114
+ }),
115
+ /* @__PURE__ */ jsx("span", {
116
+ ref: front,
117
+ className: cn2("absolute", TONE_BG[tone.current])
118
+ })
119
+ ]
120
+ })
121
+ ]
122
+ });
123
+ }
124
+ var CHECK_PATH = "M6 12L10 16L18 8";
125
+ var ERROR_PATH = "M9 9L15 15M15 9L9 15";
126
+ function CopyGlyph({
127
+ status,
128
+ copyCount,
129
+ variant,
130
+ CopyIcon
131
+ }) {
132
+ return /* @__PURE__ */ jsxs("span", {
133
+ className: "relative flex size-3.5 shrink-0 items-center justify-center",
134
+ children: [
135
+ /* @__PURE__ */ jsx(CopyDisc, {
136
+ status
137
+ }),
138
+ /* @__PURE__ */ jsx(AnimatePresence, {
139
+ initial: false,
140
+ children: status === "idle" ? /* @__PURE__ */ jsx(motion.span, {
141
+ initial: { opacity: 0, scale: 0.8 },
142
+ animate: { opacity: 1, scale: 1 },
143
+ exit: { opacity: 0, scale: 0.8, transition: spring2.fast.exit },
144
+ transition: spring2.fast,
145
+ className: "absolute inset-0 flex items-center justify-center",
146
+ children: /* @__PURE__ */ jsx(CopyIcon, {
147
+ size: 14,
148
+ strokeWidth: 1.5,
149
+ className: "transition-[stroke-width] duration-fast group-hover:stroke-[2]"
150
+ })
151
+ }, "copy") : /* @__PURE__ */ jsx(motion.span, {
152
+ initial: { opacity: 0, scale: 0.6 },
153
+ animate: { opacity: 1, scale: 1 },
154
+ exit: { opacity: 0, scale: 0.8, transition: spring2.fast.exit },
155
+ transition: spring2.fast,
156
+ className: cn2("absolute inset-0 flex items-center justify-center", TONE_TEXT[status], CHECK_STROKE[variant]),
157
+ children: /* @__PURE__ */ jsx("svg", {
158
+ width: 14,
159
+ height: 14,
160
+ viewBox: "2 4 20 16",
161
+ fill: "none",
162
+ stroke: "currentColor",
163
+ strokeLinecap: "round",
164
+ strokeLinejoin: "round",
165
+ children: /* @__PURE__ */ jsx(motion.path, {
166
+ d: status === "error" ? ERROR_PATH : CHECK_PATH,
167
+ initial: { pathLength: 0 },
168
+ animate: {
169
+ pathLength: 1,
170
+ transition: { duration: spring2.fast.duration, ease: "easeOut" }
171
+ }
172
+ })
173
+ })
174
+ }, `${status}-${copyCount}`)
175
+ })
176
+ ]
177
+ });
178
+ }
179
+ var InputCopy2 = forwardRef(({ value, label, onCopy, disabled, variant = "icon", align = "right", size, className, ...props }, ref) => {
180
+ const CopyIcon = useIcon("copy");
181
+ const [status, setStatus] = useState("idle");
182
+ const [copyCount, setCopyCount] = useState(0);
183
+ const [tooltipState, setTooltipState] = useState("idle");
184
+ const timeoutRef = useRef(null);
185
+ const tooltipVisibleRef = useRef(false);
186
+ const tooltipWasVisibleRef = useRef(false);
187
+ const shape = useShape();
188
+ const sizeClasses = useSize2(size);
189
+ const rowPy = sizeClasses.variant === "compact" ? "py-1" : "py-2";
190
+ const generatedId = useId();
191
+ const labelId = label ? `${generatedId}-label` : undefined;
192
+ const buttonId = `${generatedId}-button`;
193
+ const handlePointerDown = useCallback(() => {
194
+ tooltipWasVisibleRef.current = tooltipVisibleRef.current;
195
+ }, []);
196
+ const copyViaExecCommand = useCallback(() => {
197
+ const textarea = document.createElement("textarea");
198
+ textarea.value = value;
199
+ textarea.setAttribute("readonly", "");
200
+ textarea.style.position = "fixed";
201
+ textarea.style.opacity = "0";
202
+ document.body.appendChild(textarea);
203
+ textarea.select();
204
+ let ok = false;
205
+ try {
206
+ ok = document.execCommand("copy");
207
+ } catch {
208
+ ok = false;
209
+ }
210
+ document.body.removeChild(textarea);
211
+ return ok;
212
+ }, [value]);
213
+ const handleCopy = useCallback(async () => {
214
+ if (disabled)
215
+ return;
216
+ let ok = true;
217
+ try {
218
+ await navigator.clipboard.writeText(value);
219
+ } catch {
220
+ ok = copyViaExecCommand();
221
+ }
222
+ setStatus(ok ? "copied" : "error");
223
+ setCopyCount((c) => c + 1);
224
+ setTooltipState(tooltipWasVisibleRef.current ? "copied" : "suppressed");
225
+ if (ok)
226
+ onCopy?.();
227
+ if (timeoutRef.current)
228
+ clearTimeout(timeoutRef.current);
229
+ timeoutRef.current = setTimeout(() => {
230
+ setStatus("idle");
231
+ setTooltipState("suppressed");
232
+ }, 2000);
233
+ }, [value, disabled, onCopy, copyViaExecCommand]);
234
+ const handleTooltipOpenChange = useCallback((open) => {
235
+ tooltipVisibleRef.current = open;
236
+ }, []);
237
+ useEffect(() => {
238
+ return () => {
239
+ if (timeoutRef.current)
240
+ clearTimeout(timeoutRef.current);
241
+ };
242
+ }, []);
243
+ const handleMouseEnter = useCallback(() => {
244
+ setTooltipState((prev) => prev === "suppressed" ? "idle" : prev);
245
+ }, []);
246
+ const handleMouseLeave = useCallback(() => {
247
+ setTooltipState((prev) => prev === "copied" ? "suppressed" : prev);
248
+ }, []);
249
+ const actionElement = variant === "button" ? /* @__PURE__ */ jsxs("span", {
250
+ className: cn2("shrink-0 flex items-center gap-1.5 px-1.5 transition-colors duration-fast", rowPy, sizeClasses.text, "text-muted-foreground group-hover:text-foreground", "weight-normal"),
251
+ children: [
252
+ /* @__PURE__ */ jsx(CopyGlyph, {
253
+ status,
254
+ copyCount,
255
+ variant: "button",
256
+ CopyIcon
257
+ }),
258
+ /* @__PURE__ */ jsxs("span", {
259
+ className: "select-none inline-grid text-left",
260
+ children: [
261
+ /* @__PURE__ */ jsx("span", {
262
+ className: "col-start-1 row-start-1 invisible",
263
+ "aria-hidden": "true",
264
+ children: "Copied"
265
+ }),
266
+ /* @__PURE__ */ jsx(AnimatePresence, {
267
+ mode: "wait",
268
+ initial: false,
269
+ children: /* @__PURE__ */ jsx(motion.span, {
270
+ className: cn2("col-start-1 row-start-1", status === "error" && "text-destructive"),
271
+ initial: { opacity: 0, scale: 0.6 },
272
+ animate: { opacity: 1, scale: 1 },
273
+ exit: { opacity: 0, scale: 0.8, transition: spring2.fast.exit },
274
+ transition: spring2.fast,
275
+ children: status === "copied" ? "Copied" : status === "error" ? "Failed" : "Copy"
276
+ }, status)
277
+ })
278
+ ]
279
+ })
280
+ ]
281
+ }) : /* @__PURE__ */ jsx("span", {
282
+ className: cn2("shrink-0 flex px-1.5 transition-colors duration-fast", rowPy, "text-muted-foreground group-hover:text-foreground"),
283
+ children: /* @__PURE__ */ jsx(CopyGlyph, {
284
+ status,
285
+ copyCount,
286
+ variant: "icon",
287
+ CopyIcon
288
+ })
289
+ });
290
+ const valueElement = /* @__PURE__ */ jsx("span", {
291
+ className: cn2("flex-1 min-w-0 text-left text-foreground font-mono select-none truncate", sizeClasses.text, rowPy, align === "left" ? "pl-1" : "pl-0", "weight-normal"),
292
+ children: /* @__PURE__ */ jsx("mark", {
293
+ className: "bg-transparent text-foreground transition-colors duration-fast group-hover:bg-brand/20 group-hover:text-foreground",
294
+ children: value
295
+ })
296
+ });
297
+ const buttonContent = align === "left" ? /* @__PURE__ */ jsxs(Fragment, {
298
+ children: [
299
+ actionElement,
300
+ valueElement
301
+ ]
302
+ }) : /* @__PURE__ */ jsxs(Fragment, {
303
+ children: [
304
+ valueElement,
305
+ actionElement
306
+ ]
307
+ });
308
+ const button = /* @__PURE__ */ jsx("button", {
309
+ id: buttonId,
310
+ type: "button",
311
+ onPointerDown: handlePointerDown,
312
+ onClick: handleCopy,
313
+ disabled,
314
+ "aria-label": status === "copied" ? "Copied" : status === "error" ? "Copy failed" : label ? "Copy" : "Copy to clipboard",
315
+ "aria-labelledby": label ? `${buttonId} ${labelId}` : undefined,
316
+ className: cn2("group flex items-center w-full cursor-pointer outline-none transition-all duration-fast", "focus-visible:ring-1 focus-visible:ring-focus-ring", shape.input),
317
+ children: buttonContent
318
+ });
319
+ return /* @__PURE__ */ jsxs("div", {
320
+ ref,
321
+ className: cn2("flex flex-col gap-0.5", disabled && "opacity-50 pointer-events-none", className),
322
+ onMouseEnter: handleMouseEnter,
323
+ onMouseLeave: handleMouseLeave,
324
+ ...props,
325
+ children: [
326
+ label && /* @__PURE__ */ jsx("span", {
327
+ id: labelId,
328
+ className: cn2("text-muted-foreground", sizeClasses.text, align === "left" ? "pl-1" : "pl-0", "weight-normal"),
329
+ children: label
330
+ }),
331
+ variant === "icon" ? /* @__PURE__ */ jsx(Tooltip2, {
332
+ content: tooltipState === "idle" ? "Copy to clipboard" : status === "error" ? "Copy failed" : "Copied",
333
+ delayDuration: 500,
334
+ sideOffset: 2,
335
+ forceOpen: tooltipState === "copied" ? true : tooltipState === "suppressed" ? false : undefined,
336
+ onOpenChange: handleTooltipOpenChange,
337
+ children: button
338
+ }) : button
339
+ ]
340
+ });
341
+ });
342
+ InputCopy2.displayName = "InputCopy";
343
+ var input_copy_default = InputCopy2;
344
+
345
+ export { InputCopy2, input_copy_default };