leepi 0.0.0 → 0.0.3

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 (86) hide show
  1. package/dist/core/active-marks.d.ts +15 -0
  2. package/dist/core/active-marks.js +57 -0
  3. package/dist/core/commands.d.ts +39 -0
  4. package/dist/core/commands.js +415 -0
  5. package/dist/core/editor.d.ts +25 -0
  6. package/dist/core/editor.js +102 -0
  7. package/dist/core/field-notifier.d.ts +21 -0
  8. package/dist/core/field-notifier.js +56 -0
  9. package/dist/core/highlight-style.js +60 -0
  10. package/dist/core/highlight.d.ts +8 -0
  11. package/dist/core/highlight.js +34 -0
  12. package/dist/core/plugins/blockquote.d.ts +11 -0
  13. package/dist/core/plugins/blockquote.js +78 -0
  14. package/dist/core/plugins/bracket.d.ts +6 -0
  15. package/dist/core/plugins/bracket.js +38 -0
  16. package/dist/core/plugins/code-block.d.ts +27 -0
  17. package/dist/core/plugins/code-block.js +207 -0
  18. package/dist/core/plugins/heading.d.ts +13 -0
  19. package/dist/core/plugins/heading.js +111 -0
  20. package/dist/core/plugins/inline.d.ts +14 -0
  21. package/dist/core/plugins/inline.js +103 -0
  22. package/dist/core/plugins/link.d.ts +25 -0
  23. package/dist/core/plugins/link.js +104 -0
  24. package/dist/core/plugins/list.d.ts +14 -0
  25. package/dist/core/plugins/list.js +91 -0
  26. package/dist/core/plugins/table.d.ts +12 -0
  27. package/dist/core/plugins/table.js +161 -0
  28. package/dist/core/plugins.d.ts +9 -0
  29. package/dist/core/plugins.js +9 -0
  30. package/dist/core/popover.d.ts +9 -0
  31. package/dist/core/popover.js +16 -0
  32. package/dist/core/registry.d.ts +10 -0
  33. package/dist/core/registry.js +8 -0
  34. package/dist/core/types.d.ts +25 -0
  35. package/dist/core/types.js +0 -0
  36. package/dist/core/utils.d.ts +13 -0
  37. package/dist/core/utils.js +32 -0
  38. package/dist/leepi.css +461 -0
  39. package/dist/react/code-block-popover.d.ts +76 -0
  40. package/dist/react/code-block-popover.js +223 -0
  41. package/dist/react/context.d.ts +42 -0
  42. package/dist/react/context.js +88 -0
  43. package/dist/react/editor.d.ts +30 -0
  44. package/dist/react/editor.js +60 -0
  45. package/dist/react/floating-toolbar.d.ts +30 -0
  46. package/dist/react/floating-toolbar.js +87 -0
  47. package/dist/react/link-popover.d.ts +70 -0
  48. package/dist/react/link-popover.js +222 -0
  49. package/dist/react/preview.d.ts +13 -0
  50. package/dist/react/preview.js +56 -0
  51. package/dist/react/toolbar.d.ts +51 -0
  52. package/dist/react/toolbar.js +161 -0
  53. package/package.json +90 -1
  54. package/src/core/active-marks.ts +89 -0
  55. package/src/core/commands.ts +461 -0
  56. package/src/core/editor.ts +139 -0
  57. package/src/core/field-notifier.ts +71 -0
  58. package/src/core/highlight-style.ts +66 -0
  59. package/src/core/highlight.ts +50 -0
  60. package/src/core/plugins/blockquote.ts +108 -0
  61. package/src/core/plugins/bracket.ts +34 -0
  62. package/src/core/plugins/code-block.ts +195 -0
  63. package/src/core/plugins/heading.ts +95 -0
  64. package/src/core/plugins/index.ts +16 -0
  65. package/src/core/plugins/inline.ts +62 -0
  66. package/src/core/plugins/link.ts +124 -0
  67. package/src/core/plugins/list.ts +68 -0
  68. package/src/core/plugins/table.ts +217 -0
  69. package/src/core/popover.ts +17 -0
  70. package/src/core/registry.ts +18 -0
  71. package/src/core/types.ts +25 -0
  72. package/src/core/utils.ts +38 -0
  73. package/src/react/code-block-popover.tsx +387 -0
  74. package/src/react/context.tsx +153 -0
  75. package/src/react/editor.tsx +106 -0
  76. package/src/react/floating-toolbar.tsx +161 -0
  77. package/src/react/link-popover.tsx +354 -0
  78. package/src/react/preview.tsx +80 -0
  79. package/src/react/toolbar.tsx +294 -0
  80. package/src/styles/floating-toolbar.css +52 -0
  81. package/src/styles/leepi.css +2 -0
  82. package/src/styles/popover.css +93 -0
  83. package/src/styles/preview.css +191 -0
  84. package/src/styles/theme.css +99 -0
  85. package/src/styles/tokens.css +63 -0
  86. package/src/styles/toolbar.css +55 -0
