@almadar/ui 5.76.7 → 5.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/avl/index.cjs +264 -443
  2. package/dist/avl/index.css +3 -3
  3. package/dist/avl/index.js +265 -444
  4. package/dist/components/core/atoms/FlipContainer.d.ts +1 -1
  5. package/dist/components/core/molecules/Card.d.ts +1 -1
  6. package/dist/components/core/molecules/DataGrid.d.ts +1 -1
  7. package/dist/components/core/molecules/DataList.d.ts +1 -1
  8. package/dist/components/core/molecules/DocPagination.d.ts +1 -8
  9. package/dist/components/core/molecules/DocSearch.d.ts +1 -8
  10. package/dist/components/core/molecules/FlipCard.d.ts +1 -1
  11. package/dist/components/core/molecules/MapView.d.ts +1 -18
  12. package/dist/components/core/molecules/SortableList.d.ts +1 -1
  13. package/dist/components/core/molecules/TableView.d.ts +1 -1
  14. package/dist/components/core/organisms/DataTable.d.ts +1 -1
  15. package/dist/components/core/organisms/debug/RuntimeDebugger.d.ts +1 -10
  16. package/dist/components/core/organisms/debug/tabs/EntitiesTab.d.ts +1 -2
  17. package/dist/components/core/organisms/debug/tabs/EventDispatcherTab.d.ts +1 -2
  18. package/dist/components/core/organisms/debug/tabs/EventFlowTab.d.ts +1 -6
  19. package/dist/components/core/organisms/debug/tabs/GuardsPanel.d.ts +1 -6
  20. package/dist/components/core/organisms/debug/tabs/ServerBridgeTab.d.ts +1 -12
  21. package/dist/components/core/organisms/debug/tabs/TicksTab.d.ts +1 -2
  22. package/dist/components/core/organisms/debug/tabs/TraitsTab.d.ts +1 -2
  23. package/dist/components/core/organisms/debug/tabs/TransitionTimeline.d.ts +1 -11
  24. package/dist/components/core/organisms/debug/tabs/VerificationTab.d.ts +1 -8
  25. package/dist/components/game/2d/atoms/ActionButton.d.ts +1 -2
  26. package/dist/components/game/2d/atoms/ChoiceButton.d.ts +1 -2
  27. package/dist/components/game/2d/atoms/ComboCounter.d.ts +1 -2
  28. package/dist/components/game/2d/atoms/ControlButton.d.ts +1 -2
  29. package/dist/components/game/2d/atoms/DamageNumber.d.ts +1 -2
  30. package/dist/components/game/2d/atoms/DialogueBubble.d.ts +1 -2
  31. package/dist/components/game/2d/atoms/GameIcon.d.ts +1 -2
  32. package/dist/components/game/2d/atoms/HealthBar.d.ts +1 -2
  33. package/dist/components/game/2d/atoms/ItemSlot.d.ts +1 -2
  34. package/dist/components/game/2d/atoms/MiniMap.d.ts +1 -2
  35. package/dist/components/game/2d/atoms/ResourceCounter.d.ts +1 -2
  36. package/dist/components/game/2d/atoms/ScoreDisplay.d.ts +1 -2
  37. package/dist/components/game/2d/atoms/StatusEffect.d.ts +1 -2
  38. package/dist/components/game/2d/atoms/TimerDisplay.d.ts +1 -2
  39. package/dist/components/game/2d/atoms/TurnIndicator.d.ts +1 -2
  40. package/dist/components/game/2d/atoms/WaypointMarker.d.ts +1 -2
  41. package/dist/components/game/2d/molecules/GameHud.d.ts +1 -2
  42. package/dist/components/game/2d/molecules/GameMenu.d.ts +1 -2
  43. package/dist/components/game/2d/molecules/InventoryGrid.d.ts +1 -2
  44. package/dist/components/game/2d/molecules/ResourceBar.d.ts +1 -2
  45. package/dist/components/game/2d/molecules/StatBadge.d.ts +1 -2
  46. package/dist/components/game/shared/lib/editorUtils.d.ts +8 -8
  47. package/dist/components/index.cjs +133 -134
  48. package/dist/components/index.css +3 -3
  49. package/dist/components/index.js +133 -134
  50. package/dist/hooks/useGitHub.d.ts +7 -7
  51. package/dist/marketing/index.cjs +2 -2
  52. package/dist/marketing/index.js +2 -2
  53. package/dist/providers/EventBusProvider.d.ts +1 -1
  54. package/dist/providers/SelectionProvider.d.ts +1 -1
  55. package/dist/providers/ServerBridge.d.ts +1 -1
  56. package/dist/providers/index.cjs +260 -439
  57. package/dist/providers/index.css +3 -3
  58. package/dist/providers/index.js +261 -440
  59. package/dist/runtime/index.cjs +260 -439
  60. package/dist/runtime/index.css +3 -3
  61. package/dist/runtime/index.js +261 -440
  62. package/package.json +2 -2
package/dist/avl/index.js CHANGED
@@ -7,7 +7,7 @@ import ELK from 'elkjs/lib/elk.bundled.js';
7
7
  import { MarkerType, useReactFlow, Handle, Position, getBezierPath, EdgeLabelRenderer, useNodeId, ReactFlowProvider, BaseEdge, useNodesState, useEdgesState, ReactFlow, Controls, Background, BackgroundVariant } from '@xyflow/react';
8
8
  import { useTranslate } from '@almadar/ui/hooks';
