@heycys/gallery 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. package/THIRD-PARTY-NOTICES.md +2 -2
  2. package/browser/editor/components/align.mjs +58 -0
  3. package/browser/editor/components/code/index.mjs +1 -1
  4. package/browser/editor/components/columns/page.mjs +4 -4
  5. package/browser/editor/components/embed/index.mjs +2 -2
  6. package/browser/editor/components/embed/page.mjs +1 -1
  7. package/browser/editor/components/file/page.mjs +4 -4
  8. package/browser/editor/components/flowchart/add.mjs +7 -6
  9. package/browser/editor/components/flowchart/page.mjs +1 -1
  10. package/browser/editor/components/heading/index.mjs +7 -6
  11. package/browser/editor/components/icons.mjs +11 -0
  12. package/browser/editor/components/image/crop.mjs +6 -9
  13. package/browser/editor/components/image/index.mjs +2 -0
  14. package/browser/editor/components/image/page.mjs +172 -90
  15. package/browser/editor/components/installed/index.mjs +15 -4
  16. package/browser/editor/components/installed/page.mjs +103 -25
  17. package/browser/editor/components/installed/served.mjs +6 -5
  18. package/browser/editor/components/instances.mjs +18 -0
  19. package/browser/editor/components/list/page.mjs +3 -6
  20. package/browser/editor/components/media/icons.mjs +13 -8
  21. package/browser/editor/components/media/page.mjs +5 -3
  22. package/browser/editor/components/media/toolbar.mjs +12 -3
  23. package/browser/editor/components/paragraph/index.mjs +4 -3
  24. package/browser/editor/components/registry.mjs +30 -9
  25. package/browser/editor/components/table/index.mjs +61 -2
  26. package/browser/editor/components/table/page.mjs +1 -1
  27. package/browser/editor/page/after/index.mjs +288 -0
  28. package/browser/editor/page/align.mjs +91 -0
  29. package/browser/editor/page/annotate/card.mjs +3 -6
  30. package/browser/editor/page/autosave.mjs +310 -37
  31. package/browser/editor/page/beside.mjs +5 -6
  32. package/browser/editor/page/block-menu/index.mjs +6 -3
  33. package/browser/editor/page/blocks.mjs +3 -1
  34. package/browser/editor/page/board/client.mjs +57 -0
  35. package/browser/editor/page/board/hint.mjs +182 -0
  36. package/browser/editor/page/board/history.mjs +119 -0
  37. package/browser/editor/page/board/index.mjs +1059 -0
  38. package/browser/editor/page/board/motion.mjs +177 -0
  39. package/browser/editor/page/board/settings.mjs +210 -0
  40. package/browser/editor/page/caret.mjs +1 -1
  41. package/browser/editor/page/changes/bar.mjs +6 -14
  42. package/browser/editor/page/changes/index.mjs +2 -2
  43. package/browser/editor/page/clipboard/import/html.mjs +29 -6
  44. package/browser/editor/page/clipboard/import/inline.mjs +32 -0
  45. package/browser/editor/page/clipboard/import/markdown.mjs +58 -13
  46. package/browser/editor/page/clipboard/import/read.mjs +6 -1
  47. package/browser/editor/page/clipboard/import/to-blocks.mjs +44 -12
  48. package/browser/editor/page/clipboard/import/yuque.mjs +622 -0
  49. package/browser/editor/page/clipboard/index.mjs +133 -15
  50. package/browser/editor/page/clipboard/own/blocks.mjs +13 -14
  51. package/browser/editor/page/clipboard/own/chart-keys.mjs +41 -28
  52. package/browser/editor/page/clipboard/own/describe.mjs +6 -2
  53. package/browser/editor/page/clipboard/own/selection.mjs +1 -1
  54. package/browser/editor/page/columns/index.mjs +48 -46
  55. package/browser/editor/page/commit.mjs +80 -22
  56. package/browser/editor/page/conflicts.mjs +7 -7
  57. package/browser/editor/page/core.mjs +34 -16
  58. package/browser/editor/page/custom-page.mjs +110 -0
  59. package/browser/editor/page/editor.mjs +71 -17
  60. package/browser/editor/page/emoji-picker/styles.mjs +7 -12
  61. package/browser/editor/page/emoji-picker/upload.mjs +2 -2
  62. package/browser/editor/page/handle/index.mjs +5 -8
  63. package/browser/editor/page/history.mjs +41 -6
  64. package/browser/editor/page/insert/index.mjs +20 -22
  65. package/browser/editor/page/links/index.mjs +5 -3
  66. package/browser/editor/page/links/pages.mjs +27 -9
  67. package/browser/editor/page/look.mjs +54 -3
  68. package/browser/editor/page/margin.mjs +18 -3
  69. package/browser/editor/page/media-menu/index.mjs +6 -7
  70. package/browser/editor/page/menu.mjs +33 -14
  71. package/browser/editor/page/notices.mjs +2 -2
  72. package/browser/editor/page/page-objects.mjs +9 -2
  73. package/browser/editor/page/panel.mjs +4 -9
  74. package/browser/editor/page/present-links.mjs +15 -5
  75. package/browser/editor/page/present-shell.mjs +63 -0
  76. package/browser/editor/page/resize/index.mjs +42 -29
  77. package/browser/editor/page/selection/index.mjs +10 -2
  78. package/browser/editor/page/served.mjs +14 -0
  79. package/browser/editor/page/session.mjs +48 -4
  80. package/browser/editor/page/slash-menu/index.mjs +3 -3
  81. package/browser/editor/page/table/binding.mjs +87 -0
  82. package/browser/editor/page/table/cells.mjs +102 -46
  83. package/browser/editor/page/table/index.mjs +24 -9
  84. package/browser/editor/page/table/pictures.mjs +299 -0
  85. package/browser/editor/page/table/views.mjs +103 -0
  86. package/browser/editor/page/table/widths.mjs +82 -10
  87. package/browser/editor/page/text-select/index.mjs +26 -12
  88. package/browser/editor/page/todo-writes.mjs +75 -0
  89. package/browser/editor/page/typing/index.mjs +97 -15
  90. package/browser/editor/page/typing/leave.mjs +19 -5
  91. package/browser/editor/page/ui.mjs +13 -0
  92. package/browser/shared/block-packs.mjs +419 -0
  93. package/browser/shared/board-places.mjs +224 -0
  94. package/browser/shared/card-size.mjs +59 -0
  95. package/browser/shared/colors.mjs +3 -2
  96. package/browser/shared/component-catalog.mjs +330 -46
  97. package/browser/shared/component-source.mjs +39 -0
  98. package/browser/shared/components/heading.mjs +2 -1
  99. package/browser/shared/components/index.mjs +12 -3
  100. package/browser/shared/components/installed.mjs +35 -3
  101. package/browser/shared/components/page.mjs +20 -8
  102. package/browser/shared/components/paragraph.mjs +8 -1
  103. package/browser/shared/components/state.mjs +5 -1
  104. package/browser/shared/components/table.mjs +1 -0
  105. package/browser/shared/document-look.mjs +10 -5
  106. package/browser/shared/drafts.mjs +432 -0
  107. package/browser/shared/emoji/line-icons.mjs +37 -0
  108. package/browser/shared/extension-sidebar.mjs +126 -0
  109. package/browser/shared/extensions.mjs +79 -0
  110. package/browser/shared/file-table.mjs +101 -0
  111. package/browser/shared/http.mjs +9 -0
  112. package/browser/shared/i18n/en.mjs +330 -27
  113. package/browser/shared/json-layout.mjs +47 -0
  114. package/browser/shared/net-cache.mjs +133 -0
  115. package/browser/shared/net-keys.mjs +32 -0
  116. package/browser/shared/net-policy.mjs +177 -0
  117. package/browser/shared/outline-shape.mjs +128 -0
  118. package/browser/shared/outline.mjs +359 -67
  119. package/browser/shared/pack-manifest.mjs +88 -0
  120. package/browser/shared/page-address.mjs +6 -3
  121. package/browser/shared/page-cards.mjs +308 -0
  122. package/browser/shared/page-links.mjs +69 -6
  123. package/browser/shared/pages.mjs +500 -0
  124. package/browser/shared/paths.mjs +6 -0
  125. package/browser/shared/pinyin.mjs +92 -0
  126. package/browser/shared/present-step.mjs +17 -0
  127. package/browser/shared/preview-server.mjs +3 -7
  128. package/browser/shared/session.mjs +8 -1
  129. package/browser/shared/shipped-blocks.mjs +299 -0
  130. package/browser/shared/sidebar-head.mjs +70 -0
  131. package/browser/shared/table-chart.mjs +33 -1
  132. package/browser/shared/todos.mjs +83 -0
  133. package/browser/shared/user-directory.mjs +24 -0
  134. package/browser/shared/versions.mjs +14 -0
  135. package/browser/shared/web-links.mjs +139 -0
  136. package/browser/shared/workspace-columns.mjs +120 -0
  137. package/browser/shared/workspace-name.mjs +154 -0
  138. package/browser/shared/workspace-query.mjs +125 -0
  139. package/browser/shared/workspace-registry.mjs +272 -0
  140. package/browser/shared/workspace.mjs +171 -20
  141. package/dist/chunk-2OHANJ6Q.mjs +2 -0
  142. package/dist/chunk-3MBRL2PM.mjs +16 -0
  143. package/dist/chunk-4OKWZY5E.mjs +2 -0
  144. package/dist/chunk-4OZWXZE5.mjs +5 -0
  145. package/dist/chunk-5K44HLTZ.mjs +2 -0
  146. package/dist/{chunk-5ZKJ3H4P.mjs → chunk-5XA2ZBAE.mjs} +3 -3
  147. package/dist/{chunk-4FS7Z7WR.mjs → chunk-67N2QJYT.mjs} +1 -1
  148. package/dist/chunk-6KBYRA2C.mjs +2 -0
  149. package/dist/chunk-6N3PX4XX.mjs +8 -0
  150. package/dist/{chunk-V5JTW2LH.mjs → chunk-6QBHU4DF.mjs} +1 -1
  151. package/dist/chunk-7JDX4E65.mjs +13 -0
  152. package/dist/chunk-7M2BQQGZ.mjs +2 -0
  153. package/dist/chunk-7OG26PGF.mjs +2 -0
  154. package/dist/chunk-AHN3NFKJ.mjs +3 -0
  155. package/dist/chunk-ALZ6ZENZ.mjs +3 -0
  156. package/dist/chunk-AR5D57ZD.mjs +170 -0
  157. package/dist/{chunk-W3BGBJQW.mjs → chunk-BFJGHSQN.mjs} +1 -1
  158. package/dist/{chunk-LS4F7JUM.mjs → chunk-BZ5RAF7L.mjs} +1 -1
  159. package/dist/chunk-CMA72MAG.mjs +2 -0
  160. package/dist/{chunk-LCTHTZIL.mjs → chunk-DAZL73VK.mjs} +91 -91
  161. package/dist/{chunk-Y6RLRPG3.mjs → chunk-DJISHPUL.mjs} +1 -1
  162. package/dist/chunk-DR73Y2UJ.mjs +3 -0
  163. package/dist/{chunk-FDLXYYG4.mjs → chunk-EAIFITAV.mjs} +1 -1
  164. package/dist/{chunk-TMYZB6AV.mjs → chunk-EKNHM3P4.mjs} +1 -1
  165. package/dist/chunk-EP25HDAJ.mjs +2 -0
  166. package/dist/{chunk-GB5SOYQJ.mjs → chunk-ERLAIBOA.mjs} +2 -2
  167. package/dist/chunk-EURLTOTZ.mjs +4 -0
  168. package/dist/chunk-F4ZA6JRZ.mjs +3 -0
  169. package/dist/chunk-F6HVDZR4.mjs +2 -0
  170. package/dist/chunk-FDMAXMQA.mjs +2 -0
  171. package/dist/chunk-FETSREUN.mjs +5 -0
  172. package/dist/chunk-GHOYKMQ3.mjs +4 -0
  173. package/dist/{chunk-2B5E4CDJ.mjs → chunk-GPIWQ4X4.mjs} +1 -1
  174. package/dist/chunk-HDWTZ763.mjs +12 -0
  175. package/dist/chunk-HPOI4ZX7.mjs +6 -0
  176. package/dist/{chunk-BGGDRNYQ.mjs → chunk-HXG7EOPJ.mjs} +1 -1
  177. package/dist/chunk-IA4PSIMD.mjs +2 -0
  178. package/dist/{chunk-E7LWZRXY.mjs → chunk-ITOH5EGO.mjs} +1 -1
  179. package/dist/chunk-IV64FFI4.mjs +2 -0
  180. package/dist/chunk-J43Z6LSS.mjs +2 -0
  181. package/dist/chunk-J5PUIV3Y.mjs +4 -0
  182. package/dist/chunk-JA7G53PC.mjs +2 -0
  183. package/dist/chunk-JEUK3ZO7.mjs +2 -0
  184. package/dist/chunk-JLTZF4LA.mjs +2 -0
  185. package/dist/chunk-JZT7I2OJ.mjs +2 -0
  186. package/dist/chunk-K5XATEOO.mjs +2 -0
  187. package/dist/chunk-L2SUIS5S.mjs +2 -0
  188. package/dist/chunk-L7UP52JO.mjs +2 -0
  189. package/dist/chunk-LM4XFQHZ.mjs +2 -0
  190. package/dist/chunk-MN7BZL4R.mjs +2 -0
  191. package/dist/chunk-MTYYHM2G.mjs +15 -0
  192. package/dist/chunk-MXUBKDRO.mjs +15 -0
  193. package/dist/chunk-NAMN3RAF.mjs +2 -0
  194. package/dist/{chunk-SYGN7GLU.mjs → chunk-OEXWRJME.mjs} +1 -1
  195. package/dist/chunk-OFHXGWOX.mjs +2 -0
  196. package/dist/chunk-ORID3AE7.mjs +166 -0
  197. package/dist/chunk-PAREWQGB.mjs +4 -0
  198. package/dist/chunk-PGDE24N5.mjs +2 -0
  199. package/dist/chunk-POTA2FV4.mjs +2 -0
  200. package/dist/chunk-PUOQ65NC.mjs +2 -0
  201. package/dist/chunk-Q4UEPUWF.mjs +2 -0
  202. package/dist/chunk-QE5RG76S.mjs +549 -0
  203. package/dist/chunk-R2ZDLJYT.mjs +10 -0
  204. package/dist/{chunk-7DTINW6U.mjs → chunk-SQ6Y2ZMA.mjs} +2 -2
  205. package/dist/chunk-SWUTTZCN.mjs +2 -0
  206. package/dist/chunk-TANZRINB.mjs +2 -0
  207. package/dist/chunk-TR7TWGHB.mjs +2 -0
  208. package/dist/chunk-U5XL7D6A.mjs +3 -0
  209. package/dist/{chunk-XNROSH2T.mjs → chunk-U7NZI6N4.mjs} +2 -2
  210. package/dist/chunk-UGWMMEJ5.mjs +15 -0
  211. package/dist/chunk-UJQJKNGK.mjs +2 -0
  212. package/dist/chunk-UYVCQK3H.mjs +22 -0
  213. package/dist/chunk-VFX2KNHP.mjs +4 -0
  214. package/dist/chunk-VS7JIGJW.mjs +24 -0
  215. package/dist/chunk-W7665ZEC.mjs +6 -0
  216. package/dist/chunk-WQDQWCX5.mjs +2 -0
  217. package/dist/chunk-YI43RG4P.mjs +2 -0
  218. package/dist/chunk-YLPSMDIS.mjs +5 -0
  219. package/dist/chunk-YNAWBAYN.mjs +3 -0
  220. package/dist/chunk-YROX2O22.mjs +2 -0
  221. package/dist/chunk-ZDLPUOAG.mjs +6 -0
  222. package/dist/{chunk-IVDLMMBD.mjs → chunk-ZHEHPMBK.mjs} +1 -1
  223. package/dist/chunk-ZQS6H473.mjs +16 -0
  224. package/dist/chunk-ZTHICSSF.mjs +2 -0
  225. package/dist/chunk-ZWWC4KLF.mjs +20 -0
  226. package/dist/cli.mjs +1 -1
  227. package/dist/server.mjs +1 -1
  228. package/dist/{chunk-U6KNPJPR.mjs → update-fetch.mjs} +1 -1
  229. package/dist/worker.mjs +1 -1
  230. package/kit/board.css +95 -0
  231. package/kit/board.js +250 -0
  232. package/kit/charts.js +5 -71
  233. package/kit/code.js +17 -17
  234. package/kit/report.css +335 -18
  235. package/kit/runtime.js +1638 -125
  236. package/kit/state.js +10 -1
  237. package/kit/tables.js +130 -43
  238. package/kit/ui.js +79 -35
  239. package/package.json +2 -1
  240. package/packs/gallery/card/component.json +14 -0
  241. package/packs/gallery/card/example.html +10 -0
  242. package/packs/gallery/card/preview.svg +1 -0
  243. package/packs/gallery/card/style.css +6 -0
  244. package/packs/gallery/card/template.html +6 -0
  245. package/packs/gallery/card/writing.md +14 -0
  246. package/packs/gallery/chart-card/component.json +15 -0
  247. package/packs/gallery/chart-card/example.html +14 -0
  248. package/packs/gallery/chart-card/kit.js +130 -0
  249. package/packs/gallery/chart-card/preview.svg +1 -0
  250. package/packs/gallery/chart-card/style.css +42 -0
  251. package/packs/gallery/chart-card/template.html +13 -0
  252. package/packs/gallery/chart-card/writing.md +20 -0
  253. package/packs/gallery/chart-view/component.json +20 -0
  254. package/packs/gallery/chart-view/example.html +13 -0
  255. package/packs/gallery/chart-view/kit.js +355 -0
  256. package/packs/gallery/chart-view/preview.svg +1 -0
  257. package/packs/gallery/chart-view/style.css +94 -0
  258. package/packs/gallery/chart-view/template.html +3 -0
  259. package/packs/gallery/chart-view/writing.md +22 -0
  260. package/packs/gallery/countdown/component.json +18 -0
  261. package/packs/gallery/countdown/example.html +3 -0
  262. package/packs/gallery/countdown/kit.js +216 -0
  263. package/packs/gallery/countdown/preview.svg +1 -0
  264. package/packs/gallery/countdown/style.css +118 -0
  265. package/packs/gallery/countdown/template.html +3 -0
  266. package/packs/gallery/countdown/writing.md +22 -0
  267. package/packs/gallery/habit/component.json +14 -0
  268. package/packs/gallery/habit/example.html +3 -0
  269. package/packs/gallery/habit/kit.js +334 -0
  270. package/packs/gallery/habit/preview.svg +1 -0
  271. package/packs/gallery/habit/style.css +174 -0
  272. package/packs/gallery/habit/template.html +3 -0
  273. package/packs/gallery/habit/writing.md +21 -0
  274. package/packs/gallery/heatmap/component.json +18 -0
  275. package/packs/gallery/heatmap/example.html +3 -0
  276. package/packs/gallery/heatmap/kit.js +513 -0
  277. package/packs/gallery/heatmap/preview.svg +1 -0
  278. package/packs/gallery/heatmap/style.css +189 -0
  279. package/packs/gallery/heatmap/template.html +3 -0
  280. package/packs/gallery/heatmap/writing.md +21 -0
  281. package/packs/gallery/kanban/component.json +18 -0
  282. package/packs/gallery/kanban/example.html +12 -0
  283. package/packs/gallery/kanban/kit.js +540 -0
  284. package/packs/gallery/kanban/preview.svg +1 -0
  285. package/packs/gallery/kanban/style.css +212 -0
  286. package/packs/gallery/kanban/template.html +3 -0
  287. package/packs/gallery/kanban/writing.md +20 -0
  288. package/packs/gallery/metric/component.json +22 -0
  289. package/packs/gallery/metric/example.html +15 -0
  290. package/packs/gallery/metric/kit.js +248 -0
  291. package/packs/gallery/metric/preview.svg +1 -0
  292. package/packs/gallery/metric/style.css +92 -0
  293. package/packs/gallery/metric/template.html +3 -0
  294. package/packs/gallery/metric/writing.md +23 -0
  295. package/packs/gallery/note/component.json +14 -0
  296. package/packs/gallery/note/example.html +3 -0
  297. package/packs/gallery/note/kit.js +129 -0
  298. package/packs/gallery/note/preview.svg +1 -0
  299. package/packs/gallery/note/style.css +97 -0
  300. package/packs/gallery/note/template.html +3 -0
  301. package/packs/gallery/note/writing.md +18 -0
  302. package/packs/gallery/pack.json +8 -0
  303. package/packs/gallery/recent/component.json +13 -0
  304. package/packs/gallery/recent/example.html +1 -0
  305. package/packs/gallery/recent/kit.js +293 -0
  306. package/packs/gallery/recent/preview.svg +1 -0
  307. package/packs/gallery/recent/style.css +85 -0
  308. package/packs/gallery/recent/template.html +1 -0
  309. package/packs/gallery/recent/writing.md +15 -0
  310. package/packs/gallery/static/component.json +13 -0
  311. package/packs/gallery/static/example.html +11 -0
  312. package/packs/gallery/static/preview.svg +1 -0
  313. package/packs/gallery/static/style.css +171 -0
  314. package/packs/gallery/static/template.html +1 -0
  315. package/packs/gallery/static/writing.md +18 -0
  316. package/packs/gallery/stats/component.json +13 -0
  317. package/packs/gallery/stats/example.html +1 -0
  318. package/packs/gallery/stats/kit.js +347 -0
  319. package/packs/gallery/stats/preview.svg +1 -0
  320. package/packs/gallery/stats/style.css +73 -0
  321. package/packs/gallery/stats/template.html +1 -0
  322. package/packs/gallery/stats/writing.md +11 -0
  323. package/packs/gallery/today/component.json +12 -0
  324. package/packs/gallery/today/example.html +1 -0
  325. package/packs/gallery/today/kit.js +220 -0
  326. package/packs/gallery/today/preview.svg +1 -0
  327. package/packs/gallery/today/style.css +149 -0
  328. package/packs/gallery/today/template.html +1 -0
  329. package/packs/gallery/today/writing.md +14 -0
  330. package/packs/gallery/todos/component.json +19 -0
  331. package/packs/gallery/todos/example.html +3 -0
  332. package/packs/gallery/todos/kit.js +489 -0
  333. package/packs/gallery/todos/preview.svg +1 -0
  334. package/packs/gallery/todos/style.css +214 -0
  335. package/packs/gallery/todos/template.html +3 -0
  336. package/packs/gallery/todos/writing.md +30 -0
  337. package/packs/gallery/weather/component.json +19 -0
  338. package/packs/gallery/weather/example.html +3 -0
  339. package/packs/gallery/weather/kit.js +387 -0
  340. package/packs/gallery/weather/preview.svg +1 -0
  341. package/packs/gallery/weather/style.css +140 -0
  342. package/packs/gallery/weather/template.html +3 -0
  343. package/packs/gallery/weather/writing.md +26 -0
  344. package/packs/gallery-soft/countdown/component.json +18 -0
  345. package/packs/gallery-soft/countdown/example.html +3 -0
  346. package/packs/gallery-soft/countdown/kit.js +206 -0
  347. package/packs/gallery-soft/countdown/preview.svg +1 -0
  348. package/packs/gallery-soft/countdown/style.css +211 -0
  349. package/packs/gallery-soft/countdown/template.html +3 -0
  350. package/packs/gallery-soft/countdown/writing.md +24 -0
  351. package/packs/gallery-soft/habit/component.json +14 -0
  352. package/packs/gallery-soft/habit/example.html +3 -0
  353. package/packs/gallery-soft/habit/kit.js +366 -0
  354. package/packs/gallery-soft/habit/preview.svg +1 -0
  355. package/packs/gallery-soft/habit/style.css +251 -0
  356. package/packs/gallery-soft/habit/template.html +3 -0
  357. package/packs/gallery-soft/habit/writing.md +23 -0
  358. package/packs/gallery-soft/heatmap/component.json +18 -0
  359. package/packs/gallery-soft/heatmap/example.html +3 -0
  360. package/packs/gallery-soft/heatmap/kit.js +498 -0
  361. package/packs/gallery-soft/heatmap/preview.svg +1 -0
  362. package/packs/gallery-soft/heatmap/style.css +181 -0
  363. package/packs/gallery-soft/heatmap/template.html +3 -0
  364. package/packs/gallery-soft/heatmap/writing.md +23 -0
  365. package/packs/gallery-soft/note/component.json +14 -0
  366. package/packs/gallery-soft/note/example.html +3 -0
  367. package/packs/gallery-soft/note/kit.js +162 -0
  368. package/packs/gallery-soft/note/preview.svg +1 -0
  369. package/packs/gallery-soft/note/style.css +148 -0
  370. package/packs/gallery-soft/note/template.html +3 -0
  371. package/packs/gallery-soft/note/writing.md +20 -0
  372. package/packs/gallery-soft/pack.json +8 -0
  373. package/packs/gallery-soft/recent/component.json +13 -0
  374. package/packs/gallery-soft/recent/example.html +1 -0
  375. package/packs/gallery-soft/recent/kit.js +335 -0
  376. package/packs/gallery-soft/recent/preview.svg +1 -0
  377. package/packs/gallery-soft/recent/style.css +160 -0
  378. package/packs/gallery-soft/recent/template.html +1 -0
  379. package/packs/gallery-soft/recent/writing.md +17 -0
  380. package/packs/gallery-soft/static/component.json +13 -0
  381. package/packs/gallery-soft/static/example.html +12 -0
  382. package/packs/gallery-soft/static/preview.svg +1 -0
  383. package/packs/gallery-soft/static/style.css +186 -0
  384. package/packs/gallery-soft/static/template.html +1 -0
  385. package/packs/gallery-soft/static/writing.md +20 -0
  386. package/packs/gallery-soft/stats/component.json +13 -0
  387. package/packs/gallery-soft/stats/example.html +1 -0
  388. package/packs/gallery-soft/stats/kit.js +341 -0
  389. package/packs/gallery-soft/stats/preview.svg +1 -0
  390. package/packs/gallery-soft/stats/style.css +119 -0
  391. package/packs/gallery-soft/stats/template.html +1 -0
  392. package/packs/gallery-soft/stats/writing.md +13 -0
  393. package/packs/gallery-soft/today/component.json +12 -0
  394. package/packs/gallery-soft/today/example.html +1 -0
  395. package/packs/gallery-soft/today/kit.js +222 -0
  396. package/packs/gallery-soft/today/preview.svg +1 -0
  397. package/packs/gallery-soft/today/style.css +178 -0
  398. package/packs/gallery-soft/today/template.html +1 -0
  399. package/packs/gallery-soft/today/writing.md +16 -0
  400. package/packs/gallery-soft/todos/component.json +19 -0
  401. package/packs/gallery-soft/todos/example.html +3 -0
  402. package/packs/gallery-soft/todos/kit.js +527 -0
  403. package/packs/gallery-soft/todos/preview.svg +1 -0
  404. package/packs/gallery-soft/todos/style.css +212 -0
  405. package/packs/gallery-soft/todos/template.html +3 -0
  406. package/packs/gallery-soft/todos/writing.md +32 -0
  407. package/packs/gallery-soft/weather/component.json +19 -0
  408. package/packs/gallery-soft/weather/example.html +3 -0
  409. package/packs/gallery-soft/weather/kit.js +411 -0
  410. package/packs/gallery-soft/weather/preview.svg +1 -0
  411. package/packs/gallery-soft/weather/style.css +185 -0
  412. package/packs/gallery-soft/weather/template.html +3 -0
  413. package/packs/gallery-soft/weather/writing.md +28 -0
  414. package/release.json +12 -10
  415. package/sdk/doc-kit.d.ts +396 -5
  416. package/sdk/doc-state.d.ts +2 -0
  417. package/skill/SKILL.md +56 -23
  418. package/skill/references/block-script.md +140 -0
  419. package/skill/references/building-blocks.md +257 -0
  420. package/skill/references/extensions.md +59 -0
  421. package/skill/references/pages-and-data.md +225 -0
  422. package/skill/references/writing-html.md +8 -4
  423. package/skill/sdk/doc-kit.d.ts +396 -5
  424. package/skill/sdk/doc-state.d.ts +2 -0
  425. package/web/assets/index-BM_K-Auu.css +1 -0
  426. package/web/assets/index-DRslOBiv.js +15 -0
  427. package/web/index.html +2 -2
  428. package/dist/chunk-3HIRPVLU.mjs +0 -2
  429. package/dist/chunk-5MHMDLZD.mjs +0 -4
  430. package/dist/chunk-64K7IPLO.mjs +0 -255
  431. package/dist/chunk-6QXGZM36.mjs +0 -8
  432. package/dist/chunk-6RGJOMJP.mjs +0 -16
  433. package/dist/chunk-AJ73XJF3.mjs +0 -2
  434. package/dist/chunk-AUZGSZJH.mjs +0 -13
  435. package/dist/chunk-BFE45AKL.mjs +0 -2
  436. package/dist/chunk-BXO2ZY5P.mjs +0 -2
  437. package/dist/chunk-CEH4MRCC.mjs +0 -2
  438. package/dist/chunk-CY2FNNAB.mjs +0 -16
  439. package/dist/chunk-DFUDV4LX.mjs +0 -2
  440. package/dist/chunk-DKXG4XDG.mjs +0 -2
  441. package/dist/chunk-EZQ34M3F.mjs +0 -124
  442. package/dist/chunk-EZY3WC6Z.mjs +0 -15
  443. package/dist/chunk-FUKQNOQS.mjs +0 -9
  444. package/dist/chunk-JPOSLGOC.mjs +0 -6
  445. package/dist/chunk-JVHHHGEA.mjs +0 -3
  446. package/dist/chunk-L3QKH4OK.mjs +0 -26
  447. package/dist/chunk-LAE5NQ4B.mjs +0 -2
  448. package/dist/chunk-LEF6DRCK.mjs +0 -59
  449. package/dist/chunk-NO5NJCHO.mjs +0 -2
  450. package/dist/chunk-NQPVAU63.mjs +0 -2
  451. package/dist/chunk-NSKUTQ5J.mjs +0 -5
  452. package/dist/chunk-O35FIXRB.mjs +0 -2
  453. package/dist/chunk-P2CAZPDP.mjs +0 -3
  454. package/dist/chunk-PL6GHLGD.mjs +0 -15
  455. package/dist/chunk-QJIR2BLP.mjs +0 -6
  456. package/dist/chunk-QUPLVPB2.mjs +0 -7
  457. package/dist/chunk-R7BNENLY.mjs +0 -4
  458. package/dist/chunk-S6O4UHLC.mjs +0 -2
  459. package/dist/chunk-SGJWQKEI.mjs +0 -2
  460. package/dist/chunk-TX6JH7TR.mjs +0 -2
  461. package/dist/chunk-TYK6VNAB.mjs +0 -10
  462. package/dist/chunk-UALRNVSE.mjs +0 -4
  463. package/dist/chunk-V3HXVQEM.mjs +0 -2
  464. package/dist/chunk-V5VXUJKG.mjs +0 -2
  465. package/dist/chunk-VBXMADMP.mjs +0 -2
  466. package/dist/chunk-VNV55RUA.mjs +0 -2
  467. package/dist/chunk-VPD2PS35.mjs +0 -2
  468. package/dist/chunk-W4VKN3GF.mjs +0 -7
  469. package/dist/chunk-W5BXXPDJ.mjs +0 -3
  470. package/dist/chunk-XUNHRCOG.mjs +0 -6
  471. package/skill/references/building-components.md +0 -367
  472. package/web/assets/index-Bh74DfsV.css +0 -1
  473. package/web/assets/index-UW0RyFFt.js +0 -13
