@almadar/ui 5.12.1 → 5.13.3

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.
@@ -6260,7 +6260,7 @@ var init_Modal = __esm({
6260
6260
  document.body.style.overflow = "";
6261
6261
  };
6262
6262
  }, [isOpen]);
6263
- if (!isOpen) return null;
6263
+ if (!isOpen || typeof document === "undefined") return null;
6264
6264
  const handleClose = () => {
6265
6265
  if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
6266
6266
  onClose();
@@ -6270,124 +6270,127 @@ var init_Modal = __esm({
6270
6270
  handleClose();
6271
6271
  }
6272
6272
  };
6273
- return /* @__PURE__ */ jsxs(Fragment, { children: [
6274
- /* @__PURE__ */ jsx(
6275
- Overlay,
6276
- {
6277
- isVisible: isOpen,
6278
- onClick: handleOverlayClick,
6279
- className: "z-40"
6280
- }
6281
- ),
6282
- /* @__PURE__ */ jsx(
6283
- Box,
6284
- {
6285
- className: cn(
6286
- "fixed inset-0 z-50 pointer-events-none",
6287
- "flex items-start justify-center px-4 pb-4 pt-[10vh]",
6288
- "max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
6289
- ),
6290
- children: /* @__PURE__ */ jsxs(
6291
- Dialog,
6292
- {
6293
- ref: modalRef,
6294
- open: true,
6295
- className: cn(
6296
- // Reset browser-default dialog chrome — we own styling. `static`
6297
- // overrides the user-agent `position: absolute` so the parent
6298
- // flex container's `justify-center` actually centers the dialog
6299
- // (without this, the dialog drops out of flex flow and `m-0`
6300
- // kills the user-agent's `margin: auto` centering, pinning the
6301
- // dialog to top-left).
6302
- "static m-0 p-0 border-0 bg-transparent",
6303
- // Pre-existing dialog frame
6304
- "pointer-events-auto w-full flex flex-col bg-surface border shadow-elevation-dialog rounded-container",
6305
- // Desktop sizing + viewport-aware floor.
6306
- sizeClasses5[size],
6307
- minWidthClasses[size],
6308
- "max-h-[80vh]",
6309
- // Mobile: take the entire screen. Override desktop max-w cap,
6310
- // full height, no rounded corners, no min-width.
6311
- "max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
6312
- lookStyles2[look],
6313
- className
6314
- ),
6315
- style: dragY > 0 ? {
6316
- transform: `translateY(${dragY}px)`,
6317
- transition: isDragging.current ? "none" : "transform 200ms ease-out"
6318
- } : void 0,
6319
- ...title && { "aria-labelledby": "modal-title" },
6320
- children: [
6321
- /* @__PURE__ */ jsx(
6322
- Box,
6323
- {
6324
- className: "hidden max-sm:flex justify-center py-2 cursor-grab active:cursor-grabbing touch-none",
6325
- onPointerDown: (e) => {
6326
- if (!swipeDownToClose) return;
6327
- dragStartY.current = e.clientY;
6328
- isDragging.current = true;
6329
- e.target.setPointerCapture(e.pointerId);
6330
- },
6331
- onPointerMove: (e) => {
6332
- if (!isDragging.current) return;
6333
- const dy = Math.max(0, e.clientY - dragStartY.current);
6334
- setDragY(dy);
6335
- },
6336
- onPointerUp: () => {
6337
- if (!isDragging.current) return;
6338
- isDragging.current = false;
6339
- if (dragY > 100) {
6340
- handleClose();
6341
- }
6342
- setDragY(0);
6343
- },
6344
- onPointerCancel: () => {
6345
- isDragging.current = false;
6346
- setDragY(0);
6347
- },
6348
- children: /* @__PURE__ */ jsx(Box, { className: "w-10 h-1 rounded-full bg-border" })
6349
- }
6273
+ return createPortal(
6274
+ /* @__PURE__ */ jsxs(Fragment, { children: [
6275
+ /* @__PURE__ */ jsx(
6276
+ Overlay,
6277
+ {
6278
+ isVisible: isOpen,
6279
+ onClick: handleOverlayClick,
6280
+ className: "z-[1000]"
6281
+ }
6282
+ ),
6283
+ /* @__PURE__ */ jsx(
6284
+ Box,
6285
+ {
6286
+ className: cn(
6287
+ "fixed inset-0 z-[1001] pointer-events-none",
6288
+ "flex items-start justify-center px-4 pb-4 pt-[10vh]",
6289
+ "max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
6290
+ ),
6291
+ children: /* @__PURE__ */ jsxs(
6292
+ Dialog,
6293
+ {
6294
+ ref: modalRef,
6295
+ open: true,
6296
+ className: cn(
6297
+ // Reset browser-default dialog chrome we own styling. `static`
6298
+ // overrides the user-agent `position: absolute` so the parent
6299
+ // flex container's `justify-center` actually centers the dialog
6300
+ // (without this, the dialog drops out of flex flow and `m-0`
6301
+ // kills the user-agent's `margin: auto` centering, pinning the
6302
+ // dialog to top-left).
6303
+ "static m-0 p-0 border-0 bg-transparent",
6304
+ // Pre-existing dialog frame
6305
+ "pointer-events-auto w-full flex flex-col bg-surface border shadow-elevation-dialog rounded-container",
6306
+ // Desktop sizing + viewport-aware floor.
6307
+ sizeClasses5[size],
6308
+ minWidthClasses[size],
6309
+ "max-h-[80vh]",
6310
+ // Mobile: take the entire screen. Override desktop max-w cap,
6311
+ // full height, no rounded corners, no min-width.
6312
+ "max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
6313
+ lookStyles2[look],
6314
+ className
6350
6315
  ),
6351
- (title || showCloseButton) && /* @__PURE__ */ jsxs(
6352
- Box,
6353
- {
6354
- className: cn(
6355
- "px-6 py-4 flex items-center justify-between",
6356
- "border-b-[length:var(--border-width)] border-border"
6357
- ),
6358
- children: [
6359
- title && /* @__PURE__ */ jsx(Typography, { variant: "h4", as: "h2", id: "modal-title", children: title }),
6360
- showCloseButton && /* @__PURE__ */ jsx(
6361
- Button,
6362
- {
6363
- variant: "ghost",
6364
- size: "sm",
6365
- icon: "x",
6366
- onClick: handleClose,
6367
- "data-event": "CLOSE",
6368
- "aria-label": "Close modal"
6316
+ style: dragY > 0 ? {
6317
+ transform: `translateY(${dragY}px)`,
6318
+ transition: isDragging.current ? "none" : "transform 200ms ease-out"
6319
+ } : void 0,
6320
+ ...title && { "aria-labelledby": "modal-title" },
6321
+ children: [
6322
+ /* @__PURE__ */ jsx(
6323
+ Box,
6324
+ {
6325
+ className: "hidden max-sm:flex justify-center py-2 cursor-grab active:cursor-grabbing touch-none",
6326
+ onPointerDown: (e) => {
6327
+ if (!swipeDownToClose) return;
6328
+ dragStartY.current = e.clientY;
6329
+ isDragging.current = true;
6330
+ e.target.setPointerCapture(e.pointerId);
6331
+ },
6332
+ onPointerMove: (e) => {
6333
+ if (!isDragging.current) return;
6334
+ const dy = Math.max(0, e.clientY - dragStartY.current);
6335
+ setDragY(dy);
6336
+ },
6337
+ onPointerUp: () => {
6338
+ if (!isDragging.current) return;
6339
+ isDragging.current = false;
6340
+ if (dragY > 100) {
6341
+ handleClose();
6369
6342
  }
6370
- )
6371
- ]
6372
- }
6373
- ),
6374
- /* @__PURE__ */ jsx(Box, { className: "flex-1 overflow-y-auto p-6", children }),
6375
- footer && /* @__PURE__ */ jsx(
6376
- Box,
6377
- {
6378
- className: cn(
6379
- "px-6 py-4 bg-muted",
6380
- "border-t-[length:var(--border-width)] border-border"
6381
- ),
6382
- children: footer
6383
- }
6384
- )
6385
- ]
6386
- }
6387
- )
6388
- }
6389
- )
6390
- ] });
6343
+ setDragY(0);
6344
+ },
6345
+ onPointerCancel: () => {
6346
+ isDragging.current = false;
6347
+ setDragY(0);
6348
+ },
6349
+ children: /* @__PURE__ */ jsx(Box, { className: "w-10 h-1 rounded-full bg-border" })
6350
+ }
6351
+ ),
6352
+ (title || showCloseButton) && /* @__PURE__ */ jsxs(
6353
+ Box,
6354
+ {
6355
+ className: cn(
6356
+ "px-6 py-4 flex items-center justify-between",
6357
+ "border-b-[length:var(--border-width)] border-border"
6358
+ ),
6359
+ children: [
6360
+ title && /* @__PURE__ */ jsx(Typography, { variant: "h4", as: "h2", id: "modal-title", children: title }),
6361
+ showCloseButton && /* @__PURE__ */ jsx(
6362
+ Button,
6363
+ {
6364
+ variant: "ghost",
6365
+ size: "sm",
6366
+ icon: "x",
6367
+ onClick: handleClose,
6368
+ "data-event": "CLOSE",
6369
+ "aria-label": "Close modal"
6370
+ }
6371
+ )
6372
+ ]
6373
+ }
6374
+ ),
6375
+ /* @__PURE__ */ jsx(Box, { className: "flex-1 overflow-y-auto p-6", children }),
6376
+ footer && /* @__PURE__ */ jsx(
6377
+ Box,
6378
+ {
6379
+ className: cn(
6380
+ "px-6 py-4 bg-muted",
6381
+ "border-t-[length:var(--border-width)] border-border"
6382
+ ),
6383
+ children: footer
6384
+ }
6385
+ )
6386
+ ]
6387
+ }
6388
+ )
6389
+ }
6390
+ )
6391
+ ] }),
6392
+ document.body
6393
+ );
6391
6394
  };
6392
6395
  Modal.displayName = "Modal";
6393
6396
  }
@@ -12439,7 +12442,7 @@ var init_CodeBlock = __esm({
12439
12442
  };
12440
12443
  };
12441
12444
  }, [errorLines]);
