@editora/themes 1.0.3 → 1.0.4
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.
- package/README.md +102 -380
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +13 -11
- package/index.d.ts +15 -0
- package/package.json +8 -6
- package/src/index.css +9 -10
- package/src/themes/acme.css +212 -0
- package/src/themes/dark.css +327 -89
- package/src/themes/default.css +111 -0
package/README.md
CHANGED
|
@@ -1,461 +1,183 @@
|
|
|
1
1
|
# @editora/themes
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
<img src="../../images/editora_logo_blocks.svg" alt="Editora Logo" width="200" height="auto">
|
|
5
|
-
</div>
|
|
3
|
+
Themes and design tokens for Editora editor UIs (React wrapper + Web Component).
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
<img src="../../images/theme-comparison.png" alt="Editora Themes - Light vs Dark Theme Comparison" width="800" style="border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);">
|
|
9
|
-
<p><em>Themes and styling system with built-in light/dark mode support</em></p>
|
|
10
|
-
</div>
|
|
11
|
-
|
|
12
|
-
Themes and styling system for Editora Rich Text Editor with built-in light/dark mode support and customizable design tokens.
|
|
13
|
-
|
|
14
|
-
## 📦 Installation
|
|
5
|
+
## Installation
|
|
15
6
|
|
|
16
7
|
```bash
|
|
17
8
|
npm install @editora/themes
|
|
18
9
|
```
|
|
19
10
|
|
|
20
|
-
##
|
|
21
|
-
|
|
22
|
-
The themes package provides a comprehensive styling system using CSS variables, making it easy to customize the editor's appearance and support multiple themes.
|
|
11
|
+
## Built-in Themes
|
|
23
12
|
|
|
24
|
-
|
|
13
|
+
- `default` (`@editora/themes/themes/default.css`)
|
|
14
|
+
- `dark` (`@editora/themes/themes/dark.css`)
|
|
15
|
+
- `acme` (`@editora/themes/themes/acme.css`)
|
|
25
16
|
|
|
26
|
-
|
|
27
|
-
- **CSS Variables**: Fully customizable using CSS custom properties
|
|
28
|
-
- **Responsive**: Mobile-friendly and adaptive layouts
|
|
29
|
-
- **Accessible**: High contrast ratios and WCAG compliance
|
|
30
|
-
- **Modern Design**: Clean, professional appearance
|
|
31
|
-
- **Easy Customization**: Override any variable to match your brand
|
|
17
|
+
## Quick Start
|
|
32
18
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
### Basic Usage
|
|
19
|
+
### React
|
|
36
20
|
|
|
37
21
|
```tsx
|
|
38
|
-
import "@editora/
|
|
39
|
-
|
|
40
|
-
import "@editora/themes/themes/default.css";
|
|
41
|
-
import { EditoraEditor } from '@editora/react';
|
|
42
|
-
|
|
43
|
-
function App() {
|
|
44
|
-
return <EditoraEditor theme="light" />;
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### With Theme Toggle
|
|
22
|
+
import { EditoraEditor } from "@editora/react";
|
|
23
|
+
import { BoldPlugin, ItalicPlugin } from "@editora/plugins";
|
|
49
24
|
|
|
50
|
-
```tsx
|
|
51
|
-
import "@editora/themes/theme.css";
|
|
52
|
-
OR
|
|
53
25
|
import "@editora/themes/themes/default.css";
|
|
54
|
-
import
|
|
55
|
-
import { useState } from 'react';
|
|
56
|
-
|
|
57
|
-
function App() {
|
|
58
|
-
const [theme, setTheme] = useState<'light' | 'dark'>('light');
|
|
26
|
+
import "@editora/themes/themes/acme.css";
|
|
59
27
|
|
|
28
|
+
export default function App() {
|
|
60
29
|
return (
|
|
61
|
-
<div data-theme=
|
|
62
|
-
<
|
|
63
|
-
Toggle Theme
|
|
64
|
-
</button>
|
|
65
|
-
|
|
66
|
-
<EditoraEditor theme={theme} />
|
|
30
|
+
<div data-theme="acme">
|
|
31
|
+
<EditoraEditor plugins={[BoldPlugin(), ItalicPlugin()]} />
|
|
67
32
|
</div>
|
|
68
33
|
);
|
|
69
34
|
}
|
|
70
35
|
```
|
|
71
36
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```tsx
|
|
75
|
-
import "@editora/themes/theme.css";
|
|
76
|
-
OR
|
|
77
|
-
import "@editora/themes/themes/default.css";
|
|
78
|
-
import { EditoraEditor } from '@editora/react';
|
|
79
|
-
|
|
80
|
-
function App() {
|
|
81
|
-
return <EditoraEditor theme="auto" />;
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## 🎨 Built-in Themes
|
|
86
|
-
|
|
87
|
-
### Light Theme (Default)
|
|
88
|
-
|
|
89
|
-
Clean, professional light theme suitable for most applications.
|
|
90
|
-
|
|
91
|
-
```tsx
|
|
92
|
-
<EditoraEditor theme="light" />
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### Dark Theme
|
|
96
|
-
|
|
97
|
-
Modern dark theme with comfortable colors for low-light environments.
|
|
98
|
-
|
|
99
|
-
```tsx
|
|
100
|
-
<EditoraEditor theme="dark" />
|
|
101
|
-
```
|
|
37
|
+
Use `data-theme="light"`, `data-theme="dark"`, or `data-theme="acme"` on a wrapper.
|
|
102
38
|
|
|
103
|
-
###
|
|
39
|
+
### Web Component
|
|
104
40
|
|
|
105
|
-
|
|
41
|
+
```html
|
|
42
|
+
<link rel="stylesheet" href="/node_modules/@editora/core/dist/webcomponent.min.css" />
|
|
43
|
+
<link rel="stylesheet" href="/node_modules/@editora/themes/themes/acme.css" />
|
|
44
|
+
<script type="module" src="/node_modules/@editora/core/dist/webcomponent.js"></script>
|
|
106
45
|
|
|
107
|
-
|
|
108
|
-
|
|
46
|
+
<editora-editor
|
|
47
|
+
theme="acme"
|
|
48
|
+
plugins="bold italic underline history"
|
|
49
|
+
toolbar-items="undo redo | bold italic underline"
|
|
50
|
+
height="320"
|
|
51
|
+
></editora-editor>
|
|
109
52
|
```
|
|
110
53
|
|
|
111
|
-
|
|
54
|
+
Use `theme="light"`, `theme="dark"`, or `theme="acme"` on `<editora-editor>`.
|
|
112
55
|
|
|
113
|
-
|
|
56
|
+
## Create A Custom Theme From Scratch
|
|
114
57
|
|
|
115
|
-
|
|
58
|
+
### 1) Start from base theme
|
|
116
59
|
|
|
117
|
-
|
|
60
|
+
Create `my-theme.css` and load `default.css` first:
|
|
118
61
|
|
|
119
62
|
```css
|
|
120
|
-
|
|
121
|
-
/* Primary colors */
|
|
122
|
-
--editora-primary: #0066cc;
|
|
123
|
-
--editora-primary-hover: #0052a3;
|
|
124
|
-
--editora-primary-active: #003d7a;
|
|
125
|
-
|
|
126
|
-
/* Background colors */
|
|
127
|
-
--editora-bg: #ffffff;
|
|
128
|
-
--editora-bg-secondary: #f5f5f5;
|
|
129
|
-
--editora-bg-tertiary: #e0e0e0;
|
|
130
|
-
|
|
131
|
-
/* Text colors */
|
|
132
|
-
--editora-text: #000000;
|
|
133
|
-
--editora-text-secondary: #666666;
|
|
134
|
-
--editora-text-muted: #999999;
|
|
135
|
-
|
|
136
|
-
/* Border colors */
|
|
137
|
-
--editora-border: #cccccc;
|
|
138
|
-
--editora-border-focus: #0066cc;
|
|
139
|
-
|
|
140
|
-
/* Toolbar */
|
|
141
|
-
--editora-toolbar-bg: #f5f5f5;
|
|
142
|
-
--editora-toolbar-border: #cccccc;
|
|
143
|
-
--editora-toolbar-button-hover: #e0e0e0;
|
|
144
|
-
--editora-toolbar-button-active: #d0d0d0;
|
|
145
|
-
|
|
146
|
-
/* Content area */
|
|
147
|
-
--editora-content-bg: #ffffff;
|
|
148
|
-
--editora-content-padding: 16px;
|
|
149
|
-
|
|
150
|
-
/* Selection */
|
|
151
|
-
--editora-selection-bg: rgba(0, 102, 204, 0.2);
|
|
152
|
-
|
|
153
|
-
/* Status colors */
|
|
154
|
-
--editora-error: #dc3545;
|
|
155
|
-
--editora-warning: #ffc107;
|
|
156
|
-
--editora-success: #28a745;
|
|
157
|
-
--editora-info: #17a2b8;
|
|
158
|
-
}
|
|
63
|
+
@import "@editora/themes/themes/default.css";
|
|
159
64
|
```
|
|
160
65
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
```css
|
|
164
|
-
[data-theme="dark"] {
|
|
165
|
-
--editora-primary: #3399ff;
|
|
166
|
-
--editora-primary-hover: #5cadff;
|
|
167
|
-
--editora-primary-active: #1f8cff;
|
|
168
|
-
|
|
169
|
-
--editora-bg: #1e1e1e;
|
|
170
|
-
--editora-bg-secondary: #2d2d2d;
|
|
171
|
-
--editora-bg-tertiary: #3d3d3d;
|
|
172
|
-
|
|
173
|
-
--editora-text: #ffffff;
|
|
174
|
-
--editora-text-secondary: #cccccc;
|
|
175
|
-
--editora-text-muted: #999999;
|
|
176
|
-
|
|
177
|
-
--editora-border: #444444;
|
|
178
|
-
--editora-border-focus: #3399ff;
|
|
179
|
-
|
|
180
|
-
--editora-toolbar-bg: #2d2d2d;
|
|
181
|
-
--editora-toolbar-border: #444444;
|
|
182
|
-
--editora-toolbar-button-hover: #3d3d3d;
|
|
183
|
-
--editora-toolbar-button-active: #4d4d4d;
|
|
184
|
-
|
|
185
|
-
--editora-content-bg: #1e1e1e;
|
|
186
|
-
|
|
187
|
-
--editora-selection-bg: rgba(51, 153, 255, 0.3);
|
|
188
|
-
}
|
|
189
|
-
```
|
|
66
|
+
### 2) Scope your theme
|
|
190
67
|
|
|
191
|
-
|
|
68
|
+
Choose one scope that works for both React and Web Component:
|
|
192
69
|
|
|
193
70
|
```css
|
|
194
|
-
:
|
|
195
|
-
/*
|
|
196
|
-
--editora-font-size-sm: 12px;
|
|
197
|
-
--editora-font-size-base: 14px;
|
|
198
|
-
--editora-font-size-lg: 16px;
|
|
199
|
-
|
|
200
|
-
/* Spacing */
|
|
201
|
-
--editora-spacing-xs: 4px;
|
|
202
|
-
--editora-spacing-sm: 8px;
|
|
203
|
-
--editora-spacing-md: 16px;
|
|
204
|
-
--editora-spacing-lg: 24px;
|
|
205
|
-
--editora-spacing-xl: 32px;
|
|
206
|
-
|
|
207
|
-
/* Border radius */
|
|
208
|
-
--editora-radius-sm: 2px;
|
|
209
|
-
--editora-radius-md: 4px;
|
|
210
|
-
--editora-radius-lg: 8px;
|
|
211
|
-
|
|
212
|
-
/* Shadows */
|
|
213
|
-
--editora-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
214
|
-
--editora-shadow-md: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
215
|
-
--editora-shadow-lg: 0 4px 8px rgba(0, 0, 0, 0.15);
|
|
216
|
-
|
|
217
|
-
/* Z-indexes */
|
|
218
|
-
--editora-z-dropdown: 1000;
|
|
219
|
-
--editora-z-modal: 2000;
|
|
220
|
-
--editora-z-tooltip: 3000;
|
|
71
|
+
:is([data-theme="my-brand"], .editora-theme-my-brand) {
|
|
72
|
+
/* tokens */
|
|
221
73
|
}
|
|
222
74
|
```
|
|
223
75
|
|
|
224
|
-
###
|
|
76
|
+
### 3) Override design tokens
|
|
225
77
|
|
|
226
|
-
|
|
227
|
-
/* custom-theme.css */
|
|
228
|
-
import "@editora/themes/theme.css";
|
|
229
|
-
OR
|
|
230
|
-
import "@editora/themes/themes/default.css";
|
|
231
|
-
|
|
232
|
-
:root {
|
|
233
|
-
/* Brand colors */
|
|
234
|
-
--editora-primary: #7c3aed;
|
|
235
|
-
--editora-primary-hover: #6d28d9;
|
|
236
|
-
--editora-primary-active: #5b21b6;
|
|
237
|
-
|
|
238
|
-
/* Custom toolbar */
|
|
239
|
-
--editora-toolbar-bg: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
240
|
-
--editora-toolbar-button-hover: rgba(255, 255, 255, 0.1);
|
|
241
|
-
|
|
242
|
-
/* Rounded corners */
|
|
243
|
-
--editora-radius-md: 12px;
|
|
244
|
-
|
|
245
|
-
/* Custom font */
|
|
246
|
-
--editora-font-family: 'Inter', system-ui, sans-serif;
|
|
247
|
-
}
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## 💡 Usage Examples
|
|
251
|
-
|
|
252
|
-
### Brand Customization
|
|
78
|
+
Use the real token names used by Editora (`--rte-*`):
|
|
253
79
|
|
|
254
80
|
```css
|
|
255
|
-
|
|
256
|
-
:
|
|
257
|
-
--
|
|
258
|
-
--
|
|
259
|
-
--
|
|
260
|
-
--
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
border
|
|
265
|
-
|
|
81
|
+
:is([data-theme="my-brand"], .editora-theme-my-brand) {
|
|
82
|
+
--rte-color-primary: #1d4ed8;
|
|
83
|
+
--rte-color-primary-hover: #1e40af;
|
|
84
|
+
--rte-color-text-primary: #0f172a;
|
|
85
|
+
--rte-color-text-secondary: #334155;
|
|
86
|
+
--rte-color-text-muted: #64748b;
|
|
87
|
+
--rte-color-bg-primary: #ffffff;
|
|
88
|
+
--rte-color-bg-secondary: #f8fafc;
|
|
89
|
+
--rte-color-bg-tertiary: #e2e8f0;
|
|
90
|
+
--rte-color-border: #cbd5e1;
|
|
91
|
+
--rte-color-border-light: #dbe3ee;
|
|
92
|
+
--rte-color-border-focus: #1d4ed8;
|
|
93
|
+
--rte-shadow: 0 6px 16px rgba(15, 23, 42, 0.1);
|
|
94
|
+
--rte-shadow-lg: 0 16px 28px rgba(15, 23, 42, 0.16);
|
|
266
95
|
}
|
|
267
96
|
```
|
|
268
97
|
|
|
269
|
-
###
|
|
98
|
+
### 4) Add component overrides
|
|
270
99
|
|
|
271
|
-
|
|
272
|
-
/* Smaller toolbar and spacing */
|
|
273
|
-
:root {
|
|
274
|
-
--editora-toolbar-height: 32px;
|
|
275
|
-
--editora-spacing-md: 8px;
|
|
276
|
-
--editora-font-size-base: 12px;
|
|
277
|
-
}
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
### High Contrast Mode
|
|
100
|
+
Tokens handle most styling, but buttons/dropdowns/content usually need explicit overrides:
|
|
281
101
|
|
|
282
102
|
```css
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
--editora-text: #ffffff;
|
|
287
|
-
--editora-border: #ffffff;
|
|
288
|
-
--editora-primary: #ffff00;
|
|
103
|
+
:is([data-theme="my-brand"], .editora-theme-my-brand) :is(.rte-toolbar, .editora-toolbar) {
|
|
104
|
+
background: #f4f8ff;
|
|
105
|
+
border-color: var(--rte-color-border);
|
|
289
106
|
}
|
|
290
|
-
```
|
|
291
107
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
:root {
|
|
297
|
-
--editora-toolbar-bg: transparent;
|
|
298
|
-
--editora-toolbar-border: none;
|
|
299
|
-
--editora-border: transparent;
|
|
108
|
+
:is([data-theme="my-brand"], .editora-theme-my-brand) :is(.rte-toolbar-button, .editora-toolbar-button) {
|
|
109
|
+
background: #ffffff;
|
|
110
|
+
border-color: var(--rte-color-border);
|
|
111
|
+
color: var(--rte-color-text-secondary);
|
|
300
112
|
}
|
|
301
113
|
|
|
302
|
-
.rte-
|
|
303
|
-
|
|
114
|
+
:is([data-theme="my-brand"], .editora-theme-my-brand) :is(.rte-content, .editora-content) {
|
|
115
|
+
background: #ffffff;
|
|
116
|
+
color: var(--rte-color-text-primary);
|
|
304
117
|
}
|
|
305
118
|
```
|
|
306
119
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
The theme automatically adapts to different screen sizes:
|
|
120
|
+
### 5) Load and activate the theme
|
|
310
121
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
@media (max-width: 768px) {
|
|
314
|
-
:root {
|
|
315
|
-
--editora-toolbar-height: 48px; /* Larger touch targets */
|
|
316
|
-
--editora-font-size-base: 16px; /* Prevent zoom on iOS */
|
|
317
|
-
--editora-spacing-md: 12px;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/* Tablet */
|
|
322
|
-
@media (min-width: 769px) and (max-width: 1024px) {
|
|
323
|
-
:root {
|
|
324
|
-
--editora-content-padding: 20px;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
122
|
+
- React: import CSS + set wrapper `data-theme="my-brand"`.
|
|
123
|
+
- Web Component: include CSS + set `theme="my-brand"` on `<editora-editor>`.
|
|
327
124
|
|
|
328
|
-
|
|
329
|
-
@media (min-width: 1025px) {
|
|
330
|
-
:root {
|
|
331
|
-
--editora-content-padding: 24px;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
```
|
|
125
|
+
## Modify An Existing Theme
|
|
335
126
|
|
|
336
|
-
|
|
127
|
+
### Option A: Extend dark theme
|
|
337
128
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
import { useEffect, useState } from 'react';
|
|
342
|
-
|
|
343
|
-
function useTheme() {
|
|
344
|
-
const [theme, setTheme] = useState<'light' | 'dark'>('light');
|
|
345
|
-
|
|
346
|
-
useEffect(() => {
|
|
347
|
-
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
348
|
-
setTheme(mediaQuery.matches ? 'dark' : 'light');
|
|
349
|
-
|
|
350
|
-
const handler = (e: MediaQueryListEvent) => {
|
|
351
|
-
setTheme(e.matches ? 'dark' : 'light');
|
|
352
|
-
};
|
|
353
|
-
|
|
354
|
-
mediaQuery.addEventListener('change', handler);
|
|
355
|
-
return () => mediaQuery.removeEventListener('change', handler);
|
|
356
|
-
}, []);
|
|
129
|
+
```css
|
|
130
|
+
@import "@editora/themes/themes/default.css";
|
|
131
|
+
@import "@editora/themes/themes/dark.css";
|
|
357
132
|
|
|
358
|
-
|
|
133
|
+
:is([data-theme="dark"], .editora-theme-dark) {
|
|
134
|
+
--rte-color-primary: #22d3ee;
|
|
135
|
+
--rte-color-primary-hover: #06b6d4;
|
|
359
136
|
}
|
|
360
137
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
return (
|
|
365
|
-
<div data-theme={theme}>
|
|
366
|
-
<EditoraEditor />
|
|
367
|
-
</div>
|
|
368
|
-
);
|
|
369
|
-
}
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
### Manual Theme Toggle
|
|
373
|
-
|
|
374
|
-
```tsx
|
|
375
|
-
function App() {
|
|
376
|
-
const [theme, setTheme] = useState(() => {
|
|
377
|
-
return localStorage.getItem('theme') || 'light';
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
const toggleTheme = () => {
|
|
381
|
-
const newTheme = theme === 'light' ? 'dark' : 'light';
|
|
382
|
-
setTheme(newTheme);
|
|
383
|
-
localStorage.setItem('theme', newTheme);
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
return (
|
|
387
|
-
<div data-theme={theme}>
|
|
388
|
-
<button onClick={toggleTheme}>
|
|
389
|
-
{theme === 'light' ? '🌙' : '☀️'}
|
|
390
|
-
</button>
|
|
391
|
-
<EditoraEditor />
|
|
392
|
-
</div>
|
|
393
|
-
);
|
|
138
|
+
:is([data-theme="dark"], .editora-theme-dark) .rte-toolbar-button {
|
|
139
|
+
border-radius: 8px;
|
|
394
140
|
}
|
|
395
141
|
```
|
|
396
142
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
### Toolbar Customization
|
|
143
|
+
### Option B: Extend acme theme
|
|
400
144
|
|
|
401
145
|
```css
|
|
402
|
-
.
|
|
403
|
-
|
|
404
|
-
border-radius: 8px 8px 0 0;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
.rte-toolbar-button {
|
|
408
|
-
color: white;
|
|
409
|
-
border-radius: 4px;
|
|
410
|
-
transition: all 0.2s;
|
|
411
|
-
}
|
|
146
|
+
@import "@editora/themes/themes/default.css";
|
|
147
|
+
@import "@editora/themes/themes/acme.css";
|
|
412
148
|
|
|
413
|
-
.
|
|
414
|
-
|
|
415
|
-
|
|
149
|
+
:is([data-theme="acme"], .editora-theme-acme) {
|
|
150
|
+
--rte-color-primary: #7c3aed;
|
|
151
|
+
--rte-color-primary-hover: #6d28d9;
|
|
416
152
|
}
|
|
417
153
|
```
|
|
418
154
|
|
|
419
|
-
###
|
|
155
|
+
### Safe override strategy
|
|
420
156
|
|
|
421
|
-
|
|
422
|
-
.
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
max-width: 800px;
|
|
427
|
-
margin: 0 auto;
|
|
428
|
-
padding: 40px;
|
|
429
|
-
}
|
|
157
|
+
1. Keep selectors scoped (`[data-theme="..."]` / `.editora-theme-...`).
|
|
158
|
+
2. Prefer token overrides first, component selectors second.
|
|
159
|
+
3. Override both React and Web Component class names where needed:
|
|
160
|
+
- React classes: `.rte-*`
|
|
161
|
+
- Web Component classes: `.editora-*`
|
|
430
162
|
|
|
431
|
-
|
|
432
|
-
color: var(--editora-primary);
|
|
433
|
-
border-bottom: 2px solid var(--editora-border);
|
|
434
|
-
padding-bottom: 0.3em;
|
|
435
|
-
}
|
|
436
|
-
```
|
|
163
|
+
## New `acme` Theme Notes
|
|
437
164
|
|
|
438
|
-
|
|
165
|
+
`acme.css` is intentionally shared across both renderers:
|
|
439
166
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
border-radius: var(--editora-radius-lg);
|
|
443
|
-
box-shadow: var(--editora-shadow-lg);
|
|
444
|
-
}
|
|
167
|
+
- React support via `[data-theme="acme"]`
|
|
168
|
+
- Web Component support via `.editora-theme-acme` (set automatically from `theme="acme"`)
|
|
445
169
|
|
|
446
|
-
|
|
447
|
-
background: var(--editora-bg-secondary);
|
|
448
|
-
border-radius: var(--editora-radius-lg) var(--editora-radius-lg) 0 0;
|
|
449
|
-
}
|
|
450
|
-
```
|
|
170
|
+
## Verification Checklist
|
|
451
171
|
|
|
452
|
-
|
|
172
|
+
After adding/changing a theme, verify:
|
|
453
173
|
|
|
454
|
-
|
|
174
|
+
1. Toolbar buttons (normal/hover/active/disabled)
|
|
175
|
+
2. Dropdown menus and inputs (including font-size input placeholder)
|
|
176
|
+
3. Editor content colors + placeholder visibility
|
|
177
|
+
4. Status bar + floating toolbar
|
|
178
|
+
5. Dialogs and plugin overlays in both light/dark/custom scopes
|
|
179
|
+
6. Multi-instance behavior with different themes on the same page
|
|
455
180
|
|
|
456
|
-
##
|
|
181
|
+
## License
|
|
457
182
|
|
|
458
|
-
|
|
459
|
-
- [GitHub Repository](https://github.com/ajaykr089/Editora)
|
|
460
|
-
- [Issue Tracker](https://github.com/ajaykr089/Editora/issues)
|
|
461
|
-
- [npm Package](https://www.npmjs.com/package/@editora/themes)
|
|
183
|
+
MIT
|
package/dist/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function m(e,t){e.setAttribute("data-theme",t),e.classList.toggle("dark",t==="dark")}function u(e){return""}function r(e){document.documentElement.setAttribute("data-theme",e),document.documentElement.classList.toggle("dark",e==="dark")}function n(){const e=document.documentElement.getAttribute("data-theme");return e==="dark"||e==="acme"||e==="light"?e:"light"}function a(){const t=n()==="dark"?"light":"dark";return r(t),t}function i(){return n()==="dark"}function h(){return n()==="light"}const o={light:"light",dark:"dark",acme:"acme"};exports.applyTheme=m;exports.getCurrentTheme=n;exports.getThemeCSS=u;exports.isDarkTheme=i;exports.isLightTheme=h;exports.setGlobalTheme=r;exports.themes=o;exports.toggleTheme=a;
|
package/dist/index.esm.js
CHANGED
|
@@ -1,36 +1,38 @@
|
|
|
1
1
|
function u(t, e) {
|
|
2
2
|
t.setAttribute("data-theme", e), t.classList.toggle("dark", e === "dark");
|
|
3
3
|
}
|
|
4
|
-
function
|
|
4
|
+
function c(t) {
|
|
5
5
|
return "";
|
|
6
6
|
}
|
|
7
7
|
function r(t) {
|
|
8
8
|
document.documentElement.setAttribute("data-theme", t), document.documentElement.classList.toggle("dark", t === "dark");
|
|
9
9
|
}
|
|
10
10
|
function n() {
|
|
11
|
-
|
|
11
|
+
const t = document.documentElement.getAttribute("data-theme");
|
|
12
|
+
return t === "dark" || t === "acme" || t === "light" ? t : "light";
|
|
12
13
|
}
|
|
13
|
-
function
|
|
14
|
-
const e = n() === "
|
|
14
|
+
function a() {
|
|
15
|
+
const e = n() === "dark" ? "light" : "dark";
|
|
15
16
|
return r(e), e;
|
|
16
17
|
}
|
|
17
18
|
function i() {
|
|
18
19
|
return n() === "dark";
|
|
19
20
|
}
|
|
20
|
-
function
|
|
21
|
+
function o() {
|
|
21
22
|
return n() === "light";
|
|
22
23
|
}
|
|
23
|
-
const
|
|
24
|
+
const m = {
|
|
24
25
|
light: "light",
|
|
25
|
-
dark: "dark"
|
|
26
|
+
dark: "dark",
|
|
27
|
+
acme: "acme"
|
|
26
28
|
};
|
|
27
29
|
export {
|
|
28
30
|
u as applyTheme,
|
|
29
31
|
n as getCurrentTheme,
|
|
30
|
-
|
|
32
|
+
c as getThemeCSS,
|
|
31
33
|
i as isDarkTheme,
|
|
32
|
-
|
|
34
|
+
o as isLightTheme,
|
|
33
35
|
r as setGlobalTheme,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
m as themes,
|
|
37
|
+
a as toggleTheme
|
|
36
38
|
};
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const themes: {
|
|
2
|
+
readonly light: "light";
|
|
3
|
+
readonly dark: "dark";
|
|
4
|
+
readonly acme: "acme";
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export type ThemeName = keyof typeof themes;
|
|
8
|
+
|
|
9
|
+
export function applyTheme(element: HTMLElement, themeName: ThemeName): void;
|
|
10
|
+
export function getThemeCSS(themeName: ThemeName): string;
|
|
11
|
+
export function setGlobalTheme(themeName: ThemeName): void;
|
|
12
|
+
export function getCurrentTheme(): ThemeName;
|
|
13
|
+
export function toggleTheme(): ThemeName;
|
|
14
|
+
export function isDarkTheme(): boolean;
|
|
15
|
+
export function isLightTheme(): boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@editora/themes",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Themes and styling system for Editora Rich Text Editor with light/dark mode support",
|
|
5
5
|
"author": "Ajay Kumar <ajaykr089@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,20 +24,22 @@
|
|
|
24
24
|
],
|
|
25
25
|
"main": "dist/index.cjs.js",
|
|
26
26
|
"module": "dist/index.esm.js",
|
|
27
|
-
"types": "
|
|
27
|
+
"types": "index.d.ts",
|
|
28
28
|
"style": "src/index.css",
|
|
29
29
|
"exports": {
|
|
30
30
|
".": {
|
|
31
|
-
"types": "./
|
|
31
|
+
"types": "./index.d.ts",
|
|
32
32
|
"import": "./dist/index.esm.js",
|
|
33
33
|
"require": "./dist/index.cjs.js"
|
|
34
34
|
},
|
|
35
|
-
"./theme.css": "./src/index.css",
|
|
36
35
|
"./themes/*": "./src/themes/*.css",
|
|
37
|
-
"./themes/default.css": "./src/themes/default.css"
|
|
36
|
+
"./themes/default.css": "./src/themes/default.css",
|
|
37
|
+
"./themes/dark.css": "./src/themes/dark.css",
|
|
38
|
+
"./themes/acme.css": "./src/themes/acme.css"
|
|
38
39
|
},
|
|
39
40
|
"files": [
|
|
40
41
|
"dist",
|
|
42
|
+
"index.d.ts",
|
|
41
43
|
"src/*.css",
|
|
42
44
|
"src/themes/*.css",
|
|
43
45
|
"README.md",
|
|
@@ -57,4 +59,4 @@
|
|
|
57
59
|
"access": "public"
|
|
58
60
|
},
|
|
59
61
|
"gitHead": "694494db58b809f0dcf24501696284faa1ab68a5"
|
|
60
|
-
}
|
|
62
|
+
}
|