@byline/admin 4.1.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/fields/array/array-field.js +20 -8
  2. package/dist/fields/array/array-field.module.js +5 -1
  3. package/dist/fields/array/array-field_module.css +23 -0
  4. package/dist/fields/blocks/blocks-field.js +33 -12
  5. package/dist/fields/blocks/blocks-field.module.js +2 -0
  6. package/dist/fields/blocks/blocks-field_module.css +37 -0
  7. package/dist/fields/code/code-editor.d.ts +20 -0
  8. package/dist/fields/code/code-editor.js +239 -0
  9. package/dist/fields/code/code-field.d.ts +21 -0
  10. package/dist/fields/code/code-field.js +124 -0
  11. package/dist/fields/code/code-field.module.js +7 -0
  12. package/dist/fields/code/code-field_module.css +58 -0
  13. package/dist/fields/field-helpers.js +1 -0
  14. package/dist/fields/field-renderer.js +15 -1
  15. package/dist/fields/group/group-field.d.ts +10 -2
  16. package/dist/fields/group/group-field.js +4 -2
  17. package/dist/fields/relation/relation-picker.js +8 -2
  18. package/dist/fields/select/select-field.js +4 -2
  19. package/dist/fields/select/select-field.module.js +1 -0
  20. package/dist/fields/select/select-field_module.css +4 -0
  21. package/dist/fields/text/text-field_module.css +1 -0
  22. package/dist/fields/text-area/text-area-field_module.css +1 -0
  23. package/dist/forms/form-renderer.d.ts +1 -1
  24. package/dist/forms/tree-placement-widget.d.ts +1 -1
  25. package/package.json +18 -5
  26. package/src/fields/array/array-field.module.css +30 -0
  27. package/src/fields/array/array-field.tsx +15 -2
  28. package/src/fields/blocks/blocks-field.module.css +53 -0
  29. package/src/fields/blocks/blocks-field.tsx +33 -1
  30. package/src/fields/code/code-editor.tsx +246 -0
  31. package/src/fields/code/code-field.module.css +84 -0
  32. package/src/fields/code/code-field.tsx +191 -0
  33. package/src/fields/field-helpers.ts +1 -0
  34. package/src/fields/field-renderer.tsx +19 -2
  35. package/src/fields/field-services-types.ts +1 -1
  36. package/src/fields/group/group-field.tsx +12 -1
  37. package/src/fields/relation/relation-picker.tsx +11 -0
  38. package/src/fields/select/select-field.module.css +5 -0
  39. package/src/fields/select/select-field.tsx +9 -2
  40. package/src/fields/text/text-field.module.css +1 -0
  41. package/src/fields/text-area/text-area-field.module.css +1 -0
  42. package/src/forms/form-renderer.tsx +1 -1
  43. package/src/forms/tree-placement-widget.tsx +1 -1
