@pipe0/react 0.0.6 → 0.0.8
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.
- package/CHANGELOG.md +16 -0
- package/README.md +14 -3
- package/dist/components/compound/pipe-catalog/card.d.mts +1 -0
- package/dist/components/compound/pipe-catalog/card.d.mts.map +1 -1
- package/dist/components/compound/pipe-catalog/card.mjs +3 -1
- package/dist/components/compound/pipe-catalog/card.mjs.map +1 -1
- package/dist/components/compound/pipe-catalog/category-filter.d.mts +4 -0
- package/dist/components/compound/pipe-catalog/category-filter.d.mts.map +1 -1
- package/dist/components/compound/pipe-catalog/category-filter.mjs +11 -1
- package/dist/components/compound/pipe-catalog/category-filter.mjs.map +1 -1
- package/dist/components/compound/pipe-catalog/column-filter.d.mts +2 -0
- package/dist/components/compound/pipe-catalog/column-filter.d.mts.map +1 -1
- package/dist/components/compound/pipe-catalog/column-filter.mjs +6 -0
- package/dist/components/compound/pipe-catalog/column-filter.mjs.map +1 -1
- package/dist/components/compound/pipe-catalog/list.d.mts +2 -0
- package/dist/components/compound/pipe-catalog/list.d.mts.map +1 -1
- package/dist/components/compound/pipe-catalog/list.mjs +5 -1
- package/dist/components/compound/pipe-catalog/list.mjs.map +1 -1
- package/dist/components/compound/pipe-catalog/search-filter.d.mts +1 -0
- package/dist/components/compound/pipe-catalog/search-filter.d.mts.map +1 -1
- package/dist/components/compound/pipe-catalog/search-filter.mjs +2 -0
- package/dist/components/compound/pipe-catalog/search-filter.mjs.map +1 -1
- package/dist/components/compound/pipe-form/content.d.mts +3 -1
- package/dist/components/compound/pipe-form/content.d.mts.map +1 -1
- package/dist/components/compound/pipe-form/content.mjs +8 -2
- package/dist/components/compound/pipe-form/content.mjs.map +1 -1
- package/dist/components/compound/pipe-form/errors.d.mts +4 -0
- package/dist/components/compound/pipe-form/errors.d.mts.map +1 -1
- package/dist/components/compound/pipe-form/errors.mjs +9 -1
- package/dist/components/compound/pipe-form/errors.mjs.map +1 -1
- package/dist/components/compound/search-catalog/card.d.mts +1 -0
- package/dist/components/compound/search-catalog/card.d.mts.map +1 -1
- package/dist/components/compound/search-catalog/card.mjs +3 -1
- package/dist/components/compound/search-catalog/card.mjs.map +1 -1
- package/dist/components/compound/search-catalog/category-filter.d.mts +4 -0
- package/dist/components/compound/search-catalog/category-filter.d.mts.map +1 -1
- package/dist/components/compound/search-catalog/category-filter.mjs +11 -1
- package/dist/components/compound/search-catalog/category-filter.mjs.map +1 -1
- package/dist/components/compound/search-catalog/column-filter.d.mts +2 -0
- package/dist/components/compound/search-catalog/column-filter.d.mts.map +1 -1
- package/dist/components/compound/search-catalog/column-filter.mjs +6 -0
- package/dist/components/compound/search-catalog/column-filter.mjs.map +1 -1
- package/dist/components/compound/search-catalog/list.d.mts +2 -0
- package/dist/components/compound/search-catalog/list.d.mts.map +1 -1
- package/dist/components/compound/search-catalog/list.mjs +5 -1
- package/dist/components/compound/search-catalog/list.mjs.map +1 -1
- package/dist/components/compound/search-catalog/search-filter.d.mts +1 -0
- package/dist/components/compound/search-catalog/search-filter.d.mts.map +1 -1
- package/dist/components/compound/search-catalog/search-filter.mjs +2 -0
- package/dist/components/compound/search-catalog/search-filter.mjs.map +1 -1
- package/dist/components/compound/search-form/content.d.mts +3 -1
- package/dist/components/compound/search-form/content.d.mts.map +1 -1
- package/dist/components/compound/search-form/content.mjs +8 -2
- package/dist/components/compound/search-form/content.mjs.map +1 -1
- package/dist/components/compound/search-form/errors.d.mts +4 -0
- package/dist/components/compound/search-form/errors.d.mts.map +1 -1
- package/dist/components/compound/search-form/errors.mjs +9 -1
- package/dist/components/compound/search-form/errors.mjs.map +1 -1
- package/dist/components/compound/searches-catalog/card.d.mts +1 -0
- package/dist/components/compound/searches-catalog/card.d.mts.map +1 -1
- package/dist/components/compound/searches-catalog/card.mjs +3 -1
- package/dist/components/compound/searches-catalog/card.mjs.map +1 -1
- package/dist/components/compound/searches-catalog/category-filter.d.mts +4 -0
- package/dist/components/compound/searches-catalog/category-filter.d.mts.map +1 -1
- package/dist/components/compound/searches-catalog/category-filter.mjs +11 -1
- package/dist/components/compound/searches-catalog/category-filter.mjs.map +1 -1
- package/dist/components/compound/searches-catalog/column-filter.d.mts +2 -0
- package/dist/components/compound/searches-catalog/column-filter.d.mts.map +1 -1
- package/dist/components/compound/searches-catalog/column-filter.mjs +6 -0
- package/dist/components/compound/searches-catalog/column-filter.mjs.map +1 -1
- package/dist/components/compound/searches-catalog/list.d.mts +2 -0
- package/dist/components/compound/searches-catalog/list.d.mts.map +1 -1
- package/dist/components/compound/searches-catalog/list.mjs +5 -1
- package/dist/components/compound/searches-catalog/list.mjs.map +1 -1
- package/dist/components/compound/searches-catalog/search-filter.d.mts +1 -0
- package/dist/components/compound/searches-catalog/search-filter.d.mts.map +1 -1
- package/dist/components/compound/searches-catalog/search-filter.mjs +2 -0
- package/dist/components/compound/searches-catalog/search-filter.mjs.map +1 -1
- package/dist/components/defaults/adapters/connector-input.mjs +1 -0
- package/dist/components/defaults/adapters/connector-input.mjs.map +1 -1
- package/dist/components/defaults/adapters/providers-input.mjs +32 -24
- package/dist/components/defaults/adapters/providers-input.mjs.map +1 -1
- package/dist/components/defaults/catalog/layout.mjs +1 -1
- package/dist/components/defaults/catalog/layout.mjs.map +1 -1
- package/dist/components/defaults/layout/field-wrapper.d.mts +1 -0
- package/dist/components/defaults/layout/field-wrapper.d.mts.map +1 -1
- package/dist/components/defaults/layout/field-wrapper.mjs +2 -0
- package/dist/components/defaults/layout/field-wrapper.mjs.map +1 -1
- package/dist/components/defaults/layout/group.d.mts +3 -0
- package/dist/components/defaults/layout/group.d.mts.map +1 -1
- package/dist/components/defaults/layout/group.mjs +10 -3
- package/dist/components/defaults/layout/group.mjs.map +1 -1
- package/dist/components/defaults/layout/section.d.mts +2 -1
- package/dist/components/defaults/layout/section.d.mts.map +1 -1
- package/dist/components/defaults/layout/section.mjs +6 -2
- package/dist/components/defaults/layout/section.mjs.map +1 -1
- package/dist/components/ui/button.d.mts +1 -1
- package/dist/context/catalog-config-context.d.mts +0 -10
- package/dist/context/catalog-config-context.d.mts.map +1 -1
- package/dist/context/catalog-config-context.mjs +0 -10
- package/dist/context/catalog-config-context.mjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/styles/pipe0-form.css +0 -55
- package/package.json +2 -2
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { cn } from "../../../lib/utils.mjs";
|
|
2
2
|
import { IconGripVertical, IconPlus } from "../../internal/icons.mjs";
|
|
3
|
+
import { PricingBadge } from "../../../widgets/pricing-badge.mjs";
|
|
3
4
|
import { WidgetStrip } from "../../../widgets/widget-strip.mjs";
|
|
4
5
|
import { Popover, PopoverContent, PopoverTrigger } from "../../ui/popover.mjs";
|
|
6
|
+
import { AvatarGroup } from "../../../widgets/avatar-group.mjs";
|
|
5
7
|
import { useMemo, useState } from "react";
|
|
6
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
9
|
import { Search, X } from "lucide-react";
|
|
@@ -11,15 +13,33 @@ import { SortableContext, useSortable, verticalListSortingStrategy } from "@dnd-
|
|
|
11
13
|
//#region src/components/defaults/adapters/providers-input.tsx
|
|
12
14
|
function splitWidgets(widgets) {
|
|
13
15
|
if (!widgets) return {
|
|
16
|
+
providerName: void 0,
|
|
14
17
|
leading: void 0,
|
|
15
18
|
pricing: void 0
|
|
16
19
|
};
|
|
17
|
-
const { pricing, ...rest } = widgets;
|
|
20
|
+
const { pricing, provider_logo, ...rest } = widgets;
|
|
21
|
+
const hasLeading = Object.values(rest).some((v) => v != null);
|
|
18
22
|
return {
|
|
19
|
-
|
|
23
|
+
providerName: provider_logo?.provider,
|
|
24
|
+
leading: hasLeading ? rest : void 0,
|
|
20
25
|
pricing
|
|
21
26
|
};
|
|
22
27
|
}
|
|
28
|
+
function LeadingAvatar({ providerName, leading }) {
|
|
29
|
+
if (providerName) return /* @__PURE__ */ jsx(AvatarGroup, {
|
|
30
|
+
providers: [providerName],
|
|
31
|
+
size: "sm",
|
|
32
|
+
className: "pz:shrink-0"
|
|
33
|
+
});
|
|
34
|
+
if (leading) return /* @__PURE__ */ jsx("span", {
|
|
35
|
+
className: "pz:flex pz:items-center pz:shrink-0",
|
|
36
|
+
children: /* @__PURE__ */ jsx(WidgetStrip, {
|
|
37
|
+
widgets: leading,
|
|
38
|
+
size: 18
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
23
43
|
/**
|
|
24
44
|
* Provider waterfall — vertical, ordered list of providers tried sequentially
|
|
25
45
|
* until a valid result is returned. The list makes the running order legible
|
|
@@ -93,7 +113,7 @@ function ProviderRow({ value, index, label, widgets, onRemove }) {
|
|
|
93
113
|
transition,
|
|
94
114
|
opacity: isDragging ? .6 : 1
|
|
95
115
|
};
|
|
96
|
-
const { leading, pricing } = splitWidgets(widgets);
|
|
116
|
+
const { providerName, leading, pricing } = splitWidgets(widgets);
|
|
97
117
|
const orderLabel = String(index + 1).padStart(2, "0");
|
|
98
118
|
return /* @__PURE__ */ jsxs("li", {
|
|
99
119
|
ref: setNodeRef,
|
|
@@ -111,21 +131,15 @@ function ProviderRow({ value, index, label, widgets, onRemove }) {
|
|
|
111
131
|
height: 14
|
|
112
132
|
})
|
|
113
133
|
}),
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
widgets: leading,
|
|
118
|
-
size: 18
|
|
119
|
-
})
|
|
134
|
+
/* @__PURE__ */ jsx(LeadingAvatar, {
|
|
135
|
+
providerName,
|
|
136
|
+
leading
|
|
120
137
|
}),
|
|
121
138
|
/* @__PURE__ */ jsx("span", {
|
|
122
139
|
className: "pz:text-sm pz:font-medium pz:text-foreground pz:flex-1 pz:truncate",
|
|
123
140
|
children: label
|
|
124
141
|
}),
|
|
125
|
-
pricing && /* @__PURE__ */
|
|
126
|
-
className: "pz:text-xs pz:text-muted-foreground pz:tabular-nums",
|
|
127
|
-
children: [pricing.credits, " cr"]
|
|
128
|
-
}),
|
|
142
|
+
pricing && /* @__PURE__ */ jsx(PricingBadge, { credits: pricing.credits }),
|
|
129
143
|
/* @__PURE__ */ jsx("span", {
|
|
130
144
|
"aria-hidden": true,
|
|
131
145
|
className: cn("pz:inline-flex pz:items-center pz:justify-center pz:min-w-7 pz:h-5 pz:px-1.5", "pz:rounded-full pz:bg-muted pz:text-muted-foreground pz:text-[10.5px]", "pz:font-medium pz:tabular-nums"),
|
|
@@ -190,7 +204,7 @@ function AddProviderControl({ options, excluded, onAdd, ariaInvalid }) {
|
|
|
190
204
|
className: "pz:px-2 pz:py-3 pz:text-center pz:text-xs pz:text-muted-foreground",
|
|
191
205
|
children: "No providers"
|
|
192
206
|
}), filtered.map((option) => {
|
|
193
|
-
const { leading, pricing } = splitWidgets(option.widgets);
|
|
207
|
+
const { providerName, leading, pricing } = splitWidgets(option.widgets);
|
|
194
208
|
return /* @__PURE__ */ jsx("li", {
|
|
195
209
|
className: "pz:contents",
|
|
196
210
|
children: /* @__PURE__ */ jsxs("button", {
|
|
@@ -202,21 +216,15 @@ function AddProviderControl({ options, excluded, onAdd, ariaInvalid }) {
|
|
|
202
216
|
},
|
|
203
217
|
className: cn("pz:flex pz:items-center pz:gap-2 pz:w-full pz:text-left", "pz:px-2 pz:py-1.5 pz:rounded-md pz:text-sm", "pz:hover:bg-accent pz:hover:text-accent-foreground", "pz:transition-colors pz:cursor-pointer"),
|
|
204
218
|
children: [
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
widgets: leading,
|
|
209
|
-
size: 16
|
|
210
|
-
})
|
|
219
|
+
/* @__PURE__ */ jsx(LeadingAvatar, {
|
|
220
|
+
providerName,
|
|
221
|
+
leading
|
|
211
222
|
}),
|
|
212
223
|
/* @__PURE__ */ jsx("span", {
|
|
213
224
|
className: "pz:flex-1 pz:truncate",
|
|
214
225
|
children: option.label
|
|
215
226
|
}),
|
|
216
|
-
pricing && /* @__PURE__ */
|
|
217
|
-
className: "pz:text-xs pz:text-muted-foreground pz:tabular-nums",
|
|
218
|
-
children: [pricing.credits, " cr"]
|
|
219
|
-
})
|
|
227
|
+
pricing && /* @__PURE__ */ jsx(PricingBadge, { credits: pricing.credits })
|
|
220
228
|
]
|
|
221
229
|
})
|
|
222
230
|
}, option.value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers-input.mjs","names":["XIcon","SearchIcon"],"sources":["../../../../src/components/defaults/adapters/providers-input.tsx"],"sourcesContent":["import {\n closestCenter,\n DndContext,\n type DragEndEvent,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n} from \"@dnd-kit/core\";\nimport { SortableContext, useSortable, verticalListSortingStrategy } from \"@dnd-kit/sortable\";\nimport type { WidgetsByKind } from \"@pipe0/base\";\nimport { Search as SearchIcon, X as XIcon } from \"lucide-react\";\nimport { type CSSProperties, useMemo, useState } from \"react\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { FieldHandle } from \"../../../types/field-handle.js\";\nimport { WidgetStrip } from \"../../../widgets/widget-strip.js\";\nimport { IconGripVertical, IconPlus } from \"../../internal/icons.js\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../../ui/popover.js\";\n\ntype ProviderOption = {\n value: string;\n label: string;\n widgets?: WidgetsByKind;\n};\n\nfunction splitWidgets(widgets: WidgetsByKind | undefined): {\n leading: WidgetsByKind | undefined;\n pricing: WidgetsByKind[\"pricing\"] | undefined;\n} {\n if (!widgets) return { leading: undefined, pricing: undefined };\n const { pricing, ...rest } = widgets;\n const hasLeading = Object.values(rest).some((v) => v != null);\n return { leading: hasLeading ? rest : undefined, pricing };\n}\n\n/**\n * Provider waterfall — vertical, ordered list of providers tried sequentially\n * until a valid result is returned. The list makes the running order legible\n * (numeric badge per row, drag-to-reorder), and the credit widget per\n * provider stays visible.\n */\nexport function ProvidersInputAdapter(field: FieldHandle<\"providers_input\">) {\n const selected: string[] = useMemo(\n () => (field.value ?? []).map((p: { provider: string }) => p.provider),\n [field.value],\n );\n\n const options = field.options ?? [];\n const optionByValue = useMemo(() => {\n const map = new Map<string, ProviderOption>();\n for (const o of options) map.set(o.value, o);\n return map;\n }, [options]);\n\n const maxItems = field.meta.maxItems;\n const atMax = maxItems !== undefined && selected.length >= maxItems;\n\n const setValue = (next: string[]) =>\n field.setValue(next.map((provider) => ({ provider })));\n\n const handleRemove = (value: string) => setValue(selected.filter((v) => v !== value));\n const handleAdd = (value: string) => {\n if (selected.includes(value)) return;\n setValue([...selected, value]);\n };\n\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),\n useSensor(KeyboardSensor),\n );\n\n const handleDragEnd = (event: DragEndEvent) => {\n const { active, over } = event;\n if (!over || active.id === over.id) return;\n const from = selected.indexOf(String(active.id));\n const to = selected.indexOf(String(over.id));\n if (from === -1 || to === -1) return;\n const next = [...selected];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved);\n setValue(next);\n };\n\n return (\n <div data-p0=\"input\" className=\"pz:flex pz:flex-col pz:gap-1\">\n {selected.length > 0 && (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n <SortableContext items={selected} strategy={verticalListSortingStrategy}>\n <ul className=\"pz:flex pz:flex-col pz:gap-0.5 pz:list-none pz:m-0 pz:p-0\">\n {selected.map((value, index) => {\n const option = optionByValue.get(value);\n return (\n <ProviderRow\n key={value}\n value={value}\n index={index}\n label={option?.label ?? value}\n widgets={option?.widgets}\n onRemove={() => handleRemove(value)}\n />\n );\n })}\n </ul>\n </SortableContext>\n </DndContext>\n )}\n {!atMax && (\n <AddProviderControl\n options={options}\n excluded={selected}\n onAdd={handleAdd}\n ariaInvalid={!!field.error}\n />\n )}\n </div>\n );\n}\n\nfunction ProviderRow({\n value,\n index,\n label,\n widgets,\n onRemove,\n}: {\n value: string;\n index: number;\n label: string;\n widgets?: WidgetsByKind;\n onRemove: () => void;\n}) {\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({\n id: value,\n });\n const style: CSSProperties = {\n transform: transform\n ? `translate3d(${Math.round(transform.x)}px, ${Math.round(transform.y)}px, 0)`\n : undefined,\n transition,\n opacity: isDragging ? 0.6 : 1,\n };\n\n const { leading, pricing } = splitWidgets(widgets);\n const orderLabel = String(index + 1).padStart(2, \"0\");\n\n return (\n <li\n ref={setNodeRef}\n style={style}\n className={cn(\n \"pz:group/prov pz:flex pz:items-center pz:gap-2.5 pz:rounded-md pz:px-1.5 pz:py-1.5\",\n \"pz:hover:bg-muted/60 pz:transition-colors\",\n )}\n {...attributes}\n >\n <button\n type=\"button\"\n aria-label=\"Drag to reorder\"\n className={cn(\n \"pz:flex pz:items-center pz:justify-center pz:size-4 pz:cursor-grab pz:touch-none\",\n \"pz:text-muted-foreground/60 pz:hover:text-foreground pz:transition-colors\",\n )}\n {...listeners}\n >\n <IconGripVertical width={11} height={14} />\n </button>\n {leading && (\n <span className=\"pz:flex pz:items-center pz:shrink-0\">\n <WidgetStrip widgets={leading} size={18} />\n </span>\n )}\n <span className=\"pz:text-sm pz:font-medium pz:text-foreground pz:flex-1 pz:truncate\">\n {label}\n </span>\n {pricing && (\n <span className=\"pz:text-xs pz:text-muted-foreground pz:tabular-nums\">\n {pricing.credits} cr\n </span>\n )}\n <span\n aria-hidden\n className={cn(\n \"pz:inline-flex pz:items-center pz:justify-center pz:min-w-7 pz:h-5 pz:px-1.5\",\n \"pz:rounded-full pz:bg-muted pz:text-muted-foreground pz:text-[10.5px]\",\n \"pz:font-medium pz:tabular-nums\",\n )}\n >\n {orderLabel}\n </span>\n <button\n type=\"button\"\n aria-label={`Remove ${label}`}\n onClick={(e) => {\n e.stopPropagation();\n onRemove();\n }}\n className={cn(\n \"pz:flex pz:items-center pz:justify-center pz:size-5 pz:rounded\",\n \"pz:text-muted-foreground/70\",\n \"pz:hover:bg-destructive/10 pz:hover:text-destructive pz:transition-colors\",\n )}\n >\n <XIcon className=\"pz:size-3\" />\n </button>\n </li>\n );\n}\n\nfunction AddProviderControl({\n options,\n excluded,\n onAdd,\n ariaInvalid,\n}: {\n options: ProviderOption[];\n excluded: string[];\n onAdd: (value: string) => void;\n ariaInvalid?: boolean;\n}) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n\n const excludedSet = useMemo(() => new Set(excluded), [excluded]);\n const available = useMemo(\n () => options.filter((o) => !excludedSet.has(o.value)),\n [options, excludedSet],\n );\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return available;\n return available.filter(\n (o) => o.label.toLowerCase().includes(q) || o.value.toLowerCase().includes(q),\n );\n }, [available, query]);\n\n if (available.length === 0 && excluded.length === 0) {\n return (\n <div className=\"pz:text-xs pz:text-muted-foreground pz:px-1.5 pz:py-2\">\n No providers available\n </div>\n );\n }\n\n if (available.length === 0) return null;\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) setQuery(\"\");\n }}\n >\n <PopoverTrigger\n aria-invalid={ariaInvalid || undefined}\n className={cn(\n \"pz:flex pz:items-center pz:justify-center pz:gap-1.5 pz:w-full\",\n \"pz:px-2.5 pz:py-1.5 pz:mt-1 pz:rounded-md\",\n \"pz:border pz:border-dashed pz:border-input pz:bg-transparent\",\n \"pz:text-xs pz:text-muted-foreground\",\n \"pz:hover:bg-muted/60 pz:hover:text-foreground pz:hover:border-muted-foreground/40\",\n \"pz:transition-colors pz:cursor-pointer\",\n )}\n >\n <IconPlus width={12} height={12} />\n Add provider\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"pz:w-(--anchor-width) pz:p-0 pz:gap-0\">\n <div className=\"pz:flex pz:items-center pz:gap-1.5 pz:px-2.5 pz:py-2 pz:border-b pz:border-border\">\n <SearchIcon className=\"pz:size-3.5 pz:text-muted-foreground pz:shrink-0\" />\n <input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search providers…\"\n // biome-ignore lint/a11y/noAutofocus: popover-scoped picker\n autoFocus\n className=\"pz:flex-1 pz:bg-transparent pz:outline-none pz:text-sm pz:placeholder:text-muted-foreground/70\"\n />\n </div>\n <ul className=\"pz:flex pz:flex-col pz:p-1 pz:max-h-72 pz:overflow-auto pz:list-none pz:m-0\">\n {filtered.length === 0 && (\n <li className=\"pz:px-2 pz:py-3 pz:text-center pz:text-xs pz:text-muted-foreground\">\n No providers\n </li>\n )}\n {filtered.map((option) => {\n const { leading, pricing } = splitWidgets(option.widgets);\n return (\n <li key={option.value} className=\"pz:contents\">\n <button\n type=\"button\"\n onClick={() => {\n onAdd(option.value);\n setOpen(false);\n setQuery(\"\");\n }}\n className={cn(\n \"pz:flex pz:items-center pz:gap-2 pz:w-full pz:text-left\",\n \"pz:px-2 pz:py-1.5 pz:rounded-md pz:text-sm\",\n \"pz:hover:bg-accent pz:hover:text-accent-foreground\",\n \"pz:transition-colors pz:cursor-pointer\",\n )}\n >\n {leading && (\n <span className=\"pz:flex pz:items-center pz:shrink-0\">\n <WidgetStrip widgets={leading} size={16} />\n </span>\n )}\n <span className=\"pz:flex-1 pz:truncate\">{option.label}</span>\n {pricing && (\n <span className=\"pz:text-xs pz:text-muted-foreground pz:tabular-nums\">\n {pricing.credits} cr\n </span>\n )}\n </button>\n </li>\n );\n })}\n </ul>\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"providers-input.mjs","names":["XIcon","SearchIcon"],"sources":["../../../../src/components/defaults/adapters/providers-input.tsx"],"sourcesContent":["import {\n closestCenter,\n DndContext,\n type DragEndEvent,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n} from \"@dnd-kit/core\";\nimport { SortableContext, useSortable, verticalListSortingStrategy } from \"@dnd-kit/sortable\";\nimport type { ProviderName, WidgetsByKind } from \"@pipe0/base\";\nimport { Search as SearchIcon, X as XIcon } from \"lucide-react\";\nimport { type CSSProperties, useMemo, useState } from \"react\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { FieldHandle } from \"../../../types/field-handle.js\";\nimport { AvatarGroup } from \"../../../widgets/avatar-group.js\";\nimport { PricingBadge } from \"../../../widgets/pricing-badge.js\";\nimport { WidgetStrip } from \"../../../widgets/widget-strip.js\";\nimport { IconGripVertical, IconPlus } from \"../../internal/icons.js\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../../ui/popover.js\";\n\ntype ProviderOption = {\n value: string;\n label: string;\n widgets?: WidgetsByKind;\n};\n\nfunction splitWidgets(widgets: WidgetsByKind | undefined): {\n providerName: ProviderName | undefined;\n leading: WidgetsByKind | undefined;\n pricing: WidgetsByKind[\"pricing\"] | undefined;\n} {\n if (!widgets) return { providerName: undefined, leading: undefined, pricing: undefined };\n const { pricing, provider_logo, ...rest } = widgets;\n const hasLeading = Object.values(rest).some((v) => v != null);\n return {\n providerName: provider_logo?.provider,\n leading: hasLeading ? rest : undefined,\n pricing,\n };\n}\n\nfunction LeadingAvatar({\n providerName,\n leading,\n}: {\n providerName: ProviderName | undefined;\n leading: WidgetsByKind | undefined;\n}) {\n if (providerName) {\n return <AvatarGroup providers={[providerName]} size=\"sm\" className=\"pz:shrink-0\" />;\n }\n if (leading) {\n return (\n <span className=\"pz:flex pz:items-center pz:shrink-0\">\n <WidgetStrip widgets={leading} size={18} />\n </span>\n );\n }\n return null;\n}\n\n/**\n * Provider waterfall — vertical, ordered list of providers tried sequentially\n * until a valid result is returned. The list makes the running order legible\n * (numeric badge per row, drag-to-reorder), and the credit widget per\n * provider stays visible.\n */\nexport function ProvidersInputAdapter(field: FieldHandle<\"providers_input\">) {\n const selected: string[] = useMemo(\n () => (field.value ?? []).map((p: { provider: string }) => p.provider),\n [field.value],\n );\n\n const options = field.options ?? [];\n const optionByValue = useMemo(() => {\n const map = new Map<string, ProviderOption>();\n for (const o of options) map.set(o.value, o);\n return map;\n }, [options]);\n\n const maxItems = field.meta.maxItems;\n const atMax = maxItems !== undefined && selected.length >= maxItems;\n\n const setValue = (next: string[]) =>\n field.setValue(next.map((provider) => ({ provider })));\n\n const handleRemove = (value: string) => setValue(selected.filter((v) => v !== value));\n const handleAdd = (value: string) => {\n if (selected.includes(value)) return;\n setValue([...selected, value]);\n };\n\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),\n useSensor(KeyboardSensor),\n );\n\n const handleDragEnd = (event: DragEndEvent) => {\n const { active, over } = event;\n if (!over || active.id === over.id) return;\n const from = selected.indexOf(String(active.id));\n const to = selected.indexOf(String(over.id));\n if (from === -1 || to === -1) return;\n const next = [...selected];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved);\n setValue(next);\n };\n\n return (\n <div data-p0=\"input\" className=\"pz:flex pz:flex-col pz:gap-1\">\n {selected.length > 0 && (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n <SortableContext items={selected} strategy={verticalListSortingStrategy}>\n <ul className=\"pz:flex pz:flex-col pz:gap-0.5 pz:list-none pz:m-0 pz:p-0\">\n {selected.map((value, index) => {\n const option = optionByValue.get(value);\n return (\n <ProviderRow\n key={value}\n value={value}\n index={index}\n label={option?.label ?? value}\n widgets={option?.widgets}\n onRemove={() => handleRemove(value)}\n />\n );\n })}\n </ul>\n </SortableContext>\n </DndContext>\n )}\n {!atMax && (\n <AddProviderControl\n options={options}\n excluded={selected}\n onAdd={handleAdd}\n ariaInvalid={!!field.error}\n />\n )}\n </div>\n );\n}\n\nfunction ProviderRow({\n value,\n index,\n label,\n widgets,\n onRemove,\n}: {\n value: string;\n index: number;\n label: string;\n widgets?: WidgetsByKind;\n onRemove: () => void;\n}) {\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({\n id: value,\n });\n const style: CSSProperties = {\n transform: transform\n ? `translate3d(${Math.round(transform.x)}px, ${Math.round(transform.y)}px, 0)`\n : undefined,\n transition,\n opacity: isDragging ? 0.6 : 1,\n };\n\n const { providerName, leading, pricing } = splitWidgets(widgets);\n const orderLabel = String(index + 1).padStart(2, \"0\");\n\n return (\n <li\n ref={setNodeRef}\n style={style}\n className={cn(\n \"pz:group/prov pz:flex pz:items-center pz:gap-2.5 pz:rounded-md pz:px-1.5 pz:py-1.5\",\n \"pz:hover:bg-muted/60 pz:transition-colors\",\n )}\n {...attributes}\n >\n <button\n type=\"button\"\n aria-label=\"Drag to reorder\"\n className={cn(\n \"pz:flex pz:items-center pz:justify-center pz:size-4 pz:cursor-grab pz:touch-none\",\n \"pz:text-muted-foreground/60 pz:hover:text-foreground pz:transition-colors\",\n )}\n {...listeners}\n >\n <IconGripVertical width={11} height={14} />\n </button>\n <LeadingAvatar providerName={providerName} leading={leading} />\n <span className=\"pz:text-sm pz:font-medium pz:text-foreground pz:flex-1 pz:truncate\">\n {label}\n </span>\n {pricing && <PricingBadge credits={pricing.credits} />}\n <span\n aria-hidden\n className={cn(\n \"pz:inline-flex pz:items-center pz:justify-center pz:min-w-7 pz:h-5 pz:px-1.5\",\n \"pz:rounded-full pz:bg-muted pz:text-muted-foreground pz:text-[10.5px]\",\n \"pz:font-medium pz:tabular-nums\",\n )}\n >\n {orderLabel}\n </span>\n <button\n type=\"button\"\n aria-label={`Remove ${label}`}\n onClick={(e) => {\n e.stopPropagation();\n onRemove();\n }}\n className={cn(\n \"pz:flex pz:items-center pz:justify-center pz:size-5 pz:rounded\",\n \"pz:text-muted-foreground/70\",\n \"pz:hover:bg-destructive/10 pz:hover:text-destructive pz:transition-colors\",\n )}\n >\n <XIcon className=\"pz:size-3\" />\n </button>\n </li>\n );\n}\n\nfunction AddProviderControl({\n options,\n excluded,\n onAdd,\n ariaInvalid,\n}: {\n options: ProviderOption[];\n excluded: string[];\n onAdd: (value: string) => void;\n ariaInvalid?: boolean;\n}) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n\n const excludedSet = useMemo(() => new Set(excluded), [excluded]);\n const available = useMemo(\n () => options.filter((o) => !excludedSet.has(o.value)),\n [options, excludedSet],\n );\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return available;\n return available.filter(\n (o) => o.label.toLowerCase().includes(q) || o.value.toLowerCase().includes(q),\n );\n }, [available, query]);\n\n if (available.length === 0 && excluded.length === 0) {\n return (\n <div className=\"pz:text-xs pz:text-muted-foreground pz:px-1.5 pz:py-2\">\n No providers available\n </div>\n );\n }\n\n if (available.length === 0) return null;\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) setQuery(\"\");\n }}\n >\n <PopoverTrigger\n aria-invalid={ariaInvalid || undefined}\n className={cn(\n \"pz:flex pz:items-center pz:justify-center pz:gap-1.5 pz:w-full\",\n \"pz:px-2.5 pz:py-1.5 pz:mt-1 pz:rounded-md\",\n \"pz:border pz:border-dashed pz:border-input pz:bg-transparent\",\n \"pz:text-xs pz:text-muted-foreground\",\n \"pz:hover:bg-muted/60 pz:hover:text-foreground pz:hover:border-muted-foreground/40\",\n \"pz:transition-colors pz:cursor-pointer\",\n )}\n >\n <IconPlus width={12} height={12} />\n Add provider\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"pz:w-(--anchor-width) pz:p-0 pz:gap-0\">\n <div className=\"pz:flex pz:items-center pz:gap-1.5 pz:px-2.5 pz:py-2 pz:border-b pz:border-border\">\n <SearchIcon className=\"pz:size-3.5 pz:text-muted-foreground pz:shrink-0\" />\n <input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search providers…\"\n // biome-ignore lint/a11y/noAutofocus: popover-scoped picker\n autoFocus\n className=\"pz:flex-1 pz:bg-transparent pz:outline-none pz:text-sm pz:placeholder:text-muted-foreground/70\"\n />\n </div>\n <ul className=\"pz:flex pz:flex-col pz:p-1 pz:max-h-72 pz:overflow-auto pz:list-none pz:m-0\">\n {filtered.length === 0 && (\n <li className=\"pz:px-2 pz:py-3 pz:text-center pz:text-xs pz:text-muted-foreground\">\n No providers\n </li>\n )}\n {filtered.map((option) => {\n const { providerName, leading, pricing } = splitWidgets(option.widgets);\n return (\n <li key={option.value} className=\"pz:contents\">\n <button\n type=\"button\"\n onClick={() => {\n onAdd(option.value);\n setOpen(false);\n setQuery(\"\");\n }}\n className={cn(\n \"pz:flex pz:items-center pz:gap-2 pz:w-full pz:text-left\",\n \"pz:px-2 pz:py-1.5 pz:rounded-md pz:text-sm\",\n \"pz:hover:bg-accent pz:hover:text-accent-foreground\",\n \"pz:transition-colors pz:cursor-pointer\",\n )}\n >\n <LeadingAvatar providerName={providerName} leading={leading} />\n <span className=\"pz:flex-1 pz:truncate\">{option.label}</span>\n {pricing && <PricingBadge credits={pricing.credits} />}\n </button>\n </li>\n );\n })}\n </ul>\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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"}
|
|
@@ -27,7 +27,7 @@ function DefaultCatalogRoot({ className, render, children, ...props }) {
|
|
|
27
27
|
render,
|
|
28
28
|
ref: portalRef,
|
|
29
29
|
props: mergeProps({
|
|
30
|
-
className: cn("pz:flex pz:flex-col pz:gap-
|
|
30
|
+
className: cn("pz:flex pz:flex-col pz:gap-1", classNames?.root, className),
|
|
31
31
|
children: wrappedChildren,
|
|
32
32
|
"data-p0": "catalog"
|
|
33
33
|
}, props)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.mjs","names":[],"sources":["../../../../src/components/defaults/catalog/layout.tsx"],"sourcesContent":["import { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { type ReactNode, useCallback, useState } from \"react\";\nimport { useCatalogConfig } from \"../../../context/catalog-config-context.js\";\nimport { PortalContainerContext } from \"../../../context/portal-container-context.js\";\nimport { cn } from \"../../../lib/utils.js\";\n\n/**\n * Outermost catalog wrapper. Owns the `PortalContainerContext.Provider` so\n * elements-react popovers/dropdowns mounted inside the catalog tree portal\n * back into this container — keeping them inside the catalog's CSS scope.\n */\nexport function DefaultCatalogRoot({\n className,\n render,\n children,\n ...props\n}: useRender.ComponentProps<\"div\">) {\n const { classNames } = useCatalogConfig();\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);\n const portalRef = useCallback((node: HTMLElement | null) => {\n setPortalContainer(node);\n }, []);\n\n const wrappedChildren: ReactNode = (\n <PortalContainerContext.Provider value={portalContainer}>\n {children}\n </PortalContainerContext.Provider>\n );\n\n return useRender({\n defaultTagName: \"div\",\n render,\n ref: portalRef,\n props: mergeProps<\"div\">(\n {\n className: cn(\"pz:flex pz:flex-col pz:gap-
|
|
1
|
+
{"version":3,"file":"layout.mjs","names":[],"sources":["../../../../src/components/defaults/catalog/layout.tsx"],"sourcesContent":["import { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { type ReactNode, useCallback, useState } from \"react\";\nimport { useCatalogConfig } from \"../../../context/catalog-config-context.js\";\nimport { PortalContainerContext } from \"../../../context/portal-container-context.js\";\nimport { cn } from \"../../../lib/utils.js\";\n\n/**\n * Outermost catalog wrapper. Owns the `PortalContainerContext.Provider` so\n * elements-react popovers/dropdowns mounted inside the catalog tree portal\n * back into this container — keeping them inside the catalog's CSS scope.\n */\nexport function DefaultCatalogRoot({\n className,\n render,\n children,\n ...props\n}: useRender.ComponentProps<\"div\">) {\n const { classNames } = useCatalogConfig();\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);\n const portalRef = useCallback((node: HTMLElement | null) => {\n setPortalContainer(node);\n }, []);\n\n const wrappedChildren: ReactNode = (\n <PortalContainerContext.Provider value={portalContainer}>\n {children}\n </PortalContainerContext.Provider>\n );\n\n return useRender({\n defaultTagName: \"div\",\n render,\n ref: portalRef,\n props: mergeProps<\"div\">(\n {\n className: cn(\"pz:flex pz:flex-col pz:gap-1\", classNames?.root, className),\n children: wrappedChildren,\n ...({ \"data-p0\": \"catalog\" } as Record<string, string>),\n },\n props,\n ),\n });\n}\n\nexport function DefaultCatalogList({\n className,\n render,\n ...props\n}: useRender.ComponentProps<\"div\">) {\n const { classNames } = useCatalogConfig();\n return useRender({\n defaultTagName: \"div\",\n render,\n props: mergeProps<\"div\">(\n {\n className: cn(\n \"pz:grid pz:gap-3 pz:grid-cols-1 pz:sm:grid-cols-2 pz:lg:grid-cols-3\",\n classNames?.list,\n className,\n ),\n ...({ \"data-p0\": \"catalog-list\" } as Record<string, string>),\n },\n props,\n ),\n });\n}\n\nexport function DefaultCatalogFilters({\n className,\n render,\n ...props\n}: useRender.ComponentProps<\"div\">) {\n const { classNames } = useCatalogConfig();\n return useRender({\n defaultTagName: \"div\",\n render,\n props: mergeProps<\"div\">(\n {\n className: cn(\"pz:flex pz:flex-wrap pz:gap-2\", classNames?.filters, className),\n ...({ \"data-p0\": \"catalog-filters\" } as Record<string, string>),\n },\n props,\n ),\n });\n}\n"],"mappings":";;;;;;;;;;;;;;AAYA,SAAgB,mBAAmB,EACjC,WACA,QACA,UACA,GAAG,SAC+B;CAClC,MAAM,EAAE,eAAe,kBAAkB;CACzC,MAAM,CAAC,iBAAiB,sBAAsB,SAA6B,KAAK;CAChF,MAAM,YAAY,aAAa,SAA6B;AAC1D,qBAAmB,KAAK;IACvB,EAAE,CAAC;CAEN,MAAM,kBACJ,oBAAC,uBAAuB,UAAxB;EAAiC,OAAO;EACrC;EAC+B;AAGpC,QAAO,UAAU;EACf,gBAAgB;EAChB;EACA,KAAK;EACL,OAAO,WACL;GACE,WAAW,GAAG,gCAAgC,YAAY,MAAM,UAAU;GAC1E,UAAU;GACJ,WAAW;GAClB,EACD,MACD;EACF,CAAC;;AA0BJ,SAAgB,sBAAsB,EACpC,WACA,QACA,GAAG,SAC+B;CAClC,MAAM,EAAE,eAAe,kBAAkB;AACzC,QAAO,UAAU;EACf,gBAAgB;EAChB;EACA,OAAO,WACL;GACE,WAAW,GAAG,iCAAiC,YAAY,SAAS,UAAU;GACxE,WAAW;GAClB,EACD,MACD;EACF,CAAC"}
|
|
@@ -2,6 +2,7 @@ import { AnyFieldProps } from "../../../types/field-props.mjs";
|
|
|
2
2
|
import { useRender } from "@base-ui/react/use-render";
|
|
3
3
|
//#region src/components/defaults/layout/field-wrapper.d.ts
|
|
4
4
|
interface DefaultFieldWrapperState {
|
|
5
|
+
field: AnyFieldProps;
|
|
5
6
|
disabled: boolean;
|
|
6
7
|
hasError: boolean;
|
|
7
8
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-wrapper.d.mts","names":[],"sources":["../../../../src/components/defaults/layout/field-wrapper.tsx"],"mappings":";;;UAQiB,wBAAA;EACf,QAAA;EACA,QAAA;AAAA;AAAA,UAGe,wBAAA,SACP,SAAA,CAAU,cAAA,QAAsB,wBAAA;EACxC,KAAA,EAAO,aAAA;AAAA"}
|
|
1
|
+
{"version":3,"file":"field-wrapper.d.mts","names":[],"sources":["../../../../src/components/defaults/layout/field-wrapper.tsx"],"mappings":";;;UAQiB,wBAAA;EACf,KAAA,EAAO,aAAA;EACP,QAAA;EACA,QAAA;AAAA;AAAA,UAGe,wBAAA,SACP,SAAA,CAAU,cAAA,QAAsB,wBAAA;EACxC,KAAA,EAAO,aAAA;AAAA"}
|
|
@@ -48,9 +48,11 @@ function DefaultFieldWrapper({ field, children, className, render, ...props }) {
|
|
|
48
48
|
defaultTagName: "div",
|
|
49
49
|
render,
|
|
50
50
|
state: {
|
|
51
|
+
field,
|
|
51
52
|
disabled: isDisabled,
|
|
52
53
|
hasError
|
|
53
54
|
},
|
|
55
|
+
stateAttributesMapping: { field: () => null },
|
|
54
56
|
props: mergeProps({
|
|
55
57
|
className: cn(classNames?.field ?? "pz:grid pz:gap-2", isDisabled && classNames?.fieldDisabled, className),
|
|
56
58
|
children: defaultContent,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-wrapper.mjs","names":[],"sources":["../../../../src/components/defaults/layout/field-wrapper.tsx"],"sourcesContent":["import { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { useFormConfig } from \"../../../context/form-context.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { AnyFieldProps } from \"../../../types/field-props.js\";\nimport { HoverInfo } from \"../../hover-info.js\";\nimport { RichText } from \"../../rich-text.js\";\n\nexport interface DefaultFieldWrapperState {\n disabled: boolean;\n hasError: boolean;\n}\n\nexport interface DefaultFieldWrapperProps\n extends useRender.ComponentProps<\"div\", DefaultFieldWrapperState> {\n field: AnyFieldProps;\n}\n\nexport function DefaultFieldWrapper({\n field,\n children,\n className,\n render,\n ...props\n}: DefaultFieldWrapperProps) {\n const { classNames } = useFormConfig();\n const hasError = !!field.error;\n const isDisabled = field.disabled;\n\n // Boolean toggles render their label inline with the switch (settings-row\n // pattern), so the wrapper's label/description block is suppressed for them.\n const inlineLabel = field.kind === \"boolean_input\";\n\n const defaultContent = (\n <>\n {!inlineLabel && (field.label || field.description || field.info) && (\n <div className=\"pz:flex pz:flex-col pz:gap-1\">\n <div className=\"pz:flex pz:items-center pz:gap-1.5\">\n {field.label && (\n <label\n data-p0=\"label\"\n htmlFor={field.id}\n className={\n classNames?.label ??\n cn(\n \"pz:text-sm pz:leading-none pz:font-medium pz:select-none\",\n hasError && \"pz:text-destructive\",\n )\n }\n >\n <RichText>{field.label}</RichText>\n </label>\n )}\n {field.info && (\n <HoverInfo>\n <RichText>{field.info}</RichText>\n </HoverInfo>\n )}\n </div>\n {field.description && (\n <p\n data-p0=\"description\"\n className={classNames?.description ?? \"pz:text-xs pz:text-muted-foreground\"}\n >\n <RichText>{field.description}</RichText>\n </p>\n )}\n </div>\n )}\n {isDisabled ? (\n <div className=\"pz:opacity-60 pz:pointer-events-none\">{children}</div>\n ) : (\n children\n )}\n {isDisabled && field.disabledReason && (\n <div\n data-p0=\"disabled-reason\"\n className={\n classNames?.disabledReason ??\n \"pz:rounded-md pz:border pz:border-input pz:bg-muted/40 pz:px-3 pz:py-2 pz:text-xs pz:text-muted-foreground\"\n }\n >\n <RichText>{field.disabledReason}</RichText>\n </div>\n )}\n {hasError && (\n <span\n data-p0=\"error\"\n className={classNames?.error ?? \"pz:text-destructive pz:text-xs pz:font-medium\"}\n role=\"alert\"\n >\n <RichText>{field.error}</RichText>\n </span>\n )}\n </>\n );\n\n return useRender({\n defaultTagName: \"div\",\n render,\n state: { disabled: isDisabled, hasError },\n props: mergeProps<\"div\">(\n {\n className: cn(\n classNames?.field ?? \"pz:grid pz:gap-2\",\n isDisabled && classNames?.fieldDisabled,\n className,\n ),\n children: defaultContent,\n ...({\n \"data-p0\": \"field\",\n \"data-p0-field\": field.path,\n \"data-p0-kind\": field.kind,\n ...(isDisabled ? { \"data-p0-disabled\": \"true\", \"aria-disabled\": \"true\" } : {}),\n } as Record<string, string>),\n },\n props,\n ),\n });\n}\n"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"field-wrapper.mjs","names":[],"sources":["../../../../src/components/defaults/layout/field-wrapper.tsx"],"sourcesContent":["import { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { useFormConfig } from \"../../../context/form-context.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { AnyFieldProps } from \"../../../types/field-props.js\";\nimport { HoverInfo } from \"../../hover-info.js\";\nimport { RichText } from \"../../rich-text.js\";\n\nexport interface DefaultFieldWrapperState {\n field: AnyFieldProps;\n disabled: boolean;\n hasError: boolean;\n}\n\nexport interface DefaultFieldWrapperProps\n extends useRender.ComponentProps<\"div\", DefaultFieldWrapperState> {\n field: AnyFieldProps;\n}\n\nexport function DefaultFieldWrapper({\n field,\n children,\n className,\n render,\n ...props\n}: DefaultFieldWrapperProps) {\n const { classNames } = useFormConfig();\n const hasError = !!field.error;\n const isDisabled = field.disabled;\n\n // Boolean toggles render their label inline with the switch (settings-row\n // pattern), so the wrapper's label/description block is suppressed for them.\n const inlineLabel = field.kind === \"boolean_input\";\n\n const defaultContent = (\n <>\n {!inlineLabel && (field.label || field.description || field.info) && (\n <div className=\"pz:flex pz:flex-col pz:gap-1\">\n <div className=\"pz:flex pz:items-center pz:gap-1.5\">\n {field.label && (\n <label\n data-p0=\"label\"\n htmlFor={field.id}\n className={\n classNames?.label ??\n cn(\n \"pz:text-sm pz:leading-none pz:font-medium pz:select-none\",\n hasError && \"pz:text-destructive\",\n )\n }\n >\n <RichText>{field.label}</RichText>\n </label>\n )}\n {field.info && (\n <HoverInfo>\n <RichText>{field.info}</RichText>\n </HoverInfo>\n )}\n </div>\n {field.description && (\n <p\n data-p0=\"description\"\n className={classNames?.description ?? \"pz:text-xs pz:text-muted-foreground\"}\n >\n <RichText>{field.description}</RichText>\n </p>\n )}\n </div>\n )}\n {isDisabled ? (\n <div className=\"pz:opacity-60 pz:pointer-events-none\">{children}</div>\n ) : (\n children\n )}\n {isDisabled && field.disabledReason && (\n <div\n data-p0=\"disabled-reason\"\n className={\n classNames?.disabledReason ??\n \"pz:rounded-md pz:border pz:border-input pz:bg-muted/40 pz:px-3 pz:py-2 pz:text-xs pz:text-muted-foreground\"\n }\n >\n <RichText>{field.disabledReason}</RichText>\n </div>\n )}\n {hasError && (\n <span\n data-p0=\"error\"\n className={classNames?.error ?? \"pz:text-destructive pz:text-xs pz:font-medium\"}\n role=\"alert\"\n >\n <RichText>{field.error}</RichText>\n </span>\n )}\n </>\n );\n\n return useRender({\n defaultTagName: \"div\",\n render,\n state: { field, disabled: isDisabled, hasError },\n stateAttributesMapping: {\n field: () => null,\n },\n props: mergeProps<\"div\">(\n {\n className: cn(\n classNames?.field ?? \"pz:grid pz:gap-2\",\n isDisabled && classNames?.fieldDisabled,\n className,\n ),\n children: defaultContent,\n ...({\n \"data-p0\": \"field\",\n \"data-p0-field\": field.path,\n \"data-p0-kind\": field.kind,\n ...(isDisabled ? { \"data-p0-disabled\": \"true\", \"aria-disabled\": \"true\" } : {}),\n } as Record<string, string>),\n },\n props,\n ),\n });\n}\n"],"mappings":";;;;;;;;;AAmBA,SAAgB,oBAAoB,EAClC,OACA,UACA,WACA,QACA,GAAG,SACwB;CAC3B,MAAM,EAAE,eAAe,eAAe;CACtC,MAAM,WAAW,CAAC,CAAC,MAAM;CACzB,MAAM,aAAa,MAAM;CAMzB,MAAM,iBACJ;EACG,EAJe,MAAM,SAAS,qBAIb,MAAM,SAAS,MAAM,eAAe,MAAM,SAC1D,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,qBAAC,OAAD;IAAK,WAAU;cAAf,CACG,MAAM,SACL,oBAAC,SAAD;KACE,WAAQ;KACR,SAAS,MAAM;KACf,WACE,YAAY,SACZ,GACE,4DACA,YAAY,sBACb;eAGH,oBAAC,UAAD,YAAW,MAAM,OAAiB;KAC5B,GAET,MAAM,QACL,oBAAC,WAAD,YACE,oBAAC,UAAD,YAAW,MAAM,MAAgB,GACvB,EAEV;OACL,MAAM,eACL,oBAAC,KAAD;IACE,WAAQ;IACR,WAAW,YAAY,eAAe;cAEtC,oBAAC,UAAD,YAAW,MAAM,aAAuB;IACtC,EAEF;;EAEP,aACC,oBAAC,OAAD;GAAK,WAAU;GAAwC;GAAe,IAEtE;EAED,cAAc,MAAM,kBACnB,oBAAC,OAAD;GACE,WAAQ;GACR,WACE,YAAY,kBACZ;aAGF,oBAAC,UAAD,YAAW,MAAM,gBAA0B;GACvC;EAEP,YACC,oBAAC,QAAD;GACE,WAAQ;GACR,WAAW,YAAY,SAAS;GAChC,MAAK;aAEL,oBAAC,UAAD,YAAW,MAAM,OAAiB;GAC7B;EAER;AAGL,QAAO,UAAU;EACf,gBAAgB;EAChB;EACA,OAAO;GAAE;GAAO,UAAU;GAAY;GAAU;EAChD,wBAAwB,EACtB,aAAa,MACd;EACD,OAAO,WACL;GACE,WAAW,GACT,YAAY,SAAS,oBACrB,cAAc,YAAY,eAC1B,UACD;GACD,UAAU;GAER,WAAW;GACX,iBAAiB,MAAM;GACvB,gBAAgB,MAAM;GACtB,GAAI,aAAa;IAAE,oBAAoB;IAAQ,iBAAiB;IAAQ,GAAG,EAAE;GAEhF,EACD,MACD;EACF,CAAC"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { AnyFieldProps } from "../../../types/field-props.mjs";
|
|
1
2
|
import { FormGroupHandle } from "../../../types/form-handle.mjs";
|
|
2
3
|
import { useRender } from "@base-ui/react/use-render";
|
|
3
4
|
//#region src/components/defaults/layout/group.d.ts
|
|
4
5
|
interface DefaultGroupState {
|
|
5
6
|
expanded: boolean;
|
|
7
|
+
setExpanded: (expanded: boolean) => void;
|
|
8
|
+
fields: ReadonlyArray<AnyFieldProps>;
|
|
6
9
|
hasErrors: boolean;
|
|
7
10
|
errorCount: number;
|
|
8
11
|
setCount: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.d.mts","names":[],"sources":["../../../../src/components/defaults/layout/group.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"group.d.mts","names":[],"sources":["../../../../src/components/defaults/layout/group.tsx"],"mappings":";;;;UAaiB,iBAAA;EACf,QAAA;EACA,WAAA,GAAc,QAAA;EACd,MAAA,EAAQ,aAAA,CAAc,aAAA;EACtB,SAAA;EACA,UAAA;EACA,QAAA;EACA,UAAA;AAAA;AAAA,UAGe,iBAAA,SAA0B,SAAA,CAAU,cAAA,QAAsB,iBAAA;EACzE,KAAA,EAAO,eAAA;AAAA"}
|
|
@@ -16,7 +16,8 @@ function DefaultGroup({ group, children, className, render, ...props }) {
|
|
|
16
16
|
const { classNames } = useFormConfig();
|
|
17
17
|
const [expanded, setExpanded] = useState(group.defaultExpand);
|
|
18
18
|
const hasErrors = group.errorCount > 0;
|
|
19
|
-
const
|
|
19
|
+
const showDirty = group.dirtyCount > 0;
|
|
20
|
+
const countLabel = showDirty ? `${group.dirtyCount} modified` : group.setCount > 0 ? `${group.setCount} set` : null;
|
|
20
21
|
const defaultContent = /* @__PURE__ */ jsx(Accordion.Root, {
|
|
21
22
|
value: expanded ? [ITEM_VALUE] : [],
|
|
22
23
|
onValueChange: (next) => setExpanded(next.includes(ITEM_VALUE)),
|
|
@@ -46,7 +47,7 @@ function DefaultGroup({ group, children, className, render, ...props }) {
|
|
|
46
47
|
className: "pz:flex pz:items-center pz:gap-2",
|
|
47
48
|
children: [
|
|
48
49
|
countLabel && /* @__PURE__ */ jsx(Badge, {
|
|
49
|
-
variant: "secondary",
|
|
50
|
+
variant: showDirty ? "default" : "secondary",
|
|
50
51
|
"data-p0": "group-badge",
|
|
51
52
|
children: countLabel
|
|
52
53
|
}),
|
|
@@ -71,7 +72,7 @@ function DefaultGroup({ group, children, className, render, ...props }) {
|
|
|
71
72
|
"data-p0": "group-content",
|
|
72
73
|
className: "pz:overflow-hidden pz:border-t pz:border-border pz:data-open:animate-accordion-down pz:data-closed:animate-accordion-up",
|
|
73
74
|
children: /* @__PURE__ */ jsx("div", {
|
|
74
|
-
className: classNames?.groupContent ?? cn("pz:flex pz:flex-col pz:gap-3 pz:px-3.5 pz:pb-
|
|
75
|
+
className: classNames?.groupContent ?? cn("pz:flex pz:flex-col pz:gap-3 pz:px-3.5 pz:pb-2 pz:pt-2", "pz:h-(--accordion-panel-height) pz:data-ending-style:h-0 pz:data-starting-style:h-0"),
|
|
75
76
|
children
|
|
76
77
|
})
|
|
77
78
|
})]
|
|
@@ -82,11 +83,17 @@ function DefaultGroup({ group, children, className, render, ...props }) {
|
|
|
82
83
|
render,
|
|
83
84
|
state: {
|
|
84
85
|
expanded,
|
|
86
|
+
setExpanded,
|
|
87
|
+
fields: group.fields,
|
|
85
88
|
hasErrors,
|
|
86
89
|
errorCount: group.errorCount,
|
|
87
90
|
setCount: group.setCount,
|
|
88
91
|
dirtyCount: group.dirtyCount
|
|
89
92
|
},
|
|
93
|
+
stateAttributesMapping: {
|
|
94
|
+
setExpanded: () => null,
|
|
95
|
+
fields: () => null
|
|
96
|
+
},
|
|
90
97
|
props: mergeProps({
|
|
91
98
|
className: cn(classNames?.group ?? cn("pz:flex pz:flex-col pz:bg-card pz:border pz:border-border pz:rounded-lg pz:overflow-hidden", hasErrors && "pz:border-destructive"), className),
|
|
92
99
|
children: defaultContent,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.mjs","names":["AccordionPrimitive"],"sources":["../../../../src/components/defaults/layout/group.tsx"],"sourcesContent":["import { Accordion as AccordionPrimitive } from \"@base-ui/react/accordion\";\nimport { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { useState } from \"react\";\nimport { useFormConfig } from \"../../../context/form-context.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { FormGroupHandle } from \"../../../types/form-handle.js\";\nimport { IconGlyph } from \"../../../widgets/icon-glyph.js\";\nimport { HoverInfo } from \"../../hover-info.js\";\nimport { IconChevronDown } from \"../../internal/icons.js\";\nimport { Badge } from \"../../ui/badge.js\";\n\nexport interface DefaultGroupState {\n expanded: boolean;\n hasErrors: boolean;\n errorCount: number;\n setCount: number;\n dirtyCount: number;\n}\n\nexport interface DefaultGroupProps extends useRender.ComponentProps<\"div\", DefaultGroupState> {\n group: FormGroupHandle;\n}\n\nconst ITEM_VALUE = \"group\";\n\nexport function DefaultGroup({ group, children, className, render, ...props }: DefaultGroupProps) {\n const { classNames } = useFormConfig();\n // Track open state alongside the accordion so consumers reading\n // `state.expanded` (via render-prop) still get the right value.\n const [expanded, setExpanded] = useState(group.defaultExpand);\n const hasErrors = group.errorCount > 0;\n const showDirty = group.dirtyCount > 0;\n const countLabel = showDirty\n ? `${group.dirtyCount} modified`\n : group.setCount > 0\n ? `${group.setCount} set`\n : null;\n\n const defaultContent = (\n <AccordionPrimitive.Root\n value={expanded ? [ITEM_VALUE] : []}\n onValueChange={(next) => setExpanded(next.includes(ITEM_VALUE))}\n >\n <AccordionPrimitive.Item value={ITEM_VALUE}>\n <AccordionPrimitive.Header className=\"pz:flex\">\n <AccordionPrimitive.Trigger\n data-p0=\"group-header\"\n className={\n classNames?.groupHeader ??\n cn(\n \"pz:group/group-trigger\",\n \"pz:flex pz:items-center pz:justify-between pz:gap-4 pz:w-full\",\n \"pz:px-3.5 pz:py-2.5 pz:cursor-pointer pz:text-sm pz:font-medium pz:text-left\",\n \"pz:transition-colors pz:hover:bg-muted/60\",\n \"pz:aria-expanded:hover:bg-transparent\",\n \"pz:focus-visible:outline-none\",\n hasErrors && \"pz:text-destructive pz:bg-destructive/10\",\n )\n }\n >\n <span className=\"pz:flex pz:items-center pz:gap-2\">\n {group.iconKey && (\n <IconGlyph\n keyName={group.iconKey}\n size={14}\n className=\"pz:text-muted-foreground pz:shrink-0\"\n />\n )}\n {group.label ?? group.key}\n {group.description && (\n <span onClick={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()}>\n <HoverInfo>{group.description}</HoverInfo>\n </span>\n )}\n </span>\n <span className=\"pz:flex pz:items-center pz:gap-2\">\n {countLabel && (\n <Badge variant
|
|
1
|
+
{"version":3,"file":"group.mjs","names":["AccordionPrimitive"],"sources":["../../../../src/components/defaults/layout/group.tsx"],"sourcesContent":["import { Accordion as AccordionPrimitive } from \"@base-ui/react/accordion\";\nimport { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { useState } from \"react\";\nimport { useFormConfig } from \"../../../context/form-context.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { AnyFieldProps } from \"../../../types/field-props.js\";\nimport type { FormGroupHandle } from \"../../../types/form-handle.js\";\nimport { IconGlyph } from \"../../../widgets/icon-glyph.js\";\nimport { HoverInfo } from \"../../hover-info.js\";\nimport { IconChevronDown } from \"../../internal/icons.js\";\nimport { Badge } from \"../../ui/badge.js\";\n\nexport interface DefaultGroupState {\n expanded: boolean;\n setExpanded: (expanded: boolean) => void;\n fields: ReadonlyArray<AnyFieldProps>;\n hasErrors: boolean;\n errorCount: number;\n setCount: number;\n dirtyCount: number;\n}\n\nexport interface DefaultGroupProps extends useRender.ComponentProps<\"div\", DefaultGroupState> {\n group: FormGroupHandle;\n}\n\nconst ITEM_VALUE = \"group\";\n\nexport function DefaultGroup({ group, children, className, render, ...props }: DefaultGroupProps) {\n const { classNames } = useFormConfig();\n // Track open state alongside the accordion so consumers reading\n // `state.expanded` (via render-prop) still get the right value.\n const [expanded, setExpanded] = useState(group.defaultExpand);\n const hasErrors = group.errorCount > 0;\n const showDirty = group.dirtyCount > 0;\n const countLabel = showDirty\n ? `${group.dirtyCount} modified`\n : group.setCount > 0\n ? `${group.setCount} set`\n : null;\n\n const defaultContent = (\n <AccordionPrimitive.Root\n value={expanded ? [ITEM_VALUE] : []}\n onValueChange={(next) => setExpanded(next.includes(ITEM_VALUE))}\n >\n <AccordionPrimitive.Item value={ITEM_VALUE}>\n <AccordionPrimitive.Header className=\"pz:flex\">\n <AccordionPrimitive.Trigger\n data-p0=\"group-header\"\n className={\n classNames?.groupHeader ??\n cn(\n \"pz:group/group-trigger\",\n \"pz:flex pz:items-center pz:justify-between pz:gap-4 pz:w-full\",\n \"pz:px-3.5 pz:py-2.5 pz:cursor-pointer pz:text-sm pz:font-medium pz:text-left\",\n \"pz:transition-colors pz:hover:bg-muted/60\",\n \"pz:aria-expanded:hover:bg-transparent\",\n \"pz:focus-visible:outline-none\",\n hasErrors && \"pz:text-destructive pz:bg-destructive/10\",\n )\n }\n >\n <span className=\"pz:flex pz:items-center pz:gap-2\">\n {group.iconKey && (\n <IconGlyph\n keyName={group.iconKey}\n size={14}\n className=\"pz:text-muted-foreground pz:shrink-0\"\n />\n )}\n {group.label ?? group.key}\n {group.description && (\n <span onClick={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()}>\n <HoverInfo>{group.description}</HoverInfo>\n </span>\n )}\n </span>\n <span className=\"pz:flex pz:items-center pz:gap-2\">\n {countLabel && (\n <Badge variant={showDirty ? \"default\" : \"secondary\"} data-p0=\"group-badge\">\n {countLabel}\n </Badge>\n )}\n {hasErrors && (\n <Badge variant=\"destructive\" data-p0=\"group-error-badge\">\n {group.errorCount} {group.errorCount === 1 ? \"error\" : \"errors\"}\n </Badge>\n )}\n <IconChevronDown\n width={16}\n height={16}\n className={cn(\n \"pz:text-muted-foreground pz:transition-transform pz:duration-150\",\n \"pz:group-aria-expanded/group-trigger:rotate-180\",\n )}\n />\n </span>\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n <AccordionPrimitive.Panel\n data-p0=\"group-content\"\n // The library ships keyframes via `tw-animate-css` —\n // `animate-accordion-down` / `animate-accordion-up` plus the\n // `--accordion-panel-height` var that base-ui populates on the\n // panel give a smooth height transition without JS measuring.\n className=\"pz:overflow-hidden pz:border-t pz:border-border pz:data-open:animate-accordion-down pz:data-closed:animate-accordion-up\"\n >\n <div\n className={\n classNames?.groupContent ??\n cn(\n \"pz:flex pz:flex-col pz:gap-3 pz:px-3.5 pz:pb-2 pz:pt-2\",\n \"pz:h-(--accordion-panel-height) pz:data-ending-style:h-0 pz:data-starting-style:h-0\",\n )\n }\n >\n {children}\n </div>\n </AccordionPrimitive.Panel>\n </AccordionPrimitive.Item>\n </AccordionPrimitive.Root>\n );\n\n return useRender({\n defaultTagName: \"div\",\n render,\n state: {\n expanded,\n setExpanded,\n fields: group.fields,\n hasErrors,\n errorCount: group.errorCount,\n setCount: group.setCount,\n dirtyCount: group.dirtyCount,\n },\n stateAttributesMapping: {\n setExpanded: () => null,\n fields: () => null,\n },\n props: mergeProps<\"div\">(\n {\n className: cn(\n classNames?.group ??\n cn(\n \"pz:flex pz:flex-col pz:bg-card pz:border pz:border-border pz:rounded-lg pz:overflow-hidden\",\n hasErrors && \"pz:border-destructive\",\n ),\n className,\n ),\n children: defaultContent,\n ...({\n \"data-p0\": \"group\",\n \"data-p0-group\": group.key,\n \"data-p0-expanded\": String(expanded),\n } as Record<string, string>),\n },\n props,\n ),\n });\n}\n"],"mappings":";;;;;;;;;;;;;AA2BA,MAAM,aAAa;AAEnB,SAAgB,aAAa,EAAE,OAAO,UAAU,WAAW,QAAQ,GAAG,SAA4B;CAChG,MAAM,EAAE,eAAe,eAAe;CAGtC,MAAM,CAAC,UAAU,eAAe,SAAS,MAAM,cAAc;CAC7D,MAAM,YAAY,MAAM,aAAa;CACrC,MAAM,YAAY,MAAM,aAAa;CACrC,MAAM,aAAa,YACf,GAAG,MAAM,WAAW,aACpB,MAAM,WAAW,IACf,GAAG,MAAM,SAAS,QAClB;CAEN,MAAM,iBACJ,oBAACA,UAAmB,MAApB;EACE,OAAO,WAAW,CAAC,WAAW,GAAG,EAAE;EACnC,gBAAgB,SAAS,YAAY,KAAK,SAAS,WAAW,CAAC;YAE/D,qBAACA,UAAmB,MAApB;GAAyB,OAAO;aAAhC,CACE,oBAACA,UAAmB,QAApB;IAA2B,WAAU;cACnC,qBAACA,UAAmB,SAApB;KACE,WAAQ;KACR,WACE,YAAY,eACZ,GACE,0BACA,iEACA,gFACA,6CACA,yCACA,iCACA,aAAa,2CACd;eAZL,CAeE,qBAAC,QAAD;MAAM,WAAU;gBAAhB;OACG,MAAM,WACL,oBAAC,WAAD;QACE,SAAS,MAAM;QACf,MAAM;QACN,WAAU;QACV;OAEH,MAAM,SAAS,MAAM;OACrB,MAAM,eACL,oBAAC,QAAD;QAAM,UAAU,MAAM,EAAE,iBAAiB;QAAE,YAAY,MAAM,EAAE,iBAAiB;kBAC9E,oBAAC,WAAD,YAAY,MAAM,aAAwB;QACrC;OAEJ;SACP,qBAAC,QAAD;MAAM,WAAU;gBAAhB;OACG,cACC,oBAAC,OAAD;QAAO,SAAS,YAAY,YAAY;QAAa,WAAQ;kBAC1D;QACK;OAET,aACC,qBAAC,OAAD;QAAO,SAAQ;QAAc,WAAQ;kBAArC;SACG,MAAM;SAAW;SAAE,MAAM,eAAe,IAAI,UAAU;SACjD;;OAEV,oBAAC,iBAAD;QACE,OAAO;QACP,QAAQ;QACR,WAAW,GACT,oEACA,kDACD;QACD;OACG;QACoB;;IACH,GAC5B,oBAACA,UAAmB,OAApB;IACE,WAAQ;IAKR,WAAU;cAEV,oBAAC,OAAD;KACE,WACE,YAAY,gBACZ,GACE,0DACA,sFACD;KAGF;KACG;IACmB,EACH;;EACF;AAG5B,QAAO,UAAU;EACf,gBAAgB;EAChB;EACA,OAAO;GACL;GACA;GACA,QAAQ,MAAM;GACd;GACA,YAAY,MAAM;GAClB,UAAU,MAAM;GAChB,YAAY,MAAM;GACnB;EACD,wBAAwB;GACtB,mBAAmB;GACnB,cAAc;GACf;EACD,OAAO,WACL;GACE,WAAW,GACT,YAAY,SACV,GACE,8FACA,aAAa,wBACd,EACH,UACD;GACD,UAAU;GAER,WAAW;GACX,iBAAiB,MAAM;GACvB,oBAAoB,OAAO,SAAS;GAEvC,EACD,MACD;EACF,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { FormSectionHandle } from "../../../types/form-handle.mjs";
|
|
1
|
+
import { FormGroupHandle, FormSectionHandle } from "../../../types/form-handle.mjs";
|
|
2
2
|
import { useRender } from "@base-ui/react/use-render";
|
|
3
3
|
//#region src/components/defaults/layout/section.d.ts
|
|
4
4
|
interface DefaultSectionState {
|
|
5
|
+
groups: ReadonlyArray<FormGroupHandle>;
|
|
5
6
|
hasErrors: boolean;
|
|
6
7
|
}
|
|
7
8
|
interface DefaultSectionProps extends useRender.ComponentProps<"div", DefaultSectionState> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section.d.mts","names":[],"sources":["../../../../src/components/defaults/layout/section.tsx"],"mappings":";;;UAMiB,mBAAA;EACf,SAAA;AAAA;AAAA,UAGe,mBAAA,SAA4B,SAAA,CAAU,cAAA,QAAsB,mBAAA;EAC3E,OAAA,EAAS,iBAAA
|
|
1
|
+
{"version":3,"file":"section.d.mts","names":[],"sources":["../../../../src/components/defaults/layout/section.tsx"],"mappings":";;;UAMiB,mBAAA;EACf,MAAA,EAAQ,aAAA,CAAc,eAAA;EACtB,SAAA;AAAA;AAAA,UAGe,mBAAA,SAA4B,SAAA,CAAU,cAAA,QAAsB,mBAAA;EAC3E,OAAA,EAAS,iBAAA;EALY;;;;;;EAYrB,SAAA;AAAA"}
|
|
@@ -10,7 +10,7 @@ function DefaultSection({ section, children, className, render, hideLabel, ...pr
|
|
|
10
10
|
const hasErrors = section.groups.some((g) => g.errorCount > 0);
|
|
11
11
|
const defaultContent = /* @__PURE__ */ jsxs(Fragment, { children: [!hideLabel && section.label && /* @__PURE__ */ jsxs("div", {
|
|
12
12
|
"data-p0": "section-header",
|
|
13
|
-
className: classNames?.sectionLabel ?? "pz:flex pz:items-center pz:gap-2.5 pz:px-1",
|
|
13
|
+
className: classNames?.sectionLabel ?? "pz:flex pz:items-center pz:gap-2.5 pz:px-1 mb-0.5 mt-2 pz:select-none",
|
|
14
14
|
children: [/* @__PURE__ */ jsx("h2", {
|
|
15
15
|
className: cn("pz:text-[10.5px] pz:font-medium pz:tracking-[0.12em] pz:uppercase pz:text-muted-foreground pz:m-0 pz:whitespace-nowrap"),
|
|
16
16
|
children: section.label
|
|
@@ -22,7 +22,11 @@ function DefaultSection({ section, children, className, render, hideLabel, ...pr
|
|
|
22
22
|
return useRender({
|
|
23
23
|
defaultTagName: "div",
|
|
24
24
|
render,
|
|
25
|
-
state: {
|
|
25
|
+
state: {
|
|
26
|
+
groups: section.groups,
|
|
27
|
+
hasErrors
|
|
28
|
+
},
|
|
29
|
+
stateAttributesMapping: { groups: () => null },
|
|
26
30
|
props: mergeProps({
|
|
27
31
|
className: cn(classNames?.section ?? "pz:flex pz:flex-col pz:gap-2", className),
|
|
28
32
|
children: defaultContent,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section.mjs","names":[],"sources":["../../../../src/components/defaults/layout/section.tsx"],"sourcesContent":["import { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { useFormConfig } from \"../../../context/form-context.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { FormSectionHandle } from \"../../../types/form-handle.js\";\n\nexport interface DefaultSectionState {\n hasErrors: boolean;\n}\n\nexport interface DefaultSectionProps extends useRender.ComponentProps<\"div\", DefaultSectionState> {\n section: FormSectionHandle;\n /**\n * Suppress the section's own header. Set when several consecutive sections\n * share an umbrella label so the label only renders above the first\n * section in the cluster (the renderer in `pipe-form/content.tsx` and\n * `search-form/content.tsx` handles this automatically).\n */\n hideLabel?: boolean;\n}\n\nexport function DefaultSection({\n section,\n children,\n className,\n render,\n hideLabel,\n ...props\n}: DefaultSectionProps) {\n const { classNames } = useFormConfig();\n const hasErrors = section.groups.some((g) => g.errorCount > 0);\n\n // Section descriptions are intentionally not rendered — the umbrella label\n // alone is enough signal, and per-section descriptions add noise once\n // multiple sections sit under one umbrella. Field-level descriptions cover\n // the cases where copy is actually load-bearing.\n const defaultContent = (\n <>\n {!hideLabel && section.label && (\n <div\n data-p0=\"section-header\"\n className={classNames?.sectionLabel
|
|
1
|
+
{"version":3,"file":"section.mjs","names":[],"sources":["../../../../src/components/defaults/layout/section.tsx"],"sourcesContent":["import { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { useFormConfig } from \"../../../context/form-context.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { FormGroupHandle, FormSectionHandle } from \"../../../types/form-handle.js\";\n\nexport interface DefaultSectionState {\n groups: ReadonlyArray<FormGroupHandle>;\n hasErrors: boolean;\n}\n\nexport interface DefaultSectionProps extends useRender.ComponentProps<\"div\", DefaultSectionState> {\n section: FormSectionHandle;\n /**\n * Suppress the section's own header. Set when several consecutive sections\n * share an umbrella label so the label only renders above the first\n * section in the cluster (the renderer in `pipe-form/content.tsx` and\n * `search-form/content.tsx` handles this automatically).\n */\n hideLabel?: boolean;\n}\n\nexport function DefaultSection({\n section,\n children,\n className,\n render,\n hideLabel,\n ...props\n}: DefaultSectionProps) {\n const { classNames } = useFormConfig();\n const hasErrors = section.groups.some((g) => g.errorCount > 0);\n\n // Section descriptions are intentionally not rendered — the umbrella label\n // alone is enough signal, and per-section descriptions add noise once\n // multiple sections sit under one umbrella. Field-level descriptions cover\n // the cases where copy is actually load-bearing.\n const defaultContent = (\n <>\n {!hideLabel && section.label && (\n <div\n data-p0=\"section-header\"\n className={\n classNames?.sectionLabel ??\n \"pz:flex pz:items-center pz:gap-2.5 pz:px-1 mb-0.5 mt-2 pz:select-none\"\n }\n >\n <h2\n className={cn(\n \"pz:text-[10.5px] pz:font-medium pz:tracking-[0.12em] pz:uppercase pz:text-muted-foreground pz:m-0 pz:whitespace-nowrap\",\n )}\n >\n {section.label}\n </h2>\n <span aria-hidden className=\"pz:flex-1 pz:h-px pz:bg-border\" />\n </div>\n )}\n {children}\n </>\n );\n\n return useRender({\n defaultTagName: \"div\",\n render,\n state: { groups: section.groups, hasErrors },\n stateAttributesMapping: {\n groups: () => null,\n },\n props: mergeProps<\"div\">(\n {\n className: cn(classNames?.section ?? \"pz:flex pz:flex-col pz:gap-2\", className),\n children: defaultContent,\n ...({\n \"data-p0\": \"section\",\n \"data-p0-section\": section.key,\n } as Record<string, string>),\n },\n props,\n ),\n });\n}\n"],"mappings":";;;;;;;AAsBA,SAAgB,eAAe,EAC7B,SACA,UACA,WACA,QACA,WACA,GAAG,SACmB;CACtB,MAAM,EAAE,eAAe,eAAe;CACtC,MAAM,YAAY,QAAQ,OAAO,MAAM,MAAM,EAAE,aAAa,EAAE;CAM9D,MAAM,iBACJ,4CACG,CAAC,aAAa,QAAQ,SACrB,qBAAC,OAAD;EACE,WAAQ;EACR,WACE,YAAY,gBACZ;YAJJ,CAOE,oBAAC,MAAD;GACE,WAAW,GACT,yHACD;aAEA,QAAQ;GACN,GACL,oBAAC,QAAD;GAAM;GAAY,WAAU;GAAmC,EAC3D;KAEP,SACA;AAGL,QAAO,UAAU;EACf,gBAAgB;EAChB;EACA,OAAO;GAAE,QAAQ,QAAQ;GAAQ;GAAW;EAC5C,wBAAwB,EACtB,cAAc,MACf;EACD,OAAO,WACL;GACE,WAAW,GAAG,YAAY,WAAW,gCAAgC,UAAU;GAC/E,UAAU;GAER,WAAW;GACX,mBAAmB,QAAQ;GAE9B,EACD,MACD;EACF,CAAC"}
|
|
@@ -5,7 +5,7 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
|
|
|
5
5
|
|
|
6
6
|
//#region src/components/ui/button.d.ts
|
|
7
7
|
declare const buttonVariants: (props?: ({
|
|
8
|
-
variant?: "
|
|
8
|
+
variant?: "link" | "default" | "outline" | "secondary" | "ghost" | "destructive" | null | undefined;
|
|
9
9
|
size?: "default" | "icon" | "xs" | "sm" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
10
10
|
} & _$class_variance_authority_types0.ClassProp) | undefined) => string;
|
|
11
11
|
declare function Button$1({
|
|
@@ -23,16 +23,6 @@ interface CatalogProviderProps {
|
|
|
23
23
|
components?: CatalogComponentOverrides;
|
|
24
24
|
children: ReactNode;
|
|
25
25
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Provides customization to the catalog component tree. Nests — inner
|
|
28
|
-
* providers override outer keys.
|
|
29
|
-
*
|
|
30
|
-
* ```tsx
|
|
31
|
-
* <CatalogProvider classNames={{ card: "shadow-lg" }}>
|
|
32
|
-
* <PipeCatalog />
|
|
33
|
-
* </CatalogProvider>
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
26
|
declare function CatalogProvider({
|
|
37
27
|
classNames,
|
|
38
28
|
components,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-config-context.d.mts","names":[],"sources":["../../src/context/catalog-config-context.tsx"],"mappings":";;;;;UAIiB,aAAA;EACf,UAAA,GAAa,iBAAA;EACb,UAAA,GAAa,yBAAA;AAAA;AAAA,iBAKC,gBAAA,CAAA,GAAoB,aAAA;;;;;;iBASpB,WAAA,CAAA;EAAc;AAAA;EAAc,QAAA,EAAU,SAAA;AAAA,IAAW,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,UAIhD,oBAAA;EACf,UAAA,GAAa,iBAAA;EACb,UAAA,GAAa,yBAAA;EACb,QAAA,EAAU,SAAA;AAAA;
|
|
1
|
+
{"version":3,"file":"catalog-config-context.d.mts","names":[],"sources":["../../src/context/catalog-config-context.tsx"],"mappings":";;;;;UAIiB,aAAA;EACf,UAAA,GAAa,iBAAA;EACb,UAAA,GAAa,yBAAA;AAAA;AAAA,iBAKC,gBAAA,CAAA,GAAoB,aAAA;;;;;;iBASpB,WAAA,CAAA;EAAc;AAAA;EAAc,QAAA,EAAU,SAAA;AAAA,IAAW,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,UAIhD,oBAAA;EACf,UAAA,GAAa,iBAAA;EACb,UAAA,GAAa,yBAAA;EACb,QAAA,EAAU,SAAA;AAAA;AAAA,iBAGI,eAAA,CAAA;EAAkB,UAAA;EAAY,UAAA;EAAY;AAAA,GAAY,oBAAA,GAAoB,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -15,16 +15,6 @@ function useCatalogConfig() {
|
|
|
15
15
|
function CatalogRoot({ children }) {
|
|
16
16
|
return /* @__PURE__ */ jsx(TooltipProvider, { children });
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Provides customization to the catalog component tree. Nests — inner
|
|
20
|
-
* providers override outer keys.
|
|
21
|
-
*
|
|
22
|
-
* ```tsx
|
|
23
|
-
* <CatalogProvider classNames={{ card: "shadow-lg" }}>
|
|
24
|
-
* <PipeCatalog />
|
|
25
|
-
* </CatalogProvider>
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
18
|
function CatalogProvider({ classNames, components, children }) {
|
|
29
19
|
const parent = useCatalogConfig();
|
|
30
20
|
const merged = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-config-context.mjs","names":[],"sources":["../../src/context/catalog-config-context.tsx"],"sourcesContent":["import { createContext, type ReactNode, useContext } from \"react\";\nimport { TooltipProvider } from \"../components/ui/tooltip.js\";\nimport type { CatalogClassNames, CatalogComponentOverrides } from \"../types/catalog-adapters.js\";\n\nexport interface CatalogConfig {\n classNames?: CatalogClassNames;\n components?: CatalogComponentOverrides;\n}\n\nconst CatalogConfigContext = createContext<CatalogConfig>({});\n\nexport function useCatalogConfig(): CatalogConfig {\n return useContext(CatalogConfigContext);\n}\n\n/**\n * Root-level providers required by any catalog component tree (tooltips, etc.).\n * Always mounted by `<PipeCatalog>` / `<SearchCatalog>` / `<SearchesCatalog>`\n * at the outermost layer.\n */\nexport function CatalogRoot({ children }: { children: ReactNode }) {\n return <TooltipProvider>{children}</TooltipProvider>;\n}\n\nexport interface CatalogProviderProps {\n classNames?: CatalogClassNames;\n components?: CatalogComponentOverrides;\n children: ReactNode;\n}\n\
|
|
1
|
+
{"version":3,"file":"catalog-config-context.mjs","names":[],"sources":["../../src/context/catalog-config-context.tsx"],"sourcesContent":["import { createContext, type ReactNode, useContext } from \"react\";\nimport { TooltipProvider } from \"../components/ui/tooltip.js\";\nimport type { CatalogClassNames, CatalogComponentOverrides } from \"../types/catalog-adapters.js\";\n\nexport interface CatalogConfig {\n classNames?: CatalogClassNames;\n components?: CatalogComponentOverrides;\n}\n\nconst CatalogConfigContext = createContext<CatalogConfig>({});\n\nexport function useCatalogConfig(): CatalogConfig {\n return useContext(CatalogConfigContext);\n}\n\n/**\n * Root-level providers required by any catalog component tree (tooltips, etc.).\n * Always mounted by `<PipeCatalog>` / `<SearchCatalog>` / `<SearchesCatalog>`\n * at the outermost layer.\n */\nexport function CatalogRoot({ children }: { children: ReactNode }) {\n return <TooltipProvider>{children}</TooltipProvider>;\n}\n\nexport interface CatalogProviderProps {\n classNames?: CatalogClassNames;\n components?: CatalogComponentOverrides;\n children: ReactNode;\n}\n\nexport function CatalogProvider({ classNames, components, children }: CatalogProviderProps) {\n const parent = useCatalogConfig();\n const merged: CatalogConfig = {\n classNames: { ...parent.classNames, ...classNames },\n components: { ...parent.components, ...components },\n };\n return <CatalogConfigContext.Provider value={merged}>{children}</CatalogConfigContext.Provider>;\n}\n"],"mappings":";;;;;AASA,MAAM,uBAAuB,cAA6B,EAAE,CAAC;AAE7D,SAAgB,mBAAkC;AAChD,QAAO,WAAW,qBAAqB;;;;;;;AAQzC,SAAgB,YAAY,EAAE,YAAqC;AACjE,QAAO,oBAAC,iBAAD,EAAkB,UAA2B;;AAStD,SAAgB,gBAAgB,EAAE,YAAY,YAAY,YAAkC;CAC1F,MAAM,SAAS,kBAAkB;CACjC,MAAM,SAAwB;EAC5B,YAAY;GAAE,GAAG,OAAO;GAAY,GAAG;GAAY;EACnD,YAAY;GAAE,GAAG,OAAO;GAAY,GAAG;GAAY;EACpD;AACD,QAAO,oBAAC,qBAAqB,UAAtB;EAA+B,OAAO;EAAS;EAAyC"}
|
package/dist/index.mjs
CHANGED
|
@@ -33,6 +33,7 @@ import { PricingBadge } from "./widgets/pricing-badge.mjs";
|
|
|
33
33
|
import { ProviderLogo } from "./widgets/provider-logo.mjs";
|
|
34
34
|
import { WidgetView } from "./widgets/widget-view.mjs";
|
|
35
35
|
import { WidgetStrip } from "./widgets/widget-strip.mjs";
|
|
36
|
+
import { AvatarGroup } from "./widgets/avatar-group.mjs";
|
|
36
37
|
import { defaultAdapters } from "./components/defaults/adapters/index.mjs";
|
|
37
38
|
import { FieldRenderer } from "./components/field-renderer.mjs";
|
|
38
39
|
import { PipeFormField } from "./components/compound/pipe-form/field.mjs";
|
|
@@ -86,7 +87,6 @@ import { SearchesCatalog } from "./components/compound/searches-catalog/root.mjs
|
|
|
86
87
|
import { SearchesCatalogTagFilter } from "./components/compound/searches-catalog/tag-filter.mjs";
|
|
87
88
|
import { CatalogCopyId, CatalogCreditBadge, CatalogDocsBadge, CatalogFieldBadge } from "./components/defaults/catalog/card-derived.mjs";
|
|
88
89
|
import { CatalogCategorySection } from "./components/defaults/catalog/category-section.mjs";
|
|
89
|
-
import { AvatarGroup } from "./widgets/avatar-group.mjs";
|
|
90
90
|
import { CatalogProviderAvatars } from "./components/defaults/catalog/provider-avatars.mjs";
|
|
91
91
|
|
|
92
92
|
export { AvatarGroup, CatalogCard, CatalogCardBadge, CatalogCardBadges, CatalogCardDescription, CatalogCardHeader, CatalogCardTitle, CatalogCategorySection, CatalogCopyId, CatalogCreditBadge, CatalogDocsBadge, CatalogFieldBadge, CatalogProvider, CatalogProviderAvatars, CatalogRoot, EmojiGlyph, FieldRenderer, FieldTypeBadge, FormProvider, FormRoot, IconGlyph, LogoUrl, PipeCatalog, PipeCatalogActiveFilters, PipeCatalogCard, PipeCatalogCardContext, PipeCatalogCategoryFilter, PipeCatalogColumnFilter, PipeCatalogColumnFilters, PipeCatalogContext, PipeCatalogEmpty, PipeCatalogInputFieldFilter, PipeCatalogList, PipeCatalogOutputFieldFilter, PipeCatalogProviderFilter, PipeCatalogSearchFilter, PipeCatalogTagFilter, PipeForm, PipeFormContent, PipeFormContext, PipeFormErrors, PipeFormField, PipeFormFooter, PipeFormGroup, PipeFormHeader, PipeFormSection, PipeFormSubmitButton, PipeFormTitle, PricingBadge, ProviderLogo, SearchCatalog, SearchCatalogActiveFilters, SearchCatalogCard, SearchCatalogCardContext, SearchCatalogCategoryFilter, SearchCatalogColumnFilter, SearchCatalogColumnFilters, SearchCatalogContext, SearchCatalogEmpty, SearchCatalogList, SearchCatalogOutputFieldFilter, SearchCatalogProviderFilter, SearchCatalogSearchFilter, SearchCatalogTagFilter, SearchForm, SearchFormContent, SearchFormContext, SearchFormErrors, SearchFormField, SearchFormFooter, SearchFormGroup, SearchFormHeader, SearchFormSection, SearchFormSubmitButton, SearchFormTitle, SearchesCatalog, SearchesCatalogActiveFilters, SearchesCatalogCard, SearchesCatalogCardContext, SearchesCatalogCategoryFilter, SearchesCatalogColumnFilter, SearchesCatalogColumnFilters, SearchesCatalogContext, SearchesCatalogEmpty, SearchesCatalogList, SearchesCatalogOutputFieldFilter, SearchesCatalogProviderFilter, SearchesCatalogSearchFilter, SearchesCatalogTagFilter, WidgetStrip, WidgetView, defaultAdapters, fuzzyFilter, getFieldStatusIcon, getFieldTypeIcon, useCatalogConfig, useFieldError, usePipeCatalogCard, usePipeCatalogContext, usePipeCatalogTable, usePipeForm, usePipeFormContext, usePortalContainer, useSearchCatalogCard, useSearchCatalogContext, useSearchCatalogTable, useSearchForm, useSearchFormContext, useSearchesCatalogCard, useSearchesCatalogContext, useSearchesCatalogTable };
|