@dou-ui/sheet 0.0.0-stage → 0.1.0-alpha.1
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/LICENSE +21 -0
- package/README.md +10 -2
- package/dist/cell-types.js +20 -0
- package/dist/cell-types.js.map +1 -0
- package/dist/code/code-formula-bar.js +6 -0
- package/dist/code/code-formula-bar.js.map +1 -0
- package/dist/code/code-formula-bar.vue_vue_type_script_setup_true_lang.js +192 -0
- package/dist/code/code-formula-bar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/code/index.js +12 -0
- package/dist/code/index.js.map +1 -0
- package/dist/code/language.js +51 -0
- package/dist/code/language.js.map +1 -0
- package/dist/code/style.d.ts +1 -0
- package/dist/code/style.js +2 -0
- package/dist/collaboration/anchor.js +143 -0
- package/dist/collaboration/anchor.js.map +1 -0
- package/dist/collaboration/index.js +770 -0
- package/dist/collaboration/index.js.map +1 -0
- package/dist/collaboration/peers.js +87 -0
- package/dist/collaboration/peers.js.map +1 -0
- package/dist/collaboration/shared.js +450 -0
- package/dist/collaboration/shared.js.map +1 -0
- package/dist/components/cell-panel.js +6 -0
- package/dist/components/cell-panel.js.map +1 -0
- package/dist/components/cell-panel.vue_vue_type_script_setup_true_lang.js +70 -0
- package/dist/components/cell-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/cell-renders.js +40 -0
- package/dist/components/cell-renders.js.map +1 -0
- package/dist/components/date-panel.js +6 -0
- package/dist/components/date-panel.js.map +1 -0
- package/dist/components/date-panel.vue_vue_type_script_setup_true_lang.js +48 -0
- package/dist/components/date-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/filter-panel.js +6 -0
- package/dist/components/filter-panel.js.map +1 -0
- package/dist/components/filter-panel.vue_vue_type_script_setup_true_lang.js +259 -0
- package/dist/components/filter-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/format-dialog.js +6 -0
- package/dist/components/format-dialog.js.map +1 -0
- package/dist/components/format-dialog.vue_vue_type_script_setup_true_lang.js +432 -0
- package/dist/components/format-dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/format-list.js +6 -0
- package/dist/components/format-list.js.map +1 -0
- package/dist/components/format-list.vue_vue_type_script_setup_true_lang.js +187 -0
- package/dist/components/format-list.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/format-presets.js +97 -0
- package/dist/components/format-presets.js.map +1 -0
- package/dist/components/option-panel.js +6 -0
- package/dist/components/option-panel.js.map +1 -0
- package/dist/components/option-panel.vue_vue_type_script_setup_true_lang.js +117 -0
- package/dist/components/option-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/sheet-comment.js +6 -0
- package/dist/components/sheet-comment.js.map +1 -0
- package/dist/components/sheet-comment.vue_vue_type_script_setup_true_lang.js +104 -0
- package/dist/components/sheet-comment.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/sheet-formula-bar.js +6 -0
- package/dist/components/sheet-formula-bar.js.map +1 -0
- package/dist/components/sheet-formula-bar.vue_vue_type_script_setup_true_lang.js +124 -0
- package/dist/components/sheet-formula-bar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/sheet-link.js +6 -0
- package/dist/components/sheet-link.js.map +1 -0
- package/dist/components/sheet-link.vue_vue_type_script_setup_true_lang.js +249 -0
- package/dist/components/sheet-link.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/sheet-menu.js +6 -0
- package/dist/components/sheet-menu.js.map +1 -0
- package/dist/components/sheet-menu.vue_vue_type_script_setup_true_lang.js +115 -0
- package/dist/components/sheet-menu.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/sheet-name-box.js +6 -0
- package/dist/components/sheet-name-box.js.map +1 -0
- package/dist/components/sheet-name-box.vue_vue_type_script_setup_true_lang.js +91 -0
- package/dist/components/sheet-name-box.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/sheet-note.js +6 -0
- package/dist/components/sheet-note.js.map +1 -0
- package/dist/components/sheet-note.vue_vue_type_script_setup_true_lang.js +146 -0
- package/dist/components/sheet-note.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/sheet-outline.js +6 -0
- package/dist/components/sheet-outline.js.map +1 -0
- package/dist/components/sheet-outline.vue_vue_type_script_setup_true_lang.js +237 -0
- package/dist/components/sheet-outline.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/sheet-tabs.js +6 -0
- package/dist/components/sheet-tabs.js.map +1 -0
- package/dist/components/sheet-tabs.vue_vue_type_script_setup_true_lang.js +487 -0
- package/dist/components/sheet-tabs.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/sheet-toolbar.js +6 -0
- package/dist/components/sheet-toolbar.js.map +1 -0
- package/dist/components/sheet-toolbar.vue_vue_type_script_setup_true_lang.js +1562 -0
- package/dist/components/sheet-toolbar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/validation-dialog.js +6 -0
- package/dist/components/validation-dialog.js.map +1 -0
- package/dist/components/validation-dialog.vue_vue_type_script_setup_true_lang.js +370 -0
- package/dist/components/validation-dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/context.js +12 -0
- package/dist/context.js.map +1 -0
- package/dist/core/address.js +256 -0
- package/dist/core/address.js.map +1 -0
- package/dist/core/axis.js +72 -0
- package/dist/core/axis.js.map +1 -0
- package/dist/core/cell-type.js +30 -0
- package/dist/core/cell-type.js.map +1 -0
- package/dist/core/clipboard.js +141 -0
- package/dist/core/clipboard.js.map +1 -0
- package/dist/core/commands.js +63 -0
- package/dist/core/commands.js.map +1 -0
- package/dist/core/comments.js +74 -0
- package/dist/core/comments.js.map +1 -0
- package/dist/core/conditional.js +362 -0
- package/dist/core/conditional.js.map +1 -0
- package/dist/core/csv.js +191 -0
- package/dist/core/csv.js.map +1 -0
- package/dist/core/data.js +118 -0
- package/dist/core/data.js.map +1 -0
- package/dist/core/document.js +187 -0
- package/dist/core/document.js.map +1 -0
- package/dist/core/extension.js +60 -0
- package/dist/core/extension.js.map +1 -0
- package/dist/core/file.js +336 -0
- package/dist/core/file.js.map +1 -0
- package/dist/core/fill.js +153 -0
- package/dist/core/fill.js.map +1 -0
- package/dist/core/find.js +42 -0
- package/dist/core/find.js.map +1 -0
- package/dist/core/format.js +404 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/group.js +134 -0
- package/dist/core/group.js.map +1 -0
- package/dist/core/history.js +68 -0
- package/dist/core/history.js.map +1 -0
- package/dist/core/index.js +17 -0
- package/dist/core/link.js +34 -0
- package/dist/core/link.js.map +1 -0
- package/dist/core/merge.js +105 -0
- package/dist/core/merge.js.map +1 -0
- package/dist/core/model.js +48 -0
- package/dist/core/model.js.map +1 -0
- package/dist/core/nav.js +44 -0
- package/dist/core/nav.js.map +1 -0
- package/dist/core/paint.js +106 -0
- package/dist/core/paint.js.map +1 -0
- package/dist/core/plain-cell-types.js +54 -0
- package/dist/core/plain-cell-types.js.map +1 -0
- package/dist/core/protect.js +246 -0
- package/dist/core/protect.js.map +1 -0
- package/dist/core/selection.js +37 -0
- package/dist/core/selection.js.map +1 -0
- package/dist/core/transaction.js +1582 -0
- package/dist/core/transaction.js.map +1 -0
- package/dist/core/validation.js +135 -0
- package/dist/core/validation.js.map +1 -0
- package/dist/core/versions.js +161 -0
- package/dist/core/versions.js.map +1 -0
- package/dist/export/color.js +36 -0
- package/dist/export/color.js.map +1 -0
- package/dist/export/draw.js +316 -0
- package/dist/export/draw.js.map +1 -0
- package/dist/export/index.js +390 -0
- package/dist/export/index.js.map +1 -0
- package/dist/formula/edit.js +210 -0
- package/dist/formula/edit.js.map +1 -0
- package/dist/formula/engine.js +526 -0
- package/dist/formula/engine.js.map +1 -0
- package/dist/formula/error.js +39 -0
- package/dist/formula/error.js.map +1 -0
- package/dist/formula/functions.js +1493 -0
- package/dist/formula/functions.js.map +1 -0
- package/dist/formula/help.js +408 -0
- package/dist/formula/help.js.map +1 -0
- package/dist/formula/index.js +7 -0
- package/dist/formula/parse.js +369 -0
- package/dist/formula/parse.js.map +1 -0
- package/dist/formula/values.js +123 -0
- package/dist/formula/values.js.map +1 -0
- package/dist/formulas.js +30 -0
- package/dist/formulas.js.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/locale.js +1312 -0
- package/dist/locale.js.map +1 -0
- package/dist/sheet.js +6 -0
- package/dist/sheet.js.map +1 -0
- package/dist/sheet.vue_vue_type_script_setup_true_lang.js +7166 -0
- package/dist/sheet.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/style.css +1 -0
- package/dist/style.d.ts +1 -0
- package/dist/style.js +17 -0
- package/dist/types/cell-types.d.ts +2 -0
- package/dist/types/code/code-formula-bar.vue.d.ts +3 -0
- package/dist/types/code/index.d.ts +12 -0
- package/dist/types/code/language.d.ts +13 -0
- package/dist/types/collaboration/anchor.d.ts +65 -0
- package/dist/types/collaboration/index.d.ts +59 -0
- package/dist/types/collaboration/peers.d.ts +21 -0
- package/dist/types/collaboration/shared.d.ts +75 -0
- package/dist/types/components/cell-panel.vue.d.ts +20 -0
- package/dist/types/components/cell-renders.d.ts +9 -0
- package/dist/types/components/date-panel.vue.d.ts +9 -0
- package/dist/types/components/filter-panel.vue.d.ts +21 -0
- package/dist/types/components/format-dialog.vue.d.ts +24 -0
- package/dist/types/components/format-list.vue.d.ts +25 -0
- package/dist/types/components/format-presets.d.ts +30 -0
- package/dist/types/components/option-panel.vue.d.ts +13 -0
- package/dist/types/components/sheet-comment.vue.d.ts +29 -0
- package/dist/types/components/sheet-formula-bar.vue.d.ts +3 -0
- package/dist/types/components/sheet-link.vue.d.ts +32 -0
- package/dist/types/components/sheet-menu.vue.d.ts +20 -0
- package/dist/types/components/sheet-name-box.vue.d.ts +3 -0
- package/dist/types/components/sheet-note.vue.d.ts +22 -0
- package/dist/types/components/sheet-outline.vue.d.ts +36 -0
- package/dist/types/components/sheet-tabs.vue.d.ts +9 -0
- package/dist/types/components/sheet-toolbar.vue.d.ts +11 -0
- package/dist/types/components/validation-dialog.vue.d.ts +25 -0
- package/dist/types/context.d.ts +189 -0
- package/dist/types/core/address.d.ts +109 -0
- package/dist/types/core/axis.d.ts +23 -0
- package/dist/types/core/cell-type.d.ts +157 -0
- package/dist/types/core/clipboard.d.ts +48 -0
- package/dist/types/core/commands.d.ts +76 -0
- package/dist/types/core/comments.d.ts +22 -0
- package/dist/types/core/conditional.d.ts +114 -0
- package/dist/types/core/csv.d.ts +93 -0
- package/dist/types/core/data.d.ts +26 -0
- package/dist/types/core/document.d.ts +49 -0
- package/dist/types/core/extension.d.ts +177 -0
- package/dist/types/core/file.d.ts +301 -0
- package/dist/types/core/fill.d.ts +23 -0
- package/dist/types/core/find.d.ts +39 -0
- package/dist/types/core/format.d.ts +47 -0
- package/dist/types/core/group.d.ts +76 -0
- package/dist/types/core/history.d.ts +27 -0
- package/dist/types/core/index.d.ts +33 -0
- package/dist/types/core/link.d.ts +14 -0
- package/dist/types/core/merge.d.ts +26 -0
- package/dist/types/core/model.d.ts +363 -0
- package/dist/types/core/nav.d.ts +15 -0
- package/dist/types/core/paint.d.ts +19 -0
- package/dist/types/core/plain-cell-types.d.ts +6 -0
- package/dist/types/core/protect.d.ts +34 -0
- package/dist/types/core/selection.d.ts +25 -0
- package/dist/types/core/transaction.d.ts +470 -0
- package/dist/types/core/validation.d.ts +55 -0
- package/dist/types/core/versions.d.ts +38 -0
- package/dist/types/export/color.d.ts +7 -0
- package/dist/types/export/draw.d.ts +98 -0
- package/dist/types/export/index.d.ts +47 -0
- package/dist/types/formula/edit.d.ts +62 -0
- package/dist/types/formula/engine.d.ts +99 -0
- package/dist/types/formula/error.d.ts +30 -0
- package/dist/types/formula/functions.d.ts +62 -0
- package/dist/types/formula/help.d.ts +12 -0
- package/dist/types/formula/index.d.ts +13 -0
- package/dist/types/formula/parse.d.ts +92 -0
- package/dist/types/formula/values.d.ts +65 -0
- package/dist/types/formulas.d.ts +32 -0
- package/dist/types/index.d.ts +225 -0
- package/dist/types/locale.d.ts +531 -0
- package/dist/types/sheet.vue.d.ts +60 -0
- package/dist/types/types.d.ts +498 -0
- package/dist/types/use-comments.d.ts +47 -0
- package/dist/types/use-messages.d.ts +7 -0
- package/dist/use-comments.js +130 -0
- package/dist/use-comments.js.map +1 -0
- package/dist/use-messages.js +29 -0
- package/dist/use-messages.js.map +1 -0
- package/package.json +93 -4
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
import { cellOf, colCountOf, compactCell, rowCountOf } from "../core/model.js";
|
|
2
|
+
import { SheetLayout, SheetLines, anchorCell, anchorRange, anchorText, resolveCell, resolveRange, resolveText } from "./anchor.js";
|
|
3
|
+
import * as Y from "yjs";
|
|
4
|
+
// src/collaboration/shared.ts
|
|
5
|
+
/** The fields of a sheet that aren't kept in `meta`. */
|
|
6
|
+
var OWN_FIELDS = /* @__PURE__ */ new Set([
|
|
7
|
+
"id",
|
|
8
|
+
"cells",
|
|
9
|
+
"rowSizes",
|
|
10
|
+
"colSizes",
|
|
11
|
+
"rowCount",
|
|
12
|
+
"colCount"
|
|
13
|
+
]);
|
|
14
|
+
var isMetaKey = (key) => !OWN_FIELDS.has(key);
|
|
15
|
+
/** The parts of the shared workbook; its other keys are the workbook's own settings, such as `protect`. */
|
|
16
|
+
var BOOK_PARTS = /* @__PURE__ */ new Set([
|
|
17
|
+
"styles",
|
|
18
|
+
"types",
|
|
19
|
+
"order",
|
|
20
|
+
"sheets"
|
|
21
|
+
]);
|
|
22
|
+
/** Whether a key of the workbook is one of its own settings, kept as it is in the shared map. */
|
|
23
|
+
var isBookKey = (key) => !BOOK_PARTS.has(key);
|
|
24
|
+
/** The fields of a sheet whose ranges or formulas are anchored to its lines. */
|
|
25
|
+
var ANCHORED_META = [
|
|
26
|
+
"merges",
|
|
27
|
+
"filter",
|
|
28
|
+
"conditionalFormats",
|
|
29
|
+
"validations",
|
|
30
|
+
"groups"
|
|
31
|
+
];
|
|
32
|
+
var cellKey = (row, col) => `${row}:${col}`;
|
|
33
|
+
var threadKey = (key) => `${key}#`;
|
|
34
|
+
var isThreadKey = (key) => key.endsWith("#");
|
|
35
|
+
/** The cell a key is about: the cell's own key for its thread's. */
|
|
36
|
+
var cellOfKey = (key) => isThreadKey(key) ? key.slice(0, -1) : key;
|
|
37
|
+
/** A cell with the thread kept beside it. */
|
|
38
|
+
function withThread(cell, thread) {
|
|
39
|
+
if (typeof thread !== "string" || !thread) return cell;
|
|
40
|
+
return compactCell({
|
|
41
|
+
...cellOf(cell),
|
|
42
|
+
comment: thread
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/** A cell without its thread, and the thread. */
|
|
46
|
+
function splitThread(cell) {
|
|
47
|
+
if (!cell || typeof cell !== "object" || !cell.comment) return [cell, void 0];
|
|
48
|
+
return [compactCell({
|
|
49
|
+
...cell,
|
|
50
|
+
comment: void 0
|
|
51
|
+
}), cell.comment];
|
|
52
|
+
}
|
|
53
|
+
/** Where a cell kept under `key` is now; `-1` for a line that is gone. */
|
|
54
|
+
function cellAt(key, here) {
|
|
55
|
+
const split = key.indexOf(":");
|
|
56
|
+
return {
|
|
57
|
+
row: here.rows.indexOf(key.slice(0, split)),
|
|
58
|
+
col: here.cols.indexOf(key.slice(split + 1))
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** Sizes kept by line id, by line number. */
|
|
62
|
+
function sizesOf(map, lines) {
|
|
63
|
+
const out = {};
|
|
64
|
+
map.forEach((size, id) => {
|
|
65
|
+
const at = lines.indexOf(id);
|
|
66
|
+
if (at >= 0 && typeof size === "number") out[at] = size;
|
|
67
|
+
});
|
|
68
|
+
return Object.keys(out).length ? out : void 0;
|
|
69
|
+
}
|
|
70
|
+
/** Ids for new lines and sheets, unique across the people editing one document. */
|
|
71
|
+
var counters = /* @__PURE__ */ new WeakMap();
|
|
72
|
+
function makeIds(doc) {
|
|
73
|
+
const owner = doc ?? {};
|
|
74
|
+
let counter = counters.get(owner);
|
|
75
|
+
if (!counter) counters.set(owner, counter = { n: 0 });
|
|
76
|
+
const prefix = `${(doc?.clientID ?? Math.floor(Math.random() * 2 ** 32)).toString(36)}.`;
|
|
77
|
+
const next = () => prefix + (counter.n++).toString(36);
|
|
78
|
+
return {
|
|
79
|
+
next,
|
|
80
|
+
many: (count) => Array.from({ length: count }, next)
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/** A list without repeats, the first of each kept. */
|
|
84
|
+
function unique(list) {
|
|
85
|
+
const seen = /* @__PURE__ */ new Set();
|
|
86
|
+
const out = [];
|
|
87
|
+
for (const id of list) if (!seen.has(id)) {
|
|
88
|
+
seen.add(id);
|
|
89
|
+
out.push(id);
|
|
90
|
+
}
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
/** The parts of the shared workbook, `null` before it is filled. */
|
|
94
|
+
function partsOf(book) {
|
|
95
|
+
const styles = book.get("styles");
|
|
96
|
+
const types = book.get("types");
|
|
97
|
+
const order = book.get("order");
|
|
98
|
+
const sheets = book.get("sheets");
|
|
99
|
+
if (!(styles instanceof Y.Map) || !(types instanceof Y.Map) || !(order instanceof Y.Array) || !(sheets instanceof Y.Map)) return null;
|
|
100
|
+
return {
|
|
101
|
+
styles,
|
|
102
|
+
types,
|
|
103
|
+
order,
|
|
104
|
+
sheets
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function sheetParts(map) {
|
|
108
|
+
if (!(map instanceof Y.Map)) return null;
|
|
109
|
+
const parts = {
|
|
110
|
+
rows: map.get("rows"),
|
|
111
|
+
cols: map.get("cols"),
|
|
112
|
+
cells: map.get("cells"),
|
|
113
|
+
rowSizes: map.get("rowSizes"),
|
|
114
|
+
colSizes: map.get("colSizes"),
|
|
115
|
+
meta: map.get("meta")
|
|
116
|
+
};
|
|
117
|
+
if (!(parts.rows instanceof Y.Array) || !(parts.cols instanceof Y.Array)) return null;
|
|
118
|
+
for (const key of [
|
|
119
|
+
"cells",
|
|
120
|
+
"rowSizes",
|
|
121
|
+
"colSizes",
|
|
122
|
+
"meta"
|
|
123
|
+
]) if (!(parts[key] instanceof Y.Map)) return null;
|
|
124
|
+
return parts;
|
|
125
|
+
}
|
|
126
|
+
/** The sheets as the shared document has them: ids, names and lines. */
|
|
127
|
+
function readLayout(parts) {
|
|
128
|
+
const layout = new SheetLayout();
|
|
129
|
+
for (const id of unique(parts.order.toArray())) {
|
|
130
|
+
const sheet = sheetParts(parts.sheets.get(id));
|
|
131
|
+
if (!sheet) continue;
|
|
132
|
+
const name = sheet.meta.get("name");
|
|
133
|
+
layout.sheets.set(id, {
|
|
134
|
+
id,
|
|
135
|
+
name: typeof name === "string" ? name : id,
|
|
136
|
+
rows: new SheetLines(unique(sheet.rows.toArray())),
|
|
137
|
+
cols: new SheetLines(unique(sheet.cols.toArray()))
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return layout;
|
|
141
|
+
}
|
|
142
|
+
var isAnchored = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && "t" in value;
|
|
143
|
+
/** A field of a sheet as the shared document keeps it. */
|
|
144
|
+
function anchorMeta(key, value, here, layout) {
|
|
145
|
+
if (value == null) return value;
|
|
146
|
+
const range = (text) => anchorRange(text, here, layout);
|
|
147
|
+
const colKey = (col) => here.cols.ids[col] ?? `#${col}`;
|
|
148
|
+
switch (key) {
|
|
149
|
+
case "merges": return value.map(range);
|
|
150
|
+
case "filter": {
|
|
151
|
+
const filter = value;
|
|
152
|
+
const out = {
|
|
153
|
+
...filter,
|
|
154
|
+
range: range(filter.range)
|
|
155
|
+
};
|
|
156
|
+
if (filter.columns) out.columns = Object.fromEntries(Object.entries(filter.columns).map(([col, rule]) => [colKey(Number(col)), rule]));
|
|
157
|
+
if (filter.sorted) out.sorted = {
|
|
158
|
+
...filter.sorted,
|
|
159
|
+
col: colKey(filter.sorted.col)
|
|
160
|
+
};
|
|
161
|
+
return out;
|
|
162
|
+
}
|
|
163
|
+
case "groups": return value.map((group) => ({
|
|
164
|
+
...group,
|
|
165
|
+
range: range(group.range)
|
|
166
|
+
}));
|
|
167
|
+
case "conditionalFormats":
|
|
168
|
+
case "validations": return value.map((rule) => {
|
|
169
|
+
const out = { ...rule };
|
|
170
|
+
const ranges = rule.range;
|
|
171
|
+
out.range = Array.isArray(ranges) ? ranges.map(range) : range(ranges);
|
|
172
|
+
if (typeof rule.formula === "string") out.formula = anchorText(rule.formula, here, layout);
|
|
173
|
+
if (typeof rule.list === "string") out.list = anchorText(rule.list, here, layout);
|
|
174
|
+
return out;
|
|
175
|
+
});
|
|
176
|
+
default: return value;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/** A field of a sheet read from the shared document; `undefined` when its cells are gone. */
|
|
180
|
+
function resolveMeta(key, stored, here, layout) {
|
|
181
|
+
if (stored == null) return void 0;
|
|
182
|
+
const range = (value) => isAnchored(value) ? resolveRange(value, here, layout) : null;
|
|
183
|
+
const colOf = (col) => col[0] === "#" ? Number(col.slice(1)) : here.cols.indexOf(col);
|
|
184
|
+
switch (key) {
|
|
185
|
+
case "merges": {
|
|
186
|
+
const merges = stored.map(range).filter((text) => text !== null);
|
|
187
|
+
return merges.length ? merges : void 0;
|
|
188
|
+
}
|
|
189
|
+
case "filter": {
|
|
190
|
+
const filter = stored;
|
|
191
|
+
const text = range(filter.range);
|
|
192
|
+
if (text === null) return void 0;
|
|
193
|
+
const out = {
|
|
194
|
+
...filter,
|
|
195
|
+
range: text
|
|
196
|
+
};
|
|
197
|
+
if (filter.columns) {
|
|
198
|
+
const columns = {};
|
|
199
|
+
for (const [col, rule] of Object.entries(filter.columns)) {
|
|
200
|
+
const at = colOf(col);
|
|
201
|
+
if (at >= 0) columns[at] = rule;
|
|
202
|
+
}
|
|
203
|
+
if (Object.keys(columns).length) out.columns = columns;
|
|
204
|
+
else delete out.columns;
|
|
205
|
+
}
|
|
206
|
+
if (filter.sorted) {
|
|
207
|
+
const at = colOf(String(filter.sorted.col));
|
|
208
|
+
if (at >= 0) out.sorted = {
|
|
209
|
+
...filter.sorted,
|
|
210
|
+
col: at
|
|
211
|
+
};
|
|
212
|
+
else delete out.sorted;
|
|
213
|
+
}
|
|
214
|
+
return out;
|
|
215
|
+
}
|
|
216
|
+
case "groups": {
|
|
217
|
+
const groups = [];
|
|
218
|
+
for (const group of stored) {
|
|
219
|
+
const text = range(group.range);
|
|
220
|
+
if (text !== null) groups.push({
|
|
221
|
+
...group,
|
|
222
|
+
range: text
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
return groups.length ? groups : void 0;
|
|
226
|
+
}
|
|
227
|
+
case "conditionalFormats":
|
|
228
|
+
case "validations": {
|
|
229
|
+
const rules = [];
|
|
230
|
+
for (const rule of stored) {
|
|
231
|
+
const many = Array.isArray(rule.range);
|
|
232
|
+
const texts = (many ? rule.range : [rule.range]).map(range).filter((text) => text !== null);
|
|
233
|
+
if (!texts.length) continue;
|
|
234
|
+
const out = {
|
|
235
|
+
...rule,
|
|
236
|
+
range: many ? texts : texts[0]
|
|
237
|
+
};
|
|
238
|
+
if (isAnchored(rule.formula)) out.formula = resolveText(rule.formula, here, layout);
|
|
239
|
+
if (isAnchored(rule.list)) out.list = resolveText(rule.list, here, layout);
|
|
240
|
+
rules.push(out);
|
|
241
|
+
}
|
|
242
|
+
return rules.length ? rules : void 0;
|
|
243
|
+
}
|
|
244
|
+
default: return stored;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
var isEmpty = (cell) => cell == null || cell === "";
|
|
248
|
+
/** Writes a whole sheet into `sheets` under its id, with the lines `here` gives it. */
|
|
249
|
+
function writeSheet(sheets, data, here, layout) {
|
|
250
|
+
const map = new Y.Map();
|
|
251
|
+
sheets.set(here.id, map);
|
|
252
|
+
const rows = new Y.Array();
|
|
253
|
+
const cols = new Y.Array();
|
|
254
|
+
const cells = new Y.Map();
|
|
255
|
+
const rowSizes = new Y.Map();
|
|
256
|
+
const colSizes = new Y.Map();
|
|
257
|
+
const meta = new Y.Map();
|
|
258
|
+
map.set("rows", rows);
|
|
259
|
+
map.set("cols", cols);
|
|
260
|
+
map.set("cells", cells);
|
|
261
|
+
map.set("rowSizes", rowSizes);
|
|
262
|
+
map.set("colSizes", colSizes);
|
|
263
|
+
map.set("meta", meta);
|
|
264
|
+
rows.push(here.rows.ids);
|
|
265
|
+
cols.push(here.cols.ids);
|
|
266
|
+
data.cells.forEach((line, r) => line?.forEach((input, c) => {
|
|
267
|
+
const [cell, thread] = splitThread(input);
|
|
268
|
+
const key = cellKey(here.rows.ids[r], here.cols.ids[c]);
|
|
269
|
+
const stored = anchorCell(cell, here, layout);
|
|
270
|
+
if (!isEmpty(stored)) cells.set(key, stored);
|
|
271
|
+
if (thread) cells.set(threadKey(key), thread);
|
|
272
|
+
}));
|
|
273
|
+
for (const [index, size] of Object.entries(data.rowSizes ?? {})) rowSizes.set(here.rows.ids[Number(index)], size);
|
|
274
|
+
for (const [index, size] of Object.entries(data.colSizes ?? {})) colSizes.set(here.cols.ids[Number(index)], size);
|
|
275
|
+
for (const [key, value] of Object.entries(data)) if (isMetaKey(key) && value !== void 0) meta.set(key, anchorMeta(key, value, here, layout));
|
|
276
|
+
}
|
|
277
|
+
/** A sheet's place in the layout, with new ids for its lines. */
|
|
278
|
+
function layoutSheet(data, id, ids) {
|
|
279
|
+
return {
|
|
280
|
+
id,
|
|
281
|
+
name: data.name,
|
|
282
|
+
rows: new SheetLines(ids.many(rowCountOf(data))),
|
|
283
|
+
cols: new SheetLines(ids.many(colCountOf(data)))
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Writes a workbook into an empty shared map, e.g. when a workbook so far
|
|
288
|
+
* saved as JSON starts being edited together. Sheets without an `id` get one.
|
|
289
|
+
*/
|
|
290
|
+
function fillBook(book, workbook) {
|
|
291
|
+
const fill = () => {
|
|
292
|
+
const ids = makeIds(book.doc);
|
|
293
|
+
const styles = new Y.Map();
|
|
294
|
+
const types = new Y.Map();
|
|
295
|
+
const order = new Y.Array();
|
|
296
|
+
const sheets = new Y.Map();
|
|
297
|
+
book.set("styles", styles);
|
|
298
|
+
book.set("types", types);
|
|
299
|
+
book.set("order", order);
|
|
300
|
+
book.set("sheets", sheets);
|
|
301
|
+
for (const [name, style] of Object.entries(workbook.styles ?? {})) styles.set(name, style);
|
|
302
|
+
for (const [name, setup] of Object.entries(workbook.types ?? {})) types.set(name, setup);
|
|
303
|
+
for (const [key, value] of Object.entries(workbook)) if (isBookKey(key) && value !== void 0) book.set(key, value);
|
|
304
|
+
const layout = new SheetLayout();
|
|
305
|
+
const placed = workbook.sheets.map((data) => {
|
|
306
|
+
let id = data.id;
|
|
307
|
+
while (id == null || layout.sheets.has(id)) id = ids.next();
|
|
308
|
+
const here = layoutSheet(data, id, ids);
|
|
309
|
+
layout.sheets.set(id, here);
|
|
310
|
+
return {
|
|
311
|
+
data,
|
|
312
|
+
here
|
|
313
|
+
};
|
|
314
|
+
});
|
|
315
|
+
for (const { data, here } of placed) writeSheet(sheets, data, here, layout);
|
|
316
|
+
order.push(placed.map(({ here }) => here.id));
|
|
317
|
+
};
|
|
318
|
+
if (book.doc) book.doc.transact(fill);
|
|
319
|
+
else fill();
|
|
320
|
+
}
|
|
321
|
+
/** A sheet as the shared document has it. */
|
|
322
|
+
function readSheet(parts, here, layout) {
|
|
323
|
+
const cells = [];
|
|
324
|
+
parts.cells.forEach((stored, key) => {
|
|
325
|
+
if (isThreadKey(key)) {
|
|
326
|
+
key = cellOfKey(key);
|
|
327
|
+
if (parts.cells.has(key)) return;
|
|
328
|
+
stored = void 0;
|
|
329
|
+
}
|
|
330
|
+
const { row, col } = cellAt(key, here);
|
|
331
|
+
if (row < 0 || col < 0) return;
|
|
332
|
+
const cell = withThread(resolveCell(stored, here, layout), parts.cells.get(threadKey(key)));
|
|
333
|
+
if (isEmpty(cell)) return;
|
|
334
|
+
while (cells.length < row) cells.push(null);
|
|
335
|
+
const line = cells[row] ??= [];
|
|
336
|
+
while (line.length < col) line.push(void 0);
|
|
337
|
+
line[col] = cell;
|
|
338
|
+
});
|
|
339
|
+
const data = {
|
|
340
|
+
id: here.id,
|
|
341
|
+
name: here.name,
|
|
342
|
+
cells,
|
|
343
|
+
rowCount: here.rows.ids.length,
|
|
344
|
+
colCount: here.cols.ids.length
|
|
345
|
+
};
|
|
346
|
+
const rowSizes = sizesOf(parts.rowSizes, here.rows);
|
|
347
|
+
const colSizes = sizesOf(parts.colSizes, here.cols);
|
|
348
|
+
if (rowSizes) data.rowSizes = rowSizes;
|
|
349
|
+
if (colSizes) data.colSizes = colSizes;
|
|
350
|
+
parts.meta.forEach((stored, key) => {
|
|
351
|
+
if (key === "name" || !isMetaKey(key)) return;
|
|
352
|
+
const value = resolveMeta(key, stored, here, layout);
|
|
353
|
+
if (value !== void 0) data[key] = value;
|
|
354
|
+
});
|
|
355
|
+
return data;
|
|
356
|
+
}
|
|
357
|
+
/** The workbook a shared map holds; an empty workbook before it is filled. */
|
|
358
|
+
function readBook(book) {
|
|
359
|
+
const parts = partsOf(book);
|
|
360
|
+
if (!parts) return {
|
|
361
|
+
version: 1,
|
|
362
|
+
sheets: []
|
|
363
|
+
};
|
|
364
|
+
const layout = readLayout(parts);
|
|
365
|
+
const workbook = {
|
|
366
|
+
version: 1,
|
|
367
|
+
sheets: []
|
|
368
|
+
};
|
|
369
|
+
if (parts.styles.size) workbook.styles = parts.styles.toJSON();
|
|
370
|
+
if (parts.types.size) workbook.types = parts.types.toJSON();
|
|
371
|
+
book.forEach((value, key) => {
|
|
372
|
+
if (isBookKey(key)) workbook[key] = value;
|
|
373
|
+
});
|
|
374
|
+
for (const here of layout.sheets.values()) workbook.sheets.push(readSheet(sheetParts(parts.sheets.get(here.id)), here, layout));
|
|
375
|
+
return workbook;
|
|
376
|
+
}
|
|
377
|
+
/** The indexes of the longest strictly increasing run of `values`. */
|
|
378
|
+
function increasingRun(values) {
|
|
379
|
+
const tails = [];
|
|
380
|
+
const previous = [];
|
|
381
|
+
values.forEach((value, index) => {
|
|
382
|
+
let low = 0;
|
|
383
|
+
let high = tails.length;
|
|
384
|
+
while (low < high) {
|
|
385
|
+
const mid = low + high >> 1;
|
|
386
|
+
if (values[tails[mid]] < value) low = mid + 1;
|
|
387
|
+
else high = mid;
|
|
388
|
+
}
|
|
389
|
+
previous[index] = low > 0 ? tails[low - 1] : -1;
|
|
390
|
+
tails[low] = index;
|
|
391
|
+
});
|
|
392
|
+
const run = /* @__PURE__ */ new Set();
|
|
393
|
+
let index = tails.length ? tails[tails.length - 1] : -1;
|
|
394
|
+
while (index >= 0) {
|
|
395
|
+
run.add(index);
|
|
396
|
+
index = previous[index];
|
|
397
|
+
}
|
|
398
|
+
return run;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Brings a shared list of ids to `wanted` with as few changes as it takes:
|
|
402
|
+
* the longest run already in order stays, the rest is taken out and put
|
|
403
|
+
* back where it goes, so others' changes to the list around it still merge.
|
|
404
|
+
*/
|
|
405
|
+
function syncList(list, wanted) {
|
|
406
|
+
const current = list.toArray();
|
|
407
|
+
if (current.length === wanted.length && current.every((id, i) => id === wanted[i])) return;
|
|
408
|
+
const rank = new Map(wanted.map((id, i) => [id, i]));
|
|
409
|
+
const seen = /* @__PURE__ */ new Set();
|
|
410
|
+
const firsts = [];
|
|
411
|
+
current.forEach((id, i) => {
|
|
412
|
+
if (seen.has(id) || !rank.has(id)) return;
|
|
413
|
+
seen.add(id);
|
|
414
|
+
firsts.push(i);
|
|
415
|
+
});
|
|
416
|
+
const run = increasingRun(firsts.map((i) => rank.get(current[i])));
|
|
417
|
+
const stays = /* @__PURE__ */ new Set();
|
|
418
|
+
const kept = /* @__PURE__ */ new Set();
|
|
419
|
+
firsts.forEach((at, k) => {
|
|
420
|
+
if (!run.has(k)) return;
|
|
421
|
+
stays.add(at);
|
|
422
|
+
kept.add(current[at]);
|
|
423
|
+
});
|
|
424
|
+
for (let i = current.length - 1; i >= 0;) {
|
|
425
|
+
if (stays.has(i)) {
|
|
426
|
+
i--;
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
let start = i;
|
|
430
|
+
while (start > 0 && !stays.has(start - 1)) start--;
|
|
431
|
+
list.delete(start, i - start + 1);
|
|
432
|
+
i = start - 1;
|
|
433
|
+
}
|
|
434
|
+
let at = 0;
|
|
435
|
+
for (let k = 0; k < wanted.length;) {
|
|
436
|
+
if (kept.has(wanted[k])) {
|
|
437
|
+
at++;
|
|
438
|
+
k++;
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
let end = k;
|
|
442
|
+
while (end < wanted.length && !kept.has(wanted[end])) end++;
|
|
443
|
+
list.insert(at, wanted.slice(k, end));
|
|
444
|
+
at += end - k;
|
|
445
|
+
k = end;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
export { ANCHORED_META, anchorMeta, cellAt, cellKey, cellOfKey, fillBook, increasingRun, isBookKey, isMetaKey, isThreadKey, layoutSheet, makeIds, partsOf, readBook, readLayout, readSheet, resolveMeta, sheetParts, splitThread, syncList, threadKey, unique, withThread, writeSheet };
|
|
449
|
+
|
|
450
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","names":[],"sources":["../../src/collaboration/shared.ts"],"sourcesContent":["import * as Y from 'yjs'\nimport {\n cellOf,\n colCountOf,\n compactCell,\n rowCountOf,\n type SheetCellInput,\n type SheetData,\n type SheetWorkbook,\n} from '../core/model'\nimport {\n anchorCell,\n anchorRange,\n anchorText,\n resolveCell,\n resolveRange,\n resolveText,\n SheetLayout,\n SheetLines,\n type AnchoredText,\n type LayoutSheet,\n} from './anchor'\n\n/*\n * The shared document, under the map given as `book`:\n *\n * styles Y.Map name → style\n * types Y.Map name → cell type setup\n * order Y.Array sheet ids, in the order of the tabs\n * sheets Y.Map sheet id → Y.Map\n * rows, cols Y.Array line ids, top to bottom and left to right\n * cells Y.Map `${rowId}:${colId}` → cell, and\n * `${rowId}:${colId}#` → the id of its comment thread\n * rowSizes, colSizes Y.Map line id → px\n * meta Y.Map the sheet's other fields: name, freeze, merges, rules…\n *\n * Lines are known by ids, so a cell, a size or a reference stays with its\n * line however many are inserted, deleted or moved before it at the same\n * time. Moving a line takes its id out and puts it back elsewhere; when\n * two people move the same line at once it is in the list twice, and the\n * first one counts.\n */\n\nexport type SharedMap = Y.Map<unknown>\nexport type SharedList = Y.Array<string>\n\n/** The fields of a sheet that aren't kept in `meta`. */\nconst OWN_FIELDS = new Set(['id', 'cells', 'rowSizes', 'colSizes', 'rowCount', 'colCount'])\nexport const isMetaKey = (key: string) => !OWN_FIELDS.has(key)\n\n/** The parts of the shared workbook; its other keys are the workbook's own settings, such as `protect`. */\nconst BOOK_PARTS = new Set(['styles', 'types', 'order', 'sheets'])\n/** Whether a key of the workbook is one of its own settings, kept as it is in the shared map. */\nexport const isBookKey = (key: string) => !BOOK_PARTS.has(key)\n\n/** The fields of a sheet whose ranges or formulas are anchored to its lines. */\nexport const ANCHORED_META = [\n 'merges',\n 'filter',\n 'conditionalFormats',\n 'validations',\n 'groups',\n] as const\n\nexport const cellKey = (row: string, col: string) => `${row}:${col}`\n\n/*\n * A cell's comment thread is kept beside the cell, under its own key: undo\n * puts back a cell's value without taking the thread put on it since, and\n * putting one on doesn't overwrite what someone else typed at the same time.\n */\nexport const threadKey = (key: string) => `${key}#`\nexport const isThreadKey = (key: string) => key.endsWith('#')\n/** The cell a key is about: the cell's own key for its thread's. */\nexport const cellOfKey = (key: string) => (isThreadKey(key) ? key.slice(0, -1) : key)\n\n/** A cell with the thread kept beside it. */\nexport function withThread(cell: SheetCellInput, thread: unknown): SheetCellInput {\n if (typeof thread !== 'string' || !thread) return cell\n return compactCell({ ...cellOf(cell), comment: thread })\n}\n\n/** A cell without its thread, and the thread. */\nexport function splitThread(cell: SheetCellInput): [SheetCellInput, string | undefined] {\n if (!cell || typeof cell !== 'object' || !cell.comment) return [cell, undefined]\n return [compactCell({ ...cell, comment: undefined }), cell.comment]\n}\n\n/** Where a cell kept under `key` is now; `-1` for a line that is gone. */\nexport function cellAt(key: string, here: LayoutSheet) {\n const split = key.indexOf(':')\n return {\n row: here.rows.indexOf(key.slice(0, split)),\n col: here.cols.indexOf(key.slice(split + 1)),\n }\n}\n\n/** Sizes kept by line id, by line number. */\nfunction sizesOf(map: SharedMap, lines: SheetLines) {\n const out: Record<number, number> = {}\n map.forEach((size, id) => {\n const at = lines.indexOf(id)\n if (at >= 0 && typeof size === 'number') out[at] = size\n })\n return Object.keys(out).length ? out : undefined\n}\n\n/** Ids for new lines and sheets, unique across the people editing one document. */\nconst counters = new WeakMap<object, { n: number }>()\nexport function makeIds(doc: Y.Doc | null) {\n const owner = doc ?? {}\n let counter = counters.get(owner)\n if (!counter) counters.set(owner, (counter = { n: 0 }))\n const prefix = `${(doc?.clientID ?? Math.floor(Math.random() * 2 ** 32)).toString(36)}.`\n const next = () => prefix + (counter.n++).toString(36)\n return {\n next,\n many: (count: number) => Array.from({ length: count }, next),\n }\n}\nexport type IdMaker = ReturnType<typeof makeIds>\n\n/** A list without repeats, the first of each kept. */\nexport function unique(list: readonly string[]) {\n const seen = new Set<string>()\n const out: string[] = []\n for (const id of list)\n if (!seen.has(id)) {\n seen.add(id)\n out.push(id)\n }\n return out\n}\n\nexport interface SharedParts {\n styles: SharedMap\n types: SharedMap\n order: SharedList\n sheets: Y.Map<SharedMap>\n}\n\n/** The parts of the shared workbook, `null` before it is filled. */\nexport function partsOf(book: SharedMap): SharedParts | null {\n const styles = book.get('styles')\n const types = book.get('types')\n const order = book.get('order')\n const sheets = book.get('sheets')\n if (\n !(styles instanceof Y.Map) ||\n !(types instanceof Y.Map) ||\n !(order instanceof Y.Array) ||\n !(sheets instanceof Y.Map)\n )\n return null\n return { styles, types, order, sheets } as SharedParts\n}\n\nexport interface SharedSheet {\n rows: SharedList\n cols: SharedList\n cells: SharedMap\n rowSizes: SharedMap\n colSizes: SharedMap\n meta: SharedMap\n}\n\nexport function sheetParts(map: SharedMap | undefined): SharedSheet | null {\n if (!(map instanceof Y.Map)) return null\n const parts = {\n rows: map.get('rows'),\n cols: map.get('cols'),\n cells: map.get('cells'),\n rowSizes: map.get('rowSizes'),\n colSizes: map.get('colSizes'),\n meta: map.get('meta'),\n }\n if (!(parts.rows instanceof Y.Array) || !(parts.cols instanceof Y.Array)) return null\n for (const key of ['cells', 'rowSizes', 'colSizes', 'meta'] as const)\n if (!(parts[key] instanceof Y.Map)) return null\n return parts as SharedSheet\n}\n\n/** The sheets as the shared document has them: ids, names and lines. */\nexport function readLayout(parts: SharedParts): SheetLayout {\n const layout = new SheetLayout()\n for (const id of unique(parts.order.toArray())) {\n const sheet = sheetParts(parts.sheets.get(id))\n if (!sheet) continue\n const name = sheet.meta.get('name')\n layout.sheets.set(id, {\n id,\n name: typeof name === 'string' ? name : id,\n rows: new SheetLines(unique(sheet.rows.toArray())),\n cols: new SheetLines(unique(sheet.cols.toArray())),\n })\n }\n return layout\n}\n\n// Rules and other fields -----------------------------------------------------------------\n\ntype Json = Record<string, unknown>\n\nconst isAnchored = (value: unknown): value is AnchoredText =>\n typeof value === 'object' && value !== null && !Array.isArray(value) && 't' in value\n\n/** A field of a sheet as the shared document keeps it. */\nexport function anchorMeta(key: string, value: unknown, here: LayoutSheet, layout: SheetLayout) {\n if (value == null) return value\n const range = (text: string) => anchorRange(text, here, layout)\n const colKey = (col: number) => here.cols.ids[col] ?? `#${col}`\n switch (key) {\n case 'merges':\n return (value as string[]).map(range)\n case 'filter': {\n const filter = value as Json & { range: string; columns?: Json; sorted?: Json }\n const out: Json = { ...filter, range: range(filter.range) }\n if (filter.columns)\n out.columns = Object.fromEntries(\n Object.entries(filter.columns).map(([col, rule]) => [colKey(Number(col)), rule]),\n )\n if (filter.sorted) out.sorted = { ...filter.sorted, col: colKey(filter.sorted.col as number) }\n return out\n }\n case 'groups':\n return (value as Json[]).map((group) => ({ ...group, range: range(group.range as string) }))\n case 'conditionalFormats':\n case 'validations':\n return (value as Json[]).map((rule) => {\n const out: Json = { ...rule }\n const ranges = rule.range as string | string[]\n out.range = Array.isArray(ranges) ? ranges.map(range) : range(ranges)\n if (typeof rule.formula === 'string') out.formula = anchorText(rule.formula, here, layout)\n if (typeof rule.list === 'string') out.list = anchorText(rule.list, here, layout)\n return out\n })\n default:\n return value\n }\n}\n\n/** A field of a sheet read from the shared document; `undefined` when its cells are gone. */\nexport function resolveMeta(key: string, stored: unknown, here: LayoutSheet, layout: SheetLayout) {\n if (stored == null) return undefined\n const range = (value: unknown) => (isAnchored(value) ? resolveRange(value, here, layout) : null)\n const colOf = (col: string) => (col[0] === '#' ? Number(col.slice(1)) : here.cols.indexOf(col))\n switch (key) {\n case 'merges': {\n const merges = (stored as unknown[]).map(range).filter((text) => text !== null)\n return merges.length ? merges : undefined\n }\n case 'filter': {\n const filter = stored as Json & { columns?: Json; sorted?: Json }\n const text = range(filter.range)\n if (text === null) return undefined\n const out: Json = { ...filter, range: text }\n if (filter.columns) {\n const columns: Json = {}\n for (const [col, rule] of Object.entries(filter.columns)) {\n const at = colOf(col)\n if (at >= 0) columns[at] = rule\n }\n if (Object.keys(columns).length) out.columns = columns\n else delete out.columns\n }\n if (filter.sorted) {\n const at = colOf(String(filter.sorted.col))\n if (at >= 0) out.sorted = { ...filter.sorted, col: at }\n else delete out.sorted\n }\n return out\n }\n case 'groups': {\n // a group goes when its lines do\n const groups: Json[] = []\n for (const group of stored as Json[]) {\n const text = range(group.range)\n if (text !== null) groups.push({ ...group, range: text })\n }\n return groups.length ? groups : undefined\n }\n case 'conditionalFormats':\n case 'validations': {\n const rules: Json[] = []\n for (const rule of stored as Json[]) {\n const many = Array.isArray(rule.range)\n const texts = (many ? (rule.range as unknown[]) : [rule.range])\n .map(range)\n .filter((text) => text !== null)\n // a rule goes when all its cells do\n if (!texts.length) continue\n const out: Json = { ...rule, range: many ? texts : texts[0] }\n if (isAnchored(rule.formula)) out.formula = resolveText(rule.formula, here, layout)\n if (isAnchored(rule.list)) out.list = resolveText(rule.list, here, layout)\n rules.push(out)\n }\n return rules.length ? rules : undefined\n }\n default:\n return stored\n }\n}\n\n// Whole sheets and workbooks -------------------------------------------------------------\n\nconst isEmpty = (cell: unknown) => cell == null || cell === ''\n\n/** Writes a whole sheet into `sheets` under its id, with the lines `here` gives it. */\nexport function writeSheet(\n sheets: Y.Map<SharedMap>,\n data: SheetData,\n here: LayoutSheet,\n layout: SheetLayout,\n) {\n const map = new Y.Map<unknown>()\n sheets.set(here.id, map)\n const rows = new Y.Array<string>()\n const cols = new Y.Array<string>()\n const cells = new Y.Map<unknown>()\n const rowSizes = new Y.Map<unknown>()\n const colSizes = new Y.Map<unknown>()\n const meta = new Y.Map<unknown>()\n map.set('rows', rows)\n map.set('cols', cols)\n map.set('cells', cells)\n map.set('rowSizes', rowSizes)\n map.set('colSizes', colSizes)\n map.set('meta', meta)\n rows.push(here.rows.ids)\n cols.push(here.cols.ids)\n data.cells.forEach((line, r) =>\n line?.forEach((input, c) => {\n const [cell, thread] = splitThread(input)\n const key = cellKey(here.rows.ids[r]!, here.cols.ids[c]!)\n const stored = anchorCell(cell, here, layout)\n if (!isEmpty(stored)) cells.set(key, stored)\n if (thread) cells.set(threadKey(key), thread)\n }),\n )\n for (const [index, size] of Object.entries(data.rowSizes ?? {}))\n rowSizes.set(here.rows.ids[Number(index)]!, size)\n for (const [index, size] of Object.entries(data.colSizes ?? {}))\n colSizes.set(here.cols.ids[Number(index)]!, size)\n for (const [key, value] of Object.entries(data))\n if (isMetaKey(key) && value !== undefined) meta.set(key, anchorMeta(key, value, here, layout))\n}\n\n/** A sheet's place in the layout, with new ids for its lines. */\nexport function layoutSheet(data: SheetData, id: string, ids: IdMaker): LayoutSheet {\n return {\n id,\n name: data.name,\n rows: new SheetLines(ids.many(rowCountOf(data))),\n cols: new SheetLines(ids.many(colCountOf(data))),\n }\n}\n\n/**\n * Writes a workbook into an empty shared map, e.g. when a workbook so far\n * saved as JSON starts being edited together. Sheets without an `id` get one.\n */\nexport function fillBook(book: SharedMap, workbook: SheetWorkbook) {\n const fill = () => {\n const ids = makeIds(book.doc)\n const styles = new Y.Map<unknown>()\n const types = new Y.Map<unknown>()\n const order = new Y.Array<string>()\n const sheets = new Y.Map<SharedMap>()\n book.set('styles', styles)\n book.set('types', types)\n book.set('order', order)\n book.set('sheets', sheets)\n for (const [name, style] of Object.entries(workbook.styles ?? {})) styles.set(name, style)\n for (const [name, setup] of Object.entries(workbook.types ?? {})) types.set(name, setup)\n for (const [key, value] of Object.entries(workbook))\n if (isBookKey(key) && value !== undefined) book.set(key, value)\n const layout = new SheetLayout()\n const placed = workbook.sheets.map((data) => {\n let id = data.id\n while (id == null || layout.sheets.has(id)) id = ids.next()\n const here = layoutSheet(data, id, ids)\n layout.sheets.set(id, here)\n return { data, here }\n })\n // every sheet has its lines before any formula is anchored, as formulas reach across\n for (const { data, here } of placed) writeSheet(sheets, data, here, layout)\n order.push(placed.map(({ here }) => here.id))\n }\n if (book.doc) book.doc.transact(fill)\n else fill()\n}\n\n/** A sheet as the shared document has it. */\nexport function readSheet(parts: SharedSheet, here: LayoutSheet, layout: SheetLayout): SheetData {\n const cells: SheetData['cells'] = []\n parts.cells.forEach((stored, key) => {\n // a thread on an empty cell has no cell of its own\n if (isThreadKey(key)) {\n key = cellOfKey(key)\n if (parts.cells.has(key)) return\n stored = undefined\n }\n const { row, col } = cellAt(key, here)\n // the cells of lines someone deleted while someone else wrote them\n if (row < 0 || col < 0) return\n const cell = withThread(resolveCell(stored, here, layout), parts.cells.get(threadKey(key)))\n if (isEmpty(cell)) return\n while (cells.length < row) cells.push(null)\n const line = (cells[row] ??= [])\n while (line.length < col) line.push(undefined)\n line[col] = cell\n })\n const data: SheetData = {\n id: here.id,\n name: here.name,\n cells,\n rowCount: here.rows.ids.length,\n colCount: here.cols.ids.length,\n }\n const rowSizes = sizesOf(parts.rowSizes, here.rows)\n const colSizes = sizesOf(parts.colSizes, here.cols)\n if (rowSizes) data.rowSizes = rowSizes\n if (colSizes) data.colSizes = colSizes\n parts.meta.forEach((stored, key) => {\n if (key === 'name' || !isMetaKey(key)) return\n const value = resolveMeta(key, stored, here, layout)\n if (value !== undefined) (data as unknown as Json)[key] = value\n })\n return data\n}\n\n/** The workbook a shared map holds; an empty workbook before it is filled. */\nexport function readBook(book: SharedMap): SheetWorkbook {\n const parts = partsOf(book)\n if (!parts) return { version: 1, sheets: [] }\n const layout = readLayout(parts)\n const workbook: SheetWorkbook = { version: 1, sheets: [] }\n if (parts.styles.size) workbook.styles = parts.styles.toJSON() as SheetWorkbook['styles']\n if (parts.types.size) workbook.types = parts.types.toJSON() as SheetWorkbook['types']\n book.forEach((value, key) => {\n if (isBookKey(key)) (workbook as unknown as Json)[key] = value\n })\n for (const here of layout.sheets.values())\n workbook.sheets.push(readSheet(sheetParts(parts.sheets.get(here.id))!, here, layout))\n return workbook\n}\n\n// Lists of ids ---------------------------------------------------------------------------\n\n/** The indexes of the longest strictly increasing run of `values`. */\nexport function increasingRun(values: readonly number[]): Set<number> {\n const tails: number[] = []\n const previous: number[] = []\n values.forEach((value, index) => {\n let low = 0\n let high = tails.length\n while (low < high) {\n const mid = (low + high) >> 1\n if (values[tails[mid]!]! < value) low = mid + 1\n else high = mid\n }\n previous[index] = low > 0 ? tails[low - 1]! : -1\n tails[low] = index\n })\n const run = new Set<number>()\n let index = tails.length ? tails[tails.length - 1]! : -1\n while (index >= 0) {\n run.add(index)\n index = previous[index]!\n }\n return run\n}\n\n/**\n * Brings a shared list of ids to `wanted` with as few changes as it takes:\n * the longest run already in order stays, the rest is taken out and put\n * back where it goes, so others' changes to the list around it still merge.\n */\nexport function syncList(list: SharedList, wanted: readonly string[]) {\n const current = list.toArray()\n if (current.length === wanted.length && current.every((id, i) => id === wanted[i])) return\n const rank = new Map(wanted.map((id, i) => [id, i]))\n // the first of each wanted id, in the list's order\n const seen = new Set<string>()\n const firsts: number[] = []\n current.forEach((id, i) => {\n if (seen.has(id) || !rank.has(id)) return\n seen.add(id)\n firsts.push(i)\n })\n const run = increasingRun(firsts.map((i) => rank.get(current[i]!)!))\n const stays = new Set<number>()\n const kept = new Set<string>()\n firsts.forEach((at, k) => {\n if (!run.has(k)) return\n stays.add(at)\n kept.add(current[at]!)\n })\n for (let i = current.length - 1; i >= 0;) {\n if (stays.has(i)) {\n i--\n continue\n }\n let start = i\n while (start > 0 && !stays.has(start - 1)) start--\n list.delete(start, i - start + 1)\n i = start - 1\n }\n let at = 0\n for (let k = 0; k < wanted.length;) {\n if (kept.has(wanted[k]!)) {\n at++\n k++\n continue\n }\n let end = k\n while (end < wanted.length && !kept.has(wanted[end]!)) end++\n list.insert(at, wanted.slice(k, end))\n at += end - k\n k = end\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import cell_panel_vue_vue_type_script_setup_true_lang_default from "./cell-panel.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
// src/components/cell-panel.vue
|
|
3
|
+
var cell_panel_default = cell_panel_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
export { cell_panel_default as default };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=cell-panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cell-panel.js","names":["_sfc_main"],"sources":["../../src/components/cell-panel.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useFloating, useZIndex } from 'dou-ui'\nimport { computed, nextTick, shallowRef, useTemplateRef, watch } from 'vue'\nimport type { SheetCellPanelExpose, SheetResolvedType } from '../core/cell-type'\nimport type { SheetValue } from '../core/model'\n\n/*\n * The floating box a cell type's panel sits in, under the cell being\n * edited. The editor keeps focus; keys reach the panel through `onKey`.\n */\n\nconst props = defineProps<{\n resolved: SheetResolvedType\n value: SheetValue\n text: string\n typed: boolean\n /** The editor, which the panel hangs under. */\n anchor: HTMLElement | undefined\n}>()\nconst emit = defineEmits<{ pick: [value: SheetValue] }>()\n\nconst box = useTemplateRef<HTMLElement>('box')\nconst inner = shallowRef<(SheetCellPanelExpose & { activeId?: string | null }) | null>(null)\n\nconst open = computed(() => !!props.anchor)\nconst { style, placement, update } = useFloating(() => props.anchor, box, {\n open,\n placement: 'bottom-start',\n offset: 4,\n})\nconst { next } = useZIndex()\nconst zIndex = next()\n// the editor grows as text is typed; follow it\nwatch(\n () => props.text,\n () => void nextTick(update),\n)\n\ndefineExpose({\n onKey: (event: KeyboardEvent) => inner.value?.onKey?.(event) ?? false,\n activeId: computed(() => inner.value?.activeId ?? null),\n})\n</script>\n\n<template>\n <Transition name=\"dou-floating\" appear>\n <div\n ref=\"box\"\n class=\"dou-dropdown dou-floating dou-sheet__panel\"\n :style=\"[style, { zIndex }]\"\n :data-placement=\"placement\"\n @mousedown.prevent\n >\n <component\n :is=\"resolved.definition.panel\"\n :ref=\"(el: unknown) => (inner = el as typeof inner)\"\n :value=\"value\"\n :text=\"text\"\n :typed=\"typed\"\n :setup=\"resolved.setup\"\n @pick=\"(v: SheetValue) => emit('pick', v)\"\n />\n </div>\n </Transition>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { useFloating, useZIndex } from "dou-ui";
|
|
2
|
+
import { Transition, computed, createBlock, createElementVNode, defineComponent, nextTick, normalizeStyle, openBlock, resolveDynamicComponent, shallowRef, unref, useTemplateRef, watch, withCtx, withModifiers } from "vue";
|
|
3
|
+
// src/components/cell-panel.vue?vue&type=script&setup=true&lang.ts
|
|
4
|
+
var _hoisted_1 = ["data-placement"];
|
|
5
|
+
var cell_panel_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
6
|
+
__name: "cell-panel",
|
|
7
|
+
props: {
|
|
8
|
+
resolved: {},
|
|
9
|
+
value: { type: [
|
|
10
|
+
String,
|
|
11
|
+
Number,
|
|
12
|
+
Boolean,
|
|
13
|
+
null
|
|
14
|
+
] },
|
|
15
|
+
text: {},
|
|
16
|
+
typed: { type: Boolean },
|
|
17
|
+
anchor: {}
|
|
18
|
+
},
|
|
19
|
+
emits: ["pick"],
|
|
20
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
21
|
+
const props = __props;
|
|
22
|
+
const emit = __emit;
|
|
23
|
+
const box = useTemplateRef("box");
|
|
24
|
+
const inner = shallowRef(null);
|
|
25
|
+
const open = computed(() => !!props.anchor);
|
|
26
|
+
const { style, placement, update } = useFloating(() => props.anchor, box, {
|
|
27
|
+
open,
|
|
28
|
+
placement: "bottom-start",
|
|
29
|
+
offset: 4
|
|
30
|
+
});
|
|
31
|
+
const { next } = useZIndex();
|
|
32
|
+
const zIndex = next();
|
|
33
|
+
watch(() => props.text, () => void nextTick(update));
|
|
34
|
+
__expose({
|
|
35
|
+
onKey: (event) => inner.value?.onKey?.(event) ?? false,
|
|
36
|
+
activeId: computed(() => inner.value?.activeId ?? null)
|
|
37
|
+
});
|
|
38
|
+
return (_ctx, _cache) => {
|
|
39
|
+
return openBlock(), createBlock(Transition, {
|
|
40
|
+
name: "dou-floating",
|
|
41
|
+
appear: ""
|
|
42
|
+
}, {
|
|
43
|
+
default: withCtx(() => [createElementVNode("div", {
|
|
44
|
+
ref_key: "box",
|
|
45
|
+
ref: box,
|
|
46
|
+
class: "dou-dropdown dou-floating dou-sheet__panel",
|
|
47
|
+
style: normalizeStyle([unref(style), { zIndex: unref(zIndex) }]),
|
|
48
|
+
"data-placement": unref(placement),
|
|
49
|
+
onMousedown: _cache[1] || (_cache[1] = withModifiers(() => {}, ["prevent"]))
|
|
50
|
+
}, [(openBlock(), createBlock(resolveDynamicComponent(__props.resolved.definition.panel), {
|
|
51
|
+
ref: (el) => inner.value = el,
|
|
52
|
+
value: __props.value,
|
|
53
|
+
text: __props.text,
|
|
54
|
+
typed: __props.typed,
|
|
55
|
+
setup: __props.resolved.setup,
|
|
56
|
+
onPick: _cache[0] || (_cache[0] = (v) => emit("pick", v))
|
|
57
|
+
}, null, 40, [
|
|
58
|
+
"value",
|
|
59
|
+
"text",
|
|
60
|
+
"typed",
|
|
61
|
+
"setup"
|
|
62
|
+
]))], 44, _hoisted_1)]),
|
|
63
|
+
_: 1
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
export { cell_panel_vue_vue_type_script_setup_true_lang_default as default };
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=cell-panel.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cell-panel.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_Transition","_withCtx","_createElementVNode","_normalizeStyle","_unref","_withModifiers","_resolveDynamicComponent"],"sources":["../../src/components/cell-panel.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useFloating, useZIndex } from 'dou-ui'\nimport { computed, nextTick, shallowRef, useTemplateRef, watch } from 'vue'\nimport type { SheetCellPanelExpose, SheetResolvedType } from '../core/cell-type'\nimport type { SheetValue } from '../core/model'\n\n/*\n * The floating box a cell type's panel sits in, under the cell being\n * edited. The editor keeps focus; keys reach the panel through `onKey`.\n */\n\nconst props = defineProps<{\n resolved: SheetResolvedType\n value: SheetValue\n text: string\n typed: boolean\n /** The editor, which the panel hangs under. */\n anchor: HTMLElement | undefined\n}>()\nconst emit = defineEmits<{ pick: [value: SheetValue] }>()\n\nconst box = useTemplateRef<HTMLElement>('box')\nconst inner = shallowRef<(SheetCellPanelExpose & { activeId?: string | null }) | null>(null)\n\nconst open = computed(() => !!props.anchor)\nconst { style, placement, update } = useFloating(() => props.anchor, box, {\n open,\n placement: 'bottom-start',\n offset: 4,\n})\nconst { next } = useZIndex()\nconst zIndex = next()\n// the editor grows as text is typed; follow it\nwatch(\n () => props.text,\n () => void nextTick(update),\n)\n\ndefineExpose({\n onKey: (event: KeyboardEvent) => inner.value?.onKey?.(event) ?? false,\n activeId: computed(() => inner.value?.activeId ?? null),\n})\n</script>\n\n<template>\n <Transition name=\"dou-floating\" appear>\n <div\n ref=\"box\"\n class=\"dou-dropdown dou-floating dou-sheet__panel\"\n :style=\"[style, { zIndex }]\"\n :data-placement=\"placement\"\n @mousedown.prevent\n >\n <component\n :is=\"resolved.definition.panel\"\n :ref=\"(el: unknown) => (inner = el as typeof inner)\"\n :value=\"value\"\n :text=\"text\"\n :typed=\"typed\"\n :setup=\"resolved.setup\"\n @pick=\"(v: SheetValue) => emit('pick', v)\"\n />\n </div>\n </Transition>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAWA,MAAM,QAAQ;EAQd,MAAM,OAAO;EAEb,MAAM,MAAM,eAA4B,KAAK;EAC7C,MAAM,QAAQ,WAAyE,IAAI;EAE3F,MAAM,OAAO,eAAe,CAAC,CAAC,MAAM,MAAM;EAC1C,MAAM,EAAE,OAAO,WAAW,WAAW,kBAAkB,MAAM,QAAQ,KAAK;GACxE;GACA,WAAW;GACX,QAAQ;EACV,CAAC;EACD,MAAM,EAAE,SAAS,UAAU;EAC3B,MAAM,SAAS,KAAK;EAEpB,YACQ,MAAM,YACN,KAAK,SAAS,MAAM,CAC5B;EAEA,SAAa;GACX,QAAQ,UAAyB,MAAM,OAAO,QAAQ,KAAK,KAAK;GAChE,UAAU,eAAe,MAAM,OAAO,YAAY,IAAI;EACxD,CAAC;;GAIC,OAAAA,UAAA,GAAAC,YAkBaC,YAAA;IAlBD,MAAK;IAAe,QAAA;;IAC9B,SAAAC,cAgBM,CAhBNC,mBAgBM,OAAA;KAfA,SAAA;KAAJ,KAAI;KACJ,OAAM;KACL,OAAKC,eAAA,CAAGC,MAAA,KAAA,GAAK,EAAA,QAAIA,MAAA,MAAA,EAAM,CAAA,CAAA;KACvB,kBAAgBA,MAAA,SAAA;KAChB,aAAS,OAAA,OAAA,OAAA,KAAAC,oBAAV,CAAA,GAAkB,CAAA,SAAA,CAAA;I,KAElBP,UAAA,GAAAC,YAQEO,wBAPK,QAAA,SAAS,WAAW,KAAK,GAAA;KAC7B,MAAM,OAAiB,MAAA,QAAQ;KAC/B,OAAO,QAAA;KACP,MAAM,QAAA;KACN,OAAO,QAAA;KACP,OAAO,QAAA,SAAS;KAChB,QAAI,OAAA,OAAA,OAAA,MAAG,MAAkB,KAAI,QAAS,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { optionOf } from "../core/cell-type.js";
|
|
2
|
+
import { h } from "vue";
|
|
3
|
+
import { CheckIcon } from "@dou-ui/icons";
|
|
4
|
+
// src/components/cell-renders.ts
|
|
5
|
+
var PROPS = [
|
|
6
|
+
"value",
|
|
7
|
+
"text",
|
|
8
|
+
"setup",
|
|
9
|
+
"readonly"
|
|
10
|
+
];
|
|
11
|
+
/** A check box cell: the box of a checkbox, which a click switches. */
|
|
12
|
+
var CellCheck = (props) => h("span", {
|
|
13
|
+
class: props.value === true ? "dou-sheet__check is-checked" : "dou-sheet__check",
|
|
14
|
+
"data-sheet-toggle": "",
|
|
15
|
+
"aria-hidden": "true"
|
|
16
|
+
}, h(CheckIcon, { strokeWidth: 2 }));
|
|
17
|
+
CellCheck.props = PROPS;
|
|
18
|
+
/**
|
|
19
|
+
* A select cell: its value as a soft tag, in its option's tone or neutral.
|
|
20
|
+
* A value that isn't one of the options shows as plain text.
|
|
21
|
+
*/
|
|
22
|
+
var CellOption = (props) => {
|
|
23
|
+
let found = false;
|
|
24
|
+
let tone;
|
|
25
|
+
for (const option of props.setup.options ?? []) {
|
|
26
|
+
const picked = optionOf(option);
|
|
27
|
+
if (picked.value === props.value) {
|
|
28
|
+
found = true;
|
|
29
|
+
tone = picked.tone;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (!found || !props.text) return h("span", { class: "dou-sheet__text" }, props.text);
|
|
34
|
+
const cls = "dou-tag dou-tag--soft dou-sheet__tag";
|
|
35
|
+
return h("span", { class: tone && tone !== "neutral" ? `${cls} dou-tag--${tone}` : `${cls} is-neutral` }, props.text);
|
|
36
|
+
};
|
|
37
|
+
CellOption.props = PROPS;
|
|
38
|
+
export { CellCheck, CellOption };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=cell-renders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cell-renders.js","names":[],"sources":["../../src/components/cell-renders.ts"],"sourcesContent":["import { CheckIcon } from '@dou-ui/icons'\nimport { h, type FunctionalComponent } from 'vue'\nimport { optionOf, type SheetCellRenderProps } from '../core/cell-type'\n\n/*\n * The built-in types' cell content. Functional: they are drawn for every\n * visible cell of their type, so they have no instance of their own.\n */\n\nconst PROPS = ['value', 'text', 'setup', 'readonly'] as const\n\n/** A check box cell: the box of a checkbox, which a click switches. */\nexport const CellCheck: FunctionalComponent<SheetCellRenderProps> = (props) =>\n h(\n 'span',\n {\n class: props.value === true ? 'dou-sheet__check is-checked' : 'dou-sheet__check',\n 'data-sheet-toggle': '',\n 'aria-hidden': 'true',\n },\n h(CheckIcon, { strokeWidth: 2 }),\n )\nCellCheck.props = PROPS as unknown as string[]\n\n/**\n * A select cell: its value as a soft tag, in its option's tone or neutral.\n * A value that isn't one of the options shows as plain text.\n */\nexport const CellOption: FunctionalComponent<SheetCellRenderProps> = (props) => {\n let found = false\n let tone\n for (const option of props.setup.options ?? []) {\n const picked = optionOf(option)\n if (picked.value === props.value) {\n found = true\n tone = picked.tone\n break\n }\n }\n if (!found || !props.text) return h('span', { class: 'dou-sheet__text' }, props.text)\n const cls = 'dou-tag dou-tag--soft dou-sheet__tag'\n return h(\n 'span',\n { class: tone && tone !== 'neutral' ? `${cls} dou-tag--${tone}` : `${cls} is-neutral` },\n props.text,\n )\n}\nCellOption.props = PROPS as unknown as string[]\n"],"mappings":";;;;AASA,IAAM,QAAQ;CAAC;CAAS;CAAQ;CAAS;AAAU;;AAGnD,IAAa,aAAwD,UACnE,EACE,QACA;CACE,OAAO,MAAM,UAAU,OAAO,gCAAgC;CAC9D,qBAAqB;CACrB,eAAe;AACjB,GACA,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,CACjC;AACF,UAAU,QAAQ;;;;;AAMlB,IAAa,cAAyD,UAAU;CAC9E,IAAI,QAAQ;CACZ,IAAI;CACJ,KAAK,MAAM,UAAU,MAAM,MAAM,WAAW,CAAC,GAAG;EAC9C,MAAM,SAAS,SAAS,MAAM;EAC9B,IAAI,OAAO,UAAU,MAAM,OAAO;GAChC,QAAQ;GACR,OAAO,OAAO;GACd;EACF;CACF;CACA,IAAI,CAAC,SAAS,CAAC,MAAM,MAAM,OAAO,EAAE,QAAQ,EAAE,OAAO,kBAAkB,GAAG,MAAM,IAAI;CACpF,MAAM,MAAM;CACZ,OAAO,EACL,QACA,EAAE,OAAO,QAAQ,SAAS,YAAY,GAAG,IAAI,YAAY,SAAS,GAAG,IAAI,aAAa,GACtF,MAAM,IACR;AACF;AACA,WAAW,QAAQ"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import date_panel_vue_vue_type_script_setup_true_lang_default from "./date-panel.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
// src/components/date-panel.vue
|
|
3
|
+
var date_panel_default = date_panel_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
export { date_panel_default as default };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=date-panel.js.map
|