@k3-universe/react-kit 0.0.12 → 0.0.13
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/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5393 -1357
- package/dist/kit/builder/form/components/FormBuilder.d.ts +21 -0
- package/dist/kit/builder/form/components/FormBuilder.d.ts.map +1 -1
- package/dist/kit/builder/form/components/fields/FileField.d.ts +1 -1
- package/dist/kit/builder/form/components/fields/FileField.d.ts.map +1 -1
- package/dist/kit/builder/stack-dialog/hooks.d.ts +2 -5
- package/dist/kit/builder/stack-dialog/hooks.d.ts.map +1 -1
- package/dist/kit/builder/stack-dialog/index.d.ts +3 -3
- package/dist/kit/builder/stack-dialog/index.d.ts.map +1 -1
- package/dist/kit/builder/stack-dialog/renderer.d.ts.map +1 -1
- package/dist/kit/builder/stack-dialog/types.d.ts +1 -0
- package/dist/kit/builder/stack-dialog/types.d.ts.map +1 -1
- package/dist/kit/components/fileuploader/FileUploader.d.ts +4 -0
- package/dist/kit/components/fileuploader/FileUploader.d.ts.map +1 -0
- package/dist/kit/components/fileuploader/index.d.ts +4 -0
- package/dist/kit/components/fileuploader/index.d.ts.map +1 -0
- package/dist/kit/components/fileuploader/types.d.ts +63 -0
- package/dist/kit/components/fileuploader/types.d.ts.map +1 -0
- package/dist/kit/themes/clean-slate.css +60 -0
- package/dist/kit/themes/default.css +60 -0
- package/dist/kit/themes/minimal-modern.css +60 -0
- package/dist/kit/themes/spotify.css +60 -0
- package/package.json +2 -1
- package/src/index.ts +2 -0
- package/src/kit/builder/form/components/FormBuilder.tsx +56 -0
- package/src/kit/builder/form/components/fields/FileField.tsx +17 -5
- package/src/kit/builder/stack-dialog/hooks.ts +2 -1
- package/src/kit/builder/stack-dialog/index.ts +8 -3
- package/src/kit/builder/stack-dialog/renderer.tsx +2 -2
- package/src/kit/builder/stack-dialog/types.ts +2 -0
- package/src/kit/components/fileuploader/FileUploader.tsx +488 -0
- package/src/kit/components/fileuploader/index.ts +3 -0
- package/src/kit/components/fileuploader/types.ts +73 -0
- package/src/stories/FileUploader.stories.tsx +166 -0
- package/src/stories/kit/builder/Form.ArrayLayouts.stories.tsx +1 -1
- package/src/stories/kit/builder/Form.Autocomplete.stories.tsx +5 -5
- package/src/stories/kit/builder/Form.DateTime.stories.tsx +1 -1
- package/src/stories/kit/builder/Form.Files.stories.tsx +125 -0
- package/src/stories/kit/builder/Form.Time.stories.tsx +1 -1
|
@@ -87,6 +87,8 @@
|
|
|
87
87
|
--font-sans: var(--font-sans);
|
|
88
88
|
--font-serif: var(--font-serif);
|
|
89
89
|
--font-mono: var(--font-mono);
|
|
90
|
+
--color-red-500: oklch(63.7% .237 25.331);
|
|
91
|
+
--color-green-500: oklch(72.3% .219 149.579);
|
|
90
92
|
--color-teal-50: oklch(98.4% .014 180.72);
|
|
91
93
|
--color-teal-700: oklch(51.1% .096 186.391);
|
|
92
94
|
--color-blue-50: oklch(97% .014 254.604);
|
|
@@ -470,6 +472,10 @@
|
|
|
470
472
|
top: calc(var(--spacing) * 0);
|
|
471
473
|
}
|
|
472
474
|
|
|
475
|
+
.top-1 {
|
|
476
|
+
top: calc(var(--spacing) * 1);
|
|
477
|
+
}
|
|
478
|
+
|
|
473
479
|
.top-1\.5 {
|
|
474
480
|
top: calc(var(--spacing) * 1.5);
|
|
475
481
|
}
|
|
@@ -942,6 +948,10 @@
|
|
|
942
948
|
height: calc(var(--spacing) * 5);
|
|
943
949
|
}
|
|
944
950
|
|
|
951
|
+
.h-6 {
|
|
952
|
+
height: calc(var(--spacing) * 6);
|
|
953
|
+
}
|
|
954
|
+
|
|
945
955
|
.h-7 {
|
|
946
956
|
height: calc(var(--spacing) * 7);
|
|
947
957
|
}
|
|
@@ -970,6 +980,10 @@
|
|
|
970
980
|
height: calc(var(--spacing) * 24);
|
|
971
981
|
}
|
|
972
982
|
|
|
983
|
+
.h-28 {
|
|
984
|
+
height: calc(var(--spacing) * 28);
|
|
985
|
+
}
|
|
986
|
+
|
|
973
987
|
.h-40 {
|
|
974
988
|
height: calc(var(--spacing) * 40);
|
|
975
989
|
}
|
|
@@ -1118,6 +1132,10 @@
|
|
|
1118
1132
|
width: calc(var(--spacing) * 5);
|
|
1119
1133
|
}
|
|
1120
1134
|
|
|
1135
|
+
.w-6 {
|
|
1136
|
+
width: calc(var(--spacing) * 6);
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1121
1139
|
.w-7 {
|
|
1122
1140
|
width: calc(var(--spacing) * 7);
|
|
1123
1141
|
}
|
|
@@ -1146,6 +1164,10 @@
|
|
|
1146
1164
|
width: calc(var(--spacing) * 24);
|
|
1147
1165
|
}
|
|
1148
1166
|
|
|
1167
|
+
.w-28 {
|
|
1168
|
+
width: calc(var(--spacing) * 28);
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1149
1171
|
.w-32 {
|
|
1150
1172
|
width: calc(var(--spacing) * 32);
|
|
1151
1173
|
}
|
|
@@ -1734,6 +1756,10 @@
|
|
|
1734
1756
|
row-gap: calc(var(--spacing) * .5);
|
|
1735
1757
|
}
|
|
1736
1758
|
|
|
1759
|
+
.self-center {
|
|
1760
|
+
align-self: center;
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1737
1763
|
.self-start {
|
|
1738
1764
|
align-self: flex-start;
|
|
1739
1765
|
}
|
|
@@ -1960,6 +1986,16 @@
|
|
|
1960
1986
|
}
|
|
1961
1987
|
}
|
|
1962
1988
|
|
|
1989
|
+
.bg-black\/40 {
|
|
1990
|
+
background-color: #0006;
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1993
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1994
|
+
.bg-black\/40 {
|
|
1995
|
+
background-color: color-mix(in oklab, var(--color-black) 40%, transparent);
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1963
1999
|
.bg-black\/50 {
|
|
1964
2000
|
background-color: #00000080;
|
|
1965
2001
|
}
|
|
@@ -2420,6 +2456,10 @@
|
|
|
2420
2456
|
color: var(--color-gray-900);
|
|
2421
2457
|
}
|
|
2422
2458
|
|
|
2459
|
+
.text-green-500 {
|
|
2460
|
+
color: var(--color-green-500);
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2423
2463
|
.text-muted-foreground {
|
|
2424
2464
|
color: var(--muted-foreground);
|
|
2425
2465
|
}
|
|
@@ -2436,6 +2476,10 @@
|
|
|
2436
2476
|
color: var(--primary-foreground);
|
|
2437
2477
|
}
|
|
2438
2478
|
|
|
2479
|
+
.text-red-500 {
|
|
2480
|
+
color: var(--color-red-500);
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2439
2483
|
.text-secondary-foreground {
|
|
2440
2484
|
color: var(--secondary-foreground);
|
|
2441
2485
|
}
|
|
@@ -2594,6 +2638,12 @@
|
|
|
2594
2638
|
outline-width: 1px;
|
|
2595
2639
|
}
|
|
2596
2640
|
|
|
2641
|
+
.drop-shadow {
|
|
2642
|
+
--tw-drop-shadow-size: drop-shadow(0 1px 2px var(--tw-drop-shadow-color, #0000001a)) drop-shadow(0 1px 1px var(--tw-drop-shadow-color, #0000000f));
|
|
2643
|
+
--tw-drop-shadow: drop-shadow(0 1px 2px #0000001a) drop-shadow(0 1px 1px #0000000f);
|
|
2644
|
+
filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2597
2647
|
.filter {
|
|
2598
2648
|
filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );
|
|
2599
2649
|
}
|
|
@@ -3150,6 +3200,16 @@
|
|
|
3150
3200
|
}
|
|
3151
3201
|
|
|
3152
3202
|
@media (hover: hover) {
|
|
3203
|
+
.hover\:border-foreground\/50:hover {
|
|
3204
|
+
border-color: var(--foreground);
|
|
3205
|
+
}
|
|
3206
|
+
|
|
3207
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
3208
|
+
.hover\:border-foreground\/50:hover {
|
|
3209
|
+
border-color: color-mix(in oklab, var(--foreground) 50%, transparent);
|
|
3210
|
+
}
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3153
3213
|
.hover\:bg-accent:hover {
|
|
3154
3214
|
background-color: var(--accent);
|
|
3155
3215
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@k3-universe/react-kit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
"next-themes": "^0.4.6",
|
|
65
65
|
"react-day-picker": "^9.9.0",
|
|
66
66
|
"react-hook-form": "^7.62.0",
|
|
67
|
+
"react-dropzone": "^14.2.3",
|
|
67
68
|
"react-resizable-panels": "^3.0.4",
|
|
68
69
|
"recharts": "2.15.4",
|
|
69
70
|
"sonner": "^2.0.7",
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ export * from './kit/builder/dialog';
|
|
|
6
6
|
export * from './kit/builder/form';
|
|
7
7
|
export * from './kit/builder/section';
|
|
8
8
|
export * from './kit/builder/page';
|
|
9
|
+
export * from './kit/builder/stack-dialog';
|
|
9
10
|
// Ensure default export for Page at root
|
|
10
11
|
export { default as Page } from './kit/builder/page/Page';
|
|
11
12
|
|
|
@@ -16,6 +17,7 @@ export * from './kit/components/autocomplete';
|
|
|
16
17
|
export * from './kit/components/login';
|
|
17
18
|
// Ensure default export for Login at root
|
|
18
19
|
export { default as Login } from './kit/components/login/Login';
|
|
20
|
+
export * from './kit/components/fileuploader';
|
|
19
21
|
|
|
20
22
|
// -----------------------------
|
|
21
23
|
// KIT: layouts (admin)
|
|
@@ -17,6 +17,11 @@ import type {
|
|
|
17
17
|
AutocompleteFetcher,
|
|
18
18
|
AutocompleteOption,
|
|
19
19
|
} from '../../../components/autocomplete/types';
|
|
20
|
+
import type { Accept } from 'react-dropzone';
|
|
21
|
+
import type {
|
|
22
|
+
FileRecord,
|
|
23
|
+
FileUploaderLayout,
|
|
24
|
+
} from '../../../components/fileuploader/types';
|
|
20
25
|
|
|
21
26
|
export interface FormBuilderFieldConfig {
|
|
22
27
|
id?: string; // Optional ID for test fixtures
|
|
@@ -75,6 +80,9 @@ export interface FormBuilderFieldConfig {
|
|
|
75
80
|
max?: { value: number; message: string };
|
|
76
81
|
minLength?: { value: number; message: string };
|
|
77
82
|
maxLength?: { value: number; message: string };
|
|
83
|
+
// For array-like fields (e.g., file uploader)
|
|
84
|
+
minItems?: { value: number; message: string };
|
|
85
|
+
maxItems?: { value: number; message: string };
|
|
78
86
|
};
|
|
79
87
|
defaultValue?: unknown;
|
|
80
88
|
fields?: FormBuilderFieldConfig[]; // For nested object/array fields
|
|
@@ -136,6 +144,21 @@ export interface FormBuilderFieldConfig {
|
|
|
136
144
|
hourCycle?: 12 | 24;
|
|
137
145
|
minuteStep?: number;
|
|
138
146
|
secondStep?: number;
|
|
147
|
+
// File uploader specific options
|
|
148
|
+
fileMultiple?: boolean;
|
|
149
|
+
fileMaxFiles?: number;
|
|
150
|
+
fileAccept?: Accept;
|
|
151
|
+
fileLayout?: FileUploaderLayout;
|
|
152
|
+
fileWithDownload?: boolean;
|
|
153
|
+
fileUploader?: (
|
|
154
|
+
file: File,
|
|
155
|
+
onProgress: (pct: number) => void,
|
|
156
|
+
) => Promise<Partial<FileRecord>>;
|
|
157
|
+
fileOnUploadSuccess?: (file: FileRecord) => void;
|
|
158
|
+
fileOnUploadError?: (file: FileRecord, error: unknown) => void;
|
|
159
|
+
fileOnRemove?: (file: FileRecord) => void | Promise<void>;
|
|
160
|
+
fileOnRetry?: (file: FileRecord) => void;
|
|
161
|
+
fileOnRetryAll?: (files: FileRecord[]) => void;
|
|
139
162
|
}
|
|
140
163
|
|
|
141
164
|
export interface FormBuilderSectionConfig {
|
|
@@ -236,6 +259,9 @@ export function FormBuilder({
|
|
|
236
259
|
case 'number':
|
|
237
260
|
baseSchema = z.number();
|
|
238
261
|
break;
|
|
262
|
+
case 'file':
|
|
263
|
+
baseSchema = z.array(z.unknown());
|
|
264
|
+
break;
|
|
239
265
|
case 'date_picker':
|
|
240
266
|
case 'month':
|
|
241
267
|
case 'date':
|
|
@@ -304,6 +330,27 @@ export function FormBuilder({
|
|
|
304
330
|
validationObj.maxLength.message
|
|
305
331
|
);
|
|
306
332
|
}
|
|
333
|
+
// Array item count constraints
|
|
334
|
+
if (baseSchema instanceof z.ZodArray) {
|
|
335
|
+
let arr = baseSchema as z.ZodArray<z.ZodTypeAny>;
|
|
336
|
+
if (validationObj.minItems) {
|
|
337
|
+
arr = arr.min(
|
|
338
|
+
validationObj.minItems.value,
|
|
339
|
+
validationObj.minItems.message,
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
if (validationObj.maxItems) {
|
|
343
|
+
arr = arr.max(
|
|
344
|
+
validationObj.maxItems.value,
|
|
345
|
+
validationObj.maxItems.message,
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
// If required and file field, enforce at least 1 item when no explicit minItems
|
|
349
|
+
if (field.type === 'file' && field.required && !validationObj.minItems) {
|
|
350
|
+
arr = arr.min(1, `${field.label} requires at least 1 file`);
|
|
351
|
+
}
|
|
352
|
+
baseSchema = arr;
|
|
353
|
+
}
|
|
307
354
|
|
|
308
355
|
return field.required ? baseSchema : baseSchema.optional();
|
|
309
356
|
}
|
|
@@ -317,6 +364,15 @@ export function FormBuilder({
|
|
|
317
364
|
case 'number':
|
|
318
365
|
fieldSchema = z.number();
|
|
319
366
|
break;
|
|
367
|
+
case 'file': {
|
|
368
|
+
let arr = z.array(z.unknown());
|
|
369
|
+
// If required, ensure at least 1 file
|
|
370
|
+
if (field.required) {
|
|
371
|
+
arr = arr.min(1, `${field.label} requires at least 1 file`);
|
|
372
|
+
}
|
|
373
|
+
fieldSchema = arr;
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
320
376
|
case 'date_picker':
|
|
321
377
|
case 'month':
|
|
322
378
|
case 'date':
|
|
@@ -1,14 +1,26 @@
|
|
|
1
|
-
import { Input } from '../../../../../shadcn/ui/input'
|
|
2
1
|
import type { FieldRenderProps } from './types'
|
|
2
|
+
import { FileUploader } from '../../../../components/fileuploader/FileUploader'
|
|
3
3
|
|
|
4
|
-
export function FileField({ field, onChange, className }: FieldRenderProps) {
|
|
4
|
+
export function FileField({ field, value, onChange, className }: FieldRenderProps) {
|
|
5
|
+
const files = Array.isArray(value) ? value : []
|
|
5
6
|
return (
|
|
6
|
-
<
|
|
7
|
+
<FileUploader
|
|
7
8
|
className={className}
|
|
8
9
|
disabled={field.disabled}
|
|
9
10
|
placeholder={field.placeholder}
|
|
10
|
-
|
|
11
|
-
onChange={(
|
|
11
|
+
value={files}
|
|
12
|
+
onChange={(files) => onChange(files)}
|
|
13
|
+
multiple={field.fileMultiple ?? true}
|
|
14
|
+
maxFiles={field.fileMaxFiles}
|
|
15
|
+
accept={field.fileAccept}
|
|
16
|
+
layout={field.fileLayout ?? 'grid'}
|
|
17
|
+
withDownload={field.fileWithDownload ?? true}
|
|
18
|
+
uploader={field.fileUploader}
|
|
19
|
+
onUploadSuccess={field.fileOnUploadSuccess}
|
|
20
|
+
onUploadError={field.fileOnUploadError}
|
|
21
|
+
onRemove={field.fileOnRemove}
|
|
22
|
+
onRetry={field.fileOnRetry}
|
|
23
|
+
onRetryAll={field.fileOnRetryAll}
|
|
12
24
|
/>
|
|
13
25
|
)
|
|
14
26
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { useContext } from 'react';
|
|
2
2
|
import { StackDialogContext } from './context';
|
|
3
|
+
import type { StackDialogHook } from './types';
|
|
3
4
|
|
|
4
|
-
export function useStackDialog() {
|
|
5
|
+
export function useStackDialog(): StackDialogHook {
|
|
5
6
|
const { createDialog, closeDialog, closeAllDialogs } = useContext(StackDialogContext);
|
|
6
7
|
return {
|
|
7
8
|
createDialog,
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
export {
|
|
2
|
-
StackDialogContext
|
|
2
|
+
StackDialogContext,
|
|
3
3
|
} from './context'
|
|
4
4
|
|
|
5
5
|
export {
|
|
6
|
-
StackDialogContextProvider as
|
|
6
|
+
StackDialogContextProvider as StackDialogProvider,
|
|
7
7
|
} from './provider'
|
|
8
8
|
|
|
9
9
|
export {
|
|
10
10
|
useStackDialog
|
|
11
11
|
} from './hooks'
|
|
12
12
|
|
|
13
|
-
export type
|
|
13
|
+
export type {
|
|
14
|
+
StackDialogContextInstance,
|
|
15
|
+
StackDialogCreateConfig,
|
|
16
|
+
StackDialogHook,
|
|
17
|
+
StackDialogInstance
|
|
18
|
+
} from './types'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Dialog } from '@/shadcn/ui/dialog';
|
|
2
|
-
import { StackDialogInstance } from './types';
|
|
3
1
|
import { DialogContent } from '@radix-ui/react-dialog';
|
|
2
|
+
import { Dialog } from '../../../shadcn/ui/dialog';
|
|
3
|
+
import { StackDialogInstance } from './types';
|
|
4
4
|
|
|
5
5
|
export function StackDialogRenderer(props: {
|
|
6
6
|
dialogs: StackDialogInstance[],
|