@panneau/fields 4.1.1 → 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.
Files changed (183) hide show
  1. package/README.md +72 -0
  2. package/dist/boolean/BooleanField.d.ts +11 -0
  3. package/dist/boolean/BooleanField.d.ts.map +1 -0
  4. package/dist/boolean/BooleanField.js +67 -0
  5. package/dist/boolean/BooleanField.js.map +1 -0
  6. package/dist/boolean/index.d.ts +2 -0
  7. package/dist/boolean/index.d.ts.map +1 -0
  8. package/dist/boolean/index.js +1 -0
  9. package/dist/color/ColorField.css +33 -0
  10. package/dist/color/ColorField.d.ts +16 -0
  11. package/dist/color/ColorField.d.ts.map +1 -0
  12. package/dist/color/ColorField.js +187 -0
  13. package/dist/color/ColorField.js.map +1 -0
  14. package/dist/color/ColorField.module.js +14 -0
  15. package/dist/color/ColorField.module.js.map +1 -0
  16. package/dist/color/index.d.ts +2 -0
  17. package/dist/color/index.d.ts.map +1 -0
  18. package/dist/color/index.js +1 -0
  19. package/dist/date/DateField.d.ts +16 -0
  20. package/dist/date/DateField.d.ts.map +1 -0
  21. package/dist/date/DateField.js +132 -0
  22. package/dist/date/DateField.js.map +1 -0
  23. package/dist/date/index.d.ts +2 -0
  24. package/dist/date/index.d.ts.map +1 -0
  25. package/dist/date/index.js +1 -0
  26. package/dist/datetime/DateTimeField.d.ts +22 -0
  27. package/dist/datetime/DateTimeField.d.ts.map +1 -0
  28. package/dist/datetime/DateTimeField.js +78 -0
  29. package/dist/datetime/DateTimeField.js.map +1 -0
  30. package/dist/datetime/index.d.ts +2 -0
  31. package/dist/datetime/index.d.ts.map +1 -0
  32. package/dist/datetime/index.js +1 -0
  33. package/dist/email/EmailField.d.ts +8 -0
  34. package/dist/email/EmailField.d.ts.map +1 -0
  35. package/dist/email/EmailField.js +84 -0
  36. package/dist/email/EmailField.js.map +1 -0
  37. package/dist/email/index.d.ts +2 -0
  38. package/dist/email/index.d.ts.map +1 -0
  39. package/dist/email/index.js +1 -0
  40. package/dist/group/GroupField.css +14 -0
  41. package/dist/group/GroupField.d.ts +19 -0
  42. package/dist/group/GroupField.d.ts.map +1 -0
  43. package/dist/group/GroupField.js +140 -0
  44. package/dist/group/GroupField.js.map +1 -0
  45. package/dist/group/GroupField.module.js +8 -0
  46. package/dist/group/GroupField.module.js.map +1 -0
  47. package/dist/group/index.d.ts +2 -0
  48. package/dist/group/index.d.ts.map +1 -0
  49. package/dist/group/index.js +1 -0
  50. package/dist/index.d.ts +8 -12
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +7 -134
  53. package/dist/locales/index.d.ts +15 -0
  54. package/dist/locales/index.d.ts.map +1 -0
  55. package/dist/locales/index.js +21 -0
  56. package/dist/locales/index.js.map +1 -0
  57. package/dist/localized/LocalizedField.css +9 -0
  58. package/dist/localized/LocalizedField.d.ts +36 -0
  59. package/dist/localized/LocalizedField.d.ts.map +1 -0
  60. package/dist/localized/LocalizedField.js +207 -0
  61. package/dist/localized/LocalizedField.js.map +1 -0
  62. package/dist/localized/LocalizedField.module.js +12 -0
  63. package/dist/localized/LocalizedField.module.js.map +1 -0
  64. package/dist/localized/index.d.ts +2 -0
  65. package/dist/localized/index.d.ts.map +1 -0
  66. package/dist/localized/index.js +1 -0
  67. package/dist/missing/MissingField.css +18 -0
  68. package/dist/missing/MissingField.d.ts +7 -0
  69. package/dist/missing/MissingField.d.ts.map +1 -0
  70. package/dist/missing/MissingField.js +68 -0
  71. package/dist/missing/MissingField.js.map +1 -0
  72. package/dist/missing/MissingField.module.js +14 -0
  73. package/dist/missing/MissingField.module.js.map +1 -0
  74. package/dist/number/NumberField.d.ts +23 -0
  75. package/dist/number/NumberField.d.ts.map +1 -0
  76. package/dist/number/NumberField.js +175 -0
  77. package/dist/number/NumberField.js.map +1 -0
  78. package/dist/number/index.d.ts +2 -0
  79. package/dist/number/index.d.ts.map +1 -0
  80. package/dist/number/index.js +1 -0
  81. package/dist/relation/RelationField.css +43 -0
  82. package/dist/relation/RelationField.d.ts +40 -0
  83. package/dist/relation/RelationField.d.ts.map +1 -0
  84. package/dist/relation/RelationField.js +293 -0
  85. package/dist/relation/RelationField.js.map +1 -0
  86. package/dist/relation/RelationField.module.js +20 -0
  87. package/dist/relation/RelationField.module.js.map +1 -0
  88. package/dist/relation/index.d.ts +3 -0
  89. package/dist/relation/index.d.ts.map +1 -0
  90. package/dist/relation/index.js +3 -0
  91. package/dist/repeater/RepeaterField.css +80 -0
  92. package/dist/repeater/RepeaterField.d.ts +29 -0
  93. package/dist/repeater/RepeaterField.d.ts.map +1 -0
  94. package/dist/repeater/RepeaterField.js +220 -0
  95. package/dist/repeater/RepeaterField.js.map +1 -0
  96. package/dist/repeater/RepeaterField.module.js +26 -0
  97. package/dist/repeater/RepeaterField.module.js.map +1 -0
  98. package/dist/repeater/index.d.ts +2 -0
  99. package/dist/repeater/index.d.ts.map +1 -0
  100. package/dist/repeater/index.js +1 -0
  101. package/dist/select/SelectField.css +5 -0
  102. package/dist/select/SelectField.d.ts +38 -0
  103. package/dist/select/SelectField.d.ts.map +1 -0
  104. package/dist/select/SelectField.js +434 -0
  105. package/dist/select/SelectField.js.map +1 -0
  106. package/dist/select/SelectField.module.js +8 -0
  107. package/dist/select/SelectField.module.js.map +1 -0
  108. package/dist/select/index.d.ts +2 -0
  109. package/dist/select/index.d.ts.map +1 -0
  110. package/dist/select/index.js +1 -0
  111. package/dist/shared/DefinitionField.d.ts +32 -0
  112. package/dist/shared/DefinitionField.d.ts.map +1 -0
  113. package/dist/shared/DefinitionField.js +153 -0
  114. package/dist/shared/DefinitionField.js.map +1 -0
  115. package/dist/shared/builtIn.d.ts +17 -0
  116. package/dist/shared/builtIn.d.ts.map +1 -0
  117. package/dist/shared/builtIn.js +52 -0
  118. package/dist/shared/builtIn.js.map +1 -0
  119. package/dist/shared/context.d.ts +55 -0
  120. package/dist/shared/context.d.ts.map +1 -0
  121. package/dist/shared/context.js +72 -0
  122. package/dist/shared/context.js.map +1 -0
  123. package/dist/shared/cx.d.ts +3 -0
  124. package/dist/shared/cx.d.ts.map +1 -0
  125. package/dist/shared/cx.js +9 -0
  126. package/dist/shared/cx.js.map +1 -0
  127. package/dist/shared/dates.d.ts +15 -0
  128. package/dist/shared/dates.d.ts.map +1 -0
  129. package/dist/shared/dates.js +49 -0
  130. package/dist/shared/dates.js.map +1 -0
  131. package/dist/shared/entry.d.ts +23 -0
  132. package/dist/shared/entry.d.ts.map +1 -0
  133. package/dist/shared/entry.js +45 -0
  134. package/dist/shared/entry.js.map +1 -0
  135. package/dist/shared/messages.d.ts +2 -0
  136. package/dist/shared/messages.d.ts.map +1 -0
  137. package/dist/shared/messages.js +1 -0
  138. package/dist/shared/relation.d.ts +37 -0
  139. package/dist/shared/relation.d.ts.map +1 -0
  140. package/dist/shared/relation.js +49 -0
  141. package/dist/shared/relation.js.map +1 -0
  142. package/dist/shared/types.d.ts +50 -0
  143. package/dist/shared/types.d.ts.map +1 -0
  144. package/dist/slug/SlugField.d.ts +24 -0
  145. package/dist/slug/SlugField.d.ts.map +1 -0
  146. package/dist/slug/SlugField.js +216 -0
  147. package/dist/slug/SlugField.js.map +1 -0
  148. package/dist/slug/index.d.ts +2 -0
  149. package/dist/slug/index.d.ts.map +1 -0
  150. package/dist/slug/index.js +1 -0
  151. package/dist/text/TextField.d.ts +24 -0
  152. package/dist/text/TextField.d.ts.map +1 -0
  153. package/dist/text/TextField.js +179 -0
  154. package/dist/text/TextField.js.map +1 -0
  155. package/dist/text/index.d.ts +2 -0
  156. package/dist/text/index.d.ts.map +1 -0
  157. package/dist/text/index.js +1 -0
  158. package/dist/textarea/TextAreaField.d.ts +14 -0
  159. package/dist/textarea/TextAreaField.d.ts.map +1 -0
  160. package/dist/textarea/TextAreaField.js +126 -0
  161. package/dist/textarea/TextAreaField.js.map +1 -0
  162. package/dist/textarea/index.d.ts +2 -0
  163. package/dist/textarea/index.d.ts.map +1 -0
  164. package/dist/textarea/index.js +1 -0
  165. package/dist/time/TimeField.d.ts +13 -0
  166. package/dist/time/TimeField.d.ts.map +1 -0
  167. package/dist/time/TimeField.js +49 -0
  168. package/dist/time/TimeField.js.map +1 -0
  169. package/dist/time/index.d.ts +2 -0
  170. package/dist/time/index.d.ts.map +1 -0
  171. package/dist/time/index.js +1 -0
  172. package/dist/url/UrlField.css +11 -0
  173. package/dist/url/UrlField.d.ts +16 -0
  174. package/dist/url/UrlField.d.ts.map +1 -0
  175. package/dist/url/UrlField.js +94 -0
  176. package/dist/url/UrlField.js.map +1 -0
  177. package/dist/url/UrlField.module.js +8 -0
  178. package/dist/url/UrlField.module.js.map +1 -0
  179. package/dist/url/index.d.ts +2 -0
  180. package/dist/url/index.d.ts.map +1 -0
  181. package/dist/url/index.js +1 -0
  182. package/package.json +108 -79
  183. package/assets/css/styles.css +0 -14
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumberField.js","names":["min","max","disabled","readOnly","required","_c"],"sources":["../../src/number/NumberField.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { NumberInput } from '@panneau/ui';\n\nimport { getFieldProps, getRuleNumber, getSetting, isNumber, isString } from '../shared/entry';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\n\nexport interface NumberFieldProps extends FieldProps<number> {\n placeholder?: string;\n min?: number;\n max?: number;\n /** Step of the steppers and arrow keys. Defaults to 1. */\n step?: number;\n /** Format of the number, for the locale: decimals, percent, currency. */\n formatOptions?: Intl.NumberFormatOptions;\n /** Content after the number: a unit. */\n suffix?: ReactNode;\n controlClassName?: string;\n inputClassName?: string;\n}\n\n/** A number, formatted for the locale. An empty field is `null`. */\nexport function NumberField({\n value,\n onChange,\n min,\n max,\n disabled,\n readOnly,\n required,\n ...props\n}: NumberFieldProps) {\n return (\n <NumberInput\n {...props}\n value={value ?? null}\n onChange={(next) => onChange?.(next)}\n minValue={min}\n maxValue={max}\n isDisabled={disabled}\n isReadOnly={readOnly}\n isRequired={required}\n />\n );\n}\n\n/**\n * The `number` type: `min` and `max` from its rules, and settings `step`, `decimals` (the most\n * digits after the decimal point) and `suffix`.\n */\nexport function NumberFieldEntry(props: FieldEntryProps) {\n const { field } = props;\n const min = getRuleNumber(field, 'min');\n const max = getRuleNumber(field, 'max');\n const step = getSetting(field, 'step', isNumber);\n const decimals = getSetting(field, 'decimals', isNumber);\n const suffix = getSetting(field, 'suffix', isString);\n return (\n <NumberField\n {...getFieldProps(props)}\n value={isNumber(props.value) ? props.value : null}\n onChange={props.onChange}\n {...(min !== undefined ? { min } : {})}\n {...(max !== undefined ? { max } : {})}\n {...(step !== undefined ? { step } : {})}\n {...(decimals !== undefined\n ? { formatOptions: { maximumFractionDigits: decimals } }\n : {})}\n {...(suffix !== undefined ? { suffix } : {})}\n />\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { NumberField, NumberFieldEntry, type NumberFieldProps } from './NumberField';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/number/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1 @@
1
+ export { NumberField, NumberFieldEntry } from "./NumberField.js";
@@ -0,0 +1,43 @@
1
+ .panneau-multiple-u9IXr- {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--panneau-space-2);
5
+ }
6
+
7
+ .panneau-selected-PL7VcQ {
8
+ display: flex;
9
+ flex-wrap: wrap;
10
+ gap: var(--panneau-space-1) var(--panneau-space-2);
11
+ margin: 0;
12
+ padding: 0;
13
+ list-style: none;
14
+ }
15
+
16
+ .panneau-reference-J8YpaW {
17
+ display: inline-flex;
18
+ align-items: center;
19
+ gap: var(--panneau-space-1);
20
+ min-height: var(--panneau-control-height-sm);
21
+ max-width: 100%;
22
+ padding-inline: var(--panneau-space-3) var(--panneau-space-1);
23
+ font-size: var(--panneau-font-size-sm);
24
+ background-color: var(--panneau-color-surface-sunken);
25
+ border: var(--panneau-border-width) solid var(--panneau-color-border);
26
+ border-radius: var(--panneau-radius-full);
27
+ }
28
+
29
+ .panneau-reference-J8YpaW:only-child,
30
+ .panneau-readOnly-UunIK0 .panneau-reference-J8YpaW {
31
+ padding-inline-end: var(--panneau-space-3);
32
+ }
33
+
34
+ .panneau-referenceLabel-ydQ0bU {
35
+ overflow: hidden;
36
+ text-overflow: ellipsis;
37
+ white-space: nowrap;
38
+ }
39
+
40
+ .panneau-none-niMk7v {
41
+ font-size: var(--panneau-font-size-md);
42
+ color: var(--panneau-color-text-muted);
43
+ }
@@ -0,0 +1,40 @@
1
+ import { type RelationReference, type RelationSource } from '../shared/relation';
2
+ import type { FieldEntryProps, FieldProps } from '../shared/types';
3
+ /** Results of a search in a relation source, as it types. */
4
+ export declare function useRelationSearch(source: RelationSource | null, resource: string, query: string, { enabled, delay }?: {
5
+ enabled?: boolean;
6
+ delay?: number;
7
+ }): {
8
+ items: RelationReference[];
9
+ isLoading: boolean;
10
+ };
11
+ /** Props of both single and multiple relation fields. */
12
+ export interface RelationFieldBaseProps extends Omit<FieldProps<never>, 'value' | 'onChange'> {
13
+ /** Id of the related resource, passed to the source. */
14
+ resource: string;
15
+ /** Where to search. Defaults to the fields context's. Without one, the field is read-only. */
16
+ source?: RelationSource | null;
17
+ placeholder?: string;
18
+ controlClassName?: string;
19
+ }
20
+ export interface SingleRelationFieldProps extends RelationFieldBaseProps {
21
+ multiple?: false;
22
+ value?: RelationReference | null;
23
+ onChange?: (value: RelationReference | null) => void;
24
+ }
25
+ export interface MultipleRelationFieldProps extends RelationFieldBaseProps {
26
+ multiple: true;
27
+ value?: readonly RelationReference[] | null;
28
+ /** Called with the references. An empty list is `null`. */
29
+ onChange?: (value: RelationReference[] | null) => void;
30
+ }
31
+ export type RelationFieldProps = SingleRelationFieldProps | MultipleRelationFieldProps;
32
+ /**
33
+ * A reference to an item of another resource, or several with `multiple`, picked by searching a
34
+ * `RelationSource`. Values are references (`{ id, label }`), as items carry them. Without a
35
+ * source, the field shows its references and can't change them.
36
+ */
37
+ export declare function RelationField(props: RelationFieldProps): import("react").JSX.Element;
38
+ /** The `relation` type: `resource` and `multiple`. Items search the fields context's source. */
39
+ export declare function RelationFieldEntry(props: FieldEntryProps): import("react").JSX.Element;
40
+ //# sourceMappingURL=RelationField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelationField.d.ts","sourceRoot":"","sources":["../../src/relation/RelationField.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAgB,MAAM,oBAAoB,CAAC;AAC/F,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGnE,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,cAAc,GAAG,IAAI,EAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,EAAE,OAAc,EAAE,KAAW,EAAE,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5E;IAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAmCpD;AAED,yDAAyD;AACzD,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACzF,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,wBAAyB,SAAQ,sBAAsB;IACpE,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,KAAK,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,KAAK,IAAI,CAAC;CACxD;AAED,MAAM,WAAW,0BAA2B,SAAQ,sBAAsB;IACtE,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI,CAAC;IAC5C,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;CAC1D;AAED,MAAM,MAAM,kBAAkB,GAAG,wBAAwB,GAAG,0BAA0B,CAAC;AA+BvF;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,+BAiKtD;AAED,gGAAgG;AAChG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,+BAQxD"}
@@ -0,0 +1,293 @@
1
+ import { useFieldsContext } from "../shared/context.js";
2
+ import { cx } from "../shared/cx.js";
3
+ import { getFieldProps } from "../shared/entry.js";
4
+ import { messages } from "../shared/messages.js";
5
+ import { toReferences } from "../shared/relation.js";
6
+ import RelationField_module_default from "./RelationField.module.js";
7
+ import { c } from "react/compiler-runtime";
8
+ import { ComboBox, Fieldset, IconButton, usePanneauIntl } from "@panneau/ui";
9
+ import { useEffect, useState } from "react";
10
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+ import { X } from "lucide-react";
12
+ //#region src/relation/RelationField.tsx
13
+ /** Results of a search in a relation source, as it types. */
14
+ function useRelationSearch(source, resource, query, { enabled = true, delay = 250 } = {}) {
15
+ const [state, setState] = useState({
16
+ key: "",
17
+ items: [],
18
+ isLoading: false
19
+ });
20
+ const key = `${resource}\u0000${query}`;
21
+ useEffect(() => {
22
+ if (source === null || !enabled) return;
23
+ const controller = new AbortController();
24
+ const timer = setTimeout(() => {
25
+ setState((current) => ({
26
+ ...current,
27
+ key,
28
+ isLoading: true
29
+ }));
30
+ source.search(resource, query, { signal: controller.signal }).then((items) => {
31
+ if (!controller.signal.aborted) setState({
32
+ key,
33
+ items,
34
+ isLoading: false
35
+ });
36
+ }).catch(() => {
37
+ if (!controller.signal.aborted) setState({
38
+ key,
39
+ items: [],
40
+ isLoading: false
41
+ });
42
+ });
43
+ }, delay);
44
+ return () => {
45
+ clearTimeout(timer);
46
+ controller.abort();
47
+ };
48
+ }, [
49
+ source,
50
+ resource,
51
+ query,
52
+ key,
53
+ enabled,
54
+ delay
55
+ ]);
56
+ return {
57
+ items: state.items,
58
+ isLoading: state.isLoading || state.key !== key
59
+ };
60
+ }
61
+ function References(t0) {
62
+ const $ = c(12);
63
+ const { references, onRemove, removeLabel } = t0;
64
+ const t1 = onRemove === void 0 && RelationField_module_default.readOnly;
65
+ let t2;
66
+ if ($[0] !== t1) {
67
+ t2 = cx(RelationField_module_default.selected, t1);
68
+ $[0] = t1;
69
+ $[1] = t2;
70
+ } else t2 = $[1];
71
+ let t3;
72
+ if ($[2] !== onRemove || $[3] !== references || $[4] !== removeLabel) {
73
+ let t4;
74
+ if ($[6] !== onRemove || $[7] !== removeLabel) {
75
+ t4 = (reference) => /* @__PURE__ */ jsxs("li", {
76
+ className: RelationField_module_default.reference,
77
+ children: [/* @__PURE__ */ jsx("span", {
78
+ className: RelationField_module_default.referenceLabel,
79
+ children: reference.label
80
+ }), onRemove !== void 0 ? /* @__PURE__ */ jsx(IconButton, {
81
+ icon: X,
82
+ size: "sm",
83
+ label: removeLabel(reference),
84
+ showTooltip: false,
85
+ onPress: () => onRemove(reference)
86
+ }) : null]
87
+ }, reference.id);
88
+ $[6] = onRemove;
89
+ $[7] = removeLabel;
90
+ $[8] = t4;
91
+ } else t4 = $[8];
92
+ t3 = references.map(t4);
93
+ $[2] = onRemove;
94
+ $[3] = references;
95
+ $[4] = removeLabel;
96
+ $[5] = t3;
97
+ } else t3 = $[5];
98
+ let t4;
99
+ if ($[9] !== t2 || $[10] !== t3) {
100
+ t4 = /* @__PURE__ */ jsx("ul", {
101
+ className: t2,
102
+ children: t3
103
+ });
104
+ $[9] = t2;
105
+ $[10] = t3;
106
+ $[11] = t4;
107
+ } else t4 = $[11];
108
+ return t4;
109
+ }
110
+ /**
111
+ * A reference to an item of another resource, or several with `multiple`, picked by searching a
112
+ * `RelationSource`. Values are references (`{ id, label }`), as items carry them. Without a
113
+ * source, the field shows its references and can't change them.
114
+ */
115
+ function RelationField(props) {
116
+ const intl = usePanneauIntl();
117
+ const context = useFieldsContext();
118
+ const source = props.source === void 0 ? context.relationSource : props.source;
119
+ const { resource, label, description, errors, disabled, readOnly, required, placeholder = intl.formatMessage(messages.search), onBlur, name, id, className, labelClassName, descriptionClassName, errorsClassName, controlClassName } = props;
120
+ const selected = toReferences(props.value);
121
+ const [query, setQuery] = useState(null);
122
+ const editable = source !== null && disabled !== true && readOnly !== true;
123
+ const { items, isLoading } = useRelationSearch(source, resource, query ?? "", { enabled: editable });
124
+ const removeLabel = (reference) => `${intl.formatMessage(messages.remove)} ${reference.label}`;
125
+ const chrome = {
126
+ legend: label,
127
+ errors,
128
+ isRequired: required,
129
+ className,
130
+ legendClassName: labelClassName,
131
+ descriptionClassName,
132
+ errorsClassName
133
+ };
134
+ if (!editable) return /* @__PURE__ */ jsx(Fieldset, {
135
+ ...chrome,
136
+ description: source === null && disabled !== true && readOnly !== true ? /* @__PURE__ */ jsxs(Fragment, { children: [
137
+ description,
138
+ " ",
139
+ intl.formatMessage(messages.relationUnavailable)
140
+ ] }) : description,
141
+ children: selected.length > 0 ? /* @__PURE__ */ jsx(References, {
142
+ references: selected,
143
+ removeLabel
144
+ }) : /* @__PURE__ */ jsx("span", {
145
+ className: RelationField_module_default.none,
146
+ children: intl.formatMessage(messages.noRelation)
147
+ })
148
+ });
149
+ const comboLabel = typeof label === "string" ? label : props["aria-label"];
150
+ if (props.multiple === true) {
151
+ const { onChange } = props;
152
+ const set = (next) => onChange?.(next.length > 0 ? next : null);
153
+ return /* @__PURE__ */ jsx(Fieldset, {
154
+ ...chrome,
155
+ description,
156
+ children: /* @__PURE__ */ jsxs("div", {
157
+ className: RelationField_module_default.multiple,
158
+ children: [selected.length > 0 ? /* @__PURE__ */ jsx(References, {
159
+ references: selected,
160
+ removeLabel,
161
+ onRemove: (reference_0) => set(selected.filter((entry) => entry.id !== reference_0.id))
162
+ }) : null, /* @__PURE__ */ jsx(ComboBox, {
163
+ "aria-label": comboLabel,
164
+ items: items.filter((item) => !selected.some((entry_0) => entry_0.id === item.id)).map((item_0) => ({
165
+ id: item_0.id,
166
+ label: item_0.label
167
+ })),
168
+ value: null,
169
+ inputValue: query ?? "",
170
+ onInputChange: setQuery,
171
+ onChange: (itemId) => {
172
+ const reference_1 = items.find((item_1) => item_1.id === itemId);
173
+ if (reference_1 !== void 0) {
174
+ set([...selected, reference_1]);
175
+ setQuery(null);
176
+ }
177
+ },
178
+ isLoading,
179
+ placeholder,
180
+ emptyMessage: intl.formatMessage(messages.noResults),
181
+ ...onBlur !== void 0 ? { onBlur: () => onBlur() } : {},
182
+ ...name !== void 0 ? { name } : {},
183
+ ...id !== void 0 ? { id } : {},
184
+ ...controlClassName !== void 0 ? { controlClassName } : {}
185
+ })]
186
+ })
187
+ });
188
+ }
189
+ const { onChange: onChange_0 } = props;
190
+ const current = selected[0] ?? null;
191
+ const shown = current !== null && !items.some((item_2) => item_2.id === current.id) ? [current, ...items] : items;
192
+ return /* @__PURE__ */ jsx(ComboBox, {
193
+ label,
194
+ description,
195
+ errors,
196
+ isRequired: required,
197
+ className,
198
+ labelClassName,
199
+ descriptionClassName,
200
+ errorsClassName,
201
+ ...controlClassName !== void 0 ? { controlClassName } : {},
202
+ ...props["aria-label"] !== void 0 ? { "aria-label": props["aria-label"] } : {},
203
+ items: shown.map((item_3) => ({
204
+ id: item_3.id,
205
+ label: item_3.label
206
+ })),
207
+ value: current?.id ?? null,
208
+ inputValue: query ?? current?.label ?? "",
209
+ onInputChange: (text) => {
210
+ setQuery(text);
211
+ if (text === "" && current !== null) onChange_0?.(null);
212
+ },
213
+ onChange: (itemId_0) => {
214
+ setQuery(null);
215
+ if (itemId_0 === null) return;
216
+ const reference_2 = shown.find((item_4) => item_4.id === itemId_0) ?? null;
217
+ if (reference_2?.id !== current?.id) onChange_0?.(reference_2);
218
+ },
219
+ isLoading,
220
+ placeholder,
221
+ emptyMessage: intl.formatMessage(messages.noResults),
222
+ ...onBlur !== void 0 ? { onBlur: () => {
223
+ setQuery(null);
224
+ onBlur();
225
+ } } : { onBlur: () => setQuery(null) },
226
+ ...name !== void 0 ? { name } : {},
227
+ ...id !== void 0 ? { id } : {}
228
+ });
229
+ }
230
+ /** The `relation` type: `resource` and `multiple`. Items search the fields context's source. */
231
+ function RelationFieldEntry(props) {
232
+ const $ = c(15);
233
+ const { field } = props;
234
+ let t0;
235
+ if ($[0] !== props.value) {
236
+ t0 = toReferences(props.value);
237
+ $[0] = props.value;
238
+ $[1] = t0;
239
+ } else t0 = $[1];
240
+ const references = t0;
241
+ let t1;
242
+ if ($[2] !== props) {
243
+ t1 = getFieldProps(props);
244
+ $[2] = props;
245
+ $[3] = t1;
246
+ } else t1 = $[3];
247
+ const t2 = field.resource ?? "";
248
+ let t3;
249
+ if ($[4] !== t1 || $[5] !== t2) {
250
+ t3 = {
251
+ ...t1,
252
+ resource: t2
253
+ };
254
+ $[4] = t1;
255
+ $[5] = t2;
256
+ $[6] = t3;
257
+ } else t3 = $[6];
258
+ const shared = t3;
259
+ if (field.multiple === true) {
260
+ let t4;
261
+ if ($[7] !== props.onChange || $[8] !== references || $[9] !== shared) {
262
+ t4 = /* @__PURE__ */ jsx(RelationField, {
263
+ ...shared,
264
+ multiple: true,
265
+ value: references,
266
+ onChange: props.onChange
267
+ });
268
+ $[7] = props.onChange;
269
+ $[8] = references;
270
+ $[9] = shared;
271
+ $[10] = t4;
272
+ } else t4 = $[10];
273
+ return t4;
274
+ }
275
+ const t4 = references[0] ?? null;
276
+ let t5;
277
+ if ($[11] !== props.onChange || $[12] !== shared || $[13] !== t4) {
278
+ t5 = /* @__PURE__ */ jsx(RelationField, {
279
+ ...shared,
280
+ value: t4,
281
+ onChange: props.onChange
282
+ });
283
+ $[11] = props.onChange;
284
+ $[12] = shared;
285
+ $[13] = t4;
286
+ $[14] = t5;
287
+ } else t5 = $[14];
288
+ return t5;
289
+ }
290
+ //#endregion
291
+ export { RelationField, RelationFieldEntry, useRelationSearch };
292
+
293
+ //# sourceMappingURL=RelationField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelationField.js","names":["X","reference","entry","item","onChange","itemId","references","_c","styles","_Fragment"],"sources":["../../src/relation/RelationField.tsx"],"sourcesContent":["import { X } from 'lucide-react';\nimport { useEffect, useState } from 'react';\n\nimport { ComboBox, Fieldset, IconButton, usePanneauIntl } from '@panneau/ui';\n\nimport { useFieldsContext } from '../shared/context';\nimport { cx } from '../shared/cx';\nimport { getFieldProps } from '../shared/entry';\nimport { messages } from '../shared/messages';\nimport { type RelationReference, type RelationSource, toReferences } from '../shared/relation';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport styles from './RelationField.module.css';\n\n/** Results of a search in a relation source, as it types. */\nexport function useRelationSearch(\n source: RelationSource | null,\n resource: string,\n query: string,\n { enabled = true, delay = 250 }: { enabled?: boolean; delay?: number } = {},\n): { items: RelationReference[]; isLoading: boolean } {\n const [state, setState] = useState<{\n key: string;\n items: RelationReference[];\n isLoading: boolean;\n }>({ key: '', items: [], isLoading: false });\n const key = `${resource}\\u0000${query}`;\n\n useEffect(() => {\n if (source === null || !enabled) {\n return undefined;\n }\n const controller = new AbortController();\n const timer = setTimeout(() => {\n setState((current) => ({ ...current, key, isLoading: true }));\n source\n .search(resource, query, { signal: controller.signal })\n .then((items) => {\n if (!controller.signal.aborted) {\n setState({ key, items, isLoading: false });\n }\n })\n .catch(() => {\n if (!controller.signal.aborted) {\n setState({ key, items: [], isLoading: false });\n }\n });\n }, delay);\n return () => {\n clearTimeout(timer);\n controller.abort();\n };\n }, [source, resource, query, key, enabled, delay]);\n\n return { items: state.items, isLoading: state.isLoading || state.key !== key };\n}\n\n/** Props of both single and multiple relation fields. */\nexport interface RelationFieldBaseProps extends Omit<FieldProps<never>, 'value' | 'onChange'> {\n /** Id of the related resource, passed to the source. */\n resource: string;\n /** Where to search. Defaults to the fields context's. Without one, the field is read-only. */\n source?: RelationSource | null;\n placeholder?: string;\n controlClassName?: string;\n}\n\nexport interface SingleRelationFieldProps extends RelationFieldBaseProps {\n multiple?: false;\n value?: RelationReference | null;\n onChange?: (value: RelationReference | null) => void;\n}\n\nexport interface MultipleRelationFieldProps extends RelationFieldBaseProps {\n multiple: true;\n value?: readonly RelationReference[] | null;\n /** Called with the references. An empty list is `null`. */\n onChange?: (value: RelationReference[] | null) => void;\n}\n\nexport type RelationFieldProps = SingleRelationFieldProps | MultipleRelationFieldProps;\n\nfunction References({\n references,\n onRemove,\n removeLabel,\n}: {\n references: readonly RelationReference[];\n onRemove?: (reference: RelationReference) => void;\n removeLabel: (reference: RelationReference) => string;\n}) {\n return (\n <ul className={cx(styles.selected, onRemove === undefined && styles.readOnly)}>\n {references.map((reference) => (\n <li key={reference.id} className={styles.reference}>\n <span className={styles.referenceLabel}>{reference.label}</span>\n {onRemove !== undefined ? (\n <IconButton\n icon={X}\n size=\"sm\"\n label={removeLabel(reference)}\n showTooltip={false}\n onPress={() => onRemove(reference)}\n />\n ) : null}\n </li>\n ))}\n </ul>\n );\n}\n\n/**\n * A reference to an item of another resource, or several with `multiple`, picked by searching a\n * `RelationSource`. Values are references (`{ id, label }`), as items carry them. Without a\n * source, the field shows its references and can't change them.\n */\nexport function RelationField(props: RelationFieldProps) {\n const intl = usePanneauIntl();\n const context = useFieldsContext();\n const source = props.source === undefined ? context.relationSource : props.source;\n const {\n resource,\n label,\n description,\n errors,\n disabled,\n readOnly,\n required,\n placeholder = intl.formatMessage(messages.search),\n onBlur,\n name,\n id,\n className,\n labelClassName,\n descriptionClassName,\n errorsClassName,\n controlClassName,\n } = props;\n const selected = toReferences(props.value);\n const [query, setQuery] = useState<string | null>(null);\n const editable = source !== null && disabled !== true && readOnly !== true;\n const { items, isLoading } = useRelationSearch(source, resource, query ?? '', {\n enabled: editable,\n });\n const removeLabel = (reference: RelationReference) =>\n `${intl.formatMessage(messages.remove)} ${reference.label}`;\n const chrome = {\n legend: label,\n errors,\n isRequired: required,\n className,\n legendClassName: labelClassName,\n descriptionClassName,\n errorsClassName,\n };\n\n if (!editable) {\n return (\n <Fieldset\n {...chrome}\n description={\n source === null && disabled !== true && readOnly !== true ? (\n <>\n {description} {intl.formatMessage(messages.relationUnavailable)}\n </>\n ) : (\n description\n )\n }\n >\n {selected.length > 0 ? (\n <References references={selected} removeLabel={removeLabel} />\n ) : (\n <span className={styles.none}>{intl.formatMessage(messages.noRelation)}</span>\n )}\n </Fieldset>\n );\n }\n\n const comboLabel = typeof label === 'string' ? label : props['aria-label'];\n\n if (props.multiple === true) {\n const { onChange } = props;\n const set = (next: RelationReference[]) => onChange?.(next.length > 0 ? next : null);\n return (\n <Fieldset {...chrome} description={description}>\n <div className={styles.multiple}>\n {selected.length > 0 ? (\n <References\n references={selected}\n removeLabel={removeLabel}\n onRemove={(reference) =>\n set(selected.filter((entry) => entry.id !== reference.id))\n }\n />\n ) : null}\n <ComboBox\n aria-label={comboLabel}\n items={items\n .filter((item) => !selected.some((entry) => entry.id === item.id))\n .map((item) => ({ id: item.id, label: item.label }))}\n value={null}\n inputValue={query ?? ''}\n onInputChange={setQuery}\n onChange={(itemId) => {\n const reference = items.find((item) => item.id === itemId);\n if (reference !== undefined) {\n set([...selected, reference]);\n setQuery(null);\n }\n }}\n isLoading={isLoading}\n placeholder={placeholder}\n emptyMessage={intl.formatMessage(messages.noResults)}\n {...(onBlur !== undefined ? { onBlur: () => onBlur() } : {})}\n {...(name !== undefined ? { name } : {})}\n {...(id !== undefined ? { id } : {})}\n {...(controlClassName !== undefined ? { controlClassName } : {})}\n />\n </div>\n </Fieldset>\n );\n }\n\n const { onChange } = props;\n const current = selected[0] ?? null;\n // The selected reference is among the items, so that the combo box knows its label.\n const shown =\n current !== null && !items.some((item) => item.id === current.id)\n ? [current, ...items]\n : items;\n return (\n <ComboBox\n label={label}\n description={description}\n errors={errors}\n isRequired={required}\n className={className}\n labelClassName={labelClassName}\n descriptionClassName={descriptionClassName}\n errorsClassName={errorsClassName}\n {...(controlClassName !== undefined ? { controlClassName } : {})}\n {...(props['aria-label'] !== undefined ? { 'aria-label': props['aria-label'] } : {})}\n items={shown.map((item) => ({ id: item.id, label: item.label }))}\n value={current?.id ?? null}\n inputValue={query ?? current?.label ?? ''}\n onInputChange={(text) => {\n setQuery(text);\n if (text === '' && current !== null) {\n onChange?.(null);\n }\n }}\n onChange={(itemId) => {\n setQuery(null);\n if (itemId === null) {\n return;\n }\n const reference = shown.find((item) => item.id === itemId) ?? null;\n if (reference?.id !== current?.id) {\n onChange?.(reference);\n }\n }}\n isLoading={isLoading}\n placeholder={placeholder}\n emptyMessage={intl.formatMessage(messages.noResults)}\n {...(onBlur !== undefined\n ? {\n onBlur: () => {\n setQuery(null);\n onBlur();\n },\n }\n : { onBlur: () => setQuery(null) })}\n {...(name !== undefined ? { name } : {})}\n {...(id !== undefined ? { id } : {})}\n />\n );\n}\n\n/** The `relation` type: `resource` and `multiple`. Items search the fields context's source. */\nexport function RelationFieldEntry(props: FieldEntryProps) {\n const { field } = props;\n const references = toReferences(props.value);\n const shared = { ...getFieldProps(props), resource: field.resource ?? '' };\n if (field.multiple === true) {\n return <RelationField {...shared} multiple value={references} onChange={props.onChange} />;\n }\n return <RelationField {...shared} value={references[0] ?? null} onChange={props.onChange} />;\n}\n"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import "./RelationField.css";
2
+ //#region src/relation/RelationField.module.css
3
+ var multiple = "panneau-multiple-u9IXr-";
4
+ var selected = "panneau-selected-PL7VcQ";
5
+ var reference = "panneau-reference-J8YpaW";
6
+ var readOnly = "panneau-readOnly-UunIK0";
7
+ var referenceLabel = "panneau-referenceLabel-ydQ0bU";
8
+ var none = "panneau-none-niMk7v";
9
+ var RelationField_module_default = {
10
+ multiple,
11
+ selected,
12
+ reference,
13
+ readOnly,
14
+ referenceLabel,
15
+ none
16
+ };
17
+ //#endregion
18
+ export { RelationField_module_default as default, multiple, none, readOnly, reference, referenceLabel, selected };
19
+
20
+ //# sourceMappingURL=RelationField.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelationField.module.js","names":[],"sources":["../../src/relation/RelationField.module.css"],"sourcesContent":[".multiple {\n display: flex;\n flex-direction: column;\n gap: var(--panneau-space-2);\n}\n\n.selected {\n display: flex;\n flex-wrap: wrap;\n gap: var(--panneau-space-1) var(--panneau-space-2);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.reference {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-1);\n min-height: var(--panneau-control-height-sm);\n max-width: 100%;\n padding-inline: var(--panneau-space-3) var(--panneau-space-1);\n font-size: var(--panneau-font-size-sm);\n background-color: var(--panneau-color-surface-sunken);\n border: var(--panneau-border-width) solid var(--panneau-color-border);\n border-radius: var(--panneau-radius-full);\n}\n\n.reference:only-child,\n.readOnly .reference {\n padding-inline-end: var(--panneau-space-3);\n}\n\n.referenceLabel {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.none {\n font-size: var(--panneau-font-size-md);\n color: var(--panneau-color-text-muted);\n}\n"],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export { type MultipleRelationFieldProps, type RelationFieldBaseProps, RelationField, RelationFieldEntry, type RelationFieldProps, type SingleRelationFieldProps, useRelationSearch, } from './RelationField';
2
+ export { type RelationListAdapter, type RelationReference, type RelationSource, type RelationSourceOptions, createRelationSource, } from '../shared/relation';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/relation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC3B,aAAa,EACb,kBAAkB,EAClB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC7B,iBAAiB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,oBAAoB,GACvB,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { createRelationSource } from "../shared/relation.js";
2
+ import { RelationField, RelationFieldEntry, useRelationSearch } from "./RelationField.js";
3
+ export { RelationField, RelationFieldEntry, createRelationSource, useRelationSearch };
@@ -0,0 +1,80 @@
1
+ .panneau-items-B5uTq4 {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--panneau-space-3);
5
+ margin: 0;
6
+ padding: 0;
7
+ list-style: none;
8
+ }
9
+
10
+ .panneau-item-cNAgol {
11
+ display: flex;
12
+ flex-direction: column;
13
+ min-width: 0;
14
+ background-color: var(--panneau-color-surface);
15
+ border: var(--panneau-border-width) solid var(--panneau-color-border);
16
+ border-radius: var(--panneau-radius-md);
17
+ }
18
+
19
+ .panneau-header-QLqgvh {
20
+ display: flex;
21
+ align-items: center;
22
+ gap: var(--panneau-space-2);
23
+ min-height: var(--panneau-control-height);
24
+ padding: var(--panneau-space-1) var(--panneau-space-1) var(--panneau-space-1)
25
+ var(--panneau-space-3);
26
+ background-color: var(--panneau-color-surface-sunken);
27
+ border-bottom: var(--panneau-border-width) solid var(--panneau-color-border);
28
+ border-start-start-radius: inherit;
29
+ border-start-end-radius: inherit;
30
+ }
31
+
32
+ .panneau-title-0eDHTu {
33
+ flex: 1 1 auto;
34
+ min-width: 0;
35
+ overflow: hidden;
36
+ font-size: var(--panneau-font-size-sm);
37
+ font-weight: var(--panneau-font-weight-medium);
38
+ text-overflow: ellipsis;
39
+ white-space: nowrap;
40
+ }
41
+
42
+ .panneau-index-IrOBUU {
43
+ margin-inline-end: var(--panneau-space-2);
44
+ font-variant-numeric: tabular-nums;
45
+ color: var(--panneau-color-text-muted);
46
+ }
47
+
48
+ .panneau-tools-zbGiq2 {
49
+ display: flex;
50
+ flex: 0 0 auto;
51
+ gap: var(--panneau-space-1);
52
+ }
53
+
54
+ .panneau-body-iQtLK9 {
55
+ display: flex;
56
+ flex-direction: column;
57
+ gap: var(--panneau-space-4);
58
+ padding: var(--panneau-space-4);
59
+ }
60
+
61
+ .panneau-empty-MST5Cj {
62
+ padding: var(--panneau-space-3);
63
+ font-size: var(--panneau-font-size-sm);
64
+ color: var(--panneau-color-text-muted);
65
+ text-align: center;
66
+ border: var(--panneau-border-width) dashed var(--panneau-color-border-control);
67
+ border-radius: var(--panneau-radius-md);
68
+ }
69
+
70
+ .panneau-footer-5jeHXH {
71
+ display: flex;
72
+ flex-wrap: wrap;
73
+ gap: var(--panneau-space-2);
74
+ }
75
+
76
+ @media (max-width: 30rem) {
77
+ .panneau-body-iQtLK9 {
78
+ padding: var(--panneau-space-3);
79
+ }
80
+ }
@@ -0,0 +1,29 @@
1
+ import type { BlockType, Field } from '@panneau/protocol';
2
+ import type { FieldEntryProps, FieldProps } from '../shared/types';
3
+ /** An item of a repeater. Typed blocks have their type in `type`. */
4
+ export type RepeaterItem = Record<string, unknown>;
5
+ export interface RepeaterFieldProps extends FieldProps<RepeaterItem[]> {
6
+ /** The fields of each item. */
7
+ fields?: readonly Field[];
8
+ /** Typed blocks: each item has a `type`, and the fields of that type. */
9
+ types?: readonly BlockType[];
10
+ /** Dot path of the list, the prefix of its fields' paths (`blocks.2.body`). Defaults to `name`. */
11
+ path?: string;
12
+ /** Fewest items: items can't be removed below it. */
13
+ min?: number;
14
+ /** Most items: no item can be added above it. */
15
+ max?: number;
16
+ itemClassName?: string;
17
+ }
18
+ /**
19
+ * A list of items, each with the same fields, or typed blocks with the fields of their type. Items
20
+ * can be added, moved and removed. Each field renders at the path `<list>.<index>.<field>`. An
21
+ * empty list is `null`.
22
+ */
23
+ export declare function RepeaterField({ fields, types, path, name, value, onChange, onBlur, label, description, errors, disabled, readOnly, required, min, max, className, labelClassName, descriptionClassName, errorsClassName, itemClassName, }: RepeaterFieldProps): import("react").JSX.Element;
24
+ /**
25
+ * The `repeater` type: `fields`, or `types` for typed blocks, with `min` and `max` items from its
26
+ * rules.
27
+ */
28
+ export declare function RepeaterFieldEntry(props: FieldEntryProps): import("react").JSX.Element;
29
+ //# sourceMappingURL=RepeaterField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RepeaterField.d.ts","sourceRoot":"","sources":["../../src/repeater/RepeaterField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAe1D,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGnE,qEAAqE;AACrE,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnD,MAAM,WAAW,kBAAmB,SAAQ,UAAU,CAAC,YAAY,EAAE,CAAC;IAClE,+BAA+B;IAC/B,MAAM,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;IAC1B,yEAAyE;IACzE,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAC7B,mGAAmG;IACnG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAUD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC1B,MAAW,EACX,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,MAAM,EACN,KAAK,EACL,WAAW,EACX,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,GAAO,EACP,GAAG,EACH,SAAS,EACT,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,aAAa,GAChB,EAAE,kBAAkB,+BAuJpB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,+BAwBxD"}