@srcker/editor-vue-next 1.0.1

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 (95) hide show
  1. package/.vscode/extensions.json +3 -0
  2. package/README.md +50 -0
  3. package/index.html +13 -0
  4. package/index.ts +11 -0
  5. package/jsconfig.json +8 -0
  6. package/package.json +69 -0
  7. package/public/favicon.ico +0 -0
  8. package/src/App.vue +9 -0
  9. package/src/App.vue.js +17 -0
  10. package/src/Button/BackgroundButton.vue +331 -0
  11. package/src/Button/BackgroundButton.vue.js +243 -0
  12. package/src/Button/BlockQuoteButton.vue +26 -0
  13. package/src/Button/BlockQuoteButton.vue.js +56 -0
  14. package/src/Button/BoldButton.vue +29 -0
  15. package/src/Button/BoldButton.vue.js +56 -0
  16. package/src/Button/BulletListButton.vue +114 -0
  17. package/src/Button/BulletListButton.vue.js +147 -0
  18. package/src/Button/CodeBlockButton.vue +28 -0
  19. package/src/Button/CodeBlockButton.vue.js +56 -0
  20. package/src/Button/CodeButton.vue +30 -0
  21. package/src/Button/CodeButton.vue.js +56 -0
  22. package/src/Button/FontSizeButton.vue +85 -0
  23. package/src/Button/FontSizeButton.vue.js +131 -0
  24. package/src/Button/FormatButton.vue +25 -0
  25. package/src/Button/FormatButton.vue.js +54 -0
  26. package/src/Button/HeadingButton.vue +103 -0
  27. package/src/Button/HeadingButton.vue.js +164 -0
  28. package/src/Button/ImageUploadButton.vue +93 -0
  29. package/src/Button/ImageUploadButton.vue.js +123 -0
  30. package/src/Button/IndentLeftButton.vue +25 -0
  31. package/src/Button/IndentLeftButton.vue.js +54 -0
  32. package/src/Button/IndentRightButton.vue +29 -0
  33. package/src/Button/IndentRightButton.vue.js +54 -0
  34. package/src/Button/ItalicButton.vue +29 -0
  35. package/src/Button/ItalicButton.vue.js +56 -0
  36. package/src/Button/LineHeightButton.vue +88 -0
  37. package/src/Button/LineHeightButton.vue.js +131 -0
  38. package/src/Button/LinkButton.vue +44 -0
  39. package/src/Button/LinkButton.vue.js +69 -0
  40. package/src/Button/OrderedListButton.vue +121 -0
  41. package/src/Button/OrderedListButton.vue.js +146 -0
  42. package/src/Button/RedoButton.vue +29 -0
  43. package/src/Button/RedoButton.vue.js +55 -0
  44. package/src/Button/StrikeButton.vue +30 -0
  45. package/src/Button/StrikeButton.vue.js +56 -0
  46. package/src/Button/SubscriptButton.vue +29 -0
  47. package/src/Button/SubscriptButton.vue.js +56 -0
  48. package/src/Button/SuperscriptButton.vue +29 -0
  49. package/src/Button/SuperscriptButton.vue.js +56 -0
  50. package/src/Button/TextAlignCenterButton.vue +26 -0
  51. package/src/Button/TextAlignCenterButton.vue.js +56 -0
  52. package/src/Button/TextAlignLeftButton.vue +26 -0
  53. package/src/Button/TextAlignLeftButton.vue.js +56 -0
  54. package/src/Button/TextAlignRightButton.vue +26 -0
  55. package/src/Button/TextAlignRightButton.vue.js +56 -0
  56. package/src/Button/TextColorButton.vue +329 -0
  57. package/src/Button/TextColorButton.vue.js +243 -0
  58. package/src/Button/ThemeButton.vue +34 -0
  59. package/src/Button/ThemeButton.vue.js +63 -0
  60. package/src/Button/UnderLineButton.vue +29 -0
  61. package/src/Button/UnderLineButton.vue.js +56 -0
  62. package/src/Button/UndoButton.vue +29 -0
  63. package/src/Button/UndoButton.vue.js +55 -0
  64. package/src/Components/IconArrow.vue +16 -0
  65. package/src/Components/IconArrow.vue.js +30 -0
  66. package/src/Components/IconCheck.vue +40 -0
  67. package/src/Components/IconCheck.vue.js +59 -0
  68. package/src/EditorToolbar.vue +150 -0
  69. package/src/EditorToolbar.vue.js +306 -0
  70. package/src/Extensions/BulletListStyle.js +19 -0
  71. package/src/Extensions/BulletListStyle.ts +24 -0
  72. package/src/Extensions/FontSize.js +27 -0
  73. package/src/Extensions/FontSize.ts +37 -0
  74. package/src/Extensions/Indent.js +58 -0
  75. package/src/Extensions/Indent.ts +73 -0
  76. package/src/Extensions/OrderedListStyle.js +19 -0
  77. package/src/Extensions/OrderedListStyle.ts +24 -0
  78. package/src/Extensions/UploadImage.js +18 -0
  79. package/src/Extensions/UploadImage.ts +22 -0
  80. package/src/Extensions/shims.d.ts +26 -0
  81. package/src/RichEditor.vue +191 -0
  82. package/src/RichEditor.vue.js +199 -0
  83. package/src/env.d.ts +7 -0
  84. package/src/index.js +6 -0
  85. package/src/index.ts +11 -0
  86. package/src/main.js +4 -0
  87. package/src/main.ts +7 -0
  88. package/src/styles/style.scss +196 -0
  89. package/src/styles/theme.css +28 -0
  90. package/src/styles/variables.css +158 -0
  91. package/src/styles/variables.scss +175 -0
  92. package/src/types.js +1 -0
  93. package/src/types.ts +7 -0
  94. package/tsconfig.json +17 -0
  95. package/vite.config.ts +29 -0
