@adyen/bento-mcp 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/LICENSE +21 -0
- package/README.md +113 -0
- package/dist/assets/components/accordion/accordion.docs.mdx +77 -0
- package/dist/assets/components/accordion/accordion.stories.ts +1 -0
- package/dist/assets/components/accordion/accordion.vue +1 -0
- package/dist/assets/components/accordion/components/accordion-item.stories.ts +1 -0
- package/dist/assets/components/accordion/components/accordion-item.vue +1 -0
- package/dist/assets/components/action-bar/action-bar.docs.mdx +103 -0
- package/dist/assets/components/action-bar/action-bar.stories.ts +1 -0
- package/dist/assets/components/action-bar/action-bar.vue +1 -0
- package/dist/assets/components/alert/alert.docs.mdx +106 -0
- package/dist/assets/components/alert/alert.stories.ts +1 -0
- package/dist/assets/components/alert/alert.vue +1 -0
- package/dist/assets/components/avatar/avatar.docs.mdx +44 -0
- package/dist/assets/components/avatar/avatar.stories.ts +1 -0
- package/dist/assets/components/avatar/avatar.vue +1 -0
- package/dist/assets/components/avatar/components/avatar-image/avatar-image.vue +1 -0
- package/dist/assets/components/button/button.docs.mdx +137 -0
- package/dist/assets/components/button/button.stories.ts +1 -0
- package/dist/assets/components/button/button.vue +1 -0
- package/dist/assets/components/button/components/ai-button/ai-button.docs.mdx +40 -0
- package/dist/assets/components/button/components/ai-button/ai-button.stories.ts +1 -0
- package/dist/assets/components/button/components/ai-button/ai-button.vue +1 -0
- package/dist/assets/components/button/components/button-actions/button-actions.docs.mdx +169 -0
- package/dist/assets/components/button/components/button-actions/button-actions.stories.ts +1 -0
- package/dist/assets/components/button/components/button-actions/button-actions.vue +1 -0
- package/dist/assets/components/button/components/loading-button/loading-button.docs.mdx +106 -0
- package/dist/assets/components/button/components/loading-button/loading-button.stories.ts +1 -0
- package/dist/assets/components/button/components/loading-button/loading-button.vue +1 -0
- package/dist/assets/components/button/components/toggle-button/toggle-button.docs.mdx +81 -0
- package/dist/assets/components/button/components/toggle-button/toggle-button.stories.ts +1 -0
- package/dist/assets/components/button/components/toggle-button/toggle-button.vue +1 -0
- package/dist/assets/components/card/card.docs.mdx +166 -0
- package/dist/assets/components/card/card.stories.ts +1 -0
- package/dist/assets/components/card/card.vue +1 -0
- package/dist/assets/components/checkbox/checkbox.docs.mdx +116 -0
- package/dist/assets/components/checkbox/checkbox.stories.ts +1 -0
- package/dist/assets/components/checkbox/checkbox.vue +1 -0
- package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.docs.mdx +134 -0
- package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.stories.ts +1 -0
- package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.vue +1 -0
- package/dist/assets/components/chip/chip.docs.mdx +51 -0
- package/dist/assets/components/chip/chip.stories.ts +1 -0
- package/dist/assets/components/chip/chip.vue +1 -0
- package/dist/assets/components/click-outside/click-outside.docs.mdx +30 -0
- package/dist/assets/components/click-outside/click-outside.stories.ts +1 -0
- package/dist/assets/components/code-snippet/code-snippet.docs.mdx +73 -0
- package/dist/assets/components/code-snippet/code-snippet.stories.ts +1 -0
- package/dist/assets/components/code-snippet/code-snippet.vue +1 -0
- package/dist/assets/components/country/country.docs.mdx +61 -0
- package/dist/assets/components/country/country.stories.ts +1 -0
- package/dist/assets/components/country/country.vue +1 -0
- package/dist/assets/components/currency/currency.docs.mdx +38 -0
- package/dist/assets/components/currency/currency.stories.ts +1 -0
- package/dist/assets/components/currency/currency.vue +1 -0
- package/dist/assets/components/dashed-underline/dashed-underline.docs.mdx +57 -0
- package/dist/assets/components/dashed-underline/dashed-underline.stories.ts +1 -0
- package/dist/assets/components/dashed-underline/dashed-underline.vue +1 -0
- package/dist/assets/components/data-grid/components/data-grid-cell/data-grid-cell.vue +1 -0
- package/dist/assets/components/data-grid/components/data-grid-cell-actions/data-grid-cell-actions.vue +1 -0
- package/dist/assets/components/data-grid/components/data-grid-columns/data-grid-columns.vue +1 -0
- package/dist/assets/components/data-grid/components/data-grid-config-settings/components/data-grid-config-settings-column-row/data-grid-config-settings-column-row.vue +1 -0
- package/dist/assets/components/data-grid/components/data-grid-config-settings/data-grid-config-settings.vue +1 -0
- package/dist/assets/components/data-grid/components/data-grid-lazy-load/data-grid-lazy-load.vue +1 -0
- package/dist/assets/components/data-grid/components/data-grid-row/data-grid-row.vue +1 -0
- package/dist/assets/components/data-grid/components/data-grid-static-icon/data-grid-static-icon.docs.mdx +61 -0
- package/dist/assets/components/data-grid/components/data-grid-static-icon/data-grid-static-icon.stories.ts +1 -0
- package/dist/assets/components/data-grid/components/data-grid-static-icon/data-grid-static-icon.vue +1 -0
- package/dist/assets/components/data-grid/components/data-grid-summary-cell/data-grid-summary-cell.docs.mdx +56 -0
- package/dist/assets/components/data-grid/components/data-grid-summary-cell/data-grid-summary-cell.stories.ts +1 -0
- package/dist/assets/components/data-grid/components/data-grid-summary-cell/data-grid-summary-cell.vue +1 -0
- package/dist/assets/components/data-grid/components/data-grid-trend-cell/data-grid-trend-cell.docs.mdx +48 -0
- package/dist/assets/components/data-grid/components/data-grid-trend-cell/data-grid-trend-cell.stories.ts +1 -0
- package/dist/assets/components/data-grid/components/data-grid-trend-cell/data-grid-trend-cell.vue +1 -0
- package/dist/assets/components/data-grid/data-grid.docs.mdx +951 -0
- package/dist/assets/components/data-grid/data-grid.stories.ts +1 -0
- package/dist/assets/components/data-grid/data-grid.vue +1 -0
- package/dist/assets/components/date/date.docs.mdx +49 -0
- package/dist/assets/components/date/date.stories.ts +1 -0
- package/dist/assets/components/date/date.vue +1 -0
- package/dist/assets/components/date-picker/date-picker.docs.mdx +69 -0
- package/dist/assets/components/date-picker/date-picker.stories.ts +1 -0
- package/dist/assets/components/date-picker/date-picker.vue +1 -0
- package/dist/assets/components/date-range-picker/components/date-range-picker-calendar/date-range-picker-calendar.vue +1 -0
- package/dist/assets/components/date-range-picker/date-range-picker.docs.mdx +168 -0
- package/dist/assets/components/date-range-picker/date-range-picker.stories.ts +1 -0
- package/dist/assets/components/date-range-picker/date-range-picker.vue +1 -0
- package/dist/assets/components/divider/divider.docs.mdx +27 -0
- package/dist/assets/components/divider/divider.stories.ts +1 -0
- package/dist/assets/components/divider/divider.vue +1 -0
- package/dist/assets/components/dropdown/components/dropdown-base-textbox/dropdown-base-textbox.vue +1 -0
- package/dist/assets/components/dropdown/components/dropdown-default-textbox/dropdown-default-textbox.vue +1 -0
- package/dist/assets/components/dropdown/components/dropdown-options-container/dropdown-options-container.vue +1 -0
- package/dist/assets/components/dropdown/components/dropdown-small-textbox/dropdown-small-textbox.vue +1 -0
- package/dist/assets/components/dropdown/components/variants/dropdown-avatar/dropdown-avatar.stories.ts +1 -0
- package/dist/assets/components/dropdown/components/variants/dropdown-avatar/dropdown-avatar.vue +1 -0
- package/dist/assets/components/dropdown/components/variants/dropdown-country/dropdown-country.stories.ts +1 -0
- package/dist/assets/components/dropdown/components/variants/dropdown-country/dropdown-country.vue +1 -0
- package/dist/assets/components/dropdown/components/variants/dropdown-currency/dropdown-currency.stories.ts +1 -0
- package/dist/assets/components/dropdown/components/variants/dropdown-currency/dropdown-currency.vue +1 -0
- package/dist/assets/components/dropdown/components/variants/dropdown-payment-method/dropdown-payment-method.stories.ts +1 -0
- package/dist/assets/components/dropdown/components/variants/dropdown-payment-method/dropdown-payment-method.vue +1 -0
- package/dist/assets/components/dropdown/components/variants/dropdown-tag/dropdown-tag.stories.ts +1 -0
- package/dist/assets/components/dropdown/components/variants/dropdown-tag/dropdown-tag.vue +1 -0
- package/dist/assets/components/dropdown/dropdown.docs.mdx +420 -0
- package/dist/assets/components/dropdown/dropdown.stories.ts +1 -0
- package/dist/assets/components/dropdown/dropdown.vue +1 -0
- package/dist/assets/components/empty-state/empty-state.docs.mdx +115 -0
- package/dist/assets/components/empty-state/empty-state.stories.ts +1 -0
- package/dist/assets/components/empty-state/empty-state.vue +1 -0
- package/dist/assets/components/file-uploader/components/file-uploader-file-card/components/file-uploader-file-card-animation/file-uploader-file-card-animation.vue +1 -0
- package/dist/assets/components/file-uploader/components/file-uploader-file-card/file-uploader-file-card.stories.ts +1 -0
- package/dist/assets/components/file-uploader/components/file-uploader-file-card/file-uploader-file-card.vue +1 -0
- package/dist/assets/components/file-uploader/components/file-uploader-restrictions/file-uploader-restrictions.stories.ts +1 -0
- package/dist/assets/components/file-uploader/components/file-uploader-restrictions/file-uploader-restrictions.vue +1 -0
- package/dist/assets/components/file-uploader/file-uploader.docs.mdx +117 -0
- package/dist/assets/components/file-uploader/file-uploader.stories.ts +1 -0
- package/dist/assets/components/file-uploader/file-uploader.vue +1 -0
- package/dist/assets/components/filter-bar/components/all-filters-modal/all-filters-modal.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/all-filters-modal/all-filters-modal.vue +1 -0
- package/dist/assets/components/filter-bar/components/all-filters-modal/components/all-filters-modal-button/all-filters-modal-button.vue +1 -0
- package/dist/assets/components/filter-bar/components/base-filter/base-filter.docs.mdx +90 -0
- package/dist/assets/components/filter-bar/components/base-filter/base-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/base-filter/base-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/base-filter-button/base-filter-button.vue +1 -0
- package/dist/assets/components/filter-bar/components/boolean-filter/boolean-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/checkbox-group-filter/checkbox-group-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/checkbox-group-filter/checkbox-group-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/date-filter/date-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/date-filter/date-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/date-range-filter/date-range-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/date-range-filter/date-range-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/filter-bar-button/filter-bar-button.vue +1 -0
- package/dist/assets/components/filter-bar/components/filter-bar-button-group/filter-bar-button-group.vue +1 -0
- package/dist/assets/components/filter-bar/components/input-filter/input-filter.docs.mdx +18 -0
- package/dist/assets/components/filter-bar/components/input-filter/input-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/input-filter/input-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/input-with-dropdown-filter/input-with-dropdown-filter.docs.mdx +18 -0
- package/dist/assets/components/filter-bar/components/input-with-dropdown-filter/input-with-dropdown-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/input-with-dropdown-filter/input-with-dropdown-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/radio-group-filter/radio-group-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/radio-group-filter/radio-group-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/range-filter/range-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/components/select-filter-button/select-filter-button.vue +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/components/select-filter-dropdown/select-filter-dropdown.vue +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/select-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/select-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-avatar-filter/select-avatar-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-avatar-filter/select-avatar-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-country-filter/select-country-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-country-filter/select-country-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-currency-filter/select-currency-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-currency-filter/select-currency-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-payment-method-filter/select-payment-method-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-payment-method-filter/select-payment-method-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-tag-filter/select-tag-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-tag-filter/select-tag-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/toggle-filter/toggle-filter.stories.ts +1 -0
- package/dist/assets/components/filter-bar/components/toggle-filter/toggle-filter.vue +1 -0
- package/dist/assets/components/filter-bar/filter-bar.docs.mdx +1005 -0
- package/dist/assets/components/filter-bar/filter-bar.stories.ts +1 -0
- package/dist/assets/components/filter-bar/filter-bar.vue +1 -0
- package/dist/assets/components/focus-trap/focus-trap.docs.mdx +10 -0
- package/dist/assets/components/focus-trap/focus-trap.stories.ts +1 -0
- package/dist/assets/components/focus-trap/focus-trap.vue +1 -0
- package/dist/assets/components/form-layout/components/form-layout-field-tip/form-layout-field-tip.vue +1 -0
- package/dist/assets/components/form-layout/components/form-layout-group/form-layout-group.vue +1 -0
- package/dist/assets/components/form-layout/components/form-layout-title/form-layout-title.vue +1 -0
- package/dist/assets/components/form-layout/form-layout.docs.mdx +452 -0
- package/dist/assets/components/form-layout/form-layout.stories.ts +1 -0
- package/dist/assets/components/form-layout/form-layout.vue +1 -0
- package/dist/assets/components/header/header.docs.mdx +85 -0
- package/dist/assets/components/header/header.stories.ts +1 -0
- package/dist/assets/components/header/header.vue +1 -0
- package/dist/assets/components/header-with-views/components/header-with-views-all-views/header-with-views-all-views.vue +1 -0
- package/dist/assets/components/header-with-views/components/header-with-views-item-edit-form/header-with-views-edit-form.vue +1 -0
- package/dist/assets/components/header-with-views/header-with-views.docs.mdx +103 -0
- package/dist/assets/components/header-with-views/header-with-views.stories.ts +1 -0
- package/dist/assets/components/header-with-views/header-with-views.vue +1 -0
- package/dist/assets/components/image/image.docs.mdx +34 -0
- package/dist/assets/components/image/image.stories.ts +1 -0
- package/dist/assets/components/image/image.vue +1 -0
- package/dist/assets/components/info-icon/info-icon.docs.mdx +57 -0
- package/dist/assets/components/info-icon/info-icon.stories.ts +1 -0
- package/dist/assets/components/info-icon/info-icon.vue +1 -0
- package/dist/assets/components/input-field/input-field.docs.mdx +141 -0
- package/dist/assets/components/input-field/input-field.stories.ts +1 -0
- package/dist/assets/components/input-field/input-field.vue +1 -0
- package/dist/assets/components/input-field-password/input-field-password.docs.mdx +292 -0
- package/dist/assets/components/input-field-password/input-field-password.stories.ts +1 -0
- package/dist/assets/components/input-field-password/input-field-password.vue +1 -0
- package/dist/assets/components/input-field-phone-number/input-field-phone-number.docs.mdx +72 -0
- package/dist/assets/components/input-field-phone-number/input-field-phone-number.stories.ts +1 -0
- package/dist/assets/components/input-field-phone-number/input-field-phone-number.vue +1 -0
- package/dist/assets/components/inspector/inspector.docs.mdx +118 -0
- package/dist/assets/components/inspector/inspector.stories.ts +1 -0
- package/dist/assets/components/inspector/inspector.vue +1 -0
- package/dist/assets/components/internal/base-button/base-button.vue +1 -0
- package/dist/assets/components/internal/button-actions-with-menu/button-actions-with-menu.stories.ts +1 -0
- package/dist/assets/components/internal/button-actions-with-menu/button-actions-with-menu.vue +1 -0
- package/dist/assets/components/internal/calendar/calendar.stories.ts +1 -0
- package/dist/assets/components/internal/calendar/calendar.vue +1 -0
- package/dist/assets/components/internal/calendar/components/calendar-month/calendar-month.stories.ts +1 -0
- package/dist/assets/components/internal/calendar/components/calendar-month/calendar-month.vue +1 -0
- package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/__test__/calendar-month-day-stub.vue +1 -0
- package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/calendar-month-day.stories.ts +1 -0
- package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/calendar-month-day.vue +1 -0
- package/dist/assets/components/internal/calendar/components/calendar-year/calendar-year.vue +1 -0
- package/dist/assets/components/internal/calendar/components/calendar-year/components/calendar-year-month/__test__/calendar-year-month-stub.vue +1 -0
- package/dist/assets/components/internal/calendar/components/calendar-year/components/calendar-year-month/calendar-year-month.vue +1 -0
- package/dist/assets/components/internal/checkbox-input/checkbox-input.stories.ts +1 -0
- package/dist/assets/components/internal/checkbox-input/checkbox-input.vue +1 -0
- package/dist/assets/components/internal/controls-group/controls-group.vue +1 -0
- package/dist/assets/components/internal/copy/copy.docs.mdx +43 -0
- package/dist/assets/components/internal/copy/copy.stories.ts +1 -0
- package/dist/assets/components/internal/copy/copy.vue +1 -0
- package/dist/assets/components/internal/decorative-checkbox/decorative-checkbox.vue +1 -0
- package/dist/assets/components/internal/dialog-page/dialog-page.vue +1 -0
- package/dist/assets/components/internal/error-message/error-message.vue +1 -0
- package/dist/assets/components/internal/field-label/field-label.vue +1 -0
- package/dist/assets/components/internal/fixed-scroller/fixed-scroller.docs.mdx +21 -0
- package/dist/assets/components/internal/fixed-scroller/fixed-scroller.stories.ts +1 -0
- package/dist/assets/components/internal/fixed-scroller/fixed-scroller.vue +1 -0
- package/dist/assets/components/internal/footer-actions/footer-actions.vue +1 -0
- package/dist/assets/components/internal/grid-layout/grid-layout.vue +1 -0
- package/dist/assets/components/internal/header-meta/header-meta.vue +1 -0
- package/dist/assets/components/internal/info-icon-with-popover/info-icon-with-popover.vue +1 -0
- package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/components/listbox-multi-select-category/listbox-multi-select-category.vue +1 -0
- package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/listbox-multi-select-options.vue +1 -0
- package/dist/assets/components/internal/listbox/components/listbox-multi-select/listbox-multi-select.vue +1 -0
- package/dist/assets/components/internal/listbox/components/listbox-option/listbox-option.vue +1 -0
- package/dist/assets/components/internal/listbox/components/listbox-option-tag/listbox-option-tag.vue +1 -0
- package/dist/assets/components/internal/listbox/components/listbox-single-select/components/listbox-single-select-category/listbox-single-select-category.vue +1 -0
- package/dist/assets/components/internal/listbox/components/listbox-single-select/listbox-single-select.vue +1 -0
- package/dist/assets/components/internal/listbox/components/listbox-single-select-option/listbox-single-select-option.vue +1 -0
- package/dist/assets/components/internal/listbox/listbox.stories.ts +1 -0
- package/dist/assets/components/internal/listbox/listbox.vue +1 -0
- package/dist/assets/components/internal/radio-input/radio-input.stories.ts +1 -0
- package/dist/assets/components/internal/radio-input/radio-input.vue +1 -0
- package/dist/assets/components/internal/teleport/teleport.vue +1 -0
- package/dist/assets/components/internal/tooltip/tooltip.test.vue +1 -0
- package/dist/assets/components/internal/tooltip/tooltip.vue +1 -0
- package/dist/assets/components/layout/components/layout-row/layout-row.stories.ts +1 -0
- package/dist/assets/components/layout/components/layout-row/layout-row.vue +1 -0
- package/dist/assets/components/layout/layout.docs.mdx +108 -0
- package/dist/assets/components/layout/layout.stories.ts +1 -0
- package/dist/assets/components/layout/layout.vue +1 -0
- package/dist/assets/components/link/link.docs.mdx +119 -0
- package/dist/assets/components/link/link.stories.ts +1 -0
- package/dist/assets/components/link/link.vue +1 -0
- package/dist/assets/components/loading-indicator/loading-indicator.docs.mdx +65 -0
- package/dist/assets/components/loading-indicator/loading-indicator.stories.ts +1 -0
- package/dist/assets/components/loading-indicator/loading-indicator.vue +1 -0
- package/dist/assets/components/menu/components/menu-item/menu-item.vue +1 -0
- package/dist/assets/components/menu/components/menu-item-list/menu-item-list.vue +1 -0
- package/dist/assets/components/menu/components/menu-list-container/menu-list-container.vue +1 -0
- package/dist/assets/components/menu/components/sub-menu-item-list/sub-menu-item-list.vue +1 -0
- package/dist/assets/components/menu/menu.docs.mdx +121 -0
- package/dist/assets/components/menu/menu.stories.ts +1 -0
- package/dist/assets/components/menu/menu.vue +1 -0
- package/dist/assets/components/modal/components/base-modal/base-modal.vue +1 -0
- package/dist/assets/components/modal/components/modal-default/modal-default.vue +1 -0
- package/dist/assets/components/modal/components/modal-dialog/modal-dialog.vue +1 -0
- package/dist/assets/components/modal/components/modal-page/modal-page.vue +1 -0
- package/dist/assets/components/modal/modal.docs.mdx +215 -0
- package/dist/assets/components/modal/modal.stories.ts +1 -0
- package/dist/assets/components/modal/modal.vue +1 -0
- package/dist/assets/components/modal-fullscreen/components/modal-fullscreen-page.vue +1 -0
- package/dist/assets/components/modal-fullscreen/modal-fullscreen.docs.mdx +217 -0
- package/dist/assets/components/modal-fullscreen/modal-fullscreen.stories.ts +1 -0
- package/dist/assets/components/modal-fullscreen/modal-fullscreen.vue +1 -0
- package/dist/assets/components/pagination/components/pagination-context/pagination-context.vue +1 -0
- package/dist/assets/components/pagination/components/pagination-controls/pagination-controls.vue +1 -0
- package/dist/assets/components/pagination/components/pagination-results-per-page/pagination-results-per-page.vue +1 -0
- package/dist/assets/components/pagination/pagination.docs.mdx +116 -0
- package/dist/assets/components/pagination/pagination.stories.ts +1 -0
- package/dist/assets/components/pagination/pagination.vue +1 -0
- package/dist/assets/components/payment-method/payment-method.docs.mdx +34 -0
- package/dist/assets/components/payment-method/payment-method.stories.ts +1 -0
- package/dist/assets/components/payment-method/payment-method.vue +1 -0
- package/dist/assets/components/popover/components/popover-dismiss-button/popover-dismiss-button.vue +1 -0
- package/dist/assets/components/popover/components/popover-image/popover-image.vue +1 -0
- package/dist/assets/components/popover/components/popover-title/popover-title.vue +1 -0
- package/dist/assets/components/popover/popover.docs.mdx +89 -0
- package/dist/assets/components/popover/popover.stories.ts +1 -0
- package/dist/assets/components/popover/popover.vue +1 -0
- package/dist/assets/components/popper-container/popper-container.docs.mdx +11 -0
- package/dist/assets/components/popper-container/popper-container.stories.ts +1 -0
- package/dist/assets/components/popper-container/popper-container.vue +1 -0
- package/dist/assets/components/promo-banner/promo-banner.docs.mdx +94 -0
- package/dist/assets/components/promo-banner/promo-banner.stories.ts +1 -0
- package/dist/assets/components/promo-banner/promo-banner.vue +1 -0
- package/dist/assets/components/radio-group/components/radio-button/radio-button.docs.mdx +76 -0
- package/dist/assets/components/radio-group/components/radio-button/radio-button.stories.ts +1 -0
- package/dist/assets/components/radio-group/components/radio-button/radio-button.vue +1 -0
- package/dist/assets/components/radio-group/radio-group.docs.mdx +154 -0
- package/dist/assets/components/radio-group/radio-group.stories.ts +1 -0
- package/dist/assets/components/radio-group/radio-group.vue +1 -0
- package/dist/assets/components/rich-text-editor/components/rich-text-editor-content-area/rich-text-editor-content-area.vue +1 -0
- package/dist/assets/components/rich-text-editor/components/rich-text-editor-renderer/components/rich-text-editor-code-block/rich-text-editor-code-block.vue +1 -0
- package/dist/assets/components/rich-text-editor/components/rich-text-editor-renderer/components/rich-text-editor-inline-code/rich-text-editor-inline-code.vue +1 -0
- package/dist/assets/components/rich-text-editor/components/rich-text-editor-renderer/components/rich-text-editor-link/rich-text-editor-link.vue +1 -0
- package/dist/assets/components/rich-text-editor/components/rich-text-editor-renderer/components/rich-text-editor-list-item/rich-text-editor-list-item.vue +1 -0
- package/dist/assets/components/rich-text-editor/components/rich-text-editor-renderer/components/rich-text-editor-table/rich-text-editor-table.vue +1 -0
- package/dist/assets/components/rich-text-editor/rich-text-editor.docs.mdx +52 -0
- package/dist/assets/components/rich-text-editor/rich-text-editor.stories.ts +1 -0
- package/dist/assets/components/rich-text-editor/rich-text-editor.vue +1 -0
- package/dist/assets/components/search-bar/search-bar.docs.mdx +117 -0
- package/dist/assets/components/search-bar/search-bar.stories.ts +1 -0
- package/dist/assets/components/search-bar/search-bar.vue +1 -0
- package/dist/assets/components/secondary-nav/components/secondary-nav-category/secondary-nav-category.vue +1 -0
- package/dist/assets/components/secondary-nav/components/secondary-nav-item/secondary-nav-item.vue +1 -0
- package/dist/assets/components/secondary-nav/secondary-nav.docs.mdx +40 -0
- package/dist/assets/components/secondary-nav/secondary-nav.stories.ts +1 -0
- package/dist/assets/components/secondary-nav/secondary-nav.vue +1 -0
- package/dist/assets/components/segmented-control/components/segmented-control-button/segmented-control-button.vue +1 -0
- package/dist/assets/components/segmented-control/segmented-control.docs.mdx +90 -0
- package/dist/assets/components/segmented-control/segmented-control.stories.ts +1 -0
- package/dist/assets/components/segmented-control/segmented-control.vue +1 -0
- package/dist/assets/components/selection-card/components/selection-card-group/selection-card-group.docs.mdx +119 -0
- package/dist/assets/components/selection-card/components/selection-card-group/selection-card-group.stories.ts +1 -0
- package/dist/assets/components/selection-card/components/selection-card-group/selection-card-group.vue +1 -0
- package/dist/assets/components/selection-card/selection-card.docs.mdx +108 -0
- package/dist/assets/components/selection-card/selection-card.stories.ts +1 -0
- package/dist/assets/components/selection-card/selection-card.vue +1 -0
- package/dist/assets/components/sidepanel/components/sidepanel-page.stories.ts +1 -0
- package/dist/assets/components/sidepanel/components/sidepanel-page.vue +1 -0
- package/dist/assets/components/sidepanel/sidepanel.docs.mdx +129 -0
- package/dist/assets/components/sidepanel/sidepanel.stories.ts +1 -0
- package/dist/assets/components/sidepanel/sidepanel.vue +1 -0
- package/dist/assets/components/status/status.docs.mdx +62 -0
- package/dist/assets/components/status/status.stories.ts +1 -0
- package/dist/assets/components/status/status.vue +1 -0
- package/dist/assets/components/stepper/components/step/step.stories.ts +1 -0
- package/dist/assets/components/stepper/components/step/step.vue +1 -0
- package/dist/assets/components/stepper/stepper.docs.mdx +127 -0
- package/dist/assets/components/stepper/stepper.stories.ts +1 -0
- package/dist/assets/components/stepper/stepper.vue +1 -0
- package/dist/assets/components/structured-list/components/structered-list-item/structured-list-item.stories.ts +1 -0
- package/dist/assets/components/structured-list/components/structered-list-item/structured-list-item.vue +1 -0
- package/dist/assets/components/structured-list/structured-list.docs.mdx +68 -0
- package/dist/assets/components/structured-list/structured-list.stories.ts +1 -0
- package/dist/assets/components/structured-list/structured-list.vue +1 -0
- package/dist/assets/components/summary-grid/components/summary-grid-item/summary-grid-item.vue +1 -0
- package/dist/assets/components/summary-grid/components/summary-grid-item-amount/summary-grid-item-amount.stories.ts +1 -0
- package/dist/assets/components/summary-grid/components/summary-grid-item-amount/summary-grid-item-amount.vue +1 -0
- package/dist/assets/components/summary-grid/components/summary-grid-item-custom/summary-grid-item-custom.stories.ts +1 -0
- package/dist/assets/components/summary-grid/components/summary-grid-item-custom/summary-grid-item-custom.vue +1 -0
- package/dist/assets/components/summary-grid/components/summary-grid-item-numeric/summary-grid-item-numeric.stories.ts +1 -0
- package/dist/assets/components/summary-grid/components/summary-grid-item-numeric/summary-grid-item-numeric.vue +1 -0
- package/dist/assets/components/summary-grid/components/summary-grid-item-percentage/summary-grid-item-percentage.stories.ts +1 -0
- package/dist/assets/components/summary-grid/components/summary-grid-item-percentage/summary-grid-item-percentage.vue +1 -0
- package/dist/assets/components/summary-grid/components/summary-grid-item-text/summary-grid-item-text.stories.ts +1 -0
- package/dist/assets/components/summary-grid/components/summary-grid-item-text/summary-grid-item-text.vue +1 -0
- package/dist/assets/components/summary-grid/summary-grid.docs.mdx +152 -0
- package/dist/assets/components/summary-grid/summary-grid.stories.ts +1 -0
- package/dist/assets/components/summary-grid/summary-grid.vue +1 -0
- package/dist/assets/components/tabs/components/tab.vue +1 -0
- package/dist/assets/components/tabs/tabs.docs.mdx +98 -0
- package/dist/assets/components/tabs/tabs.stories.ts +1 -0
- package/dist/assets/components/tabs/tabs.vue +1 -0
- package/dist/assets/components/tag/tag.docs.mdx +137 -0
- package/dist/assets/components/tag/tag.stories.ts +1 -0
- package/dist/assets/components/tag/tag.vue +1 -0
- package/dist/assets/components/textarea/textarea.docs.mdx +53 -0
- package/dist/assets/components/textarea/textarea.stories.ts +1 -0
- package/dist/assets/components/textarea/textarea.vue +1 -0
- package/dist/assets/components/timeline/components/timeline-item/timeline-item.stories.ts +1 -0
- package/dist/assets/components/timeline/components/timeline-item/timeline-item.vue +1 -0
- package/dist/assets/components/timeline/timeline.docs.mdx +131 -0
- package/dist/assets/components/timeline/timeline.stories.ts +1 -0
- package/dist/assets/components/timeline/timeline.vue +1 -0
- package/dist/assets/components/toast/components/toast-item/toast-item.vue +1 -0
- package/dist/assets/components/toast/components/toast-shadow-stack/toast-shadow-stack.vue +1 -0
- package/dist/assets/components/toast/toast.docs.mdx +151 -0
- package/dist/assets/components/toast/toast.stories.ts +1 -0
- package/dist/assets/components/toast/toast.vue +1 -0
- package/dist/assets/components/toggle/toggle.docs.mdx +81 -0
- package/dist/assets/components/toggle/toggle.stories.ts +1 -0
- package/dist/assets/components/toggle/toggle.vue +1 -0
- package/dist/assets/components/tutorial/components/tutorial-popover/components/tutorial-indicator/tutorial-indicator.vue +1 -0
- package/dist/assets/components/tutorial/components/tutorial-popover/tutorial-popover.vue +1 -0
- package/dist/assets/components/tutorial/tutorial.docs.mdx +85 -0
- package/dist/assets/components/tutorial/tutorial.stories.ts +1 -0
- package/dist/assets/components/tutorial/tutorial.vue +1 -0
- package/dist/assets/components/typography/typography.docs.mdx +124 -0
- package/dist/assets/components/typography/typography.stories.ts +1 -0
- package/dist/assets/components/typography/typography.vue +1 -0
- package/dist/assets/composables/use-bento-currency/use-bento-currency.docs.mdx +28 -0
- package/dist/assets/composables/use-bento-currency/use-bento-currency.stories.ts +1 -0
- package/dist/assets/composables/use-click-outside/use-click-outside.docs.mdx +10 -0
- package/dist/assets/composables/use-click-outside/use-click-outside.stories.ts +1 -0
- package/dist/assets/directives/highlight/highlight.docs.mdx +64 -0
- package/dist/assets/directives/highlight/highlight.stories.ts +1 -0
- package/dist/assets/directives/keyboard-navigation/keyboard-navigation.docs.mdx +41 -0
- package/dist/assets/directives/keyboard-navigation/keyboard-navigation.stories.ts +1 -0
- package/dist/assets/directives/tooltip/tooltip.docs.mdx +86 -0
- package/dist/assets/directives/tooltip/tooltip.stories.ts +1 -0
- package/dist/assets/index.ts +1 -0
- package/dist/assets/templates/dashboard-template/components/dashboard-section/dashboard-section.stories.ts +1 -0
- package/dist/assets/templates/dashboard-template/components/dashboard-section/dashboard-section.vue +1 -0
- package/dist/assets/templates/dashboard-template/dashboard-template.docs.mdx +148 -0
- package/dist/assets/templates/dashboard-template/dashboard-template.stories.ts +1 -0
- package/dist/assets/templates/dashboard-template/dashboard-template.vue +1 -0
- package/dist/assets/templates/data-grid-template/data-grid-template.docs.mdx +117 -0
- package/dist/assets/templates/data-grid-template/data-grid-template.stories.ts +1 -0
- package/dist/assets/templates/data-grid-template/data-grid-template.vue +1 -0
- package/dist/main.js +30031 -0
- package/package.json +45 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<template> <div v-if="active && targetElement"> <tutorial-indicator v-if="isIndicatorVisible && targetElement" :target-element="targetElement" /> <bento-popover :target-element="targetElement" :position="position" :open="isPopoverOpen" :aria-label="title" fixed-positioning class="b-tutorial-popover" @keydown.esc.native="emit('finish')" > <template v-if="image" #image> <bento-image v-bind="image" aspect-ratio="landscape" class="b-tutorial-popover__image" /> </template> <div aria-hidden="true" class="b-tutorial-popover__ripple"></div> <div class="b-tutorial-popover__header"> <bento-typography variant="title" el="span"> {{ title }} </bento-typography> <bento-typography v-if="showSteps" el="span" class="b-tutorial-popover__steps"> {{ t('stepsOfTotal', { step, totalSteps }) }} </bento-typography> </div> <bento-typography> <slot /> </bento-typography> <div class="b-tutorial-popover__footer"> <bento-menu v-if="!isFirstStep" :data="menuData" class="b-tutorial-popover__menu" data-testid="menu-button" /> <div class="b-tutorial-popover__actions"> <bento-button-actions :actions="computedActions" layout="buttons-end" /> </div> </div> </bento-popover> </div> </template> <script setup lang="ts"> import { computed, isRef, nextTick, type PropType, ref, type default as Vue, watch } from 'vue'; import { BentoMenu } from '@/components/menu'; import { BentoPopover, BentoPopoverPositions } from '@/components/popover'; import { BentoTypography } from '@/components/typography'; import { type BentoButtonActionObject, BentoButtonActions } from '@/components/button'; import { BentoImage } from '@/components/image'; import { TutorialIndicator } from './components/tutorial-indicator'; import { useI18n } from '@/utils/ts/i18n'; import type { BentoMenuItem } from '@/components/menu/components'; import type { VueNodeElement } from '@/types/elements'; import type { BentoTutorialScrollOptions, BentoTutorialStep } from '../../tutorial.types'; import RefreshIcon from '@adyen/ui-assets-icons-16/vue/refresh'; import BlockedIcon from '@adyen/ui-assets-icons-16/vue/blocked'; import messages from './messages.json'; type MessageSchema = (typeof messages)['en-US']; const DEFAULT_SCROLL_OPTIONS: BentoTutorialScrollOptions = { behavior: 'smooth' }; const props = defineProps({ /** * Optional configuration for the secondary action. * In tour tutorials, this is ignored for the introductory step. */ action: { type: Object as PropType<BentoButtonActionObject>, default: null, }, /** * Indicates whether this popover is the active step (and should be visible). */ active: { type: Boolean, default: false, }, /** * Optional illustration to display at the top of the popover. */ image: { type: Object as PropType<BentoTutorialStep['image']>, default: null, }, /** * Popover's position relative to the target element. * Possible values are: * 'auto', 'auto-start', 'auto-end', * 'top', 'top-start', 'top-end' * 'right', 'right-start', 'right-end' * 'bottom', 'bottom-start', 'bottom-end' * 'left', 'left-start', 'left-end' */ position: { type: String as PropType<`${BentoPopoverPositions}`>, default: BentoPopoverPositions.BOTTOM_START, validator: (value: BentoPopoverPositions) => Object.values(BentoPopoverPositions).includes(value), }, /** * Options to control the scroll into view behavior. * Takes the same options as the `scrollIntoView` function * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView} */ scrollOptions: { type: [Boolean, Object] as PropType<BentoTutorialScrollOptions>, default: null, }, /** * Indicates whether this popover is a single tutorial or a tour. */ single: { type: Boolean, default: false, }, /** * The tutorial step number. * In tour tutorials, `0` is the introductory step, and is displayed next * to the title. */ step: { type: Number, default: null, }, /** * Tutorial popover's target element. * The popover will position itself relatively to target element. */ targetElement: { type: [Element, Object] as PropType<VueNodeElement>, required: true, }, /** * The tutorial step title. */ title: { type: String, required: true, }, /** * Total count of steps. * In tour tutorials, this does not include the introductory step, and is * displayed next to the title. */ totalSteps: { type: Number, default: null, }, }); const { t } = useI18n<{ message: MessageSchema }>({ messages }); const emit = defineEmits<{ /** * Emitted when the user clicks the primary action in popovers during introductory or intermediate steps of tour tutorials */ (e: 'next'): void; /** * Emitted when the user clicks the primary action in a single tutorial, the last step of a tour, or skips the tutorial */ (e: 'finish'): void; /** * Emitted when the user selects the restart tour option */ (e: 'restart'): void; }>(); const ACTION_SKIP = computed<BentoButtonActionObject>(() => ({ title: t('skipTour') as string, event: () => emit('finish'), })); const ACTION_START = computed<BentoButtonActionObject>(() => ({ title: t('startTour') as string, event: () => emit('next'), })); const ACTION_NEXT = computed<BentoButtonActionObject>(() => ({ title: t('next') as string, event: () => emit('next'), })); const ACTION_FINISH = computed<BentoButtonActionObject>(() => ({ title: t('finish') as string, event: () => emit('finish'), })); const ACTION_OK = computed<BentoButtonActionObject>(() => ({ title: t('ok') as string, event: () => emit('finish'), })); const isPopoverOpen = ref(false); const isIndicatorVisible = ref(false); const targetElement = computed(() => { if (isRef(props.targetElement)) { return ((props.targetElement.value as Vue)?.$el || props.targetElement.value) as HTMLElement; } return ((props.targetElement as Vue).$el || props.targetElement) as HTMLElement; }); const isFirstStep = computed(() => props.step === 0); const isLastStep = computed(() => props.step === props.totalSteps); const showSteps = computed(() => !isFirstStep.value); const menuData = computed<Array<BentoMenuItem>>(() => [ { text: t('restartTour'), handler: () => emit('restart'), icon: RefreshIcon, }, ...(isLastStep.value ? [] : [ { text: t('skipTour'), handler: () => emit('finish'), icon: BlockedIcon, }, ]), ]); const computedActions = computed(() => { let primaryAction: BentoButtonActionObject; if (isFirstStep.value) { primaryAction = props.single ? ACTION_OK.value : ACTION_START.value; } else if (isLastStep.value) { primaryAction = ACTION_FINISH.value; } else { primaryAction = ACTION_NEXT.value; } const actions = [primaryAction]; if (isFirstStep.value && !props.single) { actions.push(ACTION_SKIP.value); } else if (props.action) { actions.push(props.action); } return actions; }); watch( () => props.active, async isActive => { if (isActive && targetElement.value?.scrollIntoView) { targetElement.value?.scrollIntoView( props.scrollOptions != null ? props.scrollOptions : DEFAULT_SCROLL_OPTIONS ); // Skip to next tick to preserve popover appear animation await nextTick(); } isPopoverOpen.value = isActive; isIndicatorVisible.value = isActive; }, { immediate: true } ); </script> <script lang="ts"> export default { i18n: { messages }, }; </script> <style lang="scss" scoped src="./tutorial-popover.scss" />
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Canvas, Meta } from '@storybook/blocks';
|
|
2
|
+
import * as TutorialStories from './tutorial.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={TutorialStories} />
|
|
5
|
+
|
|
6
|
+
# Tutorial
|
|
7
|
+
|
|
8
|
+
The Tutorial is a temporary popover that should be used to educate users about new or unfamiliar features or
|
|
9
|
+
experiences.
|
|
10
|
+
|
|
11
|
+
You can use single tutorial or chain them into a tour.
|
|
12
|
+
|
|
13
|
+
<Canvas of={TutorialStories.Default} />
|
|
14
|
+
|
|
15
|
+
## Use Cases
|
|
16
|
+
|
|
17
|
+
### New features
|
|
18
|
+
|
|
19
|
+
Use the Tutorial component to educate users about new features/experiences that you launch in the product.
|
|
20
|
+
|
|
21
|
+
### Unfamiliar features
|
|
22
|
+
|
|
23
|
+
The Tutorial component can also be useful if you need to educate users on how to use features/experiences that already
|
|
24
|
+
exist in product but they have trouble using or discovering them (you can get signals from research or user feedback).
|
|
25
|
+
|
|
26
|
+
### Do not use
|
|
27
|
+
|
|
28
|
+
Only use this component for new features/experiences that are not obvious and self-explanatory on their own.
|
|
29
|
+
|
|
30
|
+
If you follow common design conventions, Tutorials are usually not necessary.
|
|
31
|
+
|
|
32
|
+
## Variations
|
|
33
|
+
|
|
34
|
+
### Single tutorial
|
|
35
|
+
|
|
36
|
+
A single tutorial should be used to educate or inform user about one thing.
|
|
37
|
+
|
|
38
|
+
<Canvas of={TutorialStories.Single} />
|
|
39
|
+
|
|
40
|
+
### Tour tutorial
|
|
41
|
+
|
|
42
|
+
You can define multiple, chained tutorial steps to create a tour.
|
|
43
|
+
|
|
44
|
+
In tutorial tour, interaction with the primary action on a popover will lead to the display of the next tutorial
|
|
45
|
+
popover.
|
|
46
|
+
|
|
47
|
+
Use this when you need to educate user about multiple things that are contextually connected to each other or when you
|
|
48
|
+
need to communicate a task flow.
|
|
49
|
+
|
|
50
|
+
<Canvas of={TutorialStories.Default} />
|
|
51
|
+
|
|
52
|
+
## Accessibility 🚧
|
|
53
|
+
|
|
54
|
+
NOTE: The focus trap within the popover does not function as it should right now, this issue is currently being worked
|
|
55
|
+
on.
|
|
56
|
+
|
|
57
|
+
### Keyboard Interaction
|
|
58
|
+
|
|
59
|
+
Being an interactive element, the button (that toggles the visibility of the Popover) is reachable through keyboard
|
|
60
|
+
navigation in the logical navigation flow of the page. The following keys trigger the following actions:
|
|
61
|
+
|
|
62
|
+
| Keyboard interaction | Action |
|
|
63
|
+
| -------------------- | -------------------------------------------------------- |
|
|
64
|
+
| `Tab` | Moves focus to the next tutorial action. |
|
|
65
|
+
| `Shift` + `Tab` | Moves focus to the previous tutorial action. |
|
|
66
|
+
| `Space`/`Enter` | Activates the focused action or opens the menu dropdown. |
|
|
67
|
+
| `Esc` | Skips the tutorial. |
|
|
68
|
+
|
|
69
|
+
### Roles, States, and Properties
|
|
70
|
+
|
|
71
|
+
Adhering to the [WAI-ARIA 1.2](https://www.w3.org/TR/wai-aria-1.2/) standard we follow the
|
|
72
|
+
[disclosure pattern](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/#wai-ariaroles,states,andproperties)
|
|
73
|
+
documentation provided.
|
|
74
|
+
|
|
75
|
+
#### Please note that:
|
|
76
|
+
|
|
77
|
+
- The element that shows and hides the content has role button, e.g. use the `BentoButton` component.
|
|
78
|
+
|
|
79
|
+
| ARIA attribute | is automatic? | fallback used | manual override |
|
|
80
|
+
| -------------- | ------------------------------------------------- | ------------- | --------------- |
|
|
81
|
+
| `role` | Yes, `dialog` role is set on the tutorial popover | - | - |
|
|
82
|
+
|
|
83
|
+
## Resources
|
|
84
|
+
|
|
85
|
+
- [Figma link](https://www.figma.com/file/uLabwF3243jdMDsNSP7U9I/Bento---Components?type=design&node-id=19830-61470&mode=design&t=AyPMVRNM89lPAZ1q-4)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { action } from '@storybook/addon-actions'; import { isVue2 } from 'vue-demi'; import { ref } from 'vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { BentoTutorial } from './index'; import BentoTutorialPopover from './components/tutorial-popover/tutorial-popover.vue'; import { BentoButton } from '@/components/button'; import { BentoTab, BentoTabs } from '@/components/tabs'; import { BentoTag } from '@/components/tag'; import { BentoImage } from '@/components/image'; import { BentoPaymentMethod } from '@/components/payment-method'; import { BentoTypography } from '@/components/typography'; import type { Meta, StoryObj } from '@storybook/vue'; import type { BentoTutorialStep } from './tutorial.types'; import illustration from '@/components/empty-state/assets/small/2-generic-use.svg'; import { mockImage } from '../image/const'; import './tutorial.stories.scss?module'; import TutorialDefaultExample from './__tests__/tutorial-default-example.vue?raw'; const meta: Meta = { title: 'Tutorial', component: BentoTutorial, }; export default meta; type Story = StoryObj<typeof BentoTutorial>; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoButton, BentoImage, BentoPaymentMethod, BentoTag, BentoTutorial, BentoTabs, BentoTab, }, props: Object.keys(argTypes), template: ` <div class="b-container"> <div class="b-feature-row"> <bento-button ref="feature1">Feature 1</bento-button> <bento-tag ref="feature2" label="Feature 2" variant="blue" /> <bento-image ref="feature3" src="${mockImage}" alt="Mock image" aspect-ratio="landscape" object-fit="cover" style="height: 48px" /> <bento-payment-method ref="feature4" type="ideal" label="Feature 4" /> <bento-tabs> <bento-tab title="Maria Ahlefeldt" :set-element-ref="setFeature5"> (16 January 1755 - 20 December 1810) was a Danish, (originally German), composer. She is known as the first female composer in Denmark. </bento-tab> </bento-tabs> </div> <bento-tutorial v-bind="args" :steps="steps" @update:index="onIndexUpdate" /> </div> `, setup(props) { const feature1 = ref(null); const feature2 = ref(null); const feature3 = ref(null); const feature4 = ref(null); const feature5 = ref(null); const setFeature5 = (el: Element) => { feature5.value = el; }; const steps: Array<BentoTutorialStep> = [ { target: feature1, title: 'Welcome!', description: 'This is a demo of a tutorial', image: { src: illustration, alt: 'Welcome', objectFit: 'cover', }, }, { target: feature2, title: 'Feature 2', description: 'What a shiny feature - Feature 2!', action: { title: 'Learn more', event: () => action('Learn more clicked')(), }, position: 'top-start', }, { target: feature3, title: 'Feature 3', description: 'Look at this <BentoImage> component. It is indeed, an image.', position: 'right-end', }, { target: feature4, title: 'Feature 4', description: "That's all folks!", action: { title: "What's this?", event: () => action("What's this?")(), }, position: 'bottom-end', }, { target: feature5, title: 'Feature 5', description: 'More of this feature', }, ]; const onIndexUpdate = (value: number) => action('update:index')(value); return { // Values args: isVue2 ? props : _args, steps, onIndexUpdate, // Refs feature1, feature2, feature3, feature4, setFeature5, }; }, }), parameters: storybookDocsParameter(TutorialDefaultExample), }; const singleCode = ` <template> <bento-button ref="targetElement1">Feature 1</bento-button> <bento-tutorial :steps="[ { target: targetElement1, title: 'Welcome!', description: 'This is a demo of a tutorial', image: { src: AnyImageSource, alt: 'Welcome' }, } ]" /> </template> <script setup lang="ts"> import { ref } from 'vue' import { BentoButton, BentoTutorial } from '@adyen/bento-vue2' import AnyImageSource from '@/path/to/your/image.svg' const targetElement1 = ref(null) </script> `; export const Single: Story = { render: (_args, { argTypes }) => ({ components: { BentoButton, BentoTutorial, BentoTutorialPopover, }, props: Object.keys(argTypes), template: ` <div class="b-container"> <div class="b-feature-row"> <bento-button ref="feature"> Exciting new feature </bento-button> </div> <bento-tutorial v-bind="args" :steps="steps" /> </div> `, setup(props) { const feature = ref(null); const steps: Array<BentoTutorialStep> = [ { target: feature, title: 'Welcome!', description: 'This is a demo of a tutorial', image: { src: illustration, alt: 'Welcome', objectFit: 'cover', }, action: { title: 'Learn more', event: () => action('Learn more clicked')(), }, }, ]; return { // Values args: isVue2 ? props : _args, steps, // Refs feature, }; }, }), parameters: storybookDocsParameter(singleCode), }; export const Inline: Story = { render: (_args, { argTypes }) => ({ components: { BentoTypography, BentoTutorial, }, props: Object.keys(argTypes), template: ` <div class="b-container"> <bento-typography el="p"> Did you hear that? They've shut down the main reactor. We'll be destroyed for sure. This is madness! We're doomed! There'll be no escape for the Princess this time. What's that? Artoo! Artoo-Detoo, where are you? At last! Where have you been? They're heading in this direction. What are we going to do? We'll be sent to the spice mine of Kessel or smashed into who knows what! Wait a minute, where are you going? The Death Star plans are not in the main computer. Where are those transmissions you intercepted? What have you done with those plans? We intercepted no transmissions. </bento-typography> <bento-typography el="p"> I've lost Artoo! You may fire when ready. I have you now. What? Yahoo! Look out! You're all clear, kid. Now let's blow this thing and go home! Stand by to fire at Rebel base. Standing by. </bento-typography> <bento-typography el="p"> You must learn the ways of the <strong ref="feature1">Force</strong> if you're to come with me to Alderaan. Alderaan? I'm not going to Alderaan. I've got to go home. It's late, I'm in for it as it is. </bento-typography> <bento-typography el="p"> Look, a few minutes ago you said you didn't want to just wait here to be captured. Now all you want to do is stay. Marching into the detention area is not what I had in mind. But they're going to kill her! Better her than me. She's rich. </bento-typography> <bento-typography el="p"> You may fire when ready. What? You're far too trusting. Dantooine is too remote to make an effective demonstration. But don't worry. We will deal with your <strong ref="feature2">Rebel</strong> friends soon enough. </bento-typography> <bento-tutorial v-bind="args" :steps="steps" /> </div> `, setup(props) { const feature1 = ref(null); const feature2 = ref(null); const steps: Array<BentoTutorialStep> = [ { target: feature1, title: 'The Force', description: `The Force is what gives a Jedi his power. It's an energy field created by all living things. It surrounds us and penetrates us; it binds the galaxy together`, }, { target: feature2, title: 'Rebel Alliance', description: `The Alliance to Restore the Republic (2 BBY–4 ABY), commonly known as the Rebel Alliance, Alliance, and the Rebellion, was a resistance movement to oppose the rule of the Galactic Empire and to restore the Galactic Republic.`, action: { title: 'Learn more', event: () => action('Learn more clicked')(), }, position: 'bottom', }, ]; return { // Values args: isVue2 ? props : _args, steps, // Refs feature1, feature2, }; }, }), parameters: storybookDocsParameter(singleCode), };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<template> <div class="b-tutorial"> <tutorial-popover v-for="(step, i) in steps" v-bind="getPopoverProps(step, i)" :key="step.title" @finish="currentStep = -1" @next="currentStep += 1" @restart="currentStep = 0" > {{ step.description }} </tutorial-popover> </div> </template> <script setup lang="ts"> import { computed, type PropType, ref, watch } from 'vue'; import { TutorialPopover } from './components/tutorial-popover'; import type { BentoTutorialScrollOptions, BentoTutorialStep } from './tutorial.types'; const props = defineProps({ /** * The current step index. If provided, will start the tutorial in that step. */ index: { type: Number, default: null, }, /** * The steps configuration for the tutorial. * */ steps: { type: Array as PropType<Array<BentoTutorialStep>>, required: true, validator: (value: Array<BentoTutorialStep>) => value.length > 0, }, /** * Options to control the scroll into view behavior. * Takes the same options as the `scrollIntoView` function * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView} */ scrollOptions: { type: [Boolean, Object] as PropType<BentoTutorialScrollOptions>, default: null, }, }); const emit = defineEmits<{ /** * Fired every time the step index is changed. `-1` value means the tutorial is finished/skipped. */ (e: 'update:index', value: number); }>(); const currentStep = ref(props.index || 0); const totalSteps = computed(() => props.steps.length - 1); const isSingleTutorial = computed(() => totalSteps.value === 0); function getPopoverProps(step: BentoTutorialStep, index: number) { return { // Visual targetElement: step.target, image: step.image, title: step.title, step: index, totalSteps: totalSteps.value, action: step.action, scrollOptions: props.scrollOptions, // Config active: index === currentStep.value, single: isSingleTutorial.value, position: step.position, }; } watch(currentStep, step => { emit('update:index', step); }); watch( () => props.index, value => { if (value >= -1 && value <= totalSteps.value) { currentStep.value = value; } } ); </script> <script lang="ts"> /** * The Tutorial is a temporary popover that should be used to educate users about * new or unfamiliar features or experiences. * * You can use single tutorial or chain them into a tour. * * Only use this component for new features/experiences that are not obvious and * self-explanatory on their own. * * @example * import { BentoTutorial } from '@adyen/bento-vue2'; * * export default { * components: { BentoTutorial }, * template: ` * <bento-tutorial * :steps="[ * { * target: targetElement1, * title: 'Tutorial intro title', * description: 'Intro body content', * image: { src: imageSource, alt: 'Alt text' } * }, * { * target: targetElement1, * title: 'Tutorial intro title', * description: 'Intro body content', * action: { title: 'Action label', event: () => {} } * }, * ]" * /> * ` * } */ export default {}; </script>
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { Canvas, Meta } from '@storybook/blocks';
|
|
2
|
+
import * as TypographyStories from './typography.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={TypographyStories} />
|
|
5
|
+
|
|
6
|
+
# Typography
|
|
7
|
+
|
|
8
|
+
The Typography is used to to apply text styling to specific content allowing for a 1:1 relationship between the design
|
|
9
|
+
and the component without having to write a single line of font styling CSS code.
|
|
10
|
+
|
|
11
|
+
<Canvas of={TypographyStories.Body} />
|
|
12
|
+
|
|
13
|
+
## Use Cases
|
|
14
|
+
|
|
15
|
+
Here are some examples:
|
|
16
|
+
|
|
17
|
+
- Writing an article for a blog.
|
|
18
|
+
- A sub-title for a section on a web page.
|
|
19
|
+
|
|
20
|
+
### Do not use
|
|
21
|
+
|
|
22
|
+
Here are some examples:
|
|
23
|
+
|
|
24
|
+
- Don't use to replace a `label` instead wrap the label around this component.
|
|
25
|
+
- Don't use inside a button component's `default` slot.
|
|
26
|
+
|
|
27
|
+
## Variations
|
|
28
|
+
|
|
29
|
+
### Caption
|
|
30
|
+
|
|
31
|
+
<Canvas of={TypographyStories.Caption} />
|
|
32
|
+
|
|
33
|
+
A short descriptive or explanatory text, usually one or two sentences long, which accompanies a photograph, picture,
|
|
34
|
+
map, graph, pictorial illustration, figure, table.
|
|
35
|
+
|
|
36
|
+
#### Modifiers
|
|
37
|
+
|
|
38
|
+
##### Stronger
|
|
39
|
+
|
|
40
|
+
A bolder caption.
|
|
41
|
+
|
|
42
|
+
##### Wide
|
|
43
|
+
|
|
44
|
+
A caption with more letter spacing.
|
|
45
|
+
|
|
46
|
+
### Body
|
|
47
|
+
|
|
48
|
+
<Canvas of={TypographyStories.Body} />
|
|
49
|
+
|
|
50
|
+
Text forming the main content of a book, magazine, web page, or any other printed or digital work.
|
|
51
|
+
|
|
52
|
+
#### Modifiers
|
|
53
|
+
|
|
54
|
+
##### Stronger
|
|
55
|
+
|
|
56
|
+
Emboldened body text.
|
|
57
|
+
|
|
58
|
+
##### Strongest
|
|
59
|
+
|
|
60
|
+
The most emboldened body text.
|
|
61
|
+
|
|
62
|
+
##### Wide
|
|
63
|
+
|
|
64
|
+
A caption with more letter spacing.
|
|
65
|
+
|
|
66
|
+
### Title
|
|
67
|
+
|
|
68
|
+
Text used for a headline of a section of content or web page.
|
|
69
|
+
|
|
70
|
+
<Canvas of={TypographyStories.Title} />
|
|
71
|
+
|
|
72
|
+
#### Modifiers
|
|
73
|
+
|
|
74
|
+
##### Medium
|
|
75
|
+
|
|
76
|
+
A larger (than default) title.
|
|
77
|
+
|
|
78
|
+
##### Large
|
|
79
|
+
|
|
80
|
+
The largest title text.
|
|
81
|
+
|
|
82
|
+
##### ⚠️ Subtitle (deprecated) ⚠️
|
|
83
|
+
|
|
84
|
+
> ⚠️ **Deprecation Notice**: This modifier is deprecated and will be removed in release **2.0.0**. Use the `'title'`
|
|
85
|
+
> variant and optionally combine it with a size property. e.g. `medium` OR `large`.
|
|
86
|
+
> `<bento-typography variant="title" medium>`,
|
|
87
|
+
|
|
88
|
+
Text used for a headline of a sub-section of content or web page.
|
|
89
|
+
|
|
90
|
+
#### Modifiers
|
|
91
|
+
|
|
92
|
+
##### Stronger
|
|
93
|
+
|
|
94
|
+
Emboldened sub-title text.
|
|
95
|
+
|
|
96
|
+
## Rich text
|
|
97
|
+
|
|
98
|
+
To use `bento-typography` with a block of HTML text, you can pass the `rich-text` prop, which will take care of
|
|
99
|
+
rendering everything inside with the correct styles.
|
|
100
|
+
|
|
101
|
+
Important: `rich-text` can only be used with the `body` and `caption` variant, and the `el` should always be `div` for
|
|
102
|
+
correct HTML semantics.
|
|
103
|
+
|
|
104
|
+
<Canvas of={TypographyStories.RichText} />
|
|
105
|
+
|
|
106
|
+
## El(ement)
|
|
107
|
+
|
|
108
|
+
The `el` property affects output HTML DOM element that is wrapped around the text content.
|
|
109
|
+
|
|
110
|
+
It accepts one of the following values:
|
|
111
|
+
|
|
112
|
+
- `'h1'`
|
|
113
|
+
- `'h2'`
|
|
114
|
+
- `'h3'`
|
|
115
|
+
- `'h4'`
|
|
116
|
+
- `'h5'`
|
|
117
|
+
- `'h6'`
|
|
118
|
+
- `'div'`
|
|
119
|
+
- `'paragraph'` (default)
|
|
120
|
+
- `'span'`
|
|
121
|
+
|
|
122
|
+
## Resources
|
|
123
|
+
|
|
124
|
+
- [Figma link](https://www.figma.com/file/Diqr47KAACSr6ohrQhcNgO/Bento---Product---Fundamentals?node-id=1423-55445&t=hpcF61AsBuhZRdWW-0)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import BentoTypography from './typography.vue'; import { BentoTypographyElement, BentoTypographyVariant } from './typography.types'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { isVue2 } from 'vue-demi'; import type { Meta, StoryObj } from '@storybook/vue'; const meta: Meta = { title: 'Typography', component: BentoTypography, argTypes: { default: { name: 'default', defaultValue: '', description: 'typography text', table: { type: { summary: 'VNode[]' }, }, control: { type: 'text', }, }, el: { options: Object.values(BentoTypographyElement), mapping: BentoTypographyElement, control: { type: 'select', }, }, variant: { options: Object.values(BentoTypographyVariant), mapping: BentoTypographyVariant, control: { type: 'select', }, }, }, }; export default meta; type Story = StoryObj<typeof BentoTypography>; const SIZES_DISABLED_ARG_TYPES = { small: { table: { disable: true } }, medium: { table: { disable: true } }, large: { table: { disable: true } }, }; const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoTypography }, props: Object.keys(argTypes), template: ` <bento-typography v-bind="args"> {{args.default}} </bento-typography> `, setup(props) { return { args: isVue2 ? props : _args, }; }, }), }; export const Caption: Story = { ...Default, argTypes: { ...SIZES_DISABLED_ARG_TYPES, variant: { table: { disable: true } }, strongest: { table: { disable: true } }, }, args: { default: 'Caption text', variant: 'caption' }, parameters: storybookDocsParameter('<bento-typography variant="caption">Caption text</bento-typography>'), }; export const Body: Story = { ...Default, argTypes: { ...SIZES_DISABLED_ARG_TYPES, variant: { table: { disable: true } }, stronger: { if: { arg: 'strongest', truthy: false } }, strongest: { if: { arg: 'stronger', truthy: false } }, }, args: { default: 'Body text', variant: 'body' }, parameters: storybookDocsParameter('<bento-typography :variant="body">Body text</bento-typography>'), }; export const Title: Story = { ...Default, argTypes: { variant: { table: { disable: true } }, stronger: { table: { disable: true } }, strongest: { table: { disable: true } }, wide: { table: { disable: true } }, medium: { if: { arg: 'large', truthy: false } }, large: { if: { arg: 'medium', truthy: false } }, }, args: { default: 'Title text', variant: 'title' }, parameters: storybookDocsParameter('<bento-typography :variant="title">Title text</bento-typography>'), }; const richTextTemplate = ` <h1>Heading 1</h1> <p><strong>Bento</strong> is a scalable <mark>design system</mark> that enables product teams within <em>Adyen</em> to create the <ins>best user experiences and interfaces</ins>, all built on <del>solid</del> principles like usability, consistency, and accessibility. </p> <ul> <li>Item One</li> <li>Item Two</li> <ul> <li>Item One</li> <li>Item Two</li> <ul> <li>Item One</li> <li>Item Two</li> <li>Item Three</li> </ul> </ul> </ul> <blockquote>"Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility."</blockquote> <h2>Heading 2</h2> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> <ol> <li>Item One</li> <li>Item Two</li> <ol> <li>Item One</li> <li>Item Two</li> <ol> <li>Item One</li> <li>Item Two</li> <li>Item Three</li> </ol> </ol> </ol> <pre> function welcomeBento() { console.log('Welcome to Bento design system') }</pre> <h3>Heading 3</h3> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> <code>Inline code example</code> <h4>Heading 4</h4> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> <table> <caption> Front-end web developer course 2021 </caption> <thead> <tr> <th scope="col">Person</th> <th scope="col">Most interest in</th> <th scope="col">Age</th> </tr> </thead> <tbody> <tr> <th scope="row">Chris</th> <td>HTML tables</td> <td>22</td> </tr> <tr> <th scope="row">Elizabeth</th> <td>Web accessibility</td> <td>45</td> </tr> <tr> <th scope="row">Sarah</th> <td>JavaScript frameworks</td> <td>29</td> </tr> <tr> <th scope="row">John</th> <td>Web performance</td> <td>36</td> </tr> </tbody> <tfoot> <tr> <th scope="row" colspan="2" align="right">Average age</th> <td>33</td> </tr> </tfoot> </table> <h5>Heading 5</h5> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> <h6>Heading 6</h6> <p>Bento is a scalable design system that enables product teams within Adyen to create the best user experiences and interfaces, all built on principles like usability, consistency, and accessibility. </p> `; const richTextCode = ` <bento-typography el="div" rich-text>${richTextTemplate}</bento-typography> `; export const RichText: Story = { render: (_args, { argTypes }) => ({ components: { BentoTypography }, props: Object.keys(argTypes), template: ` <bento-typography v-bind="args">${richTextTemplate}</bento-typography> `, setup(props) { return { args: isVue2 ? props : _args, }; }, }), args: { el: 'div', richText: true }, parameters: storybookDocsParameter(richTextCode), };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<template> <component :is="el" class="b-typography" :class="conditionalClasses" data-testid="typography"> <slot /> </component> </template> <script setup lang="ts"> import { computed, onMounted } from 'vue'; import { deprecate } from '@/utils/ts/deprecate'; import { BentoTypographyElement, BentoTypographyModifier, type BentoTypographyProps, BentoTypographyVariant, } from './typography.types'; const props = withDefaults(defineProps<BentoTypographyProps>(), { el: BentoTypographyElement.PARAGRAPH, large: false, medium: false, stronger: false, strongest: false, variant: BentoTypographyVariant.BODY, wide: false, }); if (props.variant === BentoTypographyVariant.SUBTITLE) { deprecate( 'BentoTypography "subtitle" variant (BentoTypographyVariant.SUBTITLE)', `Use the "title" or "BentoTypographyVariant.TITLE" variant and (optionally) combine it with a size property. e.g. medium / large. <bento-typography :variant="BentoTypographyVariant.TITLE" medium>`, '2.0.0' ); } const conditionalClasses = computed(() => ({ // Rich text ['b-typography--rich-text']: props.richText, // Caption [`b-typography--${BentoTypographyVariant.CAPTION}`]: props.variant === BentoTypographyVariant.CAPTION, [`b-typography--${BentoTypographyVariant.CAPTION}-${BentoTypographyModifier.WIDE}`]: props.variant === BentoTypographyVariant.CAPTION && props.wide, [`b-typography--${BentoTypographyVariant.CAPTION}-${BentoTypographyModifier.STRONGER}`]: props.variant === BentoTypographyVariant.CAPTION && props.stronger, // Body [`b-typography--${BentoTypographyVariant.BODY}`]: props.variant === BentoTypographyVariant.BODY, [`b-typography--${BentoTypographyVariant.BODY}-${BentoTypographyModifier.WIDE}`]: props.variant === BentoTypographyVariant.BODY && props.wide, [`b-typography--${BentoTypographyVariant.BODY}-${BentoTypographyModifier.STRONGER}`]: props.variant === BentoTypographyVariant.BODY && props.stronger, [`b-typography--${BentoTypographyVariant.BODY}-${BentoTypographyModifier.STRONGEST}`]: props.variant === BentoTypographyVariant.BODY && props.strongest, // Subtitle [`b-typography--${BentoTypographyVariant.SUBTITLE}`]: props.variant === BentoTypographyVariant.SUBTITLE, [`b-typography--${BentoTypographyVariant.SUBTITLE}-${BentoTypographyModifier.STRONGER}`]: props.variant === BentoTypographyVariant.SUBTITLE && props.stronger, // Title [`b-typography--${BentoTypographyVariant.TITLE}`]: props.variant === BentoTypographyVariant.TITLE && !props.medium && !props.large, [`b-typography--${BentoTypographyVariant.TITLE}-${BentoTypographyModifier.MEDIUM}`]: props.variant === BentoTypographyVariant.TITLE && props.medium, [`b-typography--${BentoTypographyVariant.TITLE}-${BentoTypographyModifier.LARGE}`]: props.variant === BentoTypographyVariant.TITLE && props.large, })); onMounted(() => { if (props.richText && props.el !== 'div') { throw new Error('Rich-text prop must be used with el="div" for correct HTML semantics'); } if (props.richText && props.variant === 'title') { throw new Error('Rich-text prop cannot be used with the title variant.'); } if (props.richText && props.variant === 'subtitle') { throw new Error('Rich-text prop cannot be used with the subtitle variant.'); } }); </script> <script lang="ts"> /** * The Typography component makes it easy to apply a default set of font weights, sizes and other text styles * easily to text. The variants and properties match with those found in Figma. * * For example, seeing text with the typography styling of * * @example * import { BentoTypography } from '@adyen/bento-vue2'; * * export default { * components: { BentoTypography }, * template: ` * <bento-typography> * ... text content * </bento-typography> * ` * } */ export default { name: 'bento-typography', inheritAttrs: true, }; </script> <style lang="scss" scoped src="./typography.scss" />
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Canvas, Meta } from '@storybook/blocks';
|
|
2
|
+
import * as useBentoCurrencyStories from './use-bento-currency.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={useBentoCurrencyStories} />
|
|
5
|
+
|
|
6
|
+
# useBentoCurrency
|
|
7
|
+
|
|
8
|
+
A composable that returns a function to format a number into a fully formatted and localized currency string. It
|
|
9
|
+
enforces the format `[localized number][non-breaking space][ISO code]`.
|
|
10
|
+
|
|
11
|
+
<Canvas of={useBentoCurrencyStories.Default} />
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
The `useBentoCurrency` composable returns an object containing a `formatCurrency` function that you can use to format
|
|
16
|
+
currency values.
|
|
17
|
+
|
|
18
|
+
## Remarks
|
|
19
|
+
|
|
20
|
+
The formatting process involves several steps:
|
|
21
|
+
|
|
22
|
+
1. It safely resolves the input `amount` into a valid number.
|
|
23
|
+
2. If `majorUnits` is `false` (the default), it converts the amount from minor units to major units (e.g., 12345 cents
|
|
24
|
+
becomes 123.45 euros).
|
|
25
|
+
3. It determines the correct number of decimal places for the given currency, handling standard (e.g., 2 for EUR) and
|
|
26
|
+
non-standard (e.g., 3 for BHD) cases.
|
|
27
|
+
4. It uses the underlying `vue-i18n` library to format the number according to the current locale, then reconstructs
|
|
28
|
+
the string to ensure the format is always `[number][non-breaking space][code]`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { BentoInputField } from '@/components/input-field'; import { BentoTypography } from '@/components/typography'; import type { Meta, StoryObj } from '@storybook/vue'; import { computed, ref } from 'vue'; import { useBentoCurrency } from './use-bento-currency'; import UseBentoCurrencyExample from './__tests__/use-bento-currency-example.vue?raw'; import { storybookDocsParameter } from '@/utils/ts/storybook'; const meta: Meta = { title: 'useBentoCurrency', }; export default meta; export const Default: StoryObj = { render: () => ({ components: { BentoInputField, BentoTypography }, template: ` <div> <bento-input-field v-model="input" label="Format Currency to BHD" /> <bento-typography>Formatted Currency: {{ formattedCurrency }}</bento-typography> </div> `, setup() { const input = ref('123456789'); const { formatCurrency } = useBentoCurrency(); const formattedCurrency = computed(() => { return formatCurrency(input.value, { currency: 'EUR' }); }); return { input, formattedCurrency, }; }, }), parameters: storybookDocsParameter(UseBentoCurrencyExample), };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Canvas, Meta } from '@storybook/blocks';
|
|
2
|
+
import * as useClickOutsideStories from './use-click-outside.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={useClickOutsideStories} />
|
|
5
|
+
|
|
6
|
+
# useClickOutside
|
|
7
|
+
|
|
8
|
+
Composable that listens for clicks outside of an element.
|
|
9
|
+
|
|
10
|
+
<Canvas of={useClickOutsideStories.Default} />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { action } from '@storybook/addon-actions'; import { ref } from 'vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import type { Meta, StoryObj } from '@storybook/vue'; import { BentoTypography } from '@/components/typography'; import { BentoCard } from '@/components/card'; import { isVue2 } from 'vue-demi'; import { useClickOutside } from './use-click-outside'; const meta: Meta = { title: 'useClickOutside', argTypes: { // Values target: { description: 'Reference to an HTML element to which the listener will be attached to', table: { type: { summary: 'Ref<UnwrapRef<HTMLDivElement>>' } }, control: { disable: true }, }, handler: { description: 'Function that will be called when the listener gets triggered', table: { type: { summary: 'OnClickOutsideHandler' } }, control: { disable: true }, }, optons: { name: 'options', description: 'Options to be passed to the listener (optional)', table: { type: { summary: 'OnClickOutsideOptions' } }, control: { disable: true }, }, }, }; export default meta; // Default const DefaultCode = ` <template> <div> <div ref="clickOutsideRef"></div> <div ref="ignoredElementRef"></div> </div> </template> <script setup lang="ts"> import { useClickOutside } from '@adyen/bento-vue2' import { ref } from 'vue' const clickOutsideRef = ref<HTMLDivElement>(null) const ignoredElementRef = ref<HTMLDivElement>(null) const options: OnClickOutsideOptions = { ignore: [ignoredElementRef] } const clickedAction = () => { // Your action handler } useClickOutside(clickOutsideRef, clickedAction, options) </script>`; export const Default: StoryObj = { render: _args => ({ components: { BentoCard, BentoTypography }, template: ` <div> <div ref="clickOutsideRef"> <bento-card> {{args.title}} </bento-card> </div> <bento-typography>Total click outside events triggered: {{totalClickOutsideCount}} </bento-typography> </div> `, setup(props) { const clickOutsideRef = ref<HTMLDivElement>(null); const totalClickOutsideCount = ref(0); const clickedAction = () => { totalClickOutsideCount.value += 1; return action('trigger'); }; useClickOutside(clickOutsideRef, clickedAction); return { // Refs clickOutsideRef, // Values totalClickOutsideCount, args: isVue2 ? props : _args, }; }, }), parameters: storybookDocsParameter(DefaultCode), };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Canvas, Meta, Story } from '@storybook/blocks';
|
|
2
|
+
import * as BentoHighlightStories from './highlight.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={BentoHighlightStories} />
|
|
5
|
+
|
|
6
|
+
# Highlight
|
|
7
|
+
|
|
8
|
+
The highlight component is a visual style applied to existing UI elements to draw user attention to new, updated, or
|
|
9
|
+
important information. It features a pulsating green border with a subtle green shadow, designed to be noticeable
|
|
10
|
+
without being overly intrusive.
|
|
11
|
+
|
|
12
|
+
<Canvas withSource="closed">
|
|
13
|
+
<Story of={BentoHighlightStories.Default} />
|
|
14
|
+
</Canvas>
|
|
15
|
+
|
|
16
|
+
## When to use
|
|
17
|
+
|
|
18
|
+
- Use to subtly draw attention to a single, specific element that is new, updated, or requires only brief attention.
|
|
19
|
+
- Don't use for complex new features or elements that require instruction or explanation. For those use a tutorial
|
|
20
|
+
instead.
|
|
21
|
+
- Don't use for alerts or errors. Use alert banner or toast for those instead.
|
|
22
|
+
|
|
23
|
+
## Best practices
|
|
24
|
+
|
|
25
|
+
- Use sparingly. The highlight component is a powerful attention-grabber. Its effectiveness is directly proportional to
|
|
26
|
+
its rarity. Overuse will lead to "banner blindness" where users ignore it.
|
|
27
|
+
- The highlight style should wrap the entire target element (e.g., a card, a button, a checkbox with a label), not just
|
|
28
|
+
a part of it.
|
|
29
|
+
- If the component allows it, consider combining the highlight with a green `New` tag to strengthen the message further.
|
|
30
|
+
- Avoid highlighting too many elements simultaneously or repeatedly highlighting the same element.
|
|
31
|
+
- The highlight should be configured to be visible on first encounter only. Once user visits the page again, the
|
|
32
|
+
highlight should be gone.
|
|
33
|
+
|
|
34
|
+
## Modifiers
|
|
35
|
+
|
|
36
|
+
### Size
|
|
37
|
+
|
|
38
|
+
We provide three sizes:
|
|
39
|
+
|
|
40
|
+
- small
|
|
41
|
+
- medium
|
|
42
|
+
- large
|
|
43
|
+
|
|
44
|
+
These can be passed to the directive either as e.g. `v-bento-highlight-directive.medium` or
|
|
45
|
+
`v-bento-highlight-directive="{ size: 'medium' }"`.
|
|
46
|
+
|
|
47
|
+
In each of the sizes the shadow, as well as the ripple effect takes a different amount of space.
|
|
48
|
+
|
|
49
|
+
As a rule of thumb, the bigger the element, the bigger the size should be, however, in some very cramped layouts a
|
|
50
|
+
smaller size may work better even if the element is large.
|
|
51
|
+
|
|
52
|
+
### Extra padding
|
|
53
|
+
|
|
54
|
+
In cases where components do not have their own padding, you need to add space between the component and the ripple
|
|
55
|
+
effect. This can be done by passing e.g. `v-bento-highlight-directive="{ extraPadding: true }"`
|
|
56
|
+
|
|
57
|
+
### Rounded
|
|
58
|
+
|
|
59
|
+
In cases where components do not have their border-radius, you can add border-radius by passing e.g.
|
|
60
|
+
`v-bento-highlight-directive="{ rounded: true }"`
|
|
61
|
+
|
|
62
|
+
## Resources
|
|
63
|
+
|
|
64
|
+
- [Figma link](https://www.figma.com/design/uLabwF3243jdMDsNSP7U9I/Bento---Components?node-id=43817-41758&m=dev)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { BentoHighlightDirective } from './highlight'; import { ref } from 'vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { type Meta, type StoryObj } from '@storybook/vue'; import { BentoButton } from '@/components/button'; import { BentoCard } from '@/components/card'; import { BentoCheckbox } from '@/components/checkbox'; import { BentoTypography } from '@/components/typography'; import HighlightDefaultExample from './__tests__/highlight-default-example.vue?raw'; import { isVue2 } from 'vue-demi'; const meta: Meta = { title: 'Highlight', parameters: { layout: 'centered', }, argTypes: { size: { options: ['small', 'medium', 'large'], type: { name: 'string', required: false }, description: 'Size option for the highlight directive, passed as a modifier e.g. `v-bento-highlight-directive.small`', defaultValue: 'small', control: { type: 'select', }, }, }, }; export default meta; type Story = StoryObj<typeof BentoHighlightDirective>; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoButton, BentoCheckbox, BentoCard, BentoTypography }, directives: { BentoHighlightDirective }, props: Object.keys(argTypes), template: ` <div> <div v-if="args.size === 'medium'"> <bento-checkbox v-model="checked" v-bento-highlight-directive="{ size: 'medium', extraPadding: true, rounded: true }" > Checkbox label <template #description>Description that goes with the checkbox</template> </bento-checkbox> </div> <bento-card v-else-if="args.size === 'large'" v-bento-highlight-directive.large> Card title <template #description>Description that goes with the card</template> <template #content> <bento-typography> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris. Nisi ut aliquip ex ea commodo consequat. </bento-typography> </template> </bento-card> <bento-button v-else v-bento-highlight-directive>Button</bento-button> </div> `, setup(props) { const checked = ref(false); return { args: isVue2 ? props : _args, checked, }; }, }), parameters: storybookDocsParameter(HighlightDefaultExample), };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Canvas, Meta, Story } from '@storybook/blocks';
|
|
2
|
+
import * as KeyboardNavigationStories from './keyboard-navigation.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={KeyboardNavigationStories} />
|
|
5
|
+
|
|
6
|
+
# Keyboard navigation
|
|
7
|
+
|
|
8
|
+
The _keyboard navigation_ directive facilitates the keyboard navigation logic by exposing keyboard events that can be
|
|
9
|
+
used to implement logic attached to these keys beind captured by the `keydown` event.
|
|
10
|
+
|
|
11
|
+
<Canvas withSource="closed">
|
|
12
|
+
<Story of={KeyboardNavigationStories.Default} />
|
|
13
|
+
</Canvas>
|
|
14
|
+
|
|
15
|
+
## Use Cases
|
|
16
|
+
|
|
17
|
+
Use the directive if:
|
|
18
|
+
|
|
19
|
+
- You want to capture the keydown event to implement keyboard navigation on a given component
|
|
20
|
+
- The element being captured is an HTML element
|
|
21
|
+
|
|
22
|
+
### Do not use
|
|
23
|
+
|
|
24
|
+
- Doesn't work on components, only on HTML elements
|
|
25
|
+
|
|
26
|
+
## Events
|
|
27
|
+
|
|
28
|
+
- `keydown:escape`: Triggered when the "Esc" or "Escape" keys are pressed.
|
|
29
|
+
- `keydown:enter`: Triggered when the "Enter" key is pressed.
|
|
30
|
+
- `keydown:tab`: Triggered when the "Tab" key is pressed.
|
|
31
|
+
- `keydown:space`: Triggered when the "Space" key is pressed.
|
|
32
|
+
- `keydown:arrow-right`: Triggered when the "Right" or "ArrowRight" keys are pressed.
|
|
33
|
+
- `keydown:arrow-left`: Triggered when the "Left" or "ArrowLeft" keys are pressed.
|
|
34
|
+
- `keydown:arrow-up`: Triggered when the "Left" or "ArrowLeft" keys are pressed.
|
|
35
|
+
- `keydown:arrow-down`: Triggered when the "Down" or "ArrowDown" keys are pressed.
|
|
36
|
+
- `keydown:page-up`: Triggered when the "PageUp" key is pressed.
|
|
37
|
+
- `keydown:shift-page-up`: Triggered when "Shift" and "PageUp" keys are pressed simultaneously.
|
|
38
|
+
- `keydown:page-down`: Triggered when the "PageDown" key is pressed.
|
|
39
|
+
- `keydown:shift-page-down`: Triggered when "Shift" and "PageDown" keys are pressed simultaneously.
|
|
40
|
+
- `keydown:home`: Triggered when the "Home" key is pressed.
|
|
41
|
+
- `keydown:end`: Triggered when the "End" key is pressed.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { type Meta, type StoryObj } from '@storybook/vue'; import { action } from '@storybook/addon-actions'; import { ref } from 'vue'; import { BentoCard } from '@/components/card'; import { BentoFocusTrap } from '@/components/focus-trap'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { BentoKeyboardNavigationDirective } from './keyboard-navigation'; const meta: Meta = { title: 'Keyboard navigation', argTypes: { // Events 'keydown:escape': { defaultValue: '', description: 'Triggered when the "Esc" or "Escape" keys are pressed', table: { type: { summary: '(event: Event) => void' } }, control: { disable: true }, }, 'keydown:enter': { defaultValue: '', description: 'Triggered when the "Enter" key is pressed', table: { type: { summary: '(event: Event) => void' } }, control: { disable: true }, }, 'keydown:tab': { defaultValue: '', description: 'Triggered when the "Tab" key is pressed', table: { type: { summary: '(event: Event) => void' } }, control: { disable: true }, }, 'keydown:space': { defaultValue: '', description: 'Triggered when the "Space" key is pressed', table: { type: { summary: '(event: Event) => void' } }, control: { disable: true }, }, 'keydown:arrow-right': { defaultValue: '', description: 'Triggered when the "Right" or "ArrowRight" keys are pressed', table: { type: { summary: '(event: Event) => void' } }, control: { disable: true }, }, 'keydown:arrow-left': { defaultValue: '', description: 'Triggered when the "Left" or "ArrowLeft" keys are pressed', table: { type: { summary: '(event: Event) => void' } }, control: { disable: true }, }, 'keydown:arrow-up': { defaultValue: '', description: 'Triggered when the "Up" or "ArrowUp" keys are pressed', table: { type: { summary: '(event: Event) => void' } }, control: { disable: true }, }, 'keydown:arrow-down': { defaultValue: '', description: 'Triggered when the "Down" or "ArrowDown" keys are pressed', table: { type: { summary: '(event: Event) => void' } }, control: { disable: true }, }, 'keydown:page-up': { defaultValue: '', description: 'Triggered when the "PageUp" key is pressed', table: { type: { summary: '(event: Event) => void' } }, control: { disable: true }, }, 'keydown:page-down': { defaultValue: '', description: 'Triggered when the "PageDown" key is pressed', table: { type: { summary: '(event: Event) => void' } }, control: { disable: true }, }, 'keydown:home': { defaultValue: '', description: 'Triggered when the "Home" key is pressed', table: { type: { summary: '(event: Event) => void' } }, control: { disable: true }, }, 'keydown:end': { defaultValue: '', description: 'Triggered when the "End" key is pressed', table: { type: { summary: '(event: Event) => void' } }, control: { disable: true }, }, }, }; export default meta; type Story = StoryObj<typeof BentoKeyboardNavigationDirective>; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoCard, BentoFocusTrap }, directives: { BentoKeyboardNavigationDirective }, props: Object.keys(argTypes), template: ` <div ref="containerRef" style="max-width: 300px" v-bento-keyboard-navigation-directive v-on="{ 'keydown:escape': onKeyDown('Esc'), 'keydown:enter': onKeyDown('Enter'), 'keydown:tab': onKeyDown('Tab'), 'keydown:arrow-right': onKeyDown('ArrowRight'), 'keydown:arrow-left': onKeyDown('ArrowLeft'), 'keydown:arrow-up': onKeyDown('ArrowUp'), 'keydown:arrow-down': onKeyDown('ArrowDown'), 'keydown:page-up': onKeyDown('PageUp'), 'keydown:page-down': onKeyDown('PageDown'), 'keydown:home': onKeyDown('Home'), 'keydown:end': onKeyDown('End'), 'keydown:space': onKeyDown('Space'), }" > <bento-focus-trap> <bento-card>{{ keyDownText }}</bento-card> </bento-focus-trap> </div> `, setup() { const keyDownText = ref('Press a key'); const containerRef = ref(null); const onKeyDown = (keyDown: string) => ({ detail: event }: CustomEvent) => { // Stop propagation event.stopPropagation(); event.preventDefault(); event.stopImmediatePropagation(); keyDownText.value = keyDown; action('keydown')(keyDown); }; return { // Refs containerRef, // Values keyDownText, // Events onKeyDown, }; }, }), parameters: storybookDocsParameter(` <div v-bento-keyboard-navigation-directive v-on="{ 'keydown:escape': onKeyDown('Esc'), 'keydown:enter': onKeyDown('Enter'), 'keydown:tab': onKeyDown('Tab'), 'keydown:arrow-right': onKeyDown('ArrowRight'), 'keydown:arrow-left': onKeyDown('ArrowLeft'), 'keydown:arrow-up': onKeyDown('ArrowUp'), 'keydown:arrow-down': onKeyDown('ArrowDown'), 'keydown:page-up': onKeyDown('PageUp'), 'keydown:page-down': onKeyDown('PageDown'), 'keydown:home': onKeyDown('Home'), 'keydown:end': onKeyDown('End'), 'keydown:space': onKeyDown('Space'), }" > Content here </div> `), };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Canvas, Meta, Story } from '@storybook/blocks';
|
|
2
|
+
import * as TooltipStories from './tooltip.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={TooltipStories} />
|
|
5
|
+
|
|
6
|
+
# Tooltip
|
|
7
|
+
|
|
8
|
+
A tooltip is a small container that appears contextually on hover (tap on touch devices) and sits above the page’s
|
|
9
|
+
content.
|
|
10
|
+
|
|
11
|
+
<Canvas withSource="closed">
|
|
12
|
+
<Story of={TooltipStories.Default} />
|
|
13
|
+
</Canvas>
|
|
14
|
+
|
|
15
|
+
## Use Cases
|
|
16
|
+
|
|
17
|
+
Use a tooltip when you need to display simple, concise and static text information.
|
|
18
|
+
|
|
19
|
+
It can be used to:
|
|
20
|
+
|
|
21
|
+
- Explain icon buttons.
|
|
22
|
+
- Provide guidance on form inputs.
|
|
23
|
+
- Display additional information for data visualization.
|
|
24
|
+
- Elaborate on abbreviations or acronyms.
|
|
25
|
+
- Clarify the purpose of interactive elements.
|
|
26
|
+
|
|
27
|
+
### Do not use
|
|
28
|
+
|
|
29
|
+
Don't use a tooltip in the following cases:
|
|
30
|
+
|
|
31
|
+
- when you need to provide important information that is needed by the user to complete the task.
|
|
32
|
+
- when you need to show richer piece of information (title, text, image) or get user to perform certain contextual
|
|
33
|
+
tasks. Consider using a `popover` component instead.
|
|
34
|
+
|
|
35
|
+
### Trigger
|
|
36
|
+
|
|
37
|
+
A tooltip is triggered on hover (tap on touch devices). When hovered over, it doesn't disappear until the cursor moves
|
|
38
|
+
away from the hover trigger.
|
|
39
|
+
|
|
40
|
+
If there is not enough space for the tooltip to appear in the desired position (less than `80px`), it will automatically
|
|
41
|
+
adjust its placement to the available space (`placement: auto`).
|
|
42
|
+
|
|
43
|
+
The Tooltip always appears `2px` away from the trigger, regardless of its position.
|
|
44
|
+
|
|
45
|
+
## Variations
|
|
46
|
+
|
|
47
|
+
The are no variations for this component.
|
|
48
|
+
|
|
49
|
+
## Modifiers
|
|
50
|
+
|
|
51
|
+
### Position
|
|
52
|
+
|
|
53
|
+
This property positions the tooltip relative to the trigger element. It's of type `BentoTooltipPosition` and it can take
|
|
54
|
+
the following values:
|
|
55
|
+
|
|
56
|
+
- `BentoTooltipPosition.TOP`: the default value. Displays the tooltip to the top of the trigger element.
|
|
57
|
+
- `BentoTooltipPosition.RIGHT`: displays the tooltip to the right of the trigger element.
|
|
58
|
+
- `BentoTooltipPosition.BOTTOM`: displays the tooltip to the bottom of the trigger element.
|
|
59
|
+
- `BentoTooltipPosition.LEFT`: displays the tooltip to the left of the trigger element.
|
|
60
|
+
|
|
61
|
+
## Accessibility
|
|
62
|
+
|
|
63
|
+
The Tooltip component follows the [tooltip pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/) specified in the
|
|
64
|
+
WAI-ARIA guidelines, and is thus accessible and recognised as such by assistive technology.
|
|
65
|
+
|
|
66
|
+
### Keyboard interaction
|
|
67
|
+
|
|
68
|
+
The Tooltip is reachable through keyboard navigation and follows the logical navigation flow of the page. A detailed
|
|
69
|
+
list of keyboard interactions is provided in the table below.
|
|
70
|
+
|
|
71
|
+
| Keyboard interaction | Output |
|
|
72
|
+
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
73
|
+
| `Tab` | When focus is moved to the tooltip trigger, it displays the tooltip. When the focus is moved away from the tooltip trigger, it hides the tooltip. |
|
|
74
|
+
| `Esc` | When focus is on the tooltip, it hides the tooltip. |
|
|
75
|
+
|
|
76
|
+
### Roles, States, and Properties
|
|
77
|
+
|
|
78
|
+
| ARIA attribute | is automatic? | fallback used | manual override |
|
|
79
|
+
| ------------------ | ------------------------------------------------------------------------- | ------------- | --------------- |
|
|
80
|
+
| `aria-role` | Yes, set to 'tooltip'. | - | - |
|
|
81
|
+
| `aria-describedby` | Yes, set on the tooltip trigger to reference the tooltip via a unique id. | - | - |
|
|
82
|
+
| `aria-hidden` | Yes, set internally as the tooltip is shown/hidden, | - | - |
|
|
83
|
+
|
|
84
|
+
## Resources
|
|
85
|
+
|
|
86
|
+
- [Figma link](https://www.figma.com/file/uLabwF3243jdMDsNSP7U9I/Bento---Components?node-id=1913-29485&t=GYlnKZx6QGFIh0gn-0)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { BentoTooltipDirective } from './tooltip'; import { BentoTooltipPosition } from './tooltip.types'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import BentoModal from '@/components/modal/modal.vue'; import { BentoInfoIcon } from '@/components/info-icon'; import { type Meta, type StoryObj } from '@storybook/vue'; import BentoButton from '@/components/button/button.vue'; import { isVue2 } from 'vue-demi'; const meta: Meta = { title: 'Tooltip', parameters: { layout: 'centered', }, argTypes: { position: { description: 'Position the tooltip should take if space is available. Defaults to "top"', options: Object.values(BentoTooltipPosition), mapping: BentoTooltipPosition, control: { type: 'select', }, table: { defaultValue: { summary: 'BentoTooltipPosition.TOP' }, type: { summary: 'BentoTooltipPosition' }, }, }, text: { description: 'Text showed in the tooltip on hover', control: 'text', table: { type: { summary: 'string' }, }, }, }, }; export default meta; type Story = StoryObj<typeof BentoButton>; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoButton }, directives: { BentoTooltipDirective }, props: Object.keys(argTypes), template: ` <div class="b-tooltip-story"> <bento-button class="b-tooltip-story__tooltip-target" v-bento-tooltip-directive:[args.position]="args.text" > Toggle tooltip </bento-button> </div> `, setup(props) { return { args: isVue2 ? props : _args, }; }, }), args: { text: 'Tooltip content', position: BentoTooltipPosition.TOP, }, parameters: storybookDocsParameter(` <template> <bento-button v-bento-tooltip-directive:[BentoTooltipPosition.TOP]="refWithTooltipText"> Toggle tooltip </bento-button> </template> <script setup lang="ts"> import { ref } from "vue" import { BentoButton, BentoTooltipPosition, BentoTooltipDirective as vBentoTooltipDirective, } from "@adyen/bento-vue2" const refWithTooltipText = ref('Tooltip text') </script> `), }; export const InsideModal: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoInfoIcon }, directives: { BentoTooltipDirective }, props: Object.keys(argTypes), template: ` <bento-modal :is-open="true"> Title of the Modal <template #content> Mandatory content slot <bento-info-icon :tooltip-text="args.text" :tooltip-position="args.position" /> </template> </bento-modal> `, setup(props) { return { args: isVue2 ? props : _args, }; }, }), args: { text: 'Tooltip content', position: BentoTooltipPosition.RIGHT, }, };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import BentoVue from './install'; export * from './components/accordion'; export * from './components/action-bar'; export * from './components/alert'; export * from './components/avatar'; export * from './components/button'; export * from './components/dashed-underline'; export * from './components/data-grid'; export * from './components/card'; export * from './components/date-picker'; export * from './components/date-range-picker'; export * from './components/dropdown'; export * from './components/checkbox'; export * from './components/chip'; export * from './components/click-outside'; export * from './components/code-snippet'; export * from './components/country'; export * from './components/currency'; export * from './components/date'; export * from './components/divider'; export * from './components/empty-state'; export * from './components/file-uploader'; export * from './components/filter-bar'; export * from './components/form-layout'; export * from './components/header-with-views'; export * from './components/image'; export * from './components/info-icon'; export * from './components/input-field'; export * from './components/input-field-password'; export * from './components/input-field-phone-number'; export * from './components/inspector'; export * from './components/layout'; export * from './components/loading-indicator'; export * from './components/link'; export * from './components/menu'; export * from './components/modal'; export * from './components/modal-fullscreen'; export * from './components/header'; export * from './components/pagination'; export * from './components/payment-method'; export * from './components/popover'; export * from './components/promo-banner'; export * from './components/radio-group'; export * from './components/rich-text-editor'; export * from './components/search-bar'; export * from './components/secondary-nav'; export * from './components/selection-card'; export * from './components/segmented-control'; export * from './components/sidepanel'; export * from './components/status'; export * from './components/stepper'; export * from './components/structured-list'; export * from './components/summary-grid'; export * from './components/tabs'; export * from './components/tag'; export * from './components/textarea'; export * from './components/timeline'; export * from './components/toast'; export * from './components/toggle'; export * from './components/tutorial'; export * from './components/typography'; // Export Composables export * from './composables/use-bento-base-filter'; export * from './composables/use-bento-currency'; export * from './composables/use-bento-theme'; export * from './composables/use-bento-toast-controller'; export * from './composables/use-click-outside'; export * from './composables/use-form-validate'; // Export Templates export * from './templates/dashboard-template'; export * from './templates/data-grid-template'; // Export Types export * from './types'; // Export Directives export * from './directives'; // AdlVue Plugin export default BentoVue; export { BentoTheme } from './install';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { ref } from 'vue'; import { isVue2 } from 'vue-demi'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import type { Meta, StoryObj } from '@storybook/vue'; import { BentoDropdown } from '@/components/dropdown'; import { BentoDataGrid } from '@/components/data-grid'; import { BentoSegmentedControl } from '@/components/segmented-control'; import { LumeLineChart } from '@adyen/lume'; import BentoDashboardSection from './dashboard-section.vue'; import { type BentoDashboardTemplateHeader } from '../../dashboard-template.types'; import { type BentoListboxOptions } from '@/types/listbox'; const meta: Meta = { title: 'Dashboard template/Dashboard section', component: BentoDashboardSection, }; export default meta; type Story = StoryObj<typeof BentoDashboardSection>; const HEADER_PROPS: BentoDashboardTemplateHeader = { title: 'Section', infoIconTooltipText: 'Info', }; const SEGMENTED_CONTROL_ITEMS = [ { label: 'Count', value: 'count' }, { label: 'Amount', value: 'amount' }, ]; const DROPDOWN_OPTIONS: BentoListboxOptions = [ { label: 'Monthly', value: 'monthly' }, { label: 'Yearly', value: 'yearly' }, ]; const LUME_DATA = { data: [ { label: 'Skyblue', color: 'skyblue', values: [10, 30, 20, 50, 40], }, { label: 'Green', color: 'green', values: [50, 60, 90, 30, 10], }, ], labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'], options: { yAxisOptions: { gridLines: true, title: 'Y-label', }, }, }; const GRID_DATA = [ { id: 1, paymentMethods: 'Visa', amount: '1,234 USD', numeric: '54,213' }, { id: 2, paymentMethods: 'MasterCard', amount: '1,234 USD', numeric: '54,213' }, { id: 3, paymentMethods: 'iDeal', amount: '1,234 USD', numeric: '54,213' }, { id: 4, paymentMethods: 'Klarna', amount: '1,234 USD', numeric: '54,213' }, { id: 5, paymentMethods: 'Apple Pay', amount: '1,234 USD', numeric: '54,213' }, ]; const GRID_COLUMNS = [ { field: 'paymentMethods', label: 'Payment methods', minWidth: 300, mandatory: true }, { field: 'amount', label: 'Amount', numeric: true, minWidth: 300 }, { field: 'numeric', label: 'Numeric', numeric: true, minWidth: 300 }, ]; const graphCode = ` <template> <bento-dashboard-template :header="{ title: "Dashboard" }"> <bento-dashboard-section :header="dashboardSectionHeader"> <template #controls> <bento-dropdown :model-value="dropdownValue" @update:model-value="dropdownValue = $event" :items='dropdownOptions' /> <bento-segmented-control :items="segmentedControlItems" :model-value="segmentedControlValue" @update:model-value="segmentedControlValue = $event"/> </template> <lume-line-chart v-bind="lumeData" /> </bento-dashboard-section> </bento-dashboard-section> </template> <script setup lang="ts"> import { BentoDashboardTemplate, BentoDashboardSection, BentoDropdown, BentoSegmentedControl } from '@adyen/bento-vue2' import { LumeLineChart } from '@adyen/lume'; const dashboardSectionHeader = ${JSON.stringify(HEADER_PROPS, null, 4)}; const dropdownOptions = ${JSON.stringify(DROPDOWN_OPTIONS, null, 4)}; const segmentedControlItems = ${JSON.stringify(SEGMENTED_CONTROL_ITEMS, null, 4)}; const lumeData = ${JSON.stringify(LUME_DATA, null, 4)}; const segmentedControlValue = ref('count'); const dropdownValue = ref('monthly'); </script> `; export const Graph: Story = { render: (_args, { argTypes }) => ({ components: { BentoDashboardSection, BentoDropdown, BentoSegmentedControl, LumeLineChart }, props: Object.keys(argTypes), template: ` <bento-dashboard-section v-bind="args"> <template #controls> <bento-dropdown :model-value="dropdownValue" @update:model-value="dropdownValue = $event" :items='DROPDOWN_OPTIONS' /> <bento-segmented-control :items="SEGMENTED_CONTROL_ITEMS" :model-value="segmentedControlValue" @update:model-value="segmentedControlValue = $event"/> </template> <lume-line-chart v-bind="LUME_DATA" /> </bento-dashboard-section> `, setup(props) { const segmentedControlValue = ref(SEGMENTED_CONTROL_ITEMS[0].value); const dropdownValue = ref(DROPDOWN_OPTIONS[0].value); return { // Values args: isVue2 ? props : _args, segmentedControlValue, dropdownValue, // Contants LUME_DATA, SEGMENTED_CONTROL_ITEMS, DROPDOWN_OPTIONS, }; }, }), args: { header: HEADER_PROPS, }, parameters: storybookDocsParameter(graphCode), }; const dataGridCode = ` <template> <bento-dashboard-template :header="{ title: "Dashboard" }"> <bento-dashboard-section :header="dashboardSectionHeader"> <bento-data-grid :data="gridData" :columns="gridColumns" /> </bento-dashboard-section> </bento-dashboard-section> </template> <script setup lang="ts"> import { BentoDashboardTemplate, BentoDashboardSection, BentoDataGrid, } from '@adyen/bento-vue2' import { LumeLineChart } from '@adyen/lume'; const dashboardSectionHeader = ${JSON.stringify(HEADER_PROPS, null, 4)}; const gridData = ${JSON.stringify(GRID_DATA, null, 4)}; const gridColumns = ${JSON.stringify(GRID_COLUMNS, null, 4)}; </script> `; export const DataGrid: Story = { render: (_args, { argTypes }) => ({ components: { BentoDashboardSection, BentoDataGrid }, props: Object.keys(argTypes), template: ` <bento-dashboard-section v-bind="args"> <bento-data-grid :data="GRID_DATA" :columns="GRID_COLUMNS" /> </bento-dashboard-section> `, setup(props) { return { // Values args: isVue2 ? props : _args, // Contants GRID_COLUMNS, GRID_DATA, }; }, }), args: { header: HEADER_PROPS, }, parameters: storybookDocsParameter(dataGridCode), }; const twoColumnsCode = ` <template> <bento-dashboard-template :header="{ title: "Dashboard" }"> <bento-dashboard-section :header="dashboardSectionHeader"> <template #controls> <bento-dropdown :model-value="dropdownValue" @update:model-value="dropdownValue = $event" :items='dropdownOptions' /> <bento-segmented-control :items="segmentedControlItems" :model-value="segmentedControlValue" @update:model-value="segmentedControlValue = $event"/> </template> <template #content-col-1><lume-line-chart v-bind="lumeData" /></template> <template #content-col-2><lume-line-chart v-bind="lumeData" /></template> </bento-dashboard-section> </template> <script setup lang="ts"> import { BentoDashboardTemplate, BentoDashboardSection, BentoDropdown, BentoSegmentedControl } from '@adyen/bento-vue2' import { LumeLineChart } from '@adyen/lume'; const dashboardSectionHeader = ${JSON.stringify(HEADER_PROPS, null, 4)}; const dropdownOptions = ${JSON.stringify(DROPDOWN_OPTIONS, null, 4)}; const segmentedControlItems = ${JSON.stringify(SEGMENTED_CONTROL_ITEMS, null, 4)}; const lumeData = ${JSON.stringify(LUME_DATA, null, 4)}; const segmentedControlValue = ref('count'); const dropdownValue = ref('monthly'); </script> `; export const TwoColumns: Story = { render: (_args, { argTypes }) => ({ components: { BentoDashboardSection, BentoDropdown, BentoSegmentedControl, LumeLineChart }, props: Object.keys(argTypes), template: ` <bento-dashboard-section v-bind="args"> <template #controls> <bento-dropdown :model-value="dropdownValue" @update:model-value="dropdownValue = $event" :items='DROPDOWN_OPTIONS' /> <bento-segmented-control :items="SEGMENTED_CONTROL_ITEMS" :model-value="segmentedControlValue" @update:model-value="segmentedControlValue = $event"/> </template> <template #content-col-1><lume-line-chart v-bind="LUME_DATA" /></template> <template #content-col-2><lume-line-chart v-bind="LUME_DATA" /></template> </bento-dashboard-section> `, setup(props) { const segmentedControlValue = ref(SEGMENTED_CONTROL_ITEMS[0].value); const dropdownValue = ref(DROPDOWN_OPTIONS[0].value); return { // Values args: isVue2 ? props : _args, segmentedControlValue, dropdownValue, // Contants LUME_DATA, SEGMENTED_CONTROL_ITEMS, DROPDOWN_OPTIONS, }; }, }), args: { header: HEADER_PROPS, }, parameters: storybookDocsParameter(twoColumnsCode), };
|
package/dist/assets/templates/dashboard-template/components/dashboard-section/dashboard-section.vue
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<template> <div class="b-dashboard-section" :class="conditionalClasses"> <bento-header v-bind="header" variant="component" class="b-dashboard-template__header"> <template v-if="hasSlot('infoIconTooltipContent')" #infoIconTooltipContent> <slot name="infoIconTooltipContent" /> </template> </bento-header> <div v-if="hasSlot('controls')" class="b-dashboard-section__controls"> <slot name="controls"></slot> </div> <div v-if="!hasSlot('content-col-1') && !hasSlot('content-col-2')" class="b-dashboard-section__content"> <slot name="default"></slot> </div> <div v-else class="b-dashboard-section__columns"> <div class="b-dashboard-section__content"><slot name="content-col-1"></slot></div> <div class="b-dashboard-section__content"><slot name="content-col-2"></slot></div> </div> <bento-divider class="b-dashboard-section__divider" /> </div> </template> <script setup lang="ts"> import { computed, onMounted, useSlots } from 'vue'; import { BentoHeader } from '@/components/header'; import { BentoDivider } from '@/components/divider'; import { useHasSlot } from '@/composables'; import type { BentoDashboardTemplateHeader } from '../../dashboard-template.types'; const props = withDefaults( defineProps<{ /** * The header of the section */ header: BentoDashboardTemplateHeader; /** * Renders the section to take only half of the page */ halfWidth?: boolean; }>(), { halfWidth: false, } ); const slots = useSlots(); const hasSlot = useHasSlot(slots); const conditionalClasses = computed(() => ({ 'b-dashboard-section--half-width': props.halfWidth, })); onMounted(() => { if ((hasSlot('content-col-1') || hasSlot('content-col-2')) && props.halfWidth) { throw new Error('`content-col-1` and `content-col-2` cannot be used with half-width prop'); } }); </script> <script lang="ts"> /** * Dashboard section is subcomponent of Dashboard template meant to be used to create the different sections within the page. * * @example * import { BentoDashboardSection } from '@adyen/bento-vue2'; * * export default { * components: { BentoDashboardSection }, * template: ` * <bento-dashboard-section :header="{ title: 'Section' }" half-width> * <template #controls> * // Add your controls here * </template> * // You can render content with two cols * <template #content-col-1> * // Add your content here * </template> * <template #content-col-2> * // Add your content here * </template> * // Or you can render full width content by using default slot * // Add your content here * </bento-dashboard-section> * ` * } */ export default {}; </script> <style lang="scss" scoped src="./dashboard-section.scss" />
|