@urbicon-ui/blocks 6.26.2 → 6.27.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.
@@ -379,195 +379,7 @@ declare const blocksTranslations: {
379
379
  };
380
380
  };
381
381
  };
382
- export declare const blocksI18n: import("@urbicon-ui/i18n").PackageI18n<{
383
- readonly accessibility: {
384
- readonly avatar: "Avatar";
385
- readonly breadcrumb: "Breadcrumb";
386
- readonly breadcrumbExpand: "Show all breadcrumb items";
387
- readonly clearInput: "Clear input";
388
- readonly clearSearch: "Clear search";
389
- readonly clearSelection: "Clear selection";
390
- readonly closeDialog: "Close dialog";
391
- readonly closeDrawer: "Close drawer";
392
- readonly dismiss: "Dismiss";
393
- readonly fileUpload: "File upload";
394
- readonly loading: "Loading";
395
- readonly maximum: "Maximum";
396
- readonly minimum: "Minimum";
397
- readonly pagination: "Page navigation";
398
- readonly progress: "Progress";
399
- readonly slider: "Slider";
400
- readonly toggle: "Toggle";
401
- readonly toggleOptions: "Toggle options";
402
- readonly removableBadge: "Removable badge";
403
- readonly removeBadge: "Remove badge";
404
- readonly removeFile: "Remove {{name}}";
405
- readonly removeTag: "Remove {{label}}";
406
- };
407
- readonly button: {
408
- readonly close: "Close";
409
- readonly apply: "Apply";
410
- readonly cancel: "Cancel";
411
- readonly confirm: "Confirm";
412
- };
413
- readonly menu: {
414
- readonly placeholder: "Select an option...";
415
- };
416
- readonly common: {
417
- readonly loading: "Loading...";
418
- };
419
- readonly languages: {
420
- readonly de: "Deutsch";
421
- readonly en: "English";
422
- readonly es: "Español";
423
- readonly fr: "Français";
424
- readonly it: "Italiano";
425
- readonly nl: "Nederlands";
426
- };
427
- readonly localeSwitcher: {
428
- readonly ariaLabel: "Language selection";
429
- readonly placeholder: "Select language...";
430
- };
431
- readonly pagination: {
432
- readonly next: "Next";
433
- readonly first: "First";
434
- readonly last: "Last";
435
- readonly page: "Page";
436
- readonly previous: "Previous";
437
- readonly pageInfo: "{{label}} {{current}} of {{total}}";
438
- readonly rangeInfo: "{{start}}–{{end}} of {{total}}";
439
- };
440
- readonly calendar: {
441
- readonly recurring: "Recurring event";
442
- readonly previousMonth: "Previous month";
443
- readonly nextMonth: "Next month";
444
- readonly previousWeek: "Previous week";
445
- readonly nextWeek: "Next week";
446
- readonly previousDay: "Previous day";
447
- readonly nextDay: "Next day";
448
- readonly previousYear: "Previous year";
449
- readonly nextYear: "Next year";
450
- readonly today: "Today";
451
- readonly calendarGrid: "Calendar";
452
- readonly weekdays: "Weekdays";
453
- readonly weekNumber: "Week number";
454
- readonly events: "Events";
455
- readonly noEvents: "No events";
456
- readonly showMore: "{{count}} more";
457
- readonly legend: "Legend";
458
- readonly yearView: "Year overview";
459
- readonly weekView: "Week view";
460
- readonly viewMonth: "Month";
461
- readonly viewYear: "Year";
462
- readonly viewWeek: "Week";
463
- readonly viewDay: "Day";
464
- readonly multiDayLabel: "Day {{current}} of {{total}}";
465
- readonly agendaView: "Agenda view";
466
- readonly viewAgenda: "Agenda";
467
- readonly viewSwitcher: "View mode";
468
- };
469
- readonly planner: {
470
- readonly previousWeek: "Previous week";
471
- readonly nextWeek: "Next week";
472
- readonly previousMonth: "Previous month";
473
- readonly nextMonth: "Next month";
474
- readonly previousRange: "Previous range";
475
- readonly nextRange: "Next range";
476
- readonly today: "Today";
477
- readonly grid: "Planner";
478
- readonly itemCount: "{{count}} items";
479
- };
480
- readonly commandPalette: {
481
- readonly noResults: "No results found.";
482
- readonly search: "Search...";
483
- readonly hints: {
484
- readonly navigate: "Navigate";
485
- readonly select: "Select";
486
- readonly close: "Close";
487
- };
488
- };
489
- readonly compositionBar: {
490
- readonly total: "Total";
491
- readonly summary: "Composition: {{total}} ({{count}} shares) — {{parts}}";
492
- readonly share: "Share";
493
- readonly value: "Value";
494
- readonly percent: "Percent";
495
- readonly remaining: "remaining";
496
- };
497
- readonly guide: {
498
- readonly next: "Next";
499
- readonly previous: "Back";
500
- readonly skip: "Skip tour";
501
- readonly done: "Done";
502
- readonly step: "Step {{current}} of {{total}}";
503
- readonly tour: "Guided tour";
504
- readonly close: "Close";
505
- readonly openHelp: "Help";
506
- readonly backToList: "All topics";
507
- readonly info: "More information";
508
- readonly infoAbout: "More information about {{label}}";
509
- readonly dismiss: "Dismiss hint";
510
- readonly startTour: "Start the guided tour";
511
- readonly actionRequired: "Complete the highlighted action to continue";
512
- readonly filterPlaceholder: "Filter topics…";
513
- readonly noResults: "No matching topics";
514
- };
515
- readonly journeyTimeline: {
516
- readonly label: "Journey";
517
- readonly status: {
518
- readonly complete: "Completed";
519
- readonly active: "In progress";
520
- readonly pending: "Pending";
521
- readonly attention: "Needs attention";
522
- readonly blocked: "Blocked";
523
- readonly skipped: "Skipped";
524
- };
525
- };
526
- readonly datepicker: {
527
- readonly placeholder: "Select a date...";
528
- readonly rangePlaceholder: "Select a date range...";
529
- readonly openCalendar: "Open calendar";
530
- readonly invalidDate: "Invalid date";
531
- readonly outOfRange: "Date is outside the allowed range";
532
- readonly invalidRange: "Invalid date range";
533
- };
534
- readonly fileUpload: {
535
- readonly exists: "File already added";
536
- readonly invalidType: "File type {{type}} is not allowed";
537
- readonly tooLarge: "File exceeds {{size}} limit";
538
- readonly tooMany: "Maximum {{count}} files allowed";
539
- readonly tooSmall: "File must be at least {{size}}";
540
- };
541
- readonly sankey: {
542
- readonly summary: "Sankey diagram: {{nodes}} nodes, {{links}} links — {{flows}}";
543
- readonly source: "Source";
544
- readonly target: "Target";
545
- readonly value: "Value";
546
- };
547
- readonly slider: {
548
- readonly rangeStatus: {
549
- readonly insideRecommended: "In recommended range";
550
- readonly insideValid: "In valid range";
551
- readonly insideValidOnly: "Outside recommended range, but valid";
552
- readonly outsideValid: "Outside valid range";
553
- };
554
- };
555
- readonly themeSwitcher: {
556
- readonly lightMode: "Light mode";
557
- readonly darkMode: "Dark mode";
558
- readonly systemTheme: "System theme";
559
- };
560
- readonly chart: {
561
- readonly category: "Category";
562
- readonly series: "Series {{index}}";
563
- readonly segment: "Segment";
564
- readonly value: "Value";
565
- readonly share: "Share";
566
- };
567
- readonly stepper: {
568
- readonly optional: "Optional";
569
- };
570
- }>;
382
+ export declare const blocksI18n: import("@urbicon-ui/i18n").PackageI18n<import("@urbicon-ui/i18n").Translations>;
571
383
  /**
572
384
  * Context-scoped translation hook for the blocks package. Call during component
573
385
  * initialisation, then use the returned `t` (conventionally aliased `bt`):
@@ -580,195 +392,7 @@ export declare const blocksI18n: import("@urbicon-ui/i18n").PackageI18n<{
580
392
  * Resolves against the nearest `<I18nProvider>`'s locale (or the base locale
581
393
  * when none is mounted) and re-renders reactively on locale change.
582
394
  */
