@zipify/wysiwyg 4.1.0-0 → 4.1.0-2

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 (32) hide show
  1. package/config/build/settings.js +1 -1
  2. package/config/jest/setupTests.js +3 -0
  3. package/dist/cli.js +2 -3
  4. package/dist/wysiwyg.css +37 -37
  5. package/dist/wysiwyg.mjs +920 -846
  6. package/example/ai-component/AiComponent.vue +16 -50
  7. package/lib/Wysiwyg.vue +9 -17
  8. package/lib/components/base/Modal.vue +19 -18
  9. package/lib/components/base/ModalFloating.vue +32 -0
  10. package/lib/components/base/__tests__/Modal.test.js +2 -19
  11. package/lib/components/base/composables/useModalToggler.js +3 -34
  12. package/lib/components/base/dropdown/Dropdown.vue +7 -6
  13. package/lib/components/base/dropdown/DropdownActivator.vue +4 -5
  14. package/lib/components/base/dropdown/__tests__/DropdownActivator.test.js +1 -1
  15. package/lib/components/base/dropdown/__tests__/DropdownOption.test.js +1 -1
  16. package/lib/components/toolbar/Toolbar.vue +29 -13
  17. package/lib/components/toolbar/ToolbarFloating.vue +42 -0
  18. package/lib/components/toolbar/__tests__/Toolbar.test.js +4 -6
  19. package/lib/components/toolbar/controls/LineHeightControl.vue +9 -7
  20. package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +2 -4
  21. package/lib/components/toolbar/controls/link/LinkControl.vue +13 -14
  22. package/lib/components/toolbar/controls/link/destination/LinkControlDestination.vue +1 -1
  23. package/lib/components/toolbar/controls/link/destination/LinkControlPageBlock.vue +1 -1
  24. package/lib/composables/__tests__/useEditor.test.js +26 -5
  25. package/lib/composables/index.js +0 -1
  26. package/lib/composables/useEditor.js +7 -2
  27. package/lib/styles/content.css +0 -1
  28. package/package.json +50 -51
  29. package/lib/components/base/composables/__tests__/useModalToggler.test.js +0 -59
  30. package/lib/composables/useToolbar.js +0 -36
  31. /package/config/build/{example.config.js → example.config.mjs} +0 -0
  32. /package/config/build/{lib.config.js → lib.config.mjs} +0 -0
@@ -4,7 +4,12 @@
4
4
  <Icon name="link" size="28px" auto-color />
5
5
  </Button>
6
6
 
7
- <Modal class="zw-link-modal" :toggler="toggler" ref="modalRef" focus-first-control>
7
+ <Modal
8
+ class="zw-link-modal"
9
+ :toggler="toggler"
10
+ :reference-ref="wrapperRef"
11
+ focus-first-control
12
+ >
8
13
  <LinkControlHeader @remove-link="removeLink" />
9
14
 
10
15
  <form class="zw-link-modal__body" @submit.prevent="applyLink" data-test-selector="form">
@@ -50,11 +55,9 @@ import LinkControlHeader from './LinkControlHeader';
50
55
  import { useLink } from './composables';
51
56
  import { LinkControlDestination } from './destination';
52
57
 
53
- const wrapperRef = ref(null);
54
- const modalRef = ref(null);
55
-
56
58
  const editor = inject(InjectionTokens.EDITOR);
57
59
 
60
+ const wrapperRef = ref(null);
58
61
  const link = useLink();
59
62
 
