classcard-ui 0.2.1462 → 0.2.1464

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 (209) hide show
  1. package/README.md +24 -24
  2. package/dist/classcard-ui.common.js +148 -113
  3. package/dist/classcard-ui.common.js.map +1 -1
  4. package/dist/classcard-ui.css +1 -1
  5. package/dist/classcard-ui.umd.js +148 -113
  6. package/dist/classcard-ui.umd.js.map +1 -1
  7. package/dist/classcard-ui.umd.min.js +2 -2
  8. package/dist/classcard-ui.umd.min.js.map +1 -1
  9. package/package.json +83 -83
  10. package/src/App.vue +16 -16
  11. package/src/colorConfig.js +52 -52
  12. package/src/components/CAlertModal/CAlertModal.vue +179 -179
  13. package/src/components/CAlertModal/index.js +3 -3
  14. package/src/components/CAlerts/CAlerts.vue +97 -97
  15. package/src/components/CAlerts/index.js +2 -2
  16. package/src/components/CAnchorTabs/CAnchorTabs.vue +100 -100
  17. package/src/components/CAnchorTabs/index.js +2 -2
  18. package/src/components/CAnchorTag/CAnchorTag.vue +84 -84
  19. package/src/components/CAnchorTag/index.js +2 -2
  20. package/src/components/CAvatar/CAvatar.vue +230 -230
  21. package/src/components/CAvatar/index.js +2 -2
  22. package/src/components/CAvatarGroup/CAvatarGroup.vue +213 -213
  23. package/src/components/CAvatarGroup/index.js +2 -2
  24. package/src/components/CBasicTable/CBasicTable.vue +184 -184
  25. package/src/components/CBasicTable/index.js +2 -2
  26. package/src/components/CBreadcrumbs/CBreadcrumbs.vue +38 -38
  27. package/src/components/CBreadcrumbs/index.js +2 -2
  28. package/src/components/CButton/CButton.vue +239 -239
  29. package/src/components/CButton/index.js +2 -2
  30. package/src/components/CButtonGroup/CButtonGroup.vue +155 -155
  31. package/src/components/CButtonGroup/index.js +2 -2
  32. package/src/components/CButtonIcon/CButtonIcon.vue +166 -166
  33. package/src/components/CButtonIcon/index.js +2 -2
  34. package/src/components/CButtonLink/CButtonLink.vue +43 -43
  35. package/src/components/CButtonLink/index.js +2 -2
  36. package/src/components/CButtonSelect/CButtonSelect.vue +186 -186
  37. package/src/components/CButtonSelect/index.js +2 -2
  38. package/src/components/CButtonSelectBorder/CButtonSelectBorder.vue +265 -265
  39. package/src/components/CButtonSelectBorder/index.js +3 -3
  40. package/src/components/CButtonWithDropdown/CButtonWithDropdown.vue +152 -152
  41. package/src/components/CButtonWithDropdown/index.js +2 -2
  42. package/src/components/CCalendar/CCalendar.vue +443 -443
  43. package/src/components/CCalendar/index.js +3 -3
  44. package/src/components/CCard/CCard.vue +53 -53
  45. package/src/components/CCard/index.js +2 -2
  46. package/src/components/CCheckbox/CCheckbox.vue +200 -200
  47. package/src/components/CCheckbox/index.js +2 -2
  48. package/src/components/CCircularButton/CCircularButton.vue +57 -57
  49. package/src/components/CCircularButton/index.js +2 -2
  50. package/src/components/CCollapsibleSection/CCollapsibleSection.vue +121 -121
  51. package/src/components/CCollapsibleSection/index.js +2 -2
  52. package/src/components/CColorDots/CColorDots.vue +52 -52
  53. package/src/components/CColorDots/index.js +3 -3
  54. package/src/components/CConfirmActionModal/CConfirmActionModal.vue +198 -198
  55. package/src/components/CConfirmActionModal/index.js +3 -3
  56. package/src/components/CDatepicker/CDatepicker.vue +235 -235
  57. package/src/components/CDatepicker/index.js +2 -2
  58. package/src/components/CDualSelect/CDualSelect.vue +193 -193
  59. package/src/components/CDualSelect/index.js +2 -2
  60. package/src/components/CEditor/CEditor.vue +114 -114
  61. package/src/components/CEditor/index.js +2 -2
  62. package/src/components/CFormSectionHeading/CFormSectionHeading.vue +76 -76
  63. package/src/components/CFormSectionHeading/index.js +2 -2
  64. package/src/components/CGroupedFilterDropdown/CGroupedFilterDropdown.vue +253 -253
  65. package/src/components/CGroupedFilterDropdown/index.js +2 -2
  66. package/src/components/CGroupedSelect/CGroupedSelect.vue +366 -366
  67. package/src/components/CGroupedSelect/index.js +3 -3
  68. package/src/components/CIcon/CIcon.vue +112 -112
  69. package/src/components/CIcon/index.js +2 -2
  70. package/src/components/CIconDropdown/CIconDropdown.vue +191 -191
  71. package/src/components/CIconDropdown/index.js +2 -2
  72. package/src/components/CIconSelect/CIconSelect.vue +182 -182
  73. package/src/components/CIconSelect/index.js +3 -3
  74. package/src/components/CInput/CInput.vue +173 -173
  75. package/src/components/CInput/index.js +2 -2
  76. package/src/components/CInputAddon/CInputAddon.vue +297 -297
  77. package/src/components/CInputAddon/index.js +2 -2
  78. package/src/components/CInputEmail/CInputEmail.vue +107 -107
  79. package/src/components/CInputEmail/index.js +2 -2
  80. package/src/components/CInsetTabs/CInsetTabs.vue +134 -134
  81. package/src/components/CInsetTabs/index.js +3 -3
  82. package/src/components/CModalHeading/CModalHeading.vue +22 -22
  83. package/src/components/CModalHeading/index.js +2 -2
  84. package/src/components/CModuleHelpLinks/CModuleHelpLinks.vue +88 -88
  85. package/src/components/CModuleHelpLinks/index.js +3 -3
  86. package/src/components/CMultiselect/CMultiselect.vue +930 -930
  87. package/src/components/CMultiselect/index.js +2 -2
  88. package/src/components/CMultiselectr/CMultiselectr.vue +44 -44
  89. package/src/components/CMultiselectr/index.js +2 -2
  90. package/src/components/CPageHeading/CPageHeading.vue +83 -83
  91. package/src/components/CPageHeading/index.js +2 -2
  92. package/src/components/CPagination/CPagination.vue +239 -239
  93. package/src/components/CPagination/index.js +2 -2
  94. package/src/components/CPhoneNumber/CPhoneNumber.vue +213 -213
  95. package/src/components/CPhoneNumber/index.js +2 -2
  96. package/src/components/CProgress/CProgress.vue +91 -91
  97. package/src/components/CProgress/index.js +2 -2
  98. package/src/components/CRadio/CRadio.vue +197 -197
  99. package/src/components/CRadio/index.js +2 -2
  100. package/src/components/CRadioGroup/CRadioGroup.vue +96 -96
  101. package/src/components/CRadioGroup/index.js +2 -2
  102. package/src/components/CRangeSlider/CRangeSlider.vue +55 -55
  103. package/src/components/CRangeSlider/index.js +2 -2
  104. package/src/components/CReorderableStackedList/CReorderableStackedList.vue +94 -94
  105. package/src/components/CReorderableStackedList/index.js +2 -2
  106. package/src/components/CSelect/CSelect.vue +1165 -1165
  107. package/src/components/CSelect/index.js +2 -2
  108. package/src/components/CSmallTimeline/CSmallTimeline.vue +40 -40
  109. package/src/components/CSmallTimeline/index.js +2 -2
  110. package/src/components/CStackedList/CStackedList.vue +162 -162
  111. package/src/components/CStackedList/index.js +2 -2
  112. package/src/components/CStats/CStats.vue +187 -187
  113. package/src/components/CStats/index.js +2 -2
  114. package/src/components/CSwitch/CSwitch.vue +200 -200
  115. package/src/components/CSwitch/index.js +2 -2
  116. package/src/components/CTabLazy/CTabLazy.vue +83 -83
  117. package/src/components/CTabLazy/index.js +2 -2
  118. package/src/components/CTable/CTable.vue +1114 -1114
  119. package/src/components/CTable/index.js +2 -2
  120. package/src/components/CTabs/CTabs.vue +250 -250
  121. package/src/components/CTabs/index.js +2 -2
  122. package/src/components/CTag/CTag.vue +109 -109
  123. package/src/components/CTag/index.js +2 -2
  124. package/src/components/CTextarea/CTextarea.vue +118 -118
  125. package/src/components/CTextarea/index.js +2 -2
  126. package/src/components/CTimeline/CTimeline.vue +237 -237
  127. package/src/components/CTimeline/index.js +2 -2
  128. package/src/components/CToolTip/CToolTip.vue +108 -108
  129. package/src/components/CToolTip/index.js +3 -3
  130. package/src/components/CUpload/CUpload.vue +331 -331
  131. package/src/components/CUpload/index.js +2 -2
  132. package/src/components/NumberAnimator.vue +112 -112
  133. package/src/components/index.js +57 -57
  134. package/src/helper.js +8 -8
  135. package/src/icons.js +829 -827
  136. package/src/main.js +22 -22
  137. package/src/stories/CAlertModal.stories.js +30 -30
  138. package/src/stories/CAlerts.stories.js +37 -37
  139. package/src/stories/CAnchorTabs.stories.js +29 -29
  140. package/src/stories/CAnchorTag.stories.js +38 -38
  141. package/src/stories/CAvatar.stories.js +38 -38
  142. package/src/stories/CAvatarGroup.stories.js +136 -136
  143. package/src/stories/CBasicTable.stories.js +316 -316
  144. package/src/stories/CBreadcrumbs.stories.js +24 -24
  145. package/src/stories/CButton.stories.js +49 -49
  146. package/src/stories/CButtonGroup.stories.js +43 -43
  147. package/src/stories/CButtonIcon.stories.js +27 -27
  148. package/src/stories/CButtonLink.stories.js +24 -24
  149. package/src/stories/CButtonSelect.stories.js +44 -44
  150. package/src/stories/CButtonSelectBorder.stories.js +56 -56
  151. package/src/stories/CButtonWithDropdown.stories.js +41 -41
  152. package/src/stories/CCalendar.stories.js +16 -16
  153. package/src/stories/CCard.stories.js +30 -30
  154. package/src/stories/CCheckbox.stories.js +38 -38
  155. package/src/stories/CCircularButton.stories.js +29 -29
  156. package/src/stories/CCollapsibleSection.stories.js +29 -29
  157. package/src/stories/CColorDots.stories.js +37 -37
  158. package/src/stories/CConfirmActionModal.stories.js +60 -60
  159. package/src/stories/CDatepicker.stories.js +31 -31
  160. package/src/stories/CDualSelect.stories.js +29 -29
  161. package/src/stories/CEditor.stories.js +30 -30
  162. package/src/stories/CFormSectionHeading.stories.js +37 -37
  163. package/src/stories/CGroupedFilterDropdown.stories.js +176 -176
  164. package/src/stories/CGroupedSelect.stories.js +103 -103
  165. package/src/stories/CIcon.stories.js +31 -31
  166. package/src/stories/CIconDropdown.stories.js +52 -52
  167. package/src/stories/CIconSelect.stories.js +45 -45
  168. package/src/stories/CInput.stories.js +36 -36
  169. package/src/stories/CInputAddon.stories.js +37 -37
  170. package/src/stories/CInputEmail.stories.js +27 -27
  171. package/src/stories/CInsetTabs.stories.js +48 -48
  172. package/src/stories/CModalHeading.stories.js +25 -25
  173. package/src/stories/CModuleHelpLinks.stories.js +25 -25
  174. package/src/stories/CMultiselect.stories.js +136 -136
  175. package/src/stories/CMultiselectr.stories.js +23 -23
  176. package/src/stories/CPageHeading.stories.js +32 -32
  177. package/src/stories/CPagination.stories.js +30 -30
  178. package/src/stories/CPhoneNumber.stories.js +37 -37
  179. package/src/stories/CProgress.stories.js +23 -23
  180. package/src/stories/CRadio.stories.js +44 -44
  181. package/src/stories/CRadioGroup.stories.js +51 -51
  182. package/src/stories/CRangeSlider.stories.js +23 -23
  183. package/src/stories/CReorderableStackedList.stories.js +23 -23
  184. package/src/stories/CSelect.stories.js +157 -157
  185. package/src/stories/CSmallTimeline.stories.js +26 -26
  186. package/src/stories/CStackedList.stories.js +37 -37
  187. package/src/stories/CStats.stories.js +53 -53
  188. package/src/stories/CSwitch.stories.js +28 -28
  189. package/src/stories/CTabLazy.stories.js +42 -42
  190. package/src/stories/CTable.stories.js +203 -203
  191. package/src/stories/CTabs.stories.js +36 -36
  192. package/src/stories/CTag.stories.js +37 -37
  193. package/src/stories/CTextarea.stories.js +32 -32
  194. package/src/stories/CTimeline.stories.js +26 -26
  195. package/src/stories/CToolTip.stories.js +27 -27
  196. package/src/stories/CUpload.stories.js +36 -36
  197. package/src/stories/Introduction.stories.mdx +207 -207
  198. package/src/stories/Page.vue +88 -88
  199. package/src/stories/assets/code-brackets.svg +0 -0
  200. package/src/stories/assets/colors.svg +0 -0
  201. package/src/stories/assets/comments.svg +0 -0
  202. package/src/stories/assets/direction.svg +0 -0
  203. package/src/stories/assets/flow.svg +0 -0
  204. package/src/stories/assets/plugin.svg +0 -0
  205. package/src/stories/assets/repo.svg +0 -0
  206. package/src/stories/assets/stackalt.svg +0 -0
  207. package/src/stories/header.css +26 -26
  208. package/src/stories/page.css +69 -69
  209. package/src/stories/utils.css +32 -32
