@policystudio/policy-studio-ui-vue 1.1.90-beta.74 → 1.1.90-beta.76
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.
|
@@ -4013,25 +4013,9 @@ video {
|
|
|
4013
4013
|
min-height: 27px;
|
|
4014
4014
|
font-size: 0.875rem;
|
|
4015
4015
|
}
|
|
4016
|
-
.psui-el-dropdown-menu button:focus {
|
|
4017
|
-
outline: none;
|
|
4018
|
-
box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5);
|
|
4019
|
-
}
|
|
4020
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4021
|
-
position: fixed;
|
|
4022
|
-
}
|
|
4023
4016
|
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4024
4017
|
z-index: 50;
|
|
4025
4018
|
}
|
|
4026
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4027
|
-
display: none;
|
|
4028
|
-
}
|
|
4029
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4030
|
-
width: auto;
|
|
4031
|
-
}
|
|
4032
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4033
|
-
transform-origin: top right;
|
|
4034
|
-
}
|
|
4035
4019
|
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4036
4020
|
overflow: auto;
|
|
4037
4021
|
}
|
|
@@ -4042,28 +4026,11 @@ video {
|
|
|
4042
4026
|
--tw-bg-opacity: 1;
|
|
4043
4027
|
background-color: rgb(255, 255, 255, var(--tw-bg-opacity, 1));
|
|
4044
4028
|
}
|
|
4045
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4046
|
-
opacity: 0;
|
|
4047
|
-
}
|
|
4048
4029
|
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4049
4030
|
--tw-shadow: 0px 0px 8px rgba(0, 0, 0, 0.04), 0px 5px 6px rgba(0, 0, 0, 0.1);
|
|
4050
4031
|
--tw-shadow-colored: 0px 0px 8px var(--tw-shadow-color), 0px 5px 6px var(--tw-shadow-color);
|
|
4051
4032
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 rgba(0, 0, 0, 0)), var(--tw-ring-shadow, 0 0 rgba(0, 0, 0, 0)), var(--tw-shadow);
|
|
4052
4033
|
}
|
|
4053
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4054
|
-
transition-property: all;
|
|
4055
|
-
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
4056
|
-
transition-duration: 150ms;
|
|
4057
|
-
}
|
|
4058
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4059
|
-
transition-duration: 100ms;
|
|
4060
|
-
}
|
|
4061
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4062
|
-
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
|
|
4063
|
-
}
|
|
4064
|
-
.psui-el-dropdown-menu-dialog-wrapper-dialog {
|
|
4065
|
-
width: 100%;
|
|
4066
|
-
}
|
|
4067
4034
|
|
|
4068
4035
|
.psui-el-dropdown-menu-list {
|
|
4069
4036
|
margin-top: 1rem;
|
|
@@ -6560,10 +6527,6 @@ video {
|
|
|
6560
6527
|
transition-duration: 150ms;
|
|
6561
6528
|
}
|
|
6562
6529
|
|
|
6563
|
-
.psui-duration-300 {
|
|
6564
|
-
transition-duration: 300ms;
|
|
6565
|
-
}
|
|
6566
|
-
|
|
6567
6530
|
*:focus {
|
|
6568
6531
|
outline: none;
|
|
6569
6532
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@policystudio/policy-studio-ui-vue",
|
|
3
|
-
"version": "1.1.90-beta.
|
|
3
|
+
"version": "1.1.90-beta.76",
|
|
4
4
|
"description": "Policy Studio UI",
|
|
5
5
|
"author": "Policy Studio Team",
|
|
6
6
|
"scripts": {
|
|
@@ -15,10 +15,12 @@
|
|
|
15
15
|
"main": "dist/index.js",
|
|
16
16
|
"types": "src/types/index.d.ts",
|
|
17
17
|
"dependencies": {
|
|
18
|
+
"@floating-ui/vue": "^1.1.9",
|
|
18
19
|
"@vue/compat": "^3.4.5",
|
|
19
20
|
"core-js": "^3.6.5",
|
|
20
21
|
"v-tooltip": "^2.1.3",
|
|
21
|
-
"vue": "^3.4.5"
|
|
22
|
+
"vue": "^3.4.5",
|
|
23
|
+
"vue2-teleport": "^1.1.4"
|
|
22
24
|
},
|
|
23
25
|
"devDependencies": {
|
|
24
26
|
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
|
@@ -10,19 +10,10 @@
|
|
|
10
10
|
min-height: 27px;
|
|
11
11
|
font-size: 0.875rem;
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
&:focus {
|
|
15
|
-
outline: none;
|
|
16
|
-
box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5);
|
|
17
|
-
}
|
|
18
13
|
}
|
|
19
14
|
|
|
20
15
|
&-dialog-wrapper {
|
|
21
|
-
@apply psui-
|
|
22
|
-
|
|
23
|
-
&-dialog {
|
|
24
|
-
@apply psui-w-full;
|
|
25
|
-
}
|
|
16
|
+
@apply psui-bg-white psui-rounded-md psui-z-50 psui-shadow-elevation-20 psui-overflow-auto;
|
|
26
17
|
}
|
|
27
18
|
}
|
|
28
19
|
}
|
|
@@ -1,218 +1,120 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
ref="PSDropdown"
|
|
4
3
|
class="psui-el-dropdown-menu"
|
|
5
|
-
:class="{ 'is-open': show.value }"
|
|
6
|
-
v-click-outside="close"
|
|
7
4
|
>
|
|
8
5
|
<div
|
|
9
6
|
ref="PSDropdownTrigger"
|
|
10
|
-
|
|
11
|
-
@click="show && !toggleWhenActive ? '' : toggle($event)"
|
|
12
|
-
>
|
|
13
|
-
<slot name="dropdownTrigger" />
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
<button
|
|
17
|
-
v-else
|
|
18
|
-
@click="show && !toggleWhenActive ? '' : toggle($event)"
|
|
19
|
-
type="button"
|
|
20
|
-
:id="id.value"
|
|
21
|
-
aria-haspopup="true"
|
|
22
|
-
aria-expanded="true"
|
|
23
|
-
ref="PSDropdownTrigger"
|
|
7
|
+
@click="toggle"
|
|
24
8
|
>
|
|
25
9
|
<slot
|
|
26
|
-
v-if="
|
|
27
|
-
name="
|
|
10
|
+
v-if="$slots.dropdownTrigger"
|
|
11
|
+
name="dropdownTrigger"
|
|
28
12
|
/>
|
|
29
|
-
<
|
|
13
|
+
<button
|
|
30
14
|
v-else
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<slot name="items" />
|
|
44
|
-
</div>
|
|
15
|
+
type="button"
|
|
16
|
+
:aria-expanded="show"
|
|
17
|
+
>
|
|
18
|
+
<slot
|
|
19
|
+
v-if="show && $slots.buttonLabelOnShow"
|
|
20
|
+
name="buttonLabelOnShow"
|
|
21
|
+
/>
|
|
22
|
+
<slot
|
|
23
|
+
v-else
|
|
24
|
+
name="buttonLabel"
|
|
25
|
+
/>
|
|
26
|
+
</button>
|
|
45
27
|
</div>
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
<Teleport to="body">
|
|
31
|
+
<Transition name="fade">
|
|
32
|
+
<div
|
|
33
|
+
v-if="show"
|
|
34
|
+
ref="PSDropdownFloating"
|
|
35
|
+
role="menu"
|
|
36
|
+
class="psui-el-dropdown-menu-dialog-wrapper"
|
|
37
|
+
aria-orientation="vertical"
|
|
38
|
+
:style="floatingStyles"
|
|
39
|
+
v-click-outside="close"
|
|
40
|
+
>
|
|
41
|
+
<div class="psui-el-dropdown-menu-dialog">
|
|
42
|
+
<slot name="items" />
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</Transition>
|
|
46
|
+
</Teleport>
|
|
46
47
|
</div>
|
|
47
48
|
</template>
|
|
48
49
|
|
|
49
50
|
<script setup>
|
|
50
51
|
// Figma - 2.3 Dropdown with category divider https://www.figma.com/file/Tto8hrNlSfuPcwd1pfqogF/%E2%9A%A1%EF%B8%8F-Design-System?node-id=1768%3A64886
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
import {
|
|
53
|
+
useFloating,
|
|
54
|
+
autoUpdate,
|
|
55
|
+
offset,
|
|
56
|
+
flip,
|
|
57
|
+
shift,
|
|
58
|
+
size
|
|
59
|
+
} from '@floating-ui/vue'
|
|
60
|
+
|
|
61
|
+
import { ref, defineProps } from 'vue'
|
|
62
|
+
import Teleport from 'vue2-teleport'
|
|
60
63
|
|
|
61
64
|
const props = defineProps({
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
type:
|
|
67
|
-
default:
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* It's a boolean responsible for showing a slot within the html tag button.
|
|
71
|
-
*/
|
|
72
|
-
buttonLabelOnShow: {
|
|
73
|
-
type: Boolean,
|
|
74
|
-
default: false,
|
|
75
|
-
},
|
|
76
|
-
/**
|
|
77
|
-
* It's a property responsible for toggling the dropdown menu. default: true.
|
|
78
|
-
*/
|
|
79
|
-
toggleWhenActive: {
|
|
80
|
-
type: Boolean,
|
|
81
|
-
default: true,
|
|
82
|
-
},
|
|
83
|
-
/**
|
|
84
|
-
* Disable the toogle on click. default: false.
|
|
85
|
-
*/
|
|
86
|
-
disabled: {
|
|
87
|
-
type: Boolean,
|
|
88
|
-
default: false,
|
|
89
|
-
},
|
|
90
|
-
/**
|
|
91
|
-
* It sets the vertical and horizontal position.
|
|
92
|
-
*/
|
|
93
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment, vue/require-default-prop
|
|
94
|
-
position: {
|
|
95
|
-
type: String,
|
|
96
|
-
validator: (value) => ['custom'].includes(value),
|
|
97
|
-
},
|
|
65
|
+
disabled: {type: Boolean, default: false},
|
|
66
|
+
placement: { type: String, default: 'bottom-start' },
|
|
67
|
+
offsetVal: { type: Number, default: 4 },
|
|
68
|
+
dropdownWidth: {
|
|
69
|
+
type: Number,
|
|
70
|
+
default: null
|
|
71
|
+
}
|
|
98
72
|
})
|
|
99
73
|
|
|
100
74
|
const emit = defineEmits(['open', 'close'])
|
|
101
75
|
|
|
102
76
|
const show = ref(false)
|
|
103
|
-
const id = ref(randomString(8))
|
|
104
|
-
// const marginLeft = ref('-0px')
|
|
105
|
-
const scrollableParentEl = ref(null)
|
|
106
|
-
const PSDropdown = ref(null)
|
|
107
|
-
const PSDropdownDialog = ref(null)
|
|
108
|
-
const PSDropdownTrigger = ref(null)
|
|
109
77
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
78
|
+
const PSDropdownTrigger = ref(null)
|
|
79
|
+
const PSDropdownFloating = ref(null)
|
|
80
|
+
|
|
81
|
+
const { floatingStyles } = useFloating(PSDropdownTrigger, PSDropdownFloating, {
|
|
82
|
+
placement: props.placement,
|
|
83
|
+
whileElementsMounted: autoUpdate,
|
|
84
|
+
middleware: [
|
|
85
|
+
offset(props.offsetVal),
|
|
86
|
+
flip(),
|
|
87
|
+
shift(),
|
|
88
|
+
size({
|
|
89
|
+
apply({rects, elements}) {
|
|
90
|
+
const customWidth = props.dropdownWidth ?? rects.reference.width
|
|
91
|
+
Object.assign(elements.floating.style, {
|
|
92
|
+
width: `${customWidth}px`,
|
|
93
|
+
minWidth: 'fit-content'
|
|
94
|
+
})
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
],
|
|
117
98
|
})
|
|
118
99
|
|
|
119
|
-
const toggle = (event) => {
|
|
120
|
-
if (props.disabled) return
|
|
121
|
-
if (!show.value) {
|
|
122
|
-
open()
|
|
123
|
-
} else {
|
|
124
|
-
close()
|
|
125
|
-
}
|
|
126
|
-
event.stopPropagation()
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const handleEsc = (evt) => {
|
|
130
|
-
if (show.value && evt.keyCode === 27) close()
|
|
131
|
-
}
|
|
132
|
-
|
|
133
100
|
const open = () => {
|
|
134
|
-
emit('open')
|
|
135
101
|
show.value = true
|
|
136
|
-
|
|
137
|
-
PSDropdownDialog.value.style.opacity = 0
|
|
138
|
-
PSDropdownDialog.value.style.display = 'block'
|
|
139
|
-
}
|
|
140
|
-
setTimeout(() => {
|
|
141
|
-
updatePosition()
|
|
142
|
-
watchParentScrolling()
|
|
143
|
-
document.addEventListener('keyup', handleEsc)
|
|
144
|
-
window.addEventListener('resize', updatePosition)
|
|
145
|
-
// window.addEventListener('click', clickOutside)
|
|
146
|
-
}, 10)
|
|
102
|
+
emit('open')
|
|
147
103
|
}
|
|
148
104
|
|
|
149
105
|
const close = () => {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (PSDropdownDialog.value !== null) {
|
|
153
|
-
PSDropdownDialog.value.style.display = 'none'
|
|
154
|
-
PSDropdownDialog.value.style.opacity = 0
|
|
155
|
-
}
|
|
156
|
-
show.value = false
|
|
157
|
-
unwatchParentScrolling()
|
|
158
|
-
}
|
|
159
|
-
document.removeEventListener('keyup', handleEsc)
|
|
160
|
-
document.removeEventListener('resize', updatePosition)
|
|
161
|
-
// document.removeEventListener('click', clickOutside)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const watchParentScrolling = () => {
|
|
165
|
-
scrollableParentEl.value = getParentScrollableEl(PSDropdown.value)
|
|
166
|
-
if (scrollableParentEl.value) {
|
|
167
|
-
scrollableParentEl.value.addEventListener('scroll', updatePosition)
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const unwatchParentScrolling = () => {
|
|
172
|
-
if (scrollableParentEl.value) {
|
|
173
|
-
scrollableParentEl.value.removeEventListener('scroll', updatePosition())
|
|
174
|
-
}
|
|
106
|
+
show.value = false
|
|
107
|
+
emit('close')
|
|
175
108
|
}
|
|
176
109
|
|
|
177
|
-
const
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
-
const rectTrigger = PSDropdownTrigger.value.getBoundingClientRect()
|
|
181
|
-
const rectDialog = PSDropdownDialog.value.getBoundingClientRect()
|
|
182
|
-
const windowWidth = document.documentElement.clientWidth
|
|
183
|
-
|
|
184
|
-
PSDropdownDialog.value.style.position = 'fixed'
|
|
185
|
-
PSDropdownDialog.value.style.top = `${rectTrigger.y + rectTrigger.height}px`
|
|
186
|
-
PSDropdownDialog.value.style.minWidth = `${rectTrigger.width}px`
|
|
187
|
-
|
|
188
|
-
if (rectTrigger.x + rectDialog.width + 20 > windowWidth) {
|
|
189
|
-
PSDropdownDialog.value.style.left = `${windowWidth - rectDialog.width - 30}px`
|
|
190
|
-
} else {
|
|
191
|
-
PSDropdownDialog.value.style.left = `${rectTrigger.x}px`
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (props.position == 'custom') {
|
|
195
|
-
PSDropdownDialog.value.style.top = `${rectTrigger.y}px`
|
|
196
|
-
PSDropdownDialog.value.style.left = `${rectTrigger.x + 100}px`
|
|
197
|
-
}
|
|
110
|
+
const toggle = (event) => {
|
|
111
|
+
if (props.disabled) return
|
|
198
112
|
|
|
199
|
-
if (
|
|
200
|
-
close()
|
|
201
|
-
console.warn('The dropdown are too close from the top of the page')
|
|
202
|
-
return
|
|
203
|
-
}
|
|
113
|
+
if (event) event.stopPropagation()
|
|
204
114
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
PSDropdownDialog.value.style.opacity = 1
|
|
208
|
-
}
|
|
209
|
-
}, 10)
|
|
115
|
+
show.value ? close() : open()
|
|
116
|
+
|
|
210
117
|
}
|
|
211
118
|
|
|
212
|
-
|
|
213
|
-
if (!show.value) return
|
|
214
|
-
if (!PSDropdown.value == event.target || !PSDropdown.value?.contains(event.target)) {
|
|
215
|
-
close()
|
|
216
|
-
}
|
|
217
|
-
}
|
|
119
|
+
defineExpose({ open, close })
|
|
218
120
|
</script>
|