@webitel/ui-sdk 24.12.66 → 24.12.68

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webitel/ui-sdk",
3
- "version": "24.12.66",
3
+ "version": "24.12.68",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "dev": "vite",
@@ -6,7 +6,7 @@ describe('WtPopup', () => {
6
6
  const wrapper = shallowMount(WtPopup, {
7
7
  stubs: { WtIconBtn: true },
8
8
  });
9
- expect(wrapper.classes('wt-popup')).toBe(true);
9
+ expect(wrapper.exists()).toBe(true);
10
10
  });
11
11
 
12
12
  it('renders popup header via header slot', () => {
@@ -1,12 +1,25 @@
1
1
  <template>
2
+ <!-- @slot check source code for scoped bindings :( -->
3
+ <slot
4
+ class="wt-popup-activator"
5
+ name="activator"
6
+ v-bind="{
7
+ shown: wrapperShown,
8
+ size,
9
+ disabled,
10
+ open: openPopup,
11
+ close: closePopup,
12
+ toggle: togglePopup,
13
+ } as ActivatorSlotScope"
14
+ />
2
15
  <div
3
- v-show="wrapperShown"
16
+ v-show="wrapperShown || isCloseAnimationPlaying"
4
17
  :class="[`wt-popup--size-${size}`, { 'wt-popup--overflow': overflow }]"
5
18
  class="wt-popup"
6
19
  >
7
20
  <transition-slide :offset="[0, -1440 / 2]">
8
21
  <aside
9
- v-if="shown"
22
+ v-if="wrapperShown"
10
23
  class="wt-popup__popup"
11
24
  >
12
25
  <header class="wt-popup__header">
@@ -18,7 +31,7 @@
18
31
  <wt-icon-btn
19
32
  class="wt-popup__close-btn"
20
33
  icon="close"
21
- @click="$emit('close')"
34
+ @click="closePopup"
22
35
  />
23
36
  </header>
24
37
  <section
@@ -38,49 +51,120 @@
38
51
  </div>
39
52
  </template>
40
53
 
41
- <script>
42
- import { TransitionSlide } from '@morev/vue-transitions';
54
+ <script lang="ts" setup>
55
+ import {TransitionSlide} from '@morev/vue-transitions';
56
+ import {defineEmits, defineProps, ref, watch} from 'vue';
43
57
 
44
- export default {
45
- name: 'WtPopup',
46
- components: {
47
- TransitionSlide,
48
- },
49
- props: {
50
- shown: {
51
- type: Boolean,
52
- default: true, // TODO: change me to false after refactor
53
- },
54
- size: {
55
- type: String,
56
- default: 'md',
57
- validator: (v) => ['xs', 'sm', 'md', 'lg'].includes(v),
58
- },
59
- overflow: {
60
- type: Boolean,
61
- default: false,
62
- },
63
- },
64
- emits: ['close'],
65
- data: () => ({
66
- wrapperShown: false,
67
- }),
68
- watch: {
69
- // overlay should be shown before popup to show animation properly
70
- shown: {
71
- handler(value) {
72
- if (value) {
73
- this.wrapperShown = true;
74
- } else {
75
- setTimeout(() => {
76
- this.wrapperShown = value;
77
- }, 200); // 200 -> 0.2s css var(--transition); duration
78
- }
79
- },
80
- immediate: true,
81
- },
82
- },
58
+ import {ComponentSize} from "../../enums/ComponentSize/ComponentSize.enum.ts";
59
+
60
+ interface Props {
61
+ /**
62
+ * can be used to force popup visibility state
63
+ * even if it is controlled by activator slot
64
+ */
65
+ shown?: boolean;
66
+ size?: ComponentSize;
67
+ /**
68
+ * if true, popup contents will overflow popup container, without scrolling
69
+ * useful for small popups with select components, which have not enough space
70
+ * to show its dropdown content without scrolling the popup
71
+ */
72
+ overflow?: boolean;
73
+ /**
74
+ * disable popup visibility
75
+ * __even if `shown` prop is "true"__
76
+ */
77
+ disabled?: boolean;
78
+ }
79
+
80
+ const props = withDefaults(defineProps<Props>(), {
81
+ shown: true, // TODO: change me to false after refactor
82
+ size: ComponentSize.MD,
83
+ overflow: false,
84
+ disabled: false,
85
+ });
86
+
87
+ const emit = defineEmits<{
88
+ /**
89
+ * popup header "close" button clicked
90
+ */
91
+ close: [];
92
+ 'popup:opened': [];
93
+ 'popup:closed': [];
94
+ }>();
95
+
96
+ interface ActivatorSlotScope {
97
+ shown: Props['shown'];
98
+ size: Props['size'];
99
+ disabled: Props['disabled'];
100
+ open: () => void;
101
+ close: () => void;
102
+ toggle: () => void;
103
+ }
104
+
105
+ const slots = defineSlots<{
106
+ activator?: ActivatorSlotScope;
107
+ }>();
108
+
109
+ const wrapperShown = ref(false);
110
+ const isCloseAnimationPlaying = ref(false);
111
+
112
+
113
+ const openPopup = () => {
114
+ wrapperShown.value = true;
115
+ };
116
+
117
+ const closePopup = () => {
118
+ isCloseAnimationPlaying.value = true;
119
+ wrapperShown.value = false;
120
+
121
+ setTimeout(() => {
122
+ isCloseAnimationPlaying.value = false;
123
+ }, 200); // 200 -> 0.2s css var(--transition); duration
83
124
  };
125
+
126
+ const togglePopup = () => {
127
+ if (wrapperShown.value) {
128
+ closePopup();
129
+ } else {
130
+ openPopup();
131
+ }
132
+ };
133
+
134
+ // overlay should be shown before popup to show animation properly
135
+ watch(
136
+ () => props.shown,
137
+ (value) => {
138
+
139
+ /*
140
+ * prop shown default value =true is used to allow backwards compatibility with
141
+ * older wt-popup API, when popup visibility was controlled simply by v-if
142
+ *
143
+ * however, in latest component API design using activator slot is recommended,
144
+ * but if that's so, there's no `shown` prop => it's true by default => popup is initially shown
145
+ * so we need to handle initial popup visibility depending on activator slot presence
146
+ */
147
+ const activatorMode = !!slots.activator;
148
+ if (activatorMode) return;
149
+
150
+
151
+ if (value) {
152
+ openPopup();
153
+ } else {
154
+ closePopup();
155
+ }
156
+ },
157
+ {immediate: true}
158
+ );
159
+
160
+ watch(wrapperShown, (value) => {
161
+ if (value) {
162
+ emit('popup:opened');
163
+ } else {
164
+ emit('popup:closed');
165
+ }
166
+ });
167
+
84
168
  </script>
85
169
 
86
170
  <style lang="scss">
@@ -1,4 +1,5 @@
1
1
  import { mount, shallowMount } from '@vue/test-utils';
2
+
2
3
  import WtTableColumnSelect from '../wt-table-column-select.vue';
3
4
 
4
5
  describe('WtTableColumnSelect', () => {
@@ -26,6 +27,6 @@ describe('WtTableColumnSelect', () => {
26
27
  });
27
28
  wrapper.findComponent({ name: 'wt-icon-btn' }).vm.$emit('click');
28
29
  await wrapper.vm.$nextTick();
29
- expect(wrapper.find('.wt-table-column-select__popup').exists()).toBe(true);
30
+ expect(wrapper.find('.wt-popup').exists()).toBe(true);
30
31
  });
31
32
  });
@@ -10,4 +10,6 @@ const ComponentSize = Object.freeze({
10
10
  XXXL: '3xl',
11
11
  });
12
12
 
13
+ export { ComponentSize };
14
+
13
15
  export default ComponentSize;
@@ -0,0 +1,11 @@
1
+ export enum ComponentSize {
2
+ XXXS = '3xs',
3
+ XXS = '2xs',
4
+ XS = 'xs',
5
+ SM = 'sm',
6
+ MD = 'md',
7
+ LG = 'lg',
8
+ XL = 'xl',
9
+ XXL = '2xl',
10
+ XXXL = '3xl',
11
+ }
@@ -1,12 +1,4 @@
1
- import ComponentSize from '../enums/ComponentSize/ComponentSize.enum.js';
2
-
3
- export enum eComponentSize {
4
- XS = 'xs',
5
- SM = 'sm',
6
- MD = 'md',
7
- LG = 'lg',
8
- XL = 'xl',
9
- }
1
+ import {ComponentSize} from '../enums/ComponentSize/ComponentSize.enum.ts';
10
2
 
11
3
  const numerics = Object.values(ComponentSize).reduce((nums, size, index) => {
12
4
  return {
@@ -68,8 +60,8 @@ export const greaterThen = (s1, s2) => {
68
60
  * @returns {boolean}
69
61
  */
70
62
  export const greaterOrEqual = (
71
- s1: eComponentSize,
72
- s2: eComponentSize,
63
+ s1: ComponentSize,
64
+ s2: ComponentSize,
73
65
  ): boolean => {
74
66
  return compareSize(s1, s2) >= 0;
75
67
  };