@panneau/fields 5.0.0-alpha.15 → 5.0.0-alpha.16

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 (139) hide show
  1. package/README.md +53 -3
  2. package/dist/address/AddressField.css +44 -0
  3. package/dist/address/AddressField.d.ts +37 -0
  4. package/dist/address/AddressField.d.ts.map +1 -0
  5. package/dist/address/AddressField.js +411 -0
  6. package/dist/address/AddressField.js.map +1 -0
  7. package/dist/address/AddressField.module.js +22 -0
  8. package/dist/address/AddressField.module.js.map +1 -0
  9. package/dist/address/address.d.ts +23 -0
  10. package/dist/address/address.d.ts.map +1 -0
  11. package/dist/address/address.js +58 -0
  12. package/dist/address/address.js.map +1 -0
  13. package/dist/address/index.d.ts +3 -0
  14. package/dist/address/index.d.ts.map +1 -0
  15. package/dist/address/index.js +3 -0
  16. package/dist/color/ColorField.css +9 -0
  17. package/dist/color/ColorField.d.ts +10 -3
  18. package/dist/color/ColorField.d.ts.map +1 -1
  19. package/dist/color/ColorField.js +341 -81
  20. package/dist/color/ColorField.js.map +1 -1
  21. package/dist/color/ColorField.module.js +4 -2
  22. package/dist/color/ColorField.module.js.map +1 -1
  23. package/dist/color/index.d.ts +1 -0
  24. package/dist/color/index.d.ts.map +1 -1
  25. package/dist/color/index.js +3 -1
  26. package/dist/color/palette.d.ts +23 -0
  27. package/dist/color/palette.d.ts.map +1 -0
  28. package/dist/color/palette.js +34 -0
  29. package/dist/color/palette.js.map +1 -0
  30. package/dist/country/CountryField.css +42 -0
  31. package/dist/country/CountryField.d.ts +19 -4
  32. package/dist/country/CountryField.d.ts.map +1 -1
  33. package/dist/country/CountryField.js +355 -82
  34. package/dist/country/CountryField.js.map +1 -1
  35. package/dist/country/CountryField.module.js +20 -0
  36. package/dist/country/CountryField.module.js.map +1 -0
  37. package/dist/country/index.d.ts +1 -1
  38. package/dist/country/index.d.ts.map +1 -1
  39. package/dist/daterange/DateRangeField.css +9 -0
  40. package/dist/daterange/DateRangeField.d.ts +31 -0
  41. package/dist/daterange/DateRangeField.d.ts.map +1 -0
  42. package/dist/daterange/DateRangeField.js +372 -0
  43. package/dist/daterange/DateRangeField.js.map +1 -0
  44. package/dist/daterange/DateRangeField.module.js +12 -0
  45. package/dist/daterange/DateRangeField.module.js.map +1 -0
  46. package/dist/daterange/index.d.ts +3 -0
  47. package/dist/daterange/index.d.ts.map +1 -0
  48. package/dist/daterange/index.js +3 -0
  49. package/dist/daterange/range.d.ts +61 -0
  50. package/dist/daterange/range.d.ts.map +1 -0
  51. package/dist/daterange/range.js +119 -0
  52. package/dist/daterange/range.js.map +1 -0
  53. package/dist/duration/DurationField.css +1 -1
  54. package/dist/duration/DurationField.d.ts +54 -13
  55. package/dist/duration/DurationField.d.ts.map +1 -1
  56. package/dist/duration/DurationField.js +205 -159
  57. package/dist/duration/DurationField.js.map +1 -1
  58. package/dist/duration/DurationField.module.js.map +1 -1
  59. package/dist/duration/index.d.ts +1 -1
  60. package/dist/duration/index.d.ts.map +1 -1
  61. package/dist/duration/index.js +1 -1
  62. package/dist/embed/EmbedField.d.ts +11 -2
  63. package/dist/embed/EmbedField.d.ts.map +1 -1
  64. package/dist/embed/EmbedField.js +179 -116
  65. package/dist/embed/EmbedField.js.map +1 -1
  66. package/dist/link/LinkField.css +12 -0
  67. package/dist/link/LinkField.d.ts +38 -0
  68. package/dist/link/LinkField.d.ts.map +1 -0
  69. package/dist/link/LinkField.js +742 -0
  70. package/dist/link/LinkField.js.map +1 -0
  71. package/dist/link/LinkField.module.js +8 -0
  72. package/dist/link/LinkField.module.js.map +1 -0
  73. package/dist/link/index.d.ts +3 -0
  74. package/dist/link/index.d.ts.map +1 -0
  75. package/dist/link/index.js +3 -0
  76. package/dist/link/link.d.ts +30 -0
  77. package/dist/link/link.d.ts.map +1 -0
  78. package/dist/link/link.js +63 -0
  79. package/dist/link/link.js.map +1 -0
  80. package/dist/link/pages.d.ts +17 -0
  81. package/dist/link/pages.d.ts.map +1 -0
  82. package/dist/link/pages.js +104 -0
  83. package/dist/link/pages.js.map +1 -0
  84. package/dist/location/LocationField.d.ts.map +1 -1
  85. package/dist/location/LocationField.js +9 -85
  86. package/dist/location/LocationField.js.map +1 -1
  87. package/dist/location/nominatim.d.ts +8 -2
  88. package/dist/location/nominatim.d.ts.map +1 -1
  89. package/dist/location/nominatim.js +32 -3
  90. package/dist/location/nominatim.js.map +1 -1
  91. package/dist/location/search.d.ts +10 -0
  92. package/dist/location/search.d.ts.map +1 -0
  93. package/dist/location/search.js +83 -0
  94. package/dist/location/search.js.map +1 -0
  95. package/dist/location/types.d.ts +8 -2
  96. package/dist/location/types.d.ts.map +1 -1
  97. package/dist/money/MoneyField.d.ts +28 -0
  98. package/dist/money/MoneyField.d.ts.map +1 -0
  99. package/dist/money/MoneyField.js +269 -0
  100. package/dist/money/MoneyField.js.map +1 -0
  101. package/dist/money/index.d.ts +3 -0
  102. package/dist/money/index.d.ts.map +1 -0
  103. package/dist/money/index.js +3 -0
  104. package/dist/money/money.d.ts +27 -0
  105. package/dist/money/money.d.ts.map +1 -0
  106. package/dist/money/money.js +56 -0
  107. package/dist/money/money.js.map +1 -0
  108. package/dist/region/RegionField.js +1 -1
  109. package/dist/shared/builtIn.d.ts +3 -1
  110. package/dist/shared/builtIn.d.ts.map +1 -1
  111. package/dist/shared/builtIn.js +18 -8
  112. package/dist/shared/builtIn.js.map +1 -1
  113. package/dist/shared/dates.js +2 -2
  114. package/dist/shared/dates.js.map +1 -1
  115. package/dist/shared/flow.d.ts.map +1 -1
  116. package/dist/shared/flow.js +1 -0
  117. package/dist/shared/flow.js.map +1 -1
  118. package/dist/shared/part.d.ts +26 -0
  119. package/dist/shared/part.d.ts.map +1 -0
  120. package/dist/shared/part.js +64 -0
  121. package/dist/shared/part.js.map +1 -0
  122. package/dist/tel/TelField.css +25 -0
  123. package/dist/tel/TelField.d.ts +14 -2
  124. package/dist/tel/TelField.d.ts.map +1 -1
  125. package/dist/tel/TelField.js +246 -145
  126. package/dist/tel/TelField.js.map +1 -1
  127. package/dist/tel/TelField.module.js +12 -0
  128. package/dist/tel/TelField.module.js.map +1 -0
  129. package/dist/tel/index.d.ts +1 -1
  130. package/dist/tel/index.d.ts.map +1 -1
  131. package/dist/tel/index.js +2 -2
  132. package/dist/tel/phone.d.ts +28 -0
  133. package/dist/tel/phone.d.ts.map +1 -1
  134. package/dist/tel/phone.js +48 -1
  135. package/dist/tel/phone.js.map +1 -1
  136. package/dist/url/UrlField.d.ts.map +1 -1
  137. package/dist/url/UrlField.js +1 -1
  138. package/dist/url/UrlField.js.map +1 -1
  139. package/package.json +24 -4
