create-obsidian-arrow 0.2.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +10 -7
  2. package/index.mjs +29 -10
  3. package/package.json +1 -1
  4. package/template/AGENTS.md +31 -5
  5. package/template/README.md +47 -5
  6. package/template/_gitignore +3 -0
  7. package/template/docs/prompts/agent-setup.md +26 -13
  8. package/template/docs/prompts/update-existing.md +13 -9
  9. package/template/docs/workflow.md +21 -8
  10. package/template/package.json +6 -2
  11. package/template/pnpm-lock.yaml +197 -0
  12. package/template/src/components/DiffViewer.ts +42 -0
  13. package/template/src/components/SettingsPanel.ts +1 -1
  14. package/template/src/main.ts +4 -3
  15. package/template/src/utilities.css +205 -0
  16. package/template/stories/DiffViewer.stories.ts +75 -0
  17. package/template/stories/SettingsPanel.stories.ts +11 -0
  18. package/template/stories/Toggle.stories.ts +28 -0
  19. package/template/test/token-utils.test.mjs +65 -0
  20. package/template/test/viewer-derive.test.mjs +65 -0
  21. package/template/test/viewer-stories.test.mjs +44 -0
  22. package/template/{src → tools}/router/client.ts +15 -2
  23. package/template/tools/router/routeToPage.ts +104 -0
  24. package/template/{src → tools}/sandbox/home.ts +55 -26
  25. package/template/tools/sandbox/sandbox.css +474 -0
  26. package/template/tools/viewer/ClassesPage.ts +37 -0
  27. package/template/tools/viewer/ComponentsIndex.ts +56 -0
  28. package/template/tools/viewer/StoryPage.ts +73 -0
  29. package/template/tools/viewer/TokensPage.ts +82 -0
  30. package/template/tools/viewer/derive.ts +91 -0
  31. package/template/tools/viewer/discovery.ts +64 -0
  32. package/template/tools/viewer/obsidian-classes.ts +269 -0
  33. package/template/tools/viewer/sidebar.ts +55 -0
  34. package/template/tools/viewer/stories.ts +83 -0
  35. package/template/tools/viewer/token-utils.ts +84 -0
  36. package/template/tools/viewer/tokens.ts +30 -0
  37. package/template/src/examples/ExamplesIndex.ts +0 -36
  38. package/template/src/examples/registry.ts +0 -26
  39. package/template/src/router/routeToPage.ts +0 -57
  40. package/template/src/sandbox/sandbox.css +0 -130
  41. /package/template/{src → tools}/sandbox/frame.ts +0 -0
  42. /package/template/{src → tools}/sandbox/layout.ts +0 -0
  43. /package/template/{src → tools}/sandbox/shell.ts +0 -0
  44. /package/template/{src → tools}/sandbox/theme.ts +0 -0
  45. /package/template/{src → tools}/sandbox/toolbar.ts +0 -0
@@ -14,6 +14,18 @@ importers:
14
14
  '@arrow-js/framework':
15
15
  specifier: ^1.0.6
16
16
  version: 1.0.6
17
+ '@codemirror/lang-markdown':
18
+ specifier: ^6.5.0
19
+ version: 6.5.0
20
+ '@codemirror/merge':
21
+ specifier: ^6.12.2
22
+ version: 6.12.2
23
+ '@codemirror/state':
24
+ specifier: ^6.7.0
25
+ version: 6.7.0
26
+ '@codemirror/view':
27
+ specifier: ^6.43.4
28
+ version: 6.43.4
17
29
  devDependencies:
18
30
  '@biomejs/biome':
19
31
  specifier: ^1.9.4
@@ -99,6 +111,36 @@ packages:
99
111
  cpu: [x64]
100
112
  os: [win32]
101
113
 
