@pipe0/react 0.0.7 → 0.0.9
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/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/group.mjs +4 -3
- package/dist/components/defaults/layout/group.mjs.map +1 -1
- package/dist/components/defaults/layout/section.mjs +1 -1
- 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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @pipe0/elements-react
|
|
2
2
|
|
|
3
|
+
## 0.0.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- v1 preparations
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @pipe0/base@0.0.9
|
|
10
|
+
|
|
11
|
+
## 0.0.8
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Update billing info
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
- @pipe0/base@0.0.8
|
|
18
|
+
|
|
3
19
|
## 0.0.7
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connector-input.mjs","names":[],"sources":["../../../../src/components/defaults/adapters/connector-input.tsx"],"sourcesContent":["import type { ProviderName } from \"@pipe0/base\";\nimport { useMemo } from \"react\";\nimport { useFieldError } from \"../../../hooks/use-field-error.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { FieldHandle } from \"../../../types/field-handle.js\";\nimport { ProviderLogo } from \"../../../widgets/provider-logo.js\";\nimport { SuggestCombobox } from \"../../internal/combobox/suggest-combobox.js\";\nimport { IconPlus } from \"../../internal/icons.js\";\nimport { Button } from \"../../ui/button.js\";\n\nexport function ConnectorInputAdapter(field: FieldHandle<\"connector_input\">) {\n const connections = field.meta.filteredConnections ?? [];\n const value = field.value ?? null;\n const current = value?.connections ?? [];\n const error = useFieldError(field.form, field.path);\n const hasError = !!error;\n\n const options = useMemo(\n () =>\n connections.map((c) => ({\n value: c.connection,\n label: c.connection,\n })),\n [connections],\n );\n\n const providerByConnection = useMemo(() => {\n const map = new Map<string, string>();\n for (const c of connections) map.set(c.connection, c.provider);\n return map;\n }, [connections]);\n\n const renderLogo = (connectionId: string) => {\n const provider = providerByConnection.get(connectionId);\n if (!provider) return null;\n return <ProviderLogo provider={provider as ProviderName} size={16} />;\n };\n\n if (field.meta.connectorMode === \"disabled\") {\n return (\n <div\n data-p0=\"input\"\n className=\"pz:flex pz:items-center pz:rounded-md pz:border pz:border-input pz:bg-muted pz:px-3 pz:py-2 pz:opacity-60\"\n >\n <span className=\"pz:text-sm pz:text-muted-foreground\">\n Custom connections are not supported for this pipe.\n </span>\n </div>\n );\n }\n\n if (connections.length === 0) {\n return (\n <div\n data-p0=\"input\"\n className=\"pz:flex pz:flex-col pz:gap-2 pz:rounded-md pz:border pz:border-input pz:bg-transparent pz:px-3 pz:py-2\"\n >\n <span className=\"pz:text-xs pz:text-muted-foreground\">No connections available.</span>\n </div>\n );\n }\n\n if (value == null) {\n return (\n <div data-p0=\"input\" className=\"pz:flex pz:items-center\">\n <Button\n type=\"button\"\n variant=\"link\"\n size=\"xs\"\n onClick={() => field.setValue({ connections: [] })}\n >\n <IconPlus />\n Add custom connection\n </Button>\n </div>\n );\n }\n\n return (\n <div data-p0=\"input\" className=\"pz:flex pz:flex-col pz:gap-1\">\n <div className={cn(hasError && \"pz:[&_[data-slot=combobox-chips]]:border-destructive\")}>\n <SuggestCombobox\n value={current.map((c) => c.connection)}\n onChange={(next) =>\n field.setValue({\n ...value,\n connections: next.map((connection) => ({\n type: \"vault\",\n connection,\n })),\n })\n }\n options={options}\n iconFor={renderLogo}\n ariaInvalid={hasError}\n placeholder=\"Select a connection\"\n />\n </div>\n <div className=\"pz:flex pz:items-center pz:justify-end\">\n <Button type=\"button\" variant=\"link\" size=\"xs\" onClick={() => field.setValue(null)}>\n Reset\n </Button>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAUA,SAAgB,sBAAsB,OAAuC;CAC3E,MAAM,cAAc,MAAM,KAAK,uBAAuB,EAAE;CACxD,MAAM,QAAQ,MAAM,SAAS;CAC7B,MAAM,UAAU,OAAO,eAAe,EAAE;CAExC,MAAM,WAAW,CAAC,CADJ,cAAc,MAAM,MAAM,MAAM,KAAK;CAGnD,MAAM,UAAU,cAEZ,YAAY,KAAK,OAAO;EACtB,OAAO,EAAE;EACT,OAAO,EAAE;EACV,EAAE,EACL,CAAC,YAAY,CACd;CAED,MAAM,uBAAuB,cAAc;EACzC,MAAM,sBAAM,IAAI,KAAqB;AACrC,OAAK,MAAM,KAAK,YAAa,KAAI,IAAI,EAAE,YAAY,EAAE,SAAS;AAC9D,SAAO;IACN,CAAC,YAAY,CAAC;CAEjB,MAAM,cAAc,iBAAyB;EAC3C,MAAM,WAAW,qBAAqB,IAAI,aAAa;AACvD,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO,oBAAC,cAAD;GAAwB;GAA0B,MAAM;GAAM;;AAGvE,KAAI,MAAM,KAAK,kBAAkB,WAC/B,QACE,oBAAC,OAAD;EACE,WAAQ;EACR,WAAU;YAEV,oBAAC,QAAD;GAAM,WAAU;aAAsC;GAE/C;EACH;AAIV,KAAI,YAAY,WAAW,EACzB,QACE,oBAAC,OAAD;EACE,WAAQ;EACR,WAAU;YAEV,oBAAC,QAAD;GAAM,WAAU;aAAsC;GAAgC;EAClF;AAIV,KAAI,SAAS,KACX,QACE,oBAAC,OAAD;EAAK,WAAQ;EAAQ,WAAU;YAC7B,qBAAC,QAAD;GACE,MAAK;GACL,SAAQ;GACR,MAAK;GACL,eAAe,MAAM,SAAS,EAAE,aAAa,EAAE,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"connector-input.mjs","names":[],"sources":["../../../../src/components/defaults/adapters/connector-input.tsx"],"sourcesContent":["import type { ProviderName } from \"@pipe0/base\";\nimport { useMemo } from \"react\";\nimport { useFieldError } from \"../../../hooks/use-field-error.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { FieldHandle } from \"../../../types/field-handle.js\";\nimport { ProviderLogo } from \"../../../widgets/provider-logo.js\";\nimport { SuggestCombobox } from \"../../internal/combobox/suggest-combobox.js\";\nimport { IconPlus } from \"../../internal/icons.js\";\nimport { Button } from \"../../ui/button.js\";\n\nexport function ConnectorInputAdapter(field: FieldHandle<\"connector_input\">) {\n const connections = field.meta.filteredConnections ?? [];\n const value = field.value ?? null;\n const current = value?.connections ?? [];\n const error = useFieldError(field.form, field.path);\n const hasError = !!error;\n\n const options = useMemo(\n () =>\n connections.map((c) => ({\n value: c.connection,\n label: c.connection,\n })),\n [connections],\n );\n\n const providerByConnection = useMemo(() => {\n const map = new Map<string, string>();\n for (const c of connections) map.set(c.connection, c.provider);\n return map;\n }, [connections]);\n\n const renderLogo = (connectionId: string) => {\n const provider = providerByConnection.get(connectionId);\n if (!provider) return null;\n return <ProviderLogo provider={provider as ProviderName} size={16} />;\n };\n\n if (field.meta.connectorMode === \"disabled\") {\n return (\n <div\n data-p0=\"input\"\n className=\"pz:flex pz:items-center pz:rounded-md pz:border pz:border-input pz:bg-muted pz:px-3 pz:py-2 pz:opacity-60\"\n >\n <span className=\"pz:text-sm pz:text-muted-foreground\">\n Custom connections are not supported for this pipe.\n </span>\n </div>\n );\n }\n\n if (connections.length === 0) {\n return (\n <div\n data-p0=\"input\"\n className=\"pz:flex pz:flex-col pz:gap-2 pz:rounded-md pz:border pz:border-input pz:bg-transparent pz:px-3 pz:py-2\"\n >\n <span className=\"pz:text-xs pz:text-muted-foreground\">No connections available.</span>\n </div>\n );\n }\n\n if (value == null) {\n return (\n <div data-p0=\"input\" className=\"pz:flex pz:items-center\">\n <Button\n type=\"button\"\n variant=\"link\"\n size=\"xs\"\n className=\"pz:px-0\"\n onClick={() => field.setValue({ connections: [] })}\n >\n <IconPlus />\n Add custom connection\n </Button>\n </div>\n );\n }\n\n return (\n <div data-p0=\"input\" className=\"pz:flex pz:flex-col pz:gap-1\">\n <div className={cn(hasError && \"pz:[&_[data-slot=combobox-chips]]:border-destructive\")}>\n <SuggestCombobox\n value={current.map((c) => c.connection)}\n onChange={(next) =>\n field.setValue({\n ...value,\n connections: next.map((connection) => ({\n type: \"vault\",\n connection,\n })),\n })\n }\n options={options}\n iconFor={renderLogo}\n ariaInvalid={hasError}\n placeholder=\"Select a connection\"\n />\n </div>\n <div className=\"pz:flex pz:items-center pz:justify-end\">\n <Button type=\"button\" variant=\"link\" size=\"xs\" onClick={() => field.setValue(null)}>\n Reset\n </Button>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAUA,SAAgB,sBAAsB,OAAuC;CAC3E,MAAM,cAAc,MAAM,KAAK,uBAAuB,EAAE;CACxD,MAAM,QAAQ,MAAM,SAAS;CAC7B,MAAM,UAAU,OAAO,eAAe,EAAE;CAExC,MAAM,WAAW,CAAC,CADJ,cAAc,MAAM,MAAM,MAAM,KAAK;CAGnD,MAAM,UAAU,cAEZ,YAAY,KAAK,OAAO;EACtB,OAAO,EAAE;EACT,OAAO,EAAE;EACV,EAAE,EACL,CAAC,YAAY,CACd;CAED,MAAM,uBAAuB,cAAc;EACzC,MAAM,sBAAM,IAAI,KAAqB;AACrC,OAAK,MAAM,KAAK,YAAa,KAAI,IAAI,EAAE,YAAY,EAAE,SAAS;AAC9D,SAAO;IACN,CAAC,YAAY,CAAC;CAEjB,MAAM,cAAc,iBAAyB;EAC3C,MAAM,WAAW,qBAAqB,IAAI,aAAa;AACvD,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO,oBAAC,cAAD;GAAwB;GAA0B,MAAM;GAAM;;AAGvE,KAAI,MAAM,KAAK,kBAAkB,WAC/B,QACE,oBAAC,OAAD;EACE,WAAQ;EACR,WAAU;YAEV,oBAAC,QAAD;GAAM,WAAU;aAAsC;GAE/C;EACH;AAIV,KAAI,YAAY,WAAW,EACzB,QACE,oBAAC,OAAD;EACE,WAAQ;EACR,WAAU;YAEV,oBAAC,QAAD;GAAM,WAAU;aAAsC;GAAgC;EAClF;AAIV,KAAI,SAAS,KACX,QACE,oBAAC,OAAD;EAAK,WAAQ;EAAQ,WAAU;YAC7B,qBAAC,QAAD;GACE,MAAK;GACL,SAAQ;GACR,MAAK;GACL,WAAU;GACV,eAAe,MAAM,SAAS,EAAE,aAAa,EAAE,EAAE,CAAC;aALpD,CAOE,oBAAC,UAAD,EAAY,2BAEL;;EACL;AAIV,QACE,qBAAC,OAAD;EAAK,WAAQ;EAAQ,WAAU;YAA/B,CACE,oBAAC,OAAD;GAAK,WAAW,GAAG,YAAY,uDAAuD;aACpF,oBAAC,iBAAD;IACE,OAAO,QAAQ,KAAK,MAAM,EAAE,WAAW;IACvC,WAAW,SACT,MAAM,SAAS;KACb,GAAG;KACH,aAAa,KAAK,KAAK,gBAAgB;MACrC,MAAM;MACN;MACD,EAAE;KACJ,CAAC;IAEK;IACT,SAAS;IACT,aAAa;IACb,aAAY;IACZ;GACE,GACN,oBAAC,OAAD;GAAK,WAAU;aACb,oBAAC,QAAD;IAAQ,MAAK;IAAS,SAAQ;IAAO,MAAK;IAAK,eAAe,MAAM,SAAS,KAAK;cAAE;IAE3E;GACL,EACF"}
|
|
@@ -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":";;;;;;;;;;;AAyBA,SAAS,aAAa,SAGpB;AACA,KAAI,CAAC,QAAS,QAAO;EAAE,SAAS;EAAW,SAAS;EAAW;CAC/D,MAAM,EAAE,SAAS,GAAG,SAAS;AAE7B,QAAO;EAAE,SADU,OAAO,OAAO,KAAK,CAAC,MAAM,MAAM,KAAK,KAAK,GAC9B,OAAO;EAAW;EAAS;;;;;;;;AAS5D,SAAgB,sBAAsB,OAAuC;CAC3E,MAAM,WAAqB,eAClB,MAAM,SAAS,EAAE,EAAE,KAAK,MAA4B,EAAE,SAAS,EACtE,CAAC,MAAM,MAAM,CACd;CAED,MAAM,UAAU,MAAM,WAAW,EAAE;CACnC,MAAM,gBAAgB,cAAc;EAClC,MAAM,sBAAM,IAAI,KAA6B;AAC7C,OAAK,MAAM,KAAK,QAAS,KAAI,IAAI,EAAE,OAAO,EAAE;AAC5C,SAAO;IACN,CAAC,QAAQ,CAAC;CAEb,MAAM,WAAW,MAAM,KAAK;CAC5B,MAAM,QAAQ,aAAa,UAAa,SAAS,UAAU;CAE3D,MAAM,YAAY,SAChB,MAAM,SAAS,KAAK,KAAK,cAAc,EAAE,UAAU,EAAE,CAAC;CAExD,MAAM,gBAAgB,UAAkB,SAAS,SAAS,QAAQ,MAAM,MAAM,MAAM,CAAC;CACrF,MAAM,aAAa,UAAkB;AACnC,MAAI,SAAS,SAAS,MAAM,CAAE;AAC9B,WAAS,CAAC,GAAG,UAAU,MAAM,CAAC;;CAGhC,MAAM,UAAU,WACd,UAAU,eAAe,EAAE,sBAAsB,EAAE,UAAU,GAAG,EAAE,CAAC,EACnE,UAAU,eAAe,CAC1B;CAED,MAAM,iBAAiB,UAAwB;EAC7C,MAAM,EAAE,QAAQ,SAAS;AACzB,MAAI,CAAC,QAAQ,OAAO,OAAO,KAAK,GAAI;EACpC,MAAM,OAAO,SAAS,QAAQ,OAAO,OAAO,GAAG,CAAC;EAChD,MAAM,KAAK,SAAS,QAAQ,OAAO,KAAK,GAAG,CAAC;AAC5C,MAAI,SAAS,MAAM,OAAO,GAAI;EAC9B,MAAM,OAAO,CAAC,GAAG,SAAS;EAC1B,MAAM,CAAC,SAAS,KAAK,OAAO,MAAM,EAAE;AACpC,OAAK,OAAO,IAAI,GAAG,MAAM;AACzB,WAAS,KAAK;;AAGhB,QACE,qBAAC,OAAD;EAAK,WAAQ;EAAQ,WAAU;YAA/B,CACG,SAAS,SAAS,KACjB,oBAAC,YAAD;GACW;GACT,oBAAoB;GACpB,WAAW;aAEX,oBAAC,iBAAD;IAAiB,OAAO;IAAU,UAAU;cAC1C,oBAAC,MAAD;KAAI,WAAU;eACX,SAAS,KAAK,OAAO,UAAU;MAC9B,MAAM,SAAS,cAAc,IAAI,MAAM;AACvC,aACE,oBAAC,aAAD;OAES;OACA;OACP,OAAO,QAAQ,SAAS;OACxB,SAAS,QAAQ;OACjB,gBAAgB,aAAa,MAAM;OACnC,EANK,MAML;OAEJ;KACC;IACW;GACP,GAEd,CAAC,SACA,oBAAC,oBAAD;GACW;GACT,UAAU;GACV,OAAO;GACP,aAAa,CAAC,CAAC,MAAM;GACrB,EAEA;;;AAIV,SAAS,YAAY,EACnB,OACA,OACA,OACA,SACA,YAOC;CACD,MAAM,EAAE,YAAY,WAAW,YAAY,WAAW,YAAY,eAAe,YAAY,EAC3F,IAAI,OACL,CAAC;CACF,MAAM,QAAuB;EAC3B,WAAW,YACP,eAAe,KAAK,MAAM,UAAU,EAAE,CAAC,MAAM,KAAK,MAAM,UAAU,EAAE,CAAC,UACrE;EACJ;EACA,SAAS,aAAa,KAAM;EAC7B;CAED,MAAM,EAAE,SAAS,YAAY,aAAa,QAAQ;CAClD,MAAM,aAAa,OAAO,QAAQ,EAAE,CAAC,SAAS,GAAG,IAAI;AAErD,QACE,qBAAC,MAAD;EACE,KAAK;EACE;EACP,WAAW,GACT,sFACA,4CACD;EACD,GAAI;YAPN;GASE,oBAAC,UAAD;IACE,MAAK;IACL,cAAW;IACX,WAAW,GACT,oFACA,4EACD;IACD,GAAI;cAEJ,oBAAC,kBAAD;KAAkB,OAAO;KAAI,QAAQ;KAAM;IACpC;GACR,WACC,oBAAC,QAAD;IAAM,WAAU;cACd,oBAAC,aAAD;KAAa,SAAS;KAAS,MAAM;KAAM;IACtC;GAET,oBAAC,QAAD;IAAM,WAAU;cACb;IACI;GACN,WACC,qBAAC,QAAD;IAAM,WAAU;cAAhB,CACG,QAAQ,SAAQ,MACZ;;GAET,oBAAC,QAAD;IACE;IACA,WAAW,GACT,gFACA,yEACA,iCACD;cAEA;IACI;GACP,oBAAC,UAAD;IACE,MAAK;IACL,cAAY,UAAU;IACtB,UAAU,MAAM;AACd,OAAE,iBAAiB;AACnB,eAAU;;IAEZ,WAAW,GACT,kEACA,+BACA,4EACD;cAED,oBAACA,GAAD,EAAO,WAAU,aAAc;IACxB;GACN;;;AAIT,SAAS,mBAAmB,EAC1B,SACA,UACA,OACA,eAMC;CACD,MAAM,CAAC,MAAM,WAAW,SAAS,MAAM;CACvC,MAAM,CAAC,OAAO,YAAY,SAAS,GAAG;CAEtC,MAAM,cAAc,cAAc,IAAI,IAAI,SAAS,EAAE,CAAC,SAAS,CAAC;CAChE,MAAM,YAAY,cACV,QAAQ,QAAQ,MAAM,CAAC,YAAY,IAAI,EAAE,MAAM,CAAC,EACtD,CAAC,SAAS,YAAY,CACvB;CAED,MAAM,WAAW,cAAc;EAC7B,MAAM,IAAI,MAAM,MAAM,CAAC,aAAa;AACpC,MAAI,CAAC,EAAG,QAAO;AACf,SAAO,UAAU,QACd,MAAM,EAAE,MAAM,aAAa,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC,SAAS,EAAE,CAC9E;IACA,CAAC,WAAW,MAAM,CAAC;AAEtB,KAAI,UAAU,WAAW,KAAK,SAAS,WAAW,EAChD,QACE,oBAAC,OAAD;EAAK,WAAU;YAAwD;EAEjE;AAIV,KAAI,UAAU,WAAW,EAAG,QAAO;AAEnC,QACE,qBAAC,SAAD;EACQ;EACN,eAAe,SAAS;AACtB,WAAQ,KAAK;AACb,OAAI,CAAC,KAAM,UAAS,GAAG;;YAJ3B,CAOE,qBAAC,gBAAD;GACE,gBAAc,eAAe;GAC7B,WAAW,GACT,kEACA,6CACA,gEACA,uCACA,qFACA,yCACD;aATH,CAWE,oBAAC,UAAD;IAAU,OAAO;IAAI,QAAQ;IAAM,kBAEpB;MACjB,qBAAC,gBAAD;GAAgB,OAAM;GAAQ,WAAU;aAAxC,CACE,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAACC,QAAD,EAAY,WAAU,oDAAqD,GAC3E,oBAAC,SAAD;KACE,OAAO;KACP,WAAW,MAAM,SAAS,EAAE,OAAO,MAAM;KACzC,aAAY;KAEZ;KACA,WAAU;KACV,EACE;OACN,qBAAC,MAAD;IAAI,WAAU;cAAd,CACG,SAAS,WAAW,KACnB,oBAAC,MAAD;KAAI,WAAU;eAAqE;KAE9E,GAEN,SAAS,KAAK,WAAW;KACxB,MAAM,EAAE,SAAS,YAAY,aAAa,OAAO,QAAQ;AACzD,YACE,oBAAC,MAAD;MAAuB,WAAU;gBAC/B,qBAAC,UAAD;OACE,MAAK;OACL,eAAe;AACb,cAAM,OAAO,MAAM;AACnB,gBAAQ,MAAM;AACd,iBAAS,GAAG;;OAEd,WAAW,GACT,2DACA,8CACA,sDACA,yCACD;iBAZH;QAcG,WACC,oBAAC,QAAD;SAAM,WAAU;mBACd,oBAAC,aAAD;UAAa,SAAS;UAAS,MAAM;UAAM;SACtC;QAET,oBAAC,QAAD;SAAM,WAAU;mBAAyB,OAAO;SAAa;QAC5D,WACC,qBAAC,QAAD;SAAM,WAAU;mBAAhB,CACG,QAAQ,SAAQ,MACZ;;QAEF;;MACN,EA3BI,OAAO,MA2BX;MAEP,CACC;MACU;KACT"}
|
|
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"}
|
|
@@ -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
|
})]
|
|
@@ -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 { 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
|
|
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"}
|
|
@@ -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
|
|
@@ -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 { 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={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 };
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
--pz-tracking-widest: 0.1em;
|
|
66
66
|
--pz-leading-tight: 1.25;
|
|
67
67
|
--pz-radius-md: calc(var(--p0-radius) - 2px);
|
|
68
|
-
--pz-ease-out: cubic-bezier(0, 0, 0.2, 1);
|
|
69
68
|
--pz-animate-spin: spin 1s linear infinite;
|
|
70
69
|
--pz-animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
71
70
|
--pz-blur-xs: 4px;
|
|
@@ -406,9 +405,6 @@
|
|
|
406
405
|
.pz\:w-72 {
|
|
407
406
|
width: calc(var(--pz-spacing) * 72);
|
|
408
407
|
}
|
|
409
|
-
.pz\:w-80 {
|
|
410
|
-
width: calc(var(--pz-spacing) * 80);
|
|
411
|
-
}
|
|
412
408
|
.pz\:w-auto {
|
|
413
409
|
width: auto;
|
|
414
410
|
}
|
|
@@ -500,9 +496,6 @@
|
|
|
500
496
|
.pz\:rotate-45 {
|
|
501
497
|
rotate: 45deg;
|
|
502
498
|
}
|
|
503
|
-
.pz\:rotate-180 {
|
|
504
|
-
rotate: 180deg;
|
|
505
|
-
}
|
|
506
499
|
.pz\:animate-pulse {
|
|
507
500
|
animation: var(--pz-animate-pulse);
|
|
508
501
|
}
|
|
@@ -1008,9 +1001,6 @@
|
|
|
1008
1001
|
.pz\:pt-2 {
|
|
1009
1002
|
padding-top: calc(var(--pz-spacing) * 2);
|
|
1010
1003
|
}
|
|
1011
|
-
.pz\:pt-3 {
|
|
1012
|
-
padding-top: calc(var(--pz-spacing) * 3);
|
|
1013
|
-
}
|
|
1014
1004
|
.pz\:pr-0 {
|
|
1015
1005
|
padding-right: calc(var(--pz-spacing) * 0);
|
|
1016
1006
|
}
|
|
@@ -1044,9 +1034,6 @@
|
|
|
1044
1034
|
.pz\:pb-3 {
|
|
1045
1035
|
padding-bottom: calc(var(--pz-spacing) * 3);
|
|
1046
1036
|
}
|
|
1047
|
-
.pz\:pb-3\.5 {
|
|
1048
|
-
padding-bottom: calc(var(--pz-spacing) * 3.5);
|
|
1049
|
-
}
|
|
1050
1037
|
.pz\:pl-0 {
|
|
1051
1038
|
padding-left: calc(var(--pz-spacing) * 0);
|
|
1052
1039
|
}
|
|
@@ -1255,12 +1242,6 @@
|
|
|
1255
1242
|
color: color-mix(in oklab, var(--p0-muted-foreground) 70%, transparent);
|
|
1256
1243
|
}
|
|
1257
1244
|
}
|
|
1258
|
-
.pz\:text-muted-foreground\/80 {
|
|
1259
|
-
color: var(--p0-muted-foreground);
|
|
1260
|
-
@supports (color: color-mix(in lab, red, red)) {
|
|
1261
|
-
color: color-mix(in oklab, var(--p0-muted-foreground) 80%, transparent);
|
|
1262
|
-
}
|
|
1263
|
-
}
|
|
1264
1245
|
.pz\:text-orange-700 {
|
|
1265
1246
|
color: var(--pz-color-orange-700);
|
|
1266
1247
|
}
|
|
@@ -1385,16 +1366,6 @@
|
|
|
1385
1366
|
outline-offset: 2px;
|
|
1386
1367
|
}
|
|
1387
1368
|
}
|
|
1388
|
-
.pz\:transition-\[height\,opacity\] {
|
|
1389
|
-
transition-property: height,opacity;
|
|
1390
|
-
transition-timing-function: var(--tw-ease, var(--pz-default-transition-timing-function));
|
|
1391
|
-
transition-duration: var(--tw-duration, var(--pz-default-transition-duration));
|
|
1392
|
-
}
|
|
1393
|
-
.pz\:transition-\[height\] {
|
|
1394
|
-
transition-property: height;
|
|
1395
|
-
transition-timing-function: var(--tw-ease, var(--pz-default-transition-timing-function));
|
|
1396
|
-
transition-duration: var(--tw-duration, var(--pz-default-transition-duration));
|
|
1397
|
-
}
|
|
1398
1369
|
.pz\:transition-all {
|
|
1399
1370
|
transition-property: all;
|
|
1400
1371
|
transition-timing-function: var(--tw-ease, var(--pz-default-transition-timing-function));
|
|
@@ -1426,14 +1397,6 @@
|
|
|
1426
1397
|
--tw-duration: 150ms;
|
|
1427
1398
|
transition-duration: 150ms;
|
|
1428
1399
|
}
|
|
1429
|
-
.pz\:duration-200 {
|
|
1430
|
-
--tw-duration: 200ms;
|
|
1431
|
-
transition-duration: 200ms;
|
|
1432
|
-
}
|
|
1433
|
-
.pz\:ease-out {
|
|
1434
|
-
--tw-ease: var(--pz-ease-out);
|
|
1435
|
-
transition-timing-function: var(--pz-ease-out);
|
|
1436
|
-
}
|
|
1437
1400
|
.pz\:outline-none {
|
|
1438
1401
|
--tw-outline-style: none;
|
|
1439
1402
|
outline-style: none;
|
|
@@ -1448,25 +1411,12 @@
|
|
|
1448
1411
|
.pz\:duration-150 {
|
|
1449
1412
|
animation-duration: 150ms;
|
|
1450
1413
|
}
|
|
1451
|
-
.pz\:duration-200 {
|
|
1452
|
-
animation-duration: 200ms;
|
|
1453
|
-
}
|
|
1454
|
-
.pz\:ease-out {
|
|
1455
|
-
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
|
1456
|
-
}
|
|
1457
1414
|
.pz\:not-last\:border-b {
|
|
1458
1415
|
&:not(*:last-child) {
|
|
1459
1416
|
border-bottom-style: var(--tw-border-style);
|
|
1460
1417
|
border-bottom-width: 1px;
|
|
1461
1418
|
}
|
|
1462
1419
|
}
|
|
1463
|
-
.pz\:group-hover\/prov\:opacity-100 {
|
|
1464
|
-
&:is(:where(.pz\:group\/prov):hover *) {
|
|
1465
|
-
@media (hover: hover) {
|
|
1466
|
-
opacity: 100%;
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
1420
|
.pz\:group-has-disabled\/field\:opacity-50 {
|
|
1471
1421
|
&:is(:where(.pz\:group\/field):has(*:disabled) *) {
|
|
1472
1422
|
opacity: 50%;
|
|
@@ -3935,10 +3885,6 @@
|
|
|
3935
3885
|
syntax: "*";
|
|
3936
3886
|
inherits: false;
|
|
3937
3887
|
}
|
|
3938
|
-
@property --tw-ease {
|
|
3939
|
-
syntax: "*";
|
|
3940
|
-
inherits: false;
|
|
3941
|
-
}
|
|
3942
3888
|
@property --tw-content {
|
|
3943
3889
|
syntax: "*";
|
|
3944
3890
|
initial-value: "";
|
|
@@ -4083,7 +4029,6 @@
|
|
|
4083
4029
|
--tw-ring-offset-color: #fff;
|
|
4084
4030
|
--tw-ring-offset-shadow: 0 0 #0000;
|
|
4085
4031
|
--tw-duration: initial;
|
|
4086
|
-
--tw-ease: initial;
|
|
4087
4032
|
--tw-content: "";
|
|
4088
4033
|
--tw-outline-style: solid;
|
|
4089
4034
|
--tw-backdrop-blur: initial;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pipe0/react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "React component library for building forms and catalogs powered by pipe0 pipes and searches.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "pipe0",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"lucide-react": "^0.475.0",
|
|
88
88
|
"swr": "^2.4.1",
|
|
89
89
|
"tailwind-merge": "^3.3.1",
|
|
90
|
-
"@pipe0/base": "0.0.
|
|
90
|
+
"@pipe0/base": "0.0.9"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
93
93
|
"@dnd-kit/core": "^6.3.1",
|