From 5fe28db539fcac5dfd6a529dc78338fe32d1d475 Mon Sep 17 00:00:00 2001 From: Nitwel Date: Thu, 1 Sep 2022 22:07:31 +0200 Subject: [PATCH] Add Components Package (#15094) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * move components without dependencies to packages * make every components use vue script setup * move components and utils from shared to @directus/components * fix imports * move over some more components * get rid of unnecessary isEmpty and notEmpty * move pagination * fix missing ! * move groupable components * move text-overflow and useElementSize * fix icons not being shown * add first unit tests * remove capitalizeFirst * simple cleanup * add css-var unit test * move over most other components * make every component use script setup * add some more unit tests * add more tests and burn v-switch to the ground. 🔥 * add checkbox tests * start with next test * add storybook * add more pages to storybook * add final stories * fix stories actions * improve action fix * cleaning props and adding tests * unit tests -.- * add some documentation to components * Add docs to each prop * clean storybook paths * add more unit tests * apply v-select fix * update lock file * small tweaks * move back to shared * fix imports * fix imports * cleaning * stories to typescript * Fix version number Co-authored-by: Rijk van Zanten --- .eslintignore | 1 + app/package.json | 2 +- app/src/components/register.ts | 106 +- app/src/components/transition/bounce/index.ts | 4 - app/src/components/transition/dialog/index.ts | 4 - app/src/components/transition/expand/index.ts | 4 - .../transition/expand/transition-expand.vue | 28 - app/src/components/transition/index.ts | 4 - .../v-checkbox-tree-checkbox.vue | 477 - .../v-checkbox-tree/v-checkbox-tree.vue | 164 - app/src/components/v-date-picker.vue | 263 +- app/src/components/v-detail.vue | 91 +- app/src/components/v-dialog.vue | 112 +- app/src/components/v-drawer.vue | 95 +- app/src/components/v-error.vue | 70 +- .../v-field-list/v-field-list-item.vue | 5 +- .../components/v-field-list/v-field-list.vue | 2 +- .../v-field-template/field-list-item.vue | 30 +- .../v-field-template/v-field-template.vue | 511 +- .../v-form/form-field-interface.vue | 88 +- .../components/v-form/form-field-label.vue | 88 +- app/src/components/v-form/form-field-menu.vue | 78 +- app/src/components/v-form/form-field.vue | 2 +- app/src/components/v-form/v-form.vue | 610 +- app/src/components/v-highlight.vue | 142 - app/src/components/v-hover.vue | 51 - app/src/components/v-icon/social-icon.vue | 28 - app/src/components/v-item-group.vue | 52 - app/src/components/v-item.vue | 42 - app/src/components/v-list-group.vue | 145 - app/src/components/v-menu.vue | 609 -- app/src/components/v-pagination.vue | 196 - app/src/components/v-select/v-select.vue | 454 - app/src/components/v-switch.vue | 155 - app/src/components/v-tab-item.vue | 23 - app/src/components/v-table/table-header.vue | 4 +- app/src/components/v-tabs-items.vue | 26 - app/src/components/v-tabs.vue | 73 - app/src/components/v-template-input.vue | 361 - app/src/components/v-text-overflow.vue | 55 - app/src/components/v-upload.vue | 376 +- app/src/displays/file/file.vue | 2 +- .../displays/translations/translations.vue | 4 +- .../select-multiple-checkbox.vue | 2 +- .../interfaces/select-radio/select-radio.vue | 2 +- .../interfaces/translations/translations.vue | 4 +- app/src/layouts/cards/cards.vue | 3 +- app/src/modules/insights/routes/dashboard.vue | 2 +- .../insights/routes/panel-configuration.vue | 1 - .../field-detail-advanced-display.vue | 1 - .../field-detail-advanced-interface.vue | 1 - .../modules/settings/routes/flows/flow.vue | 2 +- app/src/stores/collections.ts | 5 +- app/src/stores/fields.ts | 5 +- app/src/utils/capitalize-first.test.ts | 11 - app/src/utils/capitalize-first.ts | 15 - app/src/utils/get-js-type.ts | 28 +- app/src/utils/is-empty.test.ts | 41 - app/src/utils/is-empty.ts | 7 - app/src/utils/percentage.ts | 2 +- app/src/utils/translate-shortcut.ts | 6 +- .../private/components/comment-input.vue | 1 - .../views/private/components/search-input.vue | 2 +- .../private/components/sidebar-detail.vue | 2 +- app/src/views/private/private-view.vue | 2 +- packages/components/.gitignore | 1 + packages/components/.storybook/fix-actions.js | 22 + packages/components/.storybook/main.js | 15 + .../components/.storybook/preview-body.html | 2 + packages/components/.storybook/preview.js | 46 + packages/components/.storybook/register.js | 138 + packages/components/.storybook/styles.scss | 3 + packages/components/package.json | 77 + packages/components/shim.d.ts | 6 + packages/components/src/__utils__/focus.ts | 11 + packages/components/src/__utils__/router.ts | 9 + packages/components/src/__utils__/tooltip.ts | 7 + .../__snapshots__/V-tab.test.ts.snap | 3 + .../__snapshots__/v-avatar.test.ts.snap | 3 + .../__snapshots__/v-badge.test.ts.snap | 3 + .../__snapshots__/v-breadcrumb.test.ts.snap | 3 + .../__snapshots__/v-button.test.ts.snap | 9 + .../__snapshots__/v-card-actions.test.ts.snap | 3 + .../v-card-subtitle.test.ts.snap | 3 + .../__snapshots__/v-card-text.test.ts.snap | 3 + .../__snapshots__/v-card-title.test.ts.snap | 3 + .../__snapshots__/v-card.test.ts.snap | 3 + .../__snapshots__/v-checkbox.test.ts.snap | 9 + .../__snapshots__/v-chip.test.ts.snap | 3 + .../__snapshots__/v-divider.test.ts.snap | 7 + .../__snapshots__/v-fancy-select.test.ts.snap | 39 + .../__snapshots__/v-highlight.test.ts.snap | 10 + .../__snapshots__/v-hover.test.ts.snap | 3 + .../__snapshots__/v-icon-file.test.ts.snap | 7 + .../__snapshots__/v-info.test.ts.snap | 11 + .../__snapshots__/v-input.test.ts.snap | 15 + .../__snapshots__/v-menu.test.ts.snap | 9 + .../__snapshots__/v-notice.test.ts.snap | 7 + .../__snapshots__/v-overlay.test.ts.snap | 8 + .../__snapshots__/v-pagination.test.ts.snap | 18 + .../v-progress-circular.test.ts.snap | 8 + .../v-progress-linear.test.ts.snap | 7 + .../__snapshots__/v-radio.test.ts.snap | 7 + .../__snapshots__/v-sheet.test.ts.snap | 3 + .../v-skeleton-loader.test.ts.snap | 8 + .../__snapshots__/v-slider.test.ts.snap | 13 + .../__snapshots__/v-tabs.test.ts.snap | 3 + .../v-text-overflow.test.ts.snap | 3 + .../__snapshots__/v-textarea.test.ts.snap | 8 + .../v-workspace-tile.test.ts.snap | 18 + .../__snapshots__/v-workspace.test.ts.snap | 10 + .../src/components/transition/bounce.vue | 0 .../src/components/transition/dialog.vue | 0 .../components/transition/expand-methods.ts | 4 +- .../src/components/transition/expand.vue | 33 + .../src/components/v-avatar.test.ts | 36 + .../components}/src/components/v-avatar.vue | 38 +- .../components/src/components/v-badge.test.ts | 60 + .../components}/src/components/v-badge.vue | 60 +- .../src/components/v-breadcrumb.test.ts | 37 + .../src/components/v-breadcrumb.vue | 22 +- .../src/components/v-button.test.ts | 60 + .../components}/src/components/v-button.vue | 301 +- .../src/components/v-card-actions.test.ts | 16 + .../src/components/v-card-actions.vue | 0 .../src/components/v-card-subtitle.test.ts | 16 + .../src/components/v-card-subtitle.vue | 0 .../src/components/v-card-text.test.ts | 16 + .../src/components/v-card-text.vue | 0 .../src/components/v-card-title.test.ts | 16 + .../src/components/v-card-title.vue | 0 .../components/src/components/v-card.test.ts | 30 + .../components}/src/components/v-card.vue | 26 +- .../v-checkbox-tree.test.ts.snap | 3 + .../v-checkbox-tree/use-visible-children.ts | 13 +- .../v-checkbox-tree-checkbox.vue | 431 + .../v-checkbox-tree/v-checkbox-tree.test.ts | 91 + .../v-checkbox-tree/v-checkbox-tree.vue | 157 + .../src/components/v-checkbox.test.ts | 92 + .../components}/src/components/v-checkbox.vue | 176 +- .../components/src/components/v-chip.test.ts | 65 + .../components}/src/components/v-chip.vue | 118 +- .../src/components/v-divider.test.ts | 30 + .../components}/src/components/v-divider.vue | 30 +- .../src/components/v-emoji-picker.vue | 0 .../src/components/v-fancy-select.test.ts | 59 + .../src/components/v-fancy-select.vue | 8 +- .../src/components/v-highlight.test.ts | 29 + .../components/src/components/v-highlight.vue | 139 + .../components/src/components/v-hover.test.ts | 90 + .../components/src/components/v-hover.vue | 45 + .../src/components/v-icon-file.test.ts | 19 + .../src/components/v-icon-file.vue | 1 + .../v-icon/__snapshots__/v-icon.test.ts.snap | 3 + .../v-icon/custom-icons/bookmark_save.vue | 0 .../components/v-icon/custom-icons/box.vue | 0 .../v-icon/custom-icons/commit_node.vue | 0 .../v-icon/custom-icons/directus.vue | 0 .../v-icon/custom-icons/flip_horizontal.vue | 0 .../v-icon/custom-icons/flip_vertical.vue | 0 .../v-icon/custom-icons/folder_lock.vue | 0 .../v-icon/custom-icons/folder_move.vue | 0 .../components/v-icon/custom-icons/grid_1.vue | 0 .../components/v-icon/custom-icons/grid_2.vue | 0 .../components/v-icon/custom-icons/grid_3.vue | 0 .../components/v-icon/custom-icons/grid_4.vue | 0 .../components/v-icon/custom-icons/grid_5.vue | 0 .../components/v-icon/custom-icons/grid_6.vue | 0 .../components/v-icon/custom-icons/logout.vue | 0 .../v-icon/custom-icons/signal_wifi_1_bar.vue | 0 .../v-icon/custom-icons/signal_wifi_2_bar.vue | 0 .../v-icon/custom-icons/signal_wifi_3_bar.vue | 0 .../src/components/v-icon/social-icon.vue | 30 + .../src/components/v-icon/v-icon.test.ts | 51 + .../src/components/v-icon/v-icon.vue | 199 +- .../components/src/components/v-info.test.ts | 53 + .../components}/src/components/v-info.vue | 36 +- .../components/src/components/v-input.test.ts | 66 + .../components}/src/components/v-input.vue | 21 + .../src/components/v-item-group.vue | 47 + packages/components/src/components/v-item.vue | 36 + .../src/components/v-list-group.vue | 128 + .../src/components/v-list-item-content.vue | 0 .../src/components/v-list-item-hint.vue | 15 +- .../src/components/v-list-item-icon.vue | 15 +- .../src/components/v-list-item.vue | 226 +- .../components}/src/components/v-list.vue | 97 +- .../components/src/components/v-menu._test.ts | 36 + packages/components/src/components/v-menu.vue | 576 + .../src/components/v-notice.test.ts | 61 + .../components}/src/components/v-notice.vue | 67 +- .../src/components/v-overlay.test.ts | 39 + .../components}/src/components/v-overlay.vue | 44 +- .../src/components/v-pagination.test.ts | 65 + .../src/components/v-pagination.vue | 202 + .../components/v-progress-circular.test.ts | 40 + .../src/components/v-progress-circular.vue | 54 +- .../src/components/v-progress-linear.test.ts | 30 + .../src/components/v-progress-linear.vue | 85 +- .../components/src/components/v-radio.test.ts | 43 + .../components}/src/components/v-radio.vue | 89 +- .../__snapshots__/v-select.test.ts.snap | 3 + .../v-select/select-list-item-group.vue | 80 +- .../components/v-select/select-list-item.vue | 64 +- .../src/components/v-select/types.ts | 0 .../src/components/v-select/v-select.test.ts | 54 + .../src/components/v-select/v-select.vue | 418 + .../src/components/v-sheet.test.ts | 0 .../components}/src/components/v-sheet.vue | 0 .../src/components/v-skeleton-loader.test.ts | 30 + .../src/components/v-skeleton-loader.vue | 16 +- .../src/components/v-slider.test.ts | 50 + .../components}/src/components/v-slider.vue | 111 +- .../components/src/components/v-tab-item.vue | 20 + .../components}/src/components/v-tab.vue | 50 +- .../src/components/v-tabs-items.vue | 22 + .../components/src/components/v-tabs.test.ts | 22 + packages/components/src/components/v-tabs.vue | 70 + .../src/components/v-template-input.vue | 341 + .../src/components/v-text-overflow.test.ts | 39 + .../src/components/v-text-overflow.vue | 48 + .../src/components/v-textarea.test.ts | 69 + .../components}/src/components/v-textarea.vue | 117 +- .../src/components/v-workspace-tile.test.ts | 36 + .../src/components/v-workspace-tile.vue | 12 + .../src/components/v-workspace.test.ts | 66 + .../src/components/v-workspace.vue | 31 +- packages/components/src/shims.d.ts | 6 + packages/components/src/styles/no-wrap.scss | 5 + .../stories/transition-bounce.stories.ts | 23 + .../stories/transition-dialog.stories.ts | 23 + .../stories/transition-expand.stories.ts | 23 + .../components/stories/v-avatar.stories.ts | 23 + .../components/stories/v-badge.stories.ts | 24 + .../stories/v-breadcrumb.stories.ts | 38 + .../components/stories/v-button.stories.ts | 24 + packages/components/stories/v-card.stories.ts | 33 + .../stories/v-checkbox-tree.stories.ts | 45 + .../components/stories/v-checkbox.stories.ts | 24 + packages/components/stories/v-chip.stories.ts | 23 + .../components/stories/v-divider.stories.ts | 23 + .../stories/v-emoji-picker.stories.ts | 23 + .../stories/v-fancy-select.stories.ts | 40 + .../components/stories/v-highlight.stories.ts | 25 + .../components/stories/v-hover.stories.ts | 23 + .../components/stories/v-icon-file.stories.ts | 24 + packages/components/stories/v-icon.stories.ts | 24 + packages/components/stories/v-info.stories.ts | 25 + .../components/stories/v-input.stories.ts | 25 + .../stories/v-item-group.stories.ts | 24 + .../stories/v-list-group.stories.ts | 40 + .../components/stories/v-list-item.stories.ts | 26 + packages/components/stories/v-list.stories.ts | 30 + packages/components/stories/v-menu.stories.ts | 43 + .../components/stories/v-notice.stories.ts | 25 + .../components/stories/v-overlay.stories.ts | 24 + .../stories/v-pagination.stories.ts | 26 + .../stories/v-progress-circular.stories.ts | 24 + .../stories/v-progress-linear.stories.ts | 25 + .../components/stories/v-radio.stories.ts | 26 + .../components/stories/v-select.stories.ts | 37 + .../components/stories/v-sheet.stories.ts | 23 + .../stories/v-skeleton-loader.stories.ts | 28 + .../components/stories/v-slider.stories.ts | 31 + packages/components/stories/v-tabs.stories.ts | 43 + .../stories/v-template-input.stories.ts | 31 + .../stories/v-text-overflow.stories.ts | 24 + .../components/stories/v-textarea.stories.ts | 25 + .../stories/v-workspace-tile.stories.ts | 24 + .../components/stories/v-workspace.stories.ts | 40 + packages/components/stub/empty.d.ts | 1 + packages/components/tsconfig.json | 24 + packages/components/vite.config.js | 17 + packages/extensions-sdk/package.json | 1 + packages/shared/package.json | 1 + packages/shared/src/composables/index.ts | 4 + .../src/composables/use-custom-selection.ts | 0 .../src/composables/use-element-size.ts | 5 +- .../shared}/src/composables/use-groupable.ts | 13 +- packages/shared/src/composables/use-items.ts | 3 +- .../shared}/src/composables/use-size-class.ts | 12 +- pnpm-lock.yaml | 9500 ++++++++++++++++- 282 files changed, 17644 insertions(+), 6081 deletions(-) delete mode 100644 app/src/components/transition/bounce/index.ts delete mode 100644 app/src/components/transition/dialog/index.ts delete mode 100644 app/src/components/transition/expand/index.ts delete mode 100644 app/src/components/transition/expand/transition-expand.vue delete mode 100644 app/src/components/transition/index.ts delete mode 100644 app/src/components/v-checkbox-tree/v-checkbox-tree-checkbox.vue delete mode 100644 app/src/components/v-checkbox-tree/v-checkbox-tree.vue delete mode 100644 app/src/components/v-highlight.vue delete mode 100644 app/src/components/v-hover.vue delete mode 100644 app/src/components/v-icon/social-icon.vue delete mode 100644 app/src/components/v-item-group.vue delete mode 100644 app/src/components/v-item.vue delete mode 100644 app/src/components/v-list-group.vue delete mode 100644 app/src/components/v-menu.vue delete mode 100644 app/src/components/v-pagination.vue delete mode 100644 app/src/components/v-select/v-select.vue delete mode 100644 app/src/components/v-switch.vue delete mode 100644 app/src/components/v-tab-item.vue delete mode 100644 app/src/components/v-tabs-items.vue delete mode 100644 app/src/components/v-tabs.vue delete mode 100644 app/src/components/v-template-input.vue delete mode 100644 app/src/components/v-text-overflow.vue delete mode 100644 app/src/utils/capitalize-first.test.ts delete mode 100644 app/src/utils/capitalize-first.ts delete mode 100644 app/src/utils/is-empty.test.ts delete mode 100644 app/src/utils/is-empty.ts create mode 100644 packages/components/.gitignore create mode 100644 packages/components/.storybook/fix-actions.js create mode 100644 packages/components/.storybook/main.js create mode 100644 packages/components/.storybook/preview-body.html create mode 100644 packages/components/.storybook/preview.js create mode 100644 packages/components/.storybook/register.js create mode 100644 packages/components/.storybook/styles.scss create mode 100644 packages/components/package.json create mode 100644 packages/components/shim.d.ts create mode 100644 packages/components/src/__utils__/focus.ts create mode 100644 packages/components/src/__utils__/router.ts create mode 100644 packages/components/src/__utils__/tooltip.ts create mode 100644 packages/components/src/components/__snapshots__/V-tab.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-avatar.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-badge.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-breadcrumb.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-button.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-card-actions.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-card-subtitle.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-card-text.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-card-title.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-card.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-checkbox.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-chip.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-divider.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-fancy-select.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-highlight.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-hover.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-icon-file.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-info.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-input.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-menu.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-notice.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-overlay.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-pagination.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-progress-circular.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-progress-linear.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-radio.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-sheet.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-skeleton-loader.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-slider.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-tabs.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-text-overflow.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-textarea.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-workspace-tile.test.ts.snap create mode 100644 packages/components/src/components/__snapshots__/v-workspace.test.ts.snap rename app/src/components/transition/bounce/transition-bounce.vue => packages/components/src/components/transition/bounce.vue (100%) rename app/src/components/transition/dialog/transition-dialog.vue => packages/components/src/components/transition/dialog.vue (100%) rename app/src/components/transition/expand/transition-expand-methods.ts => packages/components/src/components/transition/expand-methods.ts (94%) create mode 100644 packages/components/src/components/transition/expand.vue create mode 100644 packages/components/src/components/v-avatar.test.ts rename {app => packages/components}/src/components/v-avatar.vue (64%) create mode 100644 packages/components/src/components/v-badge.test.ts rename {app => packages/components}/src/components/v-badge.vue (70%) create mode 100644 packages/components/src/components/v-breadcrumb.test.ts rename {app => packages/components}/src/components/v-breadcrumb.vue (87%) create mode 100644 packages/components/src/components/v-button.test.ts rename {app => packages/components}/src/components/v-button.vue (65%) create mode 100644 packages/components/src/components/v-card-actions.test.ts rename {app => packages/components}/src/components/v-card-actions.vue (100%) create mode 100644 packages/components/src/components/v-card-subtitle.test.ts rename {app => packages/components}/src/components/v-card-subtitle.vue (100%) create mode 100644 packages/components/src/components/v-card-text.test.ts rename {app => packages/components}/src/components/v-card-text.vue (100%) create mode 100644 packages/components/src/components/v-card-title.test.ts rename {app => packages/components}/src/components/v-card-title.vue (100%) create mode 100644 packages/components/src/components/v-card.test.ts rename {app => packages/components}/src/components/v-card.vue (82%) create mode 100644 packages/components/src/components/v-checkbox-tree/__snapshots__/v-checkbox-tree.test.ts.snap rename {app => packages/components}/src/components/v-checkbox-tree/use-visible-children.ts (79%) create mode 100644 packages/components/src/components/v-checkbox-tree/v-checkbox-tree-checkbox.vue create mode 100644 packages/components/src/components/v-checkbox-tree/v-checkbox-tree.test.ts create mode 100644 packages/components/src/components/v-checkbox-tree/v-checkbox-tree.vue create mode 100644 packages/components/src/components/v-checkbox.test.ts rename {app => packages/components}/src/components/v-checkbox.vue (55%) create mode 100644 packages/components/src/components/v-chip.test.ts rename {app => packages/components}/src/components/v-chip.vue (65%) create mode 100644 packages/components/src/components/v-divider.test.ts rename {app => packages/components}/src/components/v-divider.vue (82%) rename {app => packages/components}/src/components/v-emoji-picker.vue (100%) create mode 100644 packages/components/src/components/v-fancy-select.test.ts rename {app => packages/components}/src/components/v-fancy-select.vue (91%) create mode 100644 packages/components/src/components/v-highlight.test.ts create mode 100644 packages/components/src/components/v-highlight.vue create mode 100644 packages/components/src/components/v-hover.test.ts create mode 100644 packages/components/src/components/v-hover.vue create mode 100644 packages/components/src/components/v-icon-file.test.ts rename {app => packages/components}/src/components/v-icon-file.vue (96%) create mode 100644 packages/components/src/components/v-icon/__snapshots__/v-icon.test.ts.snap rename {app => packages/components}/src/components/v-icon/custom-icons/bookmark_save.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/box.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/commit_node.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/directus.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/flip_horizontal.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/flip_vertical.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/folder_lock.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/folder_move.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/grid_1.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/grid_2.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/grid_3.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/grid_4.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/grid_5.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/grid_6.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/logout.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/signal_wifi_1_bar.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/signal_wifi_2_bar.vue (100%) rename {app => packages/components}/src/components/v-icon/custom-icons/signal_wifi_3_bar.vue (100%) create mode 100644 packages/components/src/components/v-icon/social-icon.vue create mode 100644 packages/components/src/components/v-icon/v-icon.test.ts rename {app => packages/components}/src/components/v-icon/v-icon.vue (81%) create mode 100644 packages/components/src/components/v-info.test.ts rename {app => packages/components}/src/components/v-info.vue (75%) create mode 100644 packages/components/src/components/v-input.test.ts rename {app => packages/components}/src/components/v-input.vue (90%) create mode 100644 packages/components/src/components/v-item-group.vue create mode 100644 packages/components/src/components/v-item.vue create mode 100644 packages/components/src/components/v-list-group.vue rename {app => packages/components}/src/components/v-list-item-content.vue (100%) rename {app => packages/components}/src/components/v-list-item-hint.vue (83%) rename {app => packages/components}/src/components/v-list-item-icon.vue (85%) rename {app => packages/components}/src/components/v-list-item.vue (68%) rename {app => packages/components}/src/components/v-list.vue (51%) create mode 100644 packages/components/src/components/v-menu._test.ts create mode 100644 packages/components/src/components/v-menu.vue create mode 100644 packages/components/src/components/v-notice.test.ts rename {app => packages/components}/src/components/v-notice.vue (69%) create mode 100644 packages/components/src/components/v-overlay.test.ts rename {app => packages/components}/src/components/v-overlay.vue (69%) create mode 100644 packages/components/src/components/v-pagination.test.ts create mode 100644 packages/components/src/components/v-pagination.vue create mode 100644 packages/components/src/components/v-progress-circular.test.ts rename {app => packages/components}/src/components/v-progress-circular.vue (73%) create mode 100644 packages/components/src/components/v-progress-linear.test.ts rename {app => packages/components}/src/components/v-progress-linear.vue (66%) create mode 100644 packages/components/src/components/v-radio.test.ts rename {app => packages/components}/src/components/v-radio.vue (60%) create mode 100644 packages/components/src/components/v-select/__snapshots__/v-select.test.ts.snap rename {app => packages/components}/src/components/v-select/select-list-item-group.vue (57%) rename {app => packages/components}/src/components/v-select/select-list-item.vue (50%) rename {app => packages/components}/src/components/v-select/types.ts (100%) create mode 100644 packages/components/src/components/v-select/v-select.test.ts create mode 100644 packages/components/src/components/v-select/v-select.vue rename {app => packages/components}/src/components/v-sheet.test.ts (100%) rename {app => packages/components}/src/components/v-sheet.vue (100%) create mode 100644 packages/components/src/components/v-skeleton-loader.test.ts rename {app => packages/components}/src/components/v-skeleton-loader.vue (89%) create mode 100644 packages/components/src/components/v-slider.test.ts rename {app => packages/components}/src/components/v-slider.vue (77%) create mode 100644 packages/components/src/components/v-tab-item.vue rename {app => packages/components}/src/components/v-tab.vue (63%) create mode 100644 packages/components/src/components/v-tabs-items.vue create mode 100644 packages/components/src/components/v-tabs.test.ts create mode 100644 packages/components/src/components/v-tabs.vue create mode 100644 packages/components/src/components/v-template-input.vue create mode 100644 packages/components/src/components/v-text-overflow.test.ts create mode 100644 packages/components/src/components/v-text-overflow.vue create mode 100644 packages/components/src/components/v-textarea.test.ts rename {app => packages/components}/src/components/v-textarea.vue (62%) create mode 100644 packages/components/src/components/v-workspace-tile.test.ts rename {app => packages/components}/src/components/v-workspace-tile.vue (95%) create mode 100644 packages/components/src/components/v-workspace.test.ts rename {app => packages/components}/src/components/v-workspace.vue (89%) create mode 100644 packages/components/src/shims.d.ts create mode 100644 packages/components/src/styles/no-wrap.scss create mode 100644 packages/components/stories/transition-bounce.stories.ts create mode 100644 packages/components/stories/transition-dialog.stories.ts create mode 100644 packages/components/stories/transition-expand.stories.ts create mode 100644 packages/components/stories/v-avatar.stories.ts create mode 100644 packages/components/stories/v-badge.stories.ts create mode 100644 packages/components/stories/v-breadcrumb.stories.ts create mode 100644 packages/components/stories/v-button.stories.ts create mode 100644 packages/components/stories/v-card.stories.ts create mode 100644 packages/components/stories/v-checkbox-tree.stories.ts create mode 100644 packages/components/stories/v-checkbox.stories.ts create mode 100644 packages/components/stories/v-chip.stories.ts create mode 100644 packages/components/stories/v-divider.stories.ts create mode 100644 packages/components/stories/v-emoji-picker.stories.ts create mode 100644 packages/components/stories/v-fancy-select.stories.ts create mode 100644 packages/components/stories/v-highlight.stories.ts create mode 100644 packages/components/stories/v-hover.stories.ts create mode 100644 packages/components/stories/v-icon-file.stories.ts create mode 100644 packages/components/stories/v-icon.stories.ts create mode 100644 packages/components/stories/v-info.stories.ts create mode 100644 packages/components/stories/v-input.stories.ts create mode 100644 packages/components/stories/v-item-group.stories.ts create mode 100644 packages/components/stories/v-list-group.stories.ts create mode 100644 packages/components/stories/v-list-item.stories.ts create mode 100644 packages/components/stories/v-list.stories.ts create mode 100644 packages/components/stories/v-menu.stories.ts create mode 100644 packages/components/stories/v-notice.stories.ts create mode 100644 packages/components/stories/v-overlay.stories.ts create mode 100644 packages/components/stories/v-pagination.stories.ts create mode 100644 packages/components/stories/v-progress-circular.stories.ts create mode 100644 packages/components/stories/v-progress-linear.stories.ts create mode 100644 packages/components/stories/v-radio.stories.ts create mode 100644 packages/components/stories/v-select.stories.ts create mode 100644 packages/components/stories/v-sheet.stories.ts create mode 100644 packages/components/stories/v-skeleton-loader.stories.ts create mode 100644 packages/components/stories/v-slider.stories.ts create mode 100644 packages/components/stories/v-tabs.stories.ts create mode 100644 packages/components/stories/v-template-input.stories.ts create mode 100644 packages/components/stories/v-text-overflow.stories.ts create mode 100644 packages/components/stories/v-textarea.stories.ts create mode 100644 packages/components/stories/v-workspace-tile.stories.ts create mode 100644 packages/components/stories/v-workspace.stories.ts create mode 100644 packages/components/stub/empty.d.ts create mode 100644 packages/components/tsconfig.json create mode 100644 packages/components/vite.config.js rename {app => packages/shared}/src/composables/use-custom-selection.ts (100%) rename {app => packages/shared}/src/composables/use-element-size.ts (88%) rename {app => packages/shared}/src/composables/use-groupable.ts (95%) rename {app => packages/shared}/src/composables/use-size-class.ts (73%) diff --git a/.eslintignore b/.eslintignore index ae44c032fc..6204abbfee 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,4 @@ node_modules dist templates +stories \ No newline at end of file diff --git a/app/package.json b/app/package.json index 9bdf7a40b1..fe85fcdb7b 100644 --- a/app/package.json +++ b/app/package.json @@ -34,6 +34,7 @@ "@directus/extensions-sdk": "^9.14.1", "@directus/format-title": "^9.15.0", "@directus/shared": "workspace:*", + "@directus/components": "workspace:*", "@fortawesome/fontawesome-svg-core": "1.2.36", "@fortawesome/free-brands-svg-icons": "5.15.4", "@fullcalendar/core": "5.11.0", @@ -41,7 +42,6 @@ "@fullcalendar/interaction": "5.11.0", "@fullcalendar/list": "5.11.0", "@fullcalendar/timegrid": "5.11.0", - "@joeattardi/emoji-button": "^4.6.2", "@mapbox/mapbox-gl-draw": "1.3.0", "@mapbox/mapbox-gl-draw-static-mode": "1.0.1", "@mapbox/mapbox-gl-geocoder": "4.7.4", diff --git a/app/src/components/register.ts b/app/src/components/register.ts index 062faf8171..9daf9a85c0 100644 --- a/app/src/components/register.ts +++ b/app/src/components/register.ts @@ -8,70 +8,69 @@ import DocsWrapper from '@/views/private/components/docs-wrapper.vue'; import DrawerItem from '@/views/private/components/drawer-item.vue'; import DrawerBatch from '@/views/private/components/drawer-batch.vue'; import { App } from 'vue'; -import TransitionBounce from './transition/bounce'; -import TransitionDialog from './transition/dialog'; -import TransitionExpand from './transition/expand'; -import VAvatar from './v-avatar.vue'; -import VBadge from './v-badge.vue'; -import VBreadcrumb from './v-breadcrumb.vue'; -import VButton from './v-button.vue'; -import VCard from './v-card.vue'; -import VCardActions from './v-card-actions.vue'; -import VCardSubtitle from './v-card-subtitle.vue'; -import VCardText from './v-card-text.vue'; -import VCardTitle from './v-card-title.vue'; -import VCheckbox from './v-checkbox.vue'; -import VCheckboxTree from './v-checkbox-tree/v-checkbox-tree.vue'; -import VChip from './v-chip.vue'; +import TransitionBounce from '@directus/components/transition/bounce.vue'; +import TransitionDialog from '@directus/components/transition/dialog.vue'; +import TransitionExpand from '@directus/components/transition/expand.vue'; +import VAvatar from '@directus/components/v-avatar.vue'; +import VBadge from '@directus/components/v-badge.vue'; +import VBreadcrumb from '@directus/components/v-breadcrumb.vue'; +import VButton from '@directus/components/v-button.vue'; +import VCard from '@directus/components/v-card.vue'; +import VCardActions from '@directus/components/v-card-actions.vue'; +import VCardSubtitle from '@directus/components/v-card-subtitle.vue'; +import VCardText from '@directus/components/v-card-text.vue'; +import VCardTitle from '@directus/components/v-card-title.vue'; +import VCheckbox from '@directus/components/v-checkbox.vue'; +import VCheckboxTree from '@directus/components/v-checkbox-tree/v-checkbox-tree.vue'; +import VChip from '@directus/components/v-chip.vue'; import VDetail from './v-detail.vue'; import VDialog from './v-dialog.vue'; -import VDivider from './v-divider.vue'; +import VDivider from '@directus/components/v-divider.vue'; import VDrawer from './v-drawer.vue'; import VError from './v-error.vue'; -import VFancySelect from './v-fancy-select.vue'; +import VFancySelect from '@directus/components/v-fancy-select.vue'; import VFieldTemplate from './v-field-template/v-field-template.vue'; import VFieldList from './v-field-list/v-field-list.vue'; import VForm from './v-form/v-form.vue'; -import VHover from './v-hover.vue'; -import VHighlight from './v-highlight.vue'; -import VIcon from './v-icon/v-icon.vue'; +import VHover from '@directus/components/v-hover.vue'; +import VHighlight from '@directus/components/v-highlight.vue'; +import VIcon from '@directus/components/v-icon/v-icon.vue'; import VImage from './v-image.vue'; -import VIconFile from './v-icon-file.vue'; -import VInfo from './v-info.vue'; -import VInput from './v-input.vue'; -import VItemGroup from './v-item-group.vue'; -import VItem from './v-item.vue'; -import VList from './v-list.vue'; -import VListGroup from './v-list-group.vue'; -import VListItem from './v-list-item.vue'; -import VListItemContent from './v-list-item-content.vue'; -import VListItemHint from './v-list-item-hint.vue'; -import VListItemIcon from './v-list-item-icon.vue'; -import VMenu from './v-menu.vue'; -import VNotice from './v-notice.vue'; -import VOverlay from './v-overlay.vue'; -import VPagination from './v-pagination.vue'; -import VProgressCircular from './v-progress-circular.vue'; -import VProgressLinear from './v-progress-linear.vue'; -import VRadio from './v-radio.vue'; -import VSelect from './v-select/v-select.vue'; -import VSheet from './v-sheet.vue'; -import VSkeletonLoader from './v-skeleton-loader.vue'; -import VSlider from './v-slider.vue'; -import VSwitch from './v-switch.vue'; +import VIconFile from '@directus/components/v-icon-file.vue'; +import VInfo from '@directus/components/v-info.vue'; +import VInput from '@directus/components/v-input.vue'; +import VItemGroup from '@directus/components/v-item-group.vue'; +import VItem from '@directus/components/v-item.vue'; +import VList from '@directus/components/v-list.vue'; +import VListGroup from '@directus/components/v-list-group.vue'; +import VListItem from '@directus/components/v-list-item.vue'; +import VListItemContent from '@directus/components/v-list-item-content.vue'; +import VListItemHint from '@directus/components/v-list-item-hint.vue'; +import VListItemIcon from '@directus/components/v-list-item-icon.vue'; +import VMenu from '@directus/components/v-menu.vue'; +import VNotice from '@directus/components/v-notice.vue'; +import VOverlay from '@directus/components/v-overlay.vue'; +import VPagination from '@directus/components/v-pagination.vue'; +import VProgressCircular from '@directus/components/v-progress-circular.vue'; +import VProgressLinear from '@directus/components/v-progress-linear.vue'; +import VRadio from '@directus/components/v-radio.vue'; +import VSelect from '@directus/components/v-select/v-select.vue'; +import VSheet from '@directus/components/v-sheet.vue'; +import VSkeletonLoader from '@directus/components/v-skeleton-loader.vue'; +import VSlider from '@directus/components/v-slider.vue'; import VTable from './v-table/v-table.vue'; -import VTabs from './v-tabs.vue'; -import VTab from './v-tab.vue'; -import VTabItem from './v-tab-item.vue'; -import VTabsItems from './v-tabs-items.vue'; -import VTemplateInput from './v-template-input.vue'; -import VTextOverflow from './v-text-overflow.vue'; -import VTextarea from './v-textarea.vue'; +import VTabs from '@directus/components/v-tabs.vue'; +import VTab from '@directus/components/v-tab.vue'; +import VTabItem from '@directus/components/v-tab-item.vue'; +import VTabsItems from '@directus/components/v-tabs-items.vue'; +import VTemplateInput from '@directus/components/v-template-input.vue'; +import VTextOverflow from '@directus/components/v-text-overflow.vue'; +import VTextarea from '@directus/components/v-textarea.vue'; import VUpload from './v-upload.vue'; import VDatePicker from './v-date-picker.vue'; -import VEmojiPicker from './v-emoji-picker.vue'; -import VWorkspace from './v-workspace.vue'; -import VWorkspaceTile from './v-workspace-tile.vue'; +import VEmojiPicker from '@directus/components/v-emoji-picker.vue'; +import VWorkspace from '@directus/components/v-workspace.vue'; +import VWorkspaceTile from '@directus/components/v-workspace-tile.vue'; export function registerComponents(app: App): void { app.component('VAvatar', VAvatar); @@ -121,7 +120,6 @@ export function registerComponents(app: App): void { app.component('VSheet', VSheet); app.component('VSkeletonLoader', VSkeletonLoader); app.component('VSlider', VSlider); - app.component('VSwitch', VSwitch); app.component('VTabItem', VTabItem); app.component('VTab', VTab); app.component('VTable', VTable); diff --git a/app/src/components/transition/bounce/index.ts b/app/src/components/transition/bounce/index.ts deleted file mode 100644 index a39c8ebf63..0000000000 --- a/app/src/components/transition/bounce/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import TransitionBounce from './transition-bounce.vue'; - -export { TransitionBounce }; -export default TransitionBounce; diff --git a/app/src/components/transition/dialog/index.ts b/app/src/components/transition/dialog/index.ts deleted file mode 100644 index 88e6948cbc..0000000000 --- a/app/src/components/transition/dialog/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import TransitionDialog from './transition-dialog.vue'; - -export { TransitionDialog }; -export default TransitionDialog; diff --git a/app/src/components/transition/expand/index.ts b/app/src/components/transition/expand/index.ts deleted file mode 100644 index fb7fa3137d..0000000000 --- a/app/src/components/transition/expand/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import TransitionExpand from './transition-expand.vue'; - -export { TransitionExpand }; -export default TransitionExpand; diff --git a/app/src/components/transition/expand/transition-expand.vue b/app/src/components/transition/expand/transition-expand.vue deleted file mode 100644 index df55f30c3a..0000000000 --- a/app/src/components/transition/expand/transition-expand.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/app/src/components/transition/index.ts b/app/src/components/transition/index.ts deleted file mode 100644 index aaafc65f71..0000000000 --- a/app/src/components/transition/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import TransitionExpand from './expand'; - -export { TransitionExpand }; -export default { TransitionExpand }; diff --git a/app/src/components/v-checkbox-tree/v-checkbox-tree-checkbox.vue b/app/src/components/v-checkbox-tree/v-checkbox-tree-checkbox.vue deleted file mode 100644 index 1d7c08a16b..0000000000 --- a/app/src/components/v-checkbox-tree/v-checkbox-tree-checkbox.vue +++ /dev/null @@ -1,477 +0,0 @@ - - - - - diff --git a/app/src/components/v-checkbox-tree/v-checkbox-tree.vue b/app/src/components/v-checkbox-tree/v-checkbox-tree.vue deleted file mode 100644 index cc02fd2702..0000000000 --- a/app/src/components/v-checkbox-tree/v-checkbox-tree.vue +++ /dev/null @@ -1,164 +0,0 @@ - - - diff --git a/app/src/components/v-date-picker.vue b/app/src/components/v-date-picker.vue index cfa5453655..6c5d38ad66 100644 --- a/app/src/components/v-date-picker.vue +++ b/app/src/components/v-date-picker.vue @@ -4,151 +4,138 @@ - diff --git a/app/src/components/v-hover.vue b/app/src/components/v-hover.vue deleted file mode 100644 index 27a4a05a3a..0000000000 --- a/app/src/components/v-hover.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - diff --git a/app/src/components/v-icon/social-icon.vue b/app/src/components/v-icon/social-icon.vue deleted file mode 100644 index 616e23918d..0000000000 --- a/app/src/components/v-icon/social-icon.vue +++ /dev/null @@ -1,28 +0,0 @@ - diff --git a/app/src/components/v-item-group.vue b/app/src/components/v-item-group.vue deleted file mode 100644 index 99ba549dc0..0000000000 --- a/app/src/components/v-item-group.vue +++ /dev/null @@ -1,52 +0,0 @@ - - - diff --git a/app/src/components/v-item.vue b/app/src/components/v-item.vue deleted file mode 100644 index ccb0d2c6dc..0000000000 --- a/app/src/components/v-item.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - diff --git a/app/src/components/v-list-group.vue b/app/src/components/v-list-group.vue deleted file mode 100644 index 50a20df1ec..0000000000 --- a/app/src/components/v-list-group.vue +++ /dev/null @@ -1,145 +0,0 @@ - - - - - diff --git a/app/src/components/v-menu.vue b/app/src/components/v-menu.vue deleted file mode 100644 index b2e5932a8b..0000000000 --- a/app/src/components/v-menu.vue +++ /dev/null @@ -1,609 +0,0 @@ - - - - - - - diff --git a/app/src/components/v-pagination.vue b/app/src/components/v-pagination.vue deleted file mode 100644 index af1fbc078b..0000000000 --- a/app/src/components/v-pagination.vue +++ /dev/null @@ -1,196 +0,0 @@ - - - - - diff --git a/app/src/components/v-select/v-select.vue b/app/src/components/v-select/v-select.vue deleted file mode 100644 index 62955e5f00..0000000000 --- a/app/src/components/v-select/v-select.vue +++ /dev/null @@ -1,454 +0,0 @@ - - - - - diff --git a/app/src/components/v-switch.vue b/app/src/components/v-switch.vue deleted file mode 100644 index 0956d534c6..0000000000 --- a/app/src/components/v-switch.vue +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - - diff --git a/app/src/components/v-tab-item.vue b/app/src/components/v-tab-item.vue deleted file mode 100644 index 00e3f8cf56..0000000000 --- a/app/src/components/v-tab-item.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/app/src/components/v-table/table-header.vue b/app/src/components/v-table/table-header.vue index 98da0077a7..1de5079c12 100644 --- a/app/src/components/v-table/table-header.vue +++ b/app/src/components/v-table/table-header.vue @@ -111,11 +111,11 @@ import { useSync } from '@directus/shared/composables'; interface Props { headers: Header[]; sort: Sort; + reordering: boolean; + allowHeaderReorder: boolean; showSelect?: ShowSelect; showResize?: boolean; showManualSort?: boolean; - allowHeaderReorder: boolean; - reordering: boolean; someItemsSelected?: boolean; allItemsSelected?: boolean; fixed?: boolean; diff --git a/app/src/components/v-tabs-items.vue b/app/src/components/v-tabs-items.vue deleted file mode 100644 index fcfc2a2ff4..0000000000 --- a/app/src/components/v-tabs-items.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/app/src/components/v-tabs.vue b/app/src/components/v-tabs.vue deleted file mode 100644 index ef0e251ba3..0000000000 --- a/app/src/components/v-tabs.vue +++ /dev/null @@ -1,73 +0,0 @@ - - - - - diff --git a/app/src/components/v-template-input.vue b/app/src/components/v-template-input.vue deleted file mode 100644 index e8e1c0ab49..0000000000 --- a/app/src/components/v-template-input.vue +++ /dev/null @@ -1,361 +0,0 @@ - - - - - diff --git a/app/src/components/v-text-overflow.vue b/app/src/components/v-text-overflow.vue deleted file mode 100644 index 9ef01499b2..0000000000 --- a/app/src/components/v-text-overflow.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - - - diff --git a/app/src/components/v-upload.vue b/app/src/components/v-upload.vue index de738201f3..fe35b64d88 100644 --- a/app/src/components/v-upload.vue +++ b/app/src/components/v-upload.vue @@ -84,9 +84,9 @@ - diff --git a/packages/components/src/components/v-checkbox-tree/v-checkbox-tree.test.ts b/packages/components/src/components/v-checkbox-tree/v-checkbox-tree.test.ts new file mode 100644 index 0000000000..955186e005 --- /dev/null +++ b/packages/components/src/components/v-checkbox-tree/v-checkbox-tree.test.ts @@ -0,0 +1,91 @@ +import { test, expect, beforeEach } from 'vitest'; +import { mount } from '@vue/test-utils'; + +import VCheckboxTree from './v-checkbox-tree.vue'; +import VCheckboxTreeCheckbox from './v-checkbox-tree-checkbox.vue'; +import VListItem from '../v-list-item.vue'; +import VListItemIcon from '../v-list-item-icon.vue'; +import VList from '../v-list.vue'; +import VListGroup from '../v-list-group.vue'; +import VCheckbox from '../v-checkbox.vue'; +import { h } from 'vue'; +import { GlobalMountOptions } from '@vue/test-utils/dist/types'; +import { Router } from 'vue-router'; +import { generateRouter } from '@/__utils__/router'; + +let router: Router; +let global: GlobalMountOptions; + +beforeEach(async () => { + router = generateRouter([ + { + path: '/', + component: h('div', 'test'), + }, + { + path: '/test', + component: h('div', 'empty'), + }, + ]); + router.push('/'); + await router.isReady(); + + global = { + components: { + VCheckboxTreeCheckbox, + VListItem, + VListItemIcon, + VListGroup, + VCheckbox, + VList, + }, + stubs: ['v-highlight', 'v-icon'], + plugins: [router], + }; +}); + +test('Mount component', () => { + expect(VCheckboxTree).toBeTruthy(); + + const wrapper = mount(VCheckboxTree, { + global, + }); + + expect(wrapper.html()).toMatchSnapshot(); +}); + +// test('Choices prop', async () => { +// const wrapper = mount(VCheckboxTree, { +// props: { +// modelValue: ['p1', 'c1'], +// showSelectionOnly: true, +// choices: [ +// { +// text: 'Parent 1', +// value: 'p1', +// }, +// { +// text: 'Parent 2', +// value: 'p2', +// children: [ +// { +// text: 'Child 1', +// value: 'c1', +// }, +// ], +// }, +// ], +// }, +// global, +// }); + +// expect(wrapper.getComponent('.v-checkbox:nth-child(1)').classes()).toContain('checked'); +// expect(wrapper.getComponent('.v-checkbox:nth-child(1)').props().label).toBe('Parent 1'); +// expect(wrapper.getComponent('.v-checkbox:nth-child(2)').classes()).not.toContain('checked'); + +// await wrapper.get('.v-checkbox:nth-child(2)').trigger('click'); + +// const child1 = wrapper.get('.v-checkbox:nth-child(2)').find('.v-checkbox'); +// expect(child1.exists()).toBeTruthy(); +// expect(child1.props().label).toBe('Child 1'); +// }); diff --git a/packages/components/src/components/v-checkbox-tree/v-checkbox-tree.vue b/packages/components/src/components/v-checkbox-tree/v-checkbox-tree.vue new file mode 100644 index 0000000000..511f6a66ad --- /dev/null +++ b/packages/components/src/components/v-checkbox-tree/v-checkbox-tree.vue @@ -0,0 +1,157 @@ + + + + + diff --git a/packages/components/src/components/v-checkbox.test.ts b/packages/components/src/components/v-checkbox.test.ts new file mode 100644 index 0000000000..3ba99eeb2a --- /dev/null +++ b/packages/components/src/components/v-checkbox.test.ts @@ -0,0 +1,92 @@ +import { test, expect } from 'vitest'; +import { mount } from '@vue/test-utils'; + +import VCheckbox from './v-checkbox.vue'; +import { h } from 'vue'; +import { GlobalMountOptions } from '@vue/test-utils/dist/types'; + +const global: GlobalMountOptions = { + stubs: ['v-icon'], +}; + +test('Mount component', () => { + expect(VCheckbox).toBeTruthy(); + + const wrapper = mount(VCheckbox, { + slots: { + default: h('div', 'Hi'), + }, + global, + }); + + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('modelValue prop', async () => { + const wrapper = mount(VCheckbox, { + props: { + modelValue: true, + }, + global, + }); + + expect(wrapper.attributes()['aria-pressed']).toBe('true'); + + await wrapper.get('.checkbox').trigger('click'); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual([false]); +}); + +test('value prop', async () => { + const wrapper = mount(VCheckbox, { + props: { + value: 'test', + modelValue: ['test', 'test2'], + }, + global, + }); + + expect(wrapper.attributes()['aria-pressed']).toBe('true'); + + await wrapper.get('.checkbox').trigger('click'); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual([['test2']]); +}); + +test('label prop', async () => { + const wrapper = mount(VCheckbox, { + props: { + label: 'my label', + }, + global, + }); + + expect(wrapper.html()).toContain('my label'); +}); + +test('customValue prop', async () => { + const wrapper = mount(VCheckbox, { + props: { + customValue: true, + }, + global, + }); + + wrapper.find('input').setValue('my custom value'); + + expect(wrapper.emitted()['update:value'][0]).toEqual(['my custom value']); +}); + +test('disabled prop', async () => { + const wrapper = mount(VCheckbox, { + props: { + disabled: true, + modelValue: true, + }, + global, + }); + + await wrapper.get('.checkbox').trigger('click'); + + expect(wrapper.emitted()['update:modelValue']).not.toBeDefined(); +}); diff --git a/app/src/components/v-checkbox.vue b/packages/components/src/components/v-checkbox.vue similarity index 55% rename from app/src/components/v-checkbox.vue rename to packages/components/src/components/v-checkbox.vue index bac53fd88f..ce1bc55a35 100644 --- a/app/src/components/v-checkbox.vue +++ b/packages/components/src/components/v-checkbox.vue @@ -19,101 +19,93 @@ - diff --git a/packages/components/src/components/v-hover.test.ts b/packages/components/src/components/v-hover.test.ts new file mode 100644 index 0000000000..5f802d4bf6 --- /dev/null +++ b/packages/components/src/components/v-hover.test.ts @@ -0,0 +1,90 @@ +import { test, expect, vi } from 'vitest'; +import { mount } from '@vue/test-utils'; + +import VHover from './v-hover.vue'; + +test('Mount component', () => { + expect(VHover).toBeTruthy(); + + const wrapper = mount(VHover, { + slots: { + default: ({ hover }) => (hover ? 'shown' : 'hidden'), + }, + }); + + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('hover interaction', async () => { + const wrapper = mount(VHover, { + slots: { + default: ({ hover }) => (hover ? 'shown' : 'hidden'), + }, + }); + + vi.useFakeTimers(); + + expect(wrapper.text()).toBe('hidden'); + await wrapper.trigger('mouseenter'); + await vi.advanceTimersByTime(1); + expect(wrapper.text()).toBe('shown'); + await wrapper.trigger('mouseleave'); + await vi.advanceTimersByTime(1); + expect(wrapper.text()).toBe('hidden'); +}); + +test('openDelay prop', async () => { + const wrapper = mount(VHover, { + props: { + openDelay: 20, + }, + slots: { + default: ({ hover }) => (hover ? 'shown' : 'hidden'), + }, + }); + + vi.useFakeTimers(); + + expect(wrapper.text()).toBe('hidden'); + await wrapper.trigger('mouseenter'); + await vi.advanceTimersByTime(10); + expect(wrapper.text()).toBe('hidden'); + await vi.advanceTimersByTime(10); + expect(wrapper.text()).toBe('shown'); +}); + +test('closeDelay prop', async () => { + const wrapper = mount(VHover, { + props: { + closeDelay: 20, + }, + slots: { + default: ({ hover }) => (hover ? 'shown' : 'hidden'), + }, + }); + + vi.useFakeTimers(); + + expect(wrapper.text()).toBe('hidden'); + await wrapper.trigger('mouseenter'); + await vi.advanceTimersByTime(1); + expect(wrapper.text()).toBe('shown'); + await wrapper.trigger('mouseleave'); + await vi.advanceTimersByTime(10); + expect(wrapper.text()).toBe('shown'); + await vi.advanceTimersByTime(10); + expect(wrapper.text()).toBe('hidden'); +}); + +test('tag prop', async () => { + const wrapper = mount(VHover, { + props: { + tag: 'span', + }, + slots: { + default: ({ hover }) => (hover ? 'shown' : 'hidden'), + }, + }); + + expect(wrapper.element.tagName).toBe('SPAN'); +}); diff --git a/packages/components/src/components/v-hover.vue b/packages/components/src/components/v-hover.vue new file mode 100644 index 0000000000..2dbede5183 --- /dev/null +++ b/packages/components/src/components/v-hover.vue @@ -0,0 +1,45 @@ + + + diff --git a/packages/components/src/components/v-icon-file.test.ts b/packages/components/src/components/v-icon-file.test.ts new file mode 100644 index 0000000000..59cfda857c --- /dev/null +++ b/packages/components/src/components/v-icon-file.test.ts @@ -0,0 +1,19 @@ +import { test, expect } from 'vitest'; +import { mount } from '@vue/test-utils'; + +import VIconFile from './v-icon-file.vue'; + +test('Mount component', () => { + expect(VIconFile).toBeTruthy(); + + const wrapper = mount(VIconFile, { + props: { + ext: 'png', + }, + global: { + stubs: ['v-icon'], + }, + }); + + expect(wrapper.html()).toMatchSnapshot(); +}); diff --git a/app/src/components/v-icon-file.vue b/packages/components/src/components/v-icon-file.vue similarity index 96% rename from app/src/components/v-icon-file.vue rename to packages/components/src/components/v-icon-file.vue index 77b8710c09..1cbf00e703 100644 --- a/app/src/components/v-icon-file.vue +++ b/packages/components/src/components/v-icon-file.vue @@ -7,6 +7,7 @@ diff --git a/packages/components/src/components/v-icon/v-icon.test.ts b/packages/components/src/components/v-icon/v-icon.test.ts new file mode 100644 index 0000000000..b1c4c354e5 --- /dev/null +++ b/packages/components/src/components/v-icon/v-icon.test.ts @@ -0,0 +1,51 @@ +import { test, expect } from 'vitest'; +import { mount } from '@vue/test-utils'; + +import VIcon from './v-icon.vue'; + +test('Mount component', () => { + expect(VIcon).toBeTruthy(); + + const wrapper = mount(VIcon, { + props: { + name: 'close', + }, + }); + + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('style props', () => { + const props = ['x-small', 'small', 'large', 'x-large', 'left', 'right']; + + for (const prop of props) { + const wrapper = mount(VIcon, { + props: { + name: 'close', + [prop]: true, + }, + }); + + expect(wrapper.classes()).toContain(prop); + } +}); + +test('custom icon', () => { + const wrapper = mount(VIcon, { + props: { + name: 'directus', + }, + }); + + expect(wrapper.find('svg').exists()).toBeTruthy(); +}); + +test('social icon', () => { + const wrapper = mount(VIcon, { + props: { + name: 'docker', + }, + }); + + expect(wrapper.find('svg').exists()).toBeTruthy(); +}); diff --git a/app/src/components/v-icon/v-icon.vue b/packages/components/src/components/v-icon/v-icon.vue similarity index 81% rename from app/src/components/v-icon/v-icon.vue rename to packages/components/src/components/v-icon/v-icon.vue index ab812eb0d3..8729dde16a 100644 --- a/app/src/components/v-icon/v-icon.vue +++ b/packages/components/src/components/v-icon/v-icon.vue @@ -2,22 +2,24 @@ - + - diff --git a/app/src/components/v-list-item-content.vue b/packages/components/src/components/v-list-item-content.vue similarity index 100% rename from app/src/components/v-list-item-content.vue rename to packages/components/src/components/v-list-item-content.vue diff --git a/app/src/components/v-list-item-hint.vue b/packages/components/src/components/v-list-item-hint.vue similarity index 83% rename from app/src/components/v-list-item-hint.vue rename to packages/components/src/components/v-list-item-hint.vue index e1a30dad41..853f6c79c0 100644 --- a/app/src/components/v-list-item-hint.vue +++ b/packages/components/src/components/v-list-item-hint.vue @@ -4,16 +4,13 @@ - diff --git a/app/src/components/v-list-item-icon.vue b/packages/components/src/components/v-list-item-icon.vue similarity index 85% rename from app/src/components/v-list-item-icon.vue rename to packages/components/src/components/v-list-item-icon.vue index 0fa3038998..8d73280968 100644 --- a/app/src/components/v-list-item-icon.vue +++ b/packages/components/src/components/v-list-item-icon.vue @@ -4,16 +4,13 @@ - diff --git a/app/src/components/v-list-item.vue b/packages/components/src/components/v-list-item.vue similarity index 68% rename from app/src/components/v-list-item.vue rename to packages/components/src/components/v-list-item.vue index 75fd80055b..78cfa20256 100644 --- a/app/src/components/v-list-item.vue +++ b/packages/components/src/components/v-list-item.vue @@ -20,132 +20,116 @@ - + + diff --git a/packages/components/src/components/v-notice.test.ts b/packages/components/src/components/v-notice.test.ts new file mode 100644 index 0000000000..9945ec9711 --- /dev/null +++ b/packages/components/src/components/v-notice.test.ts @@ -0,0 +1,61 @@ +import { test, expect } from 'vitest'; +import { mount } from '@vue/test-utils'; + +import VNotice from './v-notice.vue'; +import { GlobalMountOptions } from '@vue/test-utils/dist/types'; +import { zip } from 'lodash'; + +const global: GlobalMountOptions = { + stubs: ['v-icon'], +}; + +test('Mount component', () => { + expect(VNotice).toBeTruthy(); + + const wrapper = mount(VNotice, { + global, + }); + + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('type prop', async () => { + const types = ['normal', 'info', 'success', 'warning', 'danger']; + + for (const type of types) { + const wrapper = mount(VNotice, { + props: { + type, + }, + global, + }); + + expect(wrapper.classes()).toContain(type); + } +}); + +test('icon prop', async () => { + const types = ['normal', 'info', 'success', 'warning', 'danger']; + const icons = ['info', 'info', 'check_circle', 'warning', 'error']; + + for (const [type, icon] of zip(types, icons)) { + const wrapper = mount(VNotice, { + props: { + type, + icon: true, + }, + global, + }); + + expect(wrapper.getComponent('v-icon-stub').attributes().name).toBe(icon); + } + + const wrapper = mount(VNotice, { + props: { + icon: 'my-icon', + }, + global, + }); + + expect(wrapper.getComponent('v-icon-stub').attributes().name).toBe('my-icon'); +}); diff --git a/app/src/components/v-notice.vue b/packages/components/src/components/v-notice.vue similarity index 69% rename from app/src/components/v-notice.vue rename to packages/components/src/components/v-notice.vue index cbb411bdd1..5baa7ce5de 100644 --- a/app/src/components/v-notice.vue +++ b/packages/components/src/components/v-notice.vue @@ -5,45 +5,40 @@ - diff --git a/packages/components/src/components/v-overlay.test.ts b/packages/components/src/components/v-overlay.test.ts new file mode 100644 index 0000000000..18aedad129 --- /dev/null +++ b/packages/components/src/components/v-overlay.test.ts @@ -0,0 +1,39 @@ +import { test, expect } from 'vitest'; +import { mount } from '@vue/test-utils'; + +import VOverlay from './v-overlay.vue'; + +test('Mount component', () => { + expect(VOverlay).toBeTruthy(); + + const wrapper = mount(VOverlay, { + props: { + active: true, + }, + slots: { + default: 'Slot Content', + }, + }); + + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('absolute prop', () => { + const wrapper = mount(VOverlay, { + props: { + absolute: true, + }, + }); + + expect(wrapper.classes()).toContain('absolute'); +}); + +test('clickable prop', () => { + const wrapper = mount(VOverlay, { + props: { + clickable: true, + }, + }); + + expect(wrapper.classes()).toContain('has-click'); +}); diff --git a/app/src/components/v-overlay.vue b/packages/components/src/components/v-overlay.vue similarity index 69% rename from app/src/components/v-overlay.vue rename to packages/components/src/components/v-overlay.vue index e47cfae707..6f26cf8168 100644 --- a/app/src/components/v-overlay.vue +++ b/packages/components/src/components/v-overlay.vue @@ -5,33 +5,27 @@ - diff --git a/packages/components/src/components/v-progress-circular.test.ts b/packages/components/src/components/v-progress-circular.test.ts new file mode 100644 index 0000000000..1d48d23685 --- /dev/null +++ b/packages/components/src/components/v-progress-circular.test.ts @@ -0,0 +1,40 @@ +import { test, expect } from 'vitest'; +import { mount } from '@vue/test-utils'; + +import VProgressCircular from './v-progress-circular.vue'; + +test('Mount component', () => { + expect(VProgressCircular).toBeTruthy(); + + const wrapper = mount(VProgressCircular, { + slots: { + default: 'Slot Content', + }, + }); + + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('size props', () => { + const props = ['x-small', 'small', 'large', 'x-large']; + + for (const prop of props) { + const wrapper = mount(VProgressCircular, { + props: { + [prop]: true, + }, + }); + + expect(wrapper.classes()).toContain(prop); + } +}); + +test('indeterminate prop', () => { + const wrapper = mount(VProgressCircular, { + props: { + indeterminate: true, + }, + }); + + expect(wrapper.get('.circle').classes()).toContain('indeterminate'); +}); diff --git a/app/src/components/v-progress-circular.vue b/packages/components/src/components/v-progress-circular.vue similarity index 73% rename from app/src/components/v-progress-circular.vue rename to packages/components/src/components/v-progress-circular.vue index dfeb21dc7f..9fefb43778 100644 --- a/app/src/components/v-progress-circular.vue +++ b/packages/components/src/components/v-progress-circular.vue @@ -4,7 +4,7 @@ class="circle" viewBox="0 0 30 30" :class="{ indeterminate }" - @animationiteration="$emit('animationiteration')" + @animationiteration="$emit('animationiteration', $event)" > - diff --git a/app/src/components/v-sheet.test.ts b/packages/components/src/components/v-sheet.test.ts similarity index 100% rename from app/src/components/v-sheet.test.ts rename to packages/components/src/components/v-sheet.test.ts diff --git a/app/src/components/v-sheet.vue b/packages/components/src/components/v-sheet.vue similarity index 100% rename from app/src/components/v-sheet.vue rename to packages/components/src/components/v-sheet.vue diff --git a/packages/components/src/components/v-skeleton-loader.test.ts b/packages/components/src/components/v-skeleton-loader.test.ts new file mode 100644 index 0000000000..db8f9b2c96 --- /dev/null +++ b/packages/components/src/components/v-skeleton-loader.test.ts @@ -0,0 +1,30 @@ +import { test, expect } from 'vitest'; +import { mount } from '@vue/test-utils'; + +import VSkeletonLoader from './v-skeleton-loader.vue'; + +test('Mount component', () => { + expect(VSkeletonLoader).toBeTruthy(); + + const wrapper = mount(VSkeletonLoader, { + props: { + type: 'list-item-icon', + }, + }); + + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('type prop', () => { + const types = ['input', 'input-tall', 'block-list-item', 'block-list-item-dense', 'text', 'list-item-icon']; + + for (const type of types) { + const wrapper = mount(VSkeletonLoader, { + props: { + type, + }, + }); + + expect(wrapper.classes()).toContain(type); + } +}); diff --git a/app/src/components/v-skeleton-loader.vue b/packages/components/src/components/v-skeleton-loader.vue similarity index 89% rename from app/src/components/v-skeleton-loader.vue rename to packages/components/src/components/v-skeleton-loader.vue index 5ed09fcaea..529bdf3c8e 100644 --- a/app/src/components/v-skeleton-loader.vue +++ b/packages/components/src/components/v-skeleton-loader.vue @@ -7,16 +7,14 @@ - diff --git a/packages/components/src/components/v-slider.test.ts b/packages/components/src/components/v-slider.test.ts new file mode 100644 index 0000000000..c5448875e4 --- /dev/null +++ b/packages/components/src/components/v-slider.test.ts @@ -0,0 +1,50 @@ +import { test, expect } from 'vitest'; +import { mount } from '@vue/test-utils'; + +import VSlider from './v-slider.vue'; + +test('Mount component', () => { + expect(VSlider).toBeTruthy(); + + const wrapper = mount(VSlider); + + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('modelValue prop', async () => { + const wrapper = mount(VSlider, { + props: { + modelValue: 20, + }, + }); + + expect(wrapper.get('input').element.value).toBe(20); + + await wrapper.get('input').setValue(30); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual([30]); +}); + +test('min prop', async () => { + const wrapper = mount(VSlider, { + props: { + min: 40, + }, + }); + + await wrapper.get('input').setValue(30); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual([40]); +}); + +test('max prop', async () => { + const wrapper = mount(VSlider, { + props: { + max: 40, + }, + }); + + await wrapper.get('input').setValue(50); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual([40]); +}); diff --git a/app/src/components/v-slider.vue b/packages/components/src/components/v-slider.vue similarity index 77% rename from app/src/components/v-slider.vue rename to packages/components/src/components/v-slider.vue index 3e28e8f1b4..23e6cf7f35 100644 --- a/app/src/components/v-slider.vue +++ b/packages/components/src/components/v-slider.vue @@ -32,71 +32,58 @@ - diff --git a/packages/components/src/components/v-template-input.vue b/packages/components/src/components/v-template-input.vue new file mode 100644 index 0000000000..12d57bd9dc --- /dev/null +++ b/packages/components/src/components/v-template-input.vue @@ -0,0 +1,341 @@ + + + + + diff --git a/packages/components/src/components/v-text-overflow.test.ts b/packages/components/src/components/v-text-overflow.test.ts new file mode 100644 index 0000000000..efcf0567ed --- /dev/null +++ b/packages/components/src/components/v-text-overflow.test.ts @@ -0,0 +1,39 @@ +import { test, expect } from 'vitest'; +import { mount } from '@vue/test-utils'; + +import VTextOverflow from './v-text-overflow.vue'; +import { GlobalMountOptions } from '@vue/test-utils/dist/types'; +import { Tooltip } from '@/__utils__/tooltip'; + +const global: GlobalMountOptions = { + stubs: ['v-icon', 'v-highlight'], + directives: { + Tooltip, + }, +}; + +test('Mount component', () => { + expect(VTextOverflow).toBeTruthy(); + + const wrapper = mount(VTextOverflow, { + props: { + text: 'My text', + }, + global, + }); + + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('highlight prop', () => { + const wrapper = mount(VTextOverflow, { + props: { + text: 'my Text', + highlight: 'text', + }, + global, + }); + + expect(wrapper.getComponent({ name: 'v-highlight' }).attributes().query).toBe('text'); + expect(wrapper.getComponent({ name: 'v-highlight' }).attributes().text).toBe('my Text'); +}); diff --git a/packages/components/src/components/v-text-overflow.vue b/packages/components/src/components/v-text-overflow.vue new file mode 100644 index 0000000000..8ada361427 --- /dev/null +++ b/packages/components/src/components/v-text-overflow.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/packages/components/src/components/v-textarea.test.ts b/packages/components/src/components/v-textarea.test.ts new file mode 100644 index 0000000000..24866a60a7 --- /dev/null +++ b/packages/components/src/components/v-textarea.test.ts @@ -0,0 +1,69 @@ +import { test, expect } from 'vitest'; +import { mount } from '@vue/test-utils'; + +import VTextarea from './v-textarea.vue'; +import { Focus } from '@/__utils__/focus'; +import { GlobalMountOptions } from '@vue/test-utils/dist/types'; + +const global: GlobalMountOptions = { + directives: { + focus: Focus, + }, +}; + +test('Mount component', () => { + expect(VTextarea).toBeTruthy(); + + const wrapper = mount(VTextarea, { + props: { + modelValue: `This is the first paragraph. +This is the second one.`, + }, + global, + }); + + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('stlye props', async () => { + const types = ['expand-on-focus', 'full-width', 'disabled']; + + for (const type of types) { + const wrapper = mount(VTextarea, { + props: { + [type]: true, + }, + global, + }); + + expect(wrapper.classes()).toContain(type); + } +}); + +test('trim prop', async () => { + const wrapper = mount(VTextarea, { + props: { + modelValue: ' This is an info ', + trim: true, + }, + global, + }); + + await wrapper.get('textarea').trigger('blur'); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['This is an info']); +}); + +test('nullable prop', async () => { + const wrapper = mount(VTextarea, { + props: { + modelValue: ' This is an info ', + nullable: true, + }, + global, + }); + + await wrapper.get('textarea').setValue(''); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual([null]); +}); diff --git a/app/src/components/v-textarea.vue b/packages/components/src/components/v-textarea.vue similarity index 62% rename from app/src/components/v-textarea.vue rename to packages/components/src/components/v-textarea.vue index 7a33a08e87..588e590026 100644 --- a/app/src/components/v-textarea.vue +++ b/packages/components/src/components/v-textarea.vue @@ -21,72 +21,63 @@ -