@sparklingopinions/sparkling-ui 0.4.2 → 0.6.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.
Files changed (100) hide show
  1. package/README.md +1 -1
  2. package/dist/aliases.d.ts +176 -26
  3. package/dist/components/Avatar/Avatar.js.map +1 -1
  4. package/dist/components/Avatar/Avatar.vue.d.ts +3 -2
  5. package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js +20 -14
  6. package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/Board/Board.js.map +1 -1
  8. package/dist/components/Board/Board.vue.d.ts +6 -2
  9. package/dist/components/Board/Board.vue_vue_type_script_setup_true_lang.js +142 -74
  10. package/dist/components/Board/Board.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/components/Button/Button.js.map +1 -1
  12. package/dist/components/Button/Button.vue.d.ts +1 -1
  13. package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js +4 -2
  14. package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -1
  15. package/dist/components/ContextMenu/ContextMenu.js +7 -0
  16. package/dist/components/ContextMenu/ContextMenu.js.map +1 -0
  17. package/dist/components/ContextMenu/ContextMenu.vue.d.ts +44 -0
  18. package/dist/components/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js +84 -0
  19. package/dist/components/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  20. package/dist/components/ContextMenu/index.d.ts +2 -0
  21. package/dist/components/DataList/DataList.js.map +1 -1
  22. package/dist/components/DataList/DataList.vue.d.ts +8 -0
  23. package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js +71 -52
  24. package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js.map +1 -1
  25. package/dist/components/DataList/types.d.ts +5 -1
  26. package/dist/components/Dialog/Dialog.js.map +1 -1
  27. package/dist/components/Dialog/Dialog.vue.d.ts +22 -6
  28. package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js +174 -72
  29. package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/Dialog/useSheetDrag.d.ts +16 -0
  31. package/dist/components/Dialog/useSheetDrag.js +37 -0
  32. package/dist/components/Dialog/useSheetDrag.js.map +1 -0
  33. package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
  34. package/dist/components/DropdownMenu/DropdownMenu.vue.d.ts +6 -30
  35. package/dist/components/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js +54 -74
  36. package/dist/components/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  37. package/dist/components/EmptyState/EmptyState.js.map +1 -1
  38. package/dist/components/EmptyState/EmptyState.vue.d.ts +9 -3
  39. package/dist/components/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js +35 -7
  40. package/dist/components/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/components/Filters/FilterChip.js.map +1 -1
  42. package/dist/components/Filters/FilterChip.vue.d.ts +4 -1
  43. package/dist/components/Filters/FilterChip.vue_vue_type_script_setup_true_lang.js +29 -24
  44. package/dist/components/Filters/FilterChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/Filters/FilterMenu.js.map +1 -1
  46. package/dist/components/Filters/FilterMenu.vue.d.ts +20 -1
  47. package/dist/components/Filters/FilterMenu.vue_vue_type_script_setup_true_lang.js +78 -56
  48. package/dist/components/Filters/FilterMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  49. package/dist/components/Filters/SortMenu.js.map +1 -1
  50. package/dist/components/Filters/SortMenu.vue.d.ts +21 -1
  51. package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js +90 -66
  52. package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  53. package/dist/components/Filters/index.d.ts +2 -1
  54. package/dist/components/Filters/trigger.d.ts +17 -0
  55. package/dist/components/Filters/trigger.js +33 -0
  56. package/dist/components/Filters/trigger.js.map +1 -0
  57. package/dist/components/Filters/types.d.ts +8 -0
  58. package/dist/components/FormField/FormField.js.map +1 -1
  59. package/dist/components/FormField/FormField.vue.d.ts +10 -0
  60. package/dist/components/FormField/FormField.vue_vue_type_script_setup_true_lang.js +31 -20
  61. package/dist/components/FormField/FormField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  62. package/dist/components/Icon/iconSet.js +9 -1
  63. package/dist/components/Icon/iconSet.js.map +1 -1
  64. package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
  65. package/dist/components/SegmentedControl/SegmentedControl.vue.d.ts +6 -3
  66. package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js +20 -17
  67. package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -1
  68. package/dist/components/SegmentedControl/index.d.ts +1 -1
  69. package/dist/components/Table/Table.js.map +1 -1
  70. package/dist/components/Table/Table.vue.d.ts +4 -0
  71. package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js +66 -56
  72. package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js.map +1 -1
  73. package/dist/components/Table/types.d.ts +2 -0
  74. package/dist/components/Tag/Tag.js.map +1 -1
  75. package/dist/components/Tag/Tag.vue.d.ts +16 -3
  76. package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js +42 -19
  77. package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js.map +1 -1
  78. package/dist/components/Toast/ToastMessage.js.map +1 -1
  79. package/dist/components/Toast/ToastMessage.vue.d.ts +13 -1
  80. package/dist/components/Toast/ToastMessage.vue_vue_type_script_setup_true_lang.js +58 -23
  81. package/dist/components/Toast/ToastMessage.vue_vue_type_script_setup_true_lang.js.map +1 -1
  82. package/dist/components/Toast/Toaster.js.map +1 -1
  83. package/dist/components/Toast/Toaster.vue.d.ts +7 -3
  84. package/dist/components/Toast/Toaster.vue_vue_type_script_setup_true_lang.js +50 -21
  85. package/dist/components/Toast/Toaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
  86. package/dist/components/internal/MenuItemContent.js +7 -0
  87. package/dist/components/internal/MenuItemContent.js.map +1 -0
  88. package/dist/components/internal/MenuItemContent.vue.d.ts +7 -0
  89. package/dist/components/internal/MenuItemContent.vue_vue_type_script_setup_true_lang.js +26 -0
  90. package/dist/components/internal/MenuItemContent.vue_vue_type_script_setup_true_lang.js.map +1 -0
  91. package/dist/components/internal/menu.d.ts +46 -0
  92. package/dist/components/internal/menu.js +33 -0
  93. package/dist/components/internal/menu.js.map +1 -0
  94. package/dist/composables/toast.d.ts +20 -5
  95. package/dist/composables/toast.js +28 -20
  96. package/dist/composables/toast.js.map +1 -1
  97. package/dist/index.d.ts +2 -1
  98. package/dist/index.js +34 -33
  99. package/package.json +1 -1
  100. package/src/styles/tailwind.css +29 -0
package/README.md CHANGED
@@ -67,7 +67,7 @@ The package is published to npm as `@sparklingopinions/sparkling-ui`. Apps insta
67
67
  import { Button } from 'sparkling-ui'
68
68
  ```
69
69
 
70
- 5. `Icon` draws the library's set of 114 icons by name: `<Icon name="users" color="ink-muted" />`. Older names (`people`, `companies`, `dot-vertical`...) resolve as aliases, and `iconNames` lists the set. To add icons or replace some of the set, register a resolver once, before mounting; names it returns a component for win. With SVG files imported as components (e.g. `vite-svg-loader`):
70
+ 5. `Icon` draws the library's set of 118 icons by name: `<Icon name="users" color="ink-muted" />`. Older names (`people`, `companies`, `dot-vertical`...) resolve as aliases, and `iconNames` lists the set. To add icons or replace some of the set, register a resolver once, before mounting; names it returns a component for win. With SVG files imported as components (e.g. `vite-svg-loader`):
71
71
 
72
72
  ```ts
73
73
  import { type Component, defineAsyncComponent } from 'vue'
