@kubex/zinc 1.1.138 → 1.1.140
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/dist/custom-elements.json +700 -590
- package/dist/vscode.html-custom-data.json +81 -81
- package/dist/web-types.json +160 -160
- package/dist/zn.d.ts +23 -6
- package/dist/zn.min.js +434 -415
- package/package.json +1 -1
- package/src/components/collapsible/collapsible.scss +10 -2
- package/src/components/filter-container/filter-container.component.ts +3 -6
- package/src/components/flow-builder/flow-layout.ts +1 -1
- package/src/components/flow-builder/modules/flow-canvas/flow-canvas.component.ts +1 -1
- package/src/components/header/header.component.ts +1 -1
- package/src/components/icon-picker/icon-picker.component.ts +6 -18
- package/src/components/input/input.component.ts +4 -2
- package/src/components/menu-item/submenu-controller.ts +7 -7
- package/src/components/page-builder/page-builder.component.ts +120 -2
- package/src/components/page-builder/page-builder.scss +22 -0
- package/src/components/page-builder/page.types.ts +20 -0
- package/src/components/query-builder/query-builder.component.ts +2 -2
- package/src/components/sidebar/sidebar.component.ts +3 -3
- package/src/components/slideout/slideout.component.ts +2 -2
- package/src/components/stat/stat.component.ts +3 -3
- package/src/components/stepper/stepper.component.ts +1 -1
- package/src/internal/form.ts +2 -2
- package/src/internal/zinc-element.ts +1 -1
- /package/src/components/hover-container/{hover-container.ts → hover-container.test.ts} +0 -0
package/package.json
CHANGED
|
@@ -79,6 +79,11 @@
|
|
|
79
79
|
// Height animates via grid-template-rows 0fr -> 1fr; the inline padding is
|
|
80
80
|
// constant so the content never reflows (and re-wraps) mid-transition.
|
|
81
81
|
.content {
|
|
82
|
+
// Padding counts toward a grid item's minimum contribution, so a 0fr track
|
|
83
|
+
// cannot collapse below it and a closed panel would keep the padding's
|
|
84
|
+
// height. Held at zero here and transitioned in with the row.
|
|
85
|
+
--content-block-padding: 0px;
|
|
86
|
+
|
|
82
87
|
display: grid;
|
|
83
88
|
// minmax(0, 1fr), not the implicit auto track: auto floors the column at the
|
|
84
89
|
// content's min-content width, so nowrap children overflow the host.
|
|
@@ -90,9 +95,10 @@
|
|
|
90
95
|
|
|
91
96
|
&__inner {
|
|
92
97
|
min-height: 0;
|
|
93
|
-
padding: 0 var(--zn-spacing-medium) var(--
|
|
98
|
+
padding: 0 var(--zn-spacing-medium) var(--content-block-padding);
|
|
94
99
|
transform: translateY(-4px);
|
|
95
|
-
transition: transform var(--zn-transition-medium) cubic-bezier(0.32, 0.72, 0, 1)
|
|
100
|
+
transition: transform var(--zn-transition-medium) cubic-bezier(0.32, 0.72, 0, 1),
|
|
101
|
+
padding-bottom var(--zn-transition-medium) cubic-bezier(0.32, 0.72, 0, 1);
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
&--flush &__inner {
|
|
@@ -108,6 +114,8 @@
|
|
|
108
114
|
}
|
|
109
115
|
|
|
110
116
|
:host([expanded]) .content {
|
|
117
|
+
--content-block-padding: var(--zn-spacing-medium);
|
|
118
|
+
|
|
111
119
|
grid-template-rows: 1fr;
|
|
112
120
|
opacity: 1;
|
|
113
121
|
|
|
@@ -84,7 +84,7 @@ export default class ZnFilterContainer extends ZincElement {
|
|
|
84
84
|
return (el as HTMLElement).style.display !== 'none';
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
let noResultsMessage = this.querySelector('.no-results-message')
|
|
87
|
+
let noResultsMessage = this.querySelector<HTMLElement>('.no-results-message');
|
|
88
88
|
if (!anyVisibleElements) {
|
|
89
89
|
if (!noResultsMessage) {
|
|
90
90
|
noResultsMessage = document.createElement('div');
|
|
@@ -93,12 +93,9 @@ export default class ZnFilterContainer extends ZincElement {
|
|
|
93
93
|
this.appendChild(noResultsMessage);
|
|
94
94
|
}
|
|
95
95
|
noResultsMessage.style.display = '';
|
|
96
|
-
} else {
|
|
97
|
-
|
|
98
|
-
noResultsMessage.style.display = 'none';
|
|
99
|
-
}
|
|
96
|
+
} else if (noResultsMessage) {
|
|
97
|
+
noResultsMessage.style.display = 'none';
|
|
100
98
|
}
|
|
101
|
-
|
|
102
99
|
}
|
|
103
100
|
|
|
104
101
|
render() {
|
|
@@ -156,7 +156,7 @@ export function untangledPositions(
|
|
|
156
156
|
nodes.forEach(n => {
|
|
157
157
|
const raw = xs.get(n.id);
|
|
158
158
|
out.set(n.id, {
|
|
159
|
-
x: snapToGrid(Number.isFinite(raw) ?
|
|
159
|
+
x: snapToGrid(Number.isFinite(raw) ? raw! - minX + MARGIN : MARGIN),
|
|
160
160
|
y: MARGIN + layerOf.get(n.id)! * LAYOUT_V_GAP,
|
|
161
161
|
});
|
|
162
162
|
});
|
|
@@ -1089,7 +1089,7 @@ export default class ZnFlowCanvas extends ZincElement {
|
|
|
1089
1089
|
const src = this.nodes.find(n => n.id === this._linking!.nodeId);
|
|
1090
1090
|
if (src) {
|
|
1091
1091
|
const branch = this._outputLayout(src).branches.find(b => b.port.id === this._linking!.port);
|
|
1092
|
-
const from = branch && branch.pillTop !== null
|
|
1092
|
+
const from = branch !== undefined && branch.pillTop !== null
|
|
1093
1093
|
? {x: branch.x, y: branch.exitY}
|
|
1094
1094
|
: {x: src.x + NODE_WIDTH / 2, y: src.y + NODE_HEIGHT};
|
|
1095
1095
|
const target = this._linkTarget ? this.nodes.find(n => n.id === this._linkTarget) : undefined;
|
|
@@ -4,7 +4,7 @@ import {HasSlotController} from "../../internal/slot";
|
|
|
4
4
|
import {property} from 'lit/decorators.js';
|
|
5
5
|
import {watch} from "../../internal/watch";
|
|
6
6
|
import ZincElement from '../../internal/zinc-element';
|
|
7
|
-
import ZnNavbar from "../navbar";
|
|
7
|
+
import type ZnNavbar from "../navbar";
|
|
8
8
|
|
|
9
9
|
import styles from './header.scss';
|
|
10
10
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {classMap} from 'lit/directives/class-map.js';
|
|
2
2
|
import {type CSSResultGroup, html, nothing, type PropertyValues, unsafeCSS} from 'lit';
|
|
3
3
|
import {defaultValue} from '../../internal/default-value';
|
|
4
|
-
import {FormControlController} from '../../internal/form';
|
|
4
|
+
import {FormControlController, validValidityState, valueMissingValidityState} from '../../internal/form';
|
|
5
5
|
import {property, query, state} from 'lit/decorators.js';
|
|
6
6
|
import ZincElement from '../../internal/zinc-element';
|
|
7
7
|
import ZnButton from '../button';
|
|
@@ -95,20 +95,7 @@ export default class ZnIconPicker extends ZincElement implements ZincFormControl
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
get validity(): ValidityState {
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
valid: false,
|
|
101
|
-
valueMissing: true,
|
|
102
|
-
badInput: false, customError: false, patternMismatch: false,
|
|
103
|
-
rangeOverflow: false, rangeUnderflow: false, stepMismatch: false,
|
|
104
|
-
tooLong: false, tooShort: false, typeMismatch: false,
|
|
105
|
-
} as ValidityState;
|
|
106
|
-
}
|
|
107
|
-
return {
|
|
108
|
-
valid: true, valueMissing: false, badInput: false, customError: false,
|
|
109
|
-
patternMismatch: false, rangeOverflow: false, rangeUnderflow: false,
|
|
110
|
-
stepMismatch: false, tooLong: false, tooShort: false, typeMismatch: false,
|
|
111
|
-
} as ValidityState;
|
|
98
|
+
return this.required && !this.icon && !this._file ? valueMissingValidityState : validValidityState;
|
|
112
99
|
}
|
|
113
100
|
|
|
114
101
|
get validationMessage(): string {
|
|
@@ -118,6 +105,7 @@ export default class ZnIconPicker extends ZincElement implements ZincFormControl
|
|
|
118
105
|
checkValidity(): boolean { return this.validity.valid; }
|
|
119
106
|
getForm(): HTMLFormElement | null { return this.formControlController.getForm(); }
|
|
120
107
|
reportValidity(): boolean { return this.checkValidity(); }
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
121
109
|
setCustomValidity(_message: string) { this.formControlController.updateValidity(); }
|
|
122
110
|
|
|
123
111
|
private static readonly freeInputLibraries = new Set(['gravatar', 'libravatar', 'avatar']);
|
|
@@ -313,7 +301,7 @@ export default class ZnIconPicker extends ZincElement implements ZincFormControl
|
|
|
313
301
|
|
|
314
302
|
private handleColorInput(e: Event) {
|
|
315
303
|
const input = e.target as ZnInput;
|
|
316
|
-
this._pendingColor = input.value;
|
|
304
|
+
this._pendingColor = String(input.value);
|
|
317
305
|
}
|
|
318
306
|
|
|
319
307
|
private handleFreeInput(e: Event) {
|
|
@@ -428,14 +416,14 @@ export default class ZnIconPicker extends ZincElement implements ZincFormControl
|
|
|
428
416
|
size="small"
|
|
429
417
|
color=${this._mode === 'icon' ? 'secondary' : 'transparent'}
|
|
430
418
|
icon="apps"
|
|
431
|
-
@click=${() => this._mode = 'icon'}>
|
|
419
|
+
@click=${() => { this._mode = 'icon'; }}>
|
|
432
420
|
Icon Library
|
|
433
421
|
</zn-button>
|
|
434
422
|
<zn-button
|
|
435
423
|
size="small"
|
|
436
424
|
color=${this._mode === 'upload' ? 'secondary' : 'transparent'}
|
|
437
425
|
icon="upload"
|
|
438
|
-
@click=${() => this._mode = 'upload'}>
|
|
426
|
+
@click=${() => { this._mode = 'upload'; }}>
|
|
439
427
|
Upload Image
|
|
440
428
|
</zn-button>
|
|
441
429
|
</div>
|
|
@@ -508,7 +508,9 @@ export default class ZnInput extends ZincElement implements ZincFormControl {
|
|
|
508
508
|
let g: number;
|
|
509
509
|
let b: number;
|
|
510
510
|
if (s === 0) {
|
|
511
|
-
r =
|
|
511
|
+
r = l;
|
|
512
|
+
g = l;
|
|
513
|
+
b = l;
|
|
512
514
|
} else {
|
|
513
515
|
const hue2rgb = (p: number, q: number, t: number) => {
|
|
514
516
|
if (t < 0) t += 1;
|
|
@@ -831,7 +833,7 @@ export default class ZnInput extends ZincElement implements ZincFormControl {
|
|
|
831
833
|
}
|
|
832
834
|
|
|
833
835
|
@watch('colorFormat', {waitUntilFirstUpdate: true})
|
|
834
|
-
|
|
836
|
+
handleColorFormatChange() {
|
|
835
837
|
// When color format changes, convert the current value to the new format
|
|
836
838
|
if (this.type === 'color' && this.value) {
|
|
837
839
|
const hexValue = this.convertToHex(this.value);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
1
|
+
import {createRef, ref, type Ref} from 'lit/directives/ref.js';
|
|
2
|
+
import {type HasSlotController} from '../../internal/slot.js';
|
|
3
|
+
import {html} from 'lit';
|
|
4
|
+
import {type LocalizeController} from '../../utilities/localize.js';
|
|
5
|
+
import type {ReactiveController, ReactiveControllerHost} from 'lit';
|
|
6
6
|
import type ZnMenuItem from '../menu-item';
|
|
7
7
|
import type ZnPopup from '../popup';
|
|
8
8
|
|
|
@@ -201,14 +201,14 @@ export class SubmenuController implements ReactiveController {
|
|
|
201
201
|
// Set the safe triangle values for the submenu when the position changes
|
|
202
202
|
private handlePopupReposition = () => {
|
|
203
203
|
const submenuSlot: HTMLSlotElement | null = this.host.renderRoot.querySelector("slot[name='submenu']");
|
|
204
|
-
const menu = submenuSlot?.assignedElements({
|
|
204
|
+
const menu = submenuSlot?.assignedElements({flatten: true}).filter(el => el.localName === 'zn-menu')[0];
|
|
205
205
|
const isRtl = this.localize.dir() === 'rtl';
|
|
206
206
|
|
|
207
207
|
if (!menu) {
|
|
208
208
|
return;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
const {
|
|
211
|
+
const {left, top, width, height} = menu.getBoundingClientRect();
|
|
212
212
|
|
|
213
213
|
this.host.style.setProperty('--safe-triangle-submenu-start-x', `${isRtl ? left + width : left}px`);
|
|
214
214
|
this.host.style.setProperty('--safe-triangle-submenu-start-y', `${top}px`);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type CSSResultGroup, html, type PropertyValues, unsafeCSS } from 'lit';
|
|
2
2
|
import {
|
|
3
|
+
emptyDragImage,
|
|
3
4
|
emptyPageState,
|
|
4
5
|
generateSectionId,
|
|
5
6
|
MAX_SLOTS,
|
|
@@ -149,6 +150,8 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
149
150
|
/** Index of the drop zone whose "+" type picker is open, if any. */
|
|
150
151
|
@state() private _pickerIndex: number | null = null;
|
|
151
152
|
@state() private _dragOverIndex: number | null = null;
|
|
153
|
+
@state() private _draggingId: string | null = null;
|
|
154
|
+
@state() private _dragGhost: { section: PageSection } | { type: PageSectionType } | null = null;
|
|
152
155
|
/** The container slot a drag is currently over, if any. */
|
|
153
156
|
@state() private _slotDragOver: { containerId: string; index: number } | null = null;
|
|
154
157
|
/** The container slot whose "+" type picker is open, if any. */
|
|
@@ -277,11 +280,13 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
277
280
|
|
|
278
281
|
connectedCallback() {
|
|
279
282
|
super.connectedCallback();
|
|
283
|
+
emptyDragImage(); // decoded up front, before a drag can ask for it
|
|
280
284
|
this._registerSlottedTemplates();
|
|
281
285
|
this._resizeObserver.observe(this);
|
|
282
286
|
}
|
|
283
287
|
|
|
284
288
|
disconnectedCallback() {
|
|
289
|
+
this._endGhost();
|
|
285
290
|
this._resizeObserver.disconnect();
|
|
286
291
|
this._stopAutoSave();
|
|
287
292
|
if (this._justSavedTimer !== null) {
|
|
@@ -820,6 +825,111 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
820
825
|
e.stopPropagation(); // a child card's drag must not also start its container's
|
|
821
826
|
e.dataTransfer.setData(PAGE_SECTION_MIME, id);
|
|
822
827
|
e.dataTransfer.effectAllowed = 'move';
|
|
828
|
+
const section = this._findSection(id);
|
|
829
|
+
if (section) this._startGhost(e, { section });
|
|
830
|
+
// Deferred: pulling the source out of the flow during the dragstart handler
|
|
831
|
+
// aborts the drag.
|
|
832
|
+
setTimeout(() => (this._draggingId = id));
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
// --- Drag ghost ---------------------------------------------------------------
|
|
836
|
+
// The browser's own drag image is a snapshot composited onto an opaque
|
|
837
|
+
// surface, so everything the card leaves transparent outside its 8px radius
|
|
838
|
+
// comes back as square white corners — not something the page can style away.
|
|
839
|
+
// The builder suppresses it and moves a real card of its own instead.
|
|
840
|
+
|
|
841
|
+
private _ghostEl: HTMLElement | null = null;
|
|
842
|
+
/** Where in the card the pointer grabbed it, so the ghost keeps that grip. */
|
|
843
|
+
private _ghostGrip = { x: 0, y: 0 };
|
|
844
|
+
/** The host's viewport origin; the ghost is positioned against the host. */
|
|
845
|
+
private _ghostOrigin = { x: 0, y: 0 };
|
|
846
|
+
|
|
847
|
+
private _startGhost(e: DragEvent, ghost: NonNullable<typeof this._dragGhost>) {
|
|
848
|
+
if (!e.dataTransfer) return;
|
|
849
|
+
const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
|
|
850
|
+
const host = this.getBoundingClientRect();
|
|
851
|
+
this._ghostGrip = { x: e.clientX - rect.left, y: e.clientY - rect.top };
|
|
852
|
+
this._ghostOrigin = { x: host.left, y: host.top };
|
|
853
|
+
this._dragGhost = ghost;
|
|
854
|
+
e.dataTransfer.setDragImage(emptyDragImage(), 0, 0);
|
|
855
|
+
// dragover is stopped short by the zone handlers, so listen at the document
|
|
856
|
+
// in capture: the ghost has to track the pointer wherever it goes.
|
|
857
|
+
document.addEventListener('dragover', this._onGhostDragOver, true);
|
|
858
|
+
document.addEventListener('drop', this._onGhostDrop, true);
|
|
859
|
+
document.addEventListener('dragleave', this._onGhostDragLeave, true);
|
|
860
|
+
void this.updateComplete.then(() => {
|
|
861
|
+
this._ghostEl = this.shadowRoot?.querySelector<HTMLElement>('.drag-ghost') ?? null;
|
|
862
|
+
if (!this._ghostEl) return;
|
|
863
|
+
this._ghostEl.style.width = `${rect.width}px`;
|
|
864
|
+
this._moveGhost(e.clientX, e.clientY);
|
|
865
|
+
});
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
private _onGhostDragOver = (e: DragEvent) => {
|
|
869
|
+
// Holds the whole document open as a drop target for the length of our own
|
|
870
|
+
// drag. Only the canvas calls preventDefault, so anywhere else the drag has
|
|
871
|
+
// no target and the OS drag session stalls for seconds hunting for one.
|
|
872
|
+
e.preventDefault();
|
|
873
|
+
// The last dragover of a cancelled drag reports 0,0 — it would fling the
|
|
874
|
+
// ghost into the corner for the frame before dragend clears it.
|
|
875
|
+
if (e.clientX === 0 && e.clientY === 0) return;
|
|
876
|
+
this._moveGhost(e.clientX, e.clientY);
|
|
877
|
+
};
|
|
878
|
+
|
|
879
|
+
// Follows from holding the document open above: a release outside the canvas
|
|
880
|
+
// would otherwise be left to the browser's default handling of the payload.
|
|
881
|
+
private _onGhostDrop = (e: DragEvent) => e.preventDefault();
|
|
882
|
+
|
|
883
|
+
// A null relatedTarget means the pointer left the window, where no dragover
|
|
884
|
+
// reaches us — the ghost would sit frozen wherever it was. The OS carries the
|
|
885
|
+
// drag from here; the ghost comes back on the first dragover on re-entry.
|
|
886
|
+
private _onGhostDragLeave = (e: DragEvent) => {
|
|
887
|
+
if (e.relatedTarget === null && this._ghostEl) this._ghostEl.style.visibility = 'hidden';
|
|
888
|
+
};
|
|
889
|
+
|
|
890
|
+
private _moveGhost(clientX: number, clientY: number) {
|
|
891
|
+
if (!this._ghostEl) return;
|
|
892
|
+
this._ghostEl.style.visibility = '';
|
|
893
|
+
const x = clientX - this._ghostOrigin.x - this._ghostGrip.x;
|
|
894
|
+
const y = clientY - this._ghostOrigin.y - this._ghostGrip.y;
|
|
895
|
+
this._ghostEl.style.transform = `translate(${x}px, ${y}px)`;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
private _endGhost() {
|
|
899
|
+
document.removeEventListener('dragover', this._onGhostDragOver, true);
|
|
900
|
+
document.removeEventListener('drop', this._onGhostDrop, true);
|
|
901
|
+
document.removeEventListener('dragleave', this._onGhostDragLeave, true);
|
|
902
|
+
this._ghostEl = null;
|
|
903
|
+
this._dragGhost = null;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
private _renderDragGhost() {
|
|
907
|
+
const ghost = this._dragGhost;
|
|
908
|
+
if (!ghost) return '';
|
|
909
|
+
if ('type' in ghost) {
|
|
910
|
+
const t = ghost.type;
|
|
911
|
+
return html`
|
|
912
|
+
<zn-page-palette-item
|
|
913
|
+
class="drag-ghost"
|
|
914
|
+
type="${t.type}"
|
|
915
|
+
label="${t.label}"
|
|
916
|
+
description="${ifDefined(t.description)}"
|
|
917
|
+
icon="${ifDefined(t.icon)}"
|
|
918
|
+
icon-library="${ifDefined(t.iconLibrary)}"
|
|
919
|
+
color="${ifDefined(t.color)}"></zn-page-palette-item>`;
|
|
920
|
+
}
|
|
921
|
+
const section = ghost.section;
|
|
922
|
+
const type = this.registry.get(section.type);
|
|
923
|
+
return html`
|
|
924
|
+
<zn-page-section-card
|
|
925
|
+
class="drag-ghost"
|
|
926
|
+
label="${section.label ?? type?.label ?? section.type}"
|
|
927
|
+
summary="${type ? sectionSummary(section, type) : `Unknown type "${section.type}"`}"
|
|
928
|
+
icon="${ifDefined(type?.icon)}"
|
|
929
|
+
icon-library="${ifDefined(type?.iconLibrary)}"
|
|
930
|
+
color="${ifDefined(type?.color)}"
|
|
931
|
+
?unknown="${!type}"
|
|
932
|
+
?locked="${this._isPinned(section.id)}"></zn-page-section-card>`;
|
|
823
933
|
}
|
|
824
934
|
|
|
825
935
|
/** Whether a drag carries one of the builder's own payloads. */
|
|
@@ -840,6 +950,8 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
840
950
|
e.preventDefault();
|
|
841
951
|
e.stopPropagation();
|
|
842
952
|
this._slotDragOver = null;
|
|
953
|
+
this._draggingId = null;
|
|
954
|
+
this._endGhost();
|
|
843
955
|
const typeKey = e.dataTransfer?.getData(PAGE_TYPE_MIME);
|
|
844
956
|
const sectionId = e.dataTransfer?.getData(PAGE_SECTION_MIME);
|
|
845
957
|
if (typeKey) this.addSectionToSlot(typeKey, containerId, index);
|
|
@@ -857,6 +969,8 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
857
969
|
e.preventDefault();
|
|
858
970
|
e.stopPropagation();
|
|
859
971
|
this._dragOverIndex = null;
|
|
972
|
+
this._draggingId = null;
|
|
973
|
+
this._endGhost();
|
|
860
974
|
const typeKey = e.dataTransfer?.getData(PAGE_TYPE_MIME);
|
|
861
975
|
const sectionId = e.dataTransfer?.getData(PAGE_SECTION_MIME);
|
|
862
976
|
if (typeKey) this.addSection(typeKey, index);
|
|
@@ -924,6 +1038,7 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
924
1038
|
private _renderPaletteItem(type: PageSectionType) {
|
|
925
1039
|
return html`
|
|
926
1040
|
<zn-page-palette-item
|
|
1041
|
+
@dragstart="${(e: DragEvent) => this._startGhost(e, { type })}"
|
|
927
1042
|
type="${type.type}"
|
|
928
1043
|
label="${type.label}"
|
|
929
1044
|
description="${ifDefined(type.description)}"
|
|
@@ -1018,7 +1133,7 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
1018
1133
|
const pinned = this._isPinned(section.id);
|
|
1019
1134
|
return html`
|
|
1020
1135
|
<zn-page-section-card
|
|
1021
|
-
class="${extraClass}"
|
|
1136
|
+
class="${extraClass} ${this._draggingId === section.id ? 'dragging' : ''}"
|
|
1022
1137
|
data-id="${section.id}"
|
|
1023
1138
|
draggable="${pinned ? 'false' : 'true'}"
|
|
1024
1139
|
tabindex="0"
|
|
@@ -1050,7 +1165,7 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
1050
1165
|
});
|
|
1051
1166
|
if (!type?.slots) return card;
|
|
1052
1167
|
return html`
|
|
1053
|
-
<div class="container">
|
|
1168
|
+
<div class="container ${this._draggingId === section.id ? 'container--dragging' : ''}">
|
|
1054
1169
|
${card}
|
|
1055
1170
|
<div class="slots" style="--pb-slot-columns:${slotColumns(section, type)}">
|
|
1056
1171
|
${sectionChildren(section, type).map((child, i) => this._renderSlot(section, child, i))}
|
|
@@ -1290,6 +1405,8 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
1290
1405
|
@dragend="${() => {
|
|
1291
1406
|
this._dragOverIndex = null;
|
|
1292
1407
|
this._slotDragOver = null;
|
|
1408
|
+
this._draggingId = null;
|
|
1409
|
+
this._endGhost();
|
|
1293
1410
|
}}">
|
|
1294
1411
|
<header part="header" class="header" ?hidden="${!hasHeader}">
|
|
1295
1412
|
<div class="header__group">
|
|
@@ -1304,6 +1421,7 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
1304
1421
|
${this._renderInspector()}
|
|
1305
1422
|
<slot name="config" class="declarations" @slotchange="${this._registerSlottedTemplates}"></slot>
|
|
1306
1423
|
</div>
|
|
1424
|
+
${this._renderDragGhost()}
|
|
1307
1425
|
`;
|
|
1308
1426
|
}
|
|
1309
1427
|
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
--pb-card-width: 1024px;
|
|
9
9
|
|
|
10
10
|
display: block;
|
|
11
|
+
position: relative; // anchors the drag ghost
|
|
11
12
|
width: 100%;
|
|
12
13
|
height: 100%;
|
|
13
14
|
min-height: 480px;
|
|
@@ -496,6 +497,14 @@ zn-page-palette-item {
|
|
|
496
497
|
}
|
|
497
498
|
}
|
|
498
499
|
|
|
500
|
+
// Out of the flow while its drag ghost stands in: the canvas would otherwise
|
|
501
|
+
// hold the card's height *and* the expanded drop placeholder, growing the page
|
|
502
|
+
// by a placeholder's worth for the length of every drag.
|
|
503
|
+
zn-page-section-card.dragging,
|
|
504
|
+
.container--dragging {
|
|
505
|
+
display: none;
|
|
506
|
+
}
|
|
507
|
+
|
|
499
508
|
// A container section: its card spans the row with a grid of child slots below.
|
|
500
509
|
.container {
|
|
501
510
|
width: 100%;
|
|
@@ -649,3 +658,16 @@ zn-page-palette-item {
|
|
|
649
658
|
}
|
|
650
659
|
}
|
|
651
660
|
}
|
|
661
|
+
|
|
662
|
+
// The builder's own drag image, moved by hand against the host. It sits outside
|
|
663
|
+
// .builder so that panel's overflow clip can't cut it, and draws its shadow with
|
|
664
|
+
// a filter so the falloff follows the card's rounded corners rather than its box.
|
|
665
|
+
.drag-ghost {
|
|
666
|
+
position: absolute;
|
|
667
|
+
top: 0;
|
|
668
|
+
left: 0;
|
|
669
|
+
z-index: 10;
|
|
670
|
+
opacity: 0.9;
|
|
671
|
+
pointer-events: none;
|
|
672
|
+
filter: drop-shadow(0 6px 16px rgba(var(--zn-shadow), 0.35));
|
|
673
|
+
}
|
|
@@ -129,3 +129,23 @@ export function sectionSummary(section: PageSection, type?: PageSectionType): st
|
|
|
129
129
|
}
|
|
130
130
|
return strings[0]?.[1] ?? type?.description ?? '';
|
|
131
131
|
}
|
|
132
|
+
|
|
133
|
+
let _emptyDragImage: HTMLImageElement | undefined;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* A cached 1×1 transparent image for `dataTransfer.setDragImage()`. The browser
|
|
137
|
+
* composites its own snapshot of the dragged node onto an opaque surface, which
|
|
138
|
+
* squares off a card's rounded corners; the builder draws its own ghost instead.
|
|
139
|
+
*/
|
|
140
|
+
export function emptyDragImage(): HTMLImageElement {
|
|
141
|
+
if (!_emptyDragImage) {
|
|
142
|
+
_emptyDragImage = new Image();
|
|
143
|
+
_emptyDragImage.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
|
144
|
+
// `complete` goes true synchronously for a data URL but the bitmap is not
|
|
145
|
+
// decoded yet, and a drag image the compositor has never rasterized is
|
|
146
|
+
// dropped in favor of the browser's own — a globe icon dragged alongside
|
|
147
|
+
// the builder's ghost, on the first drag only
|
|
148
|
+
void _emptyDragImage.decode().catch(() => undefined);
|
|
149
|
+
}
|
|
150
|
+
return _emptyDragImage;
|
|
151
|
+
}
|
|
@@ -201,7 +201,7 @@ export default class ZnQueryBuilder extends ZincElement implements ZincFormContr
|
|
|
201
201
|
size="medium"
|
|
202
202
|
placeholder="Select Filter"
|
|
203
203
|
@zn-change="${this._addRule}">
|
|
204
|
-
${this.filters
|
|
204
|
+
${this.filters?.filter(item => !this._usedFilterIds.has(item.id)).map(item => html`
|
|
205
205
|
<zn-option value="${item.id}">
|
|
206
206
|
${item.name.charAt(0).toUpperCase() + item.name.slice(1)}
|
|
207
207
|
</zn-option>`)}
|
|
@@ -460,7 +460,7 @@ export default class ZnQueryBuilder extends ZincElement implements ZincFormContr
|
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
private _updateDateValue(id: string, event: Event | {
|
|
463
|
-
target: ZnDatepicker | HTMLDivElement
|
|
463
|
+
target: ZnDatepicker | HTMLDivElement;
|
|
464
464
|
}, submitFormat: QueryBuilderDateSubmitFormat = 'legacy') {
|
|
465
465
|
const filter = this._selectedRules.get(id);
|
|
466
466
|
if (!filter) return;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import {classMap} from "lit/directives/class-map.js";
|
|
2
|
+
import {type CSSResultGroup, html, unsafeCSS} from 'lit';
|
|
1
3
|
import {MutationController} from '@lit-labs/observers/mutation-controller.js';
|
|
2
4
|
import {property} from 'lit/decorators.js';
|
|
3
|
-
import {type CSSResultGroup, html, unsafeCSS} from 'lit';
|
|
4
5
|
import ZincElement from '../../internal/zinc-element';
|
|
5
6
|
|
|
6
7
|
import styles from './sidebar.scss';
|
|
7
|
-
import {classMap} from "lit/directives/class-map.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @summary Short summary of the component's intended use.
|
|
@@ -91,7 +91,7 @@ export default class ZnSidebar extends ZincElement {
|
|
|
91
91
|
</div>`;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
handleClick(e:
|
|
94
|
+
handleClick(e: Event) {
|
|
95
95
|
this.open = !this.open;
|
|
96
96
|
e.stopPropagation();
|
|
97
97
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {animateTo} from "../../internal/animate";
|
|
2
2
|
import {classMap} from "lit/directives/class-map.js";
|
|
3
3
|
import {type CSSResultGroup, html, type PropertyValues, unsafeCSS} from 'lit';
|
|
4
|
-
import {LocalizeController} from "../../utilities/localize";
|
|
5
|
-
import {property, query} from 'lit/decorators.js';
|
|
6
4
|
import {getAnimation, setDefaultAnimation} from "../../utilities/animation-registry";
|
|
7
5
|
import {idSelector} from "../../utilities/query";
|
|
6
|
+
import {LocalizeController} from "../../utilities/localize";
|
|
7
|
+
import {property, query} from 'lit/decorators.js';
|
|
8
8
|
import {unlockBodyScrolling} from "../../internal/scroll";
|
|
9
9
|
import ZincElement from '../../internal/zinc-element';
|
|
10
10
|
import ZnButton from "../button";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {classMap} from "lit/directives/class-map.js";
|
|
2
2
|
import {type CSSResultGroup, html, unsafeCSS} from 'lit';
|
|
3
|
+
import {property} from 'lit/decorators.js';
|
|
3
4
|
import ZincElement from '../../internal/zinc-element';
|
|
4
|
-
import {classMap} from "lit/directives/class-map.js";
|
|
5
5
|
|
|
6
6
|
import styles from './stat.scss';
|
|
7
7
|
|
|
@@ -45,7 +45,7 @@ export default class ZnStatsTile extends ZincElement {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
getCurrentAmount() {
|
|
48
|
-
if (this.currency
|
|
48
|
+
if (this.currency === "") {
|
|
49
49
|
return this.amount;
|
|
50
50
|
}
|
|
51
51
|
// convert string to money
|
package/src/internal/form.ts
CHANGED
|
@@ -36,11 +36,11 @@ const interactions = new WeakMap<ZincFormControl, string[]>();
|
|
|
36
36
|
|
|
37
37
|
const formStorePrefix = 'znform:';
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
interface StoredFormControlValue {
|
|
40
40
|
checked?: boolean;
|
|
41
41
|
indeterminate?: boolean;
|
|
42
42
|
value?: unknown;
|
|
43
|
-
}
|
|
43
|
+
}
|
|
44
44
|
|
|
45
45
|
type PersistableNativeControl = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
|
|
46
46
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {LitElement, type PropertyValues} from "lit";
|
|
2
|
-
import {property} from "lit/decorators.js";
|
|
3
2
|
import {modeSignal, SignalWatcher, themeSignal} from "./theme";
|
|
3
|
+
import {property} from "lit/decorators.js";
|
|
4
4
|
import type {
|
|
5
5
|
EventTypeDoesNotRequireDetail,
|
|
6
6
|
EventTypeRequiresDetail,
|
|
File without changes
|