@@ -175,14 +175,26 @@ const ArrayField = ({ field, defaultValue, path, disableSorting = false, collect
175
175
  className: classnames('byline-field-array-stack', array_field_module.stack),
176
176
  children: [
177
177
  items.map((item, index)=>renderItem(item, index)),
178
- /*#__PURE__*/ jsx("span", {
179
- children: /*#__PURE__*/ jsx(IconButton, {
180
- onClick: ()=>{
181
- handleAddItem();
182
- },
183
- "aria-label": t('fields.array.addItemAriaLabel'),
184
- children: /*#__PURE__*/ jsx(PlusIcon, {})
185
- })
178
+ /*#__PURE__*/ jsxs("div", {
179
+ className: classnames('byline-field-array-add-row', array_field_module["add-row"]),
180
+ children: [
181
+ /*#__PURE__*/ jsx(IconButton, {
182
+ onClick: ()=>{
183
+ handleAddItem();
184
+ },
185
+ "aria-label": t('fields.array.addItemAriaLabel'),
186
+ children: /*#__PURE__*/ jsx(PlusIcon, {})
187
+ }),
188
+ /*#__PURE__*/ jsx("button", {
189
+ type: "button",
190
+ tabIndex: -1,
191
+ onClick: ()=>{
192
+ handleAddItem();
193
+ },
194
+ className: classnames('byline-field-array-add-label', array_field_module["add-label"]),
195
+ children: t('fields.array.addItem')
196
+ })
197
+ ]
186
198
  })
187
199
  ]
188
200
  })
@@ -6,6 +6,10 @@ const array_field_module = {
6
6
  "group-header": "group-header-KJxpIV",
7
7
  groupHeader: "group-header-KJxpIV",
8
8
  "group-fields": "group-fields-Bmi_hA",
9
- groupFields: "group-fields-Bmi_hA"
9
+ groupFields: "group-fields-Bmi_hA",
10
+ "add-row": "add-row-bCHtVe",
11
+ addRow: "add-row-bCHtVe",
12
+ "add-label": "add-label-KdsV2D",
13
+ addLabel: "add-label-KdsV2D"
10
14
  };
11
15
  export default array_field_module;
@@ -30,3 +30,26 @@
30
30
  display: flex;
31
31
  }
32
32
 
33
+ :is(.add-row-bCHtVe, .byline-field-array-add-row) {
34
+ color: var(--muted);
35
+ align-items: center;
36
+ gap: var(--spacing-8);
37
+ font-size: .9rem;
38
+ display: flex;
39
+ }
40
+
41
+ :is(.add-label-KdsV2D, .byline-field-array-add-label) {
42
+ appearance: none;
43
+ font: inherit;
44
+ color: inherit;
45
+ cursor: pointer;
46
+ background: none;
47
+ border: none;
48
+ padding: 0;
49
+ transition: color .12s;
50
+ }
51
+
52
+ :is(.add-row-bCHtVe:hover .add-label-KdsV2D, .byline-field-array-add-row:hover .byline-field-array-add-label) {
53
+ color: var(--text);
54
+ }
55
+
@@ -1,5 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useMemo, useState } from "react";
3
+ import { getClientConfig } from "@byline/core";
3
4
  import { useTranslation } from "@byline/i18n/react";
4
5
  import { Card, CloseIcon, DraggableSortable, IconButton, Modal, PlusIcon, moveItem } from "@byline/ui/react";
5
6
  import classnames from "classnames";
