@panneau/fields 4.1.0 → 5.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -0
- package/dist/boolean/BooleanField.d.ts +11 -0
- package/dist/boolean/BooleanField.d.ts.map +1 -0
- package/dist/boolean/BooleanField.js +67 -0
- package/dist/boolean/BooleanField.js.map +1 -0
- package/dist/boolean/index.d.ts +2 -0
- package/dist/boolean/index.d.ts.map +1 -0
- package/dist/boolean/index.js +1 -0
- package/dist/color/ColorField.css +33 -0
- package/dist/color/ColorField.d.ts +16 -0
- package/dist/color/ColorField.d.ts.map +1 -0
- package/dist/color/ColorField.js +187 -0
- package/dist/color/ColorField.js.map +1 -0
- package/dist/color/ColorField.module.js +14 -0
- package/dist/color/ColorField.module.js.map +1 -0
- package/dist/color/index.d.ts +2 -0
- package/dist/color/index.d.ts.map +1 -0
- package/dist/color/index.js +1 -0
- package/dist/date/DateField.d.ts +16 -0
- package/dist/date/DateField.d.ts.map +1 -0
- package/dist/date/DateField.js +132 -0
- package/dist/date/DateField.js.map +1 -0
- package/dist/date/index.d.ts +2 -0
- package/dist/date/index.d.ts.map +1 -0
- package/dist/date/index.js +1 -0
- package/dist/datetime/DateTimeField.d.ts +22 -0
- package/dist/datetime/DateTimeField.d.ts.map +1 -0
- package/dist/datetime/DateTimeField.js +78 -0
- package/dist/datetime/DateTimeField.js.map +1 -0
- package/dist/datetime/index.d.ts +2 -0
- package/dist/datetime/index.d.ts.map +1 -0
- package/dist/datetime/index.js +1 -0
- package/dist/email/EmailField.d.ts +8 -0
- package/dist/email/EmailField.d.ts.map +1 -0
- package/dist/email/EmailField.js +84 -0
- package/dist/email/EmailField.js.map +1 -0
- package/dist/email/index.d.ts +2 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +1 -0
- package/dist/group/GroupField.css +14 -0
- package/dist/group/GroupField.d.ts +19 -0
- package/dist/group/GroupField.d.ts.map +1 -0
- package/dist/group/GroupField.js +140 -0
- package/dist/group/GroupField.js.map +1 -0
- package/dist/group/GroupField.module.js +8 -0
- package/dist/group/GroupField.module.js.map +1 -0
- package/dist/group/index.d.ts +2 -0
- package/dist/group/index.d.ts.map +1 -0
- package/dist/group/index.js +1 -0
- package/dist/index.d.ts +8 -12
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -134
- package/dist/locales/index.d.ts +15 -0
- package/dist/locales/index.d.ts.map +1 -0
- package/dist/locales/index.js +21 -0
- package/dist/locales/index.js.map +1 -0
- package/dist/localized/LocalizedField.css +9 -0
- package/dist/localized/LocalizedField.d.ts +36 -0
- package/dist/localized/LocalizedField.d.ts.map +1 -0
- package/dist/localized/LocalizedField.js +207 -0
- package/dist/localized/LocalizedField.js.map +1 -0
- package/dist/localized/LocalizedField.module.js +12 -0
- package/dist/localized/LocalizedField.module.js.map +1 -0
- package/dist/localized/index.d.ts +2 -0
- package/dist/localized/index.d.ts.map +1 -0
- package/dist/localized/index.js +1 -0
- package/dist/missing/MissingField.css +18 -0
- package/dist/missing/MissingField.d.ts +7 -0
- package/dist/missing/MissingField.d.ts.map +1 -0
- package/dist/missing/MissingField.js +68 -0
- package/dist/missing/MissingField.js.map +1 -0
- package/dist/missing/MissingField.module.js +14 -0
- package/dist/missing/MissingField.module.js.map +1 -0
- package/dist/number/NumberField.d.ts +23 -0
- package/dist/number/NumberField.d.ts.map +1 -0
- package/dist/number/NumberField.js +175 -0
- package/dist/number/NumberField.js.map +1 -0
- package/dist/number/index.d.ts +2 -0
- package/dist/number/index.d.ts.map +1 -0
- package/dist/number/index.js +1 -0
- package/dist/relation/RelationField.css +43 -0
- package/dist/relation/RelationField.d.ts +40 -0
- package/dist/relation/RelationField.d.ts.map +1 -0
- package/dist/relation/RelationField.js +293 -0
- package/dist/relation/RelationField.js.map +1 -0
- package/dist/relation/RelationField.module.js +20 -0
- package/dist/relation/RelationField.module.js.map +1 -0
- package/dist/relation/index.d.ts +3 -0
- package/dist/relation/index.d.ts.map +1 -0
- package/dist/relation/index.js +3 -0
- package/dist/repeater/RepeaterField.css +80 -0
- package/dist/repeater/RepeaterField.d.ts +29 -0
- package/dist/repeater/RepeaterField.d.ts.map +1 -0
- package/dist/repeater/RepeaterField.js +220 -0
- package/dist/repeater/RepeaterField.js.map +1 -0
- package/dist/repeater/RepeaterField.module.js +26 -0
- package/dist/repeater/RepeaterField.module.js.map +1 -0
- package/dist/repeater/index.d.ts +2 -0
- package/dist/repeater/index.d.ts.map +1 -0
- package/dist/repeater/index.js +1 -0
- package/dist/select/SelectField.css +5 -0
- package/dist/select/SelectField.d.ts +38 -0
- package/dist/select/SelectField.d.ts.map +1 -0
- package/dist/select/SelectField.js +434 -0
- package/dist/select/SelectField.js.map +1 -0
- package/dist/select/SelectField.module.js +8 -0
- package/dist/select/SelectField.module.js.map +1 -0
- package/dist/select/index.d.ts +2 -0
- package/dist/select/index.d.ts.map +1 -0
- package/dist/select/index.js +1 -0
- package/dist/shared/DefinitionField.d.ts +32 -0
- package/dist/shared/DefinitionField.d.ts.map +1 -0
- package/dist/shared/DefinitionField.js +153 -0
- package/dist/shared/DefinitionField.js.map +1 -0
- package/dist/shared/builtIn.d.ts +17 -0
- package/dist/shared/builtIn.d.ts.map +1 -0
- package/dist/shared/builtIn.js +52 -0
- package/dist/shared/builtIn.js.map +1 -0
- package/dist/shared/context.d.ts +55 -0
- package/dist/shared/context.d.ts.map +1 -0
- package/dist/shared/context.js +72 -0
- package/dist/shared/context.js.map +1 -0
- package/dist/shared/cx.d.ts +3 -0
- package/dist/shared/cx.d.ts.map +1 -0
- package/dist/shared/cx.js +9 -0
- package/dist/shared/cx.js.map +1 -0
- package/dist/shared/dates.d.ts +15 -0
- package/dist/shared/dates.d.ts.map +1 -0
- package/dist/shared/dates.js +49 -0
- package/dist/shared/dates.js.map +1 -0
- package/dist/shared/entry.d.ts +23 -0
- package/dist/shared/entry.d.ts.map +1 -0
- package/dist/shared/entry.js +45 -0
- package/dist/shared/entry.js.map +1 -0
- package/dist/shared/messages.d.ts +2 -0
- package/dist/shared/messages.d.ts.map +1 -0
- package/dist/shared/messages.js +1 -0
- package/dist/shared/relation.d.ts +37 -0
- package/dist/shared/relation.d.ts.map +1 -0
- package/dist/shared/relation.js +49 -0
- package/dist/shared/relation.js.map +1 -0
- package/dist/shared/types.d.ts +50 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/slug/SlugField.d.ts +24 -0
- package/dist/slug/SlugField.d.ts.map +1 -0
- package/dist/slug/SlugField.js +216 -0
- package/dist/slug/SlugField.js.map +1 -0
- package/dist/slug/index.d.ts +2 -0
- package/dist/slug/index.d.ts.map +1 -0
- package/dist/slug/index.js +1 -0
- package/dist/text/TextField.d.ts +24 -0
- package/dist/text/TextField.d.ts.map +1 -0
- package/dist/text/TextField.js +179 -0
- package/dist/text/TextField.js.map +1 -0
- package/dist/text/index.d.ts +2 -0
- package/dist/text/index.d.ts.map +1 -0
- package/dist/text/index.js +1 -0
- package/dist/textarea/TextAreaField.d.ts +14 -0
- package/dist/textarea/TextAreaField.d.ts.map +1 -0
- package/dist/textarea/TextAreaField.js +126 -0
- package/dist/textarea/TextAreaField.js.map +1 -0
- package/dist/textarea/index.d.ts +2 -0
- package/dist/textarea/index.d.ts.map +1 -0
- package/dist/textarea/index.js +1 -0
- package/dist/time/TimeField.d.ts +13 -0
- package/dist/time/TimeField.d.ts.map +1 -0
- package/dist/time/TimeField.js +49 -0
- package/dist/time/TimeField.js.map +1 -0
- package/dist/time/index.d.ts +2 -0
- package/dist/time/index.d.ts.map +1 -0
- package/dist/time/index.js +1 -0
- package/dist/url/UrlField.css +11 -0
- package/dist/url/UrlField.d.ts +16 -0
- package/dist/url/UrlField.d.ts.map +1 -0
- package/dist/url/UrlField.js +94 -0
- package/dist/url/UrlField.js.map +1 -0
- package/dist/url/UrlField.module.js +8 -0
- package/dist/url/UrlField.module.js.map +1 -0
- package/dist/url/index.d.ts +2 -0
- package/dist/url/index.d.ts.map +1 -0
- package/dist/url/index.js +1 -0
- package/package.json +108 -79
- package/assets/css/styles.css +0 -14
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { cx } from "../shared/cx.js";
|
|
2
|
+
import { getFieldProps, getRuleNumber } from "../shared/entry.js";
|
|
3
|
+
import { messages } from "../shared/messages.js";
|
|
4
|
+
import RepeaterField_module_default from "./RepeaterField.module.js";
|
|
5
|
+
import { NestedField } from "../shared/DefinitionField.js";
|
|
6
|
+
import { c } from "react/compiler-runtime";
|
|
7
|
+
import { Button, Fieldset, IconButton, Menu, MenuItem, MenuTrigger, usePanneauIntl } from "@panneau/ui";
|
|
8
|
+
import { useId } from "react";
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { ArrowDown, ArrowUp, Plus, Trash2 } from "lucide-react";
|
|
11
|
+
//#region src/repeater/RepeaterField.tsx
|
|
12
|
+
function defaults(fields) {
|
|
13
|
+
return Object.fromEntries(fields.flatMap((field) => field.default !== void 0 ? [[field.name, field.default]] : []));
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A list of items, each with the same fields, or typed blocks with the fields of their type. Items
|
|
17
|
+
* can be added, moved and removed. Each field renders at the path `<list>.<index>.<field>`. An
|
|
18
|
+
* empty list is `null`.
|
|
19
|
+
*/
|
|
20
|
+
function RepeaterField({ fields = [], types, path, name, value, onChange, onBlur, label, description, errors, disabled, readOnly, required, min = 0, max, className, labelClassName, descriptionClassName, errorsClassName, itemClassName }) {
|
|
21
|
+
const intl = usePanneauIntl();
|
|
22
|
+
const id = useId();
|
|
23
|
+
const base = path ?? name ?? "";
|
|
24
|
+
const items = value ?? [];
|
|
25
|
+
const editable = disabled !== true && readOnly !== true;
|
|
26
|
+
const canAdd = editable && (max === void 0 || items.length < max);
|
|
27
|
+
const canRemove = editable && items.length > min;
|
|
28
|
+
const set = (next) => onChange?.(next.length > 0 ? next : null);
|
|
29
|
+
const move = (from, to) => {
|
|
30
|
+
const next_0 = [...items];
|
|
31
|
+
const [moved] = next_0.splice(from, 1);
|
|
32
|
+
if (moved !== void 0) {
|
|
33
|
+
next_0.splice(to, 0, moved);
|
|
34
|
+
set(next_0);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const add = (type) => set([...items, type !== void 0 ? {
|
|
38
|
+
type: type.id,
|
|
39
|
+
...defaults(type.fields)
|
|
40
|
+
} : defaults(fields)]);
|
|
41
|
+
return /* @__PURE__ */ jsxs(Fieldset, {
|
|
42
|
+
legend: label,
|
|
43
|
+
description,
|
|
44
|
+
errors,
|
|
45
|
+
isRequired: required,
|
|
46
|
+
className,
|
|
47
|
+
legendClassName: labelClassName,
|
|
48
|
+
descriptionClassName,
|
|
49
|
+
errorsClassName,
|
|
50
|
+
children: [items.length > 0 ? /* @__PURE__ */ jsx("ol", {
|
|
51
|
+
className: RepeaterField_module_default.items,
|
|
52
|
+
children: items.map((item, index) => {
|
|
53
|
+
const type_0 = types !== void 0 ? types.find((candidate) => candidate.id === item.type) : void 0;
|
|
54
|
+
const itemFields = types !== void 0 ? type_0?.fields ?? [] : fields;
|
|
55
|
+
const number = index + 1;
|
|
56
|
+
const titleId = `${id}-${index}`;
|
|
57
|
+
return /* @__PURE__ */ jsxs("li", {
|
|
58
|
+
className: cx(RepeaterField_module_default.item, itemClassName),
|
|
59
|
+
"aria-labelledby": titleId,
|
|
60
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
61
|
+
className: RepeaterField_module_default.header,
|
|
62
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
63
|
+
id: titleId,
|
|
64
|
+
className: RepeaterField_module_default.title,
|
|
65
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
66
|
+
className: RepeaterField_module_default.index,
|
|
67
|
+
children: number
|
|
68
|
+
}), type_0?.label ?? (typeof item.type === "string" ? item.type : intl.formatMessage(messages.item, { index: number }))]
|
|
69
|
+
}), editable ? /* @__PURE__ */ jsxs("span", {
|
|
70
|
+
className: RepeaterField_module_default.tools,
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ jsx(IconButton, {
|
|
73
|
+
icon: ArrowUp,
|
|
74
|
+
size: "sm",
|
|
75
|
+
label: intl.formatMessage(messages.moveUp, { index: number }),
|
|
76
|
+
isDisabled: index === 0,
|
|
77
|
+
onPress: () => move(index, index - 1)
|
|
78
|
+
}),
|
|
79
|
+
/* @__PURE__ */ jsx(IconButton, {
|
|
80
|
+
icon: ArrowDown,
|
|
81
|
+
size: "sm",
|
|
82
|
+
label: intl.formatMessage(messages.moveDown, { index: number }),
|
|
83
|
+
isDisabled: index === items.length - 1,
|
|
84
|
+
onPress: () => move(index, index + 1)
|
|
85
|
+
}),
|
|
86
|
+
/* @__PURE__ */ jsx(IconButton, {
|
|
87
|
+
icon: Trash2,
|
|
88
|
+
size: "sm",
|
|
89
|
+
label: intl.formatMessage(messages.removeItem, { index: number }),
|
|
90
|
+
isDisabled: !canRemove,
|
|
91
|
+
onPress: () => set(items.filter((_, i) => i !== index))
|
|
92
|
+
})
|
|
93
|
+
]
|
|
94
|
+
}) : null]
|
|
95
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
96
|
+
className: RepeaterField_module_default.body,
|
|
97
|
+
children: itemFields.map((field) => /* @__PURE__ */ jsx(NestedField, {
|
|
98
|
+
field,
|
|
99
|
+
path: `${base}.${index}.${field.name}`,
|
|
100
|
+
value: item[field.name],
|
|
101
|
+
onChange: (next_1) => set(items.map((current, i_0) => i_0 === index ? {
|
|
102
|
+
...current,
|
|
103
|
+
[field.name]: next_1
|
|
104
|
+
} : current)),
|
|
105
|
+
...onBlur !== void 0 ? { onBlur } : {},
|
|
106
|
+
parentValue: item,
|
|
107
|
+
...disabled !== void 0 ? { disabled } : {},
|
|
108
|
+
...readOnly !== void 0 ? { readOnly } : {}
|
|
109
|
+
}, field.name))
|
|
110
|
+
})]
|
|
111
|
+
}, index);
|
|
112
|
+
})
|
|
113
|
+
}) : /* @__PURE__ */ jsx("p", {
|
|
114
|
+
className: RepeaterField_module_default.empty,
|
|
115
|
+
children: intl.formatMessage(messages.noItems)
|
|
116
|
+
}), editable ? /* @__PURE__ */ jsx("div", {
|
|
117
|
+
className: RepeaterField_module_default.footer,
|
|
118
|
+
children: types !== void 0 ? /* @__PURE__ */ jsxs(MenuTrigger, { children: [/* @__PURE__ */ jsx(Button, {
|
|
119
|
+
size: "sm",
|
|
120
|
+
icon: Plus,
|
|
121
|
+
isDisabled: !canAdd,
|
|
122
|
+
children: intl.formatMessage(messages.add)
|
|
123
|
+
}), /* @__PURE__ */ jsx(Menu, {
|
|
124
|
+
"aria-label": intl.formatMessage(messages.add),
|
|
125
|
+
onAction: (key) => add(types.find((type_1) => type_1.id === key)),
|
|
126
|
+
children: types.map((type_2) => /* @__PURE__ */ jsx(MenuItem, {
|
|
127
|
+
id: type_2.id,
|
|
128
|
+
children: type_2.label
|
|
129
|
+
}, type_2.id))
|
|
130
|
+
})] }) : /* @__PURE__ */ jsx(Button, {
|
|
131
|
+
size: "sm",
|
|
132
|
+
icon: Plus,
|
|
133
|
+
isDisabled: !canAdd,
|
|
134
|
+
onPress: () => add(),
|
|
135
|
+
children: intl.formatMessage(messages.add)
|
|
136
|
+
})
|
|
137
|
+
}) : null]
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The `repeater` type: `fields`, or `types` for typed blocks, with `min` and `max` items from its
|
|
142
|
+
* rules.
|
|
143
|
+
*/
|
|
144
|
+
function RepeaterFieldEntry(props) {
|
|
145
|
+
const $ = c(23);
|
|
146
|
+
const { field, value } = props;
|
|
147
|
+
let t0;
|
|
148
|
+
if ($[0] !== field) {
|
|
149
|
+
t0 = getRuleNumber(field, "min");
|
|
150
|
+
$[0] = field;
|
|
151
|
+
$[1] = t0;
|
|
152
|
+
} else t0 = $[1];
|
|
153
|
+
const min = t0;
|
|
154
|
+
let t1;
|
|
155
|
+
if ($[2] !== field) {
|
|
156
|
+
t1 = getRuleNumber(field, "max");
|
|
157
|
+
$[2] = field;
|
|
158
|
+
$[3] = t1;
|
|
159
|
+
} else t1 = $[3];
|
|
160
|
+
const max = t1;
|
|
161
|
+
let t2;
|
|
162
|
+
if ($[4] !== props) {
|
|
163
|
+
t2 = getFieldProps(props);
|
|
164
|
+
$[4] = props;
|
|
165
|
+
$[5] = t2;
|
|
166
|
+
} else t2 = $[5];
|
|
167
|
+
let t3;
|
|
168
|
+
if ($[6] !== field.fields || $[7] !== field.types) {
|
|
169
|
+
t3 = field.types !== void 0 ? { types: field.types } : { fields: field.fields ?? [] };
|
|
170
|
+
$[6] = field.fields;
|
|
171
|
+
$[7] = field.types;
|
|
172
|
+
$[8] = t3;
|
|
173
|
+
} else t3 = $[8];
|
|
174
|
+
let t4;
|
|
175
|
+
if ($[9] !== value) {
|
|
176
|
+
t4 = Array.isArray(value) ? value.filter(_temp) : null;
|
|
177
|
+
$[9] = value;
|
|
178
|
+
$[10] = t4;
|
|
179
|
+
} else t4 = $[10];
|
|
180
|
+
let t5;
|
|
181
|
+
if ($[11] !== min) {
|
|
182
|
+
t5 = min !== void 0 ? { min } : {};
|
|
183
|
+
$[11] = min;
|
|
184
|
+
$[12] = t5;
|
|
185
|
+
} else t5 = $[12];
|
|
186
|
+
let t6;
|
|
187
|
+
if ($[13] !== max) {
|
|
188
|
+
t6 = max !== void 0 ? { max } : {};
|
|
189
|
+
$[13] = max;
|
|
190
|
+
$[14] = t6;
|
|
191
|
+
} else t6 = $[14];
|
|
192
|
+
let t7;
|
|
193
|
+
if ($[15] !== props.onChange || $[16] !== props.path || $[17] !== t2 || $[18] !== t3 || $[19] !== t4 || $[20] !== t5 || $[21] !== t6) {
|
|
194
|
+
t7 = /* @__PURE__ */ jsx(RepeaterField, {
|
|
195
|
+
...t2,
|
|
196
|
+
path: props.path,
|
|
197
|
+
...t3,
|
|
198
|
+
value: t4,
|
|
199
|
+
onChange: props.onChange,
|
|
200
|
+
...t5,
|
|
201
|
+
...t6
|
|
202
|
+
});
|
|
203
|
+
$[15] = props.onChange;
|
|
204
|
+
$[16] = props.path;
|
|
205
|
+
$[17] = t2;
|
|
206
|
+
$[18] = t3;
|
|
207
|
+
$[19] = t4;
|
|
208
|
+
$[20] = t5;
|
|
209
|
+
$[21] = t6;
|
|
210
|
+
$[22] = t7;
|
|
211
|
+
} else t7 = $[22];
|
|
212
|
+
return t7;
|
|
213
|
+
}
|
|
214
|
+
function _temp(item) {
|
|
215
|
+
return item !== null && typeof item === "object" && !Array.isArray(item);
|
|
216
|
+
}
|
|
217
|
+
//#endregion
|
|
218
|
+
export { RepeaterField, RepeaterFieldEntry };
|
|
219
|
+
|
|
220
|
+
//# sourceMappingURL=RepeaterField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RepeaterField.js","names":["next","type","i","styles","_c"],"sources":["../../src/repeater/RepeaterField.tsx"],"sourcesContent":["import { ArrowDown, ArrowUp, Plus, Trash2 } from 'lucide-react';\nimport { useId } from 'react';\n\nimport type { BlockType, Field } from '@panneau/protocol';\nimport {\n Button,\n Fieldset,\n IconButton,\n Menu,\n MenuItem,\n MenuTrigger,\n usePanneauIntl,\n} from '@panneau/ui';\n\nimport { NestedField } from '../shared/DefinitionField';\nimport { cx } from '../shared/cx';\nimport { getFieldProps, getRuleNumber } from '../shared/entry';\nimport { messages } from '../shared/messages';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport styles from './RepeaterField.module.css';\n\n/** An item of a repeater. Typed blocks have their type in `type`. */\nexport type RepeaterItem = Record<string, unknown>;\n\nexport interface RepeaterFieldProps extends FieldProps<RepeaterItem[]> {\n /** The fields of each item. */\n fields?: readonly Field[];\n /** Typed blocks: each item has a `type`, and the fields of that type. */\n types?: readonly BlockType[];\n /** Dot path of the list, the prefix of its fields' paths (`blocks.2.body`). Defaults to `name`. */\n path?: string;\n /** Fewest items: items can't be removed below it. */\n min?: number;\n /** Most items: no item can be added above it. */\n max?: number;\n itemClassName?: string;\n}\n\nfunction defaults(fields: readonly Field[]): RepeaterItem {\n return Object.fromEntries(\n fields.flatMap((field) =>\n field.default !== undefined ? [[field.name, field.default]] : [],\n ),\n );\n}\n\n/**\n * A list of items, each with the same fields, or typed blocks with the fields of their type. Items\n * can be added, moved and removed. Each field renders at the path `<list>.<index>.<field>`. An\n * empty list is `null`.\n */\nexport function RepeaterField({\n fields = [],\n types,\n path,\n name,\n value,\n onChange,\n onBlur,\n label,\n description,\n errors,\n disabled,\n readOnly,\n required,\n min = 0,\n max,\n className,\n labelClassName,\n descriptionClassName,\n errorsClassName,\n itemClassName,\n}: RepeaterFieldProps) {\n const intl = usePanneauIntl();\n const id = useId();\n const base = path ?? name ?? '';\n const items = value ?? [];\n const editable = disabled !== true && readOnly !== true;\n const canAdd = editable && (max === undefined || items.length < max);\n const canRemove = editable && items.length > min;\n const set = (next: RepeaterItem[]) => onChange?.(next.length > 0 ? next : null);\n const move = (from: number, to: number) => {\n const next = [...items];\n const [moved] = next.splice(from, 1);\n if (moved !== undefined) {\n next.splice(to, 0, moved);\n set(next);\n }\n };\n const add = (type?: BlockType) =>\n set([\n ...items,\n type !== undefined ? { type: type.id, ...defaults(type.fields) } : defaults(fields),\n ]);\n\n return (\n <Fieldset\n legend={label}\n description={description}\n errors={errors}\n isRequired={required}\n className={className}\n legendClassName={labelClassName}\n descriptionClassName={descriptionClassName}\n errorsClassName={errorsClassName}\n >\n {items.length > 0 ? (\n <ol className={styles.items}>\n {items.map((item, index) => {\n const type =\n types !== undefined\n ? types.find((candidate) => candidate.id === item.type)\n : undefined;\n const itemFields = types !== undefined ? (type?.fields ?? []) : fields;\n const number = index + 1;\n const titleId = `${id}-${index}`;\n return (\n <li\n key={index}\n className={cx(styles.item, itemClassName)}\n aria-labelledby={titleId}\n >\n <div className={styles.header}>\n <span id={titleId} className={styles.title}>\n <span className={styles.index}>{number}</span>\n {type?.label ??\n (typeof item.type === 'string'\n ? item.type\n : intl.formatMessage(messages.item, {\n index: number,\n }))}\n </span>\n {editable ? (\n <span className={styles.tools}>\n <IconButton\n icon={ArrowUp}\n size=\"sm\"\n label={intl.formatMessage(messages.moveUp, {\n index: number,\n })}\n isDisabled={index === 0}\n onPress={() => move(index, index - 1)}\n />\n <IconButton\n icon={ArrowDown}\n size=\"sm\"\n label={intl.formatMessage(messages.moveDown, {\n index: number,\n })}\n isDisabled={index === items.length - 1}\n onPress={() => move(index, index + 1)}\n />\n <IconButton\n icon={Trash2}\n size=\"sm\"\n label={intl.formatMessage(messages.removeItem, {\n index: number,\n })}\n isDisabled={!canRemove}\n onPress={() =>\n set(items.filter((_, i) => i !== index))\n }\n />\n </span>\n ) : null}\n </div>\n <div className={styles.body}>\n {itemFields.map((field) => (\n <NestedField\n key={field.name}\n field={field}\n path={`${base}.${index}.${field.name}`}\n value={item[field.name]}\n onChange={(next) =>\n set(\n items.map((current, i) =>\n i === index\n ? { ...current, [field.name]: next }\n : current,\n ),\n )\n }\n {...(onBlur !== undefined ? { onBlur } : {})}\n parentValue={item}\n {...(disabled !== undefined ? { disabled } : {})}\n {...(readOnly !== undefined ? { readOnly } : {})}\n />\n ))}\n </div>\n </li>\n );\n })}\n </ol>\n ) : (\n <p className={styles.empty}>{intl.formatMessage(messages.noItems)}</p>\n )}\n {editable ? (\n <div className={styles.footer}>\n {types !== undefined ? (\n <MenuTrigger>\n <Button size=\"sm\" icon={Plus} isDisabled={!canAdd}>\n {intl.formatMessage(messages.add)}\n </Button>\n <Menu\n aria-label={intl.formatMessage(messages.add)}\n onAction={(key) => add(types.find((type) => type.id === key))}\n >\n {types.map((type) => (\n <MenuItem key={type.id} id={type.id}>\n {type.label}\n </MenuItem>\n ))}\n </Menu>\n </MenuTrigger>\n ) : (\n <Button size=\"sm\" icon={Plus} isDisabled={!canAdd} onPress={() => add()}>\n {intl.formatMessage(messages.add)}\n </Button>\n )}\n </div>\n ) : null}\n </Fieldset>\n );\n}\n\n/**\n * The `repeater` type: `fields`, or `types` for typed blocks, with `min` and `max` items from its\n * rules.\n */\nexport function RepeaterFieldEntry(props: FieldEntryProps) {\n const { field, value } = props;\n const min = getRuleNumber(field, 'min');\n const max = getRuleNumber(field, 'max');\n return (\n <RepeaterField\n {...getFieldProps(props)}\n path={props.path}\n {...(field.types !== undefined\n ? { types: field.types }\n : { fields: field.fields ?? [] })}\n value={\n Array.isArray(value)\n ? value.filter(\n (item): item is RepeaterItem =>\n item !== null && typeof item === 'object' && !Array.isArray(item),\n )\n : null\n }\n onChange={props.onChange}\n {...(min !== undefined ? { min } : {})}\n {...(max !== undefined ? { max } : {})}\n />\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import "./RepeaterField.css";
|
|
2
|
+
//#region src/repeater/RepeaterField.module.css
|
|
3
|
+
var items = "panneau-items-B5uTq4";
|
|
4
|
+
var item = "panneau-item-cNAgol";
|
|
5
|
+
var header = "panneau-header-QLqgvh";
|
|
6
|
+
var title = "panneau-title-0eDHTu";
|
|
7
|
+
var index = "panneau-index-IrOBUU";
|
|
8
|
+
var tools = "panneau-tools-zbGiq2";
|
|
9
|
+
var body = "panneau-body-iQtLK9";
|
|
10
|
+
var empty = "panneau-empty-MST5Cj";
|
|
11
|
+
var footer = "panneau-footer-5jeHXH";
|
|
12
|
+
var RepeaterField_module_default = {
|
|
13
|
+
items,
|
|
14
|
+
item,
|
|
15
|
+
header,
|
|
16
|
+
title,
|
|
17
|
+
index,
|
|
18
|
+
tools,
|
|
19
|
+
body,
|
|
20
|
+
empty,
|
|
21
|
+
footer
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
export { body, RepeaterField_module_default as default, empty, footer, header, index, item, items, title, tools };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=RepeaterField.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RepeaterField.module.js","names":[],"sources":["../../src/repeater/RepeaterField.module.css"],"sourcesContent":[".items {\n display: flex;\n flex-direction: column;\n gap: var(--panneau-space-3);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.item {\n display: flex;\n flex-direction: column;\n min-width: 0;\n background-color: var(--panneau-color-surface);\n border: var(--panneau-border-width) solid var(--panneau-color-border);\n border-radius: var(--panneau-radius-md);\n}\n\n.header {\n display: flex;\n align-items: center;\n gap: var(--panneau-space-2);\n min-height: var(--panneau-control-height);\n padding: var(--panneau-space-1) var(--panneau-space-1) var(--panneau-space-1)\n var(--panneau-space-3);\n background-color: var(--panneau-color-surface-sunken);\n border-bottom: var(--panneau-border-width) solid var(--panneau-color-border);\n border-start-start-radius: inherit;\n border-start-end-radius: inherit;\n}\n\n.title {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n font-size: var(--panneau-font-size-sm);\n font-weight: var(--panneau-font-weight-medium);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.index {\n margin-inline-end: var(--panneau-space-2);\n font-variant-numeric: tabular-nums;\n color: var(--panneau-color-text-muted);\n}\n\n.tools {\n display: flex;\n flex: 0 0 auto;\n gap: var(--panneau-space-1);\n}\n\n.body {\n display: flex;\n flex-direction: column;\n gap: var(--panneau-space-4);\n padding: var(--panneau-space-4);\n}\n\n.empty {\n padding: var(--panneau-space-3);\n font-size: var(--panneau-font-size-sm);\n color: var(--panneau-color-text-muted);\n text-align: center;\n border: var(--panneau-border-width) dashed var(--panneau-color-border-control);\n border-radius: var(--panneau-radius-md);\n}\n\n.footer {\n display: flex;\n flex-wrap: wrap;\n gap: var(--panneau-space-2);\n}\n\n@media (max-width: 30rem) {\n .body {\n padding: var(--panneau-space-3);\n }\n}\n"],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repeater/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,aAAa,EACb,kBAAkB,EAClB,KAAK,kBAAkB,EACvB,KAAK,YAAY,GACpB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { RepeaterField, RepeaterFieldEntry } from "./RepeaterField.js";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Option } from '@panneau/protocol';
|
|
2
|
+
import { type OptionValue } from '@panneau/ui';
|
|
3
|
+
import type { FieldEntryProps, FieldProps } from '../shared/types';
|
|
4
|
+
export type { OptionValue };
|
|
5
|
+
/** Props of both single and multiple select fields. */
|
|
6
|
+
export interface SelectFieldBaseProps extends Omit<FieldProps<never>, 'value' | 'onChange'> {
|
|
7
|
+
/** The choices. Same shape as the protocol's `Option`. */
|
|
8
|
+
options: readonly Option[];
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
controlClassName?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface SingleSelectFieldProps extends SelectFieldBaseProps {
|
|
13
|
+
multiple?: false;
|
|
14
|
+
value?: OptionValue | null;
|
|
15
|
+
onChange?: (value: OptionValue | null) => void;
|
|
16
|
+
/** `select` (default): a dropdown. `radios`: every choice visible. */
|
|
17
|
+
widget?: 'select' | 'radios';
|
|
18
|
+
}
|
|
19
|
+
export interface MultipleSelectFieldProps extends SelectFieldBaseProps {
|
|
20
|
+
multiple: true;
|
|
21
|
+
value?: readonly OptionValue[] | null;
|
|
22
|
+
/** Called with the selected values, in the order of the options. An empty list is `null`. */
|
|
23
|
+
onChange?: (value: OptionValue[] | null) => void;
|
|
24
|
+
/** `select` (default): a dropdown. `checkboxes`: every choice visible. */
|
|
25
|
+
widget?: 'select' | 'checkboxes';
|
|
26
|
+
}
|
|
27
|
+
export type SelectFieldProps = SingleSelectFieldProps | MultipleSelectFieldProps;
|
|
28
|
+
/**
|
|
29
|
+
* A choice among options, or several with `multiple`, as a dropdown or as radios and checkboxes.
|
|
30
|
+
* Values keep their type (strings, numbers, booleans).
|
|
31
|
+
*/
|
|
32
|
+
export declare function SelectField(props: SelectFieldProps): import("react").JSX.Element;
|
|
33
|
+
/**
|
|
34
|
+
* The `select` type: `options`, `multiple`, and setting `widget` (`radios` for a single choice,
|
|
35
|
+
* `checkboxes` for several).
|
|
36
|
+
*/
|
|
37
|
+
export declare function SelectFieldEntry(props: FieldEntryProps): import("react").JSX.Element;
|
|
38
|
+
//# sourceMappingURL=SelectField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectField.d.ts","sourceRoot":"","sources":["../../src/select/SelectField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAsB,KAAK,WAAW,EAAsB,MAAM,aAAa,CAAC;AAGvF,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGnE,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B,uDAAuD;AACvD,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACvF,0DAA0D;IAC1D,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB;IAChE,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/C,sEAAsE;IACtE,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAChC;AAED,MAAM,WAAW,wBAAyB,SAAQ,oBAAoB;IAClE,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI,CAAC;IACtC,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,0EAA0E;IAC1E,MAAM,CAAC,EAAE,QAAQ,GAAG,YAAY,CAAC;CACpC;AAED,MAAM,MAAM,gBAAgB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;AAEjF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,+BAkIlD;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,+BA0BtD"}
|