@fiestaboard/ui 3.0.1 → 3.2.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 (115) hide show
  1. package/dist/components/containment/json-tree.d.ts +59 -0
  2. package/dist/components/containment/json-tree.js +122 -0
  3. package/dist/components/containment/json-tree.js.map +1 -0
  4. package/dist/components/editor/color-picker-content.d.ts +25 -0
  5. package/dist/components/editor/color-picker-content.js +118 -0
  6. package/dist/components/editor/color-picker-content.js.map +1 -0
  7. package/dist/components/editor/constants.d.ts +87 -0
  8. package/dist/components/editor/constants.js +29 -0
  9. package/dist/components/editor/constants.js.map +1 -0
  10. package/dist/components/editor/draw-char-picker-content.d.ts +22 -0
  11. package/dist/components/editor/draw-char-picker-content.js +79 -0
  12. package/dist/components/editor/draw-char-picker-content.js.map +1 -0
  13. package/dist/components/editor/extensions/color-tile-node.d.ts +10 -0
  14. package/dist/components/editor/extensions/color-tile-node.js +43 -0
  15. package/dist/components/editor/extensions/color-tile-node.js.map +1 -0
  16. package/dist/components/editor/extensions/fill-space-node.d.ts +10 -0
  17. package/dist/components/editor/extensions/fill-space-node.js +40 -0
  18. package/dist/components/editor/extensions/fill-space-node.js.map +1 -0
  19. package/dist/components/editor/extensions/formula-node.d.ts +6 -0
  20. package/dist/components/editor/extensions/formula-node.js +40 -0
  21. package/dist/components/editor/extensions/formula-node.js.map +1 -0
  22. package/dist/components/editor/extensions/line-navigation.d.ts +18 -0
  23. package/dist/components/editor/extensions/line-navigation.js +16 -0
  24. package/dist/components/editor/extensions/line-navigation.js.map +1 -0
  25. package/dist/components/editor/extensions/single-paragraph-doc.d.ts +15 -0
  26. package/dist/components/editor/extensions/single-paragraph-doc.js +11 -0
  27. package/dist/components/editor/extensions/single-paragraph-doc.js.map +1 -0
  28. package/dist/components/editor/extensions/trailing-newline.d.ts +13 -0
  29. package/dist/components/editor/extensions/trailing-newline.js +27 -0
  30. package/dist/components/editor/extensions/trailing-newline.js.map +1 -0
  31. package/dist/components/editor/extensions/variable-node.d.ts +15 -0
  32. package/dist/components/editor/extensions/variable-node.js +56 -0
  33. package/dist/components/editor/extensions/variable-node.js.map +1 -0
  34. package/dist/components/editor/extensions/wrapped-text-node.d.ts +9 -0
  35. package/dist/components/editor/extensions/wrapped-text-node.js +31 -0
  36. package/dist/components/editor/extensions/wrapped-text-node.js.map +1 -0
  37. package/dist/components/editor/filter-picker-content.d.ts +24 -0
  38. package/dist/components/editor/filter-picker-content.js +146 -0
  39. package/dist/components/editor/filter-picker-content.js.map +1 -0
  40. package/dist/components/editor/formatting-picker-content.d.ts +30 -0
  41. package/dist/components/editor/formatting-picker-content.js +154 -0
  42. package/dist/components/editor/formatting-picker-content.js.map +1 -0
  43. package/dist/components/editor/formula/formula-editor-panel.d.ts +102 -0
  44. package/dist/components/editor/formula/formula-editor-panel.js +527 -0
  45. package/dist/components/editor/formula/formula-editor-panel.js.map +1 -0
  46. package/dist/components/editor/node-views/color-tile-node-view.d.ts +21 -0
  47. package/dist/components/editor/node-views/color-tile-node-view.js +66 -0
  48. package/dist/components/editor/node-views/color-tile-node-view.js.map +1 -0
  49. package/dist/components/editor/node-views/fill-space-node-view.d.ts +16 -0
  50. package/dist/components/editor/node-views/fill-space-node-view.js +43 -0
  51. package/dist/components/editor/node-views/fill-space-node-view.js.map +1 -0
  52. package/dist/components/editor/node-views/formula-node-view.d.ts +39 -0
  53. package/dist/components/editor/node-views/formula-node-view.js +109 -0
  54. package/dist/components/editor/node-views/formula-node-view.js.map +1 -0
  55. package/dist/components/editor/node-views/node-view-context.d.ts +58 -0
  56. package/dist/components/editor/node-views/node-view-context.js +22 -0
  57. package/dist/components/editor/node-views/node-view-context.js.map +1 -0
  58. package/dist/components/editor/node-views/variable-node-view.d.ts +16 -0
  59. package/dist/components/editor/node-views/variable-node-view.js +63 -0
  60. package/dist/components/editor/node-views/variable-node-view.js.map +1 -0
  61. package/dist/components/editor/node-views/wrapped-text-view.d.ts +14 -0
  62. package/dist/components/editor/node-views/wrapped-text-view.js +46 -0
  63. package/dist/components/editor/node-views/wrapped-text-view.js.map +1 -0
  64. package/dist/components/editor/template-editor-toolbar.d.ts +146 -0
  65. package/dist/components/editor/template-editor-toolbar.js +434 -0
  66. package/dist/components/editor/template-editor-toolbar.js.map +1 -0
  67. package/dist/components/editor/template-editor.d.ts +109 -0
  68. package/dist/components/editor/template-editor.js +662 -0
  69. package/dist/components/editor/template-editor.js.map +1 -0
  70. package/dist/components/editor/toolbar-dropdown.d.ts +20 -0
  71. package/dist/components/editor/toolbar-dropdown.js +88 -0
  72. package/dist/components/editor/toolbar-dropdown.js.map +1 -0
  73. package/dist/components/editor/utils/draw-mode.d.ts +55 -0
  74. package/dist/components/editor/utils/draw-mode.js +79 -0
  75. package/dist/components/editor/utils/draw-mode.js.map +1 -0
  76. package/dist/components/editor/utils/insertion.d.ts +11 -0
  77. package/dist/components/editor/utils/insertion.js +26 -0
  78. package/dist/components/editor/utils/insertion.js.map +1 -0
  79. package/dist/components/editor/utils/length-calculator.d.ts +36 -0
  80. package/dist/components/editor/utils/length-calculator.js +32 -0
  81. package/dist/components/editor/utils/length-calculator.js.map +1 -0
  82. package/dist/components/editor/utils/serialization.d.ts +34 -0
  83. package/dist/components/editor/utils/serialization.js +184 -0
  84. package/dist/components/editor/utils/serialization.js.map +1 -0
  85. package/dist/components/editor/utils/stroke-transaction.d.ts +36 -0
  86. package/dist/components/editor/utils/stroke-transaction.js +57 -0
  87. package/dist/components/editor/utils/stroke-transaction.js.map +1 -0
  88. package/dist/components/editor/variable-picker-content.d.ts +130 -0
  89. package/dist/components/editor/variable-picker-content.js +422 -0
  90. package/dist/components/editor/variable-picker-content.js.map +1 -0
  91. package/dist/components/feedback/status-dot.d.ts +49 -0
  92. package/dist/components/feedback/status-dot.js +58 -0
  93. package/dist/components/feedback/status-dot.js.map +1 -0
  94. package/dist/components/forms/secret-input.d.ts +38 -0
  95. package/dist/components/forms/secret-input.js +42 -0
  96. package/dist/components/forms/secret-input.js.map +1 -0
  97. package/dist/components/forms/time-picker.d.ts +87 -0
  98. package/dist/components/forms/time-picker.js +260 -0
  99. package/dist/components/forms/time-picker.js.map +1 -0
  100. package/dist/components/forms/toggle-card.d.ts +120 -0
  101. package/dist/components/forms/toggle-card.js +211 -0
  102. package/dist/components/forms/toggle-card.js.map +1 -0
  103. package/dist/components/overlays/popover.d.ts +65 -0
  104. package/dist/components/overlays/popover.js +89 -0
  105. package/dist/components/overlays/popover.js.map +1 -0
  106. package/dist/editor.css +164 -0
  107. package/dist/index.d.ts +34 -0
  108. package/dist/index.js +95 -61
  109. package/dist/lib/board-colors.d.ts +16 -0
  110. package/dist/lib/board-colors.js +14 -14
  111. package/dist/lib/board-colors.js.map +1 -1
  112. package/dist/lib/use-deps-changed.d.ts +33 -0
  113. package/dist/lib/use-deps-changed.js +11 -0
  114. package/dist/lib/use-deps-changed.js.map +1 -0
  115. package/package.json +50 -2
