@domternal/theme 0.2.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.
@@ -0,0 +1,213 @@
1
+ // =============================================================================
2
+ // Toolbar Styles
3
+ // =============================================================================
4
+
5
+ .dm-toolbar {
6
+ display: flex;
7
+ flex-wrap: wrap;
8
+ align-items: center;
9
+ justify-content: var(--dm-toolbar-justify, flex-start);
10
+ gap: var(--dm-toolbar-gap);
11
+ padding: var(--dm-toolbar-padding);
12
+ background: var(--dm-toolbar-bg);
13
+ border: 1px solid var(--dm-border-color, #e5e7eb);
14
+ border-bottom: 1px solid var(--dm-border-color, #e5e7eb);
15
+ border-radius: var(--dm-toolbar-border-radius);
16
+ box-shadow: var(--dm-editor-shadow, none);
17
+ }
18
+
19
+ // Button group
20
+ .dm-toolbar-group {
21
+ display: flex;
22
+ align-items: center;
23
+ gap: var(--dm-toolbar-gap);
24
+ }
25
+
26
+ // Individual button
27
+ .dm-toolbar-button {
28
+ display: inline-flex;
29
+ align-items: center;
30
+ justify-content: center;
31
+ width: var(--dm-button-size);
32
+ height: var(--dm-button-size);
33
+ padding: 0;
34
+ border: none;
35
+ border-radius: var(--dm-button-border-radius);
36
+ background: transparent;
37
+ color: var(--dm-button-color);
38
+ cursor: pointer;
39
+ transition: background-color 0.15s, color 0.15s;
40
+ font-size: 0.875rem;
41
+ line-height: 1;
42
+
43
+ &:hover {
44
+ background: var(--dm-button-hover-bg);
45
+ }
46
+
47
+ // Active state (e.g. bold is on)
48
+ &--active {
49
+ background: var(--dm-button-active-bg);
50
+ color: var(--dm-button-active-color);
51
+ }
52
+
53
+ // Expanded state — panel/popover is open (same visual as dropdown triggers)
54
+ &[aria-expanded="true"] {
55
+ background: var(--dm-button-hover-bg);
56
+ }
57
+
58
+ // Disabled state
59
+ &--disabled,
60
+ &:disabled {
61
+ opacity: var(--dm-button-disabled-opacity);
62
+ cursor: not-allowed;
63
+ pointer-events: none;
64
+ }
65
+
66
+ // Icon inside button
67
+ svg {
68
+ width: 1.125rem;
69
+ height: 1.125rem;
70
+ }
71
+ }
72
+
73
+ // Dropdown trigger — wider to fit caret
74
+ .dm-toolbar-dropdown-trigger {
75
+ position: relative;
76
+ width: auto;
77
+ padding: 0 0.375rem;
78
+ gap: 0.125rem;
79
+
80
+ &[aria-expanded="true"] {
81
+ background: var(--dm-button-hover-bg);
82
+ }
83
+ }
84
+
85
+ // Color indicator bar under color-picker dropdown trigger icons
86
+ .dm-toolbar-color-indicator {
87
+ position: absolute;
88
+ bottom: 0.15rem;
89
+ left: 0.25rem;
90
+ width: 1.375rem;
91
+ height: 0.3rem;
92
+ border-radius: 2px;
93
+ }
94
+
95
+ // Text label inside dropdown trigger (dynamicLabel mode)
96
+ .dm-toolbar-trigger-label {
97
+ display: inline-block;
98
+ vertical-align: middle;
99
+ text-align: center;
100
+ font-size: 0.8125rem;
101
+ line-height: 1;
102
+ white-space: nowrap;
103
+ overflow: hidden;
104
+ text-overflow: ellipsis;
105
+ width: 2.5rem;
106
+
107
+ // Icon inside label span (e.g. font-size icon for headings)
108
+ svg {
109
+ width: 1.125rem;
110
+ height: 1.125rem;
111
+ }
112
+ }
113
+
114
+ // Wider trigger label for dropdowns with long labels (e.g. font family names)
115
+ [data-dropdown="fontFamily"] .dm-toolbar-trigger-label {
116
+ width: 5rem;
117
+ }
118
+
119
+ // Dropdown caret icon
120
+ .dm-toolbar-button .dm-dropdown-caret {
121
+ width: 0.625rem;
122
+ height: 0.625rem;
123
+ flex-shrink: 0;
124
+ }
125
+
126
+ // Dropdown wrapper
127
+ .dm-toolbar-dropdown-wrapper {
128
+ position: relative;
129
+ }
130
+
131
+ // Dropdown panel — positioned by floating-ui (strategy: absolute)
132
+ .dm-toolbar-dropdown-panel {
133
+ position: absolute;
134
+ z-index: 50;
135
+ display: flex;
136
+ flex-direction: column;
137
+ gap: 0.125rem;
138
+ min-width: 8rem;
139
+ padding: 0.25rem;
140
+ background: var(--dm-bg, #fff);
141
+ border: 1px solid var(--dm-border-color, #e5e7eb);
142
+ border-radius: 0.5rem;
143
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08), 0 1px 3px rgba(0, 0, 0, 0.04);
144
+ animation: dm-fade-in 0.2s ease;
145
+
146
+ // Color palette panels get a softer, rounder container
147
+ &.dm-color-palette {
148
+ padding: 0.5rem;
149
+ border-radius: 0.75rem;
150
+ }
151
+ }
152
+
153
+ // Display-mode: icon-only — compact grid-like panel
154
+ .dm-toolbar-dropdown-panel[data-display-mode="icon"] {
155
+ min-width: 0;
156
+
157
+ .dm-toolbar-dropdown-item {
158
+ width: auto;
159
+ padding: 0.375rem;
160
+ justify-content: center;
161
+ }
162
+ }
163
+
164
+ // Display-mode: text-only — shrink to text width, no icon gap
165
+ .dm-toolbar-dropdown-panel[data-display-mode="text"] {
166
+ min-width: 0;
167
+
168
+ .dm-toolbar-dropdown-item {
169
+ gap: 0;
170
+ }
171
+ }
172
+
173
+ // Dropdown item
174
+ .dm-toolbar-dropdown-item {
175
+ display: flex;
176
+ align-items: center;
177
+ gap: 0.5rem;
178
+ width: 100%;
179
+ padding: 0.375rem 0.5rem;
180
+ border: none;
181
+ border-radius: var(--dm-button-border-radius);
182
+ background: transparent;
183
+ color: var(--dm-button-color);
184
+ cursor: pointer;
185
+ font-size: 0.8125rem;
186
+ line-height: 1.4;
187
+ text-align: left;
188
+ white-space: nowrap;
189
+ transition: background-color 0.15s;
190
+
191
+ &:hover {
192
+ background: var(--dm-button-hover-bg);
193
+ }
194
+
195
+ &--active {
196
+ color: var(--dm-button-active-color);
197
+ background: var(--dm-button-active-bg);
198
+ }
199
+
200
+ svg {
201
+ width: 1rem;
202
+ height: 1rem;
203
+ flex-shrink: 0;
204
+ }
205
+ }
206
+
207
+ // Vertical separator between button groups
208
+ .dm-toolbar-separator {
209
+ width: 1px;
210
+ height: 1.25rem;
211
+ background: var(--dm-separator-color);
212
+ margin: 0 var(--dm-separator-margin);
213
+ }
@@ -0,0 +1,150 @@
1
+ // =============================================================================
2
+ // CSS Custom Properties (Design Tokens)
3
+ // =============================================================================
4
+ // All visual properties are CSS custom properties on .dm-editor.
5
+ // Override any variable on a parent or the component itself to customize.
6
+ //
7
+ // Example:
8
+ // .my-editor {
9
+ // --dm-editor-bg: #fafafa;
10
+ // --dm-accent: hotpink;
11
+ // }
12
+ // =============================================================================
13
+
14
+ .dm-editor {
15
+ // ---------------------------------------------------------------------------
16
+ // Semantic base tokens (used by component tokens below)
17
+ // ---------------------------------------------------------------------------
18
+ --dm-bg: #ffffff;
19
+ --dm-text: #1a1a1a;
20
+ --dm-muted: #999999;
21
+ --dm-surface: #f8f9fa;
22
+ --dm-border-color: #e5e7eb;
23
+ --dm-hover: rgba(0, 0, 0, 0.04);
24
+ --dm-active: rgba(0, 0, 0, 0.1);
25
+ --dm-accent: #2563eb;
26
+ --dm-accent-hover: #1d4ed8;
27
+ --dm-accent-surface: rgba(37, 99, 235, 0.1);
28
+ --dm-focus-color: rgba(66, 133, 244, 0.3);
29
+ --dm-selection: rgba(66, 133, 244, 0.2);
30
+ --dm-code-surface: #f0f0f0;
31
+ --dm-code-color: inherit;
32
+
33
+ // ---------------------------------------------------------------------------
34
+ // Editor
35
+ // ---------------------------------------------------------------------------
36
+ --dm-editor-bg: var(--dm-bg);
37
+ --dm-editor-text: var(--dm-text);
38
+ --dm-editor-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
39
+ Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
40
+ --dm-editor-font-size: 1rem;
41
+ --dm-editor-line-height: 1.6;
42
+ --dm-editor-padding: 1rem;
43
+ --dm-editor-border: 1px solid var(--dm-border-color);
44
+ --dm-editor-border-radius: 0.75rem;
45
+ // Override to add a focus ring, e.g. 0 0 0 1px var(--dm-focus-color)
46
+ --dm-editor-focus-ring: none;
47
+ --dm-editor-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.02);
48
+
49
+ // ---------------------------------------------------------------------------
50
+ // Placeholder
51
+ // ---------------------------------------------------------------------------
52
+ --dm-placeholder-color: var(--dm-muted);
53
+
54
+ // ---------------------------------------------------------------------------
55
+ // Links
56
+ // ---------------------------------------------------------------------------
57
+ --dm-link-color: var(--dm-accent);
58
+ --dm-link-hover-color: var(--dm-accent-hover);
59
+
60
+ // ---------------------------------------------------------------------------
61
+ // Inline code
62
+ // ---------------------------------------------------------------------------
63
+ --dm-code-bg: var(--dm-code-surface);
64
+ --dm-code-text: var(--dm-code-color);
65
+ --dm-code-font: "SF Mono", "Fira Code", Consolas, "Liberation Mono", Menlo, monospace;
66
+ --dm-code-border-radius: 0.25rem;
67
+
68
+ // ---------------------------------------------------------------------------
69
+ // Code blocks
70
+ // ---------------------------------------------------------------------------
71
+ --dm-code-block-bg: var(--dm-code-surface);
72
+ --dm-code-block-text: var(--dm-text);
73
+
74
+ // ---------------------------------------------------------------------------
75
+ // Syntax highlighting (CodeBlockLowlight)
76
+ // ---------------------------------------------------------------------------
77
+ --dm-syntax-keyword: #d73a49;
78
+ --dm-syntax-entity: #6f42c1;
79
+ --dm-syntax-constant: #005cc5;
80
+ --dm-syntax-string: #032f62;
81
+ --dm-syntax-variable: #e36209;
82
+ --dm-syntax-comment: #6a737d;
83
+ --dm-syntax-tag: #22863a;
84
+ --dm-syntax-addition: #22863a;
85
+ --dm-syntax-addition-bg: #f0fff4;
86
+ --dm-syntax-deletion: #b31d28;
87
+ --dm-syntax-deletion-bg: #ffeef0;
88
+
89
+ // ---------------------------------------------------------------------------
90
+ // Blockquote
91
+ // ---------------------------------------------------------------------------
92
+ --dm-blockquote-border: 3px solid #6a6a6a;
93
+ --dm-blockquote-color: #6a6a6a;
94
+
95
+ // ---------------------------------------------------------------------------
96
+ // Horizontal rule
97
+ // ---------------------------------------------------------------------------
98
+ --dm-hr-color: var(--dm-border-color);
99
+
100
+ // ---------------------------------------------------------------------------
101
+ // Table
102
+ // ---------------------------------------------------------------------------
103
+ --dm-table-border: 1px solid var(--dm-border-color);
104
+ --dm-table-header-bg: var(--dm-surface);
105
+ --dm-table-selected-bg: rgba(66, 133, 244, 0.15);
106
+
107
+ // ---------------------------------------------------------------------------
108
+ // Mention
109
+ // ---------------------------------------------------------------------------
110
+ --dm-mention-bg: var(--dm-accent-surface);
111
+ --dm-mention-color: var(--dm-accent);
112
+ --dm-mention-border-radius: 0.25rem;
113
+
114
+ // ---------------------------------------------------------------------------
115
+ // Highlight / mark
116
+ // ---------------------------------------------------------------------------
117
+ --dm-highlight-bg: #fff3cd;
118
+
119
+ // ---------------------------------------------------------------------------
120
+ // Details / accordion
121
+ // ---------------------------------------------------------------------------
122
+ --dm-details-border: 1px solid var(--dm-border-color);
123
+ --dm-details-bg: var(--dm-surface);
124
+ --dm-details-summary-font-weight: 600;
125
+ }
126
+
127
+ // =============================================================================
128
+ // Toolbar variables (on .dm-toolbar)
129
+ // =============================================================================
130
+
131
+ .dm-toolbar {
132
+ --dm-toolbar-bg: var(--dm-bg, #ffffff);
133
+ --dm-toolbar-border: none;
134
+ --dm-toolbar-padding: 0.375rem 0.5rem;
135
+ --dm-toolbar-gap: 0.125rem;
136
+ --dm-toolbar-border-radius: 0.75rem 0.75rem 0 0;
137
+
138
+ // Buttons
139
+ --dm-button-size: 2rem;
140
+ --dm-button-border-radius: 0.375rem;
141
+ --dm-button-color: var(--dm-text, #374151);
142
+ --dm-button-hover-bg: var(--dm-hover, rgba(0, 0, 0, 0.04));
143
+ --dm-button-active-bg: var(--dm-accent-surface, rgba(37, 99, 235, 0.1));
144
+ --dm-button-active-color: var(--dm-accent, #2563eb);
145
+ --dm-button-disabled-opacity: 0.35;
146
+
147
+ // Separator
148
+ --dm-separator-color: var(--dm-border-color, #e5e7eb);
149
+ --dm-separator-margin: 0.375rem;
150
+ }
package/src/index.scss ADDED
@@ -0,0 +1,53 @@
1
+ // =============================================================================
2
+ // @domternal/theme — Main Entry
3
+ // =============================================================================
4
+ // Import this file to get all Domternal editor styles:
5
+ //
6
+ // @import '@domternal/theme'; (SCSS)
7
+ // @import '@domternal/theme/css'; (precompiled CSS)
8
+ //
9
+ // Customize by overriding CSS variables on .dm-editor or a parent:
10
+ //
11
+ // .my-editor {
12
+ // --dm-accent: hotpink;
13
+ // --dm-editor-bg: #fafafa;
14
+ // }
15
+ // =============================================================================
16
+
17
+ // 1. Design tokens (CSS custom properties)
18
+ @use 'variables';
19
+
20
+ // 2. ProseMirror required styles (view, gapcursor, tables)
21
+ @use 'prosemirror';
22
+
23
+ // 3. Editor wrapper
24
+ @use 'base';
25
+
26
+ // 4. Content typography
27
+ @use 'content';
28
+
29
+ // 4b. Syntax highlighting (CodeBlockLowlight)
30
+ @use 'syntax';
31
+
32
+ // 5. Toolbar
33
+ @use 'toolbar';
34
+ @use 'color-palette';
35
+
36
+ // 6. Menus (bubble, floating, link popover)
37
+ @use 'bubble-menu';
38
+ @use 'floating-menu';
39
+ @use 'link-popover';
40
+
41
+ // 7. Extension-specific styles
42
+ @use 'placeholder';
43
+ @use 'task-list';
44
+ @use 'mention';
45
+ @use 'image';
46
+ @use 'details';
47
+ @use 'invisible-chars';
48
+ @use 'emoji-picker';
49
+ @use 'table-controls';
50
+
51
+ // 8. Themes
52
+ @use 'themes/light';
53
+ @use 'themes/dark';
@@ -0,0 +1,68 @@
1
+ // =============================================================================
2
+ // Dark Theme
3
+ // =============================================================================
4
+ // Apply .dm-theme-dark on or above the editor to activate dark theme.
5
+ // Apply .dm-theme-auto for automatic dark mode via prefers-color-scheme.
6
+ //
7
+ // Example:
8
+ // <div class="dm-theme-dark">
9
+ // <domternal-editor />
10
+ // </div>
11
+ //
12
+ // <domternal-editor class="dm-theme-auto" />
13
+ // =============================================================================
14
+
15
+ @mixin dark-tokens {
16
+ --dm-color-scheme: dark;
17
+ --dm-bg: #1e1e1e;
18
+ --dm-text: #e0e0e0;
19
+ --dm-muted: #777777;
20
+ --dm-surface: #2a2a2a;
21
+ --dm-border-color: #3a3a3a;
22
+ --dm-hover: rgba(255, 255, 255, 0.08);
23
+ --dm-active: rgba(255, 255, 255, 0.15);
24
+ --dm-accent: #60a5fa;
25
+ --dm-accent-hover: #93c5fd;
26
+ --dm-accent-surface: rgba(96, 165, 250, 0.15);
27
+ --dm-focus-color: rgba(96, 165, 250, 0.3);
28
+ --dm-selection: rgba(96, 165, 250, 0.25);
29
+ --dm-code-surface: #2d2d2d;
30
+ --dm-code-color: inherit;
31
+ --dm-highlight-bg: rgba(255, 243, 205, 0.2);
32
+ --dm-blockquote-border: 3px solid #555555;
33
+ --dm-blockquote-color: #a0a0a0;
34
+
35
+ // Syntax highlighting
36
+ --dm-syntax-keyword: #ff7b72;
37
+ --dm-syntax-entity: #d2a8ff;
38
+ --dm-syntax-constant: #79c0ff;
39
+ --dm-syntax-string: #a5d6ff;
40
+ --dm-syntax-variable: #ffa657;
41
+ --dm-syntax-comment: #8b949e;
42
+ --dm-syntax-tag: #7ee787;
43
+ --dm-syntax-addition: #aff5b4;
44
+ --dm-syntax-addition-bg: #033a16;
45
+ --dm-syntax-deletion: #ffdcd7;
46
+ --dm-syntax-deletion-bg: #67060c;
47
+ }
48
+
49
+ .dm-theme-dark,
50
+ .dm-theme-dark .dm-editor,
51
+ .dm-theme-dark .dm-toolbar,
52
+ .dm-theme-dark .dm-bubble-menu,
53
+ .dm-theme-dark .dm-emoji-picker,
54
+ .dm-theme-dark .dm-emoji-suggestion {
55
+ @include dark-tokens;
56
+ }
57
+
58
+ // Auto dark mode — follows system preference
59
+ @media (prefers-color-scheme: dark) {
60
+ .dm-theme-auto,
61
+ .dm-theme-auto .dm-editor,
62
+ .dm-theme-auto .dm-toolbar,
63
+ .dm-theme-auto .dm-bubble-menu,
64
+ .dm-theme-auto .dm-emoji-picker,
65
+ .dm-theme-auto .dm-emoji-suggestion {
66
+ @include dark-tokens;
67
+ }
68
+ }
@@ -0,0 +1,43 @@
1
+ // =============================================================================
2
+ // Light Theme
3
+ // =============================================================================
4
+ // Light is the default — CSS variables in _variables.scss already use light
5
+ // values. This class exists for explicit light override in a dark context.
6
+ // =============================================================================
7
+
8
+ @mixin light-tokens {
9
+ --dm-bg: #ffffff;
10
+ --dm-text: #1a1a1a;
11
+ --dm-muted: #999999;
12
+ --dm-surface: #f8f9fa;
13
+ --dm-border-color: #e0e0e0;
14
+ --dm-hover: rgba(0, 0, 0, 0.06);
15
+ --dm-active: rgba(0, 0, 0, 0.12);
16
+ --dm-accent: #2563eb;
17
+ --dm-accent-hover: #1d4ed8;
18
+ --dm-accent-surface: rgba(37, 99, 235, 0.1);
19
+ --dm-focus-color: rgba(66, 133, 244, 0.3);
20
+ --dm-selection: rgba(66, 133, 244, 0.2);
21
+ --dm-code-surface: #f5f5f5;
22
+ --dm-code-color: #d63384;
23
+ --dm-highlight-bg: #fff3cd;
24
+
25
+ // Syntax highlighting
26
+ --dm-syntax-keyword: #d73a49;
27
+ --dm-syntax-entity: #6f42c1;
28
+ --dm-syntax-constant: #005cc5;
29
+ --dm-syntax-string: #032f62;
30
+ --dm-syntax-variable: #e36209;
31
+ --dm-syntax-comment: #6a737d;
32
+ --dm-syntax-tag: #22863a;
33
+ --dm-syntax-addition: #22863a;
34
+ --dm-syntax-addition-bg: #f0fff4;
35
+ --dm-syntax-deletion: #b31d28;
36
+ --dm-syntax-deletion-bg: #ffeef0;
37
+ }
38
+
39
+ .dm-theme-light,
40
+ .dm-theme-light .dm-editor,
41
+ .dm-theme-light .dm-toolbar {
42
+ @include light-tokens;
43
+ }