flexdesk 0.6.3 → 0.7.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 +326 -0
- package/css/base.css +333 -0
- package/css/flexdesk.css +333 -0
- package/dist/charts.js +2 -2
- package/dist/{chunk-WLASPRGP.js → chunk-JLCJWCRS.js} +1577 -56
- package/dist/chunk-JLCJWCRS.js.map +7 -0
- package/dist/{chunk-WAVLVXYV.js → chunk-WKTYKXWF.js} +2 -2
- package/dist/flexdesk.css +333 -0
- package/dist/flow.js +24 -8
- package/dist/flow.js.map +2 -2
- package/dist/tiles.js +2 -2
- package/dist/widgets.js +672 -1
- package/dist/widgets.js.map +4 -4
- package/package.json +1 -1
- package/src/flow/outline/editor.js +46 -8
- package/src/ui/components/data_table.js +1650 -66
- package/src/ui/components/fact_table.js +342 -0
- package/src/ui/components/record_list.js +594 -0
- package/src/ui/components/table_filter_chips.js +153 -0
- package/dist/chunk-WLASPRGP.js.map +0 -7
- /package/dist/{chunk-WAVLVXYV.js.map → chunk-WKTYKXWF.js.map} +0 -0
package/package.json
CHANGED
|
@@ -27,7 +27,9 @@
|
|
|
27
27
|
* ══ GESTURES ════════════════════════════════════════════════════════════
|
|
28
28
|
*
|
|
29
29
|
* A press SELECTS — it toggles classes and fills the settings panel, and
|
|
30
|
-
* rebuilds no row, so the click lands on the node the press went down on.
|
|
30
|
+
* rebuilds no row, so the click lands on the node the press went down on. In
|
|
31
|
+
* a narrow editor, where the panel is stacked under the list, a press (like
|
|
32
|
+
* Enter, Go to it and `select()`) scrolls the panel on screen when it is off it.
|
|
31
33
|
* "+" between rows (on hover AND on focus), the add rows and a row's menu
|
|
32
34
|
* open the step picker and the step menu, both the kit's popovers. A step is
|
|
33
35
|
* dragged by its grip with POINTER EVENTS and a ghost on `document.body`
|
|
@@ -528,7 +530,7 @@ export function createOutlineEditor(host, options = {}) {
|
|
|
528
530
|
if (fs.length) row.appendChild(badge(fs));
|
|
529
531
|
item.appendChild(row);
|
|
530
532
|
item.setAttribute('aria-label', [map.startLabel(S), sum].filter(Boolean).join(', '));
|
|
531
|
-
row.addEventListener('click', () => select('flow', { focus: true }));
|
|
533
|
+
row.addEventListener('click', () => select('flow', { focus: true, picked: true }));
|
|
532
534
|
if (filter) item.classList.add('twm-flow-outline__item--context');
|
|
533
535
|
itemEls.set('flow', item);
|
|
534
536
|
return item;
|
|
@@ -645,7 +647,7 @@ export function createOutlineEditor(host, options = {}) {
|
|
|
645
647
|
row.appendChild(menu);
|
|
646
648
|
row.addEventListener('contextmenu', (ev) => { ev.preventDefault(); select(item.id); openMenu(item.id, menu); });
|
|
647
649
|
}
|
|
648
|
-
row.addEventListener('click', () => select(item.id, { focus: true }));
|
|
650
|
+
row.addEventListener('click', () => select(item.id, { focus: true, picked: true }));
|
|
649
651
|
return { row, label: [name, type?.label !== name ? type?.label : null, summary].filter(Boolean).join(', ') };
|
|
650
652
|
}
|
|
651
653
|
|
|
@@ -836,7 +838,13 @@ export function createOutlineEditor(host, options = {}) {
|
|
|
836
838
|
}
|
|
837
839
|
}
|
|
838
840
|
|
|
839
|
-
|
|
841
|
+
/**
|
|
842
|
+
* `picked`: the step was PICKED — a press on its row, Go to it, `select()`
|
|
843
|
+
* — so its settings are what the person looks at next, and they are
|
|
844
|
+
* brought on screen (`revealSettings`). ↑ ↓ ← → only move the selection
|
|
845
|
+
* through the list and leave the list where it is.
|
|
846
|
+
*/
|
|
847
|
+
function select(id, { focus = false, silent = false, picked = false } = {}) {
|
|
840
848
|
const next = id === null || id === undefined ? 'flow' : id;
|
|
841
849
|
const changed = next !== selected;
|
|
842
850
|
selected = next;
|
|
@@ -844,9 +852,33 @@ export function createOutlineEditor(host, options = {}) {
|
|
|
844
852
|
if (changed) { showPanel(); drawAside(); }
|
|
845
853
|
void silent;
|
|
846
854
|
if (focus) itemEls.get(selected)?.focus({ preventScroll: false });
|
|
855
|
+
if (picked) revealSettings();
|
|
847
856
|
if (changed) onSelect?.({ kind: selected === 'flow' ? 'flow' : 'step', id: selected === 'flow' ? null : selected });
|
|
848
857
|
}
|
|
849
858
|
|
|
859
|
+
/**
|
|
860
|
+
* BRING THE SETTINGS ON SCREEN when the layout has put them off it — the
|
|
861
|
+
* one rule for Enter, a press on a row, Go to it and `select()`. Under
|
|
862
|
+
* 1000px the columns wrap and the body scrolls as one (the container query
|
|
863
|
+
* in the sheet), so the panel sits under the whole list: a step picked
|
|
864
|
+
* there filled a panel ~860px below with nothing scrolled, and the press
|
|
865
|
+
* looked like it did nothing. A panel wholly inside the body's visible box
|
|
866
|
+
* — always, side by side, where the panel IS the body's height — or one
|
|
867
|
+
* that covers it is left alone, so nothing moves, the page included;
|
|
868
|
+
* otherwise it is scrolled into view, 'nearest' (all of it when it fits,
|
|
869
|
+
* its top when it does not).
|
|
870
|
+
*/
|
|
871
|
+
function revealSettings() {
|
|
872
|
+
if (destroyed) return;
|
|
873
|
+
const box = body.getBoundingClientRect();
|
|
874
|
+
if (!box.height) return; // not laid out: hidden, detached
|
|
875
|
+
const r = settingsHost.getBoundingClientRect();
|
|
876
|
+
const inside = r.top >= box.top - 1 && r.bottom <= box.bottom + 1;
|
|
877
|
+
const covers = r.top <= box.top + 1 && r.bottom >= box.bottom - 1;
|
|
878
|
+
if (inside || covers) return;
|
|
879
|
+
settingsHost.scrollIntoView?.({ block: 'nearest' });
|
|
880
|
+
}
|
|
881
|
+
|
|
850
882
|
function focusSelected() {
|
|
851
883
|
const li = itemEls.get(selected) ?? itemEls.get('flow');
|
|
852
884
|
if (li) li.focus({ preventScroll: true });
|
|
@@ -1152,7 +1184,8 @@ export function createOutlineEditor(host, options = {}) {
|
|
|
1152
1184
|
}
|
|
1153
1185
|
|
|
1154
1186
|
function rename(id) {
|
|
1155
|
-
|
|
1187
|
+
// The title is focused without scrolling, so it is brought on screen first.
|
|
1188
|
+
select(id, { picked: true });
|
|
1156
1189
|
const input = settingsHost.querySelector('[data-twm-flow-title]');
|
|
1157
1190
|
if (input) { input.focus({ preventScroll: true }); input.select?.(); }
|
|
1158
1191
|
}
|
|
@@ -1168,7 +1201,7 @@ export function createOutlineEditor(host, options = {}) {
|
|
|
1168
1201
|
function goTo(f) {
|
|
1169
1202
|
const id = f?.node_id && nodeOf(f.node_id) ? f.node_id : 'flow';
|
|
1170
1203
|
if (reveal(id)) render();
|
|
1171
|
-
select(id, { focus: true });
|
|
1204
|
+
select(id, { focus: true, picked: true });
|
|
1172
1205
|
if (f?.field) panel.focusField(f.field);
|
|
1173
1206
|
}
|
|
1174
1207
|
|
|
@@ -1208,6 +1241,7 @@ export function createOutlineEditor(host, options = {}) {
|
|
|
1208
1241
|
const f = settingsHost.querySelector('.twm-flow-panel__fields input, .twm-flow-panel__fields select, '
|
|
1209
1242
|
+ '.twm-flow-panel__fields textarea, .twm-flow-panel__fields [contenteditable="true"], .twm-flow-panel__fields button')
|
|
1210
1243
|
|| settingsHost.querySelector('[data-twm-flow-title]');
|
|
1244
|
+
if (f) revealSettings();
|
|
1211
1245
|
f?.focus({ preventScroll: false });
|
|
1212
1246
|
return Boolean(f);
|
|
1213
1247
|
},
|
|
@@ -1477,11 +1511,15 @@ export function createOutlineEditor(host, options = {}) {
|
|
|
1477
1511
|
updateTools();
|
|
1478
1512
|
},
|
|
1479
1513
|
setStatus(text) { statusEl.textContent = text ?? ''; },
|
|
1480
|
-
/**
|
|
1514
|
+
/**
|
|
1515
|
+
* Select a step (unfolding the blocks around it, so it is on the
|
|
1516
|
+
* screen), the flow, or nothing — and, in a narrow editor whose panel
|
|
1517
|
+
* is scrolled off, bring its settings on screen as a press does.
|
|
1518
|
+
*/
|
|
1481
1519
|
select(id) {
|
|
1482
1520
|
const want = id === null || id === undefined ? 'flow' : id;
|
|
1483
1521
|
if (want !== 'flow' && reveal(want)) render();
|
|
1484
|
-
select(want);
|
|
1522
|
+
select(want, { picked: true });
|
|
1485
1523
|
},
|
|
1486
1524
|
focus() { focusSelected(); },
|
|
1487
1525
|
undo() { if (editable() && history.undo()) emit('undo'); },
|