classcard-ui 0.2.774 → 0.2.775

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 (175) hide show
  1. package/README.md +24 -24
  2. package/dist/classcard-ui.common.js +79 -63
  3. package/dist/classcard-ui.common.js.map +1 -1
  4. package/dist/classcard-ui.umd.js +79 -63
  5. package/dist/classcard-ui.umd.js.map +1 -1
  6. package/dist/classcard-ui.umd.min.js +1 -1
  7. package/dist/classcard-ui.umd.min.js.map +1 -1
  8. package/package.json +81 -81
  9. package/src/App.vue +16 -16
  10. package/src/components/CAlerts/CAlerts.vue +70 -70
  11. package/src/components/CAlerts/index.js +2 -2
  12. package/src/components/CAnchorTabs/CAnchorTabs.vue +96 -96
  13. package/src/components/CAnchorTabs/index.js +2 -2
  14. package/src/components/CAnchorTag/CAnchorTag.vue +62 -62
  15. package/src/components/CAnchorTag/index.js +2 -2
  16. package/src/components/CAvatar/CAvatar.vue +112 -112
  17. package/src/components/CAvatar/index.js +2 -2
  18. package/src/components/CAvatarGroup/CAvatarGroup.vue +145 -145
  19. package/src/components/CAvatarGroup/index.js +2 -2
  20. package/src/components/CBasicTable/CBasicTable.vue +184 -184
  21. package/src/components/CBasicTable/index.js +2 -2
  22. package/src/components/CBreadcrumbs/CBreadcrumbs.vue +38 -38
  23. package/src/components/CBreadcrumbs/index.js +2 -2
  24. package/src/components/CButton/CButton.vue +147 -147
  25. package/src/components/CButton/index.js +2 -2
  26. package/src/components/CButtonGroup/CButtonGroup.vue +118 -118
  27. package/src/components/CButtonGroup/index.js +2 -2
  28. package/src/components/CButtonIcon/CButtonIcon.vue +112 -112
  29. package/src/components/CButtonIcon/index.js +2 -2
  30. package/src/components/CButtonLink/CButtonLink.vue +39 -39
  31. package/src/components/CButtonLink/index.js +2 -2
  32. package/src/components/CButtonSelect/CButtonSelect.vue +103 -103
  33. package/src/components/CButtonSelect/index.js +2 -2
  34. package/src/components/CButtonWithDropdown/CButtonWithDropdown.vue +168 -168
  35. package/src/components/CButtonWithDropdown/index.js +2 -2
  36. package/src/components/CCalendar/CCalendar.vue +410 -410
  37. package/src/components/CCalendar/index.js +3 -3
  38. package/src/components/CCard/CCard.vue +49 -49
  39. package/src/components/CCard/index.js +2 -2
  40. package/src/components/CCheckbox/CCheckbox.vue +70 -70
  41. package/src/components/CCheckbox/index.js +2 -2
  42. package/src/components/CCollapsibleSection/CCollapsibleSection.vue +101 -101
  43. package/src/components/CCollapsibleSection/index.js +2 -2
  44. package/src/components/CColorDots/CColorDots.vue +35 -35
  45. package/src/components/CColorDots/index.js +3 -3
  46. package/src/components/CConfirmActionModal/CConfirmActionModal.vue +131 -131
  47. package/src/components/CConfirmActionModal/index.js +3 -3
  48. package/src/components/CDatepicker/CDatepicker.vue +139 -139
  49. package/src/components/CDatepicker/index.js +2 -2
  50. package/src/components/CDualSelect/CDualSelect.vue +193 -193
  51. package/src/components/CDualSelect/index.js +2 -2
  52. package/src/components/CEditor/CEditor.vue +96 -96
  53. package/src/components/CEditor/index.js +2 -2
  54. package/src/components/CFormSectionHeading/CFormSectionHeading.vue +53 -53
  55. package/src/components/CFormSectionHeading/index.js +2 -2
  56. package/src/components/CGroupedSelect/CGroupedSelect.vue +218 -218
  57. package/src/components/CGroupedSelect/index.js +3 -3
  58. package/src/components/CIcon/CIcon.vue +77 -77
  59. package/src/components/CIcon/index.js +2 -2
  60. package/src/components/CIconDropdown/CIconDropdown.vue +118 -118
  61. package/src/components/CIconDropdown/index.js +2 -2
  62. package/src/components/CInput/CInput.vue +123 -123
  63. package/src/components/CInput/index.js +2 -2
  64. package/src/components/CInputAddon/CInputAddon.vue +202 -202
  65. package/src/components/CInputAddon/index.js +2 -2
  66. package/src/components/CInputEmail/CInputEmail.vue +93 -93
  67. package/src/components/CInputEmail/index.js +2 -2
  68. package/src/components/CModalHeading/CModalHeading.vue +22 -22
  69. package/src/components/CModalHeading/index.js +2 -2
  70. package/src/components/CModuleHelpLinks/CModuleHelpLinks.vue +39 -39
  71. package/src/components/CModuleHelpLinks/index.js +3 -3
  72. package/src/components/CMultiselect/CMultiselect.vue +361 -361
  73. package/src/components/CMultiselect/index.js +2 -2
  74. package/src/components/CMultiselectr/CMultiselectr.vue +44 -44
  75. package/src/components/CMultiselectr/index.js +2 -2
  76. package/src/components/CPageHeading/CPageHeading.vue +56 -56
  77. package/src/components/CPageHeading/index.js +2 -2
  78. package/src/components/CPagination/CPagination.vue +204 -204
  79. package/src/components/CPagination/index.js +2 -2
  80. package/src/components/CPhoneNumber/CPhoneNumber.vue +89 -89
  81. package/src/components/CPhoneNumber/index.js +2 -2
  82. package/src/components/CRadio/CRadio.vue +106 -106
  83. package/src/components/CRadio/index.js +2 -2
  84. package/src/components/CRangeSlider/CRangeSlider.vue +55 -55
  85. package/src/components/CRangeSlider/index.js +2 -2
  86. package/src/components/CReorderableStackedList/CReorderableStackedList.vue +94 -94
  87. package/src/components/CReorderableStackedList/index.js +2 -2
  88. package/src/components/CSelect/CSelect.vue +353 -353
  89. package/src/components/CSelect/index.js +2 -2
  90. package/src/components/CSmallTimeline/CSmallTimeline.vue +40 -40
  91. package/src/components/CSmallTimeline/index.js +2 -2
  92. package/src/components/CStackedList/CStackedList.vue +132 -132
  93. package/src/components/CStackedList/index.js +2 -2
  94. package/src/components/CStats/CStats.vue +116 -116
  95. package/src/components/CStats/index.js +2 -2
  96. package/src/components/CSwitch/CSwitch.vue +168 -168
  97. package/src/components/CSwitch/index.js +2 -2
  98. package/src/components/CTable/CTable.vue +542 -538
  99. package/src/components/CTable/index.js +2 -2
  100. package/src/components/CTabs/CTabs.vue +111 -111
  101. package/src/components/CTabs/index.js +2 -2
  102. package/src/components/CTag/CTag.vue +36 -36
  103. package/src/components/CTag/index.js +2 -2
  104. package/src/components/CTextarea/CTextarea.vue +95 -95
  105. package/src/components/CTextarea/index.js +2 -2
  106. package/src/components/CTimeline/CTimeline.vue +237 -237
  107. package/src/components/CTimeline/index.js +2 -2
  108. package/src/components/CUpload/CUpload.vue +231 -231
  109. package/src/components/CUpload/index.js +2 -2
  110. package/src/components/index.js +48 -48
  111. package/src/icons.js +304 -304
  112. package/src/main.js +22 -22
  113. package/src/stories/CAlerts.stories.js +37 -37
  114. package/src/stories/CAnchorTabs.stories.js +29 -29
  115. package/src/stories/CAnchorTag.stories.js +36 -36
  116. package/src/stories/CAvatar.stories.js +38 -38
  117. package/src/stories/CAvatarGroup.stories.js +100 -100
  118. package/src/stories/CBasicTable.stories.js +316 -316
  119. package/src/stories/CBreadcrumbs.stories.js +24 -24
  120. package/src/stories/CButton.stories.js +46 -46
  121. package/src/stories/CButtonGroup.stories.js +33 -33
  122. package/src/stories/CButtonIcon.stories.js +27 -27
  123. package/src/stories/CButtonLink.stories.js +24 -24
  124. package/src/stories/CButtonSelect.stories.js +32 -32
  125. package/src/stories/CButtonWithDropdown.stories.js +41 -41
  126. package/src/stories/CCalendar.stories.js +16 -16
  127. package/src/stories/CCard.stories.js +30 -30
  128. package/src/stories/CCheckbox.stories.js +29 -29
  129. package/src/stories/CCollapsibleSection.stories.js +28 -28
  130. package/src/stories/CColorDots.stories.js +28 -28
  131. package/src/stories/CConfirmActionModal.stories.js +59 -59
  132. package/src/stories/CDatepicker.stories.js +30 -30
  133. package/src/stories/CDualSelect.stories.js +29 -29
  134. package/src/stories/CEditor.stories.js +30 -30
  135. package/src/stories/CFormSectionHeading.stories.js +34 -34
  136. package/src/stories/CGroupedSelect.stories.js +69 -69
  137. package/src/stories/CIcon.stories.js +26 -26
  138. package/src/stories/CIconDropdown.stories.js +45 -45
  139. package/src/stories/CInput.stories.js +36 -36
  140. package/src/stories/CInputAddon.stories.js +37 -37
  141. package/src/stories/CInputEmail.stories.js +27 -27
  142. package/src/stories/CModalHeading.stories.js +25 -25
  143. package/src/stories/CModuleHelpLinks.stories.js +25 -25
  144. package/src/stories/CMultiselect.stories.js +103 -103
  145. package/src/stories/CMultiselectr.stories.js +23 -23
  146. package/src/stories/CPageHeading.stories.js +32 -32
  147. package/src/stories/CPagination.stories.js +30 -30
  148. package/src/stories/CPhoneNumber.stories.js +29 -29
  149. package/src/stories/CRadio.stories.js +36 -36
  150. package/src/stories/CRangeSlider.stories.js +23 -23
  151. package/src/stories/CReorderableStackedList.stories.js +23 -23
  152. package/src/stories/CSelect.stories.js +62 -62
  153. package/src/stories/CSmallTimeline.stories.js +26 -26
  154. package/src/stories/CStackedList.stories.js +37 -37
  155. package/src/stories/CStats.stories.js +33 -33
  156. package/src/stories/CSwitch.stories.js +28 -28
  157. package/src/stories/CTable.stories.js +77 -77
  158. package/src/stories/CTabs.stories.js +33 -33
  159. package/src/stories/CTag.stories.js +23 -23
  160. package/src/stories/CTextarea.stories.js +32 -32
  161. package/src/stories/CTimeline.stories.js +26 -26
  162. package/src/stories/CUpload.stories.js +36 -36
  163. package/src/stories/Introduction.stories.mdx +207 -207
  164. package/src/stories/Page.vue +88 -88
  165. package/src/stories/assets/code-brackets.svg +0 -0
  166. package/src/stories/assets/colors.svg +0 -0
  167. package/src/stories/assets/comments.svg +0 -0
  168. package/src/stories/assets/direction.svg +0 -0
  169. package/src/stories/assets/flow.svg +0 -0
  170. package/src/stories/assets/plugin.svg +0 -0
  171. package/src/stories/assets/repo.svg +0 -0
  172. package/src/stories/assets/stackalt.svg +0 -0
  173. package/src/stories/header.css +26 -26
  174. package/src/stories/page.css +69 -69
  175. package/src/stories/utils.css +17 -17
