@c2n/dashboard 0.0.11 → 0.0.12
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/{dash-card-DYabhvcS.js → dash-card-DNRGm1hM.js} +144 -10
- package/dist/dash-card.js +1 -1
- package/dist/dashboard.js +75 -16
- package/package.json +3 -3
- package/react.d.ts +21 -2
- package/types/src/dash-card.d.ts +46 -9
- package/types/src/dash-card.d.ts.map +1 -1
- package/types/src/dashboard-host.d.ts +2 -0
- package/types/src/dashboard-host.d.ts.map +1 -1
- package/types/src/dashboard.d.ts +53 -6
- package/types/src/dashboard.d.ts.map +1 -1
|
@@ -4,8 +4,9 @@ import { property, state } from "lit/decorators.js";
|
|
|
4
4
|
import { isServer } from "lit-html/is-server.js";
|
|
5
5
|
import { customElement } from "@c2n/core/element-helper.js";
|
|
6
6
|
import { classMap } from "lit/directives/class-map.js";
|
|
7
|
+
import { hasSlottedContent } from "@c2n/core/dom-helper.js";
|
|
7
8
|
//#region src/dash-card.scss?inline
|
|
8
|
-
var dash_card_default = "/* ex : var((width: 24px), width, c2-checkbox) returns var(--c2-checkbox-width, 24px) */\n:host {\n position: relative;\n display: block;\n box-sizing: border-box;\n grid-column: var(--_grid-column, auto);\n grid-row: var(--_grid-row, auto);\n min-width: 0;\n min-height: 0;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n:host([expanded=width]),\n:host([expanded=height]),\n:host([expanded=full]) {\n isolation: isolate;\n z-index: var(--c2-dash-card__expanded--z-index,20);\n background: var(--c2-dash-card__expanded--background
|
|
9
|
+
var dash_card_default = "/* ex : var((width: 24px), width, c2-checkbox) returns var(--c2-checkbox-width, 24px) */\n:host {\n position: relative;\n display: block;\n box-sizing: border-box;\n grid-column: var(--_grid-column, auto);\n grid-row: var(--_grid-row, auto);\n min-width: 0;\n min-height: 0;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n:host([expanded=width]),\n:host([expanded=height]),\n:host([expanded=full]) {\n isolation: isolate;\n z-index: var(--c2-dash-card__expanded--z-index,20);\n background: var(--c2-dash-card__expanded--background,#ffffff);\n animation: c2-dash-card-expand var(--c2-dash-card__expanded--animation-duration,200ms) cubic-bezier(0.25, 0.46, 0.45, 0.94);\n}\n\n@keyframes c2-dash-card-expand {\n from {\n transform: scale(0.97);\n }\n to {\n transform: scale(1);\n }\n}\n@media (prefers-reduced-motion: reduce) {\n :host([expanded=width]),\n :host([expanded=height]),\n :host([expanded=full]) {\n animation: none;\n }\n}\n.c2-dash-card {\n position: relative;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n height: 100%;\n transition-property: none;\n transition-duration: var(--c2-dash-card__enter--animation-duration,200ms), var(--c2-dash-card__leave--animation-duration,160ms);\n transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);\n min-width: 0;\n min-height: 0;\n padding: var(--c2-dash-card--padding,0px);\n overflow: var(--c2-dash-card--overflow,hidden);\n color: inherit;\n background: var(--c2-dash-card--background,transparent);\n border: var(--c2-dash-card--border,none);\n border-radius: var(--c2-dash-card--border-radius,0px);\n box-shadow: var(--c2-dash-card--box-shadow,none);\n}\n\n.c2-dash-card__header {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: space-between;\n box-sizing: border-box;\n gap: var(--c2-dash-card__header--gap,12px);\n min-width: 0;\n min-height: var(--c2-dash-card__header--min-height,44px);\n padding: var(--c2-dash-card__header--padding-block,8px) var(--c2-dash-card__header--padding-inline,12px);\n font-size: var(--c2-dash-card__header--font-size,14px);\n font-weight: var(--c2-dash-card__header--font-weight,600);\n color: var(--c2-dash-card__header--color,#18181b);\n background: var(--c2-dash-card__header--background,transparent);\n border-bottom: var(--c2-dash-card__header--border-bottom,none);\n}\n\n.c2-dash-card:not(.has-header) .c2-dash-card__header {\n position: absolute;\n top: var(--c2-dash-card__controls--offset,4px);\n right: var(--c2-dash-card__controls--offset,4px);\n z-index: 2;\n min-height: 0;\n padding: 0;\n background: none;\n border: none;\n}\n\n.c2-dash-card:not(.has-header) .c2-dash-card__title {\n display: none;\n}\n\n.c2-dash-card__title {\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n min-width: 0;\n}\n\n.c2-dash-card__actions {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n gap: var(--c2-dash-card__actions--gap,8px);\n min-width: 0;\n}\n\n.c2-dash-card__controls {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n gap: var(--c2-dash-card__controls--gap,2px);\n}\n\n.c2-dash-card__control {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: var(--c2-dash-card__control--size,24px);\n height: var(--c2-dash-card__control--size,24px);\n padding: 0;\n margin: 0;\n color: var(--c2-dash-card__control--color,#71717a);\n cursor: pointer;\n background: var(--c2-dash-card__control--background,transparent);\n border: none;\n border-radius: var(--c2-dash-card__control--border-radius,6px);\n}\n\n.c2-dash-card__control:hover {\n color: var(--c2-dash-card__control__hover--color,#18181b);\n background: var(--c2-dash-card__control__hover--background,#f4f4f5);\n}\n\n.c2-dash-card__control:focus-visible {\n outline: var(--c2-dash-card__control__focus--outline,2px solid rgba(2, 101, 220, 0.4));\n outline-offset: var(--c2-dash-card__control__focus--outline-offset,2px);\n}\n\n.c2-dash-card__control-icon {\n width: var(--c2-dash-card__control--icon-size,16px);\n height: var(--c2-dash-card__control--icon-size,16px);\n}\n\n.c2-dash-card__control ::slotted(*) {\n width: var(--c2-dash-card__control--icon-size,16px);\n height: var(--c2-dash-card__control--icon-size,16px);\n}\n\n.c2-dash-card__body {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n}\n\n.c2-dash-card__body ::slotted(*) {\n flex: 1 1 auto;\n min-width: 0;\n min-height: 0;\n}\n\n.c2-dash-card__footer {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n box-sizing: border-box;\n gap: var(--c2-dash-card__footer--gap,8px);\n min-width: 0;\n min-height: var(--c2-dash-card__footer--min-height,36px);\n padding: var(--c2-dash-card__footer--padding-block,6px) var(--c2-dash-card__footer--padding-inline,12px);\n font-size: var(--c2-dash-card__footer--font-size,12px);\n color: var(--c2-dash-card__footer--color,#71717a);\n background: var(--c2-dash-card__footer--background,transparent);\n border-top: var(--c2-dash-card__footer--border-top,none);\n}\n\n.c2-dash-card__header[hidden],\n.c2-dash-card__controls[hidden],\n.c2-dash-card__footer[hidden] {\n display: none;\n}\n\n.c2-dash-card__handle {\n position: absolute;\n z-index: 3;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--c2-dash-card__handle--background,transparent);\n touch-action: none;\n}\n\n.c2-dash-card__handle:focus-visible {\n outline: var(--c2-dash-card__handle__focus--outline,2px solid rgba(2, 101, 220, 0.4));\n}\n\n.c2-dash-card__handle-bar {\n display: block;\n background: transparent;\n border-radius: var(--c2-dash-card__handle--border-radius,999px);\n transition: background var(--c2-dash-card__handle--transition-duration,150ms) ease;\n}\n\n.c2-dash-card__handle:hover .c2-dash-card__handle-bar,\n.c2-dash-card__handle:focus-visible .c2-dash-card__handle-bar {\n background: var(--c2-dash-card__handle__hover--background,rgba(2, 101, 220, 0.2));\n}\n\n.c2-dash-card__handle.is-dragging .c2-dash-card__handle-bar {\n background: var(--c2-dash-card__handle__active--background,rgb(2, 101, 220));\n}\n\n.c2-dash-card__handle--left,\n.c2-dash-card__handle--right {\n top: 0;\n width: max(var(--c2-dash-card__handle--size,6px), var(--_c2-dashboard-gap, 0px));\n height: 100%;\n cursor: col-resize;\n}\n.c2-dash-card__handle--left .c2-dash-card__handle-bar,\n.c2-dash-card__handle--right .c2-dash-card__handle-bar {\n width: 2px;\n height: calc(100% - 2 * var(--c2-dash-card__handle--inset,2px));\n}\n\n.c2-dash-card__handle--left {\n left: calc(-0.5 * max(var(--c2-dash-card__handle--size,6px), var(--_c2-dashboard-gap, 0px)));\n}\n\n.c2-dash-card__handle--right {\n right: calc(-0.5 * max(var(--c2-dash-card__handle--size,6px), var(--_c2-dashboard-gap, 0px)));\n}\n\n.c2-dash-card__handle--top,\n.c2-dash-card__handle--bottom {\n left: 0;\n width: 100%;\n height: max(var(--c2-dash-card__handle--size,6px), var(--_c2-dashboard-gap, 0px));\n cursor: row-resize;\n}\n.c2-dash-card__handle--top .c2-dash-card__handle-bar,\n.c2-dash-card__handle--bottom .c2-dash-card__handle-bar {\n width: calc(100% - 2 * var(--c2-dash-card__handle--inset,2px));\n height: 2px;\n}\n\n.c2-dash-card__handle--top {\n top: calc(-0.5 * max(var(--c2-dash-card__handle--size,6px), var(--_c2-dashboard-gap, 0px)));\n}\n\n.c2-dash-card__handle--bottom {\n bottom: calc(-0.5 * max(var(--c2-dash-card__handle--size,6px), var(--_c2-dashboard-gap, 0px)));\n}\n\n@media (prefers-reduced-motion: reduce) {\n .c2-dash-card__handle-bar {\n transition: none;\n }\n .c2-dash-card {\n transition-duration: 0s, 0s;\n }\n}";
|
|
9
10
|
//#endregion
|
|
10
11
|
//#region \0@oxc-project+runtime@0.148.0/helpers/esm/decorate.js
|
|
11
12
|
function __decorate(decorators, target, key, desc) {
|
|
@@ -29,6 +30,23 @@ var ICONS = {
|
|
|
29
30
|
function clamp(value, min, max) {
|
|
30
31
|
return Math.min(Math.max(value, min), max);
|
|
31
32
|
}
|
|
33
|
+
/** First entry of a comma-separated CSS list, leaving the commas inside `cubic-bezier(…)` alone. */
|
|
34
|
+
function firstListEntry(value) {
|
|
35
|
+
let depth = 0;
|
|
36
|
+
for (let i = 0; i < value.length; i++) {
|
|
37
|
+
const char = value[i];
|
|
38
|
+
if (char === "(") depth++;
|
|
39
|
+
else if (char === ")") depth--;
|
|
40
|
+
else if (char === "," && depth === 0) return value.slice(0, i).trim();
|
|
41
|
+
}
|
|
42
|
+
return value.trim();
|
|
43
|
+
}
|
|
44
|
+
/** `'200ms'` → 200, `'0.2s'` → 200. */
|
|
45
|
+
function parseDuration(value) {
|
|
46
|
+
const amount = parseFloat(value);
|
|
47
|
+
if (Number.isNaN(amount)) return 0;
|
|
48
|
+
return value.endsWith("ms") ? amount : amount * 1e3;
|
|
49
|
+
}
|
|
32
50
|
var DashCard = class DashCard extends LitElement {
|
|
33
51
|
constructor(..._args) {
|
|
34
52
|
super(..._args);
|
|
@@ -49,6 +67,8 @@ var DashCard = class DashCard extends LitElement {
|
|
|
49
67
|
this.hasSlottedControls = false;
|
|
50
68
|
this.hasFooter = false;
|
|
51
69
|
this.dashboard = void 0;
|
|
70
|
+
this.leaving = false;
|
|
71
|
+
this.enterPending = false;
|
|
52
72
|
}
|
|
53
73
|
static {
|
|
54
74
|
this.styles = unsafeCSS(dash_card_default);
|
|
@@ -73,6 +93,7 @@ var DashCard = class DashCard extends LitElement {
|
|
|
73
93
|
disconnectedCallback() {
|
|
74
94
|
this.dashboard?.unregisterCard(this);
|
|
75
95
|
this.dashboard = void 0;
|
|
96
|
+
this.motion = void 0;
|
|
76
97
|
super.disconnectedCallback();
|
|
77
98
|
}
|
|
78
99
|
/** Called by the grid when its shape or its layout record changed. */
|
|
@@ -80,14 +101,129 @@ var DashCard = class DashCard extends LitElement {
|
|
|
80
101
|
this.requestUpdate();
|
|
81
102
|
}
|
|
82
103
|
willUpdate() {
|
|
83
|
-
|
|
84
|
-
|
|
104
|
+
if (!this.hasUpdated) {
|
|
105
|
+
this.hasHeader = hasSlottedContent(this, "header");
|
|
106
|
+
this.hasActions = hasSlottedContent(this, "actions");
|
|
107
|
+
this.hasSlottedControls = hasSlottedContent(this, "controls");
|
|
108
|
+
this.hasFooter = hasSlottedContent(this, "footer");
|
|
109
|
+
}
|
|
110
|
+
this.syncVisibility();
|
|
85
111
|
}
|
|
86
112
|
updated() {
|
|
87
113
|
const placement = this.placement;
|
|
88
114
|
this.style.setProperty("--_grid-column", `${placement.col} / span ${placement.colSpan}`);
|
|
89
115
|
this.style.setProperty("--_grid-row", `${placement.row} / span ${placement.rowSpan}`);
|
|
90
116
|
this.syncHandleValues();
|
|
117
|
+
if (this.enterPending) {
|
|
118
|
+
this.enterPending = false;
|
|
119
|
+
this.playEnter();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Applies the layout record's `visible`. Hiding is deferred until the leave animation has played; showing again
|
|
124
|
+
* cancels a leave in flight and animates in. Before the first render, and outside a grid, nothing animates.
|
|
125
|
+
*/
|
|
126
|
+
syncVisibility() {
|
|
127
|
+
const visible = this.dashboard?.placementOf(this.cardId)?.visible;
|
|
128
|
+
if (visible === void 0) return;
|
|
129
|
+
if (visible) {
|
|
130
|
+
if (this.leaving || this.motion) this.cancelMotion();
|
|
131
|
+
if (this.hidden && this.hasUpdated) this.enterPending = true;
|
|
132
|
+
this.hidden = false;
|
|
133
|
+
} else if (!this.hidden && !this.leaving) {
|
|
134
|
+
if (!this.hasUpdated) this.hidden = true;
|
|
135
|
+
else this.leave().then((done) => {
|
|
136
|
+
if (done) this.hidden = true;
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Plays the leave animation, then removes the element from the document. Resolves once it is gone. The other
|
|
142
|
+
* cards keep their placement — the grid does not close the gap; re-place them (`col`/`row` or the grid's
|
|
143
|
+
* `layout`) once the promise resolves if it should.
|
|
144
|
+
*/
|
|
145
|
+
async dismiss() {
|
|
146
|
+
if (!this.isConnected) return;
|
|
147
|
+
if (await this.leave()) this.remove();
|
|
148
|
+
}
|
|
149
|
+
get surface() {
|
|
150
|
+
return this.renderRoot.querySelector(".c2-dash-card");
|
|
151
|
+
}
|
|
152
|
+
/** Enter and leave timing, read back from the stylesheet so the variables and `prefers-reduced-motion` apply. */
|
|
153
|
+
timing(target, phase) {
|
|
154
|
+
const style = getComputedStyle(target);
|
|
155
|
+
return {
|
|
156
|
+
duration: style.transitionDuration.split(",").map((value) => parseDuration(value.trim()))[phase === "enter" ? 0 : 1] ?? 0,
|
|
157
|
+
easing: firstListEntry(style.transitionTimingFunction) || "ease"
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
cancelMotion() {
|
|
161
|
+
this.motion?.cancel();
|
|
162
|
+
this.motion = void 0;
|
|
163
|
+
this.leaving = false;
|
|
164
|
+
}
|
|
165
|
+
playEnter() {
|
|
166
|
+
if (isServer) return;
|
|
167
|
+
this.cancelMotion();
|
|
168
|
+
const target = this.surface;
|
|
169
|
+
if (!target || typeof target.animate !== "function") return;
|
|
170
|
+
const { duration, easing } = this.timing(target, "enter");
|
|
171
|
+
if (duration <= 0) return;
|
|
172
|
+
const motion = target.animate([{
|
|
173
|
+
opacity: 0,
|
|
174
|
+
transform: "scale(0.96)"
|
|
175
|
+
}, {
|
|
176
|
+
opacity: 1,
|
|
177
|
+
transform: "scale(1)"
|
|
178
|
+
}], {
|
|
179
|
+
duration,
|
|
180
|
+
easing
|
|
181
|
+
});
|
|
182
|
+
this.motion = motion;
|
|
183
|
+
motion.finished.then(() => {
|
|
184
|
+
if (this.motion === motion) this.motion = void 0;
|
|
185
|
+
}).catch(() => {});
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Fades the card out. Resolves `true` once it has finished — the caller then hides or removes the element — and
|
|
189
|
+
* `false` when a return cancelled it. The end state is held (`fill: forwards`) until the next enter cancels it,
|
|
190
|
+
* so nothing flashes between the last frame and the hide.
|
|
191
|
+
*/
|
|
192
|
+
async leave() {
|
|
193
|
+
if (this.motion) this.cancelMotion();
|
|
194
|
+
this.leaving = true;
|
|
195
|
+
await this.updateComplete;
|
|
196
|
+
if (!this.leaving) return false;
|
|
197
|
+
const target = this.surface;
|
|
198
|
+
if (isServer || !target || typeof target.animate !== "function") {
|
|
199
|
+
this.leaving = false;
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
const { duration, easing } = this.timing(target, "leave");
|
|
203
|
+
if (duration <= 0) {
|
|
204
|
+
this.leaving = false;
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
const motion = target.animate([{
|
|
208
|
+
opacity: 1,
|
|
209
|
+
transform: "scale(1)"
|
|
210
|
+
}, {
|
|
211
|
+
opacity: 0,
|
|
212
|
+
transform: "scale(0.96)"
|
|
213
|
+
}], {
|
|
214
|
+
duration,
|
|
215
|
+
easing,
|
|
216
|
+
fill: "forwards"
|
|
217
|
+
});
|
|
218
|
+
this.motion = motion;
|
|
219
|
+
try {
|
|
220
|
+
await motion.finished;
|
|
221
|
+
} catch {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
if (this.motion !== motion) return false;
|
|
225
|
+
this.leaving = false;
|
|
226
|
+
return true;
|
|
91
227
|
}
|
|
92
228
|
/**
|
|
93
229
|
* The splitter values are written straight onto the handles rather than re-rendered: a drag changes them on
|
|
@@ -103,26 +239,23 @@ var DashCard = class DashCard extends LitElement {
|
|
|
103
239
|
handle.setAttribute("aria-valuenow", String(dashboard.splitterValue(axis, index)));
|
|
104
240
|
}
|
|
105
241
|
}
|
|
106
|
-
/** `slotchange` does not fire for a server-rendered shadow root, so read every slot once. */
|
|
107
|
-
firstUpdated() {
|
|
108
|
-
for (const slot of this.renderRoot.querySelectorAll("slot")) this.updateSection(slot);
|
|
109
|
-
}
|
|
110
242
|
/**
|
|
111
243
|
* The grid may upgrade after its cards do — the card element is in the document either way, so find it and wait
|
|
112
244
|
* for the definition rather than for a parent that is already alive.
|
|
113
245
|
*/
|
|
114
|
-
attachToDashboard() {
|
|
246
|
+
attachToDashboard(late = true) {
|
|
115
247
|
const host = this.closest(DASHBOARD_TAG);
|
|
116
248
|
if (!host) return;
|
|
117
249
|
if (typeof host.registerCard !== "function") {
|
|
118
250
|
if (isServer) return;
|
|
119
251
|
customElements.whenDefined(DASHBOARD_TAG).then(() => {
|
|
120
|
-
if (this.isConnected) this.attachToDashboard();
|
|
252
|
+
if (this.isConnected) this.attachToDashboard(false);
|
|
121
253
|
});
|
|
122
254
|
return;
|
|
123
255
|
}
|
|
124
256
|
this.dashboard = host;
|
|
125
257
|
host.registerCard(this);
|
|
258
|
+
if (late && host.hasUpdated) this.enterPending = true;
|
|
126
259
|
}
|
|
127
260
|
get placement() {
|
|
128
261
|
const override = this.dashboard?.placementOf(this.cardId);
|
|
@@ -271,7 +404,7 @@ var DashCard = class DashCard extends LitElement {
|
|
|
271
404
|
`;
|
|
272
405
|
}
|
|
273
406
|
renderHandles() {
|
|
274
|
-
if (!this.dashboard || this.resize === "none") return nothing;
|
|
407
|
+
if (!this.dashboard || this.resize === "none" || this.leaving) return nothing;
|
|
275
408
|
const placement = this.placement;
|
|
276
409
|
const horizontal = this.resize === "both" || this.resize === "horizontal";
|
|
277
410
|
const vertical = this.resize === "both" || this.resize === "vertical";
|
|
@@ -348,6 +481,7 @@ __decorate([state()], DashCard.prototype, "hasActions", void 0);
|
|
|
348
481
|
__decorate([state()], DashCard.prototype, "hasSlottedControls", void 0);
|
|
349
482
|
__decorate([state()], DashCard.prototype, "hasFooter", void 0);
|
|
350
483
|
__decorate([state()], DashCard.prototype, "dashboard", void 0);
|
|
484
|
+
__decorate([state()], DashCard.prototype, "leaving", void 0);
|
|
351
485
|
DashCard = __decorate([customElement("c2-dash-card")], DashCard);
|
|
352
486
|
//#endregion
|
|
353
487
|
export { __decorate as n, DashCard as t };
|
package/dist/dash-card.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as DashCard } from "./dash-card-
|
|
1
|
+
import { t as DashCard } from "./dash-card-DNRGm1hM.js";
|
|
2
2
|
export { DashCard };
|
package/dist/dashboard.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { n as __decorate } from "./dash-card-
|
|
1
|
+
import { n as __decorate } from "./dash-card-DNRGm1hM.js";
|
|
2
2
|
import { LitElement, html, unsafeCSS } from "lit";
|
|
3
3
|
import { property, state } from "lit/decorators.js";
|
|
4
4
|
import { isServer } from "lit-html/is-server.js";
|
|
5
5
|
import { customElement } from "@c2n/core/element-helper.js";
|
|
6
6
|
//#region src/dashboard.scss?inline
|
|
7
|
-
var dashboard_default = "/* ex : var((width: 24px), width, c2-checkbox) returns var(--c2-checkbox-width, 24px) */\n:host {\n display: grid;\n box-sizing: border-box;\n grid-template-columns: var(--_columns, 1fr);\n grid-template-rows: var(--_rows, auto);\n gap: var(--c2-dashboard--gap,8px);\n padding: var(--c2-dashboard--padding,0px);\n background: var(--c2-dashboard--background,transparent);\n border: var(--c2-dashboard--border,none);\n border-radius: var(--c2-dashboard--border-radius,0px);\n min-width: 0;\n min-height: 0;\n}\n\n:host([hidden]) {\n display: none;\n}\n\nslot {\n display: contents;\n}\n\n::slotted(*) {\n min-width: 0;\n min-height: 0;\n}";
|
|
7
|
+
var dashboard_default = "/* ex : var((width: 24px), width, c2-checkbox) returns var(--c2-checkbox-width, 24px) */\n:host {\n --_c2-dashboard-gap: var(--c2-dashboard--gap,8px);\n display: grid;\n box-sizing: border-box;\n grid-template-columns: var(--_columns, 1fr);\n grid-template-rows: var(--_rows, auto);\n gap: var(--c2-dashboard--gap,8px);\n padding: var(--c2-dashboard--padding,0px);\n background: var(--c2-dashboard--background,transparent);\n border: var(--c2-dashboard--border,none);\n border-radius: var(--c2-dashboard--border-radius,0px);\n min-width: 0;\n min-height: 0;\n}\n\n:host([hidden]) {\n display: none;\n}\n\nslot {\n display: contents;\n}\n\n::slotted(*) {\n min-width: 0;\n min-height: 0;\n}";
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/dashboard.ts
|
|
10
10
|
var FRACTION = /^([\d.]*)fr$/;
|
|
@@ -38,9 +38,15 @@ var Dashboard = class Dashboard extends LitElement {
|
|
|
38
38
|
this.minRowHeight = 50;
|
|
39
39
|
this.storageKey = void 0;
|
|
40
40
|
this.layout = void 0;
|
|
41
|
+
this.layouts = void 0;
|
|
41
42
|
this.columnTracks = [];
|
|
42
43
|
this.rowTracks = [];
|
|
44
|
+
this.activeLayout = -1;
|
|
43
45
|
this.cards = /* @__PURE__ */ new Set();
|
|
46
|
+
this.mediaQueries = [];
|
|
47
|
+
this.handleMediaChange = () => {
|
|
48
|
+
this.activeLayout = this.resolveActiveLayout();
|
|
49
|
+
};
|
|
44
50
|
this.pixelCache = /* @__PURE__ */ new Map();
|
|
45
51
|
}
|
|
46
52
|
static {
|
|
@@ -60,22 +66,37 @@ var Dashboard = class Dashboard extends LitElement {
|
|
|
60
66
|
get rowCount() {
|
|
61
67
|
return this.rowTracks.length;
|
|
62
68
|
}
|
|
69
|
+
/** The entry of `layouts` in force, or `undefined` while the authored grid is. */
|
|
70
|
+
get activeResponsiveLayout() {
|
|
71
|
+
return this.layouts?.[this.activeLayout];
|
|
72
|
+
}
|
|
73
|
+
connectedCallback() {
|
|
74
|
+
super.connectedCallback();
|
|
75
|
+
if (this.hasUpdated) this.watchMedia();
|
|
76
|
+
}
|
|
77
|
+
disconnectedCallback() {
|
|
78
|
+
super.disconnectedCallback();
|
|
79
|
+
this.unwatchMedia();
|
|
80
|
+
}
|
|
63
81
|
willUpdate(changed) {
|
|
64
|
-
if (!this.hasUpdated || changed.has("
|
|
82
|
+
if (!this.hasUpdated || changed.has("layouts")) this.watchMedia();
|
|
83
|
+
if (!this.hasUpdated || changed.has("columns") || changed.has("rows") || changed.has("storageKey") || changed.has("layouts") || changed.has("activeLayout")) this.syncTracks();
|
|
65
84
|
}
|
|
66
85
|
updated(changed) {
|
|
67
86
|
this.pixelCache.clear();
|
|
68
87
|
this.style.setProperty("--_columns", this.columnTracks.join(" "));
|
|
69
88
|
this.style.setProperty("--_rows", this.rowTracks.join(" "));
|
|
70
|
-
if (changed.has("columnTracks") || changed.has("rowTracks") || changed.has("layout")) for (const card of this.cards) card.hostChanged();
|
|
89
|
+
if (changed.has("columnTracks") || changed.has("rowTracks") || changed.has("layout") || changed.has("layouts") || changed.has("activeLayout")) for (const card of this.cards) card.hostChanged();
|
|
90
|
+
if (changed.has("activeLayout") && changed.get("activeLayout") !== void 0) this.emitLayoutChange();
|
|
71
91
|
}
|
|
72
|
-
/** Back to the authored tracks, and
|
|
92
|
+
/** Back to the authored tracks of the layout in force, and its stored ones are forgotten. */
|
|
73
93
|
reset() {
|
|
74
|
-
|
|
75
|
-
|
|
94
|
+
const key = this.activeStorageKey;
|
|
95
|
+
if (key && !isServer) try {
|
|
96
|
+
localStorage.removeItem(key);
|
|
76
97
|
} catch {}
|
|
77
|
-
this.columnTracks = toTracks(this.columns);
|
|
78
|
-
this.rowTracks = toTracks(this.rows);
|
|
98
|
+
this.columnTracks = toTracks(this.activeResponsiveLayout?.columns ?? this.columns);
|
|
99
|
+
this.rowTracks = toTracks(this.activeResponsiveLayout?.rows ?? this.rows);
|
|
79
100
|
this.emitLayoutChange();
|
|
80
101
|
}
|
|
81
102
|
registerCard(card) {
|
|
@@ -86,7 +107,13 @@ var Dashboard = class Dashboard extends LitElement {
|
|
|
86
107
|
this.cards.delete(card);
|
|
87
108
|
}
|
|
88
109
|
placementOf(cardId) {
|
|
89
|
-
|
|
110
|
+
if (!cardId) return void 0;
|
|
111
|
+
const base = this.layout?.[cardId];
|
|
112
|
+
const active = this.activeResponsiveLayout?.layout?.[cardId];
|
|
113
|
+
return active && base ? {
|
|
114
|
+
...base,
|
|
115
|
+
...active
|
|
116
|
+
} : active ?? base;
|
|
90
117
|
}
|
|
91
118
|
resizeColumn(index, delta) {
|
|
92
119
|
this.pixelCache.clear();
|
|
@@ -194,17 +221,46 @@ var Dashboard = class Dashboard extends LitElement {
|
|
|
194
221
|
}
|
|
195
222
|
return Math.max(0, min);
|
|
196
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* One `MediaQueryList` per entry of `layouts`, listened to for as long as the element is connected. Whichever
|
|
226
|
+
* entry matches first is the one in force; the listeners re-run the choice whenever any of them flips.
|
|
227
|
+
*/
|
|
228
|
+
watchMedia() {
|
|
229
|
+
this.unwatchMedia();
|
|
230
|
+
if (isServer || typeof matchMedia !== "function") return;
|
|
231
|
+
for (const entry of this.layouts ?? []) {
|
|
232
|
+
const query = matchMedia(entry.media);
|
|
233
|
+
query.addEventListener("change", this.handleMediaChange);
|
|
234
|
+
this.mediaQueries.push(query);
|
|
235
|
+
}
|
|
236
|
+
this.activeLayout = this.resolveActiveLayout();
|
|
237
|
+
}
|
|
238
|
+
unwatchMedia() {
|
|
239
|
+
for (const query of this.mediaQueries) query.removeEventListener("change", this.handleMediaChange);
|
|
240
|
+
this.mediaQueries = [];
|
|
241
|
+
}
|
|
242
|
+
resolveActiveLayout() {
|
|
243
|
+
return this.mediaQueries.findIndex((query) => query.matches);
|
|
244
|
+
}
|
|
245
|
+
/** Each entry of `layouts` stores its own sizes: `<storage-key>@<media>`; the authored grid uses the bare key. */
|
|
246
|
+
get activeStorageKey() {
|
|
247
|
+
if (!this.storageKey) return void 0;
|
|
248
|
+
const active = this.activeResponsiveLayout;
|
|
249
|
+
return active ? `${this.storageKey}@${active.media}` : this.storageKey;
|
|
250
|
+
}
|
|
197
251
|
syncTracks() {
|
|
198
|
-
const
|
|
199
|
-
const
|
|
252
|
+
const active = this.activeResponsiveLayout;
|
|
253
|
+
const columns = toTracks(active?.columns ?? this.columns);
|
|
254
|
+
const rows = toTracks(active?.rows ?? this.rows);
|
|
200
255
|
const stored = this.readStored();
|
|
201
256
|
this.columnTracks = stored?.columns?.length === columns.length ? [...stored.columns] : columns;
|
|
202
257
|
this.rowTracks = stored?.rows?.length === rows.length ? [...stored.rows] : rows;
|
|
203
258
|
}
|
|
204
259
|
readStored() {
|
|
205
|
-
|
|
260
|
+
const key = this.activeStorageKey;
|
|
261
|
+
if (!key || isServer) return null;
|
|
206
262
|
try {
|
|
207
|
-
const raw = localStorage.getItem(
|
|
263
|
+
const raw = localStorage.getItem(key);
|
|
208
264
|
if (!raw) return null;
|
|
209
265
|
const parsed = JSON.parse(raw);
|
|
210
266
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
@@ -213,9 +269,10 @@ var Dashboard = class Dashboard extends LitElement {
|
|
|
213
269
|
}
|
|
214
270
|
}
|
|
215
271
|
persist() {
|
|
216
|
-
|
|
272
|
+
const key = this.activeStorageKey;
|
|
273
|
+
if (!key || isServer) return;
|
|
217
274
|
try {
|
|
218
|
-
localStorage.setItem(
|
|
275
|
+
localStorage.setItem(key, JSON.stringify({
|
|
219
276
|
columns: this.columnTracks,
|
|
220
277
|
rows: this.rowTracks
|
|
221
278
|
}));
|
|
@@ -237,8 +294,10 @@ __decorate([property({
|
|
|
237
294
|
})], Dashboard.prototype, "minRowHeight", void 0);
|
|
238
295
|
__decorate([property({ attribute: "storage-key" })], Dashboard.prototype, "storageKey", void 0);
|
|
239
296
|
__decorate([property({ attribute: false })], Dashboard.prototype, "layout", void 0);
|
|
297
|
+
__decorate([property({ attribute: false })], Dashboard.prototype, "layouts", void 0);
|
|
240
298
|
__decorate([state()], Dashboard.prototype, "columnTracks", void 0);
|
|
241
299
|
__decorate([state()], Dashboard.prototype, "rowTracks", void 0);
|
|
300
|
+
__decorate([state()], Dashboard.prototype, "activeLayout", void 0);
|
|
242
301
|
Dashboard = __decorate([customElement("c2-dashboard")], Dashboard);
|
|
243
302
|
//#endregion
|
|
244
303
|
export { Dashboard };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c2n/dashboard",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/dashboard.js",
|
|
6
6
|
"exports": {
|
|
@@ -73,12 +73,12 @@
|
|
|
73
73
|
}
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@c2n/core": "0.0.
|
|
76
|
+
"@c2n/core": "0.0.12",
|
|
77
77
|
"lit": "3.3.3"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@c2n/config": "*"
|
|
81
81
|
},
|
|
82
82
|
"customElements": "custom-elements.json",
|
|
83
|
-
"gitHead": "
|
|
83
|
+
"gitHead": "43e38b42ac221ffeef99a773c42dd3356961d26a"
|
|
84
84
|
}
|
package/react.d.ts
CHANGED
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
//
|
|
7
7
|
// Register the elements at module scope before React renders, or React writes an object prop as an
|
|
8
8
|
// attribute and it stringifies.
|
|
9
|
+
//
|
|
10
|
+
// On a server-rendered page (Next.js, React Router SSR) write a camelCase property by its kebab-case attribute
|
|
11
|
+
// name ('row-key', not rowKey): the server emits props verbatim, HTML lowercases them, and hydration does not
|
|
12
|
+
// set properties. Those names are listed next to the properties below.
|
|
9
13
|
|
|
10
14
|
import type { DetailedHTMLProps, HTMLAttributes } from 'react'
|
|
11
15
|
import type { DashCard } from '@c2n/dashboard/dash-card.js'
|
|
@@ -13,12 +17,27 @@ import type { Dashboard } from '@c2n/dashboard'
|
|
|
13
17
|
|
|
14
18
|
/** Standard React host-element attributes plus the element's own public properties. */
|
|
15
19
|
type C2Props<T> = DetailedHTMLProps<HTMLAttributes<T>, T> & Partial<Omit<T, keyof HTMLElement>>
|
|
20
|
+
/** What React writes to a custom element's attribute: true becomes the empty string, false removes it. */
|
|
21
|
+
type Attribute = string | number | boolean
|
|
16
22
|
|
|
17
23
|
declare module 'react' {
|
|
18
24
|
namespace JSX {
|
|
19
25
|
interface IntrinsicElements {
|
|
20
|
-
'c2-dash-card': C2Props<DashCard>
|
|
21
|
-
|
|
26
|
+
'c2-dash-card': C2Props<DashCard> & {
|
|
27
|
+
'card-id'?: Attribute
|
|
28
|
+
'col-span'?: Attribute
|
|
29
|
+
'row-span'?: Attribute
|
|
30
|
+
'min-width'?: Attribute
|
|
31
|
+
'min-height'?: Attribute
|
|
32
|
+
'expand-width'?: Attribute
|
|
33
|
+
'expand-height'?: Attribute
|
|
34
|
+
'expand-full'?: Attribute
|
|
35
|
+
}
|
|
36
|
+
'c2-dashboard': C2Props<Dashboard> & {
|
|
37
|
+
'min-column-width'?: Attribute
|
|
38
|
+
'min-row-height'?: Attribute
|
|
39
|
+
'storage-key'?: Attribute
|
|
40
|
+
}
|
|
22
41
|
}
|
|
23
42
|
}
|
|
24
43
|
}
|
package/types/src/dash-card.d.ts
CHANGED
|
@@ -28,15 +28,22 @@ export interface DashCard {
|
|
|
28
28
|
* it, or focus it and use the arrow keys (10px a step, 1px with Shift).
|
|
29
29
|
*
|
|
30
30
|
* Filling the `header`, `actions` or `footer` slot turns on that row; with the header and actions both empty the
|
|
31
|
-
* expand controls float over the top-right corner of the pane instead. An expanded card covers its neighbours
|
|
32
|
-
*
|
|
31
|
+
* expand controls float over the top-right corner of the pane instead. An expanded card covers its neighbours on
|
|
32
|
+
* an opaque `--c2-dash-card__expanded--background` (the theme's surface colour), while the card itself stays
|
|
33
|
+
* transparent at rest.
|
|
34
|
+
*
|
|
35
|
+
* A card that arrives while the grid is already on screen fades and scales in; one that leaves — through the
|
|
36
|
+
* grid's `layout` record (`visible: false`) or through `dismiss()`, which removes the element once the animation
|
|
37
|
+
* has played — fades out the same way. Cards present at load do not animate, and `prefers-reduced-motion` turns
|
|
38
|
+
* both off.
|
|
33
39
|
*
|
|
34
40
|
* Every built-in icon is a slot whose fallback is the default drawing, so a pane can use the host application's own
|
|
35
41
|
* icon set without giving up the behaviour.
|
|
36
42
|
*
|
|
37
43
|
* @tag c2-dash-card
|
|
38
44
|
*
|
|
39
|
-
* @slot - Pane content.
|
|
45
|
+
* @slot - Pane content. It fills the pane: the body is a column flex box and every slotted child is a `flex: 1`
|
|
46
|
+
* item with `min-height: 0`, so a chart or an editor follows the row track without a `height: 100%` chain.
|
|
40
47
|
* @slot header - Title area of the header row; filling it turns the row on.
|
|
41
48
|
* @slot actions - Your own controls at the end of the header row, before the built-in expand buttons and separated
|
|
42
49
|
* from them by `--c2-dash-card__actions--gap`.
|
|
@@ -72,9 +79,13 @@ export interface DashCard {
|
|
|
72
79
|
* @cssproperty {overflow} [--c2-dash-card--overflow=hidden] - `hidden` keeps the content inside the track; switch
|
|
73
80
|
* it to `visible` for a pane that has to overflow, such as one holding a menu.
|
|
74
81
|
*
|
|
75
|
-
* @cssproperty {background} --c2-dash-card__expanded--background - Fill while the card is expanded over
|
|
76
|
-
* neighbours
|
|
82
|
+
* @cssproperty {background} [--c2-dash-card__expanded--background=#ffffff] - Fill while the card is expanded over
|
|
83
|
+
* its neighbours, so they do not show through; the card's own `background` stays transparent.
|
|
77
84
|
* @cssproperty {number} [--c2-dash-card__expanded--z-index=20]
|
|
85
|
+
* @cssproperty {duration} [--c2-dash-card__enter--animation-duration=200ms] - Fade and scale-in of a card added to
|
|
86
|
+
* a grid that is already on screen, or shown again through the layout record. `0ms` disables it.
|
|
87
|
+
* @cssproperty {duration} [--c2-dash-card__leave--animation-duration=160ms] - Fade-out before a card is hidden by
|
|
88
|
+
* the layout record or removed by `dismiss()`. `0ms` disables it.
|
|
78
89
|
* @cssproperty {duration} [--c2-dash-card__expanded--animation-duration=200ms] - Length of the scale-in the card
|
|
79
90
|
* plays when it expands or collapses. Ignored under `prefers-reduced-motion`.
|
|
80
91
|
*
|
|
@@ -112,8 +123,8 @@ export interface DashCard {
|
|
|
112
123
|
* @cssproperty {outline} [--c2-dash-card__control__focus--outline=2px solid rgba(2, 101, 220, 0.4)]
|
|
113
124
|
* @cssproperty {pixel} [--c2-dash-card__control__focus--outline-offset=2px]
|
|
114
125
|
*
|
|
115
|
-
* @cssproperty {pixel} [--c2-dash-card__handle--size=6px] -
|
|
116
|
-
* the
|
|
126
|
+
* @cssproperty {pixel} [--c2-dash-card__handle--size=6px] - Smallest thickness of the grab area on an edge. Inside a
|
|
127
|
+
* grid the handle is as thick as the gutter when that is wider, centred on the edge, so the whole gutter drags.
|
|
117
128
|
* @cssproperty {pixel} [--c2-dash-card__handle--inset=2px] - Gap between the handle's visible bar and the ends of
|
|
118
129
|
* the edge.
|
|
119
130
|
* @cssproperty {background} [--c2-dash-card__handle--background=transparent]
|
|
@@ -154,6 +165,12 @@ export declare class DashCard extends LitElement {
|
|
|
154
165
|
private hasSlottedControls;
|
|
155
166
|
private hasFooter;
|
|
156
167
|
private dashboard;
|
|
168
|
+
/** `true` while the leave animation plays: the handles are gone, the placement is kept until it ends. */
|
|
169
|
+
private leaving;
|
|
170
|
+
/** The enter or leave animation in flight — or the finished leave, kept so a return can cancel its fill. */
|
|
171
|
+
private motion;
|
|
172
|
+
/** Set when the card should animate in after its next render. */
|
|
173
|
+
private enterPending;
|
|
157
174
|
/** The grid reads this during a drag; a hidden card asks for nothing. */
|
|
158
175
|
get constraint(): DashCardConstraint | undefined;
|
|
159
176
|
connectedCallback(): void;
|
|
@@ -162,13 +179,33 @@ export declare class DashCard extends LitElement {
|
|
|
162
179
|
hostChanged(): void;
|
|
163
180
|
willUpdate(): void;
|
|
164
181
|
updated(): void;
|
|
182
|
+
/**
|
|
183
|
+
* Applies the layout record's `visible`. Hiding is deferred until the leave animation has played; showing again
|
|
184
|
+
* cancels a leave in flight and animates in. Before the first render, and outside a grid, nothing animates.
|
|
185
|
+
*/
|
|
186
|
+
private syncVisibility;
|
|
187
|
+
/**
|
|
188
|
+
* Plays the leave animation, then removes the element from the document. Resolves once it is gone. The other
|
|
189
|
+
* cards keep their placement — the grid does not close the gap; re-place them (`col`/`row` or the grid's
|
|
190
|
+
* `layout`) once the promise resolves if it should.
|
|
191
|
+
*/
|
|
192
|
+
dismiss(): Promise<void>;
|
|
193
|
+
private get surface();
|
|
194
|
+
/** Enter and leave timing, read back from the stylesheet so the variables and `prefers-reduced-motion` apply. */
|
|
195
|
+
private timing;
|
|
196
|
+
private cancelMotion;
|
|
197
|
+
private playEnter;
|
|
198
|
+
/**
|
|
199
|
+
* Fades the card out. Resolves `true` once it has finished — the caller then hides or removes the element — and
|
|
200
|
+
* `false` when a return cancelled it. The end state is held (`fill: forwards`) until the next enter cancels it,
|
|
201
|
+
* so nothing flashes between the last frame and the hide.
|
|
202
|
+
*/
|
|
203
|
+
private leave;
|
|
165
204
|
/**
|
|
166
205
|
* The splitter values are written straight onto the handles rather than re-rendered: a drag changes them on
|
|
167
206
|
* every pointer move, and nothing else about the card changes with them.
|
|
168
207
|
*/
|
|
169
208
|
private syncHandleValues;
|
|
170
|
-
/** `slotchange` does not fire for a server-rendered shadow root, so read every slot once. */
|
|
171
|
-
firstUpdated(): void;
|
|
172
209
|
/**
|
|
173
210
|
* The grid may upgrade after its cards do — the card element is in the document either way, so find it and wait
|
|
174
211
|
* for the definition rather than for a parent that is already alive.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dash-card.d.ts","sourceRoot":"","sources":["../../src/dash-card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAiC,KAAK,cAAc,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"dash-card.d.ts","sourceRoot":"","sources":["../../src/dash-card.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,6 +28,8 @@ export interface DashCardConstraint {
|
|
|
28
28
|
export interface DashboardHost extends HTMLElement {
|
|
29
29
|
readonly columnCount: number;
|
|
30
30
|
readonly rowCount: number;
|
|
31
|
+
/** `true` once the grid has rendered; a card that registers after that arrived at runtime and animates in. */
|
|
32
|
+
readonly hasUpdated: boolean;
|
|
31
33
|
registerCard(card: DashboardCard): void;
|
|
32
34
|
unregisterCard(card: DashboardCard): void;
|
|
33
35
|
/** Resizes one column by `delta` pixels, clamped by the minimums; returns the change that was actually applied. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-host.d.ts","sourceRoot":"","sources":["../../src/dashboard-host.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,oGAAoG;AACpG,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sGAAsG;IACtG,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,iGAAiG;AACjG,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAA;IACvC,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAA;IACzC,mHAAmH;IACnH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IAClD,gHAAgH;IAChH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IAC/C,iEAAiE;IACjE,YAAY,IAAI,IAAI,CAAA;IACpB,kHAAkH;IAClH,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IAC5D,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAAA;CACvE;AAED,sDAAsD;AACtD,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,iFAAiF;IACjF,QAAQ,CAAC,UAAU,EAAE,kBAAkB,GAAG,SAAS,CAAA;IACnD,uEAAuE;IACvE,WAAW,IAAI,IAAI,CAAA;CACpB;AAED,eAAO,MAAM,aAAa,iBAAiB,CAAA"}
|
|
1
|
+
{"version":3,"file":"dashboard-host.d.ts","sourceRoot":"","sources":["../../src/dashboard-host.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,oGAAoG;AACpG,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sGAAsG;IACtG,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,iGAAiG;AACjG,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,8GAA8G;IAC9G,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAA;IACvC,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAA;IACzC,mHAAmH;IACnH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IAClD,gHAAgH;IAChH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IAC/C,iEAAiE;IACjE,YAAY,IAAI,IAAI,CAAA;IACpB,kHAAkH;IAClH,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IAC5D,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAAA;CACvE;AAED,sDAAsD;AACtD,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,iFAAiF;IACjF,QAAQ,CAAC,UAAU,EAAE,kBAAkB,GAAG,SAAS,CAAA;IACnD,uEAAuE;IACvE,WAAW,IAAI,IAAI,CAAA;CACpB;AAED,eAAO,MAAM,aAAa,iBAAiB,CAAA"}
|
package/types/src/dashboard.d.ts
CHANGED
|
@@ -18,6 +18,20 @@ export interface Dashboard {
|
|
|
18
18
|
addEventListener: TypedAddEventListener<Dashboard, DashboardEventMap>;
|
|
19
19
|
removeEventListener: TypedRemoveEventListener<Dashboard, DashboardEventMap>;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* One responsive variant of the grid. The first entry of `layouts` whose media query matches is applied over the
|
|
23
|
+
* authored `columns`, `rows` and `layout`; with none matching the authored ones stand.
|
|
24
|
+
*/
|
|
25
|
+
export interface DashboardResponsiveLayout {
|
|
26
|
+
/** Media query, as given to `matchMedia`: `'(max-width: 1279px)'`. */
|
|
27
|
+
media: string;
|
|
28
|
+
/** Column tracks while this entry is active; the authored `columns` otherwise. */
|
|
29
|
+
columns?: number | string | string[];
|
|
30
|
+
/** Row tracks while this entry is active; the authored `rows` otherwise. */
|
|
31
|
+
rows?: number | string | string[];
|
|
32
|
+
/** Placement overrides by `card-id`, merged per card over the grid's `layout`. */
|
|
33
|
+
layout?: Record<string, DashCardPlacement>;
|
|
34
|
+
}
|
|
21
35
|
/**
|
|
22
36
|
* Grid of resizable panes. The children are `c2-dash-card` elements, placed by their `col`/`row` attributes; each
|
|
23
37
|
* one draws drag handles on the edges it shares with a neighbour, and dragging one resizes the whole track, so the
|
|
@@ -26,6 +40,15 @@ export interface Dashboard {
|
|
|
26
40
|
* the `fr` tracks around it give up the space in proportion to their weight, down to the minimums. With a
|
|
27
41
|
* `storage-key` the sizes survive a reload.
|
|
28
42
|
*
|
|
43
|
+
* `layouts` makes the grid responsive without a remount: each entry names a media query and the tracks and card
|
|
44
|
+
* placements to use while it matches, the first match wins, and every entry keeps its own stored sizes under
|
|
45
|
+
* `<storage-key>@<media>`.
|
|
46
|
+
*
|
|
47
|
+
* Placement is the application's: the grid never re-places cards on its own. A pane removed or hidden at runtime
|
|
48
|
+
* leaves its cells empty and its neighbours where they were, and a pane added at runtime lands exactly where its
|
|
49
|
+
* `col`/`row` say, on top of whatever is already there if that cell is taken. To close a gap, or to make room, set
|
|
50
|
+
* the cards' `col`/`row`/`col-span`/`row-span` or hand the grid a `layout` record — both are applied in place.
|
|
51
|
+
*
|
|
29
52
|
* The grid is the sizing authority: a card never sets its own width. Give the element a height (or place it in a
|
|
30
53
|
* flex/grid parent that does) whenever the rows use `fr`, since the row tracks divide the host's height.
|
|
31
54
|
*
|
|
@@ -33,11 +56,11 @@ export interface Dashboard {
|
|
|
33
56
|
*
|
|
34
57
|
* @slot - The `c2-dash-card` panes. Anything else becomes an ordinary grid item, placed by your own CSS.
|
|
35
58
|
*
|
|
36
|
-
* @event {CustomEvent<DashboardLayoutChangeDetail>} layout-change - The track sizes changed
|
|
37
|
-
* Does not bubble: listen on the element.
|
|
59
|
+
* @event {CustomEvent<DashboardLayoutChangeDetail>} layout-change - The track sizes changed: a gesture ended, `reset()`
|
|
60
|
+
* was called, or another entry of `layouts` took over. Does not bubble: listen on the element.
|
|
38
61
|
*
|
|
39
|
-
* @cssproperty {pixel} [--c2-dashboard--gap=8px] - Gutter between the cards. The
|
|
40
|
-
*
|
|
62
|
+
* @cssproperty {pixel} [--c2-dashboard--gap=8px] - Gutter between the cards. The whole gutter drags: each card's
|
|
63
|
+
* handle is centred on its edge and as thick as the gap (never under `--c2-dash-card__handle--size`).
|
|
41
64
|
* @cssproperty {padding} [--c2-dashboard--padding=0px] - Inset around the tracks. With a `background` it is what
|
|
42
65
|
* turns the gutters into a visible frame between the panes.
|
|
43
66
|
* @cssproperty {background} [--c2-dashboard--background=transparent]
|
|
@@ -58,12 +81,23 @@ export declare class Dashboard extends LitElement {
|
|
|
58
81
|
storageKey: string | undefined;
|
|
59
82
|
/**
|
|
60
83
|
* Placement overrides keyed by the cards' `card-id`, for a layout that is chosen at runtime rather than authored
|
|
61
|
-
* in the markup. Each entry wins over the card's own `col`/`row`/`col-span`/`row-span`/visibility.
|
|
84
|
+
* in the markup. Each entry wins over the card's own `col`/`row`/`col-span`/`row-span`/visibility. This is also
|
|
85
|
+
* how an app re-flows the remaining panes after one was removed: the grid does not do that by itself.
|
|
62
86
|
*/
|
|
63
87
|
layout: Record<string, DashCardPlacement> | undefined;
|
|
88
|
+
/**
|
|
89
|
+
* Responsive variants, in priority order: the first entry whose `media` matches supplies the tracks and the card
|
|
90
|
+
* placements, and the grid switches as the viewport crosses a breakpoint. Nothing is stored across entries — each
|
|
91
|
+
* one keeps its own sizes under `<storage-key>@<media>`.
|
|
92
|
+
*/
|
|
93
|
+
layouts: DashboardResponsiveLayout[] | undefined;
|
|
64
94
|
private columnTracks;
|
|
65
95
|
private rowTracks;
|
|
96
|
+
/** Index into `layouts` of the entry in force, `-1` for the authored grid. */
|
|
97
|
+
private activeLayout;
|
|
66
98
|
private cards;
|
|
99
|
+
private mediaQueries;
|
|
100
|
+
private readonly handleMediaChange;
|
|
67
101
|
/** Used track sizes, valid until the next write to the tracks. */
|
|
68
102
|
private pixelCache;
|
|
69
103
|
/** Column tracks as they are laid out right now. */
|
|
@@ -72,9 +106,13 @@ export declare class Dashboard extends LitElement {
|
|
|
72
106
|
get rowSizes(): string[];
|
|
73
107
|
get columnCount(): number;
|
|
74
108
|
get rowCount(): number;
|
|
109
|
+
/** The entry of `layouts` in force, or `undefined` while the authored grid is. */
|
|
110
|
+
get activeResponsiveLayout(): DashboardResponsiveLayout | undefined;
|
|
111
|
+
connectedCallback(): void;
|
|
112
|
+
disconnectedCallback(): void;
|
|
75
113
|
protected willUpdate(changed: PropertyValues): void;
|
|
76
114
|
protected updated(changed: PropertyValues): void;
|
|
77
|
-
/** Back to the authored tracks, and
|
|
115
|
+
/** Back to the authored tracks of the layout in force, and its stored ones are forgotten. */
|
|
78
116
|
reset(): void;
|
|
79
117
|
registerCard(card: DashboardCard): void;
|
|
80
118
|
unregisterCard(card: DashboardCard): void;
|
|
@@ -98,6 +136,15 @@ export declare class Dashboard extends LitElement {
|
|
|
98
136
|
private resizeTrack;
|
|
99
137
|
/** The largest minimum any card covering this track asks for, spread over the tracks that card spans. */
|
|
100
138
|
private trackMin;
|
|
139
|
+
/**
|
|
140
|
+
* One `MediaQueryList` per entry of `layouts`, listened to for as long as the element is connected. Whichever
|
|
141
|
+
* entry matches first is the one in force; the listeners re-run the choice whenever any of them flips.
|
|
142
|
+
*/
|
|
143
|
+
private watchMedia;
|
|
144
|
+
private unwatchMedia;
|
|
145
|
+
private resolveActiveLayout;
|
|
146
|
+
/** Each entry of `layouts` stores its own sizes: `<storage-key>@<media>`; the authored grid uses the bare key. */
|
|
147
|
+
private get activeStorageKey();
|
|
101
148
|
private syncTracks;
|
|
102
149
|
private readStored;
|
|
103
150
|
private persist;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAA;AAItE,OAAO,KAAK,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAIxE,OAAO,aAAa,CAAA;AAEpB,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEzD,4FAA4F;AAC5F,MAAM,WAAW,2BAA2B;IAC1C,8CAA8C;IAC9C,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,kBAAkB;IAClB,IAAI,EAAE,MAAM,EAAE,CAAA;CACf;AAED,uEAAuE;AACvE,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,WAAW,CAAC,2BAA2B,CAAC,CAAA;CAC1D;AAED,MAAM,WAAW,SAAS;IACxB,gBAAgB,EAAE,qBAAqB,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAA;IACrE,mBAAmB,EAAE,wBAAwB,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAA;CAC5E;AAiCD
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/dashboard.ts"],"names":[],"mappings":"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"}
|