@miethe/ui 0.3.0 → 0.6.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 (168) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +776 -9
  3. package/dist/components/content-viewer/ArticleViewer.d.ts +42 -0
  4. package/dist/components/content-viewer/ArticleViewer.d.ts.map +1 -0
  5. package/dist/components/content-viewer/ArticleViewer.js +321 -0
  6. package/dist/components/content-viewer/ArticleViewer.js.map +1 -0
  7. package/dist/components/content-viewer/FrontmatterHeader.d.ts +32 -0
  8. package/dist/components/content-viewer/FrontmatterHeader.d.ts.map +1 -0
  9. package/dist/components/content-viewer/FrontmatterHeader.js +95 -0
  10. package/dist/components/content-viewer/FrontmatterHeader.js.map +1 -0
  11. package/dist/components/content-viewer/callouts/Callout.d.ts +43 -0
  12. package/dist/components/content-viewer/callouts/Callout.d.ts.map +1 -0
  13. package/dist/components/content-viewer/callouts/Callout.js +86 -0
  14. package/dist/components/content-viewer/callouts/Callout.js.map +1 -0
  15. package/dist/components/content-viewer/callouts/index.d.ts +2 -0
  16. package/dist/components/content-viewer/callouts/index.d.ts.map +1 -0
  17. package/dist/components/content-viewer/callouts/index.js +2 -0
  18. package/dist/components/content-viewer/callouts/index.js.map +1 -0
  19. package/dist/components/content-viewer/index.d.ts +21 -0
  20. package/dist/components/content-viewer/index.d.ts.map +1 -0
  21. package/dist/components/content-viewer/index.js +29 -0
  22. package/dist/components/content-viewer/index.js.map +1 -0
  23. package/dist/components/content-viewer/plugins/index.d.ts +5 -0
  24. package/dist/components/content-viewer/plugins/index.d.ts.map +1 -0
  25. package/dist/components/content-viewer/plugins/index.js +5 -0
  26. package/dist/components/content-viewer/plugins/index.js.map +1 -0
  27. package/dist/components/content-viewer/plugins/lowlightLoader.d.ts +63 -0
  28. package/dist/components/content-viewer/plugins/lowlightLoader.d.ts.map +1 -0
  29. package/dist/components/content-viewer/plugins/lowlightLoader.js +120 -0
  30. package/dist/components/content-viewer/plugins/lowlightLoader.js.map +1 -0
  31. package/dist/components/content-viewer/plugins/rehypeCodeHighlight.d.ts +44 -0
  32. package/dist/components/content-viewer/plugins/rehypeCodeHighlight.d.ts.map +1 -0
  33. package/dist/components/content-viewer/plugins/rehypeCodeHighlight.js +122 -0
  34. package/dist/components/content-viewer/plugins/rehypeCodeHighlight.js.map +1 -0
  35. package/dist/components/content-viewer/plugins/rehypeExternalLinks.d.ts +59 -0
  36. package/dist/components/content-viewer/plugins/rehypeExternalLinks.d.ts.map +1 -0
  37. package/dist/components/content-viewer/plugins/rehypeExternalLinks.js +79 -0
  38. package/dist/components/content-viewer/plugins/rehypeExternalLinks.js.map +1 -0
  39. package/dist/components/content-viewer/plugins/rehypeHeadingIds.d.ts +37 -0
  40. package/dist/components/content-viewer/plugins/rehypeHeadingIds.d.ts.map +1 -0
  41. package/dist/components/content-viewer/plugins/rehypeHeadingIds.js +82 -0
  42. package/dist/components/content-viewer/plugins/rehypeHeadingIds.js.map +1 -0
  43. package/dist/components/content-viewer/plugins/remarkCallouts.d.ts +39 -0
  44. package/dist/components/content-viewer/plugins/remarkCallouts.d.ts.map +1 -0
  45. package/dist/components/content-viewer/plugins/remarkCallouts.js +77 -0
  46. package/dist/components/content-viewer/plugins/remarkCallouts.js.map +1 -0
  47. package/dist/components/content-viewer/plugins/slugify.d.ts +24 -0
  48. package/dist/components/content-viewer/plugins/slugify.d.ts.map +1 -0
  49. package/dist/components/content-viewer/plugins/slugify.js +31 -0
  50. package/dist/components/content-viewer/plugins/slugify.js.map +1 -0
  51. package/dist/components/content-viewer/sanitize.d.ts +75 -0
  52. package/dist/components/content-viewer/sanitize.d.ts.map +1 -0
  53. package/dist/components/content-viewer/sanitize.js +252 -0
  54. package/dist/components/content-viewer/sanitize.js.map +1 -0
  55. package/dist/components/content-viewer/types.d.ts +315 -0
  56. package/dist/components/content-viewer/types.d.ts.map +1 -0
  57. package/dist/components/content-viewer/types.js +8 -0
  58. package/dist/components/content-viewer/types.js.map +1 -0
  59. package/dist/components/content-viewer/variants.d.ts +71 -0
  60. package/dist/components/content-viewer/variants.d.ts.map +1 -0
  61. package/dist/components/content-viewer/variants.js +105 -0
  62. package/dist/components/content-viewer/variants.js.map +1 -0
  63. package/dist/content-viewer/ContentPane.d.ts +44 -1
  64. package/dist/content-viewer/ContentPane.d.ts.map +1 -1
  65. package/dist/content-viewer/ContentPane.js +139 -5
  66. package/dist/content-viewer/ContentPane.js.map +1 -1
  67. package/dist/content-viewer/FileTree.d.ts +23 -1
  68. package/dist/content-viewer/FileTree.d.ts.map +1 -1
  69. package/dist/content-viewer/FileTree.js +20 -5
  70. package/dist/content-viewer/FileTree.js.map +1 -1
  71. package/dist/content-viewer/index.d.ts +2 -0
  72. package/dist/content-viewer/index.d.ts.map +1 -1
  73. package/dist/content-viewer/index.js +2 -0
  74. package/dist/content-viewer/index.js.map +1 -1
  75. package/dist/diff/DiffViewer.js +3 -3
  76. package/dist/diff/DiffViewer.js.map +1 -1
  77. package/dist/discovery/discovery-card.d.ts +25 -0
  78. package/dist/discovery/discovery-card.d.ts.map +1 -0
  79. package/dist/discovery/discovery-card.js +265 -0
  80. package/dist/discovery/discovery-card.js.map +1 -0
  81. package/dist/discovery/index.d.ts +3 -0
  82. package/dist/discovery/index.d.ts.map +1 -0
  83. package/dist/discovery/index.js +3 -0
  84. package/dist/discovery/index.js.map +1 -0
  85. package/dist/display/ContextInfoCard.d.ts +61 -0
  86. package/dist/display/ContextInfoCard.d.ts.map +1 -0
  87. package/dist/display/ContextInfoCard.js +45 -0
  88. package/dist/display/ContextInfoCard.js.map +1 -0
  89. package/dist/display/index.d.ts +2 -0
  90. package/dist/display/index.d.ts.map +1 -1
  91. package/dist/display/index.js +1 -0
  92. package/dist/display/index.js.map +1 -1
  93. package/dist/editor/CodeEditor.d.ts +39 -0
  94. package/dist/editor/CodeEditor.d.ts.map +1 -0
  95. package/dist/editor/CodeEditor.js +114 -0
  96. package/dist/editor/CodeEditor.js.map +1 -0
  97. package/dist/editor/MarkdownEditor.d.ts +3 -2
  98. package/dist/editor/MarkdownEditor.d.ts.map +1 -1
  99. package/dist/editor/MarkdownEditor.js +32 -80
  100. package/dist/editor/MarkdownEditor.js.map +1 -1
  101. package/dist/editor/SplitPreview.d.ts +10 -1
  102. package/dist/editor/SplitPreview.d.ts.map +1 -1
  103. package/dist/editor/SplitPreview.js +4 -2
  104. package/dist/editor/SplitPreview.js.map +1 -1
  105. package/dist/editor/codeLanguages.d.ts +28 -0
  106. package/dist/editor/codeLanguages.d.ts.map +1 -0
  107. package/dist/editor/codeLanguages.js +54 -0
  108. package/dist/editor/codeLanguages.js.map +1 -0
  109. package/dist/editor/index.d.ts +2 -0
  110. package/dist/editor/index.d.ts.map +1 -1
  111. package/dist/editor/index.js +6 -0
  112. package/dist/editor/index.js.map +1 -1
  113. package/dist/editor/theme.d.ts +16 -0
  114. package/dist/editor/theme.d.ts.map +1 -0
  115. package/dist/editor/theme.js +82 -0
  116. package/dist/editor/theme.js.map +1 -0
  117. package/dist/filters/filter-bar.d.ts +14 -0
  118. package/dist/filters/filter-bar.d.ts.map +1 -0
  119. package/dist/filters/filter-bar.js +47 -0
  120. package/dist/filters/filter-bar.js.map +1 -0
  121. package/dist/filters/filter-slot-config.d.ts +239 -0
  122. package/dist/filters/filter-slot-config.d.ts.map +1 -0
  123. package/dist/filters/filter-slot-config.js +24 -0
  124. package/dist/filters/filter-slot-config.js.map +1 -0
  125. package/dist/filters/index.d.ts +2 -0
  126. package/dist/filters/index.d.ts.map +1 -1
  127. package/dist/filters/index.js +1 -0
  128. package/dist/filters/index.js.map +1 -1
  129. package/dist/primitives/Card.d.ts +28 -0
  130. package/dist/primitives/Card.d.ts.map +1 -0
  131. package/dist/primitives/Card.js +30 -0
  132. package/dist/primitives/Card.js.map +1 -0
  133. package/dist/primitives/CollectionPicker.d.ts +47 -0
  134. package/dist/primitives/CollectionPicker.d.ts.map +1 -0
  135. package/dist/primitives/CollectionPicker.js +105 -0
  136. package/dist/primitives/CollectionPicker.js.map +1 -0
  137. package/dist/primitives/CreateEntityDialog.d.ts +144 -0
  138. package/dist/primitives/CreateEntityDialog.d.ts.map +1 -0
  139. package/dist/primitives/CreateEntityDialog.js +379 -0
  140. package/dist/primitives/CreateEntityDialog.js.map +1 -0
  141. package/dist/primitives/FormField.d.ts +29 -0
  142. package/dist/primitives/FormField.d.ts.map +1 -0
  143. package/dist/primitives/FormField.js +27 -0
  144. package/dist/primitives/FormField.js.map +1 -0
  145. package/dist/primitives/Label.d.ts +20 -0
  146. package/dist/primitives/Label.d.ts.map +1 -0
  147. package/dist/primitives/Label.js +21 -0
  148. package/dist/primitives/Label.js.map +1 -0
  149. package/dist/primitives/SecretField.d.ts +28 -0
  150. package/dist/primitives/SecretField.d.ts.map +1 -0
  151. package/dist/primitives/SecretField.js +65 -0
  152. package/dist/primitives/SecretField.js.map +1 -0
  153. package/dist/primitives/Spinner.d.ts +16 -0
  154. package/dist/primitives/Spinner.d.ts.map +1 -0
  155. package/dist/primitives/Spinner.js +34 -0
  156. package/dist/primitives/Spinner.js.map +1 -0
  157. package/dist/primitives/Switch.d.ts +32 -0
  158. package/dist/primitives/Switch.d.ts.map +1 -0
  159. package/dist/primitives/Switch.js +43 -0
  160. package/dist/primitives/Switch.js.map +1 -0
  161. package/dist/primitives/index.d.ts +16 -0
  162. package/dist/primitives/index.d.ts.map +1 -1
  163. package/dist/primitives/index.js +9 -0
  164. package/dist/primitives/index.js.map +1 -1
  165. package/dist/utils/type-colors.d.ts.map +1 -1
  166. package/dist/utils/type-colors.js +4 -0
  167. package/dist/utils/type-colors.js.map +1 -1
  168. package/package.json +40 -6
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextInfoCard.js","sourceRoot":"","sources":["../../src/display/ContextInfoCard.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAsCzC,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,KAAK,EACL,IAAI,EAAE,IAAI,EACV,QAAQ,EACR,OAAO,EACP,gBAAgB,GAAG,IAAI,EACvB,QAAQ,EACR,SAAS,GACY;IACrB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC;IAEvB,MAAM,OAAO,GACX,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QAC/C,QAAQ,KAAK,SAAS,CAAC;IAEzB,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,6CAA6C,EAC7C,SAAS,CACV,aAKD,eAAK,SAAS,EAAC,mCAAmC,aAE/C,OAAO,CAAC,CAAC,CAAC,CACT,kBACE,IAAI,EAAC,QAAQ,mBACE,MAAM,mBACN,MAAM,EACrB,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EACzC,SAAS,EAAE,EAAE,CACX,0CAA0C,EAC1C,4DAA4D,EAC5D,qDAAqD,CACtD,aAGA,MAAM,CAAC,CAAC,CAAC,CACR,KAAC,WAAW,IACV,SAAS,EAAC,wCAAwC,iBACtC,MAAM,GAClB,CACH,CAAC,CAAC,CAAC,CACF,KAAC,YAAY,IACX,SAAS,EAAC,wCAAwC,iBACtC,MAAM,GAClB,CACH,EAGA,IAAI,IAAI,CACP,KAAC,IAAI,IAAC,SAAS,EAAC,wCAAwC,GAAG,CAC5D,EAGD,eAAM,SAAS,EAAC,qCAAqC,YAAE,KAAK,GAAQ,IAC7D,CACV,CAAC,CAAC,CAAC;oBACF,kDAAkD;oBAClD,eAAK,SAAS,EAAC,gCAAgC,aAC5C,IAAI,IAAI,CACP,KAAC,IAAI,IAAC,SAAS,EAAC,wCAAwC,GAAG,CAC5D,EACD,eAAM,SAAS,EAAC,qCAAqC,YAAE,KAAK,GAAQ,IAChE,CACP,EAGA,OAAO,IAAI,CACV,cAAK,SAAS,EAAC,0CAA0C,YACtD,OAAO,GACJ,CACP,IACG,EAKL,OAAO,IAAI,CACV,cAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,MAAM,YAC9B,eAAK,SAAS,EAAC,uCAAuC,aAEnD,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAClC,aAAI,SAAS,EAAC,6CAA6C,YACxD,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC7B,eAAiB,SAAS,EAAC,UAAU,aACnC,aAAI,SAAS,EAAC,2CAA2C,YACtD,IAAI,CAAC,KAAK,GACR,EACL,aAAI,SAAS,EAAC,yBAAyB,YAAE,IAAI,CAAC,KAAK,GAAM,KAJjD,KAAK,CAKT,CACP,CAAC,GACC,CACN,EAGA,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,IAAI,CAC9C,cAAK,SAAS,EAAC,gCAAgC,GAAG,CACnD,EAGA,QAAQ,IAAI,cAAK,SAAS,EAAC,SAAS,YAAE,QAAQ,GAAO,IAClD,GACF,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
@@ -2,4 +2,6 @@ export { FrontmatterDisplay } from './FrontmatterDisplay';
2
2
  export type { FrontmatterDisplayProps } from './FrontmatterDisplay';