114
+ '@codemirror/autocomplete@6.20.3':
115
+ resolution: {integrity: sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==}
116
+
117
+ '@codemirror/lang-css@6.3.1':
118
+ resolution: {integrity: sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==}
119
+
120
+ '@codemirror/lang-html@6.4.11':
121
+ resolution: {integrity: sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw==}
122
+
123
+ '@codemirror/lang-javascript@6.2.5':
124
+ resolution: {integrity: sha512-zD4e5mS+50htS7F+TYjBPsiIFGanfVqg4HyUz6WNFikgOPf2BgKlx+TQedI1w6n/IqRBVBbBWmGFdLB/7uxO4A==}
125
+
126
+ '@codemirror/lang-markdown@6.5.0':
127
+ resolution: {integrity: sha512-0K40bZ35jpHya6FriukbgaleaqzBLZfOh7HuzqbMxBXkbYMJDxfF39c23xOgxFezR+3G+tR2/Mup+Xk865OMvw==}
128
+
129
+ '@codemirror/language@6.12.4':
130
+ resolution: {integrity: sha512-1q4PaT+o6PbgpkJt4Q8Fv5XJxTy4FUZ4MWETtyiDw3J0Pyr9E2vqcKL+k9wcvjNTIsauxvE7OfmWj3FRPHQ76A==}
131
+
132
+ '@codemirror/lint@6.9.7':
133
+ resolution: {integrity: sha512-28/+iWLYxKxsvGYhSYL7zaCZqLz5+FFFDq9tVsvGv9kv8RY4fFAchJ5WX9M3YrrRlTIsECjsXPqeNgnSmNP2dg==}
134
+
135
+ '@codemirror/merge@6.12.2':
136
+ resolution: {integrity: sha512-V8JvyAPjHbPupqP7BeMcsdsYCbyPij74jxIbaIJDORI+VZzW44zFmon8bF+oxGWvOKhcRmkiUMXd8MxHr3YA2w==}
137
+
138
+ '@codemirror/state@6.7.0':
139
+ resolution: {integrity: sha512-Zbl9NyscLMZkfXPQnNAIIAFftidrA1UbcJEIMp24C0Bukc2I5T8wJS0wsXYsnDOqCFJUeJ1BITGNs5CqPDSmSg==}
140
+
141
+ '@codemirror/view@6.43.4':
142
+ resolution: {integrity: sha512-YImu23iyKfncJzT7sRy+rEqEhSc8RhOHqDxwy4WzXRKJwYm6iwf/9OJk5ctCAdZ6yi2ZqaGEvmf55fSVqMDrgg==}
143
+
102
144
  '@csstools/color-helpers@5.1.0':
103
145
  resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==}
104
146
  engines: {node: '>=18'}
@@ -136,6 +178,30 @@ packages:
136
178
  '@emnapi/wasi-threads@1.2.2':
137
179
  resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==}
138
180
 
181
+ '@lezer/common@1.5.2':
182
+ resolution: {integrity: sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==}
183
+
184
+ '@lezer/css@1.3.4':
185
+ resolution: {integrity: sha512-N+tn9tej2hPvyKgHEApMOQfHczDJCwxrRFS3SPn9QjYN+uwHvEDnCgKRrb3mxDYxRS8sKMM8fhC3+lc04Abz5Q==}
186
+
187
+ '@lezer/highlight@1.2.3':
188
+ resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==}
189
+
190
+ '@lezer/html@1.3.13':
191
+ resolution: {integrity: sha512-oI7n6NJml729m7pjm9lvLvmXbdoMoi2f+1pwSDJkl9d68zGr7a9Btz8NdHTGQZtW2DA25ybeuv/SyDb9D5tseg==}
192
+
193
+ '@lezer/javascript@1.5.4':
194
+ resolution: {integrity: sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==}
195
+
196
+ '@lezer/lr@1.4.10':
197
+ resolution: {integrity: sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==}
198
+
199
+ '@lezer/markdown@1.6.4':
200
+ resolution: {integrity: sha512-N0SxazMj4k65DBfaf1azqtMZd6u7MqluP84/NZnB/io8Td9aleFmAhz9hcbvSfsxT5tdYlJ5qgv5aMJGY4zEtA==}
201
+
202
+ '@marijn/find-cluster-break@1.0.3':
203
+ resolution: {integrity: sha512-FY+MKLBoTsLNJF/eLWaOsXGdz6uh3Iu1axjPf6TUq92IYumcTcXWHoS747JARLkcdlJ/Waiaxc5wQfFO8jC6NA==}
204
+
139
205
  '@napi-rs/wasm-runtime@1.1.6':
140
206
  resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==}
141
207
  peerDependencies:
@@ -288,6 +354,9 @@ packages:
288
354
  resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==}