12442
- const isFoldable = foldableProp ?? (language === "orb" || language === "json");
12445
+ const isFoldable = foldableProp ?? true;
12443
12446
  const [collapsed, setCollapsed] = useState(() => /* @__PURE__ */ new Set());
12444
12447
  const foldRegions = useMemo(
12445
12448
  () => isFoldable ? computeFoldRegions(code) : [],
@@ -16378,6 +16381,7 @@ function CalendarGrid({
16378
16381
  swipeRightEvent,
16379
16382
  dayWindow = "auto"
16380
16383
  }) {
16384
+ const evs = Array.isArray(events2) ? events2 : events2 ? [events2] : [];
16381
16385
  const eventBus = useEventBus();
16382
16386
  const longPressTimer = useRef(null);
16383
16387
  const resolvedWeekStart = useMemo(
@@ -16426,7 +16430,7 @@ function CalendarGrid({
16426
16430
  [onEventClick]
16427
16431
  );
16428
16432
  const eventsForDayCount = useCallback(
16429
- (day) => events2.filter(
16433
+ (day) => evs.filter(
16430
16434
  (ev) => new Date(ev.startTime).toDateString() === day.toDateString()
16431
16435
  ).length,
16432
16436
  [events2]
@@ -16541,7 +16545,7 @@ function CalendarGrid({
16541
16545
  }
16542
16546
  ) }),
16543
16547
  visibleDays.map((day) => {
16544
- const slotEvents = events2.filter(
16548
+ const slotEvents = evs.filter(
16545
16549
  (ev) => eventInSlot(ev, day, time)
16546
16550
  );
16547
16551
  const isToday = day.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
@@ -29289,7 +29293,7 @@ function useSafeEventBus10() {
29289
29293
  }
29290
29294
  }
29291
29295
  function SortableListInner({
29292
- items: initialItems = EMPTY_ITEMS,
29296
+ items: initialItemsProp = EMPTY_ITEMS,
29293
29297
  renderItem,
29294
29298
  reorderEvent,
29295
29299
  reorderPayload,
@@ -29297,6 +29301,7 @@ function SortableListInner({
29297
29301
  className
29298
29302
  }) {
29299
29303
  const eventBus = useSafeEventBus10();
29304
+ const initialItems = Array.isArray(initialItemsProp) ? initialItemsProp : initialItemsProp ? [initialItemsProp] : [];
29300
29305
  const handleReorder = useCallback(
29301
29306
  (fromIndex, toIndex, item) => {
29302
29307
  eventBus.emit(`UI:${reorderEvent}`, {
@@ -32793,9 +32798,10 @@ var init_ReplyTree = __esm({
32793
32798
  showActions = true,
32794
32799
  className
32795
32800
  }) => {
32801
+ const nodeList = Array.isArray(nodes) ? nodes : nodes ? [nodes] : [];
32796
32802
  const [collapsedSet, setCollapsedSet] = useState(() => {
32797
32803
  const acc = /* @__PURE__ */ new Set();
32798
- collectInitiallyCollapsed(nodes, acc);
32804
+ collectInitiallyCollapsed(nodeList, acc);
32799
32805
  return acc;
32800
32806
  });
32801
32807
  const toggleCollapse = useCallback((id) => {
@@ -32809,10 +32815,10 @@ var init_ReplyTree = __esm({
32809
32815
  return next;
32810
32816
  });
32811
32817
  }, []);
32812
- if (nodes.length === 0) {
32818
+ if (nodeList.length === 0) {
32813
32819
  return /* @__PURE__ */ jsx(Box, { className: cn("text-sm text-muted-foreground", className), children: "No replies yet." });
32814
32820
  }
32815
- return /* @__PURE__ */ jsx(Box, { className: cn("flex flex-col gap-2 min-w-0", className), children: nodes.map((node) => /* @__PURE__ */ jsx(
32821
+ return /* @__PURE__ */ jsx(Box, { className: cn("flex flex-col gap-2 min-w-0", className), children: nodeList.map((node) => /* @__PURE__ */ jsx(
32816
32822
  ReplyTreeNode,
32817
32823
  {
32818
32824
  node,
@@ -6,7 +6,7 @@
6
6
  * Composes DayCell and TimeSlotCell atoms into a 7-day grid.
7
7
  */
8
8
  import React from "react";
9
- import type { EventEmit, EventPayload } from "@almadar/core";
9
+ import type { EventEmit, EventPayload, EntityCollection } from "@almadar/core";
10
10
  export interface CalendarEvent {
11
11
  id: string;
12
12
  title: string;
@@ -26,7 +26,7 @@ export interface CalendarGridProps {
26
26
  /** Time slot labels (defaults to 09:00-17:00) */
27
27
  timeSlots?: string[];
28
28
  /** Events to display on the grid */
29
- events?: CalendarEvent[];
29
+ events?: EntityCollection<CalendarEvent>;
30
30
  /** Called when a time slot is clicked */
31
31
  onSlotClick?: (day: Date, time: string) => void;
32
32
  /** Called when a day header is clicked */
@@ -11,7 +11,7 @@
11
11
  * Uses atoms only internally: Box, VStack, HStack, Typography, Badge, Button, Icon.
12
12
  */
13
13
  import React from 'react';
14
- import type { EntityRow, EventKey } from '@almadar/core';
14
+ import type { EntityRow, EventKey, EntityCollection } from '@almadar/core';
15
15
  import { type DataDndProps } from './useDataDnd';
16
16
  export interface DataGridField {
17
17
  /** Entity field name (dot-notation supported) */
@@ -54,8 +54,14 @@ export interface DataGridProps<T extends EntityRow = EntityRow> extends DataDndP
54
54
  * without widening. The generic `T` lets consumers pass a narrower
55
55
  * entity (e.g. `CartItem`) and have the `children` render function
56
56
  * receive cards typed to that exact shape.
57
+ *
58
+ * Declared as the pattern's data INLET via `EntityCollection<T>` (the inlet
59
+ * half of the circuit, symmetric with the `EventKey` outlet props below):
60
+ * pattern-sync tags it `kind:"entity", cardinality:"collection"` so consumers
61
+ * bind the domain entity without name-matching the prop. Structurally still
62
+ * `T | readonly T[]` — see the brand's doc.
57
63
  */
58
- entity: T | readonly T[];
64
+ entity: EntityCollection<T>;
59
65
  /**
60
66
  * Field definitions for rendering each card. The pattern contract in
61
67
  * `@almadar/patterns` documents `columns` as the wire-format alias the
@@ -11,7 +11,7 @@
11
11
  * Uses atoms only internally: Box, VStack, HStack, Typography, Badge, Button, Icon.
12
12
  */
13
13
  import React from 'react';
14
- import type { EntityRow, EventKey } from "@almadar/core";
14
+ import type { EntityRow, EntityCollection, EventKey } from "@almadar/core";
15
15
  import { type DataDndProps } from './useDataDnd';
16
16
  export interface DataListField {
17
17
  /** Entity field name (dot-notation supported) */
@@ -45,7 +45,7 @@ export interface DataListProps<T extends EntityRow = EntityRow> extends DataDndP
45
45
  * entity (e.g. `CartItem`) and have the `children` render function
46
46
  * receive items of that exact shape.
47
47
  */
48
- entity: T | readonly T[];
48
+ entity: EntityCollection<T>;
49
49
  /**
50
50
  * Field definitions for rendering each row. The pattern contract in
51
51
  * `@almadar/patterns` documents `columns` as the wire-format alias the
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import type { EventEmit, EventPayloadValue } from "@almadar/core";
2
+ import type { EventEmit, EntityCollection } from "@almadar/core";
3
3
  export type CanvasItemStatus = 'empty' | 'seated' | 'ordered' | 'awaiting-bill' | 'cleaning';
4
4
  export type CanvasItemShape = 'round' | 'rectangle' | 'square';
5
5
  export interface CanvasItem {
@@ -20,7 +20,7 @@ export interface PositionedCanvasProps {
20
20
  * molecule narrows non-array values to `[]` and validates element shape at
21
21
  * render time via the `id` / `x` / `y` guards.
22
22
  */
23
- items: readonly CanvasItem[] | EventPayloadValue;
23
+ items: EntityCollection<CanvasItem>;
24
24
  width?: number;
25
25
  height?: number;
26
26
  selectedId?: string | null;
@@ -5,7 +5,7 @@
5
5
  * Composes the VoteStack molecule + Avatar/Typography/Button atoms.
6
6
  */
7
7
  import React from "react";
8
- import type { EventEmit } from "@almadar/core";
8
+ import type { EventEmit, EntityCollection } from "@almadar/core";
9
9
  import { type VoteValue } from "../molecules/VoteStack";
10
10
  export interface ReplyNode {
11
11
  id: string;
@@ -19,7 +19,7 @@ export interface ReplyNode {
19
19
  collapsed?: boolean;
20
20
  }
21
21
  export interface ReplyTreeProps {
22
- nodes: ReplyNode[];
22
+ nodes: EntityCollection<ReplyNode>;
23
23
  maxDepth?: number;
24
24
  onVote?: (nodeId: string, vote: VoteValue) => void;
25
25
  onReply?: (parentNodeId: string) => void;
@@ -6,9 +6,9 @@
6
6
  * Shows a drop indicator line at the target position during drag.
7
7
  */
8
8
  import React from 'react';
9
- import type { EventKey, EventPayload, EventPayloadValue } from "@almadar/core";
9
+ import type { EntityCollection, EventKey, EventPayload, EventPayloadValue } from "@almadar/core";
10
10
  export interface SortableListProps<T extends EventPayloadValue = EventPayload> {
11
- items: T[];
11
+ items: EntityCollection<T>;
12
12
  renderItem: (item: T, index: number) => React.ReactNode;
13
13
  reorderEvent: EventKey;
14
14
  reorderPayload?: EventPayload;
@@ -12,7 +12,7 @@
12
12
  * Icon, Checkbox, Divider.
13
13
  */
14
14
  import React from 'react';
15
- import type { EntityRow, EventKey } from '@almadar/core';
15
+ import type { EntityRow, EventKey, EntityCollection } from '@almadar/core';
16
16
  import { type DataDndProps } from './useDataDnd';
17
17
  export interface TableViewColumn {
18
18
  /** Stable column key (React key + default value lookup). */
@@ -52,7 +52,7 @@ export interface TableViewItemAction {
52
52
  }
53
53
  export interface TableViewProps<T extends EntityRow = EntityRow> extends DataDndProps {
54
54
  /** Schema entity data — single record or collection. */
55
- entity: T | readonly T[];
55
+ entity: EntityCollection<T>;
56
56
  /** Column definitions. The compiler emits `columns`; `fields` is the alias. */
57
57
  columns?: readonly TableViewColumn[];
58
58
  /** Alias for `columns`. */
@@ -19,7 +19,7 @@ export interface CodeBlockProps {
19
19
  showLanguageBadge?: boolean;
20
20
  /** Maximum height before scrolling */
21
21
  maxHeight?: string;
22
- /** Enable JSON-style code folding (default: true for json/orb) */
22
+ /** Enable brace-based code folding of multi-line `{}`/`[]` blocks (default: true). */
23
23
  foldable?: boolean;
24
24
  /** Additional CSS classes */
25
25
  className?: string;
@@ -7,6 +7,7 @@
7
7
  * See EntityDisplayProps in ./types.ts for base prop contract.
8
8
  */
9
9
  import React from "react";
10
+ import type { EntityRecord, EntityRow } from "@almadar/core";
10
11
  import type { LucideIcon } from "lucide-react";
11
12
  import type { EntityDisplayProps } from "./types";
12
13
  export interface DetailField {
@@ -44,6 +45,8 @@ export type FieldDef = string | {
44
45
  type: string;
45
46
  };
46
47
  export interface DetailPanelProps extends EntityDisplayProps {
48
+ /** RECORD-cardinality override: renders ONE record (see body collapse below). */
49
+ entity?: EntityRecord<EntityRow>;
47
50
  title?: string;
48
51
  subtitle?: string;
49
52
  status?: {
@@ -10,9 +10,11 @@
10
10
  * - Never listens to events
11
11
  */
12
12
  import React from 'react';
13
+ import type { EntityRecord } from '@almadar/core';
13
14
  import type { EntityDisplayProps } from './types';
14
15
  import type { HeroEntity } from './marketing-types';
15
16
  export interface HeroOrganismProps extends EntityDisplayProps<HeroEntity> {
17
+ entity?: EntityRecord<HeroEntity>;
16
18
  children?: React.ReactNode;
17
19
  }
18
20
  export declare const HeroOrganism: React.FC<HeroOrganismProps>;
@@ -12,7 +12,7 @@
12
12
  */
13
13
  import React from "react";
14
14
  import type { EventKey } from "@almadar/core";
15
- import type { EntityRow } from "@almadar/core";
15
+ import type { EntityCollection, EntityRow } from "@almadar/core";
16
16
  import type { LucideIcon } from "lucide-react";
17
17
  export type TimelineItemStatus = "complete" | "active" | "pending" | "error";
18
18
  /**
@@ -55,7 +55,7 @@ export interface TimelineProps {
55
55
  * TimelineItem fields (`icon`, callbacks) cannot round-trip through the
56
56
  * event bus, so decorative stories that need them pass `items` directly.
57
57
  */
58
- entity?: EntityRow | readonly EntityRow[];
58
+ entity?: EntityCollection<EntityRow>;
59
59
  /** Timeline title */
60
60
  title?: string;
61
61
  /** Timeline items */
@@ -17,9 +17,12 @@
17
17
  * - Listens: UI:BOOK_START, UI:BOOK_NAVIGATE, UI:BOOK_PAGE_PREV/NEXT, UI:BOOK_PRINT, UI:BOOK_SHOW_TOC
18
18
  */
19
19
  import React from 'react';
20
+ import type { EntityRecord, EntityRow } from '@almadar/core';
20
21
  import type { EntityDisplayProps } from '../types';
21
22
  import type { BookFieldMap } from './types';
22
23
  export interface BookViewerProps extends EntityDisplayProps {
24
+ /** Renders ONE record (the book), not a collection */
25
+ entity?: EntityRecord<EntityRow>;
23
26
  /** Initial page index (default: 0 = cover) */
24
27
  initialPage?: number;
25
28
  /** Field name translation map — a BookFieldMap object or locale key ("ar") */
@@ -7,7 +7,7 @@
7
7
  * Exception: Form manages local `formData` state for field input tracking.
8
8
  * This is the ONE allowed exception — documented here.
9
9
  */
10
- import type { EntityRow } from '@almadar/core';
10
+ import type { EntityRow, EntityInlet } from '@almadar/core';
11
11
  export declare const EntityDisplayEvents: {
12
12
  readonly SORT: "SORT";
13
13
  readonly PAGINATE: "PAGINATE";
@@ -61,7 +61,7 @@ export interface EntityDisplayProps<T extends EntityRow = EntityRow> {
61
61
  * extend `EntityRow`. They surface `EntityDisplayProps<T>` constraint errors.
62
62
  * Tracked as a Phase 7 follow-up in `docs/Almadar_Entity_V2_Plan.md` §10.
63
63
  */
64
- entity?: T | readonly T[];
64
+ entity?: EntityInlet<T>;
65
65
  /** Additional CSS classes */
66
66
  className?: string;
67
67
  /** Loading state indicator */
@@ -318,7 +318,7 @@ interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "
318
318
  /** onChange handler - accepts events from input, select, or textarea */
319
319
  onChange?: React.ChangeEventHandler<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>;
320
320
  }
321
- declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>>;
321
+ declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLSelectElement | HTMLInputElement | HTMLTextAreaElement>>;
322
322
 
323
323
  /**
324
324
  * DocSidebar Molecule Component