@zipify/wysiwyg 3.5.4-ai-prototype → 3.6.0-0

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 (55) hide show
  1. package/dist/cli.js +2 -2
  2. package/dist/wysiwyg.css +112 -248
  3. package/dist/wysiwyg.mjs +8128 -10207
  4. package/example/ExampleApp.vue +4 -4
  5. package/example/ai-component/AiComponent.vue +57 -0
  6. package/lib/Wysiwyg.vue +4 -6
  7. package/lib/components/base/Button.vue +10 -0
  8. package/lib/components/base/dropdown/Dropdown.vue +7 -1
  9. package/lib/components/base/dropdown/DropdownActivator.vue +22 -0
  10. package/lib/components/base/dropdown/__tests__/DropdownActivator.test.js +21 -1
  11. package/lib/components/base/index.js +0 -1
  12. package/lib/components/toolbar/Toolbar.vue +7 -1
  13. package/lib/components/toolbar/controls/AlignmentControl.vue +12 -1
  14. package/lib/components/toolbar/controls/FontColorControl.vue +12 -0
  15. package/lib/components/toolbar/controls/FontFamilyControl.vue +19 -4
  16. package/lib/components/toolbar/controls/FontSizeControl.vue +27 -4
  17. package/lib/components/toolbar/controls/FontWeightControl.vue +26 -4
  18. package/lib/components/toolbar/controls/ItalicControl.vue +11 -1
  19. package/lib/components/toolbar/controls/LineHeightControl.vue +11 -0
  20. package/lib/components/toolbar/controls/UnderlineControl.vue +10 -0
  21. package/lib/components/toolbar/controls/__tests__/AlignmentControl.test.js +43 -1
  22. package/lib/components/toolbar/controls/__tests__/FontColorControl.test.js +22 -1
  23. package/lib/components/toolbar/controls/__tests__/FontFamilyControl.test.js +2 -0
  24. package/lib/components/toolbar/controls/__tests__/FontSizeControl.test.js +9 -1
  25. package/lib/components/toolbar/controls/__tests__/FontWeightControl.test.js +9 -1
  26. package/lib/components/toolbar/controls/__tests__/ItalicControl.test.js +23 -1
  27. package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +23 -1
  28. package/lib/components/toolbar/controls/__tests__/StylePresetControl.test.js +31 -13
  29. package/lib/components/toolbar/controls/__tests__/UnderlineControl.test.js +26 -1
  30. package/lib/components/toolbar/controls/index.js +1 -2
  31. package/lib/components/toolbar/controls/{StylePresetControl.vue → stylePreset/StylePresetControl.vue} +23 -8
  32. package/lib/components/toolbar/controls/stylePreset/StylePresetOption.vue +87 -0
  33. package/lib/components/toolbar/controls/stylePreset/index.js +1 -0
  34. package/lib/components/toolbar/layouts/ToolbarDesktop.vue +14 -5
  35. package/lib/components/toolbar/layouts/ToolbarPopup.vue +12 -0
  36. package/lib/entryLib.js +2 -0
  37. package/lib/extensions/index.js +0 -5
  38. package/lib/extensions/proseMirror/PastePlugin.js +4 -6
  39. package/lib/styles/dropdown.css +7 -0
  40. package/lib/styles/main.css +1 -0
  41. package/lib/styles/variables.css +1 -0
  42. package/package.json +1 -2
  43. package/example/aiAdapter.js +0 -52
  44. package/lib/assets/icons/loading.svg +0 -11
  45. package/lib/assets/icons/send.svg +0 -3
  46. package/lib/assets/icons/sparkles.svg +0 -3
  47. package/lib/components/base/TextArea.vue +0 -108
  48. package/lib/components/floatingMenu/AiWidgetSuggestionItem.vue +0 -74
  49. package/lib/components/floatingMenu/FloatingMenuControl.vue +0 -222
  50. package/lib/components/floatingMenu/index.js +0 -1
  51. package/lib/components/toolbar/controls/aiComponent/AiControl.vue +0 -204
  52. package/lib/components/toolbar/controls/aiComponent/AiControlHeader.vue +0 -28
  53. package/lib/components/toolbar/controls/aiComponent/AiSettings.vue +0 -153
  54. package/lib/components/toolbar/controls/aiComponent/AiSuggestionItem.vue +0 -84
  55. package/lib/extensions/AiComponent.js +0 -22
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <Button
3
+ class="zw-position--relative"
3
4
  skin="toolbar"