289
355
  engines: {node: '>=18'}
290
356
 
357
+ crelt@1.0.7:
358
+ resolution: {integrity: sha512-aK6BbWfhf4U/wCcLHKPJl/xa6VkVstRaPywWtMKGwuOLc/wZTyQYuoxgvZnNsBvv7Kg3YTBQYYBCggcviQczuA==}
359
+
291
360
  cross-spawn@7.0.6:
292
361
  resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
293
362
  engines: {node: '>= 8'}
@@ -648,6 +717,9 @@ packages:
648
717
  resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
649
718
  engines: {node: '>=12'}
650
719
 
720
+ style-mod@4.1.3:
721
+ resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==}
722
+
651
723
  symbol-tree@3.2.4:
652
724
  resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
653
725
 
@@ -731,6 +803,9 @@ packages:
731
803
  yaml:
732
804
  optional: true
733
805
 
806
+ w3c-keyname@2.2.8:
807
+ resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
808
+
734
809
  w3c-xmlserializer@5.0.0:
735
810
  resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
736
811
  engines: {node: '>=18'}
@@ -843,6 +918,87 @@ snapshots:
843
918
  '@biomejs/cli-win32-x64@1.9.4':
844
919
  optional: true
845
920
 
921
+ '@codemirror/autocomplete@6.20.3':
922
+ dependencies:
923
+ '@codemirror/language': 6.12.4
924
+ '@codemirror/state': 6.7.0
925
+ '@codemirror/view': 6.43.4
926
+ '@lezer/common': 1.5.2
927
+
928
+ '@codemirror/lang-css@6.3.1':
929
+ dependencies:
930
+ '@codemirror/autocomplete': 6.20.3
931
+ '@codemirror/language': 6.12.4
932
+ '@codemirror/state': 6.7.0
933
+ '@lezer/common': 1.5.2
934
+ '@lezer/css': 1.3.4
935
+
936
+ '@codemirror/lang-html@6.4.11':
937
+ dependencies:
938
+ '@codemirror/autocomplete': 6.20.3
939
+ '@codemirror/lang-css': 6.3.1
940
+ '@codemirror/lang-javascript': 6.2.5
941
+ '@codemirror/language': 6.12.4
942
+ '@codemirror/state': 6.7.0
943
+ '@codemirror/view': 6.43.4
944
+ '@lezer/common': 1.5.2
945
+ '@lezer/css': 1.3.4
946
+ '@lezer/html': 1.3.13
947
+
948
+ '@codemirror/lang-javascript@6.2.5':
949
+ dependencies:
950
+ '@codemirror/autocomplete': 6.20.3
951
+ '@codemirror/language': 6.12.4
952
+ '@codemirror/lint': 6.9.7
953
+ '@codemirror/state': 6.7.0
954
+ '@codemirror/view': 6.43.4
955
+ '@lezer/common': 1.5.2
956
+ '@lezer/javascript': 1.5.4
957
+
958
+ '@codemirror/lang-markdown@6.5.0':
959
+ dependencies:
960
+ '@codemirror/autocomplete': 6.20.3
961
+ '@codemirror/lang-html': 6.4.11
962
+ '@codemirror/language': 6.12.4
963
+ '@codemirror/state': 6.7.0
964
+ '@codemirror/view': 6.43.4
965
+ '@lezer/common': 1.5.2
966
+ '@lezer/markdown': 1.6.4
967
+
968
+ '@codemirror/language@6.12.4':
969
+ dependencies:
970
+ '@codemirror/state': 6.7.0
971
+ '@codemirror/view': 6.43.4
972
+ '@lezer/common': 1.5.2
973
+ '@lezer/highlight': 1.2.3
974
+ '@lezer/lr': 1.4.10
975
+ style-mod: 4.1.3
976
+
977
+ '@codemirror/lint@6.9.7':
978
+ dependencies:
979
+ '@codemirror/state': 6.7.0
980
+ '@codemirror/view': 6.43.4
981
+ crelt: 1.0.7
982
+
983
+ '@codemirror/merge@6.12.2':
984
+ dependencies:
985
+ '@codemirror/language': 6.12.4
986
+ '@codemirror/state': 6.7.0
987
+ '@codemirror/view': 6.43.4
988
+ '@lezer/highlight': 1.2.3
989
+ style-mod: 4.1.3
990
+
991
+ '@codemirror/state@6.7.0':
992
+ dependencies:
993
+ '@marijn/find-cluster-break': 1.0.3
994
+
995
+ '@codemirror/view@6.43.4':
996
+ dependencies:
997
+ '@codemirror/state': 6.7.0
998
+ crelt: 1.0.7
999
+ style-mod: 4.1.3
1000
+ w3c-keyname: 2.2.8
1001
+
846
1002
  '@csstools/color-helpers@5.1.0': {}
