@almadar/ui 3.3.1 → 3.5.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 (61) hide show
  1. package/dist/avl/index.cjs +67 -30
  2. package/dist/avl/index.js +67 -30
  3. package/dist/components/atoms/Avatar.d.ts +3 -2
  4. package/dist/components/atoms/Box.d.ts +4 -3
  5. package/dist/components/atoms/Button.d.ts +3 -2
  6. package/dist/components/atoms/InfiniteScrollSentinel.d.ts +3 -2
  7. package/dist/components/atoms/Input.d.ts +3 -2
  8. package/dist/components/atoms/Overlay.d.ts +2 -1
  9. package/dist/components/atoms/Radio.d.ts +2 -1
  10. package/dist/components/atoms/RangeSlider.d.ts +3 -2
  11. package/dist/components/atoms/Select.d.ts +2 -1
  12. package/dist/components/atoms/Stack.d.ts +3 -2
  13. package/dist/components/atoms/TextHighlight.d.ts +3 -2
  14. package/dist/components/atoms/Textarea.d.ts +2 -1
  15. package/dist/components/atoms/game/ControlButton.d.ts +3 -2
  16. package/dist/components/atoms/game/Sprite.d.ts +2 -1
  17. package/dist/components/index.cjs +67 -27
  18. package/dist/components/index.js +67 -27
  19. package/dist/components/molecules/Alert.d.ts +2 -1
  20. package/dist/components/molecules/CalendarGrid.d.ts +2 -1
  21. package/dist/components/molecules/Card.d.ts +3 -2
  22. package/dist/components/molecules/DataGrid.d.ts +4 -3
  23. package/dist/components/molecules/DataList.d.ts +7 -6
  24. package/dist/components/molecules/Drawer.d.ts +2 -1
  25. package/dist/components/molecules/NumberStepper.d.ts +3 -2
  26. package/dist/components/molecules/PullToRefresh.d.ts +3 -2
  27. package/dist/components/molecules/SortableList.d.ts +5 -4
  28. package/dist/components/molecules/StarRating.d.ts +3 -2
  29. package/dist/components/molecules/SwipeableRow.d.ts +4 -3
  30. package/dist/components/molecules/UploadDropZone.d.ts +3 -2
  31. package/dist/components/molecules/game/DialogueBox.d.ts +3 -2
  32. package/dist/components/molecules/game/GameMenu.d.ts +4 -3
  33. package/dist/components/molecules/game/GameOverScreen.d.ts +3 -2
  34. package/dist/components/molecules/game/InventoryPanel.d.ts +3 -2
  35. package/dist/components/organisms/CardGrid.d.ts +3 -2
  36. package/dist/components/organisms/CustomPattern.d.ts +5 -4
  37. package/dist/components/organisms/DataTable.d.ts +2 -1
  38. package/dist/components/organisms/Form.d.ts +3 -2
  39. package/dist/components/organisms/GraphCanvas.d.ts +3 -2
  40. package/dist/components/organisms/List.d.ts +4 -2
  41. package/dist/components/organisms/Timeline.d.ts +2 -1
  42. package/dist/components/organisms/game/three/index.cjs +0 -3
  43. package/dist/components/organisms/game/three/index.js +0 -3
  44. package/dist/docs/index.cjs +0 -3
  45. package/dist/docs/index.d.cts +10 -9
  46. package/dist/docs/index.js +0 -3
  47. package/dist/hooks/event-bus-types.d.ts +10 -10
  48. package/dist/hooks/index.cjs +0 -3
  49. package/dist/hooks/index.js +0 -3
  50. package/dist/hooks/useDraggable.d.ts +2 -1
  51. package/dist/hooks/useEventBus.d.ts +2 -1
  52. package/dist/lib/verificationRegistry.d.ts +2 -2
  53. package/dist/marketing/index.cjs +0 -3
  54. package/dist/marketing/index.d.cts +8 -7
  55. package/dist/marketing/index.js +0 -3
  56. package/dist/providers/index.cjs +67 -30
  57. package/dist/providers/index.js +67 -30
  58. package/dist/runtime/createClientEffectHandlers.d.ts +2 -1
  59. package/dist/runtime/index.cjs +67 -27
  60. package/dist/runtime/index.js +67 -27
  61. package/package.json +3 -3