@@ -1,76 +1,76 @@
1
- <template>
2
- <div>
3
- <div :class="classes" class="border-gray-200">
4
- <div class="flex items-center justify-between">
5
- <div>
6
- <h3 class="text-base font-semibold text-gray-900" :class="headingClass">
7
- {{ heading }}
8
- </h3>
9
- <div class="flex items-center gap-1">
10
- <c-icon
11
- v-if="icon"
12
- :name="icon.name"
13
- :type="icon.type"
14
- :class="icon.class"
15
- :viewBox="icon.viewBox || '0 0 20 20'"
16
- ></c-icon>
17
- <p v-if="description" class="max-w-4xl text-sm text-gray-500">
18
- {{ description }}
19
- </p>
20
- </div>
21
- </div>
22
- <c-button
23
- v-if="tabAction"
24
- :type="tabAction.type"
25
- :label="tabAction.label"
26
- :icon="tabAction.icon"
27
- :id="id + '_action_button'"
28
- @action="emitTabAction"
29
- ></c-button>
30
- <c-anchor-tag
31
- v-if="tabLink"
32
- :label="tabLink.label"
33
- :action="emitTabLink"
34
- :id="id + '_action_link'"
35
- ></c-anchor-tag>
36
- </div>
37
- </div>
38
- </div>
39
- </template>
40
- <script>
41
- import CAnchorTag from "../CAnchorTag/CAnchorTag.vue";
42
- import CButton from "../CButton/CButton.vue";
43
- import CIcon from '../CIcon/CIcon.vue';
44
- export default {
45
- name: "CFormSectionHeading",
46
- components: { CButton, CAnchorTag, CIcon },
47
- props: {
48
- heading: { type: String, required: true },
49
- description: { type: String },
50
- divider: { type: Boolean },
51
- tabAction: { type: Object },
52
- tabLink: { type: Object },
53
- actionEvent: {
54
- type: Function,
55
- },
56
- classes: {
57
- type: String,
58
- },
59
- headingClass: {
60
- type: String,
61
- default: "",
62
- },
63
- icon: {
64
- type: Object,
65
- },
66
- },
67
- methods: {
68
- emitTabAction() {
69
- this.$emit("actionEvent");
70
- },
71
- emitTabLink() {
72
- this.$emit("actionEvent");
73
- },
74
- },
75
- };
76
- </script>
1
+ <template>
2
+ <div>
3
+ <div :class="classes" class="border-gray-200">
4
+ <div class="flex items-center justify-between">
5
+ <div>
6
+ <h3 class="text-base font-semibold text-gray-900" :class="headingClass">
7
+ {{ heading }}
8
+ </h3>
9
+ <div class="flex items-center gap-1">
10
+ <c-icon
11
+ v-if="icon"
12
+ :name="icon.name"
13
+ :type="icon.type"
14
+ :class="icon.class"
15
+ :viewBox="icon.viewBox || '0 0 20 20'"
16
+ ></c-icon>
17
+ <p v-if="description" class="max-w-4xl text-sm text-gray-500">
18
+ {{ description }}
19
+ </p>
20
+ </div>
21
+ </div>
22
+ <c-button
23
+ v-if="tabAction"
24
+ :type="tabAction.type"
25
+ :label="tabAction.label"
26
+ :icon="tabAction.icon"
27
+ :id="id + '_action_button'"
28
+ @action="emitTabAction"
29
+ ></c-button>
30
+ <c-anchor-tag
31
+ v-if="tabLink"
32
+ :label="tabLink.label"
33
+ :action="emitTabLink"
34
+ :id="id + '_action_link'"
35
+ ></c-anchor-tag>
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </template>
40
+ <script>
41
+ import CAnchorTag from "../CAnchorTag/CAnchorTag.vue";
42
+ import CButton from "../CButton/CButton.vue";
43
+ import CIcon from '../CIcon/CIcon.vue';
44
+ export default {
45
+ name: "CFormSectionHeading",
46
+ components: { CButton, CAnchorTag, CIcon },
47
+ props: {
48
+ heading: { type: String, required: true },
49
+ description: { type: String },
50
+ divider: { type: Boolean },
51
+ tabAction: { type: Object },
52
+ tabLink: { type: Object },
53
+ actionEvent: {
54
+ type: Function,
55
+ },
56
+ classes: {
57
+ type: String,
58
+ },
59
+ headingClass: {
60
+ type: String,
61
+ default: "",
62
+ },
63
+ icon: {
64
+ type: Object,
65
+ },
66
+ },
67
+ methods: {
68
+ emitTabAction() {
69
+ this.$emit("actionEvent");
70
+ },
71
+ emitTabLink() {
72
+ this.$emit("actionEvent");
73
+ },
74
+ },
75
+ };
76
+ </script>
@@ -1,3 +1,3 @@
1
- import CFormSectionHeading from './CFormSectionHeading.vue'
2
-
1
+ import CFormSectionHeading from './CFormSectionHeading.vue'
2
+
3
3
  export default CFormSectionHeading
