@jvs-milkdown/crepe 1.2.12 → 1.2.13
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/block-edit/index.js +1 -0
- package/lib/cjs/feature/block-edit/index.js.map +1 -1
- package/lib/cjs/feature/image-block/index.js +1 -1
- package/lib/cjs/feature/image-block/index.js.map +1 -1
- package/lib/cjs/feature/link-tooltip/index.js +1 -0
- package/lib/cjs/feature/link-tooltip/index.js.map +1 -1
- package/lib/cjs/feature/table/index.js +1 -0
- package/lib/cjs/feature/table/index.js.map +1 -1
- package/lib/cjs/feature/toolbar/index.js +123 -9
- package/lib/cjs/feature/toolbar/index.js.map +1 -1
- package/lib/cjs/index.js +164 -15
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/feature/block-edit/index.js +1 -0
- package/lib/esm/feature/block-edit/index.js.map +1 -1
- package/lib/esm/feature/image-block/index.js +1 -1
- package/lib/esm/feature/image-block/index.js.map +1 -1
- package/lib/esm/feature/link-tooltip/index.js +1 -0
- package/lib/esm/feature/link-tooltip/index.js.map +1 -1
- package/lib/esm/feature/table/index.js +1 -0
- package/lib/esm/feature/table/index.js.map +1 -1
- package/lib/esm/feature/toolbar/index.js +123 -9
- package/lib/esm/feature/toolbar/index.js.map +1 -1
- package/lib/esm/index.js +164 -15
- package/lib/esm/index.js.map +1 -1
- package/lib/theme/common/table.css +4 -4
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/feature/fixed-toolbar/document-header.d.ts.map +1 -1
- package/lib/types/feature/fixed-toolbar/index.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/feature/toolbar/index.d.ts.map +1 -1
- package/lib/types/icons/remove.d.ts +1 -1
- package/lib/types/icons/remove.d.ts.map +1 -1
- package/lib/types/utils/fixed-toolbar-popup-state.d.ts +7 -0
- package/lib/types/utils/fixed-toolbar-popup-state.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/feature/fixed-toolbar/index.ts +39 -2
- package/src/feature/fixed-toolbar/menu-bar.tsx +13 -2
- package/src/feature/fixed-toolbar/shortcut-help-modal.tsx +1 -1
- package/src/feature/fixed-toolbar/view-menu-state.ts +1 -1
- package/src/feature/image-block/index.ts +1 -1
- package/src/feature/toolbar/component.tsx +95 -8
- package/src/feature/toolbar/index.ts +33 -0
- package/src/icons/remove.ts +1 -0
- package/src/theme/common/table.css +4 -4
- package/src/utils/fixed-toolbar-popup-state.ts +27 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-header.d.ts","sourceRoot":"","sources":["../../../../src/feature/fixed-toolbar/document-header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"document-header.d.ts","sourceRoot":"","sources":["../../../../src/feature/fixed-toolbar/document-header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAA;AAkBhD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAKjD,eAAO,MAAM,cAAc;;cAEA,MAAM,GAAG;;;;cACN,MAAM,kBAAkB;;;;;cAD3B,MAAM,GAAG;;;;cACN,MAAM,kBAAkB;;;+GAoTpD,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/feature/fixed-toolbar/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAU,SAAS,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/feature/fixed-toolbar/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAU,SAAS,EAAiB,MAAM,+BAA+B,CAAA;AAchF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAUpD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;IAC3D,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IAClC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAC/C,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;CAC9B;AAED,MAAM,MAAM,yBAAyB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;AAEnE,eAAO,MAAM,kBAAkB,0FAG9B,CAAA;AAED,eAAO,MAAM,eAAe,gBAA0C,CAAA;AA8PtE,eAAO,MAAM,kBAAkB,sCAK7B,CAAA;AAEF,eAAO,MAAM,YAAY,EAAE,aAAa,CAAC,yBAAyB,CA2BjE,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;AAMhD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,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;AAMhD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAsDjD,eAAO,MAAM,OAAO;;cAEO,MAAM,GAAG;;;;cACN,MAAM,kBAAkB;;;;;cAD3B,MAAM,GAAG;;;;cACN,MAAM,kBAAkB;;;+GA2fpD,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;AAehD,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;
|
|
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;AAehD,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,0WAw9ElB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/feature/toolbar/index.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/feature/toolbar/index.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAa3C,UAAU,aAAa;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,iBAAiB,EAAE,MAAM,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;CAC3D;AAED,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;AAqIzD,eAAO,MAAM,OAAO,EAAE,aAAa,CAAC,oBAAoB,CA+BvD,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const removeIcon = "\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n >\n <path\n d=\"M7.30775 20.4997C6.81058 20.4997 6.385 20.3227 6.031 19.9687C5.677 19.6147 5.5 19.1892 5.5 18.692V5.99973H5.25C5.0375 5.99973 4.85942 5.92782 4.71575 5.78398C4.57192 5.64015 4.5 5.46198 4.5 5.24948C4.5 5.03682 4.57192 4.85873 4.71575 4.71523C4.85942 4.57157 5.0375 4.49973 5.25 4.49973H9C9 4.2549 9.08625 4.04624 9.25875 3.87374C9.43108 3.7014 9.63967 3.61523 9.8845 3.61523H14.1155C14.3603 3.61523 14.5689 3.7014 14.7413 3.87374C14.9138 4.04624 15 4.2549 15 4.49973H18.75C18.9625 4.49973 19.1406 4.57165 19.2843 4.71548C19.4281 4.85932 19.5 5.03748 19.5 5.24998C19.5 5.46265 19.4281 5.64073 19.2843 5.78423C19.1406 5.9279 18.9625 5.99973 18.75 5.99973H18.5V18.692C18.5 19.1892 18.323 19.6147 17.969 19.9687C17.615 20.3227 17.1894 20.4997 16.6923 20.4997H7.30775ZM17 5.99973H7V18.692C7 18.7818 7.02883 18.8556 7.0865 18.9132C7.14417 18.9709 7.21792 18.9997 7.30775 18.9997H16.6923C16.7821 18.9997 16.8558 18.9709 16.9135 18.9132C16.9712 18.8556 17 18.7818 17 18.692V5.99973ZM10.1543 16.9997C10.3668 16.9997 10.5448 16.9279 10.6885 16.7842C10.832 16.6404 10.9037 16.4622 10.9037 16.2497V8.74973C10.9037 8.53723 10.8318 8.35907 10.688 8.21523C10.5443 8.07157 10.3662 7.99973 10.1535 7.99973C9.941 7.99973 9.76292 8.07157 9.61925 8.21523C9.47575 8.35907 9.404 8.53723 9.404 8.74973V16.2497C9.404 16.4622 9.47583 16.6404 9.6195 16.7842C9.76333 16.9279 9.94158 16.9997 10.1543 16.9997ZM13.8465 16.9997C14.059 16.9997 14.2371 16.9279 14.3807 16.7842C14.5243 16.6404 14.596 16.4622 14.596 16.2497V8.74973C14.596 8.53723 14.5242 8.35907 14.3805 8.21523C14.2367 8.07157 14.0584 7.99973 13.8458 7.99973C13.6333 7.99973 13.4552 8.07157 13.3115 8.21523C13.168 8.35907 13.0962 8.53723 13.0962 8.74973V16.2497C13.0962 16.4622 13.1682 16.6404 13.312 16.7842C13.4557 16.9279 13.6338 16.9997 13.8465 16.9997Z\"\n />\n </svg>\n";
|
|
1
|
+
export declare const removeIcon = "\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n >\n <path\n d=\"M7.30775 20.4997C6.81058 20.4997 6.385 20.3227 6.031 19.9687C5.677 19.6147 5.5 19.1892 5.5 18.692V5.99973H5.25C5.0375 5.99973 4.85942 5.92782 4.71575 5.78398C4.57192 5.64015 4.5 5.46198 4.5 5.24948C4.5 5.03682 4.57192 4.85873 4.71575 4.71523C4.85942 4.57157 5.0375 4.49973 5.25 4.49973H9C9 4.2549 9.08625 4.04624 9.25875 3.87374C9.43108 3.7014 9.63967 3.61523 9.8845 3.61523H14.1155C14.3603 3.61523 14.5689 3.7014 14.7413 3.87374C14.9138 4.04624 15 4.2549 15 4.49973H18.75C18.9625 4.49973 19.1406 4.57165 19.2843 4.71548C19.4281 4.85932 19.5 5.03748 19.5 5.24998C19.5 5.46265 19.4281 5.64073 19.2843 5.78423C19.1406 5.9279 18.9625 5.99973 18.75 5.99973H18.5V18.692C18.5 19.1892 18.323 19.6147 17.969 19.9687C17.615 20.3227 17.1894 20.4997 16.6923 20.4997H7.30775ZM17 5.99973H7V18.692C7 18.7818 7.02883 18.8556 7.0865 18.9132C7.14417 18.9709 7.21792 18.9997 7.30775 18.9997H16.6923C16.7821 18.9997 16.8558 18.9709 16.9135 18.9132C16.9712 18.8556 17 18.7818 17 18.692V5.99973ZM10.1543 16.9997C10.3668 16.9997 10.5448 16.9279 10.6885 16.7842C10.832 16.6404 10.9037 16.4622 10.9037 16.2497V8.74973C10.9037 8.53723 10.8318 8.35907 10.688 8.21523C10.5443 8.07157 10.3662 7.99973 10.1535 7.99973C9.941 7.99973 9.76292 8.07157 9.61925 8.21523C9.47575 8.35907 9.404 8.53723 9.404 8.74973V16.2497C9.404 16.4622 9.47583 16.6404 9.6195 16.7842C9.76333 16.9279 9.94158 16.9997 10.1543 16.9997ZM13.8465 16.9997C14.059 16.9997 14.2371 16.9279 14.3807 16.7842C14.5243 16.6404 14.596 16.4622 14.596 16.2497V8.74973C14.596 8.53723 14.5242 8.35907 14.3805 8.21523C14.2367 8.07157 14.0584 7.99973 13.8458 7.99973C13.6333 7.99973 13.4552 8.07157 13.3115 8.21523C13.168 8.35907 13.0962 8.53723 13.0962 8.74973V16.2497C13.0962 16.4622 13.1682 16.6404 13.312 16.7842C13.4557 16.9279 13.6338 16.9997 13.8465 16.9997Z\"\n fill=\"#363B4C\"\n />\n </svg>\n";
|
|
2
2
|
//# sourceMappingURL=remove.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../../src/icons/remove.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../../src/icons/remove.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,g8DAYtB,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type Listener = () => void;
|
|
2
|
+
export declare function getIsAnyPopupOpen(): boolean;
|
|
3
|
+
export declare function addPopupChangeListener(fn: Listener): () => void;
|
|
4
|
+
export declare function incrementPopupCount(): void;
|
|
5
|
+
export declare function decrementPopupCount(): void;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=fixed-toolbar-popup-state.d.ts.map
|
|
@@ -0,0 +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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jvs-milkdown/crepe",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.13",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"crepe",
|
|
6
6
|
"editor",
|
|
@@ -97,9 +97,9 @@
|
|
|
97
97
|
"@codemirror/theme-one-dark": "^6.1.2",
|
|
98
98
|
"@codemirror/view": "^6.26.0",
|
|
99
99
|
"@floating-ui/dom": "^1.7.6",
|
|
100
|
-
"@jvs-milkdown/kit": "^1.2.
|
|
101
|
-
"@jvs-milkdown/prose": "^1.2.
|
|
102
|
-
"@jvs-milkdown/utils": "^1.2.
|
|
100
|
+
"@jvs-milkdown/kit": "^1.2.13",
|
|
101
|
+
"@jvs-milkdown/prose": "^1.2.13",
|
|
102
|
+
"@jvs-milkdown/utils": "^1.2.13",
|
|
103
103
|
"@types/lodash-es": "^4.17.12",
|
|
104
104
|
"clsx": "^2.0.0",
|
|
105
105
|
"codemirror": "^6.0.1",
|
|
@@ -2,7 +2,7 @@ import type { Ctx } from '@jvs-milkdown/kit/ctx'
|
|
|
2
2
|
import type { PluginView, Selection } from '@jvs-milkdown/kit/prose/state'
|
|
3
3
|
import type { EditorView } from '@jvs-milkdown/kit/prose/view'
|
|
4
4
|
|
|
5
|
-
import { Plugin, PluginKey } from '@jvs-milkdown/kit/prose/state'
|
|
5
|
+
import { Plugin, PluginKey, TextSelection } from '@jvs-milkdown/kit/prose/state'
|
|
6
6
|
import { $ctx, $prose } from '@jvs-milkdown/kit/utils'
|
|
7
7
|
// @ts-ignore
|
|
8
8
|
import {
|
|
@@ -66,6 +66,7 @@ class FixedToolbarView implements PluginView {
|
|
|
66
66
|
#resizeObserver?: ResizeObserver
|
|
67
67
|
#updateOutlineGeometry?: () => void
|
|
68
68
|
#scrollContainers: Element[] = []
|
|
69
|
+
#onDblClick: ((event: MouseEvent) => void) | undefined
|
|
69
70
|
#view: EditorView
|
|
70
71
|
|
|
71
72
|
constructor(ctx: Ctx, view: EditorView) {
|
|
@@ -109,6 +110,39 @@ class FixedToolbarView implements PluginView {
|
|
|
109
110
|
this.#outlineContent = outlineContent
|
|
110
111
|
root.appendChild(outlineContent)
|
|
111
112
|
|
|
113
|
+
// Double-click on bottom padding area: if last block has content, append empty paragraph
|
|
114
|
+
this.#onDblClick = (event: MouseEvent) => {
|
|
115
|
+
const view = this.#view
|
|
116
|
+
if (!view.editable) return
|
|
117
|
+
|
|
118
|
+
const dom = view.dom
|
|
119
|
+
const children = dom.children
|
|
120
|
+
if (children.length === 0) return
|
|
121
|
+
|
|
122
|
+
const lastChild = children[children.length - 1]
|
|
123
|
+
if (!lastChild) return
|
|
124
|
+
const lastRect = lastChild.getBoundingClientRect()
|
|
125
|
+
if (event.clientY <= lastRect.bottom) return
|
|
126
|
+
|
|
127
|
+
const { doc } = view.state
|
|
128
|
+
const lastNode = doc.lastChild
|
|
129
|
+
if (!lastNode) return
|
|
130
|
+
|
|
131
|
+
if (lastNode.type.name === 'paragraph' && lastNode.content.size === 0)
|
|
132
|
+
return
|
|
133
|
+
|
|
134
|
+
const paragraphType = view.state.schema.nodes['paragraph']
|
|
135
|
+
if (!paragraphType) return
|
|
136
|
+
|
|
137
|
+
const pos = doc.content.size
|
|
138
|
+
const tr = view.state.tr.insert(pos, paragraphType.create())
|
|
139
|
+
const sel = TextSelection.create(tr.doc, pos + 1)
|
|
140
|
+
tr.setSelection(sel)
|
|
141
|
+
view.dispatch(tr)
|
|
142
|
+
view.focus()
|
|
143
|
+
}
|
|
144
|
+
view.dom.addEventListener('dblclick', this.#onDblClick)
|
|
145
|
+
|
|
112
146
|
this.#content.style.transition =
|
|
113
147
|
'margin 0.1s ease-out, width 0.1s ease-out'
|
|
114
148
|
|
|
@@ -225,7 +259,7 @@ class FixedToolbarView implements PluginView {
|
|
|
225
259
|
this.#view.dom.style.maxWidth = maxWidth
|
|
226
260
|
this.#view.dom.style.width = isFull ? '100%' : maxWidth
|
|
227
261
|
this.#view.dom.style.margin = isFull ? '0' : '0 auto'
|
|
228
|
-
this.#view.dom.style.padding = `20px ${px}
|
|
262
|
+
this.#view.dom.style.padding = `20px ${px} 36px`
|
|
229
263
|
if (this.#headerContent) {
|
|
230
264
|
// this.#headerContent.style.maxWidth = maxWidth
|
|
231
265
|
// this.#headerContent.style.width = isFull ? '100%' : maxWidth
|
|
@@ -250,6 +284,9 @@ class FixedToolbarView implements PluginView {
|
|
|
250
284
|
|
|
251
285
|
destroy = () => {
|
|
252
286
|
if (this.#watcher) this.#watcher()
|
|
287
|
+
if (this.#onDblClick) {
|
|
288
|
+
this.#view.dom.removeEventListener('dblclick', this.#onDblClick)
|
|
289
|
+
}
|
|
253
290
|
if (this.#resizeObserver) this.#resizeObserver.disconnect()
|
|
254
291
|
window.removeEventListener('resize', this.#updateOutlineGeometry!)
|
|
255
292
|
window.removeEventListener('scroll', this.#updateOutlineGeometry!, {
|
|
@@ -2,12 +2,16 @@ import type { Ctx } from '@jvs-milkdown/kit/ctx'
|
|
|
2
2
|
|
|
3
3
|
import { Icon } from '@jvs-milkdown/kit/component'
|
|
4
4
|
// @ts-ignore
|
|
5
|
-
import { defineComponent, ref, onUnmounted, computed, onMounted, h } from 'vue'
|
|
5
|
+
import { defineComponent, ref, onUnmounted, computed, onMounted, h, watch } from 'vue'
|
|
6
6
|
|
|
7
7
|
import type { FixedToolbarConfig } from './index'
|
|
8
8
|
|
|
9
9
|
import { i18n } from '../../core/locale'
|
|
10
10
|
import { menuIcon } from '../../icons'
|
|
11
|
+
import {
|
|
12
|
+
incrementPopupCount,
|
|
13
|
+
decrementPopupCount,
|
|
14
|
+
} from '../../utils/fixed-toolbar-popup-state'
|
|
11
15
|
import { randomCover } from './cover-defaults'
|
|
12
16
|
import { viewMenuStateCtx, type EditorWidth } from './view-menu-state'
|
|
13
17
|
|
|
@@ -116,12 +120,19 @@ export const MenuBar = defineComponent({
|
|
|
116
120
|
onUnmounted(() => {
|
|
117
121
|
document.removeEventListener('click', closeMenu)
|
|
118
122
|
if (rafId) cancelAnimationFrame(rafId)
|
|
123
|
+
if (showMenu.value) decrementPopupCount()
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
// Notify floating toolbar when the menu popup opens/closes
|
|
127
|
+
watch(showMenu, (val) => {
|
|
128
|
+
if (val) incrementPopupCount()
|
|
129
|
+
else decrementPopupCount()
|
|
119
130
|
})
|
|
120
131
|
|
|
121
132
|
const viewState = computed(() => props.ctx.get(viewMenuStateCtx.key))
|
|
122
133
|
|
|
123
134
|
const bgColors = [
|
|
124
|
-
{ name: '
|
|
135
|
+
{ name: '白色', value: '#FFFFFF' },
|
|
125
136
|
{ name: '浅灰', value: '#F7F7F5' },
|
|
126
137
|
{ name: '浅棕', value: '#F4EEDB' },
|
|
127
138
|
{ name: '浅橙', value: '#FBECDD' },
|
|
@@ -65,7 +65,7 @@ const rightGroups: ShortcutGroup[] = [
|
|
|
65
65
|
titleKey: 'shortcuts.history',
|
|
66
66
|
items: [
|
|
67
67
|
{ labelKey: 'shortcuts.undo', keys: ['Mod+z'] },
|
|
68
|
-
{ labelKey: 'shortcuts.redo', keys: ['Mod+y', 'Shift+Mod+
|
|
68
|
+
{ labelKey: 'shortcuts.redo', keys: ['Mod+y', 'Shift+Mod+Z'] },
|
|
69
69
|
],
|
|
70
70
|
},
|
|
71
71
|
]
|
|
@@ -94,6 +94,10 @@ import {
|
|
|
94
94
|
formatPainterIcon,
|
|
95
95
|
} from '../../icons'
|
|
96
96
|
import { keepAlive } from '../../utils/keep-alive'
|
|
97
|
+
import {
|
|
98
|
+
incrementPopupCount,
|
|
99
|
+
decrementPopupCount,
|
|
100
|
+
} from '../../utils/fixed-toolbar-popup-state'
|
|
97
101
|
import { menuAPI } from '../block-edit/menu'
|
|
98
102
|
import { getGroups as getBlockGroups } from '../block-edit/menu/config'
|
|
99
103
|
import {
|
|
@@ -147,6 +151,8 @@ type ToolbarProps = {
|
|
|
147
151
|
interface FormatPainterState {
|
|
148
152
|
marks: Mark[]
|
|
149
153
|
align?: string | null
|
|
154
|
+
blockType?: string | null
|
|
155
|
+
blockAttrs?: Record<string, any> | null
|
|
150
156
|
isPersistent: boolean
|
|
151
157
|
}
|
|
152
158
|
|
|
@@ -238,6 +244,8 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
238
244
|
const {
|
|
239
245
|
marks: savedMarks,
|
|
240
246
|
align: savedAlign,
|
|
247
|
+
blockType: savedBlockType,
|
|
248
|
+
blockAttrs: savedBlockAttrs,
|
|
241
249
|
isPersistent,
|
|
242
250
|
} = formatPainterState!.value
|
|
243
251
|
|
|
@@ -263,6 +271,30 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
263
271
|
}
|
|
264
272
|
)
|
|
265
273
|
}
|
|
274
|
+
if (savedBlockType) {
|
|
275
|
+
curState.doc.nodesBetween(
|
|
276
|
+
curSelection.from,
|
|
277
|
+
curSelection.to,
|
|
278
|
+
(node: any, pos: number) => {
|
|
279
|
+
if (node.type.name === 'paragraph') {
|
|
280
|
+
tr.setNodeMarkup(
|
|
281
|
+
pos,
|
|
282
|
+
curState.schema.nodes[savedBlockType],
|
|
283
|
+
{
|
|
284
|
+
...savedBlockAttrs,
|
|
285
|
+
...(savedAlign ? { align: savedAlign } : {}),
|
|
286
|
+
}
|
|
287
|
+
)
|
|
288
|
+
} else if (node.type.name === 'heading' && savedBlockAttrs) {
|
|
289
|
+
tr.setNodeMarkup(pos, null, {
|
|
290
|
+
...node.attrs,
|
|
291
|
+
...savedBlockAttrs,
|
|
292
|
+
...(savedAlign ? { align: savedAlign } : {}),
|
|
293
|
+
})
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
}
|
|
266
298
|
dispatch(tr)
|
|
267
299
|
applied = true
|
|
268
300
|
} else {
|
|
@@ -301,6 +333,28 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
301
333
|
})
|
|
302
334
|
}
|
|
303
335
|
}
|
|
336
|
+
|
|
337
|
+
if (savedBlockType) {
|
|
338
|
+
const pos = curSelection.$from.before(curSelection.$from.depth)
|
|
339
|
+
const node = curState.doc.nodeAt(pos)
|
|
340
|
+
if (node && node.type.name === 'paragraph') {
|
|
341
|
+
tr.setNodeMarkup(pos, curState.schema.nodes[savedBlockType], {
|
|
342
|
+
...savedBlockAttrs,
|
|
343
|
+
...(savedAlign ? { align: savedAlign } : {}),
|
|
344
|
+
})
|
|
345
|
+
} else if (
|
|
346
|
+
node &&
|
|
347
|
+
node.type.name === 'heading' &&
|
|
348
|
+
savedBlockAttrs
|
|
349
|
+
) {
|
|
350
|
+
tr.setNodeMarkup(pos, null, {
|
|
351
|
+
...node.attrs,
|
|
352
|
+
...savedBlockAttrs,
|
|
353
|
+
...(savedAlign ? { align: savedAlign } : {}),
|
|
354
|
+
})
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
304
358
|
tr.setStoredMarks(savedMarks)
|
|
305
359
|
dispatch(tr)
|
|
306
360
|
applied = true
|
|
@@ -363,7 +417,24 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
363
417
|
}
|
|
364
418
|
align = foundAlign
|
|
365
419
|
|
|
366
|
-
|
|
420
|
+
// Capture block type (heading level) if selection is within a heading
|
|
421
|
+
let blockType: string | null = null
|
|
422
|
+
let blockAttrs: Record<string, any> | null = null
|
|
423
|
+
{
|
|
424
|
+
const parent = selection.$from.parent
|
|
425
|
+
if (parent.type.name === 'heading') {
|
|
426
|
+
blockType = 'heading'
|
|
427
|
+
blockAttrs = { level: parent.attrs.level }
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
formatPainterState!.value = {
|
|
432
|
+
marks,
|
|
433
|
+
align,
|
|
434
|
+
blockType,
|
|
435
|
+
blockAttrs,
|
|
436
|
+
isPersistent,
|
|
437
|
+
}
|
|
367
438
|
document.removeEventListener('pointerup', formatPainterHandler!)
|
|
368
439
|
|
|
369
440
|
setTimeout(() => {
|
|
@@ -432,6 +503,23 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
432
503
|
}>({ top: 0 })
|
|
433
504
|
const cachedWidths = new Map<number, number>()
|
|
434
505
|
|
|
506
|
+
// Track popup state for fixed toolbar → notify floating toolbar
|
|
507
|
+
const anyFixedPopup = computed(
|
|
508
|
+
() =>
|
|
509
|
+
!!isFixed &&
|
|
510
|
+
(showBlockMenu.value ||
|
|
511
|
+
showAlignMenu.value ||
|
|
512
|
+
showColorMenu.value ||
|
|
513
|
+
showFontFamilyMenu.value ||
|
|
514
|
+
showFontSizeMenu.value ||
|
|
515
|
+
showTableMenu.value ||
|
|
516
|
+
showOverflowMenu.value)
|
|
517
|
+
)
|
|
518
|
+
watch(anyFixedPopup, (val) => {
|
|
519
|
+
if (val) incrementPopupCount()
|
|
520
|
+
else decrementPopupCount()
|
|
521
|
+
})
|
|
522
|
+
|
|
435
523
|
const getMenuLeftPos = (rect: DOMRect, menuWidth: number) => {
|
|
436
524
|
let left = rect.left
|
|
437
525
|
if (left + menuWidth > window.innerWidth) {
|
|
@@ -697,6 +785,7 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
697
785
|
if (hideFontFamilyTimer) clearTimeout(hideFontFamilyTimer)
|
|
698
786
|
if (hideFontSizeTimer) clearTimeout(hideFontSizeTimer)
|
|
699
787
|
if (hideTableTimer) clearTimeout(hideTableTimer)
|
|
788
|
+
if (anyFixedPopup.value) decrementPopupCount()
|
|
700
789
|
})
|
|
701
790
|
|
|
702
791
|
// --- Overflow lifecycle (fixed toolbar only) ---
|
|
@@ -1240,13 +1329,11 @@ export const Toolbar = defineComponent<ToolbarProps>({
|
|
|
1240
1329
|
})
|
|
1241
1330
|
|
|
1242
1331
|
// Ensure proper formatting tools are visible
|
|
1243
|
-
const nonHeadingGroups = toolbarGroupInfo.value.filter(
|
|
1244
|
-
(group
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
}
|
|
1249
|
-
)
|
|
1332
|
+
const nonHeadingGroups = toolbarGroupInfo.value.filter((group: any) => {
|
|
1333
|
+
if ((group as any).key === 'heading') return false
|
|
1334
|
+
if (props.isFixed && (group as any).key === 'function') return false
|
|
1335
|
+
return true
|
|
1336
|
+
})
|
|
1250
1337
|
|
|
1251
1338
|
const isSectionOverflowed = (idx: number) =>
|
|
1252
1339
|
idx >= overflowVisibleCount.value
|
|
@@ -25,6 +25,10 @@ import { colorPlugins } from './color'
|
|
|
25
25
|
import { Toolbar } from './component'
|
|
26
26
|
import { highlightMark } from './highlight-mark'
|
|
27
27
|
import { underline } from './underline'
|
|
28
|
+
import {
|
|
29
|
+
getIsAnyPopupOpen,
|
|
30
|
+
addPopupChangeListener,
|
|
31
|
+
} from '../../utils/fixed-toolbar-popup-state'
|
|
28
32
|
|
|
29
33
|
interface ToolbarConfig {
|
|
30
34
|
boldIcon: string
|
|
@@ -55,6 +59,8 @@ class ToolbarView implements PluginView {
|
|
|
55
59
|
#selection: ShallowRef<Selection>
|
|
56
60
|
#show = ref(false)
|
|
57
61
|
#mousePressed = false
|
|
62
|
+
#removePopupListener: (() => void) | undefined
|
|
63
|
+
#onDocumentMouseUp: ((ev: MouseEvent) => void) | undefined
|
|
58
64
|
|
|
59
65
|
constructor(ctx: Ctx, view: EditorView, config?: ToolbarFeatureConfig) {
|
|
60
66
|
const content = document.createElement('div')
|
|
@@ -83,12 +89,25 @@ class ToolbarView implements PluginView {
|
|
|
83
89
|
}, 0)
|
|
84
90
|
})
|
|
85
91
|
|
|
92
|
+
// Handle mouseup outside the editor view (finish selection outside)
|
|
93
|
+
const onDocumentMouseUp = () => {
|
|
94
|
+
if (this.#mousePressed) {
|
|
95
|
+
this.#mousePressed = false
|
|
96
|
+
setTimeout(() => {
|
|
97
|
+
this.update(view)
|
|
98
|
+
}, 0)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
document.addEventListener('mouseup', onDocumentMouseUp)
|
|
102
|
+
this.#onDocumentMouseUp = onDocumentMouseUp
|
|
103
|
+
|
|
86
104
|
this.#tooltipProvider = new TooltipProvider({
|
|
87
105
|
content: this.#content,
|
|
88
106
|
debounce: 20,
|
|
89
107
|
offset: 10,
|
|
90
108
|
shouldShow: (view: EditorView) => {
|
|
91
109
|
if (this.#mousePressed) return false
|
|
110
|
+
if (getIsAnyPopupOpen()) return false
|
|
92
111
|
|
|
93
112
|
const { doc, selection } = view.state
|
|
94
113
|
const { empty, from, to } = selection
|
|
@@ -127,6 +146,16 @@ class ToolbarView implements PluginView {
|
|
|
127
146
|
this.#tooltipProvider.onHide = () => {
|
|
128
147
|
this.#show.value = false
|
|
129
148
|
}
|
|
149
|
+
|
|
150
|
+
// React to fixed toolbar popup state changes
|
|
151
|
+
this.#removePopupListener = addPopupChangeListener(() => {
|
|
152
|
+
if (getIsAnyPopupOpen()) {
|
|
153
|
+
this.#tooltipProvider.hide()
|
|
154
|
+
} else {
|
|
155
|
+
this.#tooltipProvider.update(view)
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
|
|
130
159
|
this.update(view)
|
|
131
160
|
}
|
|
132
161
|
|
|
@@ -136,6 +165,10 @@ class ToolbarView implements PluginView {
|
|
|
136
165
|
}
|
|
137
166
|
|
|
138
167
|
destroy = () => {
|
|
168
|
+
this.#removePopupListener?.()
|
|
169
|
+
if (this.#onDocumentMouseUp) {
|
|
170
|
+
document.removeEventListener('mouseup', this.#onDocumentMouseUp)
|
|
171
|
+
}
|
|
139
172
|
this.#tooltipProvider.destroy()
|
|
140
173
|
this.#app.unmount()
|
|
141
174
|
this.#content.remove()
|
package/src/icons/remove.ts
CHANGED
|
@@ -7,6 +7,7 @@ export const removeIcon = `
|
|
|
7
7
|
>
|
|
8
8
|
<path
|
|
9
9
|
d="M7.30775 20.4997C6.81058 20.4997 6.385 20.3227 6.031 19.9687C5.677 19.6147 5.5 19.1892 5.5 18.692V5.99973H5.25C5.0375 5.99973 4.85942 5.92782 4.71575 5.78398C4.57192 5.64015 4.5 5.46198 4.5 5.24948C4.5 5.03682 4.57192 4.85873 4.71575 4.71523C4.85942 4.57157 5.0375 4.49973 5.25 4.49973H9C9 4.2549 9.08625 4.04624 9.25875 3.87374C9.43108 3.7014 9.63967 3.61523 9.8845 3.61523H14.1155C14.3603 3.61523 14.5689 3.7014 14.7413 3.87374C14.9138 4.04624 15 4.2549 15 4.49973H18.75C18.9625 4.49973 19.1406 4.57165 19.2843 4.71548C19.4281 4.85932 19.5 5.03748 19.5 5.24998C19.5 5.46265 19.4281 5.64073 19.2843 5.78423C19.1406 5.9279 18.9625 5.99973 18.75 5.99973H18.5V18.692C18.5 19.1892 18.323 19.6147 17.969 19.9687C17.615 20.3227 17.1894 20.4997 16.6923 20.4997H7.30775ZM17 5.99973H7V18.692C7 18.7818 7.02883 18.8556 7.0865 18.9132C7.14417 18.9709 7.21792 18.9997 7.30775 18.9997H16.6923C16.7821 18.9997 16.8558 18.9709 16.9135 18.9132C16.9712 18.8556 17 18.7818 17 18.692V5.99973ZM10.1543 16.9997C10.3668 16.9997 10.5448 16.9279 10.6885 16.7842C10.832 16.6404 10.9037 16.4622 10.9037 16.2497V8.74973C10.9037 8.53723 10.8318 8.35907 10.688 8.21523C10.5443 8.07157 10.3662 7.99973 10.1535 7.99973C9.941 7.99973 9.76292 8.07157 9.61925 8.21523C9.47575 8.35907 9.404 8.53723 9.404 8.74973V16.2497C9.404 16.4622 9.47583 16.6404 9.6195 16.7842C9.76333 16.9279 9.94158 16.9997 10.1543 16.9997ZM13.8465 16.9997C14.059 16.9997 14.2371 16.9279 14.3807 16.7842C14.5243 16.6404 14.596 16.4622 14.596 16.2497V8.74973C14.596 8.53723 14.5242 8.35907 14.3805 8.21523C14.2367 8.07157 14.0584 7.99973 13.8458 7.99973C13.6333 7.99973 13.4552 8.07157 13.3115 8.21523C13.168 8.35907 13.0962 8.53723 13.0962 8.74973V16.2497C13.0962 16.4622 13.1682 16.6404 13.312 16.7842C13.4557 16.9279 13.6338 16.9997 13.8465 16.9997Z"
|
|
10
|
+
fill="#363B4C"
|
|
10
11
|
/>
|
|
11
12
|
</svg>
|
|
12
13
|
`
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
left: 0;
|
|
92
92
|
right: 0;
|
|
93
93
|
height: 8px;
|
|
94
|
-
z-index:
|
|
94
|
+
z-index: 102;
|
|
95
95
|
overflow: visible;
|
|
96
96
|
}
|
|
97
97
|
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
left: -8px;
|
|
102
102
|
bottom: 0;
|
|
103
103
|
width: 8px;
|
|
104
|
-
z-index:
|
|
104
|
+
z-index: 102;
|
|
105
105
|
overflow: visible;
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -290,7 +290,7 @@
|
|
|
290
290
|
background-color: var(--crepe-color-surface);
|
|
291
291
|
border-radius: 8px;
|
|
292
292
|
box-shadow: var(--crepe-shadow-1);
|
|
293
|
-
z-index:
|
|
293
|
+
z-index: 102;
|
|
294
294
|
|
|
295
295
|
&::after {
|
|
296
296
|
content: '';
|
|
@@ -455,7 +455,7 @@
|
|
|
455
455
|
|
|
456
456
|
.cell-toolbar {
|
|
457
457
|
position: absolute;
|
|
458
|
-
z-index:
|
|
458
|
+
z-index: 102;
|
|
459
459
|
display: flex;
|
|
460
460
|
gap: 2px;
|
|
461
461
|
background-color: var(--crepe-color-surface);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
type Listener = () => void
|
|
2
|
+
const listeners = new Set<Listener>()
|
|
3
|
+
let _popupCount = 0
|
|
4
|
+
|
|
5
|
+
export function getIsAnyPopupOpen(): boolean {
|
|
6
|
+
return _popupCount > 0
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function addPopupChangeListener(fn: Listener): () => void {
|
|
10
|
+
listeners.add(fn)
|
|
11
|
+
return () => listeners.delete(fn)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function incrementPopupCount(): void {
|
|
15
|
+
const wasZero = _popupCount === 0
|
|
16
|
+
_popupCount++
|
|
17
|
+
if (wasZero) {
|
|
18
|
+
listeners.forEach((fn) => fn())
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function decrementPopupCount(): void {
|
|
23
|
+
_popupCount = Math.max(0, _popupCount - 1)
|
|
24
|
+
if (_popupCount === 0) {
|
|
25
|
+
listeners.forEach((fn) => fn())
|
|
26
|
+
}
|
|
27
|
+
}
|