@@ -1 +1 @@
1
- export { DurationField, DurationFieldEntry, formatDuration, splitDuration } from "./DurationField.js";
1
+ export { DurationField, DurationFieldEntry, formatDuration, getDurationUnits, isDurationUnit, resolveDurationUnits, splitDuration } from "./DurationField.js";
@@ -6,6 +6,12 @@ export interface EmbedFieldProps extends FieldProps<EmbedValue> {
6
6
  placeholder?: string;
7
7
  /** Where the preview comes from. Defaults to that of the `FieldsProvider`. */
8
8
  embedSource?: EmbedSource | null;
9
+ /**
10
+ * The providers an embed may come from (`YouTube`), compared without case: the `providers`
11
+ * rule (decision 0058). The field names them under its help, and refuses an embed of another
12
+ * provider as soon as its preview comes back. The form's errors, once shown, replace that one.
13
+ */
14
+ providers?: readonly string[];
9
15
  }
10
16
  /** Whether a value is an embed: an object with a `url`. */
11
17
  export declare function isEmbed(value: unknown): value is EmbedValue;
@@ -14,7 +20,10 @@ export declare function isEmbed(value: unknown): value is EmbedValue;
14
20
  * oEmbed: its thumbnail, title and provider. The URL is kept as soon as it is typed, and its
15
21
  * preview follows. Without an embed source, the value is the URL alone.
16
22
  */
17
- export declare function EmbedField({ value, onChange, onBlur, embedSource: embedSourceProp, errors, disabled, readOnly, required, ...props }: EmbedFieldProps): import("react").JSX.Element;
18
- /** The `embed` type: its preview comes from the embed source of the `FieldsProvider`. */
23
+ export declare function EmbedField({ value, onChange, onBlur, embedSource: embedSourceProp, providers, errors, disabled, readOnly, required, description, ...props }: EmbedFieldProps): import("react").JSX.Element;
24
+ /**
25
+ * The `embed` type: its preview comes from the embed source of the `FieldsProvider`, and its
26
+ * `providers` rule names the providers it allows.
27
+ */
19
28
  export declare function EmbedFieldEntry(props: FieldEntryProps): import("react").JSX.Element;
20
29
  //# sourceMappingURL=EmbedField.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EmbedField.d.ts","sourceRoot":"","sources":["../../src/embed/EmbedField.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGnE,YAAY,EAAE,UAAU,EAAE,CAAC;AAI3B,MAAM,WAAW,eAAgB,SAAQ,UAAU,CAAC,UAAU,CAAC;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CACpC;AAED,2DAA2D;AAC3D,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAM3D;AAOD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,WAAW,EAAE,eAAe,EAC5B,MAAW,EACX,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,GAAG,KAAK,EACX,EAAE,eAAe,+BA6EjB;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,+BAQrD"}
