@kungal/editor-nuxt 0.31.0 → 0.32.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.
- package/CHANGELOG.md +67 -0
- package/editor.css +428 -0
- package/package.json +4 -3
- package/runtime/KunEditorToolbar.vue +19 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,72 @@
|
|
|
1
1
|
# @kungal/editor-nuxt
|
|
2
2
|
|
|
3
|
+
## 0.32.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 7dd7f71: Show an active state on the toolbar's toggle marks (bold / italic /
|
|
8
|
+
strikethrough / inline code).
|
|
9
|
+
|
|
10
|
+
The toolbar buttons ran the toggle commands but never reflected whether the
|
|
11
|
+
mark was on, so a user could not tell if bold (etc.) was engaged. The
|
|
12
|
+
`#toolbar` slot API now exposes a reactive `activeMarks` map (bold / italic /
|
|
13
|
+
strike / code), recomputed from the ProseMirror selection on selection and doc
|
|
14
|
+
changes and immediately after each command. `<KunEditorToolbar>` renders the
|
|
15
|
+
pressed buttons with the primary "active" look (same as hover) and sets
|
|
16
|
+
`aria-pressed`; the headless `EditorToolbar` sets `data-active` for the
|
|
17
|
+
`.kun-editor__tool[data-active='true']` style.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [7dd7f71]
|
|
22
|
+
- Updated dependencies [35bc140]
|
|
23
|
+
- @kungal/editor-vue@0.32.0
|
|
24
|
+
- @kungal/editor-core@0.32.0
|
|
25
|
+
|
|
26
|
+
## 0.31.1
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- b7fe837: Fix a long `placeholder` overflowing the editor, and ship the reference
|
|
31
|
+
stylesheet from the layer.
|
|
32
|
+
|
|
33
|
+
The placeholder is a decoration (`.kun-editor__placeholder` +
|
|
34
|
+
`data-placeholder`) rendered by the host's `::before` rule. That rule was
|
|
35
|
+
absolutely positioned with **no positioned ancestor**, so the browser laid it
|
|
36
|
+
out against the viewport: a long placeholder ran past the editor's right edge —
|
|
37
|
+
and could even paint over the toolbar — instead of wrapping inside it. The
|
|
38
|
+
empty block is now the containing block, and the text wraps (`width: 100%` +
|
|
39
|
+
`overflow-wrap: break-word`):
|
|
40
|
+
|
|
41
|
+
```css
|
|
42
|
+
.kun-editor__placeholder {
|
|
43
|
+
position: relative;
|
|
44
|
+
}
|
|
45
|
+
.kun-editor__placeholder::before {
|
|
46
|
+
content: attr(data-placeholder);
|
|
47
|
+
position: absolute;
|
|
48
|
+
top: 0;
|
|
49
|
+
left: 0;
|
|
50
|
+
width: 100%;
|
|
51
|
+
overflow-wrap: break-word;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Because that CSS lived only in the docs app, every host had a _copy_ — an
|
|
56
|
+
upstream style fix could never reach them. The reference stylesheet now ships
|
|
57
|
+
with `@kungal/editor-nuxt`, so hosts can import it and get fixes with a version
|
|
58
|
+
bump (copying it still works):
|
|
59
|
+
|
|
60
|
+
```css
|
|
61
|
+
@import "@kungal/editor-nuxt/editor.css";
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`@kungal/editor-vue` is unchanged and still headless (zero CSS).
|
|
65
|
+
|
|
66
|
+
- Updated dependencies [b7fe837]
|
|
67
|
+
- @kungal/editor-core@0.31.1
|
|
68
|
+
- @kungal/editor-vue@0.31.1
|
|
69
|
+
|
|
3
70
|
## 0.31.0
|
|
4
71
|
|
|
5
72
|
### Patch Changes
|
package/editor.css
ADDED
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* KunEditor reference stylesheet.
|
|
3
|
+
*
|
|
4
|
+
* `@kungal/editor-vue` ships ZERO CSS — it only renders stable class hooks
|
|
5
|
+
* (`.kun-editor__*`, `.kun-mention-dropdown*`) and `data-*` state. This file is
|
|
6
|
+
* the canonical styling of those hooks, themed with KunUI design tokens
|
|
7
|
+
* (`--color-*` from `@kungal/ui-tokens`), and it ships with the KunUI layer:
|
|
8
|
+
*
|
|
9
|
+
* @import '@kungal/editor-nuxt/editor.css';
|
|
10
|
+
*
|
|
11
|
+
* Import it (fixes then arrive with a version bump) or copy it into your app and
|
|
12
|
+
* edit freely — it's plain CSS with no build step.
|
|
13
|
+
*
|
|
14
|
+
* It also carries the two structural rules the editor genuinely needs to
|
|
15
|
+
* function: ProseMirror's `white-space` and the popover positioning / show-hide.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/* ── Shell + dual-view tabs ─────────────────────────────────────────────── */
|
|
19
|
+
.kun-editor {
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-direction: column;
|
|
22
|
+
gap: 0.5rem;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.kun-editor__toolbar {
|
|
26
|
+
display: flex;
|
|
27
|
+
gap: 0.25rem;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.kun-editor__tab {
|
|
31
|
+
padding: 0.25rem 0.75rem;
|
|
32
|
+
border: 1px solid var(--color-default-200);
|
|
33
|
+
border-radius: 0.5rem;
|
|
34
|
+
background: transparent;
|
|
35
|
+
font: inherit;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.kun-editor__tab[data-active='true'] {
|
|
40
|
+
background: var(--color-primary);
|
|
41
|
+
border-color: var(--color-primary);
|
|
42
|
+
color: var(--color-primary-foreground, #fff);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Swap-sides button (split mode) — pushed to the end of the tab row. */
|
|
46
|
+
.kun-editor__swap {
|
|
47
|
+
margin-left: auto;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* ── Split view — editable source + read-only WYSIWYG preview ────────────── */
|
|
51
|
+
/* Stacked on narrow screens; side-by-side (swappable) from md up. The panes
|
|
52
|
+
div is a plain block in non-split modes, so this only affects split. */
|
|
53
|
+
.kun-editor[data-mode='split'] .kun-editor__panes {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: column;
|
|
56
|
+
gap: 0.75rem;
|
|
57
|
+
margin-top: 0.5rem;
|
|
58
|
+
}
|
|
59
|
+
.kun-editor[data-mode='split'] .kun-editor__pane {
|
|
60
|
+
flex: 1 1 0;
|
|
61
|
+
min-width: 0;
|
|
62
|
+
/* Each pane scrolls internally (a bounded height) so scroll sync has something
|
|
63
|
+
to sync. Override --kun-editor-split-height to taste. */
|
|
64
|
+
height: var(--kun-editor-split-height, 60vh);
|
|
65
|
+
}
|
|
66
|
+
/* Make each editor fill + scroll within its pane. */
|
|
67
|
+
.kun-editor[data-mode='split'] .kun-editor__source .cm-editor {
|
|
68
|
+
height: 100%;
|
|
69
|
+
}
|
|
70
|
+
.kun-editor[data-mode='split'] .kun-editor__wysiwyg {
|
|
71
|
+
overflow: auto;
|
|
72
|
+
}
|
|
73
|
+
@media (min-width: 48rem) {
|
|
74
|
+
.kun-editor[data-mode='split'] .kun-editor__panes {
|
|
75
|
+
flex-direction: row;
|
|
76
|
+
align-items: stretch;
|
|
77
|
+
}
|
|
78
|
+
.kun-editor[data-mode='split'] .kun-editor__panes[data-swap='true'] {
|
|
79
|
+
flex-direction: row-reverse;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* ── WYSIWYG surface (ProseMirror) ──────────────────────────────────────── */
|
|
84
|
+
.kun-editor__wysiwyg .milkdown {
|
|
85
|
+
outline: none;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.kun-editor__wysiwyg .ProseMirror {
|
|
89
|
+
min-height: 8rem;
|
|
90
|
+
padding: 0.75rem;
|
|
91
|
+
border: 1px solid var(--color-default-200);
|
|
92
|
+
border-radius: 0.5rem;
|
|
93
|
+
outline: none;
|
|
94
|
+
/* ProseMirror REQUIRES a white-space rule; pre-wrap keeps wrapping + spaces. */
|
|
95
|
+
white-space: pre-wrap;
|
|
96
|
+
word-wrap: break-word;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Placeholder: the editor sets a `data-placeholder` attr + this class on the
|
|
100
|
+
* empty block (a decoration, not real content). Render the text via ::before so
|
|
101
|
+
* it never affects the doc / caret. */
|
|
102
|
+
/* The ::before is absolutely positioned, so it needs a positioned ancestor —
|
|
103
|
+
* without one its containing block is the viewport and a long placeholder is
|
|
104
|
+
* laid out against THAT width, escaping the editor (horizontal overflow). */
|
|
105
|
+
.kun-editor__placeholder {
|
|
106
|
+
position: relative;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.kun-editor__placeholder::before {
|
|
110
|
+
content: attr(data-placeholder);
|
|
111
|
+
position: absolute;
|
|
112
|
+
top: 0;
|
|
113
|
+
left: 0;
|
|
114
|
+
/* Wrap inside the block instead of running past the editor's right edge. */
|
|
115
|
+
width: 100%;
|
|
116
|
+
overflow-wrap: break-word;
|
|
117
|
+
color: var(--color-default-400);
|
|
118
|
+
pointer-events: none;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* In-flight "uploading…" placeholder — a decoration widget the editor drops at
|
|
122
|
+
* the caret while `uploadImage` runs (paste / drop / toolbar), replaced by the
|
|
123
|
+
* image when it resolves. */
|
|
124
|
+
.kun-editor__uploading {
|
|
125
|
+
color: var(--color-primary);
|
|
126
|
+
font-size: 0.875rem;
|
|
127
|
+
user-select: none;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* ── Selection bubble toolbar (floats over a text selection) ────────────── */
|
|
131
|
+
/* Positioned by floating-ui (absolute left/top); visibility via data-show. */
|
|
132
|
+
.kun-editor__bubble {
|
|
133
|
+
position: absolute;
|
|
134
|
+
display: flex;
|
|
135
|
+
gap: 0.125rem;
|
|
136
|
+
padding: 0.25rem;
|
|
137
|
+
background: var(--color-background);
|
|
138
|
+
border: 1px solid var(--color-default-200);
|
|
139
|
+
border-radius: 0.5rem;
|
|
140
|
+
box-shadow: 0 4px 12px rgb(0 0 0 / 0.12);
|
|
141
|
+
z-index: 40;
|
|
142
|
+
}
|
|
143
|
+
.kun-editor__bubble[data-show='false'] {
|
|
144
|
+
display: none;
|
|
145
|
+
}
|
|
146
|
+
.kun-editor__bubble-btn {
|
|
147
|
+
display: inline-flex;
|
|
148
|
+
align-items: center;
|
|
149
|
+
justify-content: center;
|
|
150
|
+
padding: 0.25rem;
|
|
151
|
+
border: 0;
|
|
152
|
+
border-radius: 0.375rem;
|
|
153
|
+
background: transparent;
|
|
154
|
+
color: var(--color-foreground);
|
|
155
|
+
cursor: pointer;
|
|
156
|
+
}
|
|
157
|
+
.kun-editor__bubble-btn:hover {
|
|
158
|
+
background: var(--color-default-100);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* ── Loading placeholder (WYSIWYG create/hydrate gap) ───────────────────── */
|
|
162
|
+
/* Shown while Milkdown hydrates; reserves height so the area doesn't collapse. */
|
|
163
|
+
.kun-editor__loading {
|
|
164
|
+
padding: 0.75rem 0;
|
|
165
|
+
}
|
|
166
|
+
.kun-editor__skeleton {
|
|
167
|
+
height: 0.85rem;
|
|
168
|
+
margin: 0.6rem 0;
|
|
169
|
+
border-radius: 4px;
|
|
170
|
+
background: linear-gradient(
|
|
171
|
+
90deg,
|
|
172
|
+
var(--color-default-100) 25%,
|
|
173
|
+
var(--color-default-200) 50%,
|
|
174
|
+
var(--color-default-100) 75%
|
|
175
|
+
);
|
|
176
|
+
background-size: 200% 100%;
|
|
177
|
+
animation: kun-editor-shimmer 1.2s ease-in-out infinite;
|
|
178
|
+
}
|
|
179
|
+
.kun-editor__skeleton:nth-child(2) {
|
|
180
|
+
width: 85%;
|
|
181
|
+
}
|
|
182
|
+
.kun-editor__skeleton:nth-child(3) {
|
|
183
|
+
width: 60%;
|
|
184
|
+
}
|
|
185
|
+
@keyframes kun-editor-shimmer {
|
|
186
|
+
from {
|
|
187
|
+
background-position: 200% 0;
|
|
188
|
+
}
|
|
189
|
+
to {
|
|
190
|
+
background-position: -200% 0;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
@media (prefers-reduced-motion: reduce) {
|
|
194
|
+
.kun-editor__skeleton {
|
|
195
|
+
animation: none;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* ── Formatting toolbar ─────────────────────────────────────────────────── */
|
|
200
|
+
.kun-editor__format-toolbar {
|
|
201
|
+
display: flex;
|
|
202
|
+
flex-wrap: wrap;
|
|
203
|
+
align-items: center;
|
|
204
|
+
gap: 0.125rem;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.kun-editor__toolbar-divider {
|
|
208
|
+
width: 1px;
|
|
209
|
+
align-self: stretch;
|
|
210
|
+
margin: 0.25rem;
|
|
211
|
+
background: var(--color-default-200);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.kun-editor__tool {
|
|
215
|
+
display: inline-flex;
|
|
216
|
+
align-items: center;
|
|
217
|
+
justify-content: center;
|
|
218
|
+
width: 1.75rem;
|
|
219
|
+
height: 1.75rem;
|
|
220
|
+
padding: 0;
|
|
221
|
+
border: none;
|
|
222
|
+
border-radius: 0.375rem;
|
|
223
|
+
background: transparent;
|
|
224
|
+
color: var(--color-foreground);
|
|
225
|
+
cursor: pointer;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.kun-editor__tool:hover {
|
|
229
|
+
background: var(--color-default-100);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.kun-editor__tool[data-active='true'] {
|
|
233
|
+
background: var(--color-primary);
|
|
234
|
+
color: var(--color-primary-contrast, #fff);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.kun-editor__tool[data-active='true']:hover {
|
|
238
|
+
background: var(--color-primary);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.kun-editor__icon {
|
|
242
|
+
display: inline-flex;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/* ── Markdown source (CodeMirror) ───────────────────────────────────────── */
|
|
246
|
+
.kun-editor__source .cm-editor {
|
|
247
|
+
border: 1px solid var(--color-default-200);
|
|
248
|
+
border-radius: 0.5rem;
|
|
249
|
+
overflow: hidden;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* ── @mention dropdown (a slash view; positioned by SlashProvider) ──────── */
|
|
253
|
+
.kun-mention-dropdown {
|
|
254
|
+
position: absolute;
|
|
255
|
+
z-index: 30;
|
|
256
|
+
display: none;
|
|
257
|
+
min-width: 12rem;
|
|
258
|
+
max-width: 20rem;
|
|
259
|
+
max-height: 16rem;
|
|
260
|
+
overflow-y: auto;
|
|
261
|
+
padding: 0.25rem;
|
|
262
|
+
background: var(--color-background);
|
|
263
|
+
border: 1px solid var(--color-default-200);
|
|
264
|
+
border-radius: 0.5rem;
|
|
265
|
+
box-shadow:
|
|
266
|
+
0 4px 6px -1px rgb(0 0 0 / 0.1),
|
|
267
|
+
0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.kun-mention-dropdown[data-show='true'] {
|
|
271
|
+
display: block;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.kun-mention-dropdown__item {
|
|
275
|
+
display: flex;
|
|
276
|
+
width: 100%;
|
|
277
|
+
align-items: center;
|
|
278
|
+
gap: 0.5rem;
|
|
279
|
+
padding: 0.375rem 0.5rem;
|
|
280
|
+
border: none;
|
|
281
|
+
border-radius: 0.375rem;
|
|
282
|
+
background: transparent;
|
|
283
|
+
font: inherit;
|
|
284
|
+
text-align: left;
|
|
285
|
+
cursor: pointer;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.kun-mention-dropdown__item:hover,
|
|
289
|
+
.kun-mention-dropdown__item[data-active='true'] {
|
|
290
|
+
background: var(--color-default-100);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.kun-mention-dropdown__avatar {
|
|
294
|
+
width: 1.5rem;
|
|
295
|
+
height: 1.5rem;
|
|
296
|
+
flex-shrink: 0;
|
|
297
|
+
border-radius: 9999px;
|
|
298
|
+
object-fit: cover;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.kun-mention-dropdown__avatar--fallback {
|
|
302
|
+
display: flex;
|
|
303
|
+
align-items: center;
|
|
304
|
+
justify-content: center;
|
|
305
|
+
background: var(--color-default-200);
|
|
306
|
+
color: var(--color-default-600);
|
|
307
|
+
font-size: 0.75rem;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.kun-mention-dropdown__name {
|
|
311
|
+
overflow: hidden;
|
|
312
|
+
text-overflow: ellipsis;
|
|
313
|
+
white-space: nowrap;
|
|
314
|
+
font-size: 0.875rem;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.kun-mention-dropdown__hint {
|
|
318
|
+
padding: 0.375rem 0.5rem;
|
|
319
|
+
color: var(--color-default-400);
|
|
320
|
+
font-size: 0.875rem;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* ── Sticker / emoji picker (toolbar popover) ───────────────────────────── */
|
|
324
|
+
.kun-editor__picker {
|
|
325
|
+
position: relative;
|
|
326
|
+
display: inline-flex;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.kun-editor__picker-panel {
|
|
330
|
+
position: absolute;
|
|
331
|
+
top: calc(100% + 0.25rem);
|
|
332
|
+
left: 0;
|
|
333
|
+
z-index: 30;
|
|
334
|
+
width: 18rem;
|
|
335
|
+
padding: 0.5rem;
|
|
336
|
+
background: var(--color-background);
|
|
337
|
+
border: 1px solid var(--color-default-200);
|
|
338
|
+
border-radius: 0.5rem;
|
|
339
|
+
box-shadow:
|
|
340
|
+
0 4px 6px -1px rgb(0 0 0 / 0.1),
|
|
341
|
+
0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.kun-editor__picker-tabs {
|
|
345
|
+
display: flex;
|
|
346
|
+
gap: 0.25rem;
|
|
347
|
+
margin-bottom: 0.5rem;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.kun-editor__picker-tab {
|
|
351
|
+
flex: 1;
|
|
352
|
+
padding: 0.25rem 0.5rem;
|
|
353
|
+
border: none;
|
|
354
|
+
border-bottom: 2px solid transparent;
|
|
355
|
+
background: transparent;
|
|
356
|
+
font: inherit;
|
|
357
|
+
cursor: pointer;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.kun-editor__picker-tab[data-active='true'] {
|
|
361
|
+
border-bottom-color: var(--color-primary);
|
|
362
|
+
color: var(--color-primary);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.kun-editor__emoji-grid {
|
|
366
|
+
display: grid;
|
|
367
|
+
grid-template-columns: repeat(8, 1fr);
|
|
368
|
+
gap: 0.125rem;
|
|
369
|
+
max-height: 16rem;
|
|
370
|
+
overflow-y: auto;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.kun-editor__emoji {
|
|
374
|
+
aspect-ratio: 1;
|
|
375
|
+
border: none;
|
|
376
|
+
border-radius: 0.375rem;
|
|
377
|
+
background: transparent;
|
|
378
|
+
font-size: 1.25rem;
|
|
379
|
+
line-height: 1;
|
|
380
|
+
cursor: pointer;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
.kun-editor__emoji:hover {
|
|
384
|
+
background: var(--color-default-100);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.kun-editor__sticker-body {
|
|
388
|
+
max-height: 16rem;
|
|
389
|
+
overflow-y: auto;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.kun-editor__pack-name {
|
|
393
|
+
padding: 0.25rem 0.125rem;
|
|
394
|
+
color: var(--color-default-500);
|
|
395
|
+
font-size: 0.75rem;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.kun-editor__sticker-grid {
|
|
399
|
+
display: grid;
|
|
400
|
+
grid-template-columns: repeat(5, 1fr);
|
|
401
|
+
gap: 0.25rem;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.kun-editor__sticker {
|
|
405
|
+
aspect-ratio: 1;
|
|
406
|
+
padding: 0.125rem;
|
|
407
|
+
border: none;
|
|
408
|
+
border-radius: 0.375rem;
|
|
409
|
+
background: transparent;
|
|
410
|
+
cursor: pointer;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.kun-editor__sticker:hover {
|
|
414
|
+
background: var(--color-default-100);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.kun-editor__sticker img {
|
|
418
|
+
width: 100%;
|
|
419
|
+
height: 100%;
|
|
420
|
+
object-fit: contain;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
.kun-editor__picker-hint {
|
|
424
|
+
padding: 1rem;
|
|
425
|
+
color: var(--color-default-400);
|
|
426
|
+
font-size: 0.875rem;
|
|
427
|
+
text-align: center;
|
|
428
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungal/editor-nuxt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "KunEditor Nuxt Layer — wraps @kungal/editor-vue and auto-imports <KunEditor> so an existing Nuxt app keeps its exact DX (no import needed).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -27,12 +27,13 @@
|
|
|
27
27
|
"CHANGELOG.md",
|
|
28
28
|
"app",
|
|
29
29
|
"runtime",
|
|
30
|
+
"editor.css",
|
|
30
31
|
"tailwind.css",
|
|
31
32
|
"nuxt.config.ts"
|
|
32
33
|
],
|
|
33
34
|
"dependencies": {
|
|
34
|
-
"@kungal/editor-core": "0.
|
|
35
|
-
"@kungal/editor-vue": "0.
|
|
35
|
+
"@kungal/editor-core": "0.32.0",
|
|
36
|
+
"@kungal/editor-vue": "0.32.0"
|
|
36
37
|
},
|
|
37
38
|
"peerDependencies": {
|
|
38
39
|
"@kungal/ui-vue": "^2.7.0",
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
import { EMOJI } from '@kungal/editor-vue'
|
|
41
41
|
import type {
|
|
42
42
|
KunEditorToolbarApi,
|
|
43
|
+
KunToggleMark,
|
|
43
44
|
KunToolbarItem,
|
|
44
45
|
StickerPack
|
|
45
46
|
} from '@kungal/editor-vue'
|
|
@@ -101,15 +102,18 @@ interface Tool {
|
|
|
101
102
|
icon: string
|
|
102
103
|
title: string
|
|
103
104
|
run: () => void
|
|
105
|
+
// The toggle mark this button flips, when any. Buttons with a mark render a
|
|
106
|
+
// pressed/active state (see the template) driven by `api.activeMarks`.
|
|
107
|
+
mark?: KunToggleMark
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
// The plain command buttons (everything except heading / image / picker).
|
|
107
111
|
// `.key` is read at click time via props.run (populated once the editor exists).
|
|
108
112
|
const commandButtons = computed<Record<string, Tool>>(() => ({
|
|
109
|
-
bold: { icon: 'lucide:bold', title: t.value.bold, run: () => props.run(toggleStrongCommand.key) },
|
|
110
|
-
italic: { icon: 'lucide:italic', title: t.value.italic, run: () => props.run(toggleEmphasisCommand.key) },
|
|
111
|
-
strike: { icon: 'lucide:strikethrough', title: t.value.strike, run: () => props.run(toggleStrikethroughCommand.key) },
|
|
112
|
-
code: { icon: 'lucide:code', title: t.value.code, run: () => props.run(toggleInlineCodeCommand.key) },
|
|
113
|
+
bold: { icon: 'lucide:bold', title: t.value.bold, run: () => props.run(toggleStrongCommand.key), mark: 'bold' },
|
|
114
|
+
italic: { icon: 'lucide:italic', title: t.value.italic, run: () => props.run(toggleEmphasisCommand.key), mark: 'italic' },
|
|
115
|
+
strike: { icon: 'lucide:strikethrough', title: t.value.strike, run: () => props.run(toggleStrikethroughCommand.key), mark: 'strike' },
|
|
116
|
+
code: { icon: 'lucide:code', title: t.value.code, run: () => props.run(toggleInlineCodeCommand.key), mark: 'code' },
|
|
113
117
|
bulletList: { icon: 'lucide:list', title: t.value.bulletList, run: () => props.run(wrapInBulletListCommand.key) },
|
|
114
118
|
orderedList: { icon: 'lucide:list-ordered', title: t.value.orderedList, run: () => props.run(wrapInOrderedListCommand.key) },
|
|
115
119
|
quote: { icon: 'lucide:text-quote', title: t.value.quote, run: () => props.run(wrapInBlockquoteCommand.key) },
|
|
@@ -427,10 +431,20 @@ const insertSticker = (src: string, name: string) =>
|
|
|
427
431
|
:delay-show="300"
|
|
428
432
|
>
|
|
429
433
|
<KunButton
|
|
430
|
-
variant="
|
|
434
|
+
:variant="
|
|
435
|
+
item.tool.mark && props.activeMarks[item.tool.mark]
|
|
436
|
+
? 'flat'
|
|
437
|
+
: 'light'
|
|
438
|
+
"
|
|
439
|
+
:color="
|
|
440
|
+
item.tool.mark && props.activeMarks[item.tool.mark]
|
|
441
|
+
? 'primary'
|
|
442
|
+
: 'default'
|
|
443
|
+
"
|
|
431
444
|
size="sm"
|
|
432
445
|
:is-icon-only="true"
|
|
433
446
|
:aria-label="item.tool.title"
|
|
447
|
+
:aria-pressed="item.tool.mark ? props.activeMarks[item.tool.mark] : undefined"
|
|
434
448
|
@click="item.tool.run()"
|
|
435
449
|
>
|
|
436
450
|
<KunIcon :name="item.tool.icon" />
|