9
9
  import * as LucideIcons2 from 'lucide-react';
10
- import { Loader2, X, Code, FileText, WrapText, Check, Copy, Lightbulb, CheckCircle, List, Printer, ChevronRight, ChevronLeft, GitBranch, Pencil, Eye, Plus, ArrowRight, Trash, RotateCcw, Play, Terminal, XCircle, AlertTriangle, Trash2, Link2, ZoomOut, ZoomIn, Download, Menu as Menu$1, Package, Calendar, MoreHorizontal, Image as Image$1, Upload, ArrowLeft, HelpCircle, PauseCircle, Search, Type, Heading1, Heading2, Heading3, ListOrdered, Quote, Minus, Eraser, TrendingUp, TrendingDown, AlertCircle, Circle, Clock, CheckCircle2, Bug, Send, ChevronUp, ChevronDown, Wrench, Tag, User, DollarSign } from 'lucide-react';
10
+ import { Loader2, X, Code, FileText, WrapText, Check, Copy, Lightbulb, CheckCircle, List, Printer, ChevronRight, ChevronLeft, GitBranch, Pencil, Eye, Plus, ArrowRight, Trash, RotateCcw, Play, Terminal, XCircle, AlertTriangle, Trash2, Link2, ZoomOut, ZoomIn, Download, ChevronDown, Menu as Menu$1, Package, Calendar, MoreHorizontal, Image as Image$1, Upload, ArrowLeft, HelpCircle, PauseCircle, Search, Type, Heading1, Heading2, Heading3, ListOrdered, Quote, Minus, Eraser, TrendingUp, TrendingDown, AlertCircle, Circle, Clock, CheckCircle2, Bug, Send, ChevronUp, Wrench, Tag, User, DollarSign } from 'lucide-react';
11
11
  import { createPortal } from 'react-dom';
12
12
  import { UISlotProvider, useUISlots, useTheme } from '@almadar/ui/context';
13
13
  import { evaluateGuard, evaluate, createMinimalContext } from '@almadar/evaluator';
@@ -584,7 +584,7 @@ var init_AvlFieldType = __esm({
584
584
  }
585
585
  });
586
586
 