1
+ {"version":3,"file":"EmbedField.d.ts","sourceRoot":"","sources":["../../src/embed/EmbedField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGnE,YAAY,EAAE,UAAU,EAAE,CAAC;AAI3B,MAAM,WAAW,eAAgB,SAAQ,UAAU,CAAC,UAAU,CAAC;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,2DAA2D;AAC3D,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAM3D;AAgBD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,WAAW,EAAE,eAAe,EAC5B,SAAS,EACT,MAAW,EACX,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,GAAG,KAAK,EACX,EAAE,eAAe,+BAmGjB;AAUD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,+BAUrD"}
@@ -1,17 +1,24 @@
1
1
  import { useFieldsContext } from "../shared/context.js";
2
- import { getFieldProps, isString } from "../shared/entry.js";
2
+ import { findRule, getFieldProps, isString } from "../shared/entry.js";
3
3
  import { messages } from "../shared/messages.js";
4
4
  import EmbedField_module_default from "./EmbedField.module.js";
5
5
  import { c } from "react/compiler-runtime";
6
6
  import { useEffect, useEffectEvent, useState } from "react";
7
7
  import { Spinner, TextInput, usePanneauIntl } from "@panneau/ui";
8
- import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
+ import { formsMessages } from "@panneau/intl";
9
10
  //#region src/embed/EmbedField.tsx
10
11
  var RESOLVE_DELAY = 500;
11
12
  /** Whether a value is an embed: an object with a `url`. */
12
13
  function isEmbed(value) {
13
14
  return value !== null && typeof value === "object" && isString(value.url);
14
15
  }
16
+ /** Whether an embed comes from one of the providers. One without a provider is left to the backend. */
17
+ function isAllowed(value, providers) {
18
+ if (providers === void 0 || providers.length === 0 || value.provider === void 0) return true;
19
+ const provider = value.provider.toLowerCase();
20
+ return providers.some((allowed) => allowed.toLowerCase() === provider);
21
+ }
15
22
  /** Whether a value has been resolved: it has more than its URL. */
16
23
  function isResolved(value) {
17
24
  return Object.keys(value).some((key) => key !== "url");
@@ -22,45 +29,51 @@ function isResolved(value) {
22
29
  * preview follows. Without an embed source, the value is the URL alone.
23
30
  */
24
31
  function EmbedField(t0) {
25
- const $ = c(47);
32
+ const $ = c(60);
33
+ let description;
26
34
  let disabled;
27
35
  let embedSourceProp;
28
36
  let onBlur;
29
37
  let onChange;
30
38
  let props;
39
+ let providers;
31
40
  let readOnly;
32
41
  let required;
33
42
  let t1;
34
43
  let value;
35
44
  if ($[0] !== t0) {
36
- ({value, onChange, onBlur, embedSource: embedSourceProp, errors: t1, disabled, readOnly, required, ...props} = t0);
45
+ ({value, onChange, onBlur, embedSource: embedSourceProp, providers, errors: t1, disabled, readOnly, required, description, ...props} = t0);
37
46
  $[0] = t0;
38
- $[1] = disabled;
39
- $[2] = embedSourceProp;
40
- $[3] = onBlur;
41
- $[4] = onChange;
42
- $[5] = props;
43
- $[6] = readOnly;
44
- $[7] = required;
45
- $[8] = t1;
46
- $[9] = value;
47
+ $[1] = description;
48
+ $[2] = disabled;
49
+ $[3] = embedSourceProp;
50
+ $[4] = onBlur;
51
+ $[5] = onChange;
52
+ $[6] = props;
53
+ $[7] = providers;
54
+ $[8] = readOnly;
55
+ $[9] = required;
56
+ $[10] = t1;
57
+ $[11] = value;
47
58
  } else {
48
- disabled = $[1];
49
- embedSourceProp = $[2];
50
- onBlur = $[3];
51
- onChange = $[4];
52
- props = $[5];
53
- readOnly = $[6];
54
- required = $[7];
55
- t1 = $[8];
56
- value = $[9];
59
+ description = $[1];
60
+ disabled = $[2];
61
+ embedSourceProp = $[3];
62
+ onBlur = $[4];
63
+ onChange = $[5];
64
+ props = $[6];
65
+ providers = $[7];
66
+ readOnly = $[8];
67
+ required = $[9];
68
+ t1 = $[10];
69
+ value = $[11];
57
70
  }
58
71
  let t2;
59
- if ($[10] !== t1) {
72
+ if ($[12] !== t1) {
60
73
  t2 = t1 === void 0 ? [] : t1;
61
- $[10] = t1;
62
- $[11] = t2;
63
- } else t2 = $[11];
74
+ $[12] = t1;
75
+ $[13] = t2;
76
+ } else t2 = $[13];
64
77
  const errors = t2;
65
78
  const intl = usePanneauIntl();
66
79
  const context = useFieldsContext();
@@ -69,14 +82,14 @@ function EmbedField(t0) {
69
82
  const [status, setStatus] = useState(null);
70
83
  const pending = value !== null && value !== void 0 && !isResolved(value) ? value.url : null;
71
84
  let t3;
72
- if ($[12] !== onChange) {
85
+ if ($[14] !== onChange) {
73
86
  t3 = (embed) => onChange?.(embed);
74
- $[12] = onChange;
75
- $[13] = t3;
76
- } else t3 = $[13];
87
+ $[14] = onChange;
88
+ $[15] = t3;
89
+ } else t3 = $[15];
77
90
  const resolved = useEffectEvent(t3);
78
91
  let t4;
79
- if ($[14] !== embedSource || $[15] !== pending || $[16] !== resolved) {
92
+ if ($[16] !== embedSource || $[17] !== pending || $[18] !== resolved) {
80
93
  t4 = () => {
81
94
  if (embedSource === null || pending === null || !URL.canParse(pending)) return;
82
95
  const controller = new AbortController();
@@ -103,80 +116,107 @@ function EmbedField(t0) {
103
116
  controller.abort();
104
117
  };
105
118
  };
106
- $[14] = embedSource;
107
- $[15] = pending;
108
- $[16] = resolved;
109
- $[17] = t4;
110
- } else t4 = $[17];
119
+ $[16] = embedSource;
120
+ $[17] = pending;
121
+ $[18] = resolved;
122
+ $[19] = t4;
123
+ } else t4 = $[19];
111
124
  let t5;
112
- if ($[18] !== embedSource || $[19] !== pending) {
125
+ if ($[20] !== embedSource || $[21] !== pending) {
113
126
  t5 = [embedSource, pending];
114
- $[18] = embedSource;
115
- $[19] = pending;
116
- $[20] = t5;
117
- } else t5 = $[20];
127
+ $[20] = embedSource;
128
+ $[21] = pending;
129
+ $[22] = t5;
130
+ } else t5 = $[22];
118
131
  useEffect(t4, t5);
119
132
  const current = status !== null && status.url === url ? status.state : null;
133
+ let providerList;
120
134
  let t6;
121
- if ($[21] !== current || $[22] !== errors || $[23] !== intl) {
122
- t6 = current === "failed" && errors.length === 0 ? [intl.formatMessage(messages.embedFailed)] : errors;
123
- $[21] = current;
124
- $[22] = errors;
125
- $[23] = intl;
126
- $[24] = t6;
127
- } else t6 = $[24];
128
- const shownErrors = t6;
135
+ if ($[23] !== current || $[24] !== intl || $[25] !== providers || $[26] !== value) {
136
+ providerList = providers !== void 0 && providers.length > 0 ? intl.formatList(providers, { type: "disjunction" }) : null;
137
+ t6 = current === "failed" ? intl.formatMessage(messages.embedFailed) : value !== null && value !== void 0 && providerList !== null && !isAllowed(value, providers) ? intl.formatMessage(formsMessages.rule.providers, { providers: providerList }) : null;
138
+ $[23] = current;
139
+ $[24] = intl;
140
+ $[25] = providers;
141
+ $[26] = value;
142
+ $[27] = providerList;
143
+ $[28] = t6;
144
+ } else {
145
+ providerList = $[27];
146
+ t6 = $[28];
147
+ }
148
+ const ownError = t6;
129
149
  let t7;
130
- if ($[25] !== onChange) {
131
- t7 = (next) => onChange?.(next.trim() === "" ? null : { url: next.trim() });
132
- $[25] = onChange;
133
- $[26] = t7;
134
- } else t7 = $[26];
150
+ if ($[29] !== errors || $[30] !== ownError) {
151
+ t7 = ownError !== null && errors.length === 0 ? [ownError] : errors;
152
+ $[29] = errors;
153
+ $[30] = ownError;
154
+ $[31] = t7;
155
+ } else t7 = $[31];
156
+ const shownErrors = t7;
135
157
  let t8;
136
- if ($[27] !== onBlur) {
137
- t8 = () => onBlur?.();
138
- $[27] = onBlur;
139
- $[28] = t8;
140
- } else t8 = $[28];
158
+ if ($[32] !== description || $[33] !== intl || $[34] !== providerList || $[35] !== providers) {
159
+ t8 = providerList !== null ? /* @__PURE__ */ jsxs(Fragment, { children: [description !== void 0 && description !== null ? /* @__PURE__ */ jsxs(Fragment, { children: [description, " "] }) : null, intl.formatMessage(messages.embedProviders, { providers: intl.formatList(providers ?? [], { type: "conjunction" }) })] }) : description;
160
+ $[32] = description;
161
+ $[33] = intl;
162
+ $[34] = providerList;
163
+ $[35] = providers;
164
+ $[36] = t8;
165
+ } else t8 = $[36];
166
+ const help = t8;
141
167
  let t9;
142
- if ($[29] !== disabled || $[30] !== props || $[31] !== readOnly || $[32] !== required || $[33] !== shownErrors || $[34] !== t7 || $[35] !== t8 || $[36] !== url) {
143
- t9 = /* @__PURE__ */ jsx(TextInput, {
168
+ if ($[37] !== onChange) {
169
+ t9 = (next) => onChange?.(next.trim() === "" ? null : { url: next.trim() });
170
+ $[37] = onChange;
171
+ $[38] = t9;
172
+ } else t9 = $[38];
173
+ let t10;
174
+ if ($[39] !== onBlur) {
175
+ t10 = () => onBlur?.();
176
+ $[39] = onBlur;
177
+ $[40] = t10;
178
+ } else t10 = $[40];
179
+ let t11;
180
+ if ($[41] !== disabled || $[42] !== help || $[43] !== props || $[44] !== readOnly || $[45] !== required || $[46] !== shownErrors || $[47] !== t10 || $[48] !== t9 || $[49] !== url) {
181
+ t11 = /* @__PURE__ */ jsx(TextInput, {
144
182
  ...props,
145
183
  type: "url",
146
184
  inputMode: "url",
147
185
  autoComplete: "off",
148
186
  value: url,
149
- onChange: t7,
150
- onBlur: t8,
187
+ onChange: t9,
188
+ onBlur: t10,
151
189
  errors: shownErrors,
190
+ description: help,
152
191
  isDisabled: disabled,
153
192
  isReadOnly: readOnly,
154
193
  isRequired: required
155
194
  });
156
- $[29] = disabled;
157
- $[30] = props;
158
- $[31] = readOnly;
159
- $[32] = required;
160
- $[33] = shownErrors;
161
- $[34] = t7;
162
- $[35] = t8;
163
- $[36] = url;
164
- $[37] = t9;
165
- } else t9 = $[37];
166
- let t10;
167
- if ($[38] !== current || $[39] !== intl) {
168
- t10 = current === "loading" ? /* @__PURE__ */ jsxs("div", {
195
+ $[41] = disabled;
196
+ $[42] = help;
197
+ $[43] = props;
198
+ $[44] = readOnly;
199
+ $[45] = required;
200
+ $[46] = shownErrors;
201
+ $[47] = t10;
202
+ $[48] = t9;
203
+ $[49] = url;
204
+ $[50] = t11;
205
+ } else t11 = $[50];
206
+ let t12;
207
+ if ($[51] !== current || $[52] !== intl) {
208
+ t12 = current === "loading" ? /* @__PURE__ */ jsxs("div", {
169
209
  className: EmbedField_module_default.status,
170
210
  role: "status",
171
211
  children: [/* @__PURE__ */ jsx(Spinner, { size: "sm" }), intl.formatMessage(messages.embedLoading)]
172
212
  }) : null;
173
- $[38] = current;
174
- $[39] = intl;
175
- $[40] = t10;
176
- } else t10 = $[40];
177
- let t11;
178
- if ($[41] !== value) {
179
- t11 = value !== null && value !== void 0 && isResolved(value) ? /* @__PURE__ */ jsxs("a", {
213
+ $[51] = current;
214
+ $[52] = intl;
215
+ $[53] = t12;
216
+ } else t12 = $[53];
217
+ let t13;
218
+ if ($[54] !== value) {
219
+ t13 = value !== null && value !== void 0 && isResolved(value) ? /* @__PURE__ */ jsxs("a", {
180
220
  className: EmbedField_module_default.preview,
181
221
  href: value.url,
182
222
  target: "_blank",
@@ -196,49 +236,72 @@ function EmbedField(t0) {
196
236
  }) : null]
197
237
  })]
198
238
  }) : null;
199
- $[41] = value;
200
- $[42] = t11;
201
- } else t11 = $[42];
202
- let t12;
203
- if ($[43] !== t10 || $[44] !== t11 || $[45] !== t9) {
204
- t12 = /* @__PURE__ */ jsxs("div", {
239
+ $[54] = value;
240
+ $[55] = t13;
241
+ } else t13 = $[55];
242
+ let t14;
243
+ if ($[56] !== t11 || $[57] !== t12 || $[58] !== t13) {
244
+ t14 = /* @__PURE__ */ jsxs("div", {
205
245
  className: EmbedField_module_default.embed,
206
246
  children: [
207
- t9,
208
- t10,
209
- t11
247
+ t11,
248
+ t12,
249
+ t13
210
250
  ]
211
251
  });
212
- $[43] = t10;
213
- $[44] = t11;
214
- $[45] = t9;
215
- $[46] = t12;
216
- } else t12 = $[46];
217
- return t12;
252
+ $[56] = t11;
253
+ $[57] = t12;
254
+ $[58] = t13;
255
+ $[59] = t14;
256
+ } else t14 = $[59];
257
+ return t14;
258
+ }
259
+ /** The providers of a `providers` rule, if the field has one. */
260
+ function getProviders(field) {
261
+ const rule = findRule(field, "providers");
262
+ return rule !== void 0 && "value" in rule && Array.isArray(rule.value) ? rule.value.filter(isString) : void 0;
218
263
  }
219
- /** The `embed` type: its preview comes from the embed source of the `FieldsProvider`. */
264
+ /**
265
+ * The `embed` type: its preview comes from the embed source of the `FieldsProvider`, and its
266
+ * `providers` rule names the providers it allows.
267
+ */
220
268
  function EmbedFieldEntry(props) {
221
- const $ = c(6);
269
+ const $ = c(11);
222
270
  let t0;
223
- if ($[0] !== props) {
224
- t0 = getFieldProps(props);
225
- $[0] = props;
271
+ if ($[0] !== props.field) {
272
+ t0 = getProviders(props.field);
273
+ $[0] = props.field;
226
274
  $[1] = t0;
227
275
  } else t0 = $[1];
228
- const t1 = isEmbed(props.value) ? props.value : null;
229
- let t2;
230
- if ($[2] !== props.onChange || $[3] !== t0 || $[4] !== t1) {
231
- t2 = /* @__PURE__ */ jsx(EmbedField, {
232
- ...t0,
233
- value: t1,
234
- onChange: props.onChange
276
+ const providers = t0;
277
+ let t1;
278
+ if ($[2] !== props) {
279
+ t1 = getFieldProps(props);
280
+ $[2] = props;
281
+ $[3] = t1;
282
+ } else t1 = $[3];
283
+ const t2 = isEmbed(props.value) ? props.value : null;
284
+ let t3;
285
+ if ($[4] !== providers) {
286
+ t3 = providers !== void 0 ? { providers } : {};
287
+ $[4] = providers;
288
+ $[5] = t3;
289
+ } else t3 = $[5];
290
+ let t4;
291
+ if ($[6] !== props.onChange || $[7] !== t1 || $[8] !== t2 || $[9] !== t3) {
292
+ t4 = /* @__PURE__ */ jsx(EmbedField, {
293
+ ...t1,
294
+ value: t2,
295
+ onChange: props.onChange,
296
+ ...t3
235
297
  });
236
- $[2] = props.onChange;
237
- $[3] = t0;
238
- $[4] = t1;
239
- $[5] = t2;
240
- } else t2 = $[5];
241
- return t2;
298
+ $[6] = props.onChange;
299
+ $[7] = t1;
300
+ $[8] = t2;
301
+ $[9] = t3;
302
+ $[10] = t4;
303
+ } else t4 = $[10];
304
+ return t4;
242
305
  }
243
306
  //#endregion
244
307
  export { EmbedField, EmbedFieldEntry, isEmbed };
@@ -1 +1 @@
1
- {"version":3,"file":"EmbedField.js","names":["useEffect","useEffectEvent","useState","EmbedValue","Spinner","TextInput","usePanneauIntl","useFieldsContext","EmbedSource","getFieldProps","isString","messages","FieldEntryProps","FieldProps","styles","RESOLVE_DELAY","EmbedFieldProps","placeholder","embedSource","isEmbed","value","Record","url","isResolved","Object","keys","some","key","EmbedField","t0","$","_c","disabled","embedSourceProp","onBlur","onChange","props","readOnly","required","t1","errors","t2","undefined","intl","context","status","setStatus","pending","t3","embed","resolved","t4","URL","canParse","controller","AbortController","timeout","window","setTimeout","state","resolve","signal","then","embed_0","catch","aborted","clearTimeout","abort","t5","current","t6","length","formatMessage","embedFailed","shownErrors","t7","next","trim","t8","t9","t10","embedLoading","t11","preview","thumbnailUrl","thumbnail","text","title","provider","t12","EmbedFieldEntry","_c","styles"],"sources":["../../src/embed/EmbedField.tsx"],"sourcesContent":["import { useEffect, useEffectEvent, useState } from 'react';\n\nimport type { EmbedValue } from '@panneau/protocol';\nimport { Spinner, TextInput, usePanneauIntl } from '@panneau/ui';\n\nimport { useFieldsContext } from '../shared/context';\nimport type { EmbedSource } from '../shared/embed';\nimport { getFieldProps, isString } from '../shared/entry';\nimport { messages } from '../shared/messages';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport styles from './EmbedField.module.css';\n\nexport type { EmbedValue };\n\nconst RESOLVE_DELAY = 500;\n\nexport interface EmbedFieldProps extends FieldProps<EmbedValue> {\n placeholder?: string;\n /** Where the preview comes from. Defaults to that of the `FieldsProvider`. */\n embedSource?: EmbedSource | null;\n}\n\n/** Whether a value is an embed: an object with a `url`. */\nexport function isEmbed(value: unknown): value is EmbedValue {\n return (\n value !== null &&\n typeof value === 'object' &&\n isString((value as Record<string, unknown>).url)\n );\n}\n\n/** Whether a value has been resolved: it has more than its URL. */\nfunction isResolved(value: EmbedValue): boolean {\n return Object.keys(value).some((key) => key !== 'url');\n}\n\n/**\n * A URL of a video, a sound or a post, with the preview the backend gets from its provider's\n * oEmbed: its thumbnail, title and provider. The URL is kept as soon as it is typed, and its\n * preview follows. Without an embed source, the value is the URL alone.\n */\nexport function EmbedField({\n value,\n onChange,\n onBlur,\n embedSource: embedSourceProp,\n errors = [],\n disabled,\n readOnly,\n required,\n ...props\n}: EmbedFieldProps) {\n const intl = usePanneauIntl();\n const context = useFieldsContext();\n const embedSource = embedSourceProp === undefined ? context.embedSource : embedSourceProp;\n const url = value?.url ?? '';\n const [status, setStatus] = useState<{ url: string; state: 'loading' | 'failed' } | null>(null);\n\n // Resolves a URL that hasn't been, after a pause in typing\n const pending = value !== null && value !== undefined && !isResolved(value) ? value.url : null;\n // `onChange` changes on every render of a form: the latest one gets the preview\n const resolved = useEffectEvent((embed: EmbedValue) => onChange?.(embed));\n useEffect(() => {\n if (embedSource === null || pending === null || !URL.canParse(pending)) {\n return undefined;\n }\n const controller = new AbortController();\n const timeout = window.setTimeout(() => {\n setStatus({ url: pending, state: 'loading' });\n embedSource\n .resolve(pending, { signal: controller.signal })\n .then((embed) => {\n setStatus(null);\n resolved({ ...embed, url: pending });\n })\n .catch(() => {\n if (!controller.signal.aborted) {\n setStatus({ url: pending, state: 'failed' });\n }\n });\n }, RESOLVE_DELAY);\n return () => {\n window.clearTimeout(timeout);\n controller.abort();\n };\n }, [embedSource, pending]);\n\n const current = status !== null && status.url === url ? status.state : null;\n const shownErrors =\n current === 'failed' && errors.length === 0\n ? [intl.formatMessage(messages.embedFailed)]\n : errors;\n return (\n <div className={styles.embed}>\n <TextInput\n {...props}\n type=\"url\"\n inputMode=\"url\"\n autoComplete=\"off\"\n value={url}\n onChange={(next) => onChange?.(next.trim() === '' ? null : { url: next.trim() })}\n onBlur={() => onBlur?.()}\n errors={shownErrors}\n isDisabled={disabled}\n isReadOnly={readOnly}\n isRequired={required}\n />\n {current === 'loading' ? (\n <div className={styles.status} role=\"status\">\n <Spinner size=\"sm\" />\n {intl.formatMessage(messages.embedLoading)}\n </div>\n ) : null}\n {value !== null && value !== undefined && isResolved(value) ? (\n <a className={styles.preview} href={value.url} target=\"_blank\" rel=\"noreferrer\">\n {value.thumbnailUrl !== undefined ? (\n <img className={styles.thumbnail} src={value.thumbnailUrl} alt=\"\" />\n ) : null}\n <span className={styles.text}>\n <span className={styles.title}>{value.title ?? value.url}</span>\n {value.provider !== undefined ? (\n <span className={styles.provider}>{value.provider}</span>\n ) : null}\n </span>\n </a>\n ) : null}\n </div>\n );\n}\n\n/** The `embed` type: its preview comes from the embed source of the `FieldsProvider`. */\nexport function EmbedFieldEntry(props: FieldEntryProps) {\n return (\n <EmbedField\n {...getFieldProps(props)}\n value={isEmbed(props.value) ? props.value : null}\n onChange={props.onChange}\n />\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EmbedField.js","names":["ReactNode","useEffect","useEffectEvent","useState","formsMessages","EmbedValue","Spinner","TextInput","usePanneauIntl","useFieldsContext","EmbedSource","findRule","getFieldProps","isString","messages","FieldEntryProps","FieldProps","styles","RESOLVE_DELAY","EmbedFieldProps","placeholder","embedSource","providers","isEmbed","value","Record","url","isAllowed","undefined","length","provider","toLowerCase","some","allowed","isResolved","Object","keys","key","EmbedField","t0","$","_c","description","disabled","embedSourceProp","onBlur","onChange","props","readOnly","required","t1","errors","t2","intl","context","status","setStatus","pending","t3","embed","resolved","t4","URL","canParse","controller","AbortController","timeout","window","setTimeout","state","resolve","signal","then","embed_0","catch","aborted","clearTimeout","abort","t5","current","providerList","t6","formatList","type","formatMessage","embedFailed","rule","ownError","t7","shownErrors","t8","embedProviders","help","t9","next","trim","t10","t11","t12","embedLoading","t13","preview","thumbnailUrl","thumbnail","text","title","t14","getProviders","field","Array","isArray","filter","EmbedFieldEntry","_c","_Fragment","styles"],"sources":["../../src/embed/EmbedField.tsx"],"sourcesContent":["import { type ReactNode, useEffect, useEffectEvent, useState } from 'react';\n\nimport { formsMessages } from '@panneau/intl';\nimport type { EmbedValue } from '@panneau/protocol';\nimport { Spinner, TextInput, usePanneauIntl } from '@panneau/ui';\n\nimport { useFieldsContext } from '../shared/context';\nimport type { EmbedSource } from '../shared/embed';\nimport { findRule, getFieldProps, isString } from '../shared/entry';\nimport { messages } from '../shared/messages';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport styles from './EmbedField.module.css';\n\nexport type { EmbedValue };\n\nconst RESOLVE_DELAY = 500;\n\nexport interface EmbedFieldProps extends FieldProps<EmbedValue> {\n placeholder?: string;\n /** Where the preview comes from. Defaults to that of the `FieldsProvider`. */\n embedSource?: EmbedSource | null;\n /**\n * The providers an embed may come from (`YouTube`), compared without case: the `providers`\n * rule (decision 0058). The field names them under its help, and refuses an embed of another\n * provider as soon as its preview comes back. The form's errors, once shown, replace that one.\n */\n providers?: readonly string[];\n}\n\n/** Whether a value is an embed: an object with a `url`. */\nexport function isEmbed(value: unknown): value is EmbedValue {\n return (\n value !== null &&\n typeof value === 'object' &&\n isString((value as Record<string, unknown>).url)\n );\n}\n\n/** Whether an embed comes from one of the providers. One without a provider is left to the backend. */\nfunction isAllowed(value: EmbedValue, providers: readonly string[] | undefined): boolean {\n if (providers === undefined || providers.length === 0 || value.provider === undefined) {\n return true;\n }\n const provider = value.provider.toLowerCase();\n return providers.some((allowed) => allowed.toLowerCase() === provider);\n}\n\n/** Whether a value has been resolved: it has more than its URL. */\nfunction isResolved(value: EmbedValue): boolean {\n return Object.keys(value).some((key) => key !== 'url');\n}\n\n/**\n * A URL of a video, a sound or a post, with the preview the backend gets from its provider's\n * oEmbed: its thumbnail, title and provider. The URL is kept as soon as it is typed, and its\n * preview follows. Without an embed source, the value is the URL alone.\n */\nexport function EmbedField({\n value,\n onChange,\n onBlur,\n embedSource: embedSourceProp,\n providers,\n errors = [],\n disabled,\n readOnly,\n required,\n description,\n ...props\n}: EmbedFieldProps) {\n const intl = usePanneauIntl();\n const context = useFieldsContext();\n const embedSource = embedSourceProp === undefined ? context.embedSource : embedSourceProp;\n const url = value?.url ?? '';\n const [status, setStatus] = useState<{ url: string; state: 'loading' | 'failed' } | null>(null);\n\n // Resolves a URL that hasn't been, after a pause in typing\n const pending = value !== null && value !== undefined && !isResolved(value) ? value.url : null;\n // `onChange` changes on every render of a form: the latest one gets the preview\n const resolved = useEffectEvent((embed: EmbedValue) => onChange?.(embed));\n useEffect(() => {\n if (embedSource === null || pending === null || !URL.canParse(pending)) {\n return undefined;\n }\n const controller = new AbortController();\n const timeout = window.setTimeout(() => {\n setStatus({ url: pending, state: 'loading' });\n embedSource\n .resolve(pending, { signal: controller.signal })\n .then((embed) => {\n setStatus(null);\n resolved({ ...embed, url: pending });\n })\n .catch(() => {\n if (!controller.signal.aborted) {\n setStatus({ url: pending, state: 'failed' });\n }\n });\n }, RESOLVE_DELAY);\n return () => {\n window.clearTimeout(timeout);\n controller.abort();\n };\n }, [embedSource, pending]);\n\n const current = status !== null && status.url === url ? status.state : null;\n const providerList =\n providers !== undefined && providers.length > 0\n ? intl.formatList(providers, { type: 'disjunction' })\n : null;\n const ownError =\n current === 'failed'\n ? intl.formatMessage(messages.embedFailed)\n : value !== null &&\n value !== undefined &&\n providerList !== null &&\n !isAllowed(value, providers)\n ? intl.formatMessage(formsMessages.rule.providers, { providers: providerList })\n : null;\n const shownErrors = ownError !== null && errors.length === 0 ? [ownError] : errors;\n const help: ReactNode =\n providerList !== null ? (\n <>\n {description !== undefined && description !== null ? <>{description} </> : null}\n {intl.formatMessage(messages.embedProviders, {\n providers: intl.formatList(providers ?? [], { type: 'conjunction' }),\n })}\n </>\n ) : (\n description\n );\n return (\n <div className={styles.embed}>\n <TextInput\n {...props}\n type=\"url\"\n inputMode=\"url\"\n autoComplete=\"off\"\n value={url}\n onChange={(next) => onChange?.(next.trim() === '' ? null : { url: next.trim() })}\n onBlur={() => onBlur?.()}\n errors={shownErrors}\n description={help}\n isDisabled={disabled}\n isReadOnly={readOnly}\n isRequired={required}\n />\n {current === 'loading' ? (\n <div className={styles.status} role=\"status\">\n <Spinner size=\"sm\" />\n {intl.formatMessage(messages.embedLoading)}\n </div>\n ) : null}\n {value !== null && value !== undefined && isResolved(value) ? (\n <a className={styles.preview} href={value.url} target=\"_blank\" rel=\"noreferrer\">\n {value.thumbnailUrl !== undefined ? (\n <img className={styles.thumbnail} src={value.thumbnailUrl} alt=\"\" />\n ) : null}\n <span className={styles.text}>\n <span className={styles.title}>{value.title ?? value.url}</span>\n {value.provider !== undefined ? (\n <span className={styles.provider}>{value.provider}</span>\n ) : null}\n </span>\n </a>\n ) : null}\n </div>\n );\n}\n\n/** The providers of a `providers` rule, if the field has one. */\nfunction getProviders(field: FieldEntryProps['field']): string[] | undefined {\n const rule = findRule(field, 'providers');\n return rule !== undefined && 'value' in rule && Array.isArray(rule.value)\n ? rule.value.filter(isString)\n : undefined;\n}\n\n/**\n * The `embed` type: its preview comes from the embed source of the `FieldsProvider`, and its\n * `providers` rule names the providers it allows.\n */\nexport function EmbedFieldEntry(props: FieldEntryProps) {\n const providers = getProviders(props.field);\n return (\n <EmbedField\n {...getFieldProps(props)}\n value={isEmbed(props.value) ? props.value : null}\n onChange={props.onChange}\n {...(providers !== undefined ? { providers } : {})}\n />\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /* The type, its input, the label, then the new tab. */
2
+ .panneau-link-field-link {
3
+ display: flex;
4
+ flex-direction: column;
5
+ align-items: stretch;
6
+ gap: var(--panneau-space-3);
7
+ }
8
+
9
+ .panneau-link-field-link > :first-child {
10
+ align-self: flex-start;
11
+ max-width: 100%;
12
+ }
@@ -0,0 +1,38 @@
1
+ import type { LinkValue } from '@panneau/protocol';
2
+ import { type LinkNewTab, type LinkType } from '@panneau/protocol/runtime';
3
+ import type { FieldEntryProps, FieldProps } from '../shared/types.js';
4
+ /** Whether links have a label: optional, required, or none. */
5
+ export type LinkLabelMode = 'optional' | 'required' | 'none';
6
+ export interface LinkFieldProps extends FieldProps<LinkValue> {
7
+ /** Dot path of the value, the prefix of the paths of its parts. Defaults to `name`. */
8
+ path?: string;
9
+ /** The types offered, in order. Defaults to `url`, `email` and `tel`. */
10
+ types?: readonly LinkType[];
11
+ /** The resources of `page` links. */
12
+ pages?: readonly string[];
13
+ /** The media libraries of `file` links. Defaults to every library. */
14
+ libraries?: readonly string[];
15
+ /** Which links open in a new tab. Defaults to `choose`, a checkbox. */
16
+ newTab?: LinkNewTab;
17
+ /** Whether links have a label. Defaults to `optional`. */
18
+ labelMode?: LinkLabelMode;
19
+ /**
20
+ * The label is a string, not a value per locale: in a `localized` link field, where the whole
21
+ * link is per locale already.
22
+ */
23
+ singleLabel?: boolean;
24
+ }
25
+ /**
26
+ * A link (decision 0055): its type, in a segmented control, then the input of the type (a URL, a
27
+ * page searched in the resources of `pages`, an email address, a phone number, a media, or the
28
+ * text of a type of the site), its label per locale, and whether it opens in a new tab. Each part
29
+ * shows the errors of its own path (`link.url`) in a form.
30
+ */
31
+ export declare function LinkField({ value, onChange, onBlur, path, name, types: typesProp, pages, libraries, newTab, labelMode, singleLabel, label, description, errors, disabled, readOnly, required, className, }: LinkFieldProps): import("react").JSX.Element;
32
+ /**
33
+ * The `link` type: its `resource` (the resources of `page` links), and settings `types`,
34
+ * `newTab`, `label` and `libraries`. In a localized field, the label of each locale's link is a
35
+ * string.
36
+ */
37
+ export declare function LinkFieldEntry(props: FieldEntryProps): import("react").JSX.Element;
38
+ //# sourceMappingURL=LinkField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkField.d.ts","sourceRoot":"","sources":["../../src/link/LinkField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAS,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EACH,KAAK,UAAU,EACf,KAAK,QAAQ,EAGhB,MAAM,2BAA2B,CAAC;AAkBnC,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAQnE,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,cAAe,SAAQ,UAAU,CAAC,SAAS,CAAC;IACzD,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,KAAK,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC5B,qCAAqC;IACrC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,sEAAsE;IACtE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,uEAAuE;IACvE,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAoBD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,KAAK,EAAE,SAAS,EAChB,KAAU,EACV,SAAS,EACT,MAAiB,EACjB,SAAsB,EACtB,WAAmB,EACnB,KAAK,EACL,WAAW,EACX,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,GACZ,EAAE,cAAc,+BA8OhB;AAgFD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,+BAyBpD"}