@panneau/fields 5.0.0-alpha.4 → 5.0.0-alpha.6
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 +67 -21
- 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 +129 -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/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 +130 -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/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- 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 +125 -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/localized/LocalizedField.d.ts.map +1 -1
- package/dist/localized/LocalizedField.js +1 -0
- package/dist/localized/LocalizedField.js.map +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 +350 -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 +115 -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/range/RangeField.d.ts +22 -0
- package/dist/range/RangeField.d.ts.map +1 -0
- package/dist/range/RangeField.js +132 -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.d.ts.map +1 -1
- package/dist/relation/RelationField.js +24 -24
- package/dist/relation/RelationField.js.map +1 -1
- package/dist/shared/DefinitionField.d.ts +3 -1
- package/dist/shared/DefinitionField.d.ts.map +1 -1
- package/dist/shared/DefinitionField.js +80 -72
- package/dist/shared/DefinitionField.js.map +1 -1
- package/dist/shared/builtIn.d.ts +1 -0
- package/dist/shared/builtIn.d.ts.map +1 -1
- package/dist/shared/builtIn.js +16 -1
- 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 +18 -3
- package/dist/shared/context.d.ts.map +1 -1
- package/dist/shared/context.js +31 -19
- package/dist/shared/context.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/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 +31 -3
- package/dist/slug/SlugField.d.ts.map +1 -1
- package/dist/slug/SlugField.js +231 -159
- 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/package.json +41 -4
package/dist/index.js
CHANGED
|
@@ -10,4 +10,7 @@ import { FileField, FileFieldEntry, isFileValue, toFiles } from "./file/FileFiel
|
|
|
10
10
|
import { createRelationSource, toReferences, useRelationReferences } from "./shared/relation.js";
|
|
11
11
|
import { builtInFields, fieldsPlugin } from "./shared/builtIn.js";
|
|
12
12
|
import { DefinitionField, NestedField } from "./shared/DefinitionField.js";
|
|
13
|
-
|
|
13
|
+
import { createFieldCheckSource } from "./shared/check.js";
|
|
14
|
+
import { createEmbedSource } from "./shared/embed.js";
|
|
15
|
+
import { createNominatimSource } from "./location/nominatim.js";
|
|
16
|
+
export { DefinitionField, FieldsProvider, FileField, FileFieldEntry, FilePicker, MissingFieldEntry, NestedField, UploadList, builtInFields, createEmbedSource, createFieldCheckSource, createNominatimSource, createRelationSource, fieldsPlugin, findRule, formatSize, getAccept, getFieldProps, getMaxSize, getParentPath, getRuleNumber, isFileValue, isRequired, matchesMime, toFiles, toReferences, useFieldsContext, useRejectionMessage, useRelationReferences, useUploads };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FieldEntryProps, FieldProps } from '../shared/types';
|
|
2
|
+
/** The value of a `json` field: an object or an array, or the text while it doesn't parse. */
|
|
3
|
+
export type JsonValue = Record<string, unknown> | unknown[] | string;
|
|
4
|
+
export interface JsonFieldProps extends FieldProps<JsonValue> {
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
/** Visible lines. Defaults to 8. */
|
|
7
|
+
rows?: number;
|
|
8
|
+
}
|
|
9
|
+
/** The value of a text: what it parses to when it is an object or an array, or the text itself. */
|
|
10
|
+
export declare function parseJson(text: string): {
|
|
11
|
+
value: JsonValue | null;
|
|
12
|
+
error: string | null;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Structured data edited as JSON: an object or an array. While the text doesn't parse, the value
|
|
16
|
+
* is the text itself, which the `json` rule refuses, so the form can't be saved with it. The text
|
|
17
|
+
* is indented again on blur once it parses.
|
|
18
|
+
*/
|
|
19
|
+
export declare function JsonField({ value, onChange, onBlur, errors, rows, disabled, readOnly, required, ...props }: JsonFieldProps): import("react").JSX.Element;
|
|
20
|
+
/** The `json` type: an object or an array, with setting `rows`. */
|
|
21
|
+
export declare function JsonFieldEntry(props: FieldEntryProps): import("react").JSX.Element;
|
|
22
|
+
//# sourceMappingURL=JsonField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonField.d.ts","sourceRoot":"","sources":["../../src/json/JsonField.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGnE,8FAA8F;AAC9F,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC;AAErE,MAAM,WAAW,cAAe,SAAQ,UAAU,CAAC,SAAS,CAAC;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAUD,mGAAmG;AACnG,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAazF;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,MAAW,EACX,IAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,GAAG,KAAK,EACX,EAAE,cAAc,+BAwChB;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,+BAepD"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { getFieldProps, getSetting, isNumber } from "../shared/entry.js";
|
|
2
|
+
import { messages } from "../shared/messages.js";
|
|
3
|
+
import JsonField_module_default from "./JsonField.module.js";
|
|
4
|
+
import { c } from "react/compiler-runtime";
|
|
5
|
+
import { TextArea, usePanneauIntl } from "@panneau/ui";
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
//#region src/json/JsonField.tsx
|
|
9
|
+
/** The text of a value: indented JSON, or the text that doesn't parse as it is. */
|
|
10
|
+
function toText(value) {
|
|
11
|
+
if (value === null || value === void 0) return "";
|
|
12
|
+
return typeof value === "string" ? value : JSON.stringify(value, null, 2);
|
|
13
|
+
}
|
|
14
|
+
/** The value of a text: what it parses to when it is an object or an array, or the text itself. */
|
|
15
|
+
function parseJson(text) {
|
|
16
|
+
if (text.trim() === "") return {
|
|
17
|
+
value: null,
|
|
18
|
+
error: null
|
|
19
|
+
};
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(text);
|
|
22
|
+
if (parsed !== null && typeof parsed === "object") return {
|
|
23
|
+
value: parsed,
|
|
24
|
+
error: null
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
value: text,
|
|
28
|
+
error: "an object or an array"
|
|
29
|
+
};
|
|
30
|
+
} catch (error) {
|
|
31
|
+
return {
|
|
32
|
+
value: text,
|
|
33
|
+
error: error instanceof Error ? error.message : String(error)
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Structured data edited as JSON: an object or an array. While the text doesn't parse, the value
|
|
39
|
+
* is the text itself, which the `json` rule refuses, so the form can't be saved with it. The text
|
|
40
|
+
* is indented again on blur once it parses.
|
|
41
|
+
*/
|
|
42
|
+
function JsonField({ value, onChange, onBlur, errors = [], rows = 8, disabled, readOnly, required, ...props }) {
|
|
43
|
+
const intl = usePanneauIntl();
|
|
44
|
+
const [state, setState] = useState(() => ({
|
|
45
|
+
value,
|
|
46
|
+
text: toText(value)
|
|
47
|
+
}));
|
|
48
|
+
if (state.value !== value) setState({
|
|
49
|
+
value,
|
|
50
|
+
text: toText(value)
|
|
51
|
+
});
|
|
52
|
+
const { text } = state;
|
|
53
|
+
const { error } = parseJson(text);
|
|
54
|
+
const shown = error !== null && errors.length === 0 ? [intl.formatMessage(messages.jsonInvalid, { error })] : errors;
|
|
55
|
+
return /* @__PURE__ */ jsx(TextArea, {
|
|
56
|
+
...props,
|
|
57
|
+
value: text,
|
|
58
|
+
onChange: (next) => {
|
|
59
|
+
const parsed = parseJson(next).value;
|
|
60
|
+
setState({
|
|
61
|
+
value: parsed,
|
|
62
|
+
text: next
|
|
63
|
+
});
|
|
64
|
+
onChange?.(parsed);
|
|
65
|
+
},
|
|
66
|
+
onBlur: () => {
|
|
67
|
+
if (value !== null && value !== void 0 && typeof value !== "string") setState({
|
|
68
|
+
value,
|
|
69
|
+
text: toText(value)
|
|
70
|
+
});
|
|
71
|
+
onBlur?.();
|
|
72
|
+
},
|
|
73
|
+
errors: shown,
|
|
74
|
+
rows,
|
|
75
|
+
spellCheck: "false",
|
|
76
|
+
textAreaClassName: JsonField_module_default.code,
|
|
77
|
+
isDisabled: disabled,
|
|
78
|
+
isReadOnly: readOnly,
|
|
79
|
+
isRequired: required
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/** The `json` type: an object or an array, with setting `rows`. */
|
|
83
|
+
function JsonFieldEntry(props) {
|
|
84
|
+
const $ = c(11);
|
|
85
|
+
let t0;
|
|
86
|
+
if ($[0] !== props.field) {
|
|
87
|
+
t0 = getSetting(props.field, "rows", isNumber);
|
|
88
|
+
$[0] = props.field;
|
|
89
|
+
$[1] = t0;
|
|
90
|
+
} else t0 = $[1];
|
|
91
|
+
const rows = t0;
|
|
92
|
+
const { value } = props;
|
|
93
|
+
let t1;
|
|
94
|
+
if ($[2] !== props) {
|
|
95
|
+
t1 = getFieldProps(props);
|
|
96
|
+
$[2] = props;
|
|
97
|
+
$[3] = t1;
|
|
98
|
+
} else t1 = $[3];
|
|
99
|
+
const t2 = typeof value === "string" || value !== null && typeof value === "object" ? value : null;
|
|
100
|
+
let t3;
|
|
101
|
+
if ($[4] !== rows) {
|
|
102
|
+
t3 = rows !== void 0 ? { rows } : {};
|
|
103
|
+
$[4] = rows;
|
|
104
|
+
$[5] = t3;
|
|
105
|
+
} else t3 = $[5];
|
|
106
|
+
let t4;
|
|
107
|
+
if ($[6] !== props.onChange || $[7] !== t1 || $[8] !== t2 || $[9] !== t3) {
|
|
108
|
+
t4 = /* @__PURE__ */ jsx(JsonField, {
|
|
109
|
+
...t1,
|
|
110
|
+
value: t2,
|
|
111
|
+
onChange: props.onChange,
|
|
112
|
+
...t3
|
|
113
|
+
});
|
|
114
|
+
$[6] = props.onChange;
|
|
115
|
+
$[7] = t1;
|
|
116
|
+
$[8] = t2;
|
|
117
|
+
$[9] = t3;
|
|
118
|
+
$[10] = t4;
|
|
119
|
+
} else t4 = $[10];
|
|
120
|
+
return t4;
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
export { JsonField, JsonFieldEntry, parseJson };
|
|
124
|
+
|
|
125
|
+
//# sourceMappingURL=JsonField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonField.js","names":["styles","_c"],"sources":["../../src/json/JsonField.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport { TextArea, usePanneauIntl } from '@panneau/ui';\n\nimport { getFieldProps, getSetting, isNumber } from '../shared/entry';\nimport { messages } from '../shared/messages';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport styles from './JsonField.module.css';\n\n/** The value of a `json` field: an object or an array, or the text while it doesn't parse. */\nexport type JsonValue = Record<string, unknown> | unknown[] | string;\n\nexport interface JsonFieldProps extends FieldProps<JsonValue> {\n placeholder?: string;\n /** Visible lines. Defaults to 8. */\n rows?: number;\n}\n\n/** The text of a value: indented JSON, or the text that doesn't parse as it is. */\nfunction toText(value: JsonValue | null | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n return typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n}\n\n/** The value of a text: what it parses to when it is an object or an array, or the text itself. */\nexport function parseJson(text: string): { value: JsonValue | null; error: string | null } {\n if (text.trim() === '') {\n return { value: null, error: null };\n }\n try {\n const parsed: unknown = JSON.parse(text);\n if (parsed !== null && typeof parsed === 'object') {\n return { value: parsed as JsonValue, error: null };\n }\n return { value: text, error: 'an object or an array' };\n } catch (error) {\n return { value: text, error: error instanceof Error ? error.message : String(error) };\n }\n}\n\n/**\n * Structured data edited as JSON: an object or an array. While the text doesn't parse, the value\n * is the text itself, which the `json` rule refuses, so the form can't be saved with it. The text\n * is indented again on blur once it parses.\n */\nexport function JsonField({\n value,\n onChange,\n onBlur,\n errors = [],\n rows = 8,\n disabled,\n readOnly,\n required,\n ...props\n}: JsonFieldProps) {\n const intl = usePanneauIntl();\n // The text as typed: a value that comes back from the form keeps its text, and a value set\n // from outside (a reset, a reload) shows its JSON\n const [state, setState] = useState(() => ({ value, text: toText(value) }));\n if (state.value !== value) {\n setState({ value, text: toText(value) });\n }\n const { text } = state;\n const { error } = parseJson(text);\n // The parser's message, until the form shows the rule's\n const shown =\n error !== null && errors.length === 0\n ? [intl.formatMessage(messages.jsonInvalid, { error })]\n : errors;\n return (\n <TextArea\n {...props}\n value={text}\n onChange={(next) => {\n const parsed = parseJson(next).value;\n setState({ value: parsed, text: next });\n onChange?.(parsed);\n }}\n onBlur={() => {\n // Indent the text once it parses\n if (value !== null && value !== undefined && typeof value !== 'string') {\n setState({ value, text: toText(value) });\n }\n onBlur?.();\n }}\n errors={shown}\n rows={rows}\n spellCheck=\"false\"\n textAreaClassName={styles.code}\n isDisabled={disabled}\n isReadOnly={readOnly}\n isRequired={required}\n />\n );\n}\n\n/** The `json` type: an object or an array, with setting `rows`. */\nexport function JsonFieldEntry(props: FieldEntryProps) {\n const rows = getSetting(props.field, 'rows', isNumber);\n const { value } = props;\n return (\n <JsonField\n {...getFieldProps(props)}\n value={\n typeof value === 'string' || (value !== null && typeof value === 'object')\n ? (value as JsonValue)\n : null\n }\n onChange={props.onChange}\n {...(rows !== undefined ? { rows } : {})}\n />\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "./JsonField.css";
|
|
2
|
+
//#region src/json/JsonField.module.css
|
|
3
|
+
var code = "panneau-json-field-code";
|
|
4
|
+
var JsonField_module_default = { code };
|
|
5
|
+
//#endregion
|
|
6
|
+
export { code, JsonField_module_default as default };
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=JsonField.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonField.module.js","names":[],"sources":["../../src/json/JsonField.module.css"],"sourcesContent":["/* JSON reads in a monospace font, without wrapping long lines. */\n.code {\n font-family: var(--panneau-font-family-mono);\n font-size: var(--panneau-font-size-sm);\n white-space: pre;\n tab-size: 2;\n}\n"],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/json/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,SAAS,EACT,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,SAAS,GACZ,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { JsonField, JsonFieldEntry, parseJson } from "./JsonField.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalizedField.d.ts","sourceRoot":"","sources":["../../src/localized/LocalizedField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAQvC,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGnE,6EAA6E;AAC7E,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAElE,4DAA4D;AAC5D,MAAM,WAAW,mBAAmB,CAAC,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC,CAAE,SAAQ,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IACzE,yBAAyB;IACzB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,qCAAqC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,sFAAsF;AACtF,wBAAgB,aAAa,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAY1D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAC9B,OAAO,EACP,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,MAAM,EACN,KAAK,EACL,WAAW,EACX,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,eAAe,GAClB,EAAE,mBAAmB,CAAC,CAAC,CAAC,+BAsCxB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,+
|
|
1
|
+
{"version":3,"file":"LocalizedField.d.ts","sourceRoot":"","sources":["../../src/localized/LocalizedField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAQvC,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGnE,6EAA6E;AAC7E,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAElE,4DAA4D;AAC5D,MAAM,WAAW,mBAAmB,CAAC,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC,CAAE,SAAQ,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IACzE,yBAAyB;IACzB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,qCAAqC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,sFAAsF;AACtF,wBAAgB,aAAa,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAY1D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAC9B,OAAO,EACP,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,MAAM,EACN,KAAK,EACL,WAAW,EACX,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,eAAe,GAClB,EAAE,mBAAmB,CAAC,CAAC,CAAC,+BAsCxB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,+BA+BzD"}
|
|
@@ -172,6 +172,7 @@ function LocalizedFieldEntry(props) {
|
|
|
172
172
|
onChange: input.onChange,
|
|
173
173
|
...props.onBlur !== void 0 ? { onBlur: props.onBlur } : {},
|
|
174
174
|
parentValue: props.parentValue,
|
|
175
|
+
locale: input.locale,
|
|
175
176
|
...props.disabled !== void 0 ? { disabled: props.disabled } : {},
|
|
176
177
|
...props.readOnly !== void 0 ? { readOnly: props.readOnly } : {}
|
|
177
178
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalizedField.js","names":["name","locale","label","description","errors","required","className","labelClassName","descriptionClassName","errorsClassName","locales","record","_c","styles"],"sources":["../../src/localized/LocalizedField.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { Fieldset, usePanneauIntl } from '@panneau/ui';\n\nimport { NestedField } from '../shared/DefinitionField';\nimport { useFieldsContext } from '../shared/context';\nimport { cx } from '../shared/cx';\nimport { getFieldProps } from '../shared/entry';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport styles from './LocalizedField.module.css';\n\n/** A localized value: a value per locale (`{ fr: 'Été', en: 'Summer' }`). */\nexport type LocalizedValue<V> = Partial<Record<string, V | null>>;\n\n/** What `LocalizedField` gives the input of each locale. */\nexport interface LocalizedInputProps<V> {\n locale: string;\n /** Name of the locale in the UI's language, as the input's label. */\n label: string;\n value: V | null;\n onChange: (value: V | null) => void;\n onBlur?: () => void;\n disabled?: boolean;\n readOnly?: boolean;\n required?: boolean;\n}\n\nexport interface LocalizedFieldProps<V> extends FieldProps<LocalizedValue<V>> {\n /** Locales, in order. */\n locales: readonly string[];\n /** Renders the input of a locale. */\n children: (props: LocalizedInputProps<V>) => ReactNode;\n localeClassName?: string;\n}\n\n/** The name of a locale in the UI's language, capitalized (`Français`, `English`). */\nexport function useLocaleName(): (locale: string) => string {\n const intl = usePanneauIntl();\n return (locale) => {\n let name: string | undefined;\n try {\n name = intl.formatDisplayName(locale, { type: 'language' });\n } catch {\n name = undefined;\n }\n const text = name ?? locale.toUpperCase();\n return text.charAt(0).toLocaleUpperCase(intl.locale) + text.slice(1);\n };\n}\n\n/**\n * A value per locale, with an input for each locale under one legend. A value without any locale\n * filled is `null`.\n */\nexport function LocalizedField<V>({\n locales,\n children,\n value,\n onChange,\n onBlur,\n label,\n description,\n errors,\n disabled,\n readOnly,\n required,\n className,\n labelClassName,\n descriptionClassName,\n errorsClassName,\n localeClassName,\n}: LocalizedFieldProps<V>) {\n const localeName = useLocaleName();\n return (\n <Fieldset\n legend={label}\n description={description}\n errors={errors}\n isRequired={required}\n className={className}\n legendClassName={labelClassName}\n descriptionClassName={descriptionClassName}\n errorsClassName={errorsClassName}\n >\n <div className={styles.locales}>\n {locales.map((locale) => (\n <div key={locale} className={cx(styles.locale, localeClassName)}>\n {children({\n locale,\n label: localeName(locale),\n value: value?.[locale] ?? null,\n onChange: (next) => {\n const updated = { ...value, [locale]: next };\n const filled = Object.values(updated).some(\n (entry) =>\n entry !== null && entry !== undefined && entry !== '',\n );\n onChange?.(filled ? updated : null);\n },\n ...(onBlur !== undefined ? { onBlur } : {}),\n ...(disabled !== undefined ? { disabled } : {}),\n ...(readOnly !== undefined ? { readOnly } : {}),\n ...(required !== undefined ? { required } : {}),\n })}\n </div>\n ))}\n </div>\n </Fieldset>\n );\n}\n\n/**\n * A field of the definition with `localized: true`: the field of its type for each locale of the\n * fields context, each at its own path (`title.fr`).\n */\nexport function LocalizedFieldEntry(props: FieldEntryProps) {\n const { locales: contextLocales } = useFieldsContext();\n const { field, path, value } = props;\n const record =\n value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n const locales = contextLocales.length > 0 ? contextLocales : Object.keys(record);\n const { name: _name, onBlur: _onBlur, ...chrome } = getFieldProps(props);\n return (\n <LocalizedField<unknown>\n {...chrome}\n locales={locales}\n value={record}\n onChange={props.onChange}\n >\n {(input) => (\n <NestedField\n field={{ ...field, localized: false, label: input.label, help: undefined }}\n path={`${path}.${input.locale}`}\n value={input.value}\n onChange={input.onChange}\n {...(props.onBlur !== undefined ? { onBlur: props.onBlur } : {})}\n parentValue={props.parentValue}\n {...(props.disabled !== undefined ? { disabled: props.disabled } : {})}\n {...(props.readOnly !== undefined ? { readOnly: props.readOnly } : {})}\n />\n )}\n </LocalizedField>\n );\n}\n"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"LocalizedField.js","names":["name","locale","label","description","errors","required","className","labelClassName","descriptionClassName","errorsClassName","locales","record","_c","styles"],"sources":["../../src/localized/LocalizedField.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { Fieldset, usePanneauIntl } from '@panneau/ui';\n\nimport { NestedField } from '../shared/DefinitionField';\nimport { useFieldsContext } from '../shared/context';\nimport { cx } from '../shared/cx';\nimport { getFieldProps } from '../shared/entry';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport styles from './LocalizedField.module.css';\n\n/** A localized value: a value per locale (`{ fr: 'Été', en: 'Summer' }`). */\nexport type LocalizedValue<V> = Partial<Record<string, V | null>>;\n\n/** What `LocalizedField` gives the input of each locale. */\nexport interface LocalizedInputProps<V> {\n locale: string;\n /** Name of the locale in the UI's language, as the input's label. */\n label: string;\n value: V | null;\n onChange: (value: V | null) => void;\n onBlur?: () => void;\n disabled?: boolean;\n readOnly?: boolean;\n required?: boolean;\n}\n\nexport interface LocalizedFieldProps<V> extends FieldProps<LocalizedValue<V>> {\n /** Locales, in order. */\n locales: readonly string[];\n /** Renders the input of a locale. */\n children: (props: LocalizedInputProps<V>) => ReactNode;\n localeClassName?: string;\n}\n\n/** The name of a locale in the UI's language, capitalized (`Français`, `English`). */\nexport function useLocaleName(): (locale: string) => string {\n const intl = usePanneauIntl();\n return (locale) => {\n let name: string | undefined;\n try {\n name = intl.formatDisplayName(locale, { type: 'language' });\n } catch {\n name = undefined;\n }\n const text = name ?? locale.toUpperCase();\n return text.charAt(0).toLocaleUpperCase(intl.locale) + text.slice(1);\n };\n}\n\n/**\n * A value per locale, with an input for each locale under one legend. A value without any locale\n * filled is `null`.\n */\nexport function LocalizedField<V>({\n locales,\n children,\n value,\n onChange,\n onBlur,\n label,\n description,\n errors,\n disabled,\n readOnly,\n required,\n className,\n labelClassName,\n descriptionClassName,\n errorsClassName,\n localeClassName,\n}: LocalizedFieldProps<V>) {\n const localeName = useLocaleName();\n return (\n <Fieldset\n legend={label}\n description={description}\n errors={errors}\n isRequired={required}\n className={className}\n legendClassName={labelClassName}\n descriptionClassName={descriptionClassName}\n errorsClassName={errorsClassName}\n >\n <div className={styles.locales}>\n {locales.map((locale) => (\n <div key={locale} className={cx(styles.locale, localeClassName)}>\n {children({\n locale,\n label: localeName(locale),\n value: value?.[locale] ?? null,\n onChange: (next) => {\n const updated = { ...value, [locale]: next };\n const filled = Object.values(updated).some(\n (entry) =>\n entry !== null && entry !== undefined && entry !== '',\n );\n onChange?.(filled ? updated : null);\n },\n ...(onBlur !== undefined ? { onBlur } : {}),\n ...(disabled !== undefined ? { disabled } : {}),\n ...(readOnly !== undefined ? { readOnly } : {}),\n ...(required !== undefined ? { required } : {}),\n })}\n </div>\n ))}\n </div>\n </Fieldset>\n );\n}\n\n/**\n * A field of the definition with `localized: true`: the field of its type for each locale of the\n * fields context, each at its own path (`title.fr`).\n */\nexport function LocalizedFieldEntry(props: FieldEntryProps) {\n const { locales: contextLocales } = useFieldsContext();\n const { field, path, value } = props;\n const record =\n value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n const locales = contextLocales.length > 0 ? contextLocales : Object.keys(record);\n const { name: _name, onBlur: _onBlur, ...chrome } = getFieldProps(props);\n return (\n <LocalizedField<unknown>\n {...chrome}\n locales={locales}\n value={record}\n onChange={props.onChange}\n >\n {(input) => (\n <NestedField\n field={{ ...field, localized: false, label: input.label, help: undefined }}\n path={`${path}.${input.locale}`}\n value={input.value}\n onChange={input.onChange}\n {...(props.onBlur !== undefined ? { onBlur: props.onBlur } : {})}\n parentValue={props.parentValue}\n locale={input.locale}\n {...(props.disabled !== undefined ? { disabled: props.disabled } : {})}\n {...(props.readOnly !== undefined ? { readOnly: props.readOnly } : {})}\n />\n )}\n </LocalizedField>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/* The search, the map, then the coordinates and the address. */
|
|
2
|
+
.panneau-location-field-location {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
gap: var(--panneau-space-2);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.panneau-location-field-map {
|
|
9
|
+
position: relative;
|
|
10
|
+
z-index: 0;
|
|
11
|
+
height: 16rem;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
background-color: var(--panneau-color-surface-sunken);
|
|
14
|
+
border: var(--panneau-border-width) solid var(--panneau-color-border-control);
|
|
15
|
+
border-radius: var(--panneau-radius-md);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.panneau-location-field-map:focus-visible {
|
|
19
|
+
outline: var(--panneau-focus-width) solid var(--panneau-color-focus);
|
|
20
|
+
outline-offset: 1px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* A pin: a round head pointing down at the point. */
|
|
24
|
+
.panneau-location-field-marker {
|
|
25
|
+
background: none;
|
|
26
|
+
border: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.panneau-location-field-pin {
|
|
30
|
+
display: block;
|
|
31
|
+
width: 100%;
|
|
32
|
+
height: 100%;
|
|
33
|
+
box-sizing: border-box;
|
|
34
|
+
background-color: var(--panneau-color-accent);
|
|
35
|
+
border: 2px solid var(--panneau-color-surface);
|
|
36
|
+
border-radius: 50% 50% 50% 0;
|
|
37
|
+
box-shadow: var(--panneau-shadow-sm);
|
|
38
|
+
rotate: -45deg;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.panneau-location-field-coordinates {
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-wrap: wrap;
|
|
44
|
+
align-items: flex-end;
|
|
45
|
+
gap: var(--panneau-space-2);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.panneau-location-field-coordinate {
|
|
49
|
+
flex: 1 1 8rem;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.panneau-location-field-remove {
|
|
53
|
+
flex: none;
|
|
54
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LocationValue } from '@panneau/protocol';
|
|
2
|
+
import type { FieldEntryProps, FieldProps } from '../shared/types';
|
|
3
|
+
import { type Point } from './LocationMap';
|
|
4
|
+
import type { GeocodingSource, MapTiles } from './types';
|
|
5
|
+
export type { LocationValue };
|
|
6
|
+
/** OpenStreetMap's standard tiles: fine for an admin panel, with their credit. */
|
|
7
|
+
export declare const OPEN_STREET_MAP_TILES: MapTiles;
|
|
8
|
+
export interface LocationFieldProps extends FieldProps<LocationValue> {
|
|
9
|
+
/** The address search. Defaults to that of the `FieldsProvider`; without one, there is none. */
|
|
10
|
+
geocoding?: GeocodingSource | null;
|
|
11
|
+
/** The tiles of the map. Defaults to those of the `FieldsProvider`, or OpenStreetMap's. */
|
|
12
|
+
tiles?: MapTiles;
|
|
13
|
+
/** Where the map opens without a point. Defaults to the whole world. */
|
|
14
|
+
center?: Point;
|
|
15
|
+
/** Zoom of the map on a point. Defaults to 15. */
|
|
16
|
+
zoom?: number;
|
|
17
|
+
}
|
|
18
|
+
/** Whether a value is a point. */
|
|
19
|
+
export declare function isLocation(value: unknown): value is LocationValue;
|
|
20
|
+
/**
|
|
21
|
+
* A point on a map, and its address. Clicking the map or dragging the marker places the point,
|
|
22
|
+
* and its latitude and longitude can be typed. With an address search, a place found sets the
|
|
23
|
+
* point and the address; with a reverse search, placing a point fills an empty address.
|
|
24
|
+
*/
|
|
25
|
+
export declare function LocationField({ value, onChange, onBlur, geocoding: geocodingProp, tiles: tilesProp, center, zoom, label, description, errors, disabled, readOnly, required, className, }: LocationFieldProps): import("react").JSX.Element;
|
|
26
|
+
/**
|
|
27
|
+
* The `location` type: settings `zoom`, `center` (`{ "lat", "lng" }`, where the map opens without
|
|
28
|
+
* a point) and `tiles` (`{ "url", "attribution" }`), over the maps of the `FieldsProvider`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function LocationFieldEntry(props: FieldEntryProps): import("react").JSX.Element;
|
|
31
|
+
//# sourceMappingURL=LocationField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocationField.d.ts","sourceRoot":"","sources":["../../src/location/LocationField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAavD,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEnE,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAmB,eAAe,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE1E,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,kFAAkF;AAClF,eAAO,MAAM,qBAAqB,EAAE,QAKnC,CAAC;AAKF,MAAM,WAAW,kBAAmB,SAAQ,UAAU,CAAC,aAAa,CAAC;IACjE,gGAAgG;IAChG,SAAS,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACnC,2FAA2F;IAC3F,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,wEAAwE;IACxE,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kCAAkC;AAClC,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAOjE;AAkCD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,MAAM,EACN,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,SAAS,EAChB,MAA4B,EAC5B,IAAS,EACT,KAAK,EACL,WAAW,EACX,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,GACZ,EAAE,kBAAkB,+BAyKpB;AAMD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,+BAwBxD"}
|