583
- export declare const useBlocksI18n: () => import("@urbicon-ui/i18n").TypedTranslationFunction<{
584
- readonly accessibility: {
585
- readonly avatar: "Avatar";
586
- readonly breadcrumb: "Breadcrumb";
587
- readonly breadcrumbExpand: "Show all breadcrumb items";
588
- readonly clearInput: "Clear input";
589
- readonly clearSearch: "Clear search";
590
- readonly clearSelection: "Clear selection";
591
- readonly closeDialog: "Close dialog";
592
- readonly closeDrawer: "Close drawer";
593
- readonly dismiss: "Dismiss";
594
- readonly fileUpload: "File upload";
595
- readonly loading: "Loading";
596
- readonly maximum: "Maximum";
597
- readonly minimum: "Minimum";
598
- readonly pagination: "Page navigation";
599
- readonly progress: "Progress";
600
- readonly slider: "Slider";
601
- readonly toggle: "Toggle";
602
- readonly toggleOptions: "Toggle options";
603
- readonly removableBadge: "Removable badge";
604
- readonly removeBadge: "Remove badge";
605
- readonly removeFile: "Remove {{name}}";
606
- readonly removeTag: "Remove {{label}}";
607
- };
608
- readonly button: {
609
- readonly close: "Close";
610
- readonly apply: "Apply";
611
- readonly cancel: "Cancel";
612
- readonly confirm: "Confirm";
613
- };
614
- readonly menu: {
615
- readonly placeholder: "Select an option...";
616
- };
617
- readonly common: {
618
- readonly loading: "Loading...";
619
- };
620
- readonly languages: {
621
- readonly de: "Deutsch";
622
- readonly en: "English";
623
- readonly es: "Español";
624
- readonly fr: "Français";
625
- readonly it: "Italiano";
626
- readonly nl: "Nederlands";
627
- };
628
- readonly localeSwitcher: {
629
- readonly ariaLabel: "Language selection";
630
- readonly placeholder: "Select language...";
631
- };
632
- readonly pagination: {
633
- readonly next: "Next";
634
- readonly first: "First";
635
- readonly last: "Last";
636
- readonly page: "Page";
637
- readonly previous: "Previous";
638
- readonly pageInfo: "{{label}} {{current}} of {{total}}";
639
- readonly rangeInfo: "{{start}}–{{end}} of {{total}}";
640
- };
641
- readonly calendar: {
642
- readonly recurring: "Recurring event";
643
- readonly previousMonth: "Previous month";
644
- readonly nextMonth: "Next month";
645
- readonly previousWeek: "Previous week";
646
- readonly nextWeek: "Next week";
647
- readonly previousDay: "Previous day";
648
- readonly nextDay: "Next day";
649
- readonly previousYear: "Previous year";
650
- readonly nextYear: "Next year";
651
- readonly today: "Today";
652
- readonly calendarGrid: "Calendar";
653
- readonly weekdays: "Weekdays";
654
- readonly weekNumber: "Week number";
655
- readonly events: "Events";
656
- readonly noEvents: "No events";
657
- readonly showMore: "{{count}} more";
658
- readonly legend: "Legend";
659
- readonly yearView: "Year overview";
660
- readonly weekView: "Week view";
661
- readonly viewMonth: "Month";
662
- readonly viewYear: "Year";
663
- readonly viewWeek: "Week";
664
- readonly viewDay: "Day";
665
- readonly multiDayLabel: "Day {{current}} of {{total}}";
666
- readonly agendaView: "Agenda view";
667
- readonly viewAgenda: "Agenda";
668
- readonly viewSwitcher: "View mode";
669
- };
670
- readonly planner: {
671
- readonly previousWeek: "Previous week";
672
- readonly nextWeek: "Next week";
673
- readonly previousMonth: "Previous month";
674
- readonly nextMonth: "Next month";
675
- readonly previousRange: "Previous range";
676
- readonly nextRange: "Next range";
677
- readonly today: "Today";
678
- readonly grid: "Planner";
679
- readonly itemCount: "{{count}} items";
680
- };
681
- readonly commandPalette: {
682
- readonly noResults: "No results found.";
683
- readonly search: "Search...";
684
- readonly hints: {
685
- readonly navigate: "Navigate";
686
- readonly select: "Select";
687
- readonly close: "Close";
688
- };
689
- };
690
- readonly compositionBar: {
691
- readonly total: "Total";
692
- readonly summary: "Composition: {{total}} ({{count}} shares) — {{parts}}";
693
- readonly share: "Share";
694
- readonly value: "Value";
695
- readonly percent: "Percent";
696
- readonly remaining: "remaining";
697
- };
698
- readonly guide: {
699
- readonly next: "Next";
700
- readonly previous: "Back";
701
- readonly skip: "Skip tour";
702
- readonly done: "Done";
703
- readonly step: "Step {{current}} of {{total}}";
704
- readonly tour: "Guided tour";
705
- readonly close: "Close";
706
- readonly openHelp: "Help";
707
- readonly backToList: "All topics";
708
- readonly info: "More information";
709
- readonly infoAbout: "More information about {{label}}";
710
- readonly dismiss: "Dismiss hint";
711
- readonly startTour: "Start the guided tour";
712
- readonly actionRequired: "Complete the highlighted action to continue";
713
- readonly filterPlaceholder: "Filter topics…";
714
- readonly noResults: "No matching topics";
715
- };
716
- readonly journeyTimeline: {
717
- readonly label: "Journey";
718
- readonly status: {
719
- readonly complete: "Completed";
720
- readonly active: "In progress";
721
- readonly pending: "Pending";
722
- readonly attention: "Needs attention";
723
- readonly blocked: "Blocked";
724
- readonly skipped: "Skipped";
725
- };
726
- };
727
- readonly datepicker: {
728
- readonly placeholder: "Select a date...";
729
- readonly rangePlaceholder: "Select a date range...";
730
- readonly openCalendar: "Open calendar";
731
- readonly invalidDate: "Invalid date";
732
- readonly outOfRange: "Date is outside the allowed range";
733
- readonly invalidRange: "Invalid date range";
734
- };
735
- readonly fileUpload: {
736
- readonly exists: "File already added";
737
- readonly invalidType: "File type {{type}} is not allowed";
738
- readonly tooLarge: "File exceeds {{size}} limit";
739
- readonly tooMany: "Maximum {{count}} files allowed";
740
- readonly tooSmall: "File must be at least {{size}}";
741
- };
742
- readonly sankey: {
743
- readonly summary: "Sankey diagram: {{nodes}} nodes, {{links}} links — {{flows}}";
744
- readonly source: "Source";
745
- readonly target: "Target";
746
- readonly value: "Value";
747
- };
748
- readonly slider: {
749
- readonly rangeStatus: {
750
- readonly insideRecommended: "In recommended range";
751
- readonly insideValid: "In valid range";
752
- readonly insideValidOnly: "Outside recommended range, but valid";
753
- readonly outsideValid: "Outside valid range";
754
- };
755
- };
756
- readonly themeSwitcher: {
757
- readonly lightMode: "Light mode";
758
- readonly darkMode: "Dark mode";
759
- readonly systemTheme: "System theme";
760
- };
761
- readonly chart: {
762
- readonly category: "Category";
763
- readonly series: "Series {{index}}";
764
- readonly segment: "Segment";
765
- readonly value: "Value";
766
- readonly share: "Share";
767
- };
768
- readonly stepper: {
769
- readonly optional: "Optional";
770
- };
771
- }>;
395
+ export declare const useBlocksI18n: any;
772
396
  export declare const hasBlocksTranslation: (key: string) => boolean, getBlocksLocales: () => import("@urbicon-ui/i18n").Locale[];
