@almadar/ui 5.112.0 → 5.114.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) {
@@ -9458,14 +8863,16 @@ function Canvas2D({
9458
8863
  cameraPos,
9459
8864
  bgColor
9460
8865
  }) {
8866
+ const instanceId = useMemo(() => Math.random().toString(36).slice(2, 8), []);
8867
+ function isDrawableLayer(node) {
8868
+ return node.type === "draw-sprite-layer" || node.type === "draw-shape-layer" || node.type === "draw-text-layer";
8869
+ }
9461
8870
  const layerSummaries = drawables?.map((d) => {
9462
- if (!d || typeof d !== "object") return d;
9463
- const rec = d;
9464
- return { type: rec.type, itemsLen: Array.isArray(rec.items) ? rec.items.length : void 0, firstItem: Array.isArray(rec.items) ? rec.items[0] : void 0 };
8871
+ if (!isDrawableLayer(d)) return { type: d.type };
8872
+ return { type: d.type, itemsLen: d.items.length, firstItem: d.items[0] };
9465
8873
  });
9466
- console.error("[debug:Canvas2D] " + JSON.stringify({ projection, scale, cameraMode: camera, cameraPos, drawablesCount: drawables?.length, layerSummaries }));
8874
+ canvas2DLog.debug("Canvas2D render", { instanceId, projection, scale, cameraMode: camera, cameraPos: cameraPos ? JSON.stringify(cameraPos) : void 0, drawablesCount: drawables?.length, layerSummaries: layerSummaries ? JSON.stringify(layerSummaries) : void 0 });
9467
8875
  const backgroundImage = normalizeBackdrop(backgroundImageRaw);
9468
- const instanceId = useMemo(() => Math.random().toString(36).slice(2, 8), []);
9469
8876
  const isFree = projection === "free";
9470
8877
  const squareGrid = projection === "flat" || isFree || projection === "side";
9471
8878
  const layout = projection === "side" ? "free" : projection;
@@ -9600,7 +9007,7 @@ function Canvas2D({
9600
9007
  }
9601
9008
  const containerRect = containerRef.current?.getBoundingClientRect();
9602
9009
  const canvasRect = canvas.getBoundingClientRect();
9603
- console.error("[debug:Canvas2D:draw:" + instanceId + "] " + JSON.stringify({ viewportSize, baseOffsetX, cam: { x: cam.x, y: cam.y, zoom: cam.zoom }, cameraPos, containerRect: containerRect ? { width: containerRect.width, height: containerRect.height } : null, canvasRect: canvasRect ? { width: canvasRect.width, height: canvasRect.height } : null }));
9010
+ canvas2DLog.debug("Canvas2D draw", { instanceId, viewportSize, baseOffsetX, cam: { x: cam.x, y: cam.y, zoom: cam.zoom }, cameraPos: cameraPos ? JSON.stringify(cameraPos) : void 0, containerRect: containerRect ? { width: containerRect.width, height: containerRect.height } : null, canvasRect: canvasRect ? { width: canvasRect.width, height: canvasRect.height } : null });
9604
9011
  const painter = createWebPainter(ctx, bumpAtlas);
9605
9012
  painter.save();
9606
9013
  painter.translate(viewportSize.width / 2, viewportSize.height / 2);
@@ -9812,6 +9219,7 @@ function Canvas2D({
9812
9219
  }
9813
9220
  );
9814
9221
  }
9222
+ var canvas2DLog;
9815
9223
  var init_Canvas2D = __esm({
9816
9224
  "components/game/molecules/Canvas2D.tsx"() {
9817
9225
  "use client";
@@ -9833,6 +9241,7 @@ var init_Canvas2D = __esm({
9833
9241
  init_paintDispatch();
9834
9242
  init_hitTest();
9835
9243
  init_isometric();
9244
+ canvas2DLog = createLogger("almadar:ui:game-canvas");
9836
9245
  Canvas2D.displayName = "Canvas2D";
9837
9246
  }
9838
9247
  });
@@ -9871,7 +9280,7 @@ function Canvas({
9871
9280
  keyMap,
9872
9281
  keyUpMap
9873
9282
  }) {
9874
- console.error("[debug:Canvas] " + JSON.stringify({ mode, drawablesCount: drawables?.length, projection, camera }));
9283
+ canvasLog.debug("Canvas render", { mode, drawablesCount: drawables?.length, projection, camera: camera ? JSON.stringify(camera) : void 0 });
9875
9284
  const zoom = camera?.zoom;
9876
9285
  if (mode === "3d") {
9877
9286
  const props3d = {
@@ -9924,7 +9333,7 @@ function Canvas({
9924
9333
  }
9925
9334
  );
9926
9335
  }
9927
- var Canvas3DHost;
9336
+ var Canvas3DHost, canvasLog;
9928
9337
  var init_Canvas = __esm({
9929
9338
  "components/game/molecules/Canvas.tsx"() {
9930
9339
  "use client";
@@ -9932,6 +9341,7 @@ var init_Canvas = __esm({
9932
9341
  Canvas3DHost = lazy(
9933
9342
  () => import('@almadar/ui/components/molecules/game/three').then((m) => ({ default: m.Canvas3DHost }))
9934
9343
  );
9344
+ canvasLog = createLogger("almadar:ui:game-canvas");
9935
9345
  Canvas.displayName = "Canvas";
9936
9346
  }
9937
9347
  });
@@ -12117,21 +11527,6 @@ var init_renderer = __esm({
12117
11527
  init_slot_definitions();
12118
11528
  }
12119
11529
  });
12120
-
12121
- // lib/wrapCallbackForEvent.ts
12122
- function wrapCallbackForEvent(qualifiedEvent, callbackArgs, emit) {
12123
- const argNames = (callbackArgs ?? []).map((a) => a.name);
12124
- if (argNames.length === 0) {
12125
- return () => emit(qualifiedEvent);
12126
- }
12127
- return (...args) => {
12128
- const payload = {};
12129
- for (let i = 0; i < argNames.length; i += 1) {
12130
- payload[argNames[i]] = args[i];
12131
- }
12132
- emit(qualifiedEvent, payload);
12133
- };
12134
- }
12135
11530
  var init_wrapCallbackForEvent = __esm({
12136
11531
  "lib/wrapCallbackForEvent.ts"() {
12137
11532
  }
@@ -23153,7 +22548,8 @@ function DataGrid({
23153
22548
  const { t } = useTranslate();
23154
22549
  const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
23155
22550
  const [visibleCount, setVisibleCount] = useState(pageSize || Infinity);
23156
- 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 : [];
23157
22553
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
23158
22554
  const dnd = useDataDnd({
23159
22555
  items: allDataRaw,
@@ -23197,8 +22593,8 @@ function DataGrid({
23197
22593
  const titleField = fieldDefs.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fieldDefs[0];
23198
22594
  const badgeFields = fieldDefs.filter((f3) => f3.variant === "badge" && f3 !== titleField);
23199
22595
  const bodyFields = fieldDefs.filter((f3) => f3 !== titleField && !badgeFields.includes(f3));
23200
- const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
23201
- 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");
23202
22598
  const handleActionClick = (action, itemData) => (e) => {
23203
22599
  e.stopPropagation();
23204
22600
  const payload = {
@@ -35930,7 +35326,7 @@ function measureLabelWidth(text) {
35930
35326
  if (typeof document === "undefined") return text.length * 6;
35931
35327
  if (!labelMeasureCtx) labelMeasureCtx = document.createElement("canvas").getContext("2d");
35932
35328
  if (!labelMeasureCtx) return text.length * 6;
35933
- labelMeasureCtx.font = "10px system-ui";
35329
+ labelMeasureCtx.font = "12px system-ui";
35934
35330
  return labelMeasureCtx.measureText(text).width;
35935
35331
  }
35936
35332
  function getGroupColor(group, groups) {
@@ -35976,6 +35372,7 @@ var init_GraphCanvas = __esm({
35976
35372
  actions,
35977
35373
  onNodeClick,
35978
35374
  onNodeDoubleClick,
35375
+ onBadgeClick,
35979
35376
  nodeClickEvent,
35980
35377
  selectedNodeId,
35981
35378
  repulsion = 800,
@@ -36123,7 +35520,9 @@ var init_GraphCanvas = __esm({
36123
35520
  const dx = target.x - source.x;
36124
35521
  const dy = target.y - source.y;
36125
35522
  const dist = Math.sqrt(dx * dx + dy * dy) || 1;
36126
- const force = (dist - linkDistance) * 0.05;
35523
+ const w2 = edge.weight ?? 1;
35524
+ const linkTarget = linkDistance * (1 + (1 - Math.min(1, Math.max(0, w2))) * 1.5);
35525
+ const force = (dist - linkTarget) * 0.05;
36127
35526
  const fx = dx / dist * force;
36128
35527
  const fy = dy / dist * force;
36129
35528
  source.fx += fx;
@@ -36145,7 +35544,7 @@ var init_GraphCanvas = __esm({
36145
35544
  node.y = Math.max(30, Math.min(h - 30, node.y));
36146
35545
  }
36147
35546
  const LABEL_GAP = 12;
36148
- const LABEL_H = 12;
35547
+ const LABEL_H = 16;
36149
35548
  const pad = nodeSpacing / 2;
36150
35549
  for (let i = 0; i < nodes.length; i++) {
36151
35550
  for (let j = i + 1; j < nodes.length; j++) {
@@ -36200,6 +35599,11 @@ var init_GraphCanvas = __esm({
36200
35599
  const h = height;
36201
35600
  const nodes = nodesRef.current;
36202
35601
  const accentColor = resolveColor3("var(--color-accent)", canvas);
35602
+ const fontFamily = resolveColor3("var(--font-family)", canvas) || "system-ui";
35603
+ const fgColor = resolveColor3("var(--color-foreground)", canvas);
35604
+ const mutedColor = resolveColor3("var(--color-muted-foreground)", canvas) || fgColor;
35605
+ const bgColor = resolveColor3("var(--color-background)", canvas) || "#ffffff";
35606
+ const accentFg = resolveColor3("var(--color-accent-foreground)", canvas) || "#ffffff";
36203
35607
  const dpr = typeof window !== "undefined" && window.devicePixelRatio || 1;
36204
35608
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
36205
35609
  ctx.clearRect(0, 0, w, h);
@@ -36219,19 +35623,21 @@ var init_GraphCanvas = __esm({
36219
35623
  const target = nodes.find((n) => n.id === edge.target);
36220
35624
  if (!source || !target) continue;
36221
35625
  const incident = !!hoveredNode && (edge.source === hoveredNode || edge.target === hoveredNode);
36222
- ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.05 : linkOpacity;
35626
+ const w2 = edge.weight ?? 1;
35627
+ ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.05 : linkOpacity * w2;
36223
35628
  ctx.beginPath();
36224
35629
  ctx.moveTo(source.x, source.y);
36225
35630
  ctx.lineTo(target.x, target.y);
36226
35631
  ctx.strokeStyle = incident ? accentColor : edge.color || "#888888";
36227
- ctx.lineWidth = incident ? 2 : edge.weight ? Math.max(1, edge.weight) : 1;
35632
+ ctx.lineWidth = incident ? 2 : Math.max(0.75, w2);
36228
35633
  ctx.stroke();
36229
35634
  if (edge.label && showLabels) {
36230
35635
  const mx = (source.x + target.x) / 2;
36231
35636
  const my = (source.y + target.y) / 2;
36232
- ctx.fillStyle = "#888888";
36233
- ctx.font = "9px system-ui";
35637
+ ctx.fillStyle = mutedColor;
35638
+ ctx.font = `9px ${fontFamily}`;
36234
35639
  ctx.textAlign = "center";
35640
+ ctx.textBaseline = "alphabetic";
36235
35641
  ctx.fillText(edge.label, mx, my - 4);
36236
35642
  }
36237
35643
  }
@@ -36256,10 +35662,33 @@ var init_GraphCanvas = __esm({
36256
35662
  }
36257
35663
  ctx.stroke();
36258
35664
  if (showLabels && node.label) {
36259
- ctx.fillStyle = "#666666";
36260
- ctx.font = `${isSelected || isHovered ? "bold " : ""}10px system-ui`;
35665
+ ctx.font = `${isSelected || isHovered ? "600" : "500"} 12px ${fontFamily}`;
36261
35666
  ctx.textAlign = "center";
36262
- ctx.fillText(node.label, node.x, node.y + radius + 12);
35667
+ ctx.textBaseline = "middle";
35668
+ const ly = node.y + radius + 14;
35669
+ ctx.lineWidth = 3;
35670
+ ctx.lineJoin = "round";
35671
+ ctx.strokeStyle = bgColor;
35672
+ ctx.strokeText(node.label, node.x, ly);
35673
+ ctx.fillStyle = isSelected || isHovered ? fgColor : mutedColor;
35674
+ ctx.fillText(node.label, node.x, ly);
35675
+ }
35676
+ if (node.badge && node.badge > 1) {
35677
+ const bx = node.x + radius * 0.7;
35678
+ const by = node.y - radius * 0.7;
35679
+ const br = Math.max(7, Math.min(11, radius * 0.45));
35680
+ ctx.beginPath();
35681
+ ctx.arc(bx, by, br, 0, Math.PI * 2);
35682
+ ctx.fillStyle = accentColor;
35683
+ ctx.fill();
35684
+ ctx.strokeStyle = bgColor;
35685
+ ctx.lineWidth = 2;
35686
+ ctx.stroke();
35687
+ ctx.fillStyle = accentFg;
35688
+ ctx.font = `600 9px ${fontFamily}`;
35689
+ ctx.textAlign = "center";
35690
+ ctx.textBaseline = "middle";
35691
+ ctx.fillText(String(node.badge), bx, by + 0.5);
36263
35692
  }
36264
35693
  }
36265
35694
  ctx.restore();
@@ -36352,11 +35781,21 @@ var init_GraphCanvas = __esm({
36352
35781
  if (!coords) return;
36353
35782
  const node = nodeAt(coords.graphX, coords.graphY);
36354
35783
  if (node) {
35784
+ if (node.badge && node.badge > 1 && onBadgeClick) {
35785
+ const r = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
35786
+ const bx = node.x + r * 0.7;
35787
+ const by = node.y - r * 0.7;
35788
+ const br = Math.max(7, Math.min(11, r * 0.45)) + 3;
35789
+ if (Math.hypot(coords.graphX - bx, coords.graphY - by) <= br) {
35790
+ onBadgeClick(node);
35791
+ return;
35792
+ }
35793
+ }
36355
35794
  handleNodeClick(node);
36356
35795
  }
36357
35796
  }
36358
35797
  },
36359
- [toCoords, nodeAt, handleNodeClick]
35798
+ [toCoords, nodeAt, handleNodeClick, onBadgeClick, selectedNodeId]
36360
35799
  );
36361
35800
  const handlePointerLeave = useCallback(() => {
36362
35801
  setHoveredNode(null);