@zipify/wysiwyg 3.1.2 → 4.0.0-vue3.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 (134) hide show
  1. package/.eslintrc.js +1 -1
  2. package/config/build/example.config.js +12 -2
  3. package/config/build/lib.config.js +10 -2
  4. package/config/jest/matchers/index.js +0 -2
  5. package/config/jest/setupTests.js +4 -7
  6. package/config/jest/typing.d.ts +1 -2
  7. package/dist/cli.js +2 -7
  8. package/dist/wysiwyg.css +153 -152
  9. package/dist/wysiwyg.mjs +3594 -3172
  10. package/example/example.js +34 -35
  11. package/jest.config.js +4 -1
  12. package/lib/Wysiwyg.vue +166 -190
  13. package/lib/__tests__/utils/buildTestExtensions.js +1 -1
  14. package/lib/components/base/Button.vue +31 -37
  15. package/lib/components/base/ButtonToggle.vue +11 -17
  16. package/lib/components/base/Checkbox.vue +14 -20
  17. package/lib/components/base/FieldLabel.vue +7 -11
  18. package/lib/components/base/Icon.vue +31 -43
  19. package/lib/components/base/Modal.vue +59 -74
  20. package/lib/components/base/NumberField.vue +65 -80
  21. package/lib/components/base/Range.vue +46 -56
  22. package/lib/components/base/ScrollView.vue +13 -21
  23. package/lib/components/base/TextField.vue +28 -33
  24. package/lib/components/base/__tests__/Button.test.js +1 -1
  25. package/lib/components/base/__tests__/Icon.test.js +1 -1
  26. package/lib/components/base/__tests__/Modal.test.js +21 -13
  27. package/lib/components/base/__tests__/Range.test.js +1 -1
  28. package/lib/components/base/__tests__/TextField.test.js +8 -7
  29. package/lib/components/base/colorPicker/ColorPicker.vue +33 -51
  30. package/lib/components/base/composables/__tests__/useDeselectionLock.test.js +4 -2
  31. package/lib/components/base/composables/__tests__/useModalToggler.test.js +3 -1
  32. package/lib/components/base/composables/__tests__/useScrollView.test.js +3 -1
  33. package/lib/components/base/dropdown/Dropdown.vue +35 -55
  34. package/lib/components/base/dropdown/DropdownActivator.vue +38 -66
  35. package/lib/components/base/dropdown/DropdownDivider.vue +0 -6
  36. package/lib/components/base/dropdown/DropdownGroup.vue +8 -20
  37. package/lib/components/base/dropdown/DropdownMenu.vue +8 -21
  38. package/lib/components/base/dropdown/DropdownOption.vue +27 -45
  39. package/lib/components/base/dropdown/__tests__/DropdownActivator.test.js +5 -3
  40. package/lib/components/base/dropdown/__tests__/DropdownOption.test.js +9 -7
  41. package/lib/components/toolbar/Toolbar.vue +26 -42
  42. package/lib/components/toolbar/__tests__/Toolbar.test.js +1 -1
  43. package/lib/components/toolbar/base/__tests__/ToolbarDivider.test.js +1 -1
  44. package/lib/components/toolbar/controls/AlignmentControl.vue +27 -46
  45. package/lib/components/toolbar/controls/BackgroundColorControl.vue +5 -26
  46. package/lib/components/toolbar/controls/CaseStyleControl.vue +10 -32
  47. package/lib/components/toolbar/controls/FontColorControl.vue +5 -27
  48. package/lib/components/toolbar/controls/FontFamilyControl.vue +27 -49
  49. package/lib/components/toolbar/controls/FontSizeControl.vue +9 -29
  50. package/lib/components/toolbar/controls/FontWeightControl.vue +7 -27
  51. package/lib/components/toolbar/controls/ItalicControl.vue +6 -27
  52. package/lib/components/toolbar/controls/LineHeightControl.vue +10 -37
  53. package/lib/components/toolbar/controls/ListControl.vue +18 -49
  54. package/lib/components/toolbar/controls/RemoveFormatControl.vue +4 -21
  55. package/lib/components/toolbar/controls/StrikeThroughControl.vue +5 -25
  56. package/lib/components/toolbar/controls/StylePresetControl.vue +34 -59
  57. package/lib/components/toolbar/controls/SuperscriptControl.vue +5 -25
  58. package/lib/components/toolbar/controls/UnderlineControl.vue +5 -26
  59. package/lib/components/toolbar/controls/__tests__/AlignmentControl.test.js +15 -13
  60. package/lib/components/toolbar/controls/__tests__/BackgroundColorControl.test.js +17 -15
  61. package/lib/components/toolbar/controls/__tests__/CaseStyleControl.test.js +9 -8
  62. package/lib/components/toolbar/controls/__tests__/FontColorControl.test.js +17 -15
  63. package/lib/components/toolbar/controls/__tests__/FontFamilyControl.test.js +14 -12
  64. package/lib/components/toolbar/controls/__tests__/FontSizeControl.test.js +5 -3
  65. package/lib/components/toolbar/controls/__tests__/FontWeightControl.test.js +3 -1
  66. package/lib/components/toolbar/controls/__tests__/ItalicControl.test.js +3 -1
  67. package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +11 -9
  68. package/lib/components/toolbar/controls/__tests__/ListControl.test.js +16 -14
  69. package/lib/components/toolbar/controls/__tests__/RemoveFormatControl.test.js +3 -1
  70. package/lib/components/toolbar/controls/__tests__/StrikeThroughControl.test.js +3 -1
  71. package/lib/components/toolbar/controls/__tests__/StylePresetControl.test.js +3 -1
  72. package/lib/components/toolbar/controls/__tests__/SuperscriptControl.test.js +3 -1
  73. package/lib/components/toolbar/controls/__tests__/UnderlineControl.test.js +3 -1
  74. package/lib/components/toolbar/controls/composables/__tests__/useRecentFonts.test.js +6 -4
  75. package/lib/components/toolbar/controls/link/LinkControl.vue +75 -108
  76. package/lib/components/toolbar/controls/link/LinkControlHeader.vue +8 -14
  77. package/lib/components/toolbar/controls/link/__tests__/LinkControl.test.js +5 -3
  78. package/lib/components/toolbar/controls/link/__tests__/LinkControlHeader.test.js +3 -1
  79. package/lib/components/toolbar/controls/link/composables/__tests__/useLink.test.js +5 -4
  80. package/lib/components/toolbar/controls/link/destination/LinkControlDestination.vue +28 -47
  81. package/lib/components/toolbar/controls/link/destination/LinkControlPageBlock.vue +12 -20
  82. package/lib/components/toolbar/controls/link/destination/LinkControlUrl.vue +18 -26
  83. package/lib/components/toolbar/controls/link/destination/__tests__/LinkControlPageBlock.test.js +10 -10
  84. package/lib/components/toolbar/controls/link/destination/__tests__/LinkControlUrl.test.js +12 -10
  85. package/lib/components/toolbar/layouts/ToolbarDesktop.vue +36 -64
  86. package/lib/components/toolbar/layouts/ToolbarMobile.vue +38 -66
  87. package/lib/components/toolbar/layouts/ToolbarPopup.vue +36 -64
  88. package/lib/composables/__tests__/useEditor.test.js +3 -3
  89. package/lib/composables/useEditor.js +1 -1
  90. package/lib/directives/__tests__/outClick.test.js +9 -9
  91. package/lib/directives/outClick.js +3 -3
  92. package/lib/extensions/Alignment.js +1 -1
  93. package/lib/extensions/BackgroundColor.js +1 -1
  94. package/lib/extensions/CaseStyle.js +1 -1
  95. package/lib/extensions/DeviceManager.js +1 -1
  96. package/lib/extensions/FontColor.js +1 -1
  97. package/lib/extensions/FontFamily.js +2 -2
  98. package/lib/extensions/FontSize.js +3 -3
  99. package/lib/extensions/FontStyle.js +1 -1
  100. package/lib/extensions/FontWeight.js +1 -1
  101. package/lib/extensions/LineHeight.js +1 -1
  102. package/lib/extensions/Link.js +1 -1
  103. package/lib/extensions/Margin.js +1 -1
  104. package/lib/extensions/StylePreset.js +9 -9
  105. package/lib/extensions/Superscript.js +1 -1
  106. package/lib/extensions/TextDecoration.js +1 -1
  107. package/lib/extensions/__tests__/Alignment.test.js +1 -1
  108. package/lib/extensions/__tests__/BackgroundColor.test.js +1 -1
  109. package/lib/extensions/__tests__/CaseStyle.test.js +1 -1
  110. package/lib/extensions/__tests__/FontColor.test.js +1 -1
  111. package/lib/extensions/__tests__/FontFamily.test.js +1 -1
  112. package/lib/extensions/__tests__/FontSize.test.js +1 -1
  113. package/lib/extensions/__tests__/FontStyle.test.js +1 -1
  114. package/lib/extensions/__tests__/FontWeight.test.js +1 -1
  115. package/lib/extensions/__tests__/LineHeight.test.js +1 -1
  116. package/lib/extensions/__tests__/Link.test.js +1 -1
  117. package/lib/extensions/__tests__/StylePreset.test.js +1 -1
  118. package/lib/extensions/__tests__/Superscript.test.js +1 -1
  119. package/lib/extensions/__tests__/TextDecoration.test.js +1 -1
  120. package/lib/extensions/core/NodeProcessor.js +1 -1
  121. package/lib/extensions/core/SelectionProcessor.js +1 -1
  122. package/lib/extensions/core/TextProcessor.js +1 -1
  123. package/lib/extensions/core/__tests__/NodeProcessor.test.js +1 -1
  124. package/lib/extensions/core/__tests__/SelectionProcessor.test.js +1 -1
  125. package/lib/extensions/core/__tests__/TextProcessor.test.js +1 -1
  126. package/lib/extensions/core/index.js +1 -1
  127. package/lib/extensions/index.js +1 -1
  128. package/lib/extensions/list/List.js +4 -4
  129. package/lib/extensions/list/__tests__/List.test.js +1 -1
  130. package/package.json +19 -20
  131. package/config/jest/matchers/toVueEmpty.js +0 -16
  132. package/config/jest/matchers/toVuexActionHasBeenDispatched.js +0 -19
  133. package/lib/components/base/__tests__/__snapshots__/TextField.test.js.snap +0 -9
  134. package/lib/components/base/dropdown/__tests__/DropdownMenu.test.js +0 -67
