@policystudio/policy-studio-ui-vue 1.1.90-beta.2 → 1.1.90-beta.21
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/.eslintrc.js +13 -8
- package/.github/workflows/deploy-storybook.yml +4 -4
- package/.nvmrc +1 -0
- package/dist/css/psui_styles_output.css +6986 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +104 -0
- package/dist/index.js.map +1 -0
- package/dist/util/GeneralFunctions.d.ts +3 -0
- package/dist/util/GeneralFunctions.js +29 -0
- package/dist/util/GeneralFunctions.js.map +1 -0
- package/dist/util/directives.d.ts +1 -0
- package/dist/util/directives.js +22 -0
- package/dist/util/directives.js.map +1 -0
- package/dist/util/imageLoader.d.ts +6 -0
- package/dist/util/imageLoader.js +52 -0
- package/dist/util/imageLoader.js.map +1 -0
- package/package.json +24 -37
- package/src/App.vue +30 -0
- package/src/assets/scss/components/PsDataTable.scss +1 -1
- package/src/components/accordion/PsAccordionItem.vue +75 -75
- package/src/components/badges-and-tags/PsBadgeWithIcon.vue +31 -33
- package/src/components/badges-and-tags/PsCardInfos.vue +39 -41
- package/src/components/badges-and-tags/PsChartLegend.vue +46 -51
- package/src/components/badges-and-tags/PsClimateZoneBadge.vue +13 -19
- package/src/components/badges-and-tags/PsCostEffectBar.vue +24 -56
- package/src/components/badges-and-tags/PsDateCardInfo.vue +17 -18
- package/src/components/badges-and-tags/PsHighlightRippleDot.vue +3 -2
- package/src/components/badges-and-tags/PsMiniTag.vue +39 -41
- package/src/components/badges-and-tags/PsProgressBar.vue +72 -68
- package/src/components/badges-and-tags/PsTagScope.vue +17 -22
- package/src/components/badges-and-tags/PsTestimonialCard.vue +19 -26
- package/src/components/buttons/PsButton.vue +88 -111
- package/src/components/chips/PsChips.vue +98 -101
- package/src/components/controls/PsCheckbox.vue +84 -84
- package/src/components/controls/PsCheckboxSimple.vue +95 -95
- package/src/components/controls/PsDraggable.vue +53 -55
- package/src/components/controls/PsInlineSelector.vue +98 -99
- package/src/components/controls/PsRadioButton.vue +59 -58
- package/src/components/controls/PsRadioButtonSimple.vue +79 -75
- package/src/components/controls/PsSlider.vue +185 -176
- package/src/components/controls/PsSwitch.vue +51 -52
- package/src/components/controls/PsToggle.vue +52 -50
- package/src/components/data-graphics/PsBarChart.vue +18 -21
- package/src/components/datatable/PsDataTable.vue +56 -60
- package/src/components/datatable/PsDataTableItem.vue +13 -28
- package/src/components/forms/PsDropdown.vue +164 -162
- package/src/components/forms/PsDropdownList.vue +133 -130
- package/src/components/forms/PsInput.vue +154 -153
- package/src/components/forms/PsInputSelect.vue +91 -92
- package/src/components/forms/PsInputTextArea.vue +71 -71
- package/src/components/navigations/PsBreadcrumb.vue +25 -34
- package/src/components/notifications/PsDialog.vue +57 -56
- package/src/components/notifications/PsSimpleAlert.vue +27 -29
- package/src/components/notifications/PsToast.vue +40 -39
- package/src/components/table-results/PsTableResults.vue +449 -458
- package/src/components/table-results/PsTableResultsBody.vue +66 -67
- package/src/components/table-results/PsTableResultsHead.vue +62 -56
- package/src/components/table-results/PsTableResultsHeadComparison.vue +62 -56
- package/src/components/table-results/PsTableResultsHeadFlexible.vue +63 -56
- package/src/components/table-results/PsTableResultsRow.vue +55 -56
- package/src/components/tabs/PsTabHeader.vue +106 -100
- package/src/components/tooltip/PsDialogTooltip.vue +96 -101
- package/src/components/tooltip/PsRichTooltip.vue +41 -45
- package/src/components/tooltip/PsTooltip.vue +111 -116
- package/src/components/ui/PsDotLoader.vue +1 -5
- package/src/components/ui/PsIcon.vue +126 -129
- package/src/index.ts +156 -0
- package/src/tsconfig.json +12 -0
- package/src/types/index.d.ts +6 -0
- package/src/util/GeneralFunctions.js +4 -6
- package/src/util/directives.ts +24 -0
- package/src/util/imageLoader.js +14 -7
- package/tailwind.config.js +1 -1
- package/tsconfig.json +47 -0
- package/.storybook/PolicyStudio.js +0 -10
- package/.storybook/eventBus.js +0 -26
- package/.storybook/main.js +0 -21
- package/.storybook/manager.js +0 -6
- package/.storybook/preview.js +0 -17
- package/babel.config.js +0 -17
- package/dist/css/psui_styles.css +0 -4647
- package/postcss.config.js +0 -8
- package/src/assets/images/multifamily-units.svg +0 -10
- package/src/assets/images/policy-studio.svg +0 -15
- package/src/components/playground/PsScrollBar.vue +0 -320
- package/src/contents/ComparisonData.js +0 -378
- package/src/contents/FlexibleData.js +0 -502
- package/src/contents/ResultsData.js +0 -531
- package/src/index.js +0 -166
- package/src/stories/Accordion.stories.js +0 -59
- package/src/stories/BadgeWithIcon.stories.js +0 -31
- package/src/stories/BarChart.stories.js +0 -17
- package/src/stories/Breadcrumb.stories.js +0 -25
- package/src/stories/Button.stories.js +0 -48
- package/src/stories/Button.vue +0 -59
- package/src/stories/CardInfos.stories.js +0 -16
- package/src/stories/ChartLegend.stories.js +0 -16
- package/src/stories/Checkbox.stories.js +0 -45
- package/src/stories/CheckboxSimple.stories.js +0 -49
- package/src/stories/Chips.stories.js +0 -31
- package/src/stories/ClimateZoneBadge.stories.js +0 -17
- package/src/stories/Colors.mdx +0 -70
- package/src/stories/CostEffectBar.stories.js +0 -23
- package/src/stories/Datatable.stories.js +0 -50
- package/src/stories/DateCardInfo.stories.js +0 -24
- package/src/stories/Dialog.stories.js +0 -131
- package/src/stories/Draggable.stories.js +0 -22
- package/src/stories/Dropdown.stories.js +0 -99
- package/src/stories/DropdownList.stories.js +0 -211
- package/src/stories/ElevationSystem.mdx +0 -41
- package/src/stories/Header.stories.js +0 -41
- package/src/stories/Header.vue +0 -77
- package/src/stories/HighlightRippleDot.stories.js +0 -15
- package/src/stories/Icon.stories.js +0 -21
- package/src/stories/InlineSelector.stories.js +0 -18
- package/src/stories/Input.stories.js +0 -240
- package/src/stories/InputSelect.stories.js +0 -30
- package/src/stories/InputTextArea.stories.js +0 -25
- package/src/stories/Introduction.mdx +0 -211
- package/src/stories/MiniTag.stories.js +0 -52
- package/src/stories/Playground.stories.js +0 -16
- package/src/stories/ProgressBar.stories.js +0 -23
- package/src/stories/RadioButton.stories.js +0 -40
- package/src/stories/RadioButtonSimple.stories.js +0 -43
- package/src/stories/SimpleAlert.stories.js +0 -21
- package/src/stories/Slider.stories.js +0 -75
- package/src/stories/Switch.stories.js +0 -39
- package/src/stories/TabHeader.stories.js +0 -52
- package/src/stories/TableResults.stories.js +0 -724
- package/src/stories/TagScope.stories.js +0 -17
- package/src/stories/TestimonialCard.stories.js +0 -27
- package/src/stories/Toast.stories.js +0 -52
- package/src/stories/Toggle.stories.js +0 -45
- package/src/stories/Tooltip.stories.js +0 -114
- package/src/stories/Typography.mdx +0 -212
- package/src/stories/assets/code-brackets.svg +0 -1
- package/src/stories/assets/colors.svg +0 -1
- package/src/stories/assets/comments.svg +0 -1
- package/src/stories/assets/direction.svg +0 -1
- package/src/stories/assets/flow.svg +0 -1
- package/src/stories/assets/plugin.svg +0 -1
- package/src/stories/assets/repo.svg +0 -1
- package/src/stories/assets/stackalt.svg +0 -1
- package/src/stories/button.css +0 -30
- package/src/stories/header.css +0 -32
- package/webpack.config.js +0 -22
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
3
|
ref="PSDropdown"
|
|
4
|
-
class="psui-el-dropdown-menu"
|
|
5
|
-
:class="{ 'is-open'
|
|
4
|
+
class="psui-el-dropdown-menu"
|
|
5
|
+
:class="{ 'is-open': show.value }"
|
|
6
6
|
v-click-outside="close"
|
|
7
7
|
>
|
|
8
8
|
<div
|
|
9
9
|
ref="PSDropdownTrigger"
|
|
10
10
|
v-if="$slots.dropdownTrigger"
|
|
11
|
-
@click="show && !toggleWhenActive ? '' : toggle()"
|
|
11
|
+
@click="show.value && !toggleWhenActive ? '' : toggle()"
|
|
12
12
|
>
|
|
13
13
|
<slot name="dropdownTrigger" />
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
16
|
<button
|
|
17
17
|
v-else
|
|
18
|
-
@click="show && !toggleWhenActive ? '' : toggle()"
|
|
18
|
+
@click="show.value && !toggleWhenActive ? '' : toggle()"
|
|
19
19
|
type="button"
|
|
20
|
-
:id="id"
|
|
20
|
+
:id="id.value"
|
|
21
21
|
aria-haspopup="true"
|
|
22
22
|
aria-expanded="true"
|
|
23
23
|
ref="PSDropdownTrigger"
|
|
24
24
|
>
|
|
25
25
|
<slot
|
|
26
|
-
v-if="show && $slots.buttonLabelOnShow"
|
|
26
|
+
v-if="show.value && $slots.buttonLabelOnShow"
|
|
27
27
|
name="buttonLabelOnShow"
|
|
28
28
|
/>
|
|
29
29
|
<slot
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
role="menu"
|
|
37
37
|
class="psui-el-dropdown-menu-dialog-wrapper psui-duration-300"
|
|
38
38
|
aria-orientation="vertical"
|
|
39
|
-
:aria-labelledby="id"
|
|
39
|
+
:aria-labelledby="id.value"
|
|
40
40
|
:style="{ minWidth: minWidthDropDown }"
|
|
41
41
|
>
|
|
42
42
|
<div class="psui-el-dropdown-menu-dialog">
|
|
@@ -46,169 +46,171 @@
|
|
|
46
46
|
</div>
|
|
47
47
|
</template>
|
|
48
48
|
|
|
49
|
-
<script>
|
|
49
|
+
<script setup>
|
|
50
50
|
// 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
51
|
|
|
52
|
-
import {
|
|
53
|
-
randomString,
|
|
54
|
-
getParentScrollableEl,
|
|
55
|
-
} from '../../util/GeneralFunctions'
|
|
52
|
+
import { randomString, getParentScrollableEl } from '../../util/GeneralFunctions.js'
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
import { ref, onBeforeUnmount, defineEmits, defineExpose } from 'vue'
|
|
55
|
+
|
|
56
|
+
defineExpose({
|
|
57
|
+
close:() => close()
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const props = defineProps({
|
|
60
61
|
/**
|
|
61
|
-
|
|
62
|
+
* It sets a minimun width for the dropdown menu.
|
|
62
63
|
*/
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
},
|
|
67
|
-
/**
|
|
68
|
-
* It's a boolean responsible for showing a slot within the html tag button.
|
|
69
|
-
*/
|
|
70
|
-
buttonLabelOnShow: {
|
|
71
|
-
type: Boolean,
|
|
72
|
-
default: false,
|
|
73
|
-
},
|
|
74
|
-
/**
|
|
75
|
-
* It's a property responsible for toggling the dropdown menu. default: true.
|
|
76
|
-
*/
|
|
77
|
-
toggleWhenActive: {
|
|
78
|
-
type: Boolean,
|
|
79
|
-
default: true,
|
|
80
|
-
},
|
|
81
|
-
/**
|
|
82
|
-
* Disable the toogle on click. default: false.
|
|
83
|
-
*/
|
|
84
|
-
disabled: {
|
|
85
|
-
type: Boolean,
|
|
86
|
-
default: false,
|
|
87
|
-
},
|
|
88
|
-
/**
|
|
89
|
-
* It sets the vertical and horizontal position.
|
|
90
|
-
*/
|
|
91
|
-
position: {
|
|
92
|
-
type: String,
|
|
93
|
-
validator: (value)=> ['custom'].includes(value)
|
|
94
|
-
},
|
|
64
|
+
minWidthDropDown: {
|
|
65
|
+
type: String,
|
|
66
|
+
default: '240px',
|
|
95
67
|
},
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
68
|
+
/**
|
|
69
|
+
* It's a boolean responsible for showing a slot within the html tag button.
|
|
70
|
+
*/
|
|
71
|
+
buttonLabelOnShow: {
|
|
72
|
+
type: Boolean,
|
|
73
|
+
default: false,
|
|
103
74
|
},
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
75
|
+
/**
|
|
76
|
+
* It's a property responsible for toggling the dropdown menu. default: true.
|
|
77
|
+
*/
|
|
78
|
+
toggleWhenActive: {
|
|
79
|
+
type: Boolean,
|
|
80
|
+
default: true,
|
|
109
81
|
},
|
|
110
|
-
|
|
111
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Disable the toogle on click. default: false.
|
|
84
|
+
*/
|
|
85
|
+
disabled: {
|
|
86
|
+
type: Boolean,
|
|
87
|
+
default: false,
|
|
112
88
|
},
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
this.close()
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
watchParentScrolling() {
|
|
124
|
-
this.scrollableParentEl = getParentScrollableEl(this.$refs.PSDropdown)
|
|
125
|
-
if (this.scrollableParentEl) {
|
|
126
|
-
this.scrollableParentEl.addEventListener('scroll', this.updatePosition)
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
unwatchParentScrolling() {
|
|
130
|
-
if (this.scrollableParentEl) {
|
|
131
|
-
this.scrollableParentEl.removeEventListener(
|
|
132
|
-
'scroll',
|
|
133
|
-
this.updatePosition
|
|
134
|
-
)
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
updatePosition() {
|
|
138
|
-
const PSDropdownDialog = this.$refs.PSDropdownDialog
|
|
139
|
-
const PSDropdownTrigger = this.$refs.PSDropdownTrigger
|
|
140
|
-
if (!PSDropdownDialog || !PSDropdownTrigger) return
|
|
141
|
-
|
|
142
|
-
const rectTrigger = PSDropdownTrigger.getBoundingClientRect()
|
|
143
|
-
const rectDialog = PSDropdownDialog.getBoundingClientRect()
|
|
144
|
-
const windowWidth = document.documentElement.clientWidth
|
|
145
|
-
|
|
146
|
-
PSDropdownDialog.style.position = 'fixed'
|
|
147
|
-
PSDropdownDialog.style.top = `${rectTrigger.y + rectTrigger.height}px`
|
|
148
|
-
|
|
149
|
-
PSDropdownDialog.style.minWidth = `${rectTrigger.width}px`
|
|
150
|
-
|
|
151
|
-
if (rectTrigger.x + rectDialog.width + 20 > windowWidth) {
|
|
152
|
-
PSDropdownDialog.style.left = `${
|
|
153
|
-
windowWidth - rectDialog.width - 30
|
|
154
|
-
}px`
|
|
155
|
-
} else {
|
|
156
|
-
PSDropdownDialog.style.left = `${rectTrigger.x}px`
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if(this.position == 'custom') {
|
|
160
|
-
PSDropdownDialog.style.top = `${rectTrigger.y}px`
|
|
161
|
-
PSDropdownDialog.style.left = `${rectTrigger.x + 100}px`
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (rectTrigger.top < 10) {
|
|
165
|
-
this.close()
|
|
166
|
-
console.warn('The dropdown are too close from the top of the page')
|
|
167
|
-
return
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
setTimeout(() => {
|
|
171
|
-
PSDropdownDialog.style.opacity = 1
|
|
172
|
-
}, 10)
|
|
173
|
-
},
|
|
174
|
-
open() {
|
|
175
|
-
this.$emit('open')
|
|
176
|
-
this.show = true
|
|
177
|
-
if(this.$refs.PSDropdownDialog){
|
|
178
|
-
this.$refs.PSDropdownDialog.style.opacity = 0
|
|
179
|
-
this.$refs.PSDropdownDialog.style.display = 'block'
|
|
180
|
-
}
|
|
181
|
-
setTimeout(() => {
|
|
182
|
-
this.updatePosition()
|
|
183
|
-
this.watchParentScrolling()
|
|
184
|
-
document.addEventListener('keyup', this.handleEsc)
|
|
185
|
-
window.addEventListener('resize', this.updatePosition)
|
|
186
|
-
window.addEventListener('click', this.clickOutside)
|
|
187
|
-
}, 10)
|
|
188
|
-
},
|
|
189
|
-
close() {
|
|
190
|
-
if (this.show) {
|
|
191
|
-
this.$emit('close')
|
|
192
|
-
if(this.$refs.PSDropdownDialog){
|
|
193
|
-
this.$refs.PSDropdownDialog.style.display = 'none'
|
|
194
|
-
this.$refs.PSDropdownDialog.style.opacity = 0
|
|
195
|
-
}
|
|
196
|
-
this.show = false
|
|
197
|
-
this.unwatchParentScrolling()
|
|
198
|
-
}
|
|
199
|
-
document.removeEventListener('keyup', this.handleEsc)
|
|
200
|
-
document.removeEventListener('resize', this.updatePosition)
|
|
201
|
-
document.removeEventListener('click', this.clickOutside)
|
|
202
|
-
},
|
|
203
|
-
handleEsc(evt) {
|
|
204
|
-
if (this.show && evt.keyCode === 27) this.close()
|
|
205
|
-
},
|
|
206
|
-
clickOutside(event) {
|
|
207
|
-
if (!this.show) return
|
|
208
|
-
if (!this.$refs.PSDropdown == event.target || !this.$refs.PSDropdown?.contains(event.target)) {
|
|
209
|
-
this.close()
|
|
210
|
-
}
|
|
211
|
-
},
|
|
89
|
+
/**
|
|
90
|
+
* It sets the vertical and horizontal position.
|
|
91
|
+
*/
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment, vue/require-default-prop
|
|
93
|
+
position: {
|
|
94
|
+
type: String,
|
|
95
|
+
validator: (value) => ['custom'].includes(value),
|
|
212
96
|
},
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
const emit = defineEmits(['open', 'close'])
|
|
100
|
+
|
|
101
|
+
const show = ref(false)
|
|
102
|
+
const id = ref(randomString(8))
|
|
103
|
+
// const marginLeft = ref('-0px')
|
|
104
|
+
const scrollableParentEl = ref(null)
|
|
105
|
+
const PSDropdown = ref(null)
|
|
106
|
+
const PSDropdownDialog = ref(null)
|
|
107
|
+
const PSDropdownTrigger = ref(null)
|
|
108
|
+
|
|
109
|
+
// const getMaxWidth = computed(() => {
|
|
110
|
+
// let bounds = PSDropdown.getBoundingClientRect()
|
|
111
|
+
// return document.documentElement.clientWidth - bounds['left'] - 30
|
|
112
|
+
// })
|
|
113
|
+
|
|
114
|
+
onBeforeUnmount(() => {
|
|
115
|
+
unwatchParentScrolling()
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
const toggle = () => {
|
|
119
|
+
if (props.disabled) return
|
|
120
|
+
if (!show.value) {
|
|
121
|
+
open()
|
|
122
|
+
} else {
|
|
123
|
+
close()
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const handleEsc = (evt) => {
|
|
128
|
+
if (show.value && evt.keyCode === 27) close()
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const open = () => {
|
|
132
|
+
emit('open')
|
|
133
|
+
show.value = true
|
|
134
|
+
if (PSDropdownDialog.value) {
|
|
135
|
+
PSDropdownDialog.value.style.opacity = 0
|
|
136
|
+
PSDropdownDialog.value.style.display = 'block'
|
|
137
|
+
}
|
|
138
|
+
setTimeout(() => {
|
|
139
|
+
updatePosition()
|
|
140
|
+
watchParentScrolling()
|
|
141
|
+
document.addEventListener('keyup', handleEsc)
|
|
142
|
+
window.addEventListener('resize', updatePosition)
|
|
143
|
+
// window.addEventListener('click', clickOutside)
|
|
144
|
+
}, 10)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const close = () => {
|
|
148
|
+
if (show.value == true) {
|
|
149
|
+
emit('close')
|
|
150
|
+
if (PSDropdownDialog.value !== null) {
|
|
151
|
+
PSDropdownDialog.value.style.display = 'none'
|
|
152
|
+
PSDropdownDialog.value.style.opacity = 0
|
|
153
|
+
}
|
|
154
|
+
show.value = false
|
|
155
|
+
unwatchParentScrolling()
|
|
156
|
+
}
|
|
157
|
+
document.removeEventListener('keyup', handleEsc)
|
|
158
|
+
document.removeEventListener('resize', updatePosition)
|
|
159
|
+
// document.removeEventListener('click', clickOutside)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const watchParentScrolling = () => {
|
|
163
|
+
scrollableParentEl.value = getParentScrollableEl(PSDropdown.value)
|
|
164
|
+
if (scrollableParentEl.value) {
|
|
165
|
+
scrollableParentEl.value.addEventListener('scroll', updatePosition)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const unwatchParentScrolling = () => {
|
|
170
|
+
if (scrollableParentEl.value) {
|
|
171
|
+
scrollableParentEl.value.removeEventListener('scroll', updatePosition())
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const updatePosition = () => {
|
|
176
|
+
if (PSDropdownDialog.value === null || PSDropdownTrigger.value === null) return
|
|
177
|
+
|
|
178
|
+
const rectTrigger = PSDropdownTrigger.value.getBoundingClientRect()
|
|
179
|
+
const rectDialog = PSDropdownDialog.value.getBoundingClientRect()
|
|
180
|
+
const windowWidth = document.documentElement.clientWidth
|
|
181
|
+
|
|
182
|
+
PSDropdownDialog.value.style.position = 'fixed'
|
|
183
|
+
PSDropdownDialog.value.style.top = `${rectTrigger.y + rectTrigger.height}px`
|
|
184
|
+
PSDropdownDialog.value.style.minWidth = `${rectTrigger.width}px`
|
|
185
|
+
|
|
186
|
+
if (rectTrigger.x + rectDialog.width + 20 > windowWidth) {
|
|
187
|
+
PSDropdownDialog.value.style.left = `${windowWidth - rectDialog.width + 15}px`
|
|
188
|
+
} else {
|
|
189
|
+
PSDropdownDialog.value.style.left = `${rectTrigger.x}px`
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (props.position == 'custom') {
|
|
193
|
+
PSDropdownDialog.value.style.top = `${rectTrigger.y}px`
|
|
194
|
+
PSDropdownDialog.value.style.left = `${rectTrigger.x + 100}px`
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (rectTrigger.top < 10) {
|
|
198
|
+
close()
|
|
199
|
+
console.warn('The dropdown are too close from the top of the page')
|
|
200
|
+
return
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
setTimeout(() => {
|
|
204
|
+
if(PSDropdownDialog.value){
|
|
205
|
+
PSDropdownDialog.value.style.opacity = 1
|
|
206
|
+
}
|
|
207
|
+
}, 10)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const clickOutside = (event) => {
|
|
211
|
+
if (!show.value) return
|
|
212
|
+
if (!PSDropdown.value == event.target || !PSDropdown.value?.contains(event.target)) {
|
|
213
|
+
close()
|
|
214
|
+
}
|
|
213
215
|
}
|
|
214
216
|
</script>
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<ul
|
|
2
|
+
<ul
|
|
3
3
|
class="psui-el-dropdown-menu-list"
|
|
4
4
|
:class="`layout-${layout}`"
|
|
5
5
|
>
|
|
6
|
-
<li
|
|
7
|
-
v-for="(item, index) in getItems"
|
|
6
|
+
<li
|
|
7
|
+
v-for="(item, index) in getItems"
|
|
8
8
|
:key="`${index}-${getKeyValue(item)}`"
|
|
9
9
|
:id="`${index}-${getKeyValue(item)}`"
|
|
10
|
-
:class="{ 'is-selected psui-bg-blue-10 psui-text-blue-60 hover:psui-bg-blue-10 hover:psui-text-blue-60'
|
|
10
|
+
:class="{ 'is-selected psui-bg-blue-10 psui-text-blue-60 hover:psui-bg-blue-10 hover:psui-text-blue-60': getSelected === getKeyValue(item) }"
|
|
11
11
|
class="psui-el-dropdown-menu-list-item"
|
|
12
|
-
@mouseover="isHovering = index"
|
|
12
|
+
@mouseover="isHovering = index"
|
|
13
13
|
@mouseout="isHovering = false"
|
|
14
14
|
@click="selectItem(item)"
|
|
15
15
|
>
|
|
16
16
|
<div class="psui-el-dropdown-menu-list-item-left-label">
|
|
17
17
|
{{ getLeftLabel(item) }}
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
<div
|
|
20
20
|
v-if="item.description"
|
|
21
21
|
class="psui-font-normal psui-text-gray-50 psui-ml-1"
|
|
22
|
-
:class="{ 'psui-text-blue-60'
|
|
22
|
+
:class="{ 'psui-text-blue-60': item.key == getItems.key }"
|
|
23
23
|
>
|
|
24
24
|
{{ item.description }}
|
|
25
25
|
</div>
|
|
@@ -29,19 +29,19 @@
|
|
|
29
29
|
size="20"
|
|
30
30
|
class="psui-text-blue-60 psui-opacity-0 psui-transition psui-leading-none psui-cursor-pointer psui-ml-1"
|
|
31
31
|
:display="item.key == getItems.key || isHovering == index ? 'flex' : 'none'"
|
|
32
|
-
@click.stop="
|
|
32
|
+
@click.stop="emit('openDescriptionModal', { type: item.hasHelper.type, id: item.hasHelper.id, slug: item.hasHelper.slug })"
|
|
33
33
|
/>
|
|
34
34
|
</div>
|
|
35
35
|
|
|
36
36
|
<template v-if="layout == 'rich'">
|
|
37
37
|
<div class="psui-el-dropdown-menu-list-item-line" />
|
|
38
|
-
<div
|
|
38
|
+
<div
|
|
39
39
|
v-if="rightLabelFormatter"
|
|
40
40
|
class="psui-el-dropdown-menu-list-item-rigth-label"
|
|
41
41
|
>
|
|
42
42
|
{{ rightLabelFormatter(item.key, getStudyDataLevel[item.key], getStudyDataLevel) }}
|
|
43
43
|
</div>
|
|
44
|
-
<div
|
|
44
|
+
<div
|
|
45
45
|
v-else
|
|
46
46
|
class="psui-el-dropdown-menu-list-item-rigth-label"
|
|
47
47
|
>
|
|
@@ -49,132 +49,135 @@
|
|
|
49
49
|
</div>
|
|
50
50
|
</template>
|
|
51
51
|
</li>
|
|
52
|
-
</ul>
|
|
52
|
+
</ul>
|
|
53
53
|
</template>
|
|
54
54
|
|
|
55
|
-
<script>
|
|
55
|
+
<script setup>
|
|
56
56
|
import PsIcon from '../ui/PsIcon.vue'
|
|
57
|
-
|
|
57
|
+
import { ref, computed, defineEmits } from 'vue'
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
default: 'onlytext',
|
|
69
|
-
validator: (value) => {
|
|
70
|
-
return itemStyle.indexOf(value) !== -1
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
/**
|
|
74
|
-
* It sets the text key which will retrieve a icon from Google Fonts. Make sure to get the correct description of your icon on https://fonts.google.com/.
|
|
75
|
-
*/
|
|
76
|
-
icon: {
|
|
77
|
-
type: String,
|
|
78
|
-
},
|
|
79
|
-
/**
|
|
80
|
-
* It sets the items which will be displayed on the dropdown menu.
|
|
81
|
-
*/
|
|
82
|
-
items: {
|
|
83
|
-
type: [Array, Object],
|
|
84
|
-
required: true
|
|
85
|
-
},
|
|
86
|
-
/**
|
|
87
|
-
* It sets the left key label of your items if needed.
|
|
88
|
-
*/
|
|
89
|
-
leftLabel: {
|
|
90
|
-
type: [String, Function],
|
|
91
|
-
default: 'left_label'
|
|
92
|
-
},
|
|
93
|
-
/**
|
|
94
|
-
* It sets the right key label of your items if needed.
|
|
95
|
-
*/
|
|
96
|
-
rightLabel: {
|
|
97
|
-
type: [String, Function],
|
|
98
|
-
default: 'right_label'
|
|
99
|
-
},
|
|
100
|
-
/**
|
|
101
|
-
* It sets the key label of your items if needed.
|
|
102
|
-
*/
|
|
103
|
-
label: {
|
|
104
|
-
type: [String, Function],
|
|
105
|
-
default: 'label'
|
|
106
|
-
},
|
|
107
|
-
/**
|
|
108
|
-
* It sets the key value of your items if needed.
|
|
109
|
-
*/
|
|
110
|
-
keyValue: {
|
|
111
|
-
type: [String, Function],
|
|
112
|
-
default: 'value'
|
|
113
|
-
},
|
|
114
|
-
/**
|
|
115
|
-
* It sets the format function to display values.
|
|
116
|
-
*/
|
|
117
|
-
rightLabelFormatter: {
|
|
118
|
-
type: Function
|
|
59
|
+
const props = defineProps({
|
|
60
|
+
/**
|
|
61
|
+
* It sets the style of items
|
|
62
|
+
*/
|
|
63
|
+
layout: {
|
|
64
|
+
type: String,
|
|
65
|
+
default: 'onlytext',
|
|
66
|
+
validator: (value) => {
|
|
67
|
+
return ['onlytext', 'radio', 'icon', 'checkbox', 'switch', 'rich'].indexOf(value) !== -1
|
|
119
68
|
},
|
|
120
|
-
/**
|
|
121
|
-
* It sets the format function to display values.
|
|
122
|
-
*/
|
|
123
|
-
studyData: {
|
|
124
|
-
type: [String, Object]
|
|
125
|
-
},
|
|
126
|
-
/**
|
|
127
|
-
* It sets the item selected on the dropdown menu.
|
|
128
|
-
*/
|
|
129
|
-
selected: {},
|
|
130
69
|
},
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (typeof this.selected === 'object' && this.selected[this.keyValue] ) {
|
|
138
|
-
return this.selected[this.keyValue]
|
|
139
|
-
} else {
|
|
140
|
-
return this.selected
|
|
141
|
-
}
|
|
142
|
-
} else {
|
|
143
|
-
return false
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
getItems() {
|
|
147
|
-
return this.items
|
|
148
|
-
},
|
|
149
|
-
getStudyDataLevel() {
|
|
150
|
-
return this.studyData?.data || this.studyData
|
|
151
|
-
},
|
|
70
|
+
/**
|
|
71
|
+
* It sets the text key which will retrieve a icon from Google Fonts. Make sure to get the correct description of your icon on https://fonts.google.com/.
|
|
72
|
+
*/
|
|
73
|
+
icon: {
|
|
74
|
+
type: String,
|
|
75
|
+
default: '',
|
|
152
76
|
},
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
77
|
+
/**
|
|
78
|
+
* It sets the items which will be displayed on the dropdown menu.
|
|
79
|
+
*/
|
|
80
|
+
items: {
|
|
81
|
+
type: [Array, Object],
|
|
82
|
+
required: true,
|
|
83
|
+
},
|
|
84
|
+
/**
|
|
85
|
+
* It sets the left key label of your items if needed.
|
|
86
|
+
*/
|
|
87
|
+
leftLabel: {
|
|
88
|
+
type: [String, Function],
|
|
89
|
+
default: 'left_label',
|
|
90
|
+
},
|
|
91
|
+
/**
|
|
92
|
+
* It sets the right key label of your items if needed.
|
|
93
|
+
*/
|
|
94
|
+
rightLabel: {
|
|
95
|
+
type: [String, Function],
|
|
96
|
+
default: 'right_label',
|
|
97
|
+
},
|
|
98
|
+
/**
|
|
99
|
+
* It sets the key label of your items if needed.
|
|
100
|
+
*/
|
|
101
|
+
label: {
|
|
102
|
+
type: [String, Function],
|
|
103
|
+
default: 'label',
|
|
104
|
+
},
|
|
105
|
+
/**
|
|
106
|
+
* It sets the key value of your items if needed.
|
|
107
|
+
*/
|
|
108
|
+
keyValue: {
|
|
109
|
+
type: [String, Function],
|
|
110
|
+
default: 'value',
|
|
111
|
+
},
|
|
112
|
+
/**
|
|
113
|
+
* It sets the format function to display values.
|
|
114
|
+
*/
|
|
115
|
+
rightLabelFormatter: {
|
|
116
|
+
type: Function,
|
|
117
|
+
default: () => '',
|
|
118
|
+
},
|
|
119
|
+
/**
|
|
120
|
+
* It sets the format function to display values.
|
|
121
|
+
*/
|
|
122
|
+
studyData: {
|
|
123
|
+
type: [String, Object],
|
|
124
|
+
default: '',
|
|
125
|
+
},
|
|
126
|
+
/**
|
|
127
|
+
* It sets the item selected on the dropdown menu.
|
|
128
|
+
*/
|
|
129
|
+
selected: {},
|
|
130
|
+
})
|
|
131
|
+
const emit = defineEmits(['update:selected', 'change','openDescriptionModal'])
|
|
132
|
+
|
|
133
|
+
const isHovering = ref(false)
|
|
134
|
+
|
|
135
|
+
const getSelected = computed(() => {
|
|
136
|
+
if (props.selected !== undefined) {
|
|
137
|
+
if (typeof props.selected === 'object' && props.selected[props.keyValue]) {
|
|
138
|
+
return props.selected[props.keyValue]
|
|
139
|
+
} else {
|
|
140
|
+
return props.selected
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
return false
|
|
178
144
|
}
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
const getItems = computed(() => {
|
|
148
|
+
return props.items
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
const getStudyDataLevel = computed(() => {
|
|
152
|
+
return props.studyData?.data || props.studyData
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
const selectItem = (item) => {
|
|
156
|
+
emit('update:selected', getKeyValue(item))
|
|
157
|
+
emit('change', item)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const getLeftLabel = (item) => {
|
|
161
|
+
if (typeof props.leftLabel == 'function') return props.leftLabel(item)
|
|
162
|
+
if (typeof item === 'string') return item
|
|
163
|
+
return item[props.leftLabel]
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const getRightLabel = (item) => {
|
|
167
|
+
if (typeof props.rightLabel == 'function') return props.rightLabel(item)
|
|
168
|
+
if (typeof item === 'string') return item
|
|
169
|
+
return item[props.rightLabel]
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// const getLabel = (item) => {
|
|
173
|
+
// if(typeof props.label == 'function') return props.label(item)
|
|
174
|
+
// if(typeof item === 'string') return item
|
|
175
|
+
// return item[props.label]
|
|
176
|
+
// }
|
|
177
|
+
|
|
178
|
+
const getKeyValue = (item) => {
|
|
179
|
+
if (typeof props.keyValue == 'function') return props.keyValue(item)
|
|
180
|
+
if (typeof item === 'string') return item
|
|
181
|
+
return item[props.keyValue]
|
|
179
182
|
}
|
|
180
|
-
</script>
|
|
183
|
+
</script>
|