@policystudio/policy-studio-ui-vue 1.0.18 → 1.0.22

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 (66) hide show
  1. package/.eslintrc.js +67 -0
  2. package/.storybook/main.js +11 -2
  3. package/.storybook/preview.js +1 -1
  4. package/README.md +8 -0
  5. package/babel.config.js +3 -0
  6. package/backup-package-lock.json +37194 -0
  7. package/{src/assets/scss/tailwind.css → dist/css/psui_styles.css} +16720 -17120
  8. package/package.json +32 -19
  9. package/postcss.config.js +2 -0
  10. package/src/assets/images/check-checkbox-button.svg +1 -0
  11. package/src/assets/images/radio-checked-button.svg +1 -0
  12. package/src/assets/scss/base.scss +6 -5
  13. package/src/assets/scss/components/PsInput.scss +89 -0
  14. package/src/components/accordion/PsAccordion.vue +40 -0
  15. package/src/components/accordion/PsAccordionItem.vue +102 -0
  16. package/src/components/badges-and-tags/PsChartLegend.vue +128 -0
  17. package/src/components/badges-and-tags/PsClimateZoneBadge.vue +18 -0
  18. package/src/components/badges-and-tags/PsCostEffectBar.vue +114 -0
  19. package/src/components/badges-and-tags/PsHighlightRippleDot.vue +78 -0
  20. package/src/components/badges-and-tags/PsMiniTag.vue +46 -0
  21. package/src/components/badges-and-tags/PsProgressBar.vue +0 -0
  22. package/src/components/buttons/PsButton.vue +36 -13
  23. package/src/components/chips/PsChips.vue +154 -0
  24. package/src/components/controls/PsCheckbox.vue +30 -17
  25. package/src/components/controls/PsDraggable.vue +174 -3
  26. package/src/components/controls/PsRadioButton.vue +67 -60
  27. package/src/components/controls/PsSlider.vue +13 -12
  28. package/src/components/controls/PsSwitch.vue +76 -76
  29. package/src/components/datatable/PsDataTable.vue +89 -0
  30. package/src/components/datatable/PsDataTableItem.vue +57 -0
  31. package/src/components/forms/PsDropdown.vue +196 -0
  32. package/src/components/forms/PsInput.vue +122 -99
  33. package/src/components/notifications/PsDialog.vue +37 -18
  34. package/src/components/tabs/PsTabHeader.vue +20 -21
  35. package/src/components/tooltip/PsDialogTooltip.vue +79 -0
  36. package/src/components/tooltip/PsRichTooltip.vue +44 -0
  37. package/src/components/tooltip/PsTooltip.vue +118 -0
  38. package/src/components/ui/PsIcon.vue +128 -0
  39. package/src/index.js +53 -24
  40. package/src/stories/Accordion.stories.js +41 -0
  41. package/src/stories/Button.stories.js +11 -11
  42. package/src/stories/ChartLegend.stories.js +16 -0
  43. package/src/stories/Checkbox.stories.js +21 -14
  44. package/src/stories/Chips.stories.js +55 -0
  45. package/src/stories/ClimateZoneBadge.stories.js +24 -0
  46. package/src/stories/Colors.stories.mdx +35 -35
  47. package/src/stories/CostEffectBar.stories.js +23 -0
  48. package/src/stories/Datatable.stories.js +50 -0
  49. package/src/stories/Dialog.stories.js +150 -17
  50. package/src/stories/Draggable.stories.js +22 -0
  51. package/src/stories/Dropdown.stories.js +32 -0
  52. package/src/stories/HighlightRippleDot.stories.js +16 -0
  53. package/src/stories/Input.stories.js +46 -15
  54. package/src/stories/MiniTag.stories.js +46 -0
  55. package/src/stories/ProgressBar.stories.js +23 -0
  56. package/src/stories/RadioButton.stories.js +25 -9
  57. package/src/stories/Slider.stories.js +9 -9
  58. package/src/stories/Swith.stories.js +10 -10
  59. package/src/stories/TabHeader.stories.js +9 -9
  60. package/src/stories/Toast.stories.js +13 -13
  61. package/src/stories/Toggle.stories.js +12 -13
  62. package/src/stories/Tooltip.stories.js +114 -0
  63. package/src/util/GeneralFunctions.js +22 -0
  64. package/src/util/imageLoader.js +50 -0
  65. package/tailwind.config.js +82 -45
  66. package/src/assets/scss/tailwind.scss +0 -61088
