@almadar/ui 4.1.0 → 4.3.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.
@@ -10859,21 +10859,26 @@ var init_FloatingActionButton = __esm({
10859
10859
  init_useTranslate();
10860
10860
  FloatingActionButton = ({
10861
10861
  action,
10862
+ actionPayload,
10862
10863
  actions,
10863
10864
  icon,
10864
10865
  onClick,
10865
10866
  variant,
10867
+ label,
10866
10868
  position = "bottom-right",
10867
10869
  className
10868
10870
  }) => {
10869
10871
  const eventBus = useEventBus();
10870
10872
  const { t } = useTranslate();
10871
- const resolvedAction = action ?? (icon ? {
10873
+ const resolvedAction = icon ? {
10872
10874
  icon: resolveIcon2(icon),
10873
- onClick: onClick ?? (() => {
10874
- }),
10875
+ onClick: () => {
10876
+ if (action) eventBus.emit(`UI:${action}`, actionPayload ?? {});
10877
+ onClick?.();
10878
+ },
10879
+ label,
10875
10880
  variant
10876
- } : void 0);
10881
+ } : void 0;
10877
10882
  const [isExpanded, setIsExpanded] = React126.useState(false);
10878
10883
  const fabRef = React126.useRef(null);
10879
10884
  React126.useEffect(() => {
@@ -21738,6 +21743,16 @@ function statusVariant2(value) {
21738
21743
  if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
21739
21744
  return "default";
21740
21745
  }
21746
+ function resolveBadgeVariant(field, value) {
21747
+ const fromMap = field.colorMap?.[value];
21748
+ if (fromMap) {
21749
+ const normalised = fromMap === "destructive" ? "danger" : fromMap;
21750
+ if (BADGE_VARIANTS.has(normalised)) {
21751
+ return normalised;
21752
+ }
21753
+ }
21754
+ return statusVariant2(value);
21755
+ }
21741
21756
  function formatDate2(value) {
21742
21757
  if (!value) return "";
21743
21758
  const d = new Date(String(value));
@@ -21951,7 +21966,7 @@ function DataGrid({
21951
21966
  if (val === void 0 || val === null) return null;
21952
21967
  return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
21953
21968
  field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs" }),
21954
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
21969
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
21955
21970
  ] }, field.name);
21956
21971
  }) })
21957
21972
  ] }),
@@ -22044,7 +22059,7 @@ function DataGrid({
22044
22059
  )
22045
22060
  ] });
22046
22061
  }
