@almadar/ui 4.34.0 → 4.35.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.
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ export interface BranchingQuestion {
3
+ id: string;
4
+ label: string;
5
+ optionValues?: string[];
6
+ }
7
+ export type BranchingOperator = 'equals' | 'not-equals' | 'contains' | 'in';
8
+ export declare const END_OF_SURVEY = "end-of-survey";
9
+ export interface BranchingRule {
10
+ id: string;
11
+ sourceQuestionId: string;
12
+ operator: BranchingOperator;
13
+ value: string | string[];
14
+ targetQuestionId: string | typeof END_OF_SURVEY;
15
+ }
16
+ export interface BranchingLogicBuilderProps {
17
+ questions: BranchingQuestion[];
18
+ rules: BranchingRule[];
19
+ onRulesChange?: (rules: BranchingRule[]) => void;
20
+ readOnly?: boolean;
21
+ className?: string;
22
+ }
23
+ export declare const BranchingLogicBuilder: React.FC<BranchingLogicBuilderProps>;
@@ -0,0 +1,29 @@
1
+ import React from "react";
2
+ export type LikertScaleSize = "sm" | "md" | "lg";
3
+ export type LikertScaleVariant = "radios" | "buttons";
4
+ export interface LikertOption {
5
+ /** Underlying value bound to the option */
6
+ value: number | string;
7
+ /** Visible label below (radios) or inside (buttons) the control */
8
+ label: string;
9
+ }
10
+ export interface LikertScaleProps {
11
+ /** Optional row prompt above the scale */
12
+ question?: string;
13
+ /** Scale points (defaults to a 5-point agree/disagree set) */
14
+ options?: LikertOption[];
15
+ /** Selected value (controlled) */
16
+ value?: number | string | null;
17
+ /** Change callback */
18
+ onChange?: (value: number | string) => void;
19
+ /** Disabled state */
20
+ disabled?: boolean;
21
+ /** Size variant */
22
+ size?: LikertScaleSize;
23
+ /** Visual variant: classic radios or pill segmented buttons */
24
+ variant?: LikertScaleVariant;
25
+ /** Additional CSS classes */
26
+ className?: string;
27
+ }
28
+ export declare const DEFAULT_LIKERT_OPTIONS: LikertOption[];
29
+ export declare const LikertScale: React.ForwardRefExoticComponent<LikertScaleProps & React.RefAttributes<HTMLDivElement>>;
@@ -11,9 +11,31 @@ export interface MapMarkerData {
11
11
  /** Optional category for styling */
12
12
  category?: string;
13
13
  }
