@autoafleveren/ui 1.3.2 → 1.3.3
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/dist/config/tailwind/config.cjs +1 -0
- package/dist/icons.cjs +17 -17
- package/dist/icons.js +1710 -1644
- package/dist/types/composables/index.d.ts +1 -1
- package/dist/types/composables/useActionBar/index.d.ts +3 -3
- package/dist/ui.cjs +36 -36
- package/dist/ui.js +6766 -6696
- package/package.json +3 -2
- package/src/App.vue +15 -0
- package/src/Playground.vue.example +9 -0
- package/src/config/eslint.cjs +199 -0
- package/src/config/tailwind/config.cjs +229 -0
- package/src/config/tailwind/screens.json +9 -0
- package/src/css/build.css +52 -0
- package/src/css/main.css +4 -0
- package/src/css/theme.css +208 -0
- package/src/css/tinymce.css +58 -0
- package/src/main.ts +34 -0
- package/src/modules/components/AppActionBar/AppActionBar.vue +96 -0
- package/src/modules/components/AppActionBar/AppActionBarItem.vue +123 -0
- package/src/modules/components/AppActionBar/AppActionBarSubMenu.vue +89 -0
- package/src/modules/components/AppActionBar/Components/Error.vue +11 -0
- package/src/modules/components/AppActionBar/Components/Loading.vue +9 -0
- package/src/modules/components/AppActionBar/Components/MultiSelect.vue +102 -0
- package/src/modules/components/AppActionBar/Components/__tests__/multi-select.spec.ts +74 -0
- package/src/modules/components/AppActionBar/__mocks__/index.ts +36 -0
- package/src/modules/components/AppActionBar/__tests__/app-action-bar-item.spec.ts +134 -0
- package/src/modules/components/AppActionBar/__tests__/app-action-bar-sub-menu.spec.ts +45 -0
- package/src/modules/components/AppActionBar/__tests__/app-action-bar.spec.ts +92 -0
- package/src/modules/components/AppActionBar/index.d.ts +29 -0
- package/src/modules/components/AppActionBar/index.ts +18 -0
- package/src/modules/components/AppAlert/AppAlert.vue +69 -0
- package/src/modules/components/AppAlert/__tests__/app-alert.spec.ts +67 -0
- package/src/modules/components/AppAlert/index.d.ts +3 -0
- package/src/modules/components/AppAlert/index.ts +18 -0
- package/src/modules/components/AppAvatar/AppAvatar.vue +30 -0
- package/src/modules/components/AppAvatar/DefaultAvatar.vue +187 -0
- package/src/modules/components/AppAvatar/__tests__/app-avatar.spec.ts +70 -0
- package/src/modules/components/AppAvatar/index.d.ts +9 -0
- package/src/modules/components/AppAvatar/index.ts +9 -0
- package/src/modules/components/AppBackButton/AppBackButton.vue +51 -0
- package/src/modules/components/AppBackButton/__tests__/app-back-button.spec.ts +70 -0
- package/src/modules/components/AppBadge/AppBadge.vue +65 -0
- package/src/modules/components/AppBadge/__tests__/app-badge.spec.ts +64 -0
- package/src/modules/components/AppBadge/index.d.ts +13 -0
- package/src/modules/components/AppBadge/index.ts +29 -0
- package/src/modules/components/AppButton/AppButton.vue +53 -0
- package/src/modules/components/AppButton/ButtonIconSlot.vue +26 -0
- package/src/modules/components/AppButton/__tests__/app-button.spec.ts +145 -0
- package/src/modules/components/AppButton/__tests__/button-icon-slot.spec.ts +30 -0
- package/src/modules/components/AppButton/index.d.ts +16 -0
- package/src/modules/components/AppButton/index.ts +57 -0
- package/src/modules/components/AppCard/AppCard.vue +88 -0
- package/src/modules/components/AppCard/CardAction.vue +101 -0
- package/src/modules/components/AppCard/CardIconSlot.vue +65 -0
- package/src/modules/components/AppCard/__tests__/app-card.spec.ts +109 -0
- package/src/modules/components/AppCard/__tests__/card-action.spec.ts +55 -0
- package/src/modules/components/AppCard/__tests__/card-icon-slot.spec.ts +27 -0
- package/src/modules/components/AppCard/index.d.ts +12 -0
- package/src/modules/components/AppCard/index.ts +5 -0
- package/src/modules/components/AppColor/AppColor.vue +74 -0
- package/src/modules/components/AppColor/__tests__/app-color.spec.ts +53 -0
- package/src/modules/components/AppColor/index.d.ts +10 -0
- package/src/modules/components/AppColorCard/AppColorCard.vue +41 -0
- package/src/modules/components/AppColorCard/__tests__/app-color-card.spec.ts +55 -0
- package/src/modules/components/AppConfirm/AppConfirm.vue +237 -0
- package/src/modules/components/AppConfirm/__tests__/app-confirm.spec.ts +366 -0
- package/src/modules/components/AppConfirm/index.d.ts +31 -0
- package/src/modules/components/AppConfirm/index.ts +1 -0
- package/src/modules/components/AppContextMenu/AppContextMenu.vue +100 -0
- package/src/modules/components/AppContextMenu/ShortcutItem.vue +37 -0
- package/src/modules/components/AppContextMenu/__mocks__/index.ts +25 -0
- package/src/modules/components/AppContextMenu/__tests__/app-context-menu.spec.ts +71 -0
- package/src/modules/components/AppContextMenu/__tests__/shortcut-item.spec.ts +29 -0
- package/src/modules/components/AppContextMenu/index.d.ts +23 -0
- package/src/modules/components/AppDataTable/AppDataTable.vue +323 -0
- package/src/modules/components/AppDataTable/AppDataTableFooter.vue +91 -0
- package/src/modules/components/AppDataTable/__mocks__/index.ts +71 -0
- package/src/modules/components/AppDataTable/__tests__/app-data-table-footer.spec.ts +107 -0
- package/src/modules/components/AppDataTable/__tests__/app-data-table.spec.ts +153 -0
- package/src/modules/components/AppDataTable/index.d.ts +29 -0
- package/src/modules/components/AppDefinitionList/AppDefinitionItem.vue +57 -0
- package/src/modules/components/AppDefinitionList/AppDefinitionList.vue +31 -0
- package/src/modules/components/AppDefinitionList/__mocks__/index.ts +31 -0
- package/src/modules/components/AppDefinitionList/__tests__/app-definition-item.spec.ts +93 -0
- package/src/modules/components/AppDefinitionList/__tests__/app-definition-list.spec.ts +35 -0
- package/src/modules/components/AppDefinitionList/index.d.ts +8 -0
- package/src/modules/components/AppDisclosure/AppDisclosure.vue +19 -0
- package/src/modules/components/AppDisclosure/AppDisclosureButton.vue +43 -0
- package/src/modules/components/AppDisclosure/AppDisclosurePanel.vue +31 -0
- package/src/modules/components/AppDisclosure/__tests__/app-disclosure-button.spec.ts +70 -0
- package/src/modules/components/AppDisclosure/__tests__/app-disclosure-panel.spec.ts +64 -0
- package/src/modules/components/AppDisclosure/__tests__/app-disclosure.spec.ts +41 -0
- package/src/modules/components/AppDrawer/AppDrawer.vue +149 -0
- package/src/modules/components/AppDrawer/__tests__/app-drawer.spec.ts +120 -0
- package/src/modules/components/AppDrawer/index.d.ts +27 -0
- package/src/modules/components/AppDropdownButton/AppDropdownButton.vue +82 -0
- package/src/modules/components/AppDropdownButton/AppDropdownItem.vue +67 -0
- package/src/modules/components/AppDropdownButton/__mocks__/index.ts +25 -0
- package/src/modules/components/AppDropdownButton/__tests__/app-dropdown-button.spec.ts +81 -0
- package/src/modules/components/AppDropdownButton/__tests__/app-dropdown-item.spec.ts +108 -0
- package/src/modules/components/AppDropdownButton/index.d.ts +26 -0
- package/src/modules/components/AppDropdownButton/index.ts +8 -0
- package/src/modules/components/AppError/AppError.vue +233 -0
- package/src/modules/components/AppError/__tests__/app-error.spec.ts +366 -0
- package/src/modules/components/AppError/index.d.ts +30 -0
- package/src/modules/components/AppError/index.ts +1 -0
- package/src/modules/components/AppImageDropzone/AppImageDropzone.vue +130 -0
- package/src/modules/components/AppImageDropzone/__tests__/app-image-dropzone.spec.ts +92 -0
- package/src/modules/components/AppImageDropzone/index.d.ts +8 -0
- package/src/modules/components/AppInput/AppInput.vue +247 -0
- package/src/modules/components/AppInput/FileInput.vue +58 -0
- package/src/modules/components/AppInput/Input.vue +141 -0
- package/src/modules/components/AppInput/InputIconSlot.vue +27 -0
- package/src/modules/components/AppInput/LocationInput.vue +150 -0
- package/src/modules/components/AppInput/__mocks__/location.ts +13 -0
- package/src/modules/components/AppInput/__tests__/app-input.spec.ts +255 -0
- package/src/modules/components/AppInput/__tests__/file-input.spec.ts +48 -0
- package/src/modules/components/AppInput/__tests__/input-icon-slot.spec.ts +27 -0
- package/src/modules/components/AppInput/__tests__/input.spec.ts +260 -0
- package/src/modules/components/AppInput/__tests__/location-input.spec.ts +159 -0
- package/src/modules/components/AppInput/choice.ts +24 -0
- package/src/modules/components/AppInput/datepicker.ts +62 -0
- package/src/modules/components/AppInput/index.d.ts +68 -0
- package/src/modules/components/AppInput/index.ts +133 -0
- package/src/modules/components/AppInput/location.ts +8 -0
- package/src/modules/components/AppInput/richText.ts +45 -0
- package/src/modules/components/AppInputLabel/AppInputLabel.vue +15 -0
- package/src/modules/components/AppInputLabel/__tests__/app-input-label.spec.ts +38 -0
- package/src/modules/components/AppInputLabel/index.d.ts +6 -0
- package/src/modules/components/AppLicensePlate/AppLicensePlate.vue +34 -0
- package/src/modules/components/AppLicensePlate/__tests__/app-license-plate.spec.ts +46 -0
- package/src/modules/components/AppLicensePlate/index.d.ts +1 -0
- package/src/modules/components/AppLoader/AppLoader.vue +37 -0
- package/src/modules/components/AppLoader/index.d.ts +1 -0
- package/src/modules/components/AppLoader/index.ts +8 -0
- package/src/modules/components/AppMaps/AppMaps.vue +105 -0
- package/src/modules/components/AppMaps/index.ts +44 -0
- package/src/modules/components/AppMenu/AppMenu.vue +79 -0
- package/src/modules/components/AppMenu/AppMenuItem.vue +40 -0
- package/src/modules/components/AppMenu/__mocks__/index.ts +23 -0
- package/src/modules/components/AppMenu/__tests__/app-menu-item.spec.ts +47 -0
- package/src/modules/components/AppMenu/__tests__/app-menu.spec.ts +53 -0
- package/src/modules/components/AppMenu/index.d.ts +15 -0
- package/src/modules/components/AppModal/AppModal.vue +261 -0
- package/src/modules/components/AppModal/__tests__/app-modal.spec.ts +282 -0
- package/src/modules/components/AppModal/index.d.ts +36 -0
- package/src/modules/components/AppNavigationMenu/AppNavigationMenu.vue +95 -0
- package/src/modules/components/AppNavigationMenu/Mobile.vue +126 -0
- package/src/modules/components/AppNavigationMenu/NavigationItem.vue +82 -0
- package/src/modules/components/AppNavigationMenu/SupportItem.vue +29 -0
- package/src/modules/components/AppNavigationMenu/__tests__/app-navigation-menu.spec.ts +104 -0
- package/src/modules/components/AppNavigationMenu/__tests__/mobile.spec.ts +155 -0
- package/src/modules/components/AppNavigationMenu/__tests__/navigation-item.spec.ts +91 -0
- package/src/modules/components/AppNavigationMenu/__tests__/support-item.spec.ts +48 -0
- package/src/modules/components/AppPagination/AppPagination.vue +133 -0
- package/src/modules/components/AppPagination/AppPaginationItem.vue +28 -0
- package/src/modules/components/AppPagination/__mocks__/index.ts +20 -0
- package/src/modules/components/AppPagination/__tests__/app-pagination.spec.ts +143 -0
- package/src/modules/components/AppPagination/index.d.ts +24 -0
- package/src/modules/components/AppProgressBar/AppProgressBar.vue +93 -0
- package/src/modules/components/AppProgressBar/AppProgressBarStep.vue +5 -0
- package/src/modules/components/AppProgressBar/__mocks__/index.ts +17 -0
- package/src/modules/components/AppProgressBar/__tests__/app-progress-bar-step.spec.ts +18 -0
- package/src/modules/components/AppProgressBar/__tests__/app-progress-bar.spec.ts +77 -0
- package/src/modules/components/AppProgressBar/index.d.ts +21 -0
- package/src/modules/components/AppRating/AppRating.vue +42 -0
- package/src/modules/components/AppRating/VueStarRating/Star.vue +215 -0
- package/src/modules/components/AppRating/VueStarRating/StarRating.vue +231 -0
- package/src/modules/components/AppRating/VueStarRating/classes/AlphaColor.ts +68 -0
- package/src/modules/components/AppRating/VueStarRating/readme.md +279 -0
- package/src/modules/components/AppRating/__tests__/app-rating.spec.ts +36 -0
- package/src/modules/components/AppSection/AppSection.vue +35 -0
- package/src/modules/components/AppSection/__tests__/app-section.spec.ts +53 -0
- package/src/modules/components/AppSelect/AppSelect.vue +176 -0
- package/src/modules/components/AppSelect/__mocks__/index.ts +24 -0
- package/src/modules/components/AppSelect/__tests__/app-select.spec.ts +73 -0
- package/src/modules/components/AppSelect/index.d.ts +43 -0
- package/src/modules/components/AppSelect/index.ts +69 -0
- package/src/modules/components/AppStepper/AppStepper.vue +79 -0
- package/src/modules/components/AppStepper/__tests__/app-stepper.spec.ts +59 -0
- package/src/modules/components/AppTable/AppTable.vue +40 -0
- package/src/modules/components/AppTimeline/AppTimeline.vue +22 -0
- package/src/modules/components/AppTimeline/AppTimelineItem.vue +97 -0
- package/src/modules/components/AppTimeline/AppTimelineItemIcon.vue +55 -0
- package/src/modules/components/AppTimeline/__mocks__/timeline.ts +29 -0
- package/src/modules/components/AppTimeline/__tests__/app-timeline-item-Icon.spec.ts +35 -0
- package/src/modules/components/AppTimeline/__tests__/app-timeline-item.spec.ts +121 -0
- package/src/modules/components/AppTimeline/__tests__/app-timeline.spec.ts +55 -0
- package/src/modules/components/AppTimeline/index.d.ts +30 -0
- package/src/modules/components/AppTimeline/index.ts +13 -0
- package/src/modules/components/AppToggle/AppToggle.vue +36 -0
- package/src/modules/components/AppToggle/__tests__/app-toggle.spec.ts +54 -0
- package/src/modules/components/AppToggle/index.d.ts +3 -0
- package/src/modules/components/AppToggleCard/AppToggleCard.vue +45 -0
- package/src/modules/components/AppToggleCard/__tests__/app-toggle-card.spec.ts +55 -0
- package/src/modules/components/index.ts +43 -0
- package/src/modules/composables/index.ts +13 -0
- package/src/modules/composables/useActionBar/__mocks__/index.ts +17 -0
- package/src/modules/composables/useActionBar/__tests__/index.spec.ts +62 -0
- package/src/modules/composables/useActionBar/index.d.ts +1 -0
- package/src/modules/composables/useActionBar/index.ts +67 -0
- package/src/modules/composables/useComputedPosition/index.d.ts +16 -0
- package/src/modules/composables/useComputedPosition/index.ts +199 -0
- package/src/modules/composables/useConfirm/__tests__/index.spec.ts +29 -0
- package/src/modules/composables/useConfirm/index.ts +63 -0
- package/src/modules/composables/useContextMenu/index.ts +127 -0
- package/src/modules/composables/useDrawer/__tests__/index.spec.ts +34 -0
- package/src/modules/composables/useDrawer/index.ts +136 -0
- package/src/modules/composables/useEcho/index.ts +167 -0
- package/src/modules/composables/useError/__tests__/index.spec.ts +29 -0
- package/src/modules/composables/useError/index.ts +61 -0
- package/src/modules/composables/useGoogleApi/__tests__/index.spec.ts +39 -0
- package/src/modules/composables/useGoogleApi/index.ts +26 -0
- package/src/modules/composables/useLayout/__tests__/index.spec.ts +34 -0
- package/src/modules/composables/useLayout/index.d.ts +1 -0
- package/src/modules/composables/useLayout/index.ts +68 -0
- package/src/modules/composables/useModal/__tests__/index.spec.ts +34 -0
- package/src/modules/composables/useModal/index.ts +97 -0
- package/src/modules/composables/useNavigation/__mocks__/navigation.ts +22 -0
- package/src/modules/composables/useNavigation/__tests__/index.spec.ts +88 -0
- package/src/modules/composables/useNavigation/index.d.ts +17 -0
- package/src/modules/composables/useNavigation/index.ts +97 -0
- package/src/modules/icons/BuildingCircleCheck.vue +32 -0
- package/src/modules/icons/BuildingCircleXmark.vue +20 -0
- package/src/modules/icons/CarsIcon.vue +29 -0
- package/src/modules/icons/ChatPersonRoundedIcon.vue +184 -0
- package/src/modules/icons/CompanyIcon.vue +18 -0
- package/src/modules/icons/HeroGirlIcon.vue +246 -0
- package/src/modules/icons/HeroPersonIcon.vue +402 -0
- package/src/modules/icons/HeroPersonRoundedIcon.vue +412 -0
- package/src/modules/icons/HeroPersonWithBgIcon.vue +4503 -0
- package/src/modules/icons/LocationMarkerIcon.vue +33 -0
- package/src/modules/icons/PartyPopperIcon.vue +146 -0
- package/src/modules/icons/index.ts +32 -0
- package/src/modules/icons/status/ErrorIcon.vue +24 -0
- package/src/modules/icons/status/SuccessIcon.vue +24 -0
- package/src/modules/icons/status/WarningIcon.vue +27 -0
- package/src/modules/icons/status/index.ts +3 -0
- package/src/modules/index.ts +8 -0
- package/src/modules/layouts/Auth/Auth.vue +36 -0
- package/src/modules/layouts/Auth/__tests__/auth.spec.ts +63 -0
- package/src/modules/layouts/Base/Base.vue +69 -0
- package/src/modules/layouts/Base/__tests__/base.spec.ts +56 -0
- package/src/modules/layouts/Platform/Platform.vue +96 -0
- package/src/modules/layouts/Platform/__tests__/platform.spec.ts +56 -0
- package/src/modules/layouts/index.ts +9 -0
- package/src/modules/plugins/Sentry/index.d.ts +16 -0
- package/src/modules/plugins/Sentry/index.ts +65 -0
- package/src/modules/plugins/Sentry/language/nl.ts +13 -0
- package/src/modules/plugins/TinyMCE/lang/nl.js +430 -0
- package/src/modules/plugins/Toast/Toast.vue +58 -0
- package/src/modules/plugins/Toast/__tests__/toast.spec.ts +90 -0
- package/src/modules/plugins/Toast/index.ts +36 -0
- package/src/modules/plugins/Toast/types.d.ts +265 -0
- package/src/modules/plugins/index.ts +63 -0
- package/src/stories/Introduction.mdx +4 -0
- package/src/stories/assets/code-brackets.svg +1 -0
- package/src/stories/assets/colors.svg +1 -0
- package/src/stories/assets/comments.svg +1 -0
- package/src/stories/assets/direction.svg +1 -0
- package/src/stories/assets/flow.svg +1 -0
- package/src/stories/assets/images/logo.png +0 -0
- package/src/stories/assets/images/road.png +0 -0
- package/src/stories/assets/plugin.svg +1 -0
- package/src/stories/assets/repo.svg +1 -0
- package/src/stories/assets/stackalt.svg +1 -0
- package/src/stories/components/ActionBar/ActionBar.stories.ts +67 -0
- package/src/stories/components/Alert/Alert.stories.ts +53 -0
- package/src/stories/components/Avatar/Avatar.stories.ts +44 -0
- package/src/stories/components/BackButton/BackButton.stories.ts +39 -0
- package/src/stories/components/Badge/Badge.stories.ts +42 -0
- package/src/stories/components/Button/Button.stories.ts +132 -0
- package/src/stories/components/Card/Card.stories.ts +70 -0
- package/src/stories/components/Color/Color.stories.ts +41 -0
- package/src/stories/components/ColorCard/ColorCard.stories.ts +43 -0
- package/src/stories/components/Confirm/Confirm.stories.ts +110 -0
- package/src/stories/components/ContextMenu/ContextMenu.stories.ts +85 -0
- package/src/stories/components/DefinitionList/DefinitionList.stories.ts +32 -0
- package/src/stories/components/Disclosure/Disclosure.stories.ts +61 -0
- package/src/stories/components/DropdownButton/DropdownButton.stories.ts +121 -0
- package/src/stories/components/Error/Error.stories.ts +106 -0
- package/src/stories/components/ImageDropzone/ImageDropzone.stories.ts +41 -0
- package/src/stories/components/Input/Input.stories.ts +180 -0
- package/src/stories/components/Input/LocationInput.stories.ts +77 -0
- package/src/stories/components/LicensePlate/LicensePlate.stories.ts +39 -0
- package/src/stories/components/Maps/Maps.stories.ts +36 -0
- package/src/stories/components/Menu/Menu.stories.ts +41 -0
- package/src/stories/components/Modal/Modal.stories.ts +68 -0
- package/src/stories/components/Navigation/Navigation.stories.ts +62 -0
- package/src/stories/components/Pagination/Pagination.stories.ts +62 -0
- package/src/stories/components/ProgressBar/ProgressBar.stories.ts +48 -0
- package/src/stories/components/Rating/Rating.stories.ts +38 -0
- package/src/stories/components/Section/Section.stories.ts +44 -0
- package/src/stories/components/Select/Select.stories.ts +90 -0
- package/src/stories/components/Stepper/Stepper.stories.ts +38 -0
- package/src/stories/components/Table/DataTable.stories.ts +96 -0
- package/src/stories/components/Table/Table.stories.ts +45 -0
- package/src/stories/components/Timeline/Timeline.stories.ts +46 -0
- package/src/stories/components/Toast/Toast.stories.ts +47 -0
- package/src/stories/components/Toggle/Toggle.stories.ts +41 -0
- package/src/stories/components/ToggleCard/ToggleCard.stories.ts +43 -0
- package/src/stories/layouts/Auth.stories.ts +43 -0
- package/src/stories/layouts/Base.stories.ts +70 -0
- package/src/tests/mocks/resize-observer.ts +13 -0
- package/src/tests/stubs/AppSelect.ts +89 -0
- package/src/tests/stubs/HeadlessUiDialogStub.ts +24 -0
- package/src/tests/stubs/HeadlessUiTransitionChildStub.ts +20 -0
- package/src/tests/stubs/HeadlessUiTransitionRootStub.ts +25 -0
- package/src/tests/stubs/IconStub.ts +9 -0
- package/src/tests/stubs/Vue3EasyDataTableStub.ts +53 -0
- package/src/typings/plugin.d.ts +5 -0
- package/src/typings/shims-vue.d.ts +13 -0
- package/src/typings/utilities.d.ts +4 -0
- package/src/typings/vite-environment.d.ts +12 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type Multiselect from '@vueform/multiselect';
|
|
2
|
+
import type { types, classes } from '.';
|
|
3
|
+
|
|
4
|
+
export type Type = typeof types[number];
|
|
5
|
+
|
|
6
|
+
export type OpenDirection = 'up' | 'down';
|
|
7
|
+
|
|
8
|
+
export type ClassesOptions = keyof typeof classes;
|
|
9
|
+
|
|
10
|
+
export interface Props {
|
|
11
|
+
wrapperClasses?: string;
|
|
12
|
+
hasError?: boolean;
|
|
13
|
+
errorMessage?: string;
|
|
14
|
+
label?: string;
|
|
15
|
+
optionLabel?: string;
|
|
16
|
+
fetchOnOpen?: boolean;
|
|
17
|
+
openDirection?: OpenDirection;
|
|
18
|
+
dropdownClasses?: string;
|
|
19
|
+
additionalClasses?: Record<string, string>;
|
|
20
|
+
labelClasses?: string;
|
|
21
|
+
searchable?: boolean;
|
|
22
|
+
cacheable?: boolean;
|
|
23
|
+
onChange?: (value: unknown) => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface TagSlotProps {
|
|
27
|
+
disabled: boolean;
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
|
+
option: any;
|
|
30
|
+
handleTagRemove: (option: unknown, $event: Event) => void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface SingleLabelProps {
|
|
34
|
+
value: Record<string, unknown>;
|
|
35
|
+
classes: string | undefined;
|
|
36
|
+
clear: () => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface OptionProps {
|
|
40
|
+
option: Record<string, unknown>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type MultiSelectSlots = keyof InstanceType<typeof Multiselect>['$slots'];
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/* eslint-disable max-len */
|
|
2
|
+
export const classes = {
|
|
3
|
+
container: 'app-select scrollbar-primary relative mx-auto w-full flex items-center justify-end box-border cursor-pointer border border-zinc-300 rounded-lg bg-white text-base leading-snug outline-hidden rounded-lg hover:bg-zinc-100',
|
|
4
|
+
containerDisabled: 'cursor-default bg-zinc-100',
|
|
5
|
+
containerOpen: 'rounded-b-none',
|
|
6
|
+
containerOpenTop: 'rounded-t-none',
|
|
7
|
+
containerActive: 'ring-1 ring-zinc-300',
|
|
8
|
+
singleLabel: 'flex items-center h-full max-w-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3 pr-16 box-border rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3',
|
|
9
|
+
singleLabelText: 'text-ellipsis overflow-hidden block whitespace-nowrap max-w-full',
|
|
10
|
+
multipleLabel: 'flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3 rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3',
|
|
11
|
+
search: 'h-full w-full absolute inset-0 outline-hidden focus:ring-0 appearance-none box-border border-0 text-base font-sans bg-white rounded-lg pl-3 rtl:pl-0 rtl:pr-3',
|
|
12
|
+
tags: 'min-w-0 grow shrink flex flex-wrap items-center mt-1 px-2',
|
|
13
|
+
tag: 'max-w-full bg-zinc-200 text-sm font-semibold py-1 pl-2 rounded-xs h-7 mr-1 mb-1 flex items-center whitespace-nowrap rtl:pl-0 rtl:pr-2 rtl:mr-0 rtl:ml-1',
|
|
14
|
+
tagDisabled: 'pr-2 opacity-50 rtl:pl-2',
|
|
15
|
+
tagRemove: 'flex items-center justify-center p-1 mx-0.5 rounded-xs group',
|
|
16
|
+
tagRemoveIcon: 'bg-multiselect-remove bg-center bg-no-repeat inline-block w-3 h-3 text-zinc-700',
|
|
17
|
+
tagText: 'overflow-hidden text-ellipsis whitespace-nowrap',
|
|
18
|
+
tagsSearchWrapper: 'inline-block relative mx-1 mb-1 grow shrink h-full',
|
|
19
|
+
tagsSearch: 'absolute inset-0 border-0 outline-hidden focus:ring-0 appearance-none p-0 text-base font-sans box-border w-full bg-transparent',
|
|
20
|
+
tagsSearchCopy: 'invisible whitespace-pre-wrap inline-block h-px',
|
|
21
|
+
placeholder: 'flex text-base items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3 text-zinc-400 rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3',
|
|
22
|
+
caret: 'bg-multiselect-caret bg-center bg-no-repeat w-5 h-8 py-px box-content mr-3 relative z-10 stroke-2 shrink-0 grow-0 transition-transform transform pointer-events-none rtl:mr-0 rtl:ml-3',
|
|
23
|
+
caretOpen: 'rotate-180 pointer-events-auto',
|
|
24
|
+
clear: 'pr-3 relative z-10 text-zinc-700 transition duration-300 shrink-0 grow-0 flex rtl:pr-0 rtl:pl-3',
|
|
25
|
+
clearIcon: 'bg-multiselect-remove bg-center bg-no-repeat w-2.5 h-4 py-px box-content inline-block',
|
|
26
|
+
spinner: 'bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 mr-3 animate-spin shrink-0 grow-0 rtl:mr-0 rtl:ml-3',
|
|
27
|
+
inifite: 'flex items-center justify-center w-full',
|
|
28
|
+
inifiteSpinner: 'bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 animate-spin shrink-0 grow-0 m-3',
|
|
29
|
+
dropdown: 'max-h-60 absolute -left-[2px] -right-[2px] bottom-0 transform translate-y-full border-2 border-zinc-300 -mt-px overflow-y-auto z-50 bg-white flex flex-col rounded-b-lg',
|
|
30
|
+
dropdownTop: '-translate-y-full! top-px bottom-auto rounded-b-none rounded-t-lg',
|
|
31
|
+
dropdownHidden: 'hidden',
|
|
32
|
+
options: 'flex flex-col p-0 m-0 list-none',
|
|
33
|
+
optionsTop: '',
|
|
34
|
+
group: 'p-0 m-0',
|
|
35
|
+
groupLabel: 'flex text-sm box-border items-center justify-start text-left py-1 px-3 font-semibold bg-zinc-200 cursor-default leading-normal',
|
|
36
|
+
groupLabelPointable: 'cursor-pointer',
|
|
37
|
+
groupLabelPointed: 'bg-zinc-300 text-zinc-700',
|
|
38
|
+
groupLabelSelected: 'bg-primary-active text-white',
|
|
39
|
+
groupLabelDisabled: 'bg-zinc-100 text-zinc-300 cursor-not-allowed',
|
|
40
|
+
groupLabelSelectedPointed: 'bg-primary-active text-white opacity-90',
|
|
41
|
+
groupLabelSelectedDisabled: 'text-white bg-primary-active bg-opacity-50 cursor-not-allowed',
|
|
42
|
+
groupOptions: 'p-0 m-0',
|
|
43
|
+
option: 'flex items-center justify-start box-border text-left cursor-pointer text-base leading-snug py-2 px-3',
|
|
44
|
+
optionPointed: 'text-zinc-800 bg-zinc-100',
|
|
45
|
+
optionSelected: 'text-white bg-primary',
|
|
46
|
+
optionDisabled: 'text-zinc-300 cursor-not-allowed',
|
|
47
|
+
optionSelectedPointed: 'text-white bg-primary opacity-90',
|
|
48
|
+
optionSelectedDisabled: 'text-green-100 bg-primary bg-opacity-50 cursor-not-allowed',
|
|
49
|
+
noOptions: 'py-2 px-3 text-zinc-600 bg-white text-left',
|
|
50
|
+
noResults: 'py-2 px-3 text-zinc-600 bg-white text-left',
|
|
51
|
+
fakeInput: 'bg-transparent absolute left-0 right-0 -bottom-px w-full h-px border-0 p-0 appearance-none outline-hidden text-transparent',
|
|
52
|
+
spacer: 'h-9 py-px box-content',
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
type ClassKey = keyof typeof classes;
|
|
56
|
+
|
|
57
|
+
function classKeyExists(classKey: string): classKey is ClassKey {
|
|
58
|
+
return classKey in classes;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function getSlotClasses(slotName: string): string | undefined {
|
|
62
|
+
const classKey = Object.keys(classes).find(key => key.toLowerCase() === slotName);
|
|
63
|
+
|
|
64
|
+
if (classKey && classKeyExists(classKey)) {
|
|
65
|
+
return classes[classKey];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { onMounted, useTemplateRef, watch, ref } from 'vue';
|
|
3
|
+
import { NumberFlip } from 'number-flip-animation';
|
|
4
|
+
import { FontAwesomeIcon, byPrefixAndName } from '~icons';
|
|
5
|
+
import { AppCard } from '~components';
|
|
6
|
+
|
|
7
|
+
defineProps<{ title?: string }>();
|
|
8
|
+
|
|
9
|
+
const model = defineModel<number>({ required: true });
|
|
10
|
+
const flipRef = useTemplateRef<HTMLDivElement>('flipRef');
|
|
11
|
+
const numberFlip = ref<NumberFlip>();
|
|
12
|
+
|
|
13
|
+
watch(model, (value: number) => {
|
|
14
|
+
numberFlip.value?.setNumber?.(value);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
onMounted(() => {
|
|
18
|
+
if (flipRef.value) {
|
|
19
|
+
numberFlip.value = new NumberFlip({
|
|
20
|
+
rootElement: flipRef.value,
|
|
21
|
+
initialNumber: model.value,
|
|
22
|
+
durationSlide: 500,
|
|
23
|
+
wrapperClassname: 'flex overflow-hidden relative transition-opacity transition-1000',
|
|
24
|
+
digitClassname: 'flex flex-col absolute transition-transform transition-1000 ease-in-out *:text-center',
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
numberFlip.value?.setNumber?.(model.value);
|
|
29
|
+
}, 100);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
function increment(): void {
|
|
34
|
+
model.value += 1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function decrement(): void {
|
|
38
|
+
if (model.value === 0) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
model.value -= 1;
|
|
43
|
+
}
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
<template>
|
|
47
|
+
<AppCard
|
|
48
|
+
content-classes="flex items-center"
|
|
49
|
+
class="p-4!"
|
|
50
|
+
>
|
|
51
|
+
<div class="mr-6 w-full select-none">
|
|
52
|
+
<slot>
|
|
53
|
+
{{ title }}
|
|
54
|
+
</slot>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<FontAwesomeIcon
|
|
58
|
+
:icon="byPrefixAndName.far?.minus"
|
|
59
|
+
:aria-disabled="model === 0"
|
|
60
|
+
class="cursor-pointer aria-disabled:cursor-not-allowed aria-disabled:opacity-50"
|
|
61
|
+
data-test-decrement-icon
|
|
62
|
+
@click="decrement"
|
|
63
|
+
/>
|
|
64
|
+
|
|
65
|
+
<div
|
|
66
|
+
ref="flipRef"
|
|
67
|
+
class="w-16 shrink-0 justify-center text-center font-bold"
|
|
68
|
+
data-test-number-flip
|
|
69
|
+
></div>
|
|
70
|
+
|
|
71
|
+
<FontAwesomeIcon
|
|
72
|
+
:icon="byPrefixAndName.far?.plus"
|
|
73
|
+
class="cursor-pointer"
|
|
74
|
+
data-test-increment-icon
|
|
75
|
+
@click="increment"
|
|
76
|
+
/>
|
|
77
|
+
</AppCard>
|
|
78
|
+
</template>
|
|
79
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { shallowMount } from '@vue/test-utils';
|
|
3
|
+
import AppStepper from '../AppStepper.vue';
|
|
4
|
+
|
|
5
|
+
import type { VueWrapper } from '@vue/test-utils';
|
|
6
|
+
|
|
7
|
+
function createWrapper(modelValue = 5): VueWrapper<InstanceType<typeof AppStepper>> {
|
|
8
|
+
return shallowMount(AppStepper, {
|
|
9
|
+
props: { modelValue },
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
describe('the AppStepper component', () => {
|
|
14
|
+
it('renders the number flip element', () => {
|
|
15
|
+
const wrapper = createWrapper();
|
|
16
|
+
|
|
17
|
+
const element = wrapper.find('[data-test-number-flip]');
|
|
18
|
+
expect(element.exists()).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should decrement when clicking the decrement icon', async () => {
|
|
22
|
+
expect.assertions(2);
|
|
23
|
+
|
|
24
|
+
const wrapper = createWrapper();
|
|
25
|
+
|
|
26
|
+
const icon = wrapper.find('[data-test-decrement-icon]');
|
|
27
|
+
expect(icon.exists()).toBe(true);
|
|
28
|
+
|
|
29
|
+
await icon.trigger('click');
|
|
30
|
+
|
|
31
|
+
expect(wrapper.emitted('update:modelValue')).toStrictEqual([[4]]);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should not decrement when value below 0', async () => {
|
|
35
|
+
expect.assertions(2);
|
|
36
|
+
|
|
37
|
+
const wrapper = createWrapper(0);
|
|
38
|
+
|
|
39
|
+
const icon = wrapper.find('[data-test-decrement-icon]');
|
|
40
|
+
expect(icon.exists()).toBe(true);
|
|
41
|
+
|
|
42
|
+
await icon.trigger('click');
|
|
43
|
+
|
|
44
|
+
expect(wrapper.emitted('update:modelValue')).toBeUndefined();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should increment when clicking the increment icon', async () => {
|
|
48
|
+
expect.assertions(2);
|
|
49
|
+
|
|
50
|
+
const wrapper = createWrapper();
|
|
51
|
+
|
|
52
|
+
const icon = wrapper.find('[data-test-increment-icon]');
|
|
53
|
+
expect(icon.exists()).toBe(true);
|
|
54
|
+
|
|
55
|
+
await icon.trigger('click');
|
|
56
|
+
|
|
57
|
+
expect(wrapper.emitted('update:modelValue')).toStrictEqual([[6]]);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flow-root">
|
|
3
|
+
<div class="overflow-x-auto">
|
|
4
|
+
<div class="inline-block min-w-full">
|
|
5
|
+
<div class="overflow-hidden">
|
|
6
|
+
<table class="w-full">
|
|
7
|
+
<slot></slot>
|
|
8
|
+
</table>
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<style scoped>
|
|
16
|
+
@reference "./../../../css/main.css";
|
|
17
|
+
|
|
18
|
+
:deep(table) {
|
|
19
|
+
@apply drop-shadow-card rounded-lg border border-solid border-zinc-200 border-spacing-0 border-separate;
|
|
20
|
+
|
|
21
|
+
th {
|
|
22
|
+
@apply bg-secondary text-white text-center font-bold whitespace-nowrap py-3 px-4 md:py-4 md:px-6
|
|
23
|
+
first:rounded-tl-lg first:text-left last:rounded-tr-lg;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
tbody {
|
|
27
|
+
@apply divide-y divide-zinc-200;
|
|
28
|
+
|
|
29
|
+
&:last-child tr:last-child td {
|
|
30
|
+
@apply first:rounded-bl-lg last:rounded-br-lg border-b-0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
tr {
|
|
34
|
+
td {
|
|
35
|
+
@apply bg-white py-3 px-4 border-b border-zinc-200 whitespace-nowrap md:px-6 md:py-4;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
</style>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import AppTimelineItem from './AppTimelineItem.vue';
|
|
3
|
+
|
|
4
|
+
import type { TimelineProps } from './index.d';
|
|
5
|
+
|
|
6
|
+
withDefaults(defineProps<TimelineProps>(), {
|
|
7
|
+
type: 'default',
|
|
8
|
+
});
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<div class="space-y-4">
|
|
13
|
+
<slot>
|
|
14
|
+
<AppTimelineItem
|
|
15
|
+
v-for="item in items"
|
|
16
|
+
:key="item.title"
|
|
17
|
+
:item="item"
|
|
18
|
+
:item-type="type"
|
|
19
|
+
/>
|
|
20
|
+
</slot>
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { computed } from 'vue';
|
|
3
|
+
import { AppBadge } from '~components';
|
|
4
|
+
import AppTimelineItemIcon from './AppTimelineItemIcon.vue';
|
|
5
|
+
import { domClassesPerType } from './index';
|
|
6
|
+
|
|
7
|
+
import type { TimelineItemProps, TimelineBadgeType } from './index.d';
|
|
8
|
+
|
|
9
|
+
const props = withDefaults(defineProps<TimelineItemProps>(), {
|
|
10
|
+
itemType: 'default',
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const dateFormat = computed(() => {
|
|
14
|
+
if (props.item.date && !props.item.time) {
|
|
15
|
+
return props.item.date.toLocaleDateString('nl-NL', {
|
|
16
|
+
month: 'short',
|
|
17
|
+
day: 'numeric',
|
|
18
|
+
hour: 'numeric',
|
|
19
|
+
minute: 'numeric',
|
|
20
|
+
timeStyle: undefined,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (props.item.time && !props.item.date) {
|
|
25
|
+
return props.item.time;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return [];
|
|
29
|
+
});
|
|
30
|
+
const badgeType = computed<TimelineBadgeType>(() => {
|
|
31
|
+
return props.item?.badge ?? 'default';
|
|
32
|
+
});
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<article
|
|
37
|
+
:class="{ 'after:hidden': item.last }"
|
|
38
|
+
class="relative flex w-full
|
|
39
|
+
before:absolute before:-top-5 before:left-4.5 before:h-5 before:w-0.5 before:bg-primary
|
|
40
|
+
after:absolute after:left-4.5 after:h-full after:w-0.5 after:bg-primary after:[min-height:60px]
|
|
41
|
+
first-of-type:before:hidden
|
|
42
|
+
last-of-type:from-primary last-of-type:to-white last-of-type:after:bg-transparent
|
|
43
|
+
last-of-type:after:bg-linear-to-b"
|
|
44
|
+
>
|
|
45
|
+
<div class="flex">
|
|
46
|
+
<slot
|
|
47
|
+
:value="item.icon"
|
|
48
|
+
name="icon"
|
|
49
|
+
>
|
|
50
|
+
<AppTimelineItemIcon :icon="item.icon" />
|
|
51
|
+
</slot>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div class="ml-4">
|
|
55
|
+
<header
|
|
56
|
+
:class="{ 'flex items-center gap-3': itemType === 'inline', 'mb-0!': item.last }"
|
|
57
|
+
>
|
|
58
|
+
<AppBadge
|
|
59
|
+
:class="{ 'mb-2': itemType === 'default' }"
|
|
60
|
+
:type="badgeType"
|
|
61
|
+
>
|
|
62
|
+
<slot
|
|
63
|
+
:value="dateFormat"
|
|
64
|
+
name="date"
|
|
65
|
+
>
|
|
66
|
+
<time>{{ dateFormat }} uur</time>
|
|
67
|
+
</slot>
|
|
68
|
+
</AppBadge>
|
|
69
|
+
|
|
70
|
+
<h3
|
|
71
|
+
:class="{ domClassesPerType: badgeType }"
|
|
72
|
+
class="font-semibold"
|
|
73
|
+
data-test-timeline-title
|
|
74
|
+
>
|
|
75
|
+
<slot
|
|
76
|
+
:value="item.title"
|
|
77
|
+
name="title"
|
|
78
|
+
>
|
|
79
|
+
<span :class="domClassesPerType[badgeType]">
|
|
80
|
+
{{ item.title }}
|
|
81
|
+
</span>
|
|
82
|
+
</slot>
|
|
83
|
+
</h3>
|
|
84
|
+
</header>
|
|
85
|
+
|
|
86
|
+
<p
|
|
87
|
+
:class="{ 'mt-4': itemType === 'inline' }"
|
|
88
|
+
class="text-base empty:mt-0"
|
|
89
|
+
data-test-timeline-description
|
|
90
|
+
>
|
|
91
|
+
<slot :value="item.description">
|
|
92
|
+
{{ item.description }}
|
|
93
|
+
</slot>
|
|
94
|
+
</p>
|
|
95
|
+
</div>
|
|
96
|
+
</article>
|
|
97
|
+
</template>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { computed } from 'vue';
|
|
3
|
+
import { CheckIcon } from '~icons';
|
|
4
|
+
|
|
5
|
+
import type { Component } from 'vue';
|
|
6
|
+
import type { TimelineItemIconProps } from './index.d';
|
|
7
|
+
|
|
8
|
+
const props = defineProps<TimelineItemIconProps>();
|
|
9
|
+
|
|
10
|
+
const timelineIcon = computed((): Component => {
|
|
11
|
+
return props.icon ?? CheckIcon;
|
|
12
|
+
});
|
|
13
|
+
const timelineIconClass = computed(() => {
|
|
14
|
+
return props.icon ? ['w-full'] : [
|
|
15
|
+
'bg-primary',
|
|
16
|
+
'w-6',
|
|
17
|
+
'h-6',
|
|
18
|
+
'text-white',
|
|
19
|
+
'stroke-3',
|
|
20
|
+
'p-1',
|
|
21
|
+
'z-10',
|
|
22
|
+
'mx-auto',
|
|
23
|
+
'flex',
|
|
24
|
+
'items-center',
|
|
25
|
+
'justify-center',
|
|
26
|
+
'rounded-full',
|
|
27
|
+
];
|
|
28
|
+
});
|
|
29
|
+
const wrapperClasses = computed(() => {
|
|
30
|
+
return props.icon ? [
|
|
31
|
+
'border-primary',
|
|
32
|
+
'border-2',
|
|
33
|
+
'-translate-y-2',
|
|
34
|
+
'h-10',
|
|
35
|
+
'w-10',
|
|
36
|
+
'rounded-full',
|
|
37
|
+
'flex',
|
|
38
|
+
'justify-center',
|
|
39
|
+
'items-center',
|
|
40
|
+
'p-1.5',
|
|
41
|
+
'z-50',
|
|
42
|
+
'bg-white',
|
|
43
|
+
] : ['w-10'];
|
|
44
|
+
});
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<template>
|
|
48
|
+
<div :class="wrapperClasses">
|
|
49
|
+
<Component
|
|
50
|
+
:is="timelineIcon"
|
|
51
|
+
:class="timelineIconClass"
|
|
52
|
+
class="relative"
|
|
53
|
+
/>
|
|
54
|
+
</div>
|
|
55
|
+
</template>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { HandThumbUpIcon } from '~icons';
|
|
2
|
+
|
|
3
|
+
import type { TimelineItem } from '../index.d';
|
|
4
|
+
|
|
5
|
+
export const timelineItemWithIcon: TimelineItem = {
|
|
6
|
+
title: 'title with icon',
|
|
7
|
+
description: 'description with icon',
|
|
8
|
+
date: new Date('2023-05-31 02:02:02'),
|
|
9
|
+
icon: HandThumbUpIcon,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const timelineItemWithDate: TimelineItem = {
|
|
13
|
+
title: 'title without icon',
|
|
14
|
+
description: 'description without icon',
|
|
15
|
+
date: new Date('2023-05-31 02:02:02'),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const timelineItemWithTime: TimelineItem = {
|
|
19
|
+
title: 'title without icon',
|
|
20
|
+
description: 'description without icon',
|
|
21
|
+
time: '12:00',
|
|
22
|
+
sort: 1200,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const timelineItems: TimelineItem[] = [
|
|
26
|
+
timelineItemWithIcon,
|
|
27
|
+
timelineItemWithDate,
|
|
28
|
+
timelineItemWithTime,
|
|
29
|
+
];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { shallowMount } from '@vue/test-utils';
|
|
3
|
+
import { CheckIcon, HandThumbUpIcon } from '~icons';
|
|
4
|
+
import AppTimelineItemIcon from '../AppTimelineItemIcon.vue';
|
|
5
|
+
|
|
6
|
+
import type { VueWrapper } from '@vue/test-utils';
|
|
7
|
+
import type { TimelineItemIconProps } from '../index.d';
|
|
8
|
+
|
|
9
|
+
function createWrapper(
|
|
10
|
+
icon: TimelineItemIconProps['icon'] = undefined,
|
|
11
|
+
): VueWrapper<InstanceType<typeof AppTimelineItemIcon>> {
|
|
12
|
+
return shallowMount(AppTimelineItemIcon, {
|
|
13
|
+
props: {
|
|
14
|
+
icon,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe('the AppTimelineItemIcon component', () => {
|
|
20
|
+
it('renders an default icon when prop is null', () => {
|
|
21
|
+
const wrapper = createWrapper();
|
|
22
|
+
|
|
23
|
+
const icon = wrapper.findComponent(CheckIcon);
|
|
24
|
+
expect(icon.exists()).toBe(true);
|
|
25
|
+
expect(icon.classes('bg-primary')).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('renders the icon when passed by prop', () => {
|
|
29
|
+
const wrapper = createWrapper(HandThumbUpIcon);
|
|
30
|
+
|
|
31
|
+
const icon = wrapper.findComponent(HandThumbUpIcon);
|
|
32
|
+
expect(icon.exists()).toBe(true);
|
|
33
|
+
expect(icon.classes('w-full')).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { shallowMount } from '@vue/test-utils';
|
|
3
|
+
import { AppBadge } from '~components';
|
|
4
|
+
import { timelineItemWithDate, timelineItemWithTime, timelineItemWithIcon } from '../__mocks__/timeline';
|
|
5
|
+
import AppTimelineItem from '../AppTimelineItem.vue';
|
|
6
|
+
import AppTimelineItemIcon from '../AppTimelineItemIcon.vue';
|
|
7
|
+
|
|
8
|
+
import type { VueWrapper, ComponentMountingOptions } from '@vue/test-utils';
|
|
9
|
+
import type { TimelineItemProps } from '../index.d';
|
|
10
|
+
|
|
11
|
+
function createWrapper(
|
|
12
|
+
item: TimelineItemProps['item'],
|
|
13
|
+
slots?: ComponentMountingOptions<typeof AppTimelineItem>['slots'],
|
|
14
|
+
): VueWrapper<InstanceType<typeof AppTimelineItem>> {
|
|
15
|
+
return shallowMount(AppTimelineItem, {
|
|
16
|
+
props: {
|
|
17
|
+
item,
|
|
18
|
+
},
|
|
19
|
+
slots,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe('the AppTimelineItem component', () => {
|
|
24
|
+
it('renders a badge with date by prop', () => {
|
|
25
|
+
const wrapper = createWrapper(timelineItemWithDate);
|
|
26
|
+
|
|
27
|
+
const badge = wrapper.findComponent(AppBadge);
|
|
28
|
+
expect(badge.exists()).toBe(true);
|
|
29
|
+
expect(badge.text()).toBe('31 mei, 02:02 uur');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('renders a badge with date by slot', () => {
|
|
33
|
+
const date = '<span>date</span>';
|
|
34
|
+
const wrapper = createWrapper(timelineItemWithDate, {
|
|
35
|
+
date,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const badge = wrapper.findComponent(AppBadge);
|
|
39
|
+
expect(badge.exists()).toBe(true);
|
|
40
|
+
expect(badge.element.innerHTML).toBe(date);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('renders a badge with time by prop', () => {
|
|
44
|
+
const wrapper = createWrapper(timelineItemWithTime);
|
|
45
|
+
|
|
46
|
+
const badge = wrapper.findComponent(AppBadge);
|
|
47
|
+
expect(badge.exists()).toBe(true);
|
|
48
|
+
expect(badge.text()).toBe('12:00 uur');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('renders a badge with time by slot', () => {
|
|
52
|
+
const time = '<time>12:00 uur</time>';
|
|
53
|
+
const wrapper = createWrapper(timelineItemWithTime, {
|
|
54
|
+
time,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const badge = wrapper.findComponent(AppBadge);
|
|
58
|
+
expect(badge.exists()).toBe(true);
|
|
59
|
+
expect(badge.element.innerHTML).toBe(time);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('renders a title by prop', () => {
|
|
63
|
+
const wrapper = createWrapper(timelineItemWithDate);
|
|
64
|
+
|
|
65
|
+
const title = wrapper.find('[data-test-timeline-title]');
|
|
66
|
+
expect(title.exists()).toBe(true);
|
|
67
|
+
expect(title.text()).toBe(timelineItemWithDate.title);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('renders a title by slot', () => {
|
|
71
|
+
const titleSlot = '<span>title</span>';
|
|
72
|
+
const wrapper = createWrapper(timelineItemWithDate, {
|
|
73
|
+
title: titleSlot,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const title = wrapper.find('[data-test-timeline-title]');
|
|
77
|
+
expect(title.exists()).toBe(true);
|
|
78
|
+
expect(title.element.innerHTML).toBe(titleSlot);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('renders a icon by prop', () => {
|
|
82
|
+
const wrapper = createWrapper(timelineItemWithIcon);
|
|
83
|
+
|
|
84
|
+
const timelineItemIcon = wrapper.findComponent(AppTimelineItemIcon);
|
|
85
|
+
expect(timelineItemIcon.exists()).toBe(true);
|
|
86
|
+
expect(timelineItemIcon.props('icon')).toBeTypeOf('function');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('renders a icon by slot', () => {
|
|
90
|
+
const icon = '<span data-test-icon="">icon</span>';
|
|
91
|
+
const wrapper = createWrapper(timelineItemWithIcon, {
|
|
92
|
+
icon,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const timelineItemIcon = wrapper.findComponent(AppTimelineItemIcon);
|
|
96
|
+
expect(timelineItemIcon.exists()).toBe(false);
|
|
97
|
+
|
|
98
|
+
const timelineItemIconSlot = wrapper.find('[data-test-icon]');
|
|
99
|
+
expect(timelineItemIconSlot.exists()).toBe(true);
|
|
100
|
+
expect(timelineItemIconSlot.html()).toBe(icon);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('renders a description by prop', () => {
|
|
104
|
+
const wrapper = createWrapper(timelineItemWithDate);
|
|
105
|
+
|
|
106
|
+
const description = wrapper.find('[data-test-timeline-description]');
|
|
107
|
+
expect(description.exists()).toBe(true);
|
|
108
|
+
expect(description.text()).toBe(timelineItemWithDate.description);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('renders a description by slot', () => {
|
|
112
|
+
const descriptionSlot = '<span>description</span>';
|
|
113
|
+
const wrapper = createWrapper(timelineItemWithDate, {
|
|
114
|
+
default: descriptionSlot,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const description = wrapper.find('[data-test-timeline-description]');
|
|
118
|
+
expect(description.exists()).toBe(true);
|
|
119
|
+
expect(description.element.innerHTML).toBe(descriptionSlot);
|
|
120
|
+
});
|
|
121
|
+
});
|