@imaginario27/air-ui-ds 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/assets/css/defaults.css +55 -0
  2. package/assets/css/main.css +238 -0
  3. package/assets/css/theme/colors.css +106 -0
  4. package/assets/css/theme/primitives.css +105 -0
  5. package/assets/css/theme/ui-theme.css +454 -0
  6. package/assets/images/placeholders/missing-image-placeholder.png +0 -0
  7. package/components/accordions/Accordion.vue +31 -0
  8. package/components/accordions/AccordionGroup.vue +78 -0
  9. package/components/accordions/AccordionItem.vue +39 -0
  10. package/components/action-panels/ActionPanel.vue +49 -0
  11. package/components/alerts/Alert.vue +159 -0
  12. package/components/avatars/Avatar.vue +152 -0
  13. package/components/avatars/AvatarStack.vue +97 -0
  14. package/components/avatars/AvatarStackCounter.vue +74 -0
  15. package/components/badges/Badge.vue +221 -0
  16. package/components/badges/BadgeStack.vue +110 -0
  17. package/components/badges/IconBadge.vue +57 -0
  18. package/components/badges/IconTextBadge.vue +50 -0
  19. package/components/breadcrumbs/Breadcrumbs.vue +54 -0
  20. package/components/buttons/ActionButton.vue +395 -0
  21. package/components/buttons/ActionIconButton.vue +283 -0
  22. package/components/buttons/AlertButton.vue +125 -0
  23. package/components/buttons/AlertIconButton.vue +105 -0
  24. package/components/buttons/PaginationButton.vue +45 -0
  25. package/components/buttons/options/OptionButton.vue +61 -0
  26. package/components/buttons/options/OptionButtonGroup.vue +155 -0
  27. package/components/buttons/options/OptionButtonSlider.vue +154 -0
  28. package/components/buttons/toggle/ToggleButton.vue +142 -0
  29. package/components/buttons/toggle/ToggleButtonGroup.vue +73 -0
  30. package/components/cards/Card.vue +33 -0
  31. package/components/cards/CardActions.vue +5 -0
  32. package/components/cards/CardBody.vue +5 -0
  33. package/components/cards/CardFooter.vue +20 -0
  34. package/components/cards/CardHeader.vue +5 -0
  35. package/components/cards/CardTitle.vue +13 -0
  36. package/components/cards/specific/ContactDetailsCard.vue +47 -0
  37. package/components/cards/specific/FeatureCard.vue +59 -0
  38. package/components/cards/specific/HelpTopicCard.vue +62 -0
  39. package/components/cards/specific/MetricCard.vue +42 -0
  40. package/components/cards/specific/TestimonialCard.vue +57 -0
  41. package/components/cards/specific/subscription/CurrentActiveSubscriptionCard.vue +105 -0
  42. package/components/cards/specific/subscription/SubscriptionPlanCard.vue +178 -0
  43. package/components/cards/specific/subscription/UniqueSubscriptionPlanCard.vue +106 -0
  44. package/components/collapsibles/Collapsible.vue +33 -0
  45. package/components/content/ContentItem.vue +144 -0
  46. package/components/content/ContentItemImage.vue +125 -0
  47. package/components/dividers/Divider.vue +35 -0
  48. package/components/dividers/TextLineDivider.vue +58 -0
  49. package/components/dropdowns/DropdownMenu.vue +207 -0
  50. package/components/dropdowns/DropdownMenuActions.vue +11 -0
  51. package/components/dropdowns/DropdownMenuItem.vue +240 -0
  52. package/components/dropdowns/DropdownSelect.vue +469 -0
  53. package/components/dropdowns/DropdownSelectItem.vue +182 -0
  54. package/components/empty-states/EmptyState.vue +170 -0
  55. package/components/features/Feature.vue +77 -0
  56. package/components/forms/DataDetails.vue +7 -0
  57. package/components/forms/DataDetailsActions.vue +23 -0
  58. package/components/forms/DataDetailsFieldGroup.vue +35 -0
  59. package/components/forms/DataDetailsRow.vue +22 -0
  60. package/components/forms/Form.vue +25 -0
  61. package/components/forms/FormActions.vue +23 -0
  62. package/components/forms/FormFieldGroup.vue +35 -0
  63. package/components/forms/FormRow.vue +22 -0
  64. package/components/forms/fields/ButtonField.vue +119 -0
  65. package/components/forms/fields/CheckboxField.vue +205 -0
  66. package/components/forms/fields/DataField.vue +99 -0
  67. package/components/forms/fields/FileUploadField.vue +326 -0
  68. package/components/forms/fields/InputField.vue +371 -0
  69. package/components/forms/fields/OptionButtonsGroupField.vue +120 -0
  70. package/components/forms/fields/RepeaterField.vue +109 -0
  71. package/components/forms/fields/SearchField.vue +184 -0
  72. package/components/forms/fields/SelectField.vue +233 -0
  73. package/components/forms/fields/SliderField.vue +759 -0
  74. package/components/forms/fields/SwitchField.vue +257 -0
  75. package/components/forms/fields/TextareaField.vue +205 -0
  76. package/components/forms/fields/ToggleButtonsGroupField.vue +65 -0
  77. package/components/forms/fields/radio/RadioButtonField.vue +238 -0
  78. package/components/forms/fields/radio/RadioField.vue +157 -0
  79. package/components/forms/fields/radio/RadioGroupField.vue +156 -0
  80. package/components/icons/ContainedIcon.vue +130 -0
  81. package/components/images/QRCode.vue +124 -0
  82. package/components/layouts/ContainerWrapper.vue +13 -0
  83. package/components/layouts/ContentBody.vue +30 -0
  84. package/components/layouts/Grid.vue +25 -0
  85. package/components/layouts/Heading.vue +159 -0
  86. package/components/layouts/MainContent.vue +26 -0
  87. package/components/layouts/MaxWidthContainer.vue +15 -0
  88. package/components/layouts/Overtitle.vue +25 -0
  89. package/components/layouts/headers/CompactHeader.vue +181 -0
  90. package/components/layouts/headers/PageHeader.vue +102 -0
  91. package/components/layouts/headers/WebAppHeader.vue +54 -0
  92. package/components/layouts/section/Section.vue +90 -0
  93. package/components/layouts/section/SectionBody.vue +12 -0
  94. package/components/layouts/section/SectionHeader.vue +12 -0
  95. package/components/layouts/section/SectionTitle.vue +13 -0
  96. package/components/lists/List.vue +69 -0
  97. package/components/lists/ListItem.vue +58 -0
  98. package/components/loaders/Loading.vue +83 -0
  99. package/components/loaders/LoadingScreen.vue +285 -0
  100. package/components/modals/DangerModalDialog.vue +149 -0
  101. package/components/modals/InfoModalDialog.vue +143 -0
  102. package/components/modals/ModalActions.vue +22 -0
  103. package/components/modals/ModalContent.vue +5 -0
  104. package/components/modals/ModalDescription.vue +5 -0
  105. package/components/modals/ModalDialog.vue +122 -0
  106. package/components/modals/ModalHeaderGroup.vue +19 -0
  107. package/components/modals/ModalHeadings.vue +5 -0
  108. package/components/modals/ModalSubtitle.vue +14 -0
  109. package/components/modals/ModalTitle.vue +14 -0
  110. package/components/modals/SuccessModalDialog.vue +90 -0
  111. package/components/modules/AppLogo.vue +46 -0
  112. package/components/modules/SVGImage.vue +44 -0
  113. package/components/navigation/links/NavLink.vue +112 -0
  114. package/components/navigation/nav-menu/NavFooterMenu.vue +91 -0
  115. package/components/navigation/nav-menu/NavMenu.vue +36 -0
  116. package/components/navigation/nav-menu/NavMenuItem.vue +44 -0
  117. package/components/navigation/nav-sidebar/BottomUserNavBar.vue +83 -0
  118. package/components/navigation/nav-sidebar/NavSidebar.vue +172 -0
  119. package/components/navigation/nav-sidebar/NavSidebarMenu.vue +14 -0
  120. package/components/navigation/nav-sidebar/NavSidebarMenuItem.vue +76 -0
  121. package/components/navigation/nav-sidebar/NavSidebarMenuSectionTitle.vue +54 -0
  122. package/components/navigation/table-of-contents/TableOfContents.vue +35 -0
  123. package/components/navigation/table-of-contents/TableOfContentsItem.vue +40 -0
  124. package/components/navigation/table-of-contents/TableOfContentsSidebar.vue +29 -0
  125. package/components/pagination/ButtonPagination.vue +274 -0
  126. package/components/pagination/RowsPerPage.vue +60 -0
  127. package/components/pagination/SimplePagination.vue +97 -0
  128. package/components/password/SecurePasswordCondition.vue +41 -0
  129. package/components/password/SecurePasswordConditions.vue +83 -0
  130. package/components/placeholders/ContentPlaceholder.vue +41 -0
  131. package/components/popovers/Popover.vue +128 -0
  132. package/components/rating/InteractiveRating.vue +94 -0
  133. package/components/rating/Rating.vue +60 -0
  134. package/components/rating/RatingItem.vue +54 -0
  135. package/components/skeletons/Skeleton.vue +11 -0
  136. package/components/spinners/Spinner.vue +13 -0
  137. package/components/steppers/CircleStepper.vue +122 -0
  138. package/components/steppers/Step.vue +72 -0
  139. package/components/steppers/StepIndicator.vue +228 -0
  140. package/components/steppers/TabStepper.vue +126 -0
  141. package/components/steppers/vertical-stepper/VerticalStep.vue +223 -0
  142. package/components/steppers/vertical-stepper/VerticalStepper.vue +63 -0
  143. package/components/tables/Table.vue +26 -0
  144. package/components/tables/TableBody.vue +5 -0
  145. package/components/tables/TableCell.vue +34 -0
  146. package/components/tables/TableCellActions.vue +7 -0
  147. package/components/tables/TableHeader.vue +5 -0
  148. package/components/tables/TableHeaderCell.vue +15 -0
  149. package/components/tables/TableRow.vue +14 -0
  150. package/components/tables/TableWrapper.vue +12 -0
  151. package/components/tabs/Tab.vue +145 -0
  152. package/components/tabs/TabBar.vue +64 -0
  153. package/components/tabs/TabContent.vue +5 -0
  154. package/components/tabs/TabsContainer.vue +5 -0
  155. package/components/transitions/HorizontalExpansionTransition.vue +12 -0
  156. package/components/transitions/VerticalExpansionTransition.vue +14 -0
  157. package/components/users/Author.vue +113 -0
  158. package/components/users/User.vue +53 -0
  159. package/composables/useAccordion.ts +12 -0
  160. package/composables/useDarkMode.ts +9 -0
  161. package/composables/useDropdownMenu.ts +25 -0
  162. package/composables/useForm.ts +134 -0
  163. package/composables/useFormValidationMode.ts +11 -0
  164. package/composables/useIsMobile.ts +27 -0
  165. package/composables/useMobileSidebar.ts +32 -0
  166. package/composables/useShiki.ts +12 -0
  167. package/composables/useTableOfContents.ts +50 -0
  168. package/composables/useToastifyConfig.ts +7 -0
  169. package/eslint.config.mjs +14 -0
  170. package/models/constants/app.ts +8 -0
  171. package/models/constants/form.ts +22 -0
  172. package/models/enums/alerts.ts +6 -0
  173. package/models/enums/aspect-ratios.ts +9 -0
  174. package/models/enums/avatars.ts +21 -0
  175. package/models/enums/badges.ts +10 -0
  176. package/models/enums/buttons.ts +38 -0
  177. package/models/enums/colors.ts +9 -0
  178. package/models/enums/content.ts +4 -0
  179. package/models/enums/counters.ts +4 -0
  180. package/models/enums/dividers.ts +9 -0
  181. package/models/enums/dropdowns.ts +18 -0
  182. package/models/enums/effects.ts +6 -0
  183. package/models/enums/emptyPlaceholders.ts +5 -0
  184. package/models/enums/formFields.ts +19 -0
  185. package/models/enums/formValidations.ts +4 -0
  186. package/models/enums/headings.ts +11 -0
  187. package/models/enums/icons.ts +22 -0
  188. package/models/enums/images.ts +16 -0
  189. package/models/enums/lists.ts +10 -0
  190. package/models/enums/loaders.ts +15 -0
  191. package/models/enums/navigation.ts +18 -0
  192. package/models/enums/order.ts +10 -0
  193. package/models/enums/orientations.ts +4 -0
  194. package/models/enums/pages.ts +10 -0
  195. package/models/enums/positions.ts +21 -0
  196. package/models/enums/rating.ts +12 -0
  197. package/models/enums/sections.ts +8 -0
  198. package/models/enums/selects.ts +16 -0
  199. package/models/enums/sliders.ts +4 -0
  200. package/models/enums/steppers.ts +20 -0
  201. package/models/enums/tabs.ts +11 -0
  202. package/models/enums/triggers.ts +4 -0
  203. package/models/types/accordions.ts +6 -0
  204. package/models/types/avatars.ts +4 -0
  205. package/models/types/badges.ts +4 -0
  206. package/models/types/buttons.ts +26 -0
  207. package/models/types/dropdowns.ts +20 -0
  208. package/models/types/forms.ts +14 -0
  209. package/models/types/navigation.ts +11 -0
  210. package/models/types/pagination.ts +4 -0
  211. package/models/types/pdfExportTable.ts +6 -0
  212. package/models/types/radio.ts +9 -0
  213. package/models/types/selects.ts +14 -0
  214. package/models/types/steppers.ts +17 -0
  215. package/models/types/tableOfContent.ts +6 -0
  216. package/models/types/tabs.ts +7 -0
  217. package/nuxt.config.ts +40 -0
  218. package/package.json +57 -0
  219. package/plugins/vue3-toastify.ts +14 -0
  220. package/tsconfig.json +7 -0