@@ -0,0 +1,196 @@
1
+ <template>
2
+ <div
3
+ class="psui-relative psui-inline-block psui-text-left"
4
+ ref="PSDropdown"
5
+ >
6
+
7
+ <div class="psui-bg-red" ref="PSDropdownTrigger" v-if="$slots.dropdownTrigger" @click="show && !toggleWhenActive ? '' : toggle()" >
8
+ <slot name="dropdownTrigger" ></slot>
9
+ </div>
10
+
11
+ <button
12
+ v-else
13
+ @click="show && !toggleWhenActive ? '' : toggle()"
14
+ type="button"
15
+ class="psui-inline-flex psui-justify-center psui-items-center psui-w-full psui-font-medium psui-focus:shadow-outline-blue psui-dropdown-button psui-text-sm psui-leading-none"
16
+ :class="[buttonClasses]"
17
+ :id="id"
18
+ aria-haspopup="true"
19
+ aria-expanded="true"
20
+ ref="PSDropdownTrigger"
21
+ >
22
+ <slot v-if="show && $slots.buttonLabelOnShow" name="buttonLabelOnShow"></slot>
23
+ <slot v-else name="buttonLabel"></slot>
24
+ </button>
25
+
26
+ <div
27
+ ref="PSDropdownDialog"
28
+ role="menu"
29
+ class="psui-dropdown-dialog psui-hidden psui-origin-top-right psui-fixed psui-mt-2 psui-w-auto psui-rounded psui-shadow-lg psui-border psui-border-blue05 psui-z-50 psui-opacity-0"
30
+ aria-orientation="vertical"
31
+ :aria-labelledby="id"
32
+ :class="[dialogClasses]"
33
+ :style="{ minWidth: minWidthDropdown, marginLeft: marginLeft }"
34
+ >
35
+ <div class="w-full">
36
+ <h2 class="psui-text-gray02 psui-font-bold psui-whitespace-no-wrap psui-mb-4 ts--accent--1" v-if="title">{{ title }}</h2>
37
+ <slot name="items"></slot>
38
+ </div>
39
+
40
+ </div>
41
+ </div>
42
+ </template>
43
+
44
+ <script>
45
+ import { randomString, getParentScrollableEl } from '../../util/GeneralFunctions'
46
+
47
+ export default {
48
+ name: 'PsDropdown',
49
+ props: {
50
+ buttonClasses: {
51
+ type: String,
52
+ default: 'psui-bg-white psui-border psui-border-blue'
53
+ },
54
+ title: {
55
+ type: String,
56
+ },
57
+ dialogClasses: {
58
+ type: String,
59
+ default: 'psui-p-6 psui-left-0 psui-bg-white'
60
+ },
61
+ minWidthDropdown: {
62
+ type: [String, Number],
63
+ },
64
+ maxWidthDropDown: {
65
+ type: String,
66
+ default: '340px'
67
+ },
68
+ buttonLabelOnShow: {
69
+ type: Boolean,
70
+ default: false
71
+ },
72
+ toggleWhenActive: {
73
+ type: Boolean,
74
+ default: true
75
+ },
76
+ },
77
+ data() {
78
+ return {
79
+ show: false,
80
+ id: randomString(8),
81
+ marginLeft: '-0px',
82
+ scrollableParentEl : null
83
+ }
84
+ },
85
+ computed: {
86
+ getMaxWidth() {
87
+ let bounds = this.$refs.PSDropdown.getBoundingClientRect()
88
+ return (document.documentElement.clientWidth - bounds['left']) -30
89
+ }
90
+ },
91
+ beforeDestroy() {
92
+ this.unwatchParentScrolling()
93
+ },
94
+ methods: {
95
+ toggle() {
96
+ if (!this.show) {
97
+ this.open()
98
+ } else {
99
+ this.close()
100
+ }
101
+ },
102
+ watchParentScrolling() {
103
+ this.scrollableParentEl = getParentScrollableEl(this.$refs.PSDropdown)
104
+ if (this.scrollableParentEl) {
105
+ this.scrollableParentEl.addEventListener('scroll', this.updatePosition)
106
+ }
107
+ },
108
+ unwatchParentScrolling() {
109
+ if (this.scrollableParentEl) {
110
+ this.scrollableParentEl.removeEventListener('scroll', this.updatePosition)
111
+ }
112
+ },
113
+ updatePosition() {
114
+
115
+ const PSDropdownDialog = this.$refs.PSDropdownDialog
116
+ const PSDropdownTrigger = this.$refs.PSDropdownTrigger
117
+ if (!PSDropdownDialog || !PSDropdownTrigger) return
118
+
119
+ const rectTrigger = PSDropdownTrigger.getBoundingClientRect()
120
+ const rectDialog = PSDropdownDialog.getBoundingClientRect()
121
+ const windowWidth = document.documentElement.clientWidth
122
+
123
+ PSDropdownDialog.style.position = 'fixed'
124
+ PSDropdownDialog.style.top = `${rectTrigger.y + rectTrigger.height }px`
125
+
126
+ if (( rectTrigger.x + rectDialog.width + 20 ) > windowWidth ) {
127
+ PSDropdownDialog.style.left = `${windowWidth - rectDialog.width - 30}px`
128
+ } else {
129
+ PSDropdownDialog.style.left = `${rectTrigger.x}px`
130
+ }
131
+
132
+ if(rectTrigger.top < 10) {
133
+ this.close()
134
+ console.warn('The dropdown are too close from the top of the page')
135
+ return
136
+ }
137
+
138
+ setTimeout(() => { PSDropdownDialog.style.opacity = 1 }, 10)
139
+
140
+ },
141
+ open() {
142
+ this.$emit('open')
143
+ this.show = true
144
+ this.$refs.PSDropdownDialog.style.opacity = 0
145
+ this.$refs.PSDropdownDialog.style.display = 'block'
146
+ setTimeout(() => {
147
+ this.updatePosition()
148
+ this.watchParentScrolling()
149
+ document.addEventListener("keyup", this.handleEsc)
150
+ window.addEventListener("resize", this.updatePosition)
151
+ window.addEventListener("click", this.clickOutside)
152
+ }, 10)
153
+ },
154
+ close() {
155
+ if (this.show) {
156
+ this.$emit('close')
157
+ this.$refs.PSDropdownDialog.style.display = 'none'
158
+ this.$refs.PSDropdownDialog.style.opacity = 0
159
+ this.show = false
160
+ this.unwatchParentScrolling()
161
+ }
162
+ document.removeEventListener("keyup", this.handleEsc)
163
+ document.removeEventListener("resize", this.updatePosition)
164
+ document.removeEventListener("click", this.clickOutside)
165
+ },
166
+ handleEsc(evt) {
167
+ if (this.show && evt.keyCode === 27) this.close()
168
+ },
169
+ clickOutside(event) {
170
+ if(!this.show) return
171
+ if (!(this.$refs.PSDropdown == event.target || this.$refs.PSDropdown.contains(event.target))) {
172
+ this.close()
173
+ }
174
+ }
175
+ }
176
+ }
177
+ </script>
178
+
179
+ <style>
180
+
181
+ .dropdown-button {
182
+ background-color: transparent;
183
+ padding-top: 2.5px;
184
+ padding-bottom: 2.5px;
185
+ min-height: 27px;
186
+ }
187
+
188
+ .dropdown-button:focus {
189
+ outline: none;
190
+ }
191
+
192
+ .psui-dropdown-dialog {
193
+ transition: opacity 150ms ease-in-out;
194
+ }
195
+
196
+ </style>
@@ -1,99 +1,122 @@
1
- <template>
2
- <div>
3
- <div v-if="label" class="psui-font-bold psui-text-gray-80">{{ label }}</div>
4
- <div class="psui-relative">
5
- <div class="psui-absolute psui-inset-y-0 psui-left-0 psui-pl-2 psui-flex psui-items-center psui-pointer-events-none" v-if="this.$slots.prepend">
6
- <slot name="prepend"></slot>
7
- </div>
8
- <input
9
- :type="type"
10
- :placeholder="placeholder"
11
- :disabled="disabled"
12
- :aria-required="required"
13
- :aria-invalid="validation.hasError"
14
- :class="[getInputClasses, { 'psui-border-red' : validation.hasError }]"
15
- :required="required"
16
- :value="value"
17
- @focus="$emit('focus', $event)"
18
- @blur="$emit('blur', $event)"
19
- @input="$emit('input', $event)"
20
- @keydown.enter="$emit('keydown', $event)"
21
- @change="$emit('change', $event)"
22
- v-bind="getAttrs"
23
- />
24
- <div class="psui-absolute psui-inset-y-0 psui-right-0 psui-pr-2 psui-flex psui-items-center" v-if="this.$slots.append">
25
- <slot name="append"></slot>
26
- </div>
27
- </div>
28
- <div v-if="hint && !validation.hasError" class="psui-text-gray-50 psui-text-xsmall">{{ hint }}</div>
29
- <div v-if="validation.hasError && validation.label" class="psui-text-red psui-text-xsmall">{{ validation.label }}</div>
30
- </div>
31
- </template>
32
-
33
- <script>
34
- export default {
35
- name: 'PsInput',
36
- props: {
37
- type: {
38
- type: String,
39
- default: 'text'
40
- },
41
- required: {
42
- type: Boolean
43
- },
44
- placeholder: {
45
- type: String
46
- },
47
- label: {
48
- type: String
49
- },
50
- hint: {
51
- type: String
52
- },
53
- disabled: {
54
- type: Boolean,
55
- default: false
56
- },
57
- mini: {
58
- type: Boolean,
59
- default: false
60
- },
61
- validation: {
62
- type: Object,
63
- default: () => {
64
- return { hasError: false, checked: false, filled: false, required: false }
65
- }
66
- },
67
- value: {
68
- required: true,
69
- },
70
- },
71
- computed: {
72
- getInputClasses() {
73
- return `${this.getPadding} ${this.getText} psui-text-gray-60 psui-bg-white psui-w-full psui-border psui-border-gray-30 psui-rounded-md psui-block hover:psui-border-blue-50 focus:psui-border-blue-50`
74
- },
75
- getText() {
76
- return this.mini ? 'psui-text-small' : ''
77
- },
78
- getPadding() {
79
- return this.mini ? 'psui-px-2 mini-p' : 'psui-py-2 psui-px-4'
80
- },
81
- getAttrs() {
82
- const defaultAttrs = {
83
- autocapitalize: 'sentences',
84
- autocomplete: 'chrome-off',
85
- autocorrect: 'off',
86
- spellcheck: 'spellcheck'
87
- }
88
- return { ...defaultAttrs, ...this.$attrs }
89
- }
90
- },
91
- }
92
- </script>
93
-
94
- <style>
95
- .mini-p {
96
- padding-top: 6px;
97
- padding-bottom: 6px;
98
- }
99
- </style>
1
+ <template>
2
+ <div class="psui-el-input" :class="[getComponentClass, `layout-${layout}`]" >
3
+
4
+ <label v-if="label"> {{ label }} </label>
5
+
6
+ <div
7
+ class="psui-el-input-wrapper"
8
+ @mouseenter="isHoveringInputWrapper = true"
9
+ @mouseleave="isHoveringInputWrapper = false"
10
+ :class="{ 'hover' : isHoveringInputWrapper }"
11
+ >
12
+
13
+ <div v-if="$slots.prepend" class="psui-el-input-prepend">
14
+ <slot name="prepend"></slot>
15
+ </div>
16
+
17
+ <input
18
+ :type="type"
19
+ :placeholder="placeholder"
20
+ :disabled="disabled"
21
+ :value="value"
22
+ @focus="onInputFocus"
23
+ @blur="onInputBlur"
24
+ @input="$emit('input', $event)"
25
+ @keydown="$emit('keydown', $event)"
26
+ @change="$emit('change', $event)"
27
+ v-bind="getAttrs"
28
+ :class="getInputClasses"
29
+ />
30
+
31
+ <div v-if="$slots.append || hasError" class="psui-el-input-append">
32
+ <span v-if="hasError" class="material-icons psui-text-red-20 material-icons-sharp">error</span>
33
+ <slot v-else name="append"></slot>
34
+ </div>
35
+
36
+ </div>
37
+
38
+ <p v-if="hint || (hasError && typeof hasError === 'string')" class="psui-el-input-hint">
39
+ {{ typeof hasError === 'string' ? hasError : hint }}
40
+ </p>
41
+
42
+ </div>
43
+ </template>
44
+
45
+ <script>
46
+ export default {
47
+ name: 'PsInput',
48
+ props: {
49
+ type: {
50
+ type: String,
51
+ default: 'text'
52
+ },
53
+ placeholder: {
54
+ type: String
55
+ },
56
+ label: {
57
+ type: String
58
+ },
59
+ hint: {
60
+ type: String
61
+ },
62
+ layout: {
63
+ type: String,
64
+ default: 'default',
65
+ validator: (value) => ['default', 'mini'].includes(value)
66
+ },
67
+ value: {
68
+ required: true,
69
+ },
70
+ disabled: {
71
+ type: Boolean,
72
+ default: false
73
+ },
74
+ hasError: {
75
+ type: [String, Boolean],
76
+ default: false
77
+ },
78
+ active: {
79
+ type: Boolean,
80
+ default: false
81
+ },
82
+ },
83
+ data: () => ({
84
+ isHoveringInputWrapper: false,
85
+ isFocus: false,
86
+ }),
87
+ computed: {
88
+ getAttrs() {
89
+ const defaultAttrs = {
90
+ autocapitalize: 'sentences',
91
+ autocomplete: 'chrome-off',
92
+ autocorrect: 'off',
93
+ spellcheck: 'spellcheck'
94
+ }
95
+ return { ...defaultAttrs, ...this.$attrs }
96
+ },
97
+ getComponentClass() {
98
+ if (this.disabled) {
99
+ return 'status-disabled'
100
+ } else if (this.hasError) {
101
+ return 'status-error'
102
+ } else if (this.isFocus || this.isTyping || this.active ) {
103
+ return 'status-active'
104
+ } else {
105
+ return 'status-resting'
106
+ }
107
+ },
108
+ },
109
+ methods: {
110
+ onInputFocus($event) {
111
+ this.isFocus = true
112
+ this.$emit('focus', $event)
113
+ },
114
+ onInputBlur($event) {
115
+ this.isFocus = false
116
+ this.$emit('blur', $event)
117
+ }
118
+ }
119
+ }
120
+ </script>
121
+
122
+ <style> /* Please, use the file src/assets/scss/components/PsInput.scss */</style>
@@ -1,38 +1,57 @@
1
1
  <template>