4
5
  icon
5
6
  :active="currentValue"
@@ -7,6 +8,13 @@
7
8
  v-tooltip="{ text: 'Underline', hotkey: 'Mod U' }"
8
9
  >
9
10
  <Icon name="underline" size="28px" auto-color />
11
+
12
+ <span
13
+ v-if="isCustomized"
14
+ class="zw-button__customized-indicator"
15
+ data-test-selector="customizedIndicator"
16
+ v-tooltip.xs="'Style differs from Page Styles'"
17
+ />
10
18
  </Button>
11
19
  </template>
12
20
 
@@ -32,11 +40,13 @@ export default {
32
40
  const editor = inject(InjectionTokens.EDITOR);
33
41
 
34
42
  const currentValue = editor.commands.isUnderline();
43
+ const isCustomized = editor.commands.isUnderlineCustomized();
35
44
 
36
45
  const apply = () => editor.chain().focus().toggleUnderline().run();
37
46
 
38
47
  return {
39
48
  currentValue,
49
+ isCustomized,
40
50
  apply
41
51
  };
42
52
  }
@@ -5,9 +5,14 @@ import { Alignments } from '../../../../enums';
5
5
  import { ButtonToggle } from '../../../base';
6
6
  import AlignmentControl from '../AlignmentControl';
7
7
 
