@milkdown/crepe 7.14.0 → 7.15.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 (52) hide show
  1. package/lib/cjs/builder.js +5 -1
  2. package/lib/cjs/builder.js.map +1 -1
  3. package/lib/cjs/feature/block-edit/index.js.map +1 -1
  4. package/lib/cjs/feature/code-mirror/index.js +18 -0
  5. package/lib/cjs/feature/code-mirror/index.js.map +1 -1
  6. package/lib/cjs/feature/cursor/index.js.map +1 -1
  7. package/lib/cjs/feature/image-block/index.js.map +1 -1
  8. package/lib/cjs/feature/latex/index.js.map +1 -1
  9. package/lib/cjs/feature/link-tooltip/index.js.map +1 -1
  10. package/lib/cjs/feature/list-item/index.js.map +1 -1
  11. package/lib/cjs/feature/placeholder/index.js +5 -0
  12. package/lib/cjs/feature/placeholder/index.js.map +1 -1
  13. package/lib/cjs/feature/table/index.js.map +1 -1
  14. package/lib/cjs/feature/toolbar/index.js.map +1 -1
  15. package/lib/cjs/index.js +12 -2
  16. package/lib/cjs/index.js.map +1 -1
  17. package/lib/esm/builder.js +5 -1
  18. package/lib/esm/builder.js.map +1 -1
  19. package/lib/esm/feature/block-edit/index.js.map +1 -1
  20. package/lib/esm/feature/code-mirror/index.js +18 -0
  21. package/lib/esm/feature/code-mirror/index.js.map +1 -1
  22. package/lib/esm/feature/cursor/index.js.map +1 -1
  23. package/lib/esm/feature/image-block/index.js.map +1 -1
  24. package/lib/esm/feature/latex/index.js.map +1 -1
  25. package/lib/esm/feature/link-tooltip/index.js.map +1 -1
  26. package/lib/esm/feature/list-item/index.js.map +1 -1
  27. package/lib/esm/feature/placeholder/index.js +5 -0
  28. package/lib/esm/feature/placeholder/index.js.map +1 -1
  29. package/lib/esm/feature/table/index.js.map +1 -1
  30. package/lib/esm/feature/toolbar/index.js.map +1 -1
  31. package/lib/esm/index.js +12 -2
  32. package/lib/esm/index.js.map +1 -1
  33. package/lib/theme/common/code-mirror.css +35 -20
  34. package/lib/tsconfig.tsbuildinfo +1 -1
  35. package/lib/types/core/builder.d.ts +2 -1
  36. package/lib/types/core/builder.d.ts.map +1 -1
  37. package/lib/types/core/crepe.d.ts +1 -1
  38. package/lib/types/core/crepe.d.ts.map +1 -1
  39. package/lib/types/feature/code-mirror/index.d.ts +3 -0
  40. package/lib/types/feature/code-mirror/index.d.ts.map +1 -1
  41. package/lib/types/feature/latex/block-latex.d.ts +1 -1
  42. package/lib/types/feature/latex/block-latex.d.ts.map +1 -1
  43. package/lib/types/feature/placeholder/index.d.ts.map +1 -1
  44. package/lib/types/feature/placeholder/placeholder.spec.d.ts +2 -0
  45. package/lib/types/feature/placeholder/placeholder.spec.d.ts.map +1 -0
  46. package/package.json +2 -2
  47. package/src/core/builder.ts +6 -1
  48. package/src/core/crepe.ts +1 -1
  49. package/src/feature/code-mirror/index.ts +7 -0
  50. package/src/feature/placeholder/index.ts +4 -1
  51. package/src/feature/placeholder/placeholder.spec.ts +34 -0
  52. package/src/theme/common/code-mirror.css +35 -20
@@ -8,7 +8,7 @@ export interface CrepeBuilderConfig {
8
8
  }