2
- <div :class="cssClass">
3
- <div class="material-icons psui-my-auto">info</div>
4
- <div class="psui-w-full">{{ message }}</div>
5
- <div class="psui-cursor-pointer psui-font-bold psui-my-auto psui-pr-4">OK</div>
2
+ <div class="psui-flex psui-justify-between psui-pr-3 psui-pl-2 psui-py-2 psui-rounded-md" :class="getDialogColor">
3
+ <div class="psui-flex psui-justify-between psui-gap-2">
4
+ <i class="material-icons-round">info</i>
5
+ <div class="psui-flex psui-flex-col">
6
+ <p v-if="message" class="psui-w-full">{{ message }}</p>
7
+ <slot v-else name="content"></slot>
8
+ <slot v-if="layout === 'vertical'" name="action"></slot>
9
+ </div>
10
+ </div>
11
+ <div class="psui-flex psui-gap-3">
12
+ <slot v-if="layout === 'horizontal'" name="action"></slot>
13
+ <button @click="onClose" class="psui-w-4 psui-h-4 focus:psui-outline-none">
14
+ <i class="material-icons-round">close</i>
15
+ </button>
16
+ </div>
6
17
  </div>
7
18
  </template>
8
19
 
9
20
  <script>
10
- export const typeOptions = ['informative', 'success', 'alert']
21
+
11
22
  export default {
12
23
  name: 'PsDialog',
13
24
  props: {
14
- type: {
25
+ status: {
15
26
  type: String,
16
27
  default: 'informative',
17
- validator: (value) => typeOptions.indexOf(value) !== -1
28
+ validator: (value) => ['informative', 'success', 'alert'].includes(value)
18
29
  },
19
30
  message: {
20
31
  type: String,
21
- required: true
32
+ },
33
+ layout:{
34
+ type: String,
35
+ default: 'horizontal',
36
+ validator: (value) => ['horizontal', 'vertical'].includes(value)
37
+ },
38
+ cssClass:{
39
+ type: String
22
40
  }
23
41
  },
24
- data() {
25
- return {
26
- colors: {
27
- informative: { background:'blue-20', color: 'blue-60' },
28
- success: { background:'green-10', color: 'green-70' },
29
- alert: { background:'yellow-10', color: 'yellow-70' }
30
- }
42
+ emits:['close'],
43
+ computed: {
44
+ getDialogColor() {
45
+ let dialogColor = ''
46
+ if(this.status === 'informative') dialogColor = `psui-bg-blue-20 psui-text-blue-60 ${this.cssClass}`
47
+ if(this.status === 'success') dialogColor = `psui-bg-green-10 psui-text-green-70 ${this.cssClass}`
48
+ if(this.status === 'alert') dialogColor = `psui-bg-yellow-10 psui-text-yellow-70 ${this.cssClass}`
49
+ return dialogColor
31
50
  }
32
51
  },
33
- computed: {
34
- cssClass() {
35
- return `psui-flex psui-space-x-4 psui-font-small psui-rounded-md psui-py-2 psui-px-4 psui-align-middle psui-flex psui-bg-${this.colors[this.type].background} psui-text-${this.colors[this.type].color}`
52
+ methods:{
53
+ onClose(){
54
+ this.$emit('close')
36
55
  }
37
56
  }
38
57
  }
@@ -21,6 +21,26 @@
21
21
  export const themeOptions = ['standard', 'underline', 'folder']
22
22
  export default {
23
23
  name: 'PsTabHeader',
24
+ props: {
25
+ theme: {
26
+ type: String,
27
+ default: 'standard',
28
+ validator: (value) => themeOptions.indexOf(value) !== -1
29
+ },
30
+ items: {
31
+ type: Array,
32
+ required: true
33
+ },
34
+ selected: {},
35
+ keyLabel: {
36
+ type: String,
37
+ default: 'label'
38
+ },
39
+ keyValue: {
40
+ type: String,
41
+ default: 'value'
42
+ }
43
+ },
24
44
  computed: {
25
45
  wrapperClasses() {
26
46
  if (this.theme === 'underline') {
@@ -67,27 +87,6 @@ export default {
67
87
  }
68
88
  }
69
89
  },
70
-
71
- props: {
72
- theme: {
73
- type: String,
74
- default: 'standard',
75
- validator: (value) => themeOptions.indexOf(value) !== -1
76
- },
77
- items: {
78
- type: Array,
79
- required: true
80
- },
81
- selected: {},
82
- keyLabel: {
83
- type: String,
84
- default: 'label'
85
- },
86
- keyValue: {
87
- type: String,
88
- default: 'value'
89
- }
90
- },
91
90
  methods: {
92
91
  selectTab(item) {
93
92
  this.$emit('update:selected', this.getIsObject ? item : item[this.keyValue] )
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <PsTooltip :cssClass="getCssClass.content" :title="title">
3
+ <template v-slot:trigger>
4
+ <slot></slot>
5
+ </template>
6
+ <template
7
+ v-slot:dialog
8
+ class="psui-flex psui-fkex-col psui-gap-3 psui-items-start"
9
+ >
10
+ <p :class="type === 'white' ? 'psui-text-gray-50' : ''">{{ text }}</p>
11
+ <button
12
+ v-if="buttonText"
13
+ class="psui-py-2 psui-px-4 psui-rounded-md"
14
+ :class="getCssClass.button"
15
+ @click="onClick"
16
+ >
17
+ {{ buttonText }}
18
+ </button>
19
+ </template>
20
+ </PsTooltip>
21
+ </template>
22
+
23
+ <script>
24
+ import PsTooltip from "./PsTooltip.vue"
25
+
26
+ export default {
27
+ name: "PsDialogTooltip",
28
+ components: { PsTooltip },
29
+ props: {
30
+ text: {
31
+ type: String,
32
+ },
33
+ title: {
34
+ type: String,
35
+ },
36
+ buttonText: {
37
+ type: String,
38
+ },
39
+ type: {
40
+ type: String,
41
+ default: "white",
42
+ validator: (value) => ["white", "dark", "color"].includes(value),
43
+ },
44
+ cssClass: {
45
+ type: String,
46
+ required: false,
47
+ },
48
+ },
49
+ emits: ["click"],
50
+ computed: {
51
+ getCssClass() {
52
+
53
+ if (this.type === "dark")
54
+ return {
55
+ content: `psui-bg-blue-70 psui-text-white ${this.cssClass}`,
56
+ button: `psui-bg-blue-60 psui-text-white`,
57
+ }
58
+ if (this.type === "color")
59
+ return {
60
+ content: `psui-bg-blue-50 psui-text-white ${this.cssClass}`,
61
+ button: `psui-bg-blue-60 psui-text-white`,
62
+ }
63
+
64
+ return { content: `psui-bg-white psui-text-gray-80 ${this.cssClass}`, button: `psui-bg-blue-20 psui-text-blue-60`,}
65
+ },
66
+ },
67
+ methods: {
68
+ onClick() {
69
+ this.$emit("click")
70
+ },
71
+ },
72
+ }
73
+ </script>
74
+
75
+ <style scoped>
76
+ button {
77
+ width: fit-content;
78
+ }
79
+ </style>>
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <PsTooltip :cssClass="`${textColorClass} ${cssClass}`" :title="title">
3
+ <template v-slot:trigger>
4
+ <slot></slot>
5
+ </template>
6
+ <template v-slot:dialog>
7
+ <p v-if="text">{{text}}</p>
8
+ </template>
9
+ </PsTooltip>
10
+ </template>
11
+
12
+ <script>
13
+ import PsTooltip from "../tooltip/PsTooltip.vue"
14
+
15
+ export default {
16
+ name: "PsRichTooltip",
17
+ components: { PsTooltip },
18
+ props: {
19
+ title: {
20
+ type: String,
21
+ default: "",
22
+ },
23
+ type: {
24
+ type: String,
25
+ default: "gray",
26
+ validator: (type) => ["gray", "red", "blue"].includes(type),
27
+ },
28
+ text: {
29
+ type: String,
30
+ },
31
+ cssClass: {
32
+ type: String,
33
+ default: "",
34
+ },
35
+ },
36
+ computed: {
37
+ textColorClass() {
38
+ if (this.type === "red") return `psui-text-red-70 psui-bg-red-10 `
39
+ if (this.type === "blue") return `psui-bg-blue-70 psui-text-white`
40
+ return `psui-text-gray-80 psui-bg-gray-30 `
41
+ },
42
+ },
43
+ }
44
+ </script>