8
- const createEditor = ({ alignment } = {}) => ({
8
+ const SELECTORS = {
9
+ INDICATOR: '[data-test-selector="customizedIndicator"]'
10
+ };
11
+
12
+ const createEditor = ({ alignment, isSettingCustomized } = {}) => ({
9
13
  commands: {
10
14
  getAlignment: () => ref(alignment),
15
+ isSettingCustomized: () => ref(isSettingCustomized ?? false),
11
16
  focus: jest.fn().mockReturnThis(),
12
17
  applyAlignment: jest.fn().mockReturnThis(),
13
18
  run: jest.fn()
@@ -74,3 +79,40 @@ describe('selection value', () => {
74
79
  expect(editor.commands.applyAlignment).toHaveBeenCalledWith(Alignments.CENTER);
75
80
  });
76
81
  });
82
+
83
+ describe('render indicator of customized styles', () => {
84
+ test('should render indicator', () => {
85
+ const editor = createEditor({
86
+ alignment: Alignments.LEFT,
87
+ isSettingCustomized: true
88
+ });
89
+ const wrapper = createComponent({
90
+ editor,
91
+ slotParams: {
92
+ option: {
93
+ id: Alignments.LEFT,
94
+ tooltip: { text: 'Align Left', hotkey: 'Mod Shift L' }
95
+ },
96
+ isActive: true
97
+ }
98
+ });
99
+
100
+ expect(wrapper).toVueContainComponent(SELECTORS.INDICATOR);
101
+ });
102
+
103
+ test('should not render indicator', () => {
104
+ const editor = createEditor({ alignment: Alignments.LEFT });
105
+ const wrapper = createComponent({
106
+ editor,
107
+ slotParams: {
108
+ option: {
109
+ id: Alignments.LEFT,
110
+ tooltip: { text: 'Align Left', hotkey: 'Mod Shift L' }
111
+ },
112
+ isActive: true
113
+ }
114
+ });
115
+
116
+ expect(wrapper).not.toVueContainComponent(SELECTORS.INDICATOR);
117
+ });
118
+ });
@@ -4,9 +4,14 @@ import { InjectionTokens } from '../../../../injectionTokens';
4
4
  import { ColorPicker } from '../../../base';
5
5
  import FontColorControl from '../FontColorControl';
6
6
 
7
- const createEditor = ({ fontColor } = {}) => ({
7
+ const SELECTORS = {
8
+ INDICATOR: '[data-test-selector="customizedIndicator"]'
9
+ };
10
+
11
+ const createEditor = ({ fontColor, isSettingCustomized } = {}) => ({
8
12
  commands: {
9
13
  getFontColor: () => ref(fontColor),
14
+ isSettingCustomized: () => ref( isSettingCustomized ?? false),
10
15
  focus: jest.fn().mockReturnThis(),
11
16
  applyFontColor: jest.fn().mockReturnThis(),
12
17
  run: jest.fn()
@@ -57,3 +62,19 @@ describe('selection value', () => {
57
62
  expect(editor.commands.applyFontColor).toHaveBeenCalledWith('green');
58
63
  });
59
64
  });
65
+
66
+ describe('render indicator of customized styles', () => {
67
+ test('should render indicator', () => {
68
+ const editor = createEditor({ fontColor: 'red', isSettingCustomized: true });
69
+ const wrapper = createComponent({ editor });
70
+
71
+ expect(wrapper).toVueContainComponent(SELECTORS.INDICATOR);
72
+ });
73
+
74
+ test('should not render indicator', () => {
75
+ const editor = createEditor({ fontColor: 'red' });
76
+ const wrapper = createComponent({ editor });
77
+
78
+ expect(wrapper).not.toVueContainComponent(SELECTORS.INDICATOR);
79
+ });
80
+ });
@@ -7,6 +7,8 @@ import FontFamilyControl from '../FontFamilyControl';
7
7
  const createEditor = ({ fontFamily } = {}) => ({
8
8
  commands: {
9
9
  getFont: () => ref({ name: fontFamily }),
10
+ getDefaultFontFamily: () => ref(fontFamily ?? 'Lato'),
11
+ isSettingCustomized: () => ref(false),
10
12
  focus: jest.fn().mockReturnThis(),
11
13
  applyFontFamily: jest.fn().mockReturnThis(),
12
14
  run: jest.fn()
@@ -1,5 +1,5 @@
1
1
  import { shallowMount } from '@vue/test-utils';
2
- import { ref } from 'vue';
2
+ import { h, ref } from 'vue';
3
3
  import { InjectionTokens } from '../../../../injectionTokens';
4
4
  import { Dropdown } from '../../../base';
5
5
  import FontSizeControl from '../FontSizeControl';
@@ -7,6 +7,8 @@ import FontSizeControl from '../FontSizeControl';
7
7
  const createEditor = ({ fontSize } = {}) => ({
8
8
  commands: {
9
9
  getFontSize: () => ref(fontSize),
10
+ getDefaultFontSize: () => ref(fontSize ?? '18'),
11
+ isSettingCustomized: () => ref(false),
10
12
  focus: jest.fn().mockReturnThis(),
11
13
  applyFontSize: jest.fn().mockReturnThis(),
12
14
  run: jest.fn()
@@ -19,6 +21,12 @@ const createEditor = ({ fontSize } = {}) => ({
19
21
 
20
22
  function createComponent({ editor }) {
21
23
  return shallowMount(FontSizeControl, {
24
+ stubs: {
25
+ Dropdown: {
26
+ render: () => h('div'),
27
+ props: ['value']
28
+ }
29
+ },
22
30
  provide: {
23
31
  [InjectionTokens.EDITOR]: editor,
24
32
  [InjectionTokens.FONT_SIZES]: ['12', '23']
@@ -1,5 +1,5 @@
1
1
  import { shallowMount } from '@vue/test-utils';
2
- import { ref } from 'vue';
2
+ import { h, ref } from 'vue';
3
3
  import { InjectionTokens } from '../../../../injectionTokens';
4
4
  import { Dropdown } from '../../../base';
5
5
  import FontWeightControl from '../FontWeightControl';
@@ -7,6 +7,8 @@ import FontWeightControl from '../FontWeightControl';
7
7
  const createEditor = ({ fontWeight, fontWeightList } = {}) => ({
8
8
  commands: {
9
9
  getFontWeight: () => ref(fontWeight ?? '400'),
10
+ getDefaultFontWeight: () => ref(fontWeight ?? '400'),
11
+ isSettingCustomized: () => ref(false),
10
12
  getFont: () => ref({ weights: fontWeightList ?? ['400', '700'] }),
11
13
  focus: jest.fn().mockReturnThis(),
12
14
  applyFontWeight: jest.fn().mockReturnThis(),
@@ -20,6 +22,12 @@ const createEditor = ({ fontWeight, fontWeightList } = {}) => ({
20
22
 
21
23
  function createComponent({ editor }) {
22
24
  return shallowMount(FontWeightControl, {
25
+ stubs: {
26
+ Dropdown: {
27
+ render: () => h('div'),
28
+ props: ['value']
29
+ }
30
+ },
23
31
  provide: { [InjectionTokens.EDITOR]: editor }
24
32
  });
25
33
  }
@@ -4,9 +4,14 @@ import { InjectionTokens } from '../../../../injectionTokens';
4
4
  import { Button } from '../../../base';
5
5
  import ItalicControl from '../ItalicControl';
6
6
 
7
- const createEditor = ({ isItalic, isItalicAvailable } = {}) => ({
7
+ const SELECTORS = {
8
+ INDICATOR: '[data-test-selector="customizedIndicator"]'
9
+ };
10
+
11
+ const createEditor = ({ isItalic, isItalicAvailable, isSettingCustomized } = {}) => ({
8
12
  commands: {
9
13
  isItalic: () => ref(isItalic),
14
+ isSettingCustomized: () => ref(isSettingCustomized ?? false),
10
15
  isItalicAvailable: () => ref(isItalicAvailable ?? true),
11
16
  focus: jest.fn().mockReturnThis(),
12
17
  toggleItalic: jest.fn().mockReturnThis(),
@@ -40,6 +45,23 @@ describe('rendering', () => {
40
45
 
41
46
  expect(buttonWrapper.props('disabled')).toBe(true);
42
47
  });
48
+
49
+ test('should render indicator of customized styles', () => {
50
+ const editor = createEditor({
51
+ isItalic: true,
52
+ isSettingCustomized: true
53
+ });
54
+ const wrapper = createComponent({ editor });
55
+
56
+ expect(wrapper).toVueContainComponent(SELECTORS.INDICATOR);
57
+ });
58
+
59
+ test('should not render indicator of customized styles', () => {
60
+ const editor = createEditor({ isItalic: false });
61
+ const wrapper = createComponent({ editor });
62
+
63
+ expect(wrapper).not.toVueContainComponent(SELECTORS.INDICATOR);
64
+ });
43
65
  });
44
66
 
45
67
  describe('selection value', () => {
@@ -4,12 +4,17 @@ import { InjectionTokens } from '../../../../injectionTokens';
4
4
  import { Button, Modal, NumberField, Range } from '../../../base';
5
5
  import LineHeightControl from '../LineHeightControl';
6
6
 
7
- const createEditor = ({ height } = {}) => {
7
+ const SELECTORS = {
8
+ INDICATOR: '[data-test-selector="customizedIndicator"]'
9
+ };
10
+
11
+ const createEditor = ({ height, isSettingCustomized } = {}) => {
8
12
  const heightRef = ref(height ?? '1.2');
9
13
 
10
14
  return {
11
15
  commands: {
12
16
  getLineHeight: () => heightRef,
17
+ isSettingCustomized: () => ref(isSettingCustomized ?? false),
13
18
  applyLineHeight: jest.fn(function (value) {
14
19
  heightRef.value = value;
15
20
  return this;
@@ -117,4 +122,21 @@ describe('rendering', () => {
117
122
  expect(buttonWrapper.props('active')).toBe(true);
118
123
  expect(modalWrapper.props('toggler').isOpened.value).toBe(true);
119
124
  });
125
+
126
+ test('should render indicator of customized styles', () => {
127
+ const editor = createEditor({
128
+ height: '1.8',
129
+ isSettingCustomized: true
130
+ });
131
+ const wrapper = createComponent({ editor });
132
+
133
+ expect(wrapper).toVueContainComponent(SELECTORS.INDICATOR);
134
+ });
135
+
136
+ test('should not render indicator of customized styles', () => {
137
+ const editor = createEditor({ height: '1.2' });
138
+ const wrapper = createComponent({ editor });
139
+
140
+ expect(wrapper).not.toVueContainComponent(SELECTORS.INDICATOR);
141
+ });
120
142
  });
@@ -2,7 +2,7 @@ import { shallowMount } from '@vue/test-utils';
2
2
  import { ref } from 'vue';
3
3
  import { InjectionTokens } from '../../../../injectionTokens';
4
4
  import { Button, Dropdown } from '../../../base';
5
- import StylePresetControl from '../StylePresetControl';
5
+ import { StylePresetControl } from '../stylePreset';
6
6
  import { TextSettings } from '../../../../enums';
7
7
 
8
8
  const createEditor = ({ presets, preset, customization } = {}) => ({
@@ -31,27 +31,45 @@ function createComponent({ editor }) {
31
31
  });
32
32
  }
33
33
 
34
+ function createPreset({ id, name } = {}) {
35
+ return {
36
+ id: id ?? 'regular-1',
37
+ name: name ?? 'Regular 1',
38
+ common: {
39
+ color: '#262626',
40
+ font_weight: 400,
41
+ font_family: 'Lato',
42
+ font_style: 'italic'
43
+ },
44
+ desktop: { font_size: 18 }
45
+ };
46
+ }
47
+
34
48
  describe('rendering', () => {
35
49
  test('should render dropdown options', () => {
36
- const editor = createEditor({
37
- presets: [
38
- { id: 'h1', name: 'H1' },
39
- { id: 'regular-1', name: 'Regular 1' }
40
- ]
41
- });
50
+ const presets = [createPreset()];
51
+ const editor = createEditor({ presets });
42
52
  const wrapper = createComponent({ editor });
43
53
  const dropdownWrapper = wrapper.findComponent(Dropdown);
44
54
 
45
- expect(dropdownWrapper.props('options')).toEqual([
46
- { id: 'h1', title: 'H1' },
47
- { id: 'regular-1', title: 'Regular 1' }
48
- ]);
55
+ expect(dropdownWrapper.props('options')).toEqual([{
56
+ id: 'regular-1',
57
+ title: 'Regular 1',
58
+ properties: {
59
+ color: '#262626',
60
+ fontFamily: 'Lato',
61
+ fontSize: 18,
62
+ fontStyle: 'italic',
63
+ fontWeight: 400
64
+ }
65
+ }]);
49
66
  });
50
67
 
51
68
  test('should render preset from selection', () => {
69
+ const presets = [createPreset()];
52
70
  const editor = createEditor({
53
- presets: [{ id: 'regular-1', name: 'Regular 1' }],
54
- preset: { id: 'regular-1' }
71
+ presets,
72
+ preset: createPreset()
55
73
  });
56
74
  const wrapper = createComponent({ editor });
57
75
  const dropdownWrapper = wrapper.findComponent(Dropdown);
@@ -4,9 +4,14 @@ import { InjectionTokens } from '../../../../injectionTokens';
4
4
  import { Button } from '../../../base';
5
5
  import UnderlineControl from '../UnderlineControl';
6
6
 
7
- const createEditor = ({ isUnderline } = {}) => ({
7
+ const SELECTORS = {
8
+ INDICATOR: '[data-test-selector="customizedIndicator"]'
9
+ };
10
+
11
+ const createEditor = ({ isUnderline, isSettingCustomized } = {}) => ({
8
12
  commands: {
9
13
  isUnderline: () => ref(isUnderline),
14
+ isUnderlineCustomized: () => ref(isSettingCustomized ?? false),
10
15
  focus: jest.fn().mockReturnThis(),
11
16
  toggleUnderline: jest.fn().mockReturnThis(),
12
17
  run: jest.fn()
@@ -46,3 +51,23 @@ describe('selection value', () => {
46
51
  expect(editor.commands.toggleUnderline).toHaveBeenCalled();
47
52
  });
48
53
  });
54
+
55
+
56
+ describe('render indicator of customized styles', () => {
57
+ test('should render indicator', () => {
58
+ const editor = createEditor({
59
+ isUnderline: true,
60
+ isSettingCustomized: true
61
+ });
62
+ const wrapper = createComponent({ editor });
63
+
64
+ expect(wrapper).toVueContainComponent(SELECTORS.INDICATOR);
65
+ });
66
+
67
+ test('should not render indicator', () => {
68
+ const editor = createEditor({ isUnderline: false });
69
+ const wrapper = createComponent({ editor });
70
+
71
+ expect(wrapper).not.toVueContainComponent(SELECTORS.INDICATOR);
72
+ });
73
+ });
@@ -1,4 +1,3 @@
1
- export { default as StylePresetControl } from './StylePresetControl';
2
1
  export { default as FontFamilyControl } from './FontFamilyControl';
3
2
  export { default as FontWeightControl } from './FontWeightControl';
4
3
  export { default as FontSizeControl } from './FontSizeControl';
@@ -13,5 +12,5 @@ export { default as AlignmentControl } from './AlignmentControl';
13
12
  export { default as LineHeightControl } from './LineHeightControl';
14
13
  export { default as ListControl } from './ListControl';
15
14
  export { default as RemoveFormatControl } from './RemoveFormatControl';
16
- export { default as AiControl } from './aiComponent/AiControl';
17
15
  export { LinkControl } from './link';
16
+ export { StylePresetControl } from './stylePreset';
@@ -2,11 +2,16 @@
2
2
  <div class="zw-style-preset-control">
3
3
  <Dropdown
4
4
  class="zw-style-preset-control__dropdown"
5
+ :max-width="170"
5
6
  :value="preset.id"
6
7
  :options="options"
7
8
  @change="apply"
8
9
  v-tooltip="'Text Type'"
9
- />
10
+ >
11
+ <template #option="{ option }">
12
+ <StylePresetOption :option="option" />
13
+ </template>
14
+ </Dropdown>
10
15
 
11
16
  <Button
12
17
  class="zw-style-preset-control__reset"
@@ -22,10 +27,11 @@
22
27
 
23
28
  <script>
24
29
  import { computed, inject, unref } from 'vue';
25
- import { InjectionTokens } from '../../../injectionTokens';
26
- import { Dropdown, Button, Icon } from '../../base';
27
- import { tooltip } from '../../../directives';
28
- import { TextSettings } from '../../../enums';
30
+ import { InjectionTokens } from '../../../../injectionTokens';
31
+ import { Dropdown, Button, Icon } from '../../../base';
32
+ import { tooltip } from '../../../../directives';
33
+ import { Devices, TextSettings } from '../../../../enums';
34
+ import StylePresetOption from './StylePresetOption';
29
35
 
30
36
  const CLEAR_MARKS = [TextSettings.FONT_SIZE, TextSettings.FONT_WEIGHT];
31
37
 
@@ -33,9 +39,10 @@ export default {
33
39
  name: 'StylePresetControl',
34
40
 
35
41
  components: {
36
- Icon,
42
+ StylePresetOption,
43
+ Dropdown,
37
44
  Button,
38
- Dropdown
45
+ Icon
39
46
  },
40
47
 
41
48
  directives: {
@@ -58,7 +65,15 @@ export default {
58
65
  const options = computed(() => {
59
66
  return unref(presets).map((preset) => ({
60
67
  id: preset.id,
61
- title: preset.name
68
+ title: preset.name,
69
+ properties: {
70
+ color: preset.common.color,
71
+ fontWeight: preset.common.font_weight,
72
+ fontFamily: preset.common.font_family,
73
+ fontStyle: preset.common.font_style,
74
+ textDecoration: preset.common.text_decoration,
75
+ fontSize: preset[Devices.DESKTOP].font_size
76
+ }
62
77
  }));
63
78
  });
64
79
 
@@ -0,0 +1,87 @@
1
+ <template>
2
+ <DropdownOption
3
+ class="zw-style-preset-control__option"
4
+ :style="renderOptionStyles(option)"
5
+ :option="option"
6
+ v-tooltip="option.id"
7
+ >
8
+ <span class="zw-style-preset-control__color" />
9
+ <span class="zw-style-preset-control__title">{{ optionTitle }}</span>
10
+ <span class="zw-style-preset-control__size">{{ fontSizeTitle }}</span>
11
+ </DropdownOption>
12
+ </template>
13
+
14
+ <script>
15
+ import { computed } from 'vue';
16
+ import { DropdownOption } from '../../../base';
17
+ import { tooltip } from '../../../../directives';
18
+
19
+ export default {
20
+ name: 'StylePresetOption',
21
+
22
+ components: {
23
+ DropdownOption
24
+ },
25
+
26
+ directives: {
27
+ tooltip
28
+ },
29
+
30
+ props: {
31
+ option: {
32
+ type: Object,
33
+ required: true
34
+ }
35
+ },
36
+
37
+ setup(props) {
38
+ const optionTitle = computed(() => props.option.title);
39
+ const fontSizeTitle = computed(() => props.option.properties.fontSize);
40
+ const renderOptionStyles = (option) => ({
41
+ '--zw-color-option': option.properties.color,
42
+ '--zw-font-style-option': option.properties.fontStyle,
43
+ '--zw-font-family-option': `"${option.properties.fontFamily}"`,
44
+ '--zw-font-weight-option': option.properties.fontWeight,
45
+ '--zw-text-decoration-option': option.properties.textDecoration
46
+ });
47
+
48
+ return {
49
+ optionTitle,
50
+ fontSizeTitle,
51
+ renderOptionStyles
52
+ };
53
+ }
54
+ };
55
+ </script>
56
+
57
+ <style scoped>
58
+ .zw-style-preset-control__option {
59
+ display: flex;
60
+ justify-content: space-between;
61
+ align-items: center;
62
+ }
63
+
64
+ .zw-style-preset-control__color {
65
+ width: 10px;
66
+ height: 10px;
67
+ border: 1px solid rgba(var(--zw-color-black), 0.15);
68
+ border-radius: 14.71%;
69
+ background-color: var(--zw-color-option);
70
+ }
71
+
72
+ .zw-style-preset-control__size {
73
+ font-size: 10px;
74
+ color: rgb(var(--zw-color-n70));
75
+ margin-left: var(--zw-offset-sm);
76
+ }
77
+
78
+ .zw-style-preset-control__title {
79
+ width: 82px;
80
+ margin-left: var(--zw-offset-xs);
81
+ font-size: var(--zw-font-size-xxs);
82
+ font-family: var(--zw-font-family-option);
83
+ font-style: var(--zw-font-style-option);
84
+ font-weight: var(--zw-font-weight-option);
85
+ text-decoration: var(--zw-text-decoration-option);
86
+ }
87
+ </style>
@@ -0,0 +1 @@
1
+ export { default as StylePresetControl } from './StylePresetControl';
@@ -1,7 +1,10 @@
1
1
  <template>
2
2
  <div>
3
3
  <ToolbarRow>
4
- <AiControl />
4
+ <template v-if="aiComponent">
5
+ <component :is="aiComponent" />
6
+ <ToolbarDivider vertical />
7
+ </template>
5
8
  <StylePresetControl />
6
9
  <ToolbarDivider vertical />
7
10
  <FontFamilyControl />
@@ -65,8 +68,7 @@ import {
65
68
  UnderlineControl,
66
69
  ListControl,
67
70
  RemoveFormatControl,
68
- LinkControl,
69
- AiControl
71
+ LinkControl
70
72
  } from '../controls';
71
73
 
72
74
  export default {
@@ -91,8 +93,15 @@ export default {
91
93
  LineHeightControl,
92
94
  ListControl,
93
95
  RemoveFormatControl,
94
- LinkControl,
95
- AiControl
96
+ LinkControl
97
+ },
98
+
99
+ props: {
100
+ aiComponent: {
101
+ type: Object,
102
+ required: false,
103
+ default: null
104
+ }
96
105
  }
97
106
  };
98
107
  </script>
@@ -1,6 +1,10 @@
1
1
  <template>
2
2
  <div>
3
3
  <ToolbarRow>
4
+ <template v-if="aiComponent">
5
+ <component :is="aiComponent" />
6
+ <ToolbarDivider vertical />
7
+ </template>
4
8
  <StylePresetControl />
5
9
  <ToolbarDivider vertical />
6
10
  <FontFamilyControl />
@@ -90,6 +94,14 @@ export default {
90
94
  ListControl,
91
95
  RemoveFormatControl,
92
96
  LinkControl
97
+ },
98
+
99
+ props: {
100
+ aiComponent: {
101
+ type: Object,
102
+ required: false,
103
+ default: null
104
+ }
93
105
  }
94
106
  };
95
107
  </script>
package/lib/entryLib.js CHANGED
@@ -2,3 +2,5 @@ export { default as Wysiwyg } from './Wysiwyg';
2
2
  export { NodeFactory, HtmlToJsonParser } from './services';
3
3
  export { NodeTypes, TextSettings, Alignments } from './enums';
4
4
  export { isWysiwygContent, unmarkWysiwygContent, markWysiwygContent } from './utils';
5
+ export * from './components/base';
6
+ export { InjectionTokens } from './injectionTokens';
@@ -1,5 +1,4 @@
1
1
  import { reactive, toRef, watch } from 'vue';
2
- import FloatingMenu from '@tiptap/extension-floating-menu';
3
2
  import { StylePresetRenderer } from '../services';
4
3
  import { buildCoreExtensions } from './core';
5
4
  import { FontFamily } from './FontFamily';
@@ -18,7 +17,6 @@ import { List } from './list';
18
17
  import { Link } from './Link';
19
18
  import { Superscript } from './Superscript';
20
19
  import { Margin } from './Margin';
21
- import { AiComponent } from './AiComponent';
22
20
 
23
21
  export function buildExtensions(options) {
24
22
  const getPresetById = (id) => options.presetsRef.value.find((preset) => preset.id === id);
@@ -39,9 +37,6 @@ export function buildExtensions(options) {
39
37
  linkPresetId: options.linkPresetId
40
38
  })
41
39
  }),
42
- AiComponent.configure({
43
- aiComponent: options.aiComponent
44
- }),
45
40
  List.configure({
46
41
  baseClass: options.baseListClass,
47
42
  presetClass: options.basePresetClass + options.defaultPresetId
@@ -46,12 +46,10 @@ export class PastePlugin extends ProseMirrorPlugin {
46
46
  return true;
47
47
  }
48
48
 
49
- _insertPastedContent({ state, input }, slice) {
50
- if (!this._isFullBlockSelected(state)) {
51
- return state.tr.replaceSelection(slice);
52
- }
53
-
54
- return state.tr.replaceSelectionWith(slice.content, input.shiftKey);
49
+ _insertPastedContent({ state }, slice) {
50
+ return this._isFullBlockSelected(state)
51
+ ? state.tr.replaceSelectionWith(slice.content, false)
52
+ : state.tr.replaceSelection(slice);
55
53
  }
56
54
 
57
55
  _isFullBlockSelected(state) {
@@ -0,0 +1,7 @@
1
+ .zw-dropdown__default-option {
2
+ font-size: var(--zw-font-size-xxs);
3
+ color: rgb(var(--zw-color-n70));
4
+ font-family: "Lato", sans-serif;
5
+ font-style: italic;
6
+ margin-left: var(--zw-offset-xxs);
7
+ }