@@ -0,0 +1,489 @@
1
+ // gallery/todos (我的待办): the to-dos of the workspace's documents (each item of a to-do list, ul.doc-todo),
2
+ // those not done yet, read through context.workspace.query("todos") (its manifest's needs hold
3
+ // "workspace"), grouped by document, the one edited last first, each group's items in its document's
4
+ // order, each with the headings it stands under. Its box checks the item in its document
5
+ // (context.workspace.setTodo: the server writes that document as the reader's edit, and the home page's
6
+ // undo checks it back), drawn checked at once, put back with a line saying why where the write is refused
7
+ // (the item changed meanwhile, several items alike, one the document's own page cannot check, the document
8
+ // being written, no server); an item checked here stays in the list, struck through, until the page is shown
9
+ // again, so that a slip is undone where it was made, and its group stays where it is (the document the box
10
+ // wrote is the one edited last, which the facts would put first: once a box is checked here the groups keep
11
+ // the order they were drawn in, a document new to the card first). A click on an item's words opens its
12
+ // document there, at the item's block where it has an id, else at the document (context.workspace.open:
13
+ // the workbench goes there); a click on a group's title opens the document. It reads again whenever the
14
+ // workspace says its to-dos changed (the `data` signal, "todos": a to-do added, checked or taken out in any
15
+ // document, a document renamed or gone) and when its settings do (`source`). Its two settings, the card's
16
+ // form (the grip at its top right › 设置…), are kept in its data part `settings`, which the board writes and
17
+ // this block only reads: `document` (a document's slug: its to-dos alone) and `done` (the done ones too,
18
+ // checked and struck through). Where the workspace cannot be read (an exported file, where it has no
19
+ // server; a server that does not answer) it says so; where nothing writes it (an exported file: no
20
+ // setTodo) its boxes are only drawn. The words are the page's language (the UI's where Gallery says it,
21
+ // else the page's lang).
22
+ //
23
+ // Its face (the pack's design B, in the kit's card tokens), laid out by the card's cells (`data-layout`, by
24
+ // context.size, read again on `layout`): a head of the chip (a checked list), 我的待办 and its quiet meta;
25
+ // how many are done of all (of the document asked, or of every one); and the list, grouped under each
26
+ // document's icon and title (small, gray, its open count after it), each item a box, its words and, under
27
+ // them (beside them on a wide card), the headings it stands under, faint, but for the document's own
28
+ // title (its first heading, as often), which the group's says; the list fades at its foot while there is
29
+ // more under it. The share done is drawn by the room: on a 4 × 4 card ("default") a line (已完成 19 / 27,
30
+ // the percent at its end) over a row of ticks, one an item (a bar past 48); on a 4 × 6 ("tall") a ring
31
+ // of the share, its percent in the middle, beside the open count large (8 项没完成) and 已完成 19 / 27; on
32
+ // an 8 × 4 ("wide") a ring at the left over a key (已完成, 未完成, 来自文档). The head's meta says how many are
33
+ // open (8 项; 来自 4 篇文档 on a tall card). The face says by `data-state` what it shows: items, every one
34
+ // done (a full green ring with a tick, 待办都完成了), none, or the workspace not read.
35
+
36
+ const WORDS = {
37
+ zh: {
38
+ title: "我的待办",
39
+ empty: ["还没有待办", "所有文档里的待办会出现在这里", "在文档里输入 [] 就能新建一项"],
40
+ noneIn: ["这篇文档里没有待办", "在文档里输入 [] 就能新建一项"],
41
+ allDone: "待办都完成了",
42
+ allDoneSaid: (/** @type {number} */ all) => `${all} 项,全都勾掉了`,
43
+ offline: ["在 Gallery 里打开时显示", "现在读不到工作区"],
44
+ failed: ["读不到工作区的待办", "过一会儿会再读"],
45
+ open: (/** @type {string} */ title) => `打开「${title}」`,
46
+ path: (/** @type {string[]} */ path) => path.join(" › "),
47
+ check: "标记为完成",
48
+ uncheck: "标记为未完成",
49
+ done: "已完成",
50
+ left: "未完成",
51
+ from: "来自文档",
52
+ progress: (/** @type {number} */ done, /** @type {number} */ all) => ["已完成 ", String(done), ` / ${all}`],
53
+ openUnit: "项没完成",
54
+ share: (/** @type {number} */ done, /** @type {number} */ all) => `${all} 项待办完成了 ${done} 项`,
55
+ openCount: (/** @type {number} */ count) => `${count} 项`,
56
+ all: (/** @type {number} */ count) => `共 ${count} 项`,
57
+ documents: (/** @type {number} */ count) => `来自 ${count} 篇文档`,
58
+ refused: {
59
+ changed: "这一项刚被改过,已重新读取",
60
+ ambiguous: "文档里有几项一样的待办,请在文档里勾选",
61
+ locked: "这一项在文档里是只读的,不能勾选",
62
+ busy: "文档正在被修改,请稍后再勾选",
63
+ offline: "在 Gallery 里打开时才能勾选",
64
+ missing: "找不到这篇文档",
65
+ failed: "没能勾选这一项",
66
+ },
67
+ },
68
+ en: {
69
+ title: "My to-dos",
70
+ empty: ["No to-dos yet", "The to-dos of every document show here", "Type [] in a document to make one"],
71
+ noneIn: ["This document has no to-dos", "Type [] in it to make one"],
72
+ allDone: "Every to-do is done",
73
+ allDoneSaid: (/** @type {number} */ all) => `All ${all} checked off`,
74
+ offline: ["Shown when opened in Gallery", "The workspace cannot be read now"],
75
+ failed: ["The workspace's to-dos could not be read", "It reads them again in a while"],
76
+ open: (/** @type {string} */ title) => `Open “${title}”`,
77
+ path: (/** @type {string[]} */ path) => path.join(" › "),
78
+ check: "Mark as done",
79
+ uncheck: "Mark as not done",
80
+ done: "Done",
81
+ left: "Open",
82
+ from: "Documents",
83
+ progress: (/** @type {number} */ done, /** @type {number} */ all) => ["", String(done), ` of ${all} done`],
84
+ openUnit: "open",
85
+ share: (/** @type {number} */ done, /** @type {number} */ all) => `${done} of ${all} to-dos done`,
86
+ openCount: (/** @type {number} */ count) => `${count} open`,
87
+ all: (/** @type {number} */ count) => `${count} in all`,
88
+ documents: (/** @type {number} */ count) => `from ${count} ${count === 1 ? "document" : "documents"}`,
89
+ refused: {
90
+ changed: "This to-do just changed: read again",
91
+ ambiguous: "The document has several to-dos alike: check it in the document",
92
+ locked: "This to-do is read-only in its document: it cannot be checked",
93
+ busy: "The document is being written: try again in a moment",
94
+ offline: "Open it in Gallery to check it",
95
+ missing: "The document is not there",
96
+ failed: "The to-do could not be checked",
97
+ },
98
+ },
99
+ };
100
+
101
+ /** How long a line saying why a check was refused stays, in ms. */
102
+ const SAID_FOR = 4000;
103
+ /** The most items the ticks draw one each; past them, a bar. */
104
+ const MOST_TICKS = 48;
105
+
106
+ /** The language the page speaks: the UI's where Gallery says it (data-ge-language), else its lang's. */
107
+ function languageOf(/** @type {HTMLElement} */ root) {
108
+ const ui = root.getAttribute("data-ge-language");
109
+ return (ui !== null ? ui === "en" : /^en(?:-|$)/i.test(root.lang)) ? "en" : "zh";
110
+ }
111
+
112
+ /**
113
+ * What the card's settings ask (context.readJSON's, {} where none is set yet): { document, done }, the
114
+ * slug of the one document to read (null: every one) and whether the done ones show too.
115
+ * @param {any} settings
116
+ */
117
+ function askedOf(settings) {
118
+ const table = settings !== null && typeof settings === "object" && !Array.isArray(settings) ? settings : {};
119
+ return { document: typeof table.document === "string" && table.document ? table.document : null, done: table.done === true };
120
+ }
121
+
122
+ /** @typedef {{ ref: DocTodoRef, text: string, done: boolean, slug: string, title: string, icon?: string | null, path: string[] }} Todo */
123
+
124
+ /**
125
+ * An item by its document, its headings and its words: what names it while the card lives, whether it has
126
+ * an id yet or not (its check gives it one).
127
+ * @param {Todo} todo
128
+ */
129
+ const itemKey = (todo) => JSON.stringify([todo.slug, todo.path, todo.text]);
130
+
131
+ /**
132
+ * The to-dos (workspace.query("todos")'s data) as the card shows them, of `asked`: { groups, open,
133
+ * all, documents }, groups [{ slug, title, icon, items }] in the order the documents come (the one edited
134
+ * last first), items those shown (not done, or all with `asked.done`, and the ones checked on this card:
135
+ * `kept`); `open` how many are not done, `all` how many there are of the document asked or of the
136
+ * workspace, `documents` how many documents hold one open. `order` (the slugs as drawn before, or null):
137
+ * the groups keep that order, a document not in it before them.
138
+ * @param {Todo[]} todos
139
+ * @param {{ document: string | null, done: boolean }} asked
140
+ * @param {Set<string>} kept
141
+ * @param {string[] | null} [order]
142
+ */
143
+ function groupsOf(todos, asked, kept, order = null) {
144
+ const mine = todos.filter((todo) => asked.document === null || todo.slug === asked.document);
145
+ /** @type {Map<string, { slug: string, title: string, icon: string | null, items: Todo[] }>} */
146
+ const groups = new Map();
147
+ for (const todo of mine) {
148
+ if (todo.done && !asked.done && !kept.has(itemKey(todo))) continue;
149
+ if (!groups.has(todo.slug)) groups.set(todo.slug, { slug: todo.slug, title: todo.title, icon: todo.icon ?? null, items: [] });
150
+ groups.get(todo.slug)?.items.push(todo);
151
+ }
152
+ const placed = [...groups.values()];
153
+ if (order) placed.sort((a, b) => order.indexOf(a.slug) - order.indexOf(b.slug)); // stable: those not in it keep the order they came in
154
+ return { groups: placed, open: mine.filter((todo) => !todo.done).length, all: mine.length, documents: new Set(mine.filter((todo) => !todo.done).map((todo) => todo.slug)).size };
155
+ }
156
+
157
+ /**
158
+ * What the card says where it shows no item, or null where it shows some: none in the workspace, none in
159
+ * the one document asked, all done.
160
+ * @param {{ groups: unknown[], all: number }} shown
161
+ * @param {{ document: string | null }} asked
162
+ * @param {"zh" | "en"} language
163
+ */
164
+ function emptyLine(shown, asked, language) {
165
+ if (shown.groups.length > 0) return null;
166
+ const words = WORDS[language];
167
+ if (shown.all > 0) return words.allDone;
168
+ return asked.document === null ? words.empty[1] : words.noneIn[0];
169
+ }
170
+
171
+ /** What a document's icon is, as Gallery writes its value: a glyph (/icons/…), a picture of its folder (assets/…), an emoji, or none. @param {string | null | undefined} value */
172
+ function iconKindOf(value) {
173
+ if (typeof value !== "string" || !value) return null;
174
+ if (value.startsWith("/icons/")) return "glyph";
175
+ if (value.startsWith("assets/")) return "image";
176
+ return "emoji";
177
+ }
178
+
179
+ /**
180
+ * An element of the face, of `kind` (its class).
181
+ * @template {keyof HTMLElementTagNameMap} K
182
+ * @param {K} tag
183
+ * @param {string} kind
184
+ * @param {string} [text]
185
+ */
186
+ function made(tag, kind, text) {
187
+ const node = document.createElement(tag);
188
+ node.className = `gallery-todos-${kind}`;
189
+ if (text !== undefined) node.textContent = text;
190
+ return node;
191
+ }
192
+
193
+ // A document's icon, as the sidebar draws it: its picture from the server's icon route, a glyph masked
194
+ // in the muted color, or none (style.css draws a page).
195
+ function iconFor(/** @type {string} */ slug, /** @type {string | null} */ value) {
196
+ const kind = iconKindOf(value);
197
+ const icon = made("span", "icon");
198
+ icon.setAttribute("aria-hidden", "true");
199
+ if (!kind || value === null) return icon;
200
+ const address = `/__gallery/edit/icon?value=${encodeURIComponent(value)}&slug=${encodeURIComponent(slug)}`;
201
+ if (kind === "glyph") {
202
+ icon.classList.add("gallery-todos-glyph");
203
+ icon.style.setProperty("--gallery-todos-icon", `url("${address}")`);
204
+ return icon;
205
+ }
206
+ const picture = document.createElement("img");
207
+ picture.alt = "";
208
+ picture.src = address;
209
+ picture.decoding = "async";
210
+ icon.classList.add("gallery-todos-picture");
211
+ icon.append(picture);
212
+ return icon;
213
+ }
214
+
215
+ const CHIP = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="3.5" y="4" width="6.5" height="6.5" rx="1.8"/><path d="M5.2 7.3l1.3 1.3 2-2.1"/><rect x="3.5" y="13.5" width="6.5" height="6.5" rx="1.8"/><path d="M13.5 7.2h7M13.5 16.8h7"/></svg>';
216
+ const TICK = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5.5 12.5l4 4 9-9"/></svg>';
217
+
218
+ DocKit.component({
219
+ id: "gallery/todos",
220
+ on: ["source", "data", "layout"],
221
+ mount(host, context) {
222
+ const language = languageOf(document.documentElement);
223
+ const words = WORDS[language];
224
+ const face = made("div", "face");
225
+ const head = made("div", "head");
226
+ const count = made("span", "count");
227
+ const chip = made("span", "chip");
228
+ chip.setAttribute("aria-hidden", "true");
229
+ chip.innerHTML = CHIP;
230
+ head.append(chip, made("span", "title", words.title), count);
231
+ // How many are done of all: a line and its ticks, a ring and its percent, the open count large, a key.
232
+ const summary = made("div", "summary");
233
+ summary.hidden = true;
234
+ summary.setAttribute("role", "img");
235
+ const progress = made("p", "progress");
236
+ const progressWords = made("span", "progress-words");
237
+ const sharePercent = made("span", "share");
238
+ progress.append(progressWords, sharePercent);
239
+ const ticks = made("span", "ticks");
240
+ ticks.setAttribute("aria-hidden", "true");
241
+ const ring = made("span", "ring");
242
+ ring.innerHTML = '<svg aria-hidden="true"><circle class="gallery-todos-track"/><circle class="gallery-todos-arc" pathLength="100"/></svg><span class="gallery-todos-percent"></span>';
243
+ const percent = /** @type {HTMLElement} */ (ring.querySelector(".gallery-todos-percent"));
244
+ const big = made("div", "big");
245
+ const bigLine = made("p", "big-line");
246
+ const openNumber = made("span", "open");
247
+ bigLine.append(openNumber, made("span", "open-unit", words.openUnit));
248
+ const bigDone = made("p", "big-done");
249
+ big.append(bigLine, bigDone);
250
+ const key = made("dl", "key");
251
+ const keyRow = (/** @type {string} */ kind, /** @type {string} */ name) => {
252
+ const row = made("div", "key-row");
253
+ row.dataset.kind = kind;
254
+ const value = made("dd", "key-count");
255
+ row.append(made("dt", "key-name", name), value);
256
+ key.append(row);
257
+ return value;
258
+ };
259
+ const doneCount = keyRow("done", words.done);
260
+ const leftCount = keyRow("left", words.left);
261
+ const fromCount = keyRow("from", words.from);
262
+ summary.append(progress, ticks, ring, big, key);
263
+ const list = made("div", "list");
264
+ // Where it shows no item: the cards' empty face (a soft square with the list's picture, or the full ring).
265
+ const empty = made("div", "empty");
266
+ const emptyPicture = made("span", "empty-picture");
267
+ emptyPicture.setAttribute("aria-hidden", "true");
268
+ const line = made("p", "line");
269
+ const hint = made("p", "hint");
270
+ empty.append(emptyPicture, line, hint);
271
+ empty.hidden = true;
272
+ const note = made("p", "note");
273
+ note.hidden = true;
274
+ note.setAttribute("role", "status");
275
+ face.append(head, summary, list, empty, note);
276
+ host.append(face);
277
+ // The list fades at its foot while there is more under it.
278
+ const fade = () => list.toggleAttribute("data-more", list.scrollHeight - list.scrollTop - list.clientHeight > 1);
279
+ list.addEventListener("scroll", fade, { passive: true });
280
+ context.signal?.addEventListener("abort", () => list.removeEventListener("scroll", fade), { once: true });
281
+ const workspace = context.workspace;
282
+ if (!workspace) return void context.fail(new Error("its manifest's needs hold \"workspace\": context.workspace is not there"));
283
+ const open = (/** @type {{ slug: string, block?: string | null }} */ target) => workspace.open(target);
284
+ const setTodo = workspace.setTodo;
285
+ const kept = new Set(); // the items checked on this card, shown until the page is shown again
286
+ /** @type {Todo[] | null} */
287
+ let last = null; // what was read last, as drawn (a check drawn into it at once)
288
+ /** @type {{ document: string | null, done: boolean }} */
289
+ let lastAsked = { document: null, done: false };
290
+ /** @type {string[]} */
291
+ let order = []; // the documents of the groups as drawn
292
+ /** @type {string[] | null} */
293
+ let held = null; // that order as it was when the first box was checked here: the groups keep it from then on
294
+
295
+ const layoutOf = () => {
296
+ const size = context.size;
297
+ return !size ? "default" : size.w >= 8 ? "wide" : size.h >= 6 ? "tall" : "default";
298
+ };
299
+ // A ring of `size` px, its stroke `width` px, the share done (`share`, 0 to 1).
300
+ const drawRing = (/** @type {number} */ size, /** @type {number} */ width, /** @type {number} */ share) => {
301
+ const svg = /** @type {SVGSVGElement} */ (ring.querySelector("svg"));
302
+ svg.setAttribute("viewBox", `0 0 ${size} ${size}`);
303
+ svg.setAttribute("width", String(size));
304
+ svg.setAttribute("height", String(size));
305
+ for (const circle of svg.querySelectorAll("circle")) {
306
+ circle.setAttribute("cx", String(size / 2));
307
+ circle.setAttribute("cy", String(size / 2));
308
+ circle.setAttribute("r", String((size - width) / 2));
309
+ circle.setAttribute("stroke-width", String(width));
310
+ }
311
+ svg.querySelector(".gallery-todos-arc")?.setAttribute("stroke-dasharray", `${Math.max(0, Math.min(1, share)) * 100} 100`);
312
+ };
313
+ // The empty face: its words, and its picture (the list's, or the full green ring with a tick).
314
+ const sayEmpty = (/** @type {string[] | null} */ said, /** @type {"list" | "done"} */ picture = "list") => {
315
+ empty.hidden = said === null;
316
+ list.hidden = said !== null;
317
+ if (said === null) return;
318
+ empty.dataset.picture = picture;
319
+ emptyPicture.innerHTML = picture === "done" ? `<svg viewBox="0 0 72 72"><circle class="gallery-todos-done-ring" cx="36" cy="36" r="32.5"/></svg>${TICK}` : CHIP;
320
+ line.textContent = said[0];
321
+ hint.replaceChildren(...said.slice(1).flatMap((piece, index) => (index === 0 ? [piece] : [document.createElement("br"), piece])));
322
+ };
323
+ let noteTimer = 0;
324
+ const tell = (/** @type {string} */ said) => {
325
+ note.textContent = said;
326
+ note.hidden = false;
327
+ clearTimeout(noteTimer);
328
+ noteTimer = context.timeout(() => { note.hidden = true; }, SAID_FOR);
329
+ };
330
+
331
+ // An item's box checked or cleared: drawn so at once, then written in its document; a refusal puts it
332
+ // back, says why and reads again.
333
+ const check = (/** @type {Todo} */ todo) => {
334
+ if (!setTodo || !last) return;
335
+ const done = !todo.done;
336
+ const drawn = { ...todo, done };
337
+ kept.add(itemKey(todo));
338
+ held ??= order;
339
+ last = last.map((one) => (one === todo ? drawn : one));
340
+ draw();
341
+ setTodo(todo.ref, done).catch((/** @type {any} */ error) => {
342
+ if (context.signal.aborted) return;
343
+ if (last?.includes(drawn)) {
344
+ last = last.map((one) => (one === drawn ? todo : one));
345
+ draw();
346
+ }
347
+ const refused = /** @type {Record<string, string>} */ (words.refused);
348
+ tell(refused[error?.code] ?? refused.failed);
349
+ read();
350
+ });
351
+ };
352
+
353
+ // The list drawn anew of what was read, scrolled where it was.
354
+ const draw = () => {
355
+ const layout = layoutOf();
356
+ face.dataset.layout = layout;
357
+ if (!last) return;
358
+ const asked = lastAsked;
359
+ const shown = groupsOf(last, asked, kept, held);
360
+ order = shown.groups.map((group) => group.slug);
361
+ const top = list.scrollTop;
362
+ const done = shown.all - shown.open;
363
+ const allDone = shown.groups.length === 0 && shown.all > 0;
364
+ count.textContent = shown.all === 0 ? "" : allDone ? words.all(shown.all) : layout === "tall" ? words.documents(shown.documents) : words.openCount(shown.open);
365
+ // The summary of all the to-dos asked (of one document, or of every one), none where there are none.
366
+ summary.hidden = shown.all === 0 || allDone;
367
+ summary.setAttribute("aria-label", words.share(done, shown.all));
368
+ const share = shown.all > 0 ? done / shown.all : 0;
369
+ const whole = shown.all > 0 ? String(Math.floor(100 * share)) : "";
370
+ const [before, middle, after] = words.progress(done, shown.all);
371
+ const bold = document.createElement("b");
372
+ bold.textContent = middle;
373
+ progressWords.replaceChildren(before, bold, after);
374
+ sharePercent.textContent = shown.all > 0 ? `${whole}%` : "";
375
+ const value = made("span", "percent-value", whole);
376
+ value.append(made("span", "percent-sign", "%"));
377
+ percent.replaceChildren(value);
378
+ drawRing(layout === "wide" ? 96 : 64, layout === "wide" ? 9 : 7, share);
379
+ openNumber.textContent = String(shown.open);
380
+ const [doneBefore, doneMiddle, doneAfter] = words.progress(done, shown.all);
381
+ bigDone.textContent = `${doneBefore}${doneMiddle}${doneAfter}`;
382
+ doneCount.textContent = String(done);
383
+ leftCount.textContent = String(shown.open);
384
+ fromCount.textContent = String(shown.documents);
385
+ // A tick an item (done first), or one bar past MOST_TICKS.
386
+ if (shown.all > MOST_TICKS) {
387
+ const on = made("i", "tick");
388
+ on.classList.add("gallery-todos-on");
389
+ on.style.flex = String(done);
390
+ const off = made("i", "tick");
391
+ off.style.flex = String(shown.open);
392
+ ticks.replaceChildren(on, off);
393
+ } else {
394
+ ticks.replaceChildren(...Array.from({ length: shown.all }, (_, index) => {
395
+ const tick = made("i", "tick");
396
+ tick.classList.toggle("gallery-todos-on", index < done);
397
+ return tick;
398
+ }));
399
+ }
400
+ face.dataset.state = shown.groups.length > 0 ? "items" : shown.all > 0 ? "done" : "none";
401
+ list.replaceChildren(...shown.groups.map((group) => {
402
+ const section = made("section", "group");
403
+ const title = made("div", "group-head");
404
+ const doc = made("button", "doc");
405
+ doc.type = "button";
406
+ doc.title = words.open(group.title);
407
+ doc.append(iconFor(group.slug, group.icon), group.title);
408
+ doc.addEventListener("click", () => open({ slug: group.slug }));
409
+ title.append(doc, made("span", "group-count", String(group.items.filter((todo) => !todo.done).length)));
410
+ const items = made("ul", "items");
411
+ for (const todo of group.items) {
412
+ const item = made("li", "item");
413
+ const button = made("button", "todo");
414
+ button.type = "button";
415
+ if (todo.done) {
416
+ button.classList.add("gallery-todos-done");
417
+ item.classList.add("gallery-todos-done");
418
+ }
419
+ button.title = words.open(group.title);
420
+ const text = made("span", "text", todo.text);
421
+ if (setTodo) {
422
+ const box = made("button", "check");
423
+ box.type = "button";
424
+ box.setAttribute("role", "checkbox");
425
+ box.setAttribute("aria-checked", String(todo.done));
426
+ box.title = todo.done ? words.uncheck : words.check;
427
+ box.setAttribute("aria-label", `${todo.done ? words.uncheck : words.check}: ${todo.text}`);
428
+ const square = made("span", "box");
429
+ if (todo.done) square.innerHTML = TICK;
430
+ box.append(square);
431
+ box.addEventListener("click", (event) => {
432
+ event.stopPropagation();
433
+ check(todo);
434
+ });
435
+ item.append(box);
436
+ button.append(text);
437
+ } else {
438
+ const square = made("span", "box");
439
+ if (todo.done) square.innerHTML = TICK;
440
+ item.append(square);
441
+ button.append(text);
442
+ }
443
+ // Its headings, but for the document's title the group's title above says (its first heading, as often).
444
+ const path = todo.path[0] === group.title ? todo.path.slice(1) : todo.path;
445
+ if (path.length > 0) button.append(made("span", "path", words.path(path)));
446
+ button.addEventListener("click", () => open({ slug: todo.ref.slug, block: todo.ref.block }));
447
+ item.append(button);
448
+ items.append(item);
449
+ }
450
+ section.append(title, items);
451
+ return section;
452
+ }));
453
+ list.scrollTop = top;
454
+ if (shown.groups.length > 0) sayEmpty(null);
455
+ else if (shown.all > 0) sayEmpty([words.allDone, words.allDoneSaid(shown.all)], "done");
456
+ else sayEmpty(asked.document === null ? words.empty : words.noneIn);
457
+ fade();
458
+ };
459
+
460
+ let asking = 0; // the last read asked: an older answer that comes after it is dropped
461
+ const read = () => {
462
+ const settings = context.readJSON("settings");
463
+ if (settings === undefined) return; // no JSON: the instance has failed, and Gallery shows what it holds
464
+ const asked = askedOf(settings);
465
+ const ticket = ++asking;
466
+ workspace.query("todos", { limit: 1000, ...(asked.document ? { slugs: [asked.document] } : {}) }).then(({ data }) => {
467
+ if (ticket !== asking || context.signal.aborted) return;
468
+ last = data;
469
+ lastAsked = asked;
470
+ draw();
471
+ }, (/** @type {any} */ error) => {
472
+ if (ticket !== asking || context.signal.aborted) return;
473
+ last = null;
474
+ count.textContent = "";
475
+ summary.hidden = true;
476
+ face.dataset.state = "unread";
477
+ list.replaceChildren();
478
+ sayEmpty(error?.code === "offline" ? words.offline : words.failed);
479
+ });
480
+ };
481
+ read();
482
+ return {
483
+ update(reason, detail) {
484
+ if (reason === "source" || (reason === "data" && detail === "todos")) read();
485
+ else if (reason === "layout") draw();
486
+ },
487
+ };
488
+ },
489
+ });
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 120"><rect width="240" height="120" rx="8" fill="#f3f3f1"/><rect x="60.5" y="6.5" width="119" height="107" rx="8" fill="#ffffff" stroke="#e6e6e3"/><rect x="70" y="14" width="10" height="10" rx="3" fill="#efefed"/><rect x="84" y="16.5" width="30" height="5" rx="2.5" fill="#37352f"/><rect x="118" y="16.5" width="12" height="5" rx="2.5" fill="#d4d3cf"/><rect x="70" y="32" width="34" height="4" rx="2" fill="#a6a5a1"/><rect x="70" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="77.2" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="84.4" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="91.6" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="98.8" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="106" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="113.2" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="120.4" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="127.6" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="134.8" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="142" y="40" width="6" height="3" rx="1.5" fill="#e7e7e5"/><rect x="149.2" y="40" width="6" height="3" rx="1.5" fill="#e7e7e5"/><rect x="156.4" y="40" width="6" height="3" rx="1.5" fill="#e7e7e5"/><rect x="163.60000000000002" y="40" width="6" height="3" rx="1.5" fill="#e7e7e5"/><rect x="70" y="52" width="50" height="4" rx="2" fill="#a6a5a1"/><rect x="70.5" y="62.5" width="7" height="7" rx="2" fill="none" stroke="#bdbcb8"/><rect x="82" y="63" width="56" height="5" rx="2.5" fill="#37352f"/><rect x="82" y="71" width="30" height="3" rx="1.5" fill="#d4d3cf"/><rect x="70.5" y="78.5" width="7" height="7" rx="2" fill="none" stroke="#bdbcb8"/><rect x="82" y="79" width="44" height="5" rx="2.5" fill="#37352f"/><rect x="82" y="87" width="22" height="3" rx="1.5" fill="#d4d3cf"/><rect x="70.5" y="94.5" width="7" height="7" rx="2" fill="#4084cf" stroke="#4084cf"/><rect x="82" y="95" width="50" height="5" rx="2.5" fill="#d4d3cf"/><rect x="82" y="103" width="26" height="3" rx="1.5" fill="#d4d3cf"/></svg>