60
63
  const isEmpty = () => {
@@ -88,20 +91,16 @@ const resetErrors = () => {
88
91
  urlValidator.reset();
89
92
  };
90
93
 
91
- const onBeforeOpened = () => {
92
- editor.commands.extendMarkRange(TextSettings.LINK);
93
- resetErrors();
94
- link.prepareInitialFields();
95
- };
96
-
97
94
  const toggler = useModalToggler({
98
- onBeforeOpened: () => onBeforeOpened(),
99
- wrapperRef,
100
- modalRef
95
+ onBeforeOpened: () => {
96
+ editor.commands.extendMarkRange(TextSettings.LINK);
97
+ resetErrors();
98
+ link.prepareInitialFields();
99
+ }
101
100
  });
102
101
 
103
102
  const isLink = editor.commands.isLink();
104
- const isActive = computed(() => unref(toggler.isOpened) || unref(isLink));
103
+ const isActive = computed(() => toggler.isOpened || unref(isLink));
105
104
 
106
105
  const updateLinkText = (value) => {
107
106
  resetErrors();
@@ -61,7 +61,7 @@ const emit = defineEmits(['reset-errors']);
61
61
 
62
62
  const destinationTypes = [
63
63
  { id: LinkDestinations.URL, title: 'URL' },
64
- { id: LinkDestinations.BLOCK, title: 'Page Block' }
64
+ { id: LinkDestinations.BLOCK, title: 'Page Section' }
65
65
  ];
66
66
 
67
67
  const link = toRef(props, 'link');
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div>
3
3
  <FieldLabel class="zw-margin-bottom--xxs" field-id="link-destination">
4
- Select block
4
+ Select section
5
5
  </FieldLabel>
6
6
 
7
7
  <Dropdown
@@ -1,4 +1,4 @@
1
- import { h, ref, toRef } from 'vue';
1
+ import { h, toRef } from 'vue';
2
2
  import { EditorContent } from '@tiptap/vue-3';
3
3
  import { shallowMount } from '@vue/test-utils';
4
4
  import { buildTestExtensions } from '../../__tests__/utils';
@@ -14,11 +14,11 @@ const TestComponent = {
14
14
  });
15
15
  },
16
16
 
17
- props: ['value'],
17
+ props: ['value', 'readonly'],
18
18
 
19
19
  setup(props, { emit }) {
20
20
  const { editor } = useEditor({
21
- isReadonlyRef: ref(false),
21
+ isReadonlyRef: toRef(props, 'readonly'),
22
22
  content: toRef(props, 'value'),
23
23
  extensions: buildTestExtensions(),
24
24
  onChange: (content) => emit('input', content),
@@ -33,9 +33,12 @@ const createContent = (text = 'test') => NodeFactory.doc([
33
33
  NodeFactory.paragraph(text)
34
34
  ]);
35
35
 
36
- function createComponent({ content } = {}) {
36
+ function createComponent({ content, isReadonly } = {}) {
37
37
  const wrapper = shallowMount(TestComponent, {
38
- props: { value: content || createContent('test') }
38
+ props: {
39
+ value: content || createContent('test'),
40
+ readonly: isReadonly ?? false
41
+ }
39
42
  });
40
43
 
41
44
  return {
@@ -75,3 +78,21 @@ describe('life cycle', () => {
75
78
  expect(editor.getHTML()).toBe('<p class="zw-style">new</p>');
76
79
  });
77
80
  });
81
+
82
+ describe('readonly', () => {
83
+ test('should change readonly', async () => {
84
+ const { wrapper, editor } = createComponent({ isReadonly: false });
85
+
86
+ await wrapper.setProps({ readonly: true });
87
+
88
+ expect(editor.isEditable).toBe(false);
89
+ });
90
+
91
+ test('should not emit change on readonly update', async () => {
92
+ const { wrapper, editor } = createComponent({ isReadonly: false });
93
+
94
+ await wrapper.setProps({ readonly: true });
95
+
96
+ expect(wrapper.emitted('input')).toBeFalsy();
97
+ });
98
+ });
@@ -1,2 +1 @@
1
1
  export { useEditor } from './useEditor';
2
- export { useToolbar } from './useToolbar';
@@ -13,7 +13,12 @@ export function useEditor({ content, onChange, extensions, isReadonlyRef }) {
13
13
  onUpdate: () => onChange(getContent()),
14
14
  extensions,
15
15
  injectCSS: false,
16
- editable: !unref(isReadonlyRef)
16
+ editable: !unref(isReadonlyRef),
17
+ editorProps: {
18
+ attributes: {
19
+ class: 'zw-wysiwyg__content'
20
+ }
21
+ }
17
22
  }));
18
23
 
19
24
  onUnmounted(() => editor.destroy());
@@ -26,7 +31,7 @@ export function useEditor({ content, onChange, extensions, isReadonlyRef }) {
26
31
  }
27
32
  });
