@nori-ui/core 1.7.0 → 1.8.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.
- package/dist/chunk-BOMPFNM4.js +165 -0
- package/dist/chunk-BOMPFNM4.js.map +1 -0
- package/dist/chunk-BVLOX4A3.js +256 -0
- package/dist/chunk-BVLOX4A3.js.map +1 -0
- package/dist/chunk-VFUV6XJR.js +257 -0
- package/dist/chunk-VFUV6XJR.js.map +1 -0
- package/dist/client.cjs +650 -0
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +3 -0
- package/dist/client.d.ts +3 -0
- package/dist/client.js +14 -11
- package/dist/client.js.map +1 -1
- package/dist/components/Carousel/index.cjs +297 -0
- package/dist/components/Carousel/index.cjs.map +1 -0
- package/dist/components/Carousel/index.d.cts +67 -0
- package/dist/components/Carousel/index.d.ts +67 -0
- package/dist/components/Carousel/index.js +5 -0
- package/dist/components/Carousel/index.js.map +1 -0
- package/dist/components/HoverCard/index.cjs +894 -0
- package/dist/components/HoverCard/index.cjs.map +1 -0
- package/dist/components/HoverCard/index.d.cts +66 -0
- package/dist/components/HoverCard/index.d.ts +66 -0
- package/dist/components/HoverCard/index.js +9 -0
- package/dist/components/HoverCard/index.js.map +1 -0
- package/dist/components/InputOTP/index.cjs +580 -0
- package/dist/components/InputOTP/index.cjs.map +1 -0
- package/dist/components/InputOTP/index.d.cts +49 -0
- package/dist/components/InputOTP/index.d.ts +49 -0
- package/dist/components/InputOTP/index.js +7 -0
- package/dist/components/InputOTP/index.js.map +1 -0
- package/dist/index.cjs +650 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +14 -11
- package/package.json +1 -1
|
@@ -0,0 +1,894 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var reactNative = require('react-native');
|
|
5
|
+
var jsxRuntime = require('nativewind/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
+
|
|
10
|
+
// src/slot/compose-refs.ts
|
|
11
|
+
function composeRefs(...refs) {
|
|
12
|
+
return (node) => {
|
|
13
|
+
for (const ref of refs) {
|
|
14
|
+
if (ref == null) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (typeof ref === "function") {
|
|
18
|
+
ref(node);
|
|
19
|
+
} else {
|
|
20
|
+
ref.current = node;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
__name(composeRefs, "composeRefs");
|
|
26
|
+
var Slot = react.forwardRef(/* @__PURE__ */ __name(function Slot2(props, forwardedRef) {
|
|
27
|
+
const { children, ...slotProps } = props;
|
|
28
|
+
if (!react.isValidElement(children)) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const child = react.Children.only(children);
|
|
32
|
+
const merged = mergeProps(slotProps, child.props);
|
|
33
|
+
const childRef = child.ref;
|
|
34
|
+
if (forwardedRef || childRef) {
|
|
35
|
+
merged.ref = composeRefs(forwardedRef, childRef);
|
|
36
|
+
}
|
|
37
|
+
return react.cloneElement(child, merged);
|
|
38
|
+
}, "Slot"));
|
|
39
|
+
Slot.displayName = "Slot";
|
|
40
|
+
function mergeProps(outer, inner) {
|
|
41
|
+
const merged = { ...outer };
|
|
42
|
+
for (const key of Object.keys(inner)) {
|
|
43
|
+
const outerValue = outer[key];
|
|
44
|
+
const innerValue = inner[key];
|
|
45
|
+
if (key === "className" || key === "class") {
|
|
46
|
+
merged[key] = joinClass(outerValue, innerValue);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (key === "style") {
|
|
50
|
+
merged[key] = {
|
|
51
|
+
...outerValue,
|
|
52
|
+
...innerValue
|
|
53
|
+
};
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (isEventHandler(key, outerValue, innerValue)) {
|
|
57
|
+
merged[key] = composeHandlers(outerValue, innerValue);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
merged[key] = innerValue;
|
|
61
|
+
}
|
|
62
|
+
return merged;
|
|
63
|
+
}
|
|
64
|
+
__name(mergeProps, "mergeProps");
|
|
65
|
+
function joinClass(outer, inner) {
|
|
66
|
+
const a = typeof outer === "string" ? outer : "";
|
|
67
|
+
const b = typeof inner === "string" ? inner : "";
|
|
68
|
+
const joined = [a, b].filter(Boolean).join(" ");
|
|
69
|
+
return joined.length > 0 ? joined : void 0;
|
|
70
|
+
}
|
|
71
|
+
__name(joinClass, "joinClass");
|
|
72
|
+
function isEventHandler(key, outer, inner) {
|
|
73
|
+
if (!key.startsWith("on") || key.length < 3) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
if (key[2] !== key[2]?.toUpperCase()) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
return typeof outer === "function" && typeof inner === "function";
|
|
80
|
+
}
|
|
81
|
+
__name(isEventHandler, "isEventHandler");
|
|
82
|
+
function composeHandlers(outer, inner) {
|
|
83
|
+
return (...args) => {
|
|
84
|
+
outer(...args);
|
|
85
|
+
inner(...args);
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
__name(composeHandlers, "composeHandlers");
|
|
89
|
+
|
|
90
|
+
// src/theme/px.ts
|
|
91
|
+
function px(value) {
|
|
92
|
+
if (typeof value === "number") {
|
|
93
|
+
return value;
|
|
94
|
+
}
|
|
95
|
+
const n = Number.parseFloat(value);
|
|
96
|
+
return Number.isFinite(n) ? n : 0;
|
|
97
|
+
}
|
|
98
|
+
__name(px, "px");
|
|
99
|
+
|
|
100
|
+
// ../tokens/build/theme.ts
|
|
101
|
+
var theme = {
|
|
102
|
+
color: {
|
|
103
|
+
danger: "#ef4444",
|
|
104
|
+
info: "#3b82f6",
|
|
105
|
+
neutral: {
|
|
106
|
+
"100": "#f4f4f5",
|
|
107
|
+
"200": "#e4e4e7",
|
|
108
|
+
"300": "#d4d4d8",
|
|
109
|
+
"400": "#a1a1aa",
|
|
110
|
+
"50": "#fafafa",
|
|
111
|
+
"500": "#71717a",
|
|
112
|
+
"600": "#52525b",
|
|
113
|
+
"700": "#3f3f46",
|
|
114
|
+
"800": "#27272a",
|
|
115
|
+
"900": "#18181b"
|
|
116
|
+
},
|
|
117
|
+
primary: {
|
|
118
|
+
"100": "#ccfbf1",
|
|
119
|
+
"200": "#99f6e4",
|
|
120
|
+
"300": "#5eead4",
|
|
121
|
+
"400": "#2dd4bf",
|
|
122
|
+
"50": "#f0fdfa",
|
|
123
|
+
"500": "#14b8a6",
|
|
124
|
+
"600": "#0d9488",
|
|
125
|
+
"700": "#0f766e",
|
|
126
|
+
"800": "#115e59",
|
|
127
|
+
"900": "#134e4a"
|
|
128
|
+
},
|
|
129
|
+
success: "#22c55e",
|
|
130
|
+
warning: "#f59e0b"
|
|
131
|
+
},
|
|
132
|
+
fontFamily: {
|
|
133
|
+
body: "system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
|
|
134
|
+
display: "ui-serif, Georgia, 'Times New Roman', serif",
|
|
135
|
+
mono: "ui-monospace, 'SF Mono', Menlo, Consolas, 'DejaVu Sans Mono', monospace"
|
|
136
|
+
},
|
|
137
|
+
fontSize: {
|
|
138
|
+
"2xl": "24px",
|
|
139
|
+
"3xl": "30px",
|
|
140
|
+
"4xl": "36px",
|
|
141
|
+
lg: "18px",
|
|
142
|
+
md: "16px",
|
|
143
|
+
sm: "14px",
|
|
144
|
+
xl: "20px",
|
|
145
|
+
xs: "12px"
|
|
146
|
+
},
|
|
147
|
+
fontWeight: {
|
|
148
|
+
bold: "700",
|
|
149
|
+
medium: "500",
|
|
150
|
+
regular: "400",
|
|
151
|
+
semibold: "600"
|
|
152
|
+
},
|
|
153
|
+
lineHeight: {
|
|
154
|
+
normal: "1.4",
|
|
155
|
+
relaxed: "1.6",
|
|
156
|
+
tight: "1.2"
|
|
157
|
+
},
|
|
158
|
+
radius: {
|
|
159
|
+
"2xl": "16px",
|
|
160
|
+
full: "9999px",
|
|
161
|
+
lg: "8px",
|
|
162
|
+
md: "6px",
|
|
163
|
+
none: "0px",
|
|
164
|
+
sm: "4px",
|
|
165
|
+
xl: "12px"
|
|
166
|
+
},
|
|
167
|
+
semantic: {
|
|
168
|
+
background: {
|
|
169
|
+
default: "#fafafa",
|
|
170
|
+
elevated: "#ffffff",
|
|
171
|
+
subtle: "#f4f4f5"
|
|
172
|
+
},
|
|
173
|
+
border: {
|
|
174
|
+
default: "#e4e4e7",
|
|
175
|
+
strong: "#d4d4d8"
|
|
176
|
+
},
|
|
177
|
+
interactive: {
|
|
178
|
+
destructive: "#ef4444",
|
|
179
|
+
primary: "#0d9488",
|
|
180
|
+
primaryHover: "#0f766e",
|
|
181
|
+
primaryPressed: "#115e59"
|
|
182
|
+
},
|
|
183
|
+
text: {
|
|
184
|
+
default: "#18181b",
|
|
185
|
+
inverted: "#fafafa",
|
|
186
|
+
muted: "#52525b"
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
shadow: {
|
|
190
|
+
lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)",
|
|
191
|
+
md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)",
|
|
192
|
+
sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)"
|
|
193
|
+
},
|
|
194
|
+
spacing: {
|
|
195
|
+
"0": "0px",
|
|
196
|
+
"1": "4px",
|
|
197
|
+
"10": "40px",
|
|
198
|
+
"12": "48px",
|
|
199
|
+
"16": "64px",
|
|
200
|
+
"2": "8px",
|
|
201
|
+
"20": "80px",
|
|
202
|
+
"24": "96px",
|
|
203
|
+
"3": "12px",
|
|
204
|
+
"4": "16px",
|
|
205
|
+
"5": "20px",
|
|
206
|
+
"6": "24px",
|
|
207
|
+
"8": "32px"
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
var themeDark = {
|
|
211
|
+
color: {
|
|
212
|
+
danger: "#ef4444",
|
|
213
|
+
info: "#3b82f6",
|
|
214
|
+
neutral: {
|
|
215
|
+
"100": "#f4f4f5",
|
|
216
|
+
"200": "#e4e4e7",
|
|
217
|
+
"300": "#d4d4d8",
|
|
218
|
+
"400": "#a1a1aa",
|
|
219
|
+
"50": "#fafafa",
|
|
220
|
+
"500": "#71717a",
|
|
221
|
+
"600": "#52525b",
|
|
222
|
+
"700": "#3f3f46",
|
|
223
|
+
"800": "#27272a",
|
|
224
|
+
"900": "#18181b"
|
|
225
|
+
},
|
|
226
|
+
primary: {
|
|
227
|
+
"100": "#ccfbf1",
|
|
228
|
+
"200": "#99f6e4",
|
|
229
|
+
"300": "#5eead4",
|
|
230
|
+
"400": "#2dd4bf",
|
|
231
|
+
"50": "#f0fdfa",
|
|
232
|
+
"500": "#14b8a6",
|
|
233
|
+
"600": "#0d9488",
|
|
234
|
+
"700": "#0f766e",
|
|
235
|
+
"800": "#115e59",
|
|
236
|
+
"900": "#134e4a"
|
|
237
|
+
},
|
|
238
|
+
success: "#22c55e",
|
|
239
|
+
warning: "#f59e0b"
|
|
240
|
+
},
|
|
241
|
+
fontFamily: {
|
|
242
|
+
body: "system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
|
|
243
|
+
display: "ui-serif, Georgia, 'Times New Roman', serif",
|
|
244
|
+
mono: "ui-monospace, 'SF Mono', Menlo, Consolas, 'DejaVu Sans Mono', monospace"
|
|
245
|
+
},
|
|
246
|
+
fontSize: {
|
|
247
|
+
"2xl": "24px",
|
|
248
|
+
"3xl": "30px",
|
|
249
|
+
"4xl": "36px",
|
|
250
|
+
lg: "18px",
|
|
251
|
+
md: "16px",
|
|
252
|
+
sm: "14px",
|
|
253
|
+
xl: "20px",
|
|
254
|
+
xs: "12px"
|
|
255
|
+
},
|
|
256
|
+
fontWeight: {
|
|
257
|
+
bold: "700",
|
|
258
|
+
medium: "500",
|
|
259
|
+
regular: "400",
|
|
260
|
+
semibold: "600"
|
|
261
|
+
},
|
|
262
|
+
lineHeight: {
|
|
263
|
+
normal: "1.4",
|
|
264
|
+
relaxed: "1.6",
|
|
265
|
+
tight: "1.2"
|
|
266
|
+
},
|
|
267
|
+
radius: {
|
|
268
|
+
"2xl": "16px",
|
|
269
|
+
full: "9999px",
|
|
270
|
+
lg: "8px",
|
|
271
|
+
md: "6px",
|
|
272
|
+
none: "0px",
|
|
273
|
+
sm: "4px",
|
|
274
|
+
xl: "12px"
|
|
275
|
+
},
|
|
276
|
+
semantic: {
|
|
277
|
+
background: {
|
|
278
|
+
default: "#18181b",
|
|
279
|
+
elevated: "#3f3f46",
|
|
280
|
+
subtle: "#27272a"
|
|
281
|
+
},
|
|
282
|
+
border: {
|
|
283
|
+
default: "#3f3f46",
|
|
284
|
+
strong: "#52525b"
|
|
285
|
+
},
|
|
286
|
+
interactive: {
|
|
287
|
+
destructive: "#ef4444",
|
|
288
|
+
primary: "#2dd4bf",
|
|
289
|
+
primaryHover: "#5eead4",
|
|
290
|
+
primaryPressed: "#99f6e4"
|
|
291
|
+
},
|
|
292
|
+
text: {
|
|
293
|
+
default: "#fafafa",
|
|
294
|
+
inverted: "#18181b",
|
|
295
|
+
muted: "#a1a1aa"
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
shadow: {
|
|
299
|
+
lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)",
|
|
300
|
+
md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)",
|
|
301
|
+
sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)"
|
|
302
|
+
},
|
|
303
|
+
spacing: {
|
|
304
|
+
"0": "0px",
|
|
305
|
+
"1": "4px",
|
|
306
|
+
"10": "40px",
|
|
307
|
+
"12": "48px",
|
|
308
|
+
"16": "64px",
|
|
309
|
+
"2": "8px",
|
|
310
|
+
"20": "80px",
|
|
311
|
+
"24": "96px",
|
|
312
|
+
"3": "12px",
|
|
313
|
+
"4": "16px",
|
|
314
|
+
"5": "20px",
|
|
315
|
+
"6": "24px",
|
|
316
|
+
"8": "32px"
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
var defaultTheme = {
|
|
320
|
+
light: theme,
|
|
321
|
+
dark: themeDark
|
|
322
|
+
};
|
|
323
|
+
var ThemeContext = react.createContext(defaultTheme);
|
|
324
|
+
ThemeContext.displayName = "ThemeContext";
|
|
325
|
+
var ColorSchemeOverrideContext = react.createContext(null);
|
|
326
|
+
ColorSchemeOverrideContext.displayName = "ColorSchemeOverrideContext";
|
|
327
|
+
var isWeb = reactNative.Platform.OS === "web";
|
|
328
|
+
function readWebScheme() {
|
|
329
|
+
if (typeof document === "undefined") {
|
|
330
|
+
return "light";
|
|
331
|
+
}
|
|
332
|
+
const root = document.documentElement;
|
|
333
|
+
if (root.classList.contains("dark")) {
|
|
334
|
+
return "dark";
|
|
335
|
+
}
|
|
336
|
+
if (root.getAttribute("data-theme") === "dark") {
|
|
337
|
+
return "dark";
|
|
338
|
+
}
|
|
339
|
+
return "light";
|
|
340
|
+
}
|
|
341
|
+
__name(readWebScheme, "readWebScheme");
|
|
342
|
+
function useColorScheme() {
|
|
343
|
+
const override = react.useContext(ColorSchemeOverrideContext);
|
|
344
|
+
const [scheme, setScheme] = react.useState(() => {
|
|
345
|
+
if (isWeb) {
|
|
346
|
+
return readWebScheme();
|
|
347
|
+
}
|
|
348
|
+
return reactNative.Appearance.getColorScheme() ?? "light";
|
|
349
|
+
});
|
|
350
|
+
react.useEffect(() => {
|
|
351
|
+
if (isWeb) {
|
|
352
|
+
const root = document.documentElement;
|
|
353
|
+
const update = /* @__PURE__ */ __name(() => setScheme(readWebScheme()), "update");
|
|
354
|
+
const observer = new MutationObserver(update);
|
|
355
|
+
observer.observe(root, { attributes: true, attributeFilter: ["class", "data-theme"] });
|
|
356
|
+
update();
|
|
357
|
+
return () => observer.disconnect();
|
|
358
|
+
}
|
|
359
|
+
const sub = reactNative.Appearance.addChangeListener(({ colorScheme }) => {
|
|
360
|
+
setScheme(colorScheme ?? "light");
|
|
361
|
+
});
|
|
362
|
+
return () => sub.remove();
|
|
363
|
+
}, []);
|
|
364
|
+
return override ?? scheme;
|
|
365
|
+
}
|
|
366
|
+
__name(useColorScheme, "useColorScheme");
|
|
367
|
+
|
|
368
|
+
// src/theme/use-theme-colors.ts
|
|
369
|
+
function useThemeColors() {
|
|
370
|
+
const scheme = useColorScheme();
|
|
371
|
+
const themePair = react.useContext(ThemeContext);
|
|
372
|
+
return scheme === "dark" ? themePair.dark : themePair.light;
|
|
373
|
+
}
|
|
374
|
+
__name(useThemeColors, "useThemeColors");
|
|
375
|
+
|
|
376
|
+
// src/utils/cn.ts
|
|
377
|
+
function cn(...inputs) {
|
|
378
|
+
const out = [];
|
|
379
|
+
for (const input of inputs) {
|
|
380
|
+
append(out, input);
|
|
381
|
+
}
|
|
382
|
+
return out.join(" ");
|
|
383
|
+
}
|
|
384
|
+
__name(cn, "cn");
|
|
385
|
+
function append(out, input) {
|
|
386
|
+
if (!input) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
if (typeof input === "string") {
|
|
390
|
+
if (input.length > 0) {
|
|
391
|
+
out.push(input);
|
|
392
|
+
}
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
if (typeof input === "number") {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
if (Array.isArray(input)) {
|
|
399
|
+
for (const inner of input) {
|
|
400
|
+
append(out, inner);
|
|
401
|
+
}
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (typeof input === "object") {
|
|
405
|
+
for (const key of Object.keys(input)) {
|
|
406
|
+
if (input[key]) {
|
|
407
|
+
out.push(key);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
__name(append, "append");
|
|
413
|
+
var PopoverContext = react.createContext(null);
|
|
414
|
+
var usePopoverContext = /* @__PURE__ */ __name((label) => {
|
|
415
|
+
const ctx = react.useContext(PopoverContext);
|
|
416
|
+
if (!ctx) {
|
|
417
|
+
throw new Error(`<${label}> must be rendered inside a <Popover>.`);
|
|
418
|
+
}
|
|
419
|
+
return ctx;
|
|
420
|
+
}, "usePopoverContext");
|
|
421
|
+
var PopoverRoot = /* @__PURE__ */ __name(({ open, defaultOpen = false, onOpenChange, children }) => {
|
|
422
|
+
const [inner, setInner] = react.useState(defaultOpen);
|
|
423
|
+
const isControlled = open !== void 0;
|
|
424
|
+
const current = isControlled ? open : inner;
|
|
425
|
+
const setOpen = react.useCallback(
|
|
426
|
+
(next) => {
|
|
427
|
+
if (!isControlled) {
|
|
428
|
+
setInner(next);
|
|
429
|
+
}
|
|
430
|
+
onOpenChange?.(next);
|
|
431
|
+
},
|
|
432
|
+
[isControlled, onOpenChange]
|
|
433
|
+
);
|
|
434
|
+
const baseId = react.useId();
|
|
435
|
+
const triggerRef = react.useRef(null);
|
|
436
|
+
const contentRef = react.useRef(null);
|
|
437
|
+
const [triggerRect, setTriggerRect] = react.useState(null);
|
|
438
|
+
const measureTrigger = react.useCallback(() => {
|
|
439
|
+
const node = triggerRef.current;
|
|
440
|
+
if (!node || typeof node.getBoundingClientRect !== "function") {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
const rect = node.getBoundingClientRect();
|
|
444
|
+
setTriggerRect({ top: rect.top, left: rect.left, width: rect.width, height: rect.height });
|
|
445
|
+
}, []);
|
|
446
|
+
const ctxValue = {
|
|
447
|
+
open: current,
|
|
448
|
+
setOpen,
|
|
449
|
+
contentId: `${baseId}-content`,
|
|
450
|
+
triggerRef,
|
|
451
|
+
contentRef,
|
|
452
|
+
triggerRect,
|
|
453
|
+
measureTrigger
|
|
454
|
+
};
|
|
455
|
+
return /* @__PURE__ */ jsxRuntime.jsx(PopoverContext.Provider, { value: ctxValue, children });
|
|
456
|
+
}, "PopoverRoot");
|
|
457
|
+
var PopoverTrigger = /* @__PURE__ */ __name(({ asChild = true, children, className, testID }) => {
|
|
458
|
+
const ctx = usePopoverContext("PopoverTrigger");
|
|
459
|
+
const onPress = react.useCallback(() => {
|
|
460
|
+
ctx.measureTrigger();
|
|
461
|
+
ctx.setOpen(!ctx.open);
|
|
462
|
+
}, [ctx]);
|
|
463
|
+
if (asChild && react.isValidElement(children)) {
|
|
464
|
+
const child = children;
|
|
465
|
+
const fire = /* @__PURE__ */ __name((existing) => (event) => {
|
|
466
|
+
existing?.(event);
|
|
467
|
+
ctx.measureTrigger();
|
|
468
|
+
ctx.setOpen(!ctx.open);
|
|
469
|
+
}, "fire");
|
|
470
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
471
|
+
Slot,
|
|
472
|
+
{
|
|
473
|
+
ref: (node) => {
|
|
474
|
+
ctx.triggerRef.current = node;
|
|
475
|
+
},
|
|
476
|
+
onClick: fire(child.props.onClick),
|
|
477
|
+
onPress: fire(child.props.onPress),
|
|
478
|
+
"aria-haspopup": "dialog",
|
|
479
|
+
"aria-expanded": ctx.open,
|
|
480
|
+
"aria-controls": ctx.contentId,
|
|
481
|
+
...testID !== void 0 ? { "data-testid": testID } : {},
|
|
482
|
+
...className !== void 0 ? { className } : {},
|
|
483
|
+
children: child
|
|
484
|
+
}
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
488
|
+
reactNative.Pressable,
|
|
489
|
+
{
|
|
490
|
+
ref: (node) => {
|
|
491
|
+
ctx.triggerRef.current = node;
|
|
492
|
+
},
|
|
493
|
+
onPress,
|
|
494
|
+
...{
|
|
495
|
+
"aria-haspopup": "dialog",
|
|
496
|
+
"aria-expanded": ctx.open,
|
|
497
|
+
"aria-controls": ctx.contentId
|
|
498
|
+
},
|
|
499
|
+
...testID !== void 0 ? { testID } : {},
|
|
500
|
+
...className !== void 0 ? { className } : {},
|
|
501
|
+
children: wrapStringChildren(children)
|
|
502
|
+
}
|
|
503
|
+
);
|
|
504
|
+
}, "PopoverTrigger");
|
|
505
|
+
function wrapStringChildren(children) {
|
|
506
|
+
if (typeof children === "string" || typeof children === "number") {
|
|
507
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { children });
|
|
508
|
+
}
|
|
509
|
+
return children;
|
|
510
|
+
}
|
|
511
|
+
__name(wrapStringChildren, "wrapStringChildren");
|
|
512
|
+
var GAP = 4;
|
|
513
|
+
var MIN_WIDTH = 200;
|
|
514
|
+
var VIEWPORT_MARGIN = 8;
|
|
515
|
+
function computePosition(rect, side, align, contentSize) {
|
|
516
|
+
const cw = contentSize?.width ?? MIN_WIDTH;
|
|
517
|
+
const ch = contentSize?.height ?? 0;
|
|
518
|
+
let top = 0;
|
|
519
|
+
let left = 0;
|
|
520
|
+
switch (side) {
|
|
521
|
+
case "top":
|
|
522
|
+
top = rect.top - GAP - ch;
|
|
523
|
+
break;
|
|
524
|
+
case "bottom":
|
|
525
|
+
top = rect.top + rect.height + GAP;
|
|
526
|
+
break;
|
|
527
|
+
case "left":
|
|
528
|
+
left = rect.left - GAP - cw;
|
|
529
|
+
break;
|
|
530
|
+
case "right":
|
|
531
|
+
left = rect.left + rect.width + GAP;
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
534
|
+
if (side === "top" || side === "bottom") {
|
|
535
|
+
switch (align) {
|
|
536
|
+
case "start":
|
|
537
|
+
left = rect.left;
|
|
538
|
+
break;
|
|
539
|
+
case "center":
|
|
540
|
+
left = rect.left + rect.width / 2 - cw / 2;
|
|
541
|
+
break;
|
|
542
|
+
case "end":
|
|
543
|
+
left = rect.left + rect.width - cw;
|
|
544
|
+
break;
|
|
545
|
+
}
|
|
546
|
+
} else {
|
|
547
|
+
switch (align) {
|
|
548
|
+
case "start":
|
|
549
|
+
top = rect.top;
|
|
550
|
+
break;
|
|
551
|
+
case "center":
|
|
552
|
+
top = rect.top + rect.height / 2 - ch / 2;
|
|
553
|
+
break;
|
|
554
|
+
case "end":
|
|
555
|
+
top = rect.top + rect.height - ch;
|
|
556
|
+
break;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
return { top, left };
|
|
560
|
+
}
|
|
561
|
+
__name(computePosition, "computePosition");
|
|
562
|
+
var PopoverContent = /* @__PURE__ */ __name(({
|
|
563
|
+
side = "bottom",
|
|
564
|
+
align = "center",
|
|
565
|
+
children,
|
|
566
|
+
className,
|
|
567
|
+
testID,
|
|
568
|
+
...rest
|
|
569
|
+
}) => {
|
|
570
|
+
const ctx = usePopoverContext("PopoverContent");
|
|
571
|
+
const colors = useThemeColors();
|
|
572
|
+
const ariaLabel = rest["aria-label"];
|
|
573
|
+
const [contentSize, setContentSize] = react.useState(null);
|
|
574
|
+
react.useEffect(() => {
|
|
575
|
+
if (!ctx.open) {
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
if (reactNative.Platform.OS !== "web") {
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
if (typeof document === "undefined") {
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
ctx.measureTrigger();
|
|
585
|
+
const onDocMouseDown = /* @__PURE__ */ __name((event) => {
|
|
586
|
+
const target = event.target;
|
|
587
|
+
const trigger = ctx.triggerRef.current;
|
|
588
|
+
const content2 = ctx.contentRef.current;
|
|
589
|
+
if (trigger?.contains(target)) {
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
if (content2?.contains(target)) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
ctx.setOpen(false);
|
|
596
|
+
}, "onDocMouseDown");
|
|
597
|
+
const onKeyDown = /* @__PURE__ */ __name((event) => {
|
|
598
|
+
if (event.key === "Escape") {
|
|
599
|
+
event.preventDefault();
|
|
600
|
+
ctx.setOpen(false);
|
|
601
|
+
}
|
|
602
|
+
}, "onKeyDown");
|
|
603
|
+
const onResize = /* @__PURE__ */ __name(() => ctx.measureTrigger(), "onResize");
|
|
604
|
+
const onScroll = /* @__PURE__ */ __name(() => ctx.measureTrigger(), "onScroll");
|
|
605
|
+
document.addEventListener("mousedown", onDocMouseDown);
|
|
606
|
+
document.addEventListener("keydown", onKeyDown);
|
|
607
|
+
window.addEventListener("resize", onResize);
|
|
608
|
+
window.addEventListener("scroll", onScroll, true);
|
|
609
|
+
return () => {
|
|
610
|
+
document.removeEventListener("mousedown", onDocMouseDown);
|
|
611
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
612
|
+
window.removeEventListener("resize", onResize);
|
|
613
|
+
window.removeEventListener("scroll", onScroll, true);
|
|
614
|
+
};
|
|
615
|
+
}, [ctx.open, ctx.measureTrigger, ctx.setOpen, ctx.triggerRef, ctx.contentRef]);
|
|
616
|
+
react.useEffect(() => {
|
|
617
|
+
if (!ctx.open) {
|
|
618
|
+
setContentSize(null);
|
|
619
|
+
}
|
|
620
|
+
}, [ctx.open]);
|
|
621
|
+
if (!ctx.open) {
|
|
622
|
+
return null;
|
|
623
|
+
}
|
|
624
|
+
const position = ctx.triggerRect ? computePosition(ctx.triggerRect, side, align, contentSize) : null;
|
|
625
|
+
const viewportWidth = reactNative.Dimensions.get("window").width;
|
|
626
|
+
const maxContentWidth = Math.max(MIN_WIDTH, viewportWidth - VIEWPORT_MARGIN * 2);
|
|
627
|
+
const contentBaseStyle = {
|
|
628
|
+
minWidth: MIN_WIDTH,
|
|
629
|
+
maxWidth: maxContentWidth,
|
|
630
|
+
borderRadius: px(colors.radius.lg),
|
|
631
|
+
borderWidth: 1,
|
|
632
|
+
borderColor: colors.semantic.border.default,
|
|
633
|
+
backgroundColor: colors.semantic.background.elevated,
|
|
634
|
+
padding: px(colors.spacing["4"]),
|
|
635
|
+
...reactNative.Platform.OS === "web" ? {
|
|
636
|
+
boxShadow: "0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1)",
|
|
637
|
+
// Subtle scale-in. Skipped on native (do nothing fancy there).
|
|
638
|
+
transition: "opacity 120ms ease-out, transform 120ms ease-out",
|
|
639
|
+
transform: "scale(1)",
|
|
640
|
+
opacity: 1
|
|
641
|
+
} : { elevation: 8 }
|
|
642
|
+
};
|
|
643
|
+
const measuredWidth = contentSize?.width ?? maxContentWidth;
|
|
644
|
+
const clampedLeft = position ? Math.min(
|
|
645
|
+
Math.max(VIEWPORT_MARGIN, position.left),
|
|
646
|
+
Math.max(VIEWPORT_MARGIN, viewportWidth - measuredWidth - VIEWPORT_MARGIN)
|
|
647
|
+
) : 0;
|
|
648
|
+
const positionedStyle = reactNative.Platform.OS === "web" ? position ? {
|
|
649
|
+
position: "fixed",
|
|
650
|
+
top: position.top,
|
|
651
|
+
left: clampedLeft,
|
|
652
|
+
zIndex: 50
|
|
653
|
+
} : {
|
|
654
|
+
// Trigger not yet measured — render off-screen for a
|
|
655
|
+
// frame to avoid a flash at (0,0).
|
|
656
|
+
position: "fixed",
|
|
657
|
+
top: -9999,
|
|
658
|
+
left: -9999,
|
|
659
|
+
zIndex: 50
|
|
660
|
+
} : {};
|
|
661
|
+
const content = /* @__PURE__ */ jsxRuntime.jsx(
|
|
662
|
+
reactNative.View,
|
|
663
|
+
{
|
|
664
|
+
ref: (node) => {
|
|
665
|
+
ctx.contentRef.current = node;
|
|
666
|
+
if (reactNative.Platform.OS !== "web") {
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
if (!node) {
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
if (typeof node.getBoundingClientRect !== "function") {
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
const rect = node.getBoundingClientRect();
|
|
676
|
+
if (!contentSize || contentSize.width !== rect.width || contentSize.height !== rect.height) {
|
|
677
|
+
setContentSize({ width: rect.width, height: rect.height });
|
|
678
|
+
}
|
|
679
|
+
},
|
|
680
|
+
...{
|
|
681
|
+
role: "dialog",
|
|
682
|
+
id: ctx.contentId,
|
|
683
|
+
...ariaLabel !== void 0 ? { "aria-label": ariaLabel, accessibilityLabel: ariaLabel } : {}
|
|
684
|
+
},
|
|
685
|
+
...testID !== void 0 ? { testID } : {},
|
|
686
|
+
className: cn(
|
|
687
|
+
"rounded-lg border border-semantic-border-default bg-semantic-background-elevated",
|
|
688
|
+
className
|
|
689
|
+
),
|
|
690
|
+
style: [contentBaseStyle, positionedStyle],
|
|
691
|
+
children
|
|
692
|
+
}
|
|
693
|
+
);
|
|
694
|
+
if (reactNative.Platform.OS === "web") {
|
|
695
|
+
return content;
|
|
696
|
+
}
|
|
697
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Modal, { visible: ctx.open, transparent: true, animationType: "fade", onRequestClose: () => ctx.setOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
698
|
+
reactNative.Pressable,
|
|
699
|
+
{
|
|
700
|
+
accessibilityRole: "none",
|
|
701
|
+
"aria-hidden": true,
|
|
702
|
+
onPress: () => ctx.setOpen(false),
|
|
703
|
+
style: {
|
|
704
|
+
position: "absolute",
|
|
705
|
+
top: 0,
|
|
706
|
+
left: 0,
|
|
707
|
+
right: 0,
|
|
708
|
+
bottom: 0,
|
|
709
|
+
backgroundColor: "transparent"
|
|
710
|
+
},
|
|
711
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
712
|
+
reactNative.Pressable,
|
|
713
|
+
{
|
|
714
|
+
onPress: (event) => event.stopPropagation?.(),
|
|
715
|
+
style: {
|
|
716
|
+
position: "absolute",
|
|
717
|
+
top: ctx.triggerRect ? side === "top" ? Math.max(VIEWPORT_MARGIN, ctx.triggerRect.top - GAP - 80) : ctx.triggerRect.top + ctx.triggerRect.height + GAP : 80,
|
|
718
|
+
// Clamp horizontally so a wide popover near the
|
|
719
|
+
// right edge can still grow leftward without
|
|
720
|
+
// overflowing the screen.
|
|
721
|
+
left: ctx.triggerRect ? Math.min(
|
|
722
|
+
Math.max(VIEWPORT_MARGIN, ctx.triggerRect.left),
|
|
723
|
+
Math.max(VIEWPORT_MARGIN, viewportWidth - measuredWidth - VIEWPORT_MARGIN)
|
|
724
|
+
) : VIEWPORT_MARGIN * 2
|
|
725
|
+
},
|
|
726
|
+
children: content
|
|
727
|
+
}
|
|
728
|
+
)
|
|
729
|
+
}
|
|
730
|
+
) });
|
|
731
|
+
}, "PopoverContent");
|
|
732
|
+
var Popover = Object.assign(PopoverRoot, {
|
|
733
|
+
Trigger: PopoverTrigger,
|
|
734
|
+
Content: PopoverContent
|
|
735
|
+
});
|
|
736
|
+
var HoverCardContext = react.createContext(null);
|
|
737
|
+
function useHoverCardContext(caller) {
|
|
738
|
+
const ctx = react.useContext(HoverCardContext);
|
|
739
|
+
if (!ctx) {
|
|
740
|
+
throw new Error(`<${caller}> must be rendered inside <HoverCard>.`);
|
|
741
|
+
}
|
|
742
|
+
return ctx;
|
|
743
|
+
}
|
|
744
|
+
__name(useHoverCardContext, "useHoverCardContext");
|
|
745
|
+
var DEFAULT_OPEN_DELAY = 300;
|
|
746
|
+
var DEFAULT_CLOSE_DELAY = 200;
|
|
747
|
+
var HoverCardRoot = /* @__PURE__ */ __name(({
|
|
748
|
+
open: controlledOpen,
|
|
749
|
+
defaultOpen = false,
|
|
750
|
+
onOpenChange,
|
|
751
|
+
openDelay = DEFAULT_OPEN_DELAY,
|
|
752
|
+
closeDelay = DEFAULT_CLOSE_DELAY,
|
|
753
|
+
children
|
|
754
|
+
}) => {
|
|
755
|
+
const [inner, setInner] = react.useState(defaultOpen);
|
|
756
|
+
const isControlled = controlledOpen !== void 0;
|
|
757
|
+
const open = isControlled ? controlledOpen : inner;
|
|
758
|
+
const id = react.useId();
|
|
759
|
+
const setOpen = react.useCallback(
|
|
760
|
+
(next) => {
|
|
761
|
+
if (!isControlled) {
|
|
762
|
+
setInner(next);
|
|
763
|
+
}
|
|
764
|
+
onOpenChange?.(next);
|
|
765
|
+
},
|
|
766
|
+
[isControlled, onOpenChange]
|
|
767
|
+
);
|
|
768
|
+
const openTimer = react.useRef(null);
|
|
769
|
+
const closeTimer = react.useRef(null);
|
|
770
|
+
const cancelTimers = react.useCallback(() => {
|
|
771
|
+
if (openTimer.current) {
|
|
772
|
+
clearTimeout(openTimer.current);
|
|
773
|
+
openTimer.current = null;
|
|
774
|
+
}
|
|
775
|
+
if (closeTimer.current) {
|
|
776
|
+
clearTimeout(closeTimer.current);
|
|
777
|
+
closeTimer.current = null;
|
|
778
|
+
}
|
|
779
|
+
}, []);
|
|
780
|
+
const requestOpen = react.useCallback(() => {
|
|
781
|
+
if (closeTimer.current) {
|
|
782
|
+
clearTimeout(closeTimer.current);
|
|
783
|
+
closeTimer.current = null;
|
|
784
|
+
}
|
|
785
|
+
if (openTimer.current) {
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
if (openDelay <= 0) {
|
|
789
|
+
setOpen(true);
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
openTimer.current = setTimeout(() => {
|
|
793
|
+
openTimer.current = null;
|
|
794
|
+
setOpen(true);
|
|
795
|
+
}, openDelay);
|
|
796
|
+
}, [openDelay, setOpen]);
|
|
797
|
+
const requestClose = react.useCallback(() => {
|
|
798
|
+
if (openTimer.current) {
|
|
799
|
+
clearTimeout(openTimer.current);
|
|
800
|
+
openTimer.current = null;
|
|
801
|
+
}
|
|
802
|
+
if (closeTimer.current) {
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
if (closeDelay <= 0) {
|
|
806
|
+
setOpen(false);
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
closeTimer.current = setTimeout(() => {
|
|
810
|
+
closeTimer.current = null;
|
|
811
|
+
setOpen(false);
|
|
812
|
+
}, closeDelay);
|
|
813
|
+
}, [closeDelay, setOpen]);
|
|
814
|
+
react.useEffect(() => () => cancelTimers(), [cancelTimers]);
|
|
815
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
816
|
+
HoverCardContext.Provider,
|
|
817
|
+
{
|
|
818
|
+
value: { open, requestOpen, requestClose, cancelTimers, contentId: `hc-content-${id}` },
|
|
819
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Popover, { open, onOpenChange: setOpen, children })
|
|
820
|
+
}
|
|
821
|
+
);
|
|
822
|
+
}, "HoverCardRoot");
|
|
823
|
+
var HoverCardTrigger = /* @__PURE__ */ __name(({ asChild = true, children, className, testID }) => {
|
|
824
|
+
const ctx = useHoverCardContext("HoverCard.Trigger");
|
|
825
|
+
const handleMouseEnter = react.useCallback(() => {
|
|
826
|
+
ctx.cancelTimers();
|
|
827
|
+
ctx.requestOpen();
|
|
828
|
+
}, [ctx]);
|
|
829
|
+
const handleMouseLeave = react.useCallback(() => {
|
|
830
|
+
ctx.requestClose();
|
|
831
|
+
}, [ctx]);
|
|
832
|
+
const handlers = {
|
|
833
|
+
onMouseEnter: handleMouseEnter,
|
|
834
|
+
onMouseLeave: handleMouseLeave,
|
|
835
|
+
"aria-haspopup": "dialog",
|
|
836
|
+
"aria-expanded": ctx.open
|
|
837
|
+
};
|
|
838
|
+
if (asChild && react.isValidElement(children)) {
|
|
839
|
+
const child = children;
|
|
840
|
+
const compose = /* @__PURE__ */ __name((existing, next) => (event) => {
|
|
841
|
+
existing?.(event);
|
|
842
|
+
next(event);
|
|
843
|
+
}, "compose");
|
|
844
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
845
|
+
Slot,
|
|
846
|
+
{
|
|
847
|
+
...handlers,
|
|
848
|
+
onMouseEnter: compose(child.props.onMouseEnter, handleMouseEnter),
|
|
849
|
+
onMouseLeave: compose(child.props.onMouseLeave, handleMouseLeave),
|
|
850
|
+
...className !== void 0 ? { className } : {},
|
|
851
|
+
...testID !== void 0 ? { "data-testid": testID } : {},
|
|
852
|
+
children: child
|
|
853
|
+
}
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { ...handlers, className, ...testID !== void 0 ? { "data-testid": testID } : {}, children });
|
|
857
|
+
}, "HoverCardTrigger");
|
|
858
|
+
var HoverCardContent = /* @__PURE__ */ __name(({ side = "bottom", align = "start", children, className, testID }) => {
|
|
859
|
+
const ctx = useHoverCardContext("HoverCard.Content");
|
|
860
|
+
const handleMouseEnter = react.useCallback(() => {
|
|
861
|
+
ctx.cancelTimers();
|
|
862
|
+
}, [ctx]);
|
|
863
|
+
const handleMouseLeave = react.useCallback(() => {
|
|
864
|
+
ctx.requestClose();
|
|
865
|
+
}, [ctx]);
|
|
866
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
867
|
+
Popover.Content,
|
|
868
|
+
{
|
|
869
|
+
side,
|
|
870
|
+
align,
|
|
871
|
+
...className !== void 0 ? { className } : {},
|
|
872
|
+
...testID !== void 0 ? { testID } : {},
|
|
873
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
874
|
+
"div",
|
|
875
|
+
{
|
|
876
|
+
id: ctx.contentId,
|
|
877
|
+
role: "dialog",
|
|
878
|
+
"aria-label": "Hover card",
|
|
879
|
+
onMouseEnter: handleMouseEnter,
|
|
880
|
+
onMouseLeave: handleMouseLeave,
|
|
881
|
+
children
|
|
882
|
+
}
|
|
883
|
+
)
|
|
884
|
+
}
|
|
885
|
+
);
|
|
886
|
+
}, "HoverCardContent");
|
|
887
|
+
var HoverCard = Object.assign(HoverCardRoot, {
|
|
888
|
+
Trigger: HoverCardTrigger,
|
|
889
|
+
Content: HoverCardContent
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
exports.HoverCard = HoverCard;
|
|
893
|
+
//# sourceMappingURL=index.cjs.map
|
|
894
|
+
//# sourceMappingURL=index.cjs.map
|