@@ -5,7 +5,7 @@ jest.mock('../../assets/icons.svg', () => 'http://zipify.com/icons.svg');
5
5
 
6
6
  function createComponent({ name, size, isAutoColor } = {}) {
7
7
  return shallowMount(Icon, {
8
- propsData: {
8
+ props: {
9
9
  name: name ?? 'test',
10
10
  size: size ?? '',
11
11
  autoColor: isAutoColor ?? false
@@ -14,21 +14,27 @@ const createToggler = (isOpened) => ({
14
14
  isOpened: ref(isOpened ?? true)
15
15
  });
16
16
 
17
+ const SELECTORS = {
18
+ MODAL: '[data-test-selector="modal"]'
19
+ };
20
+
17
21
  function createComponent({ toggler, maxHeight, maxWidth } = {}) {
18
22
  return shallowMount(Modal, {
19
- stubs: {
20
- transition: {
21
- render() {
22
- return this.$slots.default?.[0];
23
+ global: {
24
+ stubs: {
25
+ transition: {
26
+ render() {
27
+ return this.$slots.default?.[0]?.();
28
+ }
23
29
  }
24
- }
30
+ },
31
+ provide: { [InjectionTokens.EDITOR]: null }
25
32
  },
26
- propsData: {
33
+ props: {
27
34
  toggler: toggler ?? createToggler(true),
28
35
  maxHeight: maxHeight ?? 1000,
29
36
  maxWidth: maxWidth ?? 1000
30
- },
31
- provide: { [InjectionTokens.EDITOR]: null }
37
+ }
32
38
  });
33
39
  }
34
40
 
@@ -37,14 +43,14 @@ describe('open/close', () => {
37
43
  const toggler = createToggler(true);
38
44
  const wrapper = createComponent({ toggler });
39
45
 
40
- expect(wrapper).not.toVueEmpty();
46
+ expect(wrapper).toVueContainElement(SELECTORS.MODAL);
41
47
  });
42
48
 
43
49
  test('should render closed', () => {
44
50
  const toggler = createToggler(false);
45
51
  const wrapper = createComponent({ toggler });
46
52
 
47
- expect(wrapper).toVueEmpty();
53
+ expect(wrapper).not.toVueContainElement(SELECTORS.MODAL);
48
54
  });
49
55
 
50
56
  test('should open', async () => {
@@ -54,21 +60,23 @@ describe('open/close', () => {
54
60
  toggler.isOpened.value = true;
55
61
  await nextTick();
56
62
 
57
- expect(wrapper).not.toVueEmpty();
63
+ expect(wrapper).toVueContainElement(SELECTORS.MODAL);
58
64
  });
59
65
  });
60
66
 
61
67
  describe('rendering', () => {
62
68
  test('should render max width', () => {
63
69
  const wrapper = createComponent({ maxWidth: 256 });
64
- const maxWidth = wrapper.element.style.getPropertyValue('--zw-modal-max-width');
70
+ const modalWrapper = wrapper.find(SELECTORS.MODAL);
71
+ const maxWidth = modalWrapper.element.style.getPropertyValue('--zw-modal-max-width');
65
72
 
66
73
  expect(maxWidth).toBe('256px');
67
74
  });
68
75
 
69
76
  test('should render max height', () => {
70
77
  const wrapper = createComponent({ maxHeight: 256 });
71
- const maxHeight = wrapper.element.style.getPropertyValue('--zw-modal-max-height');
78
+ const modalWrapper = wrapper.find(SELECTORS.MODAL);
79
+ const maxHeight = modalWrapper.element.style.getPropertyValue('--zw-modal-max-height');
72
80
 
73
81
  expect(maxHeight).toBe('256px');
74
82
  });
@@ -3,7 +3,7 @@ import Range from '../Range';
3
3
 
4
4
  function createComponent({ min, max, step, value }) {
5
5
  return shallowMount(Range, {
6
- propsData: {
6
+ props: {
7
7
  min: min ?? '1',
8
8
  max: max ?? '3',
9
9
  step: step ?? '0.1',
@@ -3,7 +3,7 @@ import TextField from '../TextField';
3
3
 
4
4
  function createComponent(label, error) {
5
5
  return shallowMount(TextField, {
6
- propsData: {
6
+ props: {
7
7
  value: '',
8
8
  label: label ?? '',
9
9
  placeholder: '',
@@ -35,23 +35,24 @@ describe('rendering', () => {
35
35
  test('should render errors', () => {
36
36
  const wrapper = createComponent('_', 'some error');
37
37
 
38
- expect(wrapper.contains(SELECTORS.ERROR)).toBeTruthy();
38
+ expect(wrapper).toVueContainElement(SELECTORS.ERROR);
39
39
  });
40
40
 
41
41
  test('should not render errors', () => {
42
42
  const wrapper = createComponent();
43
43
 
44
- expect(wrapper.contains(SELECTORS.ERROR)).toBeFalsy();
44
+ expect(wrapper).not.toVueContainElement(SELECTORS.ERROR);
45
45
  });
46
46
  });
47
47
 
48
48
  describe('input change handling', () => {
49
- test('should emit parsed value', () => {
49
+ test('should emit parsed value', async () => {
50
50
  const wrapper = createComponent();
51
- const inputComponentWrapper = wrapper.find(SELECTORS.INPUT);
51
+ const inputWrapper = wrapper.find(SELECTORS.INPUT);
52
52
 
53
- inputComponentWrapper.setValue('Hello world!!!');
53
+ await inputWrapper.setValue('Hello world!!!');
54
+ const [value] = wrapper.emitted('input')[0];
54
55
 
55
- expect(wrapper.emitted('input')).toMatchSnapshot();
56
+ expect(value).toBe('Hello world!!!');
56
57
  });
57
58
  });
@@ -4,9 +4,10 @@
4
4
  placement="bottom-end"
5
5
  placement-strategy="fixed"
6
6
  :favorite-colors="favoriteColors"
7
- :window="contextWindow"
7
+ :window="ContextWindow.window"
8
8
  @changeFavoriteColors="updateFavoriteColors"
9
- v-model="api.editingColor"
9
+ :color="api.editingColor"
10
+ @input="api.editingColor = $event"
10
11
  v-out-click="{ onOutClick: api.close, isDisabled: !api.isOpened }"
11
12
  >
12
13
  <template #activator>
@@ -21,64 +22,45 @@
21
22
  </ZipifyColorPicker>
22
23
  </template>
23
24
 
24
- <script>
25
+ <script setup>
25
26
  import { ZipifyColorPicker } from '@zipify/colorpicker';
26
- import { inject, ref, toRef } from 'vue';
27
- import { outClick } from '../../../directives';
27
+ import { computed, inject, ref, toRef, unref } from 'vue';
28
+ import { outClick as vOutClick } from '../../../directives';
28
29
  import { InjectionTokens } from '../../../injectionTokens';
29
30
  import { ContextWindow } from '../../../services';
30
31
  import { usePickerApi, usePickerHotkeys } from './composables';
31
32
 
32
- export default {
33
- name: 'ColorPicker',
33
+ const props = defineProps({
34
+ value: {
35
+ type: String,
36
+ required: true
37
+ }
38
+ });
34
39
 
35
- components: {
36
- ZipifyColorPicker
37
- },
40
+ const emit = defineEmits(['change']);
38
41
 
39
- directives: {
40
- outClick
41
- },
42
+ const favoriteColorsService = inject(InjectionTokens.FAVORITE_COLORS);
43
+ const editor = inject(InjectionTokens.EDITOR);
44
+ const pickerRef = ref(null);
42
45
 
43
- props: {
44
- value: {
45
- type: String,
46
- required: true
47
- }
46
+ const api = usePickerApi({
47
+ onChange: (color) => {
48
+ emit('change', color);
49
+ editor.chain().focus().restoreSelection().run();
48
50
  },
51
+ onClosed: () => editor.commands.restoreSelection(),
52
+ onBeforeOpened: () => editor.commands.storeSelection(),
53
+ colorRef: toRef(props, 'value'),
54
+ pickerRef
55
+ });
56
+ const isOpenedRef = toRef(api, 'isOpened');
49
57
 
50
- setup(props, { emit }) {
51
- const favoriteColors = inject(InjectionTokens.FAVORITE_COLORS);
52
- const editor = inject(InjectionTokens.EDITOR);
53
- const pickerRef = ref(null);
54
-
55
- const api = usePickerApi({
56
- onChange: (color) => {
57
- emit('change', color);
58
- editor.chain().focus().restoreSelection().run();
59
- },
60
- onClosed: () => editor.commands.restoreSelection(),
61
- onBeforeOpened: () => editor.commands.storeSelection(),
62
- colorRef: toRef(props, 'value'),
63
- pickerRef
64
- });
65
- const isOpenedRef = toRef(api, 'isOpened');
58
+ usePickerHotkeys({
59
+ isOpenedRef,
60
+ onCancel: api.cancel,
61
+ onApply: api.close
62
+ });
66
63
 
67
- usePickerHotkeys({
68
- isOpenedRef,
69
- onCancel: api.cancel,
70
- onApply: api.close
71
- });
72
-
73
- const updateFavoriteColors = (colors) => favoriteColors.triggerUpdate(colors);
74
-
75
- return {
76
- pickerRef,
77
- api,
78
- favoriteColors: favoriteColors.listRef,
79
- updateFavoriteColors,
80
- contextWindow: ContextWindow.window
81
- };
82
- }
83
- };
64
+ const favoriteColors = computed(() => unref(favoriteColorsService.listRef));
65
+ const updateFavoriteColors = (colors) => favoriteColorsService.triggerUpdate(colors);
84
66
  </script>
@@ -21,8 +21,10 @@ function createWrapper({ hostEl, editor } = {}) {
21
21
  return withComponentContext(() => {
22
22
  return useDeselectionLock({ hostRef: ref(hostEl), isActiveRef: ref(true) });
23
23
  }, {
24
- provide: {
25
- [InjectionTokens.EDITOR]: editor ?? createEditor({ isFocused: true })
24
+ global: {
25
+ provide: {
26
+ [InjectionTokens.EDITOR]: editor ?? createEditor({ isFocused: true })
27
+ }
26
28
  }
27
29
  });
28
30
  }
@@ -23,7 +23,9 @@ function createWrapper() {
23
23
  modalRef: elementRef
24
24
  });
25
25
  }, {
26
- provide: { [InjectionTokens.EDITOR]: createEditor() }
26
+ global: {
27
+ provide: { [InjectionTokens.EDITOR]: createEditor() }
28
+ }
27
29
  });
28
30
  }
29
31
 
@@ -4,7 +4,9 @@ import { withComponentContext } from '../../../../__tests__/utils';
4
4
 
5
5
  function useComposable({ scrollerEl }) {
6
6
  return withComponentContext(() => useScrollView(), {
7
- provide: { [SCROLL_VIEW]: ref(scrollerEl) }
7
+ global: {
8
+ provide: { [SCROLL_VIEW]: ref(scrollerEl) }
9
+ }
8
10
  });
9
11
  }
10
12
 
@@ -16,7 +16,7 @@
16
16
  </div>
17
17
  </template>
18
18
 
19
- <script>
19
+ <script setup>
20
20
  import { provide, toRef, ref } from 'vue';
21
21
  import Modal from '../Modal';
22
22
  import { useModalToggler } from '../composables';
@@ -25,70 +25,50 @@ import DropdownActivator from './DropdownActivator';
25
25
  import DropdownMenu from './DropdownMenu';
26
26
  import { useActiveOptionManager } from './composables';
27
27
 
28
- export default {
29
- name: 'Dropdown',
30
-
31
- components: {
32
- Modal,
33
- DropdownActivator,
34
- DropdownMenu
28
+ const props = defineProps({
29
+ value: {
30
+ type: [String, Number],
31
+ required: false,
32
+ default: null
35
33
  },
36
34
 
37
- model: {
38
- event: 'change'
35
+ options: {
36
+ type: Array,
37
+ required: true
39
38
  },
40
39
 
41
- props: {
42
- value: {
43
- type: [String, Number],
44
- required: false,
45
- default: null
46
- },
47
-
48
- options: {
49
- type: Array,
50
- required: true
51
- },
52
-
53
- maxWidth: {
54
- type: Number,
55
- required: false,
56
- default: 156
57
- },
58
-
59
- color: {
60
- type: String,
61
- required: false,
62
- default: 'none'
63
- }
40
+ maxWidth: {
41
+ type: Number,
42
+ required: false,
43
+ default: 156
64
44
  },
65
45
 
66
- setup(props, { emit }) {
67
- const dropdownRef = ref(null);
68
- const modalRef = ref(null);
46
+ color: {
47
+ type: String,
48
+ required: false,
49
+ default: 'none'
50
+ }
51
+ });
69
52
 
70
- const activeOptionManager = useActiveOptionManager({
71
- optionsRef: toRef(props, 'options'),
72
- inputRef: toRef(props, 'value'),
73
- stateless: props.value === null,
74
- onChange: (value) => emit('change', value.id)
75
- });
53
+ const emit = defineEmits(['change']);
76
54
 
77
- const toggler = useModalToggler({
78
- wrapperRef: dropdownRef,
79
- modalRef
80
- });
55
+ const dropdownRef = ref(null);
56
+ const modalRef = ref(null);
81
57
 
82
- provide(InjectionTokens.ACTIVE_MANAGER, activeOptionManager);
83
- provide(InjectionTokens.TOGGLER, toggler);
58
+ const activeOptionManager = useActiveOptionManager({
59
+ optionsRef: toRef(props, 'options'),
60
+ inputRef: toRef(props, 'value'),
61
+ stateless: props.value === null,
62
+ onChange: (value) => emit('change', value.id)
63
+ });
84
64
 
85
- return {
86
- dropdownRef,
87
- modalRef,
88
- toggler
89
- };
90
- }
91
- };
65
+ const toggler = useModalToggler({
66
+ wrapperRef: dropdownRef,
67
+ modalRef
68
+ });
69
+
70
+ provide(InjectionTokens.ACTIVE_MANAGER, activeOptionManager);
71
+ provide(InjectionTokens.TOGGLER, toggler);
92
72
  </script>
93
73
 
94
74
  <style scoped>
@@ -1,80 +1,52 @@
1
1
  <template>
2
- <div>
3
- <slot :open="open" :isOpened="isOpened">
4
- <Button
5
- skin="toolbar"
6
- class="zw-dropdown__activator"
7
- :class="dropdownClasses"
8
- :active="isOpened"
9
- @click="open"
10
- >
11
- <span class="zw-dropdown__activator-title zw-text--truncate">
12
- {{ activeOptionTitle }}
13
- </span>
14
-
15
- <Icon
16
- class="zw-dropdown__activator-arrow"
17
- name="arrow"
18
- size="8px"
19
- auto-color
20
- />
21
- </Button>
22
- </slot>
23
- </div>
2
+ <slot :open="dropdownToggler.open" :isOpened="isOpened">
3
+ <Button
4
+ skin="toolbar"
5
+ class="zw-dropdown__activator"
6
+ :class="dropdownClasses"
7
+ :active="isOpened"
8
+ @click="dropdownToggler.open"
9
+ >
10
+ <span class="zw-dropdown__activator-title zw-text--truncate">
11
+ {{ activeOptionTitle }}
12
+ </span>
13
+
14
+ <Icon
15
+ class="zw-dropdown__activator-arrow"
16
+ name="arrow"
17
+ size="8px"
18
+ auto-color
19
+ />
20
+ </Button>
21
+ </slot>
24
22
  </template>
25
23
 
26
- <script>
27
- import { computed, inject, toRef } from 'vue';
24
+ <script setup>
25
+ import { computed, inject, toRef, unref } from 'vue';
28
26
  import Button from '../Button';
29
27
  import Icon from '../Icon';
30
- import { tooltip } from '../../../directives';
31
28
  import { InjectionTokens } from './injectionTokens';
32
29
  import { useDropdownEntityTitle } from './composables';
33
30
 
34
- export default {
35
- name: 'DropdownActivator',
36
-
37
- components: {
38
- Icon,
39
- Button
40
- },
41
-
42
- directives: {
43
- tooltip
44
- },
45
-
46
- model: {
47
- event: 'change'
48
- },
49
-
50
- props: {
51
- color: {
52
- type: String,
53
- required: false,
54
- default: 'none'
55
- }
56
- },
57
-
58
- setup(props) {
59
- const activeOptionManager = inject(InjectionTokens.ACTIVE_MANAGER);
60
- const dropdownToggler = inject(InjectionTokens.TOGGLER);
61
- const color = toRef(props, 'color');
31
+ const props = defineProps({
32
+ color: {
33
+ type: String,
34
+ required: false,
35
+ default: 'none'
36
+ }
37
+ });
62
38
 
63
- const activeOptionTitle = useDropdownEntityTitle(activeOptionManager.activeOption);
39
+ const activeOptionManager = inject(InjectionTokens.ACTIVE_MANAGER);
40
+ const dropdownToggler = inject(InjectionTokens.TOGGLER);
41
+ const isOpened = computed(() => unref(dropdownToggler.isOpened));
42
+ const color = toRef(props, 'color');
64
43
 
65
- const dropdownClasses = computed(() => ({
66
- 'zw-dropdown__activator--active': dropdownToggler.isOpened.value,
67
- 'zw-dropdown__activator--gray': color.value === 'gray'
68
- }));
44
+ const activeOptionTitle = useDropdownEntityTitle(activeOptionManager.activeOption);
69
45
 
70
- return {
71
- activeOptionTitle,
72
- isOpened: dropdownToggler.isOpened,
73
- open: dropdownToggler.open,
74
- dropdownClasses
75
- };
76
- }
77
- };
46
+ const dropdownClasses = computed(() => ({
47
+ 'zw-dropdown__activator--active': dropdownToggler.isOpened.value,
48
+ 'zw-dropdown__activator--gray': color.value === 'gray'
49
+ }));
78
50
  </script>
79
51
 
80
52
  <style scoped>
@@ -2,12 +2,6 @@
2
2
  <div class="zw-dropdown__divider" />
3
3
  </template>
4
4
 
5
- <script>
6
- export default {
7
- name: 'DropdownDivider'
8
- };
9
- </script>
10
-
11
5
  <style scoped>
12
6
  .zw-dropdown__divider {
13
7
  padding: 0 var(--zw-offset-sm);
@@ -10,31 +10,19 @@
10
10
  </div>
11
11
  </template>
12
12
 
13
- <script>
13
+ <script setup>
14
14
  import { toRef } from 'vue';
15
15
  import DropdownOption from './DropdownOption';
16
16
  import { useDropdownEntityTitle } from './composables';
17
17
 
18
- export default {
19
- name: 'DropdownGroup',
20
-
21
- components: {
22
- DropdownOption
23
- },
24
-
25
- props: {
26
- group: {
27
- type: Object,
28
- required: true
29
- }
30
- },
31
-
32
- setup(props) {
33
- const groupTitle = useDropdownEntityTitle(toRef(props, 'group'));
34
-
35
- return { groupTitle };
18
+ const props = defineProps({
19
+ group: {
20
+ type: Object,
21
+ required: true
36
22
  }
37
- };
23
+ });
24
+
25
+ const groupTitle = useDropdownEntityTitle(toRef(props, 'group'));
38
26
  </script>
39
27
 
40
28
  <style scoped>
@@ -23,7 +23,7 @@
23
23
  </ScrollView>
24
24
  </template>
25
25
 
26
- <script>
26
+ <script setup>
27
27
  import { provide } from 'vue';
28
28
  import ScrollView from '../ScrollView';
29
29
  import { InjectionTokens } from './injectionTokens';
@@ -31,27 +31,14 @@ import DropdownGroup from './DropdownGroup';
31
31
  import DropdownOption from './DropdownOption';
32
32
  import DropdownDivider from './DropdownDivider';
33
33
 
34
- export default {
35
- name: 'DropdownMenu',
36
-
37
- components: {
38
- ScrollView,
39
- DropdownGroup,
40
- DropdownOption,
41
- DropdownDivider
42
- },
43
-
44
- props: {
45
- options: {
46
- type: Array,
47
- required: true
48
- }
49
- },
50
-
51
- setup() {
52
- provide(InjectionTokens.SESSION, {});
34
+ defineProps({
35
+ options: {
36
+ type: Array,
37
+ required: true
53
38
  }
54
- };
39
+ });
40
+
41
+ provide(InjectionTokens.SESSION, {});
55
42
  </script>
56
43
 
57
44
  <style>