@editora/themes 1.0.2 → 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 +103 -373
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +13 -11
- package/index.d.ts +15 -0
- package/package.json +9 -5
- 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/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -1,453 +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
|
|
39
|
-
import {
|
|
22
|
+
import { EditoraEditor } from "@editora/react";
|
|
23
|
+
import { BoldPlugin, ItalicPlugin } from "@editora/plugins";
|
|
40
24
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### With Theme Toggle
|
|
47
|
-
|
|
48
|
-
```tsx
|
|
49
|
-
import '@editora/themes/styles';
|
|
50
|
-
import { EditoraEditor } from '@editora/react';
|
|
51
|
-
import { useState } from 'react';
|
|
52
|
-
|
|
53
|
-
function App() {
|
|
54
|
-
const [theme, setTheme] = useState<'light' | 'dark'>('light');
|
|
25
|
+
import "@editora/themes/themes/default.css";
|
|
26
|
+
import "@editora/themes/themes/acme.css";
|
|
55
27
|
|
|
28
|
+
export default function App() {
|
|
56
29
|
return (
|
|
57
|
-
<div data-theme=
|
|
58
|
-
<
|
|
59
|
-
Toggle Theme
|
|
60
|
-
</button>
|
|
61
|
-
|
|
62
|
-
<EditoraEditor theme={theme} />
|
|
30
|
+
<div data-theme="acme">
|
|
31
|
+
<EditoraEditor plugins={[BoldPlugin(), ItalicPlugin()]} />
|
|
63
32
|
</div>
|
|
64
33
|
);
|
|
65
34
|
}
|
|
66
35
|
```
|
|
67
36
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
```tsx
|
|
71
|
-
import '@editora/themes/styles';
|
|
72
|
-
import { EditoraEditor } from '@editora/react';
|
|
73
|
-
|
|
74
|
-
function App() {
|
|
75
|
-
return <EditoraEditor theme="auto" />;
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## 🎨 Built-in Themes
|
|
80
|
-
|
|
81
|
-
### Light Theme (Default)
|
|
82
|
-
|
|
83
|
-
Clean, professional light theme suitable for most applications.
|
|
84
|
-
|
|
85
|
-
```tsx
|
|
86
|
-
<EditoraEditor theme="light" />
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Dark Theme
|
|
37
|
+
Use `data-theme="light"`, `data-theme="dark"`, or `data-theme="acme"` on a wrapper.
|
|
90
38
|
|
|
91
|
-
|
|
39
|
+
### Web Component
|
|
92
40
|
|
|
93
|
-
```
|
|
94
|
-
<
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
### Auto Theme
|
|
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>
|
|
98
45
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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>
|
|
103
52
|
```
|
|
104
53
|
|
|
105
|
-
|
|
54
|
+
Use `theme="light"`, `theme="dark"`, or `theme="acme"` on `<editora-editor>`.
|
|
106
55
|
|
|
107
|
-
|
|
56
|
+
## Create A Custom Theme From Scratch
|
|
108
57
|
|
|
109
|
-
|
|
58
|
+
### 1) Start from base theme
|
|
110
59
|
|
|
111
|
-
|
|
60
|
+
Create `my-theme.css` and load `default.css` first:
|
|
112
61
|
|
|
113
62
|
```css
|
|
114
|
-
|
|
115
|
-
/* Primary colors */
|
|
116
|
-
--editora-primary: #0066cc;
|
|
117
|
-
--editora-primary-hover: #0052a3;
|
|
118
|
-
--editora-primary-active: #003d7a;
|
|
119
|
-
|
|
120
|
-
/* Background colors */
|
|
121
|
-
--editora-bg: #ffffff;
|
|
122
|
-
--editora-bg-secondary: #f5f5f5;
|
|
123
|
-
--editora-bg-tertiary: #e0e0e0;
|
|
124
|
-
|
|
125
|
-
/* Text colors */
|
|
126
|
-
--editora-text: #000000;
|
|
127
|
-
--editora-text-secondary: #666666;
|
|
128
|
-
--editora-text-muted: #999999;
|
|
129
|
-
|
|
130
|
-
/* Border colors */
|
|
131
|
-
--editora-border: #cccccc;
|
|
132
|
-
--editora-border-focus: #0066cc;
|
|
133
|
-
|
|
134
|
-
/* Toolbar */
|
|
135
|
-
--editora-toolbar-bg: #f5f5f5;
|
|
136
|
-
--editora-toolbar-border: #cccccc;
|
|
137
|
-
--editora-toolbar-button-hover: #e0e0e0;
|
|
138
|
-
--editora-toolbar-button-active: #d0d0d0;
|
|
139
|
-
|
|
140
|
-
/* Content area */
|
|
141
|
-
--editora-content-bg: #ffffff;
|
|
142
|
-
--editora-content-padding: 16px;
|
|
143
|
-
|
|
144
|
-
/* Selection */
|
|
145
|
-
--editora-selection-bg: rgba(0, 102, 204, 0.2);
|
|
146
|
-
|
|
147
|
-
/* Status colors */
|
|
148
|
-
--editora-error: #dc3545;
|
|
149
|
-
--editora-warning: #ffc107;
|
|
150
|
-
--editora-success: #28a745;
|
|
151
|
-
--editora-info: #17a2b8;
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
#### Dark Theme Variables
|
|
156
|
-
|
|
157
|
-
```css
|
|
158
|
-
[data-theme="dark"] {
|
|
159
|
-
--editora-primary: #3399ff;
|
|
160
|
-
--editora-primary-hover: #5cadff;
|
|
161
|
-
--editora-primary-active: #1f8cff;
|
|
162
|
-
|
|
163
|
-
--editora-bg: #1e1e1e;
|
|
164
|
-
--editora-bg-secondary: #2d2d2d;
|
|
165
|
-
--editora-bg-tertiary: #3d3d3d;
|
|
166
|
-
|
|
167
|
-
--editora-text: #ffffff;
|
|
168
|
-
--editora-text-secondary: #cccccc;
|
|
169
|
-
--editora-text-muted: #999999;
|
|
170
|
-
|
|
171
|
-
--editora-border: #444444;
|
|
172
|
-
--editora-border-focus: #3399ff;
|
|
173
|
-
|
|
174
|
-
--editora-toolbar-bg: #2d2d2d;
|
|
175
|
-
--editora-toolbar-border: #444444;
|
|
176
|
-
--editora-toolbar-button-hover: #3d3d3d;
|
|
177
|
-
--editora-toolbar-button-active: #4d4d4d;
|
|
178
|
-
|
|
179
|
-
--editora-content-bg: #1e1e1e;
|
|
180
|
-
|
|
181
|
-
--editora-selection-bg: rgba(51, 153, 255, 0.3);
|
|
182
|
-
}
|
|
63
|
+
@import "@editora/themes/themes/default.css";
|
|
183
64
|
```
|
|
184
65
|
|
|
185
|
-
|
|
66
|
+
### 2) Scope your theme
|
|
186
67
|
|
|
187
|
-
|
|
188
|
-
:root {
|
|
189
|
-
/* Font sizes */
|
|
190
|
-
--editora-font-size-sm: 12px;
|
|
191
|
-
--editora-font-size-base: 14px;
|
|
192
|
-
--editora-font-size-lg: 16px;
|
|
193
|
-
|
|
194
|
-
/* Spacing */
|
|
195
|
-
--editora-spacing-xs: 4px;
|
|
196
|
-
--editora-spacing-sm: 8px;
|
|
197
|
-
--editora-spacing-md: 16px;
|
|
198
|
-
--editora-spacing-lg: 24px;
|
|
199
|
-
--editora-spacing-xl: 32px;
|
|
200
|
-
|
|
201
|
-
/* Border radius */
|
|
202
|
-
--editora-radius-sm: 2px;
|
|
203
|
-
--editora-radius-md: 4px;
|
|
204
|
-
--editora-radius-lg: 8px;
|
|
205
|
-
|
|
206
|
-
/* Shadows */
|
|
207
|
-
--editora-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
208
|
-
--editora-shadow-md: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
209
|
-
--editora-shadow-lg: 0 4px 8px rgba(0, 0, 0, 0.15);
|
|
210
|
-
|
|
211
|
-
/* Z-indexes */
|
|
212
|
-
--editora-z-dropdown: 1000;
|
|
213
|
-
--editora-z-modal: 2000;
|
|
214
|
-
--editora-z-tooltip: 3000;
|
|
215
|
-
}
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### Custom Theme Example
|
|
68
|
+
Choose one scope that works for both React and Web Component:
|
|
219
69
|
|
|
220
70
|
```css
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
:root {
|
|
225
|
-
/* Brand colors */
|
|
226
|
-
--editora-primary: #7c3aed;
|
|
227
|
-
--editora-primary-hover: #6d28d9;
|
|
228
|
-
--editora-primary-active: #5b21b6;
|
|
229
|
-
|
|
230
|
-
/* Custom toolbar */
|
|
231
|
-
--editora-toolbar-bg: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
232
|
-
--editora-toolbar-button-hover: rgba(255, 255, 255, 0.1);
|
|
233
|
-
|
|
234
|
-
/* Rounded corners */
|
|
235
|
-
--editora-radius-md: 12px;
|
|
236
|
-
|
|
237
|
-
/* Custom font */
|
|
238
|
-
--editora-font-family: 'Inter', system-ui, sans-serif;
|
|
71
|
+
:is([data-theme="my-brand"], .editora-theme-my-brand) {
|
|
72
|
+
/* tokens */
|
|
239
73
|
}
|
|
240
74
|
```
|
|
241
75
|
|
|
242
|
-
|
|
76
|
+
### 3) Override design tokens
|
|
243
77
|
|
|
244
|
-
|
|
78
|
+
Use the real token names used by Editora (`--rte-*`):
|
|
245
79
|
|
|
246
80
|
```css
|
|
247
|
-
|
|
248
|
-
:
|
|
249
|
-
--
|
|
250
|
-
--
|
|
251
|
-
--
|
|
252
|
-
--
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
border
|
|
257
|
-
|
|
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);
|
|
258
95
|
}
|
|
259
96
|
```
|
|
260
97
|
|
|
261
|
-
###
|
|
262
|
-
|
|
263
|
-
```css
|
|
264
|
-
/* Smaller toolbar and spacing */
|
|
265
|
-
:root {
|
|
266
|
-
--editora-toolbar-height: 32px;
|
|
267
|
-
--editora-spacing-md: 8px;
|
|
268
|
-
--editora-font-size-base: 12px;
|
|
269
|
-
}
|
|
270
|
-
```
|
|
98
|
+
### 4) Add component overrides
|
|
271
99
|
|
|
272
|
-
|
|
100
|
+
Tokens handle most styling, but buttons/dropdowns/content usually need explicit overrides:
|
|
273
101
|
|
|
274
102
|
```css
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
--editora-text: #ffffff;
|
|
279
|
-
--editora-border: #ffffff;
|
|
280
|
-
--editora-primary: #ffff00;
|
|
281
|
-
}
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
### Minimal Theme
|
|
285
|
-
|
|
286
|
-
```css
|
|
287
|
-
/* Clean, distraction-free editing */
|
|
288
|
-
:root {
|
|
289
|
-
--editora-toolbar-bg: transparent;
|
|
290
|
-
--editora-toolbar-border: none;
|
|
291
|
-
--editora-border: transparent;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
.rte-toolbar {
|
|
295
|
-
border-bottom: 1px solid var(--editora-border);
|
|
296
|
-
}
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
## 📱 Responsive Styles
|
|
300
|
-
|
|
301
|
-
The theme automatically adapts to different screen sizes:
|
|
302
|
-
|
|
303
|
-
```css
|
|
304
|
-
/* Mobile adjustments */
|
|
305
|
-
@media (max-width: 768px) {
|
|
306
|
-
:root {
|
|
307
|
-
--editora-toolbar-height: 48px; /* Larger touch targets */
|
|
308
|
-
--editora-font-size-base: 16px; /* Prevent zoom on iOS */
|
|
309
|
-
--editora-spacing-md: 12px;
|
|
310
|
-
}
|
|
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);
|
|
311
106
|
}
|
|
312
107
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
:
|
|
316
|
-
|
|
317
|
-
}
|
|
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);
|
|
318
112
|
}
|
|
319
113
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
:
|
|
323
|
-
--editora-content-padding: 24px;
|
|
324
|
-
}
|
|
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);
|
|
325
117
|
}
|
|
326
118
|
```
|
|
327
119
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
### System Preference Detection
|
|
120
|
+
### 5) Load and activate the theme
|
|
331
121
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
function useTheme() {
|
|
336
|
-
const [theme, setTheme] = useState<'light' | 'dark'>('light');
|
|
122
|
+
- React: import CSS + set wrapper `data-theme="my-brand"`.
|
|
123
|
+
- Web Component: include CSS + set `theme="my-brand"` on `<editora-editor>`.
|
|
337
124
|
|
|
338
|
-
|
|
339
|
-
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
340
|
-
setTheme(mediaQuery.matches ? 'dark' : 'light');
|
|
125
|
+
## Modify An Existing Theme
|
|
341
126
|
|
|
342
|
-
|
|
343
|
-
setTheme(e.matches ? 'dark' : 'light');
|
|
344
|
-
};
|
|
127
|
+
### Option A: Extend dark theme
|
|
345
128
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
129
|
+
```css
|
|
130
|
+
@import "@editora/themes/themes/default.css";
|
|
131
|
+
@import "@editora/themes/themes/dark.css";
|
|
349
132
|
|
|
350
|
-
|
|
133
|
+
:is([data-theme="dark"], .editora-theme-dark) {
|
|
134
|
+
--rte-color-primary: #22d3ee;
|
|
135
|
+
--rte-color-primary-hover: #06b6d4;
|
|
351
136
|
}
|
|
352
137
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
return (
|
|
357
|
-
<div data-theme={theme}>
|
|
358
|
-
<EditoraEditor />
|
|
359
|
-
</div>
|
|
360
|
-
);
|
|
361
|
-
}
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
### Manual Theme Toggle
|
|
365
|
-
|
|
366
|
-
```tsx
|
|
367
|
-
function App() {
|
|
368
|
-
const [theme, setTheme] = useState(() => {
|
|
369
|
-
return localStorage.getItem('theme') || 'light';
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
const toggleTheme = () => {
|
|
373
|
-
const newTheme = theme === 'light' ? 'dark' : 'light';
|
|
374
|
-
setTheme(newTheme);
|
|
375
|
-
localStorage.setItem('theme', newTheme);
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
return (
|
|
379
|
-
<div data-theme={theme}>
|
|
380
|
-
<button onClick={toggleTheme}>
|
|
381
|
-
{theme === 'light' ? '🌙' : '☀️'}
|
|
382
|
-
</button>
|
|
383
|
-
<EditoraEditor />
|
|
384
|
-
</div>
|
|
385
|
-
);
|
|
138
|
+
:is([data-theme="dark"], .editora-theme-dark) .rte-toolbar-button {
|
|
139
|
+
border-radius: 8px;
|
|
386
140
|
}
|
|
387
141
|
```
|
|
388
142
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
### Toolbar Customization
|
|
143
|
+
### Option B: Extend acme theme
|
|
392
144
|
|
|
393
145
|
```css
|
|
394
|
-
.
|
|
395
|
-
|
|
396
|
-
border-radius: 8px 8px 0 0;
|
|
397
|
-
}
|
|
146
|
+
@import "@editora/themes/themes/default.css";
|
|
147
|
+
@import "@editora/themes/themes/acme.css";
|
|
398
148
|
|
|
399
|
-
.
|
|
400
|
-
color:
|
|
401
|
-
|
|
402
|
-
transition: all 0.2s;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
.rte-toolbar-button:hover {
|
|
406
|
-
background: rgba(255, 255, 255, 0.2);
|
|
407
|
-
transform: translateY(-1px);
|
|
149
|
+
:is([data-theme="acme"], .editora-theme-acme) {
|
|
150
|
+
--rte-color-primary: #7c3aed;
|
|
151
|
+
--rte-color-primary-hover: #6d28d9;
|
|
408
152
|
}
|
|
409
153
|
```
|
|
410
154
|
|
|
411
|
-
###
|
|
155
|
+
### Safe override strategy
|
|
412
156
|
|
|
413
|
-
|
|
414
|
-
.
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
max-width: 800px;
|
|
419
|
-
margin: 0 auto;
|
|
420
|
-
padding: 40px;
|
|
421
|
-
}
|
|
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-*`
|
|
422
162
|
|
|
423
|
-
|
|
424
|
-
color: var(--editora-primary);
|
|
425
|
-
border-bottom: 2px solid var(--editora-border);
|
|
426
|
-
padding-bottom: 0.3em;
|
|
427
|
-
}
|
|
428
|
-
```
|
|
163
|
+
## New `acme` Theme Notes
|
|
429
164
|
|
|
430
|
-
|
|
165
|
+
`acme.css` is intentionally shared across both renderers:
|
|
431
166
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
border-radius: var(--editora-radius-lg);
|
|
435
|
-
box-shadow: var(--editora-shadow-lg);
|
|
436
|
-
}
|
|
167
|
+
- React support via `[data-theme="acme"]`
|
|
168
|
+
- Web Component support via `.editora-theme-acme` (set automatically from `theme="acme"`)
|
|
437
169
|
|
|
438
|
-
|
|
439
|
-
background: var(--editora-bg-secondary);
|
|
440
|
-
border-radius: var(--editora-radius-lg) var(--editora-radius-lg) 0 0;
|
|
441
|
-
}
|
|
442
|
-
```
|
|
170
|
+
## Verification Checklist
|
|
443
171
|
|
|
444
|
-
|
|
172
|
+
After adding/changing a theme, verify:
|
|
445
173
|
|
|
446
|
-
|
|
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
|
|
447
180
|
|
|
448
|
-
##
|
|
181
|
+
## License
|
|
449
182
|
|
|
450
|
-
|
|
451
|
-
- [GitHub Repository](https://github.com/ajaykr089/Editora)
|
|
452
|
-
- [Issue Tracker](https://github.com/ajaykr089/Editora/issues)
|
|
453
|
-
- [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,18 +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
|
-
"./
|
|
35
|
+
"./themes/*": "./src/themes/*.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"
|
|
36
39
|
},
|
|
37
40
|
"files": [
|
|
38
41
|
"dist",
|
|
42
|
+
"index.d.ts",
|
|
39
43
|
"src/*.css",
|
|
40
44
|
"src/themes/*.css",
|
|
41
45
|
"README.md",
|
|
@@ -54,5 +58,5 @@
|
|
|
54
58
|
"publishConfig": {
|
|
55
59
|
"access": "public"
|
|
56
60
|
},
|
|
57
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "694494db58b809f0dcf24501696284faa1ab68a5"
|
|
58
62
|
}
|