├── .editorconfig ├── .eslintignore ├── .eslintrc.cjs ├── .github └── workflows │ ├── chromatic.yml │ ├── deployment.yml │ ├── npm-publish.yml │ ├── preview.yml │ ├── static.yml │ └── tests.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .storybook ├── main.ts ├── manager-head.html ├── manager.js ├── preview.ts ├── shopwareTheme.js └── test-runner.ts ├── CHANGELOG.md ├── README.md ├── __snapshots__ ├── interaction-tests-directives-tooltip--visual-test-render-icon-snap.png ├── interaction-tests-directives-tooltip--visual-test-render-tooltip-in-wide-snap.png ├── interaction-tests-directives-tooltip--visual-test-render-tooltip-snap.png ├── interaction-tests-feedback-indicator-sw-banner--visual-test-banner-attention-snap.png ├── interaction-tests-feedback-indicator-sw-banner--visual-test-banner-critical-snap.png ├── interaction-tests-feedback-indicator-sw-banner--visual-test-banner-info-snap.png ├── interaction-tests-feedback-indicator-sw-banner--visual-test-banner-inherited-snap.png ├── interaction-tests-feedback-indicator-sw-banner--visual-test-banner-neutral-snap.png ├── interaction-tests-feedback-indicator-sw-banner--visual-test-banner-positive-snap.png ├── interaction-tests-feedback-indicator-sw-banner--visual-test-close-banner-box-snap.png ├── interaction-tests-feedback-indicator-sw-banner--visual-test-render-without-icon-snap.png ├── interaction-tests-feedback-indicator-sw-loader--visual-test-loader-at-50-snap.png ├── interaction-tests-feedback-indicator-sw-loader--visual-test-loader-at-7-snap.png ├── interaction-tests-feedback-indicator-sw-loader--visual-test-loader-at-90-snap.png ├── interaction-tests-feedback-indicator-sw-progress-bar--visual-test-error-snap.png ├── interaction-tests-feedback-indicator-sw-progress-bar--visual-test-label-snap.png ├── interaction-tests-feedback-indicator-sw-progress-bar--visual-test-no-label-snap.png ├── interaction-tests-feedback-indicator-sw-progress-bar--visual-test-progress-label-kilobyte-snap.png ├── interaction-tests-feedback-indicator-sw-progress-bar--visual-test-progress-label-percentage-snap.png ├── interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-1-snap.png ├── interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-10-snap.png ├── interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-100-of-400-snap.png ├── interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-100-snap.png ├── interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-400-of-400-snap.png ├── interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-50-snap.png ├── interaction-tests-feedback-indicator-sw-skeleton-bar--visual-test-skeleton-bar-snap.png ├── interaction-tests-form-sw-button--visual-test-action-variant-snap.png ├── interaction-tests-form-sw-button--visual-test-block-button-snap.png ├── interaction-tests-form-sw-button--visual-test-critical-ghost-variant-snap.png ├── interaction-tests-form-sw-button--visual-test-critical-variant-snap.png ├── interaction-tests-form-sw-button--visual-test-default-size-snap.png ├── interaction-tests-form-sw-button--visual-test-disabled-button-snap.png ├── interaction-tests-form-sw-button--visual-test-ghost-variant-snap.png ├── interaction-tests-form-sw-button--visual-test-is-loading-snap.png ├── interaction-tests-form-sw-button--visual-test-large-size-snap.png ├── interaction-tests-form-sw-button--visual-test-primary-variant-snap.png ├── interaction-tests-form-sw-button--visual-test-secondary-ghost-variant-snap.png ├── interaction-tests-form-sw-button--visual-test-secondary-variant-snap.png ├── interaction-tests-form-sw-button--visual-test-small-size-snap.png ├── interaction-tests-form-sw-button--visual-test-square-button-snap.png ├── interaction-tests-form-sw-checkbox--visual-test-bordered-error-snap.png ├── interaction-tests-form-sw-checkbox--visual-test-bordered-snap.png ├── interaction-tests-form-sw-checkbox--visual-test-checkable-snap.png ├── interaction-tests-form-sw-checkbox--visual-test-disabled-snap.png ├── interaction-tests-form-sw-checkbox--visual-test-error-snap.png ├── interaction-tests-form-sw-checkbox--visual-test-help-text-snap.png ├── interaction-tests-form-sw-checkbox--visual-test-inherited-snap.png ├── interaction-tests-form-sw-checkbox--visual-test-partial-checked-snap.png ├── interaction-tests-form-sw-checkbox--visual-test-uncheckable-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-color-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-label-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-hex-alpha-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-hex-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-hsl-alpha-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-hsl-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-rgb-alpha-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-rgb-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-colorpicker-clear-value-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-colorpicker-disabled-color-labels-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-colorpicker-disabled-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-colorpicker-readonly-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-colorpicker-with-help-text-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-colorpicker-without-alpha-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-open-colorpicker-snap.png ├── interaction-tests-form-sw-colorpicker--visual-test-render-colorpicker-snap.png ├── interaction-tests-form-sw-datepicker--visual-test-date-input-value-snap.png ├── interaction-tests-form-sw-datepicker--visual-test-date-time-input-value-snap.png ├── interaction-tests-form-sw-datepicker--visual-test-datepicker-should-open-snap.png ├── interaction-tests-form-sw-datepicker--visual-test-time-input-value-snap.png ├── interaction-tests-form-sw-email-field--visual-test-disabled-snap.png ├── interaction-tests-form-sw-email-field--visual-test-error-snap.png ├── interaction-tests-form-sw-email-field--visual-test-hint-snap.png ├── interaction-tests-form-sw-email-field--visual-test-prefix-snap.png ├── interaction-tests-form-sw-email-field--visual-test-suffix-snap.png ├── interaction-tests-form-sw-email-field--visual-test-validation-error-snap.png ├── interaction-tests-form-sw-external-link--visual-test-render-external-link-disabled-snap.png ├── interaction-tests-form-sw-external-link--visual-test-render-external-link-small-snap.png ├── interaction-tests-form-sw-external-link--visual-test-render-external-link-snap.png ├── interaction-tests-form-sw-number-field--visual-test-disabled-snap.png ├── interaction-tests-form-sw-number-field--visual-test-error-snap.png ├── interaction-tests-form-sw-number-field--visual-test-hint-snap.png ├── interaction-tests-form-sw-number-field--visual-test-inheritance-snap.png ├── interaction-tests-form-sw-number-field--visual-test-prefix-snap.png ├── interaction-tests-form-sw-number-field--visual-test-suffix-snap.png ├── interaction-tests-form-sw-password-field--visual-test-disabled-snap.png ├── interaction-tests-form-sw-password-field--visual-test-error-snap.png ├── interaction-tests-form-sw-password-field--visual-test-hint-snap.png ├── interaction-tests-form-sw-password-field--visual-test-prefix-snap.png ├── interaction-tests-form-sw-password-field--visual-test-show-password-snap.png ├── interaction-tests-form-sw-password-field--visual-test-suffix-snap.png ├── interaction-tests-form-sw-select--visual-test-disabled-snap.png ├── interaction-tests-form-sw-select--visual-test-ensure-single-selection-without-load-more-snap.png ├── interaction-tests-form-sw-select--visual-test-error-snap.png ├── interaction-tests-form-sw-select--visual-test-highlight-search-term-snap.png ├── interaction-tests-form-sw-select--visual-test-hint-snap.png ├── interaction-tests-form-sw-select--visual-test-inherited-snap.png ├── interaction-tests-form-sw-select--visual-test-multi-select-snap.png ├── interaction-tests-form-sw-select--visual-test-prefix-snap.png ├── interaction-tests-form-sw-select--visual-test-single-selection-snap.png ├── interaction-tests-form-sw-select--visual-test-suffix-snap.png ├── interaction-tests-form-sw-switch--visual-test-bordered-error-snap.png ├── interaction-tests-form-sw-switch--visual-test-bordered-snap.png ├── interaction-tests-form-sw-switch--visual-test-checkable-snap.png ├── interaction-tests-form-sw-switch--visual-test-disabled-snap.png ├── interaction-tests-form-sw-switch--visual-test-error-snap.png ├── interaction-tests-form-sw-switch--visual-test-help-text-snap.png ├── interaction-tests-form-sw-switch--visual-test-inherited-snap.png ├── interaction-tests-form-sw-switch--visual-test-uncheckable-snap.png ├── interaction-tests-form-sw-text-field--visual-test-disabled-snap.png ├── interaction-tests-form-sw-text-field--visual-test-error-snap.png ├── interaction-tests-form-sw-text-field--visual-test-hint-snap.png ├── interaction-tests-form-sw-text-field--visual-test-inheritance-active-snap.png ├── interaction-tests-form-sw-text-field--visual-test-inheritance-snap.png ├── interaction-tests-form-sw-text-field--visual-test-prefix-snap.png ├── interaction-tests-form-sw-text-field--visual-test-suffix-snap.png ├── interaction-tests-form-sw-textarea--visual-test-disabled-snap.png ├── interaction-tests-form-sw-textarea--visual-test-error-snap.png ├── interaction-tests-form-sw-textarea--visual-test-hint-snap.png ├── interaction-tests-form-sw-url-field--visual-test-http-switch-snap.png ├── interaction-tests-form-sw-url-field--visual-test-input-value-snap.png ├── interaction-tests-icons-media-sw-icon--visual-test-render-calendar-icon-snap.png ├── interaction-tests-icons-media-sw-icon--visual-test-render-icon-in-hidden-snap.png ├── interaction-tests-icons-media-sw-icon--visual-test-render-icon-in-yellow-snap.png ├── interaction-tests-icons-media-sw-icon--visual-test-render-icon-snap.png ├── interaction-tests-layout-sw-card--visual-test-extended-page-snap.png ├── interaction-tests-layout-sw-card--visual-test-extended-page-with-hero-snap.png ├── interaction-tests-layout-sw-card--visual-test-extended-page-with-opened-context-actions-snap.png ├── interaction-tests-layout-sw-card--visual-test-extended-page-without-avatar-snap.png ├── interaction-tests-layout-sw-card--visual-test-extended-page-without-context-actions-snap.png ├── interaction-tests-layout-sw-card--visual-test-extended-page-without-footer-snap.png ├── interaction-tests-layout-sw-card--visual-test-extended-page-without-header-right-snap.png ├── interaction-tests-layout-sw-card--visual-test-extended-page-without-tabs-snap.png ├── interaction-tests-layout-sw-card--visual-test-extended-page-without-toolbar-snap.png ├── interaction-tests-layout-sw-card--visual-test-minimal-page-snap.png ├── interaction-tests-navigation-sw-search--visual-test-default-size-disabled-snap.png ├── interaction-tests-navigation-sw-search--visual-test-default-size-snap.png ├── interaction-tests-navigation-sw-search--visual-test-small-size-disabled-snap.png ├── interaction-tests-navigation-sw-search--visual-test-small-size-snap.png ├── interaction-tests-navigation-sw-segmented-control--visual-test-render-segmented-control-snap.png ├── interaction-tests-navigation-sw-segmented-control--visual-test-render-segmented-control-with-context-snap.png ├── interaction-tests-navigation-sw-segmented-control--visual-test-render-segmented-control-with-popover-base-snap.png ├── interaction-tests-navigation-sw-segmented-control--visual-test-render-segmented-control-with-popover-second-level-snap.png ├── interaction-tests-navigation-sw-tabs--visual-test-render-context-tab-with-active-item-snap.png ├── interaction-tests-navigation-sw-tabs--visual-test-render-context-tab-with-error-snap.png ├── interaction-tests-navigation-sw-tabs--visual-test-render-many-tab-items-snap.png ├── interaction-tests-navigation-sw-tabs--visual-test-render-tabs-full-width-snap.png ├── interaction-tests-navigation-sw-tabs--visual-test-render-tabs-snap.png ├── interaction-tests-navigation-sw-tabs--visual-test-render-tabs-vertical-snap.png ├── interaction-tests-navigation-sw-tabs--visual-test-render-tabs-with-context-menu-badge-snap.png ├── interaction-tests-navigation-sw-tabs--visual-test-render-tabs-with-error-snap.png ├── interaction-tests-navigation-sw-tabs--visual-test-render-tabs-with-info-badge-snap.png ├── interaction-tests-navigation-sw-tabs--visual-test-render-tabs-with-positive-badge-snap.png ├── interaction-tests-overlay-sw-popover--visual-test-render-child-view-snap.png ├── interaction-tests-overlay-sw-popover--visual-test-render-popover-snap.png ├── interaction-tests-overlay-sw-popover--visual-test-render-popover-trigger-snap.png ├── interaction-tests-overlay-sw-popover--visual-test-render-without-float-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-add-column-indicator-popover-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-add-column-indicator-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-add-new-column-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-blank-table-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-column-drag-bar-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-column-drag-drop-ordering-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-column-settings-popover-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-column-settings-popover-without-sort-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-data-sorting-in-column-settings-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-emit-reload-event-on-clicking-reload-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-enable-row-numbering-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-hide-outlines-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-hide-stripes-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-open-column-settings-menu-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-open-settings-menu-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-render-empty-state-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-render-full-table-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-render-skeleton-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-render-table-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-render-table-sticky-header-snap.png ├── interaction-tests-table-and-list-sw-data-table--visual-test-render-table-with-scroll-shadows-snap.png └── interaction-tests-table-and-list-sw-data-table--visual-test-render-table-without-card-header-snap.png ├── adr └── sw-data-table.md ├── env.d.ts ├── index.html ├── package-lock.json ├── package.json ├── playwright.config.ts ├── public ├── favicon.ico ├── shopware_docs_horizontal_dark.svg └── shopware_docs_horizontal_white.svg ├── redirect-page └── index.html ├── src ├── _internal │ ├── story-helper.ts │ └── test-helper.ts ├── components │ ├── _internal │ │ ├── sw-floating-ui │ │ │ ├── sw-floating-ui.spec.ts │ │ │ └── sw-floating-ui.vue │ │ ├── sw-highlight-text.vue │ │ ├── sw-ignore-class.vue │ │ ├── sw-label.vue │ │ ├── sw-popover-deprecated │ │ │ └── sw-popover-deprecated.vue │ │ ├── sw-priority-plus-navigation.vue │ │ └── sw-smooth-reflow.vue │ ├── assets │ │ └── scss │ │ │ ├── all.scss │ │ │ ├── directives │ │ │ ├── dragdrop.scss │ │ │ └── tooltip.scss │ │ │ ├── fonts │ │ │ └── inter.font.scss │ │ │ ├── global.scss │ │ │ ├── mixins.scss │ │ │ ├── typography.scss │ │ │ └── variables.scss │ ├── context-menu │ │ ├── sw-context-button │ │ │ └── sw-context-button.vue │ │ ├── sw-context-menu-divider │ │ │ └── sw-context-menu-divider.vue │ │ └── sw-context-menu-item │ │ │ └── sw-context-menu-item.vue │ ├── feedback-indicator │ │ ├── sw-banner │ │ │ ├── sw-banner.interactive.stories.ts │ │ │ ├── sw-banner.stories.ts │ │ │ └── sw-banner.vue │ │ ├── sw-color-badge │ │ │ └── sw-color-badge.vue │ │ ├── sw-loader │ │ │ ├── sw-loader.interactive.stories.ts │ │ │ ├── sw-loader.stories.ts │ │ │ └── sw-loader.vue │ │ ├── sw-progress-bar │ │ │ ├── sw-progress-bar.interactive.stories.ts │ │ │ ├── sw-progress-bar.stories.ts │ │ │ └── sw-progress-bar.vue │ │ └── sw-skeleton-bar │ │ │ ├── sw-skeleton-bar.interactive.stories.ts │ │ │ ├── sw-skeleton-bar.stories.ts │ │ │ └── sw-skeleton-bar.vue │ ├── form │ │ ├── _internal │ │ │ ├── sw-base-field │ │ │ │ ├── arg-types.ts │ │ │ │ └── sw-base-field.vue │ │ │ ├── sw-field-copyable │ │ │ │ └── sw-field-copyable.vue │ │ │ ├── sw-field-error │ │ │ │ └── sw-field-error.vue │ │ │ ├── sw-inheritance-switch │ │ │ │ └── sw-inheritance-switch.vue │ │ │ └── sw-select-base │ │ │ │ ├── _internal │ │ │ │ ├── sw-select-result-list.vue │ │ │ │ ├── sw-select-result.vue │ │ │ │ └── sw-select-selection-list.vue │ │ │ │ └── sw-select-base.vue │ │ ├── sw-button │ │ │ ├── sw-button.interactive.stories.ts │ │ │ ├── sw-button.stories.ts │ │ │ └── sw-button.vue │ │ ├── sw-checkbox │ │ │ ├── sw-checkbox.interactive.stories.ts │ │ │ ├── sw-checkbox.stories.ts │ │ │ └── sw-checkbox.vue │ │ ├── sw-colorpicker │ │ │ ├── sw-colorpicker.interactive.stories.ts │ │ │ ├── sw-colorpicker.stories.ts │ │ │ └── sw-colorpicker.vue │ │ ├── sw-datepicker │ │ │ ├── sw-datepicker.interactive.stories.ts │ │ │ ├── sw-datepicker.spec.ts │ │ │ ├── sw-datepicker.stories.ts │ │ │ └── sw-datepicker.vue │ │ ├── sw-email-field │ │ │ ├── sw-email-field.interactive.stories.ts │ │ │ ├── sw-email-field.stories.ts │ │ │ └── sw-email-field.vue │ │ ├── sw-external-link │ │ │ ├── sw-external-link.interactive.stories.ts │ │ │ ├── sw-external-link.stories.ts │ │ │ └── sw-external-link.vue │ │ ├── sw-help-text │ │ │ └── sw-help-text.vue │ │ ├── sw-number-field │ │ │ ├── sw-number-field.interactive.stories.ts │ │ │ ├── sw-number-field.stories.ts │ │ │ └── sw-number-field.vue │ │ ├── sw-password-field │ │ │ ├── sw-password-field.interactive.stories.ts │ │ │ ├── sw-password-field.stories.ts │ │ │ └── sw-password-field.vue │ │ ├── sw-select │ │ │ ├── sw-select.interactive.stories.ts │ │ │ ├── sw-select.spec.ts │ │ │ ├── sw-select.stories.ts │ │ │ └── sw-select.vue │ │ ├── sw-switch │ │ │ ├── sw-switch.interactive.stories.ts │ │ │ ├── sw-switch.stories.ts │ │ │ └── sw-switch.vue │ │ ├── sw-text-field │ │ │ ├── sw-text-field.interactive.stories.ts │ │ │ ├── sw-text-field.stories.ts │ │ │ └── sw-text-field.vue │ │ ├── sw-textarea │ │ │ ├── sw-textarea.interactive.stories.ts │ │ │ ├── sw-textarea.stories.ts │ │ │ └── sw-textarea.vue │ │ └── sw-url-field │ │ │ ├── sw-url-field.interactive.stories.ts │ │ │ ├── sw-url-field.stories.ts │ │ │ └── sw-url-field.vue │ ├── icons-media │ │ ├── sw-avatar │ │ │ └── sw-avatar.vue │ │ └── sw-icon │ │ │ ├── sw-icon.interactive.stories.ts │ │ │ ├── sw-icon.stories.ts │ │ │ └── sw-icon.vue │ ├── layout │ │ ├── sw-card │ │ │ ├── sw-card.interactive.stories.ts │ │ │ ├── sw-card.stories.ts │ │ │ └── sw-card.vue │ │ └── sw-empty-state │ │ │ └── sw-empty-state.vue │ ├── navigation │ │ ├── sw-search │ │ │ ├── sw-search.interactive.stories.ts │ │ │ ├── sw-search.stories.ts │ │ │ └── sw-search.vue │ │ ├── sw-segmented-control │ │ │ ├── sw-segmented-control.interactive.stories.ts │ │ │ ├── sw-segmented-control.stories.ts │ │ │ └── sw-segmented-control.vue │ │ └── sw-tabs │ │ │ ├── sw-tabs.interactive.stories.ts │ │ │ ├── sw-tabs.stories.ts │ │ │ ├── sw-tabs.vue │ │ │ └── sw.tabs.spec.ts │ ├── overlay │ │ ├── sw-popover-item-result │ │ │ ├── sw-popover-item-result.spec.ts │ │ │ └── sw-popover-item-result.vue │ │ ├── sw-popover-item │ │ │ ├── sw-popover-item.spec.ts │ │ │ └── sw-popover-item.vue │ │ └── sw-popover │ │ │ ├── sw-popover.interfaces.ts │ │ │ ├── sw-popover.spec.ts │ │ │ ├── sw-popover.stories.interactive.stories.ts │ │ │ ├── sw-popover.stories.ts │ │ │ └── sw-popover.vue │ └── table-and-list │ │ ├── sw-data-table │ │ ├── composables │ │ │ ├── useScrollPossibilitiesClasses.spec.ts │ │ │ └── useScrollPossibilitiesClasses.ts │ │ ├── renderer │ │ │ ├── sw-data-table-badge-renderer.vue │ │ │ ├── sw-data-table-number-renderer.vue │ │ │ ├── sw-data-table-price-renderer.vue │ │ │ └── sw-data-table-text-renderer.vue │ │ ├── sub-components │ │ │ └── sw-data-table-settings │ │ │ │ ├── sw-data-table-settings.spec.ts │ │ │ │ └── sw-data-table-settings.vue │ │ ├── sw-data-table.fixtures.json │ │ ├── sw-data-table.interactive.stories.ts │ │ ├── sw-data-table.spec.ts │ │ ├── sw-data-table.stories.ts │ │ └── sw-data-table.vue │ │ └── sw-pagination │ │ ├── sw-pagination.interactive.stories.js │ │ ├── sw-pagination.spec.ts │ │ ├── sw-pagination.stories.ts │ │ └── sw-pagination.vue ├── composables │ └── useEmptySlotCheck.ts ├── directives │ ├── dragdrop.directive.ts │ ├── popover.directive.ts │ ├── stickyColumn.directive.ts │ ├── tooltip.directive.ts │ ├── tooltip.interactive.stories.js │ └── tooltip.stories.ts ├── filters │ ├── salutation.filter.js │ └── unicode-uri.filter.ts ├── helper │ ├── device.helper.js │ └── provideInjectKeys.ts ├── index.ts ├── mixins │ ├── form-field.mixin.ts │ ├── notification.mixin.ts │ └── validation.mixin.ts ├── plugin │ └── device-helper.plugin.ts ├── services │ └── validation.service.ts ├── shims-vue.d.ts └── utils │ ├── dom.ts │ ├── format.ts │ ├── object.ts │ ├── sort.ts │ └── uuid.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json ├── tsconfig.vitest.json ├── utils ├── styleMock.js └── svgStringifyTransformer.js ├── vite.config.ts └── vitest.config.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | end_of_line = lf 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | max_line_length = 100 8 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | vue.config.js 2 | jest.config.js 3 | rollup.config.js 4 | node_modules/ 5 | .eslintrc.cjs 6 | dist/ -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | require('@rushstack/eslint-patch/modern-module-resolution') 3 | 4 | module.exports = { 5 | root: true, 6 | 'extends': [ 7 | 'plugin:vue/vue3-essential', 8 | 'eslint:recommended', 9 | '@vue/eslint-config-typescript', 10 | 'plugin:storybook/recommended', 11 | 'plugin:vitest-globals/recommended', 12 | 'plugin:vitest/all', 13 | 'prettier' 14 | ], 15 | parserOptions: { 16 | ecmaVersion: 'latest' 17 | }, 18 | plugins: ['vitest'], 19 | env: { 20 | node: true, 21 | "vitest-globals/env": true 22 | }, 23 | rules: { 24 | "vitest/consistent-test-filename": ["error",{ 25 | pattern: ".*\\.spec\\.ts$", 26 | }], 27 | "vitest/no-hooks": "off", 28 | "vitest/require-hook": "off", 29 | "vitest/prefer-expect-assertions": "off", 30 | "vitest/max-expects": "off", 31 | "vitest/prefer-strict-equal": "error", 32 | "vitest/no-focused-tests": "error", 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.github/workflows/chromatic.yml: -------------------------------------------------------------------------------- 1 | name: "Chromatic" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | # List of jobs 9 | jobs: 10 | chromatic-deployment: 11 | # Operating System 12 | runs-on: ubuntu-latest 13 | # Job steps 14 | steps: 15 | - name: Checkout the repository 16 | uses: actions/checkout@v4 17 | with: 18 | fetch-depth: 0 # Required for the chromatic CLI to work 19 | 20 | - name: Setup Node.js 21 | uses: actions/setup-node@v4 22 | with: 23 | node-version: "18" 24 | 25 | - name: Retrieve the cached main "node_modules" directory (if present) 26 | uses: actions/cache@v4 27 | id: node-cache-main 28 | with: 29 | path: node_modules 30 | key: node-modules-main-${{ runner.os }}-${{ hashFiles('package-lock.json') }} 31 | 32 | - name: Install main dependencies (if the cached directory was not found) 33 | if: steps.node-cache-main.outputs.cache-hit != 'true' 34 | run: npm ci 35 | 36 | - name: Publish to Chromatic 37 | uses: chromaui/action@v1 38 | with: 39 | projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} 40 | zip: true 41 | allowConsoleErrors: true 42 | -------------------------------------------------------------------------------- /.github/workflows/deployment.yml: -------------------------------------------------------------------------------- 1 | name: Deployment 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | create_storybook_pages: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout the repository 13 | uses: actions/checkout@v4 14 | 15 | - name: Setup Node.js 16 | uses: actions/setup-node@v4 17 | with: 18 | node-version: "18" 19 | 20 | - name: Retrieve the cached main "node_modules" directory (if present) 21 | uses: actions/cache@v4 22 | id: node-cache-main 23 | with: 24 | path: node_modules 25 | key: node-modules-main-${{ runner.os }}-${{ hashFiles('package-lock.json') }} 26 | 27 | - name: Install main dependencies (if the cached directory was not found) 28 | if: steps.node-cache-main.outputs.cache-hit != 'true' 29 | run: npm ci 30 | 31 | - name: Create the static pages directory locally in CI 32 | run: npm run build-storybook 33 | 34 | - name: Deploy 🚀 35 | if: github.ref == 'refs/heads/main' 36 | uses: JamesIves/github-pages-deploy-action@4.1.4 37 | with: 38 | force: false 39 | branch: gh-pages 40 | folder: storybook-static 41 | clean-exclude: pr-preview/ 42 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to NPM 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | publish: 10 | if: github.ref == 'refs/heads/main' 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v4 15 | - name: Setup Node.js 16 | uses: actions/setup-node@v4 17 | with: 18 | node-version: "18" 19 | - name: Retrieve the cached "node_modules" directory (if present) 20 | uses: actions/cache@v4 21 | id: node-cache 22 | with: 23 | path: node_modules 24 | key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json') }} 25 | - name: Install dependencies (if the cached directory was not found) 26 | if: steps.node-cache.outputs.cache-hit != 'true' 27 | run: npm ci 28 | - name: Build distributed files 29 | run: npm run build-only 30 | - uses: JS-DevTools/npm-publish@v1 31 | with: 32 | token: ${{ secrets.NPM_TOKEN }} 33 | access: "public" 34 | -------------------------------------------------------------------------------- /.github/workflows/preview.yml: -------------------------------------------------------------------------------- 1 | name: Deploy PR previews 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - reopened 8 | - synchronize 9 | - closed 10 | 11 | concurrency: preview-${{ github.ref }} 12 | 13 | jobs: 14 | deploy-preview: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout the repository 18 | uses: actions/checkout@v4 19 | 20 | - name: Setup Node.js 21 | uses: actions/setup-node@v4 22 | with: 23 | node-version: "18" 24 | 25 | - name: Retrieve the cached main "node_modules" directory (if present) 26 | uses: actions/cache@v4 27 | id: node-cache-main 28 | with: 29 | path: node_modules 30 | key: node-modules-main-${{ runner.os }}-${{ hashFiles('package-lock.json') }} 31 | 32 | - name: Install main dependencies (if the cached directory was not found) 33 | if: steps.node-cache-main.outputs.cache-hit != 'true' 34 | run: npm ci 35 | 36 | - name: Create the static pages directory locally in CI 37 | run: npm run build-storybook 38 | 39 | - name: Deploy preview 40 | uses: rossjrw/pr-preview-action@v1 41 | with: 42 | source-dir: ./storybook-static/ 43 | -------------------------------------------------------------------------------- /.github/workflows/static.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Deploy static content to Pages 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | jobs: 25 | # Single deploy job since we're just deploying 26 | deploy: 27 | environment: 28 | name: github-pages 29 | url: ${{ steps.deployment.outputs.page_url }} 30 | runs-on: ubuntu-latest 31 | steps: 32 | - name: Checkout 33 | uses: actions/checkout@v4 34 | - name: Setup Pages 35 | uses: actions/configure-pages@v4 36 | - name: Upload artifact 37 | uses: actions/upload-pages-artifact@v3 38 | with: 39 | # Upload entire repository 40 | path: './redirect-page/' 41 | - name: Deploy to GitHub Pages 42 | id: deployment 43 | uses: actions/deploy-pages@v4 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | .yalc/ 5 | 6 | 7 | # local env files 8 | .env.local 9 | .env.*.local 10 | 11 | # Log files 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | pnpm-debug.log* 16 | 17 | # Cache files 18 | playwright-cache 19 | 20 | # Editor directories and files 21 | yalc.lock 22 | .idea 23 | .vscode 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | storybook-static 31 | test-results/ 32 | playwright-report/ 33 | __snapshots__/__diff_output__/ 34 | __snapshots__/__received__/ 35 | coverage -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .eslintrc.cjs 3 | dist/ -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import type { StorybookConfig } from "@storybook/vue3-vite"; 2 | 3 | const config: StorybookConfig = { 4 | stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], 5 | addons: [ 6 | "@storybook/addon-links", 7 | "@storybook/addon-essentials", 8 | "@storybook/addon-interactions", 9 | "storybook-dark-mode", 10 | ], 11 | framework: { 12 | name: "@storybook/vue3-vite", 13 | options: {}, 14 | }, 15 | docs: { 16 | autodocs: true, 17 | }, 18 | }; 19 | export default config; 20 | -------------------------------------------------------------------------------- /.storybook/manager-head.html: -------------------------------------------------------------------------------- 1 | 19 | 20 | 27 | -------------------------------------------------------------------------------- /.storybook/manager.js: -------------------------------------------------------------------------------- 1 | import { addons } from "@storybook/manager-api"; 2 | import { darkTheme, lightTheme } from "./shopwareTheme"; 3 | 4 | addons.setConfig({ 5 | theme: darkTheme, 6 | }); 7 | -------------------------------------------------------------------------------- /.storybook/preview.ts: -------------------------------------------------------------------------------- 1 | import type { Preview } from "@storybook/vue3"; 2 | import "~/src/components/assets/scss/all.scss"; 3 | import { darkTheme, lightTheme } from "./shopwareTheme"; 4 | import { setup } from "@storybook/vue3"; 5 | import { createI18n } from "vue-i18n"; 6 | import DeviceHelperPlugin from "./../src/plugin/device-helper.plugin"; 7 | 8 | const i18n = createI18n({ 9 | // something vue-i18n options here ... 10 | globalInjection: true, 11 | locale: "en", 12 | fallbackLocale: "en", 13 | messages: { 14 | en: {}, 15 | de: {}, 16 | }, 17 | allowComposition: true, 18 | }); 19 | 20 | setup((app) => { 21 | app.use(i18n); 22 | app.use(DeviceHelperPlugin); 23 | }); 24 | 25 | const preview: Preview = { 26 | parameters: { 27 | actions: { argTypesRegex: "^on[A-Z].*" }, 28 | controls: { 29 | matchers: { 30 | color: /(background|color)$/i, 31 | date: /Date$/i, 32 | }, 33 | expanded: true, 34 | sort: "requiredFirst", 35 | }, 36 | darkMode: { 37 | dark: { ...darkTheme }, 38 | light: { ...lightTheme }, 39 | }, 40 | }, 41 | }; 42 | 43 | export default preview; 44 | -------------------------------------------------------------------------------- /.storybook/shopwareTheme.js: -------------------------------------------------------------------------------- 1 | import { create } from "@storybook/theming"; 2 | import { color, typography, background } from "@storybook/theming"; 3 | 4 | export const darkTheme = create({ 5 | base: "dark", 6 | 7 | // Brand specifc stuff 8 | brandTitle: "Shopware", 9 | brandUrl: "https://docs.shopware.com", 10 | brandImage: 11 | "https://shopware.github.io/meteor-component-library/shopware_docs_horizontal_white.svg", 12 | brandTarget: "_self", 13 | 14 | // Storybook-specific color palette 15 | colorPrimary: "#BABABA", // coral 16 | colorSecondary: "#5DBBFF", // ocean 17 | 18 | // UI 19 | appBg: "#2f2f2f", 20 | appContentBg: "#29333d", 21 | appBorderColor: "rgba(255,255,255,.1)", 22 | appBorderRadius: 4, 23 | 24 | // Fonts 25 | fontBase: typography.fonts.base, 26 | fontCode: typography.fonts.mono, 27 | 28 | // Text colors 29 | textColor: color.lightest, 30 | textInverseColor: "#29333d", 31 | textMutedColor: "#8599ad", 32 | 33 | // Toolbar default and active colors 34 | barTextColor: "#999999", 35 | barSelectedColor: "#5DBBFF", 36 | barBg: "#29333d", 37 | 38 | // Form colors 39 | inputBg: "#3f3f3f", 40 | inputBorder: "rgba(0,0,0,.3)", 41 | inputTextColor: color.lightest, 42 | inputBorderRadius: 4, 43 | }); 44 | 45 | export const lightTheme = create({ 46 | base: "light", 47 | 48 | // Brand specifc stuff 49 | brandTitle: "Shopware", 50 | brandUrl: "https://docs.shopware.com", 51 | brandImage: 52 | "https://shopware.github.io/meteor-component-library/shopware_docs_horizontal_dark.svg", 53 | brandTarget: "_self", 54 | 55 | // Storybook-specific color palette 56 | colorPrimary: "#BABABA", // coral 57 | colorSecondary: "#5DBBFF", // ocean 58 | 59 | // UI 60 | appBg: "#f9fafb", 61 | appContentBg: color.lightest, 62 | appBorderColor: color.border, 63 | appBorderRadius: 4, 64 | 65 | // Fonts 66 | fontBase: typography.fonts.base, 67 | fontCode: typography.fonts.mono, 68 | 69 | // Text colors 70 | textColor: "#29333d", 71 | textInverseColor: color.lightest, 72 | textMutedColor: "#52667a", 73 | 74 | // Toolbar default and active colors 75 | barTextColor: "#8599ad", 76 | barSelectedColor: "#5DBBFF", 77 | barBg: color.lightest, 78 | 79 | // Form colors 80 | inputBg: color.lightest, 81 | inputBorder: color.border, 82 | inputTextColor: "#29333d", 83 | inputBorderRadius: 4, 84 | }); 85 | -------------------------------------------------------------------------------- /.storybook/test-runner.ts: -------------------------------------------------------------------------------- 1 | const { toMatchImageSnapshot } = require("jest-image-snapshot"); 2 | 3 | const customSnapshotsDir = `${process.cwd()}/__snapshots__`; 4 | const customReceivedDir = `${process.cwd()}/__snapshots__/__received__`; 5 | 6 | module.exports = { 7 | setup() { 8 | expect.extend({ toMatchImageSnapshot }); 9 | }, 10 | async preRender(page, context) { 11 | await page.setViewportSize({ width: 850, height: 650 }); 12 | 13 | // use bigger viewport for data-table 14 | if (context.id.startsWith("interaction-tests-table-and-list")) { 15 | await page.setViewportSize({ width: 1600, height: 900 }); 16 | } 17 | }, 18 | async postRender(page, context) { 19 | // Render screenshots only for interaction tests with Visual Test name 20 | if (!context.id.startsWith("interaction-tests") || !context.name.startsWith("Visual Test")) { 21 | return; 22 | } 23 | 24 | // wait 300ms before screenshot to make sure any pending animation is finished 25 | await (() => new Promise((resolve) => setTimeout(resolve, 300)))(); 26 | 27 | const image = await page.screenshot({ 28 | animations: "disabled", 29 | }); 30 | 31 | // @ts-expect-error 32 | expect(image).toMatchImageSnapshot({ 33 | comparisonMethod: "ssim", 34 | customDiffConfig: { ssim: "fast" }, 35 | failureThreshold: 0.01, 36 | failureThresholdType: "percent", 37 | customSnapshotsDir, 38 | blur: 0.001, 39 | customSnapshotIdentifier: context.id + "-snap", 40 | storeReceivedOnFailure: true, 41 | customReceivedDir: customReceivedDir, 42 | }); 43 | }, 44 | }; 45 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [3.0.0] - 16.02.2024 6 | 7 | - Updated Vue version from 2 to 3 8 | - Updated Storybook build from Webpack to Vite 9 | - Changed Jest to Vitest 10 | 11 | ## [2.2.0] - 17.10.2023 12 | 13 | - Added SwPagination and DeviceHelperPlugin to public API 14 | - Fix sw-tab emitting 'new-item-active' event 15 | 16 | ## [2.1.2] - 06.09.2023 17 | 18 | - Fix indeterminate state of `sw-checkbox` 19 | 20 | ## [2.1.1] - 26.04.2023 21 | 22 | - Fixed broken `sw-text-field` inheritance option 23 | - Fixed missing bannerIndex property in `sw-banner` 24 | - Fixed `sw-select` single select behaviour 25 | 26 | ## [2.1.0] - 21.03.2023 27 | 28 | - Fixed wrong timezone handling in datepicker 29 | 30 | ## [2.0.1] - 25.01.2022 31 | 32 | - Fixed wrong bundling of UUID utils which don't work in browser 33 | 34 | ## [2.0.0] - 09.01.2022 35 | 36 | ### BREAKING CHANGES 37 | 38 | - Changed default font from Source-Sans-Pro to Inter 39 | 40 | ## [1.0.2] - 30.12.2022 41 | 42 | ### Changed 43 | 44 | - Changed `visibleValues` computed property in `sw-select` to correctly display selected value for single select component. 45 | 46 | ### BREAKING CHANGES 47 | 48 | - Updated Vue version to 2.7 49 | 50 | ### Changed 51 | 52 | - Updated Webpack in Storybook to version 5 53 | - Changed drop-shadow to box-shadow in "sw-card" to improve performance in Safari 54 | -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-directives-tooltip--visual-test-render-icon-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-directives-tooltip--visual-test-render-icon-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-directives-tooltip--visual-test-render-tooltip-in-wide-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-directives-tooltip--visual-test-render-tooltip-in-wide-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-directives-tooltip--visual-test-render-tooltip-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-directives-tooltip--visual-test-render-tooltip-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-banner-attention-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-banner-attention-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-banner-critical-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-banner-critical-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-banner-info-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-banner-info-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-banner-inherited-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-banner-inherited-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-banner-neutral-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-banner-neutral-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-banner-positive-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-banner-positive-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-close-banner-box-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-close-banner-box-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-render-without-icon-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-banner--visual-test-render-without-icon-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-loader--visual-test-loader-at-50-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-loader--visual-test-loader-at-50-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-loader--visual-test-loader-at-7-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-loader--visual-test-loader-at-7-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-loader--visual-test-loader-at-90-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-loader--visual-test-loader-at-90-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-label-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-label-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-no-label-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-no-label-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-progress-label-kilobyte-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-progress-label-kilobyte-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-progress-label-percentage-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-progress-label-percentage-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-1-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-10-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-10-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-100-of-400-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-100-of-400-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-100-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-100-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-400-of-400-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-400-of-400-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-50-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-progress-bar--visual-test-value-progress-at-50-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-feedback-indicator-sw-skeleton-bar--visual-test-skeleton-bar-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-feedback-indicator-sw-skeleton-bar--visual-test-skeleton-bar-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-action-variant-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-action-variant-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-block-button-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-block-button-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-critical-ghost-variant-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-critical-ghost-variant-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-critical-variant-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-critical-variant-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-default-size-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-default-size-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-disabled-button-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-disabled-button-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-ghost-variant-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-ghost-variant-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-is-loading-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-is-loading-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-large-size-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-large-size-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-primary-variant-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-primary-variant-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-secondary-ghost-variant-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-secondary-ghost-variant-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-secondary-variant-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-secondary-variant-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-small-size-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-small-size-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-button--visual-test-square-button-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-button--visual-test-square-button-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-checkbox--visual-test-bordered-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-checkbox--visual-test-bordered-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-checkbox--visual-test-bordered-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-checkbox--visual-test-bordered-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-checkbox--visual-test-checkable-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-checkbox--visual-test-checkable-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-checkbox--visual-test-disabled-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-checkbox--visual-test-disabled-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-checkbox--visual-test-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-checkbox--visual-test-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-checkbox--visual-test-help-text-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-checkbox--visual-test-help-text-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-checkbox--visual-test-inherited-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-checkbox--visual-test-inherited-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-checkbox--visual-test-partial-checked-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-checkbox--visual-test-partial-checked-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-checkbox--visual-test-uncheckable-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-checkbox--visual-test-uncheckable-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-color-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-color-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-label-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-label-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-hex-alpha-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-hex-alpha-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-hex-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-hex-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-hsl-alpha-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-hsl-alpha-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-hsl-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-hsl-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-rgb-alpha-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-rgb-alpha-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-rgb-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-change-colorpicker-output-rgb-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-colorpicker-clear-value-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-colorpicker-clear-value-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-colorpicker-disabled-color-labels-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-colorpicker-disabled-color-labels-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-colorpicker-disabled-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-colorpicker-disabled-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-colorpicker-readonly-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-colorpicker-readonly-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-colorpicker-with-help-text-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-colorpicker-with-help-text-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-colorpicker-without-alpha-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-colorpicker-without-alpha-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-open-colorpicker-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-open-colorpicker-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-render-colorpicker-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-colorpicker--visual-test-render-colorpicker-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-datepicker--visual-test-date-input-value-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-datepicker--visual-test-date-input-value-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-datepicker--visual-test-date-time-input-value-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-datepicker--visual-test-date-time-input-value-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-datepicker--visual-test-datepicker-should-open-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-datepicker--visual-test-datepicker-should-open-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-datepicker--visual-test-time-input-value-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-datepicker--visual-test-time-input-value-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-email-field--visual-test-disabled-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-email-field--visual-test-disabled-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-email-field--visual-test-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-email-field--visual-test-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-email-field--visual-test-hint-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-email-field--visual-test-hint-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-email-field--visual-test-prefix-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-email-field--visual-test-prefix-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-email-field--visual-test-suffix-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-email-field--visual-test-suffix-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-email-field--visual-test-validation-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-email-field--visual-test-validation-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-external-link--visual-test-render-external-link-disabled-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-external-link--visual-test-render-external-link-disabled-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-external-link--visual-test-render-external-link-small-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-external-link--visual-test-render-external-link-small-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-external-link--visual-test-render-external-link-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-external-link--visual-test-render-external-link-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-number-field--visual-test-disabled-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-number-field--visual-test-disabled-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-number-field--visual-test-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-number-field--visual-test-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-number-field--visual-test-hint-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-number-field--visual-test-hint-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-number-field--visual-test-inheritance-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-number-field--visual-test-inheritance-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-number-field--visual-test-prefix-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-number-field--visual-test-prefix-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-number-field--visual-test-suffix-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-number-field--visual-test-suffix-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-password-field--visual-test-disabled-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-password-field--visual-test-disabled-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-password-field--visual-test-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-password-field--visual-test-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-password-field--visual-test-hint-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-password-field--visual-test-hint-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-password-field--visual-test-prefix-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-password-field--visual-test-prefix-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-password-field--visual-test-show-password-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-password-field--visual-test-show-password-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-password-field--visual-test-suffix-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-password-field--visual-test-suffix-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-select--visual-test-disabled-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-select--visual-test-disabled-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-select--visual-test-ensure-single-selection-without-load-more-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-select--visual-test-ensure-single-selection-without-load-more-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-select--visual-test-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-select--visual-test-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-select--visual-test-highlight-search-term-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-select--visual-test-highlight-search-term-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-select--visual-test-hint-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-select--visual-test-hint-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-select--visual-test-inherited-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-select--visual-test-inherited-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-select--visual-test-multi-select-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-select--visual-test-multi-select-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-select--visual-test-prefix-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-select--visual-test-prefix-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-select--visual-test-single-selection-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-select--visual-test-single-selection-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-select--visual-test-suffix-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-select--visual-test-suffix-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-switch--visual-test-bordered-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-switch--visual-test-bordered-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-switch--visual-test-bordered-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-switch--visual-test-bordered-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-switch--visual-test-checkable-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-switch--visual-test-checkable-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-switch--visual-test-disabled-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-switch--visual-test-disabled-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-switch--visual-test-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-switch--visual-test-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-switch--visual-test-help-text-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-switch--visual-test-help-text-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-switch--visual-test-inherited-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-switch--visual-test-inherited-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-switch--visual-test-uncheckable-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-switch--visual-test-uncheckable-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-text-field--visual-test-disabled-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-text-field--visual-test-disabled-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-text-field--visual-test-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-text-field--visual-test-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-text-field--visual-test-hint-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-text-field--visual-test-hint-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-text-field--visual-test-inheritance-active-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-text-field--visual-test-inheritance-active-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-text-field--visual-test-inheritance-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-text-field--visual-test-inheritance-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-text-field--visual-test-prefix-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-text-field--visual-test-prefix-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-text-field--visual-test-suffix-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-text-field--visual-test-suffix-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-textarea--visual-test-disabled-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-textarea--visual-test-disabled-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-textarea--visual-test-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-textarea--visual-test-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-textarea--visual-test-hint-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-textarea--visual-test-hint-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-url-field--visual-test-http-switch-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-url-field--visual-test-http-switch-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-form-sw-url-field--visual-test-input-value-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-form-sw-url-field--visual-test-input-value-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-icons-media-sw-icon--visual-test-render-calendar-icon-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-icons-media-sw-icon--visual-test-render-calendar-icon-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-icons-media-sw-icon--visual-test-render-icon-in-hidden-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-icons-media-sw-icon--visual-test-render-icon-in-hidden-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-icons-media-sw-icon--visual-test-render-icon-in-yellow-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-icons-media-sw-icon--visual-test-render-icon-in-yellow-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-icons-media-sw-icon--visual-test-render-icon-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-icons-media-sw-icon--visual-test-render-icon-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-with-hero-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-with-hero-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-with-opened-context-actions-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-with-opened-context-actions-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-without-avatar-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-without-avatar-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-without-context-actions-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-without-context-actions-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-without-footer-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-without-footer-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-without-header-right-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-without-header-right-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-without-tabs-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-without-tabs-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-without-toolbar-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-layout-sw-card--visual-test-extended-page-without-toolbar-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-layout-sw-card--visual-test-minimal-page-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-layout-sw-card--visual-test-minimal-page-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-search--visual-test-default-size-disabled-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-search--visual-test-default-size-disabled-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-search--visual-test-default-size-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-search--visual-test-default-size-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-search--visual-test-small-size-disabled-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-search--visual-test-small-size-disabled-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-search--visual-test-small-size-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-search--visual-test-small-size-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-segmented-control--visual-test-render-segmented-control-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-segmented-control--visual-test-render-segmented-control-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-segmented-control--visual-test-render-segmented-control-with-context-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-segmented-control--visual-test-render-segmented-control-with-context-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-segmented-control--visual-test-render-segmented-control-with-popover-base-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-segmented-control--visual-test-render-segmented-control-with-popover-base-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-segmented-control--visual-test-render-segmented-control-with-popover-second-level-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-segmented-control--visual-test-render-segmented-control-with-popover-second-level-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-context-tab-with-active-item-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-context-tab-with-active-item-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-context-tab-with-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-context-tab-with-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-many-tab-items-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-many-tab-items-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-full-width-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-full-width-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-vertical-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-vertical-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-with-context-menu-badge-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-with-context-menu-badge-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-with-error-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-with-error-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-with-info-badge-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-with-info-badge-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-with-positive-badge-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-navigation-sw-tabs--visual-test-render-tabs-with-positive-badge-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-overlay-sw-popover--visual-test-render-child-view-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-overlay-sw-popover--visual-test-render-child-view-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-overlay-sw-popover--visual-test-render-popover-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-overlay-sw-popover--visual-test-render-popover-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-overlay-sw-popover--visual-test-render-popover-trigger-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-overlay-sw-popover--visual-test-render-popover-trigger-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-overlay-sw-popover--visual-test-render-without-float-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-overlay-sw-popover--visual-test-render-without-float-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-add-column-indicator-popover-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-add-column-indicator-popover-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-add-column-indicator-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-add-column-indicator-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-add-new-column-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-add-new-column-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-blank-table-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-blank-table-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-column-drag-bar-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-column-drag-bar-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-column-drag-drop-ordering-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-column-drag-drop-ordering-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-column-settings-popover-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-column-settings-popover-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-column-settings-popover-without-sort-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-column-settings-popover-without-sort-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-data-sorting-in-column-settings-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-data-sorting-in-column-settings-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-emit-reload-event-on-clicking-reload-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-emit-reload-event-on-clicking-reload-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-enable-row-numbering-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-enable-row-numbering-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-hide-outlines-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-hide-outlines-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-hide-stripes-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-hide-stripes-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-open-column-settings-menu-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-open-column-settings-menu-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-open-settings-menu-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-open-settings-menu-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-empty-state-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-empty-state-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-full-table-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-full-table-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-skeleton-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-skeleton-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-table-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-table-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-table-sticky-header-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-table-sticky-header-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-table-with-scroll-shadows-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-table-with-scroll-shadows-snap.png -------------------------------------------------------------------------------- /__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-table-without-card-header-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/__snapshots__/interaction-tests-table-and-list-sw-data-table--visual-test-render-table-without-card-header-snap.png -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/public/favicon.ico -------------------------------------------------------------------------------- /redirect-page/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Redirect to https://meteor-component-library.vercel.app/ 9 | 10 | 11 |

Current URL is not available anymore

12 |

13 | Use https://meteor-component-library.vercel.app/ instead. 14 |

15 | 16 | 19 | 20 | -------------------------------------------------------------------------------- /src/_internal/story-helper.ts: -------------------------------------------------------------------------------- 1 | import type { Meta } from "@storybook/vue3"; 2 | import type { DefineComponent } from "vue"; 3 | 4 | export type SlottedMeta< 5 | TComponent extends abstract new (...args: any) => any, 6 | TSlots extends string, 7 | > = Meta["$props"] & Record>>; 8 | -------------------------------------------------------------------------------- /src/_internal/test-helper.ts: -------------------------------------------------------------------------------- 1 | export function waitUntilRendered(check: () => any) { 2 | return new Promise((resolve, reject) => { 3 | const waitUntilElementLoad = (retryTime = 0) => { 4 | // do not wait longer than 2.5 seconds 5 | if (retryTime > 100) { 6 | reject( 7 | new Error( 8 | `"waitUntilRendered": condition ${check.toString().replace(/(\r\n|\n|\r)/gm, "")} not met after 2.5 seconds`, 9 | ), 10 | ); 11 | return; 12 | } 13 | 14 | const result = check(); 15 | 16 | // retry selection when not found otherwise resolve it 17 | if (!result) { 18 | window.setTimeout(() => waitUntilElementLoad(retryTime + 1), 25); 19 | } else { 20 | resolve(true); 21 | } 22 | }; 23 | 24 | waitUntilElementLoad(); 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /src/components/_internal/sw-highlight-text.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | 64 | -------------------------------------------------------------------------------- /src/components/_internal/sw-ignore-class.vue: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/components/_internal/sw-popover-deprecated/sw-popover-deprecated.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 62 | 63 | 76 | -------------------------------------------------------------------------------- /src/components/_internal/sw-smooth-reflow.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 38 | -------------------------------------------------------------------------------- /src/components/assets/scss/all.scss: -------------------------------------------------------------------------------- 1 | @import "fonts/inter.font"; 2 | @import "variables"; 3 | @import "typography"; 4 | @import "global.scss"; 5 | @import "directives/tooltip"; 6 | @import "directives/dragdrop"; 7 | -------------------------------------------------------------------------------- /src/components/assets/scss/directives/dragdrop.scss: -------------------------------------------------------------------------------- 1 | @import "../variables.scss"; 2 | 3 | .is--drag-element { 4 | position: absolute; 5 | pointer-events: none; 6 | touch-action: none; 7 | user-focus: none; 8 | user-select: none; 9 | z-index: $z-index-dragdrop; 10 | box-shadow: 0 0 4px 0 $color-shopware-brand-500; 11 | overflow: hidden; 12 | cursor: grab; 13 | 14 | & > * { 15 | user-focus: none; 16 | user-select: none; 17 | user-input: none; 18 | user-modify: none; 19 | pointer-events: none; 20 | touch-action: none; 21 | -webkit-user-drag: none; 22 | } 23 | 24 | &.is--valid-drag { 25 | box-shadow: 0 0 4px 0 $color-emerald-500; 26 | } 27 | 28 | &.is--invalid-drag { 29 | box-shadow: 0 0 4px 0 $color-crimson-500; 30 | } 31 | } 32 | 33 | .is--draggable { 34 | user-focus: none; 35 | user-select: none; 36 | cursor: grab; 37 | 38 | img { 39 | user-focus: none; 40 | user-select: none; 41 | user-input: none; 42 | user-modify: none; 43 | pointer-events: none; 44 | touch-action: none; 45 | -webkit-user-drag: none; 46 | } 47 | } 48 | 49 | .is--dragging { 50 | background: $color-gray-100; 51 | border: 1px dashed $color-gray-300; 52 | box-shadow: none; 53 | color: $color-gray-100; 54 | cursor: grab; 55 | 56 | & > * { 57 | opacity: 0; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/components/assets/scss/directives/tooltip.scss: -------------------------------------------------------------------------------- 1 | @import "../variables.scss"; 2 | 3 | $sw-tooltip-z-index: $z-index-tooltip; 4 | $sw-tooltip-color-background: $color-menu-end; 5 | $sw-tooltip-color: $color-white; 6 | $sw-tooltip-border-radius: $border-radius-default; 7 | $sw-tooltip-color-light: $color-darkgray-200; 8 | $sw-tooltip-border-color-light: $color-gray-300; 9 | 10 | .sw-tooltip { 11 | position: absolute; 12 | z-index: $sw-tooltip-z-index; 13 | 14 | &.sw-tooltip--dark { 15 | background-color: $sw-tooltip-color-background; 16 | border-radius: $sw-tooltip-border-radius; 17 | color: $sw-tooltip-color; 18 | padding: 12px 16px; 19 | font-size: 14px; 20 | word-wrap: break-word; 21 | 22 | &::before { 23 | content: ""; 24 | position: absolute; 25 | height: 8px; 26 | width: 8px; 27 | transform: rotate(45deg); 28 | background: $sw-tooltip-color-background; 29 | } 30 | 31 | &.sw-tooltip--top::before { 32 | bottom: -4px; 33 | margin-left: -4px; 34 | left: 50%; 35 | } 36 | 37 | &.sw-tooltip--bottom::before { 38 | top: -4px; 39 | margin-left: -4px; 40 | left: 50%; 41 | } 42 | 43 | &.sw-tooltip--left::before { 44 | top: 50%; 45 | margin-top: -4px; 46 | right: -4px; 47 | } 48 | 49 | &.sw-tooltip--right::before { 50 | top: 50%; 51 | margin-top: -4px; 52 | left: -4px; 53 | } 54 | } 55 | 56 | &.sw-tooltip--light { 57 | color: $sw-tooltip-color-light; 58 | font-size: 12px; 59 | font-weight: lighter; 60 | letter-spacing: 0; 61 | line-height: 19px; 62 | width: auto !important; 63 | height: auto !important; 64 | padding: 5px 10px; 65 | background: $sw-tooltip-color; 66 | border: 1px solid $sw-tooltip-border-color-light; 67 | box-shadow: 0 3px 6px 0 rgba(120, 138, 155, 0.5); 68 | border-radius: 4px; 69 | 70 | &.sw-tooltip--top { 71 | margin-top: 6px; 72 | } 73 | 74 | &.sw-tooltip--bottom { 75 | margin-top: -4px; 76 | } 77 | 78 | &.sw-tooltip--left { 79 | margin-left: 5px; 80 | } 81 | 82 | &.sw-tooltip--right { 83 | margin-right: -5px; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/components/assets/scss/fonts/inter.font.scss: -------------------------------------------------------------------------------- 1 | // Normal font 2 | @use "~inter-ui/default" as inter-ui with ( 3 | $inter-font-display: swap, 4 | $inter-font-path: "~inter-ui/Inter (web)" 5 | ); 6 | 7 | // Variable font 8 | @use "~inter-ui/variable" as inter-ui-variable with ( 9 | $inter-font-display: swap, 10 | $inter-font-path: "~inter-ui/Inter (web)" 11 | ); 12 | 13 | @include inter-ui.weight-400; 14 | @include inter-ui.weight-500; 15 | @include inter-ui.weight-600; 16 | @include inter-ui.weight-700; 17 | @include inter-ui-variable.default; 18 | -------------------------------------------------------------------------------- /src/components/assets/scss/mixins.scss: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------- 2 | // This file contains all application-wide Sass mixins. 3 | // ----------------------------------------------------------------------------- 4 | 5 | /// @type Display Model 6 | @mixin flex-centering() { 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | } 11 | 12 | @mixin flex-centering-vertical() { 13 | display: flex; 14 | align-items: center; 15 | } 16 | 17 | @mixin flex-centering-horizontal() { 18 | display: flex; 19 | justify-content: center; 20 | } 21 | 22 | /// @type Box 23 | @mixin square($dimension) { 24 | width: $dimension; 25 | height: $dimension; 26 | } 27 | 28 | @mixin circle($dimension) { 29 | width: $dimension; 30 | height: $dimension; 31 | border-radius: 50%; 32 | } 33 | 34 | @mixin size($size) { 35 | width: $size; 36 | height: $size; 37 | } 38 | 39 | /// @type Text 40 | @mixin truncate() { 41 | white-space: nowrap; 42 | text-overflow: ellipsis; 43 | overflow: hidden; 44 | } 45 | 46 | @mixin reset-truncate() { 47 | white-space: inherit; 48 | text-overflow: inherit; 49 | overflow: visible; 50 | } 51 | 52 | @mixin animated-truncate() { 53 | position: relative; 54 | margin-right: 18px; 55 | 56 | &::after { 57 | position: absolute; 58 | content: "\2026"; 59 | display: inline-block; 60 | overflow: hidden; 61 | width: 0; 62 | margin-left: 3px; 63 | animation: ellipsis steps(4, end) 1.5s infinite; 64 | vertical-align: bottom; 65 | top: 0; 66 | } 67 | } 68 | 69 | @keyframes ellipsis { 70 | to { 71 | width: 1.25rem; 72 | } 73 | } 74 | 75 | /// @type Other 76 | @mixin transition($what: all, $time: 0.3s, $how: ease) { 77 | transition: $what $time $how; 78 | } 79 | 80 | @mixin hidden() { 81 | position: absolute; 82 | top: -9999px; 83 | left: -9999px; 84 | } 85 | 86 | @mixin drop-shadow-default() { 87 | box-shadow: 88 | 0 1px 1px rgba(0, 0, 0, 8%), 89 | 0 2px 1px rgba(0, 0, 0, 6%), 90 | 0 1px 3px rgba(0, 0, 0, 10%); 91 | } 92 | 93 | @mixin focus-style() { 94 | &:focus { 95 | outline: none; 96 | 97 | &::after { 98 | content: ""; 99 | z-index: 1; 100 | position: absolute; 101 | right: -3px; 102 | left: -3px; 103 | top: -3px; 104 | bottom: -3px; 105 | border: 2px solid $color-shopware-brand-500; 106 | border-radius: $border-radius-default; 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/components/assets/scss/typography.scss: -------------------------------------------------------------------------------- 1 | h1, 2 | h2, 3 | h3, 4 | h4, 5 | h5, 6 | h6 { 7 | color: $color-darkgray-200; 8 | font-weight: 600; 9 | margin: 0 0 20px 0; 10 | } 11 | -------------------------------------------------------------------------------- /src/components/context-menu/sw-context-menu-divider/sw-context-menu-divider.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | 13 | 24 | -------------------------------------------------------------------------------- /src/components/context-menu/sw-context-menu-item/sw-context-menu-item.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 72 | -------------------------------------------------------------------------------- /src/components/feedback-indicator/sw-banner/sw-banner.interactive.stories.ts: -------------------------------------------------------------------------------- 1 | import { within, userEvent } from "@storybook/testing-library"; 2 | import { expect } from "@storybook/jest"; 3 | 4 | import meta, { type SwBannerMeta, type SwBannerStory } from "./sw-banner.stories"; 5 | 6 | export default { 7 | ...meta, 8 | title: "Interaction Tests/Feedback Indicator/sw-banner", 9 | } as SwBannerMeta; 10 | 11 | export const VisualTestBannerNeutral: SwBannerStory = { 12 | name: "Banner neutral", 13 | }; 14 | 15 | export const VisualTestBannerInfo: SwBannerStory = { 16 | name: "Banner info", 17 | args: { 18 | variant: "info", 19 | }, 20 | }; 21 | 22 | export const VisualTestBannerAttention: SwBannerStory = { 23 | name: "Banner attention", 24 | args: { 25 | variant: "attention", 26 | }, 27 | }; 28 | 29 | export const VisualTestBannerCritical: SwBannerStory = { 30 | name: "Banner critical", 31 | args: { 32 | variant: "critical", 33 | }, 34 | }; 35 | 36 | export const VisualTestBannerPositive: SwBannerStory = { 37 | name: "Banner positive", 38 | args: { 39 | variant: "positive", 40 | }, 41 | }; 42 | 43 | export const VisualTestBannerInherited: SwBannerStory = { 44 | name: "Banner inherited", 45 | args: { 46 | variant: "inherited", 47 | }, 48 | }; 49 | 50 | export const VisualTestRenderWithoutIcon: SwBannerStory = { 51 | name: "Render banner without icon", 52 | args: { 53 | hideIcon: true, 54 | }, 55 | }; 56 | 57 | export const VisualTestCloseBannerBox: SwBannerStory = { 58 | name: "Close the banner", 59 | args: { 60 | closable: true, 61 | }, 62 | play: async ({ canvasElement, args }) => { 63 | const canvas = within(canvasElement); 64 | 65 | expect(args.close).not.toHaveBeenCalled(); 66 | 67 | await userEvent.click(canvas.getByRole("button")); 68 | 69 | expect(args.close).toHaveBeenCalledWith(null); 70 | }, 71 | }; 72 | -------------------------------------------------------------------------------- /src/components/feedback-indicator/sw-banner/sw-banner.stories.ts: -------------------------------------------------------------------------------- 1 | import type { StoryObj } from "@storybook/vue3"; 2 | import { action } from "@storybook/addon-actions"; 3 | import SwBanner from "./sw-banner.vue"; 4 | import type { SlottedMeta } from "@/_internal/story-helper"; 5 | import { fn } from "@storybook/test"; 6 | 7 | export type SwBannerMeta = SlottedMeta; 8 | 9 | const meta: SwBannerMeta = { 10 | title: "Components/Feedback Indicator/sw-banner", 11 | component: SwBanner, 12 | args: { 13 | title: "This is a banner", 14 | default: "I am in the default slot of the banner", 15 | variant: "neutral", 16 | close: fn(action("close")), 17 | }, 18 | render: (args) => ({ 19 | components: { SwBanner }, 20 | setup() { 21 | return { 22 | args, 23 | }; 24 | }, 25 | template: ` 26 | 30 |
31 |
`, 32 | }), 33 | }; 34 | 35 | export default meta; 36 | export type SwBannerStory = StoryObj; 37 | 38 | export const DefaultStory: SwBannerStory = { 39 | name: "sw-banner", 40 | }; 41 | -------------------------------------------------------------------------------- /src/components/feedback-indicator/sw-loader/sw-loader.interactive.stories.ts: -------------------------------------------------------------------------------- 1 | import meta, { type SwLoaderMeta, type SwLoaderStory } from "./sw-loader.stories"; 2 | 3 | export default { 4 | ...meta, 5 | title: "Interaction Tests/Feedback Indicator/sw-loader", 6 | } as SwLoaderMeta; 7 | 8 | export const VisualTestLoaderAt50: SwLoaderStory = { 9 | name: "Render loader with 50px", 10 | args: { 11 | size: "50px", 12 | }, 13 | }; 14 | 15 | export const VisualTestLoaderAt90: SwLoaderStory = { 16 | name: "Render loader with 90px", 17 | args: { 18 | size: "90px", 19 | }, 20 | }; 21 | 22 | export const VisualTestLoaderAt7: SwLoaderStory = { 23 | name: "Render loader with 7px", 24 | args: { 25 | size: "7px", 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /src/components/feedback-indicator/sw-loader/sw-loader.stories.ts: -------------------------------------------------------------------------------- 1 | import SwLoader from "./sw-loader.vue"; 2 | import type { StoryObj } from "@storybook/vue3"; 3 | import type { SlottedMeta } from "@/_internal/story-helper"; 4 | 5 | export type SwLoaderMeta = SlottedMeta; 6 | 7 | const meta: SwLoaderMeta = { 8 | title: "Components/Feedback Indicator/sw-loader", 9 | component: SwLoader, 10 | render: (args) => ({ 11 | setup: () => { 12 | return { 13 | args, 14 | }; 15 | }, 16 | components: { SwLoader }, 17 | template: '', 18 | }), 19 | args: { 20 | size: "50px", 21 | }, 22 | }; 23 | 24 | export default meta; 25 | 26 | export type SwLoaderStory = StoryObj; 27 | 28 | export const Default: SwLoaderStory = { 29 | name: "sw-loader", 30 | }; 31 | -------------------------------------------------------------------------------- /src/components/feedback-indicator/sw-progress-bar/sw-progress-bar.stories.ts: -------------------------------------------------------------------------------- 1 | import SwProgressBar from "./sw-progress-bar.vue"; 2 | import type { StoryObj } from "@storybook/vue3"; 3 | import type { SlottedMeta } from "@/_internal/story-helper"; 4 | 5 | export type SwProgressBarMeta = SlottedMeta; 6 | 7 | export default { 8 | title: "Components/Feedback Indicator/sw-progress-bar", 9 | component: SwProgressBar, 10 | render: (args) => ({ 11 | setup() { 12 | return { 13 | args, 14 | }; 15 | }, 16 | components: { SwProgressBar }, 17 | template: '', 18 | }), 19 | args: { 20 | modelValue: 121, 21 | maxValue: 356, 22 | label: "Example progress bar", 23 | error: undefined, 24 | progressLabelType: "", 25 | }, 26 | } as SwProgressBarMeta; 27 | 28 | export type SwProgressBarStory = StoryObj; 29 | 30 | export const Default: SwProgressBarStory = { 31 | name: "Minimal", 32 | }; 33 | 34 | export const Extended: SwProgressBarStory = { 35 | args: { 36 | modelValue: 277, 37 | error: { 38 | code: 500, 39 | detail: "Error while loading", 40 | }, 41 | progressLabelType: "kb", 42 | }, 43 | }; 44 | -------------------------------------------------------------------------------- /src/components/feedback-indicator/sw-skeleton-bar/sw-skeleton-bar.interactive.stories.ts: -------------------------------------------------------------------------------- 1 | import SwSkeletonBar from "./sw-skeleton-bar.vue"; 2 | import type { SwSkeletonBarStory, SwSkeletonBarMeta } from "./sw-skeleton-bar.stories"; 3 | 4 | import meta from "./sw-skeleton-bar.stories"; 5 | 6 | export default { 7 | ...meta, 8 | title: "Interaction Tests/Feedback Indicator/sw-skeleton-bar", 9 | component: SwSkeletonBar, 10 | } as SwSkeletonBarMeta; 11 | 12 | export const VisualTestSkeletonBar: SwSkeletonBarStory = { 13 | name: "Render the skeleton bar", 14 | }; 15 | -------------------------------------------------------------------------------- /src/components/feedback-indicator/sw-skeleton-bar/sw-skeleton-bar.stories.ts: -------------------------------------------------------------------------------- 1 | import SwSkeletonBar from "./sw-skeleton-bar.vue"; 2 | import type { StoryObj } from "@storybook/vue3"; 3 | import type { SlottedMeta } from "@/_internal/story-helper"; 4 | 5 | export type SwSkeletonBarMeta = SlottedMeta; 6 | 7 | export default { 8 | title: "Components/Feedback Indicator/sw-skeleton-bar", 9 | component: SwSkeletonBar, 10 | render: (args) => ({ 11 | components: { SwSkeletonBar }, 12 | template: ` 13 |
14 | 15 |
16 | `, 17 | setup: () => { 18 | return { 19 | args, 20 | }; 21 | }, 22 | }), 23 | } as SwSkeletonBarMeta; 24 | 25 | export type SwSkeletonBarStory = StoryObj; 26 | 27 | export const Default: SwSkeletonBarStory = { 28 | name: "sw-skeleton-bar", 29 | }; 30 | -------------------------------------------------------------------------------- /src/components/feedback-indicator/sw-skeleton-bar/sw-skeleton-bar.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | 15 | 56 | -------------------------------------------------------------------------------- /src/components/form/_internal/sw-base-field/arg-types.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | change: { 3 | action: "change", 4 | table: { 5 | category: "Events", 6 | }, 7 | }, 8 | updateModelValue: { 9 | action: "updateModelValue", 10 | table: { 11 | category: "Events", 12 | }, 13 | }, 14 | inheritanceRemove: { 15 | action: "inheritance-remove", 16 | table: { 17 | category: "Events", 18 | }, 19 | }, 20 | inheritanceRestore: { 21 | action: "inheritance-restore", 22 | table: { 23 | category: "Events", 24 | }, 25 | }, 26 | label: { 27 | control: { type: "text" }, 28 | }, 29 | prefix: { 30 | control: { type: "text" }, 31 | }, 32 | suffix: { 33 | control: { type: "text" }, 34 | }, 35 | hint: { 36 | control: { type: "text" }, 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /src/components/form/_internal/sw-inheritance-switch/sw-inheritance-switch.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 108 | 109 | 119 | -------------------------------------------------------------------------------- /src/components/form/sw-button/sw-button.stories.ts: -------------------------------------------------------------------------------- 1 | import type { StoryObj } from "@storybook/vue3"; 2 | import { action } from "@storybook/addon-actions"; 3 | import { fn } from "@storybook/test"; 4 | import SwButton from "./sw-button.vue"; 5 | import type { SlottedMeta } from "@/_internal/story-helper"; 6 | 7 | export type SwButtonMeta = SlottedMeta; 8 | 9 | export default { 10 | title: "Components/Form/sw-button", 11 | component: SwButton, 12 | args: { 13 | default: "Button", 14 | variant: "primary", 15 | size: "small", 16 | disabled: false, 17 | square: false, 18 | block: false, 19 | isLoading: false, 20 | ghost: false, 21 | link: undefined, 22 | click: fn(action("click")), 23 | }, 24 | render: (args) => ({ 25 | components: { SwButton }, 26 | setup() { 27 | return { 28 | args, 29 | }; 30 | }, 31 | template: `{{ args.default}}`, 32 | }), 33 | } as SwButtonMeta; 34 | 35 | export type SwButtonStory = StoryObj; 36 | 37 | export const DefaultStory: SwButtonStory = { 38 | name: "sw-button", 39 | }; 40 | -------------------------------------------------------------------------------- /src/components/form/sw-checkbox/sw-checkbox.stories.ts: -------------------------------------------------------------------------------- 1 | import { action } from "@storybook/addon-actions"; 2 | import SwCheckbox from "./sw-checkbox.vue"; 3 | import type { StoryObj } from "@storybook/vue3"; 4 | import type { SlottedMeta } from "@/_internal/story-helper"; 5 | import { fn } from "@storybook/test"; 6 | 7 | export type SwCheckboxMeta = SlottedMeta< 8 | typeof SwCheckbox, 9 | "default" | "change" | "isInherited" | "inheritanceRemove" 10 | >; 11 | 12 | export default { 13 | title: "Components/Form/sw-checkbox", 14 | component: SwCheckbox, 15 | args: { 16 | label: "Checkbox", 17 | disabled: false, 18 | bordered: false, 19 | change: fn(action("change")), 20 | inheritanceRemove: fn(action("inheritance-remove")), 21 | inheritanceRestore: fn(action("inheritance-restore")), 22 | }, 23 | render: (args) => ({ 24 | components: { SwCheckbox }, 25 | template: ``, 31 | setup: () => { 32 | return { 33 | args, 34 | }; 35 | }, 36 | }), 37 | } as SwCheckboxMeta; 38 | 39 | export type SwCheckboxStory = StoryObj; 40 | 41 | export const DefaultStory: SwCheckboxStory = { 42 | name: "sw-checkbox", 43 | }; 44 | -------------------------------------------------------------------------------- /src/components/form/sw-colorpicker/sw-colorpicker.stories.ts: -------------------------------------------------------------------------------- 1 | import SwColorpicker from "./sw-colorpicker.vue"; 2 | import type { StoryObj } from "@storybook/vue3"; 3 | import type { SlottedMeta } from "@/_internal/story-helper"; 4 | 5 | export type SwColorpickerMeta = SlottedMeta; 6 | 7 | export default { 8 | title: "Components/Form/sw-colorpicker", 9 | component: SwColorpicker, 10 | render: (args) => ({ 11 | components: { SwColorpicker }, 12 | template: '', 13 | setup: () => { 14 | return { 15 | args, 16 | }; 17 | }, 18 | }), 19 | args: { 20 | label: "Colorpicker example", 21 | modelValue: "#0fcff5", 22 | colorOutput: "auto", 23 | disabled: false, 24 | readonly: false, 25 | alpha: true, 26 | colorLabels: true, 27 | zIndex: null, 28 | helpText: "", 29 | required: false, 30 | isInherited: false, 31 | isInheritanceField: false, 32 | disableInheritanceToggle: false, 33 | }, 34 | } as SwColorpickerMeta; 35 | 36 | export type SwColorpickerStory = StoryObj; 37 | 38 | export const DefaultStory: SwColorpickerStory = { 39 | name: "sw-colorpicker", 40 | }; 41 | -------------------------------------------------------------------------------- /src/components/form/sw-datepicker/sw-datepicker.stories.ts: -------------------------------------------------------------------------------- 1 | import { action } from "@storybook/addon-actions"; 2 | import SwDatepicker from "./sw-datepicker.vue"; 3 | import type { StoryObj } from "@storybook/vue3"; 4 | import type { SlottedMeta } from "@/_internal/story-helper"; 5 | import { fn } from "@storybook/test"; 6 | 7 | export type SwDatepickerMeta = SlottedMeta< 8 | typeof SwDatepicker, 9 | "default" | "updateModelValue" | "modelValue" 10 | >; 11 | 12 | export default { 13 | title: "Components/Form/sw-datepicker", 14 | component: SwDatepicker, 15 | render: (args) => ({ 16 | template: ` 17 | `, 22 | components: { SwDatepicker }, 23 | data() { 24 | return { currentValue: "" }; 25 | }, 26 | watch: { 27 | "args.modelValue"(v) { 28 | this.currentValue = v; 29 | }, 30 | }, 31 | created() { 32 | this.currentValue = args.modelValue; 33 | }, 34 | setup: () => { 35 | return { 36 | args, 37 | }; 38 | }, 39 | }), 40 | args: { 41 | label: "Datepicker", 42 | updateModelValue: fn(action("update:modelValue")), 43 | modelValue: null, 44 | }, 45 | } as SwDatepickerMeta; 46 | 47 | export type SwDatepickerStory = StoryObj; 48 | 49 | export const DefaultStory: SwDatepickerStory = { 50 | name: "sw-datepicker", 51 | }; 52 | -------------------------------------------------------------------------------- /src/components/form/sw-email-field/sw-email-field.stories.ts: -------------------------------------------------------------------------------- 1 | import { action } from "@storybook/addon-actions"; 2 | import SwEmailField from "./sw-email-field.vue"; 3 | import baseFieldArgTypes from "../_internal/sw-base-field/arg-types"; 4 | import type { StoryObj } from "@storybook/vue3"; 5 | import type { SlottedMeta } from "@/_internal/story-helper"; 6 | import { fn } from "@storybook/test"; 7 | 8 | export type SwEmailFieldMeta = SlottedMeta< 9 | typeof SwEmailField, 10 | "default" | "updateModelValue" | "change" | "hint" | "suffix" | "prefix" | "placeholder" | "error" 11 | >; 12 | 13 | export default { 14 | title: "Components/Form/sw-email-field", 15 | component: SwEmailField, 16 | render: (args) => ({ 17 | template: ` 18 |
19 | 26 | 31 | 32 | 37 | 38 | 43 | 44 | 45 | 46 |

hidden

47 |
`, 48 | components: { SwEmailField }, 49 | data() { 50 | return { 51 | currentValue: args.modelValue, 52 | }; 53 | }, 54 | watch: { 55 | "args.modelValue"(v) { 56 | if (this.currentValue === v) { 57 | return; 58 | } 59 | 60 | this.currentValue = v; 61 | }, 62 | }, 63 | created() { 64 | this.currentValue = args.modelValue; 65 | }, 66 | methods: { 67 | onUpdateModelValue(e: string) { 68 | this.currentValue = e; 69 | args.updateModelValue(e); 70 | }, 71 | 72 | onChange(e: string) { 73 | this.currentValue = e; 74 | args.change(e); 75 | }, 76 | 77 | inheritanceRemoveWrapper(a: any) { 78 | this.inheritanceRemove(...a); 79 | this.isInherited = false; 80 | }, 81 | 82 | inheritanceRestoreWrapper(a: any) { 83 | this.inheritanceRestore(...a); 84 | this.isInherited = true; 85 | }, 86 | }, 87 | setup: () => { 88 | return { 89 | args, 90 | }; 91 | }, 92 | }), 93 | argTypes: { 94 | ...baseFieldArgTypes, 95 | }, 96 | args: { 97 | label: "Emailfield", 98 | updateModelValue: fn(action("updateModelValue")), 99 | }, 100 | } as SwEmailFieldMeta; 101 | 102 | export type SwEmailFieldStory = StoryObj; 103 | 104 | export const DefaultStory: SwEmailFieldStory = { 105 | name: "sw-email-field", 106 | }; 107 | -------------------------------------------------------------------------------- /src/components/form/sw-email-field/sw-email-field.vue: -------------------------------------------------------------------------------- 1 | 56 | 57 | 120 | -------------------------------------------------------------------------------- /src/components/form/sw-external-link/sw-external-link.interactive.stories.ts: -------------------------------------------------------------------------------- 1 | import { within, userEvent } from "@storybook/testing-library"; 2 | import { expect } from "@storybook/jest"; 3 | 4 | import meta, { 5 | type SwExternalLinkMeta, 6 | type SwExternalLinkStory, 7 | } from "./sw-external-link.stories"; 8 | 9 | export default { 10 | ...meta, 11 | title: "Interaction Tests/Form/sw-external-link", 12 | } as SwExternalLinkMeta; 13 | 14 | export const VisualTestRenderExternalLink: SwExternalLinkStory = { 15 | name: "Render external link", 16 | args: { 17 | href: "https://developers.shopware.com/", 18 | }, 19 | }; 20 | 21 | export const VisualTestRenderExternalLinkSmall: SwExternalLinkStory = { 22 | name: "Render external link in small", 23 | args: { 24 | small: true, 25 | href: "https://developers.shopware.com/", 26 | }, 27 | }; 28 | 29 | export const VisualTestRenderExternalLinkDisabled: SwExternalLinkStory = { 30 | name: "Render disabled external link", 31 | args: { 32 | disabled: true, 33 | }, 34 | play: ({ canvasElement }) => { 35 | const canvas = within(canvasElement); 36 | 37 | const link = canvas.getByRole("link"); 38 | 39 | expect(getComputedStyle(link).pointerEvents).toEqual("none"); 40 | }, 41 | }; 42 | 43 | export const TestExternalLinkWithoutHref: SwExternalLinkStory = { 44 | name: "Render external link without href attribute", 45 | args: { 46 | href: undefined, 47 | }, 48 | play: async ({ canvasElement, args }) => { 49 | const canvas = within(canvasElement); 50 | 51 | await userEvent.click(canvas.getByRole("link")); 52 | 53 | expect(args.click).toHaveBeenCalled(); 54 | }, 55 | }; 56 | -------------------------------------------------------------------------------- /src/components/form/sw-external-link/sw-external-link.stories.ts: -------------------------------------------------------------------------------- 1 | import { action } from "@storybook/addon-actions"; 2 | import SwExternalLink from "./sw-external-link.vue"; 3 | import type { StoryObj } from "@storybook/vue3"; 4 | import type { SlottedMeta } from "@/_internal/story-helper"; 5 | import { fn } from "@storybook/test"; 6 | 7 | export type SwExternalLinkMeta = SlottedMeta; 8 | 9 | export default { 10 | title: "Components/Form/sw-external-link", 11 | component: SwExternalLink, 12 | render: (args) => ({ 13 | components: { SwExternalLink }, 14 | template: ` 15 | 19 | Click here 20 | `, 21 | setup: () => { 22 | return { 23 | args, 24 | }; 25 | }, 26 | }), 27 | args: { 28 | small: false, 29 | rel: "noopener", 30 | href: "https://www.shopware.com", 31 | disabled: false, 32 | click: fn(action("click")), 33 | }, 34 | } as SwExternalLinkMeta; 35 | 36 | export type SwExternalLinkStory = StoryObj; 37 | 38 | export const DefaultStory: SwExternalLinkStory = { 39 | name: "sw-external-link", 40 | }; 41 | -------------------------------------------------------------------------------- /src/components/form/sw-help-text/sw-help-text.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 73 | 74 | 89 | -------------------------------------------------------------------------------- /src/components/form/sw-number-field/sw-number-field.stories.ts: -------------------------------------------------------------------------------- 1 | import SwNumberField from "./sw-number-field.vue"; 2 | import baseFieldArgTypes from "../_internal/sw-base-field/arg-types"; 3 | import type { StoryObj } from "@storybook/vue3"; 4 | import type { SlottedMeta } from "@/_internal/story-helper"; 5 | 6 | export type SwNumberFieldMeta = SlottedMeta< 7 | typeof SwNumberField, 8 | | "default" 9 | | "inheritanceRemove" 10 | | "inheritanceRestore" 11 | | "isInherited" 12 | | "change" 13 | | "modelValue" 14 | | "hint" 15 | | "suffix" 16 | | "prefix" 17 | | "error" 18 | >; 19 | 20 | export default { 21 | title: "Components/Form/sw-number-field", 22 | component: SwNumberField, 23 | render: (args) => ({ 24 | template: ` 25 |
26 | 33 | 38 | 43 | 48 | 49 |

hidden

50 |
`, 51 | components: { SwNumberField }, 52 | data() { 53 | return { 54 | currentValue: "", 55 | }; 56 | }, 57 | watch: { 58 | "args.modelValue"(v) { 59 | if (this.currentValue === v) { 60 | return; 61 | } 62 | 63 | this.currentValue = v; 64 | }, 65 | }, 66 | created() { 67 | this.currentValue = args.modelValue; 68 | }, 69 | methods: { 70 | inheritanceRemoveWrapper() { 71 | args.inheritanceRemove(); 72 | args.isInherited = false; 73 | }, 74 | 75 | inheritanceRestoreWrapper() { 76 | args.inheritanceRestore(); 77 | args.isInherited = true; 78 | }, 79 | }, 80 | setup: () => { 81 | return { 82 | args, 83 | }; 84 | }, 85 | }), 86 | args: { 87 | label: "Numberfield", 88 | step: 1, 89 | numberType: "int", 90 | }, 91 | argTypes: { 92 | ...baseFieldArgTypes, 93 | }, 94 | } as SwNumberFieldMeta; 95 | 96 | export type SwNumberFieldStory = StoryObj; 97 | 98 | export const DefaultStory: SwNumberFieldStory = { 99 | name: "sw-number-field", 100 | }; 101 | -------------------------------------------------------------------------------- /src/components/form/sw-password-field/sw-password-field.stories.ts: -------------------------------------------------------------------------------- 1 | import { action } from "@storybook/addon-actions"; 2 | import SwPasswordField from "./sw-password-field.vue"; 3 | import baseFieldArgTypes from "../_internal/sw-base-field/arg-types"; 4 | import type { StoryObj } from "@storybook/vue3"; 5 | import type { SlottedMeta } from "@/_internal/story-helper"; 6 | import { fn } from "@storybook/test"; 7 | 8 | export type SwPasswordFieldMeta = SlottedMeta< 9 | typeof SwPasswordField, 10 | | "default" 11 | | "inheritanceRemove" 12 | | "inheritanceRestore" 13 | | "isInherited" 14 | | "change" 15 | | "value" 16 | | "hint" 17 | | "suffix" 18 | | "prefix" 19 | | "error" 20 | >; 21 | 22 | export default { 23 | title: "Components/Form/sw-password-field", 24 | component: SwPasswordField, 25 | render: (args) => ({ 26 | template: ` 27 |
28 | 35 | 40 | 45 | 50 | 51 |

hidden

52 |
`, 53 | components: { SwPasswordField }, 54 | data() { 55 | return { currentValue: "" }; 56 | }, 57 | watch: { 58 | "args.modelValue"(v) { 59 | if (this.currentValue === v) { 60 | return; 61 | } 62 | 63 | this.currentValue = v; 64 | }, 65 | }, 66 | created() { 67 | this.currentValue = args.modelValue; 68 | }, 69 | methods: { 70 | onChange(value: string) { 71 | args.change(value); 72 | this.currentValue = value; 73 | }, 74 | inheritanceRemoveWrapper(a: any) { 75 | this.inheritanceRemove(...a); 76 | args.isInherited = false; 77 | }, 78 | 79 | inheritanceRestoreWrapper(a: any) { 80 | this.inheritanceRestore(...a); 81 | args.isInherited = true; 82 | }, 83 | }, 84 | setup: () => { 85 | return { 86 | args, 87 | }; 88 | }, 89 | }), 90 | args: { 91 | label: "Passwordfield", 92 | change: fn(action("change")), 93 | updateModelValue: fn(action("updateModelValue")), 94 | }, 95 | argTypes: { 96 | ...baseFieldArgTypes, 97 | }, 98 | } as SwPasswordFieldMeta; 99 | 100 | export type SwPasswordFieldStory = StoryObj; 101 | 102 | export const DefaultStory: SwPasswordFieldStory = { 103 | name: "sw-password-field", 104 | }; 105 | -------------------------------------------------------------------------------- /src/components/form/sw-select/sw-select.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount } from "@vue/test-utils"; 2 | import SwSelect from "../sw-select/sw-select.vue"; 3 | 4 | async function createWrapper() { 5 | const wrapper = mount(SwSelect, { 6 | props: { 7 | modelValue: "becky", 8 | options: [ 9 | { 10 | id: 1, 11 | label: "Option Alfred", 12 | value: "alfred", 13 | }, 14 | { 15 | id: 2, 16 | label: "Option Becky", 17 | value: "becky", 18 | }, 19 | { 20 | id: 3, 21 | label: "Option C", 22 | value: "c", 23 | }, 24 | ], 25 | }, 26 | }); 27 | 28 | await wrapper.vm.$nextTick(); 29 | 30 | return wrapper; 31 | } 32 | 33 | describe("sw-select", () => { 34 | it("should render the select component", async () => { 35 | const wrapper = await createWrapper(); 36 | 37 | expect(wrapper.vm).toBeDefined(); 38 | }); 39 | 40 | it("should render only one single select result with type string", async () => { 41 | const wrapper = await createWrapper(); 42 | 43 | const itemHolder = wrapper.findAll(".sw-select-selection-list__item-holder"); 44 | 45 | expect(itemHolder).toHaveLength(1); 46 | expect(itemHolder.at(0)?.text()).toBe("Option Becky"); 47 | }); 48 | 49 | it("should render only one single select result with type number", async () => { 50 | const wrapper = await createWrapper(); 51 | await wrapper.setProps({ 52 | modelValue: 25, 53 | options: [ 54 | { id: 5, label: "5", value: 5 }, 55 | { id: 10, label: "10", value: 10 }, 56 | { id: 25, label: "25", value: 25 }, 57 | { id: 50, label: "50", value: 50 }, 58 | ], 59 | }); 60 | 61 | const itemHolder = wrapper.findAll(".sw-select-selection-list__item-holder"); 62 | 63 | expect(itemHolder).toHaveLength(1); 64 | expect(itemHolder.at(0)?.text()).toBe("25"); 65 | }); 66 | }); 67 | -------------------------------------------------------------------------------- /src/components/form/sw-switch/sw-switch.stories.ts: -------------------------------------------------------------------------------- 1 | import SwSwitch from "./sw-switch.vue"; 2 | import type { StoryObj } from "@storybook/vue3"; 3 | import type { SlottedMeta } from "@/_internal/story-helper"; 4 | 5 | export type SwSwitchMeta = SlottedMeta< 6 | typeof SwSwitch, 7 | "default" | "error" | "inheritanceRemove" | "change" | "label" 8 | >; 9 | 10 | export default { 11 | title: "Components/Form/sw-switch", 12 | component: SwSwitch, 13 | render: (args) => ({ 14 | components: { SwSwitch }, 15 | template: ` 16 | `, 21 | setup: () => { 22 | return { 23 | args, 24 | }; 25 | }, 26 | }), 27 | argTypes: { 28 | change: { 29 | action: "change", 30 | table: { 31 | category: "Events", 32 | }, 33 | }, 34 | "inheritance-restore": { 35 | action: "inheritance-restore", 36 | table: { 37 | category: "Events", 38 | }, 39 | }, 40 | inheritanceRemove: { 41 | action: "inheritance-remove", 42 | table: { 43 | category: "Events", 44 | }, 45 | }, 46 | label: { 47 | control: { type: "text" }, 48 | }, 49 | }, 50 | args: { 51 | label: "Switchfield", 52 | }, 53 | } as SwSwitchMeta; 54 | 55 | export type SwSwitchStory = StoryObj; 56 | 57 | export const DefaultStory: SwSwitchStory = { 58 | name: "sw-switch", 59 | }; 60 | -------------------------------------------------------------------------------- /src/components/form/sw-text-field/sw-text-field.stories.ts: -------------------------------------------------------------------------------- 1 | import SwTextField from "./sw-text-field.vue"; 2 | import baseFieldArgTypes from "../_internal/sw-base-field/arg-types"; 3 | import type { StoryObj } from "@storybook/vue3"; 4 | import type { SlottedMeta } from "@/_internal/story-helper"; 5 | 6 | export type SwTextFieldMeta = SlottedMeta< 7 | typeof SwTextField, 8 | | "default" 9 | | "change" 10 | | "prefix" 11 | | "suffix" 12 | | "hint" 13 | | "label" 14 | | "placeholder" 15 | | "error" 16 | | "inheritanceRestore" 17 | | "inheritanceRemove" 18 | | "isInherited" 19 | >; 20 | 21 | export default { 22 | title: "Components/Form/sw-text-field", 23 | component: SwTextField, 24 | render: (args) => ({ 25 | template: ` 26 |
27 | 33 | 38 | 43 | 48 | 49 |

hidden

50 |
`, 51 | components: { SwTextField }, 52 | // argTypes contains all props of text field 53 | data() { 54 | return { currentValue: "" }; 55 | }, 56 | watch: { 57 | "args.modelValue"(v) { 58 | if (this.currentValue === v) { 59 | return; 60 | } 61 | 62 | this.currentValue = v; 63 | }, 64 | }, 65 | created() { 66 | this.currentValue = args.modelValue; 67 | }, 68 | methods: { 69 | inheritanceRemoveWrapper() { 70 | args.inheritanceRemove(); 71 | args.isInherited = false; 72 | }, 73 | 74 | inheritanceRestoreWrapper() { 75 | args.inheritanceRestore(); 76 | args.isInherited = true; 77 | }, 78 | 79 | onChange(value: string) { 80 | args.change(value); 81 | this.currentValue = value; 82 | }, 83 | }, 84 | setup: () => { 85 | return { 86 | args, 87 | }; 88 | }, 89 | }), 90 | argTypes: { 91 | ...baseFieldArgTypes, 92 | }, 93 | args: { 94 | label: "Textfield label", 95 | }, 96 | } as SwTextFieldMeta; 97 | 98 | export type SwTextFieldStory = StoryObj; 99 | 100 | export const DefaultStory: SwTextFieldStory = { 101 | name: "sw-text-field", 102 | }; 103 | -------------------------------------------------------------------------------- /src/components/form/sw-textarea/sw-textarea.interactive.stories.ts: -------------------------------------------------------------------------------- 1 | import { within, userEvent } from "@storybook/testing-library"; 2 | import { expect } from "@storybook/jest"; 3 | 4 | import meta, { type SwTextareaMeta, type SwTextareaStory } from "./sw-textarea.stories"; 5 | 6 | export default { 7 | ...meta, 8 | title: "Interaction Tests/Form/sw-textarea", 9 | } as SwTextareaMeta; 10 | 11 | export const TestInputValue: SwTextareaStory = { 12 | name: "Should keep input value", 13 | play: async ({ canvasElement, args }) => { 14 | const canvas = within(canvasElement); 15 | 16 | await userEvent.type(canvas.getByRole("textbox"), "Shopware"); 17 | await userEvent.click(canvas.getByText("hidden")); 18 | 19 | expect((canvas.getByRole("textbox") as HTMLInputElement).value).toBe("Shopware"); 20 | 21 | expect(args.change).toHaveBeenCalledWith("Shopware"); 22 | }, 23 | }; 24 | 25 | export const VisualTestHint: SwTextareaStory = { 26 | name: "Should display hint", 27 | args: { 28 | hint: "hint", 29 | }, 30 | play: ({ canvasElement, args }) => { 31 | const canvas = within(canvasElement); 32 | 33 | expect(canvas.getByText(args.hint)).toBeDefined(); 34 | }, 35 | }; 36 | 37 | export const TestLabel: SwTextareaStory = { 38 | name: "Should display label", 39 | args: { 40 | label: "label", 41 | }, 42 | play: ({ canvasElement, args }) => { 43 | const canvas = within(canvasElement); 44 | 45 | expect(canvas.getByText(args.label)).toBeDefined(); 46 | }, 47 | }; 48 | 49 | export const VisualTestDisabled: SwTextareaStory = { 50 | name: "Should disable", 51 | args: { 52 | disabled: true, 53 | modelValue: "Shopware", 54 | }, 55 | play: async ({ canvasElement }) => { 56 | const canvas = within(canvasElement); 57 | 58 | await userEvent.type(canvas.getByRole("textbox"), "1337"); 59 | 60 | expect((canvas.getByRole("textbox") as HTMLInputElement).value).toBe("Shopware"); 61 | }, 62 | }; 63 | 64 | export const TestPlaceholder: SwTextareaStory = { 65 | name: "Should display placeholder", 66 | args: { 67 | placeholder: "Placeholder", 68 | }, 69 | play: ({ canvasElement, args }) => { 70 | const canvas = within(canvasElement); 71 | 72 | expect(canvas.getByPlaceholderText(args.placeholder)).toBeDefined(); 73 | }, 74 | }; 75 | 76 | export const VisualTestError: SwTextareaStory = { 77 | name: "Should display error", 78 | args: { 79 | error: { 80 | code: 500, 81 | detail: "Error while saving!", 82 | }, 83 | }, 84 | play: ({ canvasElement, args }) => { 85 | const canvas = within(canvasElement); 86 | 87 | expect(canvas.getByText(args.error.detail)).toBeDefined(); 88 | }, 89 | }; 90 | -------------------------------------------------------------------------------- /src/components/form/sw-textarea/sw-textarea.stories.ts: -------------------------------------------------------------------------------- 1 | import SwTextarea from "./sw-textarea.vue"; 2 | import type { StoryObj } from "@storybook/vue3"; 3 | import type { SlottedMeta } from "@/_internal/story-helper"; 4 | 5 | export type SwTextareaMeta = SlottedMeta< 6 | typeof SwTextarea, 7 | | "default" 8 | | "change" 9 | | "hint" 10 | | "label" 11 | | "placeholder" 12 | | "error" 13 | | "inheritanceRestore" 14 | | "inheritanceRemove" 15 | | "isInherited" 16 | >; 17 | 18 | export default { 19 | title: "Components/Form/sw-textarea", 20 | component: SwTextarea, 21 | render: (args) => ({ 22 | template: ` 23 |
24 | 32 | 33 | 34 |

hidden

35 |
`, 36 | components: { SwTextarea }, 37 | data() { 38 | return { 39 | currentValue: "", 40 | }; 41 | }, 42 | watch: { 43 | "args.modelValue"(v) { 44 | this.currentValue = v; 45 | }, 46 | }, 47 | created() { 48 | this.currentValue = args.modelValue; 49 | }, 50 | methods: { 51 | onChange(value: string) { 52 | args.change(value); 53 | this.currentValue = value; 54 | }, 55 | }, 56 | setup: () => { 57 | return { 58 | args, 59 | }; 60 | }, 61 | }), 62 | args: { 63 | label: "Textareafield", 64 | }, 65 | argTypes: { 66 | updateModelValue: { 67 | action: "updateModelValue", 68 | table: { 69 | category: "Events", 70 | }, 71 | }, 72 | change: { 73 | action: "change", 74 | table: { 75 | category: "Events", 76 | }, 77 | }, 78 | inheritanceRestore: { 79 | action: "inheritance-restore", 80 | table: { 81 | category: "Events", 82 | }, 83 | }, 84 | inheritanceRemove: { 85 | action: "inheritance-remove", 86 | table: { 87 | category: "Events", 88 | }, 89 | }, 90 | hint: { 91 | control: { type: "text" }, 92 | }, 93 | }, 94 | } as SwTextareaMeta; 95 | 96 | export type SwTextareaStory = StoryObj; 97 | 98 | export const DefaultStory: SwTextareaStory = { 99 | name: "sw-textarea", 100 | }; 101 | -------------------------------------------------------------------------------- /src/components/form/sw-url-field/sw-url-field.stories.ts: -------------------------------------------------------------------------------- 1 | import SwUrlField from "./sw-url-field.vue"; 2 | import baseFieldArgTypes from "../_internal/sw-base-field/arg-types"; 3 | import type { StoryObj } from "@storybook/vue3"; 4 | import type { SlottedMeta } from "@/_internal/story-helper"; 5 | 6 | export type SwUrlFieldMeta = SlottedMeta< 7 | typeof SwUrlField, 8 | | "default" 9 | | "change" 10 | | "hint" 11 | | "label" 12 | | "placeholder" 13 | | "error" 14 | | "inheritanceRestore" 15 | | "inheritanceRemove" 16 | | "isInherited" 17 | | "updateModelValue" 18 | >; 19 | 20 | export default { 21 | title: "Components/Form/sw-url-field", 22 | component: SwUrlField, 23 | render: (args) => ({ 24 | components: { SwUrlField }, 25 | template: `
26 | 33 | 38 | 43 | 48 | 49 | 50 |

hidden

51 |
`, 52 | data() { 53 | return { currentValue: "" }; 54 | }, 55 | watch: { 56 | "args.modelValue"(v) { 57 | this.currentValue = v; 58 | }, 59 | }, 60 | created() { 61 | this.currentValue = args.modelValue; 62 | }, 63 | methods: { 64 | inheritanceRemoveWrapper(a: any) { 65 | args.inheritanceRemove(...a); 66 | args.isInherited = false; 67 | }, 68 | 69 | inheritanceRestoreWrapper(a: any) { 70 | args.inheritanceRestore(...a); 71 | args.isInherited = true; 72 | }, 73 | 74 | onChange(value: string) { 75 | args.change(value); 76 | this.currentValue = value; 77 | }, 78 | }, 79 | setup: () => { 80 | return { 81 | args, 82 | }; 83 | }, 84 | }), 85 | args: { 86 | label: "Url field", 87 | size: "default", 88 | }, 89 | argTypes: { 90 | ...baseFieldArgTypes, 91 | }, 92 | } as SwUrlFieldMeta; 93 | 94 | export type SwUrlFieldStory = StoryObj; 95 | 96 | export const DefaultStory: SwUrlFieldStory = { 97 | name: "sw-url-field", 98 | }; 99 | -------------------------------------------------------------------------------- /src/components/icons-media/sw-icon/sw-icon.interactive.stories.ts: -------------------------------------------------------------------------------- 1 | import { within } from "@storybook/testing-library"; 2 | import { expect } from "@storybook/jest"; 3 | import { waitUntilRendered } from "@/_internal/test-helper"; 4 | 5 | import meta, { type SwIconStory, type SwIconMeta } from "./sw-icon.stories"; 6 | 7 | export default { 8 | ...meta, 9 | title: "Interaction Tests/Icons & Media/sw-icon", 10 | } as SwIconMeta; 11 | 12 | export const VisualTestRenderIcon: SwIconStory = { 13 | name: "Render icon", 14 | play: async ({ canvasElement }) => { 15 | const canvas = within(canvasElement); 16 | 17 | // wait until tab bar is loaded and context button gets rendered 18 | await waitUntilRendered(() => document.getElementById("meteor-icon-kit__regular-products")); 19 | 20 | expect(canvas.findByTestId("sw-icon__regular-products")).toBeDefined(); 21 | }, 22 | }; 23 | 24 | export const VisualTestRenderCalendarIcon: SwIconStory = { 25 | name: "Render calendar icon", 26 | args: { 27 | name: "regular-calendar", 28 | }, 29 | play: async ({ canvasElement }) => { 30 | const canvas = within(canvasElement); 31 | 32 | // wait until tab bar is loaded and context button gets rendered 33 | await waitUntilRendered(() => document.getElementById("meteor-icon-kit__regular-calendar")); 34 | 35 | expect(canvas.findByTestId("sw-icon__regular-calendar")).toBeDefined(); 36 | }, 37 | }; 38 | 39 | export const VisualTestRenderIconInYellow: SwIconStory = { 40 | name: "Render icon in yellow", 41 | args: { 42 | color: "yellow", 43 | }, 44 | play: async ({ canvasElement }) => { 45 | const canvas = within(canvasElement); 46 | 47 | // wait until tab bar is loaded and context button gets rendered 48 | await waitUntilRendered(() => document.getElementById("meteor-icon-kit__regular-products")); 49 | 50 | expect(canvas.findByTestId("sw-icon__regular-products")).toBeDefined(); 51 | expect((await canvas.findByTestId("sw-icon__regular-products")).style.color).toBe("yellow"); 52 | }, 53 | }; 54 | 55 | export const VisualTestRenderIconInHidden: SwIconStory = { 56 | name: "Render icon in hidden", 57 | args: { 58 | decorative: true, 59 | }, 60 | play: async ({ canvasElement }) => { 61 | const canvas = within(canvasElement); 62 | 63 | // wait until tab bar is loaded and context button gets rendered 64 | await waitUntilRendered(() => document.getElementById("meteor-icon-kit__regular-products")); 65 | 66 | expect(canvas.findByTestId("sw-icon__regular-products")).toBeDefined(); 67 | expect((await canvas.findByTestId("sw-icon__regular-products")).ariaHidden).toBe("true"); 68 | }, 69 | }; 70 | -------------------------------------------------------------------------------- /src/components/icons-media/sw-icon/sw-icon.stories.ts: -------------------------------------------------------------------------------- 1 | import SwIcon from "./sw-icon.vue"; 2 | import type { StoryObj } from "@storybook/vue3"; 3 | import type { SlottedMeta } from "@/_internal/story-helper"; 4 | 5 | export type SwIconMeta = SlottedMeta; 6 | 7 | const meta: SwIconMeta = { 8 | title: "Components/Icons & Media/sw-icon", 9 | component: SwIcon, 10 | render: (args) => ({ 11 | components: { SwIcon }, 12 | template: '', 13 | setup: () => { 14 | return { 15 | args, 16 | }; 17 | }, 18 | }), 19 | args: { 20 | name: "regular-products", 21 | color: "#3498db", 22 | decorative: false, 23 | }, 24 | }; 25 | 26 | export default meta; 27 | export type SwIconStory = StoryObj; 28 | 29 | export const Default: SwIconStory = { 30 | name: "sw-icon", 31 | }; 32 | -------------------------------------------------------------------------------- /src/components/icons-media/sw-icon/sw-icon.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 98 | 99 | 122 | -------------------------------------------------------------------------------- /src/components/layout/sw-empty-state/sw-empty-state.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 48 | 49 | 80 | -------------------------------------------------------------------------------- /src/components/navigation/sw-search/sw-search.interactive.stories.ts: -------------------------------------------------------------------------------- 1 | import { within, userEvent } from "@storybook/testing-library"; 2 | import { expect, jest } from "@storybook/jest"; 3 | 4 | import meta, { type SwSearchMeta, type SwSearchStory } from "./sw-search.stories"; 5 | 6 | export default { 7 | ...meta, 8 | title: "Interaction Tests/Navigation/sw-search", 9 | } as SwSearchMeta; 10 | 11 | export const TestInputValue: SwSearchStory = { 12 | name: "Should keep input value", 13 | args: { 14 | change: jest.fn(), 15 | }, 16 | play: async ({ args, canvasElement }) => { 17 | // we can't use canvasElement because it is not available anymore 18 | const canvas = within(canvasElement); 19 | 20 | await userEvent.type(canvas.getByRole("textbox"), "Shopware"); 21 | await userEvent.click(canvas.getByText("hidden")); 22 | 23 | await expect((canvas.getByRole("textbox") as HTMLInputElement).value).toBe("Shopware"); 24 | await expect(args.change).toHaveBeenCalledWith("Shopware"); 25 | }, 26 | }; 27 | 28 | export const VisualTestDefaultSize: SwSearchStory = { 29 | name: "Render the default sized search", 30 | args: { 31 | size: "default", 32 | }, 33 | }; 34 | 35 | export const VisualTestSmallSize: SwSearchStory = { 36 | name: "Render the small sized search", 37 | args: { 38 | size: "small", 39 | }, 40 | }; 41 | 42 | export const VisualTestDefaultSizeDisabled: SwSearchStory = { 43 | name: "Render the default sized search disabled", 44 | args: { 45 | size: "default", 46 | disabled: true, 47 | }, 48 | }; 49 | 50 | export const VisualTestSmallSizeDisabled: SwSearchStory = { 51 | name: "Render the small sized search disabled", 52 | args: { 53 | size: "small", 54 | disabled: true, 55 | }, 56 | }; 57 | -------------------------------------------------------------------------------- /src/components/navigation/sw-search/sw-search.stories.ts: -------------------------------------------------------------------------------- 1 | import SwSearch from "./sw-search.vue"; 2 | import { action } from "@storybook/addon-actions"; 3 | import type { StoryObj } from "@storybook/vue3"; 4 | import { ref } from "vue"; 5 | import type { SlottedMeta } from "@/_internal/story-helper"; 6 | import { fn } from "@storybook/test"; 7 | 8 | export type SwSearchMeta = SlottedMeta; 9 | 10 | const meta: SwSearchMeta = { 11 | title: "Components/Navigation/sw-search", 12 | component: SwSearch, 13 | args: { 14 | modelValue: "", 15 | size: "default", 16 | placeholder: "", 17 | disabled: false, 18 | }, 19 | render: (args) => ({ 20 | components: { SwSearch }, 21 | data() { 22 | return { 23 | currentValue: this.value, 24 | }; 25 | }, 26 | watch: { 27 | value: { 28 | handler(v) { 29 | if (this.currentValue === v) { 30 | return; 31 | } 32 | 33 | this.currentValue = v; 34 | }, 35 | immediate: true, 36 | }, 37 | }, 38 | methods: {}, 39 | template: ` 40 |
41 | 47 | {{ args.default }} 48 | 49 | 50 | 51 |

hidden

52 |
53 | `, 54 | setup: () => { 55 | const currentValue = ref(); 56 | 57 | function changeHandler(value: string) { 58 | fn(action("change"))(value); 59 | if (args.change) args.change(value); 60 | 61 | currentValue.value = value; 62 | } 63 | 64 | function onModelValueHandler(value: string) { 65 | fn(action("updateModelValue"))(value); 66 | 67 | currentValue.value = value; 68 | } 69 | 70 | return { 71 | args, 72 | onModelValueHandler, 73 | changeHandler, 74 | currentValue, 75 | }; 76 | }, 77 | }), 78 | }; 79 | 80 | export default meta; 81 | export type SwSearchStory = StoryObj; 82 | 83 | export const Default: SwSearchStory = { 84 | name: "sw-search", 85 | }; 86 | -------------------------------------------------------------------------------- /src/components/navigation/sw-segmented-control/sw-segmented-control.interactive.stories.ts: -------------------------------------------------------------------------------- 1 | import { userEvent, within } from "@storybook/testing-library"; 2 | import { expect } from "@storybook/jest"; 3 | 4 | import meta, { 5 | type SwSegmentedControlMeta, 6 | type SwSegmentedControlStory, 7 | } from "./sw-segmented-control.stories"; 8 | 9 | export default { 10 | ...meta, 11 | title: "Interaction Tests/Navigation/sw-segmented-control", 12 | } as SwSegmentedControlMeta; 13 | 14 | export const VisualTestRenderSegmentedControl: SwSegmentedControlStory = { 15 | name: "Render segmented controls", 16 | }; 17 | 18 | export const VisualTestRenderSegmentedControlWithContext: SwSegmentedControlStory = { 19 | name: "Render segmented controls with context", 20 | args: { 21 | disableContext: false, 22 | }, 23 | }; 24 | 25 | export const VisualTestRenderSegmentedControlWithPopoverBase: SwSegmentedControlStory = { 26 | name: "Render segmented controls with popover base", 27 | play: async ({ canvasElement }) => { 28 | const canvas = within(canvasElement); 29 | 30 | const button = await canvas.getByText("Label F"); 31 | 32 | await userEvent.click(button); 33 | 34 | const popoverContent = document.getElementsByClassName("sw-popover__content")[0]; 35 | if (!popoverContent) { 36 | throw new Error("Popover content not found"); 37 | } 38 | 39 | // Look inside the popover 40 | const popover = within(popoverContent as HTMLElement); 41 | 42 | const firstLevel = await popover.getByText("First level"); 43 | await expect(firstLevel).toBeInTheDocument(); 44 | }, 45 | }; 46 | 47 | export const VisualTestRenderSegmentedControlWithPopoverSecondLevel: SwSegmentedControlStory = { 48 | name: "Render segmented controls with popover second level", 49 | play: async ({ canvasElement }) => { 50 | const canvas = within(canvasElement); 51 | 52 | const button = await canvas.getByText("Label F"); 53 | 54 | await userEvent.click(button); 55 | 56 | const popoverContent = document.getElementsByClassName("sw-popover__content")[0]; 57 | if (!popoverContent) { 58 | throw new Error("Popover content not found"); 59 | } 60 | 61 | // Look inside the popover 62 | const popover = within(popoverContent as HTMLElement); 63 | 64 | const goToSecondLevel = await popover.getByText("Go to second level"); 65 | await userEvent.click(goToSecondLevel); 66 | 67 | const secondLevel = await popover.getByText("Second level"); 68 | await expect(secondLevel).toBeInTheDocument(); 69 | 70 | const goToThirdLevel = await popover.getByText("Go to third level"); 71 | await expect(goToThirdLevel).toBeInTheDocument(); 72 | }, 73 | }; 74 | -------------------------------------------------------------------------------- /src/components/navigation/sw-tabs/sw-tabs.stories.ts: -------------------------------------------------------------------------------- 1 | import SwTabs from "./sw-tabs.vue"; 2 | import type { StoryObj } from "@storybook/vue3"; 3 | import type { SlottedMeta } from "@/_internal/story-helper"; 4 | 5 | const tabItems = [ 6 | { 7 | label: "Item 1", 8 | name: "item1", 9 | }, 10 | { 11 | label: "Item 2 very long", 12 | name: "item2", 13 | }, 14 | { 15 | label: "Item 3", 16 | name: "item3", 17 | }, 18 | { 19 | label: "Item 4 also very long", 20 | name: "item4", 21 | }, 22 | { 23 | label: "Item 5", 24 | name: "item5", 25 | }, 26 | { 27 | label: "Item 6", 28 | name: "item6", 29 | }, 30 | { 31 | label: "Item 7", 32 | name: "item7", 33 | }, 34 | { 35 | label: "Item 8 very long", 36 | name: "item8", 37 | }, 38 | { 39 | label: "Item 9", 40 | name: "item9", 41 | }, 42 | { 43 | label: "Item 10", 44 | name: "item10", 45 | }, 46 | { 47 | label: "Item 11", 48 | name: "item11", 49 | }, 50 | { 51 | label: "Item 12", 52 | name: "item12", 53 | }, 54 | { 55 | label: "Item 13", 56 | name: "item13", 57 | }, 58 | { 59 | label: "Item 14", 60 | name: "item14", 61 | }, 62 | { 63 | label: "Item 15", 64 | name: "item15", 65 | }, 66 | { 67 | label: "Item 16", 68 | name: "item16", 69 | }, 70 | { 71 | label: "Item 17", 72 | name: "item17", 73 | }, 74 | ]; 75 | 76 | export type SwTabsMeta = SlottedMeta; 77 | 78 | export default { 79 | title: "Components/Navigation/sw-tabs", 80 | component: SwTabs, 81 | render: (args) => ({ 82 | components: { SwTabs }, 83 | template: ` 84 | `, 85 | setup: () => { 86 | return { 87 | args, 88 | }; 89 | }, 90 | }), 91 | args: { 92 | vertical: false, 93 | small: false, 94 | defaultItem: "item1", 95 | }, 96 | } as SwTabsMeta; 97 | 98 | export type SwTabsStory = StoryObj; 99 | 100 | export const Default: SwTabsStory = { 101 | name: "sw-tabs", 102 | args: { 103 | items: tabItems, 104 | small: true, 105 | }, 106 | }; 107 | -------------------------------------------------------------------------------- /src/components/navigation/sw-tabs/sw.tabs.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount } from "@vue/test-utils"; 2 | import SwTabs from "./sw-tabs.vue"; 3 | 4 | async function createWrapper(customOptions = {}, props = {}) { 5 | return mount(SwTabs, { 6 | props: { 7 | items: [ 8 | { 9 | name: "foo", 10 | label: "Foo", 11 | }, 12 | { 13 | name: "bar", 14 | label: "Bar", 15 | }, 16 | ], 17 | ...props, 18 | }, 19 | global: { 20 | stubs: { 21 | "sw-icon": true, 22 | }, 23 | mocks: { 24 | $device: { 25 | onResize: () => {}, 26 | removeResizeListener: () => {}, 27 | }, 28 | }, 29 | }, 30 | ...customOptions, 31 | }); 32 | } 33 | 34 | describe("src/app/component/navigation/sw-tabs", () => { 35 | let wrapper: undefined | Awaited>; 36 | 37 | afterEach(() => { 38 | if (wrapper) { 39 | wrapper.unmount(); 40 | } 41 | }); 42 | 43 | it("should be a Vue.JS component", async () => { 44 | wrapper = await createWrapper(); 45 | expect(wrapper.vm).toBeTruthy(); 46 | }); 47 | 48 | it("should emit on clicked tab", async () => { 49 | wrapper = await createWrapper(); 50 | 51 | await wrapper.find(".sw-tabs--item[data-item-name=bar]").trigger("click"); 52 | 53 | expect(wrapper.emitted("new-item-active")?.[0]).toStrictEqual(["bar"]); 54 | }); 55 | 56 | it("should emit on clicked vertical tab", async () => { 57 | wrapper = await createWrapper(undefined, { 58 | vertical: true, 59 | }); 60 | 61 | await wrapper.find(".sw-tabs--item[data-item-name=bar]").trigger("click"); 62 | 63 | expect(wrapper.emitted("new-item-active")?.[0]).toStrictEqual(["bar"]); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /src/components/overlay/sw-popover/sw-popover.interfaces.ts: -------------------------------------------------------------------------------- 1 | import type { TranslateResult } from "vue-i18n"; 2 | 3 | export interface View { 4 | name: string | TranslateResult; 5 | title?: string | TranslateResult; 6 | childViews?: View[]; 7 | } 8 | -------------------------------------------------------------------------------- /src/components/overlay/sw-popover/sw-popover.stories.interactive.stories.ts: -------------------------------------------------------------------------------- 1 | import { waitUntilRendered } from "../../../_internal/test-helper"; 2 | import { within, userEvent } from "@storybook/testing-library"; 3 | import { expect } from "@storybook/jest"; 4 | 5 | import meta, { type SwPopoverMeta, type SwPopoverStory } from "./sw-popover.stories"; 6 | 7 | export default { 8 | ...meta, 9 | title: "Interaction Tests/Overlay/sw-popover", 10 | } as SwPopoverMeta; 11 | 12 | export const VisualTestRenderPopoverTrigger: SwPopoverStory = { 13 | name: "Should render only the popover trigger", 14 | }; 15 | 16 | export const VisualTestRenderPopover: SwPopoverStory = { 17 | name: "Should render the popover", 18 | play: async ({ canvasElement }) => { 19 | const canvas = within(canvasElement); 20 | 21 | await waitUntilRendered(() => document.body.textContent?.includes("Toggle popover")); 22 | 23 | const popoverToggle = canvas.getByText("Toggle popover"); 24 | await userEvent.click(popoverToggle); 25 | 26 | const popover = within(document.querySelector(".sw-floating-ui__content") as HTMLElement); 27 | expect(popover.getByText("Popover example")).toBeInTheDocument(); 28 | }, 29 | }; 30 | 31 | export const VisualTestRenderChildView: SwPopoverStory = { 32 | name: "Should render the popover with child view", 33 | play: async ({ canvasElement }) => { 34 | const canvas = within(canvasElement); 35 | 36 | await waitUntilRendered(() => document.body.textContent?.includes("Toggle popover")); 37 | 38 | const popoverToggle = canvas.getByText("Toggle popover"); 39 | await userEvent.click(popoverToggle); 40 | 41 | const popover = within(document.querySelector(".sw-floating-ui__content") as HTMLElement); 42 | expect(popover.getByText("Popover example")).toBeInTheDocument(); 43 | 44 | const columnsItem = popover.getByText("Columns"); 45 | 46 | await userEvent.click(columnsItem); 47 | }, 48 | }; 49 | 50 | export const VisualTestRenderWithoutFloat: SwPopoverStory = { 51 | name: "Should render the popover with disabled float and without trigger", 52 | args: { 53 | disableFloat: true, 54 | }, 55 | play: async ({ canvasElement }) => { 56 | const canvas = within(canvasElement); 57 | 58 | await waitUntilRendered(() => document.body.textContent?.includes("Popover example")); 59 | 60 | expect(canvas.getByText("Popover example")).toBeInTheDocument(); 61 | }, 62 | }; 63 | -------------------------------------------------------------------------------- /src/components/table-and-list/sw-data-table/renderer/sw-data-table-badge-renderer.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 76 | -------------------------------------------------------------------------------- /src/components/table-and-list/sw-data-table/renderer/sw-data-table-number-renderer.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 53 | 54 | 64 | -------------------------------------------------------------------------------- /src/components/table-and-list/sw-data-table/renderer/sw-data-table-price-renderer.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 93 | 94 | 104 | -------------------------------------------------------------------------------- /src/components/table-and-list/sw-data-table/renderer/sw-data-table-text-renderer.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 53 | 54 | 68 | -------------------------------------------------------------------------------- /src/components/table-and-list/sw-pagination/sw-pagination.interactive.stories.js: -------------------------------------------------------------------------------- 1 | import { expect } from "@storybook/jest"; 2 | import SwPagination from "./sw-pagination.vue"; 3 | import defaultPaginationStory, { Default } from "./sw-pagination.stories"; 4 | import flushPromises from "flush-promises"; 5 | 6 | export default { 7 | ...defaultPaginationStory, 8 | title: "Interaction Tests/Table and list/sw-pagination", 9 | component: SwPagination, 10 | }; 11 | 12 | export const TestOnePage = { 13 | render: Default.render, 14 | name: "Render with one page", 15 | 16 | args: { 17 | ...Default.args, 18 | limit: 100, 19 | }, 20 | 21 | play: async () => { 22 | const infoText = document.querySelector(".sw-pagination__info-text"); 23 | 24 | expect(infoText).not.toBeNull(); 25 | expect(infoText.innerText).toEqual("1-100 of 100"); 26 | }, 27 | }; 28 | 29 | export const TestManyPages = { 30 | render: Default.render, 31 | name: "Render with 100 page", 32 | 33 | args: { 34 | ...Default.args, 35 | limit: 1, 36 | }, 37 | 38 | play: async () => { 39 | const infoText = document.querySelector(".sw-pagination__info-text"); 40 | 41 | expect(infoText).not.toBeNull(); 42 | expect(infoText.innerText).toEqual("1-1 of 100"); 43 | }, 44 | }; 45 | 46 | export const TestPageChange = { 47 | render: Default.render, 48 | name: "Test page change", 49 | }; 50 | 51 | (TestPageChange.args = Default.args), 52 | (TestPageChange.play = async () => { 53 | document.querySelector(".sw-segmented-control__action-id-pagination-next").click(); 54 | 55 | await flushPromises(); 56 | 57 | const infoText = document.querySelector(".sw-pagination__info-text"); 58 | 59 | expect(infoText).not.toBeNull(); 60 | expect(infoText.innerText).toEqual("26-50 of 100"); 61 | }); 62 | -------------------------------------------------------------------------------- /src/components/table-and-list/sw-pagination/sw-pagination.stories.ts: -------------------------------------------------------------------------------- 1 | import SwPagination from "./sw-pagination.vue"; 2 | import type { StoryObj } from "@storybook/vue3"; 3 | import { action } from "@storybook/addon-actions"; 4 | import type { SlottedMeta } from "@/_internal/story-helper"; 5 | import { ref } from "vue"; 6 | import { fn } from "@storybook/test"; 7 | 8 | const meta: SlottedMeta = { 9 | title: "Components/Table and list/sw-pagination", 10 | component: SwPagination, 11 | }; 12 | 13 | export default meta; 14 | type Story = StoryObj; 15 | 16 | export const Default: Story = { 17 | render: (args) => ({ 18 | components: { SwPagination }, 19 | setup: () => { 20 | const page = ref(1); 21 | 22 | return { 23 | page, 24 | onChangeCurrentPage: ($event: number) => { 25 | fn(action("change-current-page"))($event); 26 | page.value = $event; 27 | }, 28 | args, 29 | }; 30 | }, 31 | template: ``, 32 | }), 33 | 34 | args: { 35 | totalItems: 100, 36 | limit: 25, 37 | }, 38 | 39 | name: "sw-pagination", 40 | }; 41 | -------------------------------------------------------------------------------- /src/composables/useEmptySlotCheck.ts: -------------------------------------------------------------------------------- 1 | import { Fragment } from "react"; 2 | import { Comment, Text, type Slot, type VNode } from "vue"; 3 | 4 | function hasSlotContent(slot: Slot | undefined | null, props: any = {}) { 5 | return !isSlotEmpty(slot, props); 6 | } 7 | 8 | function isSlotEmpty(slot: Slot | undefined | null, props: any = {}) { 9 | return isVNodeEmpty(slot?.(props)); 10 | } 11 | 12 | function isVNodeEmpty(vnode: VNode | VNode[] | undefined | null) { 13 | return ( 14 | !vnode || 15 | asArray(vnode).every( 16 | (vnode) => 17 | vnode.type === Comment || 18 | (vnode.type === Text && !vnode.children?.length) || 19 | (vnode.type === Fragment && !vnode.children?.length), 20 | ) 21 | ); 22 | } 23 | 24 | function asArray(arg: T | T[] | null) { 25 | return Array.isArray(arg) ? arg : arg !== null ? [arg] : []; 26 | } 27 | 28 | export default function useEmptySlotCheck() { 29 | return { 30 | hasSlotContent, 31 | isSlotEmpty, 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /src/directives/stickyColumn.directive.ts: -------------------------------------------------------------------------------- 1 | import { throttle } from "lodash-es"; 2 | import type { Directive } from "vue"; 3 | 4 | const getPreviousSibling = function (el: Element | undefined, selector: string) { 5 | if (!el) return; 6 | 7 | // Get the next sibling element 8 | let sibling = el.previousElementSibling; 9 | 10 | // If there's no selector, return the first sibling 11 | if (!selector) return sibling; 12 | 13 | // If the sibling matches our selector, use it 14 | // If not, jump to the next sibling and continue the loop 15 | while (sibling) { 16 | if (sibling.matches(selector)) return sibling; 17 | sibling = sibling.previousElementSibling; 18 | } 19 | }; 20 | 21 | const setLeftValue = (el: HTMLElement) => { 22 | // Calculate the width of all previous sticky column siblings 23 | let width = 0; 24 | let sibling = getPreviousSibling(el, "[data-sticky-column]"); 25 | while (sibling) { 26 | width += sibling.clientWidth; 27 | sibling = getPreviousSibling(sibling, "[data-sticky-column]"); 28 | } 29 | 30 | // Set the left position of the column to the difference between the table and column x positions 31 | el.style.left = `${width - 0.5}px`; 32 | el.dataset.stickyColumnRight = `${width + el.getBoundingClientRect().width - 0.5}`; 33 | }; 34 | 35 | let mutationObserver: MutationObserver | undefined; 36 | 37 | const stickyColumn: Directive = { 38 | beforeMount(el) { 39 | el.dataset.stickyColumn = ""; 40 | }, 41 | mounted(el) { 42 | // Set the left value on load 43 | setLeftValue(el); 44 | 45 | // Set the left value on mutation 46 | mutationObserver = new MutationObserver( 47 | throttle(() => { 48 | setLeftValue(el); 49 | }, 60), 50 | ); 51 | 52 | mutationObserver.observe(el.parentElement as Element, { 53 | childList: true, 54 | subtree: true, 55 | }); 56 | }, 57 | unmounted() { 58 | mutationObserver?.disconnect(); 59 | }, 60 | }; 61 | 62 | export default stickyColumn; 63 | -------------------------------------------------------------------------------- /src/directives/tooltip.interactive.stories.js: -------------------------------------------------------------------------------- 1 | import meta from "./tooltip.stories"; 2 | import { within, userEvent } from "@storybook/testing-library"; 3 | import { expect } from "@storybook/jest"; 4 | import { waitUntilRendered } from "../_internal/test-helper"; 5 | 6 | export default { 7 | ...meta, 8 | title: "Interaction Tests/Directives/Tooltip", 9 | }; 10 | 11 | export const VisualTestRenderIcon = { 12 | name: "Render icon", 13 | }; 14 | 15 | export const VisualTestRenderTooltip = { 16 | name: "Render tooltip", 17 | args: { 18 | message: "This is the help text", 19 | }, 20 | play: async ({ canvasElement }) => { 21 | const canvas = within(canvasElement); 22 | 23 | const icon = await canvas.getByTestId("sw-icon__regular-question-circle"); 24 | 25 | await userEvent.hover(icon); 26 | 27 | // wait until tooltip is loaded 28 | await waitUntilRendered(() => document.querySelector(".sw-tooltip")); 29 | 30 | const tooltip = within(document.getElementsByClassName("sw-tooltip")[0]); 31 | const helpText = tooltip.getByText("This is the help text"); 32 | 33 | expect(helpText).toBeDefined(); 34 | }, 35 | }; 36 | 37 | export const VisualTestRenderTooltipInWide = { 38 | name: "Render tooltip in wide", 39 | args: { 40 | message: "This is the help text", 41 | width: 300, 42 | }, 43 | play: async ({ canvasElement }) => { 44 | const canvas = within(canvasElement); 45 | 46 | const icon = canvas.getByTestId("sw-icon__regular-question-circle"); 47 | 48 | await userEvent.hover(icon); 49 | 50 | // wait until tooltip is loaded 51 | await waitUntilRendered(() => document.querySelector(".sw-tooltip")); 52 | await waitUntilRendered(() => document.querySelector(".sw-tooltip")); 53 | 54 | const tooltip = within(document.getElementsByClassName("sw-tooltip")[0]); 55 | const helpText = tooltip.getByText("This is the help text"); 56 | 57 | expect(helpText).toBeDefined(); 58 | }, 59 | }; 60 | -------------------------------------------------------------------------------- /src/directives/tooltip.stories.ts: -------------------------------------------------------------------------------- 1 | import SwIcon from "../components/icons-media/sw-icon/sw-icon.vue"; 2 | import TooltipDirective from "./tooltip.directive"; 3 | import type { SlottedMeta } from "@/_internal/story-helper"; 4 | import { defineComponent } from "vue"; 5 | 6 | const meta: SlottedMeta< 7 | typeof SwIcon, 8 | | "message" 9 | | "width" 10 | | "showDelay" 11 | | "hideDelay" 12 | | "disabled" 13 | | "appearance" 14 | | "showOnDisabledElements" 15 | > = { 16 | title: "Directives/Tooltip", 17 | component: SwIcon, 18 | render: (args) => 19 | defineComponent({ 20 | components: { SwIcon }, 21 | directives: { 22 | tooltip: TooltipDirective, 23 | }, 24 | template: `
25 | 30 | 31 |
`, 32 | setup: () => { 33 | return { 34 | args, 35 | }; 36 | }, 37 | }), 38 | args: { 39 | message: "Help text", 40 | width: 200, 41 | showDelay: 100, 42 | hideDelay: 100, 43 | disabled: false, 44 | appearance: "dark", 45 | showOnDisabledElements: false, 46 | }, 47 | argTypes: { 48 | appearance: { 49 | control: { 50 | type: "radio", 51 | options: ["dark", "light"], 52 | }, 53 | }, 54 | /** 55 | * Disable name, color and decorative because they 56 | * are automatically generated and don't belong to 57 | * the directive 58 | */ 59 | name: { 60 | table: { 61 | disable: true, 62 | }, 63 | }, 64 | color: { 65 | table: { 66 | disable: true, 67 | }, 68 | }, 69 | decorative: { 70 | table: { 71 | disable: true, 72 | }, 73 | }, 74 | }, 75 | }; 76 | 77 | export default meta; 78 | 79 | export const Default = { 80 | name: "Tooltip", 81 | }; 82 | -------------------------------------------------------------------------------- /src/filters/salutation.filter.js: -------------------------------------------------------------------------------- 1 | export default function (entity, fallbackSnippet = "") { 2 | const defaultSalutationId = "ed643807c9f84cc8b50132ea3ccb1c3b"; 3 | 4 | if (!entity) { 5 | return fallbackSnippet; 6 | } 7 | 8 | let hideSalutation = true; 9 | 10 | if (entity.salutation && entity.salutation.id !== defaultSalutationId) { 11 | hideSalutation = ["not_specified"].some((item) => item === entity.salutation.salutationKey); 12 | } 13 | 14 | const params = { 15 | salutation: !hideSalutation ? entity.salutation.displayName : "", 16 | title: entity.title || "", 17 | firstName: entity.firstName || "", 18 | lastName: entity.lastName || "", 19 | }; 20 | 21 | const fullname = Object.values(params).join(" ").replace(/\s+/g, " ").trim(); 22 | 23 | if (fullname === "") { 24 | return fallbackSnippet; 25 | } 26 | 27 | return fullname; 28 | } 29 | -------------------------------------------------------------------------------- /src/filters/unicode-uri.filter.ts: -------------------------------------------------------------------------------- 1 | import punycode from "punycode/"; 2 | 3 | export default function (value: string) { 4 | if (!value) { 5 | return ""; 6 | } 7 | 8 | const unicode = punycode.toUnicode(value); 9 | 10 | return decodeURI(unicode); 11 | } 12 | -------------------------------------------------------------------------------- /src/helper/provideInjectKeys.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey } from "vue"; 2 | 3 | export const swSelectResultAddActiveItemListener = Symbol() as InjectionKey< 4 | (listener: (index: number) => void) => void 5 | >; 6 | export const swSelectResultRemoveActiveItemListener = Symbol() as InjectionKey< 7 | (listener: (index: number) => void) => void 8 | >; 9 | export const swSelectResultAddItemSelectByKeyboardListener = Symbol() as InjectionKey< 10 | (listener: (index: number) => void) => void 11 | >; 12 | export const swSelectResultRemoveItemSelectByKeyboardListener = Symbol() as InjectionKey< 13 | (listener: (index: number) => void) => void 14 | >; 15 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import SwDatepicker from "./components/form/sw-datepicker/sw-datepicker.vue"; 2 | import SwBanner from "./components/feedback-indicator/sw-banner/sw-banner.vue"; 3 | import SwLoader from "./components/feedback-indicator/sw-loader/sw-loader.vue"; 4 | import SwProgressBar from "./components/feedback-indicator/sw-progress-bar/sw-progress-bar.vue"; 5 | import SwButton from "./components/form/sw-button/sw-button.vue"; 6 | import SwCheckbox from "./components/form/sw-checkbox/sw-checkbox.vue"; 7 | import SwColorpicker from "./components/form/sw-colorpicker/sw-colorpicker.vue"; 8 | import SwEmailField from "./components/form/sw-email-field/sw-email-field.vue"; 9 | import SwExternalLink from "./components/form/sw-external-link/sw-external-link.vue"; 10 | import SwNumberField from "./components/form/sw-number-field/sw-number-field.vue"; 11 | import SwPasswordField from "./components/form/sw-password-field/sw-password-field.vue"; 12 | import SwSelect from "./components/form/sw-select/sw-select.vue"; 13 | import SwSwitch from "./components/form/sw-switch/sw-switch.vue"; 14 | import SwTextField from "./components/form/sw-text-field/sw-text-field.vue"; 15 | import SwTextarea from "./components/form/sw-textarea/sw-textarea.vue"; 16 | import SwUrlField from "./components/form/sw-url-field/sw-url-field.vue"; 17 | import SwIcon from "./components/icons-media/sw-icon/sw-icon.vue"; 18 | import SwCard from "./components/layout/sw-card/sw-card.vue"; 19 | import SwTabs from "./components/navigation/sw-tabs/sw-tabs.vue"; 20 | import SwDataTable from "./components/table-and-list/sw-data-table/sw-data-table.vue"; 21 | import SwPagination from "./components/table-and-list/sw-pagination/sw-pagination.vue"; 22 | import SwSkeletonBar from "./components/feedback-indicator/sw-skeleton-bar/sw-skeleton-bar.vue"; 23 | import TooltipDirective from "./directives/tooltip.directive"; 24 | import DeviceHelperPlugin from "./plugin/device-helper.plugin"; 25 | // Import SCSS for styling 26 | import "./components/assets/scss/all.scss"; 27 | 28 | export { 29 | SwBanner, 30 | SwLoader, 31 | SwProgressBar, 32 | SwButton, 33 | SwCheckbox, 34 | SwColorpicker, 35 | SwDatepicker, 36 | SwEmailField, 37 | SwExternalLink, 38 | SwNumberField, 39 | SwPasswordField, 40 | SwSelect, 41 | SwSwitch, 42 | SwTextField, 43 | SwTextarea, 44 | SwUrlField, 45 | SwIcon, 46 | SwCard, 47 | SwTabs, 48 | SwDataTable, 49 | SwPagination, 50 | SwSkeletonBar, 51 | TooltipDirective, 52 | DeviceHelperPlugin, 53 | }; 54 | -------------------------------------------------------------------------------- /src/mixins/form-field.mixin.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from "vue"; 2 | 3 | export default defineComponent({ 4 | props: { 5 | mapInheritance: { 6 | type: Object, 7 | required: false, 8 | default: null, 9 | }, 10 | 11 | name: { 12 | type: String, 13 | required: false, 14 | default: null, 15 | }, 16 | }, 17 | 18 | computed: { 19 | formFieldName() { 20 | if (this.$attrs.name) { 21 | return this.$attrs.name as string; 22 | } 23 | 24 | if (this.name) { 25 | return this.name; 26 | } 27 | 28 | return undefined; 29 | }, 30 | }, 31 | }); 32 | -------------------------------------------------------------------------------- /src/mixins/validation.mixin.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from "vue"; 2 | import validationService from "../services/validation.service"; 3 | 4 | export default defineComponent({ 5 | props: { 6 | validation: { 7 | type: [String, Array, Object, Boolean], 8 | required: false, 9 | default: null, 10 | }, 11 | }, 12 | 13 | computed: { 14 | isValid(): boolean { 15 | // @ts-expect-error 16 | const value = this.currentValue || this.value || this.selections; 17 | 18 | return this.validate(value); 19 | }, 20 | }, 21 | 22 | methods: { 23 | validate(value: unknown): boolean { 24 | let { validation } = this; 25 | let valid = true; 26 | 27 | if (typeof validation === "boolean") { 28 | return validation; 29 | } 30 | 31 | if (typeof validation === "string") { 32 | const validationList = validation.split(","); 33 | 34 | if (validationList.length > 1) { 35 | validation = validationList; 36 | } else { 37 | // @ts-expect-error 38 | valid = this.validateRule(value, this.validation); 39 | } 40 | } 41 | 42 | if (Array.isArray(validation)) { 43 | valid = validation.every((validationRule) => { 44 | if (typeof validationRule === "boolean") { 45 | return validationRule; 46 | } 47 | 48 | return this.validateRule(value, validationRule.trim()); 49 | }); 50 | } 51 | 52 | return valid; 53 | }, 54 | 55 | validateRule(value: unknown, rule: string): boolean { 56 | // @ts-expect-error 57 | if (typeof validationService[rule] === "undefined") { 58 | return false; 59 | } 60 | 61 | // @ts-expect-error 62 | return validationService[rule](value); 63 | }, 64 | }, 65 | }); 66 | -------------------------------------------------------------------------------- /src/plugin/device-helper.plugin.ts: -------------------------------------------------------------------------------- 1 | import type { Plugin } from "vue"; 2 | // @ts-expect-error 3 | import DeviceHelper from "../helper/device.helper"; 4 | 5 | const DeviceHelperPlugin: Plugin = { 6 | install(app) { 7 | const deviceHelper = new DeviceHelper(); 8 | 9 | app.config.globalProperties.$device = deviceHelper; 10 | app.mixin({ 11 | unmounted() { 12 | this.$device.removeResizeListener(this); 13 | }, 14 | }); 15 | 16 | return true; 17 | }, 18 | }; 19 | 20 | export default DeviceHelperPlugin; 21 | -------------------------------------------------------------------------------- /src/services/validation.service.ts: -------------------------------------------------------------------------------- 1 | import { isObject } from "lodash-es"; 2 | 3 | /** 4 | * Checks if a value is set based on its type. 5 | */ 6 | export function required(value: unknown): boolean { 7 | if (typeof value === "string" && value.length <= 0) { 8 | return false; 9 | } 10 | 11 | if (typeof value === "boolean") { 12 | return value === true; 13 | } 14 | 15 | if (isObject(value)) { 16 | return Object.keys(value).length > 0; 17 | } 18 | 19 | return typeof value !== "undefined" && value !== null; 20 | } 21 | 22 | /** 23 | * Checks the value against the given regular expression. 24 | */ 25 | export function regex(value: string, expression: RegExp | string): boolean { 26 | if (expression instanceof RegExp) { 27 | return expression.test(value); 28 | } 29 | 30 | return new RegExp(expression).test(value); 31 | } 32 | 33 | /** 34 | * Checks if the value is a valid email address. 35 | */ 36 | export function email(value: string): boolean { 37 | const emailValidation = 38 | // eslint-disable-next-line no-useless-escape 39 | /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 40 | 41 | return regex(value, emailValidation); 42 | } 43 | 44 | export default { 45 | required, 46 | regex, 47 | email, 48 | }; 49 | -------------------------------------------------------------------------------- /src/shims-vue.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shopwareArchive/meteor-component-library/61329b3472c62557c36d9b1da6700a78eb3adbea/src/shims-vue.d.ts -------------------------------------------------------------------------------- /src/utils/dom.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns the scrollbar height of an HTML element. 3 | */ 4 | export function getScrollbarHeight(element: HTMLElement): number { 5 | if (!(element instanceof HTMLElement)) { 6 | console.warn( 7 | "DOM Utilities", 8 | 'The provided element needs to be an instance of "HTMLElement".', 9 | element, 10 | ); 11 | return 0; 12 | } 13 | return element.offsetHeight - element.clientHeight; 14 | } 15 | 16 | /** 17 | * Returns the scrollbar width of an HTML element. 18 | */ 19 | export function getScrollbarWidth(element: HTMLElement): number { 20 | if (!(element instanceof HTMLElement)) { 21 | console.warn( 22 | "DOM Utilities", 23 | 'The provided element needs to be an instance of "HTMLElement".', 24 | element, 25 | ); 26 | return 0; 27 | } 28 | return element.offsetWidth - element.clientWidth; 29 | } 30 | 31 | /** 32 | * uses the browser's copy function to copy a string 33 | */ 34 | export function copyToClipboard(stringToCopy: string): void { 35 | const tempTextArea = document.createElement("textarea"); 36 | tempTextArea.value = stringToCopy; 37 | document.body.appendChild(tempTextArea); 38 | tempTextArea.select(); 39 | document.execCommand("copy"); 40 | document.body.removeChild(tempTextArea); 41 | } 42 | 43 | export default { 44 | getScrollbarHeight, 45 | getScrollbarWidth, 46 | copyToClipboard, 47 | }; 48 | -------------------------------------------------------------------------------- /src/utils/format.ts: -------------------------------------------------------------------------------- 1 | export interface CurrencyOptions extends Intl.NumberFormatOptions { 2 | language?: string; 3 | } 4 | 5 | export function currency( 6 | val: number, 7 | sign: string, 8 | decimalPlaces?: number, 9 | additionalOptions: CurrencyOptions = {}, 10 | ): string { 11 | const decimalOpts = 12 | decimalPlaces !== undefined 13 | ? { 14 | minimumFractionDigits: decimalPlaces, 15 | maximumFractionDigits: decimalPlaces, 16 | } 17 | : { 18 | minimumFractionDigits: 2, 19 | maximumFractionDigits: 20, 20 | }; 21 | 22 | const opts = { 23 | style: "currency", 24 | currency: sign, 25 | ...decimalOpts, 26 | ...additionalOptions, 27 | }; 28 | 29 | // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-argument 30 | return val.toLocaleString(additionalOptions.language ?? "en-US", opts); 31 | } 32 | -------------------------------------------------------------------------------- /src/utils/object.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Deep copy an object 3 | */ 4 | // eslint-disable-next-line @typescript-eslint/ban-types 5 | export function deepCopyObject(copyObject: O): O { 6 | return JSON.parse(JSON.stringify(copyObject)) as O; 7 | } 8 | 9 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 10 | export function hasOwnProperty(scope: any, prop: string): boolean { 11 | return Object.prototype.hasOwnProperty.call(scope, prop); 12 | } 13 | 14 | export default { 15 | deepCopyObject, 16 | hasOwnProperty, 17 | }; 18 | -------------------------------------------------------------------------------- /src/utils/sort.ts: -------------------------------------------------------------------------------- 1 | interface SortElements { 2 | id: string; 3 | data: Record; 4 | } 5 | 6 | /** 7 | * Sorts the elements by their after id property chain 8 | * 9 | * @param {array} elements 10 | * @param {string} property 11 | * @returns {array} 12 | */ 13 | export function afterSort(elements: SortElements[], property = "afterId"): SortElements[] { 14 | if (elements.length === 0) { 15 | return elements; 16 | } 17 | 18 | // pre-sort elements to pull elements without an after id parent to the front 19 | elements.sort((a, b) => { 20 | if (a.data[property] === b.data[property] && a.data[property] === null) { 21 | return 0; 22 | } 23 | 24 | if (b.data[property] === null) { 25 | return 1; 26 | } 27 | 28 | if (a.data[property] === null) { 29 | return -1; 30 | } 31 | 32 | return 0; 33 | }); 34 | 35 | // add first element to sorted list as this will be the absolute first item 36 | const firstItem = elements.shift(); 37 | const sortedElements = [firstItem]; 38 | 39 | let lastId = firstItem?.id; 40 | 41 | while (elements.length > 0) { 42 | let loop = true; 43 | 44 | elements.forEach((leaf, key) => { 45 | if (leaf.data[property] !== lastId) { 46 | return; 47 | } 48 | 49 | // find the next element in the chain and set it as the new parent 50 | sortedElements.push(leaf); 51 | lastId = leaf.id; 52 | 53 | elements.splice(key, 1); 54 | loop = false; 55 | }); 56 | 57 | // chain is broken, continue with next element as parent 58 | if (loop) { 59 | const nextItem = elements.shift(); 60 | 61 | sortedElements.push(nextItem); 62 | 63 | if (!elements.length) { 64 | break; 65 | } 66 | 67 | lastId = nextItem && (nextItem.data[property] as string); 68 | } 69 | } 70 | 71 | return sortedElements as SortElements[]; 72 | } 73 | 74 | export default { 75 | afterSort, 76 | }; 77 | -------------------------------------------------------------------------------- /src/utils/uuid.ts: -------------------------------------------------------------------------------- 1 | function uuidv4() { 2 | // @ts-expect-error 3 | return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => 4 | (c ^ (window.crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16), 5 | ); 6 | } 7 | 8 | /** 9 | * Returns a uuid string in hex format. 10 | * 11 | * @returns {String} 12 | */ 13 | export function createId() { 14 | // eslint-disable-next-line max-len 15 | return uuidv4().replace(/-/g, ""); 16 | } 17 | 18 | export default { 19 | createId, 20 | }; 21 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": [ 4 | "env.d.ts", 5 | "src/**/*", 6 | "src/**/*.vue", 7 | "src/**/*.ts", 8 | "src/**/*.js", 9 | "src/**/*.json" 10 | ], 11 | "exclude": ["src/**/__tests__/*"], 12 | "compilerOptions": { 13 | "composite": true, 14 | "baseUrl": ".", 15 | "paths": { 16 | "@/*": ["./src/*"] 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | }, 10 | { 11 | "path": "./tsconfig.vitest.json" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node18/tsconfig.json", 3 | "include": [ 4 | "vite.config.*", 5 | "vitest.config.*", 6 | "cypress.config.*", 7 | "nightwatch.conf.*", 8 | "playwright.config.*" 9 | ], 10 | "compilerOptions": { 11 | "composite": true, 12 | "module": "ESNext", 13 | "moduleResolution": "Bundler", 14 | "types": ["node"] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tsconfig.vitest.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.app.json", 3 | "exclude": [], 4 | "compilerOptions": { 5 | "composite": true, 6 | "lib": [], 7 | "types": ["node", "jsdom", "vitest/globals"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /utils/styleMock.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; 2 | -------------------------------------------------------------------------------- /utils/svgStringifyTransformer.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-undef 2 | const path = require("path"); 3 | 4 | // eslint-disable-next-line no-undef 5 | module.exports = { 6 | process(filename) { 7 | return `module.exports = ${JSON.stringify(path.basename(filename))};`; 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from "node:url"; 2 | 3 | import { defineConfig } from "vite"; 4 | import vue from "@vitejs/plugin-vue"; 5 | // @ts-expect-error - not typed 6 | import svg from "vite-plugin-svgstring"; 7 | import dts from "vite-plugin-dts"; 8 | 9 | // https://vitejs.dev/config/ 10 | export default defineConfig({ 11 | plugins: [ 12 | vue({}), 13 | svg(), 14 | dts({ 15 | outDir: ["dist/esm", "dist/common"], 16 | cleanVueFileName: true, 17 | compilerOptions: { 18 | moduleResolution: 99, 19 | }, 20 | }), 21 | ], 22 | resolve: { 23 | alias: [ 24 | { 25 | find: "@", 26 | replacement: fileURLToPath(new URL("./src", import.meta.url)), 27 | }, 28 | { 29 | // this is required for the SCSS modules 30 | find: /^~(.*)$/, 31 | replacement: "$1", 32 | }, 33 | ], 34 | }, 35 | build: { 36 | sourcemap: true, 37 | cssMinify: false, 38 | lib: { 39 | entry: "src/index.ts", 40 | formats: ["es", "cjs"], 41 | fileName: (format, entryName) => `${{ es: "esm", cjs: "common" }[format]}/${entryName}.js`, 42 | }, 43 | rollupOptions: { 44 | external: ["vue"], 45 | }, 46 | }, 47 | }); 48 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from "node:url"; 2 | import { mergeConfig, defineConfig, configDefaults } from "vitest/config"; 3 | import viteConfig from "./vite.config"; 4 | 5 | export default mergeConfig( 6 | viteConfig, 7 | defineConfig({ 8 | test: { 9 | environment: "jsdom", 10 | exclude: [...configDefaults.exclude, "e2e/*"], 11 | root: fileURLToPath(new URL("./", import.meta.url)), 12 | globals: true, 13 | }, 14 | }), 15 | ); 16 | --------------------------------------------------------------------------------