@@ -2956,9 +2956,6 @@ function EventBusProvider({ children, debug: debug2 = false }) {
2956
2956
  const emit = React126.useCallback((type, payload, source) => {
2957
2957
  const event = {
2958
2958
  type,
2959
- // Narrow at the bus boundary: public emit takes Record for ergonomics
2960
- // (generic UI components pass consumer-defined rows) while the envelope
2961
- // stores the payload as EventPayload for listeners.
2962
2959
  payload,
2963
2960
  timestamp: Date.now(),
2964
2961
  source
@@ -3131,9 +3128,6 @@ var init_useEventBus = __esm({
3131
3128
  emit: (type, payload, source) => {
3132
3129
  const event = {
3133
3130
  type,
3134
- // Narrow at the bus boundary: public emit accepts an opaque object so
3135
- // generic UI emit sites don't require casts; the envelope stores the
3136
- // payload as EventPayload which listeners consume directly.
3137
3131
  payload,
3138
3132
  timestamp: Date.now(),
3139
3133
  source
@@ -19039,7 +19033,11 @@ var init_CardGrid = __esm({
19039
19033
  return;
19040
19034
  }
19041
19035
  if (action.event) {
19042
- eventBus.emit(`UI:${action.event}`, { id: itemData.id, row: itemData });
19036
+ const payload = {
19037
+ id: itemData.id,
19038
+ row: itemData
19039
+ };
19040
+ eventBus.emit(`UI:${action.event}`, payload);
19043
19041
  }
19044
19042
  if (action.onClick) {
19045
19043
  action.onClick(itemData);
@@ -21723,7 +21721,8 @@ var init_DataGrid = __esm({
21723
21721
  if (next.has(id)) next.delete(id);
21724
21722
  else next.add(id);
21725
21723
  if (selectionEvent) {
21726
- eventBus.emit(`UI:${selectionEvent}`, { selectedIds: Array.from(next) });
21724
+ const payload = { selectedIds: Array.from(next) };
21725
+ eventBus.emit(`UI:${selectionEvent}`, payload);
21727
21726
  }
21728
21727
  return next;
21729
21728
  });
@@ -21734,7 +21733,8 @@ var init_DataGrid = __esm({
21734
21733
  const allSelected2 = allIds2.length > 0 && allIds2.every((id) => prev.has(id));
21735
21734
  const next = allSelected2 ? /* @__PURE__ */ new Set() : new Set(allIds2);
21736
21735
  if (selectionEvent) {
21737
- eventBus.emit(`UI:${selectionEvent}`, { selectedIds: Array.from(next) });
21736
+ const payload = { selectedIds: Array.from(next) };
21737
+ eventBus.emit(`UI:${selectionEvent}`, payload);
21738
21738
  }
21739
21739
  return next;
21740
21740
  });
@@ -21746,7 +21746,11 @@ var init_DataGrid = __esm({
21746
21746
  const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
21747
21747
  const handleActionClick = (action, itemData) => (e) => {
21748
21748
  e.stopPropagation();
21749
- eventBus.emit(`UI:${action.event}`, { id: itemData.id, row: itemData });
21749
+ const payload = {
21750
+ id: itemData.id,
21751
+ row: itemData
21752
+ };
21753
+ eventBus.emit(`UI:${action.event}`, payload);
21750
21754
  };
21751
21755
  const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
21752
21756
  const colsClass = cols ? {
@@ -22074,7 +22078,11 @@ var init_DataList = __esm({
22074
22078
  );
22075
22079
  const handleActionClick = (action, itemData) => (e) => {
22076
22080
  e.stopPropagation();
22077
- eventBus.emit(`UI:${action.event}`, { id: itemData.id, row: itemData });
22081
+ const payload = {
22082
+ id: itemData.id,
22083
+ row: itemData
22084
+ };
22085
+ eventBus.emit(`UI:${action.event}`, payload);
22078
22086
  };
22079
22087
  if (isLoading) {
22080
22088
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
@@ -30458,7 +30466,8 @@ var init_DetailPanel = __esm({
30458
30466
  return;
30459
30467
  }
30460
30468
  if (action.event) {
30461
- eventBus.emit(`UI:${action.event}`, { id: data2?.id, row: data2 });
30469
+ const payload = data2 ? { id: data2.id, row: data2 } : {};
30470
+ eventBus.emit(`UI:${action.event}`, payload);
30462
30471
  }
30463
30472
  if (action.onClick) {
30464
30473
  action.onClick();
@@ -31900,9 +31909,10 @@ var init_Form = __esm({
31900
31909
  };
31901
31910
  const handleSubmit = (e) => {
31902
31911
  e.preventDefault();
31903
- eventBus.emit(`UI:${submitEvent}`, { data: formData });
31912
+ const payload = { data: formData };
31913
+ eventBus.emit(`UI:${submitEvent}`, payload);
31904
31914
  if (onSubmit) {
31905
- eventBus.emit(`UI:${onSubmit}`, { data: formData });
31915
+ eventBus.emit(`UI:${onSubmit}`, payload);
31906
31916
  }
31907
31917
  };
31908
31918
  const handleCancel = () => {
@@ -33270,6 +33280,31 @@ function normalizeFields2(fields) {
33270
33280
  if (!fields) return [];
33271
33281
  return fields.map((f3) => typeof f3 === "string" ? f3 : f3.key ?? f3.name ?? "");
33272
33282
  }
33283
+ function entityFieldsFromListItem(item) {
33284
+ const {
33285
+ icon: _icon,
33286
+ metadata: _metadata,
33287
+ onClick: _onClick,
33288
+ avatar: _avatar,
33289
+ _fields,
33290
+ ...rest
33291
+ } = item;
33292
+ const result = {};
33293
+ for (const [key, value] of Object.entries(rest)) {
33294
+ if (typeof value === "function" || value !== null && typeof value === "object" && "$$typeof" in value) {
33295
+ continue;
33296
+ }
33297
+ result[key] = value;
33298
+ }
33299
+ if (_fields && typeof _fields === "object") {
33300
+ for (const [k, v] of Object.entries(_fields)) {
33301
+ if (typeof v !== "function") {
33302
+ result[k] = v;
33303
+ }
33304
+ }
33305
+ }
33306
+ return result;
33307
+ }
33273
33308
  function getStatusStyle(fieldName, value) {
33274
33309
  const val = String(value).toLowerCase();
33275
33310
  if (val.includes("complete") || val.includes("done"))
@@ -33473,18 +33508,17 @@ var init_List = __esm({
33473
33508
  label: action.label,
33474
33509
  event: action.event,
33475
33510
  onClick: () => {
33511
+ const row = entityFieldsFromListItem(item);
33476
33512
  if (action.navigatesTo) {
33477
33513
  const url = action.navigatesTo.replace(
33478
33514
  /\{\{(\w+)\}\}/g,
33479
- (_, key) => String(item[key] || item.id || "")
33515
+ (_, key) => String(row[key] ?? item.id ?? "")
33480
33516
  );
33481
- eventBus.emit("UI:NAVIGATE", { url, row: item });
33517
+ eventBus.emit("UI:NAVIGATE", { url, row });
33482
33518
  return;
33483
33519
  }
33484
33520
  if (action.event) {
33485
- eventBus.emit(`UI:${action.event}`, {
33486
- row: item
33487
- });
33521
+ eventBus.emit(`UI:${action.event}`, { row });
33488
33522
  }
33489
33523
  }
33490
33524
  }));
@@ -33564,7 +33598,7 @@ var init_List = __esm({
33564
33598
  );
33565
33599
  const hasExplicitClick = !!(viewAction?.event || item.onClick);
33566
33600
  const rowAction = viewAction?.event ?? "VIEW";
33567
- const rowActionPayload = { row: item };
33601
+ const rowActionPayload = { row: entityFieldsFromListItem(item) };
33568
33602
  const primaryField = effectiveFieldNames?.[0];
33569
33603
  const statusField = effectiveFieldNames?.find(
33570
33604
  (f3) => f3.toLowerCase().includes("status")
@@ -39418,16 +39452,19 @@ var init_Timeline = __esm({
39418
39452
  ] }),
39419
39453
  item.description && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
39420
39454
  item.tags && item.tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", wrap: true, children: item.tags.map((tag, tagIdx) => /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", children: tag }, tagIdx)) }),
39421
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "mt-1", children: itemActions.map((action, actionIdx) => /* @__PURE__ */ jsxRuntime.jsx(
39422
- Box,
39423
- {
39424
- action: action.event,
39425
- actionPayload: { row: item },
39426
- className: "cursor-pointer hover:opacity-80 transition-opacity",
39427
- children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", children: action.label })
39428
- },
39429
- actionIdx
39430
- )) })
39455
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "mt-1", children: itemActions.map((action, actionIdx) => {
39456
+ const { icon: _icon, ...rowSafe } = item;
39457
+ return /* @__PURE__ */ jsxRuntime.jsx(
39458
+ Box,
39459
+ {
39460
+ action: action.event,
39461
+ actionPayload: { row: rowSafe },
39462
+ className: "cursor-pointer hover:opacity-80 transition-opacity",
39463
+ children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", children: action.label })
39464
+ },
39465
+ actionIdx
39466
+ );
39467
+ }) })
39431
39468
  ] })
39432
39469
  ] }, item.id);
39433
39470
  }) })
package/dist/avl/index.js CHANGED
@@ -2910,9 +2910,6 @@ function EventBusProvider({ children, debug: debug2 = false }) {
2910
2910
  const emit = useCallback((type, payload, source) => {
2911
2911
  const event = {
2912
2912
  type,
2913
- // Narrow at the bus boundary: public emit takes Record for ergonomics
2914
- // (generic UI components pass consumer-defined rows) while the envelope
2915
- // stores the payload as EventPayload for listeners.
2916
2913
  payload,
2917
2914
  timestamp: Date.now(),
2918
2915
  source
@@ -3085,9 +3082,6 @@ var init_useEventBus = __esm({
3085
3082
  emit: (type, payload, source) => {
3086
3083
  const event = {
3087
3084
  type,
3088
- // Narrow at the bus boundary: public emit accepts an opaque object so
3089
- // generic UI emit sites don't require casts; the envelope stores the
3090
- // payload as EventPayload which listeners consume directly.
3091
3085
  payload,
3092
3086
  timestamp: Date.now(),
3093
3087
  source
@@ -18993,7 +18987,11 @@ var init_CardGrid = __esm({
18993
18987
  return;
18994
18988
  }
18995
18989
  if (action.event) {
18996
- eventBus.emit(`UI:${action.event}`, { id: itemData.id, row: itemData });
18990
+ const payload = {
18991
+ id: itemData.id,
18992
+ row: itemData
18993
+ };
18994
+ eventBus.emit(`UI:${action.event}`, payload);
18997
18995
  }
18998
18996
  if (action.onClick) {
18999
18997
  action.onClick(itemData);
@@ -21677,7 +21675,8 @@ var init_DataGrid = __esm({
21677
21675
  if (next.has(id)) next.delete(id);
21678
21676
  else next.add(id);
21679
21677
  if (selectionEvent) {
21680
- eventBus.emit(`UI:${selectionEvent}`, { selectedIds: Array.from(next) });
21678
+ const payload = { selectedIds: Array.from(next) };
21679
+ eventBus.emit(`UI:${selectionEvent}`, payload);
21681
21680
  }
21682
21681
  return next;
21683
21682
  });
@@ -21688,7 +21687,8 @@ var init_DataGrid = __esm({
21688
21687
  const allSelected2 = allIds2.length > 0 && allIds2.every((id) => prev.has(id));
21689
21688
  const next = allSelected2 ? /* @__PURE__ */ new Set() : new Set(allIds2);
21690
21689
  if (selectionEvent) {
21691
- eventBus.emit(`UI:${selectionEvent}`, { selectedIds: Array.from(next) });
21690
+ const payload = { selectedIds: Array.from(next) };
21691
+ eventBus.emit(`UI:${selectionEvent}`, payload);
21692
21692
  }
21693
21693
  return next;
21694
21694
  });
@@ -21700,7 +21700,11 @@ var init_DataGrid = __esm({
21700
21700
  const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
21701
21701
  const handleActionClick = (action, itemData) => (e) => {
21702
21702
  e.stopPropagation();
21703
- eventBus.emit(`UI:${action.event}`, { id: itemData.id, row: itemData });
21703
+ const payload = {
21704
+ id: itemData.id,
21705
+ row: itemData
21706
+ };
21707
+ eventBus.emit(`UI:${action.event}`, payload);
21704
21708
  };
21705
21709
  const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
21706
21710
  const colsClass = cols ? {
@@ -22028,7 +22032,11 @@ var init_DataList = __esm({
22028
22032
  );
22029
22033
  const handleActionClick = (action, itemData) => (e) => {
22030
22034
  e.stopPropagation();
22031
- eventBus.emit(`UI:${action.event}`, { id: itemData.id, row: itemData });
22035
+ const payload = {
22036
+ id: itemData.id,
22037
+ row: itemData
22038
+ };
22039
+ eventBus.emit(`UI:${action.event}`, payload);
22032
22040
  };
22033
22041
  if (isLoading) {
22034
22042
  return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
@@ -30412,7 +30420,8 @@ var init_DetailPanel = __esm({
30412
30420
  return;
30413
30421
  }
30414
30422
  if (action.event) {
30415
- eventBus.emit(`UI:${action.event}`, { id: data2?.id, row: data2 });
30423
+ const payload = data2 ? { id: data2.id, row: data2 } : {};
30424
+ eventBus.emit(`UI:${action.event}`, payload);
30416
30425
  }
30417
30426
  if (action.onClick) {
30418
30427
  action.onClick();
@@ -31854,9 +31863,10 @@ var init_Form = __esm({
31854
31863
  };
31855
31864
  const handleSubmit = (e) => {
31856
31865
  e.preventDefault();
31857
- eventBus.emit(`UI:${submitEvent}`, { data: formData });
31866
+ const payload = { data: formData };
31867
+ eventBus.emit(`UI:${submitEvent}`, payload);
31858
31868
  if (onSubmit) {
31859
- eventBus.emit(`UI:${onSubmit}`, { data: formData });
31869
+ eventBus.emit(`UI:${onSubmit}`, payload);
31860
31870
  }
31861
31871
  };
31862
31872
  const handleCancel = () => {
@@ -33224,6 +33234,31 @@ function normalizeFields2(fields) {
33224
33234
  if (!fields) return [];
33225
33235
  return fields.map((f3) => typeof f3 === "string" ? f3 : f3.key ?? f3.name ?? "");
33226
33236
  }
33237
+ function entityFieldsFromListItem(item) {
33238
+ const {
33239
+ icon: _icon,
33240
+ metadata: _metadata,
33241
+ onClick: _onClick,
33242
+ avatar: _avatar,
33243
+ _fields,
33244
+ ...rest
33245
+ } = item;
33246
+ const result = {};
33247
+ for (const [key, value] of Object.entries(rest)) {
33248
+ if (typeof value === "function" || value !== null && typeof value === "object" && "$$typeof" in value) {
33249
+ continue;
33250
+ }
33251
+ result[key] = value;
33252
+ }
33253
+ if (_fields && typeof _fields === "object") {
33254
+ for (const [k, v] of Object.entries(_fields)) {
33255
+ if (typeof v !== "function") {
33256
+ result[k] = v;
33257
+ }
33258
+ }
33259
+ }
33260
+ return result;
33261
+ }
33227
33262
  function getStatusStyle(fieldName, value) {
33228
33263
  const val = String(value).toLowerCase();
33229
33264
  if (val.includes("complete") || val.includes("done"))
@@ -33427,18 +33462,17 @@ var init_List = __esm({
33427
33462
  label: action.label,
33428
33463
  event: action.event,
33429
33464
  onClick: () => {
33465
+ const row = entityFieldsFromListItem(item);
33430
33466
  if (action.navigatesTo) {
33431
33467
  const url = action.navigatesTo.replace(
33432
33468
  /\{\{(\w+)\}\}/g,
33433
- (_, key) => String(item[key] || item.id || "")
33469
+ (_, key) => String(row[key] ?? item.id ?? "")
33434
33470
  );
33435
- eventBus.emit("UI:NAVIGATE", { url, row: item });
33471
+ eventBus.emit("UI:NAVIGATE", { url, row });
33436
33472
  return;
33437
33473
  }
33438
33474
  if (action.event) {
33439
- eventBus.emit(`UI:${action.event}`, {
33440
- row: item
33441
- });
33475
+ eventBus.emit(`UI:${action.event}`, { row });
33442
33476
  }
33443
33477
  }
33444
33478
  }));
@@ -33518,7 +33552,7 @@ var init_List = __esm({
33518
33552
  );
33519
33553
  const hasExplicitClick = !!(viewAction?.event || item.onClick);
33520
33554
  const rowAction = viewAction?.event ?? "VIEW";
33521
- const rowActionPayload = { row: item };
33555
+ const rowActionPayload = { row: entityFieldsFromListItem(item) };
33522
33556
  const primaryField = effectiveFieldNames?.[0];
33523
33557
  const statusField = effectiveFieldNames?.find(
33524
33558
  (f3) => f3.toLowerCase().includes("status")
@@ -39372,16 +39406,19 @@ var init_Timeline = __esm({
39372
39406
  ] }),
39373
39407
  item.description && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
39374
39408
  item.tags && item.tags.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", wrap: true, children: item.tags.map((tag, tagIdx) => /* @__PURE__ */ jsx(Badge, { variant: "default", children: tag }, tagIdx)) }),
39375
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "mt-1", children: itemActions.map((action, actionIdx) => /* @__PURE__ */ jsx(
39376
- Box,
39377
- {
39378
- action: action.event,
39379
- actionPayload: { row: item },
39380
- className: "cursor-pointer hover:opacity-80 transition-opacity",
39381
- children: /* @__PURE__ */ jsx(Badge, { variant: "default", children: action.label })
39382
- },
39383
- actionIdx
39384
- )) })
39409
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "mt-1", children: itemActions.map((action, actionIdx) => {
39410
+ const { icon: _icon, ...rowSafe } = item;
39411
+ return /* @__PURE__ */ jsx(
39412
+ Box,
39413
+ {
39414
+ action: action.event,
39415
+ actionPayload: { row: rowSafe },
39416
+ className: "cursor-pointer hover:opacity-80 transition-opacity",
39417
+ children: /* @__PURE__ */ jsx(Badge, { variant: "default", children: action.label })
39418
+ },
39419
+ actionIdx
39420
+ );
39421
+ }) })
39385
39422
  ] })
39386
39423
  ] }, item.id);
39387
39424
  }) })
@@ -4,6 +4,7 @@
4
4
  * A versatile avatar component supporting images, initials, icons, and status indicators.
5
5
  */
6
6
  import React from "react";
7
+ import type { EventKey, EventPayload } from "@almadar/core";
7
8
  import type { LucideIcon } from "lucide-react";
8
9
  export type AvatarSize = "xs" | "sm" | "md" | "lg" | "xl";
9
10
  export type AvatarStatus = "online" | "offline" | "away" | "busy";
@@ -51,8 +52,8 @@ export interface AvatarProps {
51
52
  */
52
53
  onClick?: () => void;
53
54
  /** Declarative event name — emits UI:{action} via eventBus on click */
54
- action?: string;
55
+ action?: EventKey;
55
56
  /** Payload to include with the action event */
56
- actionPayload?: Record<string, unknown>;
57
+ actionPayload?: EventPayload;
57
58
  }
58
59
  export declare const Avatar: React.FC<AvatarProps>;
@@ -5,6 +5,7 @@
5
5
  * Think of it as a styled div with consistent design tokens.
6
6
  */
7
7
  import React from "react";
8
+ import type { EventKey, EventPayload } from "@almadar/core";
8
9
  export type BoxPadding = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
9
10
  export type BoxMargin = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "auto";
10
11
  export type BoxBg = "transparent" | "primary" | "secondary" | "muted" | "accent" | "surface" | "overlay";
@@ -44,11 +45,11 @@ export interface BoxProps extends React.HTMLAttributes<HTMLDivElement> {
44
45
  /** HTML element to render as */
45
46
  as?: React.ElementType;
46
47
  /** Declarative event name — emits UI:{action} via eventBus on click */
47
- action?: string;
48
+ action?: EventKey;
48
49
  /** Payload to include with the action event */
49
- actionPayload?: Record<string, unknown>;
50
+ actionPayload?: EventPayload;
50
51
  /** Declarative hover event — emits UI:{hoverEvent} with { hovered: true/false } on mouseEnter/mouseLeave */
51
- hoverEvent?: string;
52
+ hoverEvent?: EventKey;
52
53
  /** Maximum width (CSS value, e.g., "550px", "80rem") */
53
54
  maxWidth?: string;
54
55
  /** Children elements */
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import type { EventKey, EventPayload } from "@almadar/core";
2
3
  import { type LucideIcon } from "lucide-react";
3
4
  export type ButtonVariant = "primary" | "secondary" | "ghost" | "danger" | "success" | "warning" | "default";
4
5
  export type ButtonSize = "sm" | "md" | "lg";
@@ -15,9 +16,9 @@ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElemen
15
16
  /** Alias for rightIcon */
16
17
  iconRight?: React.ReactNode | LucideIcon | string;
17
18
  /** Declarative event name — emits UI:{action} via eventBus on click */
18
- action?: string;
19
+ action?: EventKey;
19
20
  /** Payload to include with the action event */
20
- actionPayload?: Record<string, unknown>;
21
+ actionPayload?: EventPayload;
21
22
  /** Button label text (alternative to children for schema-driven rendering) */
22
23
  label?: string;
23
24
  }
@@ -6,11 +6,12 @@
6
6
  * then fires a load-more event through the event bus.
7
7
  */
8
8
  import React from "react";
9
+ import type { EventKey, EventPayload } from "@almadar/core";
9
10
  export interface InfiniteScrollSentinelProps {
10
11
  /** Event name to emit when load-more is triggered (emitted as UI:{loadMoreEvent}) */
11
- loadMoreEvent: string;
12
+ loadMoreEvent: EventKey;
12
13
  /** Optional payload to include with the load-more event */
13
- loadMorePayload?: Record<string, unknown>;
14
+ loadMorePayload?: EventPayload;
14
15
  /** Whether a load operation is currently in progress */
15
16
  isLoading?: boolean;
16
17
  /** Whether there are more items to load */
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import type { EventKey } from "@almadar/core";
2
3
  import { type LucideIcon } from "lucide-react";
3
4
  export interface SelectOption {
4
5
  value: string;
@@ -12,7 +13,7 @@ export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElem
12
13
  /** Whether input is disabled */
13
14
  disabled?: boolean;
14
15
  /** Declarative event name for trait dispatch */
15
- action?: string;
16
+ action?: EventKey;
16
17
  /** Input type - supports 'select' and 'textarea' in addition to standard types */
17
18
  inputType?: "text" | "email" | "password" | "number" | "tel" | "url" | "search" | "date" | "datetime-local" | "time" | "checkbox" | "select" | "textarea";
18
19
  error?: string;
@@ -31,4 +32,4 @@ export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElem
31
32
  /** onChange handler - accepts events from input, select, or textarea */
32
33
  onChange?: React.ChangeEventHandler<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>;
33
34
  }
34
- export declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>>;
35
+ export declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>>;
@@ -4,13 +4,14 @@
4
4
  * A fixed backdrop for modals and drawers.
5
5
  */
6
6
  import React from "react";
7
+ import type { EventKey } from "@almadar/core";
7
8
  export interface OverlayProps {
8
9
  isVisible?: boolean;
9
10
  onClick?: (e: React.MouseEvent) => void;
10
11
  className?: string;
11
12
  blur?: boolean;
12
13
  /** Declarative event name — emits UI:{action} via eventBus on click */
13
- action?: string;
14
+ action?: EventKey;
14
15
  }
15
16
  export declare const Overlay: React.FC<OverlayProps>;
16
17
  export default Overlay;
@@ -4,13 +4,14 @@
4
4
  * A radio button component with label support and accessibility.
5
5
  */
6
6
  import React from "react";
7
+ import type { EventKey } from "@almadar/core";
7
8
  export interface RadioProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "size"> {
8
9
  /** Radio options (string array or SelectOption array) */
9
10
  options?: string[];
10
11
  /** Current selected value */
11
12
  value?: string;
12
13
  /** Declarative event name for trait dispatch */
13
- action?: string;
14
+ action?: EventKey;
14
15
  /**
15
16
  * Label text displayed next to the radio button
16
17
  */
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import type { EventKey, EventPayload } from "@almadar/core";
2
3
  export type RangeSliderSize = "sm" | "md" | "lg";
3
4
  export interface RangeSliderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {
4
5
  /** Minimum value */
@@ -20,9 +21,9 @@ export interface RangeSliderProps extends Omit<React.HTMLAttributes<HTMLDivEleme
20
21
  /** Disabled state */
21
22
  disabled?: boolean;
22
23
  /** Declarative event name for value changes */
23
- action?: string;
24
+ action?: EventKey;
24
25
  /** Payload to include with the action event */
25
- actionPayload?: Record<string, unknown>;
26
+ actionPayload?: EventPayload;
26
27
  /** Direct onChange callback */
27
28
  onChange?: (value: number) => void;
28
29
  /** Format function for tooltip display */
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import type { EventKey } from "@almadar/core";
2
3
  export interface SelectOption {
3
4
  value: string;
4
5
  label: string;
@@ -12,7 +13,7 @@ export interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectE
12
13
  /** Current value */
13
14
  value?: string;
14
15
  /** Declarative event name for trait dispatch */
15
- action?: string;
16
+ action?: EventKey;
16
17
  /** Error message */
17
18
  error?: string;
18
19
  }
@@ -5,6 +5,7 @@
5
5
  * Includes convenience exports VStack and HStack for common use cases.
6
6
  */
7
7
  import React from "react";
8
+ import type { EventKey, EventPayload } from "@almadar/core";
8
9
  export type StackDirection = "horizontal" | "vertical";
9
10
  export type StackGap = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
10
11
  export type StackAlign = "start" | "center" | "end" | "stretch" | "baseline";
@@ -41,9 +42,9 @@ export interface StackProps {
41
42
  /** Tab index for focus management */
42
43
  tabIndex?: number;
43
44
  /** Declarative event name — emits UI:{action} via eventBus on click */
44
- action?: string;
45
+ action?: EventKey;
45
46
  /** Payload to include with the action event */
46
- actionPayload?: Record<string, unknown>;
47
+ actionPayload?: EventPayload;
47
48
  /** When true, horizontal stacks flip to vertical below the md breakpoint (768px) */
48
49
  responsive?: boolean;
49
50
  }
@@ -7,6 +7,7 @@
7
7
  * - Notes: Yellow highlight
8
8
  */
9
9
  import React from "react";
10
+ import type { EventKey } from "@almadar/core";
10
11
  export type HighlightType = "question" | "note";
11
12
  export interface TextHighlightProps {
12
13
  /**
@@ -43,9 +44,9 @@ export interface TextHighlightProps {
43
44
  */
44
45
  children: React.ReactNode;
45
46
  /** Declarative event name — emits UI:{action} via eventBus on click */
46
- action?: string;
47
+ action?: EventKey;
47
48
  /** Declarative hover event — emits UI:{hoverEvent} with { hovered: true/false } */
48
- hoverEvent?: string;
49
+ hoverEvent?: EventKey;
49
50
  }
50
51
  /**
51
52
  * TextHighlight component for rendering highlighted text annotations
@@ -1,11 +1,12 @@
1
1
  import React from "react";
2
+ import type { EventKey } from "@almadar/core";
2
3
  export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
3
4
  /** Placeholder text */
4
5
  placeholder?: string;
5
6
  /** Number of visible rows */
6
7
  rows?: number;
7
8
  /** Declarative event name for trait dispatch */
8
- action?: string;
9
+ action?: EventKey;
9
10
  /** Error message */
10
11
  error?: string;
11
12
  }
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import type { EventKey } from "@almadar/core";
2
3
  export interface ControlButtonProps {
3
4
  /** Button label text */
4
5
  label?: string;
@@ -15,9 +16,9 @@ export interface ControlButtonProps {
15
16
  /** Called when button is released */
16
17
  onRelease?: () => void;
17
18
  /** Declarative event name emitted on press via useEventBus */
18
- pressEvent?: string;
19
+ pressEvent?: EventKey;
19
20
  /** Declarative event name emitted on release via useEventBus */
20
- releaseEvent?: string;
21
+ releaseEvent?: EventKey;
21
22
  /** Whether the button is currently pressed */
22
23
  pressed?: boolean;
23
24
  /** Whether the button is disabled */
@@ -4,6 +4,7 @@
4
4
  * Renders a single frame from a spritesheet with transform support.
5
5
  */
6
6
  import React from 'react';
7
+ import type { EventKey } from "@almadar/core";
7
8
  export interface SpriteProps {
8
9
  /** Spritesheet image URL */
9
10
  spritesheet: string;
@@ -36,7 +37,7 @@ export interface SpriteProps {
36
37
  /** Optional onClick handler */
37
38
  onClick?: () => void;
38
39
  /** Declarative event name emitted on click via useEventBus */
39
- action?: string;
40
+ action?: EventKey;
40
41
  }
41
42
  /**
42
43
  * Sprite component for rendering spritesheet frames