@blukavantui/community 1.0.1 → 1.1.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/README.md +11 -5
- package/dist/build-audit.json +181 -53
- package/dist/checkbox.css +1 -0
- package/dist/checkbox.d.ts +2 -0
- package/dist/checkbox.js +1 -0
- package/dist/chunk-3PNBQVYS.js +1 -0
- package/dist/chunk-5ENZVZGF.js +0 -0
- package/dist/chunk-AL2ETLJV.js +1 -0
- package/dist/chunk-BN3PDE5G.js +0 -0
- package/dist/chunk-EOKNLCNS.js +1 -0
- package/dist/chunk-EPZGLHPD.js +0 -0
- package/dist/chunk-FNX33PDD.js +0 -0
- package/dist/chunk-GXHANADL.js +1 -0
- package/dist/chunk-HO6CYWED.js +0 -0
- package/dist/chunk-IJ62ILKE.js +0 -0
- package/dist/chunk-IO22GWON.js +0 -0
- package/dist/chunk-IZJN3EF7.js +1 -0
- package/dist/chunk-JVE6CXCJ.js +1 -0
- package/dist/chunk-MYVLBALF.js +1 -0
- package/dist/chunk-OPMD7QNV.js +1 -0
- package/dist/chunk-RWBLICYX.js +0 -0
- package/dist/chunk-RYD6RHRX.js +0 -0
- package/dist/chunk-UN2SLVFG.js +1 -0
- package/dist/chunk-VJVFHL6P.js +0 -0
- package/dist/chunk-XWXEH3SW.js +1 -0
- package/dist/chunk-YCLR3IE3.js +0 -0
- package/dist/columns2.css +1 -0
- package/dist/columns2.d.ts +2 -0
- package/dist/columns2.js +1 -0
- package/dist/columns3.css +1 -0
- package/dist/columns3.d.ts +2 -0
- package/dist/columns3.js +1 -0
- package/dist/columns4.css +1 -0
- package/dist/columns4.d.ts +2 -0
- package/dist/columns4.js +1 -0
- package/dist/content.js +1 -1
- package/dist/core.js +1 -1
- package/dist/data.css +63 -0
- package/dist/data.d.ts +1 -0
- package/dist/data.js +1 -1
- package/dist/date-picker.css +5 -5
- package/dist/date-picker.js +1 -1
- package/dist/date-range-picker.css +5 -5
- package/dist/date-range-picker.js +1 -1
- package/dist/date-time-picker.css +5 -5
- package/dist/date-time-picker.js +1 -1
- package/dist/draft-components.json +77 -0
- package/dist/feedback.js +1 -1
- package/dist/form-field.css +1 -0
- package/dist/form-field.d.ts +2 -0
- package/dist/form-field.js +1 -0
- package/dist/form-layout/choice.d.ts +15 -0
- package/dist/form-layout/layout.d.ts +12 -0
- package/dist/form-layout/select.d.ts +3 -0
- package/dist/form-layout/shared.d.ts +21 -0
- package/dist/form-layout/table.d.ts +20 -0
- package/dist/form-layout/text.d.ts +3 -0
- package/dist/form-layout/types.d.ts +151 -0
- package/dist/form-layout.css +62 -0
- package/dist/form-layout.d.ts +12 -0
- package/dist/form-layout.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/inputs.css +83 -20
- package/dist/inputs.d.ts +8 -0
- package/dist/inputs.js +1 -1
- package/dist/layout.css +63 -0
- package/dist/layout.d.ts +3 -0
- package/dist/layout.js +1 -1
- package/dist/native/date-picker.js +1 -1
- package/dist/native/date-range-picker.js +1 -1
- package/dist/native/date-time-picker.js +1 -1
- package/dist/native/form-layout.js +1 -0
- package/dist/native/time-picker.js +1 -1
- package/dist/native-components/form-layout.d.ts +1 -0
- package/dist/radio-button.css +1 -0
- package/dist/radio-button.d.ts +2 -0
- package/dist/radio-button.js +1 -0
- package/dist/radio-group.css +1 -0
- package/dist/radio-group.d.ts +2 -0
- package/dist/radio-group.js +1 -0
- package/dist/select.css +1 -0
- package/dist/select.d.ts +2 -0
- package/dist/select.js +1 -0
- package/dist/sizes.json +272 -90
- package/dist/styles.css +83 -20
- package/dist/switch.css +1 -0
- package/dist/switch.d.ts +2 -0
- package/dist/switch.js +1 -0
- package/dist/table.css +1 -0
- package/dist/table.d.ts +2 -0
- package/dist/table.js +1 -0
- package/dist/text-area.css +1 -0
- package/dist/text-area.d.ts +2 -0
- package/dist/text-area.js +1 -0
- package/dist/text-input.css +1 -0
- package/dist/text-input.d.ts +2 -0
- package/dist/text-input.js +1 -0
- package/dist/time-picker.css +5 -5
- package/dist/time-picker.js +1 -1
- package/docs/FORM-LAYOUT-ESSENTIALS.md +122 -0
- package/docs/PUBLISHING.md +129 -25
- package/draft-components.json +77 -0
- package/edition.json +44 -7
- package/npm-shrinkwrap.json +2 -2
- package/package.json +76 -10
- package/scripts/build.mjs +16 -8
- package/src/checkbox.ts +2 -0
- package/src/columns2.ts +2 -0
- package/src/columns3.ts +2 -0
- package/src/columns4.ts +2 -0
- package/src/data.ts +1 -0
- package/src/form-field.ts +2 -0
- package/src/form-layout/choice.ts +66 -0
- package/src/form-layout/layout.ts +40 -0
- package/src/form-layout/select.ts +97 -0
- package/src/form-layout/shared.ts +57 -0
- package/src/form-layout/table.ts +86 -0
- package/src/form-layout/text.ts +73 -0
- package/src/form-layout/types.ts +59 -0
- package/src/form-layout.ts +12 -0
- package/src/index.ts +2 -0
- package/src/inputs.ts +8 -0
- package/src/layout.ts +3 -0
- package/src/native-components/form-layout.ts +21 -0
- package/src/radio-button.ts +2 -0
- package/src/radio-group.ts +2 -0
- package/src/runtime/date-picker.js +21 -12
- package/src/runtime/date-range-picker.js +21 -12
- package/src/runtime/date-time-picker.js +21 -12
- package/src/runtime/time-picker.js +21 -12
- package/src/select.ts +2 -0
- package/src/switch.ts +2 -0
- package/src/table.ts +2 -0
- package/src/text-area.ts +2 -0
- package/src/text-input.ts +2 -0
- package/src/types.ts +0 -12
- package/styles/checkbox.css +1 -0
- package/styles/columns2.css +1 -0
- package/styles/columns3.css +1 -0
- package/styles/columns4.css +1 -0
- package/styles/date-picker.css +5 -5
- package/styles/date-range-picker.css +5 -5
- package/styles/date-time-picker.css +5 -5
- package/styles/form-field.css +1 -0
- package/styles/form-layout.css +62 -0
- package/styles/radio-button.css +1 -0
- package/styles/radio-group.css +1 -0
- package/styles/select.css +1 -0
- package/styles/switch.css +1 -0
- package/styles/table.css +1 -0
- package/styles/text-area.css +1 -0
- package/styles/text-input.css +1 -0
- package/styles/time-picker.css +5 -5
- package/test/form-layout.test.mjs +28 -0
- package/test/isolation.test.mjs +2 -2
- package/dist/chunk-2TCNAQC6.js +0 -1
- package/dist/chunk-CTLZIWMX.js +0 -1
- package/dist/chunk-MHHJZYXW.js +0 -1
- package/dist/chunk-XDYBNO4P.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// docs/scripts/advanced/shared.js
|
|
2
2
|
import { state, register } from "./kernel.js";
|
|
3
3
|
var shared = state("advanced", () => ({ instances: /* @__PURE__ */ new Map(), serial: 0 }));
|
|
4
4
|
var uid = () => `blu-advanced-${++shared.serial}`;
|
|
@@ -91,7 +91,7 @@ function createAPI(kind, init2, update2) {
|
|
|
91
91
|
}, destroy }));
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
//
|
|
94
|
+
// docs/scripts/advanced/date-utils.js
|
|
95
95
|
var pad = (n) => String(n).padStart(2, "0");
|
|
96
96
|
function dateValue(d) {
|
|
97
97
|
return String(d.getFullYear()).padStart(4, "0") + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate());
|
|
@@ -172,7 +172,7 @@ function validateRange(start, end, options = {}) {
|
|
|
172
172
|
return "";
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
//
|
|
175
|
+
// docs/scripts/advanced/pickers.js
|
|
176
176
|
var formatOptions = ["YYYY-MM-DD", "MM/DD/YYYY", "DD/MM/YYYY"];
|
|
177
177
|
var today = () => dateValue(/* @__PURE__ */ new Date());
|
|
178
178
|
var datePart = (value) => String(value || "").split("T")[0];
|
|
@@ -256,14 +256,15 @@ function positionPopup(s) {
|
|
|
256
256
|
const below = Math.max(0, top + height - edge - anchor.bottom - gap), above = Math.max(0, anchor.top - gap - top - edge);
|
|
257
257
|
const natural = panel.scrollHeight + 2, up = natural > below && above > below, room = Math.max(0, height - edge * 2);
|
|
258
258
|
panel.style.maxHeight = room + "px";
|
|
259
|
-
|
|
259
|
+
const fields = s.fieldRow.getBoundingClientRect();
|
|
260
|
+
panel.style.left = Math.max(left + edge, Math.min(fields.left + (fields.width - panelWidth) / 2, left + width - edge - panelWidth)) + "px";
|
|
260
261
|
const preferred = up ? anchor.top - gap - natural : anchor.bottom + gap;
|
|
261
262
|
panel.style.top = Math.max(top + edge, Math.min(preferred, top + height - edge - Math.min(natural, room))) + "px";
|
|
262
263
|
panel.dataset.placement = up ? "top" : "bottom";
|
|
263
264
|
}
|
|
264
265
|
function focusPopup(s) {
|
|
265
266
|
const timeField = s.timeOnly || s.dateTime && s.anchor === s.fields[1].input;
|
|
266
|
-
(timeField ? s.hours : s.calendar.querySelector('[data-date="' + s.focusDate + '"]') || s.monthSelect).focus();
|
|
267
|
+
(timeField ? s.hours : s.calendar.querySelector('[data-date="' + s.focusDate + '"]') || s.monthSelect).focus({ preventScroll: true });
|
|
267
268
|
}
|
|
268
269
|
function commit(s, first, end, time, keepOpen = false) {
|
|
269
270
|
const issue = validate(s, first, end, time);
|
|
@@ -287,7 +288,7 @@ function commit(s, first, end, time, keepOpen = false) {
|
|
|
287
288
|
s.inputSignature = JSON.stringify(s.range ? [s.start, s.end] : [s.value]);
|
|
288
289
|
paintInputs(s);
|
|
289
290
|
if (!keepOpen) close(s);
|
|
290
|
-
if (returnToInput) s.fields[0].input.focus();
|
|
291
|
+
if (returnToInput) s.fields[0].input.focus({ preventScroll: true });
|
|
291
292
|
s.notice.textContent = s.range ? first ? labelDate(s, first) + " to " + labelDate(s, end) : "Date range cleared" : value ? "Selected " + (s.timeOnly ? formatTime(value, s.cycle) : labelDate(s, first) + (s.hasTime ? " at " + formatTime(time, s.cycle) : "")) : "Selection cleared";
|
|
292
293
|
if (changed) {
|
|
293
294
|
if (s.range) emit(s, "Change", first, end);
|
|
@@ -391,11 +392,18 @@ function appendOption(select, value, label) {
|
|
|
391
392
|
return option;
|
|
392
393
|
}
|
|
393
394
|
function selectField(s, label, name) {
|
|
394
|
-
const wrap = node("label", "blu-picker__select-field"), caption = node("span", "", label), select = node("select", "blu-picker__input");
|
|
395
|
+
const wrap = node("label", "blu-picker__select-field"), caption = node("span", "blu-picker__select-caption", label), select = node("select", "blu-picker__input");
|
|
395
396
|
select.id = s.uid + "-" + name;
|
|
396
397
|
wrap.append(caption, select);
|
|
397
398
|
return { wrap, select };
|
|
398
399
|
}
|
|
400
|
+
function focusPopupButton(event) {
|
|
401
|
+
if (event.button !== 0) return;
|
|
402
|
+
const target = event.target.closest?.("button");
|
|
403
|
+
if (!target || target.disabled) return;
|
|
404
|
+
event.preventDefault();
|
|
405
|
+
target.focus({ preventScroll: true });
|
|
406
|
+
}
|
|
399
407
|
function focusDay(s, value) {
|
|
400
408
|
const min = datePart(s.options.Min) || "0001-01-01", max = datePart(s.options.Max) || "9999-12-31";
|
|
401
409
|
value = value < min ? min : value > max ? max : value;
|
|
@@ -403,7 +411,7 @@ function focusDay(s, value) {
|
|
|
403
411
|
s.focusDate = value;
|
|
404
412
|
s.month = value.slice(0, 7);
|
|
405
413
|
paintCalendar(s);
|
|
406
|
-
s.calendar.querySelector('[data-date="' + value + '"]')?.focus();
|
|
414
|
+
s.calendar.querySelector('[data-date="' + value + '"]')?.focus({ preventScroll: true });
|
|
407
415
|
}
|
|
408
416
|
function keyDay(s, event, value) {
|
|
409
417
|
if (event.altKey || event.ctrlKey || event.metaKey) return;
|
|
@@ -441,7 +449,7 @@ function chooseDay(s, value) {
|
|
|
441
449
|
return;
|
|
442
450
|
}
|
|
443
451
|
paintCalendar(s);
|
|
444
|
-
s.calendar.querySelector('[data-date="' + value + '"]')?.focus();
|
|
452
|
+
s.calendar.querySelector('[data-date="' + value + '"]')?.focus({ preventScroll: true });
|
|
445
453
|
paintDraft(s);
|
|
446
454
|
}
|
|
447
455
|
function paintDraft(s) {
|
|
@@ -594,6 +602,7 @@ function init(s) {
|
|
|
594
602
|
attr(s.dialog, "aria-modal", "false");
|
|
595
603
|
if (s.dialog.showPopover) attr(s.dialog, "popover", "manual");
|
|
596
604
|
s.root.append(s.dialog);
|
|
605
|
+
s.dialog.addEventListener("mousedown", focusPopupButton);
|
|
597
606
|
s.title = node("h2", "blu-advanced-sr");
|
|
598
607
|
s.title.id = s.uid + "-title";
|
|
599
608
|
s.dialog.append(s.title);
|
|
@@ -606,7 +615,7 @@ function init(s) {
|
|
|
606
615
|
const month = selectField(s, "Month", "month");
|
|
607
616
|
s.monthSelect = month.select;
|
|
608
617
|
const year = node("label", "blu-picker__select-field");
|
|
609
|
-
year.append(node("span", "", "Year"));
|
|
618
|
+
year.append(node("span", "blu-picker__select-caption", "Year"));
|
|
610
619
|
s.yearInput = node("input", "blu-picker__input");
|
|
611
620
|
s.yearInput.type = "number";
|
|
612
621
|
s.yearInput.step = "1";
|
|
@@ -804,8 +813,8 @@ function update(s) {
|
|
|
804
813
|
else {
|
|
805
814
|
paintCalendar(s);
|
|
806
815
|
paintTimes(s);
|
|
807
|
-
if (focusDate) s.calendar.querySelector('[data-date="' + focusDate + '"]')?.focus();
|
|
808
|
-
else if (focusId) document.getElementById(focusId)?.focus();
|
|
816
|
+
if (focusDate) s.calendar.querySelector('[data-date="' + focusDate + '"]')?.focus({ preventScroll: true });
|
|
817
|
+
else if (focusId) document.getElementById(focusId)?.focus({ preventScroll: true });
|
|
809
818
|
positionPopup(s);
|
|
810
819
|
}
|
|
811
820
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// docs/scripts/advanced/shared.js
|
|
2
2
|
import { state, register } from "./kernel.js";
|
|
3
3
|
var shared = state("advanced", () => ({ instances: /* @__PURE__ */ new Map(), serial: 0 }));
|
|
4
4
|
var uid = () => `blu-advanced-${++shared.serial}`;
|
|
@@ -91,7 +91,7 @@ function createAPI(kind, init2, update2) {
|
|
|
91
91
|
}, destroy }));
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
//
|
|
94
|
+
// docs/scripts/advanced/date-utils.js
|
|
95
95
|
var pad = (n) => String(n).padStart(2, "0");
|
|
96
96
|
function dateValue(d) {
|
|
97
97
|
return String(d.getFullYear()).padStart(4, "0") + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate());
|
|
@@ -172,7 +172,7 @@ function validateRange(start, end, options = {}) {
|
|
|
172
172
|
return "";
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
//
|
|
175
|
+
// docs/scripts/advanced/pickers.js
|
|
176
176
|
var formatOptions = ["YYYY-MM-DD", "MM/DD/YYYY", "DD/MM/YYYY"];
|
|
177
177
|
var today = () => dateValue(/* @__PURE__ */ new Date());
|
|
178
178
|
var datePart = (value) => String(value || "").split("T")[0];
|
|
@@ -256,14 +256,15 @@ function positionPopup(s) {
|
|
|
256
256
|
const below = Math.max(0, top + height - edge - anchor.bottom - gap), above = Math.max(0, anchor.top - gap - top - edge);
|
|
257
257
|
const natural = panel.scrollHeight + 2, up = natural > below && above > below, room = Math.max(0, height - edge * 2);
|
|
258
258
|
panel.style.maxHeight = room + "px";
|
|
259
|
-
|
|
259
|
+
const fields = s.fieldRow.getBoundingClientRect();
|
|
260
|
+
panel.style.left = Math.max(left + edge, Math.min(fields.left + (fields.width - panelWidth) / 2, left + width - edge - panelWidth)) + "px";
|
|
260
261
|
const preferred = up ? anchor.top - gap - natural : anchor.bottom + gap;
|
|
261
262
|
panel.style.top = Math.max(top + edge, Math.min(preferred, top + height - edge - Math.min(natural, room))) + "px";
|
|
262
263
|
panel.dataset.placement = up ? "top" : "bottom";
|
|
263
264
|
}
|
|
264
265
|
function focusPopup(s) {
|
|
265
266
|
const timeField = s.timeOnly || s.dateTime && s.anchor === s.fields[1].input;
|
|
266
|
-
(timeField ? s.hours : s.calendar.querySelector('[data-date="' + s.focusDate + '"]') || s.monthSelect).focus();
|
|
267
|
+
(timeField ? s.hours : s.calendar.querySelector('[data-date="' + s.focusDate + '"]') || s.monthSelect).focus({ preventScroll: true });
|
|
267
268
|
}
|
|
268
269
|
function commit(s, first, end, time, keepOpen = false) {
|
|
269
270
|
const issue = validate(s, first, end, time);
|
|
@@ -287,7 +288,7 @@ function commit(s, first, end, time, keepOpen = false) {
|
|
|
287
288
|
s.inputSignature = JSON.stringify(s.range ? [s.start, s.end] : [s.value]);
|
|
288
289
|
paintInputs(s);
|
|
289
290
|
if (!keepOpen) close(s);
|
|
290
|
-
if (returnToInput) s.fields[0].input.focus();
|
|
291
|
+
if (returnToInput) s.fields[0].input.focus({ preventScroll: true });
|
|
291
292
|
s.notice.textContent = s.range ? first ? labelDate(s, first) + " to " + labelDate(s, end) : "Date range cleared" : value ? "Selected " + (s.timeOnly ? formatTime(value, s.cycle) : labelDate(s, first) + (s.hasTime ? " at " + formatTime(time, s.cycle) : "")) : "Selection cleared";
|
|
292
293
|
if (changed) {
|
|
293
294
|
if (s.range) emit(s, "Change", first, end);
|
|
@@ -391,11 +392,18 @@ function appendOption(select, value, label) {
|
|
|
391
392
|
return option;
|
|
392
393
|
}
|
|
393
394
|
function selectField(s, label, name) {
|
|
394
|
-
const wrap = node("label", "blu-picker__select-field"), caption = node("span", "", label), select = node("select", "blu-picker__input");
|
|
395
|
+
const wrap = node("label", "blu-picker__select-field"), caption = node("span", "blu-picker__select-caption", label), select = node("select", "blu-picker__input");
|
|
395
396
|
select.id = s.uid + "-" + name;
|
|
396
397
|
wrap.append(caption, select);
|
|
397
398
|
return { wrap, select };
|
|
398
399
|
}
|
|
400
|
+
function focusPopupButton(event) {
|
|
401
|
+
if (event.button !== 0) return;
|
|
402
|
+
const target = event.target.closest?.("button");
|
|
403
|
+
if (!target || target.disabled) return;
|
|
404
|
+
event.preventDefault();
|
|
405
|
+
target.focus({ preventScroll: true });
|
|
406
|
+
}
|
|
399
407
|
function focusDay(s, value) {
|
|
400
408
|
const min = datePart(s.options.Min) || "0001-01-01", max = datePart(s.options.Max) || "9999-12-31";
|
|
401
409
|
value = value < min ? min : value > max ? max : value;
|
|
@@ -403,7 +411,7 @@ function focusDay(s, value) {
|
|
|
403
411
|
s.focusDate = value;
|
|
404
412
|
s.month = value.slice(0, 7);
|
|
405
413
|
paintCalendar(s);
|
|
406
|
-
s.calendar.querySelector('[data-date="' + value + '"]')?.focus();
|
|
414
|
+
s.calendar.querySelector('[data-date="' + value + '"]')?.focus({ preventScroll: true });
|
|
407
415
|
}
|
|
408
416
|
function keyDay(s, event, value) {
|
|
409
417
|
if (event.altKey || event.ctrlKey || event.metaKey) return;
|
|
@@ -441,7 +449,7 @@ function chooseDay(s, value) {
|
|
|
441
449
|
return;
|
|
442
450
|
}
|
|
443
451
|
paintCalendar(s);
|
|
444
|
-
s.calendar.querySelector('[data-date="' + value + '"]')?.focus();
|
|
452
|
+
s.calendar.querySelector('[data-date="' + value + '"]')?.focus({ preventScroll: true });
|
|
445
453
|
paintDraft(s);
|
|
446
454
|
}
|
|
447
455
|
function paintDraft(s) {
|
|
@@ -594,6 +602,7 @@ function init(s) {
|
|
|
594
602
|
attr(s.dialog, "aria-modal", "false");
|
|
595
603
|
if (s.dialog.showPopover) attr(s.dialog, "popover", "manual");
|
|
596
604
|
s.root.append(s.dialog);
|
|
605
|
+
s.dialog.addEventListener("mousedown", focusPopupButton);
|
|
597
606
|
s.title = node("h2", "blu-advanced-sr");
|
|
598
607
|
s.title.id = s.uid + "-title";
|
|
599
608
|
s.dialog.append(s.title);
|
|
@@ -606,7 +615,7 @@ function init(s) {
|
|
|
606
615
|
const month = selectField(s, "Month", "month");
|
|
607
616
|
s.monthSelect = month.select;
|
|
608
617
|
const year = node("label", "blu-picker__select-field");
|
|
609
|
-
year.append(node("span", "", "Year"));
|
|
618
|
+
year.append(node("span", "blu-picker__select-caption", "Year"));
|
|
610
619
|
s.yearInput = node("input", "blu-picker__input");
|
|
611
620
|
s.yearInput.type = "number";
|
|
612
621
|
s.yearInput.step = "1";
|
|
@@ -804,8 +813,8 @@ function update(s) {
|
|
|
804
813
|
else {
|
|
805
814
|
paintCalendar(s);
|
|
806
815
|
paintTimes(s);
|
|
807
|
-
if (focusDate) s.calendar.querySelector('[data-date="' + focusDate + '"]')?.focus();
|
|
808
|
-
else if (focusId) document.getElementById(focusId)?.focus();
|
|
816
|
+
if (focusDate) s.calendar.querySelector('[data-date="' + focusDate + '"]')?.focus({ preventScroll: true });
|
|
817
|
+
else if (focusId) document.getElementById(focusId)?.focus({ preventScroll: true });
|
|
809
818
|
positionPopup(s);
|
|
810
819
|
}
|
|
811
820
|
}
|
package/src/select.ts
ADDED
package/src/switch.ts
ADDED
package/src/table.ts
ADDED
package/src/text-area.ts
ADDED
package/src/types.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './form-layout.css';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './form-layout.css';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './form-layout.css';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './form-layout.css';
|
package/styles/date-picker.css
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
.blu-picker [hidden],.blu-picker__dialog [hidden] {display:none!important;}
|
|
7
7
|
.blu-picker__fields {display:flex;flex-wrap:wrap;gap:12px;}
|
|
8
8
|
.blu-picker__field {flex:1 1 180px;min-width:0;}
|
|
9
|
-
.blu-picker__field label,.blu-picker__select-
|
|
9
|
+
.blu-picker__field label,.blu-picker__select-caption {display:block;margin-bottom:5px;color:var(--bluui-text,#182230);font-weight:600;}
|
|
10
10
|
.blu-picker__input {display:block;width:100%;min-width:0;min-height:42px;padding:9px 11px;border:1px solid var(--bluui-control-border,#69788d);border-radius:9px;background:var(--bluui-surface,#fff);color:var(--bluui-text,#182230);font:inherit;line-height:1.4;}
|
|
11
11
|
.blu-picker__field-control {position:relative;}
|
|
12
12
|
.blu-picker__field-control>.blu-picker__input {padding-right:38px;}
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
.blu-picker__dialog::backdrop {background:transparent;pointer-events:none;}
|
|
30
30
|
.blu-picker__dialog-head {display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:14px;}
|
|
31
31
|
.blu-picker__dialog-head h2 {font-size:16px;line-height:1.4;font-family:var(--blu-font-heading-family,inherit);margin:0;overflow-wrap:anywhere;}
|
|
32
|
-
.blu-picker__calendar-nav {display:grid;grid-template-columns:32px minmax(0,1fr)
|
|
32
|
+
.blu-picker__calendar-nav {display:grid;grid-template-columns:32px minmax(0,1fr) 88px 32px;align-items:end;gap:6px;margin-top:0;}
|
|
33
33
|
.blu-picker__calendar-nav>.blu-picker__button {height:36px;padding:2px;font-size:22px;}
|
|
34
34
|
.blu-picker__select-field {min-width:0;}
|
|
35
35
|
.blu-picker__caption {font-size:15px;text-align:center;margin:16px 0 8px;}
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
/* Compact popup controls; editable text stays at 16px to avoid iOS focus zoom. */
|
|
55
55
|
.blu-picker__dialog .blu-picker__input {min-height:36px;padding:5px 7px;font-size:16px;line-height:1.2;}
|
|
56
56
|
.blu-picker__dialog .blu-picker__button {min-height:34px;min-width:32px;padding:5px 9px;font-size:13px;line-height:1.25;}
|
|
57
|
-
.blu-picker__dialog .blu-picker__select-
|
|
58
|
-
.blu-picker__calendar-nav .blu-picker__select-
|
|
57
|
+
.blu-picker__dialog .blu-picker__select-caption {font-size:11px;margin-bottom:2px;}
|
|
58
|
+
.blu-picker__calendar-nav .blu-picker__select-caption {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:0;}
|
|
59
59
|
.blu-picker__dialog .blu-picker__error {margin-top:4px;font-size:12px;line-height:1.3;}
|
|
60
60
|
@media(pointer:coarse){
|
|
61
61
|
.blu-picker__field-control>.blu-picker__input {font-size:16px;min-height:44px;}
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
.blu-picker__dialog[data-compact=true] .blu-picker__calendar td {height:24px;}
|
|
73
73
|
.blu-picker__dialog[data-compact=true] .blu-picker__day {min-height:24px;padding:3px 0;}
|
|
74
74
|
.blu-picker__dialog[data-compact=true] .blu-picker__time-area {margin:4px 0;gap:6px;}
|
|
75
|
-
.blu-picker__dialog[data-compact=true] .blu-picker__time-area .blu-picker__select-
|
|
75
|
+
.blu-picker__dialog[data-compact=true] .blu-picker__time-area .blu-picker__select-caption {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}
|
|
76
76
|
.blu-picker__dialog[data-compact=true] .blu-picker__selection {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:0;}
|
|
77
77
|
.blu-picker__dialog[data-compact=true] .blu-picker__popup-actions {margin-top:4px;gap:4px;}
|
|
78
78
|
.blu-picker__dialog[data-compact=true] .blu-picker__presets {margin-bottom:4px;gap:4px;}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
.blu-picker [hidden],.blu-picker__dialog [hidden] {display:none!important;}
|
|
7
7
|
.blu-picker__fields {display:flex;flex-wrap:wrap;gap:12px;}
|
|
8
8
|
.blu-picker__field {flex:1 1 180px;min-width:0;}
|
|
9
|
-
.blu-picker__field label,.blu-picker__select-
|
|
9
|
+
.blu-picker__field label,.blu-picker__select-caption {display:block;margin-bottom:5px;color:var(--bluui-text,#182230);font-weight:600;}
|
|
10
10
|
.blu-picker__input {display:block;width:100%;min-width:0;min-height:42px;padding:9px 11px;border:1px solid var(--bluui-control-border,#69788d);border-radius:9px;background:var(--bluui-surface,#fff);color:var(--bluui-text,#182230);font:inherit;line-height:1.4;}
|
|
11
11
|
.blu-picker__field-control {position:relative;}
|
|
12
12
|
.blu-picker__field-control>.blu-picker__input {padding-right:38px;}
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
.blu-picker__dialog::backdrop {background:transparent;pointer-events:none;}
|
|
30
30
|
.blu-picker__dialog-head {display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:14px;}
|
|
31
31
|
.blu-picker__dialog-head h2 {font-size:16px;line-height:1.4;font-family:var(--blu-font-heading-family,inherit);margin:0;overflow-wrap:anywhere;}
|
|
32
|
-
.blu-picker__calendar-nav {display:grid;grid-template-columns:32px minmax(0,1fr)
|
|
32
|
+
.blu-picker__calendar-nav {display:grid;grid-template-columns:32px minmax(0,1fr) 88px 32px;align-items:end;gap:6px;margin-top:0;}
|
|
33
33
|
.blu-picker__calendar-nav>.blu-picker__button {height:36px;padding:2px;font-size:22px;}
|
|
34
34
|
.blu-picker__select-field {min-width:0;}
|
|
35
35
|
.blu-picker__caption {font-size:15px;text-align:center;margin:16px 0 8px;}
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
/* Compact popup controls; editable text stays at 16px to avoid iOS focus zoom. */
|
|
55
55
|
.blu-picker__dialog .blu-picker__input {min-height:36px;padding:5px 7px;font-size:16px;line-height:1.2;}
|
|
56
56
|
.blu-picker__dialog .blu-picker__button {min-height:34px;min-width:32px;padding:5px 9px;font-size:13px;line-height:1.25;}
|
|
57
|
-
.blu-picker__dialog .blu-picker__select-
|
|
58
|
-
.blu-picker__calendar-nav .blu-picker__select-
|
|
57
|
+
.blu-picker__dialog .blu-picker__select-caption {font-size:11px;margin-bottom:2px;}
|
|
58
|
+
.blu-picker__calendar-nav .blu-picker__select-caption {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:0;}
|
|
59
59
|
.blu-picker__dialog .blu-picker__error {margin-top:4px;font-size:12px;line-height:1.3;}
|
|
60
60
|
@media(pointer:coarse){
|
|
61
61
|
.blu-picker__field-control>.blu-picker__input {font-size:16px;min-height:44px;}
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
.blu-picker__dialog[data-compact=true] .blu-picker__calendar td {height:24px;}
|
|
73
73
|
.blu-picker__dialog[data-compact=true] .blu-picker__day {min-height:24px;padding:3px 0;}
|
|
74
74
|
.blu-picker__dialog[data-compact=true] .blu-picker__time-area {margin:4px 0;gap:6px;}
|
|
75
|
-
.blu-picker__dialog[data-compact=true] .blu-picker__time-area .blu-picker__select-
|
|
75
|
+
.blu-picker__dialog[data-compact=true] .blu-picker__time-area .blu-picker__select-caption {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}
|
|
76
76
|
.blu-picker__dialog[data-compact=true] .blu-picker__selection {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:0;}
|
|
77
77
|
.blu-picker__dialog[data-compact=true] .blu-picker__popup-actions {margin-top:4px;gap:4px;}
|
|
78
78
|
.blu-picker__dialog[data-compact=true] .blu-picker__presets {margin-bottom:4px;gap:4px;}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
.blu-picker [hidden],.blu-picker__dialog [hidden] {display:none!important;}
|
|
7
7
|
.blu-picker__fields {display:flex;flex-wrap:wrap;gap:12px;}
|
|
8
8
|
.blu-picker__field {flex:1 1 180px;min-width:0;}
|
|
9
|
-
.blu-picker__field label,.blu-picker__select-
|
|
9
|
+
.blu-picker__field label,.blu-picker__select-caption {display:block;margin-bottom:5px;color:var(--bluui-text,#182230);font-weight:600;}
|
|
10
10
|
.blu-picker__input {display:block;width:100%;min-width:0;min-height:42px;padding:9px 11px;border:1px solid var(--bluui-control-border,#69788d);border-radius:9px;background:var(--bluui-surface,#fff);color:var(--bluui-text,#182230);font:inherit;line-height:1.4;}
|
|
11
11
|
.blu-picker__field-control {position:relative;}
|
|
12
12
|
.blu-picker__field-control>.blu-picker__input {padding-right:38px;}
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
.blu-picker__dialog::backdrop {background:transparent;pointer-events:none;}
|
|
30
30
|
.blu-picker__dialog-head {display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:14px;}
|
|
31
31
|
.blu-picker__dialog-head h2 {font-size:16px;line-height:1.4;font-family:var(--blu-font-heading-family,inherit);margin:0;overflow-wrap:anywhere;}
|
|
32
|
-
.blu-picker__calendar-nav {display:grid;grid-template-columns:32px minmax(0,1fr)
|
|
32
|
+
.blu-picker__calendar-nav {display:grid;grid-template-columns:32px minmax(0,1fr) 88px 32px;align-items:end;gap:6px;margin-top:0;}
|
|
33
33
|
.blu-picker__calendar-nav>.blu-picker__button {height:36px;padding:2px;font-size:22px;}
|
|
34
34
|
.blu-picker__select-field {min-width:0;}
|
|
35
35
|
.blu-picker__caption {font-size:15px;text-align:center;margin:16px 0 8px;}
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
/* Compact popup controls; editable text stays at 16px to avoid iOS focus zoom. */
|
|
55
55
|
.blu-picker__dialog .blu-picker__input {min-height:36px;padding:5px 7px;font-size:16px;line-height:1.2;}
|
|
56
56
|
.blu-picker__dialog .blu-picker__button {min-height:34px;min-width:32px;padding:5px 9px;font-size:13px;line-height:1.25;}
|
|
57
|
-
.blu-picker__dialog .blu-picker__select-
|
|
58
|
-
.blu-picker__calendar-nav .blu-picker__select-
|
|
57
|
+
.blu-picker__dialog .blu-picker__select-caption {font-size:11px;margin-bottom:2px;}
|
|
58
|
+
.blu-picker__calendar-nav .blu-picker__select-caption {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:0;}
|
|
59
59
|
.blu-picker__dialog .blu-picker__error {margin-top:4px;font-size:12px;line-height:1.3;}
|
|
60
60
|
@media(pointer:coarse){
|
|
61
61
|
.blu-picker__field-control>.blu-picker__input {font-size:16px;min-height:44px;}
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
.blu-picker__dialog[data-compact=true] .blu-picker__calendar td {height:24px;}
|
|
73
73
|
.blu-picker__dialog[data-compact=true] .blu-picker__day {min-height:24px;padding:3px 0;}
|
|
74
74
|
.blu-picker__dialog[data-compact=true] .blu-picker__time-area {margin:4px 0;gap:6px;}
|
|
75
|
-
.blu-picker__dialog[data-compact=true] .blu-picker__time-area .blu-picker__select-
|
|
75
|
+
.blu-picker__dialog[data-compact=true] .blu-picker__time-area .blu-picker__select-caption {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}
|
|
76
76
|
.blu-picker__dialog[data-compact=true] .blu-picker__selection {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:0;}
|
|
77
77
|
.blu-picker__dialog[data-compact=true] .blu-picker__popup-actions {margin-top:4px;gap:4px;}
|
|
78
78
|
.blu-picker__dialog[data-compact=true] .blu-picker__presets {margin-bottom:4px;gap:4px;}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './form-layout.css';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/* Community Form & Layout Essentials — local draft; no OutSystems UI selectors. */
|
|
2
|
+
.blu-field,.blu-columns,.blu-table{box-sizing:border-box;min-width:0;color:var(--bluui-text,#182230);font-family:var(--blu-font-family,Inter,system-ui,sans-serif);font-size:14px}
|
|
3
|
+
.blu-field *,.blu-columns *,.blu-table *{box-sizing:border-box}
|
|
4
|
+
.blu-field [hidden],.blu-table [hidden]{display:none!important}
|
|
5
|
+
.blu-field{--blu-field-height:42px;--blu-field-padding:12px;display:flex;flex-direction:column;gap:7px;border:0;padding:0;margin:0;min-inline-size:0}
|
|
6
|
+
.blu-field--small{--blu-field-height:34px;--blu-field-padding:9px;font-size:13px}.blu-field--large{--blu-field-height:50px;--blu-field-padding:15px;font-size:16px}
|
|
7
|
+
.blu-field__label{font-weight:600;line-height:1.5;padding:0;margin:0 0 2px}.blu-field__body{min-width:0}
|
|
8
|
+
.blu-field__help,.blu-choice__description,.blu-field__count{font-size:12px;color:var(--bluui-text-muted,#5c6b80);line-height:1.5}.blu-field__error{color:var(--bluui-color-error-text,#b42318);font-size:12px;line-height:1.5}.blu-field__count{text-align:end;margin-top:5px;font-variant-numeric:tabular-nums}
|
|
9
|
+
.blu-text,.blu-textarea,.blu-select__trigger{border:1px solid var(--bluui-control-border,#7b8799);border-radius:var(--blu-radius-md,8px);background:var(--bluui-surface,#fff);color:inherit;transition:border-color .12s,box-shadow .12s}
|
|
10
|
+
.blu-text{display:flex;align-items:center;gap:8px;min-height:var(--blu-field-height);padding:0 var(--blu-field-padding)}
|
|
11
|
+
.blu-text__input{width:100%;min-width:0;border:0!important;box-shadow:none!important;outline:none!important;background:transparent!important;color:inherit;padding:9px 0!important;font:inherit;line-height:1.5;height:auto}
|
|
12
|
+
.blu-text__input::placeholder,.blu-textarea::placeholder{color:var(--bluui-text-muted,#5c6b80);opacity:1}
|
|
13
|
+
.blu-text:focus-within,.blu-textarea:focus-visible,.blu-select__trigger:focus-visible{border-color:var(--bluui-primary,#4f46e5);outline:2px solid var(--bluui-primary,#4f46e5);outline-offset:2px}
|
|
14
|
+
.blu-text__adornment{display:inline-flex;flex:none;gap:6px;align-items:center;color:var(--bluui-text-muted,#5c6b80);white-space:nowrap}.blu-text__adornment img{width:24px;height:24px;object-fit:contain;border-radius:4px}
|
|
15
|
+
.blu-text__action{display:inline-flex;align-items:center;justify-content:center;border:0;border-radius:4px;background:transparent;color:var(--bluui-primary,#4f46e5);font:inherit;font-size:12px;font-weight:600;min-width:26px;min-height:30px;cursor:pointer;white-space:nowrap;padding:3px}
|
|
16
|
+
.blu-text__action:hover{background:var(--bluui-hover,#f0f2f7)}
|
|
17
|
+
.blu-field button:focus-visible,.blu-table button:focus-visible,.blu-table__scroll:focus-visible{outline:2px solid var(--bluui-primary,#4f46e5);outline-offset:3px}
|
|
18
|
+
.blu-textarea{display:block;width:100%;min-height:var(--blu-field-height);padding:10px var(--blu-field-padding);font:inherit;line-height:1.6}
|
|
19
|
+
.blu-field[data-invalid=true] .blu-text,.blu-field[data-invalid=true] .blu-textarea,.blu-field[data-invalid=true] .blu-select__trigger{border-color:var(--bluui-color-error-text,#b42318)}
|
|
20
|
+
.blu-field[data-disabled=true]{opacity:.6}.blu-field input:disabled,.blu-field textarea:disabled,.blu-field button:disabled{cursor:not-allowed}
|
|
21
|
+
.blu-field input[readonly],.blu-field textarea[readonly]{cursor:default}
|
|
22
|
+
.blu-choice{display:flex;align-items:center;position:relative;gap:10px;min-height:32px;cursor:pointer;line-height:1.5}.blu-choice__input{position:absolute;inline-size:1px;block-size:1px;clip-path:inset(50%);overflow:hidden;white-space:nowrap;opacity:0}
|
|
23
|
+
.blu-choice__mark{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:19px;height:19px;border:1.5px solid var(--bluui-control-border,#7b8799);border-radius:5px;background:var(--bluui-surface,#fff);color:var(--bluui-on-primary,#fff)}
|
|
24
|
+
.blu-choice__input:checked+.blu-choice__mark,.blu-choice__input:indeterminate+.blu-choice__mark{background:var(--bluui-primary,#4f46e5);border-color:var(--bluui-primary,#4f46e5)}
|
|
25
|
+
.blu-choice--checkbox .blu-choice__input:checked+.blu-choice__mark:after{content:'';width:5px;height:9px;border:solid currentColor;border-width:0 2px 2px 0;transform:translateY(-1px) rotate(45deg)}
|
|
26
|
+
.blu-choice__input:indeterminate+.blu-choice__mark:after{content:'';width:9px;height:2px;background:currentColor;transform:none;border:0}
|
|
27
|
+
.blu-choice__input:focus-visible+.blu-choice__mark{outline:2px solid var(--bluui-primary,#4f46e5);outline-offset:3px}
|
|
28
|
+
.blu-choice:has(input:disabled){opacity:.6;cursor:not-allowed}.blu-field[data-disabled=true] .blu-choice:has(input:disabled){opacity:1}
|
|
29
|
+
.blu-choice--radio .blu-choice__mark{border-radius:50%}.blu-choice--radio .blu-choice__input:checked+.blu-choice__mark:after{content:'';width:7px;height:7px;border-radius:50%;background:currentColor}
|
|
30
|
+
.blu-choice--switch .blu-choice__mark{width:38px;height:22px;border-radius:20px;background:var(--bluui-control-border,#7b8799);padding:2px;justify-content:flex-start}
|
|
31
|
+
.blu-choice--switch .blu-choice__mark:after{content:'';height:16px;width:16px;background:#fff;border-radius:50%;transition:transform .15s}
|
|
32
|
+
.blu-choice--switch .blu-choice__input:checked+.blu-choice__mark:after{transform:translateX(14px)}.blu-choice--switch .blu-choice__input:checked+.blu-choice__mark{background:var(--bluui-primary,#4f46e5)}
|
|
33
|
+
.blu-choice__state{margin-inline-start:auto;font-size:12px;color:var(--bluui-text-muted,#5c6b80)}.blu-choice__description{display:block}
|
|
34
|
+
.blu-radio-group{display:flex;flex-direction:column;gap:10px}.blu-radio-group--horizontal{flex-direction:row;flex-wrap:wrap;gap:12px 24px}
|
|
35
|
+
.blu-select{position:relative;display:flex;gap:5px}.blu-select__native{position:absolute;width:1px;height:1px;opacity:0;clip-path:inset(50%);pointer-events:none}
|
|
36
|
+
.blu-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:10px;min-width:0;min-height:var(--blu-field-height);width:100%;padding:9px var(--blu-field-padding);font:inherit;text-align:start;cursor:pointer}
|
|
37
|
+
.blu-select__trigger:after{content:'';width:7px;height:7px;border:solid currentColor;border-width:0 1.5px 1.5px 0;transform:translateY(-2px) rotate(45deg);flex-shrink:0}.blu-select__trigger[data-placeholder=true]{color:var(--bluui-text-muted,#5c6b80)}
|
|
38
|
+
.blu-select__popup{box-sizing:border-box;position:absolute;inset:calc(100% + 6px) 0 auto;z-index:1000;max-height:320px;overflow:auto;margin:0;padding:6px;border:1px solid var(--bluui-border-strong,#b8c4d4);border-radius:10px;background:var(--bluui-surface,#fff);box-shadow:var(--bluui-menu-shadow,0 10px 30px #17203326);color:var(--bluui-text,#182230);font:inherit}
|
|
39
|
+
.blu-select__search{width:100%;min-height:38px;padding:8px 10px;border:1px solid var(--bluui-control-border,#7b8799);border-radius:6px;background:var(--bluui-surface,#fff);color:inherit;font:inherit;margin-bottom:5px;outline-offset:2px}
|
|
40
|
+
.blu-select__option{padding:9px 10px;border-radius:5px;cursor:pointer;line-height:1.5}.blu-select__option[aria-selected=true]{font-weight:600;color:var(--bluui-primary,#4f46e5)}.blu-select__option[data-active=true]{background:var(--bluui-selected,#e9e6ff)}.blu-select__option[aria-disabled=true]{opacity:.5;cursor:not-allowed}
|
|
41
|
+
.blu-columns{display:grid;grid-template-columns:var(--blu-columns-tracks,1fr 1fr);gap:var(--blu-columns-gap,24px)}.blu-columns__column{min-width:0;display:flex;flex-direction:column;gap:20px}
|
|
42
|
+
@media(max-width:479px){.blu-columns--stack-small{grid-template-columns:minmax(0,1fr)}}
|
|
43
|
+
@media(max-width:767px){.blu-columns--stack-medium{grid-template-columns:minmax(0,1fr)}}
|
|
44
|
+
@media(max-width:1023px){.blu-columns--stack-large{grid-template-columns:minmax(0,1fr)}}
|
|
45
|
+
.blu-table{border:1px solid var(--bluui-border,#e2e8f0);border-radius:12px;background:var(--bluui-surface,#fff);overflow:hidden}
|
|
46
|
+
.blu-table__scroll{overflow:auto}.blu-table table{width:100%;border-collapse:collapse;font:inherit;text-align:start}.blu-table caption{text-align:start;padding:18px;font-weight:600;font-size:15px}
|
|
47
|
+
.blu-table th{font-size:12px;color:var(--bluui-text-muted,#5c6b80);background:var(--bluui-surface-muted,#f7f8fb);font-weight:600;white-space:nowrap}
|
|
48
|
+
.blu-table th,.blu-table td{padding:14px 18px;border-top:1px solid var(--bluui-border,#e2e8f0);line-height:1.5}
|
|
49
|
+
.blu-table[data-density=Compact] th,.blu-table[data-density=Compact] td{padding:8px 12px}
|
|
50
|
+
.blu-table[data-striped=true] tbody tr:nth-child(even){background:var(--bluui-surface-muted,#f7f8fb)}
|
|
51
|
+
.blu-table__sort{font:inherit;font-weight:600;color:inherit;background:transparent;border:0;padding:0;cursor:pointer;display:inline-flex;align-items:center;gap:12px}
|
|
52
|
+
.blu-table__empty{text-align:center!important;height:140px;color:var(--bluui-text-muted,#5c6b80)}
|
|
53
|
+
.blu-table__footer{display:flex;align-items:center;gap:8px;padding:12px 18px;border-top:1px solid var(--bluui-border,#e2e8f0);font-size:12px;flex-wrap:wrap}.blu-table__footer>span{margin-inline-end:auto;color:var(--bluui-text-muted,#5c6b80)}
|
|
54
|
+
.blu-table-button{border:1px solid var(--bluui-border-strong,#b8c4d4);border-radius:6px;padding:6px 10px;background:var(--bluui-surface,#fff);font:inherit;font-size:12px;color:var(--bluui-text,#182230);cursor:pointer;min-height:30px;white-space:nowrap}.blu-table-button:hover{background:var(--bluui-hover,#f0f2f7)}.blu-table-button:disabled{opacity:.5;cursor:not-allowed}.blu-table__actions{display:flex;gap:6px}
|
|
55
|
+
@media(prefers-reduced-motion:reduce){.blu-field *{transition:none!important}}
|
|
56
|
+
@media(forced-colors:active){.blu-choice__mark{forced-color-adjust:none;border-color:ButtonText;background:Canvas;color:HighlightText}.blu-choice__input:checked+.blu-choice__mark,.blu-choice__input:indeterminate+.blu-choice__mark{background:Highlight;border-color:Highlight}.blu-select__option[data-active=true]{outline:2px solid Highlight}.blu-choice--switch .blu-choice__mark:after{background:ButtonText}.blu-choice--switch .blu-choice__input:checked+.blu-choice__mark:after{background:HighlightText}}
|
|
57
|
+
|
|
58
|
+
/* Equal height is row-scoped; stacked columns retain their content height. */
|
|
59
|
+
.blu-columns.blu-columns--equal-height{align-items:stretch}
|
|
60
|
+
.blu-columns--equal-height > .blu-columns__column > :only-child{flex:1 1 auto}
|
|
61
|
+
.blu-columns--equal-height > .blu-columns__column > [data-placeholder]{display:flex;flex-direction:column}
|
|
62
|
+
.blu-columns--equal-height > .blu-columns__column > [data-placeholder] > :only-child{flex:1 1 auto}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './form-layout.css';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './form-layout.css';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './form-layout.css';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './form-layout.css';
|
package/styles/table.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './form-layout.css';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './form-layout.css';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './form-layout.css';
|
package/styles/time-picker.css
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
.blu-picker [hidden],.blu-picker__dialog [hidden] {display:none!important;}
|
|
7
7
|
.blu-picker__fields {display:flex;flex-wrap:wrap;gap:12px;}
|
|
8
8
|
.blu-picker__field {flex:1 1 180px;min-width:0;}
|
|
9
|
-
.blu-picker__field label,.blu-picker__select-
|
|
9
|
+
.blu-picker__field label,.blu-picker__select-caption {display:block;margin-bottom:5px;color:var(--bluui-text,#182230);font-weight:600;}
|
|
10
10
|
.blu-picker__input {display:block;width:100%;min-width:0;min-height:42px;padding:9px 11px;border:1px solid var(--bluui-control-border,#69788d);border-radius:9px;background:var(--bluui-surface,#fff);color:var(--bluui-text,#182230);font:inherit;line-height:1.4;}
|
|
11
11
|
.blu-picker__field-control {position:relative;}
|
|
12
12
|
.blu-picker__field-control>.blu-picker__input {padding-right:38px;}
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
.blu-picker__dialog::backdrop {background:transparent;pointer-events:none;}
|
|
30
30
|
.blu-picker__dialog-head {display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:14px;}
|
|
31
31
|
.blu-picker__dialog-head h2 {font-size:16px;line-height:1.4;font-family:var(--blu-font-heading-family,inherit);margin:0;overflow-wrap:anywhere;}
|
|
32
|
-
.blu-picker__calendar-nav {display:grid;grid-template-columns:32px minmax(0,1fr)
|
|
32
|
+
.blu-picker__calendar-nav {display:grid;grid-template-columns:32px minmax(0,1fr) 88px 32px;align-items:end;gap:6px;margin-top:0;}
|
|
33
33
|
.blu-picker__calendar-nav>.blu-picker__button {height:36px;padding:2px;font-size:22px;}
|
|
34
34
|
.blu-picker__select-field {min-width:0;}
|
|
35
35
|
.blu-picker__caption {font-size:15px;text-align:center;margin:16px 0 8px;}
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
/* Compact popup controls; editable text stays at 16px to avoid iOS focus zoom. */
|
|
55
55
|
.blu-picker__dialog .blu-picker__input {min-height:36px;padding:5px 7px;font-size:16px;line-height:1.2;}
|
|
56
56
|
.blu-picker__dialog .blu-picker__button {min-height:34px;min-width:32px;padding:5px 9px;font-size:13px;line-height:1.25;}
|
|
57
|
-
.blu-picker__dialog .blu-picker__select-
|
|
58
|
-
.blu-picker__calendar-nav .blu-picker__select-
|
|
57
|
+
.blu-picker__dialog .blu-picker__select-caption {font-size:11px;margin-bottom:2px;}
|
|
58
|
+
.blu-picker__calendar-nav .blu-picker__select-caption {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:0;}
|
|
59
59
|
.blu-picker__dialog .blu-picker__error {margin-top:4px;font-size:12px;line-height:1.3;}
|
|
60
60
|
@media(pointer:coarse){
|
|
61
61
|
.blu-picker__field-control>.blu-picker__input {font-size:16px;min-height:44px;}
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
.blu-picker__dialog[data-compact=true] .blu-picker__calendar td {height:24px;}
|
|
73
73
|
.blu-picker__dialog[data-compact=true] .blu-picker__day {min-height:24px;padding:3px 0;}
|
|
74
74
|
.blu-picker__dialog[data-compact=true] .blu-picker__time-area {margin:4px 0;gap:6px;}
|
|
75
|
-
.blu-picker__dialog[data-compact=true] .blu-picker__time-area .blu-picker__select-
|
|
75
|
+
.blu-picker__dialog[data-compact=true] .blu-picker__time-area .blu-picker__select-caption {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}
|
|
76
76
|
.blu-picker__dialog[data-compact=true] .blu-picker__selection {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:0;}
|
|
77
77
|
.blu-picker__dialog[data-compact=true] .blu-picker__popup-actions {margin-top:4px;gap:4px;}
|
|
78
78
|
.blu-picker__dialog[data-compact=true] .blu-picker__presets {margin-bottom:4px;gap:4px;}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import {build} from 'esbuild';
|
|
4
|
+
import {readFile} from 'node:fs/promises';
|
|
5
|
+
import vm from 'node:vm';
|
|
6
|
+
const built=await build({entryPoints:['src/form-layout/table.ts'],bundle:true,format:'esm',platform:'node',write:false});
|
|
7
|
+
const {tableRows}=await import('data:text/javascript;base64,'+Buffer.from(built.outputFiles[0].text).toString('base64'));
|
|
8
|
+
const options={Caption:'Records',Columns:[{Key:'value',Header:'Value',Sortable:true}],Rows:[{value:10},{value:null},{value:2},{value:2}],SortKey:'value'};
|
|
9
|
+
test('Table sorts numerically without mutating records, keeps equal rows stable, and keeps nulls last',()=>{
|
|
10
|
+
const sorted=tableRows(options).rows;assert.deepEqual(sorted.map(r=>r.value),[2,2,10,null]);assert.equal(sorted[0],options.Rows[2]);assert.equal(sorted[1],options.Rows[3]);assert.deepEqual(options.Rows.map(r=>r.value),[10,null,2,2]);assert.deepEqual(tableRows({...options,SortDirection:'Descending'}).rows.map(r=>r.value),[10,2,2,null]);
|
|
11
|
+
});
|
|
12
|
+
test('Table ignores non-sortable keys and safely clamps paging after data shrinks',()=>{
|
|
13
|
+
assert.deepEqual(tableRows({...options,Columns:[{Key:'value',Header:'Value'}]}).rows,options.Rows);
|
|
14
|
+
assert.deepEqual(tableRows({...options,PageSize:2,Page:100}),{rows:[options.Rows[0],options.Rows[1]],page:2,pages:2,total:4,start:3,end:4});
|
|
15
|
+
assert.equal(tableRows({...options,Rows:[],Page:20,PageSize:5}).page,1);assert.equal(tableRows({...options,Page:NaN,PageSize:Infinity}).page,1);
|
|
16
|
+
});
|
|
17
|
+
test('every draft component has a selective entry and the Table does not load AG Grid',async()=>{
|
|
18
|
+
const draft=JSON.parse(await readFile('draft-components.json','utf8')),pkg=JSON.parse(await readFile('package.json','utf8'));
|
|
19
|
+
const sizes=JSON.parse(await readFile('dist/sizes.json','utf8'));
|
|
20
|
+
for(const c of draft.components){assert.ok(pkg.exports['./'+c.slug]);await readFile('dist/'+c.slug+'.d.ts');}
|
|
21
|
+
const code=(await Promise.all(sizes.typescript['table'].files.map(f=>readFile('dist/'+f,'utf8')))).join('\n');
|
|
22
|
+
assert.ok(!/ClientSideRowModel|BluGrid|ag-grid/.test(code));assert.ok(sizes.typescript['table'].bytes<20000);
|
|
23
|
+
});
|
|
24
|
+
test('draft native runtime registers independently without changing commercial globals',async()=>{
|
|
25
|
+
const commercial={untouched:true},window={BluUIRuntime:commercial,BluUITheme:{version:'1.0.0',setMode(){},getMode(){return 'Light';},mountSelector(){}}};const context=vm.createContext({window,Map,Set,WeakMap,WeakSet,Promise,console});
|
|
26
|
+
vm.runInContext(await readFile('dist/native/form-layout.js','utf8'),context);
|
|
27
|
+
assert.equal(window.BluUIRuntime,commercial);assert.equal(typeof window.BluUICommunity.sync,'function');assert.equal(typeof window.BluUICommunity.destroy,'function');
|
|
28
|
+
});
|
package/test/isolation.test.mjs
CHANGED
|
@@ -4,8 +4,8 @@ import {readFile,readdir} from 'node:fs/promises';
|
|
|
4
4
|
import vm from 'node:vm';
|
|
5
5
|
const edition=JSON.parse(await readFile('edition.json','utf8'));
|
|
6
6
|
const sizes=JSON.parse(await readFile('dist/sizes.json','utf8'));
|
|
7
|
-
test('all seven groups expose
|
|
8
|
-
const names=Object.values(edition.nativeModules).flat();assert.equal(names.length,
|
|
7
|
+
test('all seven groups expose the declared release component set without duplicates',()=>{
|
|
8
|
+
const names=Object.values(edition.nativeModules).flat();const expected=edition.version==='1.1.0'?67:55;assert.equal(names.length,expected);assert.equal(new Set(names).size,expected);assert.deepEqual([...names].sort(),[...edition.components].sort());assert.equal(Object.keys(edition.nativeModules).length,7);
|
|
9
9
|
});
|
|
10
10
|
test('non-grid entrypoints do not pull the AG Grid engine or unrelated component factories',async()=>{
|
|
11
11
|
for(const name of ['chat','chat-widget','float-button','date-picker','time-picker','date-time-picker','date-range-picker','font-provider','shape-mask','tree-select','transfer-list','core','layout','inputs','feedback','data']){
|