@livx.cc/bare-v3 0.1.0-alpha.38 → 0.1.0-alpha.40
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.
|
@@ -36,9 +36,9 @@ function addMonths(iso, count) {
|
|
|
36
36
|
var daysInMonth = (year, month) => new Date(year, month + 1, 0).getDate();
|
|
37
37
|
var STYLE_ID = "b3-date-picker-style";
|
|
38
38
|
var STYLE = `
|
|
39
|
-
.b3-date-picker{display:block;position:relative;color:var(--b3-color-text,#202923);
|
|
39
|
+
.b3-date-picker{container:b3-date-picker / inline-size;display:block;position:relative;color:var(--b3-color-text,#202923);
|
|
40
40
|
background:var(--b3-color-surface,#fff);border:1px solid var(--b3-color-border,#d5dbd3);
|
|
41
|
-
border-radius:var(--b3-radius,.75rem);padding:var(--b3-space,1rem);
|
|
41
|
+
border-radius:var(--b3-radius,.75rem);padding:var(--b3-space,1rem) min(var(--b3-space,1rem),4%);
|
|
42
42
|
-webkit-user-select:none;user-select:none;}
|
|
43
43
|
.b3-date-picker > :not(.b3-date-picker-ui){display:none;}
|
|
44
44
|
/* A required control that is not RENDERED cannot be focused, so Chrome refuses to submit the
|
|
@@ -49,8 +49,8 @@ var STYLE = `
|
|
|
49
49
|
inset-block-start:var(--b3-space,1rem);inset-inline-start:var(--b3-space,1rem);
|
|
50
50
|
width:1px;height:1px;overflow:hidden;opacity:0;pointer-events:none;white-space:nowrap;}
|
|
51
51
|
.b3-date-picker-bar{display:flex;align-items:center;gap:.5rem;margin-block-end:.5rem;}
|
|
52
|
-
.b3-date-picker-title{flex:1;text-align:center;font-weight:600;}
|
|
53
|
-
.b3-date-picker-nav{display:inline-flex;align-items:center;justify-content:center;
|
|
52
|
+
.b3-date-picker-title{flex:1;min-inline-size:0;overflow-wrap:anywhere;text-align:center;font-weight:600;}
|
|
53
|
+
.b3-date-picker-nav{flex:none;display:inline-flex;align-items:center;justify-content:center;
|
|
54
54
|
min-width:var(--b3-touch,44px);min-height:var(--b3-touch,44px);font:inherit;line-height:1;
|
|
55
55
|
border:1px solid var(--b3-color-border,#d5dbd3);border-radius:var(--b3-radius-small,.375rem);
|
|
56
56
|
background:var(--b3-color-surface,#fff);color:inherit;cursor:pointer;}
|
|
@@ -59,7 +59,12 @@ var STYLE = `
|
|
|
59
59
|
.b3-date-picker:dir(rtl) .b3-date-picker-nav::before{content:"\\203A";}
|
|
60
60
|
.b3-date-picker:dir(rtl) .b3-date-picker-nav[data-b3-step="1"]::before{content:"\\2039";}
|
|
61
61
|
.b3-date-picker-nav[disabled]{opacity:.4;cursor:default;}
|
|
62
|
-
|
|
62
|
+
@container b3-date-picker (max-width:18rem){
|
|
63
|
+
.b3-date-picker-bar{flex-wrap:wrap;justify-content:space-between;}
|
|
64
|
+
.b3-date-picker-title{order:-1;flex-basis:100%;}
|
|
65
|
+
}
|
|
66
|
+
.b3-date-picker-scroll{overflow:auto;overscroll-behavior-inline:contain;}
|
|
67
|
+
.b3-date-picker-grid{min-inline-size:21ch;width:100%;border-collapse:collapse;table-layout:fixed;}
|
|
63
68
|
.b3-date-picker-grid th{font-weight:500;font-size:.8125em;padding-block:.25rem;
|
|
64
69
|
color:var(--b3-color-muted,#5d6b60);}
|
|
65
70
|
.b3-date-picker-grid td{padding:1px;text-align:center;}
|
|
@@ -102,6 +107,7 @@ class B3DatePicker extends Base {
|
|
|
102
107
|
#bar = null;
|
|
103
108
|
#title = null;
|
|
104
109
|
#ui = null;
|
|
110
|
+
#gridScroll = null;
|
|
105
111
|
#observer = null;
|
|
106
112
|
#titleId = `b3-date-picker-title-${Math.random().toString(36).slice(2, 8)}`;
|
|
107
113
|
get value() {
|
|
@@ -349,10 +355,16 @@ class B3DatePicker extends Base {
|
|
|
349
355
|
row.append(document.createElement("td"));
|
|
350
356
|
body.append(row);
|
|
351
357
|
table.append(body);
|
|
352
|
-
if (this.#
|
|
358
|
+
if (!this.#gridScroll) {
|
|
359
|
+
this.#gridScroll = document.createElement("div");
|
|
360
|
+
this.#gridScroll.className = "b3-date-picker-scroll";
|
|
361
|
+
}
|
|
362
|
+
if (this.#gridScroll.parentNode !== this.#ui)
|
|
363
|
+
this.#ui.append(this.#gridScroll);
|
|
364
|
+
if (this.#grid?.parentNode === this.#gridScroll)
|
|
353
365
|
this.#grid.replaceWith(table);
|
|
354
366
|
else
|
|
355
|
-
this.#
|
|
367
|
+
this.#gridScroll.append(table);
|
|
356
368
|
this.#grid = table;
|
|
357
369
|
}
|
|
358
370
|
#ensureBar() {
|
package/dist/manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.1.0-alpha.
|
|
2
|
+
"version": "0.1.0-alpha.40",
|
|
3
3
|
"cssSha256": "d8da259da7aac4ff4c65150029fde71735d8628603359216cf86fb7047246a92",
|
|
4
4
|
"classes": [
|
|
5
5
|
"b3-accordion",
|
|
@@ -175,7 +175,7 @@
|
|
|
175
175
|
"classes": [
|
|
176
176
|
"b3-row"
|
|
177
177
|
],
|
|
178
|
-
"guidance": "Use li inside ul/ol. Direct b3-row children remove native list indentation; ordinary prose lists keep it. The row supplies spacing/dividers; app code owns state, ordering and persistence.\n\nComposition: for a short label plus actions, use b3-row b3-split. For supporting notes, use the stacked example below: b3-row b3-stack stretches children and honors --b3-space; a nested b3-split holds primary metadata/value/actions, and the note gets the full width below. Avoid squeezing long notes beside fixed controls. Inset content only when adding an enclosing border/surface. Keep secondary actions readable and visually subordinate.\n\nLists: show useful rows before large summaries, with a short count and truthful empty state. Never invent user history. If reviewing is primary, use one disclosed add flow (native details/summary with b3-accordion); read form-composition.md. Task queues should show compact rows and reveal editing fields only for the edited item. Use existing disclosure/dialog semantics, not new density utilities. Check populated phone/desktop layouts, long notes and internal overflow.\n\nEditing: keep focused controls and caret/selection stable. Save drafts synchronously before replacing rows. Keep an edited row present while focus remains inside it, even if it stops matching a filter; read editable-filtered-rows.md for Tab/blur and exit timing. Give controls immutable identity independent of changing labels/actions: Edit → Done → Edit must reopen correctly.
|
|
178
|
+
"guidance": "Use li inside ul/ol. Direct b3-row children remove native list indentation; ordinary prose lists keep it. The row supplies spacing/dividers; app code owns state, ordering and persistence.\n\nComposition: for a short label plus actions, use b3-row b3-split. For supporting notes, use the stacked example below: b3-row b3-stack stretches children and honors --b3-space; a nested b3-split holds primary metadata/value/actions, and the note gets the full width below. Avoid squeezing long notes beside fixed controls. Inset content only when adding an enclosing border/surface. Keep secondary actions readable and visually subordinate.\n\nLists: show useful rows before large summaries, with a short count and truthful empty state. Never invent user history. If reviewing is primary, use one disclosed add flow (native details/summary with b3-accordion); read form-composition.md. Task queues should show compact rows and reveal editing fields only for the edited item. Use existing disclosure/dialog semantics, not new density utilities. Check populated phone/desktop layouts, long notes and internal overflow.\n\nEditing: keep focused controls and caret/selection stable. Save drafts synchronously before replacing rows. Keep an edited row present while focus remains inside it, even if it stops matching a filter; read editable-filtered-rows.md for Tab/blur and exit timing. Give controls immutable identity independent of changing labels/actions: Edit → Done → Edit must reopen correctly. Checkbox completion: update the existing input/row and counts in place; never rebuild the list on change. If filtering hides the focused row, focus the next visible checkbox or stable add/filter control. See the concrete checkbox pattern in editable-filtered-rows.md. After deletion focus a surviving action or add control. Verify activeElement and persisted values, not just page width. Playground #row resets local state on reload.",
|
|
179
179
|
"example": "<ul>\n <li class=\"b3-row b3-stack\" style=\"--b3-space:.5rem\">\n <div class=\"b3-split\">\n <strong>Groceries</strong>\n <div class=\"b3-cluster\">\n <strong>$12.50</strong>\n <button class=\"b3-button\" data-b3-emphasis=\"quiet\" aria-label=\"Details for groceries\">Details</button>\n </div>\n </div>\n <p class=\"b3-muted\">Weekly shop and supplies for the shared kitchen.</p>\n </li>\n</ul>"
|
|
180
180
|
},
|
|
181
181
|
{
|
|
@@ -76,6 +76,10 @@ without a framework wrapper.
|
|
|
76
76
|
|
|
77
77
|
The element never selects on its own and never closes anything: it reports, and the owner decides.
|
|
78
78
|
|
|
79
|
+
### Narrow layouts and enlarged text
|
|
80
|
+
|
|
81
|
+
The month heading stacks above navigation when its container is narrow. Day columns keep a readable minimum width; the calendar scrolls horizontally within the picker when enlarged text cannot fit seven columns. Keep that scroll region intact. Roving keyboard focus reveals the focused day; do not shrink the font to force the calendar into a phone width.
|
|
82
|
+
|
|
79
83
|
### Decorating days
|
|
80
84
|
|
|
81
85
|
There is no shadow root and every day is `td[data-b3-date="YYYY-MM-DD"]`, so per-day marks — a
|
|
@@ -29,6 +29,31 @@ list.addEventListener('focusout', event => {
|
|
|
29
29
|
|
|
30
30
|
The timeout defers only filtering. Never defer validation, state updates or persistence to it. Preserve invalid or unfinished field text so users can correct it; do not normalize on every keystroke. In reactive UI, preserve stable row keys and the same focus policy.
|
|
31
31
|
|
|
32
|
+
## Checkbox completion: update the existing row
|
|
33
|
+
|
|
34
|
+
Do not rebuild the list with `innerHTML` or `replaceChildren` on checkbox change: that removes the focused input, so the next Space/Tab starts from the page instead of the task. Keep the same checkbox node (stable keys in a framework). Commit the checked state, update counts and row styling in place, then apply the filter. When completion hides the focused row, move focus to the next visible checkbox, then the previous one, then a stable add/filter control. Do not steal focus for background updates.
|
|
35
|
+
|
|
36
|
+
Here `checkbox`, `row`, `list`, and `addControl` are existing DOM nodes. `commitChecked` and `updateCountsAndFilter` are app-owned functions; the latter updates text/hidden attributes without replacing rows. Commit before hiding; on failure roll back the checkbox and announce the error.
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
checkbox.addEventListener('change', () => {
|
|
40
|
+
const ownedFocus = row.contains(document.activeElement);
|
|
41
|
+
const rows = [...list.children];
|
|
42
|
+
const index = rows.indexOf(row);
|
|
43
|
+
commitChecked(row.dataset.id, checkbox.checked);
|
|
44
|
+
row.toggleAttribute('data-complete', checkbox.checked);
|
|
45
|
+
updateCountsAndFilter();
|
|
46
|
+
if (!ownedFocus || !row.hidden) return;
|
|
47
|
+
const neighbors = [...rows.slice(index + 1), ...rows.slice(0, index).reverse()];
|
|
48
|
+
const next = neighbors.filter(el => !el.hidden)
|
|
49
|
+
.map(el => el.querySelector('input[type="checkbox"]'))
|
|
50
|
+
.find(el => el && !el.disabled);
|
|
51
|
+
(next || addControl).focus();
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Check with real keyboard input: in All, focus a checkbox and press Space twice; the same input remains focused and toggles both times. In To do, completion hides that row and focus reaches a surviving checkbox; completing the final row reaches the add/filter control. Also verify persistence after reload. The playground's Lists → “Before you head out” demonstrates stable rows and filter fallback (local example state only).
|
|
56
|
+
|
|
32
57
|
## Explicit Save, Cancel and Delete
|
|
33
58
|
|
|
34
59
|
Replacing an editor also removes its focused Save/Cancel button. Complete persistence and rendering/filtering first, then choose a connected, visible destination. On Save/Cancel prefer that row's new Edit button; if the row is hidden or removed, use a surviving row action or the stable add/filter control. Never select the row being deleted as its own fallback. Move focus only when the changed row owned it.
|
package/dist/references/row.md
CHANGED
|
@@ -6,7 +6,7 @@ Composition: for a short label plus actions, use b3-row b3-split. For supporting
|
|
|
6
6
|
|
|
7
7
|
Lists: show useful rows before large summaries, with a short count and truthful empty state. Never invent user history. If reviewing is primary, use one disclosed add flow (native details/summary with b3-accordion); read form-composition.md. Task queues should show compact rows and reveal editing fields only for the edited item. Use existing disclosure/dialog semantics, not new density utilities. Check populated phone/desktop layouts, long notes and internal overflow.
|
|
8
8
|
|
|
9
|
-
Editing: keep focused controls and caret/selection stable. Save drafts synchronously before replacing rows. Keep an edited row present while focus remains inside it, even if it stops matching a filter; read editable-filtered-rows.md for Tab/blur and exit timing. Give controls immutable identity independent of changing labels/actions: Edit → Done → Edit must reopen correctly.
|
|
9
|
+
Editing: keep focused controls and caret/selection stable. Save drafts synchronously before replacing rows. Keep an edited row present while focus remains inside it, even if it stops matching a filter; read editable-filtered-rows.md for Tab/blur and exit timing. Give controls immutable identity independent of changing labels/actions: Edit → Done → Edit must reopen correctly. Checkbox completion: update the existing input/row and counts in place; never rebuild the list on change. If filtering hides the focused row, focus the next visible checkbox or stable add/filter control. See the concrete checkbox pattern in editable-filtered-rows.md. After deletion focus a surviving action or add control. Verify activeElement and persisted values, not just page width. Playground #row resets local state on reload.
|
|
10
10
|
|
|
11
11
|
Classes: b3-row
|
|
12
12
|
|