@@ -0,0 +1,294 @@
1
+ import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
2
+ import { type EditorView } from "@codemirror/view";
3
+ import { useCallback, type ComponentProps, type JSX, type ReactNode } from "react";
4
+
5
+ import {
6
+ findCodeFenceAtCursor,
7
+ findLinkAtCursor,
8
+ toggleBlockquote,
9
+ toggleHeading,
10
+ toggleListKind,
11
+ toggleMarker,
12
+ } from "../core/commands";
13
+ import { openPopover } from "../core/popover";
14
+ import type { LinkRequest } from "../core/plugins/link";
15
+ import type { CodeBlockRequest } from "../core/plugins/code-block";
16
+ import { useActiveMarks, useEditorContext } from "./context";
17
+
18
+ // ---------------------------------------------------------------------------
19
+ // Action types
20
+ // ---------------------------------------------------------------------------
21
+
22
+ export type InlineAction = "bold" | "italic" | "strikethrough" | "code" | "link";
23
+ export type BlockAction =
24
+ | "heading1"
25
+ | "heading2"
26
+ | "heading3"
27
+ | "orderedList"
28
+ | "unorderedList"
29
+ | "taskList"
30
+ | "blockquote"
31
+ | "codeblock";
32
+
33
+ // ---------------------------------------------------------------------------
34
+ // Inline commands
35
+ // ---------------------------------------------------------------------------
36
+
37
+ const boldCmd = toggleMarker("**");
38
+ const italicCmd = toggleMarker("_");
39
+ const strikethroughCmd = toggleMarker("~~");
40
+ const codeCmd = toggleMarker("`");
41
+
42
+ const inlineCommands: Record<Exclude<InlineAction, "link">, (view: EditorView) => void> = {
43
+ bold: boldCmd,
44
+ italic: italicCmd,
45
+ strikethrough: strikethroughCmd,
46
+ code: codeCmd,
47
+ };
48
+
49
+ // ---------------------------------------------------------------------------
50
+ // Block commands
51
+ // ---------------------------------------------------------------------------
52
+
53
+ const heading1Cmd = toggleHeading(1);
54
+ const heading2Cmd = toggleHeading(2);
55
+ const heading3Cmd = toggleHeading(3);
56
+ const ulCmd = toggleListKind("ul");
57
+ const olCmd = toggleListKind("ol");
58
+ const taskCmd = toggleListKind("task");
59
+
60
+ const blockCommands: Record<Exclude<BlockAction, "codeblock">, (view: EditorView) => void> = {
61
+ heading1: heading1Cmd,
62
+ heading2: heading2Cmd,
63
+ heading3: heading3Cmd,
64
+ orderedList: ulCmd,
65
+ unorderedList: olCmd,
66
+ taskList: taskCmd,
67
+ blockquote: toggleBlockquote,
68
+ };
69
+
70
+ // ---------------------------------------------------------------------------
71
+ // Shared: prevent editor focus loss on any toolbar button mousedown
72
+ // ---------------------------------------------------------------------------
73
+
74
+ function preventFocusLoss(e: React.MouseEvent) {
75
+ e.preventDefault();
76
+ }
77
+
78
+ // ---------------------------------------------------------------------------
79
+ // Toolbar.InlineButton
80
+ // ---------------------------------------------------------------------------
81
+
82
+ export interface ToolbarInlineButtonProps extends Omit<
83
+ ComponentProps<typeof BaseToolbar.Button>,
84
+ "children"
85
+ > {
86
+ action: InlineAction;
87
+ children?: ReactNode;
88
+ }
89
+
90
+ function ToolbarInlineButton({
91
+ action,
92
+ children,
93
+ className,
94
+ ...props
95
+ }: ToolbarInlineButtonProps): JSX.Element {
96
+ const { view } = useEditorContext();
97
+ const marks = useActiveMarks();
98
+ const active = marks[action] ?? false;
99
+ const disabled = marks.codeblock ?? false;
100
+
101
+ const handleClick = useCallback(() => {
102
+ if (!view || disabled) return;
103
+
104
+ if (action === "link") {
105
+ const { state } = view;
106
+ const range = state.selection.main;
107
+ const existing = findLinkAtCursor(state, range.from);
108
+ const coords = view.coordsAtPos(range.from);
109
+ if (!coords) return;
110
+
111
+ const req: LinkRequest = existing
112
+ ? {
113
+ type: "link",
114
+ x: coords.left,
115
+ y: coords.bottom,
116
+ data: {
117
+ text: existing.label,
118
+ url: existing.url,
119
+ from: existing.from,
120
+ to: existing.to,
121
+ },
122
+ }
123
+ : {
124
+ type: "link",
125
+ x: coords.left,
126
+ y: coords.bottom,
127
+ data: {
128
+ text: state.sliceDoc(range.from, range.to),
129
+ url: "",
130
+ from: range.from,
131
+ to: range.to,
132
+ },
133
+ };
134
+
135
+ view.dispatch({ effects: openPopover.of(req) });
136
+ } else {
137
+ inlineCommands[action](view);
138
+ view.focus();
139
+ }
140
+ }, [view, disabled, action]);
141
+
142
+ return (
143
+ <BaseToolbar.Button
144
+ disabled={disabled}
145
+ className={`lp-toolbar-btn${active ? " lp-toolbar-btn--active" : ""} ${className || ""}`}
146
+ onMouseDown={preventFocusLoss}
147
+ onClick={handleClick}
148
+ {...props}
149
+ >
150
+ {children}
151
+ </BaseToolbar.Button>
152
+ );
153
+ }
154
+
155
+ // ---------------------------------------------------------------------------
156
+ // Toolbar.BlockButton
157
+ // ---------------------------------------------------------------------------
158
+
159
+ export interface ToolbarBlockButtonProps extends Omit<
160
+ ComponentProps<typeof BaseToolbar.Button>,
161
+ "children"
162
+ > {
163
+ action: BlockAction;
164
+ children?: ReactNode;
165
+ }
166
+
167
+ function ToolbarBlockButton({
168
+ action,
169
+ children,
170
+ className,
171
+ ...props
172
+ }: ToolbarBlockButtonProps): JSX.Element {
173
+ const { view } = useEditorContext();
174
+ const marks = useActiveMarks();
175
+ const active = marks[action] ?? false;
176
+ const disabled = (marks.codeblock ?? false) && action !== "codeblock";
177
+
178
+ const handleClick = useCallback(() => {
179
+ if (!view || disabled) return;
180
+
181
+ if (action === "codeblock") {
182
+ // Dispatch StateEffect to open code block popover
183
+ const { state } = view;
184
+ const range = state.selection.main;
185
+ const coords = view.coordsAtPos(range.from);
186
+ if (!coords) return;
187
+
188
+ const existing = findCodeFenceAtCursor(view);
189
+ const req: CodeBlockRequest = existing
190
+ ? {
191
+ type: "codeblock",
192
+ x: coords.left,
193
+ y: coords.bottom,
194
+ data: {
195
+ lang: existing.lang,
196
+ filename: existing.filename,
197
+ fenceFrom: existing.fenceLine.from,
198
+ fenceTo: existing.fenceLine.to,
199
+ isNew: false,
200
+ },
201
+ }
202
+ : {
203
+ type: "codeblock",
204
+ x: coords.left,
205
+ y: coords.bottom,
206
+ data: {
207
+ lang: "",
208
+ filename: "",
209
+ fenceFrom: 0,
210
+ fenceTo: 0,
211
+ isNew: true,
212
+ insertPos: range.from,
213
+ },
214
+ };
215
+
216
+ view.dispatch({ effects: openPopover.of(req) });
217
+ return;
218
+ }
219
+
220
+ blockCommands[action](view);
221
+ view.focus();
222
+ }, [view, disabled, action]);
223
+
224
+ return (
225
+ <BaseToolbar.Button
226
+ disabled={disabled}
227
+ className={`lp-toolbar-btn${active ? " lp-toolbar-btn--active" : ""} ${className || ""}`}
228
+ onMouseDown={preventFocusLoss}
229
+ onClick={handleClick}
230
+ {...props}
231
+ >
232
+ {children}
233
+ </BaseToolbar.Button>
234
+ );
235
+ }
236
+
237
+ // ---------------------------------------------------------------------------
238
+ // Toolbar.Button — generic passthrough
239
+ // ---------------------------------------------------------------------------
240
+
241
+ type ToolbarButtonProps = ComponentProps<typeof BaseToolbar.Button>;
242
+
243
+ function ToolbarButton({ className, ...props }: ToolbarButtonProps): JSX.Element {
244
+ return <BaseToolbar.Button className={`lp-toolbar-btn ${className || ""}`} {...props} />;
245
+ }
246
+
247
+ // ---------------------------------------------------------------------------
248
+ // Toolbar.Separator
249
+ // ---------------------------------------------------------------------------
250
+
251
+ type ToolbarSeparatorProps = ComponentProps<typeof BaseToolbar.Separator>;
252
+
253
+ function ToolbarSeparator({ className, ...props }: ToolbarSeparatorProps): JSX.Element {
254
+ return <BaseToolbar.Separator className={`lp-toolbar-separator ${className || ""}`} {...props} />;
255
+ }
256
+
257
+ // ---------------------------------------------------------------------------
258
+ // Toolbar.Group
259
+ // ---------------------------------------------------------------------------
260
+
261
+ type ToolbarGroupProps = ComponentProps<typeof BaseToolbar.Group>;
262
+
263
+ function ToolbarGroup({ className, ...props }: ToolbarGroupProps): JSX.Element {
264
+ return <BaseToolbar.Group className={`lp-toolbar-group ${className || ""}`} {...props} />;
265
+ }
266
+
267
+ // ---------------------------------------------------------------------------
268
+ // Toolbar root
269
+ // ---------------------------------------------------------------------------
270
+
271
+ export interface ToolbarProps extends Omit<ComponentProps<typeof BaseToolbar.Root>, "children"> {
272
+ children?: ReactNode;
273
+ }
274
+
275
+ function ToolbarRoot({ children, className, ...props }: ToolbarProps): JSX.Element {
276
+ return (
277
+ <BaseToolbar.Root className={`lp-toolbar ${className || ""}`} {...props}>
278
+ {children}
279
+ </BaseToolbar.Root>
280
+ );
281
+ }
282
+
283
+ // ---------------------------------------------------------------------------
284
+ // Namespace exports
285
+ // ---------------------------------------------------------------------------
286
+
287
+ export {
288
+ ToolbarBlockButton as BlockButton,
289
+ ToolbarButton as Button,
290
+ ToolbarGroup as Group,
291
+ ToolbarInlineButton as InlineButton,
292
+ ToolbarRoot as Root,
293
+ ToolbarSeparator as Separator,
294
+ };
@@ -0,0 +1,52 @@
1
+ @layer components {
2
+ .lp-floating-toolbar {
3
+ display: flex;
4
+ align-items: center;
5
+ gap: 2px;
6
+ padding: 0.25rem;
7
+ border-radius: 6px;
8
+ z-index: 100;
9
+ pointer-events: auto;
10
+ }
11
+
12
+ .lp-floating-toolbar-btn {
13
+ display: inline-flex;
14
+ align-items: center;
15
+ justify-content: center;
16
+ width: 1.75rem;
17
+ height: 1.75rem;
18
+ padding: 0;
19
+ border: none;
20
+ background: transparent;
21
+ color: inherit;
22
+ border-radius: 4px;
23
+ cursor: pointer;
24
+ font: inherit;
25
+ font-size: 0.75rem;
26
+ font-weight: 600;
27
+ }
28
+
29
+ .lp-floating-toolbar-btn--active {
30
+ color: var(--lp-color-accent, #0078d4);
31
+ background: var(--lp-color-selection, rgba(0, 120, 212, 0.15));
32
+ }
33
+
34
+ .lp-floating-toolbar-btn svg {
35
+ display: block;
36
+ width: 14px;
37
+ height: 14px;
38
+ }
39
+
40
+ .lp-floating-toolbar-separator {
41
+ width: 1px;
42
+ height: 1rem;
43
+ margin: 0 0.25rem;
44
+ background: var(--lp-color-border, #e0e0e0);
45
+ }
46
+
47
+ .lp-floating-toolbar-group {
48
+ display: flex;
49
+ align-items: center;
50
+ gap: 1px;
51
+ }
52
+ }
@@ -0,0 +1,2 @@
1
+ @layer components {
2
+ }
@@ -0,0 +1,93 @@
1
+ @layer components {
2
+ .lp-popover-positioner {
3
+ z-index: 50;
4
+ }
5
+
6
+ .lp-popover {
7
+ border: 1px solid var(--lp-color-border, rgba(0, 0, 0, 0.12));
8
+ border-radius: calc(var(--lp-radius, 6px) + 2px);
9
+ }
10
+
11
+ .lp-popover-form {
12
+ display: flex;
13
+ flex-direction: column;
14
+ gap: 1rem;
15
+ padding: 1.25rem;
16
+ width: 22rem;
17
+ }
18
+
19
+ .lp-popover-field {
20
+ display: flex;
21
+ flex-direction: column;
22
+ gap: 0.4rem;
23
+ }
24
+
25
+ .lp-popover-label {
26
+ font-size: 0.75rem;
27
+ text-transform: uppercase;
28
+ letter-spacing: 0.03em;
29
+ }
30
+
31
+ .lp-popover-input {
32
+ height: 2.25rem;
33
+ padding: 0 0.75rem;
34
+ border-radius: var(--lp-radius, 6px);
35
+ font: inherit;
36
+ font-size: 0.85rem;
37
+ border: 1px solid var(--lp-color-border, rgba(0, 0, 0, 0.12));
38
+ outline: none;
39
+ }
40
+
41
+ .lp-popover-input:focus {
42
+ border-color: var(--lp-color-accent, #0078d4);
43
+ }
44
+
45
+ .lp-popover-actions {
46
+ display: flex;
47
+ justify-content: space-between;
48
+ align-items: center;
49
+ padding-top: 0.375rem;
50
+ }
51
+
52
+ .lp-popover-actions-end {
53
+ display: flex;
54
+ gap: 0.5rem;
55
+ }
56
+
57
+ .lp-popover-btn {
58
+ height: 2rem;
59
+ padding: 0 0.875rem;
60
+ border-radius: var(--lp-radius, 6px);
61
+ font: inherit;
62
+ font-size: 0.8rem;
63
+ font-weight: 500;
64
+ cursor: pointer;
65
+ border: 1px solid transparent;
66
+ }
67
+
68
+ .lp-popover-btn:disabled {
69
+ opacity: 0.5;
70
+ cursor: not-allowed;
71
+ }
72
+
73
+ .lp-popover-select {
74
+ appearance: none;
75
+ height: 2.25rem;
76
+ padding: 0 2rem 0 0.75rem;
77
+ border-radius: var(--lp-radius, 6px);
78
+ font: inherit;
79
+ font-size: 0.85rem;
80
+ border: 1px solid var(--lp-color-border, rgba(0, 0, 0, 0.12));
81
+ background: transparent;
82
+ color: inherit;
83
+ cursor: pointer;
84
+ outline: none;
85
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
86
+ background-repeat: no-repeat;
87
+ background-position: right 0.75rem center;
88
+ }
89
+
90
+ .lp-popover-select:focus {
91
+ border-color: var(--lp-color-accent, #0078d4);
92
+ }
93
+ }
@@ -0,0 +1,191 @@
1
+ @layer components {
2
+ .lp-preview h1,
3
+ .lp-preview h2,
4
+ .lp-preview h3,
5
+ .lp-preview h4,
6
+ .lp-preview h5,
7
+ .lp-preview h6 {
8
+ margin-top: 1.5em;
9
+ margin-bottom: 0.5em;
10
+ line-height: 1.3;
11
+ font-family: var(--lp-font-display);
12
+ }
13
+ .lp-preview h1 {
14
+ font-size: 2em;
15
+ font-weight: 700;
16
+ }
17
+ .lp-preview h2 {
18
+ font-size: 1.6em;
19
+ font-weight: 700;
20
+ }
21
+ .lp-preview h3 {
22
+ font-size: 1.3em;
23
+ font-weight: 600;
24
+ }
25
+ .lp-preview h4 {
26
+ font-size: 1.1em;
27
+ font-weight: 600;
28
+ }
29
+ .lp-preview p {
30
+ margin-top: 0.75em;
31
+ margin-bottom: 0.75em;
32
+ }
33
+ .lp-preview a {
34
+ text-decoration: underline;
35
+ }
36
+ .lp-preview del {
37
+ text-decoration: line-through;
38
+ }
39
+ .lp-preview code {
40
+ font-family: var(--lp-font-mono, ui-monospace, monospace);
41
+ font-size: 0.875em;
42
+ }
43
+ .lp-preview .lp-code-block {
44
+ border-radius: 8px;
45
+ margin: 1em 0;
46
+ overflow: hidden;
47
+ border: 1px solid var(--lp-color-border, rgba(0, 0, 0, 0.12));
48
+ }
49
+ .lp-preview .lp-code-header {
50
+ display: flex;
51
+ justify-content: space-between;
52
+ padding: 0.4em 1em;
53
+ font-family: var(--lp-font-mono, ui-monospace, monospace);
54
+ font-size: 0.75rem;
55
+ border-bottom: 1px solid var(--lp-color-border, rgba(0, 0, 0, 0.12));
56
+ letter-spacing: 0.05em;
57
+ }
58
+ .lp-preview .lp-code-header-lang {
59
+ text-transform: uppercase;
60
+ }
61
+ .lp-preview .lp-code-block pre {
62
+ margin: 0;
63
+ border-radius: 0;
64
+ background: none;
65
+ }
66
+ .lp-preview .lp-code-block code {
67
+ display: table;
68
+ }
69
+ .lp-preview .lp-code-row {
70
+ display: table-row;
71
+ line-height: 1.5;
72
+ }
73
+ .lp-preview .lp-code-line-number {
74
+ display: table-cell;
75
+ text-align: right;
76
+ padding-right: 1em;
77
+ user-select: none;
78
+ opacity: 0.5;
79
+ white-space: nowrap;
80
+ vertical-align: top;
81
+ }
82
+ .lp-preview .lp-code-line {
83
+ display: table-cell;
84
+ white-space: pre;
85
+ }
86
+ .lp-preview pre {
87
+ border-radius: 8px;
88
+ padding: 1em;
89
+ overflow-x: auto;
90
+ margin: 1em 0;
91
+ }
92
+ .lp-preview pre code {
93
+ background: none;
94
+ padding: 0;
95
+ font-size: 0.875em;
96
+ }
97
+ .lp-preview blockquote {
98
+ border-left: 3px solid var(--lp-color-border, rgba(0, 0, 0, 0.12));
99
+ padding-left: 1em;
100
+ font-style: italic;
101
+ margin: 1em 0;
102
+ }
103
+ .lp-preview ul,
104
+ .lp-preview ol {
105
+ padding-left: 1.5em;
106
+ margin: 0.75em 0;
107
+ }
108
+ .lp-preview ul {
109
+ list-style-type: disc;
110
+ }
111
+ .lp-preview ol {
112
+ list-style-type: decimal;
113
+ }
114
+ .lp-preview li {
115
+ margin: 0.25em 0;
116
+ }
117
+ .lp-preview hr {
118
+ border: none;
119
+ border-top: 1px solid var(--lp-color-border, rgba(0, 0, 0, 0.12));
120
+ margin: 1.5em 0;
121
+ }
122
+ .lp-preview table {
123
+ width: 100%;
124
+ border-collapse: collapse;
125
+ margin: 1em 0;
126
+ }
127
+ .lp-preview th,
128
+ .lp-preview td {
129
+ border: 1px solid var(--lp-color-border, rgba(0, 0, 0, 0.12));
130
+ padding: 0.5em 0.75em;
131
+ text-align: left;
132
+ }
133
+ .lp-preview img {
134
+ max-width: 100%;
135
+ }
136
+ .lp-preview input[type="checkbox"] {
137
+ margin-right: 0.5em;
138
+ }
139
+
140
+ /* Syntax token classes from Lezer classHighlighter */
141
+ .tok-keyword {
142
+ color: var(--lp-syntax-keyword);
143
+ }
144
+ .tok-operator {
145
+ color: var(--lp-syntax-operator);
146
+ }
147
+ .tok-variableName {
148
+ color: var(--lp-syntax-variable);
149
+ }
150
+ .tok-typeName,
151
+ .tok-className,
152
+ .tok-definition,
153
+ .tok-namespace {
154
+ color: var(--lp-syntax-type);
155
+ }
156
+ .tok-propertyName {
157
+ color: var(--lp-syntax-property);
158
+ }
159
+ .tok-comment {
160
+ color: var(--lp-syntax-comment);
161
+ font-style: italic;
162
+ }
163
+ .tok-string,
164
+ .tok-string2,
165
+ .tok-attributeValue,
166
+ .tok-regexp {
167
+ color: var(--lp-syntax-string);
168
+ }
169
+ .tok-number,
170
+ .tok-bool,
171
+ .tok-null,
172
+ .tok-atom {
173
+ color: var(--lp-syntax-number);
174
+ }
175
+ .tok-function {
176
+ color: var(--lp-syntax-function);
177
+ }
178
+ .tok-tagName {
179
+ color: var(--lp-syntax-tag);
180
+ }
181
+ .tok-attributeName {
182
+ color: var(--lp-syntax-attribute);
183
+ }
184
+ .tok-escape,
185
+ .tok-link {
186
+ color: var(--lp-syntax-escape);
187
+ }
188
+ .tok-punctuation {
189
+ color: var(--lp-syntax-punctuation);
190
+ }
191
+ }