@peaske7/readit 0.3.0-rc.0 → 0.3.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (373) hide show
  1. package/dist/.vite/manifest.json +1111 -0
  2. package/dist/assets/_basePickBy-BMMA4Tou.js +1 -0
  3. package/dist/assets/_baseUniq-D40qku1I.js +1 -0
  4. package/dist/assets/arc-Ckg65iy8.js +1 -0
  5. package/dist/assets/architecture-YZFGNWBL-Dv3EY0zV.js +1 -0
  6. package/dist/assets/architectureDiagram-Q4EWVU46-ClRss4cm.js +36 -0
  7. package/dist/assets/array-Bjz-wYpJ.js +1 -0
  8. package/dist/assets/blockDiagram-DXYQGD6D-CBcFvoK1.js +132 -0
  9. package/dist/assets/c4Diagram-AHTNJAMY-D4d3ZLam.js +10 -0
  10. package/dist/assets/channel-D9EJxDy_.js +1 -0
  11. package/dist/assets/chunk-2KRD3SAO-DaFfaCGO.js +1 -0
  12. package/dist/assets/chunk-336JU56O-yLEQoF0v.js +2 -0
  13. package/dist/assets/chunk-426QAEUC-Uyzd4wAA.js +1 -0
  14. package/dist/assets/chunk-4BX2VUAB-DRuTD7x5.js +1 -0
  15. package/dist/assets/chunk-4TB4RGXK-3xbpIi_o.js +206 -0
  16. package/dist/assets/chunk-55IACEB6-BExiaAoD.js +1 -0
  17. package/dist/assets/chunk-5FUZZQ4R-DatVvHnF.js +62 -0
  18. package/dist/assets/chunk-5PVQY5BW-BKgvrGh8.js +2 -0
  19. package/dist/assets/chunk-67CJDMHE-DMt8LNEX.js +1 -0
  20. package/dist/assets/chunk-7N4EOEYR-CzLGefVf.js +1 -0
  21. package/dist/assets/chunk-AA7GKIK3-B6GFAk4U.js +1 -0
  22. package/dist/assets/chunk-BSJP7CBP-BK29yehL.js +1 -0
  23. package/dist/assets/chunk-CIAEETIT-D7hBXImP.js +1 -0
  24. package/dist/assets/chunk-Dlc7tRH4.js +1 -0
  25. package/dist/assets/chunk-EDXVE4YY-PYJdlmyH.js +1 -0
  26. package/dist/assets/chunk-ENJZ2VHE-DUHKBv6x.js +10 -0
  27. package/dist/assets/chunk-FMBD7UC4-2FWyCCAV.js +15 -0
  28. package/dist/assets/chunk-FOC6F5B3-DKFHrt4K.js +1 -0
  29. package/dist/assets/chunk-ICPOFSXX-Bh__D0ec.js +122 -0
  30. package/dist/assets/chunk-K5T4RW27-D51O7IkG.js +94 -0
  31. package/dist/assets/chunk-KGLVRYIC-DMHSCH4T.js +1 -0
  32. package/dist/assets/chunk-LIHQZDEY-C2aANxt9.js +1 -0
  33. package/dist/assets/chunk-ORNJ4GCN-Db_37NRX.js +1 -0
  34. package/dist/assets/chunk-OYMX7WX6-BltXOJLJ.js +231 -0
  35. package/dist/assets/chunk-QZHKN3VN-8Lcg9gti.js +1 -0
  36. package/dist/assets/chunk-U2HBQHQK-ByS6tilY.js +70 -0
  37. package/dist/assets/chunk-X2U36JSP-Bm-4Gqg_.js +1 -0
  38. package/dist/assets/chunk-XPW4576I-Bqbompq4.js +32 -0
  39. package/dist/assets/chunk-YZCP3GAM-CsC0imPb.js +1 -0
  40. package/dist/assets/chunk-ZZ45TVLE-CG-CqfPC.js +1 -0
  41. package/dist/assets/classDiagram-6PBFFD2Q-Jy1uFUk4.js +1 -0
  42. package/dist/assets/classDiagram-v2-HSJHXN6E-ChiLl3rR.js +1 -0
  43. package/dist/assets/clone-BBjvuERA.js +1 -0
  44. package/dist/assets/cose-bilkent-S5V4N54A-q90QeGKv.js +1 -0
  45. package/dist/assets/cytoscape.esm-BfXff3fb.js +321 -0
  46. package/dist/assets/dagre-KV5264BT-BQWiLFJB.js +4 -0
  47. package/dist/assets/dagre-nn_aIZ2E.js +1 -0
  48. package/dist/assets/defaultLocale-BwmRmqJp.js +1 -0
  49. package/dist/assets/diagram-5BDNPKRD-CJa7Y97H.js +10 -0
  50. package/dist/assets/diagram-G4DWMVQ6-tVQGBWfY.js +24 -0
  51. package/dist/assets/diagram-MMDJMWI5-CpimFldm.js +43 -0
  52. package/dist/assets/diagram-TYMM5635-D11WQVgy.js +24 -0
  53. package/dist/assets/dist-BNz65Ibc.js +1 -0
  54. package/dist/assets/erDiagram-SMLLAGMA-C2bLd0jS.js +85 -0
  55. package/dist/assets/flowDiagram-DWJPFMVM-Kw3fOOLT.js +162 -0
  56. package/dist/assets/ganttDiagram-T4ZO3ILL-fyMhyE2X.js +292 -0
  57. package/dist/assets/gitGraph-7Q5UKJZL-BGFRt2qs.js +1 -0
  58. package/dist/assets/gitGraphDiagram-UUTBAWPF-D4JoiOvg.js +106 -0
  59. package/dist/assets/graphlib-DGcD9J2L.js +1 -0
  60. package/dist/assets/index-Cow3qpoq.css +2 -0
  61. package/dist/assets/index-DUf7okYi.js +14 -0
  62. package/dist/assets/info-OMHHGYJF-DI6-Z9vh.js +1 -0
  63. package/dist/assets/infoDiagram-42DDH7IO-D1ZkeMBy.js +2 -0
  64. package/dist/assets/init-TPm5RB77.js +1 -0
  65. package/dist/assets/isArrayLikeObject-69BLnVNM.js +1 -0
  66. package/dist/assets/isEmpty-DUS28g5f.js +1 -0
  67. package/dist/assets/ishikawaDiagram-UXIWVN3A-Dv8hzjZB.js +70 -0
  68. package/dist/assets/journeyDiagram-VCZTEJTY-COeB7F5r.js +139 -0
  69. package/dist/assets/kanban-definition-6JOO6SKY-BbYmxCYU.js +89 -0
  70. package/dist/assets/katex-5SGEXwpi.js +261 -0
  71. package/dist/assets/line-_v2NGEdn.js +1 -0
  72. package/dist/assets/linear-CXMqTN8N.js +1 -0
  73. package/dist/assets/mermaid-config-C8a4L22x.js +1 -0
  74. package/dist/assets/mermaid-parser.core-CFmphzPP.js +4 -0
  75. package/dist/assets/mermaid.core-DnHAupTp.js +11 -0
  76. package/dist/assets/mindmap-definition-QFDTVHPH-D7_lIep7.js +96 -0
  77. package/dist/assets/ordinal-D7l-8DAO.js +1 -0
  78. package/dist/assets/packet-4T2RLAQJ-DidW3JFc.js +1 -0
  79. package/dist/assets/path-BVpCanzE.js +1 -0
  80. package/dist/assets/pie-ZZUOXDRM-Bff2e5hg.js +1 -0
  81. package/dist/assets/pieDiagram-DEJITSTG-DDvYHCT_.js +30 -0
  82. package/dist/assets/quadrantDiagram-34T5L4WZ-DcLcIrdi.js +7 -0
  83. package/dist/assets/radar-PYXPWWZC-CsdZBH3M.js +1 -0
  84. package/dist/assets/requirementDiagram-MS252O5E-DLX6ld7D.js +84 -0
  85. package/dist/assets/rough.esm-BoTisKeL.js +1 -0
  86. package/dist/assets/sankeyDiagram-XADWPNL6-D-1GtsHM.js +10 -0
  87. package/dist/assets/sequenceDiagram-FGHM5R23-Bwxs0YQg.js +157 -0
  88. package/dist/assets/src-CrmkjRpa.js +1 -0
  89. package/dist/assets/stateDiagram-FHFEXIEX-DW7rOcnQ.js +1 -0
  90. package/dist/assets/stateDiagram-v2-QKLJ7IA2-Jm-24vQ2.js +1 -0
  91. package/dist/assets/timeline-definition-GMOUNBTQ-DVdHyzxS.js +120 -0
  92. package/dist/assets/treeView-SZITEDCU-DPKseaET.js +1 -0
  93. package/dist/assets/treemap-W4RFUUIX-DH-7GZe_.js +1 -0
  94. package/dist/assets/vennDiagram-DHZGUBPP-DJaC6xmI.js +34 -0
  95. package/dist/assets/wardley-RL74JXVD-AgyXyBN5.js +1 -0
  96. package/dist/assets/wardleyDiagram-NUSXRM2D-CTKERPKv.js +20 -0
  97. package/dist/assets/xychartDiagram-5P7HB3ND-BuExiLXc.js +7 -0
  98. package/{index.html → dist/index.html} +2 -1
  99. package/dist/index.js +2539 -0
  100. package/package.json +11 -1
  101. package/.agents/skills/remotion-best-practices/SKILL.md +0 -61
  102. package/.agents/skills/remotion-best-practices/rules/3d.md +0 -86
  103. package/.agents/skills/remotion-best-practices/rules/animations.md +0 -27
  104. package/.agents/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +0 -178
  105. package/.agents/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +0 -100
  106. package/.agents/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +0 -108
  107. package/.agents/skills/remotion-best-practices/rules/assets.md +0 -78
  108. package/.agents/skills/remotion-best-practices/rules/audio-visualization.md +0 -198
  109. package/.agents/skills/remotion-best-practices/rules/audio.md +0 -169
  110. package/.agents/skills/remotion-best-practices/rules/calculate-metadata.md +0 -134
  111. package/.agents/skills/remotion-best-practices/rules/can-decode.md +0 -75
  112. package/.agents/skills/remotion-best-practices/rules/charts.md +0 -120
  113. package/.agents/skills/remotion-best-practices/rules/compositions.md +0 -154
  114. package/.agents/skills/remotion-best-practices/rules/display-captions.md +0 -184
  115. package/.agents/skills/remotion-best-practices/rules/extract-frames.md +0 -229
  116. package/.agents/skills/remotion-best-practices/rules/ffmpeg.md +0 -38
  117. package/.agents/skills/remotion-best-practices/rules/fonts.md +0 -152
  118. package/.agents/skills/remotion-best-practices/rules/get-audio-duration.md +0 -58
  119. package/.agents/skills/remotion-best-practices/rules/get-video-dimensions.md +0 -68
  120. package/.agents/skills/remotion-best-practices/rules/get-video-duration.md +0 -60
  121. package/.agents/skills/remotion-best-practices/rules/gifs.md +0 -141
  122. package/.agents/skills/remotion-best-practices/rules/images.md +0 -134
  123. package/.agents/skills/remotion-best-practices/rules/import-srt-captions.md +0 -69
  124. package/.agents/skills/remotion-best-practices/rules/light-leaks.md +0 -73
  125. package/.agents/skills/remotion-best-practices/rules/lottie.md +0 -70
  126. package/.agents/skills/remotion-best-practices/rules/maps.md +0 -412
  127. package/.agents/skills/remotion-best-practices/rules/measuring-dom-nodes.md +0 -34
  128. package/.agents/skills/remotion-best-practices/rules/measuring-text.md +0 -140
  129. package/.agents/skills/remotion-best-practices/rules/parameters.md +0 -109
  130. package/.agents/skills/remotion-best-practices/rules/sequencing.md +0 -118
  131. package/.agents/skills/remotion-best-practices/rules/sfx.md +0 -26
  132. package/.agents/skills/remotion-best-practices/rules/subtitles.md +0 -36
  133. package/.agents/skills/remotion-best-practices/rules/tailwind.md +0 -11
  134. package/.agents/skills/remotion-best-practices/rules/text-animations.md +0 -20
  135. package/.agents/skills/remotion-best-practices/rules/timing.md +0 -179
  136. package/.agents/skills/remotion-best-practices/rules/transcribe-captions.md +0 -70
  137. package/.agents/skills/remotion-best-practices/rules/transitions.md +0 -197
  138. package/.agents/skills/remotion-best-practices/rules/transparent-videos.md +0 -106
  139. package/.agents/skills/remotion-best-practices/rules/trimming.md +0 -51
  140. package/.agents/skills/remotion-best-practices/rules/videos.md +0 -171
  141. package/.agents/skills/remotion-best-practices/rules/voiceover.md +0 -99
  142. package/.agents/skills/simple/SKILL.md +0 -52
  143. package/.agents/skills/vercel-react-best-practices/AGENTS.md +0 -3254
  144. package/.agents/skills/vercel-react-best-practices/README.md +0 -123
  145. package/.agents/skills/vercel-react-best-practices/SKILL.md +0 -141
  146. package/.agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  147. package/.agents/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
  148. package/.agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
  149. package/.agents/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  150. package/.agents/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
  151. package/.agents/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
  152. package/.agents/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
  153. package/.agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  154. package/.agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
  155. package/.agents/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  156. package/.agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  157. package/.agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  158. package/.agents/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  159. package/.agents/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  160. package/.agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  161. package/.agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  162. package/.agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  163. package/.agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
  164. package/.agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  165. package/.agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  166. package/.agents/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  167. package/.agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  168. package/.agents/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  169. package/.agents/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
  170. package/.agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  171. package/.agents/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  172. package/.agents/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  173. package/.agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  174. package/.agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  175. package/.agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  176. package/.agents/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  177. package/.agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  178. package/.agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  179. package/.agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  180. package/.agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  181. package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  182. package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
  183. package/.agents/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
  184. package/.agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
  185. package/.agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  186. package/.agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
  187. package/.agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  188. package/.agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  189. package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
  190. package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  191. package/.agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  192. package/.agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  193. package/.agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
  194. package/.agents/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  195. package/.agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
  196. package/.agents/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
  197. package/.agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
  198. package/.agents/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  199. package/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
  200. package/.agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  201. package/.agents/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
  202. package/.agents/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  203. package/.agents/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  204. package/.agents/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
  205. package/.agents/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -142
  206. package/.agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  207. package/.agents/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
  208. package/.claude/CLAUDE.md +0 -184
  209. package/.claude/commands/review.md +0 -120
  210. package/.claude/commands/sync-docs.md +0 -71
  211. package/.claude/roadmap.md +0 -121
  212. package/.claude/rules/style-guide.md +0 -830
  213. package/.claude/settings.json +0 -18
  214. package/.claude/user-stories.md +0 -333
  215. package/AGENTS.md +0 -68
  216. package/Makefile +0 -32
  217. package/biome.json +0 -79
  218. package/bun.lock +0 -854
  219. package/bunfig.toml +0 -2
  220. package/docs/design.md +0 -563
  221. package/docs/perf-baseline.md +0 -130
  222. package/docs/plans/2026-03-13-client-mode-design.md +0 -86
  223. package/docs/plans/2026-03-13-client-mode-plan.md +0 -605
  224. package/docs/plans/2026-03-13-keyboard-shortcuts-design.md +0 -129
  225. package/docs/plans/2026-03-13-keyboard-shortcuts-plan.md +0 -1471
  226. package/docs/plans/2026-03-13-multi-document-design.md +0 -183
  227. package/docs/plans/2026-03-13-performance-benchmarks-design.md +0 -121
  228. package/docs/superpowers/plans/2026-03-26-surgical-pruning.md +0 -1176
  229. package/docs/superpowers/specs/2026-03-27-go-server-rewrite-design.md +0 -284
  230. package/e2e/comments.spec.ts +0 -81
  231. package/e2e/document-load.spec.ts +0 -32
  232. package/e2e/export.spec.ts +0 -58
  233. package/e2e/fixtures/sample.md +0 -7
  234. package/e2e/perf/add-comment.spec.ts +0 -116
  235. package/e2e/perf/fixtures/generate.ts +0 -327
  236. package/e2e/perf/initial-load.spec.ts +0 -49
  237. package/e2e/perf/perf.setup.ts +0 -23
  238. package/e2e/perf/perf.teardown.ts +0 -9
  239. package/e2e/perf/screenshot-final.png +0 -0
  240. package/e2e/perf/scroll.spec.ts +0 -39
  241. package/e2e/perf/tab-switch.spec.ts +0 -69
  242. package/e2e/perf/text-selection.spec.ts +0 -119
  243. package/e2e/perf/utils/metrics.ts +0 -350
  244. package/e2e/perf/utils/perf-cli.ts +0 -86
  245. package/e2e/persistence-file.spec.ts +0 -357
  246. package/e2e/utils/cli.ts +0 -84
  247. package/e2e/utils/selection.ts +0 -79
  248. package/go/cmd/readit/main.go +0 -416
  249. package/go/go.mod +0 -20
  250. package/go/go.sum +0 -41
  251. package/go/internal/server/anchor.go +0 -302
  252. package/go/internal/server/anchor_test.go +0 -111
  253. package/go/internal/server/comments.go +0 -390
  254. package/go/internal/server/documents.go +0 -113
  255. package/go/internal/server/embed.go +0 -17
  256. package/go/internal/server/headings.go +0 -33
  257. package/go/internal/server/headings_test.go +0 -75
  258. package/go/internal/server/htmltext.go +0 -123
  259. package/go/internal/server/markdown.go +0 -157
  260. package/go/internal/server/markdown_bench_test.go +0 -42
  261. package/go/internal/server/markdown_test.go +0 -79
  262. package/go/internal/server/server.go +0 -453
  263. package/go/internal/server/server_bench_test.go +0 -122
  264. package/go/internal/server/settings.go +0 -110
  265. package/go/internal/server/sse.go +0 -140
  266. package/go/internal/server/storage.go +0 -275
  267. package/go/internal/server/storage_test.go +0 -152
  268. package/go/internal/server/template.go +0 -66
  269. package/go/internal/server/types.go +0 -101
  270. package/go/internal/server/watcher.go +0 -74
  271. package/lefthook.yml +0 -8
  272. package/nvim-readit/lua/readit/health.lua +0 -64
  273. package/nvim-readit/lua/readit/init.lua +0 -463
  274. package/nvim-readit/plugin/readit.lua +0 -19
  275. package/playwright.config.ts +0 -34
  276. package/skills-lock.json +0 -20
  277. package/src/App.svelte +0 -890
  278. package/src/cli.ts +0 -881
  279. package/src/components/ActionsMenu.svelte +0 -95
  280. package/src/components/CommentBadge.svelte +0 -67
  281. package/src/components/CommentErrorBanner.svelte +0 -33
  282. package/src/components/CommentInput.svelte +0 -75
  283. package/src/components/CommentListItem.svelte +0 -95
  284. package/src/components/CommentManager.svelte +0 -129
  285. package/src/components/CommentNav.svelte +0 -109
  286. package/src/components/DocumentViewer.svelte +0 -233
  287. package/src/components/FloatingComment.svelte +0 -107
  288. package/src/components/Header.svelte +0 -76
  289. package/src/components/InlineEditor.svelte +0 -72
  290. package/src/components/MarginNote.svelte +0 -167
  291. package/src/components/MarginNotesContainer.svelte +0 -33
  292. package/src/components/MermaidEnhancer.svelte +0 -218
  293. package/src/components/MermaidModal.svelte +0 -67
  294. package/src/components/RawModal.svelte +0 -126
  295. package/src/components/ReanchorConfirm.svelte +0 -30
  296. package/src/components/SettingsModal.svelte +0 -220
  297. package/src/components/ShortcutCapture.svelte +0 -82
  298. package/src/components/ShortcutList.svelte +0 -145
  299. package/src/components/TabBar.svelte +0 -52
  300. package/src/components/TableOfContents.svelte +0 -125
  301. package/src/components/ui/ActionLink.svelte +0 -40
  302. package/src/components/ui/Button.svelte +0 -53
  303. package/src/components/ui/Dialog.svelte +0 -97
  304. package/src/components/ui/DropdownMenu.svelte +0 -85
  305. package/src/components/ui/DropdownMenuItem.svelte +0 -38
  306. package/src/components/ui/DropdownMenuSeparator.svelte +0 -11
  307. package/src/components/ui/Text.svelte +0 -42
  308. package/src/env.d.ts +0 -6
  309. package/src/index.css +0 -859
  310. package/src/lib/__fixtures__/bench-data.ts +0 -114
  311. package/src/lib/anchor.bench.ts +0 -91
  312. package/src/lib/anchor.test.ts +0 -527
  313. package/src/lib/anchor.ts +0 -381
  314. package/src/lib/comment-storage.bench.ts +0 -49
  315. package/src/lib/comment-storage.test.ts +0 -694
  316. package/src/lib/comment-storage.ts +0 -226
  317. package/src/lib/export.bench.ts +0 -21
  318. package/src/lib/export.ts +0 -36
  319. package/src/lib/fetch-or-throw.test.ts +0 -59
  320. package/src/lib/fetch-or-throw.ts +0 -12
  321. package/src/lib/headings.test.ts +0 -103
  322. package/src/lib/headings.ts +0 -44
  323. package/src/lib/highlight/core.test.ts +0 -93
  324. package/src/lib/highlight/dom.ts +0 -187
  325. package/src/lib/highlight/highlight-registry.ts +0 -221
  326. package/src/lib/highlight/highlight.bench.ts +0 -92
  327. package/src/lib/highlight/highlighter.ts +0 -247
  328. package/src/lib/highlight/resolver.ts +0 -38
  329. package/src/lib/highlight/types.ts +0 -17
  330. package/src/lib/html-text.test.ts +0 -162
  331. package/src/lib/html-text.ts +0 -161
  332. package/src/lib/i18n/en.ts +0 -124
  333. package/src/lib/i18n/index.ts +0 -3
  334. package/src/lib/i18n/ja.ts +0 -126
  335. package/src/lib/i18n/translations.ts +0 -27
  336. package/src/lib/i18n/types.ts +0 -130
  337. package/src/lib/key-lock.test.ts +0 -104
  338. package/src/lib/key-lock.ts +0 -23
  339. package/src/lib/margin-layout.bench.ts +0 -61
  340. package/src/lib/margin-layout.ts +0 -71
  341. package/src/lib/markdown-renderer.test.ts +0 -154
  342. package/src/lib/markdown-renderer.ts +0 -178
  343. package/src/lib/mermaid-config.ts +0 -38
  344. package/src/lib/mermaid-renderer.ts +0 -162
  345. package/src/lib/mermaid-worker.ts +0 -60
  346. package/src/lib/positions.ts +0 -157
  347. package/src/lib/shortcut-registry.ts +0 -244
  348. package/src/lib/utils.ts +0 -15
  349. package/src/main.ts +0 -16
  350. package/src/schema.ts +0 -92
  351. package/src/server.ts +0 -1216
  352. package/src/stores/app.svelte.ts +0 -231
  353. package/src/stores/locale.svelte.ts +0 -46
  354. package/src/stores/settings.svelte.ts +0 -90
  355. package/src/stores/shortcuts.svelte.ts +0 -104
  356. package/src/stores/ui.svelte.ts +0 -12
  357. package/src/template.ts +0 -104
  358. package/src/test-setup.ts +0 -48
  359. package/svelte.config.js +0 -5
  360. package/test.md +0 -74
  361. package/tsconfig.cli.json +0 -12
  362. package/tsconfig.json +0 -20
  363. package/vite.config.ts +0 -47
  364. package/vitest.config.ts +0 -15
  365. package/vscode-readit/.mcp.json +0 -7
  366. package/vscode-readit/.vscodeignore +0 -7
  367. package/vscode-readit/bun.lock +0 -78
  368. package/vscode-readit/icon.svg +0 -10
  369. package/vscode-readit/package.json +0 -110
  370. package/vscode-readit/src/extension.ts +0 -117
  371. package/vscode-readit/src/server-manager.ts +0 -272
  372. package/vscode-readit/src/webview-provider.ts +0 -204
  373. package/vscode-readit/tsconfig.json +0 -20
