@pactor-app/ui 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.
@@ -0,0 +1,1111 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/components/index.ts
31
+ var components_exports = {};
32
+ __export(components_exports, {
33
+ Alert: () => Alert2,
34
+ Button: () => Button2,
35
+ Card: () => Card2,
36
+ Flex: () => Flex,
37
+ Form: () => Form,
38
+ Grid: () => Grid,
39
+ Input: () => Input2,
40
+ Page: () => Page,
41
+ Select: () => Select2,
42
+ Statistic: () => Statistic,
43
+ Table: () => Table2,
44
+ Tabs: () => Tabs2,
45
+ createShadcnComponentRegistry: () => createShadcnComponentRegistry,
46
+ registerShadcnComponents: () => registerShadcnComponents,
47
+ shadcnComponents: () => shadcnComponents,
48
+ useFormContext: () => useFormContext
49
+ });
50
+ module.exports = __toCommonJS(components_exports);
51
+
52
+ // src/components/register.ts
53
+ var import_core = require("@pactor-app/core");
54
+
55
+ // src/ui/alert.tsx
56
+ var import_class_variance_authority = require("class-variance-authority");
57
+
58
+ // src/lib/utils.ts
59
+ var import_clsx = require("clsx");
60
+ var import_tailwind_merge = require("tailwind-merge");
61
+ function cn(...inputs) {
62
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
63
+ }
64
+
65
+ // src/ui/alert.tsx
66
+ var import_jsx_runtime = require("react/jsx-runtime");
67
+ var alertVariants = (0, import_class_variance_authority.cva)(
68
+ "relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border border-border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
69
+ {
70
+ variants: {
71
+ variant: {
72
+ default: "bg-card text-card-foreground",
73
+ destructive: "border-destructive/50 text-destructive bg-card [&>svg]:text-current",
74
+ success: "border-success/50 text-success bg-card [&>svg]:text-current",
75
+ warning: "border-warning/50 text-warning bg-card [&>svg]:text-current",
76
+ info: "border-info/50 text-info bg-card [&>svg]:text-current"
77
+ }
78
+ },
79
+ defaultVariants: {
80
+ variant: "default"
81
+ }
82
+ }
83
+ );
84
+ function Alert({
85
+ className,
86
+ variant,
87
+ ...props
88
+ }) {
89
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
90
+ "div",
91
+ {
92
+ "data-slot": "alert",
93
+ role: "alert",
94
+ className: cn(alertVariants({ variant }), className),
95
+ ...props
96
+ }
97
+ );
98
+ }
99
+ function AlertTitle({ className, ...props }) {
100
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
101
+ "div",
102
+ {
103
+ "data-slot": "alert-title",
104
+ className: cn(
105
+ "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight",
106
+ className
107
+ ),
108
+ ...props
109
+ }
110
+ );
111
+ }
112
+ function AlertDescription({
113
+ className,
114
+ ...props
115
+ }) {
116
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
117
+ "div",
118
+ {
119
+ "data-slot": "alert-description",
120
+ className: cn(
121
+ "col-start-2 grid justify-items-start gap-1 text-sm text-muted-foreground [&_p]:leading-relaxed",
122
+ className
123
+ ),
124
+ ...props
125
+ }
126
+ );
127
+ }
128
+
129
+ // src/components/components/Alert/index.tsx
130
+ var import_jsx_runtime2 = require("react/jsx-runtime");
131
+ var variantMap = {
132
+ success: "success",
133
+ info: "info",
134
+ warning: "warning",
135
+ error: "destructive"
136
+ };
137
+ function Alert2({ message, description, variant = "info" }) {
138
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Alert, { variant: variantMap[variant], children: [
139
+ message ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AlertTitle, { children: message }) : null,
140
+ description ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AlertDescription, { children: description }) : null
141
+ ] });
142
+ }
143
+
144
+ // src/components/components/Button/index.tsx
145
+ var import_lucide_react = require("lucide-react");
146
+
147
+ // src/ui/button.tsx
148
+ var import_button = require("@base-ui/react/button");
149
+ var import_class_variance_authority2 = require("class-variance-authority");
150
+ var React = __toESM(require("react"), 1);
151
+ var import_jsx_runtime3 = require("react/jsx-runtime");
152
+ var buttonVariants = (0, import_class_variance_authority2.cva)(
153
+ "inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium outline-none transition-colors focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
154
+ {
155
+ variants: {
156
+ variant: {
157
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
158
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20",
159
+ outline: "border border-border bg-background hover:bg-accent hover:text-accent-foreground",
160
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
161
+ ghost: "hover:bg-accent hover:text-accent-foreground",
162
+ link: "text-primary underline-offset-4 hover:underline"
163
+ },
164
+ size: {
165
+ default: "h-9 px-4 py-2",
166
+ sm: "h-8 gap-1.5 rounded-md px-3 text-xs",
167
+ lg: "h-10 rounded-md px-6",
168
+ icon: "size-9"
169
+ }
170
+ },
171
+ defaultVariants: {
172
+ variant: "default",
173
+ size: "default"
174
+ }
175
+ }
176
+ );
177
+ function Button({
178
+ className,
179
+ variant,
180
+ size,
181
+ asChild = false,
182
+ children,
183
+ ...props
184
+ }) {
185
+ if (asChild && React.isValidElement(children)) {
186
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
187
+ import_button.Button,
188
+ {
189
+ "data-slot": "button",
190
+ className: cn(buttonVariants({ variant, size, className })),
191
+ render: children,
192
+ ...props
193
+ }
194
+ );
195
+ }
196
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
197
+ import_button.Button,
198
+ {
199
+ "data-slot": "button",
200
+ className: cn(buttonVariants({ variant, size, className })),
201
+ ...props,
202
+ children
203
+ }
204
+ );
205
+ }
206
+
207
+ // src/components/components/Button/index.tsx
208
+ var import_jsx_runtime4 = require("react/jsx-runtime");
209
+ var variantMap2 = {
210
+ default: "outline",
211
+ primary: "default",
212
+ dashed: "outline",
213
+ link: "link",
214
+ text: "ghost"
215
+ };
216
+ var sizeMap = {
217
+ small: "sm",
218
+ middle: "default",
219
+ large: "lg"
220
+ };
221
+ function Button2({
222
+ text,
223
+ variant = "default",
224
+ danger,
225
+ size = "middle",
226
+ loading,
227
+ disabled,
228
+ submit,
229
+ onClick,
230
+ children
231
+ }) {
232
+ const textual = variant === "link" || variant === "text";
233
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
234
+ Button,
235
+ {
236
+ type: submit ? "submit" : "button",
237
+ variant: danger && !textual ? "destructive" : variantMap2[variant],
238
+ size: sizeMap[size],
239
+ disabled: disabled ?? loading,
240
+ "aria-busy": loading || void 0,
241
+ onClick: () => onClick?.(),
242
+ className: cn(
243
+ variant === "dashed" && "border-dashed",
244
+ danger && textual && "text-destructive hover:text-destructive"
245
+ ),
246
+ children: [
247
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react.Loader2, { "aria-hidden": true, className: "animate-spin" }) : null,
248
+ text ?? children
249
+ ]
250
+ }
251
+ );
252
+ }
253
+
254
+ // src/ui/card.tsx
255
+ var import_jsx_runtime5 = require("react/jsx-runtime");
256
+ function Card({ className, ...props }) {
257
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
258
+ "div",
259
+ {
260
+ "data-slot": "card",
261
+ className: cn(
262
+ "flex flex-col gap-6 rounded-xl border border-border bg-card py-6 text-card-foreground shadow-sm",
263
+ className
264
+ ),
265
+ ...props
266
+ }
267
+ );
268
+ }
269
+ function CardHeader({ className, ...props }) {
270
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
271
+ "div",
272
+ {
273
+ "data-slot": "card-header",
274
+ className: cn(
275
+ "grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
276
+ className
277
+ ),
278
+ ...props
279
+ }
280
+ );
281
+ }
282
+ function CardTitle({ className, ...props }) {
283
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
284
+ "div",
285
+ {
286
+ "data-slot": "card-title",
287
+ className: cn("leading-none font-semibold", className),
288
+ ...props
289
+ }
290
+ );
291
+ }
292
+ function CardContent({ className, ...props }) {
293
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
294
+ "div",
295
+ {
296
+ "data-slot": "card-content",
297
+ className: cn("px-6", className),
298
+ ...props
299
+ }
300
+ );
301
+ }
302
+
303
+ // src/components/components/Card/index.tsx
304
+ var import_jsx_runtime6 = require("react/jsx-runtime");
305
+ function Card2({ title, bordered = true, children }) {
306
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
307
+ Card,
308
+ {
309
+ className: cn("gap-4 py-4", !bordered && "border-transparent shadow-none"),
310
+ children: [
311
+ title ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardHeader, { className: "px-4", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardTitle, { children: title }) }) : null,
312
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardContent, { className: "px-4", children })
313
+ ]
314
+ }
315
+ );
316
+ }
317
+
318
+ // src/components/components/Flex/index.tsx
319
+ var import_jsx_runtime7 = require("react/jsx-runtime");
320
+ var gapClass = {
321
+ small: "gap-2",
322
+ middle: "gap-4",
323
+ large: "gap-6"
324
+ };
325
+ var justifyClass = {
326
+ start: "justify-start",
327
+ center: "justify-center",
328
+ end: "justify-end",
329
+ "space-between": "justify-between",
330
+ "space-around": "justify-around",
331
+ "space-evenly": "justify-evenly"
332
+ };
333
+ var alignClass = {
334
+ start: "items-start",
335
+ center: "items-center",
336
+ end: "items-end",
337
+ baseline: "items-baseline",
338
+ stretch: "items-stretch"
339
+ };
340
+ function Flex({
341
+ direction = "horizontal",
342
+ gap,
343
+ justify,
344
+ align,
345
+ children
346
+ }) {
347
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
348
+ "div",
349
+ {
350
+ "data-slot": "flex",
351
+ className: cn(
352
+ "flex",
353
+ direction === "vertical" && "flex-col",
354
+ typeof gap === "string" && gapClass[gap],
355
+ justify && justifyClass[justify],
356
+ align && alignClass[align]
357
+ ),
358
+ style: typeof gap === "number" ? { gap } : void 0,
359
+ children
360
+ }
361
+ );
362
+ }
363
+
364
+ // src/components/components/Form/index.tsx
365
+ var import_runtime = require("@pactor-app/runtime");
366
+ var import_react2 = require("react");
367
+
368
+ // src/components/components/Form/context.ts
369
+ var import_react = require("react");
370
+ var FormReactContext = (0, import_react.createContext)(null);
371
+ var FormContextProvider = FormReactContext.Provider;
372
+ function useFormContext() {
373
+ return (0, import_react.useContext)(FormReactContext);
374
+ }
375
+ function formItemClass(layout) {
376
+ switch (layout) {
377
+ case "horizontal":
378
+ return "mb-4 flex items-baseline gap-2";
379
+ case "inline":
380
+ return "flex items-center gap-2";
381
+ default:
382
+ return "mb-4 flex flex-col gap-1.5";
383
+ }
384
+ }
385
+
386
+ // src/components/components/Form/index.tsx
387
+ var import_jsx_runtime8 = require("react/jsx-runtime");
388
+ function isEmpty(value) {
389
+ return value === void 0 || value === null || value === "";
390
+ }
391
+ function Form({
392
+ name = "default",
393
+ layout = "vertical",
394
+ initialValues,
395
+ children,
396
+ onSubmit,
397
+ onValuesChange
398
+ }) {
399
+ const { context } = (0, import_runtime.useRenderer)();
400
+ const [values, setValues] = (0, import_react2.useState)(() => ({
401
+ ...initialValues
402
+ }));
403
+ const [errors, setErrors] = (0, import_react2.useState)({});
404
+ const fieldRulesRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
405
+ const mergedInitialFieldsRef = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
406
+ const setValuesBatch = (0, import_react2.useCallback)((partial) => {
407
+ setValues((prev) => ({ ...prev, ...partial }));
408
+ }, []);
409
+ (0, import_react2.useEffect)(() => {
410
+ context.forms.register(name, { setValues: setValuesBatch });
411
+ return () => {
412
+ context.forms.unregister(name);
413
+ };
414
+ }, [context, name, setValuesBatch]);
415
+ const formContext = (0, import_react2.useMemo)(
416
+ () => ({
417
+ inForm: true,
418
+ layout,
419
+ values,
420
+ errors,
421
+ setValue(name2, value) {
422
+ const next = { ...values, [name2]: value };
423
+ setValues(next);
424
+ setErrors((prev) => {
425
+ if (!(name2 in prev)) {
426
+ return prev;
427
+ }
428
+ const rest = { ...prev };
429
+ delete rest[name2];
430
+ return rest;
431
+ });
432
+ onValuesChange?.({ [name2]: value }, next);
433
+ },
434
+ setValues: setValuesBatch,
435
+ registerField(name2, rules, initialValue) {
436
+ fieldRulesRef.current.set(name2, rules);
437
+ if (initialValue !== void 0 && !mergedInitialFieldsRef.current.has(name2)) {
438
+ mergedInitialFieldsRef.current.add(name2);
439
+ setValues((prev) => ({ ...prev, [name2]: initialValue }));
440
+ }
441
+ },
442
+ unregisterField(name2) {
443
+ fieldRulesRef.current.delete(name2);
444
+ }
445
+ }),
446
+ [layout, values, errors, onValuesChange, setValuesBatch]
447
+ );
448
+ const handleSubmit = (event) => {
449
+ event.preventDefault();
450
+ const nextErrors = {};
451
+ for (const [name2, rules] of fieldRulesRef.current) {
452
+ for (const rule of rules ?? []) {
453
+ if (rule.required && isEmpty(values[name2])) {
454
+ nextErrors[name2] = rule.message ?? context.i18n.t("pactor.form.required");
455
+ break;
456
+ }
457
+ }
458
+ }
459
+ setErrors(nextErrors);
460
+ if (Object.keys(nextErrors).length > 0) {
461
+ return;
462
+ }
463
+ context.state.set("form", values);
464
+ onSubmit?.(values);
465
+ };
466
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(FormContextProvider, { value: formContext, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
467
+ "form",
468
+ {
469
+ "data-slot": "form",
470
+ className: cn(layout === "inline" && "flex flex-wrap items-center gap-3"),
471
+ onSubmit: handleSubmit,
472
+ children
473
+ }
474
+ ) });
475
+ }
476
+
477
+ // src/components/components/Grid/index.tsx
478
+ var import_react3 = require("react");
479
+ var import_jsx_runtime9 = require("react/jsx-runtime");
480
+ function Grid({ columns = 1, gap, children }) {
481
+ const cols = Math.max(1, columns);
482
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
483
+ "div",
484
+ {
485
+ "data-slot": "grid",
486
+ "data-columns": cols,
487
+ className: "grid",
488
+ style: {
489
+ gridTemplateColumns: `repeat(${cols}, minmax(0, 1fr))`,
490
+ ...gap !== void 0 ? { gap } : {}
491
+ },
492
+ children: import_react3.Children.map(children, (child, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { "data-slot": "grid-item", children: child }, index))
493
+ }
494
+ );
495
+ }
496
+
497
+ // src/components/components/Input/index.tsx
498
+ var import_react4 = require("react");
499
+
500
+ // src/ui/input.tsx
501
+ var import_jsx_runtime10 = require("react/jsx-runtime");
502
+ function Input({ className, type, ...props }) {
503
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
504
+ "input",
505
+ {
506
+ type,
507
+ "data-slot": "input",
508
+ className: cn(
509
+ "flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50",
510
+ className
511
+ ),
512
+ ...props
513
+ }
514
+ );
515
+ }
516
+
517
+ // src/components/components/Input/index.tsx
518
+ var import_jsx_runtime11 = require("react/jsx-runtime");
519
+ function Input2({
520
+ name,
521
+ label,
522
+ rules,
523
+ value,
524
+ type = "text",
525
+ placeholder,
526
+ disabled,
527
+ onChange
528
+ }) {
529
+ const form = useFormContext();
530
+ const controlId = (0, import_react4.useId)();
531
+ const inForm = form?.inForm === true && typeof name === "string" && name !== "";
532
+ (0, import_react4.useEffect)(() => {
533
+ if (inForm && form && name) {
534
+ form.registerField(name, rules, value);
535
+ return () => form.unregisterField(name);
536
+ }
537
+ return void 0;
538
+ });
539
+ if (inForm && form && name) {
540
+ const fieldValue = form.values[name];
541
+ const error = form.errors[name];
542
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { "data-slot": "form-item", className: formItemClass(form.layout), children: [
543
+ label ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
544
+ "label",
545
+ {
546
+ htmlFor: controlId,
547
+ className: "shrink-0 text-sm leading-none font-medium whitespace-nowrap",
548
+ children: label
549
+ }
550
+ ) : null,
551
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
552
+ Input,
553
+ {
554
+ id: controlId,
555
+ type,
556
+ value: typeof fieldValue === "string" ? fieldValue : "",
557
+ placeholder,
558
+ disabled,
559
+ onChange: (event) => {
560
+ form.setValue(name, event.target.value);
561
+ onChange?.(event.target.value);
562
+ }
563
+ }
564
+ ),
565
+ error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { "data-slot": "form-error", className: "text-sm text-destructive", children: error }) : null
566
+ ] });
567
+ }
568
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
569
+ Input,
570
+ {
571
+ type,
572
+ value: value ?? "",
573
+ placeholder,
574
+ disabled,
575
+ onChange: (event) => onChange?.(event.target.value)
576
+ }
577
+ );
578
+ }
579
+
580
+ // src/components/components/Page/index.tsx
581
+ var import_jsx_runtime12 = require("react/jsx-runtime");
582
+ function Page({ title, children }) {
583
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { "data-slot": "page", className: "p-6", children: [
584
+ title ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h2", { "data-slot": "page-title", className: "mb-5 text-xl font-semibold", children: title }) : null,
585
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { "data-slot": "page-content", className: "space-y-5", children })
586
+ ] });
587
+ }
588
+
589
+ // src/components/components/Select/index.tsx
590
+ var import_runtime2 = require("@pactor-app/runtime");
591
+ var import_react5 = require("react");
592
+
593
+ // src/ui/select.tsx
594
+ var import_select = require("@base-ui/react/select");
595
+ var import_lucide_react2 = require("lucide-react");
596
+ var import_jsx_runtime13 = require("react/jsx-runtime");
597
+ var Select = import_select.Select.Root;
598
+ function SelectValue({
599
+ ...props
600
+ }) {
601
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_select.Select.Value, { "data-slot": "select-value", ...props });
602
+ }
603
+ function SelectTrigger({
604
+ className,
605
+ size = "default",
606
+ children,
607
+ ...props
608
+ }) {
609
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
610
+ import_select.Select.Trigger,
611
+ {
612
+ "data-slot": "select-trigger",
613
+ "data-size": size,
614
+ className: cn(
615
+ "flex w-fit cursor-pointer items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-colors outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 data-[placeholder]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
616
+ className
617
+ ),
618
+ ...props,
619
+ children: [
620
+ children,
621
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
622
+ import_select.Select.Icon,
623
+ {
624
+ render: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.ChevronDownIcon, { className: "size-4 opacity-50" })
625
+ }
626
+ )
627
+ ]
628
+ }
629
+ );
630
+ }
631
+ function SelectContent({
632
+ className,
633
+ children,
634
+ side = "bottom",
635
+ sideOffset = 4,
636
+ align = "center",
637
+ alignItemWithTrigger = false,
638
+ ...props
639
+ }) {
640
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_select.Select.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
641
+ import_select.Select.Positioner,
642
+ {
643
+ side,
644
+ sideOffset,
645
+ align,
646
+ alignItemWithTrigger,
647
+ className: "isolate z-50",
648
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
649
+ import_select.Select.Popup,
650
+ {
651
+ "data-slot": "select-content",
652
+ className: cn(
653
+ "relative z-50 max-h-96 min-w-[8rem] overflow-x-hidden overflow-y-auto rounded-md border border-border bg-popover text-popover-foreground shadow-md duration-200 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
654
+ className
655
+ ),
656
+ ...props,
657
+ children: [
658
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SelectScrollUpButton, {}),
659
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_select.Select.List, { className: "p-1", children }),
660
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SelectScrollDownButton, {})
661
+ ]
662
+ }
663
+ )
664
+ }
665
+ ) });
666
+ }
667
+ function SelectItem({
668
+ className,
669
+ children,
670
+ ...props
671
+ }) {
672
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
673
+ import_select.Select.Item,
674
+ {
675
+ "data-slot": "select-item",
676
+ className: cn(
677
+ "relative flex w-full cursor-pointer items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-none select-none focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
678
+ className
679
+ ),
680
+ ...props,
681
+ children: [
682
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_select.Select.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.CheckIcon, { className: "size-4" }) }) }),
683
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_select.Select.ItemText, { children })
684
+ ]
685
+ }
686
+ );
687
+ }
688
+ function SelectScrollUpButton({
689
+ className,
690
+ ...props
691
+ }) {
692
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
693
+ import_select.Select.ScrollUpArrow,
694
+ {
695
+ "data-slot": "select-scroll-up-button",
696
+ className: cn(
697
+ "flex cursor-default items-center justify-center py-1",
698
+ className
699
+ ),
700
+ ...props,
701
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.ChevronUpIcon, { className: "size-4" })
702
+ }
703
+ );
704
+ }
705
+ function SelectScrollDownButton({
706
+ className,
707
+ ...props
708
+ }) {
709
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
710
+ import_select.Select.ScrollDownArrow,
711
+ {
712
+ "data-slot": "select-scroll-down-button",
713
+ className: cn(
714
+ "flex cursor-default items-center justify-center py-1",
715
+ className
716
+ ),
717
+ ...props,
718
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.ChevronDownIcon, { className: "size-4" })
719
+ }
720
+ );
721
+ }
722
+
723
+ // src/components/components/Select/index.tsx
724
+ var import_jsx_runtime14 = require("react/jsx-runtime");
725
+ function Select2({
726
+ name,
727
+ label,
728
+ rules,
729
+ options = [],
730
+ value,
731
+ placeholder,
732
+ disabled,
733
+ allowClear,
734
+ onChange
735
+ }) {
736
+ const form = useFormContext();
737
+ const { t } = (0, import_runtime2.useI18n)();
738
+ const controlId = (0, import_react5.useId)();
739
+ const inForm = form?.inForm === true && typeof name === "string" && name !== "";
740
+ (0, import_react5.useEffect)(() => {
741
+ if (inForm && form && name) {
742
+ form.registerField(name, rules, value);
743
+ return () => form.unregisterField(name);
744
+ }
745
+ return void 0;
746
+ });
747
+ const current = inForm && form && name ? form.values[name] : value;
748
+ const selectedValue = current === void 0 || current === null || current === "" ? null : current;
749
+ const handleChange = (next) => {
750
+ if (inForm && form && name) {
751
+ form.setValue(name, next ?? void 0);
752
+ }
753
+ onChange?.(next ?? void 0);
754
+ };
755
+ const select = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
756
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
757
+ Select,
758
+ {
759
+ items: options,
760
+ value: selectedValue,
761
+ onValueChange: handleChange,
762
+ disabled,
763
+ name: inForm ? name : void 0,
764
+ children: [
765
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SelectTrigger, { id: controlId, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SelectValue, { placeholder }) }),
766
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SelectContent, { children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SelectItem, { value: option.value, children: option.label }, String(option.value))) })
767
+ ]
768
+ }
769
+ ),
770
+ allowClear && selectedValue !== null && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
771
+ "button",
772
+ {
773
+ type: "button",
774
+ "aria-label": t("pactor.select.clear"),
775
+ className: "cursor-pointer text-muted-foreground hover:text-foreground",
776
+ onClick: () => {
777
+ if (inForm && form && name) {
778
+ form.setValue(name, void 0);
779
+ }
780
+ onChange?.(void 0);
781
+ },
782
+ children: "\xD7"
783
+ }
784
+ ) : null
785
+ ] });
786
+ if (inForm && form && name) {
787
+ const error = form.errors[name];
788
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { "data-slot": "form-item", className: formItemClass(form.layout), children: [
789
+ label ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
790
+ "label",
791
+ {
792
+ htmlFor: controlId,
793
+ className: "shrink-0 text-sm leading-none font-medium whitespace-nowrap",
794
+ children: label
795
+ }
796
+ ) : null,
797
+ select,
798
+ error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { "data-slot": "form-error", className: "text-sm text-destructive", children: error }) : null
799
+ ] });
800
+ }
801
+ return select;
802
+ }
803
+
804
+ // src/components/components/Statistic/index.tsx
805
+ var import_jsx_runtime15 = require("react/jsx-runtime");
806
+ function Statistic({ title, value, precision, suffix }) {
807
+ const display = typeof value === "number" && precision !== void 0 ? value.toFixed(precision) : value;
808
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { "data-slot": "statistic", children: [
809
+ title ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { "data-slot": "statistic-title", className: "text-sm text-muted-foreground", children: title }) : null,
810
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { "data-slot": "statistic-value", className: "text-2xl font-bold tabular-nums", children: [
811
+ display,
812
+ suffix ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ml-1 text-sm font-normal text-muted-foreground", children: suffix }) : null
813
+ ] })
814
+ ] });
815
+ }
816
+
817
+ // src/components/components/Table/index.tsx
818
+ var import_runtime3 = require("@pactor-app/runtime");
819
+ var import_react6 = require("react");
820
+
821
+ // src/ui/table.tsx
822
+ var import_jsx_runtime16 = require("react/jsx-runtime");
823
+ function Table({ className, ...props }) {
824
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
825
+ "div",
826
+ {
827
+ "data-slot": "table-container",
828
+ className: "relative w-full overflow-x-auto",
829
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
830
+ "table",
831
+ {
832
+ "data-slot": "table",
833
+ className: cn("w-full caption-bottom text-sm", className),
834
+ ...props
835
+ }
836
+ )
837
+ }
838
+ );
839
+ }
840
+ function TableHeader({ className, ...props }) {
841
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
842
+ "thead",
843
+ {
844
+ "data-slot": "table-header",
845
+ className: cn("[&_tr]:border-b [&_tr]:border-border", className),
846
+ ...props
847
+ }
848
+ );
849
+ }
850
+ function TableBody({ className, ...props }) {
851
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
852
+ "tbody",
853
+ {
854
+ "data-slot": "table-body",
855
+ className: cn("[&_tr:last-child]:border-0", className),
856
+ ...props
857
+ }
858
+ );
859
+ }
860
+ function TableRow({ className, ...props }) {
861
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
862
+ "tr",
863
+ {
864
+ "data-slot": "table-row",
865
+ className: cn(
866
+ "border-b border-border transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
867
+ className
868
+ ),
869
+ ...props
870
+ }
871
+ );
872
+ }
873
+ function TableHead({ className, ...props }) {
874
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
875
+ "th",
876
+ {
877
+ "data-slot": "table-head",
878
+ className: cn(
879
+ "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
880
+ className
881
+ ),
882
+ ...props
883
+ }
884
+ );
885
+ }
886
+ function TableCell({ className, ...props }) {
887
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
888
+ "td",
889
+ {
890
+ "data-slot": "table-cell",
891
+ className: cn(
892
+ "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
893
+ className
894
+ ),
895
+ ...props
896
+ }
897
+ );
898
+ }
899
+
900
+ // src/components/components/Table/index.tsx
901
+ var import_jsx_runtime17 = require("react/jsx-runtime");
902
+ function renderCellValue(value) {
903
+ if (value === void 0 || value === null) {
904
+ return "";
905
+ }
906
+ if (typeof value === "object") {
907
+ return JSON.stringify(value);
908
+ }
909
+ return String(value);
910
+ }
911
+ function Table2({
912
+ columns = [],
913
+ dataSource = [],
914
+ rowKey = "id",
915
+ loading,
916
+ pagination,
917
+ onChange
918
+ }) {
919
+ const { renderChildren } = (0, import_runtime3.useRenderer)();
920
+ const { t } = (0, import_runtime3.useI18n)();
921
+ const [current, setCurrent] = (0, import_react6.useState)(1);
922
+ const pageSize = pagination === false ? void 0 : pagination?.pageSize;
923
+ const total = dataSource.length;
924
+ const pageCount = pageSize !== void 0 && pageSize > 0 ? Math.max(1, Math.ceil(total / pageSize)) : 1;
925
+ const pageRows = pageSize !== void 0 && pageSize > 0 ? dataSource.slice((current - 1) * pageSize, current * pageSize) : dataSource;
926
+ const goToPage = (page) => {
927
+ setCurrent(page);
928
+ onChange?.({ current: page, pageSize, total });
929
+ };
930
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-slot": "dsl-table", className: "relative", children: [
931
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
932
+ "div",
933
+ {
934
+ "data-slot": "table-loading",
935
+ className: "absolute inset-0 z-10 flex items-center justify-center bg-background/60 text-sm text-muted-foreground",
936
+ children: t("pactor.table.loading")
937
+ }
938
+ ) : null,
939
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Table, { children: [
940
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TableHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TableRow, { className: "hover:bg-transparent", children: columns.map((column, index) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
941
+ TableHead,
942
+ {
943
+ style: column.width !== void 0 ? { width: column.width } : void 0,
944
+ children: column.title
945
+ },
946
+ column.dataIndex ?? String(index)
947
+ )) }) }),
948
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TableBody, { children: pageRows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TableCell, { colSpan: Math.max(1, columns.length), children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
949
+ "div",
950
+ {
951
+ "data-slot": "table-empty",
952
+ className: "py-8 text-center text-muted-foreground",
953
+ children: t("pactor.table.empty")
954
+ }
955
+ ) }) }) : pageRows.map((row, rowIndex) => {
956
+ const key = row[rowKey];
957
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
958
+ TableRow,
959
+ {
960
+ children: columns.map((column, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TableCell, { children: column.cell ? renderChildren([column.cell], { row, rowIndex }) : renderCellValue(
961
+ column.dataIndex === void 0 ? void 0 : row[column.dataIndex]
962
+ ) }, column.dataIndex ?? String(columnIndex)))
963
+ },
964
+ key === void 0 || key === null ? rowIndex : String(key)
965
+ );
966
+ }) })
967
+ ] }),
968
+ pageSize !== void 0 && pageSize > 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { "data-slot": "table-pagination", className: "mt-3 flex justify-end gap-1", children: Array.from({ length: pageCount }, (_, index) => index + 1).map(
969
+ (page) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
970
+ Button,
971
+ {
972
+ type: "button",
973
+ size: "sm",
974
+ variant: page === current ? "default" : "outline",
975
+ "aria-current": page === current ? "page" : void 0,
976
+ onClick: () => goToPage(page),
977
+ children: page
978
+ },
979
+ page
980
+ )
981
+ ) }) : null
982
+ ] });
983
+ }
984
+
985
+ // src/components/components/Tabs/index.tsx
986
+ var import_runtime4 = require("@pactor-app/runtime");
987
+
988
+ // src/ui/tabs.tsx
989
+ var import_tabs = require("@base-ui/react/tabs");
990
+ var import_jsx_runtime18 = require("react/jsx-runtime");
991
+ function Tabs({
992
+ className,
993
+ ...props
994
+ }) {
995
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
996
+ import_tabs.Tabs.Root,
997
+ {
998
+ "data-slot": "tabs",
999
+ className: cn("flex flex-col gap-2", className),
1000
+ ...props
1001
+ }
1002
+ );
1003
+ }
1004
+ function TabsList({
1005
+ className,
1006
+ ...props
1007
+ }) {
1008
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1009
+ import_tabs.Tabs.List,
1010
+ {
1011
+ "data-slot": "tabs-list",
1012
+ className: cn(
1013
+ "inline-flex h-9 w-fit items-center justify-center rounded-lg bg-muted p-[3px] text-muted-foreground",
1014
+ className
1015
+ ),
1016
+ ...props
1017
+ }
1018
+ );
1019
+ }
1020
+ function TabsTrigger({
1021
+ className,
1022
+ ...props
1023
+ }) {
1024
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1025
+ import_tabs.Tabs.Tab,
1026
+ {
1027
+ "data-slot": "tabs-trigger",
1028
+ className: cn(
1029
+ "inline-flex h-[calc(100%-1px)] flex-1 cursor-pointer items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground transition-colors focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-active:border-border data-active:bg-background data-active:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1030
+ className
1031
+ ),
1032
+ ...props
1033
+ }
1034
+ );
1035
+ }
1036
+ function TabsContent({
1037
+ className,
1038
+ ...props
1039
+ }) {
1040
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1041
+ import_tabs.Tabs.Panel,
1042
+ {
1043
+ "data-slot": "tabs-content",
1044
+ className: cn("flex-1 outline-none", className),
1045
+ ...props
1046
+ }
1047
+ );
1048
+ }
1049
+
1050
+ // src/components/components/Tabs/index.tsx
1051
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1052
+ function Tabs2({ items = [], activeKey, onChange }) {
1053
+ const { renderChildren } = (0, import_runtime4.useRenderer)();
1054
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1055
+ Tabs,
1056
+ {
1057
+ value: activeKey,
1058
+ defaultValue: activeKey === void 0 ? items[0]?.key : void 0,
1059
+ onValueChange: (key) => onChange?.(key),
1060
+ children: [
1061
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TabsList, { children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TabsTrigger, { value: item.key, children: item.label }, item.key)) }),
1062
+ items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TabsContent, { value: item.key, children: renderChildren(item.children) }, item.key))
1063
+ ]
1064
+ }
1065
+ );
1066
+ }
1067
+
1068
+ // src/components/register.ts
1069
+ var shadcnComponents = {
1070
+ Page,
1071
+ Grid,
1072
+ Flex,
1073
+ Card: Card2,
1074
+ Button: Button2,
1075
+ Alert: Alert2,
1076
+ Statistic,
1077
+ Tabs: Tabs2,
1078
+ Table: Table2,
1079
+ Form,
1080
+ Input: Input2,
1081
+ Select: Select2
1082
+ };
1083
+ function registerShadcnComponents(registry) {
1084
+ for (const [type, component] of Object.entries(shadcnComponents)) {
1085
+ registry.register(type, component);
1086
+ }
1087
+ }
1088
+ function createShadcnComponentRegistry() {
1089
+ const registry = new import_core.Registry("ComponentRegistry");
1090
+ registerShadcnComponents(registry);
1091
+ return registry;
1092
+ }
1093
+ // Annotate the CommonJS export names for ESM import in node:
1094
+ 0 && (module.exports = {
1095
+ Alert,
1096
+ Button,
1097
+ Card,
1098
+ Flex,
1099
+ Form,
1100
+ Grid,
1101
+ Input,
1102
+ Page,
1103
+ Select,
1104
+ Statistic,
1105
+ Table,
1106
+ Tabs,
1107
+ createShadcnComponentRegistry,
1108
+ registerShadcnComponents,
1109
+ shadcnComponents,
1110
+ useFormContext
1111
+ });