847
1003
 
848
1004
  '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
@@ -879,6 +1035,41 @@ snapshots:
879
1035
  tslib: 2.8.1
880
1036
  optional: true
881
1037
 
1038
+ '@lezer/common@1.5.2': {}
1039
+
1040
+ '@lezer/css@1.3.4':
1041
+ dependencies:
1042
+ '@lezer/common': 1.5.2
1043
+ '@lezer/highlight': 1.2.3
1044
+ '@lezer/lr': 1.4.10
1045
+
1046
+ '@lezer/highlight@1.2.3':
1047
+ dependencies:
1048
+ '@lezer/common': 1.5.2
1049
+
1050
+ '@lezer/html@1.3.13':
1051
+ dependencies:
1052
+ '@lezer/common': 1.5.2
1053
+ '@lezer/highlight': 1.2.3
1054
+ '@lezer/lr': 1.4.10
1055
+
1056
+ '@lezer/javascript@1.5.4':
1057
+ dependencies:
1058
+ '@lezer/common': 1.5.2
1059
+ '@lezer/highlight': 1.2.3
1060
+ '@lezer/lr': 1.4.10
1061
+
1062
+ '@lezer/lr@1.4.10':
1063
+ dependencies:
1064
+ '@lezer/common': 1.5.2
1065
+
1066
+ '@lezer/markdown@1.6.4':
1067
+ dependencies:
1068
+ '@lezer/common': 1.5.2
1069
+ '@lezer/highlight': 1.2.3
1070
+
1071
+ '@marijn/find-cluster-break@1.0.3': {}
1072
+
882
1073
  '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)':
883
1074
  dependencies:
884
1075
  '@emnapi/core': 1.11.1
@@ -986,6 +1177,8 @@ snapshots:
986
1177
 
987
1178
  commander@13.1.0: {}
988
1179
 
1180
+ crelt@1.0.7: {}
1181
+
989
1182
  cross-spawn@7.0.6:
990
1183
  dependencies:
991
1184
  path-key: 3.1.1
@@ -1326,6 +1519,8 @@ snapshots:
1326
1519
 
1327
1520
  strip-final-newline@3.0.0: {}
1328
1521
 
1522
+ style-mod@4.1.3: {}
1523
+
1329
1524
  symbol-tree@3.2.4: {}
1330
1525
 
1331
1526
  tinyglobby@0.2.17:
@@ -1372,6 +1567,8 @@ snapshots:
1372
1567
  fsevents: 2.3.3
1373
1568
  yaml: 2.9.0
1374
1569
 
1570
+ w3c-keyname@2.2.8: {}
1571
+
1375
1572
  w3c-xmlserializer@5.0.0:
1376
1573
  dependencies:
1377
1574
  xml-name-validator: 5.0.0
