@almadar/ui 5.113.0 → 5.115.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.
@@ -12,6 +12,7 @@ import { useTranslate } from '@almadar/ui/hooks';
12
12
  import { useUISlots, ThemeProvider, useTheme } from '@almadar/ui/context';
13
13
  export { DesignThemeProvider, useDesignTheme } from '@almadar/ui/context';
14
14
  import { evaluate, createMinimalContext } from '@almadar/evaluator';
15
+ import { wrapCallbackForEvent } from '@almadar/runtime/ui';
15
16
  import { Link, Outlet, useLocation } from 'react-router-dom';
16
17
  import ELK from 'elkjs/lib/elk.bundled.js';
17
18
  import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light.js';
@@ -540,41 +541,6 @@ function kebabToPascal(name) {
540
541
  return part.charAt(0).toUpperCase() + part.slice(1);
541
542
  }).join("");
542
543
  }
543
- function loadLib(key, importer) {
544
- let p = libPromises.get(key);
545
- if (!p) {
546
- p = importer();
547
- libPromises.set(key, p);
548
- }
549
- return p;
550
- }
551
- function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
552
- const Lazy = React83__default.lazy(async () => {
553
- const lib = await loadLib(libKey, importer);
554
- const Comp = pick(lib);
555
- if (!Comp) {
556
- warnFallback(fallbackName, family);
557
- return { default: makeLucideAdapter(fallbackName, true) };
558
- }
559
- return { default: Comp };
560
- });
561
- const Wrapped = (props) => /* @__PURE__ */ jsx(
562
- React83__default.Suspense,
563
- {
564
- fallback: /* @__PURE__ */ jsx(
565
- "span",
566
- {
567
- "aria-hidden": true,
568
- className: props.className,
569
- style: { display: "inline-block", ...props.style }
570
- }
571
- ),
572
- children: /* @__PURE__ */ jsx(Lazy, { ...props })
573
- }
574
- );
575
- Wrapped.displayName = `Lazy.${libKey}.${fallbackName}`;
576
- return Wrapped;
577
- }
578
544
  function isComponentLike(v) {
579
545
  return v != null && (typeof v === "function" || typeof v === "object");
580
546
  }
@@ -588,146 +554,32 @@ function resolveLucide(name) {
588
554
  if (isComponentLike(asIs)) return asIs;
589
555
  return LucideIcons2.HelpCircle;
590
556
  }
