@jvs-milkdown/crepe 1.2.18 → 1.2.21
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/lib/cjs/feature/toolbar/index.js +47 -20
- package/lib/cjs/feature/toolbar/index.js.map +1 -1
- package/lib/cjs/index.js +166 -82
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/feature/toolbar/index.js +47 -20
- package/lib/esm/feature/toolbar/index.js.map +1 -1
- package/lib/esm/index.js +325 -241
- package/lib/esm/index.js.map +1 -1
- package/lib/theme/common/toolbar.css +3 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/core/crepe.d.ts +1 -0
- package/lib/types/core/crepe.d.ts.map +1 -1
- package/lib/types/feature/fixed-toolbar/component.d.ts.map +1 -1
- package/lib/types/feature/fixed-toolbar/menu-bar.d.ts.map +1 -1
- package/lib/types/feature/toolbar/component.d.ts.map +1 -1
- package/lib/types/utils/fixed-toolbar-popup-state.d.ts +1 -0
- package/lib/types/utils/fixed-toolbar-popup-state.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/core/crepe.ts +83 -21
- package/src/feature/fixed-toolbar/component.tsx +3 -6
- package/src/feature/fixed-toolbar/index.ts +1 -1
- package/src/feature/fixed-toolbar/menu-bar.tsx +0 -1
- package/src/feature/toolbar/component.tsx +55 -21
- package/src/theme/common/toolbar.css +3 -0
- package/src/utils/fixed-toolbar-popup-state.ts +5 -0
|
@@ -8,5 +8,6 @@ export interface CrepeConfig extends CrepeBuilderConfig {
|
|
|
8
8
|
export declare class Crepe extends CrepeBuilder {
|
|
9
9
|
static Feature: typeof CrepeFeature;
|
|
10
10
|
constructor(config?: CrepeConfig);
|
|
11
|
+
destroy: () => Promise<import("@jvs-milkdown/core").Editor>;
|
|
11
12
|
}
|
|
12
13
|
//# sourceMappingURL=crepe.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crepe.d.ts","sourceRoot":"","sources":["../../../src/core/crepe.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAGpD,OAAO,EAAE,YAAY,EAAmB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"crepe.d.ts","sourceRoot":"","sources":["../../../src/core/crepe.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAGpD,OAAO,EAAE,YAAY,EAAmB,MAAM,YAAY,CAAA;AAG1D,OAAO,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAGjE,MAAM,WAAW,WAAY,SAAQ,kBAAkB;IAErD,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAA;IAGjD,cAAc,CAAC,EAAE,kBAAkB,CAAA;CACpC;AAGD,qBAAa,KAAM,SAAQ,YAAY;IAErC,MAAM,CAAC,OAAO,sBAAe;gBAKjB,MAAM,GAAE,WAAgB;IA0G3B,OAAO,qDAGf;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../../src/feature/fixed-toolbar/component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../../src/feature/fixed-toolbar/component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AAI9D,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,GAAG,EAIT,MAAM,KAAK,CAAA;AAEZ,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,GAAG,CAAA;AAOlD,KAAK,iBAAiB,GAAG;IACvB,GAAG,EAAE,GAAG,CAAA;IACR,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAClB,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;IAChC,MAAM,CAAC,EAAE,yBAAyB,CAAA;IAClC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACrB,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;CACtB,CAAA;AAED,eAAO,MAAM,qBAAqB,oXA8JhC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-bar.d.ts","sourceRoot":"","sources":["../../../../src/feature/fixed-toolbar/menu-bar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"menu-bar.d.ts","sourceRoot":"","sources":["../../../../src/feature/fixed-toolbar/menu-bar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAA;AAahD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAsDjD,eAAO,MAAM,OAAO;;cAEO,MAAM,GAAG;;;;cACN,MAAM,kBAAkB;;;;;cAD3B,MAAM,GAAG;;;;cACN,MAAM,kBAAkB;;;+GAkgBpD,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../../src/feature/toolbar/component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAA;AAgBhD,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,+BAA+B,CAAA;AAUtC,OAAO,EAEL,KAAK,GAAG,EACR,KAAK,UAAU,EAQhB,MAAM,KAAK,CAAA;AAEZ,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,GAAG,CAAA;AAmG7C,KAAK,YAAY,GAAG;IAClB,GAAG,EAAE,GAAG,CAAA;IACR,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAClB,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;IAChC,MAAM,CAAC,EAAE,oBAAoB,CAAA;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAeD,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../../src/feature/toolbar/component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAA;AAgBhD,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,+BAA+B,CAAA;AAUtC,OAAO,EAEL,KAAK,GAAG,EACR,KAAK,UAAU,EAQhB,MAAM,KAAK,CAAA;AAEZ,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,GAAG,CAAA;AAmG7C,KAAK,YAAY,GAAG;IAClB,GAAG,EAAE,GAAG,CAAA;IACR,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAClB,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;IAChC,MAAM,CAAC,EAAE,oBAAoB,CAAA;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAeD,eAAO,MAAM,OAAO,0WAihFlB,CAAA"}
|
|
@@ -3,5 +3,6 @@ export declare function getIsAnyPopupOpen(): boolean;
|
|
|
3
3
|
export declare function addPopupChangeListener(fn: Listener): () => void;
|
|
4
4
|
export declare function incrementPopupCount(): void;
|
|
5
5
|
export declare function decrementPopupCount(): void;
|
|
6
|
+
export declare function resetPopupCount(): void;
|
|
6
7
|
export {};
|
|
7
8
|
//# sourceMappingURL=fixed-toolbar-popup-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixed-toolbar-popup-state.d.ts","sourceRoot":"","sources":["../../../src/utils/fixed-toolbar-popup-state.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,GAAG,MAAM,IAAI,CAAA;AAI1B,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,IAAI,CAG/D;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAM1C;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C"}
|
|
1
|
+
{"version":3,"file":"fixed-toolbar-popup-state.d.ts","sourceRoot":"","sources":["../../../src/utils/fixed-toolbar-popup-state.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,GAAG,MAAM,IAAI,CAAA;AAI1B,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,IAAI,CAG/D;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAM1C;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C;AAED,wBAAgB,eAAe,IAAI,IAAI,CAGtC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jvs-milkdown/crepe",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.21",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"crepe",
|
|
6
6
|
"editor",
|
|
@@ -107,9 +107,9 @@
|
|
|
107
107
|
"@codemirror/theme-one-dark": "^6.1.2",
|
|
108
108
|
"@codemirror/view": "^6.26.0",
|
|
109
109
|
"@floating-ui/dom": "^1.7.6",
|
|
110
|
-
"@jvs-milkdown/kit": "^1.2.
|
|
111
|
-
"@jvs-milkdown/prose": "^1.2.
|
|
112
|
-
"@jvs-milkdown/utils": "^1.2.
|
|
110
|
+
"@jvs-milkdown/kit": "^1.2.21",
|
|
111
|
+
"@jvs-milkdown/prose": "^1.2.21",
|
|
112
|
+
"@jvs-milkdown/utils": "^1.2.21",
|
|
113
113
|
"@types/lodash-es": "^4.17.12",
|
|
114
114
|
"clsx": "^2.0.0",
|
|
115
115
|
"codemirror": "^6.0.1",
|
package/src/core/crepe.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { CrepeFeatureConfig } from '../feature'
|
|
|
6
6
|
import { defaultConfig } from '../default-config'
|
|
7
7
|
import { CrepeFeature, defaultFeatures } from '../feature'
|
|
8
8
|
import { loadFeature } from '../feature/loader'
|
|
9
|
+
import { resetPopupCount } from '../utils/fixed-toolbar-popup-state'
|
|
9
10
|
import { CrepeBuilder, type CrepeBuilderConfig } from './builder'
|
|
10
11
|
|
|
11
12
|
/// The crepe editor configuration.
|
|
@@ -26,6 +27,7 @@ export class Crepe extends CrepeBuilder {
|
|
|
26
27
|
/// You can pass configs to the editor to configure the editor.
|
|
27
28
|
/// Calling the constructor will not create the editor, you need to call `create` to create the editor.
|
|
28
29
|
constructor(config: CrepeConfig = {}) {
|
|
30
|
+
resetPopupCount()
|
|
29
31
|
const { features = {}, featureConfigs = {}, ...crepeBuilderConfig } = config
|
|
30
32
|
const finalConfigs = defaultsDeep(featureConfigs, defaultConfig)
|
|
31
33
|
const fixedToolbarConfig = finalConfigs[CrepeFeature.FixedToolbar]
|
|
@@ -67,31 +69,60 @@ export class Crepe extends CrepeBuilder {
|
|
|
67
69
|
this.on((listener) => {
|
|
68
70
|
listener.markdownUpdated((_, markdown) => {
|
|
69
71
|
try {
|
|
70
|
-
const stored = localStorage.getItem('jvs-milkdown-data')
|
|
71
|
-
let parsed: any = {}
|
|
72
|
-
if (stored) {
|
|
73
|
-
parsed = JSON.parse(stored)
|
|
74
|
-
}
|
|
75
|
-
if (!parsed.content) {
|
|
76
|
-
parsed.content = {}
|
|
77
|
-
}
|
|
78
72
|
const html = this.editor.action(getHTML())
|
|
79
73
|
const docId = fixedToolbarConfig.id || 'default'
|
|
80
74
|
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
75
|
+
const saveToLocalStorage = (mdVal: string, htmlVal: string) => {
|
|
76
|
+
try {
|
|
77
|
+
const stored = localStorage.getItem('jvs-milkdown-data')
|
|
78
|
+
let parsed: any = {}
|
|
79
|
+
if (stored) {
|
|
80
|
+
parsed = JSON.parse(stored)
|
|
81
|
+
}
|
|
82
|
+
if (!parsed.content) {
|
|
83
|
+
parsed.content = {}
|
|
84
|
+
}
|
|
85
|
+
const currentEntry = parsed.content[docId]
|
|
86
|
+
const hasChanged =
|
|
87
|
+
!currentEntry ||
|
|
88
|
+
(typeof currentEntry === 'string' &&
|
|
89
|
+
currentEntry !== mdVal) ||
|
|
90
|
+
(typeof currentEntry === 'object' &&
|
|
91
|
+
(currentEntry.markdown !== mdVal ||
|
|
92
|
+
currentEntry.html !== htmlVal))
|
|
93
|
+
|
|
94
|
+
if (hasChanged) {
|
|
95
|
+
parsed.content[docId] = {
|
|
96
|
+
markdown: mdVal,
|
|
97
|
+
html: htmlVal,
|
|
98
|
+
}
|
|
99
|
+
localStorage.setItem(
|
|
100
|
+
'jvs-milkdown-data',
|
|
101
|
+
JSON.stringify(parsed)
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
} catch (e) {
|
|
105
|
+
console.error('Error saving content to localStorage:', e)
|
|
93
106
|
}
|
|
94
|
-
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const hasBlobUrl =
|
|
110
|
+
/blob:https?:\/\//.test(markdown) || /blob:https?:\/\//.test(html)
|
|
111
|
+
|
|
112
|
+
if (hasBlobUrl) {
|
|
113
|
+
Promise.all([
|
|
114
|
+
replaceBlobUrlsWithBase64(markdown),
|
|
115
|
+
replaceBlobUrlsWithBase64(html),
|
|
116
|
+
])
|
|
117
|
+
.then(([base64Markdown, base64Html]) => {
|
|
118
|
+
saveToLocalStorage(base64Markdown, base64Html)
|
|
119
|
+
})
|
|
120
|
+
.catch((e) => {
|
|
121
|
+
console.error('Error converting blob URLs:', e)
|
|
122
|
+
saveToLocalStorage(markdown, html)
|
|
123
|
+
})
|
|
124
|
+
} else {
|
|
125
|
+
saveToLocalStorage(markdown, html)
|
|
95
126
|
}
|
|
96
127
|
} catch (e) {
|
|
97
128
|
console.error('Error saving content to localStorage:', e)
|
|
@@ -100,4 +131,35 @@ export class Crepe extends CrepeBuilder {
|
|
|
100
131
|
})
|
|
101
132
|
}
|
|
102
133
|
}
|
|
134
|
+
|
|
135
|
+
override destroy = () => {
|
|
136
|
+
resetPopupCount()
|
|
137
|
+
return this.editor.destroy()
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async function replaceBlobUrlsWithBase64(content: string): Promise<string> {
|
|
142
|
+
const blobRegex = /blob:https?:\/\/[^\s'")>]+/g
|
|
143
|
+
const matches = content.match(blobRegex)
|
|
144
|
+
if (!matches) return content
|
|
145
|
+
|
|
146
|
+
let result = content
|
|
147
|
+
const uniqueBlobs = Array.from(new Set(matches))
|
|
148
|
+
|
|
149
|
+
for (const blobUrl of uniqueBlobs) {
|
|
150
|
+
try {
|
|
151
|
+
const response = await fetch(blobUrl)
|
|
152
|
+
const blob = await response.blob()
|
|
153
|
+
const base64 = await new Promise<string>((resolve, reject) => {
|
|
154
|
+
const reader = new FileReader()
|
|
155
|
+
reader.onloadend = () => resolve(reader.result as string)
|
|
156
|
+
reader.onerror = reject
|
|
157
|
+
reader.readAsDataURL(blob)
|
|
158
|
+
})
|
|
159
|
+
result = result.replaceAll(blobUrl, base64)
|
|
160
|
+
} catch (e) {
|
|
161
|
+
console.error('Failed to convert blob URL to base64:', blobUrl, e)
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return result
|
|
103
165
|
}
|
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
import type { Ctx } from '@jvs-milkdown/kit/ctx'
|
|
2
2
|
import type { Selection } from '@jvs-milkdown/kit/prose/state'
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import { commandsCtx, editorViewCtx } from '@jvs-milkdown/kit/core'
|
|
6
|
-
import { getMarkdown } from '@jvs-milkdown/kit/utils'
|
|
7
|
-
import { replaceAll } from '@jvs-milkdown/utils'
|
|
4
|
+
import { commandsCtx } from '@jvs-milkdown/kit/core'
|
|
8
5
|
// @ts-ignore
|
|
9
6
|
import {
|
|
10
7
|
defineComponent,
|
|
11
8
|
type ShallowRef,
|
|
12
9
|
type Ref,
|
|
13
10
|
ref,
|
|
14
|
-
h,
|
|
15
11
|
onMounted,
|
|
16
12
|
onUnmounted,
|
|
17
13
|
} from 'vue'
|
|
18
14
|
|
|
19
15
|
import type { FixedToolbarFeatureConfig } from '.'
|
|
20
16
|
|
|
21
|
-
import { i18n } from '../../core/locale'
|
|
22
17
|
import { undoIcon, redoIcon } from '../../icons'
|
|
23
18
|
import { Toolbar } from '../toolbar/component'
|
|
24
19
|
import { MenuBar } from './menu-bar'
|
|
@@ -82,6 +77,8 @@ export const FixedToolbarComponent = defineComponent<FixedToolbarProps>({
|
|
|
82
77
|
justifyContent: 'center',
|
|
83
78
|
width: '100%',
|
|
84
79
|
gap: '0px',
|
|
80
|
+
minWidth: '0',
|
|
81
|
+
overflow: 'hidden',
|
|
85
82
|
}}
|
|
86
83
|
>
|
|
87
84
|
{props.config?.showMenuBar !== false && [
|
|
@@ -3,7 +3,7 @@ import type { PluginView, Selection } from '@jvs-milkdown/kit/prose/state'
|
|
|
3
3
|
import type { EditorView } from '@jvs-milkdown/kit/prose/view'
|
|
4
4
|
|
|
5
5
|
import { Plugin, PluginKey, TextSelection } from '@jvs-milkdown/kit/prose/state'
|
|
6
|
-
import { $ctx, $prose
|
|
6
|
+
import { $ctx, $prose } from '@jvs-milkdown/kit/utils'
|
|
7
7
|
import { undo, redo } from '@jvs-milkdown/prose/history'
|
|
8
8
|
// @ts-ignore
|
|
9
9
|
import {
|
|
@@ -549,7 +549,11 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
549
549
|
|
|
550
550
|
if (!isFixed) {
|
|
551
551
|
const view = ctx.get(editorViewCtx)
|
|
552
|
-
|
|
552
|
+
const containerDOM =
|
|
553
|
+
view.dom.closest('.milkdown-editor-container') ||
|
|
554
|
+
view.dom.closest('.milkdown') ||
|
|
555
|
+
view.dom
|
|
556
|
+
container.style.maxWidth = `${containerDOM.clientWidth - 32}px`
|
|
553
557
|
}
|
|
554
558
|
|
|
555
559
|
// For fixed toolbar: use available space in parent (minus MenuBar & separator)
|
|
@@ -573,18 +577,17 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
573
577
|
}
|
|
574
578
|
} else {
|
|
575
579
|
const view = ctx.get(editorViewCtx)
|
|
576
|
-
|
|
580
|
+
const containerDOM =
|
|
581
|
+
view.dom.closest('.milkdown-editor-container') ||
|
|
582
|
+
view.dom.closest('.milkdown') ||
|
|
583
|
+
view.dom
|
|
584
|
+
containerWidth = containerDOM.clientWidth - 32
|
|
577
585
|
}
|
|
578
586
|
|
|
579
|
-
if (containerWidth === lastContainerWidth) {
|
|
580
|
-
return
|
|
581
|
-
}
|
|
582
|
-
lastContainerWidth = containerWidth
|
|
583
|
-
|
|
584
587
|
if (showOverflowMenu.value) {
|
|
585
588
|
showOverflowMenu.value = false
|
|
586
589
|
}
|
|
587
|
-
const MORE_BUTTON_WIDTH =
|
|
590
|
+
const MORE_BUTTON_WIDTH = 56
|
|
588
591
|
const children = Array.from(container.children) as HTMLElement[]
|
|
589
592
|
const toolbarChildren = children.filter(
|
|
590
593
|
(el): el is HTMLElement =>
|
|
@@ -598,6 +601,15 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
598
601
|
totalWidth += measureChild(child, i)
|
|
599
602
|
}
|
|
600
603
|
|
|
604
|
+
if (totalWidth === 0) {
|
|
605
|
+
return
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
if (containerWidth === lastContainerWidth) {
|
|
609
|
+
return
|
|
610
|
+
}
|
|
611
|
+
lastContainerWidth = containerWidth
|
|
612
|
+
|
|
601
613
|
if (totalWidth <= containerWidth) {
|
|
602
614
|
overflowVisibleCount.value = Infinity
|
|
603
615
|
totalSectionCount.value = toolbarChildren.length
|
|
@@ -808,6 +820,16 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
808
820
|
} else {
|
|
809
821
|
const view = ctx.get(editorViewCtx)
|
|
810
822
|
overflowResizeObserver.observe(view.dom)
|
|
823
|
+
|
|
824
|
+
const containerDOM = view.dom.closest('.milkdown-editor-container')
|
|
825
|
+
if (containerDOM) {
|
|
826
|
+
overflowResizeObserver.observe(containerDOM)
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
const rootDOM = view.dom.closest('.milkdown')
|
|
830
|
+
if (rootDOM) {
|
|
831
|
+
overflowResizeObserver.observe(rootDOM)
|
|
832
|
+
}
|
|
811
833
|
}
|
|
812
834
|
computeOverflow()
|
|
813
835
|
}
|
|
@@ -849,6 +871,18 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
849
871
|
setTimeout(computeOverflow, 0)
|
|
850
872
|
})
|
|
851
873
|
|
|
874
|
+
watch(
|
|
875
|
+
() => props.show?.value,
|
|
876
|
+
(val) => {
|
|
877
|
+
if (val) {
|
|
878
|
+
cachedWidths.clear()
|
|
879
|
+
overflowVisibleCount.value = Infinity
|
|
880
|
+
lastContainerWidth = 0
|
|
881
|
+
setTimeout(computeOverflow, 0)
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
)
|
|
885
|
+
|
|
852
886
|
const onClick = (fn: (ctx: Ctx) => void) => (e: MouseEvent) => {
|
|
853
887
|
e.preventDefault()
|
|
854
888
|
if (ctx) fn(ctx)
|
|
@@ -1398,7 +1432,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
1398
1432
|
<div
|
|
1399
1433
|
style={{
|
|
1400
1434
|
position: 'relative',
|
|
1401
|
-
display: isSectionOverflowed(
|
|
1435
|
+
display: isSectionOverflowed(1) ? 'none' : 'flex',
|
|
1402
1436
|
flexShrink: 0,
|
|
1403
1437
|
}}
|
|
1404
1438
|
>
|
|
@@ -1444,7 +1478,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
1444
1478
|
style={{
|
|
1445
1479
|
margin: '0 4px',
|
|
1446
1480
|
alignSelf: 'center',
|
|
1447
|
-
display: isSectionOverflowed(
|
|
1481
|
+
display: isSectionOverflowed(2) ? 'none' : undefined,
|
|
1448
1482
|
flexShrink: 0,
|
|
1449
1483
|
}}
|
|
1450
1484
|
></div>
|
|
@@ -1456,7 +1490,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
1456
1490
|
onMouseleave={handleFontFamilyLeave}
|
|
1457
1491
|
style={{
|
|
1458
1492
|
position: 'relative',
|
|
1459
|
-
display: isSectionOverflowed(
|
|
1493
|
+
display: isSectionOverflowed(3) ? 'none' : 'flex',
|
|
1460
1494
|
alignItems: 'center',
|
|
1461
1495
|
padding: '0 6px',
|
|
1462
1496
|
minWidth: '50px',
|
|
@@ -1502,7 +1536,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
1502
1536
|
onMouseleave={handleFontSizeLeave}
|
|
1503
1537
|
style={{
|
|
1504
1538
|
position: 'relative',
|
|
1505
|
-
display: isSectionOverflowed(
|
|
1539
|
+
display: isSectionOverflowed(4) ? 'none' : 'flex',
|
|
1506
1540
|
alignItems: 'center',
|
|
1507
1541
|
padding: '0 6px',
|
|
1508
1542
|
minWidth: '40px',
|
|
@@ -1533,7 +1567,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
1533
1567
|
style={{
|
|
1534
1568
|
margin: '0 4px',
|
|
1535
1569
|
alignSelf: 'center',
|
|
1536
|
-
display: isSectionOverflowed(
|
|
1570
|
+
display: isSectionOverflowed(5) ? 'none' : undefined,
|
|
1537
1571
|
flexShrink: 0,
|
|
1538
1572
|
}}
|
|
1539
1573
|
></div>
|
|
@@ -1545,7 +1579,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
1545
1579
|
onMouseleave={handleAlignLeave}
|
|
1546
1580
|
style={{
|
|
1547
1581
|
position: 'relative',
|
|
1548
|
-
display: isSectionOverflowed(
|
|
1582
|
+
display: isSectionOverflowed(6) ? 'none' : 'flex',
|
|
1549
1583
|
alignItems: 'center',
|
|
1550
1584
|
padding: '0 6px',
|
|
1551
1585
|
flexShrink: 0,
|
|
@@ -1575,7 +1609,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
1575
1609
|
onMouseleave={handleColorLeave}
|
|
1576
1610
|
style={{
|
|
1577
1611
|
position: 'relative',
|
|
1578
|
-
display: isSectionOverflowed(
|
|
1612
|
+
display: isSectionOverflowed(7) ? 'none' : 'flex',
|
|
1579
1613
|
alignItems: 'center',
|
|
1580
1614
|
padding: '0 4px',
|
|
1581
1615
|
flexShrink: 0,
|
|
@@ -1608,7 +1642,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
1608
1642
|
|
|
1609
1643
|
{/* Formatting Tools (sections 7+) */}
|
|
1610
1644
|
{(() => {
|
|
1611
|
-
let sectionIdx =
|
|
1645
|
+
let sectionIdx = 8
|
|
1612
1646
|
return nonHeadingGroups.map((group: any, groupIndex: number) => {
|
|
1613
1647
|
const items = group.items.map((item: any) => {
|
|
1614
1648
|
const idx = sectionIdx
|
|
@@ -2607,7 +2641,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
2607
2641
|
)
|
|
2608
2642
|
}
|
|
2609
2643
|
// Section 2: Font Family
|
|
2610
|
-
if (
|
|
2644
|
+
if (3 >= cutoff) {
|
|
2611
2645
|
items.push(
|
|
2612
2646
|
renderIconButton(
|
|
2613
2647
|
textIcon,
|
|
@@ -2621,7 +2655,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
2621
2655
|
)
|
|
2622
2656
|
}
|
|
2623
2657
|
// Section 3: Font Size
|
|
2624
|
-
if (
|
|
2658
|
+
if (4 >= cutoff) {
|
|
2625
2659
|
items.push(
|
|
2626
2660
|
renderIconButton(
|
|
2627
2661
|
textIcon,
|
|
@@ -2635,7 +2669,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
2635
2669
|
)
|
|
2636
2670
|
}
|
|
2637
2671
|
// Section 5: Alignment
|
|
2638
|
-
if (
|
|
2672
|
+
if (6 >= cutoff) {
|
|
2639
2673
|
items.push(
|
|
2640
2674
|
renderIconButton(
|
|
2641
2675
|
currentAlignIndent.value.align === 'center'
|
|
@@ -2653,7 +2687,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
2653
2687
|
)
|
|
2654
2688
|
}
|
|
2655
2689
|
// Section 6: Color
|
|
2656
|
-
if (
|
|
2690
|
+
if (7 >= cutoff) {
|
|
2657
2691
|
items.push(
|
|
2658
2692
|
renderIconButton(
|
|
2659
2693
|
fontColorIcon,
|
|
@@ -2667,7 +2701,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
2667
2701
|
)
|
|
2668
2702
|
}
|
|
2669
2703
|
// Formatting buttons (section 7+)
|
|
2670
|
-
let fmtIdx =
|
|
2704
|
+
let fmtIdx = 8
|
|
2671
2705
|
for (const group of nonHeadingGroups) {
|
|
2672
2706
|
for (const item of group.items) {
|
|
2673
2707
|
const idx = fmtIdx
|