@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 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; }
@@ -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' ? 'Open' : 'Save here', ok: false, note: '' };
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: 'Open project', ok: true, note: 'A project is here.' };
59
- if (info.kind === 'collection') return { text: 'Open collection', ok: true, note: `${info.projects} project${info.projects === 1 ? '' : 's'} here — pick one on the next page.` };
60
- if (info.kind === 'new') return { text: 'Create project here', ok: true, note: 'No project in this folder yet.' };
61
- return { text: 'Open project', ok: false, note: 'This folder does not exist.' };
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: 'Save here', ok: false, note: 'This folder already holds projects. Choose a new or empty folder.' };
64
- if (info.kind === 'missing') return { text: 'Save here', ok: true, note: `Will create ${info.missing}.` };
65
- return { text: 'Save here', ok: true, note: 'The folder must be empty.' };
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
- primary.textContent = busy ? 'Working…' : state.text;
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');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@divlet/web",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "The divlet browser board, static client assets and transport-free host ports",
5
5
  "type": "module",
6
6
  "license": "MIT",