@@ -1,353 +1,353 @@
1
- <template>
2
- <div>
3
- <div class="flex w-full items-center justify-between" v-if="label">
4
- <div class="flex items-center">
5
- <!-- label of select field -->
6
- <label class="block text-sm font-medium text-gray-900">
7
- {{ label }}
8
- </label>
9
- <!-- asterisk sign to render if field is required -->
10
- <p v-if="isRequired" class="ml-1 text-red-600">*</p>
11
- </div>
12
- <span v-if="hint" class="text-sm text-gray-500">{{ hint }}</span>
13
- </div>
14
-
15
- <div class="relative">
16
- <div class="relative" :class="label ? 'mt-1' : ''">
17
- <input
18
- type="text"
19
- v-model="selectSearch"
20
- @click="toggleDropdown = !toggleDropdown"
21
- @focus="type == 'tertiary' ? (showFocus = true) : ''"
22
- @input="search()"
23
- aria-haspopup="listbox"
24
- aria-expanded="true"
25
- aria-labelledby="listbox-label"
26
- :class="{ ...classes, [inputClasses]: true }"
27
- class="relative w-full cursor-pointer rounded-md py-2 pl-3 pr-10 text-left text-sm focus:outline-none disabled:opacity-50 sm:text-sm"
28
- :disabled="isDisabled"
29
- autocomplete="off"
30
- />
31
-
32
- <div
33
- class="pointer-events-none absolute inset-0 left-3 flex h-[38px] items-center overflow-hidden pr-10"
34
- >
35
- <div class="flex items-center truncate" :style="selectedOptionStyles">
36
- <div v-if="showImage && !selectSearch && value">
37
- <c-avatar
38
- v-if="value.photo"
39
- size="extraextrasmall"
40
- :image="value.photo"
41
- :rounded="true"
42
- ></c-avatar>
43
- <c-avatar
44
- v-else
45
- size="extraextrasmall"
46
- :nameInitials="value.initials"
47
- :rounded="true"
48
- :isDynamicallyColored="coloredAvatars"
49
- ></c-avatar>
50
- </div>
51
- <c-icon
52
- v-if="icon && !showImage"
53
- :class="icon.class"
54
- :name="icon.name"
55
- :type="icon.type"
56
- >
57
- </c-icon>
58
- <p :class="showImage ? 'ml-3' : ''" class="block truncate text-sm">
59
- {{
60
- selectedValue
61
- ? selectedValue
62
- : !selectSearch || selectSearch == ""
63
- ? placeholder
64
- : null
65
- }}
66
- </p>
67
- </div>
68
- </div>
69
- <div class="pointer-events-none absolute top-2 right-3 flex">
70
- <div
71
- v-if="type == 'tertiary' ? showFocus : true"
72
- class="pointer-events-none right-0 flex items-center"
73
- >
74
- <c-icon
75
- name="selector"
76
- type="solid"
77
- class="h-5 w-5 text-gray-400"
78
- ></c-icon>
79
- </div>
80
- </div>
81
- </div>
82
- <transition
83
- enter-active-class="transition ease-out duration-100"
84
- enter-class="transform opacity-0 scale-95"
85
- enter-to-class="transform opacity-100 scale-100"
86
- leave-active-class="transition ease-in duration-75"
87
- leave-class="transform opacity-100 scale-100"
88
- leave-to-class="transform opacity-0 scale-95"
89
- >
90
- <div
91
- v-if="toggleDropdown && !isDisabled"
92
- class="absolute z-10 mt-1 w-full rounded-md bg-white shadow-lg"
93
- >
94
- <ul
95
- tabindex="-1"
96
- role="listbox"
97
- aria-labelledby="listbox-label"
98
- class="max-h-60 overflow-auto rounded-md py-1 text-base ring-1 ring-gray-900 ring-opacity-5 focus:outline-none sm:text-sm"
99
- >
100
- <li
101
- v-if="addAction"
102
- @mousedown="actionEvent($event)"
103
- class="relative flex cursor-pointer select-none py-2 pl-3 pr-9 text-indigo-500 hover:bg-indigo-100 hover:text-indigo-700"
104
- >
105
- <c-icon
106
- type="outline"
107
- class="mr-1 h-5 w-5 text-indigo-400 group-hover:text-indigo-500"
108
- name="plus"
109
- ></c-icon>
110
- {{ addAction.label }}
111
- </li>
112
- <li
113
- v-for="(option, index) in renderOptions"
114
- :key="index"
115
- id="listbox-option-0"
116
- role="option"
117
- :ref="`option-${String(index)}`"
118
- @mousedown="handleSelect($event, option)"
119
- class="relative cursor-pointer select-none py-2 pl-3 pr-9 text-gray-900 hover:bg-indigo-700 hover:text-white"
120
- :class="[
121
- option.isDisabled ? 'pointer-events-none opacity-50' : '',
122
- optionClasses,
123
- ]"
124
- >
125
- <span class="flex items-center">
126
- <div v-if="option.showImage">
127
- <c-avatar
128
- v-if="option.photo"
129
- size="extraextrasmall"
130
- :image="option.photo"
131
- :rounded="true"
132
- ></c-avatar>
133
- <c-avatar
134
- v-else
135
- size="extraextrasmall"
136
- :nameInitials="option.initials"
137
- :rounded="true"
138
- :isDynamicallyColored="coloredAvatars"
139
- ></c-avatar>
140
- </div>
141
- <c-icon
142
- class="flex-none"
143
- v-if="option.showIcon && option.icon"
144
- :class="option.icon.class"
145
- :name="option.icon.name"
146
- :type="option.icon.type"
147
- >
148
- </c-icon>
149
- <span
150
- :class="option.photo || option.initials ? 'ml-3' : ''"
151
- class="list-options block break-words font-normal"
152
- >{{ option[renderOptionName] }}
153
- </span>
154
- </span>
155
-
156
- <span
157
- class="absolute inset-y-0 right-0 flex items-center pr-4 text-indigo-600"
158
- >
159
- <c-icon
160
- id="list-icon"
161
- v-show="showSelectedValue"
162
- name="check"
163
- type="solid"
164
- class="h-5 w-5"
165
- ></c-icon>
166
- </span>
167
- </li>
168
- </ul>
169
- </div>
170
- </transition>
171
- <!-- validation error message -->
172
- <p v-if="!isValidate" class="mt-2 text-left text-sm text-red-600">
173
- {{ errorMessage }}
174
- </p>
175
- <p v-if="helpText" class="mt-2 text-sm text-gray-500">
176
- {{ helpText }}
177
- </p>
178
- </div>
179
- </div>
180
- </template>
181
- <script>
182
- import CIcon from "../CIcon/CIcon.vue";
183
- import CAvatar from "../CAvatar/CAvatar.vue";
184
- import { isNumber } from "lodash";
185
- export default {
186
- name: "CSelect",
187
- components: { CIcon, CAvatar },
188
- props: {
189
- // label of selectpicker
190
- label: {
191
- type: String,
192
- },
193
- // placeholder in selectpicker
194
- placeholder: {
195
- type: String,
196
- },
197
- // list to render in dropdown
198
- options: {
199
- type: Array,
200
- required: true,
201
- },
202
- // show the avatars with different colors
203
- coloredAvatars: {
204
- type: Boolean,
205
- },
206
- // text below dropdown to describe more about the field
207
- helpText: {
208
- type: String,
209
- },
210
- // text adjacent to label of dropdown to provide hint about field
211
- hint: { type: String },
212
- // to show if image is present along with dropdown option
213
- showImage: { type: Boolean },
214
- // whether the select field is mandatory or not
215
- isRequired: {
216
- type: Boolean,
217
- },
218
- // validation is passed or not
219
- isValidate: { type: Boolean, default: true },
220
- // will truncate the text in input field
221
- selectedOptionStyles: {
222
- type: String,
223
- },
224
- // validation error message
225
- errorMessage: {
226
- type: String,
227
- },
228
- // perform action on first option in dropdown
229
- addAction: { type: Object },
230
- // icons in dropdown list
231
- icon: { type: Object },
232
- // value to set as default option in dropdown
233
- value: { type: [Object, String], default: null },
234
- // type of dropdown - gray,tertiary or default
235
- type: {
236
- type: String,
237
- },
238
- // name of the field in array to that contains text to render in dropdown
239
- renderOptionName: {
240
- type: String,
241
- default: "option",
242
- },
243
- // whether to disable the selectpicker
244
- isDisabled: {
245
- type: Boolean,
246
- default: false,
247
- },
248
- inputClasses: {
249
- type: String,
250
- default: "",
251
- },
252
- optionClasses: {
253
- type: String,
254
- default: "",
255
- },
256
- },
257
- data() {
258
- return {
259
- toggleDropdown: false,
260
- selectedValue: null,
261
- showSelectedValue: false,
262
- showFocus: false,
263
- selectSearch: null,
264
- renderOptions: this.options,
265
- };
266
- },
267
- computed: {
268
- classes() {
269
- return {
270
- "text-gray-900 border border-gray-200 hover:bg-gray-200 bg-gray-100 focus:ring-2 focus:border-gray-200 focus:ring-gray-200 focus:ring-offset-2 shadow-sm":
271
- this.type == "gray",
272
- "bg-white border border-gray-200 hover:bg-indigo-100 text-indigo-600 hover:text-indigo-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-200":
273
- this.type == "tertiary",
274
- "border border-gray-300 focus:ring-indigo-500 focus:border-indigo-500 bg-white shadow-sm focus:ring-1":
275
- this.type == null,
276
- };
277
- },
278
- },
279
- methods: {
280
- handleSelect(event, option) {
281
- this.selectSearch = null;
282
- this.selectedValue = option[this.renderOptionName];
283
- this.$emit("onChangeValue", option);
284
- this.toggleDropdown = false;
285
- this.type === "tertiary" ? (this.showFocus = false) : "";
286
- this.renderOptions = this.options;
287
- },
288
- actionEvent(event) {
289
- this.$emit("listAction", event);
290
- },
291
- // close() {
292
- // console.log("Close");
293
- // this.selectSearch = null;
294
- // this.toggleDropdown = false;
295
- // this.type === "tertiary" ? (this.showFocus = false) : "";
296
- // this.renderOptions = this.options;
297
- // },
298
- search() {
299
- this.selectedValue = null;
300
- if (!this.selectSearch || this.selectSearch == "") {
301
- this.renderOptions = this.options;
302
- return;
303
- }
304
- let options = [...this.options];
305
- this.renderOptions = options.filter((option) => {
306
- isNumber(option[this.renderOptionName])
307
- ? (option[this.renderOptionName] =
308
- option[this.renderOptionName].toString())
309
- : "";
310
- return option[this.renderOptionName]
311
- .toLowerCase()
312
- .includes(this.selectSearch.toLowerCase());
313
- });
314
- this.$emit("search-term", this.selectSearch);
315
- },
316
- async scrollOptionIntoView(refName) {
317
- await this.$nextTick();
318
- this.$refs[refName][0].scrollIntoView({
319
- behavior: "smooth",
320
- block: "nearest", //changed due to pop up issue in main menu
321
- });
322
- },
323
- },
324
- watch: {
325
- value() {
326
- this.selectedValue =
327
- this.value !== null && this.value[this.renderOptionName]
328
- ? this.value[this.renderOptionName]
329
- : this.value;
330
- },
331
- options() {
332
- this.renderOptions = this.options;
333
- },
334
- toggleDropdown(newValue) {
335
- if (newValue) {
336
- let index = this.renderOptions.findIndex(
337
- (option) => option[this.renderOptionName] === this.selectedValue
338
- );
339
- if (index !== -1) {
340
- let refName = `option-${String(index)}`;
341
- this.scrollOptionIntoView(refName);
342
- }
343
- }
344
- },
345
- },
346
- mounted() {
347
- this.selectedValue =
348
- this.value !== null && this.value[this.renderOptionName]
349
- ? this.value[this.renderOptionName]
350
- : this.value;
351
- },
352
- };
353
- </script>
1
+ <template>
2
+ <div>
3
+ <div class="flex w-full items-center justify-between" v-if="label">
4
+ <div class="flex items-center">
5
+ <!-- label of select field -->
6
+ <label class="block text-sm font-medium text-gray-900">
7
+ {{ label }}
8
+ </label>
9
+ <!-- asterisk sign to render if field is required -->
10
+ <p v-if="isRequired" class="ml-1 text-red-600">*</p>
11
+ </div>
12
+ <span v-if="hint" class="text-sm text-gray-500">{{ hint }}</span>
13
+ </div>
14
+
15
+ <div class="relative">
16
+ <div class="relative" :class="label ? 'mt-1' : ''">
17
+ <input
18
+ type="text"
19
+ v-model="selectSearch"
20
+ @click="toggleDropdown = !toggleDropdown"
21
+ @focus="type == 'tertiary' ? (showFocus = true) : ''"
22
+ @input="search()"
23
+ aria-haspopup="listbox"
24
+ aria-expanded="true"
25
+ aria-labelledby="listbox-label"
26
+ :class="{ ...classes, [inputClasses]: true }"
27
+ class="relative w-full cursor-pointer rounded-md py-2 pl-3 pr-10 text-left text-sm focus:outline-none disabled:opacity-50 sm:text-sm"
28
+ :disabled="isDisabled"
29
+ autocomplete="off"
30
+ />
31
+
32
+ <div
33
+ class="pointer-events-none absolute inset-0 left-3 flex h-[38px] items-center overflow-hidden pr-10"
34
+ >
35
+ <div class="flex items-center truncate" :style="selectedOptionStyles">
36
+ <div v-if="showImage && !selectSearch && value">
37
+ <c-avatar
38
+ v-if="value.photo"
39
+ size="extraextrasmall"
40
+ :image="value.photo"
41
+ :rounded="true"
42
+ ></c-avatar>
43
+ <c-avatar
44
+ v-else
45
+ size="extraextrasmall"
46
+ :nameInitials="value.initials"
47
+ :rounded="true"
48
+ :isDynamicallyColored="coloredAvatars"
49
+ ></c-avatar>
50
+ </div>
51
+ <c-icon
52
+ v-if="icon && !showImage"
53
+ :class="icon.class"
54
+ :name="icon.name"
55
+ :type="icon.type"
56
+ >
57
+ </c-icon>
58
+ <p :class="showImage ? 'ml-3' : ''" class="block truncate text-sm">
59
+ {{
60
+ selectedValue
61
+ ? selectedValue
62
+ : !selectSearch || selectSearch == ""
63
+ ? placeholder
64
+ : null
65
+ }}
66
+ </p>
67
+ </div>
68
+ </div>
69
+ <div class="pointer-events-none absolute top-2 right-3 flex">
70
+ <div
71
+ v-if="type == 'tertiary' ? showFocus : true"
72
+ class="pointer-events-none right-0 flex items-center"
73
+ >
74
+ <c-icon
75
+ name="selector"
76
+ type="solid"
77
+ class="h-5 w-5 text-gray-400"
78
+ ></c-icon>
79
+ </div>
80
+ </div>
81
+ </div>
82
+ <transition
83
+ enter-active-class="transition ease-out duration-100"
84
+ enter-class="transform opacity-0 scale-95"
85
+ enter-to-class="transform opacity-100 scale-100"
86
+ leave-active-class="transition ease-in duration-75"
87
+ leave-class="transform opacity-100 scale-100"
88
+ leave-to-class="transform opacity-0 scale-95"
89
+ >
90
+ <div
91
+ v-if="toggleDropdown && !isDisabled"
92
+ class="absolute z-10 mt-1 w-full rounded-md bg-white shadow-lg"
93
+ >
94
+ <ul
95
+ tabindex="-1"
96
+ role="listbox"
97
+ aria-labelledby="listbox-label"
98
+ class="max-h-60 overflow-auto rounded-md py-1 text-base ring-1 ring-gray-900 ring-opacity-5 focus:outline-none sm:text-sm"
99
+ >
100
+ <li
101
+ v-if="addAction"
102
+ @mousedown="actionEvent($event)"
103
+ class="relative flex cursor-pointer select-none py-2 pl-3 pr-9 text-indigo-500 hover:bg-indigo-100 hover:text-indigo-700"
104
+ >
105
+ <c-icon
106
+ type="outline"
107
+ class="mr-1 h-5 w-5 text-indigo-400 group-hover:text-indigo-500"
108
+ name="plus"
109
+ ></c-icon>
110
+ {{ addAction.label }}
111
+ </li>
112
+ <li
113
+ v-for="(option, index) in renderOptions"
114
+ :key="index"
115
+ id="listbox-option-0"
116
+ role="option"
117
+ :ref="`option-${String(index)}`"
118
+ @mousedown="handleSelect($event, option)"
119
+ class="relative cursor-pointer select-none py-2 pl-3 pr-9 text-gray-900 hover:bg-indigo-700 hover:text-white"
120
+ :class="[
121
+ option.isDisabled ? 'pointer-events-none opacity-50' : '',
122
+ optionClasses,
123
+ ]"
124
+ >
125
+ <span class="flex items-center">
126
+ <div v-if="option.showImage">
127
+ <c-avatar
128
+ v-if="option.photo"
129
+ size="extraextrasmall"
130
+ :image="option.photo"
131
+ :rounded="true"
132
+ ></c-avatar>
133
+ <c-avatar
134
+ v-else
135
+ size="extraextrasmall"
136
+ :nameInitials="option.initials"
137
+ :rounded="true"
138
+ :isDynamicallyColored="coloredAvatars"
139
+ ></c-avatar>
140
+ </div>
141
+ <c-icon
142
+ class="flex-none"
143
+ v-if="option.showIcon && option.icon"
144
+ :class="option.icon.class"
145
+ :name="option.icon.name"
146
+ :type="option.icon.type"
147
+ >
148
+ </c-icon>
149
+ <span
150
+ :class="option.photo || option.initials ? 'ml-3' : ''"
151
+ class="list-options block break-words font-normal"
152
+ >{{ option[renderOptionName] }}
153
+ </span>
154
+ </span>
155
+
156
+ <span
157
+ class="absolute inset-y-0 right-0 flex items-center pr-4 text-indigo-600"
158
+ >
159
+ <c-icon
160
+ id="list-icon"
161
+ v-show="showSelectedValue"
162
+ name="check"
163
+ type="solid"
164
+ class="h-5 w-5"
165
+ ></c-icon>
166
+ </span>
167
+ </li>
168
+ </ul>
169
+ </div>
170
+ </transition>
171
+ <!-- validation error message -->
172
+ <p v-if="!isValidate" class="mt-2 text-left text-sm text-red-600">
173
+ {{ errorMessage }}
174
+ </p>
175
+ <p v-if="helpText" class="mt-2 text-sm text-gray-500">
176
+ {{ helpText }}
177
+ </p>
178
+ </div>
179
+ </div>
180
+ </template>
181
+ <script>
182
+ import CIcon from "../CIcon/CIcon.vue";
183
+ import CAvatar from "../CAvatar/CAvatar.vue";
184
+ import { isNumber } from "lodash";
185
+ export default {
186
+ name: "CSelect",
187
+ components: { CIcon, CAvatar },
188
+ props: {
189
+ // label of selectpicker
190
+ label: {
191
+ type: String,
192
+ },
193
+ // placeholder in selectpicker
194
+ placeholder: {
195
+ type: String,
196
+ },
197
+ // list to render in dropdown
198
+ options: {
199
+ type: Array,
200
+ required: true,
201
+ },
202
+ // show the avatars with different colors
203
+ coloredAvatars: {
204
+ type: Boolean,
205
+ },
206
+ // text below dropdown to describe more about the field
207
+ helpText: {
208
+ type: String,
209
+ },
210
+ // text adjacent to label of dropdown to provide hint about field
211
+ hint: { type: String },
212
+ // to show if image is present along with dropdown option
213
+ showImage: { type: Boolean },
214
+ // whether the select field is mandatory or not
215
+ isRequired: {
216
+ type: Boolean,
217
+ },
218
+ // validation is passed or not
219
+ isValidate: { type: Boolean, default: true },
220
+ // will truncate the text in input field
221
+ selectedOptionStyles: {
222
+ type: String,
223
+ },
224
+ // validation error message
225
+ errorMessage: {
226
+ type: String,
227
+ },
228
+ // perform action on first option in dropdown
229
+ addAction: { type: Object },
230
+ // icons in dropdown list
231
+ icon: { type: Object },
232
+ // value to set as default option in dropdown
233
+ value: { type: [Object, String], default: null },
234
+ // type of dropdown - gray,tertiary or default
235
+ type: {
236
+ type: String,
237
+ },
238
+ // name of the field in array to that contains text to render in dropdown
239
+ renderOptionName: {
240
+ type: String,
241
+ default: "option",
242
+ },
243
+ // whether to disable the selectpicker
244
+ isDisabled: {
245
+ type: Boolean,
246
+ default: false,
247
+ },
248
+ inputClasses: {
249
+ type: String,
250
+ default: "",
251
+ },
252
+ optionClasses: {
253
+ type: String,
254
+ default: "",
255
+ },
256
+ },
257
+ data() {
258
+ return {
259
+ toggleDropdown: false,
260
+ selectedValue: null,
261
+ showSelectedValue: false,
262
+ showFocus: false,
263
+ selectSearch: null,
264
+ renderOptions: this.options,
265
+ };
266
+ },
267
+ computed: {
268
+ classes() {
269
+ return {
270
+ "text-gray-900 border border-gray-200 hover:bg-gray-200 bg-gray-100 focus:ring-2 focus:border-gray-200 focus:ring-gray-200 focus:ring-offset-2 shadow-sm":
271
+ this.type == "gray",
272
+ "bg-white border border-gray-200 hover:bg-indigo-100 text-indigo-600 hover:text-indigo-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-200":
273
+ this.type == "tertiary",
274
+ "border border-gray-300 focus:ring-indigo-500 focus:border-indigo-500 bg-white shadow-sm focus:ring-1":
275
+ this.type == null,
276
+ };
277
+ },
278
+ },
279
+ methods: {
280
+ handleSelect(event, option) {
281
+ this.selectSearch = null;
282
+ this.selectedValue = option[this.renderOptionName];
283
+ this.$emit("onChangeValue", option);
284
+ this.toggleDropdown = false;
285
+ this.type === "tertiary" ? (this.showFocus = false) : "";
286
+ this.renderOptions = this.options;
287
+ },
288
+ actionEvent(event) {
289
+ this.$emit("listAction", event);
290
+ },
291
+ // close() {
292
+ // console.log("Close");
293
+ // this.selectSearch = null;
294
+ // this.toggleDropdown = false;
295
+ // this.type === "tertiary" ? (this.showFocus = false) : "";
296
+ // this.renderOptions = this.options;
297
+ // },
298
+ search() {
299
+ this.selectedValue = null;
300
+ if (!this.selectSearch || this.selectSearch == "") {
301
+ this.renderOptions = this.options;
302
+ return;
303
+ }
304
+ let options = [...this.options];
305
+ this.renderOptions = options.filter((option) => {
306
+ isNumber(option[this.renderOptionName])
307
+ ? (option[this.renderOptionName] =
308
+ option[this.renderOptionName].toString())
309
+ : "";
310
+ return option[this.renderOptionName]
311
+ .toLowerCase()
312
+ .includes(this.selectSearch.toLowerCase());
313
+ });
314
+ this.$emit("search-term", this.selectSearch);
315
+ },
316
+ async scrollOptionIntoView(refName) {
317
+ await this.$nextTick();
318
+ this.$refs[refName][0].scrollIntoView({
319
+ behavior: "smooth",
320
+ block: "nearest", //changed due to pop up issue in main menu
321
+ });
322
+ },
323
+ },
324
+ watch: {
325
+ value() {
326
+ this.selectedValue =
327
+ this.value !== null && this.value[this.renderOptionName]
328
+ ? this.value[this.renderOptionName]
329
+ : this.value;
330
+ },
331
+ options() {
332
+ this.renderOptions = this.options;
333
+ },
334
+ toggleDropdown(newValue) {
335
+ if (newValue) {
336
+ let index = this.renderOptions.findIndex(
337
+ (option) => option[this.renderOptionName] === this.selectedValue
338
+ );
339
+ if (index !== -1) {
340
+ let refName = `option-${String(index)}`;
341
+ this.scrollOptionIntoView(refName);
342
+ }
343
+ }
344
+ },
345
+ },
346
+ mounted() {
347
+ this.selectedValue =
348
+ this.value !== null && this.value[this.renderOptionName]
349
+ ? this.value[this.renderOptionName]
350
+ : this.value;
351
+ },
352
+ };
353
+ </script>