22047
- var gapStyles6;
22062
+ var BADGE_VARIANTS, gapStyles6;
22048
22063
  var init_DataGrid = __esm({
22049
22064
  "components/molecules/DataGrid.tsx"() {
22050
22065
  "use client";
@@ -22059,6 +22074,17 @@ var init_DataGrid = __esm({
22059
22074
  init_Button();
22060
22075
  init_Icon();
22061
22076
  init_InfiniteScrollSentinel();
22077
+ BADGE_VARIANTS = /* @__PURE__ */ new Set([
22078
+ "default",
22079
+ "primary",
22080
+ "secondary",
22081
+ "success",
22082
+ "warning",
22083
+ "danger",
22084
+ "error",
22085
+ "info",
22086
+ "neutral"
22087
+ ]);
22062
22088
  gapStyles6 = {
22063
22089
  none: "gap-0",
22064
22090
  sm: "gap-2",
package/dist/avl/index.js CHANGED
@@ -10813,21 +10813,26 @@ var init_FloatingActionButton = __esm({
10813
10813
  init_useTranslate();
10814
10814
  FloatingActionButton = ({
10815
10815
  action,
10816
+ actionPayload,
10816
10817
  actions,
10817
10818
  icon,
10818
10819
  onClick,
10819
10820
  variant,
10821
+ label,
10820
10822
  position = "bottom-right",
10821
10823
  className
10822
10824
  }) => {
10823
10825
  const eventBus = useEventBus();
10824
10826
  const { t } = useTranslate();
10825
- const resolvedAction = action ?? (icon ? {
10827
+ const resolvedAction = icon ? {
10826
10828
  icon: resolveIcon2(icon),
10827
- onClick: onClick ?? (() => {
10828
- }),
10829
+ onClick: () => {
10830
+ if (action) eventBus.emit(`UI:${action}`, actionPayload ?? {});
10831
+ onClick?.();
10832
+ },
10833
+ label,
10829
10834
  variant
10830
- } : void 0);
10835
+ } : void 0;
10831
10836
  const [isExpanded, setIsExpanded] = useState(false);
10832
10837
  const fabRef = useRef(null);
10833
10838
  useEffect(() => {
@@ -21692,6 +21697,16 @@ function statusVariant2(value) {
21692
21697
  if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
21693
21698
  return "default";
21694
21699
  }
21700
+ function resolveBadgeVariant(field, value) {
21701
+ const fromMap = field.colorMap?.[value];
21702
+ if (fromMap) {
21703
+ const normalised = fromMap === "destructive" ? "danger" : fromMap;
21704
+ if (BADGE_VARIANTS.has(normalised)) {
21705
+ return normalised;
21706
+ }
21707
+ }
21708
+ return statusVariant2(value);
21709
+ }
21695
21710
  function formatDate2(value) {
21696
21711
  if (!value) return "";
21697
21712
  const d = new Date(String(value));
@@ -21905,7 +21920,7 @@ function DataGrid({
21905
21920
  if (val === void 0 || val === null) return null;
21906
21921
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
21907
21922
  field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
21908
- /* @__PURE__ */ jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
21923
+ /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
21909
21924
  ] }, field.name);
21910
21925
  }) })
21911
21926
  ] }),
@@ -21998,7 +22013,7 @@ function DataGrid({
21998
22013
  )
21999
22014
  ] });
22000
22015
  }
22001
- var gapStyles6;
22016
+ var BADGE_VARIANTS, gapStyles6;
22002
22017
  var init_DataGrid = __esm({
22003
22018
  "components/molecules/DataGrid.tsx"() {
22004
22019
  "use client";
@@ -22013,6 +22028,17 @@ var init_DataGrid = __esm({
22013
22028
  init_Button();
22014
22029
  init_Icon();
22015
22030
  init_InfiniteScrollSentinel();
22031
+ BADGE_VARIANTS = /* @__PURE__ */ new Set([
22032
+ "default",
22033
+ "primary",
22034
+ "secondary",
22035
+ "success",
22036
+ "warning",
22037
+ "danger",
22038
+ "error",
22039
+ "info",
22040
+ "neutral"
22041
+ ]);
22016
22042
  gapStyles6 = {
22017
22043
  none: "gap-0",
22018
22044
  sm: "gap-2",
@@ -6112,21 +6112,26 @@ var init_FloatingActionButton = __esm({
6112
6112
  init_useTranslate();
6113
6113
  exports.FloatingActionButton = ({
6114
6114
  action,
6115
+ actionPayload,
6115
6116
  actions,
6116
6117
  icon,
6117
6118
  onClick,
6118
6119
  variant,
6120
+ label,
6119
6121
  position = "bottom-right",
6120
6122
  className
6121
6123
  }) => {
6122
6124
  const eventBus = useEventBus();
6123
6125
  const { t } = useTranslate();
6124
- const resolvedAction = action ?? (icon ? {
6126
+ const resolvedAction = icon ? {
6125
6127
  icon: resolveIcon2(icon),
6126
- onClick: onClick ?? (() => {
6127
- }),
6128
+ onClick: () => {
6129
+ if (action) eventBus.emit(`UI:${action}`, actionPayload ?? {});
6130
+ onClick?.();
6131
+ },
6132
+ label,
6128
6133
  variant
6129
- } : void 0);
6134
+ } : void 0;
6130
6135
  const [isExpanded, setIsExpanded] = React110.useState(false);
6131
6136
  const fabRef = React110.useRef(null);
6132
6137
  React110.useEffect(() => {
@@ -17266,6 +17271,16 @@ function statusVariant2(value) {
17266
17271
  if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
17267
17272
  return "default";
17268
17273
  }
17274
+ function resolveBadgeVariant(field, value) {
17275
+ const fromMap = field.colorMap?.[value];
17276
+ if (fromMap) {
17277
+ const normalised = fromMap === "destructive" ? "danger" : fromMap;
17278
+ if (BADGE_VARIANTS.has(normalised)) {
17279
+ return normalised;
17280
+ }
17281
+ }
17282
+ return statusVariant2(value);
17283
+ }
17269
17284
  function formatDate2(value) {
17270
17285
  if (!value) return "";
17271
17286
  const d = new Date(String(value));
@@ -17479,7 +17494,7 @@ function DataGrid({
17479
17494
  if (val === void 0 || val === null) return null;
17480
17495
  return /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", className: "items-center", children: [
17481
17496
  field.icon && /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: field.icon, size: "xs" }),
17482
- /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: statusVariant2(String(val)), children: String(val) })
17497
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
17483
17498
  ] }, field.name);
17484
17499
  }) })
17485
17500
  ] }),
@@ -17572,7 +17587,7 @@ function DataGrid({
17572
17587
  )
17573
17588
  ] });