14
+ export interface MapRouteWaypoint {
15
+ lat: number;
16
+ lng: number;
17
+ }
18
+ export interface MapRouteData {
19
+ /** Unique route identifier */
20
+ id: string | number;
21
+ /** Ordered waypoints rendered as a polyline */
22
+ waypoints: MapRouteWaypoint[];
23
+ /** Stroke color (CSS color). Defaults to a theme-aware accent. */
24
+ color?: string;
25
+ /** Stroke weight in pixels (default 4) */
26
+ weight?: number;
27
+ /** Stroke opacity 0..1 (default 0.8) */
28
+ opacity?: number;
29
+ /** Optional dashed pattern (e.g. "8 4") */
30
+ dashArray?: string;
31
+ /** Label shown in a popup at the midpoint */
32
+ label?: string;
33
+ }
14
34
  export interface MapViewProps {
15
35
  /** Array of markers to display */
16
36
  markers?: MapMarkerData[];
37
+ /** Routes (polylines with optional popups) drawn over the tile layer */
38
+ routes?: MapRouteData[];
17
39
  /** Map center latitude */
18
40
  centerLat?: number;
19
41
  /** Map center longitude */
@@ -0,0 +1,29 @@
1
+ import React from "react";
2
+ export interface MatrixRow {
3
+ id: string;
4
+ label: string;
5
+ }
6
+ export interface MatrixColumn {
7
+ value: number | string;
8
+ label: string;
9
+ }
10
+ export interface MatrixQuestionProps {
11
+ /** Optional title rendered above the matrix */
12
+ title?: string;
13
+ /** Question rows */
14
+ rows: MatrixRow[];
15
+ /** Column definitions; defaults to 5-point Likert */
16
+ columns?: MatrixColumn[];
17
+ /** Selected value per row, keyed by rowId */
18
+ values?: Record<string, number | string>;
19
+ /** Change handler invoked with rowId and selected column value */
20
+ onChange?: (rowId: string, value: number | string) => void;
21
+ /** Disable all inputs */
22
+ disabled?: boolean;
23
+ /** Visual size */
24
+ size?: 'sm' | 'md';
25
+ /** Additional CSS classes */
26
+ className?: string;
27
+ }
28
+ export declare const DEFAULT_MATRIX_COLUMNS: MatrixColumn[];
29
+ export declare const MatrixQuestion: React.FC<MatrixQuestionProps>;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * OptionConstraintGroup Molecule Component
3
+ *
4
+ * Generic constrained option selector (radio for "single", checkbox for "multi") with required/optional/multi
5
+ * constraints. Renders radio inputs for `single` constraint and checkboxes for
6
+ * `multi`. Reports validation errors inline when the current selection
7
+ * violates the constraint.
8
+ *
9
+ * **Atomic Design**: Composed using Typography atom and native form controls.
10
+ */
11
+ import React from 'react';
12
+ export interface OptionConstraintOption {
13
+ id: string;
14
+ label: string;
15
+ priceDelta?: number;
16
+ disabled?: boolean;
17
+ outOfStock?: boolean;
18
+ }
19
+ export type OptionConstraint = {
20
+ type: 'single';
21
+ required?: boolean;
22
+ } | {
23
+ type: 'multi';
24
+ min?: number;
25
+ max?: number;
26
+ };
27
+ export interface OptionConstraintGroupProps {
28
+ groupId: string;
29
+ title: string;
30
+ description?: string;
31
+ options: OptionConstraintOption[];
32
+ constraint: OptionConstraint;
33
+ selected?: string[];
34
+ onChange?: (selected: string[]) => void;
35
+ size?: 'sm' | 'md';
36
+ className?: string;
37
+ }
38
+ export declare const OptionConstraintGroup: React.FC<OptionConstraintGroupProps>;
@@ -0,0 +1,32 @@
1
+ import React from "react";
2
+ import type { EventPayloadValue } from "@almadar/core";
3
+ export type CanvasItemStatus = 'empty' | 'seated' | 'ordered' | 'awaiting-bill' | 'cleaning';
4
+ export type CanvasItemShape = 'round' | 'rectangle' | 'square';
5
+ export interface CanvasItem {
6
+ id: string;
7
+ label: string;
8
+ x: number;
9
+ y: number;
10
+ shape?: CanvasItemShape;
11
+ capacity: number;
12
+ status?: CanvasItemStatus;
13
+ partySize?: number;
14
+ serverName?: string;
15
+ }
16
+ export interface PositionedCanvasProps {
17
+ /**
18
+ * Items to render. Accepts either a typed array (direct consumers) or the
19
+ * runtime payload shape from a render-ui binding (`@payload.data`). The
20
+ * molecule narrows non-array values to `[]` and validates element shape at
21
+ * render time via the `id` / `x` / `y` guards.
22
+ */
23
+ items: readonly CanvasItem[] | EventPayloadValue;
24
+ width?: number;
25
+ height?: number;
26
+ selectedId?: string | null;
27
+ editable?: boolean;
28
+ onSelect?: (id: string | null) => void;
29
+ onMove?: (id: string, x: number, y: number) => void;
30
+ className?: string;
31
+ }
32
+ export declare const PositionedCanvas: React.FC<PositionedCanvasProps>;
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ export interface QrScanResult {
3
+ text: string;
4
+ format: string;
5
+ timestamp: number;
6
+ }
7
+ export interface QrScannerProps {
8
+ onScan?: (result: QrScanResult) => void;
9
+ onError?: (error: Error) => void;
10
+ facingMode?: 'environment' | 'user';
11
+ paused?: boolean;
12
+ showOverlay?: boolean;
13
+ showCameraControls?: boolean;
14
+ fallback?: React.ReactNode;
15
+ className?: string;
16
+ }
17
+ export declare const QrScanner: React.FC<QrScannerProps>;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * ReplyTree Organism Component
3
+ *
4
+ * Recursive nested-thread reply renderer with collapse, per-node mod actions, and vote.
5
+ * Composes the VoteStack molecule + Avatar/Typography/Button atoms.
6
+ */
7
+ import React from "react";
8
+ export interface ReplyNode {
9
+ id: string;
10
+ authorName: string;
11
+ authorAvatarUrl?: string;
12
+ content: string;
13
+ postedAt: string;
14
+ voteCount?: number;
15
+ userVote?: 'up' | 'down' | null;
16
+ replies?: ReplyNode[];
17
+ collapsed?: boolean;
18
+ }
19
+ export interface ReplyTreeProps {
20
+ nodes: ReplyNode[];
21
+ maxDepth?: number;
22
+ onVote?: (nodeId: string, vote: 'up' | 'down' | null) => void;
23
+ onReply?: (parentNodeId: string) => void;
24
+ onFlag?: (nodeId: string) => void;
25
+ onContinueThread?: (nodeId: string) => void;
26
+ showActions?: boolean;
27
+ className?: string;
28
+ }
29
+ export declare const ReplyTree: React.FC<ReplyTreeProps>;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * RichBlockEditor Organism Component
3
+ *
4
+ * Notion / Lexical-style block authoring editor. Internal state owns the
5
+ * block tree; contentEditable spans flow updates back through onInput.
6
+ *
7
+ * TODO(phase-11): collaboration / undo-redo / markdown export are out of
8
+ * scope for the Phase 10 scaffold.
9
+ */
10
+ import React from "react";
11
+ export type BlockType = "paragraph" | "heading-1" | "heading-2" | "heading-3" | "bullet-list" | "numbered-list" | "quote" | "code" | "divider" | "image";
12
+ export interface RichBlock {
13
+ id: string;
14
+ type: BlockType;
15
+ content?: string;
16
+ metadata?: Record<string, string | number | boolean>;
17
+ children?: RichBlock[];
18
+ }
19
+ export interface RichBlockEditorProps {
20
+ initialBlocks?: RichBlock[];
21
+ onChange?: (blocks: RichBlock[]) => void;
22
+ readOnly?: boolean;
23
+ placeholder?: string;
24
+ showToolbar?: boolean;
25
+ className?: string;
26
+ }
27
+ export declare const RichBlockEditor: React.FC<RichBlockEditorProps>;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * VersionDiff Organism Component
3
+ *
4
+ * Side-by-side or inline diff render with line-level highlights and
5
+ * a revision picker. Composes atoms for layout. Computes a minimal
6
+ * LCS-based line diff inline (no external diff library).
7
+ */
8
+ import React from "react";
9
+ export interface DiffRevision {
10
+ id: string;
11
+ label: string;
12
+ author?: string;
13
+ timestamp?: string;
14
+ content: string;
15
+ }
16
+ export type DiffLineType = "added" | "removed" | "unchanged" | "context";
17
+ export interface DiffLine {
18
+ type: DiffLineType;
19
+ beforeLineNumber?: number;
20
+ afterLineNumber?: number;
21
+ content: string;
22
+ }
23
+ export type VersionDiffView = "side-by-side" | "inline";
24
+ export interface VersionDiffProps {
25
+ /** All available revisions (at least 2). */
26
+ revisions: DiffRevision[];
27
+ /** Currently selected "before" revision id. */
28
+ beforeId?: string;
29
+ /** Currently selected "after" revision id. */
30
+ afterId?: string;
31
+ /** Display mode. */
32
+ view?: VersionDiffView;
33
+ /** Called when the user picks a different "before" revision. */
34
+ onSelectBefore?: (id: string) => void;
35
+ /** Called when the user picks a different "after" revision. */
36
+ onSelectAfter?: (id: string) => void;
37
+ /** Called when the user clicks the revert button (passes the "before" id). */
38
+ onRevert?: (id: string) => void;
39
+ /** Language label (informational). */
40
+ language?: string;
41
+ /** Additional CSS classes. */
42
+ className?: string;
43
+ }
44
+ export declare const VersionDiff: React.FC<VersionDiffProps>;
@@ -0,0 +1,23 @@
1
+ import React from "react";
2
+ export type VoteStackSize = "sm" | "md" | "lg";
3
+ export type VoteStackVariant = "vertical" | "horizontal";
4
+ export type VoteValue = "up" | "down" | null;
5
+ export interface VoteStackProps {
6
+ /** Current tally */
7
+ count: number;
8
+ /** Current user's vote (null = no vote cast) */
9
+ userVote?: VoteValue;
10
+ /** Toggle handler. Clicking the same arrow clears (emits null). */
11
+ onVote?: (next: VoteValue) => void;
12
+ /** Disabled state */
13
+ disabled?: boolean;
14
+ /** Size variant */
15
+ size?: VoteStackSize;
16
+ /** Layout orientation. `vertical` = forum/Q&A column; `horizontal` = compact row. */
17
+ variant?: VoteStackVariant;
18
+ /** Additional CSS classes */
19
+ className?: string;
20
+ /** Accessible label for the group */
21
+ label?: string;
22
+ }
23
+ export declare const VoteStack: React.FC<VoteStackProps>;
@@ -45,7 +45,7 @@ export { LineChart, type LineChartProps, type ChartDataPoint } from './LineChart
45
45
  export { ProgressDots, type ProgressDotsProps, type DotState, type DotSize } from './ProgressDots';
46
46
  export * from './game';
47
47
  export { GraphView, type GraphViewProps, type GraphViewNode, type GraphViewEdge } from './GraphView';
48
- export { MapView, type MapViewProps, type MapMarkerData } from './MapView';
48
+ export { MapView, type MapViewProps, type MapMarkerData, type MapRouteData, type MapRouteWaypoint } from './MapView';
49
49
  export { NumberStepper, type NumberStepperProps, type NumberStepperSize } from './NumberStepper';
50
50
  export { StarRating, type StarRatingProps, type StarRatingSize, type StarRatingPrecision } from './StarRating';
51
51
  export { UploadDropZone, type UploadDropZoneProps } from './UploadDropZone';
@@ -79,3 +79,13 @@ export { TeamCard, type TeamCardProps } from './TeamCard';
79
79
  export { ShowcaseCard, type ShowcaseCardProps } from './ShowcaseCard';
80
80
  export { GeometricPattern, type GeometricPatternProps } from './GeometricPattern';
81
81
  export { EdgeDecoration, type EdgeDecorationProps, type EdgeVariant, type EdgeSide } from './EdgeDecoration';
82
+ export { VoteStack, type VoteStackProps } from './VoteStack';
83
+ export { LikertScale, type LikertScaleProps, type LikertOption, DEFAULT_LIKERT_OPTIONS } from './LikertScale';
84
+ export { MatrixQuestion, type MatrixQuestionProps, type MatrixRow, type MatrixColumn, DEFAULT_MATRIX_COLUMNS } from './MatrixQuestion';
85
+ export { QrScanner, type QrScannerProps, type QrScanResult } from './QrScanner';
86
+ export { OptionConstraintGroup, type OptionConstraintGroupProps, type OptionConstraintOption, type OptionConstraint } from './OptionConstraintGroup';
87
+ export { PositionedCanvas, type PositionedCanvasProps, type CanvasItem, type CanvasItemStatus, type CanvasItemShape } from './PositionedCanvas';
88
+ export { RichBlockEditor, type RichBlockEditorProps, type RichBlock, type BlockType } from './RichBlockEditor';
89
+ export { ReplyTree, type ReplyTreeProps, type ReplyNode } from './ReplyTree';
90
+ export { BranchingLogicBuilder, type BranchingLogicBuilderProps, type BranchingQuestion, type BranchingRule } from './BranchingLogicBuilder';
91
+ export { VersionDiff, type VersionDiffProps, type DiffRevision, type DiffLine as VersionDiffLine, type DiffLineType } from './VersionDiff';
@@ -88,6 +88,13 @@ export interface DashboardLayoutProps {
88
88
  /** Custom sidebar footer (optional). When omitted, the sidebar has
89
89
  * no footer — apps that need Settings/etc. add them via navItems. */
90
90
  sidebarFooter?: React.ReactNode;
91
+ /** Active path used to highlight the matching nav item. Falls back
92
+ * to `useCurrentPagePath()` (set by `CurrentPagePathProvider`), then
93
+ * to `useLocation().pathname`. Production deploys can omit it; the
94
+ * studio preview passes the in-frame `?page=` value so highlighting
95
+ * works inside the embedded playground where `pathname` would be
96
+ * the studio route. */
97
+ currentPath?: string;
91
98
  /** Callback when user clicks sign out (optional - uses auth context signOut if not provided) */
92
99
  onSignOut?: () => void;
93
100
  /** Page content rendered inside the main area */
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ declare const CurrentPagePathContext: React.Context<string | undefined>;
3
+ export interface CurrentPagePathProviderProps {
4
+ value: string | undefined;
5
+ children: React.ReactNode;
6
+ }
7
+ export declare const CurrentPagePathProvider: React.FC<CurrentPagePathProviderProps>;
8
+ export declare const useCurrentPagePath: () => string | undefined;
9
+ export { CurrentPagePathContext };
@@ -675,6 +675,13 @@ function useDesignTheme() {
675
675
  availableThemes: availableThemes.map((t) => t.name)
676
676
  };
677
677
  }
678
+ var CurrentPagePathContext = react.createContext(void 0);
679
+ var CurrentPagePathProvider = ({
680
+ value,
681
+ children
682
+ }) => /* @__PURE__ */ jsxRuntime.jsx(CurrentPagePathContext.Provider, { value, children });
683
+ CurrentPagePathProvider.displayName = "CurrentPagePathProvider";
684
+ var useCurrentPagePath = () => react.useContext(CurrentPagePathContext);
678
685
  var ANONYMOUS_USER = {
679
686
  id: "anonymous",
680
687
  role: "anonymous",
@@ -776,6 +783,8 @@ function useUserForEvaluation() {
776
783
 
777
784
  exports.ANONYMOUS_USER = ANONYMOUS_USER;
778
785
  exports.BUILT_IN_THEMES = BUILT_IN_THEMES;
786
+ exports.CurrentPagePathContext = CurrentPagePathContext;
787
+ exports.CurrentPagePathProvider = CurrentPagePathProvider;
779
788
  exports.DesignThemeProvider = DesignThemeProvider;
780
789
  exports.ThemeContext = ThemeContext_default;
781
790
  exports.ThemeProvider = ThemeProvider;
@@ -783,6 +792,7 @@ exports.UISlotContext = UISlotContext;
783
792
  exports.UISlotProvider = UISlotProvider;
784
793
  exports.UserContext = UserContext;
785
794
  exports.UserProvider = UserProvider;
795
+ exports.useCurrentPagePath = useCurrentPagePath;
786
796
  exports.useDesignTheme = useDesignTheme;
787
797
  exports.useHasPermission = useHasPermission;
788
798
  exports.useHasRole = useHasRole;
@@ -5,4 +5,5 @@ export { UISlotProvider, useUISlots, useSlotContent, useSlotHasContent, UISlotCo
5
5
  export { ThemeProvider, useTheme, BUILT_IN_THEMES, type ThemeDefinition, type ThemeProviderProps, type ColorMode, type ResolvedMode, type DesignTheme, } from "./ThemeContext";
6
6
  export { default as ThemeContext } from "./ThemeContext";
7
7
  export { DesignThemeProvider, useDesignTheme } from "./DesignThemeContext";
8
+ export { CurrentPagePathProvider, CurrentPagePathContext, useCurrentPagePath, type CurrentPagePathProviderProps, } from "./CurrentPagePathContext";
8
9
  export { UserProvider, UserContext, useUser, useHasRole, useHasPermission, useUserForEvaluation, ANONYMOUS_USER, type UserData, type UserContextValue, type UserProviderProps, } from "./UserContext";
@@ -673,6 +673,13 @@ function useDesignTheme() {
673
673
  availableThemes: availableThemes.map((t) => t.name)
674
674
  };
675
675
  }
676
+ var CurrentPagePathContext = createContext(void 0);
677
+ var CurrentPagePathProvider = ({
678
+ value,
679
+ children
680
+ }) => /* @__PURE__ */ jsx(CurrentPagePathContext.Provider, { value, children });
681
+ CurrentPagePathProvider.displayName = "CurrentPagePathProvider";
682
+ var useCurrentPagePath = () => useContext(CurrentPagePathContext);
676
683
  var ANONYMOUS_USER = {
677
684
  id: "anonymous",
678
685
  role: "anonymous",
@@ -772,4 +779,4 @@ function useUserForEvaluation() {
772
779
  return isLoggedIn && user ? user : void 0;
773
780
  }
774
781
 
775
- export { ANONYMOUS_USER, BUILT_IN_THEMES, DesignThemeProvider, ThemeContext_default as ThemeContext, ThemeProvider, UISlotContext, UISlotProvider, UserContext, UserProvider, useDesignTheme, useHasPermission, useHasRole, useSlotContent, useSlotHasContent, useTheme, useUISlots, useUser, useUserForEvaluation };
782
+ export { ANONYMOUS_USER, BUILT_IN_THEMES, CurrentPagePathContext, CurrentPagePathProvider, DesignThemeProvider, ThemeContext_default as ThemeContext, ThemeProvider, UISlotContext, UISlotProvider, UserContext, UserProvider, useCurrentPagePath, useDesignTheme, useHasPermission, useHasRole, useSlotContent, useSlotHasContent, useTheme, useUISlots, useUser, useUserForEvaluation };