@@ -1,218 +0,0 @@
1
- <script lang="ts">
2
- import { Code2, Image as ImageIcon, Maximize2 } from "lucide-svelte";
3
- import { mount, unmount } from "svelte";
4
- import { localeState, t } from "../stores/locale.svelte";
5
- import MermaidModal from "./MermaidModal.svelte";
6
-
7
- interface Props {
8
- /** The article element that contains all rendered mermaid containers. */
9
- root: HTMLElement | undefined;
10
- /** Bumped whenever document content is re-rendered (rescan triggers). */
11
- contentVersion: number;
12
- /** Called after an inline toggle so margin notes / positions can recache. */
13
- notifyContentChanged?: () => void;
14
- }
15
-
16
- let { root, contentVersion, notifyContentChanged }: Props = $props();
17
-
18
- let modalOpen = $state(false);
19
- let modalSvg = $state("");
20
- let modalSource = $state("");
21
-
22
- const ENHANCED_FLAG = "readitMermaidEnhanced";
23
-
24
- function decodeSource(container: HTMLElement): string {
25
- const encoded = container.dataset.mermaidSource ?? "";
26
- try {
27
- return decodeURIComponent(encoded);
28
- } catch {
29
- return encoded;
30
- }
31
- }
32
-
33
- function openModal(container: HTMLElement) {
34
- const svgEl = container.querySelector("svg");
35
- modalSvg = svgEl ? svgEl.outerHTML : "";
36
- modalSource = decodeSource(container);
37
- modalOpen = true;
38
- }
39
-
40
- function ensureSourceView(container: HTMLElement, source: string): HTMLElement {
41
- let pre = container.querySelector<HTMLElement>(".mermaid-source-view");
42
- if (pre) return pre;
43
- pre = document.createElement("pre");
44
- pre.className = "mermaid-source-view";
45
- const codeEl = document.createElement("code");
46
- codeEl.className = "language-mermaid";
47
- codeEl.textContent = source;
48
- pre.appendChild(codeEl);
49
- pre.style.display = "none";
50
- // Insert before the toolbar so the toolbar stays the last child.
51
- const toolbar = container.querySelector(".mermaid-toolbar");
52
- container.insertBefore(pre, toolbar);
53
- return pre;
54
- }
55
-
56
- function toggleInline(container: HTMLElement, source: string): void {
57
- const svg = container.querySelector<SVGElement>("svg");
58
- const pre = ensureSourceView(container, source);
59
- const showingCode = container.dataset.mermaidView === "code";
60
- const next = showingCode ? "graph" : "code";
61
-
62
- if (svg) svg.style.display = next === "code" ? "none" : "";
63
- pre.style.display = next === "code" ? "block" : "none";
64
- container.dataset.mermaidView = next;
65
-
66
- const toolbar = container.querySelector<HTMLElement>(".mermaid-toolbar");
67
- const toggleBtn = toolbar?.querySelector<HTMLButtonElement>(
68
- '[data-action="toggle"]',
69
- );
70
- toggleBtn?.setAttribute(
71
- "aria-label",
72
- next === "code" ? t("mermaid.showDiagram") : t("mermaid.showSource"),
73
- );
74
- toggleBtn?.setAttribute("aria-pressed", next === "code" ? "true" : "false");
75
-
76
- const handle = (
77
- toolbar as (HTMLElement & { _readitHandle?: ToolbarHandle }) | null
78
- )?._readitHandle;
79
- handle?.remountToggleIcon(next);
80
-
81
- notifyContentChanged?.();
82
- }
83
-
84
- interface ToolbarHandle {
85
- cleanup: () => void;
86
- remountToggleIcon: (view: "graph" | "code") => void;
87
- }
88
-
89
- function mountToggleIcon(target: HTMLElement, view: "graph" | "code") {
90
- // Show "code" icon when graph is visible (click to see code), and vice versa.
91
- const Icon = view === "graph" ? Code2 : ImageIcon;
92
- return mount(Icon, { target, props: { size: 14 } });
93
- }
94
-
95
- function buildToolbar(container: HTMLElement): HTMLElement {
96
- const toolbar = document.createElement("div");
97
- toolbar.className = "mermaid-toolbar";
98
- toolbar.setAttribute("contenteditable", "false");
99
-
100
- const toggleBtn = document.createElement("button");
101
- toggleBtn.type = "button";
102
- toggleBtn.dataset.action = "toggle";
103
- toggleBtn.setAttribute("aria-label", t("mermaid.showSource"));
104
- toggleBtn.setAttribute("aria-pressed", "false");
105
-
106
- const expandBtn = document.createElement("button");
107
- expandBtn.type = "button";
108
- expandBtn.dataset.action = "expand";
109
- expandBtn.setAttribute("aria-label", t("mermaid.expand"));
110
-
111
- toolbar.appendChild(toggleBtn);
112
- toolbar.appendChild(expandBtn);
113
-
114
- let toggleIcon = mountToggleIcon(toggleBtn, "graph");
115
- const expandIcon = mount(Maximize2, {
116
- target: expandBtn,
117
- props: { size: 14 },
118
- });
119
-
120
- toggleBtn.addEventListener("click", (e) => {
121
- e.preventDefault();
122
- e.stopPropagation();
123
- toggleInline(container, decodeSource(container));
124
- });
125
-
126
- expandBtn.addEventListener("click", (e) => {
127
- e.preventDefault();
128
- e.stopPropagation();
129
- openModal(container);
130
- });
131
-
132
- const handle: ToolbarHandle = {
133
- cleanup: () => {
134
- void unmount(toggleIcon);
135
- void unmount(expandIcon);
136
- },
137
- remountToggleIcon: (view) => {
138
- void unmount(toggleIcon);
139
- toggleIcon = mountToggleIcon(toggleBtn, view);
140
- },
141
- };
142
- (toolbar as HTMLElement & { _readitHandle?: ToolbarHandle })._readitHandle =
143
- handle;
144
-
145
- return toolbar;
146
- }
147
-
148
- function enhance(target: HTMLElement) {
149
- const containers = target.querySelectorAll<HTMLElement>(
150
- ".mermaid-container[data-mermaid-source]",
151
- );
152
-
153
- for (const container of containers) {
154
- if (container.dataset[ENHANCED_FLAG] === "true") continue;
155
- container.dataset[ENHANCED_FLAG] = "true";
156
-
157
- // Ensure the container can host the absolutely-positioned toolbar.
158
- container.style.position = "relative";
159
-
160
- const toolbar = buildToolbar(container);
161
- container.appendChild(toolbar);
162
- }
163
- }
164
-
165
- function cleanup(target: HTMLElement) {
166
- const toolbars = target.querySelectorAll<HTMLElement>(".mermaid-toolbar");
167
- for (const tb of toolbars) {
168
- (
169
- tb as HTMLElement & { _readitHandle?: ToolbarHandle }
170
- )._readitHandle?.cleanup();
171
- tb.remove();
172
- }
173
- const enhanced = target.querySelectorAll<HTMLElement>(
174
- ".mermaid-container[data-readit-mermaid-enhanced]",
175
- );
176
- for (const c of enhanced) {
177
- delete c.dataset[ENHANCED_FLAG];
178
- }
179
- }
180
-
181
- $effect(() => {
182
- if (!root) return;
183
- // Re-scan whenever contentVersion changes; declared so Svelte tracks it.
184
- void contentVersion;
185
- enhance(root);
186
- return () => {
187
- if (root) cleanup(root);
188
- };
189
- });
190
-
191
- // Refresh aria-labels on existing imperative toolbars when locale changes.
192
- $effect(() => {
193
- if (!root) return;
194
- void localeState.locale;
195
- const toolbars = root.querySelectorAll<HTMLElement>(".mermaid-toolbar");
196
- for (const tb of toolbars) {
197
- const container = tb.closest<HTMLElement>(".mermaid-container");
198
- const showingCode = container?.dataset.mermaidView === "code";
199
- tb.querySelector<HTMLButtonElement>('[data-action="toggle"]')?.setAttribute(
200
- "aria-label",
201
- showingCode ? t("mermaid.showDiagram") : t("mermaid.showSource"),
202
- );
203
- tb.querySelector<HTMLButtonElement>('[data-action="expand"]')?.setAttribute(
204
- "aria-label",
205
- t("mermaid.expand"),
206
- );
207
- }
208
- });
209
- </script>
210
-
211
- <MermaidModal
212
- bind:open={modalOpen}
213
- svg={modalSvg}
214
- source={modalSource}
215
- onclose={() => {
216
- modalOpen = false;
217
- }}
218
- />
@@ -1,67 +0,0 @@
1
- <script lang="ts">
2
- import { Code2, Image as ImageIcon } from "lucide-svelte";
3
- import { t } from "../stores/locale.svelte";
4
- import Dialog from "./ui/Dialog.svelte";
5
-
6
- interface Props {
7
- open: boolean;
8
- svg: string;
9
- source: string;
10
- onclose: () => void;
11
- }
12
-
13
- let { open = $bindable(false), svg, source, onclose }: Props = $props();
14
-
15
- type View = "graph" | "code";
16
- let view = $state<View>("graph");
17
-
18
- // Reset to graph view each time the modal opens so the user always
19
- // lands on the diagram first.
20
- $effect(() => {
21
- if (open) view = "graph";
22
- });
23
- </script>
24
-
25
- <Dialog
26
- bind:open
27
- {onclose}
28
- contentClass="w-[90vw] h-[90vh] max-w-[90vw]"
29
- >
30
- {#snippet header()}
31
- {t("mermaid.modalTitle")}
32
- {/snippet}
33
-
34
- {#snippet headerActions()}
35
- <div class="flex items-center gap-1 mr-8">
36
- <button
37
- type="button"
38
- onclick={() => (view = "graph")}
39
- aria-pressed={view === "graph"}
40
- class="inline-flex items-center gap-1.5 px-2.5 py-1 text-xs rounded-md text-zinc-600 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800 aria-pressed:bg-zinc-100 dark:aria-pressed:bg-zinc-800 aria-pressed:text-zinc-900 dark:aria-pressed:text-zinc-100"
41
- >
42
- <ImageIcon class="w-3.5 h-3.5" />
43
- {t("mermaid.viewGraph")}
44
- </button>
45
- <button
46
- type="button"
47
- onclick={() => (view = "code")}
48
- aria-pressed={view === "code"}
49
- class="inline-flex items-center gap-1.5 px-2.5 py-1 text-xs rounded-md text-zinc-600 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800 aria-pressed:bg-zinc-100 dark:aria-pressed:bg-zinc-800 aria-pressed:text-zinc-900 dark:aria-pressed:text-zinc-100"
50
- >
51
- <Code2 class="w-3.5 h-3.5" />
52
- {t("mermaid.viewCode")}
53
- </button>
54
- </div>
55
- {/snippet}
56
-
57
- <div class="w-full h-full overflow-auto flex items-center justify-center">
58
- {#if view === "graph"}
59
- <!-- eslint-disable-next-line -- trusted mermaid render output -->
60
- <div class="mermaid-container mermaid-modal-graph">{@html svg}</div>
61
- {:else}
62
- <pre
63
- class="w-full h-full m-0 p-4 text-xs leading-relaxed font-mono text-zinc-800 dark:text-zinc-200 bg-zinc-50 dark:bg-zinc-950 rounded-lg overflow-auto whitespace-pre"
64
- >{source}</pre>
65
- {/if}
66
- </div>
67
- </Dialog>
@@ -1,126 +0,0 @@
1
- <script lang="ts">
2
- import { Copy } from "lucide-svelte";
3
- import { app } from "../stores/app.svelte";
4
- import { t } from "../stores/locale.svelte";
5
- import Button from "./ui/Button.svelte";
6
- import Dialog from "./ui/Dialog.svelte";
7
- import Text from "./ui/Text.svelte";
8
-
9
- interface Props {
10
- open: boolean;
11
- onclose: () => void;
12
- }
13
-
14
- let { open = $bindable(false), onclose }: Props = $props();
15
-
16
- type ModalState =
17
- | { status: "idle" }
18
- | { status: "loading" }
19
- | { status: "error"; error: string }
20
- | { status: "empty"; path: string }
21
- | { status: "success"; content: string; path: string };
22
-
23
- let modalState = $state<ModalState>({ status: "idle" });
24
-
25
- $effect(() => {
26
- if (!open) {
27
- modalState = { status: "idle" };
28
- return;
29
- }
30
-
31
- modalState = { status: "loading" };
32
-
33
- const query = app.activeDocumentPath
34
- ? `?path=${encodeURIComponent(app.activeDocumentPath)}`
35
- : "";
36
-
37
- fetch(`/api/comments/raw${query}`)
38
- .then((response) => {
39
- if (!response.ok) {
40
- throw new Error("Failed to fetch raw comments");
41
- }
42
- return response.json();
43
- })
44
- .then((result) => {
45
- if (result.content === null) {
46
- modalState = { status: "empty", path: result.path };
47
- } else {
48
- modalState = {
49
- status: "success",
50
- content: result.content,
51
- path: result.path,
52
- };
53
- }
54
- })
55
- .catch((err) => {
56
- modalState = {
57
- status: "error",
58
- error: err instanceof Error ? err.message : "Unknown error",
59
- };
60
- });
61
- });
62
-
63
- async function handleCopy() {
64
- if (modalState.status !== "success") return;
65
-
66
- try {
67
- await navigator.clipboard.writeText(modalState.content);
68
- } catch {}
69
- }
70
- </script>
71
-
72
- <Dialog bind:open {onclose} contentClass="max-w-2xl max-h-[80vh]">
73
- {#snippet header()}
74
- {t("rawModal.title")}
75
- {/snippet}
76
-
77
- {#snippet headerActions()}
78
- {#if modalState.status === "success"}
79
- <Button
80
- variant="ghost"
81
- size="icon"
82
- class="size-7"
83
- onclick={handleCopy}
84
- title={t("rawModal.copyTitle")}
85
- >
86
- <Copy class="w-4 h-4" />
87
- </Button>
88
- {/if}
89
- {/snippet}
90
-
91
- {#if modalState.status === "success" || modalState.status === "empty"}
92
- <div
93
- class="px-4 py-2 border-b border-zinc-50 dark:border-zinc-800 text-xs text-zinc-400 dark:text-zinc-500 font-mono truncate -mt-4 -mx-4 mb-4"
94
- >
95
- {modalState.path}
96
- </div>
97
- {/if}
98
-
99
- {#if modalState.status === "loading"}
100
- <Text variant="caption" class="text-center py-8">
101
- {t("rawModal.loading")}
102
- </Text>
103
- {/if}
104
-
105
- {#if modalState.status === "error"}
106
- <Text variant="body" class="text-red-500 text-center py-8">
107
- {modalState.error}
108
- </Text>
109
- {/if}
110
-
111
- {#if modalState.status === "empty"}
112
- <Text variant="caption" class="text-center py-8">
113
- {t("rawModal.noComments")}
114
- </Text>
115
- {/if}
116
-
117
- {#if modalState.status === "success"}
118
- <Text
119
- variant="body"
120
- as="pre"
121
- class="text-xs font-mono whitespace-pre-wrap break-words leading-relaxed"
122
- >
123
- {modalState.content}
124
- </Text>
125
- {/if}
126
- </Dialog>
@@ -1,30 +0,0 @@
1
- <script lang="ts">
2
- import { t } from "../stores/locale.svelte";
3
- import Button from "./ui/Button.svelte";
4
- import Text from "./ui/Text.svelte";
5
-
6
- interface Props {
7
- selectionText: string;
8
- onconfirm: () => void;
9
- oncancel: () => void;
10
- }
11
-
12
- let { selectionText, onconfirm, oncancel }: Props = $props();
13
- </script>
14
-
15
- <div class="border-t border-zinc-200 dark:border-zinc-700 pt-2 pb-3 pl-6">
16
- <Text variant="body" class="mb-2">
17
- {t("reanchor.question")}
18
- </Text>
19
- <Text variant="caption" class="italic line-clamp-2 mb-2">
20
- "{selectionText}"
21
- </Text>
22
- <div class="flex gap-3 text-sm">
23
- <Button variant="link" size="sm" onclick={onconfirm}>
24
- {t("reanchor.confirm")}
25
- </Button>
26
- <Button variant="ghost" size="sm" onclick={oncancel}>
27
- {t("reanchor.cancel")}
28
- </Button>
29
- </div>
30
- </div>
@@ -1,220 +0,0 @@
1
- <script lang="ts">
2
- import { Check, ChevronDown } from "lucide-svelte";
3
- import { type Locale, Locales } from "../lib/i18n";
4
- import { cn } from "../lib/utils";
5
- import { FontFamilies, type FontFamily, ThemeModes } from "../schema";
6
- import { localeState, setLocale, t } from "../stores/locale.svelte";
7
- import {
8
- settings,
9
- updateFontFamily,
10
- updateThemeMode,
11
- } from "../stores/settings.svelte";
12
- import ShortcutList from "./ShortcutList.svelte";
13
- import Dialog from "./ui/Dialog.svelte";
14
- import DropdownMenu from "./ui/DropdownMenu.svelte";
15
- import DropdownMenuItem from "./ui/DropdownMenuItem.svelte";
16
- import Text from "./ui/Text.svelte";
17
-
18
- interface Props {
19
- open: boolean;
20
- onclose: () => void;
21
- }
22
-
23
- let { open = $bindable(false), onclose }: Props = $props();
24
-
25
- const LOCALE_OPTIONS = [
26
- { value: Locales.JA, label: "日本語" },
27
- { value: Locales.EN, label: "English" },
28
- ] as const;
29
-
30
- let themeOptions = $derived([
31
- { value: ThemeModes.SYSTEM, label: t("settings.theme.system") },
32
- { value: ThemeModes.LIGHT, label: t("settings.theme.light") },
33
- { value: ThemeModes.DARK, label: t("settings.theme.dark") },
34
- ]);
35
-
36
- let fontOptions = $derived([
37
- {
38
- value: FontFamilies.SERIF,
39
- label: t("settings.font.serif"),
40
- fontClass: "font-serif",
41
- },
42
- {
43
- value: FontFamilies.SANS_SERIF,
44
- label: t("settings.font.sansSerif"),
45
- fontClass: "font-sans",
46
- },
47
- ]);
48
-
49
- let activeTheme = $derived(
50
- themeOptions.find((o) => o.value === settings.themeMode) ?? themeOptions[0],
51
- );
52
- let activeFont = $derived(
53
- fontOptions.find((o) => o.value === settings.fontFamily) ?? fontOptions[0],
54
- );
55
- let activeLocale = $derived(
56
- LOCALE_OPTIONS.find((o) => o.value === localeState.locale) ??
57
- LOCALE_OPTIONS[0],
58
- );
59
-
60
- const triggerClassName = cn(
61
- "inline-flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-sm",
62
- "border border-zinc-200 dark:border-zinc-700",
63
- "bg-white dark:bg-zinc-800",
64
- "text-zinc-700 dark:text-zinc-300",
65
- "hover:bg-zinc-50 dark:hover:bg-zinc-700/50",
66
- "transition-colors cursor-pointer",
67
- );
68
-
69
- let themeDropdownOpen = $state(false);
70
- let fontDropdownOpen = $state(false);
71
- let localeDropdownOpen = $state(false);
72
- </script>
73
-
74
- <Dialog bind:open {onclose} contentClass="max-w-md">
75
- {#snippet header()}
76
- {t("settings.title")}
77
- {/snippet}
78
-
79
- <div class="space-y-4">
80
- <div>
81
- <Text variant="overline" as="h3" class="mb-3">
82
- {t("settings.theme")}
83
- </Text>
84
- <DropdownMenu bind:open={themeDropdownOpen} align="start" contentClass="min-w-[160px]">
85
- {#snippet trigger()}
86
- <button type="button" class={triggerClassName}>
87
- {#if activeTheme.value === ThemeModes.SYSTEM}
88
- <span
89
- class="size-2.5 rounded-full bg-gradient-to-r from-amber-400 to-indigo-400"
90
- ></span>
91
- {:else}
92
- <span
93
- class={cn(
94
- "size-2.5 rounded-full",
95
- activeTheme.value === ThemeModes.LIGHT
96
- ? "bg-amber-400"
97
- : "bg-indigo-400",
98
- )}
99
- ></span>
100
- {/if}
101
- <span
102
- class="text-[10px] font-semibold leading-none text-zinc-500 dark:text-zinc-400 bg-zinc-100 dark:bg-zinc-800 rounded px-1 py-0.5"
103
- >Aa</span>
104
- <span>{activeTheme.label}</span>
105
- <ChevronDown class="size-3 text-zinc-400 dark:text-zinc-500" />
106
- </button>
107
- {/snippet}
108
-
109
- {#each themeOptions as option (option.value)}
110
- <DropdownMenuItem
111
- onselect={() => {
112
- updateThemeMode(option.value);
113
- themeDropdownOpen = false;
114
- }}
115
- class="flex items-center gap-2"
116
- >
117
- {#if option.value === ThemeModes.SYSTEM}
118
- <span
119
- class="size-2.5 rounded-full bg-gradient-to-r from-amber-400 to-indigo-400"
120
- ></span>
121
- {:else}
122
- <span
123
- class={cn(
124
- "size-2.5 rounded-full",
125
- option.value === ThemeModes.LIGHT
126
- ? "bg-amber-400"
127
- : "bg-indigo-400",
128
- )}
129
- ></span>
130
- {/if}
131
- <span
132
- class="text-[10px] font-semibold leading-none text-zinc-500 dark:text-zinc-400 bg-zinc-100 dark:bg-zinc-800 rounded px-1 py-0.5"
133
- >Aa</span>
134
- <span class="flex-1">{option.label}</span>
135
- {#if settings.themeMode === option.value}
136
- <Check class="size-3.5 text-zinc-500 dark:text-zinc-400" />
137
- {/if}
138
- </DropdownMenuItem>
139
- {/each}
140
- </DropdownMenu>
141
- </div>
142
-
143
- <div>
144
- <Text variant="overline" as="h3" class="mb-3">
145
- {t("settings.font")}
146
- </Text>
147
- <DropdownMenu bind:open={fontDropdownOpen} align="start" contentClass="min-w-[160px]">
148
- {#snippet trigger()}
149
- <button type="button" class={triggerClassName}>
150
- <span
151
- class={cn(
152
- "text-[10px] font-semibold leading-none text-zinc-500 dark:text-zinc-400 bg-zinc-100 dark:bg-zinc-800 rounded px-1 py-0.5",
153
- activeFont.fontClass,
154
- )}
155
- >Aa</span>
156
- <span>{activeFont.label}</span>
157
- <ChevronDown class="size-3 text-zinc-400 dark:text-zinc-500" />
158
- </button>
159
- {/snippet}
160
-
161
- {#each fontOptions as option (option.value)}
162
- <DropdownMenuItem
163
- onselect={() => {
164
- updateFontFamily(option.value as FontFamily);
165
- fontDropdownOpen = false;
166
- }}
167
- class="flex items-center gap-2"
168
- >
169
- <span
170
- class={cn(
171
- "text-[10px] font-semibold leading-none text-zinc-500 dark:text-zinc-400 bg-zinc-100 dark:bg-zinc-800 rounded px-1 py-0.5",
172
- option.fontClass,
173
- )}
174
- >Aa</span>
175
- <span class="flex-1">{option.label}</span>
176
- {#if settings.fontFamily === option.value}
177
- <Check class="size-3.5 text-zinc-500 dark:text-zinc-400" />
178
- {/if}
179
- </DropdownMenuItem>
180
- {/each}
181
- </DropdownMenu>
182
- </div>
183
-
184
- <div>
185
- <Text variant="overline" as="h3" class="mb-3">
186
- {t("settings.language")}
187
- </Text>
188
- <DropdownMenu bind:open={localeDropdownOpen} align="start" contentClass="min-w-[160px]">
189
- {#snippet trigger()}
190
- <button type="button" class={triggerClassName}>
191
- <span>{activeLocale.label}</span>
192
- <ChevronDown class="size-3 text-zinc-400 dark:text-zinc-500" />
193
- </button>
194
- {/snippet}
195
-
196
- {#each LOCALE_OPTIONS as option (option.value)}
197
- <DropdownMenuItem
198
- onselect={() => {
199
- setLocale(option.value as Locale);
200
- localeDropdownOpen = false;
201
- }}
202
- class="flex items-center gap-2"
203
- >
204
- <span class="flex-1">{option.label}</span>
205
- {#if localeState.locale === option.value}
206
- <Check class="size-3.5 text-zinc-500 dark:text-zinc-400" />
207
- {/if}
208
- </DropdownMenuItem>
209
- {/each}
210
- </DropdownMenu>
211
- </div>
212
-
213
- <div>
214
- <Text variant="overline" as="h3" class="mb-3">
215
- {t("shortcuts.title")}
216
- </Text>
217
- <ShortcutList />
218
- </div>
219
- </div>
220
- </Dialog>