@@ -0,0 +1,42 @@
1
+ import type { ArrowExpression } from "@arrow-js/core";
2
+ import { markdown } from "@codemirror/lang-markdown";
3
+ import { MergeView } from "@codemirror/merge";
4
+ import { EditorState } from "@codemirror/state";
5
+
6
+ export interface DiffViewerOptions {
7
+ original: string;
8
+ modified: string;
9
+ /** Which side shows original (a) and which shows modified (b). Default: a-b */
10
+ orientation?: "a-b" | "b-a";
11
+ }
12
+
13
+ /**
14
+ * CodeMirror 6 MergeView — side-by-side diff using the same CM6 engine as
15
+ * Obsidian's editor. Obsidian's app.css styles .cm-* classes automatically,
16
+ * so this looks native without additional theming.
17
+ *
18
+ * Arrow's ArrowExpression type doesn't include Node but accepts it at runtime.
19
+ * The cast is intentional — CM6 manages its own DOM and Arrow inserts it as-is.
20
+ */
21
+ export function DiffViewer(options: DiffViewerOptions): ArrowExpression {
22
+ const el = document.createElement("div");
23
+ el.className = "oas-diff-viewer";
24
+
25
+ new MergeView({
26
+ a: {
27
+ doc: options.original,
28
+ extensions: [markdown(), EditorState.readOnly.of(true)],
29
+ },
30
+ b: {
31
+ doc: options.modified,
32
+ extensions: [markdown(), EditorState.readOnly.of(true)],
33
+ },
34
+ parent: el,
35
+ orientation: options.orientation ?? "a-b",
36
+ highlightChanges: true,
37
+ collapseUnchanged: { margin: 3, minSize: 4 },
38
+ });
39
+
40
+ // biome-ignore lint/suspicious/noExplicitAny: Arrow accepts Node at runtime; type doesn't include it
41
+ return el as unknown as ArrowExpression;
42
+ }
@@ -70,7 +70,7 @@ function rebuildIndex(): void {
70
70
  * live state; clicking flips it in place (deep reactivity re-runs only the
71
71
  * tracked expressions below — no list re-render).
72
72
  */
73
- const Toggle = (enabled: () => boolean, onToggle: () => void): ArrowTemplate => html`<div
73
+ export const Toggle = (enabled: () => boolean, onToggle: () => void): ArrowTemplate => html`<div
74
74
  class="${() => `checkbox-container${enabled() ? " is-enabled" : ""}`}"
75
75
  @click="${onToggle}"
76
76
  >
@@ -2,9 +2,10 @@
2
2
  // This is the one extra line a plugin would add to adopt @arrow-js/framework.
3
3
  import "@arrow-js/framework";
4
4
 
5
- import { startRouter } from "./router/client";
6
- import { applyTheme } from "./sandbox/theme";
7
- import "./sandbox/sandbox.css";
5
+ import { startRouter } from "../tools/router/client";
6
+ import { applyTheme } from "../tools/sandbox/theme";
7
+ import "./utilities.css";
8
+ import "../tools/sandbox/sandbox.css";
8
9
 
9
10
  applyTheme();
10
11
 
@@ -0,0 +1,205 @@
1
+ /*
2
+ * Portable utility classes for Obsidian Arrow components.
3
+ *
4
+ * These travel with component ports into the plugin — copy this file once into
5
+ * the plugin's styles directory and import it alongside your component CSS.
6
+ * All classes are prefixed `oas-` to avoid any conflict with Obsidian's own
7
+ * selectors. Values use Obsidian's CSS custom property scale so they track the
8
+ * active theme automatically.
9
+ */
10
+
11
+ /* ── Layout ──────────────────────────────────────────────────── */
12
+ .oas-flex {
13
+ display: flex;
14
+ }
15
+ .oas-inline-flex {
16
+ display: inline-flex;
17
+ }
18
+ .oas-flex-col {
19
+ flex-direction: column;
20
+ }
21
+ .oas-flex-wrap {
22
+ flex-wrap: wrap;
23
+ }
24
+ .oas-items-start {
25
+ align-items: flex-start;
26
+ }
27
+ .oas-items-center {
28
+ align-items: center;
29
+ }
30
+ .oas-items-end {
31
+ align-items: flex-end;
32
+ }
33
+ .oas-items-baseline {
34
+ align-items: baseline;
35
+ }
36
+ .oas-justify-start {
37
+ justify-content: flex-start;
38
+ }
39
+ .oas-justify-center {
40
+ justify-content: center;
41
+ }
42
+ .oas-justify-end {
43
+ justify-content: flex-end;
44
+ }
45
+ .oas-justify-between {
46
+ justify-content: space-between;
47
+ }
48
+ .oas-grow {
49
+ flex: 1;
50
+ }
51
+ .oas-shrink-0 {
52
+ flex-shrink: 0;
53
+ }
54
+
55
+ /* ── Spacing (Obsidian 4-px step scale) ─────────────────────── */
56
+ .oas-gap-1 {
57
+ gap: var(--size-4-1);
58
+ }
59
+ .oas-gap-2 {
60
+ gap: var(--size-4-2);
61
+ }
62
+ .oas-gap-3 {
63
+ gap: var(--size-4-3);
64
+ }
65
+ .oas-gap-4 {
66
+ gap: var(--size-4-4);
67
+ }
68
+ .oas-p-1 {
69
+ padding: var(--size-4-1);
70
+ }
71
+ .oas-p-2 {
72
+ padding: var(--size-4-2);
73
+ }
74
+ .oas-p-3 {
75
+ padding: var(--size-4-3);
76
+ }
77
+ .oas-p-4 {
78
+ padding: var(--size-4-4);
79
+ }
80
+ .oas-px-2 {
81
+ padding-inline: var(--size-4-2);
82
+ }
83
+ .oas-px-3 {
84
+ padding-inline: var(--size-4-3);
85
+ }
86
+ .oas-py-1 {
87
+ padding-block: var(--size-4-1);
88
+ }
89
+ .oas-py-2 {
90
+ padding-block: var(--size-4-2);
91
+ }
92
+ .oas-py-3 {
93
+ padding-block: var(--size-4-3);
94
+ }
95
+ .oas-mt-1 {
96
+ margin-top: var(--size-4-1);
97
+ }
98
+ .oas-mt-2 {
99
+ margin-top: var(--size-4-2);
100
+ }
101
+ .oas-mt-3 {
102
+ margin-top: var(--size-4-3);
103
+ }
104
+ .oas-mb-1 {
105
+ margin-bottom: var(--size-4-1);
106
+ }
107
+ .oas-mb-2 {
108
+ margin-bottom: var(--size-4-2);
109
+ }
110
+ .oas-mb-3 {
111
+ margin-bottom: var(--size-4-3);
112
+ }
113
+ .oas-ml-auto {
114
+ margin-left: auto;
115
+ }
116
+
117
+ /* ── Sizing ──────────────────────────────────────────────────── */
118
+ .oas-w-full {
119
+ width: 100%;
120
+ }
121
+ .oas-min-w-0 {
122
+ min-width: 0;
123
+ }
124
+ .oas-min-h-0 {
125
+ min-height: 0;
126
+ }
127
+
128
+ /* ── Typography ──────────────────────────────────────────────── */
129
+ .oas-text-xs {
130
+ font-size: var(--font-ui-smaller);
131
+ }
132
+ .oas-text-sm {
133
+ font-size: var(--font-ui-small);
134
+ }
135
+ .oas-text-md {
136
+ font-size: var(--font-ui-medium);
137
+ }
138
+ .oas-font-medium {
139
+ font-weight: var(--font-medium);
140
+ }
141
+ .oas-font-semibold {
142
+ font-weight: var(--font-semibold);
143
+ }
144
+ .oas-font-mono {
145
+ font-family: var(--font-monospace);
146
+ }
147
+ .oas-leading-1 {
148
+ line-height: 1;
149
+ }
150
+ .oas-text-normal {
151
+ color: var(--text-normal);
152
+ }
153
+ .oas-text-muted {
154
+ color: var(--text-muted);
155
+ }
156
+ .oas-text-faint {
157
+ color: var(--text-faint);
158
+ }
159
+ .oas-text-accent {
160
+ color: var(--text-accent);
161
+ }
162
+ .oas-text-success {
163
+ color: var(--text-success);
164
+ }
165
+ .oas-text-error {
166
+ color: var(--text-error);
167
+ }
168
+
169
+ /* ── Overflow ────────────────────────────────────────────────── */
170
+ .oas-truncate {
171
+ overflow: hidden;
172
+ text-overflow: ellipsis;
173
+ white-space: nowrap;
174
+ }
175
+ .oas-overflow-hidden {
176
+ overflow: hidden;
177
+ }
178
+ .oas-overflow-auto {
179
+ overflow: auto;
180
+ }
181
+
182
+ /* ── Border ──────────────────────────────────────────────────── */
183
+ .oas-border {
184
+ border: 1px solid var(--background-modifier-border);
185
+ }
186
+ .oas-border-b {
187
+ border-bottom: 1px solid var(--background-modifier-border);
188
+ }
189
+ .oas-border-t {
190
+ border-top: 1px solid var(--background-modifier-border);
191
+ }
192
+ .oas-rounded-s {
193
+ border-radius: var(--radius-s);
194
+ }
195
+ .oas-rounded-m {
196
+ border-radius: var(--radius-m);
197
+ }
198
+
199
+ /* ── Interaction ─────────────────────────────────────────────── */
200
+ .oas-cursor-pointer {
201
+ cursor: pointer;
202
+ }
203
+ .oas-select-none {
204
+ user-select: none;
205
+ }
@@ -0,0 +1,75 @@
1
+ import { DiffViewer } from "../src/components/DiffViewer";
2
+ import { defineStories } from "../tools/viewer/stories";
3
+
4
+ const ORIGINAL = `---
5
+ title: Meeting Notes
6
+ status: draft
7
+ ---
8
+
9
+ # Team Standup
10
+
11
+ Quick notes from today's standup.
12
+
13
+ ## Done
14
+
15
+ - Reviewed the PR for the search panel
16
+ - Fixed the token filter in the reference viewer
17
+
18
+ ## In Progress
19
+
20
+ - Arrow component for the diff viewer
21
+ - Documentation updates
22
+
23
+ ## Notes
24
+
25
+ See the project board for full task breakdown.
26
+ `;
27
+
28
+ const MODIFIED = `---
29
+ title: Meeting Notes
30
+ status: complete
31
+ tags: [standup, team]
32
+ ---
33
+
34
+ # Team Standup — 2026-07-02
35
+
36
+ Notes from today's standup.
37
+
38
+ ## Done
39
+
40
+ - Reviewed and merged the PR for the search panel
41
+ - Fixed the token filter in the reference viewer
42
+ - Added DiffViewer component to the sandbox
43
+
44
+ ## In Progress
45
+
46
+ - Documentation updates
47
+ - Editor pane integration
48
+
49
+ ## Notes
50
+
51
+ See the project board for full task breakdown.
52
+ Next standup: Thursday.
53
+ `;
54
+
55
+ const SHORT_ORIGINAL = `function greet(name: string): string {
56
+ return "Hello, " + name;
57
+ }
58
+ `;
59
+
60
+ const SHORT_MODIFIED = `function greet(name: string, greeting = "Hello"): string {
61
+ return \`\${greeting}, \${name}!\`;
62
+ }
63
+ `;
64
+
65
+ export default defineStories({
66
+ description:
67
+ "CodeMirror 6 MergeView — side-by-side diff using the same engine as Obsidian's editor. Changed lines highlight inline; unchanged sections collapse.",
68
+ status: "draft",
69
+ variants: {
70
+ "markdown document": () => DiffViewer({ original: ORIGINAL, modified: MODIFIED }),
71
+ "code snippet": () => DiffViewer({ original: SHORT_ORIGINAL, modified: SHORT_MODIFIED }),
72
+ "reversed (b-a)": () =>
73
+ DiffViewer({ original: ORIGINAL, modified: MODIFIED, orientation: "b-a" }),
74
+ },
75
+ });
@@ -0,0 +1,11 @@
1
+ import { SettingsPanel } from "../src/components/SettingsPanel";
2
+ import { defineStories } from "../tools/viewer/stories";
3
+
4
+ export default defineStories({
5
+ description: "Vertical tabs, toggles, a keyed list, and an async boundary() section.",
6
+ status: "live",
7
+ variants: {
8
+ default: () => SettingsPanel(),
9
+ },
10
+ children: ["toggle"],
11
+ });
@@ -0,0 +1,28 @@
1
+ import { reactive } from "@arrow-js/core";
2
+ import { Toggle } from "../src/components/SettingsPanel";
3
+ import { defineStories } from "../tools/viewer/stories";
4
+
5
+ export default defineStories({
6
+ description: "Obsidian checkbox-container toggle used by SettingsPanel.",
7
+ componentPath: "src/components/SettingsPanel.ts",
8
+ status: "live",
9
+ variants: {
10
+ interactive: () => {
11
+ const state = reactive({ on: true });
12
+ return Toggle(
13
+ () => state.on,
14
+ () => {
15
+ state.on = !state.on;
16
+ }
17
+ );
18
+ },
19
+ off: {
20
+ render: () =>
21
+ Toggle(
22
+ () => false,
23
+ () => {}
24
+ ),
25
+ notes: "Static off state (click does nothing).",
26
+ },
27
+ },
28
+ });