28
33
 
29
- watch(isReadonlyRef, (isReadonly) => editor.setEditable(!isReadonly));
34
+ watch(isReadonlyRef, (isReadonly) => editor.setEditable(!isReadonly, false));
30
35
 
31
36
  return { editor, getContent };
32
37
  }
@@ -60,7 +60,6 @@ h4.zw-style.zw-style.zw-style {
60
60
 
61
61
  /* ProseMirror styles */
62
62
 
63
-
64
63
  .ProseMirror {
65
64
  position: relative;
66
65
  outline: none;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zipify/wysiwyg",
3
- "version": "4.1.0-0",
3
+ "version": "4.1.0-2",
4
4
  "description": "Zipify modification of TipTap text editor",
5
5
  "main": "dist/wysiwyg.mjs",
6
6
  "bin": {
@@ -17,12 +17,12 @@
17
17
  "url": "https://github.com/ZipifyApps/ZipifyWysiwyg/issues"
18
18
  },
19
19
  "scripts": {
20
- "lib:build": "vite build --config config/build/lib.config.js",
21
- "lib:release": "export $(cat ./.env | xargs) && release-it",
20
+ "lib:build": "vite build --config config/build/lib.config.mjs",
21
+ "lib:release": "[ -f .env ] && export $(cat .env | xargs) && release-it",
22
22
  "cli:build": "NODE_ENV=production rollup --config config/build/cli.config.js --bundleConfigAsCjs",
23
23
  "cli:dev": "NODE_ENV=development rollup --config config/build/cli.config.js --bundleConfigAsCjs --watch",
24
- "example:start": "NODE_ENV=development vite serve --config config/build/example.config.js",
25
- "example:build": "NODE_ENV=production vite build --config config/build/example.config.js",
24
+ "example:start": "NODE_ENV=development vite serve --config config/build/example.config.mjs",
25
+ "example:build": "NODE_ENV=production vite build --config config/build/example.config.mjs",
26
26
  "test:unit": "jest .",
27
27
  "lint:js": "eslint ./lib",
28
28
  "lint:css": "stylelint ./lib/**/*.{css,vue}",
@@ -30,25 +30,24 @@
30
30
  "prepare": "husky install"
31
31
  },
32
32
  "dependencies": {
33
- "@floating-ui/dom": "^1.5.3",
34
- "@popperjs/core": "^2.11.7",
35
- "@tiptap/core": "^2.0.0",
36
- "@tiptap/extension-document": "^2.0.0",
37
- "@tiptap/extension-heading": "^2.0.0",
38
- "@tiptap/extension-history": "^2.0.0",
39
- "@tiptap/extension-link": "^2.0.0",
40
- "@tiptap/extension-list-item": "^2.0.0",
41
- "@tiptap/extension-paragraph": "^2.0.0",
42
- "@tiptap/extension-text": "^2.0.0",
43
- "@tiptap/pm": "^2.0.0",
44
- "@tiptap/vue-3": "^2.0.0",
45
- "commander": "^10.0.0",
46
- "jsdom": "^21.1.1",
33
+ "@floating-ui/vue": "^1.0.2",
34
+ "@tiptap/core": "^2.1.13",
35
+ "@tiptap/extension-document": "^2.1.13",
36
+ "@tiptap/extension-heading": "^2.1.13",
37
+ "@tiptap/extension-history": "^2.1.13",
38
+ "@tiptap/extension-link": "^2.1.13",
39
+ "@tiptap/extension-list-item": "^2.1.13",
40
+ "@tiptap/extension-paragraph": "^2.1.13",
41
+ "@tiptap/extension-text": "^2.1.13",
42
+ "@tiptap/pm": "^2.1.13",
43
+ "@tiptap/vue-3": "^2.1.13",
44
+ "commander": "^11.1.0",
45
+ "jsdom": "^23.0.1",
47
46
  "lodash": "^4.17.21",
48
- "simplebar": "^6.2.4"
47
+ "simplebar": "^6.2.5"
49
48
  },
50
49
  "peerDependencies": {
51
- "@zipify/colorpicker": "^3.0",
50
+ "@zipify/colorpicker": "^3.1",
52
51
  "vue": "^3.2"
53
52
  },
54
53
  "peerDependenciesMeta": {
@@ -60,39 +59,39 @@
60
59
  }
61
60
  },
62
61
  "devDependencies": {
63
- "@babel/core": "^7.21.3",
64
- "@babel/eslint-parser": "^7.21.3",
65
- "@babel/plugin-transform-runtime": "^7.21.0",
66
- "@babel/preset-env": "^7.20.2",
67
- "@babel/runtime": "^7.21.0",
68
- "@optimize-lodash/rollup-plugin": "^4.0.3",
69
- "@rollup/plugin-babel": "^6.0.3",
70
- "@rollup/plugin-commonjs": "^24.0.1",
71
- "@rollup/plugin-json": "^6.0.0",
72
- "@rollup/plugin-node-resolve": "^15.0.1",
73
- "@rollup/plugin-replace": "^5.0.2",
74
- "@rollup/plugin-terser": "^0.4.0",
75
- "@vitejs/plugin-vue": "^4.2.3",
76
- "@vue/test-utils": "^2.3.2",
77
- "@vue/vue3-jest": "^29.2.2",
78
- "@zipify/colorpicker": "^3.0.0",
79
- "@zipify/eslint-config": "^1.2.0",
80
- "babel-jest": "^29.5.0",
81
- "eslint": "8.37.0",
82
- "eslint-plugin-import": "^2.27.5",
83
- "eslint-plugin-jest": "^27.2.1",
84
- "eslint-plugin-vue": "^9.10.0",
62
+ "@babel/core": "^7.23.5",
63
+ "@babel/eslint-parser": "^7.23.3",
64
+ "@babel/plugin-transform-runtime": "^7.23.4",
65
+ "@babel/preset-env": "^7.23.5",
66
+ "@babel/runtime": "^7.23.5",
67
+ "@optimize-lodash/rollup-plugin": "^4.0.4",
68
+ "@rollup/plugin-babel": "^6.0.4",
69
+ "@rollup/plugin-commonjs": "^25.0.7",
70
+ "@rollup/plugin-json": "^6.0.1",
71
+ "@rollup/plugin-node-resolve": "^15.2.3",
72
+ "@rollup/plugin-replace": "^5.0.5",
73
+ "@rollup/plugin-terser": "^0.4.4",
74
+ "@vitejs/plugin-vue": "^4.5.2",
75
+ "@vue/test-utils": "^2.4.3",
76
+ "@vue/vue3-jest": "^29.2.6",
77
+ "@zipify/colorpicker": "^3.1.0",
78
+ "@zipify/eslint-config": "^1.4.1",
79
+ "babel-jest": "^29.7.0",
80
+ "eslint": "^8.55.0",
81
+ "eslint-plugin-import": "^2.29.0",
82
+ "eslint-plugin-jest": "^27.6.0",
83
+ "eslint-plugin-vue": "^9.19.2",
85
84
  "husky": "^8.0.3",
86
- "jest": "^29.5.0",
87
- "jest-environment-jsdom": "^29.5.0",
88
- "lint-staged": "^13.2.0",
85
+ "jest": "^29.7.0",
86
+ "jest-environment-jsdom": "^29.7.0",
87
+ "lint-staged": "^15.2.0",
89
88
  "postcss-html": "^1.5.0",
90
- "release-it": "^15.9.3",
91
- "rollup": "^3.20.2",
89
+ "release-it": "^17.0.0",
90
+ "rollup": "^4.6.1",
92
91
  "stylelint": "^14.16.1",
93
- "svgo": "^3.0.2",
94
- "vite": "^4.2.1",
95
- "vue": "3.3.4"
92
+ "svgo": "^3.0.5",
93
+ "vite": "^5.0.6",
94
+ "vue": "3.3.10"
96
95
  },
97
96
  "engines": {
98
97
  "node": ">=18.12.0"
@@ -1,59 +0,0 @@
1
- import { ref } from 'vue';
2
- import { withComponentContext } from '../../../../__tests__/utils';
3
- import { InjectionTokens } from '../../../../injectionTokens';
4
- import { useModalToggler } from '../useModalToggler';
5
- import { useElementRef } from '../useElementRef';
6
-
7
- jest.mock('@floating-ui/dom');
8
-
9
- const createEditor = () => ({
10
- commands: {
11
- storeSelection: jest.fn(),
12
- restoreSelection: jest.fn()
13
- }
14
- });
15
-
16
- const el = document.createElement('div');
17
- const elementRef = useElementRef(ref(el));
18
-
19
- function createWrapper() {
20
- return withComponentContext(() => {
21
- return useModalToggler({
22
- onClosed: jest.fn(),
23
- onBeforeOpened: jest.fn(),
24
- wrapperRef: elementRef,
25
- modalRef: elementRef
26
- });
27
- }, {
28
- global: {
29
- provide: { [InjectionTokens.EDITOR]: createEditor() }
30
- }
31
- });
32
- }
33
-
34
- describe('manage opened state', () => {
35
- test('should open modal', () => {
36
- const toggler = createWrapper();
37
-
38
- toggler.open();
39
-
40
- expect(toggler.isOpened.value).toBe(true);
41
- });
42
-
43
- test('should close modal', () => {
44
- const toggler = createWrapper();
45
-
46
- toggler.open();
47
- toggler.close();
48
-
49
- expect(toggler.isOpened.value).toBe(false);
50
- });
51
-
52
- test('should toggle modal', () => {
53
- const toggler = createWrapper();
54
-
55
- toggler.toggle(true);
56
-
57
- expect(toggler.isOpened.value).toBe(true);
58
- });
59
- });
@@ -1,36 +0,0 @@
1
- import { onUnmounted } from 'vue';
2
- import { autoUpdate, computePosition, limitShift, offset, shift } from '@floating-ui/dom';
3
- import { useElementRef } from '../components/base';
4
-
5
- export function useToolbar({ wrapperRef, offsets, isActiveRef, placementRef }) {
6
- const wrapperEl = useElementRef(wrapperRef);
7
- let floatingInstance;
8
-
9
- function mount(element) {
10
- floatingInstance = autoUpdate(wrapperEl.value, element, async () => {
11
- const positioning = await computePosition(wrapperEl.value, element, {
12
- placement: placementRef.value,
13
- strategy: 'fixed',
14
- middleware: [
15
- shift({ padding: 16, crossAxis: true, limiter: limitShift() }),
16
- offset({ crossAxis: offsets[0], mainAxis: offsets[1] })
17
- ]
18
- });
19
-
20
- const { x, y } = positioning;
21
-
22
- Object.assign(element.style, {
23
- left: `${x}px`,
24
- top: `${y}px`
25
- });
26
- });
27
- }
28
-
29
- onUnmounted(() => floatingInstance?.());
30
-
31
- return {
32
- mount,
33
- isActiveRef,
34
- offsets
35
- };
36
- }
File without changes