773
397
  export type BlocksTranslationKey = keyof typeof enTranslations;
774
398
  export { blocksTranslations };
@@ -1,53 +1,53 @@
1
1
  import { type SlotNames, type VariantProps } from '../../utils/variants.js';
2
2
  export declare const alertVariants: ((props?: {
3
- intent?: "info" | "primary" | "success" | "warning" | "danger" | "neutral" | undefined;
3
+ intent?: "primary" | "info" | "success" | "warning" | "danger" | "neutral" | undefined;
4
4
  variant?: "inline" | "filled" | "soft" | undefined;
5
5
  size?: "sm" | "md" | "lg" | undefined;
6
6
  } | undefined) => {
7
7
  base: (props?: ({
8
- intent?: "info" | "primary" | "success" | "warning" | "danger" | "neutral" | undefined;
8
+ intent?: "primary" | "info" | "success" | "warning" | "danger" | "neutral" | undefined;
9
9
  variant?: "inline" | "filled" | "soft" | undefined;
10
10
  size?: "sm" | "md" | "lg" | undefined;
11
11
  } & {
12
12
  class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
13
13
  }) | undefined) => string;
14
14
  icon: (props?: ({
15
- intent?: "info" | "primary" | "success" | "warning" | "danger" | "neutral" | undefined;
15
+ intent?: "primary" | "info" | "success" | "warning" | "danger" | "neutral" | undefined;
16
16
  variant?: "inline" | "filled" | "soft" | undefined;
17
17
  size?: "sm" | "md" | "lg" | undefined;
18
18
  } & {
19
19
  class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
20
20
  }) | undefined) => string;
21
21
  content: (props?: ({
22
- intent?: "info" | "primary" | "success" | "warning" | "danger" | "neutral" | undefined;
22
+ intent?: "primary" | "info" | "success" | "warning" | "danger" | "neutral" | undefined;
23
23
  variant?: "inline" | "filled" | "soft" | undefined;
24
24
  size?: "sm" | "md" | "lg" | undefined;
25
25
  } & {
26
26
  class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
27
27
  }) | undefined) => string;
28
28
  title: (props?: ({
29
- intent?: "info" | "primary" | "success" | "warning" | "danger" | "neutral" | undefined;
29
+ intent?: "primary" | "info" | "success" | "warning" | "danger" | "neutral" | undefined;
30
30
  variant?: "inline" | "filled" | "soft" | undefined;
31
31
  size?: "sm" | "md" | "lg" | undefined;
32
32
  } & {
33
33
  class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
34
34
  }) | undefined) => string;
35
35
  description: (props?: ({
36
- intent?: "info" | "primary" | "success" | "warning" | "danger" | "neutral" | undefined;
36
+ intent?: "primary" | "info" | "success" | "warning" | "danger" | "neutral" | undefined;
37
37
  variant?: "inline" | "filled" | "soft" | undefined;
38
38
  size?: "sm" | "md" | "lg" | undefined;
39
39
  } & {
40
40
  class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
41
41
  }) | undefined) => string;
42
42
  actions: (props?: ({
43
- intent?: "info" | "primary" | "success" | "warning" | "danger" | "neutral" | undefined;
43
+ intent?: "primary" | "info" | "success" | "warning" | "danger" | "neutral" | undefined;
44
44
  variant?: "inline" | "filled" | "soft" | undefined;
45
45
  size?: "sm" | "md" | "lg" | undefined;
46
46
  } & {
47
47
  class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
48
48
  }) | undefined) => string;
49
49
  dismissButton: (props?: ({
50
- intent?: "info" | "primary" | "success" | "warning" | "danger" | "neutral" | undefined;
50
+ intent?: "primary" | "info" | "success" | "warning" | "danger" | "neutral" | undefined;
51
51
  variant?: "inline" | "filled" | "soft" | undefined;
52
52
  size?: "sm" | "md" | "lg" | undefined;
53
53
  } & {
@@ -89,7 +89,14 @@ export const cardVariants = tv({
89
89
  },
90
90
  elementType: {
91
91
  button: {
92
- base: 'border-none font-inherit text-left cursor-pointer'
92
+ // `[font:inherit]` (arbitrary property), NOT `font-inherit`: Tailwind
93
+ // v4 has no `font-inherit` utility (no `--font-inherit` theme key), so
94
+ // that class emitted no rule and a clickable Card kept the UA button
95
+ // font instead of inheriting the surrounding type. Same utility gap as
96
+ // Button's `[gap:inherit]` (Codeberg #21); found ground-truthing the
97
+ // variants-lint theme-existence guard (`font-` itself stays unguarded —
98
+ // family keys are legitimately consumer-supplied).
99
+ base: 'border-none [font:inherit] text-left cursor-pointer'
93
100
  },
94
101
  a: {
95
102
  base: 'no-underline text-inherit'
@@ -35,6 +35,7 @@
35
35
  queryFn,
36
36
  debounceMs = 250,
37
37
  loadingText = 'Loading…',
38
+ onError,
38
39
  tier,
39
40
  variant = 'outlined',
40
41
  size = 'md',
@@ -154,12 +155,21 @@
154
155
  // The dev-warn is gated to *sync* mode: with `queryFn`, a pre-bound value that
155
156
  // isn't in the current result set is expected, not a bug (there is no API to
156
157
  // seed labels for it), so warning there would cry wolf on a legitimate pattern.
157
- // See technical-debt (async pre-selected labels + warn dedup).
158
+ // See technical-debt (async pre-selected labels).
159
+ //
160
+ // Warn dedup: `selectedTags` recomputes on every fresh `options` array a
161
+ // parent re-render passes in (the common `options={items.map(…)}` idiom), so
162
+ // an unguarded warn would re-fire per recompute. A plain Set — deliberately
163
+ // outside the reactive graph, so adding to it never invalidates the derived —
164
+ // makes it one warn per orphan value for the instance's lifetime (mirrors
165
+ // Select).
166
+ const warnedOrphanValues = new Set<T>();
158
167
  const selectedTags = $derived.by<ComboboxOption<T>[]>(() =>
159
168
  selectedValues.map((v) => {
160
169
  const found = allOptions.find((o) => o.value === v) ?? tagCache.get(v);
161
170
  if (found) return found;
162
- if (!queryFn && import.meta.env?.DEV) {
171
+ if (!queryFn && import.meta.env?.DEV && !warnedOrphanValues.has(v)) {
172
+ warnedOrphanValues.add(v);
163
173
  console.warn(
164
174
  `[Combobox] value ${JSON.stringify(v)} has no matching option — tag falls back to its raw value.`
165
175
  );
@@ -261,7 +271,18 @@
261
271
  .catch((err: unknown) => {
262
272
  if (controller.signal.aborted || (err as { name?: string })?.name === 'AbortError')
263
273
  return;
264
- if (import.meta.env?.DEV) console.warn('[Combobox] queryFn rejected:', err);
274
+ // Failure contract: the loading state ends (`finally`) and the
275
+ // previous — now stale — options stay in place (no result-set
276
+ // clobber; a UI error slot remains an open debt). The rejection is
277
+ // handed to `onError`; without one it is surfaced DEV-only instead
278
+ // of vanishing silently (ConfirmDialog onConfirm precedent). A
279
+ // throwing `onError` is a consumer bug and deliberately escapes
280
+ // (fail-loud, mirrors createCronRunner).
281
+ if (onError) {
282
+ onError(err);
283
+ } else if (import.meta.env?.DEV) {
284
+ console.warn('[Combobox] queryFn rejected:', err);
285
+ }
265
286
  })
266
287
  .finally(() => {
267
288
  if (!controller.signal.aborted) loading = false;
@@ -56,16 +56,25 @@ interface ComboboxBaseProps<T extends SelectValue = string> extends ComboboxVari
56
56
  * by {@link debounceMs} — on each query change, replacing the option list with
57
57
  * the resolved result. The `AbortSignal` is aborted when a newer query
58
58
  * supersedes an in-flight request, so a slow stale response never clobbers a
59
- * fresh one. Aborted rejections are swallowed; other rejections leave the
60
- * previous options in place (and warn in dev). `options`/`groups` are ignored
61
- * in this mode. The selected option's label is cached so it survives result
62
- * sets that no longer contain it.
59
+ * fresh one. Aborted rejections are swallowed; other rejections end the
60
+ * loading state, leave the previous options in place, and are reported via
61
+ * `onError`. `options`/`groups` are ignored in this mode. The selected
62
+ * option's label is cached so it survives result sets that no longer
63
+ * contain it.
63
64
  */
64
65
  queryFn?: (query: string, signal: AbortSignal) => Promise<ComboboxOption<T>[]>;
65
66
  /** Debounce applied to `queryFn` in milliseconds. @default 250 */
66
67
  debounceMs?: number;
67
68
  /** Text shown in the listbox while an async `queryFn` request is in flight. @default 'Loading…' */
68
69
  loadingText?: string;
70
+ /**
71
+ * Fired when `queryFn` rejects (aborted / superseded requests are ignored).
72
+ * The loading state ends and the previous option list stays in place — use
73
+ * this to surface the failure (toast, inline message). Without a handler
74
+ * the rejection is logged DEV-only (`console.warn`) and swallowed in
75
+ * production; it never escapes as an unhandled promise rejection.
76
+ */
77
+ onError?: (error: unknown) => void;
69
78
  /** Show a clear button when a value is selected. Click or press Escape to reset. @default false */
70
79
  clearable?: boolean;
71
80
  /** Disable the entire combobox. @default false */