@heycys/gallery 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD-PARTY-NOTICES.md +51 -1
- package/browser/editor/components/callout/index.mjs +40 -15
- package/browser/editor/components/columns/page.mjs +45 -32
- package/browser/editor/components/details/index.mjs +2 -1
- package/browser/editor/components/dialog/index.mjs +2 -1
- package/browser/editor/components/dialog/page.mjs +0 -18
- package/browser/editor/components/divider/index.mjs +1 -1
- package/browser/editor/components/embed/index.mjs +2 -2
- package/browser/editor/components/figure/page.mjs +10 -1
- package/browser/editor/components/file/page.mjs +2 -2
- package/browser/editor/components/flowchart/add.mjs +7 -6
- package/browser/editor/components/flowchart/page.mjs +1 -1
- package/browser/editor/components/heading/index.mjs +2 -0
- package/browser/editor/components/heading/page.mjs +6 -0
- package/browser/editor/components/highlight/index.mjs +4 -20
- package/browser/editor/components/icons.mjs +13 -2
- package/browser/editor/components/image/crop.mjs +6 -9
- package/browser/editor/components/image/page.mjs +2 -2
- package/browser/editor/components/installed/index.mjs +82 -29
- package/browser/editor/components/installed/page.mjs +146 -34
- package/browser/editor/components/installed/served.mjs +6 -5
- package/browser/editor/components/instances.mjs +18 -0
- package/browser/editor/components/kit.mjs +3 -0
- package/browser/editor/components/list/page.mjs +3 -6
- package/browser/editor/components/media/page.mjs +44 -14
- package/browser/editor/components/pages.mjs +2 -2
- package/browser/editor/components/registry.mjs +68 -33
- package/browser/editor/components/section/index.mjs +2 -1
- package/browser/editor/components/set-apart.mjs +24 -0
- package/browser/editor/components/table/index.mjs +64 -5
- package/browser/editor/components/table/page.mjs +30 -19
- package/browser/editor/page/annotate/anchors.mjs +4 -3
- package/browser/editor/page/annotate/card.mjs +3 -6
- package/browser/editor/page/annotate/index.mjs +61 -34
- package/browser/editor/page/autosave.mjs +357 -38
- package/browser/editor/page/beside.mjs +5 -5
- package/browser/editor/page/block-menu/colors.mjs +3 -1
- package/browser/editor/page/block-menu/index.mjs +8 -6
- package/browser/editor/page/blocks.mjs +16 -7
- package/browser/editor/page/board/client.mjs +57 -0
- package/browser/editor/page/board/hint.mjs +145 -0
- package/browser/editor/page/board/history.mjs +119 -0
- package/browser/editor/page/board/index.mjs +970 -0
- package/browser/editor/page/board/settings.mjs +209 -0
- package/browser/editor/page/caret.mjs +5 -2
- package/browser/editor/page/changes/bar.mjs +94 -0
- package/browser/editor/page/changes/ghost.mjs +206 -0
- package/browser/editor/page/changes/gone-words.mjs +94 -0
- package/browser/editor/page/changes/index.mjs +447 -0
- package/browser/editor/page/changes/words.mjs +27 -0
- package/browser/editor/page/clipboard/import/colors.mjs +3 -3
- package/browser/editor/page/clipboard/import/html.mjs +29 -6
- package/browser/editor/page/clipboard/import/inline.mjs +32 -0
- package/browser/editor/page/clipboard/import/markdown.mjs +58 -13
- package/browser/editor/page/clipboard/import/read.mjs +6 -1
- package/browser/editor/page/clipboard/import/to-blocks.mjs +44 -12
- package/browser/editor/page/clipboard/import/yuque.mjs +622 -0
- package/browser/editor/page/clipboard/index.mjs +156 -26
- package/browser/editor/page/clipboard/own/blocks.mjs +25 -16
- package/browser/editor/page/clipboard/own/chart-keys.mjs +41 -28
- package/browser/editor/page/clipboard/own/describe.mjs +16 -7
- package/browser/editor/page/clipboard/own/export.mjs +6 -6
- package/browser/editor/page/clipboard/own/selection.mjs +3 -3
- package/browser/editor/page/clipboard/own/writers.mjs +0 -11
- package/browser/editor/page/columns/index.mjs +48 -46
- package/browser/editor/page/commit.mjs +98 -25
- package/browser/editor/page/conflicts.mjs +13 -33
- package/browser/editor/page/convert.mjs +8 -7
- package/browser/editor/page/core.mjs +81 -27
- package/browser/editor/page/custom-page.mjs +106 -0
- package/browser/editor/page/drag/index.mjs +40 -24
- package/browser/editor/page/drag/preview.mjs +9 -4
- package/browser/editor/page/editor.mjs +120 -28
- package/browser/editor/page/emoji-picker/emoji-tab.mjs +22 -13
- package/browser/editor/page/emoji-picker/grid.mjs +7 -5
- package/browser/editor/page/emoji-picker/icon-tab.mjs +4 -4
- package/browser/editor/page/emoji-picker/icons.mjs +0 -1
- package/browser/editor/page/emoji-picker/index.mjs +11 -9
- package/browser/editor/page/emoji-picker/styles.mjs +156 -2
- package/browser/editor/page/emoji-picker/support.mjs +6 -4
- package/browser/editor/page/emoji-picker/upload.mjs +14 -13
- package/browser/editor/page/fills.mjs +5 -3
- package/browser/editor/page/fold/index.mjs +348 -0
- package/browser/editor/page/fold/rule.mjs +125 -0
- package/browser/editor/page/folded.mjs +23 -0
- package/browser/editor/page/format-bar/bar.mjs +2 -1
- package/browser/editor/page/format-bar/index.mjs +1 -1
- package/browser/editor/page/geometry.mjs +8 -6
- package/browser/editor/page/handle/index.mjs +22 -14
- package/browser/editor/page/hints/index.mjs +1 -1
- package/browser/editor/page/history.mjs +24 -4
- package/browser/editor/page/insert/index.mjs +30 -17
- package/browser/editor/page/links/index.mjs +5 -3
- package/browser/editor/page/links/pages.mjs +27 -9
- package/browser/editor/page/long-runs.mjs +75 -0
- package/browser/editor/page/look.mjs +69 -6
- package/browser/editor/page/margin.mjs +63 -27
- package/browser/editor/page/media-menu/index.mjs +6 -7
- package/browser/editor/page/menu.mjs +86 -31
- package/browser/editor/page/merge.mjs +24 -0
- package/browser/editor/page/notices.mjs +3 -3
- package/browser/editor/page/offered.mjs +1 -1
- package/browser/editor/page/outline/folds.mjs +11 -10
- package/browser/editor/page/outline/index.mjs +131 -45
- package/browser/editor/page/outline/list.mjs +23 -11
- package/browser/editor/page/outline/read.mjs +1 -1
- package/browser/editor/page/outline/strip.mjs +7 -1
- package/browser/editor/page/page-objects.mjs +13 -2
- package/browser/editor/page/panel.mjs +9 -13
- package/browser/editor/page/present-links.mjs +11 -2
- package/browser/editor/page/resize/index.mjs +42 -29
- package/browser/editor/page/selection/delete.mjs +8 -6
- package/browser/editor/page/selection/index.mjs +10 -3
- package/browser/editor/page/served.mjs +14 -0
- package/browser/editor/page/session.mjs +101 -6
- package/browser/editor/page/slash-menu/index.mjs +3 -3
- package/browser/editor/page/table/cell-bar.mjs +4 -1
- package/browser/editor/page/table/cells.mjs +103 -47
- package/browser/editor/page/table/icons.mjs +3 -1
- package/browser/editor/page/table/index.mjs +40 -16
- package/browser/editor/page/table/pictures.mjs +299 -0
- package/browser/editor/page/table/views.mjs +150 -0
- package/browser/editor/page/table/widths.mjs +9 -4
- package/browser/editor/page/text-select/index.mjs +43 -14
- package/browser/editor/page/todo-writes.mjs +75 -0
- package/browser/editor/page/tooltip.mjs +1 -1
- package/browser/editor/page/type-grid.mjs +4 -3
- package/browser/editor/page/typing/code-edges.mjs +63 -17
- package/browser/editor/page/typing/index.mjs +65 -9
- package/browser/editor/page/typing/leave.mjs +1 -1
- package/browser/editor/page/ui.mjs +13 -0
- package/browser/shared/annotations.mjs +8 -10
- package/browser/shared/block-packs.mjs +404 -0
- package/browser/shared/board-places.mjs +224 -0
- package/browser/shared/card-size.mjs +59 -0
- package/browser/shared/code-folds.mjs +5 -1
- package/browser/shared/colors.mjs +17 -14
- package/browser/shared/component-catalog.mjs +345 -54
- package/browser/shared/component-source.mjs +37 -0
- package/browser/shared/components/callout.mjs +4 -2
- package/browser/shared/components/index.mjs +72 -9
- package/browser/shared/components/installed.mjs +110 -8
- package/browser/shared/components/page.mjs +22 -3
- package/browser/shared/components/state.mjs +5 -1
- package/browser/shared/components/table.mjs +1 -1
- package/browser/shared/components/text.mjs +2 -2
- package/browser/shared/document-look.mjs +183 -0
- package/browser/shared/drafts.mjs +432 -0
- package/browser/shared/emoji/data/LICENSE-lucide.txt +43 -0
- package/browser/shared/emoji/data/README.md +4 -2
- package/browser/shared/emoji/data/categories.json +1 -1
- package/browser/shared/emoji/data/keywords-en.json +1 -1
- package/browser/shared/emoji/data/keywords-zh.json +1 -1
- package/browser/shared/emoji/data/names.json +1 -1
- package/browser/shared/emoji/data/positions.json +1 -1
- package/browser/shared/emoji/data/twemoji-index.json +1 -1
- package/browser/shared/emoji/data/twemoji-svg.bin +0 -0
- package/browser/shared/emoji/data.mjs +10 -12
- package/browser/shared/emoji/emoji.mjs +8 -7
- package/browser/shared/emoji/icon-value.mjs +4 -3
- package/browser/shared/extension-sidebar.mjs +126 -0
- package/browser/shared/extensions.mjs +79 -0
- package/browser/shared/file-table.mjs +101 -0
- package/browser/shared/html-tree.mjs +11 -5
- package/browser/shared/i18n/en.mjs +374 -35
- package/browser/shared/json-layout.mjs +47 -0
- package/browser/shared/long-runs.mjs +39 -0
- package/browser/shared/net-cache.mjs +133 -0
- package/browser/shared/net-keys.mjs +32 -0
- package/browser/shared/net-policy.mjs +177 -0
- package/browser/shared/new-names.mjs +5 -2
- package/browser/shared/outline-shape.mjs +128 -0
- package/browser/shared/outline.mjs +458 -0
- package/browser/shared/pack-manifest.mjs +77 -0
- package/browser/shared/page-address.mjs +6 -3
- package/browser/shared/page-cards.mjs +308 -0
- package/browser/shared/page-links.mjs +69 -6
- package/browser/shared/pages.mjs +388 -0
- package/browser/shared/paths.mjs +6 -0
- package/browser/shared/preferences.mjs +10 -4
- package/browser/shared/preview-server.mjs +3 -7
- package/browser/shared/session.mjs +13 -5
- package/browser/shared/shipped-blocks.mjs +299 -0
- package/browser/shared/table-chart.mjs +33 -1
- package/browser/shared/todos.mjs +83 -0
- package/browser/shared/user-directory.mjs +24 -0
- package/browser/shared/versions.mjs +14 -0
- package/browser/shared/web-links.mjs +134 -0
- package/browser/shared/workspace-columns.mjs +120 -0
- package/browser/shared/workspace-look.mjs +91 -0
- package/browser/shared/workspace-name.mjs +154 -0
- package/browser/shared/workspace-query.mjs +125 -0
- package/browser/shared/workspace-registry.mjs +272 -0
- package/browser/shared/workspace.mjs +171 -20
- package/browser/shared/zoom.mjs +5 -5
- package/dist/chunk-2NRBY6AJ.mjs +2 -0
- package/dist/chunk-32ZUEFZ7.mjs +2 -0
- package/dist/chunk-35NQ4PLQ.mjs +2 -0
- package/dist/chunk-3KJHLHUO.mjs +2 -0
- package/dist/chunk-3NJACR4W.mjs +2 -0
- package/dist/chunk-4AV456RQ.mjs +2 -0
- package/dist/chunk-4OZWXZE5.mjs +5 -0
- package/dist/chunk-5XYHDBJ5.mjs +2 -0
- package/dist/chunk-5ZJA7CXT.mjs +2 -0
- package/dist/chunk-6A53MZYZ.mjs +2 -0
- package/dist/chunk-6EXH3ORZ.mjs +166 -0
- package/dist/chunk-6EZ7FNIK.mjs +3 -0
- package/dist/{chunk-UXUK4PMC.mjs → chunk-6QBHU4DF.mjs} +1 -1
- package/dist/{chunk-6U2SLSDN.mjs → chunk-6VTU6KEO.mjs} +1 -1
- package/dist/chunk-B4P2CM2J.mjs +3 -0
- package/dist/chunk-BPL64HGA.mjs +4 -0
- package/dist/chunk-BVEFGE4B.mjs +2 -0
- package/dist/chunk-BZ5RAF7L.mjs +2 -0
- package/dist/chunk-CRJEG7MT.mjs +2 -0
- package/dist/{chunk-B3VTYBYR.mjs → chunk-D4CKRD3V.mjs} +91 -91
- package/dist/chunk-D4EURAX4.mjs +4 -0
- package/dist/chunk-DQCE7TJY.mjs +5 -0
- package/dist/chunk-DR73Y2UJ.mjs +3 -0
- package/dist/{chunk-TMYZB6AV.mjs → chunk-EKNHM3P4.mjs} +1 -1
- package/dist/{chunk-DB4WKGYF.mjs → chunk-ERLAIBOA.mjs} +2 -2
- package/dist/chunk-EURLTOTZ.mjs +4 -0
- package/dist/chunk-FJYN7RTH.mjs +4 -0
- package/dist/chunk-FWNRPMCJ.mjs +12 -0
- package/dist/chunk-FWW4CSAZ.mjs +2 -0
- package/dist/{chunk-2B5E4CDJ.mjs → chunk-GPIWQ4X4.mjs} +1 -1
- package/dist/chunk-GY3FAUVM.mjs +2 -0
- package/dist/chunk-HLYV7RIH.mjs +2 -0
- package/dist/chunk-HMYTM3GT.mjs +15 -0
- package/dist/chunk-IA4PSIMD.mjs +2 -0
- package/dist/chunk-JEUK3ZO7.mjs +2 -0
- package/dist/chunk-JVHHHGEA.mjs +3 -0
- package/dist/chunk-KTKHRC6H.mjs +2 -0
- package/dist/chunk-L7UP52JO.mjs +2 -0
- package/dist/chunk-MHW7ZKOU.mjs +2 -0
- package/dist/chunk-N76HWBA3.mjs +10 -0
- package/dist/chunk-N7AZZLGT.mjs +548 -0
- package/dist/chunk-NAMN3RAF.mjs +2 -0
- package/dist/{chunk-YXAUQPVK.mjs → chunk-NFMCP2HI.mjs} +3 -3
- package/dist/chunk-NG375ILQ.mjs +2 -0
- package/dist/chunk-NVRNLK25.mjs +6 -0
- package/dist/chunk-NWFBE2YA.mjs +2 -0
- package/dist/chunk-NWR2LT5B.mjs +2 -0
- package/dist/chunk-OJKMINIU.mjs +20 -0
- package/dist/chunk-OUUP3WKT.mjs +2 -0
- package/dist/chunk-OW5NWPOJ.mjs +10 -0
- package/dist/chunk-PAREWQGB.mjs +4 -0
- package/dist/chunk-POQSE4C2.mjs +2 -0
- package/dist/chunk-PUOQ65NC.mjs +2 -0
- package/dist/{chunk-Z52HTUW7.mjs → chunk-PVER7LSC.mjs} +2 -2
- package/dist/chunk-PZDLJJTJ.mjs +3 -0
- package/dist/chunk-Q47PLKIJ.mjs +15 -0
- package/dist/chunk-Q4UEPUWF.mjs +2 -0
- package/dist/chunk-QKXMPUXC.mjs +2 -0
- package/dist/chunk-QOUEFUCH.mjs +16 -0
- package/dist/chunk-RFDZXFJF.mjs +13 -0
- package/dist/chunk-RKPWLGZ3.mjs +4 -0
- package/dist/chunk-RMECZA2K.mjs +2 -0
- package/dist/{chunk-EUX7IC5J.mjs → chunk-SQ6Y2ZMA.mjs} +2 -2
- package/dist/chunk-SX4LJYT6.mjs +8 -0
- package/dist/chunk-SXHBYZST.mjs +16 -0
- package/dist/chunk-TANZRINB.mjs +2 -0
- package/dist/chunk-TEZAWDSQ.mjs +2 -0
- package/dist/chunk-UBBRTJ2R.mjs +24 -0
- package/dist/chunk-UFNYFFKO.mjs +20 -0
- package/dist/chunk-UGWYKHBL.mjs +170 -0
- package/dist/chunk-UKSHDZZ6.mjs +2 -0
- package/dist/chunk-UMHUSOPJ.mjs +2 -0
- package/dist/chunk-UNOYVIYR.mjs +2 -0
- package/dist/chunk-V6RIYQZZ.mjs +4 -0
- package/dist/chunk-VJPFVNNW.mjs +15 -0
- package/dist/chunk-VS3ZMVGX.mjs +5 -0
- package/dist/chunk-VTKNEYT3.mjs +6 -0
- package/dist/chunk-VXACTLO3.mjs +3 -0
- package/dist/chunk-W3BGBJQW.mjs +2 -0
- package/dist/chunk-YI43RG4P.mjs +2 -0
- package/dist/chunk-YQGT4AB2.mjs +6 -0
- package/dist/chunk-ZB4H7ZN4.mjs +2 -0
- package/dist/{chunk-ACOPDCNB.mjs → chunk-ZHEHPMBK.mjs} +1 -1
- package/dist/chunk-ZTHICSSF.mjs +2 -0
- package/dist/chunk-ZUNVAXLH.mjs +2 -0
- package/dist/chunk-ZWPMCK7P.mjs +2 -0
- package/dist/cli.mjs +1 -1
- package/dist/server.mjs +1 -1
- package/dist/{chunk-EVJ3BX3M.mjs → update-fetch.mjs} +1 -1
- package/dist/worker.mjs +1 -1
- package/kit/board.css +95 -0
- package/kit/board.js +250 -0
- package/kit/charts.js +5 -71
- package/kit/code.js +14 -14
- package/kit/math.js +18 -2
- package/kit/report.css +500 -151
- package/kit/runtime.js +1720 -170
- package/kit/state.js +10 -1
- package/kit/tables.js +172 -37
- package/kit/ui.js +166 -27
- package/package.json +2 -1
- package/packs/gallery/card/component.json +14 -0
- package/packs/gallery/card/example.html +10 -0
- package/packs/gallery/card/preview.svg +1 -0
- package/packs/gallery/card/style.css +6 -0
- package/packs/gallery/card/template.html +6 -0
- package/packs/gallery/card/writing.md +14 -0
- package/packs/gallery/chart-card/component.json +15 -0
- package/packs/gallery/chart-card/example.html +14 -0
- package/packs/gallery/chart-card/kit.js +130 -0
- package/packs/gallery/chart-card/preview.svg +1 -0
- package/packs/gallery/chart-card/style.css +42 -0
- package/packs/gallery/chart-card/template.html +13 -0
- package/packs/gallery/chart-card/writing.md +20 -0
- package/packs/gallery/chart-view/component.json +20 -0
- package/packs/gallery/chart-view/example.html +13 -0
- package/packs/gallery/chart-view/kit.js +355 -0
- package/packs/gallery/chart-view/preview.svg +1 -0
- package/packs/gallery/chart-view/style.css +94 -0
- package/packs/gallery/chart-view/template.html +3 -0
- package/packs/gallery/chart-view/writing.md +22 -0
- package/packs/gallery/countdown/component.json +18 -0
- package/packs/gallery/countdown/example.html +3 -0
- package/packs/gallery/countdown/kit.js +156 -0
- package/packs/gallery/countdown/preview.svg +1 -0
- package/packs/gallery/countdown/style.css +130 -0
- package/packs/gallery/countdown/template.html +3 -0
- package/packs/gallery/countdown/writing.md +22 -0
- package/packs/gallery/habit/component.json +14 -0
- package/packs/gallery/habit/example.html +3 -0
- package/packs/gallery/habit/kit.js +295 -0
- package/packs/gallery/habit/preview.svg +1 -0
- package/packs/gallery/habit/style.css +246 -0
- package/packs/gallery/habit/template.html +3 -0
- package/packs/gallery/habit/writing.md +21 -0
- package/packs/gallery/heatmap/component.json +18 -0
- package/packs/gallery/heatmap/example.html +3 -0
- package/packs/gallery/heatmap/kit.js +351 -0
- package/packs/gallery/heatmap/preview.svg +1 -0
- package/packs/gallery/heatmap/style.css +201 -0
- package/packs/gallery/heatmap/template.html +3 -0
- package/packs/gallery/heatmap/writing.md +21 -0
- package/packs/gallery/kanban/component.json +18 -0
- package/packs/gallery/kanban/example.html +12 -0
- package/packs/gallery/kanban/kit.js +540 -0
- package/packs/gallery/kanban/preview.svg +1 -0
- package/packs/gallery/kanban/style.css +212 -0
- package/packs/gallery/kanban/template.html +3 -0
- package/packs/gallery/kanban/writing.md +20 -0
- package/packs/gallery/metric/component.json +22 -0
- package/packs/gallery/metric/example.html +15 -0
- package/packs/gallery/metric/kit.js +248 -0
- package/packs/gallery/metric/preview.svg +1 -0
- package/packs/gallery/metric/style.css +92 -0
- package/packs/gallery/metric/template.html +3 -0
- package/packs/gallery/metric/writing.md +23 -0
- package/packs/gallery/note/component.json +14 -0
- package/packs/gallery/note/example.html +3 -0
- package/packs/gallery/note/kit.js +102 -0
- package/packs/gallery/note/preview.svg +1 -0
- package/packs/gallery/note/style.css +76 -0
- package/packs/gallery/note/template.html +3 -0
- package/packs/gallery/note/writing.md +18 -0
- package/packs/gallery/pack.json +8 -0
- package/packs/gallery/recent/component.json +13 -0
- package/packs/gallery/recent/example.html +1 -0
- package/packs/gallery/recent/kit.js +238 -0
- package/packs/gallery/recent/preview.svg +1 -0
- package/packs/gallery/recent/style.css +158 -0
- package/packs/gallery/recent/template.html +1 -0
- package/packs/gallery/recent/writing.md +15 -0
- package/packs/gallery/static/component.json +13 -0
- package/packs/gallery/static/example.html +11 -0
- package/packs/gallery/static/preview.svg +1 -0
- package/packs/gallery/static/style.css +138 -0
- package/packs/gallery/static/template.html +1 -0
- package/packs/gallery/static/writing.md +18 -0
- package/packs/gallery/stats/component.json +13 -0
- package/packs/gallery/stats/example.html +1 -0
- package/packs/gallery/stats/kit.js +166 -0
- package/packs/gallery/stats/preview.svg +1 -0
- package/packs/gallery/stats/style.css +151 -0
- package/packs/gallery/stats/template.html +1 -0
- package/packs/gallery/stats/writing.md +11 -0
- package/packs/gallery/today/component.json +12 -0
- package/packs/gallery/today/example.html +1 -0
- package/packs/gallery/today/kit.js +185 -0
- package/packs/gallery/today/preview.svg +1 -0
- package/packs/gallery/today/style.css +120 -0
- package/packs/gallery/today/template.html +1 -0
- package/packs/gallery/today/writing.md +14 -0
- package/packs/gallery/todos/component.json +19 -0
- package/packs/gallery/todos/example.html +3 -0
- package/packs/gallery/todos/kit.js +342 -0
- package/packs/gallery/todos/preview.svg +1 -0
- package/packs/gallery/todos/style.css +267 -0
- package/packs/gallery/todos/template.html +3 -0
- package/packs/gallery/todos/writing.md +30 -0
- package/packs/gallery/weather/component.json +19 -0
- package/packs/gallery/weather/example.html +3 -0
- package/packs/gallery/weather/kit.js +312 -0
- package/packs/gallery/weather/preview.svg +1 -0
- package/packs/gallery/weather/style.css +258 -0
- package/packs/gallery/weather/template.html +3 -0
- package/packs/gallery/weather/writing.md +26 -0
- package/packs/gallery-soft/pack.json +8 -0
- package/release.json +13 -11
- package/sdk/doc-kit.d.ts +404 -7
- package/sdk/doc-state.d.ts +2 -0
- package/skill/SKILL.md +71 -26
- package/skill/references/block-script.md +140 -0
- package/skill/references/building-blocks.md +257 -0
- package/skill/references/example-report.html +1 -1
- package/skill/references/extensions.md +59 -0
- package/skill/references/pages-and-data.md +221 -0
- package/skill/references/writing-html.md +9 -7
- package/skill/sdk/doc-kit.d.ts +404 -7
- package/skill/sdk/doc-state.d.ts +2 -0
- package/web/assets/index-BK2e_07w.js +13 -0
- package/web/assets/index-CWFI83mF.css +1 -0
- package/web/index.html +2 -2
- package/browser/editor/components/callout/page.mjs +0 -13
- package/dist/chunk-2PBALTR3.mjs +0 -57
- package/dist/chunk-3LA3EMDE.mjs +0 -15
- package/dist/chunk-5FRMCDPY.mjs +0 -16
- package/dist/chunk-5LEK2CBS.mjs +0 -2
- package/dist/chunk-5OFN5AHC.mjs +0 -2
- package/dist/chunk-5SIYS5HN.mjs +0 -2
- package/dist/chunk-5TEK3RAD.mjs +0 -2
- package/dist/chunk-6CYG3Z4V.mjs +0 -2
- package/dist/chunk-7GHT2UCA.mjs +0 -15
- package/dist/chunk-7QQBR7PB.mjs +0 -2
- package/dist/chunk-ATCJYAR4.mjs +0 -2
- package/dist/chunk-C7HWOBIF.mjs +0 -2
- package/dist/chunk-E7VYDG2X.mjs +0 -2
- package/dist/chunk-EZY3WC6Z.mjs +0 -15
- package/dist/chunk-FQGQH4KM.mjs +0 -2
- package/dist/chunk-G7TOXONE.mjs +0 -6
- package/dist/chunk-GPF4YWWB.mjs +0 -9
- package/dist/chunk-GYQV7Y4J.mjs +0 -120
- package/dist/chunk-HMHK3EQ6.mjs +0 -2
- package/dist/chunk-HQQMJCQJ.mjs +0 -10
- package/dist/chunk-IERUOGC3.mjs +0 -6
- package/dist/chunk-ITNLYXXV.mjs +0 -3
- package/dist/chunk-L4DVONOG.mjs +0 -2
- package/dist/chunk-LAE5NQ4B.mjs +0 -2
- package/dist/chunk-LC7YNQFG.mjs +0 -2
- package/dist/chunk-LHTFLRB6.mjs +0 -4
- package/dist/chunk-NFIBI4IP.mjs +0 -26
- package/dist/chunk-NSKUTQ5J.mjs +0 -5
- package/dist/chunk-O52JMOCZ.mjs +0 -2
- package/dist/chunk-P2CAZPDP.mjs +0 -3
- package/dist/chunk-QMQUXTU4.mjs +0 -12
- package/dist/chunk-QVWVFC5K.mjs +0 -6
- package/dist/chunk-QYKCJ7FG.mjs +0 -8
- package/dist/chunk-QZY6Q64C.mjs +0 -2
- package/dist/chunk-TDQP3DKQ.mjs +0 -10
- package/dist/chunk-TX6JH7TR.mjs +0 -2
- package/dist/chunk-UNUEWH4S.mjs +0 -2
- package/dist/chunk-V4CPWKMZ.mjs +0 -2
- package/dist/chunk-VACRB2NE.mjs +0 -3
- package/dist/chunk-W63L7367.mjs +0 -7
- package/dist/chunk-W7CXPCRV.mjs +0 -6
- package/dist/chunk-XINNG4F2.mjs +0 -4
- package/dist/chunk-YL2DPWVS.mjs +0 -4
- package/dist/chunk-YZ5Z6H4W.mjs +0 -4
- package/dist/chunk-ZBIM6ARY.mjs +0 -216
- package/skill/references/building-components.md +0 -327
- package/web/assets/index-B6Ai3wsa.js +0 -13
- package/web/assets/index-SYPC3EZy.css +0 -1
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
// gallery/chart-view (图表): a view of a table of the document (its manifest's needs hold "tables"; the
|
|
2
|
+
// table's frame carries the key its data-doc-from names, which the table's 视图 › puts on both), drawn as
|
|
3
|
+
// horizontal bars from zero, each with its value at its end, under its title. Its settings (its data part
|
|
4
|
+
// `settings`, JSON) say what: `by` a column whose values are the bars (the rows grouped by it, in the order
|
|
5
|
+
// the rows first say them), each the `op` of its rows, "count" (how many), "sum" or "average" of the
|
|
6
|
+
// numbers of the column `value`; with no `by` a bar for each row, its first cell its name and its number
|
|
7
|
+
// in `value`. Left out: `by` the column that reads as a status or whose words repeat (none: a bar a row),
|
|
8
|
+
// `value` the first column of numbers, `op` "sum" where there is one, else "count"; `title` one made of
|
|
9
|
+
// the rest. At most MAX_BARS bars, a line saying how many more.
|
|
10
|
+
//
|
|
11
|
+
// It reads the table each time its rows change (the `data` signal), and draws only what changed: a bar
|
|
12
|
+
// is kept by its group's value (or its row's element) and its label, its value and its length written
|
|
13
|
+
// only where they changed, so that typing in a table of 500 rows moves one bar. Its ⚙, at its head while
|
|
14
|
+
// the page edits, opens its settings, each change one undo step of the document's (context.editJSON); it
|
|
15
|
+
// writes nothing else. The colors are the kit's series colors, which follow the theme. The words are the
|
|
16
|
+
// page's language.
|
|
17
|
+
|
|
18
|
+
const WORDS = {
|
|
19
|
+
zh: {
|
|
20
|
+
settings: "设置",
|
|
21
|
+
by: "分组依据",
|
|
22
|
+
each: "每行一条",
|
|
23
|
+
op: "计算",
|
|
24
|
+
ops: { count: "计数", sum: "合计", average: "平均" },
|
|
25
|
+
value: "数值列",
|
|
26
|
+
title: "标题",
|
|
27
|
+
none: "(空)",
|
|
28
|
+
rows: (/** @type {string} */ by) => `各${by}的行数`,
|
|
29
|
+
sum: (/** @type {string} */ by, /** @type {string} */ value) => `各${by}的${value}合计`,
|
|
30
|
+
average: (/** @type {string} */ by, /** @type {string} */ value) => `各${by}的${value}平均`,
|
|
31
|
+
each_: (/** @type {string} */ name, /** @type {string} */ value) => `各${name}的${value}`,
|
|
32
|
+
more: (/** @type {number} */ shown, /** @type {number} */ all) => `只画了前 ${shown} 条,共 ${all} 条:按一列分组可以都画出来。`,
|
|
33
|
+
unbound: "这张图还没有接到表格上:在表格的菜单里选“视图 › 图表”。",
|
|
34
|
+
unread: "读不到这张图的表格:它不在页面上了,或者有合并的单元格。",
|
|
35
|
+
missing: (/** @type {string} */ name) => `找不到列“${name}”:表格的列名改过了吗?`,
|
|
36
|
+
noNumbers: "表格里没有写数的列:每行一条、合计和平均要一列数。",
|
|
37
|
+
empty: "表格里还没有行。",
|
|
38
|
+
},
|
|
39
|
+
en: {
|
|
40
|
+
settings: "Settings",
|
|
41
|
+
by: "Group by",
|
|
42
|
+
each: "A bar a row",
|
|
43
|
+
op: "Calculate",
|
|
44
|
+
ops: { count: "Count", sum: "Sum", average: "Average" },
|
|
45
|
+
value: "Numbers",
|
|
46
|
+
title: "Title",
|
|
47
|
+
none: "(empty)",
|
|
48
|
+
rows: (/** @type {string} */ by) => `Rows by ${by}`,
|
|
49
|
+
sum: (/** @type {string} */ by, /** @type {string} */ value) => `Total ${value} by ${by}`,
|
|
50
|
+
average: (/** @type {string} */ by, /** @type {string} */ value) => `Average ${value} by ${by}`,
|
|
51
|
+
each_: (/** @type {string} */ name, /** @type {string} */ value) => `${value} by ${name}`,
|
|
52
|
+
more: (/** @type {number} */ shown, /** @type {number} */ all) => `The first ${shown} bars of ${all}: group by a column to draw them all.`,
|
|
53
|
+
unbound: "This chart reads no table yet: pick View › Chart in a table's menu.",
|
|
54
|
+
unread: "This chart's table cannot be read: it is not on the page, or it has merged cells.",
|
|
55
|
+
missing: (/** @type {string} */ name) => `No column “${name}”: was the table's column renamed?`,
|
|
56
|
+
noNumbers: "The table has no column of numbers: a bar a row, a sum and an average need one.",
|
|
57
|
+
empty: "The table has no rows yet.",
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// The most bars it draws.
|
|
62
|
+
const MAX_BARS = 50;
|
|
63
|
+
|
|
64
|
+
// A column whose name says it is a status, the one it groups by when its settings name none.
|
|
65
|
+
const STATUS = /状态|進度|进度|阶段|階段|状況|状况|status|stage|state|phase/i;
|
|
66
|
+
|
|
67
|
+
const GEAR = '<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M3 4.5h6M12 4.5h1M3 11.5h1M7 11.5h6" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><circle cx="10.5" cy="4.5" r="1.5" fill="none" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="11.5" r="1.5" fill="none" stroke="currentColor" stroke-width="1.3"/></svg>';
|
|
68
|
+
|
|
69
|
+
/** The language the page speaks: the UI's where Gallery says it (data-ge-language), else its lang's. */
|
|
70
|
+
function languageOf(/** @type {HTMLElement} */ root) {
|
|
71
|
+
const ui = root.getAttribute("data-ge-language");
|
|
72
|
+
return (ui !== null ? ui === "en" : /^en(?:-|$)/i.test(root.lang)) ? "en" : "zh";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Words as a cell shows them, its white space one space. */
|
|
76
|
+
const wordsOf = (/** @type {Node | null | undefined} */ node) => (node?.textContent ?? "").replace(/\s+/g, " ").trim();
|
|
77
|
+
|
|
78
|
+
/** A row's value of a column as a group: its words ("" for none). */
|
|
79
|
+
const keyOf = (/** @type {DocRow} */ row, /** @type {string} */ column) => {
|
|
80
|
+
const value = row.values[column];
|
|
81
|
+
return value === null || value === undefined ? "" : String(value).trim();
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* What its settings ask (context.readJSON's; {} where none is set): "" where a setting is left out.
|
|
86
|
+
* @param {any} settings
|
|
87
|
+
* @returns {{ by: string, op: "" | "count" | "sum" | "average", value: string, title: string }}
|
|
88
|
+
*/
|
|
89
|
+
function askedOf(settings) {
|
|
90
|
+
const table = settings !== null && typeof settings === "object" && !Array.isArray(settings) ? settings : {};
|
|
91
|
+
const text = (/** @type {string} */ key) => (typeof table[key] === "string" ? table[key].trim() : "");
|
|
92
|
+
const op = table.op === "count" || table.op === "sum" || table.op === "average" ? table.op : "";
|
|
93
|
+
return { by: text("by"), op, value: text("value"), title: text("title") };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** The columns of `table` holding numbers: a number in a cell at least, and no words. */
|
|
97
|
+
const numberColumns = (/** @type {DocTableView} */ table) => table.columns.filter((name) => table.rows.some((row) => typeof row.values[name] === "number") && table.rows.every((row) => row.values[name] === null || typeof row.values[name] === "number"));
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The column it groups by where its settings name none: one after the first whose name says it is a
|
|
101
|
+
* status, else the one after the first holding words whose values repeat most (fewer than its rows),
|
|
102
|
+
* else none: a bar a row.
|
|
103
|
+
* @param {DocTableView} table
|
|
104
|
+
*/
|
|
105
|
+
function groupColumnOf(table) {
|
|
106
|
+
const numbers = numberColumns(table);
|
|
107
|
+
const rest = table.columns.slice(1).filter((name) => !numbers.includes(name));
|
|
108
|
+
const named = rest.find((name) => STATUS.test(name));
|
|
109
|
+
if (named) return named;
|
|
110
|
+
/** @type {[string, number] | null} */
|
|
111
|
+
let best = null;
|
|
112
|
+
for (const name of rest) {
|
|
113
|
+
const kinds = new Set(table.rows.map((row) => keyOf(row, name))).size;
|
|
114
|
+
if (kinds < table.rows.length && (best === null || kinds < best[1])) best = [name, kinds];
|
|
115
|
+
}
|
|
116
|
+
return best ? best[0] : "";
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The chart `asked` says of `table`: { title, bars: [{ key, label, value }], all } or { line }.
|
|
121
|
+
* @param {DocTableView} table
|
|
122
|
+
* @param {ReturnType<typeof askedOf>} asked
|
|
123
|
+
* @param {typeof WORDS.zh} words
|
|
124
|
+
*/
|
|
125
|
+
function chartOf(table, asked, words) {
|
|
126
|
+
if (table.rows.length === 0) return { line: words.empty };
|
|
127
|
+
const by = asked.by || groupColumnOf(table);
|
|
128
|
+
if (by && !table.columns.includes(by)) return { line: words.missing(by) };
|
|
129
|
+
const value = asked.value || numberColumns(table)[0] || "";
|
|
130
|
+
const op = asked.op || (value ? "sum" : "count");
|
|
131
|
+
if (value && !table.columns.includes(value)) return { line: words.missing(value) };
|
|
132
|
+
if (!value && (!by || op !== "count")) return { line: words.noNumbers };
|
|
133
|
+
/** @type {{ key: unknown, label: string, value: number | null }[]} */
|
|
134
|
+
let bars;
|
|
135
|
+
let title;
|
|
136
|
+
if (by) {
|
|
137
|
+
/** @type {Map<string, { count: number, sum: number, numbers: number }>} */
|
|
138
|
+
const groups = new Map();
|
|
139
|
+
for (const row of table.rows) {
|
|
140
|
+
const group = keyOf(row, by);
|
|
141
|
+
const kept = groups.get(group) ?? { count: 0, sum: 0, numbers: 0 };
|
|
142
|
+
kept.count += 1;
|
|
143
|
+
const number = value ? row.values[value] : null;
|
|
144
|
+
if (typeof number === "number") {
|
|
145
|
+
kept.sum += number;
|
|
146
|
+
kept.numbers += 1;
|
|
147
|
+
}
|
|
148
|
+
groups.set(group, kept);
|
|
149
|
+
}
|
|
150
|
+
bars = [...groups].map(([group, { count, sum, numbers }]) => ({ key: group, label: group || words.none, value: op === "count" ? count : op === "sum" ? sum : numbers > 0 ? sum / numbers : null }));
|
|
151
|
+
title = op === "count" ? words.rows(by) : op === "sum" ? words.sum(by, value) : words.average(by, value);
|
|
152
|
+
} else {
|
|
153
|
+
bars = table.rows.map((row) => {
|
|
154
|
+
const number = row.values[value];
|
|
155
|
+
return { key: row.el, label: wordsOf(row.el.cells[0]), value: typeof number === "number" ? number : null };
|
|
156
|
+
});
|
|
157
|
+
title = words.each_(table.columns[0] ?? "", value);
|
|
158
|
+
}
|
|
159
|
+
return { title: asked.title || title, bars: bars.slice(0, MAX_BARS), all: bars.length, by, op, value };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* An element of the drawing, of `kind` (its class gallery-chart-view-<kind>).
|
|
164
|
+
* @template {keyof HTMLElementTagNameMap} K
|
|
165
|
+
* @param {K} tag
|
|
166
|
+
* @param {string} kind
|
|
167
|
+
* @param {string} [text]
|
|
168
|
+
*/
|
|
169
|
+
function made(tag, kind, text) {
|
|
170
|
+
const node = document.createElement(tag);
|
|
171
|
+
node.className = `gallery-chart-view-${kind}`;
|
|
172
|
+
if (text !== undefined) node.textContent = text;
|
|
173
|
+
return node;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* `parent`'s children made `nodes`, what is there already left in place: where only some are new, each
|
|
178
|
+
* standing where the one it replaces stood, those alone are put in; anything else is the list anew.
|
|
179
|
+
* @param {Element} parent
|
|
180
|
+
* @param {Element[]} nodes
|
|
181
|
+
*/
|
|
182
|
+
function put(parent, nodes) {
|
|
183
|
+
const now = [...parent.children];
|
|
184
|
+
if (now.length === nodes.length) {
|
|
185
|
+
const differs = nodes.map((node, at) => node !== now[at]);
|
|
186
|
+
if (!differs.includes(true)) return;
|
|
187
|
+
if (nodes.every((node, at) => !differs[at] || !node.isConnected)) {
|
|
188
|
+
nodes.forEach((node, at) => { if (differs[at]) parent.replaceChild(node, now[at]); });
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
parent.replaceChildren(...nodes);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* The settings strip: a field a setting, a select of its choices (`options()`, [value, words]) or a
|
|
197
|
+
* text, shown while `shown()` says so, each committed (DocKit.input: Enter, the field left, a choice
|
|
198
|
+
* made) as one write of the settings part, a key set or, for "", taken off.
|
|
199
|
+
* @param {DocComponentContext} context
|
|
200
|
+
* @param {{ key: string, label: string, options?: () => [string, string][], shown?: () => boolean, value: () => string }[]} fields
|
|
201
|
+
*/
|
|
202
|
+
function settingsStrip(context, fields) {
|
|
203
|
+
const strip = made("div", "strip");
|
|
204
|
+
strip.hidden = true;
|
|
205
|
+
const write = (/** @type {string} */ key, /** @type {string} */ value) => context.editJSON("settings", (draft) => {
|
|
206
|
+
const settings = draft !== null && typeof draft === "object" && !Array.isArray(draft) ? draft : {};
|
|
207
|
+
if (value.trim() === "") delete settings[key];
|
|
208
|
+
else settings[key] = value.trim();
|
|
209
|
+
return settings;
|
|
210
|
+
});
|
|
211
|
+
const controls = fields.map((field) => {
|
|
212
|
+
const label = made("label", "setting");
|
|
213
|
+
const control = field.options ? document.createElement("select") : document.createElement("input");
|
|
214
|
+
if (control instanceof HTMLInputElement) control.type = "text";
|
|
215
|
+
label.append(made("span", "setting-name", field.label), control);
|
|
216
|
+
strip.append(label);
|
|
217
|
+
const handle = DocKit.input(control, { commit: (value) => void write(field.key, value), signal: context.signal });
|
|
218
|
+
return { field, label, control, handle, signed: "" };
|
|
219
|
+
});
|
|
220
|
+
return {
|
|
221
|
+
strip,
|
|
222
|
+
/** The fields as the settings and the table say now: their choices, which show, their values. */
|
|
223
|
+
update() {
|
|
224
|
+
for (const each of controls) {
|
|
225
|
+
each.label.hidden = each.field.shown ? !each.field.shown() : false;
|
|
226
|
+
const { control, field } = each;
|
|
227
|
+
if (field.options && control instanceof HTMLSelectElement) {
|
|
228
|
+
const options = field.options();
|
|
229
|
+
const signed = JSON.stringify(options);
|
|
230
|
+
if (signed !== each.signed) {
|
|
231
|
+
each.signed = signed;
|
|
232
|
+
control.replaceChildren(...options.map(([value, words]) => new Option(words, value)));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
each.handle.set(field.value());
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
DocKit.component({
|
|
242
|
+
id: "gallery/chart-view",
|
|
243
|
+
on: ["source", "data", "editable"],
|
|
244
|
+
mount(host, context) {
|
|
245
|
+
const language = languageOf(document.documentElement);
|
|
246
|
+
const words = WORDS[language];
|
|
247
|
+
const format = new Intl.NumberFormat(language === "en" ? "en-US" : "zh-CN", { maximumFractionDigits: 2 });
|
|
248
|
+
const face = made("div", "face");
|
|
249
|
+
const head = made("div", "head");
|
|
250
|
+
const title = made("span", "title");
|
|
251
|
+
const gear = made("button", "gear");
|
|
252
|
+
gear.type = "button";
|
|
253
|
+
gear.title = words.settings;
|
|
254
|
+
gear.setAttribute("aria-label", words.settings);
|
|
255
|
+
gear.setAttribute("aria-expanded", "false");
|
|
256
|
+
gear.innerHTML = GEAR;
|
|
257
|
+
head.append(title, gear);
|
|
258
|
+
const bars = made("div", "bars");
|
|
259
|
+
bars.setAttribute("role", "img");
|
|
260
|
+
const line = made("p", "line");
|
|
261
|
+
|
|
262
|
+
/** @type {DocTableView | null} */
|
|
263
|
+
let table = null;
|
|
264
|
+
let asked = askedOf({});
|
|
265
|
+
/** @type {{ by: string, op: string, value: string } | null} */
|
|
266
|
+
let drawn = null; // what it drew last: its column, its op, its numbers
|
|
267
|
+
const pairs = (/** @type {string[]} */ names) => names.map((name) => /** @type {[string, string]} */ ([name, name]));
|
|
268
|
+
const { strip, update: updateStrip } = settingsStrip(context, [
|
|
269
|
+
{ key: "by", label: words.by, options: () => [["", words.each], ...pairs(table ? table.columns.slice(1) : [])], value: () => drawn ? drawn.by : asked.by },
|
|
270
|
+
{ key: "op", label: words.op, options: () => [["count", words.ops.count], ["sum", words.ops.sum], ["average", words.ops.average]], shown: () => Boolean(drawn && drawn.by), value: () => drawn ? drawn.op : asked.op },
|
|
271
|
+
{ key: "value", label: words.value, options: () => pairs(table ? numberColumns(table) : []), shown: () => !drawn || !drawn.by || drawn.op !== "count", value: () => drawn ? drawn.value : asked.value },
|
|
272
|
+
{ key: "title", label: words.title, value: () => asked.title },
|
|
273
|
+
]);
|
|
274
|
+
face.append(head, strip, bars, line);
|
|
275
|
+
host.append(face);
|
|
276
|
+
gear.addEventListener("click", () => {
|
|
277
|
+
strip.hidden = !strip.hidden;
|
|
278
|
+
gear.setAttribute("aria-expanded", String(!strip.hidden));
|
|
279
|
+
}, { signal: context.signal });
|
|
280
|
+
|
|
281
|
+
/** @type {Map<unknown, { line: HTMLElement, label: HTMLElement, bar: HTMLElement, value: HTMLElement, said: string, at: string }>} */
|
|
282
|
+
const lines = new Map(); // a bar's key (its group's value, or its row's element) -> what draws it
|
|
283
|
+
const say = (/** @type {string | null} */ text) => {
|
|
284
|
+
line.hidden = text === null;
|
|
285
|
+
if (line.textContent !== (text ?? "")) line.textContent = text ?? "";
|
|
286
|
+
};
|
|
287
|
+
const drawNow = () => {
|
|
288
|
+
table = context.table();
|
|
289
|
+
asked = askedOf(context.readJSON("settings"));
|
|
290
|
+
face.toggleAttribute("data-writes", context.canEdit());
|
|
291
|
+
head.hidden = !table;
|
|
292
|
+
const chart = table ? chartOf(table, asked, words) : { line: host.hasAttribute("data-doc-from") ? words.unread : words.unbound };
|
|
293
|
+
if (chart.line !== undefined) {
|
|
294
|
+
drawn = null;
|
|
295
|
+
updateStrip();
|
|
296
|
+
title.textContent = asked.title;
|
|
297
|
+
head.classList.toggle("gallery-chart-view-untitled", !asked.title);
|
|
298
|
+
lines.clear();
|
|
299
|
+
bars.replaceChildren();
|
|
300
|
+
bars.hidden = true;
|
|
301
|
+
return say(chart.line);
|
|
302
|
+
}
|
|
303
|
+
drawn = { by: chart.by, op: chart.by ? chart.op : "", value: chart.value };
|
|
304
|
+
updateStrip();
|
|
305
|
+
head.classList.remove("gallery-chart-view-untitled");
|
|
306
|
+
if (title.textContent !== chart.title) title.textContent = chart.title;
|
|
307
|
+
bars.setAttribute("aria-label", chart.title);
|
|
308
|
+
bars.hidden = false;
|
|
309
|
+
say(chart.all > chart.bars.length ? words.more(chart.bars.length, chart.all) : null);
|
|
310
|
+
const values = /** @type {number[]} */ (chart.bars.map(({ value }) => value).filter((value) => value !== null));
|
|
311
|
+
const low = Math.min(0, ...values);
|
|
312
|
+
const span = Math.max(0, ...values) - low || 1;
|
|
313
|
+
const at = (/** @type {number} */ value) => ((value - low) / span) * 100;
|
|
314
|
+
const zero = at(0);
|
|
315
|
+
bars.classList.toggle("gallery-chart-view-below", low < 0);
|
|
316
|
+
bars.style.setProperty("--gallery-chart-view-zero", `${zero}%`);
|
|
317
|
+
const keys = new Set(chart.bars.map(({ key }) => key));
|
|
318
|
+
for (const key of [...lines.keys()]) if (!keys.has(key)) lines.delete(key);
|
|
319
|
+
put(bars, chart.bars.map(({ key, label, value }) => {
|
|
320
|
+
let kept = lines.get(key);
|
|
321
|
+
if (!kept) {
|
|
322
|
+
const row = made("div", "row");
|
|
323
|
+
const name = made("span", "label");
|
|
324
|
+
const lane = made("span", "lane");
|
|
325
|
+
const bar = made("span", "bar");
|
|
326
|
+
const said = made("span", "value");
|
|
327
|
+
lane.append(bar, said);
|
|
328
|
+
row.append(name, lane);
|
|
329
|
+
kept = { line: row, label: name, bar, value: said, said: "", at: "" };
|
|
330
|
+
lines.set(key, kept);
|
|
331
|
+
}
|
|
332
|
+
if (kept.label.textContent !== label) kept.label.textContent = label;
|
|
333
|
+
const text = value === null ? "" : format.format(value);
|
|
334
|
+
const from = value === null ? zero : Math.min(zero, at(value));
|
|
335
|
+
const to = value === null ? zero : Math.max(zero, at(value));
|
|
336
|
+
const place = `${from} ${to} ${value !== null && value < 0}`;
|
|
337
|
+
if (kept.said !== text) {
|
|
338
|
+
kept.said = text;
|
|
339
|
+
kept.value.textContent = text;
|
|
340
|
+
}
|
|
341
|
+
if (kept.at !== place) {
|
|
342
|
+
kept.at = place;
|
|
343
|
+
kept.bar.hidden = value === null;
|
|
344
|
+
kept.bar.style.left = `${from}%`;
|
|
345
|
+
kept.bar.style.width = `${to - from}%`;
|
|
346
|
+
kept.value.style.left = value !== null && value < 0 ? "" : `calc(${to}% + 4px)`;
|
|
347
|
+
kept.value.style.right = value !== null && value < 0 ? `calc(${100 - from}% + 4px)` : "";
|
|
348
|
+
}
|
|
349
|
+
return kept.line;
|
|
350
|
+
}));
|
|
351
|
+
};
|
|
352
|
+
drawNow();
|
|
353
|
+
return { update: () => context.frame(drawNow) };
|
|
354
|
+
},
|
|
355
|
+
});
|
|
@@ -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="#f2f4f7"/><rect x="16" y="12" width="208" height="96" rx="8" fill="#ffffff" stroke="#d0d5dd"/><rect x="28" y="22" width="70" height="7" rx="3.5" fill="#475467"/><rect x="28" y="42" width="28" height="7" rx="3" fill="#98a2b3"/><rect x="64" y="40" width="110" height="11" rx="3" fill="#2678d8"/><rect x="28" y="60" width="28" height="7" rx="3" fill="#98a2b3"/><rect x="64" y="58" width="72" height="11" rx="3" fill="#2678d8"/><rect x="28" y="78" width="28" height="7" rx="3" fill="#98a2b3"/><rect x="64" y="76" width="140" height="11" rx="3" fill="#2678d8"/><rect x="180" y="43" width="16" height="5" rx="2" fill="#d0d5dd"/><rect x="142" y="61" width="16" height="5" rx="2" fill="#d0d5dd"/></svg>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/* Every selector starts at the instance and goes down a step at a time (>), so that nothing here
|
|
2
|
+
reaches the rest of the page. A framed card of the kit's (gallery/chart-card's look): its title, the
|
|
3
|
+
settings (⚙) at the right of its head while the page edits and the strip they open under it, then
|
|
4
|
+
horizontal bars from zero, each its name at its left and its value at its end, in the kit's first
|
|
5
|
+
series color, which follows the theme; laid out in percents of the card's width, so that a width
|
|
6
|
+
draws nothing again. A muted line where there is nothing to draw or more than it draws. */
|
|
7
|
+
[data-doc-component="gallery/chart-view"] {
|
|
8
|
+
margin: var(--doc-component-gap) 0;
|
|
9
|
+
padding: 16px 20px 12px;
|
|
10
|
+
border: 1px solid var(--doc-border);
|
|
11
|
+
border-radius: 10px;
|
|
12
|
+
background: var(--doc-surface);
|
|
13
|
+
> .gallery-chart-view-face { color: var(--doc-text); }
|
|
14
|
+
> .gallery-chart-view-face > .gallery-chart-view-head {
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
gap: 8px;
|
|
18
|
+
min-height: 26px;
|
|
19
|
+
margin: 0 0 10px;
|
|
20
|
+
> .gallery-chart-view-title { flex: 1 1 auto; min-width: 0; font-size: var(--doc-card-title-font-size); line-height: var(--doc-card-title-line-height); font-weight: 600; letter-spacing: -.025em; }
|
|
21
|
+
> .gallery-chart-view-gear {
|
|
22
|
+
display: none;
|
|
23
|
+
flex: none;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
width: 26px;
|
|
27
|
+
height: 26px;
|
|
28
|
+
margin: 0 -8px 0 0;
|
|
29
|
+
padding: 0;
|
|
30
|
+
border: 0;
|
|
31
|
+
border-radius: 6px;
|
|
32
|
+
background: transparent;
|
|
33
|
+
color: var(--doc-muted);
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
opacity: 0;
|
|
36
|
+
transition: opacity .12s;
|
|
37
|
+
}
|
|
38
|
+
> .gallery-chart-view-gear > svg { width: 16px; height: 16px; }
|
|
39
|
+
> .gallery-chart-view-gear:hover { background: var(--doc-hover); color: var(--doc-text); }
|
|
40
|
+
> .gallery-chart-view-gear[aria-expanded="true"] { background: var(--doc-press); color: var(--doc-text); opacity: 1; }
|
|
41
|
+
}
|
|
42
|
+
> .gallery-chart-view-face > .gallery-chart-view-head.gallery-chart-view-untitled { margin-bottom: 2px; }
|
|
43
|
+
> .gallery-chart-view-face > .gallery-chart-view-head[hidden] { display: none; }
|
|
44
|
+
> .gallery-chart-view-face[data-writes] > .gallery-chart-view-head > .gallery-chart-view-gear { display: inline-flex; }
|
|
45
|
+
> .gallery-chart-view-face[data-writes]:hover > .gallery-chart-view-head > .gallery-chart-view-gear,
|
|
46
|
+
> .gallery-chart-view-face[data-writes]:focus-within > .gallery-chart-view-head > .gallery-chart-view-gear { opacity: 1; }
|
|
47
|
+
> .gallery-chart-view-face > .gallery-chart-view-strip {
|
|
48
|
+
display: flex;
|
|
49
|
+
flex-wrap: wrap;
|
|
50
|
+
gap: 6px 14px;
|
|
51
|
+
margin: -4px 0 12px;
|
|
52
|
+
padding: 8px 10px;
|
|
53
|
+
border-radius: 8px;
|
|
54
|
+
background: var(--doc-hover);
|
|
55
|
+
font-size: 12px;
|
|
56
|
+
> .gallery-chart-view-setting { display: inline-flex; align-items: center; gap: 6px; color: var(--doc-muted); }
|
|
57
|
+
> .gallery-chart-view-setting[hidden] { display: none; }
|
|
58
|
+
> .gallery-chart-view-setting > select,
|
|
59
|
+
> .gallery-chart-view-setting > input {
|
|
60
|
+
box-sizing: border-box;
|
|
61
|
+
max-width: 180px;
|
|
62
|
+
height: 24px;
|
|
63
|
+
padding: 2px 6px;
|
|
64
|
+
border: 1px solid var(--doc-border);
|
|
65
|
+
border-radius: 6px;
|
|
66
|
+
background: var(--doc-surface);
|
|
67
|
+
color: var(--doc-text);
|
|
68
|
+
font: inherit;
|
|
69
|
+
}
|
|
70
|
+
/* A select is a button that opens the kit's menu (DocKit's choices): no line, as every button. */
|
|
71
|
+
> .gallery-chart-view-setting > select { border: 0; cursor: pointer; }
|
|
72
|
+
> .gallery-chart-view-setting > input { width: 160px; }
|
|
73
|
+
}
|
|
74
|
+
> .gallery-chart-view-face > .gallery-chart-view-strip[hidden] { display: none; }
|
|
75
|
+
> .gallery-chart-view-face > .gallery-chart-view-bars {
|
|
76
|
+
display: grid;
|
|
77
|
+
grid-template-columns: fit-content(40%) minmax(0, 1fr);
|
|
78
|
+
gap: 8px 12px;
|
|
79
|
+
align-items: center;
|
|
80
|
+
margin: 0 0 4px;
|
|
81
|
+
font-size: 13px;
|
|
82
|
+
line-height: 1.4;
|
|
83
|
+
> .gallery-chart-view-row { display: contents; }
|
|
84
|
+
> .gallery-chart-view-row > .gallery-chart-view-label { text-align: right; overflow-wrap: anywhere; color: var(--doc-text); }
|
|
85
|
+
> .gallery-chart-view-row > .gallery-chart-view-lane { position: relative; height: 18px; margin-right: 4.5em; }
|
|
86
|
+
> .gallery-chart-view-row > .gallery-chart-view-lane > .gallery-chart-view-bar { position: absolute; top: 0; bottom: 0; min-width: 1px; border-radius: 3px; background: var(--doc-series-1); }
|
|
87
|
+
> .gallery-chart-view-row > .gallery-chart-view-lane > .gallery-chart-view-bar[hidden] { display: none; }
|
|
88
|
+
> .gallery-chart-view-row > .gallery-chart-view-lane > .gallery-chart-view-value { position: absolute; top: 50%; transform: translateY(-50%); font-size: 12px; line-height: 1; color: var(--doc-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
|
|
89
|
+
&.gallery-chart-view-below > .gallery-chart-view-row > .gallery-chart-view-lane { margin-left: 4.5em; background: linear-gradient(var(--doc-grid), var(--doc-grid)) var(--gallery-chart-view-zero) 0 / 1px 100% no-repeat; }
|
|
90
|
+
}
|
|
91
|
+
> .gallery-chart-view-face > .gallery-chart-view-bars[hidden] { display: none; }
|
|
92
|
+
> .gallery-chart-view-face > .gallery-chart-view-line { margin: 6px 0 2px; font-size: 13px; line-height: 1.5; color: var(--doc-muted); }
|
|
93
|
+
> .gallery-chart-view-face > .gallery-chart-view-line[hidden] { display: none; }
|
|
94
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# 图表 (gallery/chart-view)
|
|
2
|
+
|
|
3
|
+
A bar chart of a table of the document: the rows counted, summed or averaged by a column (tasks by status, sales by region), or a bar for each row's number. It is a view of the table, drawn again as the table is typed in: the table holds the data, the chart never writes it. Use it beside a 看板 or a few 指标 over the same table. For a chart of numbers written for the chart alone, use 表格图表卡片 (gallery/chart-card), whose table is its own; for any other kind of chart, a chart of the document's (references/writing-html.md, "Figures and charts").
|
|
4
|
+
|
|
5
|
+
## How to write it
|
|
6
|
+
|
|
7
|
+
Write a table, then the chart, as example.html does (`gallery block show gallery/chart-view` prints it):
|
|
8
|
+
|
|
9
|
+
- the table: an ordinary table of the document whose `<table>` carries `data-doc-chart-source="<key>"`, a key of the document's own (a letter, then letters, digits, `_` or `-`; 32 at most), its header row naming the columns, the first column naming each row. No merged cells.
|
|
10
|
+
- the chart: `<div data-doc-component="gallery/chart-view" data-doc-from="<key>">`, the same key, holding its settings, one `<script type="application/json">` on one line, each optional:
|
|
11
|
+
- `by`: the column whose values are the bars, the rows grouped by it in the order they first say them. Left out, a column named like a status (状态, 阶段, status), else one whose words repeat; with none, a bar for each row (its first cell its name; at most 50);
|
|
12
|
+
- `op`: `"count"`, `"sum"` or `"average"` of each group's rows. Left out: `"sum"` where the table has a column of numbers, else `"count"`;
|
|
13
|
+
- `value`: the column of numbers summed, averaged, or drawn a bar a row. Left out: the first column of numbers;
|
|
14
|
+
- `title`: what it shows, with its unit. Left out, one is made (各状态的行数, 各区域的金额合计).
|
|
15
|
+
|
|
16
|
+
One table may have several views (a 看板, 指标, another chart), each with the same key.
|
|
17
|
+
|
|
18
|
+
The reader adds a chart in Gallery from a table's menu, 视图 › 图表, which writes the key on both; it is not in "/", as a chart needs its table. Its ⚙ (where the page edits) changes its settings.
|
|
19
|
+
|
|
20
|
+
## How it looks
|
|
21
|
+
|
|
22
|
+
A framed card: its title, then horizontal bars from zero, each with its name and its value, in the kit's series color, which follows the theme. The bars are drawn by the block's script and are not in the file: where the block is not, and in a Markdown export, a reader has the table.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "gallery/countdown",
|
|
3
|
+
"apiVersion": 1,
|
|
4
|
+
"version": "1.3.0",
|
|
5
|
+
"name": { "zh": "倒计时", "en": "Countdown" },
|
|
6
|
+
"description": { "zh": "离某一天还有几天,到了那天说今天,过了说已经几天", "en": "How many days until a date: today on the day, and the days since after it" },
|
|
7
|
+
"words": "daojishi daoshu countdown days until 倒计时 倒数日 纪念日 日子",
|
|
8
|
+
"parts": {
|
|
9
|
+
"settings": { "at": ":scope > script", "edit": "data" }
|
|
10
|
+
},
|
|
11
|
+
"runtime": { "generated": [":scope > .gallery-countdown-face"] },
|
|
12
|
+
"places": ["page"],
|
|
13
|
+
"card": { "sizes": [[2, 2], [4, 2]], "resize": true },
|
|
14
|
+
"settings": [
|
|
15
|
+
{ "key": "title", "label": { "zh": "名称", "en": "Name" }, "type": "text", "default": "" },
|
|
16
|
+
{ "key": "date", "label": { "zh": "日期", "en": "Date" }, "type": "date", "required": true }
|
|
17
|
+
]
|
|
18
|
+
}
|