9
9
  export declare class CrepeBuilder {
10
10
  #private;
11
- constructor({ root, defaultValue }: CrepeBuilderConfig);
11
+ constructor({ root, defaultValue }?: CrepeBuilderConfig);
12
12
  addFeature: {
13
13
  <T extends CrepeFeature>(feature: DefineFeature<CrepeFeatureConfig[T]>, config?: CrepeFeatureConfig[T]): CrepeBuilder;
14
14
  <C>(feature: DefineFeature<C>, config?: C): CrepeBuilder;
@@ -16,6 +16,7 @@ export declare class CrepeBuilder {
16
16
  create: () => Promise<Editor>;
17
17
  destroy: () => Promise<Editor>;
18
18
  get editor(): Editor;
19
+ get readonly(): boolean;
19
20
  setReadonly: (value: boolean) => this;
20
21
  getMarkdown: () => string;
21
22
  on: (fn: (api: ListenerManager) => void) => this;
@@ -1 +1 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../src/core/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EAEjB,MAAM,EAKP,MAAM,oBAAoB,CAAA;AAI3B,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,+BAA+B,CAAA;AAMtC,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAKtD,MAAM,WAAW,kBAAkB;IAIjC,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAA;IAG3B,YAAY,CAAC,EAAE,YAAY,CAAA;CAC5B;AAID,qBAAa,YAAY;;gBAYX,EAAE,IAAI,EAAE,YAAiB,EAAE,EAAE,kBAAkB;IA8B3D,UAAU,EAAE;QACV,CAAC,CAAC,SAAS,YAAY,EACrB,OAAO,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAC7C,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC7B,YAAY,CAAA;QACf,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,YAAY,CAAA;KACzD,CAGA;IAGD,MAAM,wBAEL;IAGD,OAAO,wBAEN;IAGD,IAAI,MAAM,IAAI,MAAM,CAEnB;IAGD,WAAW,GAAI,OAAO,OAAO,UAW5B;IAGD,WAAW,eAEV;IAGD,EAAE,GAAI,IAAI,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,UAavC;CACF"}
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../src/core/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EAEjB,MAAM,EAKP,MAAM,oBAAoB,CAAA;AAI3B,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,+BAA+B,CAAA;AAMtC,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAKtD,MAAM,WAAW,kBAAkB;IAIjC,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAA;IAG3B,YAAY,CAAC,EAAE,YAAY,CAAA;CAC5B;AAID,qBAAa,YAAY;;gBAYX,EAAE,IAAI,EAAE,YAAiB,EAAE,GAAE,kBAAuB;IA8BhE,UAAU,EAAE;QACV,CAAC,CAAC,SAAS,YAAY,EACrB,OAAO,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAC7C,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC7B,YAAY,CAAA;QACf,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,YAAY,CAAA;KACzD,CAGA;IAGD,MAAM,wBAEL;IAGD,OAAO,wBAEN;IAGD,IAAI,MAAM,IAAI,MAAM,CAEnB;IAGD,IAAI,QAAQ,YAEX;IAGD,WAAW,GAAI,OAAO,OAAO,UAW5B;IAGD,WAAW,eAEV;IAGD,EAAE,GAAI,IAAI,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,UAavC;CACF"}
@@ -7,6 +7,6 @@ export interface CrepeConfig extends CrepeBuilderConfig {
7
7
  }
8
8
  export declare class Crepe extends CrepeBuilder {
9
9
  static Feature: typeof CrepeFeature;
10
- constructor({ features, featureConfigs, ...crepeBuilderConfig }: CrepeConfig);
10
+ constructor({ features, featureConfigs, ...crepeBuilderConfig }?: CrepeConfig);
11
11
  }
12
12
  //# sourceMappingURL=crepe.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"crepe.d.ts","sourceRoot":"","sources":["../../../src/core/crepe.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAGpD,OAAO,EAAE,YAAY,EAAmB,MAAM,YAAY,CAAA;AAE1D,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,EACV,QAAa,EACb,cAAmB,EACnB,GAAG,kBAAkB,EACtB,EAAE,WAAW;CAmBf"}
1
+ {"version":3,"file":"crepe.d.ts","sourceRoot":"","sources":["../../../src/core/crepe.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAGpD,OAAO,EAAE,YAAY,EAAmB,MAAM,YAAY,CAAA;AAE1D,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,EACV,QAAa,EACb,cAAmB,EACnB,GAAG,kBAAkB,EACtB,GAAE,WAAgB;CAmBpB"}
@@ -9,6 +9,9 @@ interface CodeMirrorConfig {
9
9
  searchIcon: string;
10
10
  clearSearchIcon: string;
11
11
  searchPlaceholder: string;
12
+ copyText: string;
13
+ copyIcon: string;
14
+ onCopy: (text: string) => void;
12
15
  noResultText: string;
13
16
  renderLanguage: (language: string, selected: boolean) => string;
14
17
  renderPreview: (language: string, content: string) => string | HTMLElement | null;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/feature/code-mirror/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAUlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAY9C,UAAU,gBAAgB;IACxB,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,SAAS,EAAE,mBAAmB,EAAE,CAAA;IAChC,KAAK,EAAE,SAAS,CAAA;IAEhB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,eAAe,EAAE,MAAM,CAAA;IAEvB,iBAAiB,EAAE,MAAM,CAAA;IACzB,YAAY,EAAE,MAAM,CAAA;IAEpB,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,MAAM,CAAA;IAE/D,aAAa,EAAE,CACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,KACZ,MAAM,GAAG,WAAW,GAAG,IAAI,CAAA;IAEhC,iBAAiB,EAAE,CAAC,eAAe,EAAE,OAAO,KAAK,MAAM,CAAA;IACvD,iBAAiB,EAAE,CAAC,eAAe,EAAE,OAAO,KAAK,MAAM,CAAA;IACvD,YAAY,EAAE,MAAM,CAAA;CACrB;AACD,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;AAE/D,eAAO,MAAM,UAAU,EAAE,aAAa,CAAC,uBAAuB,CA2C7D,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/feature/code-mirror/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAUlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAa9C,UAAU,gBAAgB;IACxB,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,SAAS,EAAE,mBAAmB,EAAE,CAAA;IAChC,KAAK,EAAE,SAAS,CAAA;IAEhB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,eAAe,EAAE,MAAM,CAAA;IAEvB,iBAAiB,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,YAAY,EAAE,MAAM,CAAA;IAEpB,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,MAAM,CAAA;IAE/D,aAAa,EAAE,CACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,KACZ,MAAM,GAAG,WAAW,GAAG,IAAI,CAAA;IAEhC,iBAAiB,EAAE,CAAC,eAAe,EAAE,OAAO,KAAK,MAAM,CAAA;IACvD,iBAAiB,EAAE,CAAC,eAAe,EAAE,OAAO,KAAK,MAAM,CAAA;IACvD,YAAY,EAAE,MAAM,CAAA;CACrB;AACD,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;AAE/D,eAAO,MAAM,UAAU,EAAE,aAAa,CAAC,uBAAuB,CA8C7D,CAAA"}
@@ -1,2 +1,2 @@
1
- export declare const blockLatexSchema: import("@milkdown/ctx").MilkdownPlugin;
1
+ export declare const blockLatexSchema: import("@milkdown/utils").$NodeSchema<"code_block">;
2
2
  //# sourceMappingURL=block-latex.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"block-latex.d.ts","sourceRoot":"","sources":["../../../../src/feature/latex/block-latex.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB,wCAsB3B,CAAA"}
1
+ {"version":3,"file":"block-latex.d.ts","sourceRoot":"","sources":["../../../../src/feature/latex/block-latex.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB,qDAsB3B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/feature/placeholder/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAgC9C,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,KAAK,GAAG,OAAO,CAAA;CACtB;AAED,MAAM,MAAM,wBAAwB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;AAEjE,eAAO,MAAM,iBAAiB,2EAM7B,CAAA;AAED,eAAO,MAAM,iBAAiB,kCAmB5B,CAAA;AAEF,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,wBAAwB,CAkB/D,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/feature/placeholder/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAgC9C,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,KAAK,GAAG,OAAO,CAAA;CACtB;AAED,MAAM,MAAM,wBAAwB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;AAEjE,eAAO,MAAM,iBAAiB,2EAM7B,CAAA;AAED,eAAO,MAAM,iBAAiB,kCAsB5B,CAAA;AAEF,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,wBAAwB,CAkB/D,CAAA"}
@@ -0,0 +1,2 @@
1
+ import '@testing-library/jest-dom/vitest';
2
+ //# sourceMappingURL=placeholder.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"placeholder.spec.d.ts","sourceRoot":"","sources":["../../../../src/feature/placeholder/placeholder.spec.ts"],"names":[],"mappings":"AAAA,OAAO,kCAAkC,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@milkdown/crepe",
3
3
  "type": "module",
4
- "version": "7.14.0",
4
+ "version": "7.15.1",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -108,7 +108,7 @@
108
108
  "tslib": "^2.8.1",
109
109
  "unist-util-visit": "^5.0.0",
110
110
  "vue": "^3.5.13",
111
- "@milkdown/kit": "7.14.0"
111
+ "@milkdown/kit": "7.15.1"
112
112
  },
113
113
  "scripts": {
114
114
  "build": "pnpm run build:es && pnpm run build:theme && echo",
@@ -50,7 +50,7 @@ export class CrepeBuilder {
50
50
 
51
51
  /// The constructor of the crepe builder.
52
52
  /// You can pass configs to the builder to configure the editor.
53
- constructor({ root, defaultValue = '' }: CrepeBuilderConfig) {
53
+ constructor({ root, defaultValue = '' }: CrepeBuilderConfig = {}) {
54
54
  this.#rootElement =
55
55
  (typeof root === 'string' ? document.querySelector(root) : root) ??
56
56
  document.body
@@ -106,6 +106,11 @@ export class CrepeBuilder {
106
106
  return this.#editor
107
107
  }
108
108
 
109
+ /// Get the readonly state of the editor.
110
+ get readonly() {
111
+ return !this.#editable
112
+ }
113
+
109
114
  /// Set the readonly mode of the editor.
110
115
  setReadonly = (value: boolean) => {
111
116
  this.#editable = !value
package/src/core/crepe.ts CHANGED
@@ -28,7 +28,7 @@ export class Crepe extends CrepeBuilder {
28
28
  features = {},
29
29
  featureConfigs = {},
30
30
  ...crepeBuilderConfig
31
- }: CrepeConfig) {
31
+ }: CrepeConfig = {}) {
32
32
  super(crepeBuilderConfig)
33
33
 
34
34
  const finalConfigs = defaultsDeep(featureConfigs, defaultConfig)
@@ -15,6 +15,7 @@ import { crepeFeatureConfig } from '../../core/slice'
15
15
  import {
16
16
  chevronDownIcon,
17
17
  clearIcon,
18
+ copyIcon,
18
19
  editIcon,
19
20
  searchIcon,
20
21
  visibilityOffIcon,
@@ -31,6 +32,9 @@ interface CodeMirrorConfig {
31
32
  clearSearchIcon: string
32
33
 
33
34
  searchPlaceholder: string
35
+ copyText: string
36
+ copyIcon: string
37
+ onCopy: (text: string) => void
34
38
  noResultText: string
35
39
 
36
40
  renderLanguage: (language: string, selected: boolean) => string
@@ -73,6 +77,9 @@ export const codeMirror: DefineFeature<CodeMirrorFeatureConfig> = (
73
77
  searchIcon: config.searchIcon || searchIcon,
74
78
  clearSearchIcon: config.clearSearchIcon || clearIcon,
75
79
  searchPlaceholder: config.searchPlaceholder || 'Search language',
80
+ copyText: config.copyText || 'Copy',
81
+ copyIcon: config.copyIcon || copyIcon,
82
+ onCopy: config.onCopy || (() => {}),
76
83
  noResultText: config.noResultText || 'No result',
77
84
  renderLanguage: config.renderLanguage || defaultConfig.renderLanguage,
78
85
  renderPreview: config.renderPreview || defaultConfig.renderPreview,
@@ -8,7 +8,7 @@ import { $ctx, $prose } from '@milkdown/kit/utils'
8
8
 
9
9
  import type { DefineFeature } from '../shared'
10
10
 
11
- import { crepeFeatureConfig } from '../../core/slice'
11
+ import { crepeFeatureConfig, useCrepe } from '../../core/slice'
12
12
  import { isInCodeBlock, isInList } from '../../utils'
13
13
  import { CrepeFeature } from '../index'
14
14
 
@@ -58,6 +58,9 @@ export const placeholderPlugin = $prose((ctx) => {
58
58
  key: new PluginKey('CREPE_PLACEHOLDER'),
59
59
  props: {
60
60
  decorations: (state) => {
61
+ const crepe = useCrepe(ctx)
62
+ if (crepe.readonly) return null
63
+
61
64
  const config = ctx.get(placeholderConfig.key)
62
65
  if (config.mode === 'doc' && !isDocEmpty(state.doc)) return null
63
66
 
@@ -0,0 +1,34 @@
1
+ import '@testing-library/jest-dom/vitest'
2
+ import { editorViewCtx } from '@milkdown/kit/core'
3
+ import { test, expect, describe } from 'vitest'
4
+
5
+ import { Crepe } from '../../core'
6
+
7
+ test('show placeholder in empty editor', async () => {
8
+ const crepe = new Crepe()
9
+ await crepe.create()
10
+
11
+ const view = crepe.editor.ctx.get(editorViewCtx)
12
+ expect(view.dom.querySelector('[data-placeholder]')).toBeInTheDocument()
13
+ })
14
+
15
+ describe('hide placeholder in readonly editor', () => {
16
+ test('hide before create', async () => {
17
+ const crepe = new Crepe()
18
+ crepe.setReadonly(true)
19
+ await crepe.create()
20
+
21
+ const view = crepe.editor.ctx.get(editorViewCtx)
22
+ expect(view.dom.querySelector('[data-placeholder]')).not.toBeInTheDocument()
23
+ })
24
+
25
+ test('hide after create', async () => {
26
+ const crepe = new Crepe()
27
+ await crepe.create()
28
+
29
+ crepe.setReadonly(true)
30
+
31
+ const view = crepe.editor.ctx.get(editorViewCtx)
32
+ expect(view.dom.querySelector('[data-placeholder]')).not.toBeInTheDocument()
33
+ })
34
+ })
@@ -100,27 +100,42 @@
100
100
  caret-color: var(--crepe-color-outline);
101
101
  }
102
102
 
103
- .preview-toggle-button {
104
- background: var(--crepe-color-secondary);
105
- color: var(--crepe-color-on-surface-variant);
106
- padding: 4px 10px;
107
- opacity: 0;
108
- cursor: pointer;
109
- border-radius: 100px;
110
- font-size: 12px;
111
- line-height: 16px;
112
- font-weight: 600;
113
- font-family: var(--crepe-font-default);
114
- transition: opacity 0.2s ease-in-out;
103
+ .tools-button-group {
115
104
  display: flex;
116
- align-items: center;
117
- justify-content: center;
118
- gap: 4px;
105
+ gap: 2px;
119
106
 
120
- svg {
121
- width: 14px;
122
- height: 14px;
123
- fill: var(--crepe-color-on-surface-variant);
107
+ button {
108
+ background: var(--crepe-color-secondary);
109
+ color: var(--crepe-color-on-surface-variant);
110
+ padding: 4px 10px;
111
+ opacity: 0;
112
+ cursor: pointer;
113
+ border-radius: 4px;
114
+ font-size: 12px;
115
+ line-height: 16px;
116
+ font-weight: 600;
117
+ font-family: var(--crepe-font-default);
118
+ transition: opacity 0.2s ease-in-out;
119
+ display: flex;
120
+ align-items: center;
121
+ justify-content: center;
122
+ gap: 4px;
123
+
124
+ svg {
125
+ width: 14px;
126
+ height: 14px;
127
+ fill: var(--crepe-color-on-surface-variant);
128
+ }
129
+ }
130
+
131
+ button:first-child {
132
+ border-top-left-radius: 100px;
133
+ border-bottom-left-radius: 100px;
134
+ }
135
+
136
+ button:last-child {
137
+ border-top-right-radius: 100px;
138
+ border-bottom-right-radius: 100px;
124
139
  }
125
140
  }
126
141
 
@@ -175,7 +190,7 @@
175
190
  opacity: 1;
176
191
  }
177
192
 
178
- &:hover .preview-toggle-button {
193
+ &:hover .tools-button-group > button {
179
194
  opacity: 1;
180
195
  }
181
196