3
3
  export { FilePreviewPane } from './FilePreviewPane';
4
4
  export type { FilePreviewPaneProps } from './FilePreviewPane';
5
+ export { ContextInfoCard } from './ContextInfoCard';
6
+ export type { ContextInfoCardProps, ContextInfoCardMetadataItem } from './ContextInfoCard';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,4 +1,5 @@
1
1
  // @miethe/ui — display submodule
2
2
  export { FrontmatterDisplay } from './FrontmatterDisplay';
3
3
  export { FilePreviewPane } from './FilePreviewPane';
4
+ export { ContextInfoCard } from './ContextInfoCard';
4
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,39 @@
1
+ import type { ReactElement } from 'react';
2
+ import type { LanguageSupport } from '@codemirror/language';
3
+ export interface CodeEditorProps {
4
+ initialContent: string;
5
+ onChange: (content: string) => void;
6
+ readOnly?: boolean;
7
+ className?: string;
8
+ /**
9
+ * CodeMirror language extension. Omit for plain-text mode.
10
+ * @default undefined
11
+ */
12
+ language?: LanguageSupport;
13
+ }
14
+ /**
15
+ * CodeEditor - CodeMirror 6 based code editor with configurable language support
16
+ *
17
+ * Features:
18
+ * - Configurable language grammar via the `language` prop
19
+ * - Plain-text mode when `language` is omitted
20
+ * - Basic keymaps (undo/redo, etc.)
21
+ * - Reactive theme support (updates instantly on OS light↔dark switch)
22
+ * - onChange callback for content changes
23
+ * - ReadOnly mode support
24
+ * - React 19 StrictMode safe (destroy-guard prevents double-mount leaks)
25
+ * - Proper cleanup on unmount (view.destroy + matchMedia listener)
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * import { javascript } from '@codemirror/lang-javascript';
30
+ *
31
+ * <CodeEditor
32
+ * initialContent="const x = 1;"
33
+ * onChange={(content) => setContent(content)}
34
+ * language={javascript({ typescript: true })}
35
+ * />
36
+ * ```
37
+ */
38
+ export declare function CodeEditor({ initialContent, onChange, readOnly, className, language, }: CodeEditorProps): ReactElement;
39
+ //# sourceMappingURL=CodeEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeEditor.d.ts","sourceRoot":"","sources":["../../src/editor/CodeEditor.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAQ5D,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,EACzB,cAAc,EACd,QAAQ,EACR,QAAgB,EAChB,SAAS,EACT,QAAQ,GACT,EAAE,eAAe,GAAG,YAAY,CAiGhC"}
@@ -0,0 +1,114 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from 'react';
4
+ import { Compartment, EditorState } from '@codemirror/state';
5
+ import { EditorView, keymap } from '@codemirror/view';
6
+ import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
7
+ import { cn } from '../primitives/utils';
8
+ import { darkTheme, lightTheme, prefersDark } from './theme';
9
+ // ============================================================================
10
+ // Main Component
11
+ // ============================================================================
12
+ /**
13
+ * CodeEditor - CodeMirror 6 based code editor with configurable language support
14
+ *
15
+ * Features:
16
+ * - Configurable language grammar via the `language` prop
17
+ * - Plain-text mode when `language` is omitted
18
+ * - Basic keymaps (undo/redo, etc.)
19
+ * - Reactive theme support (updates instantly on OS light↔dark switch)
20
+ * - onChange callback for content changes
21
+ * - ReadOnly mode support
22
+ * - React 19 StrictMode safe (destroy-guard prevents double-mount leaks)
23
+ * - Proper cleanup on unmount (view.destroy + matchMedia listener)
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * import { javascript } from '@codemirror/lang-javascript';
28
+ *
29
+ * <CodeEditor
30
+ * initialContent="const x = 1;"
31
+ * onChange={(content) => setContent(content)}
32
+ * language={javascript({ typescript: true })}
33
+ * />
34
+ * ```
35
+ */
36
+ export function CodeEditor({ initialContent, onChange, readOnly = false, className, language, }) {
37
+ const containerRef = useRef(null);
38
+ const editorRef = useRef(null);
39
+ // Stored so the matchMedia change-handler can dispatch a reconfigure without
40
+ // capturing a stale closure over the Compartment created during mount.
41
+ const themeCompartmentRef = useRef(null);
42
+ useEffect(() => {
43
+ if (!containerRef.current)
44
+ return;
45
+ // StrictMode guard: destroy any existing view before creating a new one
46
+ // so we never leak a second editor or a second matchMedia listener.
47
+ if (editorRef.current) {
48
+ editorRef.current.destroy();
49
+ editorRef.current = null;
50
+ }
51
+ const themeCompartment = new Compartment();
52
+ themeCompartmentRef.current = themeCompartment;
53
+ // Create editor state with all extensions
54
+ const startState = EditorState.create({
55
+ doc: initialContent,
56
+ extensions: [
57
+ // Optional language support — plain-text mode when omitted
58
+ ...(language ? [language] : []),
59
+ // History (undo/redo)
60
+ history(),
61
+ // Keymaps
62
+ keymap.of([...defaultKeymap, ...historyKeymap]),
63
+ // Update listener for onChange callback
64
+ EditorView.updateListener.of((update) => {
65
+ if (update.docChanged) {
66
+ onChange(update.state.doc.toString());
67
+ }
68
+ }),
69
+ // ReadOnly mode
70
+ EditorView.editable.of(!readOnly),
71
+ // Reactive theme compartment — starts with the current OS preference
72
+ themeCompartment.of(prefersDark() ? darkTheme : lightTheme),
73
+ // Line wrapping
74
+ EditorView.lineWrapping,
75
+ ],
76
+ });
77
+ // Create editor view
78
+ const view = new EditorView({
79
+ state: startState,
80
+ parent: containerRef.current,
81
+ });
82
+ editorRef.current = view;
83
+ // Reactive dark-mode: reconfigure the theme compartment whenever the OS
84
+ // preference changes while the editor is mounted.
85
+ const mql = window.matchMedia('(prefers-color-scheme: dark)');
86
+ const handleColorSchemeChange = () => {
87
+ editorRef.current?.dispatch({
88
+ effects: themeCompartment.reconfigure(prefersDark() ? darkTheme : lightTheme),
89
+ });
90
+ };
91
+ mql.addEventListener('change', handleColorSchemeChange);
92
+ // Cleanup on unmount: remove listener before destroying the view
93
+ return () => {
94
+ mql.removeEventListener('change', handleColorSchemeChange);
95
+ view.destroy();
96
+ editorRef.current = null;
97
+ themeCompartmentRef.current = null;
98
+ };
99
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps — intentional mount-once
100
+ // Update content when initialContent changes externally
101
+ useEffect(() => {
102
+ if (editorRef.current && editorRef.current.state.doc.toString() !== initialContent) {
103
+ editorRef.current.dispatch({
104
+ changes: {
105
+ from: 0,
106
+ to: editorRef.current.state.doc.length,
107
+ insert: initialContent,
108
+ },
109
+ });
110
+ }
111
+ }, [initialContent]);
112
+ return (_jsx("div", { ref: containerRef, className: cn('h-full w-full overflow-auto rounded-md border', className) }));
113
+ }
114
+ //# sourceMappingURL=CodeEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeEditor.js","sourceRoot":"","sources":["../../src/editor/CodeEditor.tsx"],"names":[],"mappings":"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"}
@@ -10,10 +10,11 @@ export interface MarkdownEditorProps {
10
10
  * Features:
11
11
  * - Markdown syntax highlighting
12
12
  * - Basic keymaps (undo/redo, etc.)
13
- * - Theme support (light/dark based on system preference)
13
+ * - Reactive theme support (updates instantly on OS light↔dark switch)
14
14
  * - onChange callback for content changes
15
15
  * - ReadOnly mode support
16
- * - Proper cleanup on unmount
16
+ * - React 19 StrictMode safe (destroy-guard prevents double-mount leaks)
17
+ * - Proper cleanup on unmount (view.destroy + matchMedia listener)
17
18
  *
18
19
  * @example
19
20
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownEditor.d.ts","sourceRoot":"","sources":["../../src/editor/MarkdownEditor.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsFD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,cAAc,EACd,QAAQ,EACR,QAAgB,EAChB,SAAS,GACV,EAAE,mBAAmB,2CA0ErB"}
1
+ {"version":3,"file":"MarkdownEditor.d.ts","sourceRoot":"","sources":["../../src/editor/MarkdownEditor.tsx"],"names":[],"mappings":"AAcA,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,cAAc,EACd,QAAQ,EACR,QAAgB,EAChB,SAAS,GACV,EAAE,mBAAmB,2CAiGrB"}
@@ -1,82 +1,12 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { useEffect, useRef } from 'react';
4
- import { EditorState } from '@codemirror/state';
4
+ import { Compartment, EditorState } from '@codemirror/state';
5
5
  import { EditorView, keymap } from '@codemirror/view';
6
6
  import { markdown } from '@codemirror/lang-markdown';
7
7
  import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
8
8
  import { cn } from '../primitives/utils';
9
- // ============================================================================
10
- // Theme Extensions
11
- // ============================================================================
12
- /**
13
- * Light theme extension for CodeMirror
14
- */
15
- const lightTheme = EditorView.theme({
16
- '&': {
17
- backgroundColor: 'hsl(var(--background))',
18
- color: 'hsl(var(--foreground))',
19
- height: '100%',
20
- },
21
- '.cm-content': {
22
- caretColor: 'hsl(var(--foreground))',
23
- fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
24
- fontSize: '14px',
25
- lineHeight: '1.6',
26
- padding: '16px',
27
- },
28
- '.cm-cursor, .cm-dropCursor': {
29
- borderLeftColor: 'hsl(var(--foreground))',
30
- },
31
- '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {
32
- backgroundColor: 'hsl(var(--accent))',
33
- },
34
- '.cm-activeLine': {
35
- backgroundColor: 'hsl(var(--accent) / 0.1)',
36
- },
37
- '.cm-gutters': {
38
- backgroundColor: 'hsl(var(--muted))',
39
- color: 'hsl(var(--muted-foreground))',
40
- border: 'none',
41
- },
42
- '.cm-activeLineGutter': {
43
- backgroundColor: 'hsl(var(--accent) / 0.1)',
44
- },
45
- }, { dark: false });
46
- /**
47
- * Dark theme extension for CodeMirror
48
- */
49
- const darkTheme = EditorView.theme({
50
- '&': {
51
- backgroundColor: 'hsl(var(--background))',
52
- color: 'hsl(var(--foreground))',
53
- height: '100%',
54
- },
55
- '.cm-content': {
56
- caretColor: 'hsl(var(--foreground))',
57
- fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
58
- fontSize: '14px',
59
- lineHeight: '1.6',
60
- padding: '16px',
61
- },
62
- '.cm-cursor, .cm-dropCursor': {
63
- borderLeftColor: 'hsl(var(--foreground))',
64
- },
65
- '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {
66
- backgroundColor: 'hsl(var(--accent))',
67
- },
68
- '.cm-activeLine': {
69
- backgroundColor: 'hsl(var(--accent) / 0.1)',
70
- },
71
- '.cm-gutters': {
72
- backgroundColor: 'hsl(var(--muted))',
73
- color: 'hsl(var(--muted-foreground))',
74
- border: 'none',
75
- },
76
- '.cm-activeLineGutter': {
77
- backgroundColor: 'hsl(var(--accent) / 0.1)',
78
- },
79
- }, { dark: true });
9
+ import { darkTheme, lightTheme, prefersDark } from './theme';
80
10
  // ============================================================================
81
11
  // Main Component
82
12
  // ============================================================================
@@ -86,10 +16,11 @@ const darkTheme = EditorView.theme({
86
16
  * Features:
87
17
  * - Markdown syntax highlighting
88
18
  * - Basic keymaps (undo/redo, etc.)
89
- * - Theme support (light/dark based on system preference)
19
+ * - Reactive theme support (updates instantly on OS light↔dark switch)
90
20
  * - onChange callback for content changes
91
21
  * - ReadOnly mode support
92
- * - Proper cleanup on unmount
22
+ * - React 19 StrictMode safe (destroy-guard prevents double-mount leaks)
23
+ * - Proper cleanup on unmount (view.destroy + matchMedia listener)
93
24
  *
94
25
  * @example
95
26
  * ```tsx
@@ -103,11 +34,20 @@ const darkTheme = EditorView.theme({
103
34
  export function MarkdownEditor({ initialContent, onChange, readOnly = false, className, }) {
104
35
  const containerRef = useRef(null);
105
36
  const editorRef = useRef(null);
37
+ // Stored so the matchMedia change-handler can dispatch a reconfigure without
38
+ // capturing a stale closure over the Compartment created during mount.
39
+ const themeCompartmentRef = useRef(null);
106
40
  useEffect(() => {
107
41
  if (!containerRef.current)
108
42
  return;
109
- // Detect dark mode from system preference
110
- const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
43
+ // StrictMode guard: destroy any existing view before creating a new one
44
+ // so we never leak a second editor or a second matchMedia listener.
45
+ if (editorRef.current) {
46
+ editorRef.current.destroy();
47
+ editorRef.current = null;
48
+ }
49
+ const themeCompartment = new Compartment();
50
+ themeCompartmentRef.current = themeCompartment;
111
51
  // Create editor state with all extensions
112
52
  const startState = EditorState.create({
113
53
  doc: initialContent,
@@ -126,8 +66,8 @@ export function MarkdownEditor({ initialContent, onChange, readOnly = false, cla
126
66
  }),
127
67
  // ReadOnly mode
128
68
  EditorView.editable.of(!readOnly),
129
- // Theme based on system preference
130
- isDarkMode ? darkTheme : lightTheme,
69
+ // Reactive theme compartment starts with the current OS preference
70
+ themeCompartment.of(prefersDark() ? darkTheme : lightTheme),
131
71
  // Line wrapping
132
72
  EditorView.lineWrapping,
133
73
  ],
@@ -138,11 +78,23 @@ export function MarkdownEditor({ initialContent, onChange, readOnly = false, cla
138
78
  parent: containerRef.current,
139
79
  });
140
80
  editorRef.current = view;
141
- // Cleanup on unmount
81
+ // Reactive dark-mode: reconfigure the theme compartment whenever the OS
82
+ // preference changes while the editor is mounted.
83
+ const mql = window.matchMedia('(prefers-color-scheme: dark)');
84
+ const handleColorSchemeChange = () => {
85
+ editorRef.current?.dispatch({
86
+ effects: themeCompartment.reconfigure(prefersDark() ? darkTheme : lightTheme),
87
+ });
88
+ };
89
+ mql.addEventListener('change', handleColorSchemeChange);
90
+ // Cleanup on unmount: remove listener before destroying the view
142
91
  return () => {
92
+ mql.removeEventListener('change', handleColorSchemeChange);
143
93
  view.destroy();
94
+ editorRef.current = null;
95
+ themeCompartmentRef.current = null;
144
96
  };
145
- }, []); // Only run once on mount
97
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps intentional mount-once
146
98
  // Update content when initialContent changes externally
147
99
  useEffect(() => {
148
100
  if (editorRef.current && editorRef.current.state.doc.toString() !== initialContent) {
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownEditor.js","sourceRoot":"","sources":["../../src/editor/MarkdownEditor.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MarkdownEditor.js","sourceRoot":"","sources":["../../src/editor/MarkdownEditor.tsx"],"names":[],"mappings":"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"}
@@ -3,6 +3,15 @@ export interface SplitPreviewProps {
3
3
  onChange: (content: string) => void;
4
4
  isEditing: boolean;
5
5
  className?: string;
6
+ /**
7
+ * When true, the rendered markdown HTML is passed through rehype-sanitize
8
+ * before display. Strips dangerous constructs: <script>, inline event
9
+ * handlers (onerror=, onclick=, etc.), javascript: URLs, and unsafe elements
10
+ * like <iframe>. When false (default), behavior is identical to before this
11
+ * prop was added — no sanitization, no performance change.
12
+ * @default false
13
+ */
14
+ sanitize?: boolean;
6
15
  }
7
16
  /**
8
17
  * SplitPreview - Split-view markdown editor with live preview
@@ -24,5 +33,5 @@ export interface SplitPreviewProps {
24
33
  * />
25
34
  * ```
26
35
  */
27
- export declare function SplitPreview({ content, onChange, isEditing, className }: SplitPreviewProps): import("react/jsx-runtime").JSX.Element;
36
+ export declare function SplitPreview({ content, onChange, isEditing, className, sanitize }: SplitPreviewProps): import("react/jsx-runtime").JSX.Element;
28
37
  //# sourceMappingURL=SplitPreview.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SplitPreview.d.ts","sourceRoot":"","sources":["../../src/editor/SplitPreview.tsx"],"names":[],"mappings":"AAYA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,iBAAiB,2CA+B1F"}
1
+ {"version":3,"file":"SplitPreview.d.ts","sourceRoot":"","sources":["../../src/editor/SplitPreview.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,QAAgB,EAAE,EAAE,iBAAiB,2CAgC5G"}
@@ -2,6 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import ReactMarkdown from 'react-markdown';
4
4
  import remarkGfm from 'remark-gfm';
5
+ import rehypeSanitize from 'rehype-sanitize';
5
6
  import { MarkdownEditor } from './MarkdownEditor';
6
7
  import { ScrollArea } from '../primitives/ScrollArea';
7
8
  import { cn } from '../primitives/utils';
@@ -28,7 +29,8 @@ import { cn } from '../primitives/utils';
28
29
  * />
29
30
  * ```
30
31
  */
31
- export function SplitPreview({ content, onChange, isEditing, className }) {
32
- return (_jsxs("div", { className: cn('flex h-full min-w-0 flex-col gap-4 overflow-hidden lg:flex-row', className), children: [isEditing && (_jsx("div", { className: "min-h-[300px] min-w-0 flex-1 lg:min-h-0", children: _jsx(MarkdownEditor, { initialContent: content, onChange: onChange, className: "h-full" }) })), _jsx("div", { className: cn('min-h-[300px] min-w-0 flex-1 overflow-hidden lg:min-h-0', !isEditing && 'w-full'), children: _jsx("div", { className: "h-full overflow-hidden rounded-md border bg-card", children: _jsx(ScrollArea, { className: "h-full w-full [&>[data-radix-scroll-area-viewport]>div]:!block [&>[data-radix-scroll-area-viewport]>div]:!min-w-0", children: _jsx("div", { className: "prose prose-sm max-w-none overflow-x-hidden break-words p-6 [overflow-wrap:anywhere] [word-break:break-word] dark:prose-invert prose-headings:break-words prose-p:break-words prose-code:break-all prose-pre:overflow-x-auto", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: content || '*No content to preview*' }) }) }) }) })] }));
32
+ export function SplitPreview({ content, onChange, isEditing, className, sanitize = false }) {
33
+ const rehypePlugins = sanitize ? [rehypeSanitize] : [];
34
+ return (_jsxs("div", { className: cn('flex h-full min-w-0 flex-col gap-4 overflow-hidden lg:flex-row', className), children: [isEditing && (_jsx("div", { className: "min-h-[300px] min-w-0 flex-1 lg:min-h-0", children: _jsx(MarkdownEditor, { initialContent: content, onChange: onChange, className: "h-full" }) })), _jsx("div", { className: cn('min-h-[300px] min-w-0 flex-1 overflow-hidden lg:min-h-0', !isEditing && 'w-full'), children: _jsx("div", { className: "h-full overflow-hidden rounded-md border bg-card", children: _jsx(ScrollArea, { className: "h-full w-full [&>[data-radix-scroll-area-viewport]>div]:!block [&>[data-radix-scroll-area-viewport]>div]:!min-w-0", children: _jsx("div", { className: "prose prose-sm max-w-none overflow-x-hidden break-words p-6 [overflow-wrap:anywhere] [word-break:break-word] dark:prose-invert prose-headings:break-words prose-p:break-words prose-code:break-all prose-pre:overflow-x-auto", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], rehypePlugins: rehypePlugins, children: content || '*No content to preview*' }) }) }) }) })] }));
33
35
  }
34
36
  //# sourceMappingURL=SplitPreview.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SplitPreview.js","sourceRoot":"","sources":["../../src/editor/SplitPreview.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAC3C,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAazC,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAqB;IACzF,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CAAC,gEAAgE,EAAE,SAAS,CAAC,aAGzF,SAAS,IAAI,CACZ,cAAK,SAAS,EAAC,yCAAyC,YACtD,KAAC,cAAc,IAAC,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAC,QAAQ,GAAG,GAC9E,CACP,EAGD,cACE,SAAS,EAAE,EAAE,CACX,yDAAyD,EACzD,CAAC,SAAS,IAAI,QAAQ,CACvB,YAED,cAAK,SAAS,EAAC,kDAAkD,YAC/D,KAAC,UAAU,IAAC,SAAS,EAAC,mHAAmH,YACvI,cAAK,SAAS,EAAC,8NAA8N,YAC3O,KAAC,aAAa,IAAC,aAAa,EAAE,CAAC,SAAS,CAAC,YACtC,OAAO,IAAI,yBAAyB,GACvB,GACZ,GACK,GACT,GACF,IACF,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"SplitPreview.js","sourceRoot":"","sources":["../../src/editor/SplitPreview.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAC3C,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,cAAc,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAsBzC,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,GAAG,KAAK,EAAqB;IAC3G,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CAAC,gEAAgE,EAAE,SAAS,CAAC,aAGzF,SAAS,IAAI,CACZ,cAAK,SAAS,EAAC,yCAAyC,YACtD,KAAC,cAAc,IAAC,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAC,QAAQ,GAAG,GAC9E,CACP,EAGD,cACE,SAAS,EAAE,EAAE,CACX,yDAAyD,EACzD,CAAC,SAAS,IAAI,QAAQ,CACvB,YAED,cAAK,SAAS,EAAC,kDAAkD,YAC/D,KAAC,UAAU,IAAC,SAAS,EAAC,mHAAmH,YACvI,cAAK,SAAS,EAAC,8NAA8N,YAC3O,KAAC,aAAa,IAAC,aAAa,EAAE,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,aAAa,YACpE,OAAO,IAAI,yBAAyB,GACvB,GACZ,GACK,GACT,GACF,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { LanguageSupport } from '@codemirror/language';
2
+ /**
3
+ * Resolves a CodeMirror `LanguageSupport` instance from a file path.
4
+ *
5
+ * Matches on the lowercased file extension. Returns `undefined` for unknown
6
+ * extensions so callers can fall back to plain-text mode.
7
+ *
8
+ * Supported extensions:
9
+ * - `.ts` → TypeScript
10
+ * - `.tsx` → TypeScript + JSX
11
+ * - `.js` → JavaScript
12
+ * - `.jsx` → JavaScript + JSX
13
+ * - `.py` → Python
14
+ * - `.json` → JSON
15
+ * - `.css` → CSS
16
+ *
17
+ * This module is intended to be loaded only inside a lazy boundary (e.g. a
18
+ * React.lazy wrapper in ContentPane) so the lang-pack weight stays in a
19
+ * deferred chunk and is never part of the initial bundle.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const lang = resolveCodeMirrorLanguage('src/index.tsx');
24
+ * // lang === javascript({ typescript: true, jsx: true })
25
+ * ```
26
+ */
27
+ export declare function resolveCodeMirrorLanguage(path: string): LanguageSupport | undefined;
28
+ //# sourceMappingURL=codeLanguages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeLanguages.d.ts","sourceRoot":"","sources":["../../src/editor/codeLanguages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAU5D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAqBnF"}
@@ -0,0 +1,54 @@
1
+ import { javascript } from '@codemirror/lang-javascript';
2
+ import { python } from '@codemirror/lang-python';
3
+ import { json } from '@codemirror/lang-json';
4
+ import { css } from '@codemirror/lang-css';
5
+ // ============================================================================
6
+ // Language resolver
7
+ // ============================================================================
8
+ /**
9
+ * Resolves a CodeMirror `LanguageSupport` instance from a file path.
10
+ *
11
+ * Matches on the lowercased file extension. Returns `undefined` for unknown
12
+ * extensions so callers can fall back to plain-text mode.
13
+ *
14
+ * Supported extensions:
15
+ * - `.ts` → TypeScript
16
+ * - `.tsx` → TypeScript + JSX
17
+ * - `.js` → JavaScript
18
+ * - `.jsx` → JavaScript + JSX
19
+ * - `.py` → Python
20
+ * - `.json` → JSON
21
+ * - `.css` → CSS
22
+ *
23
+ * This module is intended to be loaded only inside a lazy boundary (e.g. a
24
+ * React.lazy wrapper in ContentPane) so the lang-pack weight stays in a
25
+ * deferred chunk and is never part of the initial bundle.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const lang = resolveCodeMirrorLanguage('src/index.tsx');
30
+ * // lang === javascript({ typescript: true, jsx: true })
31
+ * ```
32
+ */
33
+ export function resolveCodeMirrorLanguage(path) {
34
+ const ext = path.slice(path.lastIndexOf('.')).toLowerCase();
35
+ switch (ext) {
36
+ case '.ts':
37
+ return javascript({ typescript: true });
38
+ case '.tsx':
39
+ return javascript({ typescript: true, jsx: true });
40
+ case '.js':
41
+ return javascript();
42
+ case '.jsx':
43
+ return javascript({ jsx: true });
44
+ case '.py':
45
+ return python();
46
+ case '.json':
47
+ return json();
48
+ case '.css':
49
+ return css();
50
+ default:
51
+ return undefined;
52
+ }
53
+ }
54
+ //# sourceMappingURL=codeLanguages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeLanguages.js","sourceRoot":"","sources":["../../src/editor/codeLanguages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAE3C,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAE5D,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,KAAK;YACR,OAAO,UAAU,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,KAAK,MAAM;YACT,OAAO,UAAU,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,KAAK,KAAK;YACR,OAAO,UAAU,EAAE,CAAC;QACtB,KAAK,MAAM;YACT,OAAO,UAAU,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QACnC,KAAK,KAAK;YACR,OAAO,MAAM,EAAE,CAAC;QAClB,KAAK,OAAO;YACV,OAAO,IAAI,EAAE,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,GAAG,EAAE,CAAC;QACf;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -2,4 +2,6 @@ export { MarkdownEditor } from './MarkdownEditor';
2
2
  export type { MarkdownEditorProps } from './MarkdownEditor';
3
3
  export { SplitPreview } from './SplitPreview';
4
4
  export type { SplitPreviewProps } from './SplitPreview';
5
+ export { CodeEditor } from './CodeEditor';
6
+ export type { CodeEditorProps } from './CodeEditor';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/editor/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/editor/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
@@ -1,4 +1,10 @@
1
1
  // @miethe/ui — editor submodule
2
2
  export { MarkdownEditor } from './MarkdownEditor';
3
3
  export { SplitPreview } from './SplitPreview';
4
+ export { CodeEditor } from './CodeEditor';
5
+ // NOTE: `resolveCodeMirrorLanguage` is intentionally NOT re-exported here.
6
+ // Its module statically imports the @codemirror/lang-* grammar packs; re-exporting
7
+ // it from this barrel would pull those packs into every consumer of `@miethe/ui/editor`
8
+ // (e.g. importers of MarkdownEditor), defeating the lazy-chunk isolation. ContentPane
9
+ // imports it via a dynamic `import('./codeLanguages')` boundary instead.
4
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/editor/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/editor/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,2EAA2E;AAC3E,mFAAmF;AACnF,wFAAwF;AACxF,sFAAsF;AACtF,yEAAyE"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Light theme extension for CodeMirror.
3
+ * Uses CSS custom properties so it adapts to any Tailwind/shadcn token set.
4
+ */
5
+ export declare const lightTheme: import("@codemirror/state").Extension;
6
+ /**
7
+ * Dark theme extension for CodeMirror.
8
+ * Uses CSS custom properties so it adapts to any Tailwind/shadcn token set.
9
+ */
10
+ export declare const darkTheme: import("@codemirror/state").Extension;
11
+ /**
12
+ * Returns true when the OS/browser is currently in dark mode.
13
+ * Safe to call in SSR contexts — returns false when `window` is unavailable.
14
+ */
15
+ export declare function prefersDark(): boolean;
16
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/editor/theme.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,eAAO,MAAM,UAAU,uCAiCtB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,uCAiCrB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAErC"}