package/dist/aliases.d.ts CHANGED
@@ -182,6 +182,11 @@ export declare const List: <T extends Record<string, any>>(__VLS_props: NonNulla
182
182
  'group-leading'?: (props: {
183
183
  group: DataListGroup<T>;
184
184
  }) => unknown;
185
+ 'group-header'?: (props: {
186
+ group: DataListGroup<T>;
187
+ count: number;
188
+ collapsed: boolean;
189
+ }) => unknown;
185
190
  leading?: (props: {
186
191
  item: T;
187
192
  }) => unknown;
@@ -200,6 +205,7 @@ export declare const List: <T extends Record<string, any>>(__VLS_props: NonNulla
200
205
  rowKey?: (keyof T & string) | undefined;
201
206
  selectable?: boolean | undefined;
202
207
  loading?: boolean | undefined;
208
+ variant?: "joined" | "cards" | undefined;
203
209
  headingLevel?: 2 | 3 | 4 | 5 | 6 | undefined;
204
210
  onRowClick?: ((item: T) => void) | undefined;
205
211
  onNew?: ((group: DataListGroup<T>) => void) | undefined;
@@ -220,6 +226,11 @@ export declare const List: <T extends Record<string, any>>(__VLS_props: NonNulla
220
226
  'group-leading'?: (props: {
221
227
  group: DataListGroup<T>;
222
228
  }) => unknown;
229
+ 'group-header'?: (props: {
230
+ group: DataListGroup<T>;
231
+ count: number;
232
+ collapsed: boolean;
233
+ }) => unknown;
223
234
  leading?: (props: {
224
235
  item: T;
225
236
  }) => unknown;
@@ -262,6 +273,8 @@ export declare const Modal: {
262
273
  confirmIcon: string;
263
274
  band: string | boolean;
264
275
  hint: string;
276
+ presentation: "dialog" | "auto" | "sheet";
277
+ sheetBelow: number;
265
278
  }, false, {}, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
266
279
  P: {};
267
280
  B: {};
@@ -286,6 +299,8 @@ export declare const Modal: {
286
299
  confirmIcon: string;
287
300
  band: string | boolean;
288
301
  hint: string;
302
+ presentation: "dialog" | "auto" | "sheet";
303
+ sheetBelow: number;
289
304
  }>;
290
305
  __isFragment?: never;
291
306
  __isTeleport?: never;
@@ -311,8 +326,18 @@ export declare const Modal: {
311
326
  confirmIcon: string;
312
327
  band: string | boolean;
313
328
  hint: string;
329
+ presentation: "dialog" | "auto" | "sheet";
330
+ sheetBelow: number;
314
331
  }, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new () => {
315
332
  $slots: {
333
+ title?: (props: {}) => any;
334
+ } & {
335
+ default?: (props: {}) => any;
336
+ } & {
337
+ footer?: (props: {}) => any;
338
+ } & {
339
+ 'footer-start'?: (props: {}) => any;
340
+ } & {
316
341
  hero?: (props: {}) => any;
317
342
  } & {
318
343
  title?: (props: {}) => any;
@@ -345,13 +370,13 @@ export declare const OptionsMenu: {
345
370
  confirmLabel: string;
346
371
  cancelLabel: string;
347
372
  id: string;
373
+ confirmTitle: string;
374
+ confirmMessage: string;
375
+ deleteLabel: string;
348
376
  items: DropdownMenuEntry[];
349
377
  buttonIcon: string;
350
378
  buttonLabel: string;
351
379
  tooltip: string | null;
352
- confirmTitle: string;
353
- confirmMessage: string;
354
- deleteLabel: string;
355
380
  }, false, {}, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
356
381
  P: {};
357
382
  B: {};
@@ -370,13 +395,13 @@ export declare const OptionsMenu: {
370
395
  confirmLabel: string;
371
396
  cancelLabel: string;
372
397
  id: string;
398
+ confirmTitle: string;
399
+ confirmMessage: string;
400
+ deleteLabel: string;
373
401
  items: DropdownMenuEntry[];
374
402
  buttonIcon: string;
375
403
  buttonLabel: string;
376
404
  tooltip: string | null;
377
- confirmTitle: string;
378
- confirmMessage: string;
379
- deleteLabel: string;
380
405
  }>;
381
406
  __isFragment?: never;
382
407
  __isTeleport?: never;
@@ -398,13 +423,13 @@ export declare const OptionsMenu: {
398
423
  confirmLabel: string;
399
424
  cancelLabel: string;
400
425
  id: string;
426
+ confirmTitle: string;
427
+ confirmMessage: string;
428
+ deleteLabel: string;
401
429
  items: DropdownMenuEntry[];
402
430
  buttonIcon: string;
403
431
  buttonLabel: string;
404
432
  tooltip: string | null;
405
- confirmTitle: string;
406
- confirmMessage: string;
407
- deleteLabel: string;
408
433
  }, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new () => {
409
434
  $slots: {
410
435
  trigger?: (props: {
@@ -425,17 +450,67 @@ export declare const FormErrors: import("vue").DefineComponent<ErrorSummaryProps
425
450
  /** @deprecated Renamed to ErrorSummaryProps. */
426
451
  export type FormErrorsProps = ErrorSummaryProps;
427
452
  /** @deprecated Renamed to FilterMenu. */
428
- export declare const FilterFieldPicker: import("vue").DefineComponent<FilterMenuProps & {
429
- open?: boolean;
430
- }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
431
- pick: (name: string) => any;
432
- "update:open": (value: boolean) => any;
433
- }, string, import("vue").PublicProps, Readonly<FilterMenuProps & {
453
+ export declare const FilterFieldPicker: {
454
+ new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<Readonly<FilterMenuProps & {
455
+ open?: boolean;
456
+ }> & Readonly<{
457
+ onPick?: ((name: string) => any) | undefined;
458
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
459
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
460
+ pick: (name: string) => any;
461
+ "update:open": (value: boolean) => any;
462
+ }, import("vue").PublicProps, {
463
+ variant: "secondary" | "tinted" | "ghost";
464
+ as: "button" | "chip";
465
+ label: string;
466
+ closeLabel: string;
467
+ buttonLabel: string;
468
+ status: string;
469
+ inUse: string[];
470
+ searchPlaceholder: string;
471
+ inUseLabel: string;
472
+ addLabel: string;
473
+ fieldsLabel: string;
474
+ noMatchLabel: string;
475
+ }, false, {}, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
476
+ P: {};
477
+ B: {};
478
+ D: {};
479
+ C: {};
480
+ M: {};
481
+ Defaults: {};
482
+ }, Readonly<FilterMenuProps & {
483
+ open?: boolean;
484
+ }> & Readonly<{
485
+ onPick?: ((name: string) => any) | undefined;
486
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
487
+ }>, {}, {}, {}, {}, {
488
+ variant: "secondary" | "tinted" | "ghost";
489
+ as: "button" | "chip";
490
+ label: string;
491
+ closeLabel: string;
492
+ buttonLabel: string;
493
+ status: string;
494
+ inUse: string[];
495
+ searchPlaceholder: string;
496
+ inUseLabel: string;
497
+ addLabel: string;
498
+ fieldsLabel: string;
499
+ noMatchLabel: string;
500
+ }>;
501
+ __isFragment?: never;
502
+ __isTeleport?: never;
503
+ __isSuspense?: never;
504
+ } & import("vue").ComponentOptionsBase<Readonly<FilterMenuProps & {
434
505
  open?: boolean;
435
506
  }> & Readonly<{
436
507
  onPick?: ((name: string) => any) | undefined;
437
508
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
438
- }>, {
509
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
510
+ pick: (name: string) => any;
511
+ "update:open": (value: boolean) => any;
512
+ }, string, {
513
+ variant: "secondary" | "tinted" | "ghost";
439
514
  as: "button" | "chip";
440
515
  label: string;
441
516
  closeLabel: string;
@@ -447,23 +522,79 @@ export declare const FilterFieldPicker: import("vue").DefineComponent<FilterMenu
447
522
  addLabel: string;
448
523
  fieldsLabel: string;
449
524
  noMatchLabel: string;
450
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
525
+ }, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new () => {
526
+ $slots: {
527
+ trigger?: (props: {
528
+ open: boolean;
529
+ toggle: () => void;
530
+ count: number;
531
+ props: import("./index.ts").FilterTriggerProps;
532
+ }) => unknown;
533
+ };
534
+ });
451
535
  /** @deprecated Renamed to FilterMenuProps. */
452
536
  export type FilterFieldPickerProps = FilterMenuProps;
453
537
  /** @deprecated Renamed to SortMenu. */
454
- export declare const SortControl: import("vue").DefineComponent<SortMenuProps & {
455
- modelValue?: import("./index.ts").ViewSort | null;
456
- open?: boolean;
457
- }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
458
- "update:modelValue": (value: import("./index.ts").ViewSort | null) => any;
459
- "update:open": (value: boolean) => any;
460
- }, string, import("vue").PublicProps, Readonly<SortMenuProps & {
538
+ export declare const SortControl: {
539
+ new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<Readonly<SortMenuProps & {
540
+ modelValue?: import("./index.ts").ViewSort | null;
541
+ open?: boolean;
542
+ }> & Readonly<{
543
+ "onUpdate:modelValue"?: ((value: import("./index.ts").ViewSort | null) => any) | undefined;
544
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
545
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
546
+ "update:modelValue": (value: import("./index.ts").ViewSort | null) => any;
547
+ "update:open": (value: boolean) => any;
548
+ }, import("vue").PublicProps, {
549
+ variant: "secondary" | "tinted" | "ghost";
550
+ as: "button" | "chip";
551
+ title: string;
552
+ clearLabel: string;
553
+ closeLabel: string;
554
+ buttonLabel: string;
555
+ status: string;
556
+ directionLabels: Partial<Record<import("./index.ts").FilterFieldType, [string, string]>>;
557
+ directionLabel: string;
558
+ doneLabel: string;
559
+ }, false, {}, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
560
+ P: {};
561
+ B: {};
562
+ D: {};
563
+ C: {};
564
+ M: {};
565
+ Defaults: {};
566
+ }, Readonly<SortMenuProps & {
567
+ modelValue?: import("./index.ts").ViewSort | null;
568
+ open?: boolean;
569
+ }> & Readonly<{
570
+ "onUpdate:modelValue"?: ((value: import("./index.ts").ViewSort | null) => any) | undefined;
571
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
572
+ }>, {}, {}, {}, {}, {
573
+ variant: "secondary" | "tinted" | "ghost";
574
+ as: "button" | "chip";
575
+ title: string;
576
+ clearLabel: string;
577
+ closeLabel: string;
578
+ buttonLabel: string;
579
+ status: string;
580
+ directionLabels: Partial<Record<import("./index.ts").FilterFieldType, [string, string]>>;
581
+ directionLabel: string;
582
+ doneLabel: string;
583
+ }>;
584
+ __isFragment?: never;
585
+ __isTeleport?: never;
586
+ __isSuspense?: never;
587
+ } & import("vue").ComponentOptionsBase<Readonly<SortMenuProps & {
461
588
  modelValue?: import("./index.ts").ViewSort | null;
462
589
  open?: boolean;
463
590
  }> & Readonly<{
464
591
  "onUpdate:modelValue"?: ((value: import("./index.ts").ViewSort | null) => any) | undefined;
465
592
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
466
- }>, {
593
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
594
+ "update:modelValue": (value: import("./index.ts").ViewSort | null) => any;
595
+ "update:open": (value: boolean) => any;
596
+ }, string, {
597
+ variant: "secondary" | "tinted" | "ghost";
467
598
  as: "button" | "chip";
468
599
  title: string;
469
600
  clearLabel: string;
@@ -473,7 +604,17 @@ export declare const SortControl: import("vue").DefineComponent<SortMenuProps &
473
604
  directionLabels: Partial<Record<import("./index.ts").FilterFieldType, [string, string]>>;
474
605
  directionLabel: string;
475
606
  doneLabel: string;
476
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
607
+ }, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new () => {
608
+ $slots: {
609
+ trigger?: (props: {
610
+ open: boolean;
611
+ toggle: () => void;
612
+ active: boolean;
613
+ label: string;
614
+ props: import("./index.ts").FilterTriggerProps;
615
+ }) => unknown;
616
+ };
617
+ });
477
618
  /** @deprecated Renamed to SortMenuProps. */
478
619
  export type SortControlProps = SortMenuProps;
479
620
  /** @deprecated Renamed to FormField. */
@@ -484,10 +625,13 @@ export declare const Field: {
484
625
  id: string;
485
626
  hint: string;
486
627
  maxLength: number;
628
+ softLimit: number;
487
629
  layout: "stacked" | "inline";
488
630
  optionalLabel: string;
489
631
  requiredLabel: string;
490
632
  counterLabel: string;
633
+ softCounterLabel: string;
634
+ overSoftLabel: string;
491
635
  }, false, {}, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
492
636
  P: {};
493
637
  B: {};
@@ -501,10 +645,13 @@ export declare const Field: {
501
645
  id: string;
502
646
  hint: string;
503
647
  maxLength: number;
648
+ softLimit: number;
504
649
  layout: "stacked" | "inline";
505
650
  optionalLabel: string;
506
651
  requiredLabel: string;
507
652
  counterLabel: string;
653
+ softCounterLabel: string;
654
+ overSoftLabel: string;
508
655
  }>;
509
656
  __isFragment?: never;
510
657
  __isTeleport?: never;
@@ -515,10 +662,13 @@ export declare const Field: {
515
662
  id: string;
516
663
  hint: string;
517
664
  maxLength: number;
665
+ softLimit: number;
518
666
  layout: "stacked" | "inline";
519
667
  optionalLabel: string;
520
668
  requiredLabel: string;
521
669
  counterLabel: string;
670
+ softCounterLabel: string;
671
+ overSoftLabel: string;
522
672
  }, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new () => {
523
673
  $slots: {
524
674
  default?: (props: {
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.js","names":["_sfc_main","Avatar_vue_vue_type_script_setup_true_lang_default","Avatar_default"],"sources":["../../../src/components/Avatar/Avatar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { type Hue, hueFor } from '../../utils/hues'\n\nexport interface AvatarProps {\n name?: string | null\n image?: string | null\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n shape?: 'circle' | 'square'\n /** An attention dot, e.g. unread. */\n badge?: boolean\n /** Pins the colour when it means something; otherwise it comes from the name, stable per person. */\n hue?: Hue\n}\n\nconst props = withDefaults(defineProps<AvatarProps>(), {\n name: undefined,\n image: undefined,\n size: 'sm',\n shape: 'circle',\n hue: undefined\n})\n\n// One uppercased initial reads cleaner than two letters.\nconst initial = computed(() => (props.name || '?').trim().charAt(0).toUpperCase() || '?')\n\nconst sizes = {\n xs: 'h-4 w-4 text-10',\n sm: 'h-6 w-6 text-11',\n md: 'h-8 w-8 text-xs',\n lg: 'h-10 w-10 text-sm',\n xl: 'h-16 w-16 text-2xl'\n}\n\n// A soft coin of one hue: tinted fill, saturated text, a hairline of the hue.\nconst hues: Record<Hue, string> = {\n blue: 'border-sui-hue-blue-line bg-sui-hue-blue-soft text-sui-hue-blue-ink',\n green: 'border-sui-hue-green-line bg-sui-hue-green-soft text-sui-hue-green-ink',\n orange: 'border-sui-hue-orange-line bg-sui-hue-orange-soft text-sui-hue-orange-ink',\n pink: 'border-sui-hue-pink-line bg-sui-hue-pink-soft text-sui-hue-pink-ink',\n purple: 'border-sui-hue-purple-line bg-sui-hue-purple-soft text-sui-hue-purple-ink',\n slate: 'border-sui-hue-slate-line bg-sui-hue-slate-soft text-sui-hue-slate-ink',\n red: 'border-sui-hue-red-line bg-sui-hue-red-soft text-sui-hue-red-ink',\n amber: 'border-sui-hue-amber-line bg-sui-hue-amber-soft text-sui-hue-amber-ink',\n gray: 'border-sui-line bg-sui-sunken text-sui-ink-body'\n}\n\nconst shapeClass = computed(() => (props.shape === 'square' ? 'rounded-lg' : 'rounded-full'))\n\n// A photo gets a neutral hairline, so it reads as a crisp coin too.\nconst colorClass = computed(() => (props.image ? 'border-sui-line-subtle' : hues[props.hue ?? hueFor(props.name)]))\n</script>\n\n<template>\n <div\n class=\"relative inline-flex shrink-0 items-center justify-center border font-semibold\"\n :class=\"[sizes[size], shapeClass, colorClass]\"\n >\n <img v-if=\"image\" alt=\"\" class=\"h-full w-full object-cover\" :class=\"shapeClass\" :src=\"image\" />\n <template v-else>{{ initial }}</template>\n <span\n v-if=\"badge\"\n class=\"absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-sui-accent-solid ring-2 ring-sui-surface\"\n />\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Avatar.js","names":["_sfc_main","Avatar_vue_vue_type_script_setup_true_lang_default","Avatar_default"],"sources":["../../../src/components/Avatar/Avatar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { type Hue, hueFor } from '../../utils/hues'\n\nexport interface AvatarProps {\n name?: string | null\n image?: string | null\n /** xs 16, sm 24, md 32, lg 40, xl 64; or a number of px, 20 for list rows and activity feeds. */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number\n shape?: 'circle' | 'square'\n /** An attention dot, e.g. unread. */\n badge?: boolean\n /** Pins the colour when it means something; otherwise it comes from the name, stable per person. */\n hue?: Hue\n}\n\nconst props = withDefaults(defineProps<AvatarProps>(), {\n name: undefined,\n image: undefined,\n size: 'sm',\n shape: 'circle',\n hue: undefined\n})\n\n// One uppercased initial reads cleaner than two letters.\nconst initial = computed(() => (props.name || '?').trim().charAt(0).toUpperCase() || '?')\n\nconst sizes = {\n xs: 'h-4 w-4 text-10',\n sm: 'h-6 w-6 text-11',\n md: 'h-8 w-8 text-xs',\n lg: 'h-10 w-10 text-sm',\n xl: 'h-16 w-16 text-2xl'\n}\n\n// A soft coin of one hue: tinted fill, saturated text, a hairline of the hue.\nconst hues: Record<Hue, string> = {\n blue: 'border-sui-hue-blue-line bg-sui-hue-blue-soft text-sui-hue-blue-ink',\n green: 'border-sui-hue-green-line bg-sui-hue-green-soft text-sui-hue-green-ink',\n orange: 'border-sui-hue-orange-line bg-sui-hue-orange-soft text-sui-hue-orange-ink',\n pink: 'border-sui-hue-pink-line bg-sui-hue-pink-soft text-sui-hue-pink-ink',\n purple: 'border-sui-hue-purple-line bg-sui-hue-purple-soft text-sui-hue-purple-ink',\n slate: 'border-sui-hue-slate-line bg-sui-hue-slate-soft text-sui-hue-slate-ink',\n red: 'border-sui-hue-red-line bg-sui-hue-red-soft text-sui-hue-red-ink',\n amber: 'border-sui-hue-amber-line bg-sui-hue-amber-soft text-sui-hue-amber-ink',\n gray: 'border-sui-line bg-sui-sunken text-sui-ink-body'\n}\n\n// A number of px: the initial steps down with the coin.\nconst sizeClass = computed(() => {\n if (typeof props.size !== 'number') return sizes[props.size]\n if (props.size <= 20) return 'text-10'\n if (props.size <= 28) return 'text-11'\n return props.size <= 36 ? 'text-xs' : 'text-sm'\n})\nconst sizeStyle = computed(() =>\n typeof props.size === 'number' ? { width: `${props.size}px`, height: `${props.size}px` } : undefined\n)\n\nconst shapeClass = computed(() => (props.shape === 'square' ? 'rounded-lg' : 'rounded-full'))\n\n// A photo gets a neutral hairline, so it reads as a crisp coin too.\nconst colorClass = computed(() => (props.image ? 'border-sui-line-subtle' : hues[props.hue ?? hueFor(props.name)]))\n</script>\n\n<template>\n <div\n class=\"relative inline-flex shrink-0 items-center justify-center border font-semibold\"\n :class=\"[sizeClass, shapeClass, colorClass]\"\n :style=\"sizeStyle\"\n >\n <img v-if=\"image\" alt=\"\" class=\"h-full w-full object-cover\" :class=\"shapeClass\" :src=\"image\" />\n <template v-else>{{ initial }}</template>\n <span\n v-if=\"badge\"\n class=\"absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-sui-accent-solid ring-2 ring-sui-surface\"\n />\n </div>\n</template>\n"],"mappings":""}
@@ -2,7 +2,8 @@ import { type Hue } from '../../utils/hues';
2
2
  export interface AvatarProps {
3
3
  name?: string | null;
4
4
  image?: string | null;
5
- size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
5
+ /** xs 16, sm 24, md 32, lg 40, xl 64; or a number of px, 20 for list rows and activity feeds. */
6
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number;
6
7
  shape?: 'circle' | 'square';
7
8
  /** An attention dot, e.g. unread. */
8
9
  badge?: boolean;
@@ -10,7 +11,7 @@ export interface AvatarProps {
10
11
  hue?: Hue;
11
12
  }
12
13
  declare const __VLS_export: import("vue").DefineComponent<AvatarProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<AvatarProps> & Readonly<{}>, {
13
- size: "xs" | "sm" | "md" | "lg" | "xl";
14
+ size: number | "xs" | "sm" | "md" | "lg" | "xl";
14
15
  image: string | null;
15
16
  name: string | null;
16
17
  shape: "circle" | "square";
@@ -1,10 +1,10 @@
1
1
  import { hueFor as e } from "../../utils/hues.js";
2
- import { Fragment as t, computed as n, createCommentVNode as r, createElementBlock as i, createTextVNode as a, defineComponent as o, normalizeClass as s, openBlock as c, toDisplayString as l } from "vue";
2
+ import { Fragment as t, computed as n, createCommentVNode as r, createElementBlock as i, createTextVNode as a, defineComponent as o, normalizeClass as s, normalizeStyle as c, openBlock as l, toDisplayString as u } from "vue";
3
3
  //#region src/components/Avatar/Avatar.vue?vue&type=script&setup=true&lang.ts
4
- var u = ["src"], d = {
4
+ var d = ["src"], f = {
5
5
  key: 2,
6
6
  class: "absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-sui-accent-solid ring-2 ring-sui-surface"
7
- }, f = /*@__PURE__*/ o({
7
+ }, p = /*@__PURE__*/ o({
8
8
  __name: "Avatar",
9
9
  props: {
10
10
  name: { default: void 0 },
@@ -15,13 +15,13 @@ var u = ["src"], d = {
15
15
  hue: { default: void 0 }
16
16
  },
17
17
  setup(o) {
18
- let f = o, p = n(() => (f.name || "?").trim().charAt(0).toUpperCase() || "?"), m = {
18
+ let p = o, m = n(() => (p.name || "?").trim().charAt(0).toUpperCase() || "?"), h = {
19
19
  xs: "h-4 w-4 text-10",
20
20
  sm: "h-6 w-6 text-11",
21
21
  md: "h-8 w-8 text-xs",
22
22
  lg: "h-10 w-10 text-sm",
23
23
  xl: "h-16 w-16 text-2xl"
24
- }, h = {
24
+ }, g = {
25
25
  blue: "border-sui-hue-blue-line bg-sui-hue-blue-soft text-sui-hue-blue-ink",
26
26
  green: "border-sui-hue-green-line bg-sui-hue-green-soft text-sui-hue-green-ink",
27
27
  orange: "border-sui-hue-orange-line bg-sui-hue-orange-soft text-sui-hue-orange-ink",
@@ -31,20 +31,26 @@ var u = ["src"], d = {
31
31
  red: "border-sui-hue-red-line bg-sui-hue-red-soft text-sui-hue-red-ink",
32
32
  amber: "border-sui-hue-amber-line bg-sui-hue-amber-soft text-sui-hue-amber-ink",
33
33
  gray: "border-sui-line bg-sui-sunken text-sui-ink-body"
34
- }, g = n(() => f.shape === "square" ? "rounded-lg" : "rounded-full"), _ = n(() => f.image ? "border-sui-line-subtle" : h[f.hue ?? e(f.name)]);
35
- return (e, n) => (c(), i("div", { class: s(["relative inline-flex shrink-0 items-center justify-center border font-semibold", [
36
- m[o.size],
37
- g.value,
38
- _.value
39
- ]]) }, [o.image ? (c(), i("img", {
34
+ }, _ = n(() => typeof p.size == "number" ? p.size <= 20 ? "text-10" : p.size <= 28 ? "text-11" : p.size <= 36 ? "text-xs" : "text-sm" : h[p.size]), v = n(() => typeof p.size == "number" ? {
35
+ width: `${p.size}px`,
36
+ height: `${p.size}px`
37
+ } : void 0), y = n(() => p.shape === "square" ? "rounded-lg" : "rounded-full"), b = n(() => p.image ? "border-sui-line-subtle" : g[p.hue ?? e(p.name)]);
38
+ return (e, n) => (l(), i("div", {
39
+ class: s(["relative inline-flex shrink-0 items-center justify-center border font-semibold", [
40
+ _.value,
41
+ y.value,
42
+ b.value
43
+ ]]),
44
+ style: c(v.value)
45
+ }, [o.image ? (l(), i("img", {
40
46
  key: 0,
41
47
  alt: "",
42
- class: s(["h-full w-full object-cover", g.value]),
48
+ class: s(["h-full w-full object-cover", y.value]),
43
49
  src: o.image
44
- }, null, 10, u)) : (c(), i(t, { key: 1 }, [a(l(p.value), 1)], 64)), o.badge ? (c(), i("span", d)) : r("", !0)], 2));
50
+ }, null, 10, d)) : (l(), i(t, { key: 1 }, [a(u(m.value), 1)], 64)), o.badge ? (l(), i("span", f)) : r("", !0)], 6));
45
51
  }
46
52
  });
47
53
  //#endregion
48
- export { f as default };
54
+ export { p as default };
49
55
 
50
56
  //# sourceMappingURL=Avatar.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_Fragment","_createTextVNode","_toDisplayString","_createCommentVNode","_hoisted_1","_hoisted_2","Avatar_vue_vue_type_script_setup_true_lang_default","props","__props","initial","computed","sizes","hues","shapeClass","colorClass","hueFor","openBlock","createElementBlock","normalizeClass","Fragment","createTextVNode","toDisplayString","createCommentVNode"],"sources":["../../../src/components/Avatar/Avatar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { type Hue, hueFor } from '../../utils/hues'\n\nexport interface AvatarProps {\n name?: string | null\n image?: string | null\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n shape?: 'circle' | 'square'\n /** An attention dot, e.g. unread. */\n badge?: boolean\n /** Pins the colour when it means something; otherwise it comes from the name, stable per person. */\n hue?: Hue\n}\n\nconst props = withDefaults(defineProps<AvatarProps>(), {\n name: undefined,\n image: undefined,\n size: 'sm',\n shape: 'circle',\n hue: undefined\n})\n\n// One uppercased initial reads cleaner than two letters.\nconst initial = computed(() => (props.name || '?').trim().charAt(0).toUpperCase() || '?')\n\nconst sizes = {\n xs: 'h-4 w-4 text-10',\n sm: 'h-6 w-6 text-11',\n md: 'h-8 w-8 text-xs',\n lg: 'h-10 w-10 text-sm',\n xl: 'h-16 w-16 text-2xl'\n}\n\n// A soft coin of one hue: tinted fill, saturated text, a hairline of the hue.\nconst hues: Record<Hue, string> = {\n blue: 'border-sui-hue-blue-line bg-sui-hue-blue-soft text-sui-hue-blue-ink',\n green: 'border-sui-hue-green-line bg-sui-hue-green-soft text-sui-hue-green-ink',\n orange: 'border-sui-hue-orange-line bg-sui-hue-orange-soft text-sui-hue-orange-ink',\n pink: 'border-sui-hue-pink-line bg-sui-hue-pink-soft text-sui-hue-pink-ink',\n purple: 'border-sui-hue-purple-line bg-sui-hue-purple-soft text-sui-hue-purple-ink',\n slate: 'border-sui-hue-slate-line bg-sui-hue-slate-soft text-sui-hue-slate-ink',\n red: 'border-sui-hue-red-line bg-sui-hue-red-soft text-sui-hue-red-ink',\n amber: 'border-sui-hue-amber-line bg-sui-hue-amber-soft text-sui-hue-amber-ink',\n gray: 'border-sui-line bg-sui-sunken text-sui-ink-body'\n}\n\nconst shapeClass = computed(() => (props.shape === 'square' ? 'rounded-lg' : 'rounded-full'))\n\n// A photo gets a neutral hairline, so it reads as a crisp coin too.\nconst colorClass = computed(() => (props.image ? 'border-sui-line-subtle' : hues[props.hue ?? hueFor(props.name)]))\n</script>\n\n<template>\n <div\n class=\"relative inline-flex shrink-0 items-center justify-center border font-semibold\"\n :class=\"[sizes[size], shapeClass, colorClass]\"\n >\n <img v-if=\"image\" alt=\"\" class=\"h-full w-full object-cover\" :class=\"shapeClass\" :src=\"image\" />\n <template v-else>{{ initial }}</template>\n <span\n v-if=\"badge\"\n class=\"absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-sui-accent-solid ring-2 ring-sui-surface\"\n />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;EAgBA,IAAMU,IAAQC,GASRC,IAAUC,SAAgBH,EAAM,QAAQ,IAAA,CAAK,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,KAAK,GAAG,GAElFI,IAAQ;GACZ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN,GAGMC,IAA4B;GAChC,MAAM;GACN,OAAO;GACP,QAAQ;GACR,MAAM;GACN,QAAQ;GACR,OAAO;GACP,KAAK;GACL,OAAO;GACP,MAAM;EACR,GAEMC,IAAaH,QAAgBH,EAAM,UAAU,WAAW,eAAe,cAAe,GAGtFO,IAAaJ,QAAgBH,EAAM,QAAQ,2BAA2BK,EAAKL,EAAM,OAAOQ,EAAOR,EAAM,IAAI,EAAG;E,kBAIhHV,EAAA,GAAAC,EAUM,OAAA,EATJ,OAAKC,EAAA,CAAC,kFAAgF;GAC7EY,EAAMH,EAAA;GAAOK,EAAA;GAAYC,EAAA;EAAU,CAAA,CAAA,E,IAEjCN,EAAA,SAAXX,EAAA,GAAAC,EAA+F,OAAA;;GAA7E,KAAI;GAAG,OAAKC,EAAA,CAAC,8BAAqCc,EAAA,KAAU,CAAA;GAAG,KAAKL,EAAA;E,oBACtFX,EAAA,GAAAC,EAAyCE,GAAA,EAAA,KAAA,EAAA,GAAA,CAArBC,EAAAC,EAAAO,EAAA,KAAO,GAAA,CAAA,C,SAEnBD,EAAA,SADRX,EAAA,GAAAC,EAGE,QAHFO,CAGE,K"}
1
+ {"version":3,"file":"Avatar.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle","_Fragment","_createTextVNode","_toDisplayString","_createCommentVNode","_hoisted_1","_hoisted_2","Avatar_vue_vue_type_script_setup_true_lang_default","props","__props","initial","computed","sizes","hues","sizeClass","sizeStyle","shapeClass","colorClass","hueFor","openBlock","createElementBlock","normalizeClass","normalizeStyle","Fragment","createTextVNode","toDisplayString","createCommentVNode"],"sources":["../../../src/components/Avatar/Avatar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { type Hue, hueFor } from '../../utils/hues'\n\nexport interface AvatarProps {\n name?: string | null\n image?: string | null\n /** xs 16, sm 24, md 32, lg 40, xl 64; or a number of px, 20 for list rows and activity feeds. */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number\n shape?: 'circle' | 'square'\n /** An attention dot, e.g. unread. */\n badge?: boolean\n /** Pins the colour when it means something; otherwise it comes from the name, stable per person. */\n hue?: Hue\n}\n\nconst props = withDefaults(defineProps<AvatarProps>(), {\n name: undefined,\n image: undefined,\n size: 'sm',\n shape: 'circle',\n hue: undefined\n})\n\n// One uppercased initial reads cleaner than two letters.\nconst initial = computed(() => (props.name || '?').trim().charAt(0).toUpperCase() || '?')\n\nconst sizes = {\n xs: 'h-4 w-4 text-10',\n sm: 'h-6 w-6 text-11',\n md: 'h-8 w-8 text-xs',\n lg: 'h-10 w-10 text-sm',\n xl: 'h-16 w-16 text-2xl'\n}\n\n// A soft coin of one hue: tinted fill, saturated text, a hairline of the hue.\nconst hues: Record<Hue, string> = {\n blue: 'border-sui-hue-blue-line bg-sui-hue-blue-soft text-sui-hue-blue-ink',\n green: 'border-sui-hue-green-line bg-sui-hue-green-soft text-sui-hue-green-ink',\n orange: 'border-sui-hue-orange-line bg-sui-hue-orange-soft text-sui-hue-orange-ink',\n pink: 'border-sui-hue-pink-line bg-sui-hue-pink-soft text-sui-hue-pink-ink',\n purple: 'border-sui-hue-purple-line bg-sui-hue-purple-soft text-sui-hue-purple-ink',\n slate: 'border-sui-hue-slate-line bg-sui-hue-slate-soft text-sui-hue-slate-ink',\n red: 'border-sui-hue-red-line bg-sui-hue-red-soft text-sui-hue-red-ink',\n amber: 'border-sui-hue-amber-line bg-sui-hue-amber-soft text-sui-hue-amber-ink',\n gray: 'border-sui-line bg-sui-sunken text-sui-ink-body'\n}\n\n// A number of px: the initial steps down with the coin.\nconst sizeClass = computed(() => {\n if (typeof props.size !== 'number') return sizes[props.size]\n if (props.size <= 20) return 'text-10'\n if (props.size <= 28) return 'text-11'\n return props.size <= 36 ? 'text-xs' : 'text-sm'\n})\nconst sizeStyle = computed(() =>\n typeof props.size === 'number' ? { width: `${props.size}px`, height: `${props.size}px` } : undefined\n)\n\nconst shapeClass = computed(() => (props.shape === 'square' ? 'rounded-lg' : 'rounded-full'))\n\n// A photo gets a neutral hairline, so it reads as a crisp coin too.\nconst colorClass = computed(() => (props.image ? 'border-sui-line-subtle' : hues[props.hue ?? hueFor(props.name)]))\n</script>\n\n<template>\n <div\n class=\"relative inline-flex shrink-0 items-center justify-center border font-semibold\"\n :class=\"[sizeClass, shapeClass, colorClass]\"\n :style=\"sizeStyle\"\n >\n <img v-if=\"image\" alt=\"\" class=\"h-full w-full object-cover\" :class=\"shapeClass\" :src=\"image\" />\n <template v-else>{{ initial }}</template>\n <span\n v-if=\"badge\"\n class=\"absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-sui-accent-solid ring-2 ring-sui-surface\"\n />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;EAiBA,IAAMW,IAAQC,GASRC,IAAUC,SAAgBH,EAAM,QAAQ,IAAA,CAAK,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,KAAK,GAAG,GAElFI,IAAQ;GACZ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN,GAGMC,IAA4B;GAChC,MAAM;GACN,OAAO;GACP,QAAQ;GACR,MAAM;GACN,QAAQ;GACR,OAAO;GACP,KAAK;GACL,OAAO;GACP,MAAM;EACR,GAGMC,IAAYH,QACZ,OAAOH,EAAM,QAAS,WACtBA,EAAM,QAAQ,KAAW,YACzBA,EAAM,QAAQ,KAAW,YACtBA,EAAM,QAAQ,KAAK,YAAY,YAHKI,EAAMJ,EAAM,KAIxD,GACKO,IAAYJ,QAChB,OAAOH,EAAM,QAAS,WAAW;GAAE,OAAO,GAAGA,EAAM,KAAK;GAAK,QAAQ,GAAGA,EAAM,KAAK;EAAI,IAAI,KAAA,CAC7F,GAEMQ,IAAaL,QAAgBH,EAAM,UAAU,WAAW,eAAe,cAAe,GAGtFS,IAAaN,QAAgBH,EAAM,QAAQ,2BAA2BK,EAAKL,EAAM,OAAOU,EAAOV,EAAM,IAAI,EAAG;E,kBAIhHX,EAAA,GAAAC,EAWM,OAAA;GAVJ,OAAKC,EAAA,CAAC,kFAAgF;IAC7Ee,EAAA;IAAWE,EAAA;IAAYC,EAAA;GAAU,CAAA,CAAA;GACzC,OAAKjB,EAAEe,EAAA,KAAS;E,IAENN,EAAA,SAAXZ,EAAA,GAAAC,EAA+F,OAAA;;GAA7E,KAAI;GAAG,OAAKC,EAAA,CAAC,8BAAqCiB,EAAA,KAAU,CAAA;GAAG,KAAKP,EAAA;E,oBACtFZ,EAAA,GAAAC,EAAyCG,GAAA,EAAA,KAAA,EAAA,GAAA,CAArBC,EAAAC,EAAAO,EAAA,KAAO,GAAA,CAAA,C,SAEnBD,EAAA,SADRZ,EAAA,GAAAC,EAGE,QAHFQ,CAGE,K"}
@@ -1 +1 @@
1
- {"version":3,"file":"Board.js","names":["_sfc_main","Board_vue_vue_type_script_setup_true_lang_default","Board_default"],"sources":["../../../src/components/Board/Board.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { ref, useId } from 'vue'\n\nimport Icon from '../Icon/Icon.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { BoardColumn } from './types'\n\nexport interface BoardProps<T> {\n columns: BoardColumn<T>[]\n /** The item field that identifies it. */\n rowKey?: keyof T & string\n /** Cards also reorder within a column, for records that carry a position. */\n sortable?: boolean\n /** Columns run to the bottom of the parent and scroll inside it; give the parent a height. False sizes them to their cards. */\n fill?: boolean\n loading?: boolean\n /** The columns' heading level, to fit the page's outline. */\n headingLevel?: 2 | 3 | 4 | 5 | 6\n /** Adds a dashed \"New\" button at the foot of each column, shown on hover (`@new`). */\n onNew?: (column: BoardColumn<T>) => void\n newLabel?: string\n emptyLabel?: string\n}\n\nconst props = withDefaults(defineProps<BoardProps<T>>(), {\n rowKey: 'id' as never,\n fill: true,\n headingLevel: 3,\n onNew: undefined,\n newLabel: 'New',\n emptyLabel: 'No cards'\n})\n\nconst emit = defineEmits<{\n 'card-click': [item: T]\n /** A card dropped into a column, at its new index there. Show it moved at once; put it back if saving fails. */\n move: [id: unknown, column: string, index: number]\n}>()\n\ndefineSlots<{\n /** A card's content; `item.name` as a title by default. */\n card?: (props: { item: T; column: BoardColumn<T> }) => unknown\n /** Replaces a column's count, e.g. its summed deal value. */\n count?: (props: { column: BoardColumn<T> }) => unknown\n}>()\n\nconst id = useId()\nconst idOf = (item: T): unknown => item[props.rowKey ?? 'id']\n\nconst dragged = ref<{ id: unknown; column: string; index: number } | null>(null)\nconst target = ref<{ column: string; index: number } | null>(null)\n\nfunction onDragStart(event: DragEvent, item: T, column: string, index: number) {\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move'\n event.dataTransfer.setData('text/plain', String(idOf(item)))\n }\n dragged.value = { id: idOf(item), column, index }\n}\n\nfunction onDragEnd() {\n dragged.value = null\n target.value = null\n}\n\nfunction overColumn(event: DragEvent, column: BoardColumn<T>) {\n if (!dragged.value) return\n event.preventDefault()\n if (target.value?.column !== column.id) target.value = { column: column.id, index: column.items.length }\n}\n\n// The card's top half drops before it, the bottom half after.\nfunction overCard(event: DragEvent, column: string, index: number) {\n if (!dragged.value) return\n event.preventDefault()\n event.stopPropagation()\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()\n const at = event.clientY < rect.top + rect.height / 2 ? index : index + 1\n if (target.value?.column !== column || target.value.index !== at) target.value = { column, index: at }\n}\n\nfunction onLeave(event: DragEvent) {\n if (!(event.currentTarget as HTMLElement).contains(event.relatedTarget as Node | null)) target.value = null\n}\n\nfunction onDrop(event: DragEvent, column: BoardColumn<T>) {\n event.preventDefault()\n const from = dragged.value\n if (from) {\n let index = target.value?.column === column.id ? target.value.index : column.items.length\n if (from.column === column.id) {\n // Within a column the dragged card leaves its old slot first.\n if (index > from.index) index--\n if (props.sortable && index !== from.index) emit('move', from.id, column.id, index)\n } else {\n emit('move', from.id, column.id, index)\n }\n }\n onDragEnd()\n}\n\nfunction onCardKeydown(event: KeyboardEvent, item: T) {\n if (event.target !== event.currentTarget || (event.key !== 'Enter' && event.key !== ' ')) return\n event.preventDefault()\n emit('card-click', item)\n}\n\nconst isTarget = (column: string, index: number, item: T) =>\n target.value?.column === column && target.value.index === index && dragged.value?.id !== idOf(item)\n</script>\n\n<!-- A board: cards in columns by a field (a stage, a status), dragged between columns. -->\n<template>\n <div\n class=\"flex items-stretch gap-5 overflow-x-auto pb-2 after:w-1 after:shrink-0 after:content-['']\"\n :class=\"fill && 'h-full min-h-0 flex-1'\"\n >\n <section\n v-for=\"column in columns\"\n :key=\"column.id\"\n :aria-labelledby=\"`${id}-${column.id}`\"\n class=\"flex min-h-0 w-full max-w-xs min-w-[16rem] shrink-0 flex-col\"\n >\n <header class=\"flex items-center justify-between px-1 pb-2.5\">\n <component\n :is=\"`h${headingLevel}`\"\n :id=\"`${id}-${column.id}`\"\n class=\"m-0 flex items-center gap-2 text-sm font-semibold text-sui-ink\"\n >\n <Icon v-if=\"column.icon\" :color=\"column.iconColor ?? 'ink-subtle'\" :name=\"column.icon\" />\n {{ column.name }}\n </component>\n <span\n class=\"ml-2 inline-flex h-5 items-center justify-center rounded-full bg-sui-sunken px-2 text-xs text-sui-ink-muted tabular-nums\"\n >\n <slot :column=\"column\" name=\"count\">{{ column.items.length }}</slot>\n </span>\n </header>\n <div\n class=\"group/body flex min-h-[120px] flex-1 flex-col gap-2.5 overflow-y-auto rounded-xl bg-sui-sunken p-2.5 transition-shadow duration-150\"\n :class=\"target?.column === column.id && 'ring-2 ring-sui-accent-line ring-inset'\"\n @dragleave=\"onLeave\"\n @dragover=\"overColumn($event, column)\"\n @drop=\"onDrop($event, column)\"\n >\n <template v-if=\"loading\">\n <div\n v-for=\"i in 3\"\n :key=\"i\"\n aria-hidden=\"true\"\n class=\"rounded-xl border border-sui-line-subtle bg-sui-surface p-4\"\n >\n <Skeleton class=\"mb-3\" />\n <Skeleton height=\"0.75rem\" width=\"70%\" />\n </div>\n </template>\n <p\n v-else-if=\"column.items.length === 0 && !dragged\"\n class=\"m-0 px-1 py-3 text-center text-13 text-sui-ink-muted\"\n >\n {{ emptyLabel }}\n </p>\n <ul v-else class=\"m-0 flex list-none flex-col gap-2.5 p-0\">\n <li v-for=\"(item, index) in column.items\" :key=\"idOf(item) as PropertyKey\">\n <div\n class=\"relative cursor-pointer rounded-xl border border-sui-line-subtle bg-sui-surface p-4 outline-hidden transition-[border-color,opacity] duration-150 hover:border-sui-line focus-visible:sui-ring\"\n :class=\"[\n dragged?.id === idOf(item) && 'opacity-40',\n isTarget(column.id, index, item) && 'shadow-[0_-6px_0_-4px_rgb(var(--sui-accent-solid))]'\n ]\"\n draggable=\"true\"\n role=\"button\"\n tabindex=\"0\"\n @click=\"emit('card-click', item)\"\n @dragend=\"onDragEnd\"\n @dragover=\"overCard($event, column.id, index)\"\n @dragstart=\"onDragStart($event, item, column.id, index)\"\n @keydown=\"onCardKeydown($event, item)\"\n >\n <slot :column=\"column\" :item=\"item\" name=\"card\">\n <p class=\"m-0 text-sm font-semibold text-sui-ink\">{{ item.name }}</p>\n </slot>\n </div>\n </li>\n </ul>\n <button\n v-if=\"onNew && !loading\"\n class=\"flex h-9 w-full shrink-0 items-center justify-center gap-1.5 rounded-lg border border-dashed border-sui-line-strong text-xs font-medium text-sui-ink-muted opacity-0 outline-hidden transition-all duration-150 group-hover/body:opacity-100 hover:border-sui-ink-muted hover:bg-sui-surface/60 hover:text-sui-ink-body focus-visible:opacity-100 focus-visible:sui-ring\"\n type=\"button\"\n @click=\"onNew(column)\"\n >\n <svg\n aria-hidden=\"true\"\n class=\"size-3.5 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 14 14\"\n >\n <path d=\"M7 2.5v9M2.5 7h9\" />\n </svg>\n {{ newLabel }}\n </button>\n </div>\n </section>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Board.js","names":["_sfc_main","Board_vue_vue_type_script_setup_true_lang_default","Board_default"],"sources":["../../../src/components/Board/Board.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { onBeforeUnmount, ref, useId } from 'vue'\n\nimport Icon from '../Icon/Icon.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { BoardColumn } from './types'\n\nexport interface BoardProps<T> {\n columns: BoardColumn<T>[]\n /** The item field that identifies it. */\n rowKey?: keyof T & string\n /** Cards also reorder within a column, for records that carry a position. */\n sortable?: boolean\n /** Columns run to the bottom of the parent and scroll inside it; give the parent a height. False sizes them to their cards. */\n fill?: boolean\n loading?: boolean\n /** The columns' heading level, to fit the page's outline. */\n headingLevel?: 2 | 3 | 4 | 5 | 6\n /** Draws each card's border, padding and surface. False when the `card` slot draws its own. */\n cardFrame?: boolean\n /** Makes a card a button that opens on click, Enter and Space (`@card-click`). Without it, the card slot carries its\n * own link or buttons. */\n onCardClick?: (item: T) => void\n /** Adds a dashed \"New\" button at the foot of each column, shown on hover (`@new`). */\n onNew?: (column: BoardColumn<T>) => void\n newLabel?: string\n emptyLabel?: string\n}\n\nconst props = withDefaults(defineProps<BoardProps<T>>(), {\n rowKey: 'id' as never,\n fill: true,\n headingLevel: 3,\n cardFrame: true,\n onCardClick: undefined,\n onNew: undefined,\n newLabel: 'New',\n emptyLabel: 'No cards'\n})\n\nconst emit = defineEmits<{\n /** A card dropped into a column, at its new index there. Show it moved at once; put it back if saving fails. */\n move: [id: unknown, column: string, index: number]\n}>()\n\ndefineSlots<{\n /** A card's content; `item.name` as a title by default. */\n card?: (props: { item: T; column: BoardColumn<T> }) => unknown\n /** Replaces a column's count, e.g. its summed deal value. */\n count?: (props: { column: BoardColumn<T> }) => unknown\n}>()\n\nconst id = useId()\nconst idOf = (item: T): unknown => item[props.rowKey ?? 'id']\nconst root = ref<HTMLElement>()\n\nconst dragged = ref<{ id: unknown; column: string; index: number } | null>(null)\nconst target = ref<{ column: string; index: number } | null>(null)\n\n// Dragging runs on pointer events, so it works with a mouse, a pen and a finger. A mouse drags once it moves a few\n// pixels, so a click still clicks; a finger after a short press, so a swipe still scrolls.\nconst MOUSE_SLOP = 4\nconst TOUCH_SLOP = 8\nconst TOUCH_DELAY = 250\nconst EDGE = 48\n\nlet pending: {\n item: T\n column: string\n index: number\n x: number\n y: number\n card: HTMLElement\n touch: boolean\n} | null = null\nlet pressTimer: number | undefined\nlet ghost: HTMLElement | null = null\nlet grab = { x: 0, y: 0 }\nlet justDragged = false\n\nfunction onPointerDown(event: PointerEvent, item: T, column: string, index: number) {\n if (event.button !== 0 || (event.target as HTMLElement).closest('input, textarea, select, [contenteditable]')) return\n const touch = event.pointerType === 'touch'\n pending = { item, column, index, x: event.clientX, y: event.clientY, card: event.currentTarget as HTMLElement, touch }\n if (touch) pressTimer = window.setTimeout(() => pending && start(), TOUCH_DELAY)\n window.addEventListener('pointermove', onPointerMove)\n window.addEventListener('pointerup', onPointerUp)\n window.addEventListener('pointercancel', stop)\n window.addEventListener('touchmove', holdScroll, { passive: false })\n window.addEventListener('keydown', onEscape)\n}\n\nfunction start() {\n if (!pending) return\n const rect = pending.card.getBoundingClientRect()\n grab = { x: pending.x - rect.left, y: pending.y - rect.top }\n ghost = pending.card.cloneNode(true) as HTMLElement\n ghost.removeAttribute('id')\n ghost.setAttribute('aria-hidden', 'true')\n ghost.classList.add('pointer-events-none', 'fixed', 'top-0', 'left-0', 'z-[1300]', 'shadow-lg', 'opacity-95')\n ghost.style.width = `${rect.width}px`\n document.body.appendChild(ghost)\n follow(pending.x, pending.y)\n dragged.value = { id: idOf(pending.item), column: pending.column, index: pending.index }\n}\n\nfunction onPointerMove(event: PointerEvent) {\n if (!pending) return\n if (!dragged.value) {\n const moved = Math.hypot(event.clientX - pending.x, event.clientY - pending.y)\n // A finger that moves before the press is long enough is scrolling.\n if (pending.touch) return moved > TOUCH_SLOP ? stop() : undefined\n if (moved < MOUSE_SLOP) return\n start()\n }\n event.preventDefault()\n follow(event.clientX, event.clientY)\n aim(event.clientX, event.clientY)\n scrollNear(event.clientX, event.clientY)\n}\n\nfunction follow(x: number, y: number) {\n if (ghost) ghost.style.transform = `translate(${x - grab.x}px, ${y - grab.y}px) rotate(1.5deg)`\n}\n\n// What's under the pointer: a card's top half drops before it, the bottom half after; an empty spot, at the end.\nfunction aim(x: number, y: number) {\n const under = document.elementFromPoint(x, y)\n const body = under?.closest<HTMLElement>('[data-board-column]')\n if (!body || !root.value?.contains(body)) {\n target.value = null\n return\n }\n const column = body.dataset.boardColumn!\n const card = under!.closest<HTMLElement>('[data-board-index]')\n let index = props.columns.find((c) => c.id === column)?.items.length ?? 0\n if (card && body.contains(card)) {\n const rect = card.getBoundingClientRect()\n index = Number(card.dataset.boardIndex) + (y < rect.top + rect.height / 2 ? 0 : 1)\n }\n if (target.value?.column !== column || target.value.index !== index) target.value = { column, index }\n}\n\n// Near a column's top or bottom, or the board's sides, it scrolls that way.\nfunction scrollNear(x: number, y: number) {\n const body = document.elementFromPoint(x, y)?.closest<HTMLElement>('[data-board-column]')\n if (body) {\n const rect = body.getBoundingClientRect()\n if (y < rect.top + EDGE) body.scrollTop -= 12\n else if (y > rect.bottom - EDGE) body.scrollTop += 12\n }\n const board = root.value?.getBoundingClientRect()\n if (board && root.value) {\n if (x < board.left + EDGE) root.value.scrollLeft -= 12\n else if (x > board.right - EDGE) root.value.scrollLeft += 12\n }\n}\n\nfunction onPointerUp() {\n const from = dragged.value\n const to = target.value\n if (from && to) {\n let index = to.index\n if (from.column === to.column) {\n // Within a column the dragged card leaves its old slot first.\n if (index > from.index) index--\n if (props.sortable && index !== from.index) emit('move', from.id, to.column, index)\n } else {\n emit('move', from.id, to.column, index)\n }\n }\n stop()\n}\n\nfunction holdScroll(event: TouchEvent) {\n if (dragged.value) event.preventDefault()\n}\n\nfunction onEscape(event: KeyboardEvent) {\n if (event.key === 'Escape' && dragged.value) {\n event.preventDefault()\n stop()\n }\n}\n\nfunction stop() {\n window.clearTimeout(pressTimer)\n window.removeEventListener('pointermove', onPointerMove)\n window.removeEventListener('pointerup', onPointerUp)\n window.removeEventListener('pointercancel', stop)\n window.removeEventListener('touchmove', holdScroll)\n window.removeEventListener('keydown', onEscape)\n ghost?.remove()\n ghost = null\n // The click that ends a drag isn't a click on the card.\n if (dragged.value) {\n justDragged = true\n window.setTimeout(() => (justDragged = false))\n }\n pending = null\n dragged.value = null\n target.value = null\n}\n\nonBeforeUnmount(stop)\n\nfunction clickCard(event: MouseEvent, item: T) {\n if (justDragged) {\n event.preventDefault()\n event.stopPropagation()\n return\n }\n props.onCardClick?.(item)\n}\n\nfunction onCardKeydown(event: KeyboardEvent, item: T) {\n if (!props.onCardClick || event.target !== event.currentTarget || (event.key !== 'Enter' && event.key !== ' ')) return\n event.preventDefault()\n props.onCardClick(item)\n}\n\nconst isTarget = (column: string, index: number, item: T) =>\n target.value?.column === column && target.value.index === index && dragged.value?.id !== idOf(item)\n\nconst frame =\n 'border border-sui-line-subtle bg-sui-surface p-4 transition-[border-color,opacity] duration-150 hover:border-sui-line'\n</script>\n\n<!-- A board: cards in columns by a field (a stage, a status), dragged between columns. -->\n<template>\n <div\n ref=\"root\"\n class=\"flex items-stretch gap-5 overflow-x-auto pb-2 after:w-1 after:shrink-0 after:content-['']\"\n :class=\"fill && 'h-full min-h-0 flex-1'\"\n >\n <section\n v-for=\"column in columns\"\n :key=\"column.id\"\n :aria-labelledby=\"`${id}-${column.id}`\"\n class=\"flex min-h-0 w-full max-w-xs min-w-[16rem] shrink-0 flex-col\"\n >\n <header class=\"flex items-center justify-between px-1 pb-2.5\">\n <component\n :is=\"`h${headingLevel}`\"\n :id=\"`${id}-${column.id}`\"\n class=\"m-0 flex items-center gap-2 text-sm font-semibold text-sui-ink\"\n >\n <Icon v-if=\"column.icon\" :color=\"column.iconColor ?? 'ink-subtle'\" :name=\"column.icon\" />\n {{ column.name }}\n </component>\n <span\n class=\"ml-2 inline-flex h-5 items-center justify-center rounded-full bg-sui-sunken px-2 text-xs text-sui-ink-muted tabular-nums\"\n >\n <slot :column=\"column\" name=\"count\">{{ column.items.length }}</slot>\n </span>\n </header>\n <div\n class=\"group/body flex min-h-[120px] flex-1 flex-col gap-2.5 overflow-y-auto rounded-xl bg-sui-sunken p-2.5 transition-shadow duration-150\"\n :class=\"target?.column === column.id && 'ring-2 ring-sui-accent-line ring-inset'\"\n :data-board-column=\"column.id\"\n >\n <template v-if=\"loading\">\n <div\n v-for=\"i in 3\"\n :key=\"i\"\n aria-hidden=\"true\"\n class=\"rounded-xl border border-sui-line-subtle bg-sui-surface p-4\"\n >\n <Skeleton class=\"mb-3\" />\n <Skeleton height=\"0.75rem\" width=\"70%\" />\n </div>\n </template>\n <p\n v-else-if=\"column.items.length === 0 && !dragged\"\n class=\"m-0 px-1 py-3 text-center text-13 text-sui-ink-muted\"\n >\n {{ emptyLabel }}\n </p>\n <ul v-else class=\"m-0 flex list-none flex-col gap-2.5 p-0\">\n <li v-for=\"(item, index) in column.items\" :key=\"idOf(item) as PropertyKey\">\n <div\n class=\"relative rounded-xl outline-hidden transition-opacity duration-150 select-none\"\n :class=\"[\n cardFrame && frame,\n onCardClick && 'cursor-pointer focus-visible:sui-ring',\n dragged?.id === idOf(item) && 'opacity-40',\n isTarget(column.id, index, item) && 'shadow-[0_-6px_0_-4px_rgb(var(--sui-accent-solid))]'\n ]\"\n :data-board-index=\"index\"\n :role=\"onCardClick ? 'button' : undefined\"\n :tabindex=\"onCardClick ? 0 : undefined\"\n @click.capture=\"clickCard($event, item)\"\n @contextmenu=\"dragged && $event.preventDefault()\"\n @dragstart.prevent\n @keydown=\"onCardKeydown($event, item)\"\n @pointerdown=\"onPointerDown($event, item, column.id, index)\"\n >\n <slot :column=\"column\" :item=\"item\" name=\"card\">\n <p class=\"m-0 text-sm font-semibold text-sui-ink\">{{ item.name }}</p>\n </slot>\n </div>\n </li>\n </ul>\n <button\n v-if=\"onNew && !loading\"\n class=\"flex h-9 w-full shrink-0 items-center justify-center gap-1.5 rounded-lg border border-dashed border-sui-line-strong text-xs font-medium text-sui-ink-muted opacity-0 outline-hidden transition-all duration-150 group-hover/body:opacity-100 hover:border-sui-ink-muted hover:bg-sui-surface/60 hover:text-sui-ink-body focus-visible:opacity-100 focus-visible:sui-ring\"\n type=\"button\"\n @click=\"onNew(column)\"\n >\n <svg\n aria-hidden=\"true\"\n class=\"size-3.5 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 14 14\"\n >\n <path d=\"M7 2.5v9M2.5 7h9\" />\n </svg>\n {{ newLabel }}\n </button>\n </div>\n </section>\n </div>\n</template>\n"],"mappings":""}
@@ -10,6 +10,11 @@ export interface BoardProps<T> {
10
10
  loading?: boolean;
11
11
  /** The columns' heading level, to fit the page's outline. */
12
12
  headingLevel?: 2 | 3 | 4 | 5 | 6;
13
+ /** Draws each card's border, padding and surface. False when the `card` slot draws its own. */
14
+ cardFrame?: boolean;
15
+ /** Makes a card a button that opens on click, Enter and Space (`@card-click`). Without it, the card slot carries its
16
+ * own link or buttons. */
17
+ onCardClick?: (item: T) => void;
13
18
  /** Adds a dashed "New" button at the foot of each column, shown on hover (`@new`). */
14
19
  onNew?: (column: BoardColumn<T>) => void;
15
20
  newLabel?: string;
@@ -17,7 +22,6 @@ export interface BoardProps<T> {
17
22
  }
18
23
  declare const __VLS_export: <T extends Record<string, any>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
19
24
  props: import("vue").PublicProps & __VLS_PrettifyLocal<BoardProps<T> & {
20
- "onCard-click"?: ((item: T) => any) | undefined;
21
25
  onMove?: ((id: unknown, column: string, index: number) => any) | undefined;
22
26
  }> & (typeof globalThis extends {
23
27
  __VLS_PROPS_FALLBACK: infer P;
@@ -35,7 +39,7 @@ declare const __VLS_export: <T extends Record<string, any>>(__VLS_props: NonNull
35
39
  column: BoardColumn<T>;
36
40
  }) => unknown;
37
41
  };
38
- emit: ((evt: "card-click", item: T) => void) & ((evt: "move", id: unknown, column: string, index: number) => void);
42
+ emit: (evt: "move", id: unknown, column: string, index: number) => void;
39
43
  }>) => import("vue").VNode & {
40
44
  __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
41
45
  };