@schukai/monster 4.148.8 → 4.149.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/package.json +1 -1
- package/source/components/accessibility/stylesheet/locale-picker.mjs +61 -1
- package/source/components/content/image-editor.mjs +79 -11
- package/source/components/content/style/copy.pcss +1 -1
- package/source/components/content/stylesheet/camera-capture.mjs +1 -1
- package/source/components/content/stylesheet/copy.mjs +1 -1
- package/source/components/content/stylesheet/fetch-box.mjs +1 -1
- package/source/components/content/stylesheet/viewer.mjs +61 -1
- package/source/components/data/kpi-tile.mjs +5 -3
- package/source/components/data/metric-graph.mjs +22 -20
- package/source/components/data/metric.mjs +20 -18
- package/source/components/data/style/kpi-tile.pcss +65 -43
- package/source/components/data/style/metric-graph.pcss +35 -18
- package/source/components/data/style/metric.pcss +35 -28
- package/source/components/data/stylesheet/kpi-tile.mjs +61 -1
- package/source/components/data/stylesheet/metric-graph.mjs +61 -1
- package/source/components/data/stylesheet/metric.mjs +61 -1
- package/source/components/datatable/columnbar.mjs +4 -2
- package/source/components/datatable/datatable.mjs +73 -15
- package/source/components/datatable/filter/date-range.mjs +61 -61
- package/source/components/datatable/filter/date-time.mjs +5 -1
- package/source/components/datatable/filter/range.mjs +3 -3
- package/source/components/datatable/filter/select-operator.mjs +7 -1
- package/source/components/datatable/filter/text-operator.mjs +11 -3
- package/source/components/datatable/filter.mjs +16 -0
- package/source/components/datatable/pagination.mjs +2 -2
- package/source/components/datatable/style/column-bar.pcss +115 -23
- package/source/components/datatable/style/datatable.pcss +257 -29
- package/source/components/datatable/style/embedded-pagination.pcss +63 -34
- package/source/components/datatable/style/filter-button.pcss +1 -1
- package/source/components/datatable/style/filter-controls-defaults.pcss +49 -3
- package/source/components/datatable/style/filter-select.pcss +4 -1
- package/source/components/datatable/style/filter.pcss +18 -1
- package/source/components/datatable/stylesheet/change-button.mjs +61 -1
- package/source/components/datatable/stylesheet/column-bar.mjs +69 -1
- package/source/components/datatable/stylesheet/dataset.mjs +61 -1
- package/source/components/datatable/stylesheet/datatable.mjs +71 -1
- package/source/components/datatable/stylesheet/embedded-pagination.mjs +1 -1
- package/source/components/datatable/stylesheet/filter-button.mjs +1 -1
- package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +1 -1
- package/source/components/datatable/stylesheet/filter-select.mjs +61 -1
- package/source/components/datatable/stylesheet/filter.mjs +61 -1
- package/source/components/datatable/stylesheet/pagination.mjs +67 -1
- package/source/components/datatable/stylesheet/save-button.mjs +61 -1
- package/source/components/datatable/stylesheet/status.mjs +61 -1
- package/source/components/form/action-button.mjs +2 -1
- package/source/components/form/button-bar.mjs +7 -2
- package/source/components/form/context-error.mjs +4 -3
- package/source/components/form/context-help.mjs +10 -4
- package/source/components/form/context-hint.mjs +1 -1
- package/source/components/form/context-info.mjs +1 -1
- package/source/components/form/context-note.mjs +1 -1
- package/source/components/form/context-success.mjs +1 -1
- package/source/components/form/context-warning.mjs +1 -1
- package/source/components/form/control-bar.mjs +300 -14
- package/source/components/form/credential-button.mjs +4 -2
- package/source/components/form/digits.mjs +28 -1
- package/source/components/form/field-set.mjs +30 -0
- package/source/components/form/login.mjs +13 -10
- package/source/components/form/password.mjs +6 -0
- package/source/components/form/popper-button.mjs +1 -1
- package/source/components/form/quantity.mjs +14 -6
- package/source/components/form/register-wizard.mjs +46 -26
- package/source/components/form/select.mjs +17 -10
- package/source/components/form/sheet.mjs +13 -2
- package/source/components/form/style/action-button.pcss +131 -5
- package/source/components/form/style/button-bar.pcss +204 -3
- package/source/components/form/style/control-bar.pcss +254 -26
- package/source/components/form/style/digits.pcss +7 -6
- package/source/components/form/style/input-group.pcss +65 -1
- package/source/components/form/style/login.pcss +1 -1
- package/source/components/form/style/mixin/field-set-layout.pcss +8 -0
- package/source/components/form/style/password.pcss +25 -1
- package/source/components/form/style/popper-button.pcss +1 -0
- package/source/components/form/style/quantity.pcss +11 -20
- package/source/components/form/style/select.pcss +52 -7
- package/source/components/form/style/sheet.pcss +70 -1
- package/source/components/form/style/state-button.pcss +5 -2
- package/source/components/form/style/toggle-switch.pcss +7 -4
- package/source/components/form/stylesheet/action-button.mjs +63 -1
- package/source/components/form/stylesheet/button-bar.mjs +153 -1
- package/source/components/form/stylesheet/button.mjs +61 -1
- package/source/components/form/stylesheet/control-bar.mjs +163 -1
- package/source/components/form/stylesheet/digits.mjs +1 -1
- package/source/components/form/stylesheet/field-layout.mjs +1 -1
- package/source/components/form/stylesheet/field-set.mjs +1 -1
- package/source/components/form/stylesheet/form.mjs +1 -1
- package/source/components/form/stylesheet/input-group.mjs +15 -1
- package/source/components/form/stylesheet/login.mjs +1 -1
- package/source/components/form/stylesheet/password.mjs +7 -1
- package/source/components/form/stylesheet/popper-button.mjs +61 -1
- package/source/components/form/stylesheet/quantity.mjs +1 -1
- package/source/components/form/stylesheet/register-wizard.mjs +1 -1
- package/source/components/form/stylesheet/select.mjs +3 -1
- package/source/components/form/stylesheet/sheet.mjs +1 -1
- package/source/components/form/stylesheet/state-button.mjs +3 -1
- package/source/components/form/stylesheet/toggle-switch.mjs +1 -1
- package/source/components/form/stylesheet/wizard.mjs +1 -1
- package/source/components/form/util/floating-ui.mjs +35 -7
- package/source/components/host/call-button.mjs +3 -1
- package/source/components/host/stylesheet/call-button.mjs +61 -1
- package/source/components/host/stylesheet/host.mjs +1 -1
- package/source/components/host/stylesheet/toggle-button.mjs +61 -1
- package/source/components/layout/full-screen.mjs +31 -23
- package/source/components/layout/iframe.mjs +5 -1
- package/source/components/layout/popper.mjs +34 -4
- package/source/components/layout/style/full-screen.pcss +94 -23
- package/source/components/layout/style/split-panel.pcss +57 -5
- package/source/components/layout/style/tabs.pcss +277 -47
- package/source/components/layout/style/vertical-tabs.pcss +147 -0
- package/source/components/layout/stylesheet/collapse.mjs +61 -1
- package/source/components/layout/stylesheet/details.mjs +61 -1
- package/source/components/layout/stylesheet/full-screen.mjs +23 -1
- package/source/components/layout/stylesheet/overlay.mjs +1 -1
- package/source/components/layout/stylesheet/panel.mjs +1 -1
- package/source/components/layout/stylesheet/slider.mjs +1 -1
- package/source/components/layout/stylesheet/split-panel.mjs +17 -1
- package/source/components/layout/stylesheet/tabs.mjs +97 -1
- package/source/components/layout/stylesheet/vertical-tabs.mjs +33 -95
- package/source/components/layout/tabs.mjs +63 -0
- package/source/components/layout/vertical-tabs.mjs +63 -0
- package/source/components/navigation/stylesheet/site-navigation.mjs +1 -1
- package/source/components/navigation/stylesheet/table-of-content.mjs +1 -1
- package/source/components/navigation/stylesheet/wizard-navigation.mjs +1 -1
- package/source/components/navigation/table-of-content.mjs +13 -0
- package/source/components/notify/style/notify.pcss +1 -2
- package/source/components/notify/stylesheet/message.mjs +1 -1
- package/source/components/notify/stylesheet/notify.mjs +1 -1
- package/source/components/state/style/log.pcss +1 -0
- package/source/components/state/style/state.pcss +5 -1
- package/source/components/state/stylesheet/log.mjs +1 -1
- package/source/components/state/stylesheet/state.mjs +7 -1
- package/source/components/style/button.css +61 -205
- package/source/components/style/button.pcss +78 -34
- package/source/components/style/common.css +1 -170
- package/source/components/style/common.pcss +5 -9
- package/source/components/style/form.css +1 -49
- package/source/components/style/form.pcss +24 -6
- package/source/components/style/link.css +1 -39
- package/source/components/style/link.pcss +8 -16
- package/source/components/style/mixin/button.pcss +19 -10
- package/source/components/style/mixin/property.pcss +8 -0
- package/source/components/style/mixin/skeleton.pcss +11 -5
- package/source/components/style/normalize.css +1 -144
- package/source/components/style/normalize.pcss +5 -5
- package/source/components/style/property.css +1 -387
- package/source/components/style/skeleton.css +1 -198
- package/source/components/style/skeleton.pcss +8 -2
- package/source/components/style/theme-modern.css +74 -0
- package/source/components/style/theme-modern.pcss +498 -0
- package/source/components/stylesheet/button.mjs +61 -1
- package/source/components/stylesheet/common.mjs +1 -1
- package/source/components/stylesheet/form.mjs +1 -1
- package/source/components/stylesheet/link.mjs +1 -1
- package/source/components/stylesheet/normalize.mjs +1 -1
- package/source/components/stylesheet/property.mjs +1 -1
- package/source/components/stylesheet/skeleton.mjs +1 -1
- package/source/components/stylesheet/theme-modern.mjs +110 -0
- package/source/components/time/stylesheet/day.mjs +61 -1
- package/source/components/time/stylesheet/month-calendar.mjs +61 -1
- package/source/components/time/timeline/stylesheet/appointment.mjs +61 -1
- package/source/components/time/timeline/stylesheet/segment.mjs +61 -1
- package/source/components/tree-menu/style/tree-menu.pcss +26 -37
- package/source/components/tree-menu/stylesheet/tree-menu.mjs +1 -1
- package/source/dom/customelement.mjs +105 -40
- package/source/dom/updater.mjs +381 -119
- package/test/cases/components/content/image-editor.mjs +19 -0
- package/test/cases/components/datatable/accessibility-defaults.mjs +112 -0
- package/test/cases/components/datatable/filter-availability.mjs +37 -0
- package/test/cases/components/datatable/filter-date-range-layout.mjs +40 -0
- package/test/cases/components/datatable/filter-select-operator.mjs +118 -0
- package/test/cases/components/datatable/mobile-layout.mjs +203 -0
- package/test/cases/components/datatable/responsive-breakpoint.mjs +41 -0
- package/test/cases/components/datatable/selection.mjs +149 -0
- package/test/cases/components/form/action-button-style.mjs +85 -0
- package/test/cases/components/form/button-bar.mjs +222 -3
- package/test/cases/components/form/context-theme-colors.mjs +59 -0
- package/test/cases/components/form/control-bar.mjs +228 -3
- package/test/cases/components/form/control-heights.mjs +103 -0
- package/test/cases/components/form/digits-accessibility.mjs +65 -0
- package/test/cases/components/form/field-set.mjs +54 -0
- package/test/cases/components/form/floating-ui.mjs +74 -0
- package/test/cases/components/form/input-group.mjs +61 -28
- package/test/cases/components/form/login.mjs +47 -0
- package/test/cases/components/form/password.mjs +63 -0
- package/test/cases/components/form/popper-button.mjs +30 -15
- package/test/cases/components/form/quantity-accessibility.mjs +46 -0
- package/test/cases/components/form/register-wizard.mjs +79 -0
- package/test/cases/components/form/select.mjs +94 -2
- package/test/cases/components/form/sheet.mjs +56 -2
- package/test/cases/components/host/toggle-button.mjs +50 -0
- package/test/cases/components/layout/full-screen.mjs +60 -0
- package/test/cases/components/layout/iframe-accessibility.mjs +44 -0
- package/test/cases/components/layout/popper.mjs +128 -0
- package/test/cases/components/layout/slit-panel.mjs +30 -1
- package/test/cases/components/layout/tabs.mjs +93 -0
- package/test/cases/components/navigation/table-of-content.mjs +18 -0
- package/test/cases/components/state/state-style.mjs +31 -0
- package/test/cases/components/style/action-menu.mjs +74 -0
- package/test/cases/components/style/form-controls.mjs +37 -0
- package/test/cases/components/style/kpi-tile.mjs +60 -0
- package/test/cases/components/style/legacy-theme-compatibility.mjs +137 -0
- package/test/cases/components/style/metric-layout.mjs +94 -0
- package/test/cases/components/style/skeleton.mjs +69 -0
- package/test/cases/components/style/theme-component-catalog.mjs +853 -0
- package/test/cases/components/style/theme-modern.mjs +439 -0
- package/test/cases/components/style/theme-review-regressions.mjs +41 -0
- package/test/cases/dom/customelement.mjs +136 -1
- package/test/cases/dom/updater.mjs +174 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
import {readFileSync} from "node:fs";
|
|
3
4
|
import * as chai from 'chai';
|
|
4
5
|
import {getDocument} from "../../../../source/dom/util.mjs";
|
|
5
6
|
import {chaiDom} from "../../../util/chai-dom.mjs";
|
|
@@ -90,4 +91,22 @@ describe('ImageEditor', function () {
|
|
|
90
91
|
}
|
|
91
92
|
}, 20);
|
|
92
93
|
});
|
|
94
|
+
|
|
95
|
+
it('keeps narrow split-panel form controls in full-width field rows', function () {
|
|
96
|
+
const source = readFileSync(
|
|
97
|
+
new URL(
|
|
98
|
+
"../../../../source/components/content/image-editor.mjs",
|
|
99
|
+
import.meta.url,
|
|
100
|
+
),
|
|
101
|
+
"utf8",
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
expect(source).to.include(".image-editor-field");
|
|
105
|
+
expect(source).to.include(
|
|
106
|
+
'<label class="grid-span-full image-editor-field">',
|
|
107
|
+
);
|
|
108
|
+
expect(source).to.include(
|
|
109
|
+
'<monster-button-bar class="grid-span-full monster-margin-top-2">',
|
|
110
|
+
);
|
|
111
|
+
});
|
|
93
112
|
});
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import * as chai from "chai";
|
|
2
|
+
import { getGlobal } from "../../../../source/types/global.mjs";
|
|
3
|
+
import { initJSDOM } from "../../../util/jsdom.mjs";
|
|
4
|
+
import { ResizeObserverMock } from "../../../util/resize-observer.mjs";
|
|
5
|
+
|
|
6
|
+
const { expect } = chai;
|
|
7
|
+
const nextTask = () => new Promise((resolve) => setTimeout(resolve, 0));
|
|
8
|
+
|
|
9
|
+
describe("Datatable accessibility defaults", function () {
|
|
10
|
+
before(async () => {
|
|
11
|
+
await initJSDOM();
|
|
12
|
+
await import("element-internals-polyfill");
|
|
13
|
+
const global = getGlobal();
|
|
14
|
+
global.ResizeObserver ??= ResizeObserverMock;
|
|
15
|
+
await Promise.all([
|
|
16
|
+
import("../../../../source/components/datatable/filter/date-range.mjs"),
|
|
17
|
+
import("../../../../source/components/datatable/filter/date-time.mjs"),
|
|
18
|
+
import("../../../../source/components/datatable/filter/range.mjs"),
|
|
19
|
+
import(
|
|
20
|
+
"../../../../source/components/datatable/filter/text-operator.mjs"
|
|
21
|
+
),
|
|
22
|
+
import("../../../../source/components/datatable/columnbar.mjs"),
|
|
23
|
+
]);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
afterEach(() => {
|
|
27
|
+
document.getElementById("mocks").replaceChildren();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
for (const [tag, option, selector] of [
|
|
31
|
+
[
|
|
32
|
+
"monster-filter-date-range",
|
|
33
|
+
"Choose reporting period",
|
|
34
|
+
'[data-monster-role="input"]',
|
|
35
|
+
],
|
|
36
|
+
[
|
|
37
|
+
"monster-filter-range",
|
|
38
|
+
"Choose score range",
|
|
39
|
+
'[data-monster-role="input"]',
|
|
40
|
+
],
|
|
41
|
+
]) {
|
|
42
|
+
it(`should name the ${tag} trigger from labels.button`, async function () {
|
|
43
|
+
const filter = document.createElement(tag);
|
|
44
|
+
filter.setOption("labels.button", option);
|
|
45
|
+
document.getElementById("mocks").append(filter);
|
|
46
|
+
await nextTask();
|
|
47
|
+
|
|
48
|
+
expect(
|
|
49
|
+
filter.shadowRoot.querySelector(selector).getAttribute("aria-label"),
|
|
50
|
+
).to.equal(option);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
it("should name the date-time query input", async function () {
|
|
55
|
+
const filter = document.createElement("monster-filter-date-time");
|
|
56
|
+
filter.setOption("labels.query", "Updated after");
|
|
57
|
+
document.getElementById("mocks").append(filter);
|
|
58
|
+
await nextTask();
|
|
59
|
+
|
|
60
|
+
expect(
|
|
61
|
+
filter.shadowRoot
|
|
62
|
+
.querySelector('[data-monster-role="query"]')
|
|
63
|
+
.getAttribute("aria-label"),
|
|
64
|
+
).to.equal("Updated after");
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("should name both text-operator controls", async function () {
|
|
68
|
+
const filter = document.createElement("monster-filter-text-operator");
|
|
69
|
+
filter.setOptions({
|
|
70
|
+
labels: {
|
|
71
|
+
operator: "Comparison",
|
|
72
|
+
query: "Search term",
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
document.getElementById("mocks").append(filter);
|
|
76
|
+
await nextTask();
|
|
77
|
+
|
|
78
|
+
expect(
|
|
79
|
+
filter.shadowRoot
|
|
80
|
+
.querySelector('[data-monster-role="operator"]')
|
|
81
|
+
.getAttribute("aria-label"),
|
|
82
|
+
).to.equal("Comparison");
|
|
83
|
+
expect(
|
|
84
|
+
filter.shadowRoot
|
|
85
|
+
.querySelector('[data-monster-role="query"]')
|
|
86
|
+
.getAttribute("aria-label"),
|
|
87
|
+
).to.equal("Search term");
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("should render column toggles as named stateful buttons", async function () {
|
|
91
|
+
const columnBar = document.createElement("monster-column-bar");
|
|
92
|
+
columnBar.setOption("columns", [
|
|
93
|
+
{ index: 0, name: "Name", visible: true },
|
|
94
|
+
{ index: 1, name: "Status", visible: false },
|
|
95
|
+
]);
|
|
96
|
+
document.getElementById("mocks").append(columnBar);
|
|
97
|
+
await nextTask();
|
|
98
|
+
|
|
99
|
+
const buttons = [
|
|
100
|
+
...columnBar.shadowRoot.querySelectorAll(
|
|
101
|
+
'[data-monster-role="dots"] button[data-monster-role="column"]',
|
|
102
|
+
),
|
|
103
|
+
];
|
|
104
|
+
expect(buttons).to.have.length(2);
|
|
105
|
+
expect(
|
|
106
|
+
buttons.map((button) => button.getAttribute("aria-label")),
|
|
107
|
+
).to.deep.equal(["Name", "Status"]);
|
|
108
|
+
expect(
|
|
109
|
+
buttons.map((button) => button.getAttribute("aria-pressed")),
|
|
110
|
+
).to.deep.equal(["true", "false"]);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { strict as assert } from "node:assert";
|
|
2
|
+
import { getGlobal } from "../../../../source/types/global.mjs";
|
|
3
|
+
import { initJSDOM } from "../../../util/jsdom.mjs";
|
|
4
|
+
import { ResizeObserverMock } from "../../../util/resize-observer.mjs";
|
|
5
|
+
|
|
6
|
+
describe("Datatable filter availability", () => {
|
|
7
|
+
before(async () => {
|
|
8
|
+
await initJSDOM();
|
|
9
|
+
await import("element-internals-polyfill");
|
|
10
|
+
|
|
11
|
+
const global = getGlobal();
|
|
12
|
+
if (!global.ResizeObserver) {
|
|
13
|
+
global.ResizeObserver = ResizeObserverMock;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
await import("../../../../source/components/datatable/filter.mjs");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
document.getElementById("mocks").replaceChildren();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("disables filter actions when no filter definitions exist", async () => {
|
|
24
|
+
globalThis.name = "";
|
|
25
|
+
globalThis.location = window.location;
|
|
26
|
+
const element = document.createElement("monster-datatable-filter");
|
|
27
|
+
document.getElementById("mocks").append(element);
|
|
28
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
29
|
+
|
|
30
|
+
for (const role of ["filter-select", "search-button", "reset-button"]) {
|
|
31
|
+
const control = element.shadowRoot.querySelector(
|
|
32
|
+
`[data-monster-role="${role}"]`,
|
|
33
|
+
);
|
|
34
|
+
assert.equal(control.getOption("disabled"), true, role);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { strict as assert } from "node:assert";
|
|
2
|
+
import { getGlobal } from "../../../../source/types/global.mjs";
|
|
3
|
+
import { initJSDOM } from "../../../util/jsdom.mjs";
|
|
4
|
+
import { ResizeObserverMock } from "../../../util/resize-observer.mjs";
|
|
5
|
+
|
|
6
|
+
describe("Datatable date-range filter layout", () => {
|
|
7
|
+
before(async () => {
|
|
8
|
+
await initJSDOM();
|
|
9
|
+
await import("element-internals-polyfill");
|
|
10
|
+
|
|
11
|
+
const global = getGlobal();
|
|
12
|
+
if (!global.ResizeObserver) {
|
|
13
|
+
global.ResizeObserver = ResizeObserverMock;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
await import(
|
|
17
|
+
"../../../../source/components/datatable/filter/date-range.mjs"
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
document.getElementById("mocks").replaceChildren();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("keeps its fields inside the adaptive popper content area", async () => {
|
|
26
|
+
const element = document.createElement("monster-filter-date-range");
|
|
27
|
+
document.getElementById("mocks").append(element);
|
|
28
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
29
|
+
|
|
30
|
+
const popper = element.shadowRoot.querySelector(
|
|
31
|
+
'[data-monster-role="popper"]',
|
|
32
|
+
);
|
|
33
|
+
const content = popper.querySelector("[part=content]");
|
|
34
|
+
assert.ok(content);
|
|
35
|
+
|
|
36
|
+
const filter = content.querySelector("[part=filter]");
|
|
37
|
+
assert.ok(filter);
|
|
38
|
+
assert.ok(filter.querySelector('[data-monster-role="form"]'));
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { strict as assert } from "node:assert";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { getGlobal } from "../../../../source/types/global.mjs";
|
|
4
|
+
import { initJSDOM } from "../../../util/jsdom.mjs";
|
|
5
|
+
import { ResizeObserverMock } from "../../../util/resize-observer.mjs";
|
|
6
|
+
|
|
7
|
+
const filterSelectSource = readFileSync(
|
|
8
|
+
new URL(
|
|
9
|
+
"../../../../source/components/datatable/style/filter-select.pcss",
|
|
10
|
+
import.meta.url,
|
|
11
|
+
),
|
|
12
|
+
"utf8",
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
const filterSelectGenerated = readFileSync(
|
|
16
|
+
new URL(
|
|
17
|
+
"../../../../source/components/datatable/stylesheet/filter-select.mjs",
|
|
18
|
+
import.meta.url,
|
|
19
|
+
),
|
|
20
|
+
"utf8",
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const waitForUpdates = () =>
|
|
24
|
+
new Promise((resolve) => {
|
|
25
|
+
setTimeout(resolve, 300);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe("Datatable select operator filter", () => {
|
|
29
|
+
before(async () => {
|
|
30
|
+
await initJSDOM();
|
|
31
|
+
await import("element-internals-polyfill");
|
|
32
|
+
|
|
33
|
+
const global = getGlobal();
|
|
34
|
+
if (!global.ResizeObserver) {
|
|
35
|
+
global.ResizeObserver = ResizeObserverMock;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
await import(
|
|
39
|
+
"../../../../source/components/datatable/filter/select-operator.mjs"
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
afterEach(() => {
|
|
44
|
+
document.getElementById("mocks").replaceChildren();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("keeps option markers compact after shared form defaults", () => {
|
|
48
|
+
for (const property of ["height", "min-height", "min-width", "width"]) {
|
|
49
|
+
assert.match(
|
|
50
|
+
filterSelectSource,
|
|
51
|
+
new RegExp(
|
|
52
|
+
`${property}: var\\(--monster-select-option-control-size, 1rem\\)`,
|
|
53
|
+
"u",
|
|
54
|
+
),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
assert.match(
|
|
58
|
+
filterSelectGenerated,
|
|
59
|
+
/height:var\(--monster-select-option-control-size,1rem\)/u,
|
|
60
|
+
);
|
|
61
|
+
assert.match(
|
|
62
|
+
filterSelectGenerated,
|
|
63
|
+
/min-height:var\(--monster-select-option-control-size,1rem\)/u,
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("summarizes multiple selected values inside the fixed-height control", async () => {
|
|
68
|
+
const element = document.createElement(
|
|
69
|
+
"monster-filter-select-operator",
|
|
70
|
+
);
|
|
71
|
+
const options = [
|
|
72
|
+
{ value: "ready", label: "Ready" },
|
|
73
|
+
{ value: "review", label: "Review" },
|
|
74
|
+
{ value: "blocked", label: "Blocked" },
|
|
75
|
+
{ value: "progress", label: "In progress" },
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
element.setOptions({
|
|
79
|
+
select: {
|
|
80
|
+
options,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
document.getElementById("mocks").append(element);
|
|
84
|
+
await waitForUpdates();
|
|
85
|
+
element.selection = options.map(({ value }) => value);
|
|
86
|
+
await waitForUpdates();
|
|
87
|
+
|
|
88
|
+
const select = element.shadowRoot.querySelector(
|
|
89
|
+
"monster-filter-select",
|
|
90
|
+
);
|
|
91
|
+
const summary = select.shadowRoot.querySelector('[part="summary"]');
|
|
92
|
+
|
|
93
|
+
assert.equal(
|
|
94
|
+
select.getAttribute("data-monster-selected-template"),
|
|
95
|
+
"summary",
|
|
96
|
+
);
|
|
97
|
+
assert.ok(summary);
|
|
98
|
+
assert.equal(
|
|
99
|
+
select.shadowRoot.querySelectorAll('[data-monster-role="badge"]')
|
|
100
|
+
.length,
|
|
101
|
+
0,
|
|
102
|
+
);
|
|
103
|
+
assert.match(
|
|
104
|
+
summary.querySelector('[part="summary-messages"]').textContent,
|
|
105
|
+
/4/u,
|
|
106
|
+
);
|
|
107
|
+
assert.deepEqual(element.selection, [
|
|
108
|
+
"ready",
|
|
109
|
+
"review",
|
|
110
|
+
"blocked",
|
|
111
|
+
"progress",
|
|
112
|
+
]);
|
|
113
|
+
assert.equal(
|
|
114
|
+
element.value,
|
|
115
|
+
"one-of:ready,review,blocked,progress",
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { expect } from "chai";
|
|
3
|
+
|
|
4
|
+
const source = readFileSync(
|
|
5
|
+
new URL(
|
|
6
|
+
"../../../../source/components/datatable/style/datatable.pcss",
|
|
7
|
+
import.meta.url,
|
|
8
|
+
),
|
|
9
|
+
"utf8",
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
const generated = readFileSync(
|
|
13
|
+
new URL(
|
|
14
|
+
"../../../../source/components/datatable/stylesheet/datatable.mjs",
|
|
15
|
+
import.meta.url,
|
|
16
|
+
),
|
|
17
|
+
"utf8",
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const columnBarSource = readFileSync(
|
|
21
|
+
new URL(
|
|
22
|
+
"../../../../source/components/datatable/style/column-bar.pcss",
|
|
23
|
+
import.meta.url,
|
|
24
|
+
),
|
|
25
|
+
"utf8",
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const columnBarGenerated = readFileSync(
|
|
29
|
+
new URL(
|
|
30
|
+
"../../../../source/components/datatable/stylesheet/column-bar.mjs",
|
|
31
|
+
import.meta.url,
|
|
32
|
+
),
|
|
33
|
+
"utf8",
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const embeddedPaginationSource = readFileSync(
|
|
37
|
+
new URL(
|
|
38
|
+
"../../../../source/components/datatable/style/embedded-pagination.pcss",
|
|
39
|
+
import.meta.url,
|
|
40
|
+
),
|
|
41
|
+
"utf8",
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const embeddedPaginationGenerated = readFileSync(
|
|
45
|
+
new URL(
|
|
46
|
+
"../../../../source/components/datatable/stylesheet/embedded-pagination.mjs",
|
|
47
|
+
import.meta.url,
|
|
48
|
+
),
|
|
49
|
+
"utf8",
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
describe("Datatable mobile layout", () => {
|
|
53
|
+
it("groups responsive cells into readable row cards", () => {
|
|
54
|
+
expect(source).to.include("[data-monster-datatable-row-start]");
|
|
55
|
+
expect(source).to.include("[data-monster-datatable-row-end]");
|
|
56
|
+
expect(source).to.include("grid-template-columns:");
|
|
57
|
+
expect(source).to.include("content: attr(data-monster-head)");
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("gives mobile actions and multiselects the full card width", () => {
|
|
61
|
+
for (const selector of [
|
|
62
|
+
"monster-button",
|
|
63
|
+
"monster-button-bar",
|
|
64
|
+
"monster-filter-select",
|
|
65
|
+
"monster-select",
|
|
66
|
+
"select[multiple]",
|
|
67
|
+
]) {
|
|
68
|
+
expect(source).to.include(selector);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
expect(source).to.include("var(--monster-control-min-block-size, 44px)");
|
|
72
|
+
expect(source).to.include("var(--monster-bg-color-selection-2)");
|
|
73
|
+
expect(source).to.include("width: 100%");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("keeps adjoining mobile row actions visually joined", () => {
|
|
77
|
+
expect(source).to.include("--monster-button-bar-gap: 0");
|
|
78
|
+
expect(source).not.to.include("--monster-button-bar-gap: 0.5rem");
|
|
79
|
+
expect(generated).to.include("--monster-button-bar-gap:0");
|
|
80
|
+
expect(generated).not.to.include("--monster-button-bar-gap:0.5rem");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("stacks labels above values when a responsive card becomes narrow", () => {
|
|
84
|
+
expect(source).to.include("container-name: monster-datatable-responsive");
|
|
85
|
+
expect(source).to.include("container-type: inline-size");
|
|
86
|
+
expect(source).to.include(
|
|
87
|
+
"@container monster-datatable-responsive (max-width: 26rem)",
|
|
88
|
+
);
|
|
89
|
+
expect(source).to.include("max-inline-size: 100%");
|
|
90
|
+
expect(source).to.include("min-inline-size: 0");
|
|
91
|
+
expect(source).to.include("grid-template-columns: minmax(0, 1fr)");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("groups narrow toolbar utilities into a compact action cluster", () => {
|
|
95
|
+
expect(source).to.include('slot[name="bar"]::slotted(*)');
|
|
96
|
+
expect(source).to.include("flex-flow: row wrap");
|
|
97
|
+
expect(source).to.include(
|
|
98
|
+
"--monster-datatable-utility-action-size: 2.25rem",
|
|
99
|
+
);
|
|
100
|
+
expect(source).to.include("margin-inline-start: auto");
|
|
101
|
+
expect(source).to.include("font-size: 0");
|
|
102
|
+
expect(source).to.include("monster-context-help::part(button)");
|
|
103
|
+
expect(source).to.include("var(--monster-control-min-block-size, 44px)");
|
|
104
|
+
expect(columnBarSource).to.include(":host(.small)");
|
|
105
|
+
expect(columnBarSource).to.include(
|
|
106
|
+
"--monster-datatable-utility-action-size: 2.25rem",
|
|
107
|
+
);
|
|
108
|
+
expect(columnBarSource).to.include("font-size: 0");
|
|
109
|
+
expect(columnBarSource).to.include("display: none");
|
|
110
|
+
expect(columnBarSource).to.include("@media (pointer: coarse)");
|
|
111
|
+
expect(generated).to.include(
|
|
112
|
+
"--monster-datatable-utility-action-size:2.25rem",
|
|
113
|
+
);
|
|
114
|
+
expect(generated).to.include("flex-flow:row wrap");
|
|
115
|
+
expect(columnBarGenerated).to.include(
|
|
116
|
+
"--monster-datatable-utility-action-size:2.25rem",
|
|
117
|
+
);
|
|
118
|
+
expect(columnBarGenerated).to.include("font-size:0");
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("keeps column visibility dots compact and touch friendly", () => {
|
|
122
|
+
expect(columnBarSource).to.include(
|
|
123
|
+
"var(--monster-column-toggle-target-size, 16px)",
|
|
124
|
+
);
|
|
125
|
+
expect(columnBarSource).to.include(
|
|
126
|
+
"--monster-column-toggle-target-inline-size",
|
|
127
|
+
);
|
|
128
|
+
expect(columnBarSource).to.include(
|
|
129
|
+
"--monster-column-toggle-target-block-size",
|
|
130
|
+
);
|
|
131
|
+
expect(columnBarSource).to.include("& li {");
|
|
132
|
+
expect(columnBarSource).to.include("margin: 0;");
|
|
133
|
+
expect(columnBarSource).not.to.include("margin: 0 5px 0 0");
|
|
134
|
+
expect(columnBarSource).to.include("@media (pointer: coarse)");
|
|
135
|
+
expect(columnBarSource).to.include("min-width: 24px");
|
|
136
|
+
expect(columnBarSource).to.include("min-height: 24px");
|
|
137
|
+
expect(columnBarSource).to.include(
|
|
138
|
+
"min-height: var(--monster-column-settings-target-size, 24px)",
|
|
139
|
+
);
|
|
140
|
+
expect(columnBarGenerated).to.include(
|
|
141
|
+
"[data-monster-role=dots]) li{list-style:none;padding:0;margin:0;",
|
|
142
|
+
);
|
|
143
|
+
expect(columnBarGenerated).not.to.include("margin:0 5px 0 0");
|
|
144
|
+
expect(columnBarGenerated).to.include(
|
|
145
|
+
"--monster-column-toggle-target-size,16px",
|
|
146
|
+
);
|
|
147
|
+
expect(columnBarGenerated).to.include("@media (pointer:coarse)");
|
|
148
|
+
expect(columnBarGenerated).to.include("min-width:24px");
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("keeps embedded pagination compact and touch friendly", () => {
|
|
152
|
+
expect(embeddedPaginationSource).to.include("margin: 0");
|
|
153
|
+
expect(embeddedPaginationSource).to.include("grid-template-columns:");
|
|
154
|
+
expect(embeddedPaginationSource).to.include(
|
|
155
|
+
"var(--monster-control-min-block-size, 44px)",
|
|
156
|
+
);
|
|
157
|
+
expect(embeddedPaginationSource).to.include("min-width:");
|
|
158
|
+
expect(embeddedPaginationSource).to.include("&::after");
|
|
159
|
+
expect(embeddedPaginationSource).to.include(
|
|
160
|
+
"border: 1px solid var(--monster-theme-control-border-color)",
|
|
161
|
+
);
|
|
162
|
+
expect(embeddedPaginationSource).not.to.include(
|
|
163
|
+
"inset 0 0 0 1px",
|
|
164
|
+
);
|
|
165
|
+
expect(embeddedPaginationSource).to.include(
|
|
166
|
+
"background-color: var(--monster-bg-color-primary-disabled-1)",
|
|
167
|
+
);
|
|
168
|
+
expect(embeddedPaginationSource).to.include(
|
|
169
|
+
"color: var(--monster-color-primary-disabled-1)",
|
|
170
|
+
);
|
|
171
|
+
expect(embeddedPaginationSource).to.include("opacity: 1");
|
|
172
|
+
expect(embeddedPaginationSource).not.to.include("@mixin viewport-7");
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("ships the generated responsive card styles", () => {
|
|
176
|
+
expect(generated).to.include("data-monster-datatable-row-start");
|
|
177
|
+
expect(generated).to.include("data-monster-datatable-row-end");
|
|
178
|
+
expect(generated).to.include("monster-filter-select");
|
|
179
|
+
expect(generated).to.include("container-name:monster-datatable-responsive");
|
|
180
|
+
expect(generated).to.include("container-type:inline-size");
|
|
181
|
+
expect(generated).to.include(
|
|
182
|
+
"@container monster-datatable-responsive (max-width: 26rem)",
|
|
183
|
+
);
|
|
184
|
+
expect(generated).to.include("slot[name=bar]::slotted(*)");
|
|
185
|
+
expect(generated).to.include("monster-context-help::part(button)");
|
|
186
|
+
expect(embeddedPaginationGenerated).to.include(
|
|
187
|
+
"grid-template-columns:var(--monster-control-min-block-size,44px)",
|
|
188
|
+
);
|
|
189
|
+
expect(embeddedPaginationGenerated).to.include(
|
|
190
|
+
"min-height:var(--monster-control-min-block-size,44px)",
|
|
191
|
+
);
|
|
192
|
+
expect(embeddedPaginationGenerated).to.include(
|
|
193
|
+
"border:1px solid var(--monster-theme-control-border-color)",
|
|
194
|
+
);
|
|
195
|
+
expect(embeddedPaginationGenerated).to.include(
|
|
196
|
+
"background-color:var(--monster-bg-color-primary-disabled-1)",
|
|
197
|
+
);
|
|
198
|
+
expect(embeddedPaginationGenerated).to.include("opacity:1");
|
|
199
|
+
expect(embeddedPaginationGenerated).not.to.include(
|
|
200
|
+
"box-shadow:inset 0 0 0 1px",
|
|
201
|
+
);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import { initJSDOM } from "../../../util/jsdom.mjs";
|
|
3
|
+
import { ResizeObserverMock } from "../../../util/resize-observer.mjs";
|
|
4
|
+
|
|
5
|
+
const nextTask = () => new Promise((resolve) => setTimeout(resolve, 0));
|
|
6
|
+
let declarativeBreakpoint;
|
|
7
|
+
|
|
8
|
+
describe("Datatable responsive breakpoint", function () {
|
|
9
|
+
before(async function () {
|
|
10
|
+
await initJSDOM();
|
|
11
|
+
await import("element-internals-polyfill").catch(() => {});
|
|
12
|
+
globalThis.ResizeObserver ??= ResizeObserverMock;
|
|
13
|
+
|
|
14
|
+
document.getElementById("mocks").innerHTML = `
|
|
15
|
+
<monster-datatable
|
|
16
|
+
data-monster-responsive-breakpoint="720"
|
|
17
|
+
></monster-datatable>
|
|
18
|
+
`;
|
|
19
|
+
await import("../../../../source/components/datatable/datatable.mjs");
|
|
20
|
+
await nextTask();
|
|
21
|
+
|
|
22
|
+
declarativeBreakpoint = document
|
|
23
|
+
.querySelector("monster-datatable")
|
|
24
|
+
.getOption("responsive.breakpoint");
|
|
25
|
+
document.getElementById("mocks").replaceChildren();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
afterEach(function () {
|
|
29
|
+
document.getElementById("mocks").replaceChildren();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("uses 960px as the default responsive threshold", function () {
|
|
33
|
+
const datatable = document.createElement("monster-datatable");
|
|
34
|
+
|
|
35
|
+
expect(datatable.getOption("responsive.breakpoint")).to.equal(960);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("keeps the responsive breakpoint attribute as an explicit override", function () {
|
|
39
|
+
expect(declarativeBreakpoint).to.equal(720);
|
|
40
|
+
});
|
|
41
|
+
});
|