587
- // node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
587
+ // node_modules/clsx/dist/clsx.mjs
588
588
  function r(e) {
589
589
  var t, f3, n = "";
590
590
  if ("string" == typeof e || "number" == typeof e) n += e;
@@ -599,11 +599,11 @@ function clsx() {
599
599
  return n;
600
600
  }
601
601
  var init_clsx = __esm({
602
- "node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs"() {
602
+ "node_modules/clsx/dist/clsx.mjs"() {
603
603
  }
604
604
  });
605
605
 
606
- // node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs
606
+ // node_modules/tailwind-merge/dist/bundle-mjs.mjs
607
607
  function twJoin() {
608
608
  let index = 0;
609
609
  let argument;
@@ -647,7 +647,7 @@ function createTailwindMerge(createConfigFirst, ...createConfigRest) {
647
647
  }
648
648
  var CLASS_PART_SEPARATOR, createClassGroupUtils, getGroupRecursive, arbitraryPropertyRegex, getGroupIdForArbitraryProperty, createClassMap, processClassesRecursively, getPart, isThemeGetter, getPrefixedClassGroupEntries, createLruCache, IMPORTANT_MODIFIER, createParseClassName, sortModifiers, createConfigUtils, SPLIT_CLASSES_REGEX, mergeClassList, toValue, fromTheme, arbitraryValueRegex, fractionRegex, stringLengths, tshirtUnitRegex, lengthUnitRegex, colorFunctionRegex, shadowRegex, imageRegex, isLength, isArbitraryLength, isNumber, isArbitraryNumber, isInteger, isPercent, isArbitraryValue, isTshirtSize, sizeLabels, isArbitrarySize, isArbitraryPosition, imageLabels, isArbitraryImage, isArbitraryShadow, isAny, getIsArbitraryValue, isLengthOnly, isNever, isShadow, isImage, getDefaultConfig, twMerge;
649
649
  var init_bundle_mjs = __esm({
650
- "node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs"() {
650
+ "node_modules/tailwind-merge/dist/bundle-mjs.mjs"() {
651
651
  CLASS_PART_SEPARATOR = "-";
652
652
  createClassGroupUtils = (config) => {
653
653
  const classMap = createClassMap(config);
@@ -15862,318 +15862,14 @@ var init_useCanvasEffects = __esm({
15862
15862
  "use client";
15863
15863
  }
15864
15864
  });
15865
- function pickPath(entry) {
15866
- if (Array.isArray(entry.path)) {
15867
- return entry.path[Math.floor(Math.random() * entry.path.length)];
15868
- }
15869
- return entry.path;
15870
- }
15871
- function useGameAudio({
15872
- manifest,
15873
- baseUrl = "",
15874
- initialMuted = false,
15875
- initialVolume = 1
15876
- }) {
15877
- const [muted, setMutedState] = useState(initialMuted);
15878
- const [masterVolume, setMasterVolumeState] = useState(initialVolume);
15879
- const mutedRef = useRef(muted);
15880
- const volumeRef = useRef(masterVolume);
15881
- const manifestRef = useRef(manifest);
15882
- mutedRef.current = muted;
15883
- volumeRef.current = masterVolume;
15884
- manifestRef.current = manifest;
15885
- const poolsRef = useRef(/* @__PURE__ */ new Map());
15886
- const getOrCreateElement = useCallback((key) => {
15887
- const entry = manifestRef.current[key];
15888
- if (!entry) return null;
15889
- let pool = poolsRef.current.get(key);
15890
- if (!pool) {
15891
- pool = [];
15892
- poolsRef.current.set(key, pool);
15893
- }
15894
- const maxSize = entry.poolSize ?? 1;
15895
- for (const audio of pool) {
15896
- if (audio.paused && (audio.ended || audio.currentTime === 0)) {
15897
- return audio;
15898
- }
15899
- }
15900
- if (pool.length < maxSize) {
15901
- const src = baseUrl + pickPath(entry);
15902
- const audio = new Audio(src);
15903
- audio.loop = entry.loop ?? false;
15904
- pool.push(audio);
15905
- return audio;
15906
- }
15907
- if (!entry.loop) {
15908
- let oldest = pool[0];
15909
- for (const audio of pool) {
15910
- if (audio.currentTime > oldest.currentTime) {
15911
- oldest = audio;
15912
- }
15913
- }
15914
- oldest.pause();
15915
- oldest.currentTime = 0;
15916
- return oldest;
15917
- }
15918
- return null;
15919
- }, [baseUrl]);
15920
- const play = useCallback((key) => {
15921
- if (mutedRef.current) return;
15922
- const entry = manifestRef.current[key];
15923
- if (!entry) return;
15924
- const audio = getOrCreateElement(key);
15925
- if (!audio) return;
15926
- audio.volume = Math.min(1, (entry.volume ?? 1) * volumeRef.current);
15927
- if (!entry.loop) {
15928
- audio.currentTime = 0;
15929
- }
15930
- const promise = audio.play();
15931
- if (promise) {
15932
- promise.catch(() => {
15933
- });
15934
- }
15935
- }, [getOrCreateElement]);
15936
- const stop = useCallback((key) => {
15937
- const pool = poolsRef.current.get(key);
15938
- if (!pool) return;
15939
- for (const audio of pool) {
15940
- audio.pause();
15941
- audio.currentTime = 0;
15942
- }
15943
- }, []);
15944
- const currentMusicKeyRef = useRef(null);
15945
- const currentMusicElRef = useRef(null);
15946
- const musicFadeRef = useRef(null);
15947
- const pendingMusicKeyRef = useRef(null);
15948
- const clearMusicFade = useCallback(() => {
15949
- if (musicFadeRef.current) {
15950
- clearInterval(musicFadeRef.current);
15951
- musicFadeRef.current = null;
15952
- }
15953
- }, []);
15954
- const playMusic = useCallback((key) => {
15955
- if (key === currentMusicKeyRef.current) return;
15956
- pendingMusicKeyRef.current = key;
15957
- const entry = manifestRef.current[key];
15958
- if (!entry) return;
15959
- const fadeDurationMs = entry.crossfadeDurationMs ?? 1500;
15960
- const stepMs = 50;
15961
- const totalSteps = Math.max(1, fadeDurationMs / stepMs);
15962
- const targetVolume = Math.min(1, (entry.volume ?? 1) * volumeRef.current);
15963
- clearMusicFade();
15964
- const src = baseUrl + (Array.isArray(entry.path) ? entry.path[0] : entry.path);
15965
- const incoming = new Audio(src);
15966
- incoming.loop = true;
15967
- incoming.volume = 0;
15968
- const outgoing = currentMusicElRef.current;
15969
- const outgoingStartVol = outgoing?.volume ?? 0;
15970
- currentMusicKeyRef.current = key;
15971
- currentMusicElRef.current = incoming;
15972
- if (!mutedRef.current) {
15973
- incoming.play().catch(() => {
15974
- currentMusicKeyRef.current = null;
15975
- currentMusicElRef.current = outgoing;
15976
- });
15977
- }
15978
- let step = 0;
15979
- musicFadeRef.current = setInterval(() => {
15980
- step++;
15981
- const progress = Math.min(step / totalSteps, 1);
15982
- incoming.volume = Math.min(1, targetVolume * progress);
15983
- if (outgoing) {
15984
- outgoing.volume = Math.max(0, outgoingStartVol * (1 - progress));
15985
- }
15986
- if (progress >= 1) {
15987
- clearMusicFade();
15988
- if (outgoing) {
15989
- outgoing.pause();
15990
- outgoing.src = "";
15991
- }
15992
- }
15993
- }, stepMs);
15994
- }, [baseUrl, clearMusicFade]);
15995
- const stopMusic = useCallback((fadeDurationMs = 1e3) => {
15996
- const outgoing = currentMusicElRef.current;
15997
- if (!outgoing) return;
15998
- currentMusicKeyRef.current = null;
15999
- currentMusicElRef.current = null;
16000
- pendingMusicKeyRef.current = null;
16001
- clearMusicFade();
16002
- const startVolume = outgoing.volume;
16003
- const stepMs = 50;
16004
- const totalSteps = Math.max(1, fadeDurationMs / stepMs);
16005
- let step = 0;
16006
- musicFadeRef.current = setInterval(() => {
16007
- step++;
16008
- const progress = step / totalSteps;
16009
- outgoing.volume = Math.max(0, startVolume * (1 - progress));
16010
- if (progress >= 1) {
16011
- clearMusicFade();
16012
- outgoing.pause();
16013
- outgoing.src = "";
16014
- }
16015
- }, stepMs);
16016
- }, [clearMusicFade]);
16017
- const stopAll = useCallback(() => {
16018
- for (const pool of poolsRef.current.values()) {
16019
- for (const audio of pool) {
16020
- audio.pause();
16021
- audio.currentTime = 0;
16022
- }
16023
- }
16024
- stopMusic(0);
16025
- }, [stopMusic]);
16026
- const setMuted = useCallback((value) => {
16027
- setMutedState(value);
16028
- if (value) {
16029
- for (const [key, pool] of poolsRef.current.entries()) {
16030
- if (manifestRef.current[key]?.loop) {
16031
- for (const audio of pool) {
16032
- if (!audio.paused) audio.pause();
16033
- }
16034
- }
16035
- }
16036
- currentMusicElRef.current?.pause();
16037
- } else {
16038
- for (const [key, pool] of poolsRef.current.entries()) {
16039
- const entry = manifestRef.current[key];
16040
- if (entry?.loop && entry?.autostart) {
16041
- for (const audio of pool) {
16042
- if (audio.paused) audio.play().catch(() => {
16043
- });
16044
- }
16045
- }
16046
- }
16047
- const musicEl = currentMusicElRef.current;
16048
- if (musicEl) {
16049
- musicEl.play().catch(() => {
16050
- });
16051
- }
16052
- }
16053
- }, []);
16054
- const setMasterVolume = useCallback((volume) => {
16055
- const clamped = Math.max(0, Math.min(1, volume));
16056
- setMasterVolumeState(clamped);
16057
- for (const [key, pool] of poolsRef.current.entries()) {
16058
- const entryVol = manifestRef.current[key]?.volume ?? 1;
16059
- for (const audio of pool) {
16060
- audio.volume = Math.min(1, entryVol * clamped);
16061
- }
16062
- }
16063
- if (!musicFadeRef.current && currentMusicElRef.current) {
16064
- const key = currentMusicKeyRef.current;
16065
- const entryVol = key ? manifestRef.current[key]?.volume ?? 1 : 1;
16066
- currentMusicElRef.current.volume = Math.min(1, entryVol * clamped);
16067
- }
16068
- }, []);
16069
- const unlockedRef = useRef(false);
16070
- useEffect(() => {
16071
- const autoKeys = Object.keys(manifest).filter((k) => manifest[k].autostart);
16072
- const hasPendingMusic = () => pendingMusicKeyRef.current !== null;
16073
- const hasAutoStart = autoKeys.length > 0;
16074
- if (!hasAutoStart && !hasPendingMusic()) return;
16075
- const unlock = () => {
16076
- if (unlockedRef.current) return;
16077
- unlockedRef.current = true;
16078
- if (!mutedRef.current) {
16079
- for (const key of autoKeys) {
16080
- play(key);
16081
- }
16082
- const pending = pendingMusicKeyRef.current;
16083
- if (pending && pending !== currentMusicKeyRef.current) {
16084
- playMusic(pending);
16085
- }
16086
- }
16087
- };
16088
- document.addEventListener("click", unlock, { once: true });
16089
- document.addEventListener("keydown", unlock, { once: true });
16090
- document.addEventListener("touchstart", unlock, { once: true });
16091
- return () => {
16092
- document.removeEventListener("click", unlock);
16093
- document.removeEventListener("keydown", unlock);
16094
- document.removeEventListener("touchstart", unlock);
16095
- };
16096
- }, [manifest, play, playMusic]);
16097
- useEffect(() => {
16098
- return () => {
16099
- clearMusicFade();
16100
- for (const pool of poolsRef.current.values()) {
16101
- for (const audio of pool) {
16102
- audio.pause();
16103
- audio.src = "";
16104
- }
16105
- }
16106
- poolsRef.current.clear();
16107
- if (currentMusicElRef.current) {
16108
- currentMusicElRef.current.pause();
16109
- currentMusicElRef.current.src = "";
16110
- currentMusicElRef.current = null;
16111
- }
16112
- };
16113
- }, [clearMusicFade]);
16114
- return {
16115
- play,
16116
- stop,
16117
- stopAll,
16118
- playMusic,
16119
- stopMusic,
16120
- muted,
16121
- setMuted,
16122
- masterVolume,
16123
- setMasterVolume
16124
- };
16125
- }
16126
15865
  var init_useGameAudio = __esm({
16127
15866
  "components/game/shared/hooks/useGameAudio.ts"() {
16128
15867
  "use client";
16129
- useGameAudio.displayName = "useGameAudio";
16130
15868
  }
16131
15869
  });
16132
15870
  function useGameAudioContextOptional() {
16133
15871
  return useContext(GameAudioContext);
16134
15872
  }
16135
- function GameAudioProvider({
16136
- manifest,
16137
- baseUrl = "",
16138
- children,
16139
- initialMuted = false
16140
- }) {
16141
- const eventBus = useEventBus();
16142
- const { play, stop, stopAll, playMusic, stopMusic, muted, setMuted, masterVolume, setMasterVolume } = useGameAudio({ manifest, baseUrl, initialMuted });
16143
- useEffect(() => {
16144
- const unsubPlay = eventBus.on("UI:PLAY_SOUND", (event) => {
16145
- const key = event.payload?.key;
16146
- if (key) play(key);
16147
- });
16148
- const unsubStop = eventBus.on("UI:STOP_SOUND", (event) => {
16149
- const key = event.payload?.key;
16150
- if (key) {
16151
- stop(key);
16152
- } else {
16153
- stopAll();
16154
- }
16155
- });
16156
- const unsubChangeMusic = eventBus.on("UI:CHANGE_MUSIC", (event) => {
16157
- const key = event.payload?.key;
16158
- if (key) {
16159
- playMusic(key);
16160
- } else {
16161
- stopMusic();
16162
- }
16163
- });
16164
- const unsubStopMusic = eventBus.on("UI:STOP_MUSIC", () => {
16165
- stopMusic();
16166
- });
16167
- return () => {
16168
- unsubPlay();
16169
- unsubStop();
16170
- unsubChangeMusic();
16171
- unsubStopMusic();
16172
- };
16173
- }, [eventBus, play, stop, stopAll, playMusic, stopMusic]);
16174
- const value = { muted, setMuted, masterVolume, setMasterVolume, play, playMusic, stopMusic };
16175
- return /* @__PURE__ */ jsx(GameAudioContext.Provider, { value, children });
16176
- }
16177
15873
  var GameAudioContext;
16178
15874
  var init_GameAudioProvider = __esm({
16179
15875
  "components/game/shared/providers/GameAudioProvider.tsx"() {
@@ -16182,7 +15878,6 @@ var init_GameAudioProvider = __esm({
16182
15878
  init_useGameAudio();
16183
15879
  GameAudioContext = createContext(null);
16184
15880
  GameAudioContext.displayName = "GameAudioContext";
16185
- GameAudioProvider.displayName = "GameAudioProvider";
16186
15881
  }
16187
15882
  });
16188
15883
  function GameAudioToggle({
@@ -25530,9 +25225,9 @@ var init_AuthLayout = __esm({
25530
25225
  }
25531
25226
  });
25532
25227
 
25533
- // node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css
25228
+ // node_modules/katex/dist/katex.min.css
25534
25229
  var init_katex_min = __esm({
25535
- "node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css"() {
25230
+ "node_modules/katex/dist/katex.min.css"() {
25536
25231
  }
25537
25232
  });
25538
25233
  var Tabs;
@@ -29925,129 +29620,6 @@ var init_Breadcrumb = __esm({
29925
29620
  Breadcrumb.displayName = "Breadcrumb";
29926
29621
  }
29927
29622
  });
29928
- function useSafeEventBus2() {
29929
- try {
29930
- return useEventBus();
29931
- } catch {
29932
- return { emit: () => {
29933
- }, on: () => () => {
29934
- }, once: () => {
29935
- } };
29936
- }
29937
- }
29938
- var log5, lookStyles4, ButtonGroup;
29939
- var init_ButtonGroup = __esm({
29940
- "components/core/molecules/ButtonGroup.tsx"() {
29941
- "use client";
29942
- init_cn();
29943
- init_atoms();
29944
- init_useEventBus();
29945
- log5 = createLogger("almadar:ui:button-group");
29946
- lookStyles4 = {
29947
- "right-aligned-buttons": "",
29948
- "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
29949
- "inline-row": "gap-2 inline-flex",
29950
- "dropdown-menu": "[&>button:not(:first-child)]:hidden",
29951
- "command-palette-trigger": "[&>button:not(:first-child)]:hidden"
29952
- };
29953
- ButtonGroup = ({
29954
- children,
29955
- primary,
29956
- secondary,
29957
- variant = "default",
29958
- orientation = "horizontal",
29959
- className,
29960
- // Filter-group pattern props (entity and filters are used for schema-driven filtering)
29961
- entity: _entity,
29962
- filters,
29963
- look = "right-aligned-buttons"
29964
- }) => {
29965
- const eventBus = useSafeEventBus2();
29966
- const variantClasses2 = {
29967
- default: "gap-0",
29968
- segmented: "gap-0 [&>button]:rounded-none [&>button:first-child]:rounded-l-lg [&>button:last-child]:rounded-r-lg [&>button:not(:first-child)]:border-l-0",
29969
- toggle: "gap-0 [&>button]:rounded-none [&>button:first-child]:rounded-l-lg [&>button:last-child]:rounded-r-lg [&>button:not(:first-child)]:border-l-0"
29970
- };
29971
- const orientationClasses = {
29972
- horizontal: "flex-row",
29973
- vertical: "flex-col [&>button:first-child]:rounded-t-lg [&>button:last-child]:rounded-b-lg [&>button:not(:first-child)]:border-t-0 [&>button:not(:first-child)]:border-l"
29974
- };
29975
- const handleActionClick = (action) => {
29976
- if (action.event) {
29977
- eventBus.emit("UI:DISPATCH", { event: action.event });
29978
- }
29979
- if (action.navigatesTo) {
29980
- eventBus.emit("UI:NAVIGATE", { url: action.navigatesTo });
29981
- }
29982
- };
29983
- const renderFormActions = () => {
29984
- const buttons = [];
29985
- if (secondary) {
29986
- secondary.forEach((action, index) => {
29987
- buttons.push(
29988
- /* @__PURE__ */ jsx(
29989
- Button,
29990
- {
29991
- type: action.actionType === "submit" ? "submit" : "button",
29992
- variant: action.variant || "ghost",
29993
- onClick: () => handleActionClick(action),
29994
- children: action.label
29995
- },
29996
- `secondary-${index}`
29997
- )
29998
- );
29999
- });
30000
- }
30001
- if (primary) {
30002
- const isSubmit = primary.actionType === "submit";
30003
- buttons.push(
30004
- /* @__PURE__ */ jsx(
30005
- Button,
30006
- {
30007
- type: isSubmit ? "submit" : "button",
30008
- variant: primary.variant || "primary",
30009
- onClick: () => handleActionClick(primary),
30010
- "data-testid": isSubmit ? "form-submit" : void 0,
30011
- children: primary.label
30012
- },
30013
- "primary"
30014
- )
30015
- );
30016
- }
30017
- return buttons;
30018
- };
30019
- const renderFilters = () => {
30020
- if (!filters || filters.length === 0) return null;
30021
- return filters.map((filter, index) => /* @__PURE__ */ jsx(
30022
- Button,
30023
- {
30024
- variant: "ghost",
30025
- onClick: () => {
30026
- log5.debug("Filter clicked", { field: filter.field });
30027
- },
30028
- children: filter.label
30029
- },
30030
- `filter-${filter.field}-${index}`
30031
- ));
30032
- };
30033
- return /* @__PURE__ */ jsx(
30034
- "div",
30035
- {
30036
- className: cn(
30037
- "inline-flex gap-2",
30038
- variantClasses2[variant],
30039
- orientationClasses[orientation],
30040
- lookStyles4[look],
30041
- className
30042
- ),
30043
- role: "group",
30044
- children: children || renderFilters() || renderFormActions()
30045
- }
30046
- );
30047
- };
30048
- ButtonGroup.displayName = "ButtonGroup";
30049
- }
30050
- });
30051
29623
  function useSwipeGesture(callbacks, options = {}) {
30052
29624
  const { threshold = 50, velocityThreshold = 0.3, preventDefault = false } = options;
30053
29625
  const startX = useRef(0);
@@ -30857,7 +30429,7 @@ var init_CardGrid = __esm({
30857
30429
  CardGrid.displayName = "CardGrid";
30858
30430
  }
30859
30431
  });
30860
- function useSafeEventBus3() {
30432
+ function useSafeEventBus2() {
30861
30433
  try {
30862
30434
  return useEventBus();
30863
30435
  } catch {
@@ -30893,7 +30465,7 @@ var init_Carousel = __esm({
30893
30465
  const [activeIndex, setActiveIndex] = useState(0);
30894
30466
  const scrollRef = useRef(null);
30895
30467
  const autoPlayRef = useRef(null);
30896
- const eventBus = useSafeEventBus3();
30468
+ const eventBus = useSafeEventBus2();
30897
30469
  const { t } = useTranslate();
30898
30470
  const safeItems = items ?? [];
30899
30471
  const totalSlides = safeItems.length;
@@ -34229,7 +33801,7 @@ function DataGrid({
34229
33801
  /* @__PURE__ */ jsx(
34230
33802
  Box,
34231
33803
  {
34232
- className: cn("grid", gapStyles5[gap], scrollX ? "grid-flow-col overflow-x-auto" : colsClass, lookStyles5[look], className),
33804
+ className: cn("grid", gapStyles5[gap], scrollX ? "grid-flow-col overflow-x-auto" : colsClass, lookStyles4[look], className),
34233
33805
  style: scrollX ? { gridAutoFlow: "column", gridAutoColumns: `minmax(${minCardWidth}px, 1fr)` } : gridTemplateColumns ? { gridTemplateColumns } : void 0,
34234
33806
  children: data.map((item, index) => {
34235
33807
  const itemData = item;
@@ -34424,7 +33996,7 @@ function DataGrid({
34424
33996
  ] })
34425
33997
  );
34426
33998
  }
34427
- var dataGridLog, BADGE_VARIANTS, gapStyles5, lookStyles5;
33999
+ var dataGridLog, BADGE_VARIANTS, gapStyles5, lookStyles4;
34428
34000
  var init_DataGrid = __esm({
34429
34001
  "components/core/molecules/DataGrid.tsx"() {
34430
34002
  "use client";
@@ -34459,7 +34031,7 @@ var init_DataGrid = __esm({
34459
34031
  lg: "gap-6",
34460
34032
  xl: "gap-8"
34461
34033
  };
34462
- lookStyles5 = {
34034
+ lookStyles4 = {
34463
34035
  dense: "gap-2 [&>*]:p-card-sm",
34464
34036
  spacious: "gap-8 [&>*]:p-card-lg",
34465
34037
  striped: "[&>*:nth-child(even)]:bg-muted/30",
@@ -34886,6 +34458,133 @@ var init_DataList = __esm({
34886
34458
  DataList.displayName = "DataList";
34887
34459
  }
34888
34460
  });
34461
+ var FormSection, FormLayout, FormActions;
34462
+ var init_FormSection = __esm({
34463
+ "components/core/molecules/FormSection.tsx"() {
34464
+ "use client";
34465
+ init_cn();
34466
+ init_atoms();
34467
+ init_Box();
34468
+ init_Typography();
34469
+ init_Button();
34470
+ init_Stack();
34471
+ init_Icon();
34472
+ init_useEventBus();
34473
+ FormSection = ({
34474
+ title,
34475
+ description,
34476
+ children,
34477
+ collapsible = false,
34478
+ defaultCollapsed = false,
34479
+ card = false,
34480
+ columns = 1,
34481
+ className
34482
+ }) => {
34483
+ const [collapsed, setCollapsed] = React114__default.useState(defaultCollapsed);
34484
+ const { t } = useTranslate();
34485
+ const eventBus = useEventBus();
34486
+ const gridClass = {
34487
+ 1: "grid-cols-1",
34488
+ 2: "grid-cols-1 md:grid-cols-2",
34489
+ 3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
34490
+ }[columns];
34491
+ React114__default.useCallback(() => {
34492
+ if (collapsible) {
34493
+ setCollapsed((prev) => !prev);
34494
+ eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
34495
+ }
34496
+ }, [collapsible, collapsed, eventBus]);
34497
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
34498
+ (title || description) && /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "mb-4", children: [
34499
+ title && /* @__PURE__ */ jsxs(
34500
+ HStack,
34501
+ {
34502
+ justify: "between",
34503
+ align: "center",
34504
+ className: cn(collapsible && "cursor-pointer"),
34505
+ action: collapsible ? "TOGGLE_COLLAPSE" : void 0,
34506
+ children: [
34507
+ /* @__PURE__ */ jsx(Typography, { variant: "h3", weight: "semibold", children: title }),
34508
+ collapsible && /* @__PURE__ */ jsx(
34509
+ Button,
34510
+ {
34511
+ variant: "ghost",
34512
+ size: "sm",
34513
+ action: "TOGGLE_COLLAPSE",
34514
+ children: /* @__PURE__ */ jsx(
34515
+ Icon,
34516
+ {
34517
+ icon: ChevronDown,
34518
+ size: "sm",
34519
+ className: cn(
34520
+ "text-muted-foreground transition-transform",
34521
+ collapsed && "rotate-180"
34522
+ )
34523
+ }
34524
+ )
34525
+ }
34526
+ )
34527
+ ]
34528
+ }
34529
+ ),
34530
+ description && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: description })
34531
+ ] }),
34532
+ (!collapsible || !collapsed) && /* @__PURE__ */ jsx(Box, { className: cn("grid gap-4", gridClass), children })
34533
+ ] });
34534
+ if (card) {
34535
+ return /* @__PURE__ */ jsx(Card, { className: cn("p-6", className), children: content });
34536
+ }
34537
+ return /* @__PURE__ */ jsx(Box, { className, children: content });
34538
+ };
34539
+ FormSection.displayName = "FormSection";
34540
+ FormLayout = ({
34541
+ children,
34542
+ dividers = true,
34543
+ className
34544
+ }) => {
34545
+ return /* @__PURE__ */ jsx(
34546
+ VStack,
34547
+ {
34548
+ gap: "lg",
34549
+ className: cn(
34550
+ dividers && "[&>*+*]:pt-8 [&>*+*]:border-t [&>*+*]:border-border",
34551
+ className
34552
+ ),
34553
+ children
34554
+ }
34555
+ );
34556
+ };
34557
+ FormLayout.displayName = "FormLayout";
34558
+ FormActions = ({
34559
+ children,
34560
+ sticky = false,
34561
+ align = "right",
34562
+ className
34563
+ }) => {
34564
+ const alignClass2 = {
34565
+ left: "justify-start",
34566
+ right: "justify-end",
34567
+ between: "justify-between",
34568
+ center: "justify-center"
34569
+ }[align];
34570
+ return /* @__PURE__ */ jsx(
34571
+ HStack,
34572
+ {
34573
+ gap: "sm",
34574
+ align: "center",
34575
+ className: cn(
34576
+ "pt-6 border-t border-border",
34577
+ alignClass2,
34578
+ sticky && "sticky bottom-0 bg-card py-4 -mx-6 px-6 shadow-[0_-4px_6px_-1px_rgb(0,0,0,0.05)]",
34579
+ className
34580
+ ),
34581
+ children
34582
+ }
34583
+ );
34584
+ };
34585
+ FormActions.displayName = "FormActions";
34586
+ }
34587
+ });
34889
34588
  function fileIcon(name) {
34890
34589
  const ext = name.split(".").pop()?.toLowerCase() ?? "";
34891
34590
  switch (ext) {
@@ -35047,6 +34746,129 @@ var init_FormField = __esm({
35047
34746
  FormField.displayName = "FormField";
35048
34747
  }
35049
34748
  });
34749
+ function useSafeEventBus3() {
34750
+ try {
34751
+ return useEventBus();
34752
+ } catch {
34753
+ return { emit: () => {
34754
+ }, on: () => () => {
34755
+ }, once: () => {
34756
+ } };
34757
+ }
34758
+ }
34759
+ var log5, lookStyles5, ButtonGroup;
34760
+ var init_ButtonGroup = __esm({
34761
+ "components/core/molecules/ButtonGroup.tsx"() {
34762
+ "use client";
34763
+ init_cn();
34764
+ init_atoms();
34765
+ init_useEventBus();
34766
+ log5 = createLogger("almadar:ui:button-group");
34767
+ lookStyles5 = {
34768
+ "right-aligned-buttons": "",
34769
+ "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
34770
+ "inline-row": "gap-2 inline-flex",
34771
+ "dropdown-menu": "[&>button:not(:first-child)]:hidden",
34772
+ "command-palette-trigger": "[&>button:not(:first-child)]:hidden"
34773
+ };
34774
+ ButtonGroup = ({
34775
+ children,
34776
+ primary,
34777
+ secondary,
34778
+ variant = "default",
34779
+ orientation = "horizontal",
34780
+ className,
34781
+ // Filter-group pattern props (entity and filters are used for schema-driven filtering)
34782
+ entity: _entity,
34783
+ filters,
34784
+ look = "right-aligned-buttons"
34785
+ }) => {
34786
+ const eventBus = useSafeEventBus3();
34787
+ const variantClasses2 = {
34788
+ default: "gap-0",
34789
+ segmented: "gap-0 [&>button]:rounded-none [&>button:first-child]:rounded-l-lg [&>button:last-child]:rounded-r-lg [&>button:not(:first-child)]:border-l-0",
34790
+ toggle: "gap-0 [&>button]:rounded-none [&>button:first-child]:rounded-l-lg [&>button:last-child]:rounded-r-lg [&>button:not(:first-child)]:border-l-0"
34791
+ };
34792
+ const orientationClasses = {
34793
+ horizontal: "flex-row",
34794
+ vertical: "flex-col [&>button:first-child]:rounded-t-lg [&>button:last-child]:rounded-b-lg [&>button:not(:first-child)]:border-t-0 [&>button:not(:first-child)]:border-l"
34795
+ };
34796
+ const handleActionClick = (action) => {
34797
+ if (action.event) {
34798
+ eventBus.emit("UI:DISPATCH", { event: action.event });
34799
+ }
34800
+ if (action.navigatesTo) {
34801
+ eventBus.emit("UI:NAVIGATE", { url: action.navigatesTo });
34802
+ }
34803
+ };
34804
+ const renderFormActions = () => {
34805
+ const buttons = [];
34806
+ if (secondary) {
34807
+ secondary.forEach((action, index) => {
34808
+ buttons.push(
34809
+ /* @__PURE__ */ jsx(
34810
+ Button,
34811
+ {
34812
+ type: action.actionType === "submit" ? "submit" : "button",
34813
+ variant: action.variant || "ghost",
34814
+ onClick: () => handleActionClick(action),
34815
+ children: action.label
34816
+ },
34817
+ `secondary-${index}`
34818
+ )
34819
+ );
34820
+ });
34821
+ }
34822
+ if (primary) {
34823
+ const isSubmit = primary.actionType === "submit";
34824
+ buttons.push(
34825
+ /* @__PURE__ */ jsx(
34826
+ Button,
34827
+ {
34828
+ type: isSubmit ? "submit" : "button",
34829
+ variant: primary.variant || "primary",
34830
+ onClick: () => handleActionClick(primary),
34831
+ "data-testid": isSubmit ? "form-submit" : void 0,
34832
+ children: primary.label
34833
+ },
34834
+ "primary"
34835
+ )
34836
+ );
34837
+ }
34838
+ return buttons;
34839
+ };
34840
+ const renderFilters = () => {
34841
+ if (!filters || filters.length === 0) return null;
34842
+ return filters.map((filter, index) => /* @__PURE__ */ jsx(
34843
+ Button,
34844
+ {
34845
+ variant: "ghost",
34846
+ onClick: () => {
34847
+ log5.debug("Filter clicked", { field: filter.field });
34848
+ },
34849
+ children: filter.label
34850
+ },
34851
+ `filter-${filter.field}-${index}`
34852
+ ));
34853
+ };
34854
+ return /* @__PURE__ */ jsx(
34855
+ "div",
34856
+ {
34857
+ className: cn(
34858
+ "inline-flex gap-2",
34859
+ variantClasses2[variant],
34860
+ orientationClasses[orientation],
34861
+ lookStyles5[look],
34862
+ className
34863
+ ),
34864
+ role: "group",
34865
+ children: children || renderFilters() || renderFormActions()
34866
+ }
34867
+ );
34868
+ };
34869
+ ButtonGroup.displayName = "ButtonGroup";
34870
+ }
34871
+ });
35050
34872
  function getOrCreateStore(query) {
35051
34873
  if (!queryStores.has(query)) {
35052
34874
  queryStores.set(query, {
@@ -53217,7 +53039,6 @@ var init_component_registry_generated = __esm({
53217
53039
  init_BranchingLogicBuilder();
53218
53040
  init_Breadcrumb();
53219
53041
  init_BuilderBoard();
53220
- init_ButtonGroup();
53221
53042
  init_CTABanner();
53222
53043
  init_CalendarGrid();
53223
53044
  init_Canvas2D();
@@ -53294,9 +53115,9 @@ var init_component_registry_generated = __esm({
53294
53115
  init_FlipContainer();
53295
53116
  init_FloatingActionButton();
53296
53117
  init_Form();
53118
+ init_FormSection();
53297
53119
  init_FormField();
53298
53120
  init_FormSectionHeader();
53299
- init_GameAudioProvider();
53300
53121
  init_GameAudioToggle();
53301
53122
  init_GameCard();
53302
53123
  init_GameHud();
@@ -53545,7 +53366,6 @@ var init_component_registry_generated = __esm({
53545
53366
  "Breadcrumb": Breadcrumb,
53546
53367
  "BuilderBoard": BuilderBoard,
53547
53368
  "Button": ButtonPattern,
53548
- "ButtonGroup": ButtonGroup,
53549
53369
  "ButtonPattern": ButtonPattern,
53550
53370
  "CTABanner": CTABanner,
53551
53371
  "CalendarGrid": CalendarGrid,
@@ -53625,9 +53445,10 @@ var init_component_registry_generated = __esm({
53625
53445
  "FlipContainer": FlipContainer,
53626
53446
  "FloatingActionButton": FloatingActionButton,
53627
53447
  "Form": Form,
53448
+ "FormActions": FormActions,
53628
53449
  "FormField": FormField,
53450
+ "FormLayout": FormLayout,
53629
53451
  "FormSectionHeader": FormSectionHeader,
53630
- "GameAudioProvider": GameAudioProvider,
53631
53452
  "GameAudioToggle": GameAudioToggle,
53632
53453
  "GameBoard3D": GameBoard3D,
53633
53454
  "GameCanvas3D": GameCanvas3D,