@limetech/lime-elements 40.12.3 → 40.13.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.
- package/CHANGELOG.md +10 -0
- package/dist/cjs/drag-to-reorder-BP5YkPuu.js +3092 -0
- package/dist/cjs/lime-elements.cjs.js +1 -1
- package/dist/cjs/{limel-scroller.cjs.entry.js → limel-drag-handle_2.cjs.entry.js} +38 -0
- package/dist/cjs/limel-file-viewer.cjs.entry.js +64 -55
- package/dist/cjs/limel-form.cjs.entry.js +539 -3171
- package/dist/cjs/limel-tab-bar.cjs.entry.js +120 -16
- package/dist/cjs/limel-tab-panel.cjs.entry.js +7 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/form/form.css +59 -0
- package/dist/collection/components/form/form.js +49 -2
- package/dist/collection/components/form/show-field.js +116 -0
- package/dist/collection/components/form/templates/array-field-collapsible-item.js +1 -0
- package/dist/collection/components/form/templates/array-field-item.js +5 -0
- package/dist/collection/components/form/templates/array-field.js +20 -158
- package/dist/collection/components/form/templates/field.js +17 -0
- package/dist/collection/components/tab-bar/tab-bar.css +68 -22
- package/dist/collection/components/tab-bar/tab-bar.js +131 -4
- package/dist/collection/components/tab-bar/tabs.js +23 -0
- package/dist/collection/components/tab-panel/tab-panel.js +54 -1
- package/dist/collection/util/drag-to-reorder.js +116 -0
- package/dist/esm/{_baseForOwn-D5j7fHlv.js → _baseForOwn-vKFWmmaS.js} +1 -1
- package/dist/esm/{_baseIsEqual-CyF4P8uM.js → _baseIsEqual-B_JRErB0.js} +1 -1
- package/dist/esm/{_baseIteratee-CpbczHY1.js → _baseIteratee-CVz7aes3.js} +1 -1
- package/dist/esm/{_baseSet-Cw2IE6ZF.js → _baseSet-BUAq8NGm.js} +1 -1
- package/dist/esm/{cloneDeep-DAbOtbs8.js → cloneDeep-Bcll-3f8.js} +1 -1
- package/dist/esm/drag-to-reorder-BXmXIwCa.js +3086 -0
- package/dist/esm/{isEqual-CE83yS8T.js → isEqual-C-pK6AAU.js} +1 -1
- package/dist/esm/lime-elements.js +1 -1
- package/dist/esm/limel-chip-set.entry.js +2 -2
- package/dist/esm/limel-dialog.entry.js +2 -2
- package/dist/esm/{limel-scroller.entry.js → limel-drag-handle_2.entry.js} +38 -1
- package/dist/esm/limel-file-dropzone_2.entry.js +3 -3
- package/dist/esm/limel-file-viewer.entry.js +64 -55
- package/dist/esm/limel-form.entry.js +536 -3168
- package/dist/esm/limel-prosemirror-adapter.entry.js +3 -3
- package/dist/esm/limel-tab-bar.entry.js +117 -13
- package/dist/esm/limel-tab-panel.entry.js +7 -1
- package/dist/esm/limel-table.entry.js +4 -4
- package/dist/esm/loader.js +1 -1
- package/dist/lime-elements/lime-elements.esm.js +1 -1
- package/dist/lime-elements/{p-35bc5ed2.entry.js → p-13f2afc9.entry.js} +1 -1
- package/dist/lime-elements/p-3b6d4934.entry.js +1 -0
- package/dist/lime-elements/p-67767276.entry.js +1 -0
- package/dist/lime-elements/{p-fb15f608.entry.js → p-6d65ee35.entry.js} +1 -1
- package/dist/lime-elements/p-714ab66d.entry.js +16 -0
- package/dist/lime-elements/{p-ff4a8b89.entry.js → p-7ae71c13.entry.js} +1 -1
- package/dist/lime-elements/p-BAqAt5It.js +1 -0
- package/dist/lime-elements/p-Cu9Ji1iJ.js +1 -0
- package/dist/lime-elements/{p-BY5NjPj8.js → p-D9Ezd43A.js} +1 -1
- package/dist/lime-elements/{p-nVemxylR.js → p-DFu1q54T.js} +1 -1
- package/dist/lime-elements/p-DdnBHYb-.js +7 -0
- package/dist/lime-elements/{p-B6-3WXAv.js → p-DeIIlp6m.js} +1 -1
- package/dist/lime-elements/p-Dq0uNStc.js +1 -0
- package/dist/lime-elements/p-b5bb124f.entry.js +1 -0
- package/dist/lime-elements/{p-9168793f.entry.js → p-bd58c761.entry.js} +1 -1
- package/dist/lime-elements/{p-458c131f.entry.js → p-c7e34502.entry.js} +1 -1
- package/dist/lime-elements/p-fb526a05.entry.js +1 -0
- package/dist/types/components/form/form.d.ts +15 -0
- package/dist/types/components/form/show-field.d.ts +9 -0
- package/dist/types/components/form/templates/array-context.d.ts +4 -0
- package/dist/types/components/form/templates/array-field-collapsible-item.d.ts +5 -0
- package/dist/types/components/form/templates/array-field.d.ts +3 -13
- package/dist/types/components/form/templates/field.d.ts +1 -0
- package/dist/types/components/form/templates/object-field.d.ts +2 -2
- package/dist/types/components/tab-bar/tab-bar.d.ts +25 -0
- package/dist/types/components/tab-bar/tab.types.d.ts +18 -0
- package/dist/types/components/tab-bar/tabs.d.ts +12 -1
- package/dist/types/components/tab-panel/tab-panel.d.ts +18 -1
- package/dist/types/components.d.ts +80 -2
- package/dist/types/util/drag-to-reorder.d.ts +65 -0
- package/package.json +4 -4
- package/dist/cjs/isArrayLikeObject-U2Ddbw4n.js +0 -326
- package/dist/cjs/limel-drag-handle.cjs.entry.js +0 -42
- package/dist/esm/isArrayLikeObject-CJB8HbtH.js +0 -321
- package/dist/esm/limel-drag-handle.entry.js +0 -40
- package/dist/lime-elements/p-49eb2f64.entry.js +0 -13
- package/dist/lime-elements/p-646731b6.entry.js +0 -1
- package/dist/lime-elements/p-8d567e42.entry.js +0 -1
- package/dist/lime-elements/p-BQeIv4aA.js +0 -1
- package/dist/lime-elements/p-COdirXg1.js +0 -1
- package/dist/lime-elements/p-ORUNaKm-.js +0 -1
- package/dist/lime-elements/p-a5246373.entry.js +0 -1
- package/dist/lime-elements/p-b609552e.entry.js +0 -1
- package/dist/lime-elements/p-bf849dc9.entry.js +0 -1
- package/dist/lime-elements/p-pk5KIdKH.js +0 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { flushSync } from "react-dom";
|
|
2
|
+
import { toSchemaPath } from "./templates/object-field";
|
|
3
|
+
import { getFocusTarget } from "../../util/get-focus-target";
|
|
4
|
+
const HIGHLIGHT_CLASS = 'limel-form-field--highlighted';
|
|
5
|
+
const STABLE_FRAMES = 3;
|
|
6
|
+
const MAX_SETTLE_MS = 2000;
|
|
7
|
+
const MAX_RENDER_FRAMES = 30;
|
|
8
|
+
/**
|
|
9
|
+
* Open what is closed above a field, scroll it into view, focus it and
|
|
10
|
+
* highlight it.
|
|
11
|
+
*
|
|
12
|
+
* @param root - the element the form is rendered in
|
|
13
|
+
* @param path - the path of the field in the value of the form
|
|
14
|
+
*/
|
|
15
|
+
export async function showField(root, path) {
|
|
16
|
+
if (!(await waitUntilRendered(root, path))) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
let target;
|
|
20
|
+
for (let depth = 1; depth <= path.length; depth++) {
|
|
21
|
+
const element = findByPath(root, path.slice(0, depth));
|
|
22
|
+
if (!element) {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
target = element;
|
|
26
|
+
openSectionsAround(root, element);
|
|
27
|
+
}
|
|
28
|
+
if (!target) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
// The components inside the field have to be drawn, and the sections
|
|
32
|
+
// around it opened, before the field is where it will stay.
|
|
33
|
+
const focusTarget = await getFocusTarget(target);
|
|
34
|
+
await waitForLayoutToSettle(target);
|
|
35
|
+
target.scrollIntoView({
|
|
36
|
+
block: 'center',
|
|
37
|
+
behavior: prefersReducedMotion() ? 'instant' : 'smooth',
|
|
38
|
+
});
|
|
39
|
+
focusTarget === null || focusTarget === void 0 ? void 0 : focusTarget.focus({ preventScroll: true });
|
|
40
|
+
await waitForLayoutToSettle(target);
|
|
41
|
+
highlight(target);
|
|
42
|
+
}
|
|
43
|
+
function findByPath(root, path) {
|
|
44
|
+
const schemaPath = toSchemaPath(path.map(String));
|
|
45
|
+
return root.querySelector(`[data-schema-path="${CSS.escape(schemaPath)}"]`);
|
|
46
|
+
}
|
|
47
|
+
// The form is drawn a moment after its value or schema is set, so give it a few
|
|
48
|
+
// frames to show the start of the path.
|
|
49
|
+
async function waitUntilRendered(root, path) {
|
|
50
|
+
for (let frame = 0; frame < MAX_RENDER_FRAMES; frame++) {
|
|
51
|
+
if (findByPath(root, path.slice(0, 1))) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
await nextFrame();
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
function openSectionsAround(root, element) {
|
|
59
|
+
for (let node = element; node && node !== root; node = node.parentElement) {
|
|
60
|
+
if (isClosedSection(node)) {
|
|
61
|
+
open(node);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function isClosedSection(element) {
|
|
66
|
+
return (element.tagName === 'LIMEL-COLLAPSIBLE-SECTION' &&
|
|
67
|
+
!element.isOpen);
|
|
68
|
+
}
|
|
69
|
+
// A collapsed list item renders its fields only once its section says it has
|
|
70
|
+
// been opened, and they have to be in place before the next step is looked up.
|
|
71
|
+
function open(section) {
|
|
72
|
+
section.isOpen = true;
|
|
73
|
+
flushSync(() => {
|
|
74
|
+
section.dispatchEvent(new CustomEvent('open'));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// Wait until the field has a size and has stayed in place for a few frames, so
|
|
78
|
+
// it is not scrolled to while the form still grows, nor flashed while scrolling.
|
|
79
|
+
async function waitForLayoutToSettle(element) {
|
|
80
|
+
let previous = '';
|
|
81
|
+
let stableFrames = 0;
|
|
82
|
+
const deadline = performance.now() + MAX_SETTLE_MS;
|
|
83
|
+
while (performance.now() < deadline) {
|
|
84
|
+
await nextFrame();
|
|
85
|
+
const { top, height } = element.getBoundingClientRect();
|
|
86
|
+
const current = `${top}:${height}`;
|
|
87
|
+
const isStill = height > 0 && current === previous;
|
|
88
|
+
stableFrames = isStill ? stableFrames + 1 : 0;
|
|
89
|
+
if (stableFrames === STABLE_FRAMES) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
previous = current;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function highlight(element) {
|
|
96
|
+
// Removed for a frame first, so showing the same field again restarts it.
|
|
97
|
+
element.classList.remove(HIGHLIGHT_CLASS);
|
|
98
|
+
const removeHighlight = (event) => {
|
|
99
|
+
// Animations of what the field holds end here too.
|
|
100
|
+
if (event.animationName !== 'highlight-field-shadow') {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
element.classList.remove(HIGHLIGHT_CLASS);
|
|
104
|
+
element.removeEventListener('animationend', removeHighlight);
|
|
105
|
+
};
|
|
106
|
+
requestAnimationFrame(() => {
|
|
107
|
+
element.classList.add(HIGHLIGHT_CLASS);
|
|
108
|
+
element.addEventListener('animationend', removeHighlight);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function prefersReducedMotion() {
|
|
112
|
+
return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
113
|
+
}
|
|
114
|
+
function nextFrame() {
|
|
115
|
+
return new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
|
116
|
+
}
|
|
@@ -54,6 +54,7 @@ export class CollapsibleItemTemplate extends React.Component {
|
|
|
54
54
|
this.section = section;
|
|
55
55
|
},
|
|
56
56
|
'is-open': this.state.isOpen,
|
|
57
|
+
'data-schema-path': this.props.schemaPath,
|
|
57
58
|
'data-reorder-id': String(this.props.index),
|
|
58
59
|
'data-reorderable': this.props.allowItemReorder
|
|
59
60
|
? 'true'
|
|
@@ -3,6 +3,7 @@ import { isObjectType } from "../schema";
|
|
|
3
3
|
import { CollapsibleItemTemplate } from "./array-field-collapsible-item";
|
|
4
4
|
import { SimpleItemTemplate } from "./array-field-simple-item";
|
|
5
5
|
import { ArrayFieldContext, ArrayItemErrorsContext } from "./array-context";
|
|
6
|
+
import { toSchemaPath } from "./object-field";
|
|
6
7
|
export const ArrayFieldItemTemplate = (props) => {
|
|
7
8
|
const arrayContext = useContext(ArrayFieldContext);
|
|
8
9
|
const itemErrors = useContext(ArrayItemErrorsContext);
|
|
@@ -26,6 +27,10 @@ export const ArrayFieldItemTemplate = (props) => {
|
|
|
26
27
|
allowItemReorder: allowItemReorder,
|
|
27
28
|
errorSchema: itemErrors === null || itemErrors === void 0 ? void 0 : itemErrors[props.index],
|
|
28
29
|
revealErrors: (formContext === null || formContext === void 0 ? void 0 : formContext.revealErrors) === true,
|
|
30
|
+
schemaPath: toSchemaPath([
|
|
31
|
+
...arrayContext.schemaPath,
|
|
32
|
+
String(props.index),
|
|
33
|
+
]),
|
|
29
34
|
}, props.children);
|
|
30
35
|
}
|
|
31
36
|
return React.createElement(SimpleItemTemplate, {
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { renderDescription, renderTitle } from "./common";
|
|
3
|
-
import
|
|
3
|
+
import { toSchemaPath } from "./object-field";
|
|
4
|
+
import { DragToReorder } from "../../../util/drag-to-reorder";
|
|
4
5
|
import { ArrayFieldContext } from "./array-context";
|
|
5
6
|
export const ARRAY_REORDER_EVENT = 'arrayReorder';
|
|
6
|
-
const DRAG_HANDLE_SELECTOR = '[data-drag-handle]';
|
|
7
7
|
const DRAGGABLE_ITEM_SELECTOR = '.array-item[data-reorderable="true"]';
|
|
8
|
-
const DEFAULT_CONTAINER_CLASS = 'has-an-item-which-is-being-dragged';
|
|
9
|
-
const DEFAULT_DROP_ELEVATION_CLASS = 'is-elevated';
|
|
10
|
-
const DROP_ELEVATION_DURATION = 1000;
|
|
11
|
-
const TOUCH_DRAG_DELAY_MS = 200; // Adds a short hold on touch (long-press) so scroll gestures do not reorder items.
|
|
12
8
|
export class ArrayFieldTemplate extends React.Component {
|
|
13
9
|
constructor(props) {
|
|
14
10
|
super(props);
|
|
@@ -21,68 +17,28 @@ export class ArrayFieldTemplate extends React.Component {
|
|
|
21
17
|
if (this.container === element) {
|
|
22
18
|
return;
|
|
23
19
|
}
|
|
24
|
-
this.
|
|
20
|
+
this.dragToReorder.teardown();
|
|
25
21
|
this.container = element !== null && element !== void 0 ? element : undefined;
|
|
26
22
|
this.setupDragController();
|
|
27
23
|
};
|
|
28
|
-
this.
|
|
29
|
-
if (!this.canReorderItems()) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
this.dragSnapshot = [...this.state.order];
|
|
33
|
-
this.draggedItemIndex = this.getReorderId(event.item);
|
|
34
|
-
if (this.container) {
|
|
35
|
-
this.container.classList.add(DEFAULT_CONTAINER_CLASS);
|
|
36
|
-
}
|
|
37
|
-
if (event.item instanceof HTMLElement) {
|
|
38
|
-
this.applyDropElevation(event.item);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
this.handleSortEnd = (event) => {
|
|
24
|
+
this.handleReorder = ({ order, fromIndex, toIndex, }) => {
|
|
42
25
|
var _a;
|
|
43
|
-
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
if (this.container) {
|
|
47
|
-
this.container.classList.remove(DEFAULT_CONTAINER_CLASS);
|
|
48
|
-
}
|
|
49
|
-
const snapshot = this.dragSnapshot;
|
|
50
|
-
const draggedItemIndex = this.draggedItemIndex;
|
|
51
|
-
this.dragSnapshot = undefined;
|
|
52
|
-
this.draggedItemIndex = undefined;
|
|
53
|
-
if (event.item instanceof HTMLElement) {
|
|
54
|
-
this.dropElevationTarget = event.item;
|
|
55
|
-
}
|
|
56
|
-
const finalOrder = this.readOrderFromDom();
|
|
57
|
-
if (!this.arraysEqual(this.state.order, finalOrder)) {
|
|
58
|
-
this.setState({ order: finalOrder });
|
|
59
|
-
}
|
|
60
|
-
if (snapshot === undefined ||
|
|
61
|
-
draggedItemIndex === undefined ||
|
|
62
|
-
!(event.item instanceof HTMLElement)) {
|
|
63
|
-
this.scheduleDropElevationRemoval();
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const fromPosition = snapshot.indexOf(draggedItemIndex);
|
|
67
|
-
const toPosition = finalOrder.indexOf(draggedItemIndex);
|
|
68
|
-
if (fromPosition === -1 ||
|
|
69
|
-
toPosition === -1 ||
|
|
70
|
-
fromPosition === toPosition) {
|
|
71
|
-
this.scheduleDropElevationRemoval();
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
26
|
+
this.setState({ order: order.map(Number) });
|
|
74
27
|
(_a = this.container) === null || _a === void 0 ? void 0 : _a.dispatchEvent(new CustomEvent(ARRAY_REORDER_EVENT, {
|
|
75
28
|
bubbles: true,
|
|
76
|
-
detail: { fromIndex
|
|
29
|
+
detail: { fromIndex, toIndex },
|
|
77
30
|
}));
|
|
78
|
-
this.scheduleDropElevationRemoval();
|
|
79
31
|
};
|
|
80
32
|
this.state = {
|
|
81
33
|
order: this.extractIndices(props.items),
|
|
82
34
|
};
|
|
35
|
+
this.dragToReorder = new DragToReorder({
|
|
36
|
+
draggable: DRAGGABLE_ITEM_SELECTOR,
|
|
37
|
+
onReorder: this.handleReorder,
|
|
38
|
+
});
|
|
83
39
|
}
|
|
84
40
|
componentWillUnmount() {
|
|
85
|
-
this.
|
|
41
|
+
this.dragToReorder.teardown();
|
|
86
42
|
}
|
|
87
43
|
componentDidMount() {
|
|
88
44
|
this.setupDragController();
|
|
@@ -151,47 +107,10 @@ export class ArrayFieldTemplate extends React.Component {
|
|
|
151
107
|
}
|
|
152
108
|
setupDragController() {
|
|
153
109
|
if (!this.container || !this.canReorderItems()) {
|
|
154
|
-
this.
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
const reorderableItems = this.container.querySelectorAll(`:scope > ${DRAGGABLE_ITEM_SELECTOR}`);
|
|
158
|
-
if (reorderableItems.length < 2) {
|
|
159
|
-
this.teardownDragController();
|
|
110
|
+
this.dragToReorder.teardown();
|
|
160
111
|
return;
|
|
161
112
|
}
|
|
162
|
-
|
|
163
|
-
this.sortable.option('handle', DRAG_HANDLE_SELECTOR);
|
|
164
|
-
this.sortable.option('draggable', DRAGGABLE_ITEM_SELECTOR);
|
|
165
|
-
this.sortable.option('disabled', false);
|
|
166
|
-
this.sortable.option('delay', TOUCH_DRAG_DELAY_MS);
|
|
167
|
-
this.sortable.option('delayOnTouchOnly', true);
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
this.sortable = Sortable.create(this.container, {
|
|
171
|
-
animation: 150,
|
|
172
|
-
handle: DRAG_HANDLE_SELECTOR,
|
|
173
|
-
draggable: DRAGGABLE_ITEM_SELECTOR,
|
|
174
|
-
delay: TOUCH_DRAG_DELAY_MS,
|
|
175
|
-
delayOnTouchOnly: true,
|
|
176
|
-
onStart: this.handleSortStart,
|
|
177
|
-
onEnd: this.handleSortEnd,
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
teardownDragController() {
|
|
181
|
-
if (this.sortable) {
|
|
182
|
-
this.sortable.destroy();
|
|
183
|
-
this.sortable = undefined;
|
|
184
|
-
}
|
|
185
|
-
this.clearDropElevationTimer();
|
|
186
|
-
if (this.dropElevationTarget) {
|
|
187
|
-
this.dropElevationTarget.classList.remove(DEFAULT_DROP_ELEVATION_CLASS);
|
|
188
|
-
this.dropElevationTarget = undefined;
|
|
189
|
-
}
|
|
190
|
-
if (this.container) {
|
|
191
|
-
this.container.classList.remove(DEFAULT_CONTAINER_CLASS);
|
|
192
|
-
}
|
|
193
|
-
this.dragSnapshot = undefined;
|
|
194
|
-
this.draggedItemIndex = undefined;
|
|
113
|
+
this.dragToReorder.setup(this.container);
|
|
195
114
|
}
|
|
196
115
|
canReorderItems() {
|
|
197
116
|
if (this.props.disabled || this.props.readonly) {
|
|
@@ -201,67 +120,6 @@ export class ArrayFieldTemplate extends React.Component {
|
|
|
201
120
|
const limeOptions = (schema === null || schema === void 0 ? void 0 : schema.lime) || {};
|
|
202
121
|
return limeOptions.allowItemReorder !== false;
|
|
203
122
|
}
|
|
204
|
-
readOrderFromDom() {
|
|
205
|
-
if (!this.container) {
|
|
206
|
-
return [];
|
|
207
|
-
}
|
|
208
|
-
// Only read the order of the direct children of this array field.
|
|
209
|
-
// Nested array fields may render `.array-item` elements inside items,
|
|
210
|
-
// and those must not affect the parent order.
|
|
211
|
-
const items = [...this.container.children].filter((element) => {
|
|
212
|
-
var _a, _b;
|
|
213
|
-
return Boolean((_b = (_a = element === null || element === void 0 ? void 0 : element.classList) === null || _a === void 0 ? void 0 : _a.contains) === null || _b === void 0 ? void 0 : _b.call(_a, 'array-item'));
|
|
214
|
-
});
|
|
215
|
-
const order = [];
|
|
216
|
-
for (const element of items) {
|
|
217
|
-
const index = this.getReorderId(element);
|
|
218
|
-
if (index !== undefined) {
|
|
219
|
-
order.push(index);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return order;
|
|
223
|
-
}
|
|
224
|
-
getReorderId(element) {
|
|
225
|
-
var _a;
|
|
226
|
-
if (!element) {
|
|
227
|
-
return undefined;
|
|
228
|
-
}
|
|
229
|
-
const value = (_a = element === null || element === void 0 ? void 0 : element.dataset) === null || _a === void 0 ? void 0 : _a.reorderId;
|
|
230
|
-
if (value === undefined) {
|
|
231
|
-
return undefined;
|
|
232
|
-
}
|
|
233
|
-
const parsed = Number.parseInt(value, 10);
|
|
234
|
-
return Number.isNaN(parsed) ? undefined : parsed;
|
|
235
|
-
}
|
|
236
|
-
applyDropElevation(item) {
|
|
237
|
-
if (this.dropElevationTarget && this.dropElevationTarget !== item) {
|
|
238
|
-
this.dropElevationTarget.classList.remove(DEFAULT_DROP_ELEVATION_CLASS);
|
|
239
|
-
}
|
|
240
|
-
this.clearDropElevationTimer();
|
|
241
|
-
item.classList.add(DEFAULT_DROP_ELEVATION_CLASS);
|
|
242
|
-
this.dropElevationTarget = item;
|
|
243
|
-
}
|
|
244
|
-
scheduleDropElevationRemoval() {
|
|
245
|
-
if (!this.dropElevationTarget) {
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
const target = this.dropElevationTarget;
|
|
249
|
-
this.clearDropElevationTimer();
|
|
250
|
-
this.dropElevationTimeout = setTimeout(() => {
|
|
251
|
-
target.classList.remove(DEFAULT_DROP_ELEVATION_CLASS);
|
|
252
|
-
if (this.dropElevationTarget === target) {
|
|
253
|
-
this.dropElevationTarget = undefined;
|
|
254
|
-
}
|
|
255
|
-
this.dropElevationTimeout = undefined;
|
|
256
|
-
}, DROP_ELEVATION_DURATION);
|
|
257
|
-
}
|
|
258
|
-
clearDropElevationTimer() {
|
|
259
|
-
if (this.dropElevationTimeout === undefined) {
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
clearTimeout(this.dropElevationTimeout);
|
|
263
|
-
this.dropElevationTimeout = undefined;
|
|
264
|
-
}
|
|
265
123
|
arraysEqual(a, b) {
|
|
266
124
|
if (a.length !== b.length) {
|
|
267
125
|
return false;
|
|
@@ -279,17 +137,21 @@ export class ArrayFieldTemplate extends React.Component {
|
|
|
279
137
|
return (items !== null && items !== void 0 ? items : []).map((_, index) => index);
|
|
280
138
|
}
|
|
281
139
|
getContextValue() {
|
|
282
|
-
var _a;
|
|
140
|
+
var _a, _b, _c;
|
|
283
141
|
const schema = this.props.schema;
|
|
284
142
|
const formData = ((_a = this.props.formData) !== null && _a !== void 0 ? _a : []);
|
|
143
|
+
const schemaPath = ((_c = (_b = this.props.fieldPathId) === null || _b === void 0 ? void 0 : _b.path) !== null && _c !== void 0 ? _c : []).map(String);
|
|
144
|
+
const path = toSchemaPath(schemaPath);
|
|
285
145
|
if (this.cachedContextValue &&
|
|
286
146
|
this.cachedSchema === schema &&
|
|
287
|
-
this.cachedFormData === formData
|
|
147
|
+
this.cachedFormData === formData &&
|
|
148
|
+
this.cachedPath === path) {
|
|
288
149
|
return this.cachedContextValue;
|
|
289
150
|
}
|
|
290
151
|
this.cachedSchema = schema;
|
|
291
152
|
this.cachedFormData = formData;
|
|
292
|
-
this.
|
|
153
|
+
this.cachedPath = path;
|
|
154
|
+
this.cachedContextValue = { arraySchema: schema, formData, schemaPath };
|
|
293
155
|
return this.cachedContextValue;
|
|
294
156
|
}
|
|
295
157
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { isObjectType } from "../schema";
|
|
3
|
+
import { toSchemaPath } from "./object-field";
|
|
4
|
+
import { isCustomObjectSchema } from "../fields/field-helpers";
|
|
3
5
|
export const FieldTemplate = (props) => {
|
|
4
6
|
let classNames = props.classNames;
|
|
5
7
|
const colSpan = getColSpan(props.schema);
|
|
@@ -17,8 +19,23 @@ export const FieldTemplate = (props) => {
|
|
|
17
19
|
return React.createElement('div', {
|
|
18
20
|
className: classNames,
|
|
19
21
|
style: style,
|
|
22
|
+
'data-schema-path': getFieldSchemaPath(props),
|
|
20
23
|
}, props.children);
|
|
21
24
|
};
|
|
25
|
+
// An object marks its own layout wrapper, unless a component or the code
|
|
26
|
+
// editor draws it instead. It lets a host find the element of one field by its path.
|
|
27
|
+
function getFieldSchemaPath(props) {
|
|
28
|
+
var _a;
|
|
29
|
+
if (isObjectType(props.schema) && hasOwnLayout(props.schema)) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const path = (_a = props.fieldPathId) === null || _a === void 0 ? void 0 : _a.path;
|
|
33
|
+
return path ? toSchemaPath(path.map(String)) : undefined;
|
|
34
|
+
}
|
|
35
|
+
function hasOwnLayout(schema) {
|
|
36
|
+
var _a, _b;
|
|
37
|
+
return !((_b = (_a = schema.lime) === null || _a === void 0 ? void 0 : _a.component) === null || _b === void 0 ? void 0 : _b.name) && !isCustomObjectSchema(schema);
|
|
38
|
+
}
|
|
22
39
|
function getColSpan(schema) {
|
|
23
40
|
var _a;
|
|
24
41
|
const layout = (_a = schema.lime) === null || _a === void 0 ? void 0 : _a.layout;
|
|
@@ -128,12 +128,57 @@ limel-scroller {
|
|
|
128
128
|
background-color: rgb(var(--limel-tab-background-color));
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
:host(.has-tabs-with-equal-width:not([orientation=vertical])) button
|
|
131
|
+
:host(.has-tabs-with-equal-width:not([orientation=vertical])) button[role=tab],
|
|
132
|
+
:host(.has-tabs-with-equal-width:not([orientation=vertical])) limel-scroller > div {
|
|
132
133
|
flex: 1 0 auto;
|
|
133
134
|
max-width: var(--tab-bar-horizontal-tab-max-width, none);
|
|
134
135
|
}
|
|
135
136
|
|
|
136
|
-
|
|
137
|
+
limel-scroller > div:has(limel-drag-handle:hover), limel-scroller > div:has(limel-drag-handle:focus-within), limel-scroller > div.is-elevated, limel-scroller > div.sortable-chosen {
|
|
138
|
+
will-change: transform, box-shadow, border-radius, background-color;
|
|
139
|
+
}
|
|
140
|
+
limel-scroller > div.sortable-ghost {
|
|
141
|
+
border-radius: 0.5rem;
|
|
142
|
+
box-shadow: var(--shadow-depth-64), 0 0.65rem 0.75rem -0.425rem rgb(var(--color-black), 0.3);
|
|
143
|
+
}
|
|
144
|
+
limel-scroller > div.sortable-chosen {
|
|
145
|
+
border-radius: 0.5rem;
|
|
146
|
+
background-color: var(--lime-elevated-surface-background-color);
|
|
147
|
+
}
|
|
148
|
+
limel-scroller > div.is-elevated[draggable=false] {
|
|
149
|
+
animation: sit-here 0.8s forwards;
|
|
150
|
+
}
|
|
151
|
+
@keyframes sit-here {
|
|
152
|
+
0% {
|
|
153
|
+
border-radius: 0.5rem;
|
|
154
|
+
background-color: var(--lime-elevated-surface-background-color);
|
|
155
|
+
box-shadow: var(--shadow-depth-64), 0 0.65rem 0.75rem -0.425rem rgb(var(--color-black), 0.3);
|
|
156
|
+
}
|
|
157
|
+
100% {
|
|
158
|
+
box-shadow: none;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
limel-scroller > div {
|
|
162
|
+
position: relative;
|
|
163
|
+
display: flex;
|
|
164
|
+
flex: 0 0 auto;
|
|
165
|
+
}
|
|
166
|
+
limel-scroller > div button[role=tab] {
|
|
167
|
+
flex: 1 1 auto;
|
|
168
|
+
min-width: 0;
|
|
169
|
+
}
|
|
170
|
+
limel-scroller > div span.content {
|
|
171
|
+
padding-right: 2rem;
|
|
172
|
+
}
|
|
173
|
+
limel-scroller > div limel-drag-handle {
|
|
174
|
+
position: absolute;
|
|
175
|
+
z-index: 3;
|
|
176
|
+
top: 0;
|
|
177
|
+
bottom: 0;
|
|
178
|
+
right: 0.25rem;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
button[role=tab] {
|
|
137
182
|
appearance: none;
|
|
138
183
|
background: none;
|
|
139
184
|
border: none;
|
|
@@ -156,34 +201,34 @@ button {
|
|
|
156
201
|
white-space: nowrap;
|
|
157
202
|
font-size: var(--limel-theme-default-font-size);
|
|
158
203
|
}
|
|
159
|
-
button limel-icon {
|
|
204
|
+
button[role=tab] limel-icon {
|
|
160
205
|
transition: color 0.2s ease;
|
|
161
206
|
color: rgb(var(--contrast-800));
|
|
162
207
|
margin-left: -0.25rem;
|
|
163
208
|
flex-shrink: 0;
|
|
164
209
|
}
|
|
165
|
-
button span.text {
|
|
210
|
+
button[role=tab] span.text {
|
|
166
211
|
transition: color 0.2s ease;
|
|
167
212
|
line-height: 1.25;
|
|
168
213
|
overflow: hidden;
|
|
169
214
|
text-overflow: ellipsis;
|
|
170
215
|
color: var(--limel-theme-on-surface-color);
|
|
171
216
|
}
|
|
172
|
-
button:hover span.text {
|
|
217
|
+
button[role=tab]:hover span.text {
|
|
173
218
|
color: var(--limel-theme-text-primary-on-background-color);
|
|
174
219
|
}
|
|
175
|
-
button limel-badge {
|
|
220
|
+
button[role=tab] limel-badge {
|
|
176
221
|
margin-right: -0.25rem;
|
|
177
222
|
box-shadow: 0 0 0 1px rgb(var(--contrast-600));
|
|
178
223
|
pointer-events: none;
|
|
179
224
|
flex-shrink: 0;
|
|
180
225
|
}
|
|
181
226
|
|
|
182
|
-
button[aria-selected=true] {
|
|
227
|
+
button[role=tab][aria-selected=true] {
|
|
183
228
|
background-color: var(--limel-active-tab-background-color);
|
|
184
229
|
z-index: 2;
|
|
185
230
|
}
|
|
186
|
-
button[aria-selected=true]:before, button[aria-selected=true]:after {
|
|
231
|
+
button[role=tab][aria-selected=true]:before, button[role=tab][aria-selected=true]:after {
|
|
187
232
|
content: "";
|
|
188
233
|
display: block;
|
|
189
234
|
width: var(--limel-tab-active-outer-edge-curve-size);
|
|
@@ -193,10 +238,10 @@ button[aria-selected=true]:before, button[aria-selected=true]:after {
|
|
|
193
238
|
-webkit-mask-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20fill-rule='evenodd'%20stroke-linejoin='round'%20stroke-miterlimit='2'%20clip-rule='evenodd'%20viewBox='0%200%2050%2050'%3E%3Cdefs/%3E%3Cpath%20d='M0%200c0%2027.594%2022.406%2050%2050%2050H0V0z'/%3E%3C/svg%3E");
|
|
194
239
|
mask-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20fill-rule='evenodd'%20stroke-linejoin='round'%20stroke-miterlimit='2'%20clip-rule='evenodd'%20viewBox='0%200%2050%2050'%3E%3Cdefs/%3E%3Cpath%20d='M0%200c0%2027.594%2022.406%2050%2050%2050H0V0z'/%3E%3C/svg%3E");
|
|
195
240
|
}
|
|
196
|
-
button[aria-selected=true] limel-icon {
|
|
241
|
+
button[role=tab][aria-selected=true] limel-icon {
|
|
197
242
|
color: var(--limel-active-tab-color);
|
|
198
243
|
}
|
|
199
|
-
button[aria-selected=true] span.text {
|
|
244
|
+
button[role=tab][aria-selected=true] span.text {
|
|
200
245
|
color: var(--limel-active-tab-color);
|
|
201
246
|
}
|
|
202
247
|
|
|
@@ -211,15 +256,15 @@ span.content {
|
|
|
211
256
|
padding: 0 0.75rem;
|
|
212
257
|
border-radius: calc(var(--limel-tab-border-radius) - var(--limel-tab-content-inset));
|
|
213
258
|
}
|
|
214
|
-
button:focus-visible span.content {
|
|
259
|
+
button[role=tab]:focus-visible span.content {
|
|
215
260
|
transition-duration: 0.3s;
|
|
216
261
|
box-shadow: var(--shadow-depth-8-focused);
|
|
217
262
|
}
|
|
218
263
|
|
|
219
|
-
:host(limel-tab-bar:not([orientation=vertical])) button {
|
|
264
|
+
:host(limel-tab-bar:not([orientation=vertical])) button[role=tab] {
|
|
220
265
|
max-width: var(--tab-bar-horizontal-tab-max-width, 16rem);
|
|
221
266
|
}
|
|
222
|
-
:host(limel-tab-bar:not([orientation=vertical])) button:not([aria-selected=true]):after {
|
|
267
|
+
:host(limel-tab-bar:not([orientation=vertical])) button[role=tab]:not([aria-selected=true]):after {
|
|
223
268
|
content: "";
|
|
224
269
|
display: block;
|
|
225
270
|
background-color: var(--limel-tab-separator-background-color);
|
|
@@ -232,20 +277,21 @@ button:focus-visible span.content {
|
|
|
232
277
|
border-radius: 1rem;
|
|
233
278
|
right: calc(-1 * var(--limel-tab-separator-width));
|
|
234
279
|
}
|
|
235
|
-
:host(limel-tab-bar:not([orientation=vertical]))
|
|
280
|
+
:host(limel-tab-bar:not([orientation=vertical])) limel-scroller > :last-child:not([aria-selected=true]):after,
|
|
281
|
+
:host(limel-tab-bar:not([orientation=vertical])) limel-scroller > :last-child > button[role=tab]:not([aria-selected=true]):after {
|
|
236
282
|
display: none;
|
|
237
283
|
}
|
|
238
|
-
:host(limel-tab-bar:not([orientation=vertical])) button[aria-selected=true] {
|
|
284
|
+
:host(limel-tab-bar:not([orientation=vertical])) button[role=tab][aria-selected=true] {
|
|
239
285
|
border-radius: var(--limel-tab-border-radius) var(--limel-tab-border-radius) 0 0;
|
|
240
286
|
}
|
|
241
|
-
:host(limel-tab-bar:not([orientation=vertical])) button[aria-selected=true]:before, :host(limel-tab-bar:not([orientation=vertical])) button[aria-selected=true]:after {
|
|
287
|
+
:host(limel-tab-bar:not([orientation=vertical])) button[role=tab][aria-selected=true]:before, :host(limel-tab-bar:not([orientation=vertical])) button[role=tab][aria-selected=true]:after {
|
|
242
288
|
bottom: 0;
|
|
243
289
|
}
|
|
244
|
-
:host(limel-tab-bar:not([orientation=vertical])) button[aria-selected=true]:before {
|
|
290
|
+
:host(limel-tab-bar:not([orientation=vertical])) button[role=tab][aria-selected=true]:before {
|
|
245
291
|
left: calc(-1 * var(--limel-tab-active-outer-edge-curve-size));
|
|
246
292
|
transform: rotateY(180deg);
|
|
247
293
|
}
|
|
248
|
-
:host(limel-tab-bar:not([orientation=vertical])) button[aria-selected=true]:after {
|
|
294
|
+
:host(limel-tab-bar:not([orientation=vertical])) button[role=tab][aria-selected=true]:after {
|
|
249
295
|
right: calc(-1 * var(--limel-tab-active-outer-edge-curve-size));
|
|
250
296
|
}
|
|
251
297
|
|
|
@@ -262,17 +308,17 @@ button:focus-visible span.content {
|
|
|
262
308
|
0 var(--limel-tab-active-outer-edge-curve-size) 0.25rem;
|
|
263
309
|
height: 100%;
|
|
264
310
|
}
|
|
265
|
-
:host(limel-tab-bar[orientation=vertical]) button[aria-selected=true] {
|
|
311
|
+
:host(limel-tab-bar[orientation=vertical]) button[role=tab][aria-selected=true] {
|
|
266
312
|
border-radius: var(--limel-tab-border-radius) 0 0 var(--limel-tab-border-radius);
|
|
267
313
|
}
|
|
268
|
-
:host(limel-tab-bar[orientation=vertical]) button[aria-selected=true]:before, :host(limel-tab-bar[orientation=vertical]) button[aria-selected=true]:after {
|
|
314
|
+
:host(limel-tab-bar[orientation=vertical]) button[role=tab][aria-selected=true]:before, :host(limel-tab-bar[orientation=vertical]) button[role=tab][aria-selected=true]:after {
|
|
269
315
|
right: 0;
|
|
270
316
|
}
|
|
271
|
-
:host(limel-tab-bar[orientation=vertical]) button[aria-selected=true]:before {
|
|
317
|
+
:host(limel-tab-bar[orientation=vertical]) button[role=tab][aria-selected=true]:before {
|
|
272
318
|
bottom: 100%;
|
|
273
319
|
transform: rotateY(180deg);
|
|
274
320
|
}
|
|
275
|
-
:host(limel-tab-bar[orientation=vertical]) button[aria-selected=true]:after {
|
|
321
|
+
:host(limel-tab-bar[orientation=vertical]) button[role=tab][aria-selected=true]:after {
|
|
276
322
|
top: 100%;
|
|
277
323
|
transform: rotate(180deg);
|
|
278
324
|
}
|