@@ -0,0 +1,283 @@
1
+ <template>
2
+ <component
3
+ :is="actionType === ButtonActionType.LINK ? NuxtLink : 'button'"
4
+ :id
5
+ :type="actionType === ButtonActionType.ACTION ? type : undefined"
6
+ :class="[
7
+ 'flex items-center justify-center rounded-button',
8
+ isRounded ? 'rounded-full' : 'rounded-button',
9
+ 'aspect-square',
10
+ ...buttonStyleClass,
11
+ buttonSizeClass,
12
+ ]"
13
+ v-bind="{
14
+ ...componentProps,
15
+ ...$attrs,
16
+ ...(actionType === ButtonActionType.ACTION ? { onClick: emitClick } : {})
17
+ }"
18
+ :disabled="disabled"
19
+
20
+ >
21
+ <MdiIcon
22
+ v-if="icon && !svgIcon"
23
+ :icon
24
+ preserveAspectRatio="xMidYMid meet"
25
+ :class="iconSizeClass"
26
+ />
27
+ <span
28
+ v-else-if="svgIcon"
29
+ :class="iconSizeClass"
30
+ >
31
+ <SVGImage
32
+ :src="svgIcon"
33
+ :color="resolvedSvgIconColor"
34
+ />
35
+ </span>
36
+ </component>
37
+ </template>
38
+
39
+ <script setup lang="ts">
40
+ // Imports
41
+ import { NuxtLink } from '#components'
42
+
43
+ // Component options
44
+ defineOptions({
45
+ inheritAttrs: false, // Prevents Vue from automatically applying attributes incorrectly
46
+ })
47
+
48
+ // Props
49
+ const props = defineProps({
50
+ actionType: {
51
+ type: String as PropType<ButtonActionType>,
52
+ default: ButtonActionType.ACTION,
53
+ validator: (value: ButtonActionType) => Object.values(ButtonActionType).includes(value),
54
+ },
55
+ styleType: {
56
+ type: String as PropType<ButtonStyleType>,
57
+ default: ButtonStyleType.NEUTRAL_OUTLINED,
58
+ validator: (value: ButtonStyleType) => Object.values(ButtonStyleType).includes(value),
59
+ },
60
+ type: {
61
+ type: String as PropType<'button' | 'submit' | 'reset'>,
62
+ default: 'button',
63
+ validator: (value: string) =>
64
+ ['button', 'submit', 'reset'].includes(value),
65
+ },
66
+ size: {
67
+ type: String as PropType<ButtonSize>,
68
+ default: ButtonSize.LG,
69
+ validator: (value: ButtonSize) => Object.values(ButtonSize).includes(value),
70
+ },
71
+ icon: {
72
+ type: String as PropType<any>,
73
+ default: "mdiHelp"
74
+ },
75
+ svgIcon: String as PropType<string>,
76
+ useSVGIconColor: {
77
+ type: Boolean as PropType<boolean>,
78
+ default: false
79
+ },
80
+ disabled: {
81
+ type: Boolean as PropType<boolean>,
82
+ default: false,
83
+ },
84
+ to: {
85
+ type: String as PropType<string>,
86
+ default: '/'
87
+ },
88
+ isRounded: {
89
+ type: Boolean as PropType<boolean>,
90
+ default: false
91
+ },
92
+ isExternal: {
93
+ type: Boolean as PropType<boolean>,
94
+ default: false
95
+ },
96
+ id: String as PropType<string>,
97
+ })
98
+
99
+ // Emits
100
+ const emit = defineEmits(['click'])
101
+ const emitClick = () => {
102
+ if (!props.disabled) {
103
+ emit('click')
104
+ }
105
+ }
106
+
107
+ // Computed classes
108
+ const buttonStyleClass = computed(() => {
109
+ const variant = {
110
+ [ButtonStyleType.PRIMARY_BRAND_FILLED]: [
111
+ 'bg-background-primary-brand-default',
112
+ !props.disabled && 'hover:bg-background-primary-brand-hover',
113
+ 'focus:ring-offset-2',
114
+ 'focus:ring-2',
115
+ 'focus:ring-border-primary-brand-default',
116
+ 'text-text-neutral-on-filled',
117
+ ],
118
+ [ButtonStyleType.PRIMARY_BRAND_SOFT]: [
119
+ 'bg-background-primary-brand-soft',
120
+ !props.disabled && 'hover:bg-background-primary-brand-soft-hover',
121
+ 'focus:ring-offset-2',
122
+ 'focus:ring-2',
123
+ 'focus:ring-border-primary-brand-default',
124
+ 'text-icon-primary-brand-on-soft-bg',
125
+ ],
126
+ [ButtonStyleType.PRIMARY_BRAND_TRANSPARENT]: [
127
+ 'focus:ring-offset-2',
128
+ 'focus:ring-2',
129
+ 'focus:ring-border-primary-brand-default',
130
+ 'text-text-primary-brand-default',
131
+ !props.disabled && 'hover:text-text-primary-brand-hover',
132
+ ],
133
+ [ButtonStyleType.SECONDARY_BRAND_FILLED]: [
134
+ 'bg-background-secondary-brand-default',
135
+ !props.disabled && 'hover:bg-background-secondary-brand-hover',
136
+ 'focus:ring-offset-2',
137
+ 'focus:ring-2',
138
+ 'focus:ring-border-secondary-brand',
139
+ 'text-text-neutral-on-filled',
140
+ ],
141
+ [ButtonStyleType.NEUTRAL_FILLED]: [
142
+ 'bg-background-neutral-filled-default',
143
+ !props.disabled && 'hover:bg-background-neutral-filled-hover',
144
+ 'focus:ring-offset-2',
145
+ 'focus:ring-2',
146
+ 'focus:ring-border-primary-brand-default',
147
+ 'text-text-neutral-on-neutral-filled-bg',
148
+ ],
149
+ [ButtonStyleType.NEUTRAL_OUTLINED]: [
150
+ 'border',
151
+ 'border-border-default',
152
+ 'bg-background-neutral-default',
153
+ !props.disabled && 'hover:bg-background-neutral-hover',
154
+ 'focus:ring-offset-2',
155
+ 'focus:ring-2',
156
+ 'focus:ring-border-primary-brand-default',
157
+ 'text-text-default',
158
+ ],
159
+ [ButtonStyleType.NEUTRAL_TRANSPARENT]: [
160
+ !props.disabled && 'hover:bg-background-neutral-hover',
161
+ 'focus:ring-offset-2',
162
+ 'focus:ring-2',
163
+ 'focus:ring-border-primary-brand-default',
164
+ 'text-text-default',
165
+ ],
166
+ [ButtonStyleType.NEUTRAL_TRANSPARENT_SUBTLE]: [
167
+ !props.disabled && 'hover:bg-background-neutral-hover hover:text-text-default',
168
+ 'focus:ring-offset-2',
169
+ 'focus:ring-2',
170
+ 'focus:ring-border-primary-brand-default',
171
+ 'text-text-neutral-subtler',
172
+ ],
173
+ [ButtonStyleType.DELETE_FILLED]: [
174
+ 'bg-background-delete-default',
175
+ !props.disabled && 'hover:bg-background-delete-hover',
176
+ 'focus:ring-offset-2',
177
+ 'focus:ring-2',
178
+ 'focus:ring-border-delete',
179
+ 'text-text-neutral-on-filled',
180
+ ],
181
+ [ButtonStyleType.DELETE_SOFT]: [
182
+ 'bg-background-delete-soft',
183
+ !props.disabled && 'hover:bg-background-delete-soft-hover',
184
+ 'focus:ring-offset-2',
185
+ 'focus:ring-2',
186
+ 'focus:ring-border-delete',
187
+ 'text-text-delete',
188
+ ],
189
+ [ButtonStyleType.DELETE_OUTLINED]: [
190
+ 'border',
191
+ 'border-border-delete-subtle',
192
+ 'bg-background-neutral-default',
193
+ !props.disabled && 'hover:bg-background-delete-on-neutral-hover',
194
+ 'focus:ring-offset-2',
195
+ 'focus:ring-2',
196
+ 'focus:ring-border-delete',
197
+ 'text-text-delete',
198
+ ],
199
+ [ButtonStyleType.DELETE_TRANSPARENT]: [
200
+ !props.disabled && 'hover:bg-background-delete-on-neutral-hover',
201
+ 'focus:ring-offset-2',
202
+ 'focus:ring-2',
203
+ 'focus:ring-border-delete',
204
+ 'text-text-delete',
205
+ ],
206
+ }
207
+
208
+ return variant[props.styleType as ButtonStyleType]?.filter(Boolean) || [
209
+ 'border',
210
+ 'border-border-default',
211
+ 'bg-background-neutral-default',
212
+ !props.disabled && 'hover:bg-background-neutral-hover',
213
+ 'focus:ring-offset-2',
214
+ 'focus:ring-2',
215
+ 'focus:ring-border-primary-brand-default',
216
+ 'text-text-default',
217
+ ].filter(Boolean)
218
+ })
219
+
220
+ const buttonSizeClass = computed(() => {
221
+ const variant = {
222
+ [ButtonSize.XS]: 'w-[24px] h-[24px]',
223
+ [ButtonSize.SM]: 'w-[28px] h-[28px]',
224
+ [ButtonSize.MD]: 'w-[32px] h-[32px]',
225
+ [ButtonSize.LG]: 'w-[36px] h-[36px]',
226
+ [ButtonSize.XL]: 'w-[40px] h-[40px]',
227
+ [ButtonSize.XXL]: 'w-[48px] h-[48px]',
228
+ }
229
+ return variant[props.size as ButtonSize] || 'w-[36px] h-[36px]'
230
+ })
231
+
232
+ const iconSizeClass = computed(() => {
233
+ const variant = {
234
+ [ButtonSize.XS]: 'w-[16px] h-[16px] min-w-[16px] min-h-[16px]',
235
+ [ButtonSize.SM]: 'w-[16px] h-[16px] min-w-[16px] min-h-[16px]',
236
+ [ButtonSize.MD]: 'w-[16px] h-[16px] min-w-[16px] min-h-[16px]',
237
+ [ButtonSize.LG]: 'w-[20px] h-[20px] min-w-[20px] min-h-[20px]',
238
+ [ButtonSize.XL]: 'w-[20px] h-[20px] min-w-[20px] min-h-[20px]',
239
+ [ButtonSize.XXL]: 'w-[24px] h-[24px] min-w-[24px] min-h-[24px]',
240
+ }
241
+ return variant[props.size as ButtonSize] || 'w-[20px] h-[20px] min-w-[20px] min-h-[20px]'
242
+ })
243
+
244
+ const svgIconColorClass = computed(() => {
245
+ const variant = {
246
+ [ButtonStyleType.PRIMARY_BRAND_FILLED]: 'text-text-neutral-on-filled',
247
+ [ButtonStyleType.PRIMARY_BRAND_SOFT]: 'text-icon-primary-brand-on-soft-bg',
248
+ [ButtonStyleType.PRIMARY_BRAND_TRANSPARENT]: [
249
+ 'text-text-primary-brand-default',
250
+ !props.disabled && 'hover:text-text-primary-brand-hover',
251
+ ],
252
+ [ButtonStyleType.SECONDARY_BRAND_FILLED]: 'text-text-neutral-on-filled',
253
+ [ButtonStyleType.NEUTRAL_FILLED]: 'text-text-neutral-on-neutral-filled-bg',
254
+ [ButtonStyleType.NEUTRAL_OUTLINED]: 'text-text-default',
255
+ [ButtonStyleType.NEUTRAL_TRANSPARENT]: 'text-text-default',
256
+ [ButtonStyleType.NEUTRAL_TRANSPARENT_SUBTLE]: 'text-text-neutral-subtler',
257
+ [ButtonStyleType.DELETE_FILLED]: 'text-text-neutral-on-filled',
258
+ [ButtonStyleType.DELETE_SOFT]: 'text-text-delete',
259
+ [ButtonStyleType.DELETE_OUTLINED]: 'text-text-delete',
260
+ [ButtonStyleType.DELETE_TRANSPARENT]: 'text-text-delete',
261
+ }
262
+ return variant[props.styleType as ButtonStyleType] || 'text-text-default'
263
+ })
264
+
265
+ // Computed functions
266
+ const resolvedSvgIconColor = computed(() => {
267
+ return props.useSVGIconColor ? undefined : svgIconColorClass
268
+ })
269
+
270
+ // Props for the dynamic component
271
+ const componentProps = computed(() => {
272
+ if (props.actionType === ButtonActionType.LINK) {
273
+ return {
274
+ to: props.to,
275
+ target: props.isExternal ? '_blank' : '_self',
276
+ rel: props.isExternal ? 'noopener noreferrer' : undefined,
277
+ external: props.isExternal,
278
+ }
279
+ } else {
280
+ return {}
281
+ }
282
+ })
283
+ </script>
@@ -0,0 +1,125 @@
1
+ <template>
2
+ <component
3
+ :is="actionType === ButtonActionType.LINK ? NuxtLink : 'button'"
4
+ :type="actionType === ButtonActionType.ACTION ? 'button' : undefined"
5
+ :class="[
6
+ 'flex items-center justify-center',
7
+ 'text-nowrap',
8
+ 'h-[32px]',
9
+ 'gap-2',
10
+ 'self-start',
11
+ 'text-sm',
12
+ 'hover:opacity-75',
13
+ textIconClass
14
+ ]"
15
+ v-bind="{
16
+ ...componentProps,
17
+ ...$attrs,
18
+ ...(actionType === ButtonActionType.ACTION ? { onClick: emitClick } : {})
19
+ }"
20
+ :disabled
21
+
22
+ >
23
+ <!-- Left icon -->
24
+ <MdiIcon
25
+ v-if="iconPosition === IconPosition.LEFT"
26
+ :icon
27
+ size="20"
28
+ preserveAspectRatio="xMidYMid meet"
29
+ class="min-w-[20px]"
30
+ />
31
+ <span :class="[ 'font-semibold' ]">
32
+ {{ text }}
33
+ </span>
34
+ <!-- Right icon -->
35
+ <MdiIcon
36
+ v-if="iconPosition === IconPosition.RIGHT"
37
+ :icon
38
+ size="20"
39
+ preserveAspectRatio="xMidYMid meet"
40
+ class="min-w-[20px]"
41
+ />
42
+ </component>
43
+ </template>
44
+
45
+ <script setup lang="ts">
46
+ // Imports
47
+ import { NuxtLink } from '#components'
48
+
49
+ // Component options
50
+ defineOptions({
51
+ inheritAttrs: false, // Prevents Vue from automatically applying attributes incorrectly
52
+ })
53
+
54
+ // Props
55
+ const props = defineProps({
56
+ type: {
57
+ type: String as PropType<AlertType>,
58
+ default: AlertType.WARNING,
59
+ validator: (value: AlertType) => Object.values(AlertType).includes(value),
60
+ },
61
+ actionType: {
62
+ type: String as PropType<ButtonActionType>,
63
+ default: ButtonActionType.ACTION,
64
+ validator: (value: ButtonActionType) => Object.values(ButtonActionType).includes(value),
65
+ },
66
+ text: {
67
+ type: String as PropType<string>,
68
+ default: 'Button text'
69
+ },
70
+ icon: {
71
+ type: String as PropType<any>,
72
+ default: "mdiHelp"
73
+ },
74
+ iconPosition: {
75
+ type: String as PropType<IconPosition>,
76
+ default: IconPosition.NONE,
77
+ validator: (value: IconPosition) => Object.values(IconPosition).includes(value),
78
+ },
79
+ disabled: {
80
+ type: Boolean as PropType<boolean>,
81
+ default: false,
82
+ },
83
+ to: {
84
+ type: String as PropType<string>,
85
+ default: '/'
86
+ },
87
+ isExternal: {
88
+ type: Boolean as PropType<boolean>,
89
+ default: false
90
+ },
91
+ })
92
+
93
+ // Emits
94
+ const emit = defineEmits(['click'])
95
+ const emitClick = () => {
96
+ if (!props.disabled) {
97
+ emit('click')
98
+ }
99
+ }
100
+
101
+ // Computed classes
102
+ const textIconClass = computed(() => {
103
+ const variant = {
104
+ [AlertType.WARNING]: 'text-text-warning-on-bg',
105
+ [AlertType.DANGER]: 'text-text-danger',
106
+ [AlertType.SUCCESS]: 'text-text-success',
107
+ [AlertType.INFO]: 'text-text-info',
108
+ }
109
+ return variant[props.type as AlertType] || 'text-text-warning-on-bg'
110
+ })
111
+
112
+ // Props for the dynamic component
113
+ const componentProps = computed(() => {
114
+ if (props.actionType === ButtonActionType.LINK) {
115
+ return {
116
+ to: props.to,
117
+ target: props.isExternal ? '_blank' : '_self',
118
+ rel: props.isExternal ? 'noopener noreferrer' : undefined,
119
+ external: props.isExternal,
120
+ }
121
+ } else {
122
+ return {}
123
+ }
124
+ })
125
+ </script>
@@ -0,0 +1,105 @@
1
+ <template>
2
+ <component
3
+ :is="actionType === ButtonActionType.LINK ? NuxtLink : 'button'"
4
+ :type="actionType === ButtonActionType.ACTION ? 'button' : undefined"
5
+ :class="[
6
+ 'flex items-center justify-center',
7
+ 'text-nowrap',
8
+ 'w-[32px] h-[32px]',
9
+ 'self-start',
10
+ 'aspect-square',
11
+ 'hover:opacity-75',
12
+ iconClass
13
+ ]"
14
+ v-bind="{
15
+ ...componentProps,
16
+ ...$attrs,
17
+ ...(actionType === ButtonActionType.ACTION ? { onClick: emitClick } : {})
18
+ }"
19
+ :disabled
20
+ >
21
+ <MdiIcon
22
+ :icon
23
+ size="20"
24
+ preserveAspectRatio="xMidYMid meet"
25
+ class="min-w-[20px]"
26
+ />
27
+ </component>
28
+ </template>
29
+
30
+ <script setup lang="ts">
31
+ // Imports
32
+ import { NuxtLink } from '#components'
33
+
34
+ // Component options
35
+ defineOptions({
36
+ inheritAttrs: false, // Prevents Vue from automatically applying attributes incorrectly
37
+ })
38
+
39
+ // Props
40
+ const props = defineProps({
41
+ type: {
42
+ type: String as PropType<AlertType>,
43
+ default: AlertType.WARNING,
44
+ validator: (value: AlertType) => Object.values(AlertType).includes(value),
45
+ },
46
+ actionType: {
47
+ type: String as PropType<ButtonActionType>,
48
+ default: ButtonActionType.ACTION,
49
+ validator: (value: ButtonActionType) => Object.values(ButtonActionType).includes(value),
50
+ },
51
+ text: {
52
+ type: String as PropType<string>,
53
+ default: 'Button text'
54
+ },
55
+ icon: {
56
+ type: String as PropType<any>,
57
+ default: "mdiHelp"
58
+ },
59
+ disabled: {
60
+ type: Boolean as PropType<boolean>,
61
+ default: false,
62
+ },
63
+ to: {
64
+ type: String as PropType<string>,
65
+ default: '/'
66
+ },
67
+ isExternal: {
68
+ type: Boolean as PropType<boolean>,
69
+ default: false
70
+ },
71
+ })
72
+
73
+ // Emits
74
+ const emit = defineEmits(['click'])
75
+ const emitClick = () => {
76
+ if (!props.disabled) {
77
+ emit('click')
78
+ }
79
+ }
80
+
81
+ // Computed classes
82
+ const iconClass = computed(() => {
83
+ const variant = {
84
+ [AlertType.WARNING]: 'text-icon-warning-on-bg',
85
+ [AlertType.DANGER]: 'text-icon-danger',
86
+ [AlertType.SUCCESS]: 'text-icon-success',
87
+ [AlertType.INFO]: 'text-icon-info',
88
+ }
89
+ return variant[props.type as AlertType] || 'text-icon-warning-on-bg'
90
+ })
91
+
92
+ // Props for the dynamic component
93
+ const componentProps = computed(() => {
94
+ if (props.actionType === ButtonActionType.LINK) {
95
+ return {
96
+ to: props.to,
97
+ target: props.isExternal ? '_blank' : '_self',
98
+ rel: props.isExternal ? 'noopener noreferrer' : undefined,
99
+ external: props.isExternal,
100
+ }
101
+ } else {
102
+ return {}
103
+ }
104
+ })
105
+ </script>
@@ -0,0 +1,45 @@
1
+ <template>
2
+ <button
3
+ :class="[
4
+ styleType === ButtonPaginationStyle.BUTTON ? 'border' : 'border-t',
5
+ 'border-border-default',
6
+ styleType === ButtonPaginationStyle.BUTTON && 'first:rounded-l last:rounded-r',
7
+ 'min-w-[40px] h-[36px] w-full',
8
+ 'flex',
9
+ 'items-center',
10
+ 'justify-center',
11
+ 'text-sm',
12
+ 'text-text-default',
13
+ 'font-semibold',
14
+ 'hover:bg-background-neutral-hover',
15
+ props.disabled ? 'opacity-50 hover:cursor-not-allowed hover:bg-transparent' : 'hover:cursor-pointer'
16
+ ]"
17
+ :disabled="props.disabled"
18
+ @click="emitClick"
19
+ >
20
+ <slot />
21
+ </button>
22
+ </template>
23
+
24
+ <script setup lang="ts">
25
+ // Props
26
+ const props = defineProps({
27
+ styleType: {
28
+ type: String as PropType<ButtonPaginationStyle>,
29
+ default: ButtonPaginationStyle.BUTTON,
30
+ validator: (value: ButtonPaginationStyle) => Object.values(ButtonPaginationStyle).includes(value),
31
+ },
32
+ disabled: {
33
+ type: Boolean as PropType<boolean>,
34
+ default: false,
35
+ },
36
+ })
37
+
38
+ // Emits
39
+ const emit = defineEmits(['click'])
40
+ const emitClick = () => {
41
+ if (!props.disabled) {
42
+ emit('click')
43
+ }
44
+ }
45
+ </script>
@@ -0,0 +1,61 @@
1
+ <template>
2
+ <ActionButton
3
+ :text
4
+ :size
5
+ :iconPosition
6
+ :icon
7
+ :disabled
8
+ :isRounded
9
+ :styleType
10
+ textClass="!font-medium"
11
+ @click="emitClick"
12
+ />
13
+ </template>
14
+
15
+ <script setup lang="ts">
16
+ // Props
17
+ const props = defineProps({
18
+ text: {
19
+ type: String as PropType<string>,
20
+ default: 'Button text',
21
+ },
22
+ size: {
23
+ type: String as PropType<ButtonSize>,
24
+ default: ButtonSize.LG,
25
+ validator: (value: ButtonSize) => Object.values(ButtonSize).includes(value),
26
+ },
27
+ styleType: {
28
+ type: String as PropType<ButtonStyleType>,
29
+ default: ButtonStyleType.NEUTRAL_OUTLINED,
30
+ },
31
+ icon: {
32
+ type: String as PropType<any>,
33
+ default: 'mdiHelp',
34
+ },
35
+ iconPosition: {
36
+ type: String as PropType<IconPosition>,
37
+ default: IconPosition.NONE,
38
+ validator: (value: IconPosition) => Object.values(IconPosition).includes(value),
39
+ },
40
+ isRounded: {
41
+ type: Boolean as PropType<boolean>,
42
+ default: false
43
+ },
44
+ disabled: {
45
+ type: Boolean as PropType<boolean>,
46
+ default: false,
47
+ },
48
+ active: {
49
+ type: Boolean as PropType<boolean>,
50
+ default: true,
51
+ },
52
+ })
53
+
54
+ // Emits
55
+ const emit = defineEmits(['click'])
56
+ const emitClick = () => {
57
+ if (!props.disabled) {
58
+ emit('click')
59
+ }
60
+ }
61
+ </script>