@kilnonedre/foundation 0.0.25 → 0.0.27

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 CHANGED
@@ -136,16 +136,16 @@ type SemanticColorToken = {
136
136
  };
137
137
  declare const getSemanticColor: (semanticColor: EnumSemanticColor, variant: EnumVariant) => SemanticColorToken;
138
138
 
139
- interface ConfigProp$j {
139
+ interface ConfigProp$k {
140
140
  semanticColor?: EnumSemanticColor;
141
141
  variant?: EnumVariant;
142
142
  children?: ReactNode;
143
143
  className?: string;
144
144
  }
145
145
 
146
- declare const Badge: ({ semanticColor, variant, children, className, }: ConfigProp$j) => react_jsx_runtime.JSX.Element;
146
+ declare const Badge: ({ semanticColor, variant, children, className, }: ConfigProp$k) => react_jsx_runtime.JSX.Element;
147
147
 
148
- interface ConfigProp$i {
148
+ interface ConfigProp$j {
149
149
  semanticColor?: EnumSemanticColor;
150
150
  variant?: EnumVariant;
151
151
  children?: ReactNode;
@@ -157,15 +157,15 @@ interface ConfigProp$i {
157
157
  type?: 'button' | 'submit' | 'reset';
158
158
  }
159
159
 
160
- declare const Button: ({ semanticColor, variant, children, className, onClick, disabled, type, size, loading, }: ConfigProp$i) => react_jsx_runtime.JSX.Element;
160
+ declare const Button: ({ semanticColor, variant, children, className, onClick, disabled, type, size, loading, }: ConfigProp$j) => react_jsx_runtime.JSX.Element;
161
161
 
162
- interface ConfigProp$h {
162
+ interface ConfigProp$i {
163
163
  options: Array<CommonOption>;
164
164
  value?: string | null;
165
165
  onChange: (_v: string) => void;
166
166
  }
167
167
 
168
- declare const CheckboxSingleList: (props: ConfigProp$h) => react_jsx_runtime.JSX.Element;
168
+ declare const CheckboxSingleList: (props: ConfigProp$i) => react_jsx_runtime.JSX.Element;
169
169
 
170
170
  interface ConfigListRespT<T> {
171
171
  items: Array<T>;
@@ -193,7 +193,7 @@ type AdvancedFilterCtx = {
193
193
  draftFilters: Record<string, unknown>;
194
194
  setDraftFilters: (_updater: (_prev: Record<string, unknown>) => Record<string, unknown>) => void;
195
195
  };
196
- type ConfigProp$g<T, P> = {
196
+ type ConfigProp$h<T, P> = {
197
197
  columns: Array<ColumnDef<T>>;
198
198
  renderList: (_params: P) => Promise<ConfigApiRespT<ConfigListRespT<T>>>;
199
199
  getRowId?: (_row: T) => string;
@@ -221,7 +221,7 @@ declare const KeywordSearchBar: (props: ConfigProps$1) => react_jsx_runtime.JSX.
221
221
 
222
222
  declare const TableEmpty: () => react_jsx_runtime.JSX.Element;
223
223
 
224
- interface ConfigProp$f {
224
+ interface ConfigProp$g {
225
225
  id?: string;
226
226
  mode: EnumFormMode;
227
227
  children: ReactNode;
@@ -235,22 +235,22 @@ interface ConfigProp$f {
235
235
  onOpenChange: (_nextOpen: boolean) => void;
236
236
  }
237
237
 
238
- declare const TableFormDialog: (props: ConfigProp$f) => react_jsx_runtime.JSX.Element;
238
+ declare const TableFormDialog: (props: ConfigProp$g) => react_jsx_runtime.JSX.Element;
239
239
 
240
- interface ConfigProp$e {
240
+ interface ConfigProp$f {
241
241
  text: string;
242
242
  className?: ClassValue;
243
243
  }
244
244
 
245
- declare const TableHeaderText: (props: ConfigProp$e) => react_jsx_runtime.JSX.Element;
245
+ declare const TableHeaderText: (props: ConfigProp$f) => react_jsx_runtime.JSX.Element;
246
246
 
247
- interface ConfigProp$d {
247
+ interface ConfigProp$e {
248
248
  value: Array<CommonObject>;
249
249
  }
250
250
 
251
- declare const TableImage: (props: ConfigProp$d) => react_jsx_runtime.JSX.Element;
251
+ declare const TableImage: (props: ConfigProp$e) => react_jsx_runtime.JSX.Element;
252
252
 
253
- interface ConfigProp$c {
253
+ interface ConfigProp$d {
254
254
  totalPage: number;
255
255
  size: number;
256
256
  sizeList: Array<number>;
@@ -259,18 +259,18 @@ interface ConfigProp$c {
259
259
  onUpdateSize: (_size: number) => void;
260
260
  }
261
261
 
262
- declare const TablePagination: (props: ConfigProp$c) => react_jsx_runtime.JSX.Element;
262
+ declare const TablePagination: (props: ConfigProp$d) => react_jsx_runtime.JSX.Element;
263
263
 
264
- interface ConfigProp$b {
264
+ interface ConfigProp$c {
265
265
  text?: string | number;
266
266
  wrap?: boolean;
267
267
  }
268
268
 
269
- declare const TableText: (props: ConfigProp$b) => react_jsx_runtime.JSX.Element;
269
+ declare const TableText: (props: ConfigProp$c) => react_jsx_runtime.JSX.Element;
270
270
 
271
- declare const DataTable: <T, P>(props: ConfigProp$g<T, P>) => react_jsx_runtime.JSX.Element;
271
+ declare const DataTable: <T, P>(props: ConfigProp$h<T, P>) => react_jsx_runtime.JSX.Element;
272
272
 
273
- interface ConfigProp$a {
273
+ interface ConfigProp$b {
274
274
  children: ReactNode;
275
275
  title?: string;
276
276
  content?: ReactNode;
@@ -279,9 +279,9 @@ interface ConfigProp$a {
279
279
  onConfirm?: () => void | Promise<void>;
280
280
  }
281
281
 
282
- declare const Dialog: (props: ConfigProp$a) => react_jsx_runtime.JSX.Element;
282
+ declare const Dialog: (props: ConfigProp$b) => react_jsx_runtime.JSX.Element;
283
283
 
284
- interface ConfigProp$9<T> {
284
+ interface ConfigProp$a<T> {
285
285
  columns: Array<ColumnDef<T>>;
286
286
  list?: Array<T>;
287
287
  enableRowSelection?: boolean;
@@ -290,7 +290,7 @@ interface ConfigProp$9<T> {
290
290
  navigate?: (_id: UUID) => void;
291
291
  }
292
292
 
293
- declare const DisplayTable: <T>(props: ConfigProp$9<T>) => react_jsx_runtime.JSX.Element;
293
+ declare const DisplayTable: <T>(props: ConfigProp$a<T>) => react_jsx_runtime.JSX.Element;
294
294
 
295
295
  interface ConfigCascaderOption {
296
296
  label: string;
@@ -327,7 +327,7 @@ declare const DropdownCascaderMulti: ({ value, ...props }: ConfigDropdownCascade
327
327
 
328
328
  declare const DropdownCascaderSingle: (props: ConfigDropdownCascaderSingleProp) => react_jsx_runtime.JSX.Element;
329
329
 
330
- interface ConfigProp$8<T extends FieldValues, TName extends FieldPath<T> = FieldPath<T>> {
330
+ interface ConfigProp$9<T extends FieldValues, TName extends FieldPath<T> = FieldPath<T>> {
331
331
  id: string;
332
332
  name: TName;
333
333
  label: string;
@@ -342,16 +342,16 @@ interface ConfigProp$8<T extends FieldValues, TName extends FieldPath<T> = Field
342
342
  }) => ReactNode;
343
343
  }
344
344
 
345
- declare const FieldController: <T extends FieldValues, TName extends FieldPath<T> = FieldPath<T>>({ required, ...props }: ConfigProp$8<T, TName>) => react_jsx_runtime.JSX.Element;
345
+ declare const FieldController: <T extends FieldValues, TName extends FieldPath<T> = FieldPath<T>>({ required, ...props }: ConfigProp$9<T, TName>) => react_jsx_runtime.JSX.Element;
346
346
 
347
- interface ConfigProp$7 {
347
+ interface ConfigProp$8 {
348
348
  className?: string;
349
349
  children: ReactNode;
350
350
  }
351
351
 
352
- declare const FieldGroup: (props: ConfigProp$7) => react_jsx_runtime.JSX.Element;
352
+ declare const FieldGroup: (props: ConfigProp$8) => react_jsx_runtime.JSX.Element;
353
353
 
354
- interface ConfigProp$6 {
354
+ interface ConfigProp$7 {
355
355
  id: string;
356
356
  name: string;
357
357
  required?: boolean;
@@ -362,9 +362,9 @@ interface ConfigProp$6 {
362
362
  children?: ReactNode;
363
363
  }
364
364
 
365
- declare const FieldPlain: ({ required, mode, ...props }: ConfigProp$6) => react_jsx_runtime.JSX.Element;
365
+ declare const FieldPlain: ({ required, mode, ...props }: ConfigProp$7) => react_jsx_runtime.JSX.Element;
366
366
 
367
- interface ConfigProp$5 {
367
+ interface ConfigProp$6 {
368
368
  id?: string;
369
369
  name: string;
370
370
  value?: string | number | null;
@@ -373,9 +373,9 @@ interface ConfigProp$5 {
373
373
  render?: ReactNode;
374
374
  }
375
375
 
376
- declare const FieldText: ({ id, name, value, placeholder, required, render, }: ConfigProp$5) => react_jsx_runtime.JSX.Element;
376
+ declare const FieldText: ({ id, name, value, placeholder, required, render, }: ConfigProp$6) => react_jsx_runtime.JSX.Element;
377
377
 
378
- interface ConfigProp$4 {
378
+ interface ConfigProp$5 {
379
379
  value: string;
380
380
  onValueChange: (_val: string) => void;
381
381
  onLabelChange?: (_val: string) => void;
@@ -383,9 +383,9 @@ interface ConfigProp$4 {
383
383
  optionList: Array<CommonOption>;
384
384
  }
385
385
 
386
- declare const FormSelect: (props: ConfigProp$4) => react_jsx_runtime.JSX.Element;
386
+ declare const FormSelect: (props: ConfigProp$5) => react_jsx_runtime.JSX.Element;
387
387
 
388
- interface ConfigProp$3 {
388
+ interface ConfigProp$4 {
389
389
  value?: Date;
390
390
  onChange: (_value?: Date) => void;
391
391
  id?: string;
@@ -394,7 +394,7 @@ interface ConfigProp$3 {
394
394
  timePlaceholder?: string;
395
395
  }
396
396
 
397
- declare const FormTimePicker: (props: ConfigProp$3) => react_jsx_runtime.JSX.Element;
397
+ declare const FormTimePicker: (props: ConfigProp$4) => react_jsx_runtime.JSX.Element;
398
398
 
399
399
  interface ConfigProps {
400
400
  value?: Array<UUID>;
@@ -415,19 +415,26 @@ declare const Provider: ({ children }: {
415
415
  children: React.ReactNode;
416
416
  }) => react_jsx_runtime.JSX.Element;
417
417
 
418
+ interface ConfigProp$3 {
419
+ children: ReactNode;
420
+ className?: ClassValue;
421
+ }
422
+
423
+ declare const Text: (props: ConfigProp$3) => react_jsx_runtime.JSX.Element;
424
+
418
425
  interface ConfigProp$2 {
419
426
  children: ReactNode;
420
427
  className?: ClassValue;
421
428
  }
422
429
 
423
- declare const Text: (props: ConfigProp$2) => react_jsx_runtime.JSX.Element;
430
+ declare const Title: (props: ConfigProp$2) => react_jsx_runtime.JSX.Element;
424
431
 
425
432
  interface ConfigProp$1 {
426
433
  children: ReactNode;
427
- className?: ClassValue;
434
+ footer?: ReactNode;
428
435
  }
429
436
 
430
- declare const Title: (props: ConfigProp$1) => react_jsx_runtime.JSX.Element;
437
+ declare const BaseLayout: (props: ConfigProp$1) => react_jsx_runtime.JSX.Element;
431
438
 
432
439
  interface ConfigProp<T extends object, K extends keyof T> {
433
440
  key: K;
@@ -459,6 +466,42 @@ declare const renderTextarea: <T extends FieldValues>(props: ConfigRenderBase<T>
459
466
  declare const renderInput: <T extends FieldValues>(props: ConfigRenderBase<T>) => react_jsx_runtime.JSX.Element;
460
467
  declare const renderPasswordInput: <T extends FieldValues>(props: ConfigRenderPasswordInput<T>) => react_jsx_runtime.JSX.Element;
461
468
 
469
+ type Events = {
470
+ 'HTTP:ERR': ConfigHttpErr;
471
+ 'HTTP:UNAUTH': ConfigHttpUnauth;
472
+ 'API:ERR': ConfigApiErr;
473
+ };
474
+ interface ConfigHttpErr {
475
+ status: number;
476
+ url: string;
477
+ method: string;
478
+ }
479
+ interface ConfigHttpUnauth {
480
+ status: 401;
481
+ url: string;
482
+ }
483
+ interface ConfigApiErr {
484
+ code: string;
485
+ msg: string;
486
+ url: string;
487
+ }
488
+ type Listener<T> = (_payload: T) => void;
489
+ type AnyFn = (..._args: unknown[]) => unknown;
490
+
491
+ declare const registerRouterSubscriber: (onLogoutRequired: () => void) => () => void;
492
+
493
+ declare const registerToastSubscriber: () => () => void;
494
+
495
+ declare const assembleApp: (onLogoutRequired: () => void) => () => void;
496
+
497
+ declare class EventBus {
498
+ private listeners;
499
+ on<K extends keyof Events>(event: K, cb: Listener<Events[K]>): () => void;
500
+ off<K extends keyof Events>(event: K, cb: Listener<Events[K]>): void;
501
+ emit<K extends keyof Events>(event: K, payload: Events[K]): void;
502
+ }
503
+ declare const eventBus: EventBus;
504
+
462
505
  declare const boolToText: (bool: boolean) => "是" | "否";
463
506
 
464
507
  declare function cn(...inputs: ClassValue[]): string;
@@ -524,4 +567,4 @@ declare const zCoerceNumberOptional: (label: string, min?: number, max?: number)
524
567
  declare const zDecimal: (label: string, min?: number, max?: number) => z.ZodString;
525
568
  declare const zDecimalOptional: (label: string, min?: number, max?: number) => z.ZodOptional<z.ZodString>;
526
569
 
527
- export { Badge, Button, CheckboxSingleList, type CommonObject, type CommonOption, type ConfigCascaderOption, type ConfigDropdownCascaderMultiProp, type ConfigDropdownCascaderSingleProp, type ConfigRenderBase, type ConfigRenderPasswordInput, DataTable, Dialog, DisplayTable, DropdownCascaderMulti, DropdownCascaderSingle, EnumApprovalStatus, EnumApprovalStatusLabel, EnumApprovalView, EnumApprovalViewLabel, EnumEntityStatus, EnumEntityStatusLabel, EnumFormMode, EnumFormModeLabel, EnumGenderType, EnumGenderTypeLabel, EnumMapProvider, EnumMapProviderLabel, EnumOrderStatus, EnumOrderStatusLabel, EnumPublishMethod, EnumPublishMethodLabel, EnumSemanticColor, EnumSemanticColorLabel, EnumStorageMethod, EnumStorageMethodLabel, EnumVariant, EnumVariantLabel, FieldController, FieldGroup, FieldPlain, FieldText, FormSelect, FormTimePicker, KeywordSearchBar, MediaUploader, Provider, type SemanticColorToken, TableEmpty, TableFormDialog, TableHeaderText, TableImage, TablePagination, TableText, Text, Title, type UUID, boolToText, buildColumn, cn, emptyToUndefined, enumApprovalStatusOptions, enumApprovalViewOptions, enumEntityStatusOptions, enumFormModeOptions, enumGenderTypeOptions, enumMapProviderOptions, enumOrderStatusOptions, enumPublishMethodOptions, enumSemanticColorOptions, enumStorageMethodOptions, enumToOptions, enumValues, enumVariantOptions, formatDateTime, formatDecimal, genUuid, getOptionMap, getSemanticColor, getSuccessMessage, isEmpty, isFormData, isValidEmail, isValidURL, renderBody, renderCascaderNodes, renderConfirmFooter, renderFooter, renderInput, renderPasswordInput, renderTextarea, zBool, zCoerceNumber, zCoerceNumberOptional, zDate, zDateOptional, zDecimal, zDecimalOptional, zEmail, zEnumNullable, zEnumNullableOptional, zEnumNullableRequired, zEnumOptional, zEnumRequired, zId, zIdCard, zIdCardOptional, zIds, zImageId, zImageIdRequired, zImageIds, zImageIdsOptional, zNumber, zNumberOptional, zPhone, zTextOptional, zTextRequired, zTexts };
570
+ export { type AnyFn, Badge, BaseLayout, Button, CheckboxSingleList, type CommonObject, type CommonOption, type ConfigApiErr, type ConfigCascaderOption, type ConfigDropdownCascaderMultiProp, type ConfigDropdownCascaderSingleProp, type ConfigHttpErr, type ConfigHttpUnauth, type ConfigRenderBase, type ConfigRenderPasswordInput, DataTable, Dialog, DisplayTable, DropdownCascaderMulti, DropdownCascaderSingle, EnumApprovalStatus, EnumApprovalStatusLabel, EnumApprovalView, EnumApprovalViewLabel, EnumEntityStatus, EnumEntityStatusLabel, EnumFormMode, EnumFormModeLabel, EnumGenderType, EnumGenderTypeLabel, EnumMapProvider, EnumMapProviderLabel, EnumOrderStatus, EnumOrderStatusLabel, EnumPublishMethod, EnumPublishMethodLabel, EnumSemanticColor, EnumSemanticColorLabel, EnumStorageMethod, EnumStorageMethodLabel, EnumVariant, EnumVariantLabel, type Events, FieldController, FieldGroup, FieldPlain, FieldText, FormSelect, FormTimePicker, KeywordSearchBar, type Listener, MediaUploader, Provider, type SemanticColorToken, TableEmpty, TableFormDialog, TableHeaderText, TableImage, TablePagination, TableText, Text, Title, type UUID, assembleApp, boolToText, buildColumn, cn, emptyToUndefined, enumApprovalStatusOptions, enumApprovalViewOptions, enumEntityStatusOptions, enumFormModeOptions, enumGenderTypeOptions, enumMapProviderOptions, enumOrderStatusOptions, enumPublishMethodOptions, enumSemanticColorOptions, enumStorageMethodOptions, enumToOptions, enumValues, enumVariantOptions, eventBus, formatDateTime, formatDecimal, genUuid, getOptionMap, getSemanticColor, getSuccessMessage, isEmpty, isFormData, isValidEmail, isValidURL, registerRouterSubscriber, registerToastSubscriber, renderBody, renderCascaderNodes, renderConfirmFooter, renderFooter, renderInput, renderPasswordInput, renderTextarea, zBool, zCoerceNumber, zCoerceNumberOptional, zDate, zDateOptional, zDecimal, zDecimalOptional, zEmail, zEnumNullable, zEnumNullableOptional, zEnumNullableRequired, zEnumOptional, zEnumRequired, zId, zIdCard, zIdCardOptional, zIds, zImageId, zImageIdRequired, zImageIds, zImageIdsOptional, zNumber, zNumberOptional, zPhone, zTextOptional, zTextRequired, zTexts };
package/dist/index.js CHANGED
@@ -3263,25 +3263,7 @@ var FormTimePicker = (props) => {
3263
3263
  // src/components/media-uploader/index.tsx
3264
3264
  import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef2, useState as useState8 } from "react";
3265
3265
  import { Eye as Eye2, Loader2, Plus, Trash2 } from "lucide-react";
3266
-
3267
- // src/shadcn/components/card.tsx
3268
- import { jsx as jsx46 } from "react/jsx-runtime";
3269
- function Card({ className, ...props }) {
3270
- return /* @__PURE__ */ jsx46(
3271
- "div",
3272
- {
3273
- "data-slot": "card",
3274
- className: cn(
3275
- "flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-sm",
3276
- className
3277
- ),
3278
- ...props
3279
- }
3280
- );
3281
- }
3282
-
3283
- // src/components/media-uploader/index.tsx
3284
- import { jsx as jsx47, jsxs as jsxs28 } from "react/jsx-runtime";
3266
+ import { jsx as jsx46, jsxs as jsxs28 } from "react/jsx-runtime";
3285
3267
  var MediaUploader = ({ value = [], ...props }) => {
3286
3268
  const inputRef = useRef2(null);
3287
3269
  const [items, setItems] = useState8([]);
@@ -3408,7 +3390,7 @@ var MediaUploader = ({ value = [], ...props }) => {
3408
3390
  };
3409
3391
  const showUploadButton = canEdit && (!props.multiple && items.length === 0 || props.multiple);
3410
3392
  return /* @__PURE__ */ jsxs28("div", { className: cn2("space-y-3", props.className), children: [
3411
- /* @__PURE__ */ jsx47(
3393
+ /* @__PURE__ */ jsx46(
3412
3394
  "input",
3413
3395
  {
3414
3396
  ref: inputRef,
@@ -3425,56 +3407,63 @@ var MediaUploader = ({ value = [], ...props }) => {
3425
3407
  }
3426
3408
  }
3427
3409
  ),
3428
- /* @__PURE__ */ jsx47(ScrollArea, { className: "rounded-lg border", children: /* @__PURE__ */ jsxs28("div", { className: "grid grid-cols-2 gap-3 p-3 sm:grid-cols-3 lg:grid-cols-4", children: [
3429
- items.map((it, index) => /* @__PURE__ */ jsx47(Card, { className: "group overflow-hidden", children: /* @__PURE__ */ jsxs28("div", { className: "relative aspect-square bg-muted", children: [
3430
- it.url || it.localUrl ? /* @__PURE__ */ jsx47(
3431
- "img",
3432
- {
3433
- src: it.url ?? it.localUrl,
3434
- alt: "",
3435
- className: "h-full w-full object-cover"
3436
- }
3437
- ) : /* @__PURE__ */ jsx47("div", { className: "h-full w-full" }),
3438
- it.uploading && /* @__PURE__ */ jsx47("div", { className: "absolute inset-0 flex items-center justify-center bg-black/40", children: /* @__PURE__ */ jsx47(Loader2, { className: "h-6 w-6 animate-spin text-white" }) }),
3439
- !it.uploading && (it.url || it.localUrl) && /* @__PURE__ */ jsxs28("div", { className: "absolute inset-0 flex items-start justify-end gap-2 p-2 opacity-0 transition group-hover:opacity-100", children: [
3440
- /* @__PURE__ */ jsx47(
3441
- Button,
3442
- {
3443
- size: "icon",
3444
- variant: "secondary",
3445
- className: "h-8 w-8",
3446
- onClick: () => setPreview(it),
3447
- type: "button",
3448
- children: /* @__PURE__ */ jsx47(Eye2, { className: "h-4 w-4" })
3449
- }
3450
- ),
3451
- canEdit && /* @__PURE__ */ jsx47(
3452
- Button,
3453
- {
3454
- size: "icon",
3455
- variant: "destructive",
3456
- className: "h-8 w-8",
3457
- onClick: () => remove(it.id),
3458
- type: "button",
3459
- children: /* @__PURE__ */ jsx47(Trash2, { className: "h-4 w-4" })
3460
- }
3461
- )
3462
- ] })
3463
- ] }) }, it.id + index)),
3464
- showUploadButton && /* @__PURE__ */ jsx47(
3465
- Card,
3410
+ /* @__PURE__ */ jsx46(ScrollArea, { className: "rounded-lg border", children: /* @__PURE__ */ jsxs28("div", { className: "grid grid-cols-2 gap-3 p-3 sm:grid-cols-3 lg:grid-cols-4", children: [
3411
+ items.map((it, index) => /* @__PURE__ */ jsx46(
3412
+ "div",
3413
+ {
3414
+ className: "rounded-xl border bg-card text-card-foreground shadow group overflow-hidden",
3415
+ children: /* @__PURE__ */ jsxs28("div", { className: "relative aspect-square bg-muted", children: [
3416
+ it.url || it.localUrl ? /* @__PURE__ */ jsx46(
3417
+ "img",
3418
+ {
3419
+ src: it.url ?? it.localUrl,
3420
+ alt: "",
3421
+ className: "h-full w-full object-cover"
3422
+ }
3423
+ ) : /* @__PURE__ */ jsx46("div", { className: "h-full w-full" }),
3424
+ it.uploading && /* @__PURE__ */ jsx46("div", { className: "absolute inset-0 flex items-center justify-center bg-black/40", children: /* @__PURE__ */ jsx46(Loader2, { className: "h-6 w-6 animate-spin text-white" }) }),
3425
+ !it.uploading && (it.url || it.localUrl) && /* @__PURE__ */ jsxs28("div", { className: "absolute inset-0 flex items-start justify-end gap-2 p-2 opacity-0 transition group-hover:opacity-100", children: [
3426
+ /* @__PURE__ */ jsx46(
3427
+ Button,
3428
+ {
3429
+ size: "icon",
3430
+ variant: "secondary",
3431
+ className: "h-8 w-8",
3432
+ onClick: () => setPreview(it),
3433
+ type: "button",
3434
+ children: /* @__PURE__ */ jsx46(Eye2, { className: "h-4 w-4" })
3435
+ }
3436
+ ),
3437
+ canEdit && /* @__PURE__ */ jsx46(
3438
+ Button,
3439
+ {
3440
+ size: "icon",
3441
+ variant: "destructive",
3442
+ className: "h-8 w-8",
3443
+ onClick: () => remove(it.id),
3444
+ type: "button",
3445
+ children: /* @__PURE__ */ jsx46(Trash2, { className: "h-4 w-4" })
3446
+ }
3447
+ )
3448
+ ] })
3449
+ ] })
3450
+ },
3451
+ it.id + index
3452
+ )),
3453
+ showUploadButton && /* @__PURE__ */ jsx46(
3454
+ "div",
3466
3455
  {
3467
- className: "flex aspect-square cursor-pointer items-center justify-center hover:bg-muted/50",
3456
+ className: "rounded-xl border bg-card text-card-foreground shadow flex aspect-square cursor-pointer items-center justify-center hover:bg-muted/50",
3468
3457
  onClick: () => {
3469
3458
  inputRef.current?.click();
3470
3459
  },
3471
- children: /* @__PURE__ */ jsx47(Plus, { className: "h-6 w-6 text-muted-foreground" })
3460
+ children: /* @__PURE__ */ jsx46(Plus, { className: "h-6 w-6 text-muted-foreground" })
3472
3461
  }
3473
3462
  )
3474
3463
  ] }) }),
3475
- /* @__PURE__ */ jsx47(Dialog, { open: !!preview, onOpenChange: () => setPreview(null), children: /* @__PURE__ */ jsxs28(DialogContent, { className: "max-w-3xl", children: [
3476
- /* @__PURE__ */ jsx47(DialogHeader, { children: /* @__PURE__ */ jsx47(DialogTitle, { children: "\u9884\u89C8" }) }),
3477
- preview && /* @__PURE__ */ jsx47("div", { className: "relative aspect-video w-full overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ jsx47(
3464
+ /* @__PURE__ */ jsx46(Dialog, { open: !!preview, onOpenChange: () => setPreview(null), children: /* @__PURE__ */ jsxs28(DialogContent, { className: "max-w-3xl", children: [
3465
+ /* @__PURE__ */ jsx46(DialogHeader, { children: /* @__PURE__ */ jsx46(DialogTitle, { children: "\u9884\u89C8" }) }),
3466
+ preview && /* @__PURE__ */ jsx46("div", { className: "relative aspect-video w-full overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ jsx46(
3478
3467
  "img",
3479
3468
  {
3480
3469
  src: preview.url ?? preview.localUrl ?? "",
@@ -3487,15 +3476,24 @@ var MediaUploader = ({ value = [], ...props }) => {
3487
3476
  };
3488
3477
 
3489
3478
  // src/components/provider/index.tsx
3490
- import { jsx as jsx48 } from "react/jsx-runtime";
3479
+ import { jsx as jsx47 } from "react/jsx-runtime";
3491
3480
  var Provider = ({ children }) => {
3492
- return /* @__PURE__ */ jsx48(TooltipProvider, { children });
3481
+ return /* @__PURE__ */ jsx47(TooltipProvider, { children });
3493
3482
  };
3494
3483
 
3495
3484
  // src/components/title/index.tsx
3496
- import { jsx as jsx49 } from "react/jsx-runtime";
3485
+ import { jsx as jsx48 } from "react/jsx-runtime";
3497
3486
  var Title = (props) => {
3498
- return /* @__PURE__ */ jsx49("div", { className: cn2("text-lg font-bold", props.className), children: props.children });
3487
+ return /* @__PURE__ */ jsx48("div", { className: cn2("text-lg font-bold", props.className), children: props.children });
3488
+ };
3489
+
3490
+ // src/layout/base/index.tsx
3491
+ import { jsx as jsx49, jsxs as jsxs29 } from "react/jsx-runtime";
3492
+ var BaseLayout = (props) => {
3493
+ return /* @__PURE__ */ jsxs29("div", { className: "flex flex-col h-full", children: [
3494
+ /* @__PURE__ */ jsx49("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ jsx49("div", { className: "py-4 px-4 md:gap-6 md:py-6 lg:px-6", children: props.children }) }),
3495
+ props.footer && /* @__PURE__ */ jsx49("div", { className: "border-t bg-white px-4 py-3 lg:px-6 sticky bottom-0", children: props.footer })
3496
+ ] });
3499
3497
  };
3500
3498
 
3501
3499
  // src/render/column/build-column/index.tsx
@@ -3514,8 +3512,90 @@ var buildColumn = () => (props) => {
3514
3512
  }
3515
3513
  };
3516
3514
  };
3515
+
3516
+ // src/shared/event-bus/module/toast/toast-subscriber.ts
3517
+ import { toast } from "sonner";
3518
+ var errMessageObj = {
3519
+ 400: "\u8BF7\u6C42\u9519\u8BEF(400)",
3520
+ 401: "\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55(401)",
3521
+ 403: "\u62D2\u7EDD\u8BBF\u95EE(403)",
3522
+ 404: "\u8BF7\u6C42\u51FA\u9519(404)",
3523
+ 408: "\u8BF7\u6C42\u8D85\u65F6(408)",
3524
+ 500: "\u670D\u52A1\u5668\u9519\u8BEF(500)",
3525
+ 501: "\u670D\u52A1\u672A\u5B9E\u73B0(501)",
3526
+ 502: "\u7F51\u7EDC\u9519\u8BEF(502)",
3527
+ 503: "\u670D\u52A1\u4E0D\u53EF\u7528(503)",
3528
+ 504: "\u7F51\u7EDC\u8D85\u65F6(504)",
3529
+ 505: "HTTP\u7248\u672C\u4E0D\u53D7\u652F\u6301(505)"
3530
+ };
3531
+ var errMessage = (status) => {
3532
+ const message = errMessageObj[status] ?? `\u8FDE\u63A5\u51FA\u9519(${status})`;
3533
+ return `${message}\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u6216\u8054\u7CFB\u7BA1\u7406\u5458\uFF01`;
3534
+ };
3535
+ var registerToastSubscriber = () => {
3536
+ const onHttpUnauth = ({ status }) => {
3537
+ toast.error(errMessage(status));
3538
+ };
3539
+ const onHttpErr = ({ status }) => {
3540
+ toast.error(errMessage(status));
3541
+ };
3542
+ const onApiErr = ({ msg }) => {
3543
+ toast.error(msg);
3544
+ };
3545
+ eventBus.on("HTTP:UNAUTH", onHttpUnauth);
3546
+ eventBus.on("HTTP:ERR", onHttpErr);
3547
+ eventBus.on("API:ERR", onApiErr);
3548
+ return () => {
3549
+ eventBus.off("HTTP:UNAUTH", onHttpUnauth);
3550
+ eventBus.off("HTTP:ERR", onHttpErr);
3551
+ eventBus.off("API:ERR", onApiErr);
3552
+ };
3553
+ };
3554
+
3555
+ // src/shared/event-bus/module/router/router-subscriber.ts
3556
+ var registerRouterSubscriber = (onLogoutRequired) => {
3557
+ eventBus.on("HTTP:UNAUTH", onLogoutRequired);
3558
+ return () => {
3559
+ eventBus.off("HTTP:UNAUTH", onLogoutRequired);
3560
+ };
3561
+ };
3562
+
3563
+ // src/shared/event-bus/module/index.ts
3564
+ var composeCleanups = (...cleanups) => {
3565
+ return () => {
3566
+ cleanups.forEach((fn) => typeof fn === "function" && fn());
3567
+ };
3568
+ };
3569
+ var assembleApp = (onLogoutRequired) => {
3570
+ return composeCleanups(registerToastSubscriber(), onLogoutRequired());
3571
+ };
3572
+
3573
+ // src/shared/event-bus/index.ts
3574
+ var EventBus = class {
3575
+ listeners = /* @__PURE__ */ new Map();
3576
+ on(event, cb) {
3577
+ let set = this.listeners.get(event);
3578
+ if (!set) {
3579
+ set = /* @__PURE__ */ new Set();
3580
+ this.listeners.set(event, set);
3581
+ }
3582
+ set.add(cb);
3583
+ return () => this.off(event, cb);
3584
+ }
3585
+ off(event, cb) {
3586
+ this.listeners.get(event)?.delete(cb);
3587
+ }
3588
+ emit(event, payload) {
3589
+ this.listeners.get(event)?.forEach((fn) => {
3590
+ ;
3591
+ fn(payload);
3592
+ });
3593
+ }
3594
+ };
3595
+ var eventBus = new EventBus();
3517
3596
  export {
3518
3597
  Badge2 as Badge,
3598
+ BaseLayout,
3519
3599
  Button2 as Button,
3520
3600
  CheckboxSingleList,
3521
3601
  DataTable,
@@ -3562,6 +3642,7 @@ export {
3562
3642
  TableText,
3563
3643
  Text,
3564
3644
  Title,
3645
+ assembleApp,
3565
3646
  boolToText,
3566
3647
  buildColumn,
3567
3648
  cn2 as cn,
@@ -3579,6 +3660,7 @@ export {
3579
3660
  enumToOptions,
3580
3661
  enumValues,
3581
3662
  enumVariantOptions,
3663
+ eventBus,
3582
3664
  formatDateTime,
3583
3665
  formatDecimal,
3584
3666
  genUuid,
@@ -3589,6 +3671,8 @@ export {
3589
3671
  isFormData,
3590
3672
  isValidEmail,
3591
3673
  isValidURL,
3674
+ registerRouterSubscriber,
3675
+ registerToastSubscriber,
3592
3676
  renderBody,
3593
3677
  renderCascaderNodes,
3594
3678
  renderConfirmFooter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kilnonedre/foundation",
3
- "version": "0.0.25",
3
+ "version": "0.0.27",
4
4
  "private": false,
5
5
  "description": "Kilnonedre frontend foundation package",
6
6
  "type": "module",
@@ -70,6 +70,7 @@
70
70
  "radix-ui": "^1.4.3",
71
71
  "react-day-picker": "^10.0.1",
72
72
  "react-hook-form": "^7.76.1",
73
+ "sonner": "^2.0.7",
73
74
  "tailwind-merge": "^3.6.0",
74
75
  "uuid": "^14.0.0",
75
76
  "zod": "^4.4.3"