17574
17589
  }
17575
- var gapStyles6;
17590
+ var BADGE_VARIANTS, gapStyles6;
17576
17591
  var init_DataGrid = __esm({
17577
17592
  "components/molecules/DataGrid.tsx"() {
17578
17593
  "use client";
@@ -17587,6 +17602,17 @@ var init_DataGrid = __esm({
17587
17602
  init_Button();
17588
17603
  init_Icon();
17589
17604
  init_InfiniteScrollSentinel();
17605
+ BADGE_VARIANTS = /* @__PURE__ */ new Set([
17606
+ "default",
17607
+ "primary",
17608
+ "secondary",
17609
+ "success",
17610
+ "warning",
17611
+ "danger",
17612
+ "error",
17613
+ "info",
17614
+ "neutral"
17615
+ ]);
17590
17616
  gapStyles6 = {
17591
17617
  none: "gap-0",
17592
17618
  sm: "gap-2",
@@ -6067,21 +6067,26 @@ var init_FloatingActionButton = __esm({
6067
6067
  init_useTranslate();
6068
6068
  FloatingActionButton = ({
6069
6069
  action,
6070
+ actionPayload,
6070
6071
  actions,
6071
6072
  icon,
6072
6073
  onClick,
6073
6074
  variant,
6075
+ label,
6074
6076
  position = "bottom-right",
6075
6077
  className
6076
6078
  }) => {
6077
6079
  const eventBus = useEventBus();
6078
6080
  const { t } = useTranslate();
6079
- const resolvedAction = action ?? (icon ? {
6081
+ const resolvedAction = icon ? {
6080
6082
  icon: resolveIcon2(icon),
6081
- onClick: onClick ?? (() => {
6082
- }),
6083
+ onClick: () => {
6084
+ if (action) eventBus.emit(`UI:${action}`, actionPayload ?? {});
6085
+ onClick?.();
6086
+ },
6087
+ label,
6083
6088
  variant
6084
- } : void 0);
6089
+ } : void 0;
6085
6090
  const [isExpanded, setIsExpanded] = useState(false);
6086
6091
  const fabRef = useRef(null);
6087
6092
  useEffect(() => {
@@ -17221,6 +17226,16 @@ function statusVariant2(value) {
17221
17226
  if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
17222
17227
  return "default";
17223
17228
  }
17229
+ function resolveBadgeVariant(field, value) {
17230
+ const fromMap = field.colorMap?.[value];
17231
+ if (fromMap) {
17232
+ const normalised = fromMap === "destructive" ? "danger" : fromMap;
17233
+ if (BADGE_VARIANTS.has(normalised)) {
17234
+ return normalised;
17235
+ }
17236
+ }
17237
+ return statusVariant2(value);
17238
+ }
17224
17239
  function formatDate2(value) {
17225
17240
  if (!value) return "";
17226
17241
  const d = new Date(String(value));
@@ -17434,7 +17449,7 @@ function DataGrid({
17434
17449
  if (val === void 0 || val === null) return null;
17435
17450
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
17436
17451
  field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
17437
- /* @__PURE__ */ jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
17452
+ /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
17438
17453
  ] }, field.name);
17439
17454
  }) })
17440
17455
  ] }),
@@ -17527,7 +17542,7 @@ function DataGrid({
17527
17542
  )
17528
17543
  ] });
17529
17544
  }
17530
- var gapStyles6;
17545
+ var BADGE_VARIANTS, gapStyles6;
17531
17546
  var init_DataGrid = __esm({
17532
17547
  "components/molecules/DataGrid.tsx"() {
17533
17548
  "use client";
@@ -17542,6 +17557,17 @@ var init_DataGrid = __esm({
17542
17557
  init_Button();
17543
17558
  init_Icon();
17544
17559
  init_InfiniteScrollSentinel();
17560
+ BADGE_VARIANTS = /* @__PURE__ */ new Set([
17561
+ "default",
17562
+ "primary",
17563
+ "secondary",
17564
+ "success",
17565
+ "warning",
17566
+ "danger",
17567
+ "error",
17568
+ "info",
17569
+ "neutral"
17570
+ ]);
17545
17571
  gapStyles6 = {
17546
17572
  none: "gap-0",
17547
17573
  sm: "gap-2",
@@ -24,6 +24,16 @@ export interface DataGridField {
24
24
  variant?: 'h3' | 'h4' | 'body' | 'caption' | 'badge' | 'small' | 'progress';
25
25
  /** Optional format function name: 'date', 'currency', 'number', 'boolean' */
26
26
  format?: 'date' | 'currency' | 'number' | 'boolean' | 'percent';
27
+ /**
28
+ * Per-value color mapping for `variant: 'badge'`. Keys are exact field
29
+ * values; values are Badge variant names. Accepts the shadcn-style
30
+ * `destructive` alias and normalises it to `danger` at render time. When
31
+ * present, takes precedence over the built-in `statusVariant` heuristic.
32
+ *
33
+ * Example:
34
+ * colorMap: { active: 'success', pending: 'warning', failed: 'destructive' }
35
+ */
36
+ colorMap?: Record<string, string>;
27
37
  }
28
38
  export interface DataGridItemAction {
29
39
  /** Button label */
@@ -3,9 +3,15 @@
3
3
  *
4
4
  * A floating action button that can expand into multiple actions vertically.
5
5
  * Uses Button atom.
6
+ *
7
+ * Props mirror Button's `action`/`actionPayload` convention so a schema can
8
+ * declare `{ type: "floating-action-button", action: "INIT", icon: "plus" }`
9
+ * and have the FAB emit `UI:INIT` via the event bus on click — same shape
10
+ * any other clickable surface uses.
6
11
  */
7
12
  import React from "react";
8
13
  import type { LucideIcon } from "lucide-react";
14
+ import type { EventKey, EventPayload } from "@almadar/core";
9
15
  export interface FloatingAction {
10
16
  /**
11
17
  * Action ID
@@ -32,30 +38,38 @@ export interface FloatingAction {
32
38
  }
33
39
  export interface FloatingActionButtonProps {
34
40
  /**
35
- * Single action (if only one action, button will directly trigger onClick)
41
+ * Declarative event name. When set, clicking the FAB emits `UI:{action}`
42
+ * via the event bus and (if also provided) calls `onClick`. Mirrors the
43
+ * Button atom's `action` prop so schemas can write
44
+ * `{ type: "floating-action-button", action: "INIT" }` uniformly.
45
+ */
46
+ action?: EventKey;
47
+ /**
48
+ * Payload to include with the dispatched action event.
36
49
  */
37
- action?: {
38
- icon: LucideIcon;
39
- onClick: () => void;
40
- label?: string;
41
- variant?: "primary" | "secondary" | "success" | "danger" | "warning";
42
- };
50
+ actionPayload?: EventPayload;
43
51
  /**
44
- * Multiple actions (if provided, button will expand to show all actions)
52
+ * Multiple actions. When provided, the button expands to show all of them.
45
53
  */
46
54
  actions?: FloatingAction[];
47
55
  /**
48
- * Icon name (simplified API for pattern compatibility)
56
+ * Icon name (resolves to a Lucide icon by PascalCase / kebab-case lookup).
49
57
  */
50
58
  icon?: string;
51
59
  /**
52
- * Click handler (simplified API for pattern compatibility)
60
+ * Optional direct click handler. Runs after the action emit when both are
61
+ * present.
53
62
  */
54
63
  onClick?: () => void;
55
64
  /**
56
- * Variant (simplified API for pattern compatibility)
65
+ * Visual variant.
57
66
  */
58
67
  variant?: "primary" | "secondary" | "success" | "danger" | "warning";
68
+ /**
69
+ * Optional label shown via `aria-label` (visually hidden in single-action
70
+ * mode; rendered as a tooltip beside expanded actions in multi-action mode).
71
+ */
72
+ label?: string;
59
73
  /**
60
74
  * Button position
61
75
  * @default 'bottom-right'
@@ -7743,21 +7743,26 @@ var init_FloatingActionButton = __esm({
7743
7743
  init_useTranslate();
7744
7744
  FloatingActionButton = ({
7745
7745
  action,
7746
+ actionPayload,
7746
7747
  actions,
7747
7748
  icon,
7748
7749
  onClick,
7749
7750
  variant,
7751
+ label,
7750
7752
  position = "bottom-right",
7751
7753
  className
7752
7754
  }) => {
7753
7755
  const eventBus = useEventBus();
7754
7756
  const { t } = useTranslate();
7755
- const resolvedAction = action ?? (icon ? {
7757
+ const resolvedAction = icon ? {
7756
7758
  icon: resolveIcon2(icon),
7757
- onClick: onClick ?? (() => {
7758
- }),
7759
+ onClick: () => {
7760
+ if (action) eventBus.emit(`UI:${action}`, actionPayload ?? {});
7761
+ onClick?.();
7762
+ },
7763
+ label,
7759
7764
  variant
7760
- } : void 0);
7765
+ } : void 0;
7761
7766
  const [isExpanded, setIsExpanded] = React115.useState(false);
7762
7767
  const fabRef = React115.useRef(null);
7763
7768
  React115.useEffect(() => {
@@ -18578,6 +18583,16 @@ function statusVariant2(value) {
18578
18583
  if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
18579
18584
  return "default";
18580
18585
  }
18586
+ function resolveBadgeVariant(field, value) {
18587
+ const fromMap = field.colorMap?.[value];
18588
+ if (fromMap) {
18589
+ const normalised = fromMap === "destructive" ? "danger" : fromMap;
18590
+ if (BADGE_VARIANTS.has(normalised)) {
18591
+ return normalised;
18592
+ }
18593
+ }
18594
+ return statusVariant2(value);
18595
+ }
18581
18596
  function formatDate2(value) {
18582
18597
  if (!value) return "";
18583
18598
  const d = new Date(String(value));
@@ -18791,7 +18806,7 @@ function DataGrid({
18791
18806
  if (val === void 0 || val === null) return null;
18792
18807
  return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
18793
18808
  field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs" }),
18794
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
18809
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
18795
18810
  ] }, field.name);
18796
18811
  }) })
18797
18812
  ] }),
@@ -18884,7 +18899,7 @@ function DataGrid({
18884
18899
  )
18885
18900
  ] });
18886
18901
  }
18887
- var gapStyles6;
18902
+ var BADGE_VARIANTS, gapStyles6;
18888
18903
  var init_DataGrid = __esm({
18889
18904
  "components/molecules/DataGrid.tsx"() {
18890
18905
  "use client";
@@ -18899,6 +18914,17 @@ var init_DataGrid = __esm({
18899
18914
  init_Button();
18900
18915
  init_Icon();
18901
18916
  init_InfiniteScrollSentinel();
18917
+ BADGE_VARIANTS = /* @__PURE__ */ new Set([
18918
+ "default",
18919
+ "primary",
18920
+ "secondary",
18921
+ "success",
18922
+ "warning",
18923
+ "danger",
18924
+ "error",
18925
+ "info",
18926
+ "neutral"
18927
+ ]);
18902
18928
  gapStyles6 = {
18903
18929
  none: "gap-0",
18904
18930
  sm: "gap-2",
@@ -7698,21 +7698,26 @@ var init_FloatingActionButton = __esm({
7698
7698
  init_useTranslate();
7699
7699
  FloatingActionButton = ({
7700
7700
  action,
7701
+ actionPayload,
7701
7702
  actions,
7702
7703
  icon,
7703
7704
  onClick,
7704
7705
  variant,
7706
+ label,
7705
7707
  position = "bottom-right",
7706
7708
  className
7707
7709
  }) => {
7708
7710
  const eventBus = useEventBus();
7709
7711
  const { t } = useTranslate();
7710
- const resolvedAction = action ?? (icon ? {
7712
+ const resolvedAction = icon ? {
7711
7713
  icon: resolveIcon2(icon),
7712
- onClick: onClick ?? (() => {
7713
- }),
7714
+ onClick: () => {
7715
+ if (action) eventBus.emit(`UI:${action}`, actionPayload ?? {});
7716
+ onClick?.();
7717
+ },
7718
+ label,
7714
7719
  variant
7715
- } : void 0);
7720
+ } : void 0;
7716
7721
  const [isExpanded, setIsExpanded] = useState(false);
7717
7722
  const fabRef = useRef(null);
7718
7723
  useEffect(() => {
@@ -18533,6 +18538,16 @@ function statusVariant2(value) {
18533
18538
  if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
18534
18539
  return "default";
18535
18540
  }
18541
+ function resolveBadgeVariant(field, value) {
18542
+ const fromMap = field.colorMap?.[value];
18543
+ if (fromMap) {
18544
+ const normalised = fromMap === "destructive" ? "danger" : fromMap;
18545
+ if (BADGE_VARIANTS.has(normalised)) {
18546
+ return normalised;
18547
+ }
18548
+ }
18549
+ return statusVariant2(value);
18550
+ }
18536
18551
  function formatDate2(value) {
18537
18552
  if (!value) return "";
18538
18553
  const d = new Date(String(value));
@@ -18746,7 +18761,7 @@ function DataGrid({
18746
18761
  if (val === void 0 || val === null) return null;
18747
18762
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
18748
18763
  field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
18749
- /* @__PURE__ */ jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
18764
+ /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
18750
18765
  ] }, field.name);
18751
18766
  }) })
18752
18767
  ] }),
@@ -18839,7 +18854,7 @@ function DataGrid({
18839
18854
  )
18840
18855
  ] });
18841
18856
  }
18842
- var gapStyles6;
18857
+ var BADGE_VARIANTS, gapStyles6;
18843
18858
  var init_DataGrid = __esm({
18844
18859
  "components/molecules/DataGrid.tsx"() {
18845
18860
  "use client";
@@ -18854,6 +18869,17 @@ var init_DataGrid = __esm({
18854
18869
  init_Button();
18855
18870
  init_Icon();
18856
18871
  init_InfiniteScrollSentinel();
18872
+ BADGE_VARIANTS = /* @__PURE__ */ new Set([
18873
+ "default",
18874
+ "primary",
18875
+ "secondary",
18876
+ "success",
18877
+ "warning",
18878
+ "danger",
18879
+ "error",
18880
+ "info",
18881
+ "neutral"
18882
+ ]);
18857
18883
  gapStyles6 = {
18858
18884
  none: "gap-0",
18859
18885
  sm: "gap-2",
@@ -7894,21 +7894,26 @@ var init_FloatingActionButton = __esm({
7894
7894
  init_useTranslate();
7895
7895
  FloatingActionButton = ({
7896
7896
  action,
7897
+ actionPayload,
7897
7898
  actions,
7898
7899
  icon,
7899
7900
  onClick,
7900
7901
  variant,
7902
+ label,
7901
7903
  position = "bottom-right",
7902
7904
  className
7903
7905
  }) => {
7904
7906
  const eventBus = useEventBus();
7905
7907
  const { t } = useTranslate();
7906
- const resolvedAction = action ?? (icon ? {
7908
+ const resolvedAction = icon ? {
7907
7909
  icon: resolveIcon2(icon),
7908
- onClick: onClick ?? (() => {
7909
- }),
7910
+ onClick: () => {
7911
+ if (action) eventBus.emit(`UI:${action}`, actionPayload ?? {});
7912
+ onClick?.();
7913
+ },
7914
+ label,
7910
7915
  variant
7911
- } : void 0);
7916
+ } : void 0;
7912
7917
  const [isExpanded, setIsExpanded] = React115.useState(false);
7913
7918
  const fabRef = React115.useRef(null);
7914
7919
  React115.useEffect(() => {
@@ -18382,6 +18387,16 @@ function statusVariant2(value) {
18382
18387
  if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
18383
18388
  return "default";
18384
18389
  }
18390
+ function resolveBadgeVariant(field, value) {
18391
+ const fromMap = field.colorMap?.[value];
18392
+ if (fromMap) {
18393
+ const normalised = fromMap === "destructive" ? "danger" : fromMap;
18394
+ if (BADGE_VARIANTS.has(normalised)) {
18395
+ return normalised;
18396
+ }
18397
+ }
18398
+ return statusVariant2(value);
18399
+ }
18385
18400
  function formatDate2(value) {
18386
18401
  if (!value) return "";
18387
18402
  const d = new Date(String(value));
@@ -18595,7 +18610,7 @@ function DataGrid({
18595
18610
  if (val === void 0 || val === null) return null;
18596
18611
  return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
18597
18612
  field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs" }),
18598
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
18613
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
18599
18614
  ] }, field.name);
18600
18615
  }) })
18601
18616
  ] }),
@@ -18688,7 +18703,7 @@ function DataGrid({
18688
18703
  )
18689
18704
  ] });
18690
18705
  }
18691
- var gapStyles6;
18706
+ var BADGE_VARIANTS, gapStyles6;
18692
18707
  var init_DataGrid = __esm({
18693
18708
  "components/molecules/DataGrid.tsx"() {
18694
18709
  "use client";
@@ -18703,6 +18718,17 @@ var init_DataGrid = __esm({
18703
18718
  init_Button();
18704
18719
  init_Icon();
18705
18720
  init_InfiniteScrollSentinel();
18721
+ BADGE_VARIANTS = /* @__PURE__ */ new Set([
18722
+ "default",
18723
+ "primary",
18724
+ "secondary",
18725
+ "success",
18726
+ "warning",
18727
+ "danger",
18728
+ "error",
18729
+ "info",
18730
+ "neutral"
18731
+ ]);
18706
18732
  gapStyles6 = {
18707
18733
  none: "gap-0",
18708
18734
  sm: "gap-2",
@@ -7849,21 +7849,26 @@ var init_FloatingActionButton = __esm({
7849
7849
  init_useTranslate();
7850
7850
  FloatingActionButton = ({
7851
7851
  action,
7852
+ actionPayload,
7852
7853
  actions,
7853
7854
  icon,
7854
7855
  onClick,
7855
7856
  variant,
7857
+ label,
7856
7858
  position = "bottom-right",
7857
7859
  className
7858
7860
  }) => {
7859
7861
  const eventBus = useEventBus();
7860
7862
  const { t } = useTranslate();
7861
- const resolvedAction = action ?? (icon ? {
7863
+ const resolvedAction = icon ? {
7862
7864
  icon: resolveIcon2(icon),
7863
- onClick: onClick ?? (() => {
7864
- }),
7865
+ onClick: () => {
7866
+ if (action) eventBus.emit(`UI:${action}`, actionPayload ?? {});
7867
+ onClick?.();
7868
+ },
7869
+ label,
7865
7870
  variant
7866
- } : void 0);
7871
+ } : void 0;
7867
7872
  const [isExpanded, setIsExpanded] = useState(false);
7868
7873
  const fabRef = useRef(null);
7869
7874
  useEffect(() => {
@@ -18337,6 +18342,16 @@ function statusVariant2(value) {
18337
18342
  if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
18338
18343
  return "default";
18339
18344
  }
18345
+ function resolveBadgeVariant(field, value) {
18346
+ const fromMap = field.colorMap?.[value];
18347
+ if (fromMap) {
18348
+ const normalised = fromMap === "destructive" ? "danger" : fromMap;
18349
+ if (BADGE_VARIANTS.has(normalised)) {
18350
+ return normalised;
18351
+ }
18352
+ }
18353
+ return statusVariant2(value);
18354
+ }
18340
18355
  function formatDate2(value) {
18341
18356
  if (!value) return "";
18342
18357
  const d = new Date(String(value));
@@ -18550,7 +18565,7 @@ function DataGrid({
18550
18565
  if (val === void 0 || val === null) return null;
18551
18566
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
18552
18567
  field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
18553
- /* @__PURE__ */ jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
18568
+ /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
18554
18569
  ] }, field.name);
18555
18570
  }) })
18556
18571
  ] }),
@@ -18643,7 +18658,7 @@ function DataGrid({
18643
18658
  )
18644
18659
  ] });
18645
18660
  }
18646
- var gapStyles6;
18661
+ var BADGE_VARIANTS, gapStyles6;
18647
18662
  var init_DataGrid = __esm({
18648
18663
  "components/molecules/DataGrid.tsx"() {
18649
18664
  "use client";
@@ -18658,6 +18673,17 @@ var init_DataGrid = __esm({
18658
18673
  init_Button();
18659
18674
  init_Icon();
18660
18675
  init_InfiniteScrollSentinel();
18676
+ BADGE_VARIANTS = /* @__PURE__ */ new Set([
18677
+ "default",
18678
+ "primary",
18679
+ "secondary",
18680
+ "success",
18681
+ "warning",
18682
+ "danger",
18683
+ "error",
18684
+ "info",
18685
+ "neutral"
18686
+ ]);
18661
18687
  gapStyles6 = {
18662
18688
  none: "gap-0",
18663
18689
  sm: "gap-2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "4.1.0",
3
+ "version": "4.3.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "main": "./dist/components/index.js",