591
- function resolvePhosphor(name, weight, family) {
592
- const target = phosphorAliases[name] ?? kebabToPascal(name);
593
- return lazyFamilyIcon(
594
- "phosphor",
595
- () => import('@phosphor-icons/react'),
596
- (lib) => {
597
- const PhosphorComp = lib[target];
598
- if (!PhosphorComp) return null;
599
- const Component = PhosphorComp;
600
- const Adapter = (props) => /* @__PURE__ */ jsx(
601
- Component,
602
- {
603
- weight,
604
- className: props.className,
605
- style: props.style,
606
- size: props.size ?? "1em"
607
- }
608
- );
609
- Adapter.displayName = `Phosphor.${target}.${weight}`;
610
- return Adapter;
611
- },
612
- name,
613
- family
614
- );
615
- }
616
- function resolveTabler(name, family) {
617
- const suffix = tablerAliases[name] ?? kebabToPascal(name);
618
- const target = `Icon${suffix}`;
619
- return lazyFamilyIcon(
620
- "tabler",
621
- () => import('@tabler/icons-react'),
622
- (lib) => {
623
- const TablerComp = lib[target];
624
- if (!TablerComp) return null;
625
- const Component = TablerComp;
626
- const Adapter = (props) => /* @__PURE__ */ jsx(
627
- Component,
628
- {
629
- stroke: props.strokeWidth ?? 1.5,
630
- className: props.className,
631
- style: props.style,
632
- size: props.size ?? 24
633
- }
634
- );
635
- Adapter.displayName = `Tabler.${target}`;
636
- return Adapter;
637
- },
638
- name,
639
- family
640
- );
641
- }
642
- function resolveFa(name, family) {
643
- const suffix = faAliases[name] ?? kebabToPascal(name);
644
- const target = `Fa${suffix}`;
645
- return lazyFamilyIcon(
646
- "fa",
647
- () => import('react-icons/fa'),
648
- (lib) => {
649
- const FaComp = lib[target];
650
- if (!FaComp) return null;
651
- const Component = FaComp;
652
- const Adapter = (props) => /* @__PURE__ */ jsx(
653
- Component,
654
- {
655
- className: props.className,
656
- style: props.style,
657
- size: props.size ?? "1em"
658
- }
659
- );
660
- Adapter.displayName = `Fa.${target}`;
661
- return Adapter;
662
- },
663
- name,
664
- family
665
- );
666
- }
667
- function warnFallback(name, family) {
668
- const key = `${family}::${name}`;
669
- if (warned.has(key)) return;
670
- warned.add(key);
671
- if (typeof console !== "undefined") {
672
- console.warn(
673
- `[iconFamily] No '${name}' mapping in family '${family}'; falling back to lucide. Add an alias in lib/iconFamily.ts.`
674
- );
675
- }
676
- }
677
- function makeLucideAdapter(name, isFallback = false) {
557
+ function makeLucideAdapter(name) {
678
558
  const LucideComp = resolveLucide(name);
679
- const Adapter = (props) => {
680
- const stroke = props.strokeWidth ?? (isFallback ? 2 : void 0);
681
- const style = isFallback ? { ...props.style ?? {}, strokeWidth: stroke ?? 2 } : props.style;
682
- return /* @__PURE__ */ jsx(
683
- LucideComp,
684
- {
685
- className: props.className,
686
- strokeWidth: stroke,
687
- style,
688
- size: props.size
689
- }
690
- );
691
- };
692
- Adapter.displayName = `Lucide.${name}${isFallback ? ".fallback" : ""}`;
559
+ const Adapter = (props) => /* @__PURE__ */ jsx(
560
+ LucideComp,
561
+ {
562
+ className: props.className,
563
+ strokeWidth: props.strokeWidth,
564
+ style: props.style,
565
+ size: props.size
566
+ }
567
+ );
568
+ Adapter.displayName = `Lucide.${name}`;
693
569
  return Adapter;
694
570
  }
695
- function resolveIconForFamily(name, family) {
696
- switch (family) {
697
- case "lucide":
698
- return makeLucideAdapter(name, false);
699
- // Non-lucide families resolve to a lazy, Suspense-wrapped component that
700
- // dynamic-imports the library on first render and falls back to lucide
701
- // internally when the family lacks the icon (see lazyFamilyIcon).
702
- case "phosphor-outline":
703
- return resolvePhosphor(name, "regular", family);
704
- case "phosphor-fill":
705
- return resolvePhosphor(name, "fill", family);
706
- case "phosphor-duotone":
707
- return resolvePhosphor(name, "duotone", family);
708
- case "tabler":
709
- return resolveTabler(name, family);
710
- case "fa-solid":
711
- return resolveFa(name, family);
712
- }
713
- }
714
- var DEFAULT_FAMILY, VALID_FAMILIES, cachedFamily, listeners, observer, libPromises, lucideAliases, phosphorAliases, tablerAliases, faAliases, warned;
571
+ function resolveIconForFamily(name, _family) {
572
+ return makeLucideAdapter(name);
573
+ }
574
+ var DEFAULT_FAMILY, VALID_FAMILIES, cachedFamily, listeners, observer, lucideAliases;
715
575
  var init_iconFamily = __esm({
716
576
  "lib/iconFamily.tsx"() {
717
577
  "use client";
718
578
  DEFAULT_FAMILY = "lucide";
719
- VALID_FAMILIES = [
720
- "lucide",
721
- "phosphor-outline",
722
- "phosphor-fill",
723
- "phosphor-duotone",
724
- "tabler",
725
- "fa-solid"
726
- ];
579
+ VALID_FAMILIES = [DEFAULT_FAMILY];
727
580
  cachedFamily = null;
728
581
  listeners = /* @__PURE__ */ new Set();
729
582
  observer = null;
730
- libPromises = /* @__PURE__ */ new Map();
731
583
  lucideAliases = {
732
584
  close: LucideIcons2.X,
733
585
  trash: LucideIcons2.Trash2,
@@ -740,478 +592,6 @@ var init_iconFamily = __esm({
740
592
  "sort-asc": LucideIcons2.ArrowUpNarrowWide,
741
593
  "sort-desc": LucideIcons2.ArrowDownNarrowWide
742
594
  };
743
- phosphorAliases = {
744
- // lucide name → phosphor PascalCase name
745
- // Actions
746
- plus: "Plus",
747
- minus: "Minus",
748
- x: "X",
749
- check: "Check",
750
- close: "X",
751
- edit: "PencilSimple",
752
- pencil: "PencilSimple",
753
- trash: "Trash",
754
- save: "FloppyDisk",
755
- copy: "Copy",
756
- share: "Share",
757
- send: "PaperPlaneRight",
758
- download: "DownloadSimple",
759
- upload: "UploadSimple",
760
- archive: "Archive",
761
- refresh: "ArrowsClockwise",
762
- loader: "CircleNotch",
763
- link: "Link",
764
- paperclip: "Paperclip",
765
- // Navigation
766
- "chevron-down": "CaretDown",
767
- "chevron-up": "CaretUp",
768
- "chevron-left": "CaretLeft",
769
- "chevron-right": "CaretRight",
770
- "arrow-up": "ArrowUp",
771
- "arrow-down": "ArrowDown",
772
- "arrow-left": "ArrowLeft",
773
- "arrow-right": "ArrowRight",
774
- menu: "List",
775
- more: "DotsThree",
776
- "more-vertical": "DotsThreeVertical",
777
- "more-horizontal": "DotsThree",
778
- external: "ArrowSquareOut",
779
- "external-link": "ArrowSquareOut",
780
- // Files
781
- file: "File",
782
- "file-text": "FileText",
783
- "file-plus": "FilePlus",
784
- "file-minus": "FileMinus",
785
- folder: "Folder",
786
- "folder-open": "FolderOpen",
787
- document: "FileText",
788
- // Charts
789
- "bar-chart": "ChartBar",
790
- "bar-chart-2": "ChartBar",
791
- "bar-chart-3": "ChartBar",
792
- "line-chart": "ChartLine",
793
- "pie-chart": "ChartPie",
794
- activity: "Pulse",
795
- "trending-up": "TrendUp",
796
- "trending-down": "TrendDown",
797
- // Messages
798
- message: "ChatCircle",
799
- "message-circle": "ChatCircle",
800
- "message-square": "ChatText",
801
- "messages-square": "ChatsCircle",
802
- comment: "ChatCircle",
803
- comments: "ChatsCircle",
804
- inbox: "Tray",
805
- mail: "Envelope",
806
- envelope: "Envelope",
807
- // Status
808
- "alert-circle": "WarningCircle",
809
- "alert-triangle": "Warning",
810
- "check-circle": "CheckCircle",
811
- "x-circle": "XCircle",
812
- info: "Info",
813
- "help-circle": "Question",
814
- "life-buoy": "Lifebuoy",
815
- lifebuoy: "Lifebuoy",
816
- warning: "Warning",
817
- error: "WarningCircle",
818
- // Media
819
- image: "Image",
820
- video: "VideoCamera",
821
- film: "FilmStrip",
822
- camera: "Camera",
823
- music: "MusicNote",
824
- play: "Play",
825
- pause: "Pause",
826
- stop: "Stop",
827
- "skip-forward": "SkipForward",
828
- "skip-back": "SkipBack",
829
- volume: "SpeakerHigh",
830
- "volume-2": "SpeakerHigh",
831
- "volume-x": "SpeakerX",
832
- mic: "Microphone",
833
- "mic-off": "MicrophoneSlash",
834
- // People
835
- user: "User",
836
- users: "Users",
837
- "user-plus": "UserPlus",
838
- "user-check": "UserCheck",
839
- // Time
840
- calendar: "Calendar",
841
- clock: "Clock",
842
- timer: "Timer",
843
- // Location
844
- map: "MapTrifold",
845
- "map-pin": "MapPin",
846
- navigation: "NavigationArrow",
847
- compass: "Compass",
848
- globe: "Globe",
849
- target: "Target",
850
- // Project / layout
851
- kanban: "Kanban",
852
- list: "List",
853
- table: "Table",
854
- grid: "GridFour",
855
- layout: "Layout",
856
- columns: "Columns",
857
- rows: "Rows",
858
- // Misc
859
- bell: "Bell",
860
- bookmark: "Bookmark",
861
- briefcase: "Briefcase",
862
- flag: "Flag",
863
- tag: "Tag",
864
- tags: "Tag",
865
- star: "Star",
866
- heart: "Heart",
867
- home: "House",
868
- settings: "Gear",
869
- eye: "Eye",
870
- "eye-off": "EyeSlash",
871
- lock: "Lock",
872
- unlock: "LockOpen",
873
- key: "Key",
874
- shield: "Shield",
875
- search: "MagnifyingGlass",
876
- filter: "Funnel",
877
- "sort-asc": "SortAscending",
878
- "sort-desc": "SortDescending",
879
- zap: "Lightning",
880
- sparkles: "Sparkle",
881
- // Code
882
- code: "Code",
883
- terminal: "Terminal",
884
- database: "Database",
885
- server: "HardDrives",
886
- cloud: "Cloud",
887
- wifi: "WifiHigh",
888
- package: "Package",
889
- box: "Package",
890
- // Theme
891
- sun: "Sun",
892
- moon: "Moon",
893
- // Phone
894
- phone: "Phone",
895
- printer: "Printer",
896
- // Hierarchy
897
- tree: "Tree",
898
- network: "Network"
899
- };
900
- tablerAliases = {
901
- // lucide name → tabler suffix (after the `Icon` prefix)
902
- // Actions
903
- plus: "Plus",
904
- minus: "Minus",
905
- x: "X",
906
- check: "Check",
907
- close: "X",
908
- edit: "Pencil",
909
- pencil: "Pencil",
910
- trash: "Trash",
911
- save: "DeviceFloppy",
912
- copy: "Copy",
913
- share: "Share",
914
- send: "Send",
915
- download: "Download",
916
- upload: "Upload",
917
- archive: "Archive",
918
- refresh: "Refresh",
919
- loader: "Loader2",
920
- link: "Link",
921
- paperclip: "Paperclip",
922
- external: "ExternalLink",
923
- "external-link": "ExternalLink",
924
- // Navigation
925
- "chevron-down": "ChevronDown",
926
- "chevron-up": "ChevronUp",
927
- "chevron-left": "ChevronLeft",
928
- "chevron-right": "ChevronRight",
929
- "arrow-down": "ArrowDown",
930
- "arrow-up": "ArrowUp",
931
- "arrow-left": "ArrowLeft",
932
- "arrow-right": "ArrowRight",
933
- menu: "Menu2",
934
- more: "Dots",
935
- "more-vertical": "DotsVertical",
936
- // Files
937
- file: "File",
938
- "file-text": "FileText",
939
- "file-plus": "FilePlus",
940
- "file-check": "FileCheck",
941
- "file-minus": "FileMinus",
942
- folder: "Folder",
943
- "folder-open": "FolderOpen",
944
- document: "FileText",
945
- // Charts
946
- "bar-chart": "ChartBar",
947
- "bar-chart-2": "ChartBar",
948
- "bar-chart-3": "ChartBar",
949
- "line-chart": "ChartLine",
950
- "pie-chart": "ChartPie",
951
- activity: "Activity",
952
- "trending-up": "TrendingUp",
953
- "trending-down": "TrendingDown",
954
- // Messages
955
- message: "Message",
956
- "message-circle": "MessageCircle",
957
- "message-square": "Message2",
958
- "messages-square": "Messages",
959
- comment: "Message",
960
- comments: "Messages",
961
- inbox: "Inbox",
962
- mail: "Mail",
963
- envelope: "Mail",
964
- // Status
965
- "alert-circle": "AlertCircle",
966
- "alert-triangle": "AlertTriangle",
967
- "check-circle": "CircleCheck",
968
- "x-circle": "CircleX",
969
- info: "InfoCircle",
970
- "help-circle": "HelpCircle",
971
- "life-buoy": "Lifebuoy",
972
- warning: "AlertTriangle",
973
- error: "AlertOctagon",
974
- // Media
975
- image: "Photo",
976
- video: "Video",
977
- camera: "Camera",
978
- music: "Music",
979
- play: "PlayerPlay",
980
- pause: "PlayerPause",
981
- stop: "PlayerStop",
982
- "skip-forward": "PlayerSkipForward",
983
- "skip-back": "PlayerSkipBack",
984
- volume: "Volume",
985
- "volume-2": "Volume",
986
- "volume-x": "VolumeOff",
987
- mic: "Microphone",
988
- "mic-off": "MicrophoneOff",
989
- // People
990
- user: "User",
991
- users: "Users",
992
- "user-plus": "UserPlus",
993
- "user-check": "UserCheck",
994
- // Time
995
- calendar: "Calendar",
996
- clock: "Clock",
997
- timer: "Hourglass",
998
- // Location
999
- map: "Map",
1000
- "map-pin": "MapPin",
1001
- navigation: "Navigation",
1002
- compass: "Compass",
1003
- globe: "World",
1004
- target: "Target",
1005
- // Project / layout
1006
- kanban: "LayoutKanban",
1007
- list: "List",
1008
- table: "Table",
1009
- grid: "LayoutGrid",
1010
- layout: "Layout",
1011
- columns: "LayoutColumns",
1012
- rows: "LayoutRows",
1013
- // Misc
1014
- bell: "Bell",
1015
- bookmark: "Bookmark",
1016
- briefcase: "Briefcase",
1017
- flag: "Flag",
1018
- tag: "Tag",
1019
- tags: "Tags",
1020
- star: "Star",
1021
- heart: "Heart",
1022
- home: "Home",
1023
- settings: "Settings",
1024
- eye: "Eye",
1025
- "eye-off": "EyeOff",
1026
- lock: "Lock",
1027
- unlock: "LockOpen",
1028
- key: "Key",
1029
- shield: "Shield",
1030
- search: "Search",
1031
- filter: "Filter",
1032
- "sort-asc": "SortAscending",
1033
- "sort-desc": "SortDescending",
1034
- zap: "Bolt",
1035
- sparkles: "Sparkles",
1036
- // Code / data
1037
- code: "Code",
1038
- terminal: "Terminal",
1039
- database: "Database",
1040
- server: "Server",
1041
- cloud: "Cloud",
1042
- wifi: "Wifi",
1043
- package: "Package",
1044
- box: "Box",
1045
- // Theme
1046
- sun: "Sun",
1047
- moon: "Moon",
1048
- // Phone
1049
- phone: "Phone",
1050
- printer: "Printer",
1051
- // Hierarchy
1052
- tree: "Hierarchy",
1053
- network: "Network"
1054
- };
1055
- faAliases = {
1056
- // lucide name → fa-solid suffix (after the `Fa` prefix).
1057
- // react-icons/fa ships FontAwesome 5 — names like `FaFileText` don't exist
1058
- // (FA renamed to `FaFileAlt`). When you see a console.warn from
1059
- // [iconFamily] about an unmapped lucide name in this family, add the
1060
- // closest FA5 sibling here so the fallback stays in-family.
1061
- search: "Search",
1062
- close: "Times",
1063
- x: "Times",
1064
- loader: "Spinner",
1065
- refresh: "Sync",
1066
- "sort-asc": "SortAmountUp",
1067
- "sort-desc": "SortAmountDown",
1068
- "chevron-down": "ChevronDown",
1069
- "chevron-up": "ChevronUp",
1070
- "chevron-left": "ChevronLeft",
1071
- "chevron-right": "ChevronRight",
1072
- "help-circle": "QuestionCircle",
1073
- "alert-triangle": "ExclamationTriangle",
1074
- "alert-circle": "ExclamationCircle",
1075
- "check-circle": "CheckCircle",
1076
- "x-circle": "TimesCircle",
1077
- edit: "Edit",
1078
- pencil: "PencilAlt",
1079
- trash: "Trash",
1080
- send: "PaperPlane",
1081
- share: "ShareAlt",
1082
- external: "ExternalLinkAlt",
1083
- plus: "Plus",
1084
- minus: "Minus",
1085
- check: "Check",
1086
- star: "Star",
1087
- heart: "Heart",
1088
- home: "Home",
1089
- user: "User",
1090
- users: "Users",
1091
- "user-plus": "UserPlus",
1092
- "user-check": "UserCheck",
1093
- settings: "Cog",
1094
- menu: "Bars",
1095
- "arrow-up": "ArrowUp",
1096
- "arrow-down": "ArrowDown",
1097
- "arrow-left": "ArrowLeft",
1098
- "arrow-right": "ArrowRight",
1099
- copy: "Copy",
1100
- download: "Download",
1101
- upload: "Upload",
1102
- filter: "Filter",
1103
- calendar: "Calendar",
1104
- clock: "Clock",
1105
- bell: "Bell",
1106
- mail: "Envelope",
1107
- envelope: "Envelope",
1108
- lock: "Lock",
1109
- unlock: "LockOpen",
1110
- eye: "Eye",
1111
- "eye-off": "EyeSlash",
1112
- more: "EllipsisH",
1113
- "more-vertical": "EllipsisV",
1114
- info: "InfoCircle",
1115
- warning: "ExclamationTriangle",
1116
- error: "ExclamationCircle",
1117
- // Time
1118
- timer: "Hourglass",
1119
- // Files (FA renamed FileText → FileAlt)
1120
- file: "File",
1121
- "file-text": "FileAlt",
1122
- "file-plus": "FileMedical",
1123
- "file-minus": "FileExcel",
1124
- "file-check": "FileSignature",
1125
- document: "FileAlt",
1126
- // Charts (lucide BarChart2 / BarChart3 → FA ChartBar)
1127
- "bar-chart": "ChartBar",
1128
- "bar-chart-2": "ChartBar",
1129
- "bar-chart-3": "ChartBar",
1130
- "line-chart": "ChartLine",
1131
- "pie-chart": "ChartPie",
1132
- activity: "ChartLine",
1133
- "trending-up": "ChartLine",
1134
- "trending-down": "ChartLine",
1135
- // Messages (lucide MessageCircle/MessageSquare → FA CommentDots/CommentAlt)
1136
- message: "Comment",
1137
- "message-circle": "CommentDots",
1138
- "message-square": "CommentAlt",
1139
- "messages-square": "Comments",
1140
- comment: "Comment",
1141
- comments: "Comments",
1142
- inbox: "Inbox",
1143
- // Support / help
1144
- "life-buoy": "LifeRing",
1145
- lifebuoy: "LifeRing",
1146
- // Project / kanban (FA has no kanban; closest semantic is Tasks/Columns)
1147
- kanban: "Tasks",
1148
- columns: "Columns",
1149
- rows: "Bars",
1150
- layout: "ThLarge",
1151
- grid: "Th",
1152
- list: "List",
1153
- table: "Table",
1154
- // Storage / folders
1155
- folder: "Folder",
1156
- "folder-open": "FolderOpen",
1157
- archive: "Archive",
1158
- bookmark: "Bookmark",
1159
- briefcase: "Briefcase",
1160
- package: "Box",
1161
- box: "Box",
1162
- // Map / location
1163
- map: "Map",
1164
- "map-pin": "MapMarkerAlt",
1165
- navigation: "LocationArrow",
1166
- compass: "Compass",
1167
- globe: "Globe",
1168
- target: "Bullseye",
1169
- // Media
1170
- image: "Image",
1171
- video: "Video",
1172
- film: "Film",
1173
- camera: "Camera",
1174
- music: "Music",
1175
- play: "Play",
1176
- pause: "Pause",
1177
- stop: "Stop",
1178
- "skip-forward": "Forward",
1179
- "skip-back": "Backward",
1180
- volume: "VolumeUp",
1181
- "volume-2": "VolumeUp",
1182
- "volume-x": "VolumeMute",
1183
- mic: "Microphone",
1184
- "mic-off": "MicrophoneSlash",
1185
- phone: "Phone",
1186
- // Code / data
1187
- code: "Code",
1188
- terminal: "Terminal",
1189
- database: "Database",
1190
- server: "Server",
1191
- cloud: "Cloud",
1192
- wifi: "Wifi",
1193
- // Security
1194
- shield: "ShieldAlt",
1195
- key: "Key",
1196
- // Misc actions
1197
- printer: "Print",
1198
- save: "Save",
1199
- link: "Link",
1200
- unlink: "Unlink",
1201
- paperclip: "Paperclip",
1202
- flag: "Flag",
1203
- tag: "Tag",
1204
- tags: "Tags",
1205
- zap: "Bolt",
1206
- sparkles: "Magic",
1207
- // Theme
1208
- sun: "Sun",
1209
- moon: "Moon",
1210
- // Hierarchy (FA has no Tree icon for hierarchies; Sitemap is the org-chart icon)
1211
- tree: "Sitemap",
1212
- network: "NetworkWired"
1213
- };
1214
- warned = /* @__PURE__ */ new Set();
1215
595
  }
1216
596
  });
1217
597
  function kebabToPascal2(name) {
@@ -1292,7 +672,7 @@ var init_Icon = __esm({
1292
672
  const family = useIconFamily();
1293
673
  const RenderedComponent = React83__default.useMemo(() => {
1294
674
  if (directIcon) return null;
1295
- return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
675
+ return effectiveName ? resolveIconForFamily(effectiveName) : null;
1296
676
  }, [directIcon, effectiveName, family]);
1297
677
  const effectiveStrokeWidth = strokeWidth ?? void 0;
1298
678
  const inlineStyle = {
@@ -1671,7 +1051,7 @@ var init_Button = __esm({
1671
1051
  ref,
1672
1052
  disabled: disabled || isLoading,
1673
1053
  className: cn(
1674
- "inline-flex items-center justify-center gap-2",
1054
+ "relative inline-flex items-center justify-center gap-2",
1675
1055
  "font-medium",
1676
1056
  "rounded-sm",
1677
1057
  "cursor-pointer",
@@ -3439,6 +2819,7 @@ var init_Input = __esm({
3439
2819
  icon: iconProp,
3440
2820
  clearable,
3441
2821
  onClear,
2822
+ action,
3442
2823
  value,
3443
2824
  options,
3444
2825
  rows = 3,
@@ -3488,6 +2869,11 @@ var init_Input = __esm({
3488
2869
  onClear?.();
3489
2870
  }
3490
2871
  };
2872
+ const handleKeyDown = (e) => {
2873
+ if (action && e.key === "Enter") {
2874
+ eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
2875
+ }
2876
+ };
3491
2877
  const wrapField = (field) => /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
3492
2878
  label && /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
3493
2879
  field,
@@ -3561,6 +2947,7 @@ var init_Input = __esm({
3561
2947
  type,
3562
2948
  value,
3563
2949
  onChange: handleChange,
2950
+ onKeyDown: handleKeyDown,
3564
2951
  className: baseClassName,
3565
2952
  ...props
3566
2953
  }
@@ -4093,7 +3480,7 @@ var init_Card = __esm({
4093
3480
  });
4094
3481
  function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
4095
3482
  const px = typeof size === "number" ? size : sizeMap[size];
4096
- const family = useIconFamily();
3483
+ useIconFamily();
4097
3484
  if (assetUrl?.url) {
4098
3485
  return /* @__PURE__ */ jsx(
4099
3486
  AtlasImage,
@@ -4105,7 +3492,7 @@ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
4105
3492
  }
4106
3493
  );
4107
3494
  }
4108
- const I = typeof icon === "string" ? resolveIconForFamily(icon, family) : icon;
3495
+ const I = typeof icon === "string" ? resolveIconForFamily(icon) : icon;
4109
3496
  return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
4110
3497
  }
4111
3498
  var sizeMap;
@@ -9154,9 +8541,9 @@ var init_webPainter2d = __esm({
9154
8541
  // lib/drawable/projector.ts
9155
8542
  function create2DProjector(opts) {
9156
8543
  const { scale, baseOffsetX, layout } = opts;
9157
- const tileWidth = TILE_WIDTH * scale;
9158
- const floorHeight = FLOOR_HEIGHT * scale;
9159
- const diamondTopY = (opts.diamondTopY ?? DIAMOND_TOP_Y) * scale;
8544
+ const tileWidth = layout === "free" ? 1 : TILE_WIDTH * scale;
8545
+ const floorHeight = layout === "free" ? 1 : FLOOR_HEIGHT * scale;
8546
+ const diamondTopY = layout === "free" ? 0 : (opts.diamondTopY ?? DIAMOND_TOP_Y) * scale;
9160
8547
  const squareGrid = layout === "flat" || layout === "free";
9161
8548
  const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y, scale, baseOffsetX, layout);
9162
8549
  const anchorPoint = (pos, anchor) => {
@@ -9197,6 +8584,15 @@ var init_projector = __esm({
9197
8584
  }
9198
8585
  });
9199
8586
 
8587
+ // lib/drawable/contract.ts
8588
+ function isValidScenePos(pos) {
8589
+ return Number.isFinite(pos?.x) && Number.isFinite(pos?.y);
8590
+ }
8591
+ var init_contract = __esm({
8592
+ "lib/drawable/contract.ts"() {
8593
+ }
8594
+ });
8595
+
9200
8596
  // components/game/atoms/DrawSprite.tsx
9201
8597
  function DrawSprite(_props) {
9202
8598
  return null;
@@ -9206,10 +8602,12 @@ var init_DrawSprite = __esm({
9206
8602
  "components/game/atoms/DrawSprite.tsx"() {
9207
8603
  "use client";
9208
8604
  init_atlasSlice();
8605
+ init_contract();
9209
8606
  paintSprite = (painter, node, dctx) => {
8607
+ if (!node.asset?.url || !isValidScenePos(node.position)) return;
9210
8608
  const tex = painter.resolveTexture(node.asset.url);
9211
8609
  if (!tex) return;
9212
- let src = node.frame;
8610
+ let src = typeof node.frame === "object" ? node.frame : void 0;
9213
8611
  if (!src && isAtlasAsset(node.asset)) {
9214
8612
  const atlas = getAtlas(node.asset.atlas, dctx.invalidate);
9215
8613
  if (!atlas) return;
@@ -9254,7 +8652,9 @@ var paintShape;
9254
8652
  var init_DrawShape = __esm({
9255
8653
  "components/game/atoms/DrawShape.tsx"() {
9256
8654
  "use client";
8655
+ init_contract();
9257
8656
  paintShape = (painter, node, dctx) => {
8657
+ if (!isValidScenePos(node.position)) return;
9258
8658
  painter.save();
9259
8659
  if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
9260
8660
  switch (node.shape) {
@@ -9308,7 +8708,9 @@ var paintText;
9308
8708
  var init_DrawText = __esm({
9309
8709
  "components/game/atoms/DrawText.tsx"() {
9310
8710
  "use client";
8711
+ init_contract();
9311
8712
  paintText = (painter, node, dctx) => {
8713
+ if (!isValidScenePos(node.position)) return;
9312
8714
  const p = dctx.projector.anchorPoint(node.position, node.anchor ?? "center");
9313
8715
  const x = p.x + (node.offsetX ?? 0);
9314
8716
  const y = p.y + (node.offsetY ?? 0);
@@ -9413,12 +8815,14 @@ function collectDrawnItems(nodes) {
9413
8815
  case "draw-sprite":
9414
8816
  case "draw-shape":
9415
8817
  case "draw-text":
9416
- out.push({ pos: n.position, id: n.id });
8818
+ if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id });
9417
8819
  break;
9418
8820
  case "draw-sprite-layer":
9419
8821
  case "draw-shape-layer":
9420
8822
  case "draw-text-layer":
9421
- for (const it of n.items) out.push({ pos: it.position, id: it.id });
8823
+ for (const it of n.items) {
8824
+ if (isValidScenePos(it.position)) out.push({ pos: it.position, id: it.id });
8825
+ }
9422
8826
  break;
9423
8827
  }
9424
8828
  }
@@ -9433,6 +8837,7 @@ function buildHitIndex(items) {
9433
8837
  }
9434
8838
  var init_hitTest = __esm({
9435
8839
  "lib/drawable/hitTest.ts"() {
8840
+ init_contract();
9436
8841
  }
9437
8842
  });
9438
8843
  function normalizeBackdrop(bg) {
@@ -12122,21 +11527,6 @@ var init_renderer = __esm({
12122
11527
  init_slot_definitions();
12123
11528
  }
12124
11529
  });
12125
-
12126
- // lib/wrapCallbackForEvent.ts
12127
- function wrapCallbackForEvent(qualifiedEvent, callbackArgs, emit) {
12128
- const argNames = (callbackArgs ?? []).map((a) => a.name);
12129
- if (argNames.length === 0) {
12130
- return () => emit(qualifiedEvent);
12131
- }
12132
- return (...args) => {
12133
- const payload = {};
12134
- for (let i = 0; i < argNames.length; i += 1) {
12135
- payload[argNames[i]] = args[i];
12136
- }
12137
- emit(qualifiedEvent, payload);
12138
- };
12139
- }
12140
11530
  var init_wrapCallbackForEvent = __esm({
12141
11531
  "lib/wrapCallbackForEvent.ts"() {
12142
11532
  }
@@ -23158,7 +22548,8 @@ function DataGrid({
23158
22548
  const { t } = useTranslate();
23159
22549
  const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
23160
22550
  const [visibleCount, setVisibleCount] = useState(pageSize || Infinity);
23161
- const fieldDefs = fields ?? columns ?? [];
22551
+ const fieldDefs = (Array.isArray(fields) ? fields : void 0) ?? (Array.isArray(columns) ? columns : void 0) ?? [];
22552
+ const actionDefs = Array.isArray(itemActions) ? itemActions : [];
23162
22553
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
23163
22554
  const dnd = useDataDnd({
23164
22555
  items: allDataRaw,
@@ -23202,8 +22593,8 @@ function DataGrid({
23202
22593
  const titleField = fieldDefs.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fieldDefs[0];
23203
22594
  const badgeFields = fieldDefs.filter((f3) => f3.variant === "badge" && f3 !== titleField);
23204
22595
  const bodyFields = fieldDefs.filter((f3) => f3 !== titleField && !badgeFields.includes(f3));
23205
- const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
23206
- const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
22596
+ const primaryActions = actionDefs.filter((a) => a.variant !== "danger");
22597
+ const dangerActions = actionDefs.filter((a) => a.variant === "danger");
23207
22598
  const handleActionClick = (action, itemData) => (e) => {
23208
22599
  e.stopPropagation();
23209
22600
  const payload = {
@@ -35935,7 +35326,7 @@ function measureLabelWidth(text) {
35935
35326
  if (typeof document === "undefined") return text.length * 6;
35936
35327
  if (!labelMeasureCtx) labelMeasureCtx = document.createElement("canvas").getContext("2d");
35937
35328
  if (!labelMeasureCtx) return text.length * 6;
35938
- labelMeasureCtx.font = "10px system-ui";
35329
+ labelMeasureCtx.font = "12px system-ui";
35939
35330
  return labelMeasureCtx.measureText(text).width;
35940
35331
  }
35941
35332
  function getGroupColor(group, groups) {
@@ -35981,6 +35372,7 @@ var init_GraphCanvas = __esm({
35981
35372
  actions,
35982
35373
  onNodeClick,
35983
35374
  onNodeDoubleClick,
35375
+ onBadgeClick,
35984
35376
  nodeClickEvent,
35985
35377
  selectedNodeId,
35986
35378
  repulsion = 800,
@@ -36098,7 +35490,7 @@ var init_GraphCanvas = __esm({
36098
35490
  nodesRef.current = simNodes;
36099
35491
  if (layout === "force") {
36100
35492
  let iterations = 0;
36101
- const maxIterations = 100;
35493
+ const maxIterations = 300;
36102
35494
  const tick = () => {
36103
35495
  const nodes = nodesRef.current;
36104
35496
  const centerX = w / 2;
@@ -36128,7 +35520,9 @@ var init_GraphCanvas = __esm({
36128
35520
  const dx = target.x - source.x;
36129
35521
  const dy = target.y - source.y;
36130
35522
  const dist = Math.sqrt(dx * dx + dy * dy) || 1;
36131
- const force = (dist - linkDistance) * 0.05;
35523
+ const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
35524
+ const linkTarget = linkDistance * (0.5 + (1 - w2) * 1.5);
35525
+ const force = (dist - linkTarget) * (0.04 + 0.1 * w2);
36132
35526
  const fx = dx / dist * force;
36133
35527
  const fy = dy / dist * force;
36134
35528
  source.fx += fx;
@@ -36136,9 +35530,27 @@ var init_GraphCanvas = __esm({
36136
35530
  target.fx -= fx;
36137
35531
  target.fy -= fy;
36138
35532
  }
35533
+ const centroids = /* @__PURE__ */ new Map();
36139
35534
  for (const node of nodes) {
36140
- node.fx += (centerX - node.x) * 0.01;
36141
- node.fy += (centerY - node.y) * 0.01;
35535
+ const g = node.group ?? "__none__";
35536
+ let c = centroids.get(g);
35537
+ if (!c) {
35538
+ c = { x: 0, y: 0, n: 0 };
35539
+ centroids.set(g, c);
35540
+ }
35541
+ c.x += node.x;
35542
+ c.y += node.y;
35543
+ c.n += 1;
35544
+ }
35545
+ for (const node of nodes) {
35546
+ const c = centroids.get(node.group ?? "__none__");
35547
+ if (c && c.n > 1) {
35548
+ node.fx += (c.x / c.n - node.x) * 0.04;
35549
+ node.fy += (c.y / c.n - node.y) * 0.04;
35550
+ } else {
35551
+ node.fx += (centerX - node.x) * 0.01;
35552
+ node.fy += (centerY - node.y) * 0.01;
35553
+ }
36142
35554
  }
36143
35555
  const damping = 0.9;
36144
35556
  for (const node of nodes) {
@@ -36150,7 +35562,7 @@ var init_GraphCanvas = __esm({
36150
35562
  node.y = Math.max(30, Math.min(h - 30, node.y));
36151
35563
  }
36152
35564
  const LABEL_GAP = 12;
36153
- const LABEL_H = 12;
35565
+ const LABEL_H = 16;
36154
35566
  const pad = nodeSpacing / 2;
36155
35567
  for (let i = 0; i < nodes.length; i++) {
36156
35568
  for (let j = i + 1; j < nodes.length; j++) {
@@ -36205,6 +35617,11 @@ var init_GraphCanvas = __esm({
36205
35617
  const h = height;
36206
35618
  const nodes = nodesRef.current;
36207
35619
  const accentColor = resolveColor3("var(--color-accent)", canvas);
35620
+ const fontFamily = resolveColor3("var(--font-family)", canvas) || "system-ui";
35621
+ const fgColor = resolveColor3("var(--color-foreground)", canvas);
35622
+ const mutedColor = resolveColor3("var(--color-muted-foreground)", canvas) || fgColor;
35623
+ const bgColor = resolveColor3("var(--color-background)", canvas) || "#ffffff";
35624
+ const accentFg = resolveColor3("var(--color-accent-foreground)", canvas) || "#ffffff";
36208
35625
  const dpr = typeof window !== "undefined" && window.devicePixelRatio || 1;
36209
35626
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
36210
35627
  ctx.clearRect(0, 0, w, h);
@@ -36224,19 +35641,21 @@ var init_GraphCanvas = __esm({
36224
35641
  const target = nodes.find((n) => n.id === edge.target);
36225
35642
  if (!source || !target) continue;
36226
35643
  const incident = !!hoveredNode && (edge.source === hoveredNode || edge.target === hoveredNode);
36227
- ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.05 : linkOpacity;
35644
+ const w2 = edge.weight ?? 1;
35645
+ ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.05 : linkOpacity * w2;
36228
35646
  ctx.beginPath();
36229
35647
  ctx.moveTo(source.x, source.y);
36230
35648
  ctx.lineTo(target.x, target.y);
36231
35649
  ctx.strokeStyle = incident ? accentColor : edge.color || "#888888";
36232
- ctx.lineWidth = incident ? 2 : edge.weight ? Math.max(1, edge.weight) : 1;
35650
+ ctx.lineWidth = incident ? 2 : Math.max(0.75, w2);
36233
35651
  ctx.stroke();
36234
35652
  if (edge.label && showLabels) {
36235
35653
  const mx = (source.x + target.x) / 2;
36236
35654
  const my = (source.y + target.y) / 2;
36237
- ctx.fillStyle = "#888888";
36238
- ctx.font = "9px system-ui";
35655
+ ctx.fillStyle = mutedColor;
35656
+ ctx.font = `9px ${fontFamily}`;
36239
35657
  ctx.textAlign = "center";
35658
+ ctx.textBaseline = "alphabetic";
36240
35659
  ctx.fillText(edge.label, mx, my - 4);
36241
35660
  }
36242
35661
  }
@@ -36261,10 +35680,33 @@ var init_GraphCanvas = __esm({
36261
35680
  }
36262
35681
  ctx.stroke();
36263
35682
  if (showLabels && node.label) {
36264
- ctx.fillStyle = "#666666";
36265
- ctx.font = `${isSelected || isHovered ? "bold " : ""}10px system-ui`;
35683
+ ctx.font = `${isSelected || isHovered ? "600" : "500"} 12px ${fontFamily}`;
36266
35684
  ctx.textAlign = "center";
36267
- ctx.fillText(node.label, node.x, node.y + radius + 12);
35685
+ ctx.textBaseline = "middle";
35686
+ const ly = node.y + radius + 14;
35687
+ ctx.lineWidth = 3;
35688
+ ctx.lineJoin = "round";
35689
+ ctx.strokeStyle = bgColor;
35690
+ ctx.strokeText(node.label, node.x, ly);
35691
+ ctx.fillStyle = isSelected || isHovered ? fgColor : mutedColor;
35692
+ ctx.fillText(node.label, node.x, ly);
35693
+ }
35694
+ if (node.badge && node.badge > 1) {
35695
+ const bx = node.x + radius * 0.7;
35696
+ const by = node.y - radius * 0.7;
35697
+ const br = Math.max(7, Math.min(11, radius * 0.45));
35698
+ ctx.beginPath();
35699
+ ctx.arc(bx, by, br, 0, Math.PI * 2);
35700
+ ctx.fillStyle = accentColor;
35701
+ ctx.fill();
35702
+ ctx.strokeStyle = bgColor;
35703
+ ctx.lineWidth = 2;
35704
+ ctx.stroke();
35705
+ ctx.fillStyle = accentFg;
35706
+ ctx.font = `600 9px ${fontFamily}`;
35707
+ ctx.textAlign = "center";
35708
+ ctx.textBaseline = "middle";
35709
+ ctx.fillText(String(node.badge), bx, by + 0.5);
36268
35710
  }
36269
35711
  }
36270
35712
  ctx.restore();
@@ -36357,11 +35799,21 @@ var init_GraphCanvas = __esm({
36357
35799
  if (!coords) return;
36358
35800
  const node = nodeAt(coords.graphX, coords.graphY);
36359
35801
  if (node) {
35802
+ if (node.badge && node.badge > 1 && onBadgeClick) {
35803
+ const r = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
35804
+ const bx = node.x + r * 0.7;
35805
+ const by = node.y - r * 0.7;
35806
+ const br = Math.max(7, Math.min(11, r * 0.45)) + 3;
35807
+ if (Math.hypot(coords.graphX - bx, coords.graphY - by) <= br) {
35808
+ onBadgeClick(node);
35809
+ return;
35810
+ }
35811
+ }
36360
35812
  handleNodeClick(node);
36361
35813
  }
36362
35814
  }
36363
35815
  },
36364
- [toCoords, nodeAt, handleNodeClick]
35816
+ [toCoords, nodeAt, handleNodeClick, onBadgeClick, selectedNodeId]
36365
35817
  );
36366
35818
  const handlePointerLeave = useCallback(() => {
36367
35819
  setHoveredNode(null);