@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.
Files changed (262) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/dist/cell-types.js +20 -0
  4. package/dist/cell-types.js.map +1 -0
  5. package/dist/code/code-formula-bar.js +6 -0
  6. package/dist/code/code-formula-bar.js.map +1 -0
  7. package/dist/code/code-formula-bar.vue_vue_type_script_setup_true_lang.js +192 -0
  8. package/dist/code/code-formula-bar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  9. package/dist/code/index.js +12 -0
  10. package/dist/code/index.js.map +1 -0
  11. package/dist/code/language.js +51 -0
  12. package/dist/code/language.js.map +1 -0
  13. package/dist/code/style.d.ts +1 -0
  14. package/dist/code/style.js +2 -0
  15. package/dist/collaboration/anchor.js +143 -0
  16. package/dist/collaboration/anchor.js.map +1 -0
  17. package/dist/collaboration/index.js +770 -0
  18. package/dist/collaboration/index.js.map +1 -0
  19. package/dist/collaboration/peers.js +87 -0
  20. package/dist/collaboration/peers.js.map +1 -0
  21. package/dist/collaboration/shared.js +450 -0
  22. package/dist/collaboration/shared.js.map +1 -0
  23. package/dist/components/cell-panel.js +6 -0
  24. package/dist/components/cell-panel.js.map +1 -0
  25. package/dist/components/cell-panel.vue_vue_type_script_setup_true_lang.js +70 -0
  26. package/dist/components/cell-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  27. package/dist/components/cell-renders.js +40 -0
  28. package/dist/components/cell-renders.js.map +1 -0
  29. package/dist/components/date-panel.js +6 -0
  30. package/dist/components/date-panel.js.map +1 -0
  31. package/dist/components/date-panel.vue_vue_type_script_setup_true_lang.js +48 -0
  32. package/dist/components/date-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  33. package/dist/components/filter-panel.js +6 -0
  34. package/dist/components/filter-panel.js.map +1 -0
  35. package/dist/components/filter-panel.vue_vue_type_script_setup_true_lang.js +259 -0
  36. package/dist/components/filter-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  37. package/dist/components/format-dialog.js +6 -0
  38. package/dist/components/format-dialog.js.map +1 -0
  39. package/dist/components/format-dialog.vue_vue_type_script_setup_true_lang.js +432 -0
  40. package/dist/components/format-dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  41. package/dist/components/format-list.js +6 -0
  42. package/dist/components/format-list.js.map +1 -0
  43. package/dist/components/format-list.vue_vue_type_script_setup_true_lang.js +187 -0
  44. package/dist/components/format-list.vue_vue_type_script_setup_true_lang.js.map +1 -0
  45. package/dist/components/format-presets.js +97 -0
  46. package/dist/components/format-presets.js.map +1 -0
  47. package/dist/components/option-panel.js +6 -0
  48. package/dist/components/option-panel.js.map +1 -0
  49. package/dist/components/option-panel.vue_vue_type_script_setup_true_lang.js +117 -0
  50. package/dist/components/option-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  51. package/dist/components/sheet-comment.js +6 -0
  52. package/dist/components/sheet-comment.js.map +1 -0
  53. package/dist/components/sheet-comment.vue_vue_type_script_setup_true_lang.js +104 -0
  54. package/dist/components/sheet-comment.vue_vue_type_script_setup_true_lang.js.map +1 -0
  55. package/dist/components/sheet-formula-bar.js +6 -0
  56. package/dist/components/sheet-formula-bar.js.map +1 -0
  57. package/dist/components/sheet-formula-bar.vue_vue_type_script_setup_true_lang.js +124 -0
  58. package/dist/components/sheet-formula-bar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  59. package/dist/components/sheet-link.js +6 -0
  60. package/dist/components/sheet-link.js.map +1 -0
  61. package/dist/components/sheet-link.vue_vue_type_script_setup_true_lang.js +249 -0
  62. package/dist/components/sheet-link.vue_vue_type_script_setup_true_lang.js.map +1 -0
  63. package/dist/components/sheet-menu.js +6 -0
  64. package/dist/components/sheet-menu.js.map +1 -0
  65. package/dist/components/sheet-menu.vue_vue_type_script_setup_true_lang.js +115 -0
  66. package/dist/components/sheet-menu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  67. package/dist/components/sheet-name-box.js +6 -0
  68. package/dist/components/sheet-name-box.js.map +1 -0
  69. package/dist/components/sheet-name-box.vue_vue_type_script_setup_true_lang.js +91 -0
  70. package/dist/components/sheet-name-box.vue_vue_type_script_setup_true_lang.js.map +1 -0
  71. package/dist/components/sheet-note.js +6 -0
  72. package/dist/components/sheet-note.js.map +1 -0
  73. package/dist/components/sheet-note.vue_vue_type_script_setup_true_lang.js +146 -0
  74. package/dist/components/sheet-note.vue_vue_type_script_setup_true_lang.js.map +1 -0
  75. package/dist/components/sheet-outline.js +6 -0
  76. package/dist/components/sheet-outline.js.map +1 -0
  77. package/dist/components/sheet-outline.vue_vue_type_script_setup_true_lang.js +237 -0
  78. package/dist/components/sheet-outline.vue_vue_type_script_setup_true_lang.js.map +1 -0
  79. package/dist/components/sheet-tabs.js +6 -0
  80. package/dist/components/sheet-tabs.js.map +1 -0
  81. package/dist/components/sheet-tabs.vue_vue_type_script_setup_true_lang.js +487 -0
  82. package/dist/components/sheet-tabs.vue_vue_type_script_setup_true_lang.js.map +1 -0
  83. package/dist/components/sheet-toolbar.js +6 -0
  84. package/dist/components/sheet-toolbar.js.map +1 -0
  85. package/dist/components/sheet-toolbar.vue_vue_type_script_setup_true_lang.js +1562 -0
  86. package/dist/components/sheet-toolbar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  87. package/dist/components/validation-dialog.js +6 -0
  88. package/dist/components/validation-dialog.js.map +1 -0
  89. package/dist/components/validation-dialog.vue_vue_type_script_setup_true_lang.js +370 -0
  90. package/dist/components/validation-dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  91. package/dist/context.js +12 -0
  92. package/dist/context.js.map +1 -0
  93. package/dist/core/address.js +256 -0
  94. package/dist/core/address.js.map +1 -0
  95. package/dist/core/axis.js +72 -0
  96. package/dist/core/axis.js.map +1 -0
  97. package/dist/core/cell-type.js +30 -0
  98. package/dist/core/cell-type.js.map +1 -0
  99. package/dist/core/clipboard.js +141 -0
  100. package/dist/core/clipboard.js.map +1 -0
  101. package/dist/core/commands.js +63 -0
  102. package/dist/core/commands.js.map +1 -0
  103. package/dist/core/comments.js +74 -0
  104. package/dist/core/comments.js.map +1 -0
  105. package/dist/core/conditional.js +362 -0
  106. package/dist/core/conditional.js.map +1 -0
  107. package/dist/core/csv.js +191 -0
  108. package/dist/core/csv.js.map +1 -0
  109. package/dist/core/data.js +118 -0
  110. package/dist/core/data.js.map +1 -0
  111. package/dist/core/document.js +187 -0
  112. package/dist/core/document.js.map +1 -0
  113. package/dist/core/extension.js +60 -0
  114. package/dist/core/extension.js.map +1 -0
  115. package/dist/core/file.js +336 -0
  116. package/dist/core/file.js.map +1 -0
  117. package/dist/core/fill.js +153 -0
  118. package/dist/core/fill.js.map +1 -0
  119. package/dist/core/find.js +42 -0
  120. package/dist/core/find.js.map +1 -0
  121. package/dist/core/format.js +404 -0
  122. package/dist/core/format.js.map +1 -0
  123. package/dist/core/group.js +134 -0
  124. package/dist/core/group.js.map +1 -0
  125. package/dist/core/history.js +68 -0
  126. package/dist/core/history.js.map +1 -0
  127. package/dist/core/index.js +17 -0
  128. package/dist/core/link.js +34 -0
  129. package/dist/core/link.js.map +1 -0
  130. package/dist/core/merge.js +105 -0
  131. package/dist/core/merge.js.map +1 -0
  132. package/dist/core/model.js +48 -0
  133. package/dist/core/model.js.map +1 -0
  134. package/dist/core/nav.js +44 -0
  135. package/dist/core/nav.js.map +1 -0
  136. package/dist/core/paint.js +106 -0
  137. package/dist/core/paint.js.map +1 -0
  138. package/dist/core/plain-cell-types.js +54 -0
  139. package/dist/core/plain-cell-types.js.map +1 -0
  140. package/dist/core/protect.js +246 -0
  141. package/dist/core/protect.js.map +1 -0
  142. package/dist/core/selection.js +37 -0
  143. package/dist/core/selection.js.map +1 -0
  144. package/dist/core/transaction.js +1582 -0
  145. package/dist/core/transaction.js.map +1 -0
  146. package/dist/core/validation.js +135 -0
  147. package/dist/core/validation.js.map +1 -0
  148. package/dist/core/versions.js +161 -0
  149. package/dist/core/versions.js.map +1 -0
  150. package/dist/export/color.js +36 -0
  151. package/dist/export/color.js.map +1 -0
  152. package/dist/export/draw.js +316 -0
  153. package/dist/export/draw.js.map +1 -0
  154. package/dist/export/index.js +390 -0
  155. package/dist/export/index.js.map +1 -0
  156. package/dist/formula/edit.js +210 -0
  157. package/dist/formula/edit.js.map +1 -0
  158. package/dist/formula/engine.js +526 -0
  159. package/dist/formula/engine.js.map +1 -0
  160. package/dist/formula/error.js +39 -0
  161. package/dist/formula/error.js.map +1 -0
  162. package/dist/formula/functions.js +1493 -0
  163. package/dist/formula/functions.js.map +1 -0
  164. package/dist/formula/help.js +408 -0
  165. package/dist/formula/help.js.map +1 -0
  166. package/dist/formula/index.js +7 -0
  167. package/dist/formula/parse.js +369 -0
  168. package/dist/formula/parse.js.map +1 -0
  169. package/dist/formula/values.js +123 -0
  170. package/dist/formula/values.js.map +1 -0
  171. package/dist/formulas.js +30 -0
  172. package/dist/formulas.js.map +1 -0
  173. package/dist/index.js +39 -0
  174. package/dist/index.js.map +1 -0
  175. package/dist/locale.js +1312 -0
  176. package/dist/locale.js.map +1 -0
  177. package/dist/sheet.js +6 -0
  178. package/dist/sheet.js.map +1 -0
  179. package/dist/sheet.vue_vue_type_script_setup_true_lang.js +7166 -0
  180. package/dist/sheet.vue_vue_type_script_setup_true_lang.js.map +1 -0
  181. package/dist/style.css +1 -0
  182. package/dist/style.d.ts +1 -0
  183. package/dist/style.js +17 -0
  184. package/dist/types/cell-types.d.ts +2 -0
  185. package/dist/types/code/code-formula-bar.vue.d.ts +3 -0
  186. package/dist/types/code/index.d.ts +12 -0
  187. package/dist/types/code/language.d.ts +13 -0
  188. package/dist/types/collaboration/anchor.d.ts +65 -0
  189. package/dist/types/collaboration/index.d.ts +59 -0
  190. package/dist/types/collaboration/peers.d.ts +21 -0
  191. package/dist/types/collaboration/shared.d.ts +75 -0
  192. package/dist/types/components/cell-panel.vue.d.ts +20 -0
  193. package/dist/types/components/cell-renders.d.ts +9 -0
  194. package/dist/types/components/date-panel.vue.d.ts +9 -0
  195. package/dist/types/components/filter-panel.vue.d.ts +21 -0
  196. package/dist/types/components/format-dialog.vue.d.ts +24 -0
  197. package/dist/types/components/format-list.vue.d.ts +25 -0
  198. package/dist/types/components/format-presets.d.ts +30 -0
  199. package/dist/types/components/option-panel.vue.d.ts +13 -0
  200. package/dist/types/components/sheet-comment.vue.d.ts +29 -0
  201. package/dist/types/components/sheet-formula-bar.vue.d.ts +3 -0
  202. package/dist/types/components/sheet-link.vue.d.ts +32 -0
  203. package/dist/types/components/sheet-menu.vue.d.ts +20 -0
  204. package/dist/types/components/sheet-name-box.vue.d.ts +3 -0
  205. package/dist/types/components/sheet-note.vue.d.ts +22 -0
  206. package/dist/types/components/sheet-outline.vue.d.ts +36 -0
  207. package/dist/types/components/sheet-tabs.vue.d.ts +9 -0
  208. package/dist/types/components/sheet-toolbar.vue.d.ts +11 -0
  209. package/dist/types/components/validation-dialog.vue.d.ts +25 -0
  210. package/dist/types/context.d.ts +189 -0
  211. package/dist/types/core/address.d.ts +109 -0
  212. package/dist/types/core/axis.d.ts +23 -0
  213. package/dist/types/core/cell-type.d.ts +157 -0
  214. package/dist/types/core/clipboard.d.ts +48 -0
  215. package/dist/types/core/commands.d.ts +76 -0
  216. package/dist/types/core/comments.d.ts +22 -0
  217. package/dist/types/core/conditional.d.ts +114 -0
  218. package/dist/types/core/csv.d.ts +93 -0
  219. package/dist/types/core/data.d.ts +26 -0
  220. package/dist/types/core/document.d.ts +49 -0
  221. package/dist/types/core/extension.d.ts +177 -0
  222. package/dist/types/core/file.d.ts +301 -0
  223. package/dist/types/core/fill.d.ts +23 -0
  224. package/dist/types/core/find.d.ts +39 -0
  225. package/dist/types/core/format.d.ts +47 -0
  226. package/dist/types/core/group.d.ts +76 -0
  227. package/dist/types/core/history.d.ts +27 -0
  228. package/dist/types/core/index.d.ts +33 -0
  229. package/dist/types/core/link.d.ts +14 -0
  230. package/dist/types/core/merge.d.ts +26 -0
  231. package/dist/types/core/model.d.ts +363 -0
  232. package/dist/types/core/nav.d.ts +15 -0
  233. package/dist/types/core/paint.d.ts +19 -0
  234. package/dist/types/core/plain-cell-types.d.ts +6 -0
  235. package/dist/types/core/protect.d.ts +34 -0
  236. package/dist/types/core/selection.d.ts +25 -0
  237. package/dist/types/core/transaction.d.ts +470 -0
  238. package/dist/types/core/validation.d.ts +55 -0
  239. package/dist/types/core/versions.d.ts +38 -0
  240. package/dist/types/export/color.d.ts +7 -0
  241. package/dist/types/export/draw.d.ts +98 -0
  242. package/dist/types/export/index.d.ts +47 -0
  243. package/dist/types/formula/edit.d.ts +62 -0
  244. package/dist/types/formula/engine.d.ts +99 -0
  245. package/dist/types/formula/error.d.ts +30 -0
  246. package/dist/types/formula/functions.d.ts +62 -0
  247. package/dist/types/formula/help.d.ts +12 -0
  248. package/dist/types/formula/index.d.ts +13 -0
  249. package/dist/types/formula/parse.d.ts +92 -0
  250. package/dist/types/formula/values.d.ts +65 -0
  251. package/dist/types/formulas.d.ts +32 -0
  252. package/dist/types/index.d.ts +225 -0
  253. package/dist/types/locale.d.ts +531 -0
  254. package/dist/types/sheet.vue.d.ts +60 -0
  255. package/dist/types/types.d.ts +498 -0
  256. package/dist/types/use-comments.d.ts +47 -0
  257. package/dist/types/use-messages.d.ts +7 -0
  258. package/dist/use-comments.js +130 -0
  259. package/dist/use-comments.js.map +1 -0
  260. package/dist/use-messages.js +29 -0
  261. package/dist/use-messages.js.map +1 -0
  262. package/package.json +93 -4
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ @layer dou.components{.dou-sheet{--dou-sheet-line:var(--dou-color-border-subtle);--dou-sheet-line-strong:var(--dou-color-border);--dou-sheet-freeze-line:var(--dou-color-border-strong);--dou-sheet-scroll-shadow:color-mix(in oklab,var(--dou-color-text)14%,transparent);--dou-sheet-header-bg:var(--dou-color-bg-canvas);--dou-sheet-ring:var(--dou-color-primary);--dou-sheet-tint:color-mix(in oklab,var(--dou-color-primary)8%,transparent);--dou-sheet-found:color-mix(in oklab,var(--dou-color-warning)22%,transparent);--dou-sheet-found-current:color-mix(in oklab,var(--dou-color-warning)45%,transparent);--dou-sheet-header-marked:color-mix(in oklab,var(--dou-color-text)6%,var(--dou-sheet-header-bg));--dou-sheet-header-full:color-mix(in oklab,var(--dou-color-primary)12%,var(--dou-sheet-header-bg));position:relative;box-sizing:border-box;overflow:hidden;border:1px solid var(--dou-color-border);border-radius:var(--dou-radius-container);background-color:var(--dou-color-bg-surface);color:var(--dou-color-text);font-family:var(--dou-font-family);font-size:var(--dou-font-size-sm);line-height:var(--dou-font-line-height);display:flex;flex-direction:column;width:100%;min-width:0;height:480px}.dou-sheet:not(.is-focused){--dou-sheet-ring:color-mix(in oklab,var(--dou-color-text)45%,transparent);--dou-sheet-tint:color-mix(in oklab,var(--dou-color-text)5%,transparent)}.dou-sheet:not(.has-gridlines){--dou-sheet-line:transparent}.dou-sheet.is-dragging{user-select:none;-webkit-user-select:none}.dou-sheet.is-dragging *{user-select:none;-webkit-user-select:none}.dou-sheet__frame{position:relative;display:flex;box-sizing:border-box;flex-direction:column;flex:1;min-height:0}.dou-sheet__main{position:relative;overflow:hidden;flex:1;min-height:0}.dou-sheet__viewport{position:absolute;overflow:auto;overscroll-behavior:contain;outline:none;scrollbar-width:thin;scrollbar-color:color-mix(in oklab,var(--dou-color-text)22%,transparent)transparent;touch-action:manipulation;-webkit-tap-highlight-color:transparent;inset:0}.dou-sheet__head{position:sticky;z-index:3;top:0}.dou-sheet__body{position:relative}.dou-sheet__row{display:flex;box-sizing:border-box}.dou-sheet__body>.dou-sheet__row{position:absolute;left:0}.dou-sheet__head>.dou-sheet__row{position:relative}.dou-sheet__outline{position:absolute;background-color:var(--dou-sheet-header-bg)}.dou-sheet__outline.is-row{border-right:1px solid var(--dou-sheet-line-strong);bottom:0;left:0}.dou-sheet__outline.is-col{border-bottom:1px solid var(--dou-sheet-line-strong);top:0;right:0}.dou-sheet__outline-corner{position:absolute;box-sizing:border-box;border-right:1px solid var(--dou-sheet-line-strong);border-bottom:1px solid var(--dou-sheet-line-strong);background-color:var(--dou-sheet-header-bg);top:0;left:0}.dou-sheet__outline-levels{position:absolute;z-index:1}.dou-sheet__outline-layer{position:absolute;overflow:hidden}.dou-sheet__outline-inner{position:absolute;inset:0}.dou-sheet__outline-line{position:absolute;box-sizing:border-box;border:0 solid var(--dou-sheet-freeze-line)}.is-row .dou-sheet__outline-line{border-left-width:1px}.is-row .dou-sheet__outline-line.is-tick-end{border-bottom-width:1px}.is-row .dou-sheet__outline-line.is-tick-start{border-top-width:1px}.is-col .dou-sheet__outline-line{border-top-width:1px}.is-col .dou-sheet__outline-line.is-tick-end{border-right-width:1px}.is-col .dou-sheet__outline-line.is-tick-start{border-left-width:1px}.dou-sheet__outline-button{position:absolute;display:inline-flex;box-sizing:border-box;border:1px solid var(--dou-sheet-freeze-line);background-color:var(--dou-color-bg-surface);color:var(--dou-color-text-secondary);font:inherit;font-variant-numeric:tabular-nums;cursor:pointer;-webkit-tap-highlight-color:transparent;border-radius:3px;justify-content:center;align-items: center;padding:0;font-size:10px;line-height:1}.dou-sheet__outline-button svg{width:10px;height:10px}.dou-sheet__outline-button:hover{background-color:var(--dou-color-bg-muted);color:var(--dou-color-text)}.dou-sheet__outline-button:focus-visible{outline:2px solid var(--dou-color-primary);outline-offset:1px}.dou-sheet__outline-button.is-level{border-color:var(--dou-color-border);color:var(--dou-color-text-tertiary)}@media (pointer:coarse){.dou-sheet__outline-button:before{position:absolute;inset:var(--dou-sheet-hit,0);content:""}}.dou-sheet__corner,.dou-sheet__col-head,.dou-sheet__row-head{display:flex;box-sizing:border-box;overflow:hidden;border-right:1px solid var(--dou-sheet-line-strong);border-bottom:1px solid var(--dou-sheet-line-strong);background-color:var(--dou-sheet-header-bg);color:var(--dou-color-text-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;text-box:trim-both cap alphabetic;cursor:default;user-select:none;-webkit-user-select:none;box-shadow:var(--dou-sheet-mark,0 0 transparent),var(--dou-sheet-edge-shadow,0 0 transparent);flex:none;justify-content:center;align-items: center;height:100%;font-size:12px}:is(.dou-sheet__corner,.dou-sheet__col-head,.dou-sheet__row-head).is-marked{background-color:var(--dou-sheet-header-marked);color:var(--dou-color-text)}:is(.dou-sheet__corner,.dou-sheet__col-head,.dou-sheet__row-head).is-full{background-color:var(--dou-sheet-header-full);color:var(--dou-color-primary-text)}.dou-sheet__corner{position:sticky;z-index:3;left:0}.dou-sheet__col-head{border-right-color:var(--dou-sheet-line)}.dou-sheet__col-head.is-freeze-edge{border-right-color:var(--dou-sheet-freeze-line)}.dou-sheet__col-head.is-frozen{position:sticky;z-index:2}.dou-sheet__col-head:not(.is-frozen){position:absolute;top:0}.dou-sheet__col-head.is-marked{--dou-sheet-mark:inset 0 -2px 0 var(--dou-sheet-ring)}.dou-sheet__row-head{position:sticky;z-index:2;border-bottom-color:var(--dou-sheet-line);left:0}.is-freeze-edge>.dou-sheet__row-head{border-bottom-color:var(--dou-sheet-freeze-line)}.dou-sheet__row-head.is-marked{--dou-sheet-mark:inset -2px 0 0 var(--dou-sheet-ring)}.dou-sheet__cell{display:flex;box-sizing:border-box;border-right:1px solid var(--dou-sheet-line);border-bottom:1px solid var(--dou-sheet-line);white-space:pre;cursor:cell;flex:none;align-items: center;height:100%;padding:0 8px}.dou-sheet__cell:not(.is-frozen){position:absolute;z-index:0;top:0}.dou-sheet__cell.is-frozen{position:sticky;z-index:1;background-color:var(--dou-color-bg-surface)}.dou-sheet__cell.is-freeze-edge{border-right-color:var(--dou-sheet-freeze-line)}.is-freeze-edge>.dou-sheet__cell{border-bottom-color:var(--dou-sheet-freeze-line)}.dou-sheet__cell.is-covered{background:0 0;border-color:#0000}.dou-sheet__cell.is-merged{background-color:var(--dou-color-bg-surface)}.dou-sheet__cell.is-merged:not(.is-frozen){z-index:0}.dou-sheet__cell.is-merged.is-frozen{z-index:2;align-self: flex-start}.dou-sheet__cell.is-bold{font-weight:var(--dou-font-weight-bold)}.dou-sheet__cell.is-italic{font-style:italic}.dou-sheet__cell.is-align-center .dou-sheet__text{text-align:center}.dou-sheet__cell.is-align-right .dou-sheet__text{text-align:right}.dou-sheet__cell.is-valign-top{align-items: flex-start;padding-top:4px}.dou-sheet__cell.is-valign-bottom{align-items: flex-end;padding-bottom:4px}.dou-sheet__cell.is-wrap{white-space:pre-wrap;align-items: flex-start;padding-block-start:4px;padding-block-end:4px}.dou-sheet__cell.is-wrap .dou-sheet__text{text-box:normal;overflow-wrap:anywhere;margin-block-start:0;margin-block-end:0;padding-block-start:0;padding-block-end:0}.dou-sheet__cell.is-link{color:var(--dou-color-primary-text);text-decoration-line:underline;text-decoration-color:color-mix(in oklab,currentColor 40%,transparent);text-decoration-thickness:1px;text-underline-offset:.2em}.dou-sheet__cell.is-tone-neutral{color:var(--dou-color-neutral-text)}.dou-sheet__cell.is-tone-primary{color:var(--dou-color-primary-text)}.dou-sheet__cell.is-tone-success{color:var(--dou-color-success-text)}.dou-sheet__cell.is-tone-warning{color:var(--dou-color-warning-text)}.dou-sheet__cell.is-tone-danger{color:var(--dou-color-danger-text)}.has-gridlines .dou-sheet__cell[class*=is-fill-]{--dou-sheet-line:color-mix(in oklab,var(--dou-color-text)7%,var(--dou-color-border-subtle))}.dou-sheet__cell.is-fill-neutral{background-color:color-mix(in oklab,var(--dou-color-text)6%,var(--dou-color-bg-surface))}.dou-sheet__cell.is-fill-primary{background-color:color-mix(in oklab,var(--dou-color-primary)12%,var(--dou-color-bg-surface))}.dou-sheet__cell.is-fill-success{background-color:color-mix(in oklab,var(--dou-color-success)12%,var(--dou-color-bg-surface))}.dou-sheet__cell.is-fill-warning{background-color:color-mix(in oklab,var(--dou-color-warning)14%,var(--dou-color-bg-surface))}.dou-sheet__cell.is-fill-danger{background-color:color-mix(in oklab,var(--dou-color-danger)12%,var(--dou-color-bg-surface))}.dou-sheet__cell.is-selected{background-image:linear-gradient(var(--dou-sheet-tint),var(--dou-sheet-tint))}.dou-sheet__cell.is-selected:after{position:absolute;border:0 solid var(--dou-sheet-ring);content:"";pointer-events:none;inset:-1px 0 0 -1px}.dou-sheet__cell.is-edge-top:after{border-top-width:1px}.dou-sheet__cell.is-edge-bottom:after{border-bottom-width:1px}.dou-sheet__cell.is-edge-left:after{border-left-width:1px}.dou-sheet__cell.is-edge-right:after{border-right-width:1px}.dou-sheet__cell.is-active{background-image:none}.dou-sheet__cell.is-active:before{position:absolute;z-index:1;border:2px solid var(--dou-sheet-ring);content:"";pointer-events:none;inset:-1px 0 0 -1px}.dou-sheet__text{overflow-x:clip;text-box:trim-both cap alphabetic;flex:auto;min-width:0;margin-block-start:-4px;margin-block-end:-4px;padding-block-start:4px;padding-block-end:4px}.dou-sheet__check{display:inline-flex;box-sizing:border-box;border:1px solid var(--dou-color-border-strong);border-radius:calc(var(--dou-radius-control) - 2px);background-color:var(--dou-color-bg-surface);box-shadow:var(--dou-shadow-sm);color:var(--dou-color-neutral-on);cursor:pointer;transition-property:background-color,border-color,box-shadow;transition-duration:var(--dou-motion-duration-fast);transition-timing-function:var(--dou-motion-easing);flex:none;justify-content:center;align-items: center;width:14px;height:14px}.dou-sheet__check>svg{opacity:0;transition-property:opacity,transform;transition-duration:var(--dou-motion-duration-fast);transition-timing-function:var(--dou-motion-easing);width:100%;height:100%;transform:scale(.6)}.dou-sheet__check:hover{border-color:color-mix(in oklab,var(--dou-color-neutral)45%,var(--dou-color-border-strong))}.dou-sheet__check.is-checked{border-color:color-mix(in oklab,var(--dou-color-neutral)90%,var(--dou-color-edge));background-color:var(--dou-color-neutral);box-shadow:var(--dou-shadow-highlight),0 1px 2px color-mix(in oklab,var(--dou-color-neutral)24%,transparent)}.dou-sheet__check.is-checked>svg{opacity:1;transform:none}.is-readonly .dou-sheet__check{cursor:inherit}@media (pointer:coarse){.dou-sheet__check{position:relative}.dou-sheet__check:before{position:absolute;content:"";inset:-7px -12px}}.dou-sheet__cell.has-bar{--dou-sheet-bar:linear-gradient(to right,transparent var(--dou-sheet-bar-from),var(--dou-sheet-bar-color)var(--dou-sheet-bar-from),var(--dou-sheet-bar-color)var(--dou-sheet-bar-to),transparent var(--dou-sheet-bar-to));--dou-sheet-bar-size:calc(100% - 6px)calc(100% - 10px);background-image:var(--dou-sheet-bar);background-position:50%;background-size:var(--dou-sheet-bar-size);background-repeat:no-repeat}.dou-sheet__cell.has-bar.is-selected{background-image:linear-gradient(var(--dou-sheet-tint),var(--dou-sheet-tint)),var(--dou-sheet-bar);background-size:100% 100%,var(--dou-sheet-bar-size)}.dou-sheet__cell.has-bar.is-active{background-image:var(--dou-sheet-bar);background-size:var(--dou-sheet-bar-size)}.dou-sheet__content{display:contents}.dou-sheet__cell.is-error{color:var(--dou-color-danger-text)}.dou-sheet__invalid,.dou-sheet__noted{position:absolute;z-index:2;pointer-events:none;border:4px solid #0000;top:0}.dou-sheet__invalid{border-top-color:var(--dou-color-danger);border-left-color:var(--dou-color-danger);left:0}.dou-sheet__noted{border-top-color:var(--dou-color-warning);border-right-color:var(--dou-color-warning);right:0}.dou-sheet__noted.is-over-fill{z-index:5;right:auto}.dou-sheet__commented{position:absolute;z-index:2;border:4px solid #0000;border-top-color:var(--dou-color-focus);border-right-color:var(--dou-color-focus);pointer-events:none;top:0;right:0}.dou-sheet__commented.is-below-note{top:8px}.dou-sheet__cell.is-changed{background-image:linear-gradient(color-mix(in oklab,var(--dou-color-warning)18%,transparent),color-mix(in oklab,var(--dou-color-warning)18%,transparent));box-shadow:inset 0 -2px 0 var(--dou-color-warning)}.dou-sheet-comment{box-sizing:border-box;overflow-y:auto;overscroll-behavior:contain;border:1px solid var(--dou-color-border);border-radius:var(--dou-radius-container);background-color:color-mix(in oklab,var(--dou-color-text)calc(4%*var(--dou-scheme-dark)),var(--dou-color-bg-surface));box-shadow:var(--dou-shadow-md);font-family:var(--dou-font-family);width:min(340px,100vw - 32px);max-height:min(480px,100vh - 32px);padding:12px;line-height:normal}.dou-sheet__note{box-sizing:border-box;font-size:var(--dou-font-size-sm);width:224px;max-width:calc(100vw - 16px);padding:8px 10px;line-height:20px}.dou-sheet__note.is-editing{padding:4px}.dou-sheet__note-text{overflow:auto;color:var(--dou-color-text);overflow-wrap:anywhere;white-space:pre-wrap;max-height:240px;margin:0}.dou-sheet__note-input{display:block;box-sizing:border-box;border-radius:calc(var(--dou-radius-control) - 2px);outline:none;color:var(--dou-color-text);font:inherit;font-size:max(var(--dou-font-size-input-min,0px),1em);resize:none;background:0 0;border:0;width:100%;min-height:68px;max-height:240px;padding:4px 6px;line-height:20px}.dou-sheet__note-actions{display:flex;border-top:1px solid var(--dou-color-border-subtle);justify-content:flex-end;gap:4px;padding:4px 2px 2px}.dou-sheet__link{display:flex;box-sizing:border-box;font-size:var(--dou-font-size-sm);pointer-events:none;align-items: center;gap:6px;max-width:min(320px,100vw - 16px);padding:4px 4px 4px 10px;line-height:20px}.dou-sheet__link a{pointer-events:auto}.dou-sheet__link button{pointer-events:auto}.dou-sheet__link.is-editing{pointer-events:auto;display:block;width:288px;padding:8px}@media (pointer:coarse){.dou-sheet__link .dou-button{--dou-button-height:40px}}.dou-sheet__link.is-docked{position:absolute;z-index:5;width:-moz-fit-content;width:fit-content;max-width:none;margin-inline-start:auto;margin-inline-end:auto;bottom:12px;left:12px;right:12px}.dou-sheet__link-icon{display:inline-flex;color:var(--dou-color-text-tertiary);flex:none}.dou-sheet__link-icon svg{width:14px;height:14px}.dou-sheet__link-address{overflow:hidden;font:inherit;text-align:start;cursor:pointer;color:var(--dou-color-text);text-decoration-line:underline;text-decoration-color:color-mix(in oklab,currentColor 28%,transparent);text-decoration-thickness:1px;text-underline-offset:.25em;text-overflow:ellipsis;white-space:nowrap;background:0 0;border:0;min-width:0;padding:0}.dou-sheet__link-address:hover{text-decoration-color:currentColor}.dou-sheet__link-address:focus-visible{outline:2px solid var(--dou-color-focus);outline-offset:2px;border-radius:2px}.dou-sheet__link-buttons{display:flex;border-left:1px solid var(--dou-color-border-subtle);flex:none;gap:2px;margin-left:2px;padding-left:4px}.dou-sheet__link-form{display:flex;flex-direction:column;gap:8px;margin:0}.dou-sheet__link-field{display:flex;flex-direction:column;gap:4px}.dou-sheet__link-label{color:var(--dou-color-text-secondary);font-size:var(--dou-font-size-sm);line-height:18px}.dou-sheet__link-problem{color:var(--dou-color-danger-text);font-size:var(--dou-font-size-sm);margin:0;line-height:18px}.dou-sheet__link-actions{display:flex;justify-content:flex-end;gap:4px}.dou-sheet__tag{--dou-tag-height:20px;--dou-tag-padding-x:6px;overflow:hidden;text-overflow:ellipsis;flex:none;min-width:0;max-width:100%}.dou-sheet__tag.is-neutral{--dou-tag-fg:var(--dou-color-text-secondary);--dou-tag-border:var(--dou-color-border-subtle)}.dou-sheet__cell.is-align-center>.dou-sheet__check{margin-inline-start:auto;margin-inline-end:auto}.dou-sheet__cell.is-align-center>.dou-sheet__tag{margin-inline-start:auto;margin-inline-end:auto}.dou-sheet__cell.is-align-right>.dou-sheet__check{margin-left:auto}.dou-sheet__cell.is-align-right>.dou-sheet__tag{margin-left:auto}.dou-sheet__panel-button{position:absolute;z-index:4;display:inline-flex;box-sizing:border-box;border:1px solid var(--dou-color-border);border-radius:calc(var(--dou-radius-control) - 2px);background-color:var(--dou-color-bg-surface);box-shadow:var(--dou-shadow-sm);color:var(--dou-color-text-secondary);cursor:pointer;justify-content:center;align-items: center;width:20px;height:20px;margin:-10px 0 0 -23px;padding:0}@media (pointer:coarse){.dou-sheet__panel-button:after{position:absolute;content:"";inset:-10px}}.dou-sheet__panel-button:hover{background-color:var(--dou-color-bg-muted);color:var(--dou-color-text)}.dou-sheet__panel-button>svg{width:14px;height:14px}@media (pointer:coarse){.dou-sheet__panel-button{width:24px;height:24px;margin:-12px 0 0 -26px}.dou-sheet__panel-button:before{position:absolute;content:"";inset:-8px}}.dou-sheet__options{overflow-y:auto;overscroll-behavior:contain;min-width:160px;max-width:280px;max-height:264px}.dou-sheet__option{justify-content:space-between}.dou-sheet__option.is-active{background-color:var(--dou-dropdown-item-active-bg)}.dou-sheet__option-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.dou-sheet-validation__remove{margin-inline-end:auto}.dou-sheet__option-check{color:var(--dou-color-text-secondary);flex:none;width:14px;height:14px}.dou-sheet__options-empty{color:var(--dou-color-text-tertiary);font-size:var(--dou-font-size-sm);padding:8px}.dou-sheet__input{position:absolute;z-index:5;box-sizing:border-box;overflow:hidden;outline:none;color:#0000;font:inherit;font-size:max(var(--dou-font-size-input-min,0px),1em);white-space:pre;caret-color:transparent;opacity:0;resize:none;pointer-events:none;background:0 0;border:0;border-radius:0;margin:0;padding:4px 9px;line-height:20px}.dou-sheet__input.is-open{background-color:var(--dou-color-bg-surface);color:var(--dou-color-text);caret-color:auto;opacity:1;box-shadow:inset 0 0 0 2px var(--dou-color-primary),var(--dou-shadow-md);pointer-events:auto}.dou-sheet__input.is-wrap{white-space:pre-wrap;overflow-wrap:anywhere}.dou-sheet__input.is-bold{font-weight:var(--dou-font-weight-bold)}.dou-sheet__input.is-italic{font-style:italic}.dou-sheet.is-scrolled-y .dou-sheet__head{box-shadow:0 4px 6px -4px var(--dou-sheet-scroll-shadow)}.dou-sheet.is-scrolled-x .dou-sheet__cell.is-freeze-edge{--dou-sheet-edge-shadow:4px 0 6px -4px var(--dou-sheet-scroll-shadow)}.dou-sheet.is-scrolled-x .dou-sheet__col-head.is-freeze-edge{--dou-sheet-edge-shadow:4px 0 6px -4px var(--dou-sheet-scroll-shadow)}.dou-sheet.is-scrolled-x:not(.has-frozen-cols) .dou-sheet__corner{--dou-sheet-edge-shadow:4px 0 6px -4px var(--dou-sheet-scroll-shadow)}.dou-sheet.is-scrolled-x:not(.has-frozen-cols) .dou-sheet__row-head{--dou-sheet-edge-shadow:4px 0 6px -4px var(--dou-sheet-scroll-shadow)}.dou-sheet.is-scrolled-x .dou-sheet__cell.is-freeze-edge{box-shadow:var(--dou-sheet-edge-shadow)}.dou-sheet.is-resizing-col,.dou-sheet.is-resizing-col *{cursor:col-resize}.dou-sheet.is-resizing-row,.dou-sheet.is-resizing-row *{cursor:row-resize}.dou-sheet:not(.is-readonly) .is-full:-webkit-any(.dou-sheet__col-head,.dou-sheet__row-head){cursor:grab}.dou-sheet:not(.is-readonly) .is-full:-moz-any(.dou-sheet__col-head,.dou-sheet__row-head){cursor:grab}.dou-sheet:not(.is-readonly) .is-full:is(.dou-sheet__col-head,.dou-sheet__row-head){cursor:grab}.dou-sheet.is-moving,.dou-sheet.is-moving *{cursor:grabbing}.dou-sheet__col-head.is-after-hidden:before,.dou-sheet__row-head.is-after-hidden:before{position:absolute;border:0 solid var(--dou-sheet-freeze-line);content:"";pointer-events:none}.dou-sheet__col-head.is-after-hidden:before{border-left-width:1px;border-right-width:1px;width:2px;inset:0 auto 0 0}.dou-sheet__row-head.is-after-hidden:before{border-block-start-width:1px;border-block-end-width:1px;height:2px;inset:0 0 auto}.dou-sheet__found{position:absolute;z-index:3;box-sizing:border-box;background-color:var(--dou-sheet-found);pointer-events:none}.dou-sheet__found.is-current{background-color:var(--dou-sheet-found-current)}.dou-sheet__find{position:absolute;z-index:8;display:flex;container-type:inline-size;pointer-events:none;justify-content:flex-end;top:6px;left:6px;right:14px}.dou-sheet__find>*{pointer-events:auto}.dou-sheet__find.is-below{top:auto;bottom:14px}.dou-sheet__find.is-docked{position:static;border-bottom:1px solid var(--dou-sheet-line-strong);padding:6px}.dou-sheet__find.is-docked>.dou-find-replace{box-shadow:none;border:0;flex:auto;padding:0}.dou-sheet__mark{position:absolute;z-index:4;box-sizing:border-box;border:1px dashed var(--dou-sheet-ring);pointer-events:none}.dou-sheet__mark.is-cut{border-style:dotted}.dou-sheet__mark.is-fill{border-color:var(--dou-color-text-secondary)}.dou-sheet__mark.is-drop{border:2px solid var(--dou-sheet-ring);background-color:color-mix(in oklab,var(--dou-sheet-ring)10%,transparent)}.dou-sheet__clearing{position:absolute;z-index:4;background-color:color-mix(in oklab,var(--dou-color-text)10%,transparent);pointer-events:none}.dou-sheet__guide{position:absolute;z-index:4;background-color:var(--dou-color-primary);pointer-events:none}.dou-sheet__guide.is-thin{background-color:var(--dou-sheet-ring)}.dou-sheet__fill{position:absolute;z-index:4;box-sizing:border-box;border:1px solid var(--dou-color-bg-surface);background-color:var(--dou-sheet-ring);cursor:crosshair;touch-action:none;border-radius:1px;width:8px;height:8px;margin:-5px 0 0 -5px}.dou-sheet__fill.is-dragging{opacity:0}@media (pointer:coarse){.dou-sheet__fill{border-width:2px;border-radius:50%;width:14px;height:14px;margin:-8px 0 0 -8px}.dou-sheet__fill:before{position:absolute;content:"";border-radius:50%;inset:-11px}}.dou-sheet__prompt{position:absolute;z-index:5;box-sizing:border-box;display:flex;border:1px solid var(--dou-color-border);border-radius:var(--dou-radius-control);background-color:var(--dou-color-bg-surface);box-shadow:var(--dou-shadow-md);color:var(--dou-color-text-secondary);font-size:var(--dou-font-size-sm);line-height:var(--dou-font-line-height);pointer-events:none;flex-direction:column;gap:2px;width:max-content;padding:4px 8px}.dou-sheet__prompt-problem{color:var(--dou-color-danger-text)}.dou-sheet__fill-hint{position:absolute;z-index:5;overflow:hidden;border:1px solid var(--dou-color-border);border-radius:var(--dou-radius-control);background-color:var(--dou-color-bg-surface);box-shadow:var(--dou-shadow-md);color:var(--dou-color-text);font-size:var(--dou-font-size-sm);line-height:var(--dou-font-line-height);white-space:nowrap;text-overflow:ellipsis;pointer-events:none;max-width:240px;margin-left:8px;padding:2px 8px;transform:translateY(-50%)}@media (pointer:coarse){.dou-sheet__fill-hint{margin-left:28px}}.dou-sheet__fill-hint.is-flipped{margin-left:-8px;transform:translate(-100%,-50%)}.dou-sheet__layer{position:absolute;z-index:3;overflow:hidden;pointer-events:none;inset:0}.dou-sheet__layer.is-above{z-index:4}.dou-sheet__peers{position:absolute;overflow:hidden;pointer-events:none;inset:0}.dou-sheet__peer-range,.dou-sheet__peer-cell{--dou-sheet-peer:var(--dou-color-text-secondary);position:absolute;z-index:4;box-sizing:border-box}.dou-sheet__peer-range{border:1px solid color-mix(in oklab,var(--dou-sheet-peer)60%,transparent);background-color:color-mix(in oklab,var(--dou-sheet-peer)8%,transparent)}.dou-sheet__peer-cell{border:2px solid var(--dou-sheet-peer)}.dou-sheet__peer-cell.is-editing{background-color:color-mix(in oklab,var(--dou-sheet-peer)6%,transparent)}.dou-sheet__peer-name{position:absolute;display:inline-flex;background-color:var(--dou-sheet-peer);color:oklch(from var(--dou-sheet-peer)clamp(.2,(.66 - l)*100,.99)0 0);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;animation:dou-sheet-peer-name var(--dou-motion-duration-fast)var(--dou-motion-easing)3s forwards;border-radius:4px;align-items: center;gap:2px;max-width:160px;height:14px;padding:0 5px;font-size:11px;line-height:14px;right:-2px;transform:translateY(-50%)}.dou-sheet__peer-cell.is-editing .dou-sheet__peer-name{animation:none}.dou-sheet__peer-name.is-above{top:-1px}.dou-sheet__peer-name.is-below{top:calc(100% + 1px)}.dou-sheet__peer-icon{flex:none;width:10px;height:10px}.dou-sheet__notice{position:absolute;z-index:6;box-sizing:border-box;border:1px solid var(--dou-color-border);border-radius:var(--dou-radius-control);background-color:var(--dou-color-bg-surface);box-shadow:var(--dou-shadow-md);font-size:var(--dou-font-size-sm);width:max-content;max-width:calc(100% - 24px);padding:6px 12px;bottom:12px;left:50%;transform:translate(-50%)}.dou-sheet__menu-anchor{position:absolute;overflow:hidden;width:0;height:0}.dou-sheet__probe{position:absolute;visibility:hidden;white-space:pre-wrap;overflow-wrap:anywhere;line-height:var(--dou-font-line-height);pointer-events:none}.dou-sheet__sr-only{position:absolute;overflow:hidden;clip-path:inset(50%);white-space:nowrap;width:1px;height:1px}.dou-sheet-tabs{position:relative;display:flex;box-sizing:border-box;border-top:1px solid var(--dou-color-border);background-color:var(--dou-sheet-header-bg);flex:none;align-items: flex-start;gap:4px;min-width:0;height:36px;padding:0 6px}@media (pointer:coarse){.dou-sheet-tabs{height:42px}}.dou-sheet-tabs__add{flex:none;margin-top:4px}.dou-sheet-tabs__list{display:flex;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior-x:contain;flex:1;gap:2px;min-width:0;height:100%}.dou-sheet-tabs__list::-webkit-scrollbar{display:none}.dou-sheet-tabs__list.has-more-start{mask-image:linear-gradient(90deg,#0000,#000 24px)}.dou-sheet-tabs__list.has-more-end{mask-image:linear-gradient(270deg,#0000,#000 24px)}.dou-sheet-tabs__list.has-more-start.has-more-end{mask-image:linear-gradient(90deg,#0000,#000 24px calc(100% - 24px),#0000)}.dou-sheet-tabs__tab{position:relative;display:inline-flex;box-sizing:border-box;border-radius:0 0 var(--dou-radius-control)var(--dou-radius-control);color:var(--dou-color-text-secondary);cursor:pointer;outline:none;user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;transition-property:background-color,color;transition-duration:var(--dou-motion-duration-fast);transition-timing-function:var(--dou-motion-easing);border:1px solid #0000;border-top:0;flex:none;align-items: center;max-width:200px;height:30px;margin-top:-1px;padding:0 12px}.dou-sheet-tabs__tab:hover{background-color:color-mix(in oklab,var(--dou-color-text)5%,transparent);color:var(--dou-color-text)}.dou-sheet-tabs__tab.is-active{border-color:var(--dou-color-border);background-color:var(--dou-color-bg-surface);color:var(--dou-color-text);box-shadow:0 1px 2px color-mix(in oklab,var(--dou-color-text)6%,transparent);font-weight:500}.dou-sheet-tabs__tab:focus-visible{box-shadow:inset 0 0 0 2px var(--dou-color-primary)}.dou-sheet-tabs__tab.is-dragging{opacity:.4}@media (pointer:coarse){.dou-sheet-tabs__tab{height:36px}}.is-readonly .dou-sheet-tabs__tab{cursor:default}.dou-sheet-tabs__lock{color:var(--dou-color-text-tertiary);flex:none;width:14px;height:14px;margin-right:4px}.dou-sheet-tabs__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dou-sheet-tabs__size,.dou-sheet-tabs__input{font:inherit;font-size:max(var(--dou-font-size-input-min,0px),1em);white-space:pre;min-width:2em}.dou-sheet-tabs__size{visibility:hidden;padding:0 4px}.dou-sheet-tabs__input{position:absolute;border:1px solid var(--dou-color-primary);border-radius:calc(var(--dou-radius-control) - 2px);background-color:var(--dou-color-bg-surface);color:var(--dou-color-text);outline:none;box-sizing:border-box;width:calc(100% - 16px);padding:0 3px;inset:4px 8px}.dou-sheet-tabs__input[aria-invalid]{border-color:var(--dou-color-danger)}.dou-sheet-tabs__problem{position:absolute;z-index:5;border:1px solid var(--dou-color-border);border-radius:var(--dou-radius-control);background-color:var(--dou-color-bg-surface);box-shadow:var(--dou-shadow-md);color:var(--dou-color-danger-text);font-size:var(--dou-font-size-sm);white-space:nowrap;padding:4px 8px;bottom:calc(100% + 6px);left:8px}.dou-sheet-toolbar{display:flex;border-bottom:1px solid var(--dou-color-border);background-color:var(--dou-sheet-header-bg);flex:none;min-width:0}@media (pointer:coarse){.dou-sheet-toolbar .dou-button{--dou-button-height:36px}}.dou-sheet-toolbar__bar{box-sizing:border-box;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior-x:contain;flex-wrap:nowrap;flex:1;gap:2px;height:40px;padding:0 6px}@media (pointer:coarse){.dou-sheet-toolbar__bar{height:46px}}.dou-sheet-toolbar__bar::-webkit-scrollbar{display:none}.dou-sheet-toolbar__bar.has-more-start{mask-image:linear-gradient(90deg,#0000,#000 40px)}.dou-sheet-toolbar__bar.has-more-end{mask-image:linear-gradient(270deg,#0000,#000 40px)}.dou-sheet-toolbar__bar.has-more-start.has-more-end{mask-image:linear-gradient(90deg,#0000,#000 40px calc(100% - 40px),#0000)}.dou-sheet-toolbar__bar>*{flex:none}.dou-sheet-toolbar__bar .dou-toggle-group{flex:none}.dou-sheet-toolbar__trigger{display:inline-flex;flex:none}.dou-sheet-toolbar__picker{display:none}.dou-sheet-toolbar__format{justify-content:space-between;min-width:72px}.dou-sheet-toolbar__format-label{text-align:start;flex:1}.dou-sheet-toolbar__example{color:var(--dou-color-text-tertiary);font-variant-numeric:tabular-nums;margin-inline-start:16px}.dou-sheet-toolbar__menu{gap:2px;padding-inline-start:4px;padding-inline-end:4px}.dou-sheet-toolbar__menu.is-on{--dou-button-fg:var(--dou-color-text);--dou-button-bg:color-mix(in oklab,var(--dou-color-text)9%,transparent)}.dou-sheet-toolbar__color.is-color svg>:last-child{stroke:var(--dou-sheet-swatch,currentColor);stroke-width:3}.dou-sheet-toolbar__color.is-fill svg>:last-child{fill:var(--dou-sheet-swatch,none);stroke:var(--dou-sheet-swatch,currentColor)}.dou-sheet-toolbar__colors{display:flex;gap:6px}.dou-sheet-toolbar__swatch{display:inline-flex;border:1px solid color-mix(in oklab,var(--dou-color-text)14%,transparent);background-color:var(--dou-sheet-swatch,var(--dou-color-bg-surface));color:var(--dou-color-text-secondary);cursor:pointer;border-radius:6px;flex:none;justify-content:center;align-items: center;width:24px;height:24px;padding:0}@media (pointer:coarse){.dou-sheet-toolbar__swatch{width:32px;height:32px}}.dou-sheet-toolbar__swatch:hover{border-color:color-mix(in oklab,var(--dou-color-text)30%,transparent)}.dou-sheet-toolbar__swatch:focus-visible{outline:2px solid var(--dou-color-primary);outline-offset:2px}.dou-sheet-toolbar__swatch[aria-pressed=true]{box-shadow:0 0 0 2px var(--dou-color-bg-elevated,var(--dou-color-bg-surface)),0 0 0 3px var(--dou-color-text)}.dou-sheet-toolbar__swatch.is-color{background-color:var(--dou-color-bg-surface);color:var(--dou-sheet-swatch,var(--dou-color-text));font-size:14px;font-weight:600}.dou-sheet-toolbar__swatch.is-fill.is-default{background-color:var(--dou-color-bg-surface)}.dou-sheet-toolbar__swatch.is-default{position:relative;overflow:hidden}.dou-sheet-toolbar__swatch.is-default:after{position:absolute;background-color:var(--dou-color-text-tertiary);content:"";height:1px;inset:50% -4px auto;transform:rotate(-45deg)}.dou-sheet-toolbar__swatch.is-custom:not([style*=--dou-sheet-swatch\:]){color:var(--dou-color-text-secondary)}.dou-sheet-toolbar__swatch.is-color.is-tone-neutral{--dou-sheet-swatch:var(--dou-color-neutral-text)}.dou-sheet-toolbar__swatch.is-color.is-tone-primary{--dou-sheet-swatch:var(--dou-color-primary-text)}.dou-sheet-toolbar__swatch.is-color.is-tone-success{--dou-sheet-swatch:var(--dou-color-success-text)}.dou-sheet-toolbar__swatch.is-color.is-tone-warning{--dou-sheet-swatch:var(--dou-color-warning-text)}.dou-sheet-toolbar__swatch.is-color.is-tone-danger{--dou-sheet-swatch:var(--dou-color-danger-text)}.dou-sheet-toolbar__swatch.is-fill.is-tone-neutral{--dou-sheet-swatch:color-mix(in oklab,var(--dou-color-text)6%,var(--dou-color-bg-surface))}.dou-sheet-toolbar__swatch.is-fill.is-tone-primary{--dou-sheet-swatch:color-mix(in oklab,var(--dou-color-primary)12%,var(--dou-color-bg-surface))}.dou-sheet-toolbar__swatch.is-fill.is-tone-success{--dou-sheet-swatch:color-mix(in oklab,var(--dou-color-success)12%,var(--dou-color-bg-surface))}.dou-sheet-toolbar__swatch.is-fill.is-tone-warning{--dou-sheet-swatch:color-mix(in oklab,var(--dou-color-warning)14%,var(--dou-color-bg-surface))}.dou-sheet-toolbar__swatch.is-fill.is-tone-danger{--dou-sheet-swatch:color-mix(in oklab,var(--dou-color-danger)12%,var(--dou-color-bg-surface))}.dou-sheet-toolbar__swatch svg{width:14px;height:14px}.dou-sheet-toolbar__panel{margin-top:12px}:where(.dou-sheet,.dou-sheet-formula-bar){--dou-sheet-ref-0:var(--dou-color-chart-2);--dou-sheet-ref-1:var(--dou-color-chart-3);--dou-sheet-ref-2:var(--dou-color-chart-4);--dou-sheet-ref-3:var(--dou-color-chart-5);--dou-sheet-ref-4:var(--dou-color-chart-6);--dou-sheet-ref-5:var(--dou-color-chart-7);--dou-sheet-ref-6:var(--dou-color-chart-8)}:where(.dou-sheet,.dou-sheet-formula-bar) .is-ref-0{--dou-sheet-ref:var(--dou-sheet-ref-0)}:where(.dou-sheet,.dou-sheet-formula-bar) .is-ref-1{--dou-sheet-ref:var(--dou-sheet-ref-1)}:where(.dou-sheet,.dou-sheet-formula-bar) .is-ref-2{--dou-sheet-ref:var(--dou-sheet-ref-2)}:where(.dou-sheet,.dou-sheet-formula-bar) .is-ref-3{--dou-sheet-ref:var(--dou-sheet-ref-3)}:where(.dou-sheet,.dou-sheet-formula-bar) .is-ref-4{--dou-sheet-ref:var(--dou-sheet-ref-4)}:where(.dou-sheet,.dou-sheet-formula-bar) .is-ref-5{--dou-sheet-ref:var(--dou-sheet-ref-5)}:where(.dou-sheet,.dou-sheet-formula-bar) .is-ref-6{--dou-sheet-ref:var(--dou-sheet-ref-6)}:where(.dou-sheet,.dou-sheet-formula-bar) span[class*=is-ref-]{color:var(--dou-sheet-ref)}.dou-sheet__ref{position:absolute;z-index:4;box-sizing:border-box;border:1px solid var(--dou-sheet-ref);background-color:color-mix(in oklab,var(--dou-sheet-ref)8%,transparent);pointer-events:none}.dou-sheet__input.is-mirror{overflow:hidden;color:var(--dou-color-text);pointer-events:none;user-select:none}.dou-sheet__input.is-open.is-formula{color:#0000;caret-color:var(--dou-color-text);box-shadow:none;background:0 0}.dou-sheet__input.is-open.is-formula::selection{background-color:color-mix(in oklab,var(--dou-color-primary)24%,transparent)}.dou-sheet__assist{position:fixed;z-index:2000;box-sizing:border-box;overflow-y:auto;overscroll-behavior:contain;border:1px solid var(--dou-color-border);border-radius:calc(var(--dou-radius-control) + 4px);background-color:color-mix(in oklab,var(--dou-color-text)calc(4%*var(--dou-scheme-dark)),var(--dou-color-bg-surface));box-shadow:var(--dou-shadow-md);color:var(--dou-color-text);font-family:var(--dou-font-family);font-size:var(--dou-font-size-sm);line-height:var(--dou-font-line-height);width:max-content;min-width:200px;max-width:min(320px,100vw - 16px);max-height:240px;padding:4px}.dou-sheet__assist:not([role=listbox]){max-width:min(480px,100vw - 16px);padding:6px 10px}.dou-sheet__assist-item{display:flex;border-radius:var(--dou-radius-control);cursor:pointer;flex-direction:column;gap:2px;padding:5px 8px}.dou-sheet__assist-item.is-active{background-color:color-mix(in oklab,var(--dou-color-text)6%,transparent)}@media (pointer:coarse){.dou-sheet__assist-item{padding:8px}}.dou-sheet__assist-name{font-family:var(--dou-font-family-mono);font-weight:var(--dou-font-weight-bold)}.dou-sheet__assist-text{overflow:hidden;color:var(--dou-color-text-secondary);text-overflow:ellipsis}.dou-sheet__assist-item .dou-sheet__assist-text{white-space:nowrap}.dou-sheet__assist-call{font-family:var(--dou-font-family-mono)}.dou-sheet__assist-call .is-current{font-weight:var(--dou-font-weight-bold);text-decoration:underline;text-underline-offset:3px}.dou-sheet__assist-call+.dou-sheet__assist-text{margin-top:2px}.dou-sheet-formula-bar{display:flex;border-bottom:1px solid var(--dou-color-border);background-color:var(--dou-color-bg-surface);font-size:var(--dou-font-size-md);flex:none;align-items:stretch;min-width:0}.dou-sheet-formula-bar__name,.dou-sheet-formula-bar__input,.dou-sheet-formula-bar__mirror{box-sizing:border-box;outline:none;color:var(--dou-color-text);font:inherit;font-size:max(var(--dou-font-size-input-min,0px),1em);background:0 0;border:0;margin:0;line-height:20px}.dou-sheet-formula-bar__name{border-right:1px solid var(--dou-color-border-subtle);font-variant-numeric:tabular-nums;flex:none;width:88px;min-height:32px;padding:0 10px}.dou-sheet-formula-bar__name:focus-visible{box-shadow:inset 0 0 0 2px var(--dou-sheet-ring,var(--dou-color-primary))}.dou-sheet-formula-bar__name.is-invalid{color:var(--dou-color-danger-text);box-shadow:inset 0 0 0 2px var(--dou-color-danger)}.dou-sheet-formula-bar__mark{display:flex;color:var(--dou-color-text-tertiary);flex:none;justify-content:center;align-items: center;width:32px;font-size:16px}.dou-sheet-formula-bar__box{position:relative;flex:1;min-width:0}.dou-sheet-formula-bar__input,.dou-sheet-formula-bar__mirror{display:block;height:calc(var(--dou-sheet-bar-lines,1)*20px + 12px);white-space:pre;width:100%;padding:6px 10px 6px 0}.dou-sheet-formula-bar__input{position:relative;overflow:auto;resize:none;scrollbar-width:none}.dou-sheet-formula-bar__input::-webkit-scrollbar{display:none}.dou-sheet-formula-bar__input.is-formula{color:#0000;caret-color:var(--dou-color-text)}.dou-sheet-formula-bar__input.is-formula::selection{background-color:color-mix(in oklab,var(--dou-color-primary)24%,transparent)}.dou-sheet-formula-bar__mirror{position:absolute;overflow:hidden;pointer-events:none;inset:0}.dou-sheet-code-bar__box{flex:1;min-width:0}.dou-sheet-code-bar__box .dou-code-input{--dou-code-input-height:32px}.dou-sheet-code-bar__box .dou-code-editor{--dou-code-editor-bg:transparent;--dou-code-editor-border:transparent;--dou-code-editor-border-focus:transparent;--dou-code-editor-padding-x:0px;--dou-code-editor-padding-y:6px;--dou-code-editor-font-size:max(var(--dou-font-size-input-min,0px),1em);font-family:var(--dou-font-family-mono);border-radius:0}.dou-sheet-code-bar__ref,.dou-sheet-code-bar__ref *{color:var(--dou-sheet-ref)}.dou-sheet__filter-button{position:absolute;z-index:4;display:inline-flex;box-sizing:border-box;border:1px solid var(--dou-color-border);border-radius:calc(var(--dou-radius-control) - 2px);background-color:var(--dou-color-bg-surface);color:var(--dou-color-text-tertiary);cursor:pointer;justify-content:center;align-items: center;width:20px;height:20px;margin:-10px 0 0 -23px;padding:0}.dou-sheet__filter-button:hover{background-color:var(--dou-color-bg-muted);color:var(--dou-color-text)}.dou-sheet__filter-button[aria-expanded=true]{background-color:var(--dou-color-bg-muted);color:var(--dou-color-text)}.dou-sheet__filter-button.is-active{border-color:color-mix(in oklab,var(--dou-color-primary)40%,var(--dou-color-border));color:var(--dou-color-primary-text)}.dou-sheet__filter-button>svg{width:14px;height:14px}@media (pointer:coarse){.dou-sheet__filter-button{width:24px;height:24px;margin:-12px 0 0 -26px}.dou-sheet__filter-button:after{position:absolute;content:"";inset:-8px}}.dou-sheet-filter{display:flex;font-size:var(--dou-font-size-sm);flex-direction:column;gap:8px}.dou-sheet-filter__sort{display:flex;border-bottom:1px solid var(--dou-color-border-subtle);flex-direction:column;gap:2px;padding-bottom:8px}.dou-sheet-filter__sort .dou-button{justify-content:flex-start}.dou-sheet-filter__list{display:flex;overflow-y:auto;overscroll-behavior:contain;flex-direction:column;max-height:200px;padding:4px 0}.dou-sheet-filter__item{min-height:28px;padding:0 4px}.dou-sheet-filter__item.is-blank{color:var(--dou-color-text-secondary)}.dou-sheet-filter__item.is-all{color:var(--dou-color-text-secondary)}.dou-sheet-filter__hint{color:var(--dou-color-text-tertiary);padding:6px 4px}.dou-sheet-filter__condition{display:flex;flex-direction:column;gap:8px}.dou-sheet-filter__footer{display:flex;border-top:1px solid var(--dou-color-border-subtle);justify-content:space-between;gap:8px;padding-top:8px}.dou-sheet-toolbar__gradient{display:inline-block;border:1px solid var(--dou-color-border-subtle);border-radius:3px;width:28px;height:12px}.dou-sheet-format__values{display:flex;flex:1;align-items: center;gap:8px}.dou-sheet-format__values>.dou-input{flex:1;min-width:0}.dou-sheet-format__and{color:var(--dou-color-text-secondary);flex:none}.dou-sheet-format__look{display:inline-flex;align-items: center;gap:8px;min-width:0}.dou-sheet-format__sample{display:inline-flex;box-sizing:border-box;border:1px solid var(--dou-color-border);background-color:var(--dou-color-bg-surface);color:var(--dou-color-text);font-size:var(--dou-font-size-xs);font-variant-numeric:tabular-nums;background-repeat:no-repeat;border-radius:4px;flex:none;justify-content:center;align-items: center;width:40px;height:20px}.dou-sheet-format__sample.is-bold{font-weight:600}.dou-sheet-format__sample.is-italic{font-style:italic}.dou-sheet-format__sample.is-cell-bar{background-position:3px;background-size:calc(100% - 6px) 10px}.dou-sheet-format__sample.is-bar{background-size:0 0;padding:4px}.dou-sheet-format__sample.is-bar:before{background-image:inherit;content:"";border-radius:2px;width:100%;height:100%}.dou-sheet-format__sample.is-tone-neutral{color:var(--dou-color-neutral-text)}.dou-sheet-format__sample.is-tone-primary{color:var(--dou-color-primary-text)}.dou-sheet-format__sample.is-tone-success{color:var(--dou-color-success-text)}.dou-sheet-format__sample.is-tone-warning{color:var(--dou-color-warning-text)}.dou-sheet-format__sample.is-tone-danger{color:var(--dou-color-danger-text)}.dou-sheet-format__sample.is-fill-neutral{background-color:color-mix(in oklab,var(--dou-color-text)6%,var(--dou-color-bg-surface))}.dou-sheet-format__sample.is-fill-primary{background-color:color-mix(in oklab,var(--dou-color-primary)12%,var(--dou-color-bg-surface))}.dou-sheet-format__sample.is-fill-success{background-color:color-mix(in oklab,var(--dou-color-success)12%,var(--dou-color-bg-surface))}.dou-sheet-format__sample.is-fill-warning{background-color:color-mix(in oklab,var(--dou-color-warning)14%,var(--dou-color-bg-surface))}.dou-sheet-format__sample.is-fill-danger{background-color:color-mix(in oklab,var(--dou-color-danger)12%,var(--dou-color-bg-surface))}.dou-sheet-formats{display:flex;list-style:none;flex-direction:column;margin:0;padding:0}.dou-sheet-formats__item{display:flex;align-items: center;gap:12px;padding:8px 0}.dou-sheet-formats__item+.dou-sheet-formats__item{border-top:1px solid var(--dou-color-border-subtle)}.dou-sheet-formats__what{display:flex;flex-direction:column;flex:1;gap:2px;min-width:0}.dou-sheet-formats__rule{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dou-sheet-formats__range{color:var(--dou-color-text-tertiary);font-size:var(--dou-font-size-sm);font-variant-numeric:tabular-nums}.dou-sheet-formats__actions{display:flex;flex:none;gap:2px}.dou-sheet-formats__empty{color:var(--dou-color-text-tertiary);text-align:center;margin:0;padding:16px 0}}@keyframes dou-sheet-peer-name{to{opacity:0;visibility:hidden}}
@@ -0,0 +1 @@
1
+ export {}
package/dist/style.js ADDED
@@ -0,0 +1,17 @@
1
+ import 'dou-ui/components/autocomplete/style'
2
+ import 'dou-ui/components/checkbox/style'
3
+ import 'dou-ui/components/color-panel/style'
4
+ import 'dou-ui/components/comment-thread/style'
5
+ import 'dou-ui/components/date-picker/style'
6
+ import 'dou-ui/components/dialog/style'
7
+ import 'dou-ui/components/dropdown/style'
8
+ import 'dou-ui/components/context-menu/style'
9
+ import 'dou-ui/components/form/style'
10
+ import 'dou-ui/components/input-number/style'
11
+ import 'dou-ui/components/popover/style'
12
+ import 'dou-ui/components/segmented-control/style'
13
+ import 'dou-ui/components/sortable/style'
14
+ import 'dou-ui/components/toggle/style'
15
+ import 'dou-ui/components/toolbar/style'
16
+ import 'dou-ui/components/find-replace/style'
17
+ import './style.css'
@@ -0,0 +1,2 @@
1
+ import type { SheetCellType } from './core/cell-type';
2
+ export declare const builtinCellTypes: readonly SheetCellType[];
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The formula bar with the formula in `@dou-ui/code`'s code input. Use it
3
+ * in place of `DouSheetFormulaBar`; needs `@dou-ui/code` and its styles.
4
+ */
5
+ export declare const DouSheetCodeFormulaBar: import("dou-ui").WithInstall<import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>, import("vue").HTMLAttributes>;
6
+ export { sheetFormula } from './language';
7
+ export type { SheetFormulaState } from './language';
8
+ declare module 'vue' {
9
+ interface GlobalComponents {
10
+ DouSheetCodeFormulaBar: typeof DouSheetCodeFormulaBar;
11
+ }
12
+ }
@@ -0,0 +1,13 @@
1
+ import { type CodeLanguage } from '@dou-ui/code';
2
+ export interface SheetFormulaState {
3
+ /** A "text" value still open at the line's end. */
4
+ quote: boolean;
5
+ }
6
+ /**
7
+ * Spreadsheet formulas, as the sheet writes them: `=SUM(A1:B2, "text")`.
8
+ * Function names, references, "text", numbers, error values and
9
+ * `TRUE` / `FALSE` each have their color. For the text after the `=`, or
10
+ * with it; a value typed into a cell isn't a formula, so leave the
11
+ * language out for it.
12
+ */
13
+ export declare const sheetFormula: CodeLanguage<SheetFormulaState>;
@@ -0,0 +1,65 @@
1
+ import { type SheetCell, type SheetCellInput } from '../core/model';
2
+ /** The ids of a sheet's rows or columns, in order, with a lookup of each one's number. */
3
+ export declare class SheetLines {
4
+ ids: string[];
5
+ private at;
6
+ constructor(ids: string[]);
7
+ /** The number of a line, `-1` when it is gone. */
8
+ indexOf(id: string): number;
9
+ /** Call after changing `ids`. */
10
+ changed(): void;
11
+ }
12
+ /** A sheet as references see it: its id, its name and its lines. */
13
+ export interface LayoutSheet {
14
+ id: string;
15
+ name: string;
16
+ rows: SheetLines;
17
+ cols: SheetLines;
18
+ }
19
+ /** The sheets of a workbook, by id and by name. */
20
+ export declare class SheetLayout {
21
+ readonly sheets: Map<string, LayoutSheet>;
22
+ byName(name: string): LayoutSheet | undefined;
23
+ }
24
+ /** One end of a reference: a line id, a number past the sheet's lines, or `null` for none (`B:B` has no row). */
25
+ type End = string | number | null;
26
+ /**
27
+ * A reference held by ids: the sheet it names (`null`: the formula's own
28
+ * sheet), then the rows and columns of its two ends. `0` for a reference
29
+ * to a sheet that isn't there, kept as written.
30
+ */
31
+ export type AnchoredRef = 0 | [sheet: string | null, rowA: End, colA: End, rowB: End, colB: End];
32
+ /** Text with references, and their anchors in the order they come. */
33
+ export interface AnchoredText {
34
+ t: string;
35
+ r?: AnchoredRef[];
36
+ }
37
+ /** The anchors of a formula's references, or `undefined` when it has none to keep. */
38
+ export declare function anchorFormula(formula: string, here: LayoutSheet, layout: SheetLayout): AnchoredRef[] | undefined;
39
+ /** The number of a line: its id's place, `-1` when it is gone, or the number kept for one past the ids. */
40
+ export declare function lineOf(lines: SheetLines, end: string | number): number;
41
+ export declare function lineOf(lines: SheetLines, end: End): number | undefined;
42
+ /**
43
+ * A formula with its references where their lines are now. A reference
44
+ * whose line or sheet is gone reads `#REF!`; one whose sheet was renamed
45
+ * names it anew. Unchanged references keep their text as written.
46
+ */
47
+ export declare function resolveFormula(formula: string, refs: readonly AnchoredRef[], here: LayoutSheet, layout: SheetLayout): string;
48
+ /** A range such as `A1:C4`, anchored. */
49
+ export declare function anchorRange(range: string, here: LayoutSheet, layout: SheetLayout): AnchoredText;
50
+ /** A range where its lines are now; `null` when they are gone. */
51
+ export declare function resolveRange(stored: AnchoredText, here: LayoutSheet, layout: SheetLayout): string | null;
52
+ /** A formula, or text that may be one, anchored. */
53
+ export declare function anchorText(text: string, here: LayoutSheet, layout: SheetLayout): AnchoredText;
54
+ export declare function resolveText(stored: AnchoredText, here: LayoutSheet, layout: SheetLayout): string;
55
+ /** Where a cell keeps the anchors of its formula in the shared document. */
56
+ export declare const REFS = "$refs";
57
+ /** A cell as the shared document keeps it: as it is, with the anchors of its formula beside. */
58
+ export declare function anchorCell(cell: SheetCellInput, here: LayoutSheet, layout: SheetLayout): unknown;
59
+ /** Whether a cell kept in the shared document has references to resolve. */
60
+ export declare const hasRefs: (stored: unknown) => stored is SheetCell & {
61
+ [REFS]: AnchoredRef[];
62
+ };
63
+ /** A cell kept in the shared document, with its formula's references where they are now. */
64
+ export declare function resolveCell(stored: unknown, here: LayoutSheet, layout: SheetLayout): SheetCellInput;
65
+ export {};
@@ -0,0 +1,59 @@
1
+ import { collaborationColors } from 'dou-ui';
2
+ import * as Y from 'yjs';
3
+ import { type SheetExtension } from '../core/extension';
4
+ export { fillBook, readBook } from './shared';
5
+ /** The part of an `Awareness` (`y-protocols/awareness`) the sheet uses. */
6
+ export interface AwarenessLike {
7
+ clientID: number;
8
+ getLocalState(): Record<string, unknown> | null;
9
+ setLocalStateField(field: string, value: unknown): void;
10
+ getStates(): Map<number, Record<string, unknown>>;
11
+ on(event: 'change', listener: (...args: unknown[]) => void): void;
12
+ off(event: 'change', listener: (...args: unknown[]) => void): void;
13
+ }
14
+ /** How the people editing together see each other. */
15
+ export interface CollaborationUser {
16
+ name: string;
17
+ /** The color of this user's marks, any CSS color. Picked from the client id when left out. */
18
+ color?: string;
19
+ }
20
+ export interface CollaborationOptions {
21
+ /** Where the workbook lives, e.g. `ydoc.getMap('book')`. */
22
+ book: Y.Map<unknown>;
23
+ /** Shares what each person has selected and is editing (`y-protocols/awareness`). */
24
+ awareness?: AwarenessLike;
25
+ /** This user, shown to the others. Needs `awareness`. */
26
+ user?: CollaborationUser;
27
+ /**
28
+ * Where the comment threads live, e.g. `ydoc.getMap('comments')`, so
29
+ * they reach everyone with the workbook. `v-model:comments` then only
30
+ * mirrors them. Without it, the cells' anchors still travel with the
31
+ * workbook and the threads are the app's to share.
32
+ */
33
+ comments?: Y.Map<unknown>;
34
+ }
35
+ /** A line by its id, or by number when it is past the lines the sheet has. */
36
+ type LineAt = string | number;
37
+ /** What each person shares under the awareness field `sheet`: lines by id, so they read right everywhere. */
38
+ export interface SheetPresence {
39
+ /** The `id` of the sheet they have open. */
40
+ sheet: string;
41
+ /** Their active cell, `[row, col]`. */
42
+ active: [LineAt, LineAt];
43
+ /** What they have selected, each range `[top, left, bottom, right]`. */
44
+ ranges: [LineAt, LineAt, LineAt, LineAt][];
45
+ /** Whether they are editing the active cell. */
46
+ editing: boolean;
47
+ }
48
+ export { collaborationColors };
49
+ /**
50
+ * Edit a workbook together through a Yjs document. Every row and column
51
+ * has an id there; cells, sizes, formulas and rules are kept by those ids,
52
+ * so two people inserting, deleting or moving lines at once keep each
53
+ * other's cells in place, and formulas still point at the cells they were
54
+ * written for. The grid's `v-model` only mirrors the shared workbook: a
55
+ * workbook set through `v-model` from outside is not written back. Undo
56
+ * only takes back this user's own changes. With `awareness`, each person
57
+ * sees the others' selections and the cells they edit, in their colors.
58
+ */
59
+ export declare function collaboration(options: CollaborationOptions): SheetExtension;
@@ -0,0 +1,21 @@
1
+ import { type Component, type Ref } from 'vue';
2
+ import type { SheetBounds, SheetPoint } from '../core/address';
3
+ /** A person editing the workbook too, with where they are, in this side's numbers. */
4
+ export interface SheetPeer {
5
+ client: number;
6
+ name: string;
7
+ color: string;
8
+ /** The `id` of the sheet they have open. */
9
+ sheet: string;
10
+ active: SheetPoint | null;
11
+ ranges: SheetBounds[];
12
+ editing: boolean;
13
+ }
14
+ /**
15
+ * A layer that shows the other people on the sheet shown, in their colors:
16
+ * a tint over what they have selected and a ring on their cell. Their name
17
+ * sits on the ring's corner, over the grid line rather than the cells'
18
+ * text; it fades a few seconds after they stop moving, and stays with a
19
+ * pencil while they edit.
20
+ */
21
+ export declare function createPeers(peers: Ref<SheetPeer[]>): Component;
@@ -0,0 +1,75 @@
1
+ import * as Y from 'yjs';
2
+ import { type SheetCellInput, type SheetData, type SheetWorkbook } from '../core/model';
3
+ import { SheetLayout, type LayoutSheet } from './anchor';
4
+ export type SharedMap = Y.Map<unknown>;
5
+ export type SharedList = Y.Array<string>;
6
+ export declare const isMetaKey: (key: string) => boolean;
7
+ /** Whether a key of the workbook is one of its own settings, kept as it is in the shared map. */
8
+ export declare const isBookKey: (key: string) => boolean;
9
+ /** The fields of a sheet whose ranges or formulas are anchored to its lines. */
10
+ export declare const ANCHORED_META: readonly ["merges", "filter", "conditionalFormats", "validations", "groups"];
11
+ export declare const cellKey: (row: string, col: string) => string;
12
+ export declare const threadKey: (key: string) => string;
13
+ export declare const isThreadKey: (key: string) => boolean;
14
+ /** The cell a key is about: the cell's own key for its thread's. */
15
+ export declare const cellOfKey: (key: string) => string;
16
+ /** A cell with the thread kept beside it. */
17
+ export declare function withThread(cell: SheetCellInput, thread: unknown): SheetCellInput;
18
+ /** A cell without its thread, and the thread. */
19
+ export declare function splitThread(cell: SheetCellInput): [SheetCellInput, string | undefined];
20
+ /** Where a cell kept under `key` is now; `-1` for a line that is gone. */
21
+ export declare function cellAt(key: string, here: LayoutSheet): {
22
+ row: number;
23
+ col: number;
24
+ };
25
+ export declare function makeIds(doc: Y.Doc | null): {
26
+ next: () => string;
27
+ many: (count: number) => string[];
28
+ };
29
+ export type IdMaker = ReturnType<typeof makeIds>;
30
+ /** A list without repeats, the first of each kept. */
31
+ export declare function unique(list: readonly string[]): string[];
32
+ export interface SharedParts {
33
+ styles: SharedMap;
34
+ types: SharedMap;
35
+ order: SharedList;
36
+ sheets: Y.Map<SharedMap>;
37
+ }
38
+ /** The parts of the shared workbook, `null` before it is filled. */
39
+ export declare function partsOf(book: SharedMap): SharedParts | null;
40
+ export interface SharedSheet {
41
+ rows: SharedList;
42
+ cols: SharedList;
43
+ cells: SharedMap;
44
+ rowSizes: SharedMap;
45
+ colSizes: SharedMap;
46
+ meta: SharedMap;
47
+ }
48
+ export declare function sheetParts(map: SharedMap | undefined): SharedSheet | null;
49
+ /** The sheets as the shared document has them: ids, names and lines. */
50
+ export declare function readLayout(parts: SharedParts): SheetLayout;
51
+ /** A field of a sheet as the shared document keeps it. */
52
+ export declare function anchorMeta(key: string, value: unknown, here: LayoutSheet, layout: SheetLayout): {} | null | undefined;
53
+ /** A field of a sheet read from the shared document; `undefined` when its cells are gone. */
54
+ export declare function resolveMeta(key: string, stored: unknown, here: LayoutSheet, layout: SheetLayout): {} | undefined;
55
+ /** Writes a whole sheet into `sheets` under its id, with the lines `here` gives it. */
56
+ export declare function writeSheet(sheets: Y.Map<SharedMap>, data: SheetData, here: LayoutSheet, layout: SheetLayout): void;
57
+ /** A sheet's place in the layout, with new ids for its lines. */
58
+ export declare function layoutSheet(data: SheetData, id: string, ids: IdMaker): LayoutSheet;
59
+ /**
60
+ * Writes a workbook into an empty shared map, e.g. when a workbook so far
61
+ * saved as JSON starts being edited together. Sheets without an `id` get one.
62
+ */
63
+ export declare function fillBook(book: SharedMap, workbook: SheetWorkbook): void;
64
+ /** A sheet as the shared document has it. */
65
+ export declare function readSheet(parts: SharedSheet, here: LayoutSheet, layout: SheetLayout): SheetData;
66
+ /** The workbook a shared map holds; an empty workbook before it is filled. */
67
+ export declare function readBook(book: SharedMap): SheetWorkbook;
68
+ /** The indexes of the longest strictly increasing run of `values`. */
69
+ export declare function increasingRun(values: readonly number[]): Set<number>;
70
+ /**
71
+ * Brings a shared list of ids to `wanted` with as few changes as it takes:
72
+ * the longest run already in order stays, the rest is taken out and put
73
+ * back where it goes, so others' changes to the list around it still merge.
74
+ */
75
+ export declare function syncList(list: SharedList, wanted: readonly string[]): void;
@@ -0,0 +1,20 @@
1
+ import type { SheetResolvedType } from '../core/cell-type';
2
+ import type { SheetValue } from '../core/model';
3
+ type __VLS_Props = {
4
+ resolved: SheetResolvedType;
5
+ value: SheetValue;
6
+ text: string;
7
+ typed: boolean;
8
+ /** The editor, which the panel hangs under. */
9
+ anchor: HTMLElement | undefined;
10
+ };
11
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
12
+ onKey: (event: KeyboardEvent) => boolean;
13
+ activeId: import("vue").ComputedRef<string | null>;
14
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
15
+ pick: (value: SheetValue) => any;
16
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
17
+ onPick?: ((value: SheetValue) => any) | undefined;
18
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
19
+ declare const _default: typeof __VLS_export;
20
+ export default _default;
@@ -0,0 +1,9 @@
1
+ import { type FunctionalComponent } from 'vue';
2
+ import { type SheetCellRenderProps } from '../core/cell-type';
3
+ /** A check box cell: the box of a checkbox, which a click switches. */
4
+ export declare const CellCheck: FunctionalComponent<SheetCellRenderProps>;
5
+ /**
6
+ * A select cell: its value as a soft tag, in its option's tone or neutral.
7
+ * A value that isn't one of the options shows as plain text.
8
+ */
9
+ export declare const CellOption: FunctionalComponent<SheetCellRenderProps>;
@@ -0,0 +1,9 @@
1
+ import type { SheetCellPanelProps } from '../core/cell-type';
2
+ import type { SheetValue } from '../core/model';
3
+ declare const __VLS_export: import("vue").DefineComponent<SheetCellPanelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
4
+ pick: (value: SheetValue) => any;
5
+ }, string, import("vue").PublicProps, Readonly<SheetCellPanelProps> & Readonly<{
6
+ onPick?: ((value: SheetValue) => any) | undefined;
7
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
8
+ declare const _default: typeof __VLS_export;
9
+ export default _default;
@@ -0,0 +1,21 @@
1
+ import type { SheetFilterRule, SheetSortOrder } from '../core/model';
2
+ import { type SheetMessages } from '../locale';
3
+ type __VLS_Props = {
4
+ /** The column's values as they show, each once, in sorted order; `''` is empty. */
5
+ values: readonly string[];
6
+ /** Whether most of the column's values are numbers: conditions then start at “≥”. */
7
+ numeric?: boolean;
8
+ rule: SheetFilterRule | undefined;
9
+ sorted: SheetSortOrder | undefined;
10
+ messages: SheetMessages;
11
+ readonly: boolean;
12
+ };
13
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
14
+ sort: (order: SheetSortOrder) => any;
15
+ apply: (rule: SheetFilterRule | undefined) => any;
16
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
17
+ onSort?: ((order: SheetSortOrder) => any) | undefined;
18
+ onApply?: ((rule: SheetFilterRule | undefined) => any) | undefined;
19
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
20
+ declare const _default: typeof __VLS_export;
21
+ export default _default;
@@ -0,0 +1,24 @@
1
+ import type { SheetConditionalFormat, SheetStyle } from '../core/model';
2
+ import type { SheetMessages } from '../locale';
3
+ type __VLS_Props = {
4
+ format: SheetConditionalFormat;
5
+ title: string;
6
+ /** The workbook's named styles, for a rule that names one. */
7
+ styles: Record<string, SheetStyle> | undefined;
8
+ messages: SheetMessages;
9
+ };
10
+ type __VLS_ModelProps = {
11
+ 'open': boolean;
12
+ };
13
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
14
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
15
+ apply: (format: SheetConditionalFormat) => any;
16
+ "update:open": (value: boolean) => any;
17
+ closed: () => any;
18
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
19
+ onApply?: ((format: SheetConditionalFormat) => any) | undefined;
20
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
21
+ onClosed?: (() => any) | undefined;
22
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
+ declare const _default: typeof __VLS_export;
24
+ export default _default;
@@ -0,0 +1,25 @@
1
+ import type { SheetConditionalFormat, SheetStyle } from '../core/model';
2
+ import { type SheetMessages } from '../locale';
3
+ type __VLS_Props = {
4
+ formats: readonly SheetConditionalFormat[];
5
+ /** The workbook's named styles, for formats that name one. */
6
+ styles: Record<string, SheetStyle> | undefined;
7
+ messages: SheetMessages;
8
+ };
9
+ type __VLS_ModelProps = {
10
+ 'open': boolean;
11
+ };
12
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
13
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
14
+ edit: (index: number) => any;
15
+ change: (formats: SheetConditionalFormat[]) => any;
16
+ "update:open": (value: boolean) => any;
17
+ closed: () => any;
18
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
19
+ onEdit?: ((index: number) => any) | undefined;
20
+ onChange?: ((formats: SheetConditionalFormat[]) => any) | undefined;
21
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
22
+ onClosed?: (() => any) | undefined;
23
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
24
+ declare const _default: typeof __VLS_export;
25
+ export default _default;
@@ -0,0 +1,30 @@
1
+ import type { Tone } from 'dou-ui';
2
+ import type { SheetColor, SheetConditionalFormat, SheetStyle } from '../core/model';
3
+ import type { SheetMessages } from '../locale';
4
+ export declare const TONES: Tone[];
5
+ export type SheetLookName = keyof SheetMessages['formats']['looks'];
6
+ export declare const LOOKS: Record<SheetLookName, SheetStyle>;
7
+ export type SheetScaleName = keyof SheetMessages['formats']['scales'];
8
+ export type SheetScaleColors = [SheetColor, SheetColor] | [SheetColor, SheetColor, SheetColor];
9
+ export declare const SCALES: Record<SheetScaleName, SheetScaleColors>;
10
+ /** The message key of a tone's name. */
11
+ export declare const toneKey: (tone: Tone) => `tone${Capitalize<Tone>}`;
12
+ export declare const scaleSwatch: (colors: readonly SheetColor[]) => string;
13
+ /** A data bar color as a chip; it fills its box so it sits centered like the scale swatches. */
14
+ export declare const barSwatch: (color: SheetColor) => string;
15
+ /** Whether two styles set the same parts the same way. */
16
+ export declare function sameStyle(a: SheetStyle, b: SheetStyle): boolean;
17
+ /** The preset a style is, if any. */
18
+ export declare function lookName(style: SheetStyle): SheetLookName | undefined;
19
+ /** The preset some scale colors are, if any. */
20
+ export declare function scaleName(colors: readonly SheetColor[]): SheetScaleName | undefined;
21
+ /** How a sample `123` of a look shows: its classes and inline style. */
22
+ export declare function styleSample(style: SheetStyle | undefined): {
23
+ cls: string[];
24
+ css: string;
25
+ };
26
+ /** How the sample of a format shows. */
27
+ export declare function formatSample(f: SheetConditionalFormat, styles: Record<string, SheetStyle> | undefined): {
28
+ cls: string[];
29
+ css: string;
30
+ };
@@ -0,0 +1,13 @@
1
+ import { type SheetCellPanelProps } from '../core/cell-type';
2
+ import type { SheetValue } from '../core/model';
3
+ declare function onKey(event: KeyboardEvent): boolean;
4
+ declare const __VLS_export: import("vue").DefineComponent<SheetCellPanelProps, {
5
+ onKey: typeof onKey;
6
+ activeId: import("vue").ComputedRef<string | null>;
7
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
+ pick: (value: SheetValue) => any;
9
+ }, string, import("vue").PublicProps, Readonly<SheetCellPanelProps> & Readonly<{
10
+ onPick?: ((value: SheetValue) => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -0,0 +1,29 @@
1
+ import { type CommentAction, type CommentAuthor, type CommentThread, type VirtualElement } from 'dou-ui';
2
+ type __VLS_Props = {
3
+ /** The cell it is about. */
4
+ anchor: VirtualElement;
5
+ /** The thread; `null` to write the first comment. */
6
+ thread: CommentThread | null;
7
+ author?: CommentAuthor;
8
+ readonly: boolean;
9
+ label: string;
10
+ /** Bumped to put the cursor in the reply box. */
11
+ focusRequest: number;
12
+ /** The last request the cursor was put there for; a card opened for a newer one takes it. */
13
+ focusHandled: number;
14
+ /** What belongs to the grid: a press there is the grid's, not outside the card. */
15
+ grid: () => HTMLElement | null;
16
+ };
17
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
18
+ panel: import("vue").ShallowRef<HTMLElement | null, HTMLElement | null>;
19
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
20
+ close: (refocus: boolean) => any;
21
+ action: (action: CommentAction) => any;
22
+ focused: (request: number) => any;
23
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
24
+ onClose?: ((refocus: boolean) => any) | undefined;
25
+ onAction?: ((action: CommentAction) => any) | undefined;
26
+ onFocused?: ((request: number) => any) | undefined;
27
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
+ declare const _default: typeof __VLS_export;
29
+ export default _default;
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,32 @@
1
+ import { type VirtualElement } from 'dou-ui';
2
+ import type { SheetLinkMessages } from '../locale';
3
+ type __VLS_Props = {
4
+ /** The cell the link belongs to. */
5
+ anchor: VirtualElement;
6
+ link: string;
7
+ /** What the cell shows; `null` for a formula's cell, whose text isn't edited here. */
8
+ text: string | null;
9
+ editing: boolean;
10
+ /** At the grid's foot rather than under the cell, so a finger can still reach the cells around it. */
11
+ docked?: boolean;
12
+ /** Whether the link can be changed: the grid is editable and the cell isn't locked. */
13
+ editable: boolean;
14
+ /** Whether the cell has a link of its own to take off, not only a formula's. */
15
+ removable: boolean;
16
+ messages: SheetLinkMessages;
17
+ };
18
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ edit: () => any;
20
+ cancel: (leaving: boolean) => any;
21
+ open: () => any;
22
+ save: (link: string, text: string | null, leaving: boolean) => any;
23
+ remove: () => any;
24
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
25
+ onEdit?: (() => any) | undefined;
26
+ onCancel?: ((leaving: boolean) => any) | undefined;
27
+ onOpen?: (() => any) | undefined;
28
+ onSave?: ((link: string, text: string | null, leaving: boolean) => any) | undefined;
29
+ onRemove?: (() => any) | undefined;
30
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
+ declare const _default: typeof __VLS_export;
32
+ export default _default;