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