@panneau/fields 5.0.0-alpha.0 → 5.0.0-alpha.10
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 +103 -20
- package/dist/boolean/BooleanField.d.ts +1 -1
- package/dist/boolean/BooleanField.js +78 -17
- package/dist/boolean/BooleanField.js.map +1 -1
- package/dist/boolean/index.d.ts +1 -1
- package/dist/color/ColorField.css +5 -5
- package/dist/color/ColorField.d.ts +2 -2
- package/dist/color/ColorField.js.map +1 -1
- package/dist/color/ColorField.module.js +3 -3
- package/dist/color/index.d.ts +1 -1
- package/dist/date/DateField.d.ts +1 -1
- package/dist/date/DateField.js.map +1 -1
- package/dist/date/index.d.ts +1 -1
- package/dist/datetime/DateTimeField.d.ts +1 -1
- package/dist/datetime/DateTimeField.js +107 -20
- package/dist/datetime/DateTimeField.js.map +1 -1
- package/dist/datetime/index.d.ts +1 -1
- package/dist/duration/DurationField.css +11 -0
- package/dist/duration/DurationField.d.ts +26 -0
- package/dist/duration/DurationField.d.ts.map +1 -0
- package/dist/duration/DurationField.js +214 -0
- package/dist/duration/DurationField.js.map +1 -0
- package/dist/duration/DurationField.module.js +12 -0
- package/dist/duration/DurationField.module.js.map +1 -0
- package/dist/duration/index.d.ts +2 -0
- package/dist/duration/index.d.ts.map +1 -0
- package/dist/duration/index.js +1 -0
- package/dist/email/EmailField.d.ts +2 -2
- package/dist/email/EmailField.js.map +1 -1
- package/dist/email/index.d.ts +1 -1
- package/dist/embed/EmbedField.css +60 -0
- package/dist/embed/EmbedField.d.ts +20 -0
- package/dist/embed/EmbedField.d.ts.map +1 -0
- package/dist/embed/EmbedField.js +246 -0
- package/dist/embed/EmbedField.js.map +1 -0
- package/dist/embed/EmbedField.module.js +22 -0
- package/dist/embed/EmbedField.module.js.map +1 -0
- package/dist/embed/index.d.ts +3 -0
- package/dist/embed/index.d.ts.map +1 -0
- package/dist/embed/index.js +3 -0
- package/dist/file/FileField.css +54 -0
- package/dist/file/FileField.d.ts +50 -0
- package/dist/file/FileField.d.ts.map +1 -0
- package/dist/file/FileField.js +288 -0
- package/dist/file/FileField.js.map +1 -0
- package/dist/file/FileField.module.js +22 -0
- package/dist/file/FileField.module.js.map +1 -0
- package/dist/file/index.d.ts +3 -0
- package/dist/file/index.d.ts.map +1 -0
- package/dist/file/index.js +1 -0
- package/dist/group/GroupField.css +2 -2
- package/dist/group/GroupField.d.ts +1 -1
- package/dist/group/GroupField.js.map +1 -1
- package/dist/group/GroupField.module.js +1 -1
- package/dist/group/index.d.ts +1 -1
- package/dist/index.d.ts +18 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -3
- package/dist/json/JsonField.css +7 -0
- package/dist/json/JsonField.d.ts +22 -0
- package/dist/json/JsonField.d.ts.map +1 -0
- package/dist/json/JsonField.js +207 -0
- package/dist/json/JsonField.js.map +1 -0
- package/dist/json/JsonField.module.js +8 -0
- package/dist/json/JsonField.module.js.map +1 -0
- package/dist/json/index.d.ts +2 -0
- package/dist/json/index.d.ts.map +1 -0
- package/dist/json/index.js +1 -0
- package/dist/locales/index.js.map +1 -1
- package/dist/localized/LocalizedField.css +2 -2
- package/dist/localized/LocalizedField.d.ts +1 -1
- package/dist/localized/LocalizedField.d.ts.map +1 -1
- package/dist/localized/LocalizedField.js +1 -0
- package/dist/localized/LocalizedField.js.map +1 -1
- package/dist/localized/LocalizedField.module.js +2 -2
- package/dist/localized/index.d.ts +1 -1
- package/dist/location/LocationField.css +54 -0
- package/dist/location/LocationField.d.ts +31 -0
- package/dist/location/LocationField.d.ts.map +1 -0
- package/dist/location/LocationField.js +563 -0
- package/dist/location/LocationField.js.map +1 -0
- package/dist/location/LocationField.module.js +22 -0
- package/dist/location/LocationField.module.js.map +1 -0
- package/dist/location/LocationMap.d.ts +25 -0
- package/dist/location/LocationMap.d.ts.map +1 -0
- package/dist/location/LocationMap.js +205 -0
- package/dist/location/LocationMap.js.map +1 -0
- package/dist/location/index.d.ts +5 -0
- package/dist/location/index.d.ts.map +1 -0
- package/dist/location/index.js +4 -0
- package/dist/location/leafletCss.d.ts +2 -0
- package/dist/location/leafletCss.d.ts.map +1 -0
- package/dist/location/leafletCss.js +6 -0
- package/dist/location/leafletCss.js.map +1 -0
- package/dist/location/nominatim.d.ts +17 -0
- package/dist/location/nominatim.d.ts.map +1 -0
- package/dist/location/nominatim.js +50 -0
- package/dist/location/nominatim.js.map +1 -0
- package/dist/location/types.d.ts +40 -0
- package/dist/location/types.d.ts.map +1 -0
- package/dist/missing/MissingField.css +4 -3
- package/dist/missing/MissingField.d.ts +4 -3
- package/dist/missing/MissingField.d.ts.map +1 -1
- package/dist/missing/MissingField.js +3 -2
- package/dist/missing/MissingField.js.map +1 -1
- package/dist/missing/MissingField.module.js +3 -3
- package/dist/missing/MissingField.module.js.map +1 -1
- package/dist/number/NumberField.d.ts +1 -1
- package/dist/number/NumberField.js.map +1 -1
- package/dist/number/index.d.ts +1 -1
- package/dist/range/RangeField.d.ts +22 -0
- package/dist/range/RangeField.d.ts.map +1 -0
- package/dist/range/RangeField.js +203 -0
- package/dist/range/RangeField.js.map +1 -0
- package/dist/range/index.d.ts +2 -0
- package/dist/range/index.d.ts.map +1 -0
- package/dist/range/index.js +1 -0
- package/dist/relation/RelationField.css +7 -7
- package/dist/relation/RelationField.d.ts +12 -4
- package/dist/relation/RelationField.d.ts.map +1 -1
- package/dist/relation/RelationField.js +535 -160
- package/dist/relation/RelationField.js.map +1 -1
- package/dist/relation/RelationField.module.js +6 -6
- package/dist/relation/index.d.ts +2 -2
- package/dist/relation/index.d.ts.map +1 -1
- package/dist/relation/index.js +2 -2
- package/dist/repeater/RepeaterField.css +12 -11
- package/dist/repeater/RepeaterField.d.ts +1 -1
- package/dist/repeater/RepeaterField.js +118 -34
- package/dist/repeater/RepeaterField.js.map +1 -1
- package/dist/repeater/RepeaterField.module.js +9 -9
- package/dist/repeater/RepeaterField.module.js.map +1 -1
- package/dist/repeater/index.d.ts +1 -1
- package/dist/select/SelectField.css +1 -1
- package/dist/select/SelectField.d.ts +1 -1
- package/dist/select/SelectField.js.map +1 -1
- package/dist/select/SelectField.module.js +1 -1
- package/dist/select/index.d.ts +1 -1
- package/dist/shared/DefinitionField.d.ts +5 -3
- package/dist/shared/DefinitionField.d.ts.map +1 -1
- package/dist/shared/DefinitionField.js +81 -73
- package/dist/shared/DefinitionField.js.map +1 -1
- package/dist/shared/builtIn.d.ts +5 -3
- package/dist/shared/builtIn.d.ts.map +1 -1
- package/dist/shared/builtIn.js +21 -3
- package/dist/shared/builtIn.js.map +1 -1
- package/dist/shared/check.d.ts +27 -0
- package/dist/shared/check.d.ts.map +1 -0
- package/dist/shared/check.js +18 -0
- package/dist/shared/check.js.map +1 -0
- package/dist/shared/context.d.ts +28 -5
- package/dist/shared/context.d.ts.map +1 -1
- package/dist/shared/context.js +35 -19
- package/dist/shared/context.js.map +1 -1
- package/dist/shared/cx.js.map +1 -1
- package/dist/shared/dates.js.map +1 -1
- package/dist/shared/embed.d.ts +19 -0
- package/dist/shared/embed.d.ts.map +1 -0
- package/dist/shared/embed.js +14 -0
- package/dist/shared/embed.js.map +1 -0
- package/dist/shared/entry.d.ts +11 -2
- package/dist/shared/entry.d.ts.map +1 -1
- package/dist/shared/entry.js +19 -3
- package/dist/shared/entry.js.map +1 -1
- package/dist/shared/relation.d.ts +41 -5
- package/dist/shared/relation.d.ts.map +1 -1
- package/dist/shared/relation.js +119 -12
- package/dist/shared/relation.js.map +1 -1
- package/dist/shared/types.d.ts +2 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/slug/SlugField.css +18 -0
- package/dist/slug/SlugField.d.ts +33 -5
- package/dist/slug/SlugField.d.ts.map +1 -1
- package/dist/slug/SlugField.js +346 -126
- package/dist/slug/SlugField.js.map +1 -1
- package/dist/slug/SlugField.module.js +14 -0
- package/dist/slug/SlugField.module.js.map +1 -0
- package/dist/slug/index.d.ts +1 -1
- package/dist/slug/index.d.ts.map +1 -1
- package/dist/slug/index.js +1 -1
- package/dist/tags/TagsField.d.ts +17 -0
- package/dist/tags/TagsField.d.ts.map +1 -0
- package/dist/tags/TagsField.js +120 -0
- package/dist/tags/TagsField.js.map +1 -0
- package/dist/tags/index.d.ts +2 -0
- package/dist/tags/index.d.ts.map +1 -0
- package/dist/tags/index.js +1 -0
- package/dist/tel/TelField.d.ts +11 -0
- package/dist/tel/TelField.d.ts.map +1 -0
- package/dist/tel/TelField.js +87 -0
- package/dist/tel/TelField.js.map +1 -0
- package/dist/tel/index.d.ts +2 -0
- package/dist/tel/index.d.ts.map +1 -0
- package/dist/tel/index.js +1 -0
- package/dist/text/TextField.d.ts +12 -4
- package/dist/text/TextField.d.ts.map +1 -1
- package/dist/text/TextField.js +104 -60
- package/dist/text/TextField.js.map +1 -1
- package/dist/text/index.d.ts +1 -1
- package/dist/textarea/TextAreaField.d.ts +1 -1
- package/dist/textarea/TextAreaField.js.map +1 -1
- package/dist/textarea/index.d.ts +1 -1
- package/dist/time/TimeField.d.ts +1 -1
- package/dist/time/TimeField.js +64 -10
- package/dist/time/TimeField.js.map +1 -1
- package/dist/time/index.d.ts +1 -1
- package/dist/upload/FilePicker.css +24 -0
- package/dist/upload/FilePicker.d.ts +14 -0
- package/dist/upload/FilePicker.d.ts.map +1 -0
- package/dist/upload/FilePicker.js +130 -0
- package/dist/upload/FilePicker.js.map +1 -0
- package/dist/upload/FilePicker.module.js +12 -0
- package/dist/upload/FilePicker.module.js.map +1 -0
- package/dist/upload/UploadList.css +93 -0
- package/dist/upload/UploadList.d.ts +18 -0
- package/dist/upload/UploadList.d.ts.map +1 -0
- package/dist/upload/UploadList.js +144 -0
- package/dist/upload/UploadList.js.map +1 -0
- package/dist/upload/UploadList.module.js +32 -0
- package/dist/upload/UploadList.module.js.map +1 -0
- package/dist/upload/files.d.ts +5 -0
- package/dist/upload/files.d.ts.map +1 -0
- package/dist/upload/files.js +26 -0
- package/dist/upload/files.js.map +1 -0
- package/dist/upload/types.d.ts +58 -0
- package/dist/upload/types.d.ts.map +1 -0
- package/dist/upload/useRejectionMessage.d.ts +4 -0
- package/dist/upload/useRejectionMessage.d.ts.map +1 -0
- package/dist/upload/useRejectionMessage.js +25 -0
- package/dist/upload/useRejectionMessage.js.map +1 -0
- package/dist/upload/useUploads.d.ts +30 -0
- package/dist/upload/useUploads.d.ts.map +1 -0
- package/dist/upload/useUploads.js +115 -0
- package/dist/upload/useUploads.js.map +1 -0
- package/dist/uppy/index.d.ts +3 -0
- package/dist/uppy/index.d.ts.map +1 -0
- package/dist/uppy/index.js +1 -0
- package/dist/uppy/uploader.d.ts +44 -0
- package/dist/uppy/uploader.d.ts.map +1 -0
- package/dist/uppy/uploader.js +139 -0
- package/dist/uppy/uploader.js.map +1 -0
- package/dist/url/UrlField.css +2 -2
- package/dist/url/UrlField.d.ts +2 -2
- package/dist/url/UrlField.js +69 -14
- package/dist/url/UrlField.js.map +1 -1
- package/dist/url/UrlField.module.js +1 -1
- package/dist/url/index.d.ts +1 -1
- package/package.json +69 -7
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { useFieldsContext } from "../shared/context.js";
|
|
2
|
+
import { getFieldProps, isString } from "../shared/entry.js";
|
|
3
|
+
import { messages } from "../shared/messages.js";
|
|
4
|
+
import EmbedField_module_default from "./EmbedField.module.js";
|
|
5
|
+
import { c } from "react/compiler-runtime";
|
|
6
|
+
import { Spinner, TextInput, usePanneauIntl } from "@panneau/ui";
|
|
7
|
+
import { useEffect, useEffectEvent, useState } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
//#region src/embed/EmbedField.tsx
|
|
10
|
+
var RESOLVE_DELAY = 500;
|
|
11
|
+
/** Whether a value is an embed: an object with a `url`. */
|
|
12
|
+
function isEmbed(value) {
|
|
13
|
+
return value !== null && typeof value === "object" && isString(value.url);
|
|
14
|
+
}
|
|
15
|
+
/** Whether a value has been resolved: it has more than its URL. */
|
|
16
|
+
function isResolved(value) {
|
|
17
|
+
return Object.keys(value).some((key) => key !== "url");
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A URL of a video, a sound or a post, with the preview the backend gets from its provider's
|
|
21
|
+
* oEmbed: its thumbnail, title and provider. The URL is kept as soon as it is typed, and its
|
|
22
|
+
* preview follows. Without an embed source, the value is the URL alone.
|
|
23
|
+
*/
|
|
24
|
+
function EmbedField(t0) {
|
|
25
|
+
const $ = c(47);
|
|
26
|
+
let disabled;
|
|
27
|
+
let embedSourceProp;
|
|
28
|
+
let onBlur;
|
|
29
|
+
let onChange;
|
|
30
|
+
let props;
|
|
31
|
+
let readOnly;
|
|
32
|
+
let required;
|
|
33
|
+
let t1;
|
|
34
|
+
let value;
|
|
35
|
+
if ($[0] !== t0) {
|
|
36
|
+
({value, onChange, onBlur, embedSource: embedSourceProp, errors: t1, disabled, readOnly, required, ...props} = t0);
|
|
37
|
+
$[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
|
+
} 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];
|
|
57
|
+
}
|
|
58
|
+
let t2;
|
|
59
|
+
if ($[10] !== t1) {
|
|
60
|
+
t2 = t1 === void 0 ? [] : t1;
|
|
61
|
+
$[10] = t1;
|
|
62
|
+
$[11] = t2;
|
|
63
|
+
} else t2 = $[11];
|
|
64
|
+
const errors = t2;
|
|
65
|
+
const intl = usePanneauIntl();
|
|
66
|
+
const context = useFieldsContext();
|
|
67
|
+
const embedSource = embedSourceProp === void 0 ? context.embedSource : embedSourceProp;
|
|
68
|
+
const url = value?.url ?? "";
|
|
69
|
+
const [status, setStatus] = useState(null);
|
|
70
|
+
const pending = value !== null && value !== void 0 && !isResolved(value) ? value.url : null;
|
|
71
|
+
let t3;
|
|
72
|
+
if ($[12] !== onChange) {
|
|
73
|
+
t3 = (embed) => onChange?.(embed);
|
|
74
|
+
$[12] = onChange;
|
|
75
|
+
$[13] = t3;
|
|
76
|
+
} else t3 = $[13];
|
|
77
|
+
const resolved = useEffectEvent(t3);
|
|
78
|
+
let t4;
|
|
79
|
+
if ($[14] !== embedSource || $[15] !== pending || $[16] !== resolved) {
|
|
80
|
+
t4 = () => {
|
|
81
|
+
if (embedSource === null || pending === null || !URL.canParse(pending)) return;
|
|
82
|
+
const controller = new AbortController();
|
|
83
|
+
const timeout = window.setTimeout(() => {
|
|
84
|
+
setStatus({
|
|
85
|
+
url: pending,
|
|
86
|
+
state: "loading"
|
|
87
|
+
});
|
|
88
|
+
embedSource.resolve(pending, { signal: controller.signal }).then((embed_0) => {
|
|
89
|
+
setStatus(null);
|
|
90
|
+
resolved({
|
|
91
|
+
...embed_0,
|
|
92
|
+
url: pending
|
|
93
|
+
});
|
|
94
|
+
}).catch(() => {
|
|
95
|
+
if (!controller.signal.aborted) setStatus({
|
|
96
|
+
url: pending,
|
|
97
|
+
state: "failed"
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}, RESOLVE_DELAY);
|
|
101
|
+
return () => {
|
|
102
|
+
window.clearTimeout(timeout);
|
|
103
|
+
controller.abort();
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
$[14] = embedSource;
|
|
107
|
+
$[15] = pending;
|
|
108
|
+
$[16] = resolved;
|
|
109
|
+
$[17] = t4;
|
|
110
|
+
} else t4 = $[17];
|
|
111
|
+
let t5;
|
|
112
|
+
if ($[18] !== embedSource || $[19] !== pending) {
|
|
113
|
+
t5 = [embedSource, pending];
|
|
114
|
+
$[18] = embedSource;
|
|
115
|
+
$[19] = pending;
|
|
116
|
+
$[20] = t5;
|
|
117
|
+
} else t5 = $[20];
|
|
118
|
+
useEffect(t4, t5);
|
|
119
|
+
const current = status !== null && status.url === url ? status.state : null;
|
|
120
|
+
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;
|
|
129
|
+
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];
|
|
135
|
+
let t8;
|
|
136
|
+
if ($[27] !== onBlur) {
|
|
137
|
+
t8 = () => onBlur?.();
|
|
138
|
+
$[27] = onBlur;
|
|
139
|
+
$[28] = t8;
|
|
140
|
+
} else t8 = $[28];
|
|
141
|
+
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, {
|
|
144
|
+
...props,
|
|
145
|
+
type: "url",
|
|
146
|
+
inputMode: "url",
|
|
147
|
+
autoComplete: "off",
|
|
148
|
+
value: url,
|
|
149
|
+
onChange: t7,
|
|
150
|
+
onBlur: t8,
|
|
151
|
+
errors: shownErrors,
|
|
152
|
+
isDisabled: disabled,
|
|
153
|
+
isReadOnly: readOnly,
|
|
154
|
+
isRequired: required
|
|
155
|
+
});
|
|
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", {
|
|
169
|
+
className: EmbedField_module_default.status,
|
|
170
|
+
role: "status",
|
|
171
|
+
children: [/* @__PURE__ */ jsx(Spinner, { size: "sm" }), intl.formatMessage(messages.embedLoading)]
|
|
172
|
+
}) : 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", {
|
|
180
|
+
className: EmbedField_module_default.preview,
|
|
181
|
+
href: value.url,
|
|
182
|
+
target: "_blank",
|
|
183
|
+
rel: "noreferrer",
|
|
184
|
+
children: [value.thumbnailUrl !== void 0 ? /* @__PURE__ */ jsx("img", {
|
|
185
|
+
className: EmbedField_module_default.thumbnail,
|
|
186
|
+
src: value.thumbnailUrl,
|
|
187
|
+
alt: ""
|
|
188
|
+
}) : null, /* @__PURE__ */ jsxs("span", {
|
|
189
|
+
className: EmbedField_module_default.text,
|
|
190
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
191
|
+
className: EmbedField_module_default.title,
|
|
192
|
+
children: value.title ?? value.url
|
|
193
|
+
}), value.provider !== void 0 ? /* @__PURE__ */ jsx("span", {
|
|
194
|
+
className: EmbedField_module_default.provider,
|
|
195
|
+
children: value.provider
|
|
196
|
+
}) : null]
|
|
197
|
+
})]
|
|
198
|
+
}) : 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", {
|
|
205
|
+
className: EmbedField_module_default.embed,
|
|
206
|
+
children: [
|
|
207
|
+
t9,
|
|
208
|
+
t10,
|
|
209
|
+
t11
|
|
210
|
+
]
|
|
211
|
+
});
|
|
212
|
+
$[43] = t10;
|
|
213
|
+
$[44] = t11;
|
|
214
|
+
$[45] = t9;
|
|
215
|
+
$[46] = t12;
|
|
216
|
+
} else t12 = $[46];
|
|
217
|
+
return t12;
|
|
218
|
+
}
|
|
219
|
+
/** The `embed` type: its preview comes from the embed source of the `FieldsProvider`. */
|
|
220
|
+
function EmbedFieldEntry(props) {
|
|
221
|
+
const $ = c(6);
|
|
222
|
+
let t0;
|
|
223
|
+
if ($[0] !== props) {
|
|
224
|
+
t0 = getFieldProps(props);
|
|
225
|
+
$[0] = props;
|
|
226
|
+
$[1] = t0;
|
|
227
|
+
} 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
|
|
235
|
+
});
|
|
236
|
+
$[2] = props.onChange;
|
|
237
|
+
$[3] = t0;
|
|
238
|
+
$[4] = t1;
|
|
239
|
+
$[5] = t2;
|
|
240
|
+
} else t2 = $[5];
|
|
241
|
+
return t2;
|
|
242
|
+
}
|
|
243
|
+
//#endregion
|
|
244
|
+
export { EmbedField, EmbedFieldEntry, isEmbed };
|
|
245
|
+
|
|
246
|
+
//# sourceMappingURL=EmbedField.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import "./EmbedField.css";
|
|
2
|
+
//#region src/embed/EmbedField.module.css
|
|
3
|
+
var embed = "panneau-embed-field-embed";
|
|
4
|
+
var status = "panneau-embed-field-status";
|
|
5
|
+
var preview = "panneau-embed-field-preview";
|
|
6
|
+
var thumbnail = "panneau-embed-field-thumbnail";
|
|
7
|
+
var text = "panneau-embed-field-text";
|
|
8
|
+
var title = "panneau-embed-field-title";
|
|
9
|
+
var provider = "panneau-embed-field-provider";
|
|
10
|
+
var EmbedField_module_default = {
|
|
11
|
+
embed,
|
|
12
|
+
status,
|
|
13
|
+
preview,
|
|
14
|
+
thumbnail,
|
|
15
|
+
text,
|
|
16
|
+
title,
|
|
17
|
+
provider
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
20
|
+
export { EmbedField_module_default as default, embed, preview, provider, status, text, thumbnail, title };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=EmbedField.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmbedField.module.js","names":[],"sources":["../../src/embed/EmbedField.module.css"],"sourcesContent":["/* The URL, then the preview of what it embeds. */\n.embed {\n display: flex;\n flex-direction: column;\n gap: var(--panneau-space-2);\n}\n\n.status {\n display: flex;\n align-items: center;\n gap: var(--panneau-space-2);\n font-size: var(--panneau-font-size-sm);\n color: var(--panneau-color-text-muted);\n}\n\n.preview {\n display: flex;\n align-items: center;\n gap: var(--panneau-space-3);\n padding: var(--panneau-space-2);\n color: var(--panneau-color-text);\n text-decoration: none;\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-md);\n}\n\n.preview:hover {\n border-color: var(--panneau-color-border-control);\n}\n\n.preview:focus-visible {\n outline: var(--panneau-focus-width) solid var(--panneau-color-focus);\n outline-offset: 1px;\n}\n\n.thumbnail {\n flex: none;\n width: 7rem;\n aspect-ratio: 16 / 9;\n object-fit: cover;\n border-radius: var(--panneau-radius-sm);\n}\n\n.text {\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n min-width: 0;\n}\n\n.title {\n font-weight: var(--panneau-font-weight-medium);\n overflow-wrap: anywhere;\n}\n\n.provider {\n font-size: var(--panneau-font-size-sm);\n color: var(--panneau-color-text-muted);\n}\n"],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/embed/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,UAAU,EACV,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,OAAO,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
.panneau-file-field-field {
|
|
2
|
+
display: grid;
|
|
3
|
+
gap: var(--panneau-space-2);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.panneau-file-field-files {
|
|
7
|
+
display: grid;
|
|
8
|
+
gap: var(--panneau-space-1);
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
list-style: none;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.panneau-file-field-file {
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
gap: var(--panneau-space-2);
|
|
18
|
+
min-height: var(--panneau-control-height-sm);
|
|
19
|
+
padding-inline: var(--panneau-space-2) var(--panneau-space-1);
|
|
20
|
+
background-color: var(--panneau-color-surface-sunken);
|
|
21
|
+
border: var(--panneau-border-width) solid var(--panneau-color-border);
|
|
22
|
+
border-radius: var(--panneau-radius-md);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.panneau-file-field-icon {
|
|
26
|
+
flex: none;
|
|
27
|
+
width: 1rem;
|
|
28
|
+
height: 1rem;
|
|
29
|
+
color: var(--panneau-color-text-muted);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.panneau-file-field-name {
|
|
33
|
+
flex: 1 1 auto;
|
|
34
|
+
min-width: 0;
|
|
35
|
+
overflow: hidden;
|
|
36
|
+
font-size: var(--panneau-font-size-sm);
|
|
37
|
+
text-overflow: ellipsis;
|
|
38
|
+
white-space: nowrap;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
a.panneau-file-field-name {
|
|
42
|
+
color: var(--panneau-color-link);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.panneau-file-field-size {
|
|
46
|
+
flex: none;
|
|
47
|
+
font-size: var(--panneau-font-size-sm);
|
|
48
|
+
color: var(--panneau-color-text-muted);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.panneau-file-field-none {
|
|
52
|
+
font-size: var(--panneau-font-size-md);
|
|
53
|
+
color: var(--panneau-color-text-muted);
|
|
54
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { StoredFile } from '@panneau/protocol';
|
|
2
|
+
import type { FieldEntryProps, FieldProps } from '../shared/types.js';
|
|
3
|
+
import type { UploadSource, UploadedFile } from '../upload/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* A file of a `file` value: a stored file, as items give it; an upload, once the browser sent the
|
|
6
|
+
* file to storage; or the file itself, sent in a multipart request without direct uploads.
|
|
7
|
+
*/
|
|
8
|
+
export type FileValue = StoredFile | UploadedFile | File;
|
|
9
|
+
export interface FileFieldBaseProps extends Omit<FieldProps<never>, 'value' | 'onChange'> {
|
|
10
|
+
/** Accepted MIME types (`application/pdf`, `image/*`). Others are refused before they are sent. */
|
|
11
|
+
accept?: readonly string[] | null;
|
|
12
|
+
/** Largest file, in bytes. Larger ones are refused before they are sent. */
|
|
13
|
+
maxSize?: number | null;
|
|
14
|
+
/**
|
|
15
|
+
* Where files are uploaded directly to storage. Defaults to the one of the fields context.
|
|
16
|
+
* Without one, the value holds the files themselves, which the adapter sends in
|
|
17
|
+
* `multipart/form-data`.
|
|
18
|
+
*/
|
|
19
|
+
uploadSource?: UploadSource | null;
|
|
20
|
+
}
|
|
21
|
+
export interface SingleFileFieldProps extends FileFieldBaseProps {
|
|
22
|
+
multiple?: false;
|
|
23
|
+
value?: FileValue | null;
|
|
24
|
+
onChange?: (value: FileValue | null) => void;
|
|
25
|
+
}
|
|
26
|
+
export interface MultipleFileFieldProps extends FileFieldBaseProps {
|
|
27
|
+
multiple: true;
|
|
28
|
+
value?: readonly FileValue[] | null;
|
|
29
|
+
/** Called with the files. An empty list is `null`. */
|
|
30
|
+
onChange?: (value: FileValue[] | null) => void;
|
|
31
|
+
}
|
|
32
|
+
export type FileFieldProps = SingleFileFieldProps | MultipleFileFieldProps;
|
|
33
|
+
/** Whether a value is a file of a `file` value. */
|
|
34
|
+
export declare function isFileValue(value: unknown): value is FileValue;
|
|
35
|
+
/** The files of a value, single or multiple. */
|
|
36
|
+
export declare function toFiles(value: unknown): FileValue[];
|
|
37
|
+
/**
|
|
38
|
+
* Files that belong to an item, outside the media library: an attachment, a PDF, a CSV (the
|
|
39
|
+
* `file` type). With an upload source, files go directly to storage, and the value references
|
|
40
|
+
* each upload (`{ upload, name, mime, size }`). Without one, the value is the file itself. Items
|
|
41
|
+
* give stored files, which the field shows with a link. A new file replaces the file of a single
|
|
42
|
+
* value, and is added to a multiple one.
|
|
43
|
+
*/
|
|
44
|
+
export declare function FileField(props: FileFieldProps): import("react").JSX.Element;
|
|
45
|
+
/**
|
|
46
|
+
* The registry entry of the `file` type: the field's `multiple`, `accept` (or its `accept` rule)
|
|
47
|
+
* and `maxSize` rule, with the upload source of the fields context.
|
|
48
|
+
*/
|
|
49
|
+
export declare function FileFieldEntry(props: FieldEntryProps): import("react").JSX.Element;
|
|
50
|
+
//# sourceMappingURL=FileField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileField.d.ts","sourceRoot":"","sources":["../../src/file/FileField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAMpD,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAInE,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAKlE;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,IAAI,CAAC;AAEzD,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACrF,mGAAmG;IACnG,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAClC,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC5D,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;CAChD;AAED,MAAM,WAAW,sBAAuB,SAAQ,kBAAkB;IAC9D,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAAC;IACpC,sDAAsD;IACtD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;CAClD;AAED,MAAM,MAAM,cAAc,GAAG,oBAAoB,GAAG,sBAAsB,CAAC;AAY3E,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAS9D;AAED,gDAAgD;AAChD,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,EAAE,CAKnD;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,+BAiI9C;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,+BAYpD"}
|