@@ -0,0 +1,120 @@
1
+ import { type VariantProps } from "class-variance-authority";
2
+ import * as React from "react";
3
+ /**
4
+ * A `radiogroup` has no implicit label, so axe (and every screen reader)
5
+ * needs one from the call site. Requiring it in the type means a group can
6
+ * never ship nameless: pass `aria-label`, or `aria-labelledby` pointing at
7
+ * the heading/`<Label>` that already introduces the options.
8
+ */
9
+ export type SelectionGroupNameProps = {
10
+ "aria-label": string;
11
+ "aria-labelledby"?: string;
12
+ } | {
13
+ "aria-labelledby": string;
14
+ "aria-label"?: string;
15
+ };
16
+ export interface SelectionGroupBaseProps {
17
+ /** Selected option value (controlled). Pair with `onValueChange`. */
18
+ value?: string | null;
19
+ /** Initially selected option value (uncontrolled). */
20
+ defaultValue?: string | null;
21
+ /** Fired with the newly selected value. Selection is never emptied. */
22
+ onValueChange?: (value: string) => void;
23
+ /** Disables every option in the group. */
24
+ disabled?: boolean;
25
+ /** Form field name — each option renders a hidden radio input under it. */
26
+ name?: string;
27
+ /** id of the form that owns the group, when rendered outside it. */
28
+ form?: string;
29
+ /** Marks the group required for form validation. */
30
+ required?: boolean;
31
+ }
32
+ declare const toggleCardGroupVariants: (props?: ({
33
+ columns?: "1" | "2" | "3" | null | undefined;
34
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
35
+ declare const toggleCardVariants: (props?: ({
36
+ size?: "sm" | "md" | "lg" | null | undefined;
37
+ align?: "start" | "center" | null | undefined;
38
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
39
+ type ToggleCardSize = NonNullable<VariantProps<typeof toggleCardVariants>["size"]>;
40
+ type ToggleCardAlign = NonNullable<VariantProps<typeof toggleCardVariants>["align"]>;
41
+ export type ToggleCardGroupProps = SelectionGroupBaseProps & SelectionGroupNameProps & VariantProps<typeof toggleCardGroupVariants> & {
42
+ /** Size applied to every card in the group; a card may override it. */
43
+ size?: ToggleCardSize;
44
+ /** Content alignment applied to every card in the group. */
45
+ align?: ToggleCardAlign;
46
+ /** Show the selected-check on every card in the group. @default true */
47
+ indicator?: boolean;
48
+ className?: string;
49
+ children?: React.ReactNode;
50
+ } & Omit<React.ComponentProps<"div">, "defaultValue" | "onChange">;
51
+ /**
52
+ * Single-select group of {@link ToggleCard}s — a real `radiogroup`.
53
+ *
54
+ * One tab stop for the whole group; arrow keys move the selection and wrap.
55
+ * Cards inside it take their state from the group's `value`, so they need a
56
+ * `value` of their own and must NOT be given `pressed`.
57
+ */
58
+ declare function ToggleCardGroup({ className, columns, size, align, indicator, children, ...props }: ToggleCardGroupProps): React.JSX.Element;
59
+ export type ToggleCardProps = Omit<React.ComponentProps<"button">, "value" | "title"> & VariantProps<typeof toggleCardVariants> & {
60
+ /** Identifies the card inside a {@link ToggleCardGroup}. */
61
+ value?: string;
62
+ /** Standalone toggle state — only outside a group. Pair with `onPressedChange`. */
63
+ pressed?: boolean;
64
+ onPressedChange?: (pressed: boolean) => void;
65
+ /** Leading icon (a lucide element); sized to 16px unless it sets its own. */
66
+ icon?: React.ReactNode;
67
+ /** Primary label. Provides the card's accessible name. */
68
+ title?: React.ReactNode;
69
+ /** Secondary line under the title. */
70
+ description?: React.ReactNode;
71
+ /** Trailing content on the title row — a badge, a size indicator, a price. */
72
+ meta?: React.ReactNode;
73
+ /**
74
+ * Render a check in the corner when selected, so selection is not carried
75
+ * by hue alone. @default true
76
+ */
77
+ indicator?: boolean;
78
+ /** Extra body content below the title row — a preview, a thumbnail row. */
79
+ children?: React.ReactNode;
80
+ };
81
+ /**
82
+ * A large selectable tile: optional icon, title, description and preview
83
+ * body.
84
+ *
85
+ * Inside a {@link ToggleCardGroup} it is a `radio` (`aria-checked`, roving
86
+ * tabindex, arrow-key navigation). On its own, with `pressed`, it is a
87
+ * toggle button (`aria-pressed`). See the note at the top of this file.
88
+ */
89
+ declare function ToggleCard({ className, size, align, value, pressed, onPressedChange, icon, title, description, meta, indicator, children, ...props }: ToggleCardProps): React.JSX.Element;
90
+ declare const segmentedControlVariants: (props?: ({
91
+ wrap?: boolean | null | undefined;
92
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
93
+ declare const segmentedControlItemVariants: (props?: ({
94
+ size?: "sm" | "md" | "lg" | null | undefined;
95
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
96
+ type SegmentedControlSize = NonNullable<VariantProps<typeof segmentedControlItemVariants>["size"]>;
97
+ export type SegmentedControlProps = SelectionGroupBaseProps & SelectionGroupNameProps & VariantProps<typeof segmentedControlVariants> & {
98
+ /** Size applied to every item; an item may override it. */
99
+ size?: SegmentedControlSize;
100
+ className?: string;
101
+ children?: React.ReactNode;
102
+ } & Omit<React.ComponentProps<"div">, "defaultValue" | "onChange">;
103
+ /**
104
+ * Compact single-select pill row — the toolbar-scale sibling of
105
+ * {@link ToggleCardGroup}, with the same `radiogroup` semantics.
106
+ */
107
+ declare function SegmentedControl({ className, size, wrap, children, ...props }: SegmentedControlProps): React.JSX.Element;
108
+ export type SegmentedControlItemProps = Omit<React.ComponentProps<"button">, "value"> & VariantProps<typeof segmentedControlItemVariants> & {
109
+ /** Identifies the item inside a {@link SegmentedControl}. */
110
+ value?: string;
111
+ /** Standalone toggle state — only outside a SegmentedControl. */
112
+ pressed?: boolean;
113
+ onPressedChange?: (pressed: boolean) => void;
114
+ };
115
+ /**
116
+ * One pill. Inside a {@link SegmentedControl} it is a `radio`; on its own
117
+ * with `pressed` it is an `aria-pressed` toggle (a filter chip).
118
+ */
119
+ declare function SegmentedControlItem({ className, size, value, pressed, onPressedChange, children, ...props }: SegmentedControlItemProps): React.JSX.Element;
120
+ export { SegmentedControl, SegmentedControlItem, segmentedControlItemVariants, segmentedControlVariants, ToggleCard, ToggleCardGroup, toggleCardGroupVariants, toggleCardVariants, };
@@ -0,0 +1,211 @@
1
+ "use client";
2
+ import { cn as e } from "../../lib/utils.js";
3
+ import { Check as t } from "lucide-react";
4
+ import * as n from "react";
5
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
6
+ import { cva as a } from "class-variance-authority";
7
+ import { Radio as o } from "@base-ui/react/radio";
8
+ import { RadioGroup as s } from "@base-ui/react/radio-group";
9
+ //#region src/components/forms/toggle-card.tsx
10
+ function c({ slot: e, onValueChange: t, className: n, children: i, ...a }) {
11
+ return /* @__PURE__ */ r(s, {
12
+ "data-slot": e,
13
+ className: n,
14
+ onValueChange: (e) => t?.(e),
15
+ ...a,
16
+ children: i
17
+ });
18
+ }
19
+ function l({ grouped: e, value: t, pressed: n, onPressedChange: i, onClick: a, disabled: s, ref: c, children: l, ...u }) {
20
+ if (e) return /* @__PURE__ */ r(o.Root, {
21
+ value: t,
22
+ render: /* @__PURE__ */ r("button", { type: "button" }),
23
+ nativeButton: !0,
24
+ disabled: s,
25
+ onClick: a,
26
+ ref: c,
27
+ ...u,
28
+ children: l
29
+ });
30
+ let d = (e) => {
31
+ a?.(e), !e.defaultPrevented && i?.(!n);
32
+ };
33
+ return /* @__PURE__ */ r("button", {
34
+ type: "button",
35
+ disabled: s,
36
+ ref: c,
37
+ ...n === void 0 ? {} : {
38
+ "aria-pressed": n,
39
+ ...n ? { "data-checked": "" } : { "data-unchecked": "" }
40
+ },
41
+ onClick: d,
42
+ ...u,
43
+ children: l
44
+ });
45
+ }
46
+ var u = a("gap-3", {
47
+ variants: { columns: {
48
+ 1: "flex flex-col",
49
+ 2: "grid grid-cols-1 sm:grid-cols-2",
50
+ 3: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"
51
+ } },
52
+ defaultVariants: { columns: "1" }
53
+ }), d = a([
54
+ "group/toggle-card relative flex w-full cursor-pointer flex-col border border-input bg-transparent",
55
+ "transition-[color,background-color,border-color,box-shadow] duration-control outline-none",
56
+ "not-data-[checked]:hover:border-primary/50 not-data-[checked]:hover:bg-accent/50",
57
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
58
+ "data-[checked]:border-primary data-[checked]:bg-primary/5",
59
+ "disabled:pointer-events-none disabled:opacity-50",
60
+ "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
61
+ ], {
62
+ variants: {
63
+ size: {
64
+ sm: "gap-1.5 rounded-md p-2 text-xs",
65
+ md: "gap-2 rounded-lg p-3 text-sm",
66
+ lg: "gap-2.5 rounded-xl px-4 py-3.5 text-sm"
67
+ },
68
+ align: {
69
+ start: "text-left",
70
+ center: "text-center"
71
+ }
72
+ },
73
+ defaultVariants: {
74
+ size: "md",
75
+ align: "start"
76
+ }
77
+ }), f = a("flex w-full min-w-0", {
78
+ variants: { align: {
79
+ start: "flex-row items-start gap-3",
80
+ center: "flex-col items-center gap-1.5"
81
+ } },
82
+ defaultVariants: { align: "start" }
83
+ }), p = n.createContext(null);
84
+ function m({ className: t, columns: i, size: a, align: o, indicator: s, children: l, ...d }) {
85
+ let f = n.useMemo(() => ({
86
+ size: a,
87
+ align: o,
88
+ indicator: s
89
+ }), [
90
+ a,
91
+ o,
92
+ s
93
+ ]);
94
+ return /* @__PURE__ */ r(p.Provider, {
95
+ value: f,
96
+ children: /* @__PURE__ */ r(c, {
97
+ slot: "toggle-card-group",
98
+ className: e(u({ columns: i }), t),
99
+ ...d,
100
+ children: l
101
+ })
102
+ });
103
+ }
104
+ function h({ className: a, size: o, align: s, value: c, pressed: u, onPressedChange: m, icon: h, title: g, description: _, meta: v, indicator: y, children: b, ...x }) {
105
+ let S = n.useContext(p), C = o ?? S?.size ?? "md", w = s ?? S?.align ?? "start", T = y ?? S?.indicator ?? !0;
106
+ return /* @__PURE__ */ i(l, {
107
+ grouped: S !== null,
108
+ value: c,
109
+ pressed: u,
110
+ onPressedChange: m,
111
+ "data-slot": "toggle-card",
112
+ "data-size": C,
113
+ className: e(d({
114
+ size: C,
115
+ align: w
116
+ }), T && (w === "center" ? "px-6" : "pr-8"), a),
117
+ ...x,
118
+ children: [
119
+ /* @__PURE__ */ i("span", {
120
+ "data-slot": "toggle-card-header",
121
+ className: f({ align: w }),
122
+ children: [
123
+ h != null && /* @__PURE__ */ r("span", {
124
+ "data-slot": "toggle-card-icon",
125
+ className: e("flex shrink-0 items-center text-muted-foreground transition-colors duration-control group-data-[checked]/toggle-card:text-primary", w === "start" && "mt-0.5"),
126
+ "aria-hidden": "true",
127
+ children: h
128
+ }),
129
+ (g != null || _ != null) && /* @__PURE__ */ i("span", {
130
+ "data-slot": "toggle-card-body",
131
+ className: "flex min-w-0 flex-1 flex-col gap-1",
132
+ children: [g != null && /* @__PURE__ */ r("span", {
133
+ "data-slot": "toggle-card-title",
134
+ className: "font-medium",
135
+ children: g
136
+ }), _ != null && /* @__PURE__ */ r("span", {
137
+ "data-slot": "toggle-card-description",
138
+ className: "text-xs font-normal text-muted-foreground",
139
+ children: _
140
+ })]
141
+ }),
142
+ v != null && /* @__PURE__ */ r("span", {
143
+ "data-slot": "toggle-card-meta",
144
+ className: "shrink-0 text-muted-foreground",
145
+ children: v
146
+ })
147
+ ]
148
+ }),
149
+ b,
150
+ T && /* @__PURE__ */ r("span", {
151
+ "data-slot": "toggle-card-indicator",
152
+ "aria-hidden": "true",
153
+ className: "pointer-events-none absolute right-2 top-2 flex size-4 items-center justify-center rounded-full border border-input text-primary-foreground opacity-0 transition-[color,background-color,border-color,opacity] duration-control group-data-[checked]/toggle-card:border-primary group-data-[checked]/toggle-card:bg-primary group-data-[checked]/toggle-card:opacity-100",
154
+ children: /* @__PURE__ */ r(t, { className: "size-3" })
155
+ })
156
+ ]
157
+ });
158
+ }
159
+ var g = a("flex items-center gap-2", {
160
+ variants: { wrap: {
161
+ true: "flex-wrap",
162
+ false: "flex-nowrap"
163
+ } },
164
+ defaultVariants: { wrap: !0 }
165
+ }), _ = a([
166
+ "group/segmented-item inline-flex cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap",
167
+ "border border-input bg-transparent font-medium text-foreground",
168
+ "transition-[color,background-color,border-color,box-shadow] duration-control outline-none",
169
+ "not-data-[checked]:hover:border-primary/50 not-data-[checked]:hover:bg-accent",
170
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
171
+ "data-[checked]:border-primary data-[checked]:bg-primary/10 data-[checked]:text-primary",
172
+ "disabled:pointer-events-none disabled:opacity-50",
173
+ "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
174
+ ], {
175
+ variants: { size: {
176
+ sm: "h-7 rounded-md px-2.5 text-xs",
177
+ md: "h-8 rounded-md px-3 text-sm",
178
+ lg: "h-9 rounded-md px-4 text-sm"
179
+ } },
180
+ defaultVariants: { size: "md" }
181
+ }), v = n.createContext(null);
182
+ function y({ className: t, size: i, wrap: a, children: o, ...s }) {
183
+ let l = n.useMemo(() => ({ size: i }), [i]);
184
+ return /* @__PURE__ */ r(v.Provider, {
185
+ value: l,
186
+ children: /* @__PURE__ */ r(c, {
187
+ slot: "segmented-control",
188
+ className: e(g({ wrap: a }), t),
189
+ ...s,
190
+ children: o
191
+ })
192
+ });
193
+ }
194
+ function b({ className: t, size: i, value: a, pressed: o, onPressedChange: s, children: c, ...u }) {
195
+ let d = n.useContext(v), f = i ?? d?.size ?? "md";
196
+ return /* @__PURE__ */ r(l, {
197
+ grouped: d !== null,
198
+ value: a,
199
+ pressed: o,
200
+ onPressedChange: s,
201
+ "data-slot": "segmented-control-item",
202
+ "data-size": f,
203
+ className: e(_({ size: f }), t),
204
+ ...u,
205
+ children: c
206
+ });
207
+ }
208
+ //#endregion
209
+ export { y as SegmentedControl, b as SegmentedControlItem, h as ToggleCard, m as ToggleCardGroup, _ as segmentedControlItemVariants, g as segmentedControlVariants, u as toggleCardGroupVariants, d as toggleCardVariants };
210
+
211
+ //# sourceMappingURL=toggle-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toggle-card.js","names":[],"sources":["../../../src/components/forms/toggle-card.tsx"],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import { Popover as PopoverPrimitive } from "@base-ui/react/popover";
2
+ import * as React from "react";
3
+ type PopoverRootProps = React.ComponentProps<typeof PopoverPrimitive.Root>;
4
+ type PopoverPositionerProps = React.ComponentProps<typeof PopoverPrimitive.Positioner>;
5
+ declare function usePopoverClose(): () => void;
6
+ interface PopoverProps extends Omit<PopoverRootProps, "children"> {
7
+ children?: React.ReactNode;
8
+ /**
9
+ * Whether a press outside the popup dismisses it. Escape and `<PopoverClose>`
10
+ * keep working when this is `false`, so the popup is never a keyboard trap.
11
+ * @default true
12
+ */
13
+ closeOnOutsideClick?: boolean;
14
+ }
15
+ declare function Popover({ actionsRef, closeOnOutsideClick, onOpenChange, children, ...props }: PopoverProps): React.JSX.Element;
16
+ declare function PopoverTrigger({ asChild, children, ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger> & {
17
+ asChild?: boolean;
18
+ }): React.JSX.Element;
19
+ interface PopoverContentProps extends Omit<React.ComponentProps<typeof PopoverPrimitive.Popup>, "children"> {
20
+ /** Preferred side of the anchor. Flipped automatically when it does not fit. */
21
+ side?: "top" | "right" | "bottom" | "left";
22
+ /** Alignment along the chosen side. Shifted automatically when it does not fit. */
23
+ align?: "start" | "center" | "end";
24
+ /** Distance in pixels between the anchor and the popup. */
25
+ sideOffset?: number;
26
+ /** Offset in pixels along the alignment axis. */
27
+ alignOffset?: number;
28
+ /** Minimum gap kept between the popup and the edge of the viewport. */
29
+ collisionPadding?: PopoverPositionerProps["collisionPadding"];
30
+ /** Element the popup is kept inside of. Defaults to the viewport. */
31
+ collisionBoundary?: PopoverPositionerProps["collisionBoundary"];
32
+ /** How side/alignment overflow is corrected. See Base UI's `collisionAvoidance`. */
33
+ collisionAvoidance?: PopoverPositionerProps["collisionAvoidance"];
34
+ /** Keep the popup on screen after the anchor scrolls out of view. */
35
+ sticky?: boolean;
36
+ /**
37
+ * Anchor the popup to something other than the trigger — an element, a ref,
38
+ * or a virtual element (`getBoundingClientRect`). Useful for anchoring to a
39
+ * text selection or an editor node rather than a button.
40
+ */
41
+ anchor?: PopoverPositionerProps["anchor"];
42
+ /** Class applied to the positioner wrapper rather than the popup surface. */
43
+ positionerClassName?: string;
44
+ /**
45
+ * Accessible name for the popup, which Base UI renders with `role="dialog"`.
46
+ * Ignored once a `<PopoverTitle>` is rendered inside, since that wins by
47
+ * `aria-labelledby`.
48
+ * @default "Popover"
49
+ */
50
+ label?: string;
51
+ /**
52
+ * Popup body. A function receives an imperative `close`, so a picker can
53
+ * dismiss itself on selection.
54
+ */
55
+ children?: React.ReactNode | ((api: {
56
+ close: () => void;
57
+ }) => React.ReactNode);
58
+ }
59
+ declare function PopoverContent({ className, positionerClassName, side, align, sideOffset, alignOffset, collisionPadding, collisionBoundary, collisionAvoidance, sticky, anchor, label, children, ...props }: PopoverContentProps): React.JSX.Element;
60
+ declare function PopoverTitle({ className, ...props }: React.ComponentProps<typeof PopoverPrimitive.Title>): React.JSX.Element;
61
+ declare function PopoverDescription({ className, ...props }: React.ComponentProps<typeof PopoverPrimitive.Description>): React.JSX.Element;
62
+ declare function PopoverClose({ asChild, children, ...props }: React.ComponentProps<typeof PopoverPrimitive.Close> & {
63
+ asChild?: boolean;
64
+ }): React.JSX.Element;
65
+ export { Popover, PopoverClose, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, usePopoverClose };
@@ -0,0 +1,89 @@
1
+ "use client";
2
+ import { cn as e } from "../../lib/utils.js";
3
+ import * as t from "react";
4
+ import { jsx as n } from "react/jsx-runtime";
5
+ import { Popover as r } from "@base-ui/react/popover";
6
+ //#region src/components/overlays/popover.tsx
7
+ var i = "outside-press", a = t.createContext(() => {});
8
+ function o() {
9
+ return t.useContext(a);
10
+ }
11
+ function s({ actionsRef: e, closeOnOutsideClick: o = !0, onOpenChange: s, children: c, ...l }) {
12
+ let u = t.useRef(null);
13
+ t.useImperativeHandle(e, () => ({
14
+ close: () => u.current?.close(),
15
+ unmount: () => u.current?.unmount()
16
+ }));
17
+ let d = t.useCallback(() => {
18
+ u.current?.close();
19
+ }, []), f = t.useCallback((e, t) => {
20
+ if (!e && !o && t.reason === i) {
21
+ t.cancel();
22
+ return;
23
+ }
24
+ s?.(e, t);
25
+ }, [o, s]);
26
+ return /* @__PURE__ */ n(r.Root, {
27
+ actionsRef: u,
28
+ onOpenChange: f,
29
+ ...l,
30
+ children: /* @__PURE__ */ n(a.Provider, {
31
+ value: d,
32
+ children: c
33
+ })
34
+ });
35
+ }
36
+ function c({ asChild: e = !1, children: i, ...a }) {
37
+ return /* @__PURE__ */ n(r.Trigger, {
38
+ "data-slot": "popover-trigger",
39
+ ...e ? { render: t.Children.only(i) } : { children: i },
40
+ ...a
41
+ });
42
+ }
43
+ function l({ className: t, positionerClassName: i, side: a = "bottom", align: s = "center", sideOffset: c = 4, alignOffset: l, collisionPadding: u = 8, collisionBoundary: d, collisionAvoidance: f, sticky: p, anchor: m, label: h = "Popover", children: g, ..._ }) {
44
+ let v = o();
45
+ return /* @__PURE__ */ n(r.Portal, { children: /* @__PURE__ */ n(r.Positioner, {
46
+ side: a,
47
+ align: s,
48
+ sideOffset: c,
49
+ alignOffset: l,
50
+ collisionPadding: u,
51
+ collisionBoundary: d,
52
+ collisionAvoidance: f,
53
+ sticky: p,
54
+ anchor: m,
55
+ className: e("z-[var(--z-popover)]", i),
56
+ children: /* @__PURE__ */ n(r.Popup, {
57
+ "data-slot": "popover-content",
58
+ "aria-label": h,
59
+ className: e("max-h-[var(--available-height)] max-w-[var(--available-width)] origin-[var(--transform-origin)] overflow-auto rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-hidden data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[ending-style]:animate-out data-[ending-style]:fade-out-0 data-[ending-style]:zoom-out-95 data-[open]:animate-in data-[open]:fade-in-0 data-[open]:zoom-in-95", t),
60
+ ..._,
61
+ children: typeof g == "function" ? g({ close: v }) : g
62
+ })
63
+ }) });
64
+ }
65
+ function u({ className: t, ...i }) {
66
+ return /* @__PURE__ */ n(r.Title, {
67
+ "data-slot": "popover-title",
68
+ className: e("text-sm font-semibold leading-none tracking-tight", t),
69
+ ...i
70
+ });
71
+ }
72
+ function d({ className: t, ...i }) {
73
+ return /* @__PURE__ */ n(r.Description, {
74
+ "data-slot": "popover-description",
75
+ className: e("text-sm text-muted-foreground", t),
76
+ ...i
77
+ });
78
+ }
79
+ function f({ asChild: e = !1, children: i, ...a }) {
80
+ return /* @__PURE__ */ n(r.Close, {
81
+ "data-slot": "popover-close",
82
+ ...e ? { render: t.Children.only(i) } : { children: i },
83
+ ...a
84
+ });
85
+ }
86
+ //#endregion
87
+ export { s as Popover, f as PopoverClose, l as PopoverContent, d as PopoverDescription, u as PopoverTitle, c as PopoverTrigger, o as usePopoverClose };
88
+
89
+ //# sourceMappingURL=popover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popover.js","names":[],"sources":["../../../src/components/overlays/popover.tsx"],"mappings":";;;;;;AAiBA,IAAM,IAAgB,iBAWhB,IAAsB,EAAM,oBATf,CAAC,CAS4C;AAEhE,SAAS,IAA8B;CACrC,OAAO,EAAM,WAAW,CAAmB;AAC7C;AAYA,SAAS,EAAQ,EAAE,eAAY,yBAAsB,IAAM,iBAAc,aAAU,GAAG,KAAuB;CAC3G,IAAM,IAAU,EAAM,OAA8B,IAAI;CAKxD,EAAM,oBAAoB,UAAmB;EAC3C,aAAa,EAAQ,SAAS,MAAM;EACpC,eAAe,EAAQ,SAAS,QAAQ;CAC1C,EAAE;CAEF,IAAM,IAAQ,EAAM,kBAAkB;EACpC,EAAQ,SAAS,MAAM;CACzB,GAAG,CAAC,CAAC,GAEC,IAAmB,EAAM,aAC5B,GAAe,MAAsC;EACpD,IAAI,CAAC,KAAQ,CAAC,KAAuB,EAAQ,WAAW,GAAe;GACrE,EAAQ,OAAO;GACf;EACF;EACA,IAAe,GAAM,CAAO;CAC9B,GACA,CAAC,GAAqB,CAAY,CACpC;CAEA,OACE,kBAAC,EAAiB,MAAlB;EAAuB,YAAY;EAAS,cAAc;EAAkB,GAAI;EAC9E,UAAA,kBAAC,EAAoB,UAArB;GAA8B,OAAO;GAAQ;EAAuC,CAAA;CAC/D,CAAA;AAE3B;AAEA,SAAS,EAAe,EACtB,aAAU,IACV,aACA,GAAG,KAC6E;CAChF,OACE,kBAAC,EAAiB,SAAlB;EACE,aAAU;EACV,GAAK,IAAU,EAAE,QAAQ,EAAM,SAAS,KAAK,CAAQ,EAAwB,IAAI,EAAE,YAAS;EAC5F,GAAI;CACL,CAAA;AAEL;AAyCA,SAAS,EAAe,EACtB,cACA,wBACA,UAAO,UACP,WAAQ,UACR,gBAAa,GACb,gBAEA,sBAAmB,GACnB,sBACA,uBACA,WACA,WACA,WAAQ,WACR,aACA,GAAG,KACmB;CACtB,IAAM,IAAQ,EAAgB;CAE9B,OACE,kBAAC,EAAiB,QAAlB,EAAA,UACE,kBAAC,EAAiB,YAAlB;EACQ;EACC;EACK;EACC;EACK;EACC;EACC;EACZ;EACA;EACR,WAAW,EAAG,wBAAwB,CAAmB;EAEzD,UAAA,kBAAC,EAAiB,OAAlB;GACE,aAAU;GACV,cAAY;GACZ,WAAW,EACT,kgBACA,CACF;GACA,GAAI;GAEH,UAAA,OAAO,KAAa,aAAa,EAAS,EAAE,SAAM,CAAC,IAAI;EAClC,CAAA;CACG,CAAA,EACN,CAAA;AAE7B;AAEA,SAAS,EAAa,EAAE,cAAW,GAAG,KAA8D;CAClG,OACE,kBAAC,EAAiB,OAAlB;EACE,aAAU;EACV,WAAW,EAAG,qDAAqD,CAAS;EAC5E,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,EAAmB,EAAE,cAAW,GAAG,KAAoE;CAC9G,OACE,kBAAC,EAAiB,aAAlB;EACE,aAAU;EACV,WAAW,EAAG,iCAAiC,CAAS;EACxD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,EAAa,EACpB,aAAU,IACV,aACA,GAAG,KAC2E;CAC9E,OACE,kBAAC,EAAiB,OAAlB;EACE,aAAU;EACV,GAAK,IAAU,EAAE,QAAQ,EAAM,SAAS,KAAK,CAAQ,EAAwB,IAAI,EAAE,YAAS;EAC5F,GAAI;CACL,CAAA;AAEL"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Template editor stylesheet — ProseMirror surface rules for
3
+ * `components/editor/template-editor.tsx`.
4
+ *
5
+ * Opt-in subpath, exactly like `fonts.css`: nothing in the package imports it,
6
+ * so an app that never renders the editor never pays for it. Consumers of
7
+ * `TemplateEditor` MUST import it once, alongside `theme.css`:
8
+ *
9
+ * import "@fiestaboard/ui/theme.css";
10
+ * import "@fiestaboard/ui/editor.css";
11
+ *
12
+ * Ported verbatim from the FiestaBoard app, where these rules lived in an
13
+ * inline `<style>` element rendered inside the editor component — i.e. the
14
+ * whole sheet was re-parsed on every mount, duplicated per instance, and could
15
+ * not be treeshaken, cached, or overridden by app CSS with predictable
16
+ * ordering. They are global on purpose: ProseMirror owns the DOM inside
17
+ * `.ProseMirror` and Tailwind utilities cannot reach nodes it creates
18
+ * (`<br>`, node-view wrappers, the `::before` placeholder). Tailwind
19
+ * arbitrary-variant classes that CAN reach their target stay inline on the
20
+ * component.
21
+ *
22
+ * `var(--primary)`, `var(--muted-foreground)` come from theme.css.
23
+ */
24
+
25
+ /* Ensure ProseMirror container looks like a single textarea */
26
+ .ProseMirror {
27
+ margin: 0;
28
+ padding: 0;
29
+ width: 100%;
30
+ max-width: 100%;
31
+ overflow: visible;
32
+ outline: none;
33
+ }
34
+
35
+ /* Placeholder for first empty line only - textarea-like */
36
+ .ProseMirror[data-placeholder] > p:first-child:empty::before {
37
+ content: attr(data-placeholder);
38
+ color: var(--muted-foreground);
39
+ pointer-events: none;
40
+ position: absolute;
41
+ }
42
+
43
+ .ProseMirror:focus[data-placeholder] > p:first-child:empty::before {
44
+ opacity: 0.5;
45
+ }
46
+
47
+ /* Standard paragraph - no wrapping, fixed line height */
48
+ .ProseMirror > p {
49
+ margin: 0;
50
+ padding: 0;
51
+ text-transform: uppercase;
52
+ font-family: "Courier New", "Courier", monospace;
53
+ font-size: 0.875rem;
54
+ letter-spacing: 0;
55
+ line-height: 1.5rem;
56
+ white-space: nowrap;
57
+ overflow: visible; /* Let content flow naturally, limit via input handling */
58
+ display: block;
59
+ }
60
+
61
+ /* Hard breaks create line breaks naturally */
62
+ .ProseMirror br {
63
+ display: block;
64
+ content: "";
65
+ margin: 0;
66
+ padding: 0;
67
+ line-height: 0;
68
+ }
69
+
70
+ /* Prevent any extra spacing around hard breaks */
71
+ .ProseMirror br::before,
72
+ .ProseMirror br::after {
73
+ content: none;
74
+ }
75
+
76
+ /* Empty paragraph minimum height */
77
+ .ProseMirror > p:empty {
78
+ min-height: 1.5rem;
79
+ }
80
+
81
+ /* Cursor styling */
82
+ .ProseMirror {
83
+ caret-color: var(--primary);
84
+ }
85
+
86
+ .ProseMirror:focus {
87
+ outline: none;
88
+ }
89
+
90
+ /* Inline nodes - keep them truly inline, no wrapping */
91
+ .ProseMirror [data-type="variable"],
92
+ .ProseMirror [data-type="color-tile"],
93
+ .ProseMirror [data-type="fill-space"],
94
+ .ProseMirror [data-type="wrapped-text"] {
95
+ display: inline-block !important;
96
+ vertical-align: middle;
97
+ white-space: nowrap;
98
+ }
99
+
100
+ /* Node view wrappers - prevent wrapping */
101
+ .ProseMirror [data-node-view-wrapper] {
102
+ display: inline-block !important;
103
+ vertical-align: middle;
104
+ white-space: nowrap;
105
+ }
106
+
107
+ /* Ensure text nodes also don't wrap */
108
+ .ProseMirror p > span {
109
+ white-space: nowrap;
110
+ }
111
+
112
+ /* All inline nodes must not exceed line height */
113
+ .ProseMirror [data-type="variable"],
114
+ .ProseMirror [data-type="color-tile"],
115
+ .ProseMirror [data-type="fill-space"],
116
+ .ProseMirror [data-type="wrapped-text"] {
117
+ max-height: 1.4rem !important;
118
+ height: auto !important;
119
+ line-height: 1.4rem;
120
+ vertical-align: middle;
121
+ }
122
+
123
+ /* Text should be monospace and equal width - each character is exactly 1ch */
124
+ .ProseMirror {
125
+ font-family: "Courier New", "Courier", monospace;
126
+ font-variant-numeric: tabular-nums;
127
+ }
128
+
129
+ /* Don't transform node views (they handle their own display) */
130
+ .ProseMirror [data-type="variable"],
131
+ .ProseMirror [data-type="color-tile"],
132
+ .ProseMirror [data-type="fill-space"],
133
+ .ProseMirror [data-type="wrapped-text"] {
134
+ text-transform: none;
135
+ }
136
+
137
+ /* Enable dragging for nodes with data-drag-handle */
138
+ .ProseMirror [data-drag-handle] {
139
+ cursor: grab;
140
+ }
141
+
142
+ .ProseMirror [data-drag-handle]:active {
143
+ cursor: grabbing;
144
+ }
145
+
146
+ /* Ensure no weird spacing around inline nodes */
147
+ .ProseMirror [data-type="variable"]::before,
148
+ .ProseMirror [data-type="variable"]::after,
149
+ .ProseMirror [data-type="color-tile"]::before,
150
+ .ProseMirror [data-type="color-tile"]::after {
151
+ content: none;
152
+ }
153
+
154
+ /* Range-selection highlight for inline atom nodes (color tiles,
155
+ variables, fill-space). onSelectionUpdate adds this
156
+ class to any atom node DOM element inside the selection range,
157
+ giving shift+arrow and click-drag a visible highlight without
158
+ needing user-select: all (which made Safari treat clicks on a
159
+ tag as selecting the entire line). */
160
+ .ProseMirror .selected-inline {
161
+ outline: 2px solid var(--primary);
162
+ outline-offset: 1px;
163
+ border-radius: 3px;
164
+ }