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