@teammodlr/ui-kit 2.2.2 → 2.3.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.
@@ -1,331 +1,207 @@
1
- <template>
2
- <Primitive
3
- as-child
4
- ref="wrapper">
5
-
6
- <DropdownTrigger
7
- ref="referenceRef"
8
- :class="computedReferenceClasses"
9
- @click="toggleDropdown">
10
- <slot />
11
- </DropdownTrigger>
12
-
13
- <DropdownWrapper>
14
- <Teleport :disabled="isNested" to="body">
15
- <transition
16
- :enter-active-class="scale.enterActive"
17
- :leave-active-class="scale.leaveActive"
18
- :enter-from-class="scale.enterFrom"
19
- :leave-to-class="scale.leaveTo">
20
- <div
21
- v-if="isOpen"
22
- ref="popper"
23
- :class="menuClasses"
24
- :style="{ zIndex: zIndex, maxHeight: maxHeight }">
25
- <slot name="menu" />
26
- </div>
27
- </transition>
28
- </Teleport>
29
- </DropdownWrapper>
30
- </Primitive>
31
- </template>
32
-
33
- <script lang="ts">
34
- import { usePopper } from '../../composables/usePopper';
35
- import type { Placement, VirtualElement } from '@popperjs/core';
36
- import { scale } from '../../styles/transitions.css';
37
- import {Primitive} from "../primative/primitive";
38
- import {
39
- defineComponent,
40
- inject,
41
- ref,
42
- type PropType,
43
- provide,
44
- watch,
45
- onMounted,
46
- nextTick,
47
- computed,
48
- toRef,
49
- reactive,
50
- watchEffect, type Ref
51
- } from 'vue';
52
- import { onClickOutside, useEventListener } from '@vueuse/core';
53
- import DropdownWrapper from './DropdownWrapper.vue';
54
- import { useLabel } from './hooks';
55
- import { useZIndex } from '../../composables/useZIndex';
56
- import type { DropdownState } from './symbol';
57
- import { DROPDOWN_STATE } from './symbol';
58
- import * as style from './style';
59
- import {createContext} from "../../utils/injection";
60
- import DropdownTrigger from "./DropdownTrigger.vue";
61
-
62
- interface DropdownContext {
63
- reference: Ref<HTMLElement | undefined>
64
- onReferenceChange: (element: HTMLElement | undefined) => void
65
- }
66
-
67
- export const [injectDropdownContext, provideDropdownContext] = createContext<DropdownContext>('Dropdown');
68
-
69
-
70
- export default defineComponent({
71
- name: 'Dropdown',
72
- components: {
73
- DropdownTrigger,
74
- DropdownWrapper,
75
- Primitive
76
- },
77
- props: {
78
- open: {
79
- type: Boolean,
80
- default: false
81
- },
82
- placement: {
83
- type: String as PropType<Placement>,
84
- default: 'bottom-start'
85
- },
86
- transfer: {
87
- type: Boolean,
88
- default: false
89
- },
90
- trigger: {
91
- type: String as PropType<'click' | 'hover'>,
92
- default: 'click'
93
- },
94
- virtual: {
95
- type: [Object],
96
- default: null
97
- },
98
- x: {
99
- type: Number,
100
- default: 0
101
- },
102
- y: {
103
- type: Number,
104
- default: 0
105
- },
106
- label: {
107
- default: null,
108
- static: true
109
- },
110
- transitionName: {
111
- type: String,
112
- default: 'fade'
113
- },
114
- onSelect: {
115
- type: Function as PropType<(labels: any) => void>,
116
- default: () => {}
117
- },
118
- zIndex: {
119
- type: Number
120
- }
121
- },
122
- emits: ['update:open'],
123
- setup(props, { emit }) {
124
- const parentState = inject(DROPDOWN_STATE, null);
125
- const { nextZIndex } = useZIndex();
126
- const isNested = !!parentState;
127
- const label = toRef(props, 'label');
128
- const isOpen = ref(props.open);
129
- const placement = ref(props.placement);
130
- const transfer = toRef(props, 'transfer');
131
- const wrapper = ref(null);
132
- const referenceRef = ref<HTMLElement>();
133
- const zIndex = ref(props.zIndex ?? nextZIndex());
134
- const reference = computed(() => {
135
- if (props.virtual !== null) {
136
- const virtual = (props.virtual as any).$el ?? props.virtual;
137
- if (virtual) {
138
- if ('getBoundingClientRect' in virtual) {
139
- return virtual as VirtualElement;
140
- }
141
-
142
- if ('x' in virtual && 'y' in virtual) {
143
- return {
144
- getBoundingClientRect: () => ({
145
- x: virtual.x,
146
- y: virtual.y,
147
- left: virtual.x,
148
- top: virtual.y,
149
- width: 0,
150
- height: 0
151
- })
152
- } as VirtualElement;
153
- }
154
- }
155
- }
156
-
157
- return referenceRef.value;
158
- });
159
-
160
- provideDropdownContext({
161
- reference: referenceRef,
162
- onReferenceChange: element => referenceRef.value = element
163
- });
164
-
165
- const { popper, transferTo, updatePopper } = usePopper({
166
- reference: reference,
167
- placement,
168
- transfer,
169
- wrapper,
170
- isDrop: true,
171
- offset: isNested ? [-2, 2] : [0, 14]
172
- });
173
-
174
- const currentLabel = useLabel(label, referenceRef);
175
-
176
- provide('dropdown-select', null);
177
-
178
- const startState: DropdownState = reactive({
179
- handleSelect: handleSelect,
180
- isOpen: isOpen
181
- });
182
-
183
- provide(DROPDOWN_STATE, startState);
184
-
185
- watch(
186
- () => props.open,
187
- value => {
188
- isOpen.value = value;
189
- }
190
- );
191
-
192
- watch(
193
- () => props.placement,
194
- value => {
195
- setPlacement(value);
196
- }
197
- );
198
-
199
- watch(isOpen, value => {
200
- if (value) {
201
- updatePopper();
202
- }
203
-
204
- emit('update:open', value);
205
- });
206
-
207
- onMounted(() => {
208
- nextTick(() => {
209
- setPlacement(props.placement);
210
- });
211
- });
212
-
213
- useEventListener('resize', () => {
214
- updatePopper();
215
- });
216
-
217
- onClickOutside(wrapper, e => {
218
- let parent = e.target as HTMLElement;
219
-
220
- let i = 0;
221
- while (parent) {
222
- if (parent.classList.contains('m-dropdown-menu')) {
223
- return;
224
- }
225
- parent = parent.parentElement as HTMLElement;
226
-
227
- if (i > 10) {
228
- break;
229
- }
230
- i++;
231
- }
232
-
233
- isOpen.value = false;
234
- });
235
-
236
- function setPlacement(value: Placement) {
237
- const [xPlacement] = value.split('-');
238
-
239
- if (isNested && xPlacement !== 'right' && xPlacement !== 'left') {
240
- placement.value = 'right-start';
241
- } else {
242
- placement.value = value;
243
- }
244
- }
245
-
246
- function toggleDropdown() {
247
- isOpen.value = !isOpen.value;
248
- }
249
-
250
- function handleSelect(labels: string[]) {
251
- isOpen.value = false;
252
- props.onSelect(labels);
253
- if (typeof parentState?.handleSelect === 'function') {
254
- // @ts-ignore
255
- parentState.handleSelect([currentLabel.value!, ...labels]);
256
- }
257
- }
258
-
259
- const computedWrapperClasses = computed(() => {
260
- return [
261
- 'm-dropdown',
262
- {
263
- 'm-dropdown--open': isOpen.value,
264
- 'm-dropdown--nested': isNested
265
- }
266
- ];
267
- });
268
-
269
- const computedReferenceClasses = computed(() => {});
270
-
271
- const menuClasses = computed(() => {
272
- return ['m-dropdown-menu', style.menu];
273
- });
274
-
275
- const transitionName = computed(() => {
276
- return `m-transition__${props.transitionName}`;
277
- });
278
-
279
- const maxHeight = ref('auto');
280
- useEventListener(window, 'resize', () => {
281
- if (isOpen.value) {
282
- resize();
283
- updatePopper();
284
- }
285
- });
286
-
287
- watchEffect(() => {
288
- resize();
289
- });
290
-
291
- function resize() {
292
- if (!isOpen.value || !reference.value) {
293
- maxHeight.value = 'auto';
294
- return;
295
- }
296
-
297
- // @ts-ignore
298
- const referenceElement = reference.value.$el.getBoundingClientRect()
299
- const referenceHeight = referenceElement.height;
300
-
301
- const referenceTop = referenceElement.top;
302
- if (!referenceHeight || !referenceTop) {
303
- return;
304
- }
305
- let windowHeight = window.innerHeight;
306
-
307
- maxHeight.value = `${
308
- windowHeight - referenceHeight - referenceTop - 30
309
- }px`;
310
- }
311
-
312
- return {
313
- wrapper,
314
- referenceRef,
315
- popper,
316
- transferTo,
317
- isOpen,
318
- isNested,
319
- placement,
320
- menuClasses,
321
- computedWrapperClasses,
322
- computedReferenceClasses,
323
- transitionName,
324
- toggleDropdown,
325
- zIndex,
326
- scale,
327
- maxHeight
328
- };
329
- }
330
- });
331
- </script>
1
+ <template>
2
+ <ContextMenuRoot v-if="contextMenu">
3
+ <ContextMenuTrigger as-child>
4
+ <slot />
5
+ </ContextMenuTrigger>
6
+ <ContextMenuPortal>
7
+ <ContextMenuContent :align="placement" :class="menuClasses" :side-offset="5">
8
+ <slot name="menu" />
9
+ </ContextMenuContent>
10
+ </ContextMenuPortal>
11
+ </ContextMenuRoot>
12
+ <DropdownMenuRoot v-model:open="isOpen" v-else :modal="modal">
13
+ <DropdownMenuTrigger as-child>
14
+ <slot />
15
+ </DropdownMenuTrigger>
16
+ <DropdownMenuPortal>
17
+ <DropdownMenuContent :align="placement" :class="menuClasses" :side-offset="5">
18
+ <slot name="menu" />
19
+ </DropdownMenuContent>
20
+ </DropdownMenuPortal>
21
+ </DropdownMenuRoot>
22
+ </template>
23
+
24
+ <script lang="ts">
25
+ import {
26
+ DropdownMenuArrow,
27
+ DropdownMenuCheckboxItem,
28
+ DropdownMenuContent,
29
+ DropdownMenuItem,
30
+ DropdownMenuItemIndicator,
31
+ DropdownMenuLabel,
32
+ DropdownMenuPortal,
33
+ DropdownMenuRadioGroup,
34
+ DropdownMenuRadioItem,
35
+ DropdownMenuRoot,
36
+ DropdownMenuSeparator,
37
+ DropdownMenuSub,
38
+ DropdownMenuSubContent,
39
+ DropdownMenuSubTrigger,
40
+ DropdownMenuTrigger,
41
+
42
+ ContextMenuCheckboxItem,
43
+ ContextMenuContent,
44
+ ContextMenuItem,
45
+ ContextMenuItemIndicator,
46
+ ContextMenuLabel,
47
+ ContextMenuPortal,
48
+ ContextMenuRadioGroup,
49
+ ContextMenuRadioItem,
50
+ ContextMenuRoot,
51
+ ContextMenuSeparator,
52
+ ContextMenuSub,
53
+ ContextMenuSubContent,
54
+ ContextMenuSubTrigger,
55
+ ContextMenuTrigger,
56
+ } from 'radix-vue';
57
+ import {
58
+ computed,
59
+ defineComponent,
60
+ ref,
61
+ watch,
62
+ type PropType
63
+ } from 'vue';
64
+ import { useZIndex } from '../../composables/useZIndex';
65
+ import { scale } from '../../styles/transitions.css';
66
+ import * as style from './style';
67
+ import { DROPDOWN_STATE } from './symbol';
68
+
69
+ export default defineComponent({
70
+ name: 'Dropdown',
71
+ components: {
72
+ DropdownMenuArrow,
73
+ DropdownMenuCheckboxItem,
74
+ DropdownMenuContent,
75
+ DropdownMenuItem,
76
+ DropdownMenuItemIndicator,
77
+ DropdownMenuLabel,
78
+ DropdownMenuPortal,
79
+ DropdownMenuRadioGroup,
80
+ DropdownMenuRadioItem,
81
+ DropdownMenuRoot,
82
+ DropdownMenuSeparator,
83
+ DropdownMenuSub,
84
+ DropdownMenuSubContent,
85
+ DropdownMenuSubTrigger,
86
+ DropdownMenuTrigger,
87
+
88
+ ContextMenuCheckboxItem,
89
+ ContextMenuContent,
90
+ ContextMenuItem,
91
+ ContextMenuItemIndicator,
92
+ ContextMenuLabel,
93
+ ContextMenuPortal,
94
+ ContextMenuRadioGroup,
95
+ ContextMenuRadioItem,
96
+ ContextMenuRoot,
97
+ ContextMenuSeparator,
98
+ ContextMenuSub,
99
+ ContextMenuSubContent,
100
+ ContextMenuSubTrigger,
101
+ ContextMenuTrigger,
102
+ },
103
+ props: {
104
+ open: {
105
+ type: Boolean,
106
+ default: false
107
+ },
108
+ modal: {
109
+ type: Boolean,
110
+ default: false
111
+ },
112
+ placement: {
113
+ type: String as PropType<"start" | "center" | "end">,
114
+ default: 'start'
115
+ },
116
+ transfer: {
117
+ type: Boolean,
118
+ default: false
119
+ },
120
+ trigger: {
121
+ type: String as PropType<'click' | 'hover'>,
122
+ default: 'click'
123
+ },
124
+ contextMenu: {
125
+ type: Boolean,
126
+ default: false
127
+ },
128
+ x: {
129
+ type: Number,
130
+ default: 0
131
+ },
132
+ y: {
133
+ type: Number,
134
+ default: 0
135
+ },
136
+ label: {
137
+ default: null,
138
+ static: true
139
+ },
140
+ transitionName: {
141
+ type: String,
142
+ default: 'fade'
143
+ },
144
+ onSelect: {
145
+ type: Function as PropType<(labels: any) => void>,
146
+ default: () => {}
147
+ },
148
+ zIndex: {
149
+ type: Number
150
+ }
151
+ },
152
+ emits: ['update:open'],
153
+ setup(props, { emit }) {
154
+ const { nextZIndex } = useZIndex();
155
+ const isOpen = ref(props.open);
156
+ const placement = ref(props.placement);
157
+ const wrapper = ref(null);
158
+ const referenceRef = ref<HTMLElement>();
159
+ const zIndex = ref(props.zIndex ?? nextZIndex());
160
+
161
+ watch(
162
+ () => props.open,
163
+ value => {
164
+ isOpen.value = value;
165
+ }
166
+ );
167
+
168
+ function toggleDropdown() {
169
+ isOpen.value = !isOpen.value;
170
+ }
171
+
172
+
173
+ const computedWrapperClasses = computed(() => {
174
+ return [
175
+ 'm-dropdown',
176
+ {
177
+ 'm-dropdown--open': isOpen.value
178
+ }
179
+ ];
180
+ });
181
+
182
+ const computedReferenceClasses = computed(() => {});
183
+
184
+ const menuClasses = computed(() => {
185
+ return ['m-dropdown-menu', style.menu];
186
+ });
187
+
188
+ const transitionName = computed(() => {
189
+ return `m-transition__${props.transitionName}`;
190
+ });
191
+
192
+ return {
193
+ wrapper,
194
+ referenceRef,
195
+ isOpen,
196
+ placement,
197
+ menuClasses,
198
+ computedWrapperClasses,
199
+ computedReferenceClasses,
200
+ transitionName,
201
+ toggleDropdown,
202
+ zIndex,
203
+ scale
204
+ };
205
+ }
206
+ });
207
+ </script>
@@ -1,23 +1,23 @@
1
- <template>
2
- <li :class="computedClasses">
3
- <slot />
4
- </li>
5
- </template>
6
-
7
- <script lang="ts">
8
- import { computed, defineComponent } from 'vue';
9
- import * as style from './style';
10
-
11
- export default defineComponent({
12
- name: 'DropdownHeading',
13
- setup() {
14
- const computedClasses = computed(() => {
15
- return [style.heading];
16
- });
17
-
18
- return {
19
- computedClasses
20
- };
21
- }
22
- });
23
- </script>
1
+ <template>
2
+ <div :class="computedClasses">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <script lang="ts">
8
+ import { computed, defineComponent } from 'vue';
9
+ import * as style from './style';
10
+
11
+ export default defineComponent({
12
+ name: 'DropdownHeading',
13
+ setup() {
14
+ const computedClasses = computed(() => {
15
+ return [style.heading];
16
+ });
17
+
18
+ return {
19
+ computedClasses
20
+ };
21
+ }
22
+ });
23
+ </script>