@@ -1,253 +1,253 @@
1
- <template>
2
- <div :class="`relative ${mainCustomClass}`" ref="dropdownRoot">
3
- <button
4
- class="relative flex h-9 w-max cursor-pointer items-center justify-between gap-2 rounded-md border border-gray-300 bg-white p-2 hover:bg-gray-100"
5
- @click="handleToggleDropdown"
6
- @mouseenter="showTooltip(true)"
7
- @mouseleave="showTooltip(false)"
8
- @focus="showTooltip(true)"
9
- @blur="showTooltip(false)"
10
- >
11
- <c-icon
12
- type="solid"
13
- name="funnel-mini"
14
- class="h-5 w-5 text-gray-400"
15
- cursorType="cursor-pointer"
16
- viewBox="0 0 22 22"
17
- ></c-icon>
18
- <p
19
- v-if="filterSelected"
20
- class="flex h-6 w-6 items-center justify-center rounded-full border border-gray-200 bg-gray-50 py-0.5 px-2 text-sm text-gray-700"
21
- >
22
- {{ filterSelected }}
23
- </p>
24
- <c-icon
25
- v-if="!filterSelected"
26
- name="chevron-down"
27
- type="solid"
28
- class="h-5 w-5 text-gray-400"
29
- cursorType="cursor-pointer"
30
- ></c-icon>
31
- <c-tool-tip
32
- v-if="hasToolTip && displayTooltip"
33
- :tooltipText="tooltipText"
34
- :isTopAligned="true"
35
- color="#1f2937"
36
- classes="text-white absolute -mt-12 whitespace-nowrap top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 font-normal bg-gray-800 w-auto"
37
- ></c-tool-tip>
38
- </button>
39
- <div
40
- v-if="toggleDropdown"
41
- :class="`absolute top-11 ${
42
- menuDirection === 'left' ? 'left-0' : 'right-0'
43
- } z-50 flex w-56 rounded-md bg-white shadow-lg ring-1 ring-gray-900 ring-opacity-5`"
44
- >
45
- <div class="my-1 w-56">
46
- <button
47
- v-for="(option, index) in options"
48
- :key="index"
49
- class="relative w-56 hover:bg-gray-100 focus:bg-gray-100"
50
- @mouseenter="handleMainOptionMouseEnter(option, index)"
51
- @mouseleave="closeSubmenuWithDelay"
52
- @focus="handleMainOptionMouseEnter(option, index)"
53
- >
54
- <div
55
- class="group flex cursor-pointer items-center justify-between px-3 py-2 text-sm text-gray-700"
56
- >
57
- <div class="flex items-center gap-1">
58
- <p class="text-sm text-gray-900">
59
- {{ option.label }}
60
- </p>
61
- <p
62
- v-if="option.selected"
63
- class="flex items-center justify-center rounded-full border border-gray-200 bg-gray-50 py-0.5 px-2"
64
- >
65
- {{ option.selected }}
66
- </p>
67
- </div>
68
- <c-icon
69
- v-if="hasSubOptions(option)"
70
- name="chevron-right-mini-v2"
71
- type="solid"
72
- class="h-5 w-5 text-gray-400"
73
- cursorType="cursor-pointer"
74
- ></c-icon>
75
- </div>
76
- <div
77
- v-if="activeOptionIndex === index && hasSubOptions(option)"
78
- :class="`absolute top-0 ${
79
- submenuDirection === 'right'
80
- ? 'left-full ml-2'
81
- : 'right-full mr-2'
82
- } max-h-48 w-56 overflow-auto rounded-md bg-white py-1 shadow-lg ring-1 ring-gray-900 ring-opacity-5`"
83
- style="z-index: 60"
84
- @mouseenter="clearSubmenuCloseTimeout"
85
- >
86
- <div
87
- v-for="(sub, subIdx) in option.options"
88
- :key="subIdx"
89
- tabindex="0"
90
- class="flex cursor-pointer items-center gap-3 py-2 px-3 text-left hover:bg-gray-100 focus:bg-gray-100"
91
- @click="selectFilter(sub.isSelected ? 0 : 1, index, subIdx)"
92
- @keydown.enter="
93
- selectFilter(sub.isSelected ? 0 : 1, index, subIdx)
94
- "
95
- >
96
- <c-checkbox :value="sub.isSelected" setMarginLeft="ml-0"></c-checkbox>
97
- <p class="text-sm text-gray-700">{{ sub.label }}</p>
98
- </div>
99
- </div>
100
- </button>
101
- </div>
102
- </div>
103
- </div>
104
- </template>
105
-
106
- <script>
107
- import CIcon from "../CIcon/CIcon.vue";
108
- import CToolTip from "../CToolTip/CToolTip.vue";
109
- import CCheckbox from "../CCheckbox/CCheckbox.vue";
110
-
111
- export default {
112
- name: "CGroupedFilterDropdown",
113
- components: { CIcon, CToolTip, CCheckbox },
114
- props: {
115
- mainCustomClass: {
116
- type: String,
117
- default: "",
118
- },
119
- tooltipText: {
120
- type: String,
121
- default: "",
122
- },
123
- submenuDirection: {
124
- type: String,
125
- default: "right",
126
- },
127
- menuDirection: {
128
- type: String,
129
- default: "right",
130
- },
131
- filterSelected: {
132
- type: Number,
133
- default: 0,
134
- },
135
- options: {
136
- type: Array,
137
- required: true,
138
- default: () => [],
139
- },
140
- hasToolTip: {
141
- type: Boolean,
142
- default: false,
143
- },
144
- },
145
- data() {
146
- return {
147
- toggleDropdown: false,
148
- activeOptionIndex: null,
149
- submenuCloseTimeout: null,
150
- subMenuLocked: false,
151
- displayTooltip: false,
152
- };
153
- },
154
- methods: {
155
- showTooltip(value) {
156
- this.displayTooltip = value;
157
- },
158
- handleToggleDropdown() {
159
- this.toggleDropdown = !this.toggleDropdown;
160
- if (this.toggleDropdown) this.updateEventListeners();
161
- else document.removeEventListener("click", this.handleClickOutside);
162
- },
163
- closeSubmenuWithDelay() {
164
- if (!this.subMenuLocked) {
165
- this.submenuCloseTimeout = setTimeout(() => {
166
- this.activeOptionIndex = null;
167
- this.subMenuLocked = false;
168
- }, 200);
169
- }
170
- },
171
- computeSubmenuDirection() {
172
- try {
173
- const rootEl = this.$refs.dropdownRoot;
174
- if (!rootEl) {
175
- this.submenuDirection = "right";
176
- return;
177
- }
178
- const rect = rootEl.getBoundingClientRect();
179
- const viewportWidth =
180
- window.innerWidth || document.documentElement.clientWidth;
181
- const rightSpace = viewportWidth - rect.right;
182
- const submenuWidthPx = 224 + 8;
183
- this.submenuDirection = rightSpace < submenuWidthPx ? "left" : "right";
184
- } catch (e) {
185
- this.submenuDirection = "right";
186
- }
187
- },
188
- handleMainOptionMouseEnter(option, index) {
189
- this.clearSubmenuCloseTimeout();
190
- if (this.subMenuLocked && this.activeOptionIndex !== index) {
191
- this.subMenuLocked = false;
192
- this.activeOptionIndex = index;
193
- } else if (!this.subMenuLocked && this.hasSubOptions(option))
194
- this.activeOptionIndex = index;
195
- else this.activeOptionIndex = index;
196
- if (this.hasSubOptions(option)) {
197
- this.computeSubmenuDirection();
198
- }
199
- },
200
- hasSubOptions(option) {
201
- if (
202
- !option ||
203
- !option.options ||
204
- !Array.isArray(option.options) ||
205
- !option.options.length
206
- )
207
- return false;
208
- return true;
209
- },
210
- clearSubmenuCloseTimeout() {
211
- if (this.submenuCloseTimeout) {
212
- clearTimeout(this.submenuCloseTimeout);
213
- this.submenuCloseTimeout = null;
214
- }
215
- },
216
- selectFilter(value, index, subIdx) {
217
- this.options[index].options[subIdx].isSelected = value ? true : false;
218
- if (value) {
219
- this.options[index].selected++;
220
- } else {
221
- this.options[index].selected--;
222
- }
223
- this.filterSelected = this.options.reduce(
224
- (acc, option) => (option.selected ? acc + 1 : acc),
225
- 0
226
- );
227
- this.$emit(
228
- "filter-changed",
229
- this.options[index].options[subIdx].isSelected,
230
- this.options[index].label,
231
- this.options[index].options[subIdx]
232
- );
233
- },
234
- handleClickOutside(event) {
235
- if (
236
- this.$refs.dropdownRoot &&
237
- !this.$refs.dropdownRoot.contains(event.target)
238
- ) {
239
- this.activeOptionIndex = null;
240
- this.subMenuLocked = false;
241
- this.toggleDropdown = false;
242
- document.removeEventListener("click", this.handleClickOutside);
243
- }
244
- },
245
- updateEventListeners() {
246
- document.addEventListener("click", this.handleClickOutside);
247
- },
248
- },
249
- beforeDestroy() {
250
- document.removeEventListener("click", this.handleClickOutside);
251
- },
252
- };
253
- </script>
1
+ <template>
2
+ <div :class="`relative ${mainCustomClass}`" ref="dropdownRoot">
3
+ <button
4
+ class="relative flex h-9 w-max cursor-pointer items-center justify-between gap-2 rounded-md border border-gray-300 bg-white p-2 hover:bg-gray-100"
5
+ @click="handleToggleDropdown"
6
+ @mouseenter="showTooltip(true)"
7
+ @mouseleave="showTooltip(false)"
8
+ @focus="showTooltip(true)"
9
+ @blur="showTooltip(false)"
10
+ >
11
+ <c-icon
12
+ type="solid"
13
+ name="funnel-mini"
14
+ class="h-5 w-5 text-gray-400"
15
+ cursorType="cursor-pointer"
16
+ viewBox="0 0 22 22"
17
+ ></c-icon>
18
+ <p
19
+ v-if="filterSelected"
20
+ class="flex h-6 w-6 items-center justify-center rounded-full border border-gray-200 bg-gray-50 py-0.5 px-2 text-sm text-gray-700"
21
+ >
22
+ {{ filterSelected }}
23
+ </p>
24
+ <c-icon
25
+ v-if="!filterSelected"
26
+ name="chevron-down"
27
+ type="solid"
28
+ class="h-5 w-5 text-gray-400"
29
+ cursorType="cursor-pointer"
30
+ ></c-icon>
31
+ <c-tool-tip
32
+ v-if="hasToolTip && displayTooltip"
33
+ :tooltipText="tooltipText"
34
+ :isTopAligned="true"
35
+ color="#1f2937"
36
+ classes="text-white absolute -mt-12 whitespace-nowrap top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 font-normal bg-gray-800 w-auto"
37
+ ></c-tool-tip>
38
+ </button>
39
+ <div
40
+ v-if="toggleDropdown"
41
+ :class="`absolute top-11 ${
42
+ menuDirection === 'left' ? 'left-0' : 'right-0'
43
+ } z-50 flex w-56 rounded-md bg-white shadow-lg ring-1 ring-gray-900 ring-opacity-5`"
44
+ >
45
+ <div class="my-1 w-56">
46
+ <button
47
+ v-for="(option, index) in options"
48
+ :key="index"
49
+ class="relative w-56 hover:bg-gray-100 focus:bg-gray-100"
50
+ @mouseenter="handleMainOptionMouseEnter(option, index)"
51
+ @mouseleave="closeSubmenuWithDelay"
52
+ @focus="handleMainOptionMouseEnter(option, index)"
53
+ >
54
+ <div
55
+ class="group flex cursor-pointer items-center justify-between px-3 py-2 text-sm text-gray-700"
56
+ >
57
+ <div class="flex items-center gap-1">
58
+ <p class="text-sm text-gray-900">
59
+ {{ option.label }}
60
+ </p>
61
+ <p
62
+ v-if="option.selected"
63
+ class="flex items-center justify-center rounded-full border border-gray-200 bg-gray-50 py-0.5 px-2"
64
+ >
65
+ {{ option.selected }}
66
+ </p>
67
+ </div>
68
+ <c-icon
69
+ v-if="hasSubOptions(option)"
70
+ name="chevron-right-mini-v2"
71
+ type="solid"
72
+ class="h-5 w-5 text-gray-400"
73
+ cursorType="cursor-pointer"
74
+ ></c-icon>
75
+ </div>
76
+ <div
77
+ v-if="activeOptionIndex === index && hasSubOptions(option)"
78
+ :class="`absolute top-0 ${
79
+ submenuDirection === 'right'
80
+ ? 'left-full ml-2'
81
+ : 'right-full mr-2'
82
+ } max-h-48 w-56 overflow-auto rounded-md bg-white py-1 shadow-lg ring-1 ring-gray-900 ring-opacity-5`"
83
+ style="z-index: 60"
84
+ @mouseenter="clearSubmenuCloseTimeout"
85
+ >
86
+ <div
87
+ v-for="(sub, subIdx) in option.options"
88
+ :key="subIdx"
89
+ tabindex="0"
90
+ class="flex cursor-pointer items-center gap-3 py-2 px-3 text-left hover:bg-gray-100 focus:bg-gray-100"
91
+ @click="selectFilter(sub.isSelected ? 0 : 1, index, subIdx)"
92
+ @keydown.enter="
93
+ selectFilter(sub.isSelected ? 0 : 1, index, subIdx)
94
+ "
95
+ >
96
+ <c-checkbox :value="sub.isSelected" setMarginLeft="ml-0"></c-checkbox>
97
+ <p class="text-sm text-gray-700">{{ sub.label }}</p>
98
+ </div>
99
+ </div>
100
+ </button>
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </template>
105
+
106
+ <script>
107
+ import CIcon from "../CIcon/CIcon.vue";
108
+ import CToolTip from "../CToolTip/CToolTip.vue";
109
+ import CCheckbox from "../CCheckbox/CCheckbox.vue";
110
+
111
+ export default {
112
+ name: "CGroupedFilterDropdown",
113
+ components: { CIcon, CToolTip, CCheckbox },
114
+ props: {
115
+ mainCustomClass: {
116
+ type: String,
117
+ default: "",
118
+ },
119
+ tooltipText: {
120
+ type: String,
121
+ default: "",
122
+ },
123
+ submenuDirection: {
124
+ type: String,
125
+ default: "right",
126
+ },
127
+ menuDirection: {
128
+ type: String,
129
+ default: "right",
130
+ },
131
+ filterSelected: {
132
+ type: Number,
133
+ default: 0,
134
+ },
135
+ options: {
136
+ type: Array,
137
+ required: true,
138
+ default: () => [],
139
+ },
140
+ hasToolTip: {
141
+ type: Boolean,
142
+ default: false,
143
+ },
144
+ },
145
+ data() {
146
+ return {
147
+ toggleDropdown: false,
148
+ activeOptionIndex: null,
149
+ submenuCloseTimeout: null,
150
+ subMenuLocked: false,
151
+ displayTooltip: false,
152
+ };
153
+ },
154
+ methods: {
155
+ showTooltip(value) {
156
+ this.displayTooltip = value;
157
+ },
158
+ handleToggleDropdown() {
159
+ this.toggleDropdown = !this.toggleDropdown;
160
+ if (this.toggleDropdown) this.updateEventListeners();
161
+ else document.removeEventListener("click", this.handleClickOutside);
162
+ },
163
+ closeSubmenuWithDelay() {
164
+ if (!this.subMenuLocked) {
165
+ this.submenuCloseTimeout = setTimeout(() => {
166
+ this.activeOptionIndex = null;
167
+ this.subMenuLocked = false;
168
+ }, 200);
169
+ }
170
+ },
171
+ computeSubmenuDirection() {
172
+ try {
173
+ const rootEl = this.$refs.dropdownRoot;
174
+ if (!rootEl) {
175
+ this.submenuDirection = "right";
176
+ return;
177
+ }
178
+ const rect = rootEl.getBoundingClientRect();
179
+ const viewportWidth =
180
+ window.innerWidth || document.documentElement.clientWidth;
181
+ const rightSpace = viewportWidth - rect.right;
182
+ const submenuWidthPx = 224 + 8;
183
+ this.submenuDirection = rightSpace < submenuWidthPx ? "left" : "right";
184
+ } catch (e) {
185
+ this.submenuDirection = "right";
186
+ }
187
+ },
188
+ handleMainOptionMouseEnter(option, index) {
189
+ this.clearSubmenuCloseTimeout();
190
+ if (this.subMenuLocked && this.activeOptionIndex !== index) {
191
+ this.subMenuLocked = false;
192
+ this.activeOptionIndex = index;
193
+ } else if (!this.subMenuLocked && this.hasSubOptions(option))
194
+ this.activeOptionIndex = index;
195
+ else this.activeOptionIndex = index;
196
+ if (this.hasSubOptions(option)) {
197
+ this.computeSubmenuDirection();
198
+ }
199
+ },
200
+ hasSubOptions(option) {
201
+ if (
202
+ !option ||
203
+ !option.options ||
204
+ !Array.isArray(option.options) ||
205
+ !option.options.length
206
+ )
207
+ return false;
208
+ return true;
209
+ },
210
+ clearSubmenuCloseTimeout() {
211
+ if (this.submenuCloseTimeout) {
212
+ clearTimeout(this.submenuCloseTimeout);
213
+ this.submenuCloseTimeout = null;
214
+ }
215
+ },
216
+ selectFilter(value, index, subIdx) {
217
+ this.options[index].options[subIdx].isSelected = value ? true : false;
218
+ if (value) {
219
+ this.options[index].selected++;
220
+ } else {
221
+ this.options[index].selected--;
222
+ }
223
+ this.filterSelected = this.options.reduce(
224
+ (acc, option) => (option.selected ? acc + 1 : acc),
225
+ 0
226
+ );
227
+ this.$emit(
228
+ "filter-changed",
229
+ this.options[index].options[subIdx].isSelected,
230
+ this.options[index].label,
231
+ this.options[index].options[subIdx]
232
+ );
233
+ },
234
+ handleClickOutside(event) {
235
+ if (
236
+ this.$refs.dropdownRoot &&
237
+ !this.$refs.dropdownRoot.contains(event.target)
238
+ ) {
239
+ this.activeOptionIndex = null;
240
+ this.subMenuLocked = false;
241
+ this.toggleDropdown = false;
242
+ document.removeEventListener("click", this.handleClickOutside);
243
+ }
244
+ },
245
+ updateEventListeners() {
246
+ document.addEventListener("click", this.handleClickOutside);
247
+ },
248
+ },
249
+ beforeDestroy() {
250
+ document.removeEventListener("click", this.handleClickOutside);
251
+ },
252
+ };
253
+ </script>
@@ -1,3 +1,3 @@
1
- import CGroupedFilterDropdown from './CGroupedFilterDropdown.vue'
2
-
1
+ import CGroupedFilterDropdown from './CGroupedFilterDropdown.vue'
2
+
3
3
  export default CGroupedFilterDropdown