@@ -0,0 +1,329 @@
1
+ <template>
2
+ <div
3
+ class="color-button"
4
+ ref="wrapperRef"
5
+ :class="{ 'open': isOpen }"
6
+ @click="isOpen = !isOpen"
7
+ title="字体颜色">
8
+
9
+ <div class="trigger" >
10
+ <div class="icon">
11
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
12
+ <path fill="currentColor" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M285.1 50.7C279.9 39.3 268.5 32 256 32s-23.9 7.3-29.1 18.7L59.5 416 48 416c-17.7 0-32 14.3-32 32s14.3 32 32 32l88 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-6.1 0 22-48 208.3 0 22 48-6.1 0c-17.7 0-32 14.3-32 32s14.3 32 32 32l88 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-11.5 0-167.4-365.3zM330.8 304L181.2 304 256 140.8 330.8 304z"/>
13
+ </svg>
14
+ </div>
15
+ <div class="bar" :style="{ backgroundColor: getColor || '#000' }"></div>
16
+ </div>
17
+
18
+ <div class="dropdown" v-if="isOpen">
19
+ <div class="grid">
20
+ <div
21
+ v-for="color in colorPalette"
22
+ :key="color"
23
+ class="item"
24
+ :style="{ backgroundColor: color }"
25
+ @click="setColor(color)"
26
+ :title="color">
27
+ <IconCheck v-if="editor.isActive('textStyle', { color })" :size="10" color="#fff" />
28
+ </div>
29
+ </div>
30
+
31
+ <div class="footer">
32
+ <label>自定义颜色</label>
33
+ <div class="input">
34
+ <input
35
+ type="color"
36
+ @input="editor.chain().focus().setColor($event.target.value).run()"
37
+ :value="getColor"/>
38
+ </div>
39
+
40
+ <div class="button" @click="editor.chain().focus().unsetColor().run();">清除</div>
41
+ </div>
42
+ </div>
43
+
44
+ </div>
45
+ </template>
46
+
47
+
48
+ <script setup>
49
+
50
+ import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
51
+ import IconCheck from '../components/IconCheck.vue';
52
+
53
+ const isOpen = ref(false)
54
+ const wrapperRef = ref(null)
55
+
56
+ const colorPalette = [
57
+ // 黑白灰
58
+ '#000000',
59
+ '#262626',
60
+ '#595959',
61
+ '#8C8C8C',
62
+ '#BFBFBF',
63
+ '#D9D9D9',
64
+ '#E9E9E9',
65
+ '#F5F5F5',
66
+ '#FAFAFA',
67
+ '#FFFFFF',
68
+
69
+ // 基础色
70
+ '#F5222D',
71
+ '#FA541C',
72
+ '#FA8C16',
73
+ '#FADB14',
74
+ '#52C41A',
75
+ '#13C2C2',
76
+ '#1890FF',
77
+ '#2F54EB',
78
+ '#722ED1',
79
+ '#EB2F96',
80
+
81
+ // 浅色系
82
+ '#FFE8E6',
83
+ '#FFECE0',
84
+ '#FFEF D1'.replace(' ', ''),
85
+ '#FCFCCA',
86
+ '#E4F7D2',
87
+ '#D3F5F0',
88
+ '#D4EEFC',
89
+ '#DEE8FC',
90
+ '#EFE1FA',
91
+ '#FAE1EB',
92
+
93
+ // 中色系
94
+ '#FFA39E',
95
+ '#FFBB96',
96
+ '#FFD591',
97
+ '#FFFB8F',
98
+ '#B7EB8F',
99
+ '#87E8DE',
100
+ '#91D5FF',
101
+ '#ADC6FF',
102
+ '#D3ADF7',
103
+ '#FFADD2',
104
+
105
+ // 深色系
106
+ '#FF4D4F',
107
+ '#FF7A45',
108
+ '#FFA940',
109
+ '#FFEC3D',
110
+ '#73D13D',
111
+ '#36CFC9',
112
+ '#40A9FF',
113
+ '#597EF7',
114
+ '#9254DE',
115
+ '#F759AB',
116
+
117
+ // 暗色系
118
+ '#CF1322',
119
+ '#D4380D',
120
+ '#D46B08',
121
+ '#D4B106',
122
+ '#389E0D',
123
+ '#08979C',
124
+ '#096DD9',
125
+ '#1D39C4',
126
+ '#531DAB',
127
+ '#C41D7F',
128
+
129
+ // 极深色
130
+ '#820014',
131
+ '#871400',
132
+ '#873800',
133
+ '#614700',
134
+ '#135200',
135
+ '#00474F',
136
+ '#003A8C',
137
+ '#061178',
138
+ '#22075E',
139
+ '#780650'
140
+ ];
141
+
142
+
143
+ const setColor = (color) => {
144
+ props.editor.chain().focus().setColor(color).run();
145
+ isOpen.value = false
146
+ }
147
+
148
+
149
+
150
+ const getColor = computed(() => {
151
+ if (!props.editor) return '#fff'
152
+ const color = props.editor.getAttributes('textStyle').color
153
+ return color || '#000'
154
+ })
155
+
156
+
157
+
158
+ const props = defineProps({
159
+ editor: {
160
+ type: Object,
161
+ required: true
162
+ }
163
+ })
164
+
165
+ const handleClickOutside = (e) => {
166
+ if (!wrapperRef.value) return
167
+
168
+ if (!wrapperRef.value.contains(e.target)) {
169
+ isOpen.value = false
170
+ }
171
+ }
172
+
173
+ onMounted(() => {
174
+ document.addEventListener('mousedown', handleClickOutside)
175
+ })
176
+
177
+ onBeforeUnmount(() => {
178
+ document.removeEventListener('mousedown', handleClickOutside)
179
+ })
180
+
181
+ </script>
182
+
183
+
184
+
185
+ <style lang="scss" scoped>
186
+
187
+ .color-button {
188
+ position: relative;
189
+ display: inline-flex;
190
+ align-items: center;
191
+
192
+ .trigger {
193
+ height: 25px;
194
+ padding: 3px 8px;
195
+ display: flex;
196
+ align-items: center;
197
+ justify-content: space-between;
198
+ cursor: pointer;
199
+ border-radius: 6px;
200
+ font-size: 14px;
201
+ transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
202
+ color: var(--color);
203
+ background: var(--background);
204
+
205
+ &:hover,
206
+ &.is-open {
207
+ color: var(--hover-color);
208
+ background: var(--hover-background);
209
+ }
210
+
211
+ .icon{
212
+ display: inline-flex;
213
+ align-items: center;
214
+ justify-content: center;
215
+ svg{
216
+ height: 14px;
217
+ }
218
+ }
219
+
220
+ .bar{
221
+ position: absolute;
222
+ bottom: 5px;
223
+ width: 15px;
224
+ height: 3px;
225
+ left: 50%;
226
+ border: 1px solid rgba($color: #fff, $alpha: 0.5);
227
+ transform: translateX(-50%);
228
+ }
229
+
230
+ .label {
231
+ margin: 0 5px;
232
+ display: inline-flex;
233
+ align-items: center;
234
+ white-space: nowrap;
235
+ overflow: hidden;
236
+ text-overflow: ellipsis;
237
+ }
238
+ .arrow {
239
+ font-size: 14px;
240
+ color: #666;
241
+ display: inline-flex;
242
+ align-items: center;
243
+ }
244
+ }
245
+
246
+ .dropdown {
247
+ position: absolute;
248
+ top: 100%;
249
+ left: 0;
250
+ margin-top: 5px;
251
+ background: #1f1f1f;
252
+ box-shadow: 0 0px 15px rgba(0,0,0,0.05);
253
+ border-radius: 10px;
254
+ z-index: 1000;
255
+ overflow-y: auto;
256
+ padding: 15px;
257
+ transition: all 0.3s cubic-bezier(0.46, 0.03, 0.52, 0.96);
258
+
259
+ .grid{
260
+ display: grid;
261
+ grid-template-columns: repeat(10, 1fr);
262
+ gap: 5px;
263
+ width: 300px;
264
+ .item{
265
+ width: 20px;
266
+ height: 20px;
267
+ padding: 2px;
268
+ border-radius: 50%;
269
+ border: 1px solid transparent;
270
+ cursor: pointer;
271
+ display: flex;
272
+ align-items: center;
273
+ justify-content: center;
274
+ transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
275
+ &:hover {
276
+ border-color: rgba($color: #fff, $alpha: 0.5);
277
+ z-index: 1;
278
+ }
279
+
280
+ .icon{
281
+ display: inline-flex;
282
+ align-items: center;
283
+ color: rgba($color: #fff, $alpha: 1);
284
+ }
285
+ }
286
+ }
287
+
288
+ .footer{
289
+ margin-top: 20px;
290
+ display: flex;
291
+ align-items: center;
292
+
293
+ label{
294
+ font-size: 14px;
295
+ color: #fff;
296
+ }
297
+
298
+ .input{
299
+ flex: 1;
300
+ padding-left: 15px;
301
+
302
+ input{
303
+ padding: 0;
304
+ block-size: 20px;
305
+ border: none;
306
+ inline-size: 40px;
307
+ }
308
+ }
309
+
310
+ .button{
311
+ display: flex;
312
+ align-items: center;
313
+ padding: 5px 15px;
314
+ border-radius: 12px;
315
+ color: rgba($color: #fff, $alpha: 0.5);
316
+ background: rgba($color: #fff, $alpha: 0.1);
317
+ font-size: 14px;
318
+ justify-content: center;
319
+
320
+ &:hover {
321
+ cursor: pointer;
322
+ background: rgba($color: #000000, $alpha: 0.2);
323
+ color: rgba($color: #fff, $alpha: 0.8);
324
+ }
325
+ }
326
+ }
327
+ }
328
+ }
329
+ </style>
@@ -0,0 +1,243 @@
1
+ import { ref, computed, onMounted, onBeforeUnmount } from 'vue';
2
+ import IconCheck from '../components/IconCheck.vue';
3
+ const isOpen = ref(false);
4
+ const wrapperRef = ref(null);
5
+ const colorPalette = [
6
+ // 黑白灰
7
+ '#000000',
8
+ '#262626',
9
+ '#595959',
10
+ '#8C8C8C',
11
+ '#BFBFBF',
12
+ '#D9D9D9',
13
+ '#E9E9E9',
14
+ '#F5F5F5',
15
+ '#FAFAFA',
16
+ '#FFFFFF',
17
+ // 基础色
18
+ '#F5222D',
19
+ '#FA541C',
20
+ '#FA8C16',
21
+ '#FADB14',
22
+ '#52C41A',
23
+ '#13C2C2',
24
+ '#1890FF',
25
+ '#2F54EB',
26
+ '#722ED1',
27
+ '#EB2F96',
28
+ // 浅色系
29
+ '#FFE8E6',
30
+ '#FFECE0',
31
+ '#FFEF D1'.replace(' ', ''),
32
+ '#FCFCCA',
33
+ '#E4F7D2',
34
+ '#D3F5F0',
35
+ '#D4EEFC',
36
+ '#DEE8FC',
37
+ '#EFE1FA',
38
+ '#FAE1EB',
39
+ // 中色系
40
+ '#FFA39E',
41
+ '#FFBB96',
42
+ '#FFD591',
43
+ '#FFFB8F',
44
+ '#B7EB8F',
45
+ '#87E8DE',
46
+ '#91D5FF',
47
+ '#ADC6FF',
48
+ '#D3ADF7',
49
+ '#FFADD2',
50
+ // 深色系
51
+ '#FF4D4F',
52
+ '#FF7A45',
53
+ '#FFA940',
54
+ '#FFEC3D',
55
+ '#73D13D',
56
+ '#36CFC9',
57
+ '#40A9FF',
58
+ '#597EF7',
59
+ '#9254DE',
60
+ '#F759AB',
61
+ // 暗色系
62
+ '#CF1322',
63
+ '#D4380D',
64
+ '#D46B08',
65
+ '#D4B106',
66
+ '#389E0D',
67
+ '#08979C',
68
+ '#096DD9',
69
+ '#1D39C4',
70
+ '#531DAB',
71
+ '#C41D7F',
72
+ // 极深色
73
+ '#820014',
74
+ '#871400',
75
+ '#873800',
76
+ '#614700',
77
+ '#135200',
78
+ '#00474F',
79
+ '#003A8C',
80
+ '#061178',
81
+ '#22075E',
82
+ '#780650'
83
+ ];
84
+ const setColor = (color) => {
85
+ props.editor.chain().focus().setColor(color).run();
86
+ isOpen.value = false;
87
+ };
88
+ const getColor = computed(() => {
89
+ if (!props.editor)
90
+ return '#fff';
91
+ const color = props.editor.getAttributes('textStyle').color;
92
+ return color || '#000';
93
+ });
94
+ const props = defineProps({
95
+ editor: {
96
+ type: Object,
97
+ required: true
98
+ }
99
+ });
100
+ const handleClickOutside = (e) => {
101
+ if (!wrapperRef.value)
102
+ return;
103
+ if (!wrapperRef.value.contains(e.target)) {
104
+ isOpen.value = false;
105
+ }
106
+ };
107
+ onMounted(() => {
108
+ document.addEventListener('mousedown', handleClickOutside);
109
+ });
110
+ onBeforeUnmount(() => {
111
+ document.removeEventListener('mousedown', handleClickOutside);
112
+ });
113
+ const __VLS_ctx = {
114
+ ...{},
115
+ ...{},
116
+ ...{},
117
+ ...{},
118
+ };
119
+ let __VLS_components;
120
+ let __VLS_intrinsics;
121
+ let __VLS_directives;
122
+ /** @type {__VLS_StyleScopedClasses['icon']} */ ;
123
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
124
+ ...{ onClick: (...[$event]) => {
125
+ __VLS_ctx.isOpen = !__VLS_ctx.isOpen;
126
+ // @ts-ignore
127
+ [isOpen, isOpen,];
128
+ } },
129
+ ...{ class: "color-button" },
130
+ ref: "wrapperRef",
131
+ ...{ class: ({ 'open': __VLS_ctx.isOpen }) },
132
+ title: "字体颜色",
133
+ });
134
+ /** @type {__VLS_StyleScopedClasses['color-button']} */ ;
135
+ /** @type {__VLS_StyleScopedClasses['open']} */ ;
136
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
137
+ ...{ class: "trigger" },
138
+ });
139
+ /** @type {__VLS_StyleScopedClasses['trigger']} */ ;
140
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
141
+ ...{ class: "icon" },
142
+ });
143
+ /** @type {__VLS_StyleScopedClasses['icon']} */ ;
144
+ __VLS_asFunctionalElement1(__VLS_intrinsics.svg, __VLS_intrinsics.svg)({
145
+ xmlns: "http://www.w3.org/2000/svg",
146
+ viewBox: "0 0 512 512",
147
+ });
148
+ __VLS_asFunctionalElement1(__VLS_intrinsics.path)({
149
+ fill: "currentColor",
150
+ stroke: "currentColor",
151
+ 'stroke-width': "4",
152
+ 'stroke-linecap': "round",
153
+ 'stroke-linejoin': "round",
154
+ d: "M285.1 50.7C279.9 39.3 268.5 32 256 32s-23.9 7.3-29.1 18.7L59.5 416 48 416c-17.7 0-32 14.3-32 32s14.3 32 32 32l88 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-6.1 0 22-48 208.3 0 22 48-6.1 0c-17.7 0-32 14.3-32 32s14.3 32 32 32l88 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-11.5 0-167.4-365.3zM330.8 304L181.2 304 256 140.8 330.8 304z",
155
+ });
156
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
157
+ ...{ class: "bar" },
158
+ ...{ style: ({ backgroundColor: __VLS_ctx.getColor || '#000' }) },
159
+ });
160
+ /** @type {__VLS_StyleScopedClasses['bar']} */ ;
161
+ if (__VLS_ctx.isOpen) {
162
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
163
+ ...{ class: "dropdown" },
164
+ });
165
+ /** @type {__VLS_StyleScopedClasses['dropdown']} */ ;
166
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
167
+ ...{ class: "grid" },
168
+ });
169
+ /** @type {__VLS_StyleScopedClasses['grid']} */ ;
170
+ for (const [color] of __VLS_vFor((__VLS_ctx.colorPalette))) {
171
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
172
+ ...{ onClick: (...[$event]) => {
173
+ if (!(__VLS_ctx.isOpen))
174
+ return;
175
+ __VLS_ctx.setColor(color);
176
+ // @ts-ignore
177
+ [isOpen, isOpen, getColor, colorPalette, setColor,];
178
+ } },
179
+ key: (color),
180
+ ...{ class: "item" },
181
+ ...{ style: ({ backgroundColor: color }) },
182
+ title: (color),
183
+ });
184
+ /** @type {__VLS_StyleScopedClasses['item']} */ ;
185
+ if (__VLS_ctx.editor.isActive('textStyle', { color })) {
186
+ const __VLS_0 = IconCheck;
187
+ // @ts-ignore
188
+ const __VLS_1 = __VLS_asFunctionalComponent1(__VLS_0, new __VLS_0({
189
+ size: (10),
190
+ color: "#fff",
191
+ }));
192
+ const __VLS_2 = __VLS_1({
193
+ size: (10),
194
+ color: "#fff",
195
+ }, ...__VLS_functionalComponentArgsRest(__VLS_1));
196
+ }
197
+ // @ts-ignore
198
+ [editor,];
199
+ }
200
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
201
+ ...{ class: "footer" },
202
+ });
203
+ /** @type {__VLS_StyleScopedClasses['footer']} */ ;
204
+ __VLS_asFunctionalElement1(__VLS_intrinsics.label, __VLS_intrinsics.label)({});
205
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
206
+ ...{ class: "input" },
207
+ });
208
+ /** @type {__VLS_StyleScopedClasses['input']} */ ;
209
+ __VLS_asFunctionalElement1(__VLS_intrinsics.input)({
210
+ ...{ onInput: (...[$event]) => {
211
+ if (!(__VLS_ctx.isOpen))
212
+ return;
213
+ __VLS_ctx.editor.chain().focus().setColor($event.target.value).run();
214
+ // @ts-ignore
215
+ [editor,];
216
+ } },
217
+ type: "color",
218
+ value: (__VLS_ctx.getColor),
219
+ });
220
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
221
+ ...{ onClick: (...[$event]) => {
222
+ if (!(__VLS_ctx.isOpen))
223
+ return;
224
+ __VLS_ctx.editor.chain().focus().unsetColor().run();
225
+ ;
226
+ // @ts-ignore
227
+ [getColor, editor,];
228
+ } },
229
+ ...{ class: "button" },
230
+ });
231
+ /** @type {__VLS_StyleScopedClasses['button']} */ ;
232
+ }
233
+ // @ts-ignore
234
+ [];
235
+ const __VLS_export = (await import('vue')).defineComponent({
236
+ props: {
237
+ editor: {
238
+ type: Object,
239
+ required: true
240
+ }
241
+ },
242
+ });
243
+ export default {};
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <button
3
+ class="icon-button"
4
+ @click="toggleTheme" >
5
+ <div class="icon">
6
+ <!-- 黑色 -->
7
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" v-if="theme === 'light'">
8
+ <path fill="currentColor" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M256 0C114.6 0 0 114.6 0 256S114.6 512 256 512c68.8 0 131.3-27.2 177.3-71.4 7.3-7 9.4-17.9 5.3-27.1s-13.7-14.9-23.8-14.1c-4.9 .4-9.8 .6-14.8 .6-101.6 0-184-82.4-184-184 0-72.1 41.5-134.6 102.1-164.8 9.1-4.5 14.3-14.3 13.1-24.4S322.6 8.5 312.7 6.3C294.4 2.2 275.4 0 256 0z"/>
9
+ </svg>
10
+ <!-- 白色 -->
11
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" v-else>
12
+ <path fill="currentColor" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M239.3 48.7c-107.1 8.5-191.3 98.1-191.3 207.3 0 114.9 93.1 208 208 208 33.3 0 64.7-7.8 92.6-21.7-103.4-23.4-180.6-115.8-180.6-226.3 0-65.8 27.4-125.1 71.3-167.3zM0 256c0-141.4 114.6-256 256-256 19.4 0 38.4 2.2 56.7 6.3 9.9 2.2 17.3 10.5 18.5 20.5s-4 19.8-13.1 24.4c-60.6 30.2-102.1 92.7-102.1 164.8 0 101.6 82.4 184 184 184 5 0 9.9-.2 14.8-.6 10.1-.8 19.6 4.8 23.8 14.1s2 20.1-5.3 27.1C387.3 484.8 324.8 512 256 512 114.6 512 0 397.4 0 256z"/>
13
+ </svg>
14
+ </div>
15
+
16
+ <div class="tips">切换主题</div>
17
+ </button>
18
+ </template>
19
+
20
+
21
+ <script setup lang="ts">
22
+ const props = defineProps<{
23
+ theme: 'light' | 'dark' // TS 类型优化,避免 String 报错
24
+ }>()
25
+
26
+ const emit = defineEmits<{
27
+ (e: 'toggle-theme'): void
28
+ }>()
29
+
30
+ const toggleTheme = () => {
31
+ emit('toggle-theme')
32
+ }
33
+
34
+ </script>
@@ -0,0 +1,63 @@
1
+ const props = defineProps();
2
+ const emit = defineEmits();
3
+ const toggleTheme = () => {
4
+ emit('toggle-theme');
5
+ };
6
+ const __VLS_ctx = {
7
+ ...{},
8
+ ...{},
9
+ ...{},
10
+ ...{},
11
+ ...{},
12
+ };
13
+ let __VLS_components;
14
+ let __VLS_intrinsics;
15
+ let __VLS_directives;
16
+ __VLS_asFunctionalElement1(__VLS_intrinsics.button, __VLS_intrinsics.button)({
17
+ ...{ onClick: (__VLS_ctx.toggleTheme) },
18
+ ...{ class: "icon-button" },
19
+ });
20
+ /** @type {__VLS_StyleScopedClasses['icon-button']} */ ;
21
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
22
+ ...{ class: "icon" },
23
+ });
24
+ /** @type {__VLS_StyleScopedClasses['icon']} */ ;
25
+ if (__VLS_ctx.theme === 'light') {
26
+ __VLS_asFunctionalElement1(__VLS_intrinsics.svg, __VLS_intrinsics.svg)({
27
+ xmlns: "http://www.w3.org/2000/svg",
28
+ viewBox: "0 0 512 512",
29
+ });
30
+ __VLS_asFunctionalElement1(__VLS_intrinsics.path)({
31
+ fill: "currentColor",
32
+ stroke: "currentColor",
33
+ 'stroke-width': "4",
34
+ 'stroke-linecap': "round",
35
+ 'stroke-linejoin': "round",
36
+ d: "M256 0C114.6 0 0 114.6 0 256S114.6 512 256 512c68.8 0 131.3-27.2 177.3-71.4 7.3-7 9.4-17.9 5.3-27.1s-13.7-14.9-23.8-14.1c-4.9 .4-9.8 .6-14.8 .6-101.6 0-184-82.4-184-184 0-72.1 41.5-134.6 102.1-164.8 9.1-4.5 14.3-14.3 13.1-24.4S322.6 8.5 312.7 6.3C294.4 2.2 275.4 0 256 0z",
37
+ });
38
+ }
39
+ else {
40
+ __VLS_asFunctionalElement1(__VLS_intrinsics.svg, __VLS_intrinsics.svg)({
41
+ xmlns: "http://www.w3.org/2000/svg",
42
+ viewBox: "0 0 512 512",
43
+ });
44
+ __VLS_asFunctionalElement1(__VLS_intrinsics.path)({
45
+ fill: "currentColor",
46
+ stroke: "currentColor",
47
+ 'stroke-width': "4",
48
+ 'stroke-linecap': "round",
49
+ 'stroke-linejoin': "round",
50
+ d: "M239.3 48.7c-107.1 8.5-191.3 98.1-191.3 207.3 0 114.9 93.1 208 208 208 33.3 0 64.7-7.8 92.6-21.7-103.4-23.4-180.6-115.8-180.6-226.3 0-65.8 27.4-125.1 71.3-167.3zM0 256c0-141.4 114.6-256 256-256 19.4 0 38.4 2.2 56.7 6.3 9.9 2.2 17.3 10.5 18.5 20.5s-4 19.8-13.1 24.4c-60.6 30.2-102.1 92.7-102.1 164.8 0 101.6 82.4 184 184 184 5 0 9.9-.2 14.8-.6 10.1-.8 19.6 4.8 23.8 14.1s2 20.1-5.3 27.1C387.3 484.8 324.8 512 256 512 114.6 512 0 397.4 0 256z",
51
+ });
52
+ }
53
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
54
+ ...{ class: "tips" },
55
+ });
56
+ /** @type {__VLS_StyleScopedClasses['tips']} */ ;
57
+ // @ts-ignore
58
+ [toggleTheme, theme,];
59
+ const __VLS_export = (await import('vue')).defineComponent({
60
+ __typeEmits: {},
61
+ __typeProps: {},
62
+ });
63
+ export default {};
@@ -0,0 +1,29 @@
1
+ <template>
2
+ <button
3
+ class="icon-button"
4
+ :class="{ 'active': editor.isActive('underline') }"
5
+ @click="editor.chain().focus().toggleUnderline().run()" >
6
+
7
+ <div class="icon">
8
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
9
+ <path fill="currentColor" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M0 32C0 14.3 14.3 0 32 0L96 0c17.7 0 32 14.3 32 32S113.7 64 96 64l0 160c0 53 43 96 96 96s96-43 96-96l0-160c-17.7 0-32-14.3-32-32S270.3 0 288 0l64 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l0 160c0 88.4-71.6 160-160 160S32 312.4 32 224L32 64C14.3 64 0 49.7 0 32zM0 480c0-17.7 14.3-32 32-32l320 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 512c-17.7 0-32-14.3-32-32z"/>
10
+ </svg>
11
+ </div>
12
+
13
+ <div class="tips">下划线</div>
14
+ </button>
15
+ </template>
16
+
17
+
18
+ <script setup>
19
+ const props = defineProps({
20
+ editor: {
21
+ type: Object,
22
+ required: true
23
+ }
24
+ })
25
+
26
+
27
+
28
+ </script>
29
+