@pol-studios/ui 1.0.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/adapters/index.js +359 -0
- package/dist/auth/index.js +588 -0
- package/dist/canvas-UVNDA54X.node +0 -0
- package/dist/cards/index.js +872 -0
- package/dist/charts/index.js +54148 -0
- package/dist/components/chat-agent/index.js +21434 -0
- package/dist/components/index.js +148416 -0
- package/dist/contexts/index.js +188 -0
- package/dist/crud/index.js +6550 -0
- package/dist/data/index.js +372 -0
- package/dist/feedback/index.js +9534 -0
- package/dist/file/index.js +256 -0
- package/dist/forms/index.js +504 -0
- package/dist/hooks/index.js +345 -0
- package/dist/index.js +15650 -0
- package/dist/nav/index.js +1556 -0
- package/dist/navbar/index.js +45262 -0
- package/dist/primitives/index.js +15646 -0
- package/dist/providers/index.js +1927 -0
- package/dist/types/index.js +1 -0
- package/package.json +226 -0
- package/src/styles/globals.css +157 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/hooks/useKeyboardShortcuts.ts
|
|
4
|
+
import { useEffect, useCallback, useRef } from "react";
|
|
5
|
+
function useKeyboardShortcuts({ shortcuts, enabled = true }) {
|
|
6
|
+
const shortcutsRef = useRef(shortcuts);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
shortcutsRef.current = shortcuts;
|
|
9
|
+
}, [shortcuts]);
|
|
10
|
+
const handleKeyDown = useCallback(
|
|
11
|
+
(event) => {
|
|
12
|
+
if (!enabled) return;
|
|
13
|
+
const target = event.target;
|
|
14
|
+
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable || target.tagName === "SELECT" && !event.ctrlKey && !event.metaKey) {
|
|
15
|
+
if (!event.ctrlKey && !event.metaKey && !event.altKey) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
for (const shortcut of shortcutsRef.current) {
|
|
20
|
+
if (shortcut.enabled === false) continue;
|
|
21
|
+
const keyMatches = shortcut.key.toLowerCase() === event.key.toLowerCase();
|
|
22
|
+
const isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0;
|
|
23
|
+
const hasCtrlOrCmd = event.ctrlKey || event.metaKey;
|
|
24
|
+
let ctrlMatches = true;
|
|
25
|
+
if (shortcut.ctrl !== void 0) {
|
|
26
|
+
ctrlMatches = shortcut.ctrl === (isMac ? event.metaKey : event.ctrlKey);
|
|
27
|
+
}
|
|
28
|
+
let metaMatches = true;
|
|
29
|
+
if (shortcut.meta !== void 0) {
|
|
30
|
+
metaMatches = shortcut.meta === event.metaKey;
|
|
31
|
+
}
|
|
32
|
+
if (shortcut.ctrl !== void 0 && shortcut.meta === void 0 && event.metaKey && !isMac) {
|
|
33
|
+
ctrlMatches = false;
|
|
34
|
+
}
|
|
35
|
+
if (shortcut.meta !== void 0 && shortcut.ctrl === void 0 && event.ctrlKey) {
|
|
36
|
+
metaMatches = false;
|
|
37
|
+
}
|
|
38
|
+
const shiftMatches = shortcut.shift === void 0 ? true : shortcut.shift === event.shiftKey;
|
|
39
|
+
const altMatches = shortcut.alt === void 0 ? true : shortcut.alt === event.altKey;
|
|
40
|
+
if (keyMatches && ctrlMatches && metaMatches && shiftMatches && altMatches) {
|
|
41
|
+
if (shortcut.preventDefault !== false) {
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
}
|
|
44
|
+
shortcut.action();
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
[enabled]
|
|
50
|
+
);
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (!enabled) return;
|
|
53
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
54
|
+
return () => {
|
|
55
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
56
|
+
};
|
|
57
|
+
}, [handleKeyDown, enabled]);
|
|
58
|
+
}
|
|
59
|
+
function formatShortcut(shortcut) {
|
|
60
|
+
const isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0;
|
|
61
|
+
const parts = [];
|
|
62
|
+
if (shortcut.ctrl || shortcut.meta) {
|
|
63
|
+
parts.push(isMac ? "\u2318" : "Ctrl");
|
|
64
|
+
}
|
|
65
|
+
if (shortcut.alt) {
|
|
66
|
+
parts.push(isMac ? "\u2325" : "Alt");
|
|
67
|
+
}
|
|
68
|
+
if (shortcut.shift) {
|
|
69
|
+
parts.push(isMac ? "\u21E7" : "Shift");
|
|
70
|
+
}
|
|
71
|
+
let key = shortcut.key;
|
|
72
|
+
if (key.length === 1) {
|
|
73
|
+
key = key.toUpperCase();
|
|
74
|
+
} else {
|
|
75
|
+
key = key.charAt(0).toUpperCase() + key.slice(1).toLowerCase();
|
|
76
|
+
}
|
|
77
|
+
parts.push(key);
|
|
78
|
+
return parts.join(isMac ? "" : "+");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/hooks/useMultistepForm.tsx
|
|
82
|
+
import { useState } from "react";
|
|
83
|
+
function useMultistepForm(steps) {
|
|
84
|
+
const [currentStepIndex, setCurrentStepIndex] = useState(0);
|
|
85
|
+
function goNext() {
|
|
86
|
+
setCurrentStepIndex((x) => {
|
|
87
|
+
if (x >= steps.length - 1) return x;
|
|
88
|
+
return x + 1;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function goBack() {
|
|
92
|
+
setCurrentStepIndex((x) => {
|
|
93
|
+
if (x === 0) return x;
|
|
94
|
+
return x - 1;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function goTo(index) {
|
|
98
|
+
setCurrentStepIndex(index);
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
currentStepIndex,
|
|
102
|
+
currentStep: steps[currentStepIndex],
|
|
103
|
+
steps,
|
|
104
|
+
goTo,
|
|
105
|
+
goNext,
|
|
106
|
+
goBack
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/hooks/usePOLNavigate.tsx
|
|
111
|
+
import { useContext as useContext2 } from "react";
|
|
112
|
+
import { useNavigate as useTanstackNavigate } from "@tanstack/react-router";
|
|
113
|
+
|
|
114
|
+
// src/providers/router/RouterContext.tsx
|
|
115
|
+
import { createContext, useContext } from "react";
|
|
116
|
+
import { jsx } from "react/jsx-runtime";
|
|
117
|
+
var RouterContext = createContext(null);
|
|
118
|
+
|
|
119
|
+
// src/hooks/usePOLNavigate.tsx
|
|
120
|
+
function usePolNavigate() {
|
|
121
|
+
const routerContext = useContext2(RouterContext);
|
|
122
|
+
let tanstackNavigate = null;
|
|
123
|
+
try {
|
|
124
|
+
tanstackNavigate = useTanstackNavigate();
|
|
125
|
+
} catch {
|
|
126
|
+
}
|
|
127
|
+
if (tanstackNavigate) {
|
|
128
|
+
return tanstackNavigate;
|
|
129
|
+
}
|
|
130
|
+
if (routerContext) {
|
|
131
|
+
return (options) => {
|
|
132
|
+
const searchValue = typeof options.search === "object" && options.search !== null ? options.search : void 0;
|
|
133
|
+
const adapterOptions = {
|
|
134
|
+
to: typeof options.to === "string" ? options.to : String(options.to),
|
|
135
|
+
params: options.params,
|
|
136
|
+
search: searchValue,
|
|
137
|
+
replace: options.replace
|
|
138
|
+
};
|
|
139
|
+
routerContext.navigate(adapterOptions);
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
throw new Error("usePOLNavigate requires either a RouterProvider or TanStack Router context");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// src/hooks/use-mobile.tsx
|
|
146
|
+
import * as React2 from "react";
|
|
147
|
+
var MOBILE_BREAKPOINT = 768;
|
|
148
|
+
function useIsMobile() {
|
|
149
|
+
const [isMobile, setIsMobile] = React2.useState(void 0);
|
|
150
|
+
React2.useEffect(() => {
|
|
151
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
152
|
+
const onChange = () => {
|
|
153
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
154
|
+
};
|
|
155
|
+
mql.addEventListener("change", onChange);
|
|
156
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
157
|
+
return () => mql.removeEventListener("change", onChange);
|
|
158
|
+
}, []);
|
|
159
|
+
return !!isMobile;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// src/hooks/use-auto-height.tsx
|
|
163
|
+
import * as React3 from "react";
|
|
164
|
+
function useAutoHeight(deps = [], options = {
|
|
165
|
+
includeParentBox: true,
|
|
166
|
+
includeSelfBox: false
|
|
167
|
+
}) {
|
|
168
|
+
const ref = React3.useRef(null);
|
|
169
|
+
const roRef = React3.useRef(null);
|
|
170
|
+
const [height, setHeight] = React3.useState(0);
|
|
171
|
+
const measure = React3.useCallback(() => {
|
|
172
|
+
const el = ref.current;
|
|
173
|
+
if (!el) return 0;
|
|
174
|
+
const base = el.getBoundingClientRect().height || 0;
|
|
175
|
+
let extra = 0;
|
|
176
|
+
if (options.includeParentBox && el.parentElement) {
|
|
177
|
+
const cs = getComputedStyle(el.parentElement);
|
|
178
|
+
const paddingY = (parseFloat(cs.paddingTop || "0") || 0) + (parseFloat(cs.paddingBottom || "0") || 0);
|
|
179
|
+
const borderY = (parseFloat(cs.borderTopWidth || "0") || 0) + (parseFloat(cs.borderBottomWidth || "0") || 0);
|
|
180
|
+
const isBorderBox = cs.boxSizing === "border-box";
|
|
181
|
+
if (isBorderBox) {
|
|
182
|
+
extra += paddingY + borderY;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (options.includeSelfBox) {
|
|
186
|
+
const cs = getComputedStyle(el);
|
|
187
|
+
const paddingY = (parseFloat(cs.paddingTop || "0") || 0) + (parseFloat(cs.paddingBottom || "0") || 0);
|
|
188
|
+
const borderY = (parseFloat(cs.borderTopWidth || "0") || 0) + (parseFloat(cs.borderBottomWidth || "0") || 0);
|
|
189
|
+
const isBorderBox = cs.boxSizing === "border-box";
|
|
190
|
+
if (isBorderBox) {
|
|
191
|
+
extra += paddingY + borderY;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
195
|
+
const total = Math.ceil((base + extra) * dpr) / dpr;
|
|
196
|
+
return total;
|
|
197
|
+
}, [options.includeParentBox, options.includeSelfBox]);
|
|
198
|
+
React3.useLayoutEffect(() => {
|
|
199
|
+
const el = ref.current;
|
|
200
|
+
if (!el) return;
|
|
201
|
+
setHeight(measure());
|
|
202
|
+
if (roRef.current) {
|
|
203
|
+
roRef.current.disconnect();
|
|
204
|
+
roRef.current = null;
|
|
205
|
+
}
|
|
206
|
+
const ro = new ResizeObserver(() => {
|
|
207
|
+
const next = measure();
|
|
208
|
+
requestAnimationFrame(() => setHeight(next));
|
|
209
|
+
});
|
|
210
|
+
ro.observe(el);
|
|
211
|
+
if (options.includeParentBox && el.parentElement) {
|
|
212
|
+
ro.observe(el.parentElement);
|
|
213
|
+
}
|
|
214
|
+
roRef.current = ro;
|
|
215
|
+
return () => {
|
|
216
|
+
ro.disconnect();
|
|
217
|
+
roRef.current = null;
|
|
218
|
+
};
|
|
219
|
+
}, deps);
|
|
220
|
+
React3.useLayoutEffect(() => {
|
|
221
|
+
if (height === 0) {
|
|
222
|
+
const next = measure();
|
|
223
|
+
if (next !== 0) setHeight(next);
|
|
224
|
+
}
|
|
225
|
+
}, [height, measure]);
|
|
226
|
+
return { ref, height };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// src/hooks/use-controlled-state.tsx
|
|
230
|
+
import * as React4 from "react";
|
|
231
|
+
function useControlledState(props) {
|
|
232
|
+
const { value, defaultValue, onChange } = props;
|
|
233
|
+
const [state, setInternalState] = React4.useState(
|
|
234
|
+
value !== void 0 ? value : defaultValue
|
|
235
|
+
);
|
|
236
|
+
React4.useEffect(() => {
|
|
237
|
+
if (value !== void 0) setInternalState(value);
|
|
238
|
+
}, [value]);
|
|
239
|
+
const setState = React4.useCallback(
|
|
240
|
+
(next, ...args) => {
|
|
241
|
+
setInternalState(next);
|
|
242
|
+
onChange?.(next, ...args);
|
|
243
|
+
},
|
|
244
|
+
[onChange]
|
|
245
|
+
);
|
|
246
|
+
return [state, setState];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// src/hooks/use-data-state.tsx
|
|
250
|
+
import * as React5 from "react";
|
|
251
|
+
function parseDatasetValue(value) {
|
|
252
|
+
if (value === null) return null;
|
|
253
|
+
if (value === "" || value === "true") return true;
|
|
254
|
+
if (value === "false") return false;
|
|
255
|
+
return value;
|
|
256
|
+
}
|
|
257
|
+
function useDataState(key, forwardedRef, onChange) {
|
|
258
|
+
const localRef = React5.useRef(null);
|
|
259
|
+
React5.useImperativeHandle(forwardedRef, () => localRef.current);
|
|
260
|
+
const getSnapshot = () => {
|
|
261
|
+
const el = localRef.current;
|
|
262
|
+
return el ? parseDatasetValue(el.getAttribute(`data-${key}`)) : null;
|
|
263
|
+
};
|
|
264
|
+
const subscribe = (callback) => {
|
|
265
|
+
const el = localRef.current;
|
|
266
|
+
if (!el) return () => {
|
|
267
|
+
};
|
|
268
|
+
const observer = new MutationObserver((records) => {
|
|
269
|
+
for (const record of records) {
|
|
270
|
+
if (record.attributeName === `data-${key}`) {
|
|
271
|
+
callback();
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
observer.observe(el, {
|
|
277
|
+
attributes: true,
|
|
278
|
+
attributeFilter: [`data-${key}`]
|
|
279
|
+
});
|
|
280
|
+
return () => observer.disconnect();
|
|
281
|
+
};
|
|
282
|
+
const value = React5.useSyncExternalStore(subscribe, getSnapshot);
|
|
283
|
+
React5.useEffect(() => {
|
|
284
|
+
if (onChange) onChange(value);
|
|
285
|
+
}, [value, onChange]);
|
|
286
|
+
return [value, localRef];
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// src/hooks/use-is-in-view.tsx
|
|
290
|
+
import * as React6 from "react";
|
|
291
|
+
import { useInView } from "motion/react";
|
|
292
|
+
function useIsInView(ref, options = {}) {
|
|
293
|
+
const { inView, inViewOnce = false, inViewMargin = "0px" } = options;
|
|
294
|
+
const localRef = React6.useRef(null);
|
|
295
|
+
React6.useImperativeHandle(ref, () => localRef.current);
|
|
296
|
+
const inViewResult = useInView(localRef, {
|
|
297
|
+
once: inViewOnce,
|
|
298
|
+
margin: inViewMargin
|
|
299
|
+
});
|
|
300
|
+
const isInView = !inView || inViewResult;
|
|
301
|
+
return { ref: localRef, isInView };
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// src/providers/alert/AlertContext.tsx
|
|
305
|
+
import { createContext as createContext2, useContext as useContext3, useState as useState5 } from "react";
|
|
306
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
307
|
+
var defaultAlertState = {
|
|
308
|
+
isOpen: false,
|
|
309
|
+
title: "",
|
|
310
|
+
description: "",
|
|
311
|
+
confirmTitle: "Confirm",
|
|
312
|
+
cancelTitle: "Cancel",
|
|
313
|
+
variant: "default",
|
|
314
|
+
onConfirm: () => {
|
|
315
|
+
},
|
|
316
|
+
onCancel: () => {
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
var defaultContextValue = {
|
|
320
|
+
showAlert: async () => false,
|
|
321
|
+
hideAlert: () => {
|
|
322
|
+
},
|
|
323
|
+
alertState: defaultAlertState
|
|
324
|
+
};
|
|
325
|
+
var AlertContext = createContext2(defaultContextValue);
|
|
326
|
+
var useAlert = () => {
|
|
327
|
+
const context = useContext3(AlertContext);
|
|
328
|
+
if (!context) {
|
|
329
|
+
throw new Error("useAlert must be used within an AlertProvider");
|
|
330
|
+
}
|
|
331
|
+
return { hideAlert: context.hideAlert, showAlert: context.showAlert };
|
|
332
|
+
};
|
|
333
|
+
export {
|
|
334
|
+
formatShortcut,
|
|
335
|
+
useAlert,
|
|
336
|
+
useAutoHeight,
|
|
337
|
+
useControlledState,
|
|
338
|
+
useDataState,
|
|
339
|
+
useIsInView,
|
|
340
|
+
useIsMobile,
|
|
341
|
+
useKeyboardShortcuts,
|
|
342
|
+
useMultistepForm,
|
|
343
|
+
usePolNavigate as useNavigate,
|
|
344
|
+
usePolNavigate
|
|
345
|
+
};
|