@divlet/web 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/board.css +3 -1
- package/dist/lib/project.js +19 -9
- package/package.json +1 -1
package/dist/board.css
CHANGED
|
@@ -630,7 +630,9 @@ body.bar-dragging { user-select: none; }
|
|
|
630
630
|
/* Anchored to the top so a longer message or recovery box grows downward and never moves the controls above it. */
|
|
631
631
|
#project { place-items: start center; padding-top: min(calc(var(--vh) * 0.14), 120px); }
|
|
632
632
|
#project .dialog-foot { align-items: flex-start; padding-bottom: 0; }
|
|
633
|
-
.project-go { height: 32px; min-width: 156px; padding: 0 14px; }
|
|
633
|
+
.project-go { display: inline-grid; grid-template-columns: minmax(0, 1fr); height: auto; min-height: 32px; min-width: min(156px, 100%); max-width: 100%; padding: 0 14px; }
|
|
634
|
+
.project-go > span { grid-area: 1 / 1; min-width: 0; }
|
|
635
|
+
.project-go-sizer { visibility: hidden; pointer-events: none; }
|
|
634
636
|
.project-go:disabled { opacity: var(--disabled); cursor: default; }
|
|
635
637
|
/* Read-only external-file recovery (picker, launcher and diagnostics). */
|
|
636
638
|
.project-recovery:empty, .project-revision:empty { display: none; }
|
package/dist/lib/project.js
CHANGED
|
@@ -47,27 +47,29 @@ const clearRecovery = () => { failure = ''; recovery.replaceChildren(); };
|
|
|
47
47
|
let input;
|
|
48
48
|
let status;
|
|
49
49
|
let primary;
|
|
50
|
+
let primaryLabel;
|
|
51
|
+
const actionLabels = { open: 'Open', save: 'Save here', project: 'Open project', collection: 'Open collection', create: 'Create project here', working: 'Working…' };
|
|
50
52
|
|
|
51
53
|
export const isOpen = () => !scrim.hidden;
|
|
52
54
|
export const canShowCopy = () => !!store.state?.project?.capabilities?.saveAs;
|
|
53
55
|
|
|
54
56
|
function label() {
|
|
55
57
|
const info = picker?.state.info;
|
|
56
|
-
if (!info) return { text: mode === 'open' ?
|
|
58
|
+
if (!info) return { text: mode === 'open' ? actionLabels.open : actionLabels.save, ok: false, note: '' };
|
|
57
59
|
if (mode === 'open') {
|
|
58
|
-
if (info.kind === 'project') return { text:
|
|
59
|
-
if (info.kind === 'collection') return { text:
|
|
60
|
-
if (info.kind === 'new') return { text:
|
|
61
|
-
return { text:
|
|
60
|
+
if (info.kind === 'project') return { text: actionLabels.project, ok: true, note: 'A project is here.' };
|
|
61
|
+
if (info.kind === 'collection') return { text: actionLabels.collection, ok: true, note: `${info.projects} project${info.projects === 1 ? '' : 's'} here — pick one on the next page.` };
|
|
62
|
+
if (info.kind === 'new') return { text: actionLabels.create, ok: true, note: 'No project in this folder yet.' };
|
|
63
|
+
return { text: actionLabels.project, ok: false, note: 'This folder does not exist.' };
|
|
62
64
|
}
|
|
63
|
-
if (info.kind === 'project' || info.kind === 'collection') return { text:
|
|
64
|
-
if (info.kind === 'missing') return { text:
|
|
65
|
-
return { text:
|
|
65
|
+
if (info.kind === 'project' || info.kind === 'collection') return { text: actionLabels.save, ok: false, note: 'This folder already holds projects. Choose a new or empty folder.' };
|
|
66
|
+
if (info.kind === 'missing') return { text: actionLabels.save, ok: true, note: `Will create ${info.missing}.` };
|
|
67
|
+
return { text: actionLabels.save, ok: true, note: 'The folder must be empty.' };
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
function paintControls() {
|
|
69
71
|
const state = label();
|
|
70
|
-
|
|
72
|
+
primaryLabel.textContent = busy ? actionLabels.working : state.text;
|
|
71
73
|
// Keep keyboard focus inside the modal when pending work disables a focused control.
|
|
72
74
|
const focused = document.activeElement;
|
|
73
75
|
if (focused === primary && (busy || !state.ok)) input.focus({ preventScroll: true });
|
|
@@ -127,6 +129,14 @@ function render() {
|
|
|
127
129
|
status = el('span', 'caption project-status');
|
|
128
130
|
status.setAttribute('role', 'status');
|
|
129
131
|
primary = el('button', 'cta project-go');
|
|
132
|
+
primaryLabel = el('span', 'project-go-label');
|
|
133
|
+
primary.append(primaryLabel);
|
|
134
|
+
// All state labels share one grid cell, reserving real font-dependent width without another accessible control.
|
|
135
|
+
for (const text of Object.values(actionLabels)) {
|
|
136
|
+
const sizer = el('span', 'project-go-sizer', text);
|
|
137
|
+
sizer.setAttribute('aria-hidden', 'true');
|
|
138
|
+
primary.append(sizer);
|
|
139
|
+
}
|
|
130
140
|
primary.type = 'button';
|
|
131
141
|
primary.addEventListener('click', submit);
|
|
132
142
|
const foot = el('div', 'dialog-foot');
|