@@ -17,6 +18,11 @@ const BlocksField = ({ field, defaultValue, path, contentLocale })=>{
17
18
  const availableBlocks = useMemo(()=>field.blocks ?? [], [
18
19
  field.blocks
19
20
  ]);
21
+ const blockAdminByType = useMemo(()=>{
22
+ const map = new Map();
23
+ for (const entry of getClientConfig().blockAdmin ?? [])map.set(entry.blockType, entry);
24
+ return map;
25
+ }, []);
20
26
  const [selectedBlockName, setSelectedBlockName] = useState(()=>availableBlocks[0]?.blockType ?? '');
21
27
  useEffect(()=>{
22
28
  if (null == selectedBlockName || !availableBlocks.some((b)=>b.blockType === selectedBlockName)) setSelectedBlockName(availableBlocks[0]?.blockType ?? '');
@@ -130,7 +136,8 @@ const BlocksField = ({ field, defaultValue, path, contentLocale })=>{
130
136
  },
131
137
  defaultValue: fieldData,
132
138
  path: arrayElementPath,
133
- contentLocale: contentLocale
139
+ contentLocale: contentLocale,
140
+ fieldAdmin: blockAdminByType.get(item._type)?.fields
134
141
  }, subField.blockType);
135
142
  return /*#__PURE__*/ jsx(SortableItem, {
136
143
  id: itemWrapper.id,
@@ -153,17 +160,31 @@ const BlocksField = ({ field, defaultValue, path, contentLocale })=>{
153
160
  className: classnames('byline-field-blocks-stack', blocks_field_module.stack),
154
161
  children: [
155
162
  items.map((item, index)=>renderItem(item, index)),
156
- /*#__PURE__*/ jsx("div", {
163
+ /*#__PURE__*/ jsxs("div", {
157
164
  className: classnames('byline-field-blocks-add-row', blocks_field_module["add-row"]),
158
- children: /*#__PURE__*/ jsx(IconButton, {
159
- onClick: ()=>{
160
- setPendingInsertIndex(null);
161
- setShowAddBlockModal(true);
162
- },
163
- disabled: !selectedBlockName,
164
- "aria-label": t('fields.blocks.addBlockAriaLabel'),
165
- children: /*#__PURE__*/ jsx(PlusIcon, {})
166
- })
165
+ children: [
166
+ /*#__PURE__*/ jsx(IconButton, {
167
+ onClick: ()=>{
168
+ setPendingInsertIndex(null);
169
+ setShowAddBlockModal(true);
170
+ },
171
+ disabled: !selectedBlockName,
172
+ "aria-label": t('fields.blocks.addBlockAriaLabel'),
173
+ variant: "outlined",
174
+ children: /*#__PURE__*/ jsx(PlusIcon, {})
175
+ }),
176
+ /*#__PURE__*/ jsx("button", {
177
+ type: "button",
178
+ tabIndex: -1,
179
+ disabled: !selectedBlockName,
180
+ onClick: ()=>{
181
+ setPendingInsertIndex(null);
182
+ setShowAddBlockModal(true);
183
+ },
184
+ className: classnames('byline-field-blocks-add-label', blocks_field_module["add-label"]),
185
+ children: t('fields.blocks.addBlock')
186
+ })
187
+ ]
167
188
  })
168
189
  ]
169
190
  }),
@@ -176,7 +197,7 @@ const BlocksField = ({ field, defaultValue, path, contentLocale })=>{
176
197
  },
177
198
  children: /*#__PURE__*/ jsxs(Modal.Container, {
178
199
  style: {
179
- maxWidth: '600px'
200
+ maxWidth: '700px'
180
201
  },
181
202
  children: [
182
203
  /*#__PURE__*/ jsxs(Modal.Header, {
@@ -4,6 +4,8 @@ const blocks_field_module = {
4
4
  stack: "stack-Xxa89J",
5
5
  "add-row": "add-row-gEqjM_",
6
6
  addRow: "add-row-gEqjM_",
7
+ "add-label": "add-label-jiOURu",
8
+ addLabel: "add-label-jiOURu",
7
9
  "modal-head": "modal-head-BTxR9C",
8
10
  modalHead: "modal-head-BTxR9C",
9
11
  "modal-title": "modal-title-jwOfU_",
@@ -11,11 +11,32 @@
11
11
  }
12
12
 
13
13
  :is(.add-row-gEqjM_, .byline-field-blocks-add-row) {
14
+ color: var(--muted);
14
15
  align-items: center;
15
16
  gap: var(--spacing-8);
17
+ font-size: .9rem;
16
18
  display: flex;
17
19
  }
18
20
 
21
+ :is(.add-label-jiOURu, .byline-field-blocks-add-label) {
22
+ appearance: none;
23
+ font: inherit;
24
+ color: inherit;
25
+ cursor: pointer;
26
+ background: none;
27
+ border: none;
28
+ padding: 0;
29
+ transition: color .12s;
30
+ }
31
+
32
+ :is(.add-label-jiOURu:disabled, .byline-field-blocks-add-label:disabled) {
33
+ cursor: default;
34
+ }
35
+
36
+ :is(.add-row-gEqjM_:hover .add-label-jiOURu:not(:disabled), .byline-field-blocks-add-row:hover .byline-field-blocks-add-label:not(:disabled)) {
37
+ color: var(--text);
38
+ }
39
+
19
40
  :is(.modal-head-BTxR9C, .byline-field-blocks-modal-head) {
20
41
  margin-bottom: var(--spacing-8);
21
42
  padding-top: 1rem;
@@ -28,6 +49,22 @@
28
49
 
29
50
  :is(.modal-content-S12b_T, .byline-field-blocks-card-cursor) {
30
51
  cursor: pointer;
52
+ overscroll-behavior: contain;
53
+ min-height: 0;
54
+ max-height: 80dvh;
55
+ overflow-y: auto;
56
+ }
57
+
58
+ @media (min-width: 40rem) {
59
+ :is(.modal-content-S12b_T, .byline-field-blocks-card-cursor) {
60
+ max-height: 70dvh;
61
+ }
62
+ }
63
+
64
+ @media (min-width: 64rem) {
65
+ :is(.modal-content-S12b_T, .byline-field-blocks-card-cursor) {
66
+ max-height: 60dvh;
67
+ }
31
68
  }
32
69
 
33
70
  :is(.grid-gALL6j, .byline-field-blocks-grid) {
@@ -0,0 +1,20 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ export interface CodeEditorProps {
9
+ id?: string;
10
+ /** Initial document. External updates sync only while the editor is unfocused. */
11
+ value: string;
12
+ /** Highlight language (canonical name or alias). Unknown → plain text. */
13
+ language?: string;
14
+ readOnly?: boolean;
15
+ onChange?: (value: string) => void;
16
+ ariaInvalid?: boolean;
17
+ ariaDescribedBy?: string;
18
+ }
19
+ declare const CodeEditor: ({ id, value, language, readOnly, onChange, ariaInvalid, ariaDescribedBy, }: CodeEditorProps) => import("react").JSX.Element;
20
+ export default CodeEditor;
@@ -0,0 +1,239 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from "react";
3
+ import { defaultKeymap, history as commands_history, historyKeymap, indentWithTab } from "@codemirror/commands";
4
+ import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
5
+ import { Compartment, EditorState } from "@codemirror/state";
6
+ import { EditorView, keymap, lineNumbers } from "@codemirror/view";
7
+ import { tags } from "@lezer/highlight";
8
+ const LANGUAGE_LOADERS = {
9
+ javascript: ()=>import("@codemirror/lang-javascript").then((m)=>m.javascript()),
10
+ jsx: ()=>import("@codemirror/lang-javascript").then((m)=>m.javascript({
11
+ jsx: true
12
+ })),
13
+ typescript: ()=>import("@codemirror/lang-javascript").then((m)=>m.javascript({
14
+ typescript: true
15
+ })),
16
+ tsx: ()=>import("@codemirror/lang-javascript").then((m)=>m.javascript({
17
+ jsx: true,
18
+ typescript: true
19
+ })),
20
+ json: ()=>import("@codemirror/lang-json").then((m)=>m.json()),
21
+ html: ()=>import("@codemirror/lang-html").then((m)=>m.html()),
22
+ css: ()=>import("@codemirror/lang-css").then((m)=>m.css()),
23
+ markdown: ()=>import("@codemirror/lang-markdown").then((m)=>m.markdown()),
24
+ python: ()=>import("@codemirror/lang-python").then((m)=>m.python()),
25
+ sql: ()=>import("@codemirror/lang-sql").then((m)=>m.sql()),
26
+ yaml: ()=>import("@codemirror/lang-yaml").then((m)=>m.yaml())
27
+ };
28
+ const LANGUAGE_ALIASES = {
29
+ js: "javascript",
30
+ ts: "typescript",
31
+ md: 'markdown',
32
+ py: 'python',
33
+ yml: 'yaml'
34
+ };
35
+ const resolveLanguageLoader = (language)=>{
36
+ if (!language) return null;
37
+ const key = LANGUAGE_ALIASES[language] ?? language;
38
+ return LANGUAGE_LOADERS[key] ?? null;
39
+ };
40
+ const bylineCodeTheme = EditorView.theme({
41
+ '&': {
42
+ backgroundColor: 'var(--byline-code-bg)',
43
+ color: 'var(--byline-code-fg)',
44
+ fontSize: 'var(--byline-code-font-size, 13px)',
45
+ border: '1px solid var(--byline-code-border)',
46
+ borderRadius: 'var(--byline-code-radius, 4px)'
47
+ },
48
+ '&.cm-focused': {
49
+ outline: '2px solid var(--byline-code-focus-ring)',
50
+ outlineOffset: '-1px'
51
+ },
52
+ '.cm-content': {
53
+ fontFamily: 'var(--byline-code-font, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)',
54
+ caretColor: 'var(--byline-code-caret)',
55
+ minHeight: 'var(--byline-code-min-height, 6rem)'
56
+ },
57
+ '.cm-scroller': {
58
+ fontFamily: 'inherit',
59
+ maxHeight: 'var(--byline-code-max-height, 32rem)'
60
+ },
61
+ '.cm-gutters': {
62
+ backgroundColor: 'var(--byline-code-gutter-bg)',
63
+ color: 'var(--byline-code-gutter-fg)',
64
+ border: 'none',
65
+ borderRight: '1px solid var(--byline-code-border)'
66
+ },
67
+ '.cm-activeLine': {
68
+ backgroundColor: 'var(--byline-code-active-line)'
69
+ },
70
+ '.cm-activeLineGutter': {
71
+ backgroundColor: 'var(--byline-code-active-line)'
72
+ },
73
+ '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection': {
74
+ backgroundColor: 'var(--byline-code-selection) !important'
75
+ },
76
+ '.cm-cursor': {
77
+ borderLeftColor: 'var(--byline-code-caret)'
78
+ }
79
+ });
80
+ const bylineHighlightStyle = HighlightStyle.define([
81
+ {
82
+ tag: tags.keyword,
83
+ color: 'var(--byline-code-keyword)'
84
+ },
85
+ {
86
+ tag: [
87
+ tags.string,
88
+ tags.special(tags.string)
89
+ ],
90
+ color: 'var(--byline-code-string)'
91
+ },
92
+ {
93
+ tag: tags.comment,
94
+ color: 'var(--byline-code-comment)',
95
+ fontStyle: 'italic'
96
+ },
97
+ {
98
+ tag: [
99
+ tags.number,
100
+ tags.bool,
101
+ tags["null"]
102
+ ],
103
+ color: 'var(--byline-code-number)'
104
+ },
105
+ {
106
+ tag: [
107
+ tags["function"](tags.variableName),
108
+ tags["function"](tags.propertyName)
109
+ ],
110
+ color: 'var(--byline-code-function)'
111
+ },
112
+ {
113
+ tag: [
114
+ tags.typeName,
115
+ tags.className,
116
+ tags.tagName
117
+ ],
118
+ color: 'var(--byline-code-type)'
119
+ },
120
+ {
121
+ tag: [
122
+ tags.propertyName,
123
+ tags.attributeName
124
+ ],
125
+ color: 'var(--byline-code-property)'
126
+ },
127
+ {
128
+ tag: [
129
+ tags.operator,
130
+ tags.definitionKeyword
131
+ ],
132
+ color: 'var(--byline-code-operator)'
133
+ }
134
+ ]);
135
+ const CodeEditor = ({ id, value, language, readOnly, onChange, ariaInvalid, ariaDescribedBy })=>{
136
+ const containerRef = useRef(null);
137
+ const viewRef = useRef(null);
138
+ const onChangeRef = useRef(onChange);
139
+ onChangeRef.current = onChange;
140
+ const languageCompartment = useRef(new Compartment());
141
+ const readOnlyCompartment = useRef(new Compartment());
142
+ const ariaCompartment = useRef(new Compartment());
143
+ const initialValueRef = useRef(value);
144
+ useEffect(()=>{
145
+ if (null == containerRef.current) return;
146
+ const state = EditorState.create({
147
+ doc: initialValueRef.current,
148
+ extensions: [
149
+ lineNumbers(),
150
+ commands_history(),
151
+ bracketMatching(),
152
+ keymap.of([
153
+ ...defaultKeymap,
154
+ ...historyKeymap,
155
+ indentWithTab
156
+ ]),
157
+ EditorView.lineWrapping,
158
+ bylineCodeTheme,
159
+ syntaxHighlighting(bylineHighlightStyle),
160
+ languageCompartment.current.of([]),
161
+ readOnlyCompartment.current.of([]),
162
+ ariaCompartment.current.of([]),
163
+ EditorView.updateListener.of((update)=>{
164
+ if (update.docChanged) onChangeRef.current?.(update.state.doc.toString());
165
+ })
166
+ ]
167
+ });
168
+ const view = new EditorView({
169
+ state,
170
+ parent: containerRef.current
171
+ });
172
+ viewRef.current = view;
173
+ return ()=>{
174
+ view.destroy();
175
+ viewRef.current = null;
176
+ };
177
+ }, []);
178
+ useEffect(()=>{
179
+ const view = viewRef.current;
180
+ if (null == view || view.hasFocus) return;
181
+ const current = view.state.doc.toString();
182
+ if (current !== value) view.dispatch({
183
+ changes: {
184
+ from: 0,
185
+ to: current.length,
186
+ insert: value
187
+ }
188
+ });
189
+ }, [
190
+ value
191
+ ]);
192
+ useEffect(()=>{
193
+ let cancelled = false;
194
+ const view = viewRef.current;
195
+ if (null == view) return;
196
+ const loader = resolveLanguageLoader(language);
197
+ if (null == loader) return void view.dispatch({
198
+ effects: languageCompartment.current.reconfigure([])
199
+ });
200
+ loader().then((extension)=>{
201
+ if (!cancelled && null != viewRef.current) viewRef.current.dispatch({
202
+ effects: languageCompartment.current.reconfigure(extension)
203
+ });
204
+ }).catch(()=>{});
205
+ return ()=>{
206
+ cancelled = true;
207
+ };
208
+ }, [
209
+ language
210
+ ]);
211
+ useEffect(()=>{
212
+ viewRef.current?.dispatch({
213
+ effects: readOnlyCompartment.current.reconfigure([
214
+ EditorState.readOnly.of(true === readOnly),
215
+ EditorView.editable.of(true !== readOnly)
216
+ ])
217
+ });
218
+ }, [
219
+ readOnly
220
+ ]);
221
+ useEffect(()=>{
222
+ const attributes = {};
223
+ if (ariaInvalid) attributes['aria-invalid'] = 'true';
224
+ if (ariaDescribedBy) attributes['aria-describedby'] = ariaDescribedBy;
225
+ viewRef.current?.dispatch({
226
+ effects: ariaCompartment.current.reconfigure(EditorView.contentAttributes.of(attributes))
227
+ });
228
+ }, [
229
+ ariaInvalid,
230
+ ariaDescribedBy
231
+ ]);
232
+ return /*#__PURE__*/ jsx("div", {
233
+ ref: containerRef,
234
+ id: id,
235
+ className: "byline-code-editor"
236
+ });
237
+ };
238
+ const code_editor = CodeEditor;
239
+ export default code_editor;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import React from 'react';
9
+ import type { FieldComponentSlots, CodeField as FieldType } from '@byline/core';
10
+ export declare const CodeField: ({ field, value, defaultValue, onChange, id, path, locale, components, }: {
11
+ field: FieldType;
12
+ value?: string;
13
+ defaultValue?: string;
14
+ onChange?: (value: string) => void;
15
+ id?: string;
16
+ path?: string;
17
+ /** When provided, renders a LocaleBadge next to the field label. */
18
+ locale?: string;
19
+ /** Optional UI component slot overrides from the admin config. */
20
+ components?: FieldComponentSlots;
21
+ }) => React.JSX.Element;
@@ -0,0 +1,124 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import react, { Suspense, useCallback } from "react";
3
+ import { ErrorText, HelpText, Label } from "@byline/ui/react";
4
+ import classnames from "classnames";
5
+ import { useFieldError, useFieldValue } from "../../forms/form-context.js";
6
+ import { LocaleBadge } from "../locale-badge.js";
7
+ import code_field_module from "./code-field.module.js";
8
+ const CodeEditor = /*#__PURE__*/ react.lazy(()=>import("./code-editor.js"));
9
+ const siblingFieldPath = (fieldPath, siblingName)=>{
10
+ const lastDot = fieldPath.lastIndexOf('.');
11
+ return -1 === lastDot ? siblingName : `${fieldPath.slice(0, lastDot + 1)}${siblingName}`;
12
+ };
13
+ const CodeField = ({ field, value, defaultValue, onChange, id, path, locale, components })=>{
14
+ const fieldPath = path ?? field.name;
15
+ const fieldError = useFieldError(fieldPath);
16
+ const fieldValue = useFieldValue(fieldPath);
17
+ const incomingValue = value ?? fieldValue ?? defaultValue ?? '';
18
+ const htmlId = id ?? fieldPath;
19
+ const siblingPath = field.languageField ? siblingFieldPath(fieldPath, field.languageField) : fieldPath;
20
+ const siblingLanguage = useFieldValue(siblingPath);
21
+ const effectiveLanguage = (field.languageField ? siblingLanguage : void 0) || field.language;
22
+ const handleChange = useCallback((value)=>{
23
+ if (onChange) onChange(value);
24
+ }, [
25
+ onChange
26
+ ]);
27
+ const slots = components;
28
+ const CustomLabel = slots?.Label;
29
+ const CustomHelpText = slots?.HelpText;
30
+ const CustomField = slots?.Field;
31
+ const BeforeField = slots?.beforeField;
32
+ const AfterField = slots?.afterField;
33
+ const slotBaseProps = {
34
+ field: field,
35
+ path: fieldPath,
36
+ value: incomingValue,
37
+ error: fieldError,
38
+ id: htmlId
39
+ };
40
+ const showBadge = !!locale && !!field.label;
41
+ const hasCustomLabel = !!CustomLabel;
42
+ const labelRowClass = classnames('byline-field-code-label-row', code_field_module["label-row"]);
43
+ const renderLabel = ()=>{
44
+ if (hasCustomLabel) return /*#__PURE__*/ jsxs("div", {
45
+ className: labelRowClass,
46
+ children: [
47
+ /*#__PURE__*/ jsx(CustomLabel, {
48
+ ...slotBaseProps,
49
+ label: field.label,
50
+ required: !field.optional
51
+ }),
52
+ showBadge && /*#__PURE__*/ jsx(LocaleBadge, {
53
+ locale: locale
54
+ })
55
+ ]
56
+ });
57
+ if (field.label) return /*#__PURE__*/ jsxs("div", {
58
+ className: labelRowClass,
59
+ children: [
60
+ /*#__PURE__*/ jsx(Label, {
61
+ id: `${htmlId}-label`,
62
+ htmlFor: htmlId,
63
+ label: field.label,
64
+ required: !field.optional
65
+ }),
66
+ showBadge && /*#__PURE__*/ jsx(LocaleBadge, {
67
+ locale: locale
68
+ })
69
+ ]
70
+ });
71
+ return null;
72
+ };
73
+ const renderInput = ()=>{
74
+ if (CustomField) return /*#__PURE__*/ jsx(CustomField, {
75
+ ...slotBaseProps,
76
+ onChange: handleChange,
77
+ defaultValue: defaultValue,
78
+ placeholder: field.placeholder
79
+ });
80
+ return /*#__PURE__*/ jsx(Suspense, {
81
+ fallback: /*#__PURE__*/ jsx("textarea", {
82
+ className: classnames('byline-field-code-loading', code_field_module.loading),
83
+ readOnly: true,
84
+ value: incomingValue,
85
+ rows: 6,
86
+ "aria-label": field.label
87
+ }),
88
+ children: /*#__PURE__*/ jsx(CodeEditor, {
89
+ id: htmlId,
90
+ value: incomingValue,
91
+ language: effectiveLanguage,
92
+ onChange: handleChange,
93
+ readOnly: true === field.readOnly,
94
+ ariaInvalid: null != fieldError,
95
+ ariaDescribedBy: null != fieldError ? `error-for-${htmlId}` : field.helpText ? `help-for-${htmlId}` : void 0
96
+ })
97
+ });
98
+ };
99
+ return /*#__PURE__*/ jsxs("div", {
100
+ className: `byline-field-code ${field.name}`,
101
+ children: [
102
+ renderLabel(),
103
+ BeforeField && /*#__PURE__*/ jsx(BeforeField, {
104
+ ...slotBaseProps
105
+ }),
106
+ renderInput(),
107
+ AfterField && /*#__PURE__*/ jsx(AfterField, {
108
+ ...slotBaseProps
109
+ }),
110
+ null != fieldError && /*#__PURE__*/ jsx(ErrorText, {
111
+ id: `error-for-${htmlId}`,
112
+ text: fieldError
113
+ }),
114
+ CustomHelpText ? /*#__PURE__*/ jsx(CustomHelpText, {
115
+ ...slotBaseProps,
116
+ helpText: field.helpText
117
+ }) : null == fieldError && field.helpText && /*#__PURE__*/ jsx(HelpText, {
118
+ id: `help-for-${htmlId}`,
119
+ text: field.helpText
120
+ })
121
+ ]
122
+ });
123
+ };
124
+ export { CodeField };
@@ -0,0 +1,7 @@
1
+ import "./code-field_module.css";
2
+ const code_field_module = {
3
+ "label-row": "label-row-bNilI8",
4
+ labelRow: "label-row-bNilI8",
5
+ loading: "loading-sejBT6"
6
+ };
7
+ export default code_field_module;