@adyen/bento-mcp 0.11.0 → 0.12.1
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 +36 -0
- package/README.md +24 -2
- package/SKILL.md +37 -7
- package/dist/assets/components/accordion/accordion.stories.ts +1 -1
- package/dist/assets/components/accordion/components/accordion-item.stories.ts +1 -1
- package/dist/assets/components/accordion/components/accordion-item.vue +1 -1
- package/dist/assets/components/action-bar/action-bar.docs.mdx +10 -3
- package/dist/assets/components/action-bar/action-bar.internal.types.ts +1 -0
- package/dist/assets/components/action-bar/action-bar.stories.ts +1 -1
- package/dist/assets/components/action-bar/action-bar.types.ts +1 -1
- package/dist/assets/components/action-bar/action-bar.vue +1 -1
- package/dist/assets/components/ai-tag/ai-tag.stories.ts +1 -1
- package/dist/assets/components/ai-tag/ai-tag.vue +1 -1
- package/dist/assets/components/alert/alert.stories.ts +1 -1
- package/dist/assets/components/alert/alert.types.ts +1 -1
- package/dist/assets/components/anchor-scroller/anchor-scroller.stories.ts +1 -1
- package/dist/assets/components/anchor-scroller/anchor-scroller.vue +1 -1
- package/dist/assets/components/avatar/avatar.internal.types.ts +1 -0
- package/dist/assets/components/avatar/avatar.stories.ts +1 -1
- package/dist/assets/components/avatar/avatar.types.ts +1 -1
- package/dist/assets/components/button/button.docs.mdx +4 -3
- package/dist/assets/components/button/button.stories.ts +1 -1
- package/dist/assets/components/button/button.types.ts +1 -1
- package/dist/assets/components/button/components/ai-button/ai-button.stories.ts +1 -1
- package/dist/assets/components/button/components/ai-button/ai-button.vue +1 -1
- package/dist/assets/components/button/components/button-actions/button-actions.docs.mdx +3 -0
- package/dist/assets/components/button/components/button-actions/button-actions.internal.types.ts +1 -0
- package/dist/assets/components/button/components/button-actions/button-actions.stories.ts +1 -1
- package/dist/assets/components/button/components/button-actions/button-actions.types.ts +1 -1
- package/dist/assets/components/button/components/button-actions/button-actions.vue +1 -1
- package/dist/assets/components/button/components/loading-button/loading-button.docs.mdx +26 -23
- package/dist/assets/components/button/components/loading-button/loading-button.stories.ts +1 -1
- package/dist/assets/components/button/components/loading-button/loading-button.vue +1 -1
- package/dist/assets/components/button/components/toggle-button/toggle-button.stories.ts +1 -1
- package/dist/assets/components/card/card.docs.mdx +18 -1
- package/dist/assets/components/card/card.stories.ts +1 -1
- package/dist/assets/components/card/card.types.ts +1 -1
- package/dist/assets/components/card/card.vue +1 -1
- package/dist/assets/components/checkbox/checkbox.stories.ts +1 -1
- package/dist/assets/components/checkbox/checkbox.types.ts +1 -1
- package/dist/assets/components/checkbox/checkbox.vue +1 -1
- package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.docs.mdx +9 -14
- package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.stories.ts +1 -1
- package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.types.ts +1 -1
- package/dist/assets/components/checkbox/components/checkbox-group/checkbox-group.vue +1 -1
- package/dist/assets/components/chip/chip.stories.ts +1 -1
- package/dist/assets/components/chip/chip.vue +1 -1
- package/dist/assets/components/click-outside/click-outside.stories.ts +1 -1
- package/dist/assets/components/code-snippet/code-snippet.types.ts +1 -1
- package/dist/assets/components/code-snippet/code-snippet.vue +1 -1
- package/dist/assets/components/country/country.stories.ts +1 -1
- package/dist/assets/components/country/country.types.ts +1 -1
- package/dist/assets/components/country/country.vue +1 -1
- package/dist/assets/components/currency/currency.stories.ts +1 -1
- package/dist/assets/components/currency/currency.vue +1 -1
- package/dist/assets/components/dashed-underline/dashed-underline.stories.ts +1 -1
- package/dist/assets/components/data-grid/components/data-grid-cell-actions/data-grid-cell-actions.types.ts +1 -1
- package/dist/assets/components/data-grid/components/data-grid-cell-actions/data-grid-cell-actions.vue +1 -1
- package/dist/assets/components/data-grid/components/data-grid-config-settings/data-grid-config-settings.vue +1 -1
- package/dist/assets/components/data-grid/components/data-grid-row/data-grid-row.vue +1 -1
- package/dist/assets/components/data-grid/components/data-grid-static-icon/data-grid-static-icon.stories.ts +1 -1
- package/dist/assets/components/data-grid/components/data-grid-summary-cell/data-grid-summary-cell.stories.ts +1 -1
- package/dist/assets/components/data-grid/components/data-grid-summary-cell/data-grid-summary-cell.vue +1 -1
- package/dist/assets/components/data-grid/components/data-grid-tag-with-text-cell/data-grid-tag-with-text-cell.stories.ts +1 -1
- package/dist/assets/components/data-grid/components/data-grid-trend-cell/data-grid-trend-cell.stories.ts +1 -1
- package/dist/assets/components/data-grid/components/data-grid-trend-cell/data-grid-trend-cell.vue +1 -1
- package/dist/assets/components/data-grid/data-grid.docs.mdx +14 -61
- package/dist/assets/components/data-grid/data-grid.stories.ts +1 -1
- package/dist/assets/components/data-grid/data-grid.vue +1 -1
- package/dist/assets/components/date/date.stories.ts +1 -1
- package/dist/assets/components/date-picker/date-picker.stories.ts +1 -1
- package/dist/assets/components/date-picker/date-picker.types.ts +1 -1
- package/dist/assets/components/date-picker/date-picker.vue +1 -1
- package/dist/assets/components/date-range-picker/components/date-range-picker-calendar/date-range-picker-calendar.vue +1 -1
- package/dist/assets/components/date-range-picker/components/date-time-input/date-time-input.types.ts +1 -1
- package/dist/assets/components/date-range-picker/components/date-time-input/date-time-input.vue +1 -1
- package/dist/assets/components/date-range-picker/date-range-picker.docs.mdx +31 -6
- package/dist/assets/components/date-range-picker/date-range-picker.stories.ts +1 -1
- package/dist/assets/components/date-range-picker/date-range-picker.types.ts +1 -1
- package/dist/assets/components/date-range-picker/date-range-picker.vue +1 -1
- package/dist/assets/components/date-time-picker/date-time-picker.stories.ts +1 -1
- package/dist/assets/components/date-time-picker/date-time-picker.types.ts +1 -1
- package/dist/assets/components/divider/divider.internal.types.ts +1 -0
- package/dist/assets/components/divider/divider.stories.ts +1 -1
- package/dist/assets/components/divider/divider.types.ts +1 -1
- package/dist/assets/components/divider/divider.vue +1 -1
- package/dist/assets/components/draggable/components/draggable-handle/draggable-handle.stories.ts +1 -1
- package/dist/assets/components/draggable/draggable.stories.ts +1 -1
- package/dist/assets/components/draggable/draggable.vue +1 -1
- package/dist/assets/components/drawer/drawer.stories.ts +1 -1
- package/dist/assets/components/dropdown/components/dropdown-base-textbox/dropdown-base-textbox.internal.types.ts +1 -0
- package/dist/assets/components/dropdown/components/dropdown-base-textbox/dropdown-base-textbox.types.ts +1 -1
- package/dist/assets/components/dropdown/components/dropdown-base-textbox/dropdown-base-textbox.vue +1 -1
- package/dist/assets/components/dropdown/components/dropdown-default-textbox/dropdown-default-textbox.vue +1 -1
- package/dist/assets/components/dropdown/components/dropdown-options-container/dropdown-options-container.vue +1 -1
- package/dist/assets/components/dropdown/components/dropdown-small-textbox/dropdown-small-textbox.vue +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-avatar/dropdown-avatar.stories.ts +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-avatar/dropdown-avatar.types.ts +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-avatar/dropdown-avatar.vue +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-country/dropdown-country.stories.ts +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-country/dropdown-country.types.ts +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-country/dropdown-country.vue +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-currency/dropdown-currency.stories.ts +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-currency/dropdown-currency.types.ts +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-currency/dropdown-currency.vue +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-payment-method/dropdown-payment-method.stories.ts +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-payment-method/dropdown-payment-method.types.ts +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-payment-method/dropdown-payment-method.vue +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-tag/dropdown-tag.stories.ts +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-tag/dropdown-tag.types.ts +1 -1
- package/dist/assets/components/dropdown/components/variants/dropdown-tag/dropdown-tag.vue +1 -1
- package/dist/assets/components/dropdown/dropdown.docs.mdx +4 -40
- package/dist/assets/components/dropdown/dropdown.internal.types.ts +1 -0
- package/dist/assets/components/dropdown/dropdown.stories.ts +1 -1
- package/dist/assets/components/dropdown/dropdown.types.ts +1 -1
- package/dist/assets/components/dropdown/dropdown.vue +1 -1
- package/dist/assets/components/empty-state/empty-state.stories.ts +1 -1
- package/dist/assets/components/empty-state/empty-state.types.ts +1 -1
- package/dist/assets/components/file-uploader/components/file-uploader-file-card/file-uploader-file-card.stories.ts +1 -1
- package/dist/assets/components/file-uploader/components/file-uploader-file-card/file-uploader-file-card.types.ts +1 -1
- package/dist/assets/components/file-uploader/components/file-uploader-file-card/file-uploader-file-card.vue +1 -1
- package/dist/assets/components/file-uploader/components/file-uploader-restrictions/file-uploader-restrictions.types.ts +1 -1
- package/dist/assets/components/file-uploader/components/file-uploader-restrictions/file-uploader-restrictions.vue +1 -1
- package/dist/assets/components/file-uploader/file-uploader.internal.types.ts +1 -0
- package/dist/assets/components/file-uploader/file-uploader.stories.ts +1 -1
- package/dist/assets/components/file-uploader/file-uploader.types.ts +1 -1
- package/dist/assets/components/file-uploader/file-uploader.vue +1 -1
- package/dist/assets/components/filter-bar/components/all-filters-modal/all-filters-modal.stories.ts +1 -1
- package/dist/assets/components/filter-bar/components/all-filters-modal/all-filters-modal.types.ts +1 -1
- package/dist/assets/components/filter-bar/components/all-filters-modal/all-filters-modal.vue +1 -1
- package/dist/assets/components/filter-bar/components/all-filters-modal/components/all-filters-modal-filter-selection/all-filters-modal-filter-selection.types.ts +1 -0
- package/dist/assets/components/filter-bar/components/all-filters-modal/components/all-filters-modal-filter-selection/all-filters-modal-filter-selection.vue +1 -0
- package/dist/assets/components/filter-bar/components/all-filters-modal/components/all-filters-modal-selected-filter/all-filters-modal-selected-filter.vue +1 -0
- package/dist/assets/components/filter-bar/components/base-filter/base-filter.internal.types.ts +1 -0
- package/dist/assets/components/filter-bar/components/base-filter/base-filter.types.ts +1 -1
- package/dist/assets/components/filter-bar/components/base-filter/base-filter.vue +1 -1
- package/dist/assets/components/filter-bar/components/boolean-filter/boolean-filter.vue +1 -1
- package/dist/assets/components/filter-bar/components/date-filter/date-filter.vue +1 -1
- package/dist/assets/components/filter-bar/components/date-range-filter/date-range-filter.vue +1 -1
- package/dist/assets/components/filter-bar/components/input-filter/input-filter.types.ts +1 -1
- package/dist/assets/components/filter-bar/components/input-filter/input-filter.vue +1 -1
- package/dist/assets/components/filter-bar/components/input-with-dropdown-filter/input-with-dropdown-filter.stories.ts +1 -1
- package/dist/assets/components/filter-bar/components/input-with-dropdown-filter/input-with-dropdown-filter.vue +1 -1
- package/dist/assets/components/filter-bar/components/select-filter/components/select-filter-button/select-filter-button.vue +1 -1
- package/dist/assets/components/filter-bar/components/select-filter/select-filter.vue +1 -1
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-avatar-filter/select-avatar-filter.stories.ts +1 -1
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-country-filter/select-country-filter.stories.ts +1 -1
- package/dist/assets/components/filter-bar/components/select-filter/variants/select-country-filter/select-country-filter.vue +1 -1
- package/dist/assets/components/filter-bar/components/toggle-filter/toggle-filter.vue +1 -1
- package/dist/assets/components/filter-bar/filter-bar.docs.mdx +4 -62
- package/dist/assets/components/filter-bar/filter-bar.stories.ts +1 -1
- package/dist/assets/components/filter-bar/filter-bar.types.ts +1 -1
- package/dist/assets/components/filter-bar/filter-bar.vue +1 -1
- package/dist/assets/components/form-layout/form-layout.docs.mdx +0 -23
- package/dist/assets/components/form-layout/form-layout.stories.ts +1 -1
- package/dist/assets/components/header/header.stories.ts +1 -1
- package/dist/assets/components/header/header.types.ts +1 -1
- package/dist/assets/components/header/header.vue +1 -1
- package/dist/assets/components/header-with-views/components/header-with-views-all-views/header-with-views-all-views.vue +1 -1
- package/dist/assets/components/header-with-views/components/header-with-views-item-edit-form/header-with-views-edit-form.types.ts +1 -1
- package/dist/assets/components/header-with-views/components/header-with-views-item-edit-form/header-with-views-edit-form.vue +1 -1
- package/dist/assets/components/header-with-views/header-with-views.internal.types.ts +1 -0
- package/dist/assets/components/header-with-views/header-with-views.stories.ts +1 -1
- package/dist/assets/components/header-with-views/header-with-views.types.ts +1 -1
- package/dist/assets/components/header-with-views/header-with-views.vue +1 -1
- package/dist/assets/components/image/image.stories.ts +1 -1
- package/dist/assets/components/info-icon/info-icon.stories.ts +1 -1
- package/dist/assets/components/input-field/input-field.docs.mdx +1 -13
- package/dist/assets/components/input-field/input-field.stories.ts +1 -1
- package/dist/assets/components/input-field/input-field.types.ts +1 -1
- package/dist/assets/components/input-field/input-field.vue +1 -1
- package/dist/assets/components/input-field-password/input-field-password.internal.types.ts +1 -0
- package/dist/assets/components/input-field-password/input-field-password.stories.ts +1 -1
- package/dist/assets/components/input-field-password/input-field-password.types.ts +1 -1
- package/dist/assets/components/input-field-password/input-field-password.vue +1 -1
- package/dist/assets/components/input-field-phone-number/input-field-phone-number.stories.ts +1 -1
- package/dist/assets/components/input-field-phone-number/input-field-phone-number.types.ts +1 -1
- package/dist/assets/components/input-field-phone-number/input-field-phone-number.vue +1 -1
- package/dist/assets/components/input-time/input-time.docs.mdx +17 -0
- package/dist/assets/components/input-time/input-time.stories.ts +1 -1
- package/dist/assets/components/input-time/input-time.types.ts +1 -1
- package/dist/assets/components/input-time/input-time.vue +1 -1
- package/dist/assets/components/inspector/inspector.stories.ts +1 -1
- package/dist/assets/components/inspector/inspector.vue +1 -1
- package/dist/assets/components/layout/components/layout-row/layout-row.stories.ts +1 -1
- package/dist/assets/components/layout/components/layout-row/layout-row.vue +1 -1
- package/dist/assets/components/layout/layout.docs.mdx +10 -0
- package/dist/assets/components/layout/layout.internal.types.ts +1 -0
- package/dist/assets/components/layout/layout.stories.ts +1 -1
- package/dist/assets/components/layout/layout.types.ts +1 -1
- package/dist/assets/components/link/link.stories.ts +1 -1
- package/dist/assets/components/link/link.types.ts +1 -1
- package/dist/assets/components/link/link.vue +1 -1
- package/dist/assets/components/list/list.stories.ts +1 -1
- package/dist/assets/components/loading-indicator/loading-indicator.stories.ts +1 -1
- package/dist/assets/components/menu/components/menu-item/menu-item.types.ts +1 -1
- package/dist/assets/components/menu/components/menu-item/menu-item.vue +1 -1
- package/dist/assets/components/menu/components/menu-item-list/menu-item-list.vue +1 -1
- package/dist/assets/components/menu/components/sub-menu-item-list/sub-menu-item-list.vue +1 -1
- package/dist/assets/components/menu/menu.docs.mdx +9 -0
- package/dist/assets/components/menu/menu.stories.ts +1 -1
- package/dist/assets/components/menu/menu.types.ts +1 -1
- package/dist/assets/components/menu/menu.vue +1 -1
- package/dist/assets/components/modal/components/base-modal/base-modal.vue +1 -1
- package/dist/assets/components/modal/components/modal-page/modal-page.vue +1 -1
- package/dist/assets/components/modal/modal.internal.types.ts +1 -0
- package/dist/assets/components/modal/modal.stories.ts +1 -1
- package/dist/assets/components/modal/modal.types.ts +1 -1
- package/dist/assets/components/modal/modal.vue +1 -1
- package/dist/assets/components/modal-fullscreen/components/modal-fullscreen-page.vue +1 -1
- package/dist/assets/components/modal-fullscreen/modal-fullscreen.stories.ts +1 -1
- package/dist/assets/components/modal-fullscreen/modal-fullscreen.vue +1 -1
- package/dist/assets/components/navigation-menu/components/navigation-menu-group/navigation-menu-group.internal.types.ts +1 -0
- package/dist/assets/components/navigation-menu/components/navigation-menu-group/navigation-menu-group.types.ts +1 -1
- package/dist/assets/components/navigation-menu/components/navigation-menu-group/navigation-menu-group.vue +1 -1
- package/dist/assets/components/navigation-menu/components/navigation-menu-item/navigation-menu-item.vue +1 -1
- package/dist/assets/components/navigation-menu/navigation-menu.internal.types.ts +1 -0
- package/dist/assets/components/navigation-menu/navigation-menu.stories.ts +1 -1
- package/dist/assets/components/navigation-menu/navigation-menu.types.ts +1 -1
- package/dist/assets/components/navigation-menu/navigation-menu.vue +1 -1
- package/dist/assets/components/pagination/components/pagination-context/pagination-context.vue +1 -1
- package/dist/assets/components/pagination/components/pagination-results-per-page/pagination-results-per-page.vue +1 -1
- package/dist/assets/components/pagination/pagination.stories.ts +1 -1
- package/dist/assets/components/pagination/pagination.types.ts +1 -1
- package/dist/assets/components/pagination/pagination.vue +1 -1
- package/dist/assets/components/payment-method/payment-method.stories.ts +1 -1
- package/dist/assets/components/payment-method/payment-method.types.ts +1 -1
- package/dist/assets/components/popover/popover.docs.mdx +32 -9
- package/dist/assets/components/popover/popover.stories.ts +1 -1
- package/dist/assets/components/popover/popover.types.ts +1 -1
- package/dist/assets/components/popover/popover.vue +1 -1
- package/dist/assets/components/popper-container/popper-container.types.ts +1 -1
- package/dist/assets/components/popper-container/popper-container.vue +1 -1
- package/dist/assets/components/progress-bar/progress-bar.stories.ts +1 -1
- package/dist/assets/components/progress-bar/progress-bar.vue +1 -1
- package/dist/assets/components/promo-banner/promo-banner.stories.ts +1 -1
- package/dist/assets/components/promo-banner/promo-banner.types.ts +1 -1
- package/dist/assets/components/promo-banner/promo-banner.vue +1 -1
- package/dist/assets/components/radio-group/components/radio-button/radio-button.vue +1 -1
- package/dist/assets/components/radio-group/radio-group.docs.mdx +1 -6
- package/dist/assets/components/radio-group/radio-group.stories.ts +1 -1
- package/dist/assets/components/radio-group/radio-group.types.ts +1 -1
- package/dist/assets/components/radio-group/radio-group.vue +1 -1
- package/dist/assets/components/rich-text-editor/rich-text-editor.internal.types.ts +1 -0
- package/dist/assets/components/rich-text-editor/rich-text-editor.stories.ts +1 -1
- package/dist/assets/components/rich-text-editor/rich-text-editor.types.ts +1 -1
- package/dist/assets/components/rich-text-editor/rich-text-editor.vue +1 -1
- package/dist/assets/components/search-bar/search-bar.stories.ts +1 -1
- package/dist/assets/components/search-bar/search-bar.vue +1 -1
- package/dist/assets/components/secondary-nav/components/secondary-nav-item/secondary-nav-item.vue +1 -1
- package/dist/assets/components/secondary-nav/secondary-nav.stories.ts +1 -1
- package/dist/assets/components/secondary-nav/secondary-nav.vue +1 -1
- package/dist/assets/components/segmented-control/components/segmented-control-button/segmented-control-button.vue +1 -1
- package/dist/assets/components/segmented-control/segmented-control.stories.ts +1 -1
- package/dist/assets/components/segmented-control/segmented-control.types.ts +1 -1
- package/dist/assets/components/segmented-control/segmented-control.vue +1 -1
- package/dist/assets/components/selection-card/components/selection-card-group/selection-card-group.docs.mdx +12 -13
- package/dist/assets/components/selection-card/components/selection-card-group/selection-card-group.stories.ts +1 -1
- package/dist/assets/components/selection-card/components/selection-card-group/selection-card-group.vue +1 -1
- package/dist/assets/components/selection-card/selection-card.stories.ts +1 -1
- package/dist/assets/components/selection-card/selection-card.types.ts +1 -1
- package/dist/assets/components/selection-card/selection-card.vue +1 -1
- package/dist/assets/components/sidepanel/sidepanel.docs.mdx +1 -1
- package/dist/assets/components/sidepanel/sidepanel.stories.ts +1 -1
- package/dist/assets/components/sidepanel/sidepanel.vue +1 -1
- package/dist/assets/components/status/status.stories.ts +1 -1
- package/dist/assets/components/status/status.types.ts +1 -1
- package/dist/assets/components/stepper/components/step/step.vue +1 -1
- package/dist/assets/components/stepper/stepper.stories.ts +1 -1
- package/dist/assets/components/stepper/stepper.vue +1 -1
- package/dist/assets/components/structured-list/structured-list.stories.ts +1 -1
- package/dist/assets/components/structured-list/structured-list.vue +1 -1
- package/dist/assets/components/summary-grid/components/summary-grid-item/summary-grid-item.types.ts +1 -1
- package/dist/assets/components/summary-grid/summary-grid.stories.ts +1 -1
- package/dist/assets/components/summary-grid/summary-grid.types.ts +1 -1
- package/dist/assets/components/table-of-contents/components/table-of-contents-list/table-of-contents-list.vue +1 -1
- package/dist/assets/components/table-of-contents/table-of-contents.internal.types.ts +1 -0
- package/dist/assets/components/table-of-contents/table-of-contents.stories.ts +1 -1
- package/dist/assets/components/table-of-contents/table-of-contents.types.ts +1 -1
- package/dist/assets/components/table-of-contents/table-of-contents.vue +1 -1
- package/dist/assets/components/tabs/components/tab.internal.types.ts +1 -0
- package/dist/assets/components/tabs/components/tab.types.ts +1 -1
- package/dist/assets/components/tabs/components/tab.vue +1 -1
- package/dist/assets/components/tabs/tabs.stories.ts +1 -1
- package/dist/assets/components/tabs/tabs.vue +1 -1
- package/dist/assets/components/tag/tag.docs.mdx +1 -1
- package/dist/assets/components/tag/tag.stories.ts +1 -1
- package/dist/assets/components/tag/tag.types.ts +1 -1
- package/dist/assets/components/tag/tag.vue +1 -1
- package/dist/assets/components/textarea/textarea.docs.mdx +0 -7
- package/dist/assets/components/textarea/textarea.stories.ts +1 -1
- package/dist/assets/components/textarea/textarea.types.ts +1 -1
- package/dist/assets/components/textarea/textarea.vue +1 -1
- package/dist/assets/components/timeline/components/timeline-item/timeline-item.stories.ts +1 -1
- package/dist/assets/components/timeline/components/timeline-item/timeline-item.vue +1 -1
- package/dist/assets/components/timeline/timeline.docs.mdx +0 -10
- package/dist/assets/components/timeline/timeline.internal.types.ts +1 -0
- package/dist/assets/components/timeline/timeline.stories.ts +1 -1
- package/dist/assets/components/timeline/timeline.types.ts +1 -1
- package/dist/assets/components/timeline/timeline.vue +1 -1
- package/dist/assets/components/toast/components/toast-item/toast-item.vue +1 -1
- package/dist/assets/components/toggle/toggle.stories.ts +1 -1
- package/dist/assets/components/toggle/toggle.types.ts +1 -1
- package/dist/assets/components/toggle/toggle.vue +1 -1
- package/dist/assets/components/tutorial/tutorial.stories.ts +1 -1
- package/dist/assets/components/typography/typography.stories.ts +1 -1
- package/dist/assets/components/typography/typography.types.ts +1 -1
- package/dist/assets/components/typography/typography.vue +1 -1
- package/dist/assets/composables/use-bento-base-filter/index.ts +1 -0
- package/dist/assets/composables/use-bento-base-filter/use-bento-base-filter.ts +1 -0
- package/dist/assets/composables/use-bento-base-filter/utils/index.ts +1 -0
- package/dist/assets/composables/use-bento-base-filter/utils/utils.ts +1 -0
- package/dist/assets/composables/use-bento-currency/index.ts +1 -0
- package/dist/assets/composables/use-bento-currency/use-bento-currency.stories.ts +1 -1
- package/dist/assets/composables/use-bento-currency/use-bento-currency.ts +1 -0
- package/dist/assets/composables/use-bento-delayed-hover/index.ts +1 -0
- package/dist/assets/composables/use-bento-delayed-hover/use-bento-delayed-hover.stories.ts +1 -1
- package/dist/assets/composables/use-bento-delayed-hover/use-bento-delayed-hover.ts +1 -0
- package/dist/assets/composables/use-bento-theme/index.ts +1 -0
- package/dist/assets/composables/use-bento-theme/install.ts +1 -1
- package/dist/assets/composables/use-bento-theme/install.types.ts +1 -1
- package/dist/assets/composables/use-bento-theme/use-bento-theme.ts +1 -0
- package/dist/assets/composables/use-bento-toast-controller/index.ts +1 -0
- package/dist/assets/composables/use-bento-toast-controller/toast-stack.ts +1 -0
- package/dist/assets/composables/use-bento-toast-controller/use-bento-toast-controller.ts +1 -0
- package/dist/assets/composables/use-click-outside/index.ts +1 -0
- package/dist/assets/composables/use-click-outside/use-click-outside.stories.ts +1 -1
- package/dist/assets/composables/use-click-outside/use-click-outside.ts +1 -0
- package/dist/assets/composables/use-form-validate/index.ts +1 -0
- package/dist/assets/composables/use-form-validate/use-form.ts +1 -0
- package/dist/assets/composables/use-form-validate/use-form.types.ts +1 -1
- package/dist/assets/composables.json +9 -0
- package/dist/assets/deprecations.md +132 -236
- package/dist/assets/directives/highlight/highlight.stories.ts +1 -1
- package/dist/assets/directives/keyboard-navigation/keyboard-navigation.stories.ts +1 -1
- package/dist/assets/directives/tooltip/tooltip.internal.types.ts +1 -0
- package/dist/assets/directives/tooltip/tooltip.stories.ts +1 -1
- package/dist/assets/directives/tooltip/tooltip.types.ts +1 -1
- package/dist/assets/icons.json +1 -0
- package/dist/assets/install.ts +1 -1
- package/dist/assets/tailwind/README.md +3 -3
- package/dist/assets/templates/dashboard-template/components/dashboard-section/dashboard-section.stories.ts +1 -1
- package/dist/assets/templates/dashboard-template/dashboard-template.stories.ts +1 -1
- package/dist/assets/templates/data-grid-template/data-grid-template.stories.ts +1 -1
- package/dist/assets/usage.json +77 -77
- package/dist/assets/variables.css +113 -101
- package/dist/main.js +228 -34
- package/package.json +2 -2
- package/dist/assets/components/internal/base-button/base-button.types.ts +0 -1
- package/dist/assets/components/internal/base-button/base-button.vue +0 -1
- package/dist/assets/components/internal/button-actions-with-menu/button-actions-with-menu.stories.ts +0 -1
- package/dist/assets/components/internal/button-actions-with-menu/button-actions-with-menu.types.ts +0 -1
- package/dist/assets/components/internal/button-actions-with-menu/button-actions-with-menu.vue +0 -1
- package/dist/assets/components/internal/calendar/calendar.stories.ts +0 -1
- package/dist/assets/components/internal/calendar/calendar.types.ts +0 -1
- package/dist/assets/components/internal/calendar/calendar.vue +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-month/calendar-month.stories.ts +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-month/calendar-month.types.ts +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-month/calendar-month.vue +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/__test__/calendar-month-day-stub.vue +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/calendar-month-day.stories.ts +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/calendar-month-day.types.ts +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-month/components/calendar-month-day/calendar-month-day.vue +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-month/composables/granular-min-max-date.types.ts +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-year/calendar-year.types.ts +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-year/calendar-year.vue +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-year/components/calendar-year-month/__test__/calendar-year-month-stub.vue +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-year/components/calendar-year-month/calendar-year-month.types.ts +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-year/components/calendar-year-month/calendar-year-month.vue +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-year-selector/calendar-year-selector.types.ts +0 -1
- package/dist/assets/components/internal/calendar/components/calendar-year-selector/calendar-year-selector.vue +0 -1
- package/dist/assets/components/internal/calendar/composables/use-granularity-adjustments.types.ts +0 -1
- package/dist/assets/components/internal/checkbox-input/checkbox-input.stories.ts +0 -1
- package/dist/assets/components/internal/checkbox-input/checkbox-input.types.ts +0 -1
- package/dist/assets/components/internal/checkbox-input/checkbox-input.vue +0 -1
- package/dist/assets/components/internal/controls-group/controls-group.vue +0 -1
- package/dist/assets/components/internal/copy/copy.docs.mdx +0 -43
- package/dist/assets/components/internal/copy/copy.stories.ts +0 -1
- package/dist/assets/components/internal/copy/copy.types.ts +0 -1
- package/dist/assets/components/internal/copy/copy.vue +0 -1
- package/dist/assets/components/internal/decorative-checkbox/decorative-checkbox.vue +0 -1
- package/dist/assets/components/internal/dialog-page/dialog-page.types.ts +0 -1
- package/dist/assets/components/internal/dialog-page/dialog-page.vue +0 -1
- package/dist/assets/components/internal/error-message/error-message.vue +0 -1
- package/dist/assets/components/internal/field-label/field-label.vue +0 -1
- package/dist/assets/components/internal/fixed-scroller/fixed-scroller.docs.mdx +0 -21
- package/dist/assets/components/internal/fixed-scroller/fixed-scroller.stories.ts +0 -1
- package/dist/assets/components/internal/fixed-scroller/fixed-scroller.vue +0 -1
- package/dist/assets/components/internal/footer-actions/footer-actions.vue +0 -1
- package/dist/assets/components/internal/grid-layout/grid-layout.types.ts +0 -1
- package/dist/assets/components/internal/grid-layout/grid-layout.vue +0 -1
- package/dist/assets/components/internal/header-meta/header-meta.types.ts +0 -1
- package/dist/assets/components/internal/header-meta/header-meta.vue +0 -1
- package/dist/assets/components/internal/info-icon-with-popover/info-icon-with-popover.vue +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-lazy-load/listbox-lazy-load.types.ts +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-lazy-load/listbox-lazy-load.vue +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/components/listbox-multi-select-category/listbox-multi-select-category.types.ts +0 -1
- 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 +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/components/listbox-multi-select-nested-lazy-load/listbox-multi-select-nested-lazy-load.types.ts +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/components/listbox-multi-select-nested-lazy-load/listbox-multi-select-nested-lazy-load.vue +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/listbox-multi-select-options.types.ts +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-multi-select/components/listbox-multi-select-options/listbox-multi-select-options.vue +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-multi-select/listbox-multi-select.types.ts +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-multi-select/listbox-multi-select.vue +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-option/listbox-option.vue +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-option-tag/listbox-option-tag.vue +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-single-select/components/listbox-single-select-category/listbox-single-select-category.vue +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-single-select/listbox-single-select.vue +0 -1
- package/dist/assets/components/internal/listbox/components/listbox-single-select-option/listbox-single-select-option.vue +0 -1
- package/dist/assets/components/internal/listbox/listbox.stories.ts +0 -1
- package/dist/assets/components/internal/listbox/listbox.types.ts +0 -1
- package/dist/assets/components/internal/listbox/listbox.vue +0 -1
- package/dist/assets/components/internal/radio-input/radio-input.stories.ts +0 -1
- package/dist/assets/components/internal/radio-input/radio-input.types.ts +0 -1
- package/dist/assets/components/internal/radio-input/radio-input.vue +0 -1
- package/dist/assets/components/internal/teleport/teleport.types.ts +0 -1
- package/dist/assets/components/internal/teleport/teleport.vue +0 -1
- package/dist/assets/components/internal/tooltip/tooltip.test.vue +0 -1
- package/dist/assets/components/internal/tooltip/tooltip.types.ts +0 -1
- package/dist/assets/components/internal/tooltip/tooltip.vue +0 -1
- package/dist/assets/composables/use-form-validate-zod-4/use-form.types.ts +0 -1
- package/dist/assets/composables/use-numeric-input/use-numeric-input.types.ts +0 -1
- package/dist/assets/composables/use-section-navigation-keyboard/use-section-navigation-keyboard.types.ts +0 -1
- package/dist/assets/composables/use-virtual-list/use-virtual-list.types.ts +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/vue'; import { action } from '@storybook/addon-actions'; import { ref } from 'vue'; import { isVue2 } from 'vue-demi'; import { BentoButton } from '@/components/button'; import { BentoModalColumnLayoutVariant, BentoModalDialogType, BentoModalSize, BentoModalVariant } from './modal.types'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { BentoModalPage } from '@/components/modal'; import BentoModal from './modal.vue'; import ModalWithMultiplePages from './__tests__/modal-with-multiple-pages.vue?raw'; const meta: Meta<typeof BentoModal> = { title: 'Modal', component: BentoModal, argTypes: { default: { name: 'default', defaultValue: '', description: 'Modal title', table: { type: { summary: 'VNode[]' }, }, control: { type: null }, }, content: { name: 'content', defaultValue: '', description: 'Modal content', table: { type: { summary: 'VNode[]' }, }, control: { type: null }, }, 'content-col-1': { name: 'content-col-1', defaultValue: '', description: 'Modal with column layout - first column content', table: { type: { summary: 'VNode[]' }, }, control: { type: null }, }, 'content-col-2': { name: 'content-col-2', defaultValue: '', description: 'Modal with column layout - second column content', table: { type: { summary: 'VNode[]' }, }, control: { type: null }, }, variant: { options: Object.values(BentoModalVariant), mapping: BentoModalVariant, control: { type: 'select', }, }, size: { options: Object.values(BentoModalSize), mapping: BentoModalSize, control: { type: 'select', }, }, dialogType: { options: Object.values(BentoModalDialogType), mapping: BentoModalDialogType, control: { type: 'select', }, }, columnsSize: { options: Object.values(BentoModalColumnLayoutVariant), mapping: BentoModalColumnLayoutVariant, control: { type: 'select', }, }, isDismissible: { control: { type: 'boolean', }, }, hideCloseButton: { control: { type: 'boolean', }, }, destructiveActions: { control: { type: 'boolean', }, }, isOpen: { control: { type: 'boolean', }, }, // Events 'close-modal': { table: { type: { summary: '() => void' }, }, control: { disable: true }, }, }, }; export default meta; type Story = StoryObj<typeof BentoModal>; const MODAL_TITLE = 'Modal title'; const MODAL_CONTENT = 'Modal content'; const MODAL_ACTIONS_LABEL = 'Label Text'; const MODAL_ACTIONS = [ { title: 'Action', event: () => action('Primary')(), }, { title: 'Action', event: () => action('Secondary')(), }, ]; const SHARED_DEFAULT_PROPS = { default: MODAL_TITLE, content: MODAL_CONTENT, isOpen: false, }; const MODAL_DEFAULT_PROPS = { ...SHARED_DEFAULT_PROPS, variant: 'default', size: 'medium', hideCloseButton: false, actions: MODAL_ACTIONS, destructiveActions: false, }; const MODAL_DIALOG_PROPS = { ...SHARED_DEFAULT_PROPS, variant: 'dialog', actions: [MODAL_ACTIONS[0]], dialogType: 'confirmation', }; const defaultTemplate = ` <div class="b-modal-story--default"> <bento-modal v-bind="args" aria-label="Aria label content" :is-open="isOpen" @close-modal="closeModal"> <template #default v-if='args.default'> {{ args.default }} </template> <template #content v-if='args.content'> {{ args.content }} </template> </bento-modal> <bento-button :aria-expanded="isOpen" @click="openModal" > Open modal </bento-button> </div> `; const defaultCode = ` <template> <bento-modal aria-label="Aria label content" :actions="actionsArray" :is-open="isOpen" @close-modal="closeModal" > Modal Title <template #content> {{ ${MODAL_DIALOG_PROPS.content} }} </template> </bento-modal> <bento-button :aria-expanded="isOpen" @click="openModal" > Open modal </bento-button> </template> <script setup lang="ts"> import { BentoModal, BentoButton, BentoButtonActionsList } from '@adyen/bento-vue2'; const actionsArray: BentoButtonActionsList = [{ title: 'Action 1', event: () => { // Your handler here }, title: 'Action 2', event: () => { // Your handler here }, }]; const isOpen = ref(false); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; </script> `; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoButton }, props: Object.keys(argTypes), template: defaultTemplate, setup(props) { const args = isVue2 ? props : _args; const isOpen = ref(args.isOpen); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; return { // Values isOpen, args, // Methods openModal, closeModal, }; }, }), parameters: storybookDocsParameter(defaultCode), args: { ...MODAL_DEFAULT_PROPS, }, }; const columnLayoutCode = ` <template> <bento-modal v-bind="args" aria-label="Aria label content" :actions="actionsArray" :is-open="isOpen" @close-modal="closeModal" > <template #default>Modal Title</template> <template #content-col-1> Your modal content here </template> <template #content-col-2> Some other content here </template> </bento-modal> <bento-button :aria-expanded="isOpen" @click="openModal" > Open modal </bento-button> </template> <script setup lang="ts"> import { BentoModal, BentoButton, BentoButtonActionsList } from '@adyen/bento-vue2'; const actionsArray: BentoButtonActionsList = [{ title: 'Action 1', event: () => { // Your handler here }, title: 'Action 2', event: () => { // Your handler here }, }]; const isOpen = ref(false); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; </script> `; export const ColumnLayout: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoButton }, props: Object.keys(argTypes), template: ` <div class="b-modal-story--default"> <bento-modal v-bind="args" aria-label="Aria label content" :is-open="isOpen" @close-modal="closeModal" > <template #default v-if='args.default'> {{ args.default }} </template> <template v-if='args.content' #content-col-1> <div>content column 1</div> </template> <template v-if='args.content' #content-col-2> <div>content column 2</div> </template> </bento-modal> <bento-button :aria-expanded="isOpen" @click="openModal" > Open modal </bento-button> </div> `, setup(props) { const args = isVue2 ? props : _args; const isOpen = ref(args.isOpen); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; return { // Values isOpen, args, // Methods openModal, closeModal, }; }, }), parameters: storybookDocsParameter(columnLayoutCode), args: { ...MODAL_DEFAULT_PROPS, size: 'large', withColumnLayout: true, }, }; const dialogCode = ` <template> <bento-modal aria-label="Aria label content" :content="${MODAL_DIALOG_PROPS.content}" variant="dialog" dialog-type="confirmation" :actions="dialogActions" :is-open="isOpen" @close-modal="closeModal" > Modal Title </bento-modal> <bento-button :aria-expanded="isOpen" @click="openModal" > Open modal </bento-button> </template> <script setup lang="ts"> import { BentoModal, BentoButton, BentoButtonActionsList } from '@adyen/bento-vue2'; const dialogActions: BentoButtonActionsList = [{ title: 'Action', event: () => { //Your handler here }, }] const isOpen = ref(false); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; </script> `; export const Dialog: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoButton }, props: Object.keys(argTypes), template: defaultTemplate, setup(props) { const args = isVue2 ? props : _args; const isOpen = ref(args.isOpen); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; return { // Values isOpen, args, // Methods openModal, closeModal, }; }, }), parameters: storybookDocsParameter(dialogCode), args: { ...MODAL_DIALOG_PROPS, }, }; const ActionsWithLabelCode = ` <template> <bento-modal :actions="actionsArray" :is-open="isOpen" @close-modal="closeModal" > Modal Title <template #content> {{ ${MODAL_DIALOG_PROPS.content} }} </template> </bento-modal> <bento-button :aria-expanded="isOpen" @click="openModal" > Open modal </bento-button> </template> <script setup lang="ts"> import { BentoModal, BentoButton, BentoButtonActionsList } from '@adyen/bento-vue2'; const actionsArray: BentoButtonActionsList = [{ title: 'Action 1', event: () => { // Your handler here }, title: 'Action 2', event: () => { // Your handler here }, }]; const isOpen = ref(false); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; </script> `; export const ActionsWithLabel: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoButton }, props: Object.keys(argTypes), template: defaultTemplate, setup(props) { const args = isVue2 ? props : _args; const isOpen = ref(args.isOpen); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; return { // Values isOpen, args, // Methods openModal, closeModal, }; }, }), parameters: storybookDocsParameter(ActionsWithLabelCode), args: { ...MODAL_DEFAULT_PROPS, actionsLabel: MODAL_ACTIONS_LABEL, }, }; const DestructiveActionsCode = ` <template> <bento-modal destructive-actions :actions="actionsArray" :is-open="isOpen" @close-modal="closeModal" > Modal Title <template #content> {{ ${MODAL_DIALOG_PROPS.content} }} </template> </bento-modal> <bento-button :aria-expanded="isOpen" @click="openModal" > Open modal </bento-button> </template> <script setup lang="ts"> import { BentoModal, BentoButton, BentoButtonActionsList } from '@adyen/bento-vue2'; const actionsArray: BentoButtonActionsList = [{ title: 'Action 1', event: () => { // Your handler here }, title: 'Action 2', event: () => { // Your handler here }, }]; const isOpen = ref(false); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; </script> `; export const DestructiveActions: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoButton }, props: Object.keys(argTypes), template: defaultTemplate, setup(props) { const args = isVue2 ? props : _args; const isOpen = ref(args.isOpen); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; return { // Values isOpen, args, // Methods openModal, closeModal, }; }, }), parameters: storybookDocsParameter(DestructiveActionsCode), args: { ...MODAL_DEFAULT_PROPS, destructiveActions: true, }, }; export const MultiplePages: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoModalPage, BentoButton }, props: Object.keys(argTypes), template: ` <div class="b-modal-story--default"> <bento-modal v-bind="args" aria-label="Aria label content" :is-open="isOpen" @close-modal="closeModal" :activePage="activePage" @update:active-page="activePage = $event"> <bento-modal-page v-bind="intro"> {{ intro.title }} <template #content> <p style="margin-top: 0;">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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <p>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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <p>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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <p>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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <p>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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </template> </bento-modal-page> <bento-modal-page v-bind="newProfile" :withColumnLayout='true' > {{ newProfile.title }} <template #content> This page has some info about creating a new profile </template> </bento-modal-page> <bento-modal-page v-bind="editProfile" > {{ editProfile.title }} <template #content> This is where you edit your profile </template> </bento-modal-page> <bento-modal-page v-bind="newProfileForm"> {{ newProfileForm.title }} <template #content> This is where you create a new profile </template> </bento-modal-page> <bento-modal-page v-bind="success"> {{ success.title }} <template #content> Your profile is created </template> </bento-modal-page> </bento-modal> <bento-button :aria-expanded="isOpen" @click="openModal" > Open modal </bento-button> </div> `, setup(props) { const args = isVue2 ? props : _args; const isOpen = ref(args.isOpen); const activePage = ref('intro'); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; const intro = { pageId: 'intro', title: 'Intro', actions: [ { title: 'New profile', event: () => { activePage.value = 'newProfile'; }, }, { title: 'Edit profile', event: () => { activePage.value = 'editProfile'; }, }, ], actionsLabel: 'What do you wanna do?', }; const newProfile = { pageId: 'newProfile', title: 'New profile', actions: [ { title: 'Go to form', event: () => { activePage.value = 'newProfileForm'; }, }, ], }; const editProfile = { pageId: 'editProfile', title: 'Edit profile', actions: [ { title: 'Save', event: () => action('save')(), }, { title: 'Cancel', event: () => action('cancel')(), }, ], }; const newProfileForm = { pageId: 'newProfileForm', title: 'New profile form', actions: [ { title: 'Save', event: () => { activePage.value = 'success'; }, }, { title: 'Cancel', event: () => action('cancel')(), }, ], }; const success = { pageId: 'success', title: 'Success!', destructiveActions: true, actions: [ { title: 'Delete', event: () => action('delete')(), }, { title: 'Cancel', event: () => action('cancel')(), }, ], previousPage: null, }; return { // Values isOpen, args, activePage, intro, newProfile, newProfileForm, success, editProfile, // Methods openModal, closeModal, }; }, }), parameters: storybookDocsParameter(ModalWithMultiplePages), args: MODAL_DEFAULT_PROPS, };
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue'; import { action } from '@storybook/addon-actions'; import { ref } from 'vue'; import { isVue2 } from 'vue-demi'; import { BentoButton } from '@/components/button'; import { BentoModalColumnLayoutVariant, BentoModalDialogType, BentoModalSize, BentoModalVariant } from './modal.types'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { BentoModalPage } from '@/components/modal'; import BentoModal from './modal.vue'; const ModalActionsWithLabelExample = "<template>\n <div>\n <bento-modal\n actions-label=\"Label Text\"\n aria-label=\"Aria label content\"\n :actions=\"actions\"\n :is-open=\"isOpen\"\n size=\"medium\"\n variant=\"default\"\n @close-modal=\"isOpen = false\"\n >\n Modal title\n <template #content>Modal content</template>\n </bento-modal>\n\n <bento-button :aria-expanded=\"isOpen\" @click=\"isOpen = true\">Open modal</bento-button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { ref } from 'vue';\n import { BentoButton, type BentoButtonActionsList, BentoModal } from '@adyen/bento-vue2';\n\n const isOpen = ref(false);\n const actions: BentoButtonActionsList = [\n { title: 'Action', event: () => undefined },\n { title: 'Action', event: () => undefined },\n ];\n</script>\n"; const ModalColumnLayoutExample = "<template>\n <div>\n <bento-modal\n aria-label=\"Aria label content\"\n :actions=\"actions\"\n :is-open=\"isOpen\"\n size=\"large\"\n variant=\"default\"\n with-column-layout\n @close-modal=\"isOpen = false\"\n >\n <template #default>Modal title</template>\n <template #content-col-1>Your modal content here</template>\n <template #content-col-2>Some other content here</template>\n </bento-modal>\n\n <bento-button :aria-expanded=\"isOpen\" @click=\"isOpen = true\">Open modal</bento-button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { ref } from 'vue';\n import { BentoButton, type BentoButtonActionsList, BentoModal } from '@adyen/bento-vue2';\n\n const isOpen = ref(false);\n const actions: BentoButtonActionsList = [\n { title: 'Action', event: () => undefined },\n { title: 'Action', event: () => undefined },\n ];\n</script>\n"; const ModalDefaultExample = "<template>\n <div>\n <bento-modal\n aria-label=\"Aria label content\"\n :actions=\"actions\"\n :is-open=\"isOpen\"\n size=\"medium\"\n variant=\"default\"\n @close-modal=\"isOpen = false\"\n >\n Modal title\n <template #content>Modal content</template>\n </bento-modal>\n\n <bento-button :aria-expanded=\"isOpen\" @click=\"isOpen = true\">Open modal</bento-button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { ref } from 'vue';\n import { BentoButton, type BentoButtonActionsList, BentoModal } from '@adyen/bento-vue2';\n\n const isOpen = ref(false);\n const actions: BentoButtonActionsList = [\n { title: 'Action', event: () => undefined },\n { title: 'Action', event: () => undefined },\n ];\n</script>\n"; const ModalDestructiveActionsExample = "<template>\n <div>\n <bento-modal\n aria-label=\"Aria label content\"\n :actions=\"actions\"\n destructive-actions\n :is-open=\"isOpen\"\n size=\"medium\"\n variant=\"default\"\n @close-modal=\"isOpen = false\"\n >\n Modal title\n <template #content>Modal content</template>\n </bento-modal>\n\n <bento-button :aria-expanded=\"isOpen\" @click=\"isOpen = true\">Open modal</bento-button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { ref } from 'vue';\n import { BentoButton, type BentoButtonActionsList, BentoModal } from '@adyen/bento-vue2';\n\n const isOpen = ref(false);\n const actions: BentoButtonActionsList = [\n { title: 'Action', event: () => undefined },\n { title: 'Action', event: () => undefined },\n ];\n</script>\n"; const ModalDialogExample = "<template>\n <div>\n <bento-modal\n aria-label=\"Aria label content\"\n :actions=\"actions\"\n content=\"Modal content\"\n dialog-type=\"confirmation\"\n :is-open=\"isOpen\"\n variant=\"dialog\"\n @close-modal=\"isOpen = false\"\n >\n Modal title\n </bento-modal>\n\n <bento-button :aria-expanded=\"isOpen\" @click=\"isOpen = true\">Open modal</bento-button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { ref } from 'vue';\n import { BentoButton, type BentoButtonActionsList, BentoModal } from '@adyen/bento-vue2';\n\n const isOpen = ref(false);\n const actions: BentoButtonActionsList = [{ title: 'Action', event: () => undefined }];\n</script>\n"; const ModalWithMultiplePages = "<template>\n <div>\n <bento-button :aria-expanded=\"isOpen\" @click=\"isOpen = !isOpen\"> Open modal </bento-button>\n <bento-modal\n :is-open=\"isOpen\"\n :active-page=\"activePage\"\n @update:active-page=\"activePage = $event\"\n @update:is-open=\"isOpen = $event\"\n >\n <bento-modal-page v-bind=\"page1\">\n Page 1\n <template #content>\n <!-- Put the content of your page here -->\n </template>\n </bento-modal-page>\n <bento-modal-page v-bind=\"page2\">\n Page 2\n <template #content>\n <!-- Put the content of your page here -->\n </template>\n </bento-modal-page>\n <bento-modal-page v-bind=\"page3\">\n Page 3\n <template #content>\n <!-- Put the content of your page here -->\n </template>\n </bento-modal-page>\n <bento-modal-page v-bind=\"page4\">\n Page 4\n <template #content>\n <!-- Put the content of your page here -->\n </template>\n </bento-modal-page>\n </bento-modal>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { ref } from 'vue';\n import { BentoButton, BentoModal, BentoModalPage, type BentoModalPageProps } from '@adyen/bento-vue2';\n\n const isOpen = ref(false);\n const activePage = ref('page1');\n\n const page1: BentoModalPageProps = {\n pageId: 'page1',\n actions: [\n {\n title: 'Go to next page',\n event: () => {\n activePage.value = 'page2';\n },\n },\n ],\n };\n\n const page2: BentoModalPageProps = {\n pageId: 'page2',\n actions: [\n {\n title: 'Go to next page',\n event: () => {\n activePage.value = 'page3';\n },\n },\n ],\n };\n\n const page3: BentoModalPageProps = {\n pageId: 'page3',\n actions: [\n {\n title: 'Go to next page',\n event: () => {\n activePage.value = 'page4';\n },\n },\n ],\n };\n\n const page4: BentoModalPageProps = {\n pageId: 'page4',\n actions: [\n {\n title: 'Finish',\n event: () => {\n isOpen.value = false;\n },\n },\n ],\n previousPage: null,\n };\n</script>\n"; const meta: Meta<typeof BentoModal> = { title: 'Modal', component: BentoModal, argTypes: { default: { name: 'default', defaultValue: '', description: 'Modal title', table: { type: { summary: 'VNode[]' }, }, control: { type: null }, }, content: { name: 'content', defaultValue: '', description: 'Modal content', table: { type: { summary: 'VNode[]' }, }, control: { type: null }, }, 'content-col-1': { name: 'content-col-1', defaultValue: '', description: 'Modal with column layout - first column content', table: { type: { summary: 'VNode[]' }, }, control: { type: null }, }, 'content-col-2': { name: 'content-col-2', defaultValue: '', description: 'Modal with column layout - second column content', table: { type: { summary: 'VNode[]' }, }, control: { type: null }, }, variant: { options: Object.values(BentoModalVariant), mapping: BentoModalVariant, control: { type: 'select', }, }, size: { options: Object.values(BentoModalSize), mapping: BentoModalSize, control: { type: 'select', }, }, dialogType: { options: Object.values(BentoModalDialogType), mapping: BentoModalDialogType, control: { type: 'select', }, }, columnsSize: { options: Object.values(BentoModalColumnLayoutVariant), mapping: BentoModalColumnLayoutVariant, control: { type: 'select', }, }, isDismissible: { control: { type: 'boolean', }, }, hideCloseButton: { control: { type: 'boolean', }, }, destructiveActions: { control: { type: 'boolean', }, }, isOpen: { control: { type: 'boolean', }, }, // Events 'close-modal': { table: { type: { summary: '() => void' }, }, control: { disable: true }, }, }, }; export default meta; type Story = StoryObj<typeof BentoModal>; const MODAL_TITLE = 'Modal title'; const MODAL_CONTENT = 'Modal content'; const MODAL_ACTIONS_LABEL = 'Label Text'; const MODAL_ACTIONS = [ { title: 'Action', event: () => action('Primary')(), }, { title: 'Action', event: () => action('Secondary')(), }, ]; const SHARED_DEFAULT_PROPS = { default: MODAL_TITLE, content: MODAL_CONTENT, isOpen: false, }; const MODAL_DEFAULT_PROPS = { ...SHARED_DEFAULT_PROPS, variant: 'default', size: 'medium', hideCloseButton: false, actions: MODAL_ACTIONS, destructiveActions: false, }; const MODAL_DIALOG_PROPS = { ...SHARED_DEFAULT_PROPS, variant: 'dialog', actions: [MODAL_ACTIONS[0]], dialogType: 'confirmation', }; const defaultTemplate = ` <div class="b-modal-story--default"> <bento-modal v-bind="args" aria-label="Aria label content" :is-open="isOpen" @close-modal="closeModal"> <template #default v-if='args.default'> {{ args.default }} </template> <template #content v-if='args.content'> {{ args.content }} </template> </bento-modal> <bento-button :aria-expanded="isOpen" @click="openModal" > Open modal </bento-button> </div> `; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoButton }, props: Object.keys(argTypes), template: defaultTemplate, setup(props) { const args = isVue2 ? props : _args; const isOpen = ref(args.isOpen); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; return { // Values isOpen, args, // Methods openModal, closeModal, }; }, }), parameters: storybookDocsParameter(ModalDefaultExample), args: { ...MODAL_DEFAULT_PROPS, }, }; export const ColumnLayout: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoButton }, props: Object.keys(argTypes), template: ` <div class="b-modal-story--default"> <bento-modal v-bind="args" aria-label="Aria label content" :is-open="isOpen" @close-modal="closeModal" > <template #default v-if='args.default'> {{ args.default }} </template> <template v-if='args.content' #content-col-1> <div>content column 1</div> </template> <template v-if='args.content' #content-col-2> <div>content column 2</div> </template> </bento-modal> <bento-button :aria-expanded="isOpen" @click="openModal" > Open modal </bento-button> </div> `, setup(props) { const args = isVue2 ? props : _args; const isOpen = ref(args.isOpen); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; return { // Values isOpen, args, // Methods openModal, closeModal, }; }, }), parameters: storybookDocsParameter(ModalColumnLayoutExample), args: { ...MODAL_DEFAULT_PROPS, size: 'large', withColumnLayout: true, }, }; export const Dialog: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoButton }, props: Object.keys(argTypes), template: defaultTemplate, setup(props) { const args = isVue2 ? props : _args; const isOpen = ref(args.isOpen); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; return { // Values isOpen, args, // Methods openModal, closeModal, }; }, }), parameters: storybookDocsParameter(ModalDialogExample), args: { ...MODAL_DIALOG_PROPS, }, }; export const ActionsWithLabel: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoButton }, props: Object.keys(argTypes), template: defaultTemplate, setup(props) { const args = isVue2 ? props : _args; const isOpen = ref(args.isOpen); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; return { // Values isOpen, args, // Methods openModal, closeModal, }; }, }), parameters: storybookDocsParameter(ModalActionsWithLabelExample), args: { ...MODAL_DEFAULT_PROPS, actionsLabel: MODAL_ACTIONS_LABEL, }, }; export const DestructiveActions: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoButton }, props: Object.keys(argTypes), template: defaultTemplate, setup(props) { const args = isVue2 ? props : _args; const isOpen = ref(args.isOpen); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; return { // Values isOpen, args, // Methods openModal, closeModal, }; }, }), parameters: storybookDocsParameter(ModalDestructiveActionsExample), args: { ...MODAL_DEFAULT_PROPS, destructiveActions: true, }, }; export const MultiplePages: Story = { render: (_args, { argTypes }) => ({ components: { BentoModal, BentoModalPage, BentoButton }, props: Object.keys(argTypes), template: ` <div class="b-modal-story--default"> <bento-modal v-bind="args" aria-label="Aria label content" :is-open="isOpen" @close-modal="closeModal" :activePage="activePage" @update:active-page="activePage = $event"> <bento-modal-page v-bind="intro"> {{ intro.title }} <template #content> <p style="margin-top: 0;">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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <p>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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <p>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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <p>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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <p>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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </template> </bento-modal-page> <bento-modal-page v-bind="newProfile" :withColumnLayout='true' > {{ newProfile.title }} <template #content> This page has some info about creating a new profile </template> </bento-modal-page> <bento-modal-page v-bind="editProfile" > {{ editProfile.title }} <template #content> This is where you edit your profile </template> </bento-modal-page> <bento-modal-page v-bind="newProfileForm"> {{ newProfileForm.title }} <template #content> This is where you create a new profile </template> </bento-modal-page> <bento-modal-page v-bind="success"> {{ success.title }} <template #content> Your profile is created </template> </bento-modal-page> </bento-modal> <bento-button :aria-expanded="isOpen" @click="openModal" > Open modal </bento-button> </div> `, setup(props) { const args = isVue2 ? props : _args; const isOpen = ref(args.isOpen); const activePage = ref('intro'); const closeModal = () => { isOpen.value = false; }; const openModal = () => { isOpen.value = true; }; const intro = { pageId: 'intro', title: 'Intro', actions: [ { title: 'New profile', event: () => { activePage.value = 'newProfile'; }, }, { title: 'Edit profile', event: () => { activePage.value = 'editProfile'; }, }, ], actionsLabel: 'What do you wanna do?', }; const newProfile = { pageId: 'newProfile', title: 'New profile', actions: [ { title: 'Go to form', event: () => { activePage.value = 'newProfileForm'; }, }, ], }; const editProfile = { pageId: 'editProfile', title: 'Edit profile', actions: [ { title: 'Save', event: () => action('save')(), }, { title: 'Cancel', event: () => action('cancel')(), }, ], }; const newProfileForm = { pageId: 'newProfileForm', title: 'New profile form', actions: [ { title: 'Save', event: () => { activePage.value = 'success'; }, }, { title: 'Cancel', event: () => action('cancel')(), }, ], }; const success = { pageId: 'success', title: 'Success!', destructiveActions: true, actions: [ { title: 'Delete', event: () => action('delete')(), }, { title: 'Cancel', event: () => action('cancel')(), }, ], previousPage: null, }; return { // Values isOpen, args, activePage, intro, newProfile, newProfileForm, success, editProfile, // Methods openModal, closeModal, }; }, }), parameters: storybookDocsParameter(ModalWithMultiplePages), args: MODAL_DEFAULT_PROPS, };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
/** * @deprecated Since v3.0.0. Use string literal instead. */ export enum BentoModalVariant { DEFAULT = 'default', DIALOG = 'dialog', } /** * @deprecated Since v3.0.0. Use string literal instead. */ export enum BentoModalVariantMapping { DEFAULT = 'BentoModalDefault', DIALOG = 'BentoModalDialog', } /** * @deprecated Since v3.0.0. Use string literal instead. */ export enum BentoModalSize { SMALL = 'small', MEDIUM = 'medium', LARGE = 'large', } /** * @deprecated Since v3.0.0. Use string literal instead. */ export enum BentoModalColumnLayoutVariant { SMALLER = 'smaller', EQUAL = 'equal', BIGGER = 'bigger', } export enum BentoModalRole { DIALOG = 'dialog', ALERT_DIALOG = 'alertdialog', } /** * @deprecated Since v3.0.0. Use string literal instead. */ export enum BentoModalDialogType { CONFIRMATION = 'confirmation', DESTRUCTIVE = 'destructive', INFO = 'info', ACKNOWLEDGEMENT = 'acknowledgement', } export enum BentoModalEvent { CLOSE_MODAL = 'close-modal', }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<template> <component :is="computedVariant" class="b-modal" :is-open="isOpen" :actions="actions" :initially-open="initiallyOpen" v-bind="customProps" @close-modal="onCloseModal" @update:active-page="emit('update:active-page', $event)" > <template v-if="hasSlot('default')" #default> <slot></slot> </template> <template v-if="hasSlot('content-col-1')" #content-col-1><slot name="content-col-1"></slot></template> <template v-if="hasSlot('content-col-2')" #content-col-2><slot name="content-col-2"></slot></template> <template v-if="hasSlot('content')" #content><slot name="content"></slot></template> </component> </template> <script setup lang="ts"> import { computed, defineComponent, type PropType, useAttrs, useSlots } from 'vue'; import { BentoModalColumnLayoutVariant, BentoModalDialogType, BentoModalSize, BentoModalVariant, BentoModalVariantMapping, } from './modal.types'; import { BentoModalDefault, BentoModalDialog } from '@/components/modal/components'; import { useHasSlot } from '@/composables'; import { type BentoButtonActionsList } from '@/components/button'; import { deprecate } from '@/utils/ts/deprecate'; type BentoModalVariantProp = BentoModalVariant | `${BentoModalVariant}` | `${BentoModalVariantMapping}`; const slots = useSlots(); const hasSlot = useHasSlot(slots); const attrs = useAttrs(); const emit = defineEmits<{ /** * Emits update event when page is changed internally */ (e: 'update:active-page', page: string): void; /** * Emitted when the modal is closed */ (e: 'close-modal'); }>(); const props = defineProps({ /** * List of actions that will be used to render the buttons. * First element in the list will be rendered as "primary". * All elements after the first will be rendered as "secondary". * * Each object in the list should have a `title`, an `event` and * (optional) a Vue `icon` from the library `@adyen/ui-assets-icons-16`. * * `title`: Button's text. * * `event`: Event triggered when clicking the Button. * * `icon`: Vue Icon from the library `@adyen/ui-assets-icons-16`. * * ``` * [{ * title: 'Primary',2 * event: () => { ... }, * icon: FourPeopleIcon * }, { * title: 'Secondary', * event: () => { ... } * }] * ``` */ actions: { type: Array as PropType<BentoButtonActionsList>, default: null, }, /** * The id of the current active page * Should be the same id as the BentoModalPage to be displayed */ activePage: { type: String, default: null, }, /** * Text label that is displayed left to the action buttons */ actionsLabel: { type: String, default: null }, /** * Text that will be displayed in the content section of Modal */ content: { type: String, default: null }, /** * If a column layout is provided, it renders the respective left column width variant. This can be smaller than the second column, the same size as the second column or bigger than the second column. */ columnsSize: { type: String as PropType<BentoModalColumnLayoutVariant | `${BentoModalColumnLayoutVariant}`>, default: BentoModalColumnLayoutVariant.SMALLER, validator: (value: BentoModalColumnLayoutVariant) => Object.values(BentoModalColumnLayoutVariant).includes(value), }, /** * If provided, manages the padding of the whole modal container */ customPadding: { type: String, default: null }, /** * If passed - sets first button color to red */ destructiveActions: { type: Boolean, default: false }, /** * Changes the visual styling of action buttons */ dialogType: { type: String as PropType<BentoModalDialogType | `${BentoModalDialogType}`>, default: BentoModalDialogType.CONFIRMATION, validator: (value: BentoModalDialogType) => Object.values(BentoModalDialogType).includes(value), }, /** * Hides a cross icon on the right side of the title */ hideCloseButton: { type: Boolean, default: false }, /** * If set to true, it allows the modal to be closed without performing an action */ isDismissible: { type: Boolean, default: null }, /** * Controls the modal's state from the outside. Set it to true to open the modal */ isOpen: { type: Boolean, default: false, }, /** * Sets the open attribute on the dialog element, use isOpen instead to toggle modal visbility. */ initiallyOpen: { type: Boolean, default: false }, /** * Sets the width of the modal */ size: { type: String as PropType<BentoModalSize | `${BentoModalSize}`>, default: BentoModalSize.SMALL, validator: (value: BentoModalSize) => Object.values(BentoModalSize).includes(value), }, /** * Choose between default or dialog versions of modal */ variant: { type: String as PropType<BentoModalVariantProp>, default: 'default', validator: (value: BentoModalVariantProp) => Object.values<BentoModalVariantProp>(BentoModalVariant).includes(value) || Object.values<BentoModalVariantProp>(BentoModalVariantMapping).includes(value), }, /** * If provided, renders the modal's content in a two-column layout an wth dividers separating its content */ withColumnLayout: { type: Boolean, default: false }, }); const computedVariant = computed(() => { if (Object.values<BentoModalVariantProp>(BentoModalVariantMapping).includes(props.variant)) { return props.variant; } return BentoModalVariantMapping[props.variant.toUpperCase()]; }); const customProps = computed(() => computedVariant.value === BentoModalVariantMapping.DEFAULT ? { activePage: props.activePage, hideCloseButton: props.hideCloseButton, size: props.size, customPadding: props.customPadding, actionsLabel: props.actionsLabel, destructiveActions: props.destructiveActions, isDismissible: props.isDismissible ?? true, withColumnLayout: props.withColumnLayout, columnsSize: props.columnsSize, ...attrs, } : { activePage: props.activePage, dialogType: props.dialogType, content: props.content, isDismissible: props.isDismissible ?? false, ...attrs, } ); const onCloseModal = () => { emit('close-modal'); }; if (Object.keys(attrs).includes('overflow-visible')) { deprecate( 'BentoModal "overflow-visible" property', `"overflow-visible" property was made redundant. BentoModal can work correctly without the need to pass the propery. Remove the "overflow-visible" prop from BentoModal to remove this error.`, '
|
|
1
|
+
<template> <component :is="computedVariant" class="b-modal" :is-open="isOpen" :actions="actions" :initially-open="initiallyOpen" v-bind="customProps" @close-modal="onCloseModal" @update:active-page="emit('update:active-page', $event)" > <template v-if="hasSlot('default')" #default> <slot></slot> </template> <template v-if="hasSlot('content-col-1')" #content-col-1><slot name="content-col-1"></slot></template> <template v-if="hasSlot('content-col-2')" #content-col-2><slot name="content-col-2"></slot></template> <template v-if="hasSlot('content')" #content><slot name="content"></slot></template> </component> </template> <script setup lang="ts"> import { computed, defineComponent, type PropType, useAttrs, useSlots } from 'vue'; import { BentoModalColumnLayoutVariant, BentoModalDialogType, BentoModalSize, BentoModalVariant, BentoModalVariantMapping, } from './modal.types'; import { BentoModalDefault, BentoModalDialog } from '@/components/modal/components'; import { useHasSlot } from '@/composables'; import { type BentoButtonActionsList } from '@/components/button'; import { deprecate } from '@/utils/ts/deprecate'; type BentoModalVariantProp = BentoModalVariant | `${BentoModalVariant}` | `${BentoModalVariantMapping}`; const slots = useSlots(); const hasSlot = useHasSlot(slots); const attrs = useAttrs(); const emit = defineEmits<{ /** * Emits update event when page is changed internally */ (e: 'update:active-page', page: string): void; /** * Emitted when the modal is closed */ (e: 'close-modal'); }>(); const props = defineProps({ /** * List of actions that will be used to render the buttons. * First element in the list will be rendered as "primary". * All elements after the first will be rendered as "secondary". * * Each object in the list should have a `title`, an `event` and * (optional) a Vue `icon` from the library `@adyen/ui-assets-icons-16`. * * `title`: Button's text. * * `event`: Event triggered when clicking the Button. * * `icon`: Vue Icon from the library `@adyen/ui-assets-icons-16`. * * ``` * [{ * title: 'Primary',2 * event: () => { ... }, * icon: FourPeopleIcon * }, { * title: 'Secondary', * event: () => { ... } * }] * ``` */ actions: { type: Array as PropType<BentoButtonActionsList>, default: null, }, /** * The id of the current active page * Should be the same id as the BentoModalPage to be displayed */ activePage: { type: String, default: null, }, /** * Text label that is displayed left to the action buttons */ actionsLabel: { type: String, default: null }, /** * Text that will be displayed in the content section of Modal */ content: { type: String, default: null }, /** * If a column layout is provided, it renders the respective left column width variant. This can be smaller than the second column, the same size as the second column or bigger than the second column. */ columnsSize: { type: String as PropType<BentoModalColumnLayoutVariant | `${BentoModalColumnLayoutVariant}`>, default: BentoModalColumnLayoutVariant.SMALLER, validator: (value: BentoModalColumnLayoutVariant) => Object.values(BentoModalColumnLayoutVariant).includes(value), }, /** * If provided, manages the padding of the whole modal container */ customPadding: { type: String, default: null }, /** * If passed - sets first button color to red */ destructiveActions: { type: Boolean, default: false }, /** * Changes the visual styling of action buttons */ dialogType: { type: String as PropType<BentoModalDialogType | `${BentoModalDialogType}`>, default: BentoModalDialogType.CONFIRMATION, validator: (value: BentoModalDialogType) => Object.values(BentoModalDialogType).includes(value), }, /** * Hides a cross icon on the right side of the title */ hideCloseButton: { type: Boolean, default: false }, /** * If set to true, it allows the modal to be closed without performing an action */ isDismissible: { type: Boolean, default: null }, /** * Controls the modal's state from the outside. Set it to true to open the modal */ isOpen: { type: Boolean, default: false, }, /** * Sets the open attribute on the dialog element, use isOpen instead to toggle modal visbility. */ initiallyOpen: { type: Boolean, default: false }, /** * Sets the width of the modal */ size: { type: String as PropType<BentoModalSize | `${BentoModalSize}`>, default: BentoModalSize.SMALL, validator: (value: BentoModalSize) => Object.values(BentoModalSize).includes(value), }, /** * Choose between default or dialog versions of modal */ variant: { type: String as PropType<BentoModalVariantProp>, default: 'default', validator: (value: BentoModalVariantProp) => Object.values<BentoModalVariantProp>(BentoModalVariant).includes(value) || Object.values<BentoModalVariantProp>(BentoModalVariantMapping).includes(value), }, /** * If provided, renders the modal's content in a two-column layout an wth dividers separating its content */ withColumnLayout: { type: Boolean, default: false }, }); const computedVariant = computed(() => { if (Object.values<BentoModalVariantProp>(BentoModalVariantMapping).includes(props.variant)) { return props.variant; } return BentoModalVariantMapping[props.variant.toUpperCase()]; }); const customProps = computed(() => computedVariant.value === BentoModalVariantMapping.DEFAULT ? { activePage: props.activePage, hideCloseButton: props.hideCloseButton, size: props.size, customPadding: props.customPadding, actionsLabel: props.actionsLabel, destructiveActions: props.destructiveActions, isDismissible: props.isDismissible ?? true, withColumnLayout: props.withColumnLayout, columnsSize: props.columnsSize, ...attrs, } : { activePage: props.activePage, dialogType: props.dialogType, content: props.content, isDismissible: props.isDismissible ?? false, ...attrs, } ); const onCloseModal = () => { emit('close-modal'); }; if (Object.keys(attrs).includes('overflow-visible')) { deprecate( 'BentoModal "overflow-visible" property', `"overflow-visible" property was made redundant. BentoModal can work correctly without the need to pass the propery. Remove the "overflow-visible" prop from BentoModal to remove this error.`, '3.0.0' ); } </script> <script lang="ts"> /** * Modal is a window that appear over any other page content * and focus user attention exclusively on one task or piece of * information at the moment. * * @example * import { BentoModal } from '@adyen/bento-vue2'; * * export default { * components: { BentoModal }, * template: ` * <bento-modal :isOpen="true"> * Title of the Modal * <template #content> * Mandatory content slot * </template> * </bento-modal> * ` * }; */ export default defineComponent({ components: { BentoModalDefault, BentoModalDialog }, }); </script>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<template> <dialog-page class="b-modal-fullscreen-page" :page-id="pageId" :previous-page="previousPage" always-show-border> <template #header> <div class="b-modal-fullscreen-page__header"> <div class="b-modal-fullscreen-page__header-section b-modal-fullscreen-page__header-section--title"> <bento-typography v-if="title" :id="computedTitleId" el="h2" variant="title" class="b-modal-fullscreen-page__title" :title="title" >{{ title }}</bento-typography > </div> <div v-if="hasSlot('header')" class="b-modal-fullscreen-page__header-section b-modal-fullscreen-page__header-section--slot" > <slot name="header" /> </div> <div class="b-modal-fullscreen-page__header-section b-modal-fullscreen-page__header-section--actions"> <bento-typography v-if="contextualLabel" class="b-modal-fullscreen-page__contextual-label" el="span" :title="contextualLabel" >{{ contextualLabel }}</bento-typography > <bento-button-actions v-if="actions" class="b-modal-fullscreen-page__actions" :actions="actions" /> <div class="b-modal-fullscreen-page__separator"></div> <div class="b-modal-fullscreen-page__close-button"> <bento-button variant="tertiary" :aria-label="t('close')" @click="handleClose"> <template #iconLeft><cross-icon :aria-hidden="true" /></template> </bento-button> </div> </div> </div> </template> <template #content> <slot /> </template> </dialog-page> </template> <script setup lang="ts"> import { inject, onMounted, type PropType, useSlots } from 'vue'; import { BentoButton, BentoButtonActions, type BentoButtonActionsList } from '@/components/button'; import { BentoTypography } from '@/components/typography'; import { DialogPage } from '@/internal'; import { useHasSlot } from '@/composables'; import { useI18n } from '@/utils/ts/i18n'; import { MODAL_FULLSCREEN_CLOSE_INJECTION_KEY, MODAL_FULLSCREEN_TITLE_ID_INJECTION_KEY, } from '@/components/modal-fullscreen/modal-fullscreen.keys'; import CrossIcon from '@adyen/ui-assets-icons-16/vue/cross'; import messages from './messages.json'; type MessageSchema = (typeof messages)['en-US']; const { t } = useI18n<{ message: MessageSchema }>({ messages }); const props = defineProps({ /** * List of actions that will be used to render the buttons. * First element in the list will be rendered as "primary". * All elements after the first will be rendered as "secondary". * * Each object in the list should have a `title`, an `event` and * (optional) a Vue `icon` from the library `@adyen/ui-assets-icons-16`. * * @see BentoButton for a list of all the other props supported by each button action. */ actions: { type: Array as PropType<BentoButtonActionsList>, default: null, }, /** * Label shown next to the modal actions */ contextualLabel: { type: String, default: null, }, /** * Identifier of the page, used with activePage prop to handle sidepanel navigation */ pageId: { type: String, default: undefined, }, /** * ID of the page for the back button to navigate to. Only use it to overwrite the default back behavior * Used when the back button should not take the user to the natural previous page * Set to `null` to hide back button in the page */ previousPage: { type: String, default: undefined, }, /** * Title of the modal */ title: { type: String, default: null, }, /** * ID to be applied to the title to be used with aria-labelledby */ titleId: { type: String, default: undefined, }, }); const emit = defineEmits<{ /** * Emits event when close button is clicked */ (e: 'close'); }>(); const slots = useSlots(); const hasSlot = useHasSlot(slots); const injectedTitleId = inject(MODAL_FULLSCREEN_TITLE_ID_INJECTION_KEY, undefined); const computedTitleId = props.titleId ?? injectedTitleId; const closeModal = inject(MODAL_FULLSCREEN_CLOSE_INJECTION_KEY, undefined); const handleClose = () => { emit('close'); closeModal?.(); }; onMounted(() => { if (props.actions && props.actions.length > 2) { throw new Error('Not more than 2 action buttons may be provided in Bento Modal Fullscreen'); } }); </script> <script lang="ts"> /** * ModalFullscreenPage is used to render different pages of ModalFullscreen component * * @example * import { BentoModalFullscreen, BentoModalFullscreenPage } from '@adyen/bento-vue2'; * * export default { * components: { BentoModalFullscreen, BentoModalFullscreenPage }, * template: ` * <bento-modal-fullscreen active-page='page1' is-open='true'> * <bento-modal-fullscreen-page * title='Page 1' * pageId='page1' * contextual-label='Move to next page' * :actions="[ * { * title: 'Next page', * event: () => { * activePage.value = 'page2'; * }, * }]"> * Page 1 info * </bento-modal-fullscreen-page> * <bento-modal-fullscreen-page * title='Page 2' * pageId='page2' * :actions="[ * { * title: 'Save', * event: () => {}, * }]"> * Page 2 info * </bento-modal-fullscreen-page> * </bento-modal-fullscreen> * ` * } */ export default { i18n: { messages }, }; </script> <style lang="scss" scoped src="./modal-fullscreen-page.scss" />
|
|
1
|
+
<template> <dialog-page class="b-modal-fullscreen-page" :page-id="pageId" :previous-page="previousPage" always-show-border> <template #header> <div class="b-modal-fullscreen-page__header"> <div class="b-modal-fullscreen-page__header-section b-modal-fullscreen-page__header-section--title"> <bento-typography v-if="title" :id="computedTitleId" el="h2" variant="title" class="b-modal-fullscreen-page__title" :title="title" >{{ title }}</bento-typography > </div> <div v-if="hasSlot('header')" class="b-modal-fullscreen-page__header-section b-modal-fullscreen-page__header-section--slot" > <slot name="header" /> </div> <div class="b-modal-fullscreen-page__header-section b-modal-fullscreen-page__header-section--actions"> <bento-typography v-if="contextualLabel" class="b-modal-fullscreen-page__contextual-label" el="span" :title="contextualLabel" >{{ contextualLabel }}</bento-typography > <bento-button-actions v-if="actions" class="b-modal-fullscreen-page__actions" :actions="actions" /> <div class="b-modal-fullscreen-page__separator"></div> <div class="b-modal-fullscreen-page__close-button"> <bento-button variant="tertiary" :aria-label="t('close')" @click="handleClose"> <template #iconLeft><cross-icon :aria-hidden="true" /></template> </bento-button> </div> </div> </div> </template> <template #content> <slot /> </template> </dialog-page> </template> <script setup lang="ts"> import { inject, onMounted, type PropType, useSlots } from 'vue'; import { BentoButton, BentoButtonActions, type BentoButtonActionsList } from '@/components/button'; import { BentoTypography } from '@/components/typography'; import { DialogPage } from '@/internal'; import { useHasSlot } from '@/composables'; import { useI18n } from '@/utils/ts/i18n'; import { MODAL_FULLSCREEN_CLOSE_INJECTION_KEY, MODAL_FULLSCREEN_TITLE_ID_INJECTION_KEY, } from '@/components/modal-fullscreen/modal-fullscreen.keys'; import CrossIcon from '@adyen/ui-assets-icons-16/vue/cross'; import messages from './messages.json'; type MessageSchema = (typeof messages)['en-US']; const { t } = useI18n<{ message: MessageSchema }>({ messages }); const props = defineProps({ /** * List of actions that will be used to render the buttons. * First element in the list will be rendered as "primary". * All elements after the first will be rendered as "secondary". * * Each object in the list should have a `title`, an `event` and * (optional) a Vue `icon` from the library `@adyen/ui-assets-icons-16`. * * @see BentoButton for a list of all the other props supported by each button action. */ actions: { type: Array as PropType<BentoButtonActionsList>, default: null, }, /** * Label shown next to the modal actions */ contextualLabel: { type: String, default: null, }, /** * Identifier of the page, used with activePage prop to handle sidepanel navigation */ pageId: { type: String, default: undefined, }, /** * ID of the page for the back button to navigate to. Only use it to overwrite the default back behavior * Used when the back button should not take the user to the natural previous page * Set to `null` to hide back button in the page */ previousPage: { type: String, default: undefined, }, /** * Title of the modal */ title: { type: String, default: null, }, /** * ID to be applied to the title to be used with aria-labelledby */ titleId: { type: String, default: undefined, }, }); const emit = defineEmits<{ /** * Emits event when close button is clicked */ (e: 'close'); }>(); const slots = useSlots(); const hasSlot = useHasSlot(slots); const injectedTitleId = inject(MODAL_FULLSCREEN_TITLE_ID_INJECTION_KEY, undefined); const computedTitleId = props.titleId ?? injectedTitleId; const closeModal = inject(MODAL_FULLSCREEN_CLOSE_INJECTION_KEY, undefined); const handleClose = () => { emit('close'); closeModal?.(); }; onMounted(() => { if (props.actions && props.actions.length > 2) { throw new Error('Not more than 2 action buttons may be provided in Bento Modal Fullscreen'); } }); </script> <script lang="ts"> /** * ModalFullscreenPage is used to render different pages of ModalFullscreen component * * @example * import { BentoModalFullscreen, BentoModalFullscreenPage } from '@adyen/bento-vue2'; * * export default { * components: { BentoModalFullscreen, BentoModalFullscreenPage }, * template: ` * <bento-modal-fullscreen active-page='page1' is-open='true'> * <bento-modal-fullscreen-page * title='Page 1' * pageId='page1' * contextual-label='Move to next page' * :actions="[ * { * title: 'Next page', * event: () => { * activePage.value = 'page2'; * }, * }]"> * Page 1 info * </bento-modal-fullscreen-page> * <bento-modal-fullscreen-page * title='Page 2' * pageId='page2' * :actions="[ * { * title: 'Save', * event: () => {}, * }]"> * Page 2 info * </bento-modal-fullscreen-page> * </bento-modal-fullscreen> * ` * } */ export default { i18n: { messages }, name: 'bento-modal-fullscreen-page', }; </script> <style lang="scss" scoped src="./modal-fullscreen-page.scss" />
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import { ref, watch } from 'vue'; import { isVue2 } from 'vue-demi'; import { BentoSegmentedControl } from '@/components/segmented-control'; import { BentoTypography } from '@/components/typography'; import { BentoButton, type BentoButtonActionsList } from '@/components/button'; import BentoModalFullscreen from './modal-fullscreen.vue'; import BentoModalFullscreenPage from './components/modal-fullscreen-page.vue'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { action } from '@storybook/addon-actions'; import type { Meta, StoryObj } from '@storybook/vue'; import BentoModal from '../modal/modal.vue'; const meta: Meta = { title: 'Modal fullscreen', component: BentoModalFullscreen, argTypes: { // Slots default: { name: 'default', description: 'Content of the fullscreen modal', control: 'text', table: { type: { summary: 'VNode[]' }, }, }, header: { name: 'header', description: 'Header slot in the middle of the modal header', control: 'text', table: { type: { summary: 'VNode[]' }, }, }, }, }; export default meta; type Story = StoryObj<typeof BentoModalFullscreen>; const DEFAULT_PROPS = { title: 'Fullscreen modal title', contextualLabel: 'Aditional contextual label', isOpen: false, actions: [ { title: 'Primary', event: () => true, }, { title: 'Secondary', event: () => true, }, ], }; const SEGMENTED_CONTROL_ITEMS = [ { label: 'Segment 1', value: 1 }, { label: 'Segment 2', value: 2 }, { label: 'Segment 3', value: 3 }, ]; const LONG_CONTENT = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum molestie gravida velit id fermentum. Sed posuere dapibus odio vel consectetur. Vivamus sapien erat, vulputate ut porttitor sit amet, congue vel enim. Nullam laoreet nulla elit, in elementum mauris hendrerit sit amet. Fusce a magna lobortis, fermentum sapien vel, hendrerit ex. Nam vel lectus quam. Ut non vulputate est. In hac habitasse platea dictumst. Integer at lectus vestibulum, pulvinar ante in, efficitur neque. Duis sodales libero a dui scelerisque, in auctor enim malesuada. Aenean vitae velit aliquet, viverra velit et, consectetur nulla. Nulla sagittis, enim nec lacinia sagittis, quam tortor dictum arcu, consequat sodales nisi turpis sit amet diam. Etiam varius porta pharetra. Curabitur vestibulum placerat purus. Aliquam erat volutpat.'; const defaultCode = ` <template> <bento-button :aria-expanded="isOpen" @click="isOpen = !isOpen" > Open modal fullscreen </bento-button> <bento-modal-fullscreen title="Fullscreen modal title" contextual-label="Aditional contextual label" :is-open="isOpen" @update:is-open="isOpen = $event" :actions="actions" > <template #header> <!-- Put content/component you want in the header slot here, for example, a Segmented Control --> <bento-segmented-control :items="SEGMENTED_CONTROL_ITEMS" :model-value="selectedValue" @update:model-value="selectedValue = $event"/> </template> <div> <!-- Put the content of your modal here --> </div> </bento-modal-fullscreen> </template> <script setup lang="ts"> import { ref } from 'vue'; import { BentoModalFullscreen, BentoButton } from '@adyen/bento-vue2'; const isOpen = ref(false); const actions = [ { title: 'Primary', event: () => true, }, { title: 'Secondary', event: () => true, }, ]; // Segmented control props const SEGMENTED_CONTROL_ITEMS = [ { label: 'Segment 1', value: 1 }, { label: 'Segment 2', value: 2 }, { label: 'Segment 3', value: 3 }, ]; const selectedValue = ref(SEGMENTED_CONTROL_ITEMS[0].value); </script> `; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoModalFullscreen, BentoButton, BentoSegmentedControl, BentoTypography }, props: Object.keys(argTypes), template: ` <div> <bento-button :aria-expanded="isOpen" @click="isOpen = true" > Open modal fullscreen </bento-button> <bento-modal-fullscreen v-bind="args" :is-open="isOpen" @update:is-open="isOpen = $event"> <template #header> <template v-if='args.header'>{{ args.header }}</template> <bento-segmented-control v-else :items="SEGMENTED_CONTROL_ITEMS" :model-value="selectedValue" @update:model-value="selectedValue = $event"/> </template> <template v-if='args.default'>{{ args.default }}</template> <div v-else style="display: flex; height: 100%"> <div style="border-right: 1px solid #dbdee2; padding: 2em; min-height: 100%; height: max-content"> <bento-typography> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> </bento-typography> </div> <div style="padding: 2em"> <bento-typography> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> </bento-typography> </div> </div> </bento-modal-fullscreen> </div> `, setup(props) { const isOpen = ref(false); const args = isVue2 ? props : _args; const selectedValue = ref(SEGMENTED_CONTROL_ITEMS[0].value); watch( () => args.isOpen, () => { isOpen.value = args.isOpen; } ); return { args, isOpen, selectedValue, LONG_CONTENT, SEGMENTED_CONTROL_ITEMS, }; }, }), args: DEFAULT_PROPS, parameters: storybookDocsParameter(defaultCode), }; const multiplePagesCode = ` <template> <bento-button :aria-expanded="isOpen" @click="isOpen = !isOpen" > Open modal fullscreen </bento-button> <bento-modal-fullscreen :is-open="isOpen" :active-page="activePage" @update:active-page="activePage = $event" @update:is-open='isOpen = $event' > <bento-modal-fullscreen-page v-bind="page1"> <bento-typography> <!-- Put the content of your page here --> </bento-typography> </bento-modal-fullscreen-page> <bento-modal-fullscreen-page v-bind="page2" > <bento-typography> <!-- Put the content of your page here --> </bento-typography> </bento-modal-fullscreen-page> <bento-modal-fullscreen-page v-bind="page3" > <bento-typography> <!-- Put the content of your page here --> </bento-typography> </bento-modal-fullscreen-page> <bento-modal-fullscreen-page v-bind="page4"> <bento-typography> <!-- Put the content of your page here --> </bento-typography> </bento-modal-fullscreen> </template> <script setup lang="ts"> import { ref } from 'vue'; import { BentoModalFullscreen, BentoModalFullscreenPage, BentoButton, BentoTypography } from '@adyen/bento-vue2'; const isOpen = ref(false); const activePage = ref('intro'); const page1 = { pageId: 'page1', title: 'Page 1', actions: [ { title: 'Go to next page', event: () => { activePage.value = 'page2'; }, } ] }; const page2 = { pageId: 'page2', title: 'Page 2', actions: [ { title: 'Go to next page', event: () => { activePage.value = 'page3'; }, } ] }; const page3 = { pageId: 'page3', title: 'Page 3', actions: [ { title: 'Go to next page', event: () => { activePage.value = 'page4'; }, } ] }; const page4 = { pageId: 'page4', title: 'Page 4', actions: [ { title: 'Finish', event: () => { isOpen.value = false; }, } ], previousPage: null, }; </script> `; export const MultiplePages: Story = { render: (_args, { argTypes }) => ({ components: { BentoModalFullscreen, BentoModalFullscreenPage, BentoButton, BentoTypography }, props: Object.keys(argTypes), template: ` <div> <bento-button :aria-expanded="isOpen" @click="isOpen = true" > Open modal fullscreen </bento-button> <bento-modal-fullscreen v-bind="args" :is-open="isOpen" :active-page="activePage" @update:active-page="activePage = $event" @update:is-open='isOpen = $event'> <bento-modal-fullscreen-page v-bind="intro"> <bento-typography style="padding: 24px"> {{ LONG_CONTENT }} <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> </bento-typography> </bento-modal-fullscreen-page> <bento-modal-fullscreen-page v-bind="newProfile" > <bento-typography style="padding: 24px"> This page has some info about creating a new profile </bento-typography> </bento-modal-fullscreen-page> <bento-modal-fullscreen-page v-bind="editProfile" > <bento-typography style="padding: 24px"> This is where you edit your profile </bento-typography> </bento-modal-fullscreen-page> <bento-modal-fullscreen-page v-bind="newProfileForm"> <bento-typography style="padding: 24px"> This is where you create a new profile </bento-typography> </bento-modal-fullscreen-page> <bento-modal-fullscreen-page v-bind="success"> <bento-typography style="padding: 24px"> Your profile is created </bento-typography> </bento-modal-fullscreen-page> </bento-modal-fullscreen> </div> `, setup(props) { const isOpen = ref(false); const activePage = ref('intro'); const args = isVue2 ? props : _args; watch( () => args.isOpen, () => { isOpen.value = args.isOpen; } ); watch( () => args.activePage, () => { activePage.value = args.activePage; } ); const intro = { pageId: 'intro', title: 'Intro', actions: [ { title: 'New profile', event: () => { activePage.value = 'newProfile'; }, }, { title: 'Edit profile', event: () => { activePage.value = 'editProfile'; }, }, ], contextualLabel: 'What do you wanna do?', }; const newProfile = { pageId: 'newProfile', title: 'New profile', actions: [ { title: 'Go to form', event: () => { activePage.value = 'newProfileForm'; }, }, ], }; const editProfile = { pageId: 'editProfile', title: 'Edit profile', actions: [ { title: 'Save', event: () => { activePage.value = 'success'; }, }, { title: 'Cancel', event: () => { isOpen.value = false; }, }, ], }; const newProfileForm = { pageId: 'newProfileForm', title: 'New profile form', actions: [ { title: 'Save', event: () => { activePage.value = 'success'; }, }, { title: 'Cancel', event: () => { isOpen.value = false; }, }, ], }; const success = { pageId: 'success', title: 'Success!', actions: [ { title: 'Delete', critical: true, event: () => { isOpen.value = false; action('delete')(); }, }, { title: 'Cancel', event: () => { isOpen.value = false; }, }, ], previousPage: null, }; return { args, activePage, intro, newProfile, newProfileForm, success, editProfile, isOpen, LONG_CONTENT, }; }, }), args: { ...DEFAULT_PROPS, activePage: 'intro' }, parameters: storybookDocsParameter(multiplePagesCode), }; export const withBeforeClose: Story = { render: (_args, { argTypes }) => ({ components: { BentoModalFullscreen, BentoModalFullscreenPage, BentoButton, BentoTypography, BentoModal, BentoSegmentedControl, }, props: Object.keys(argTypes), template: ` <div> <bento-button :aria-expanded="isOpen" @click="isOpen = !isOpen"> Open modal fullscreen </bento-button> <bento-modal-fullscreen title="Fullscreen modal title" contextual-label="Click on the 'X' to get the confirmation modal" :is-open="isOpen" @before-close="onClose" @click="onClose" @update:is-open="isOpen = $event" > <div> <!-- Put the content of your modal here --> <p>This is the content of the fullscreen modal.</p> <p>Click on the "X" (close) button to get the confirmation modal.</p> </div> </bento-modal-fullscreen> <bento-modal content="Are you sure you want to proceed with this action?" variant="dialog" dialog-type="confirmation" :actions="dialogActions" :is-open="isConfirmationOpened" @close-modal="closeModal" > Modal Title </bento-modal> </div> `, setup() { const isOpen = ref(false); const isConfirmationOpened = ref(false); const onClose = () => { openModal(); }; const dialogActions: BentoButtonActionsList = [ { title: 'Confirm', event: () => { isOpen.value = false; closeModal(); }, }, ]; const closeModal = () => { isConfirmationOpened.value = false; }; const openModal = () => { isConfirmationOpened.value = true; }; return { dialogActions, isConfirmationOpened, isOpen, onClose, closeModal, openModal, }; }, }), };
|
|
1
|
+
import { ref, watch } from 'vue'; import { isVue2 } from 'vue-demi'; import { BentoSegmentedControl } from '@/components/segmented-control'; import { BentoTypography } from '@/components/typography'; import { BentoButton, type BentoButtonActionsList } from '@/components/button'; import BentoModalFullscreen from './modal-fullscreen.vue'; import BentoModalFullscreenPage from './components/modal-fullscreen-page.vue'; const ModalFullscreenDefaultExample = "<template>\n <div>\n <bento-button :aria-expanded=\"isOpen\" @click=\"isOpen = !isOpen\">Open modal fullscreen</bento-button>\n <bento-modal-fullscreen\n title=\"Fullscreen modal title\"\n contextual-label=\"Additional contextual label\"\n :is-open=\"isOpen\"\n :actions=\"actions\"\n @update:is-open=\"isOpen = $event\"\n >\n <template #header>\n <bento-segmented-control\n :items=\"segmentedControlItems\"\n :model-value=\"selectedValue\"\n @update:model-value=\"selectedValue = $event\"\n />\n </template>\n <div>Put the content of your modal here.</div>\n </bento-modal-fullscreen>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\n import { ref } from 'vue';\n import { BentoButton, BentoModalFullscreen, BentoSegmentedControl } from '@adyen/bento-vue2';\n\n const isOpen = ref(false);\n const actions = [\n {\n title: 'Primary',\n event: () => true,\n },\n {\n title: 'Secondary',\n event: () => true,\n },\n ];\n const segmentedControlItems = [\n { label: 'Segment 1', value: 1 },\n { label: 'Segment 2', value: 2 },\n { label: 'Segment 3', value: 3 },\n ];\n const selectedValue = ref(segmentedControlItems[0].value);\n</script>\n"; const ModalFullscreenMultiplePagesExample = "<template>\n <div>\n <bento-button :aria-expanded=\"isOpen\" @click=\"isOpen = !isOpen\">Open modal fullscreen</bento-button>\n <bento-modal-fullscreen\n title=\"Fullscreen modal title\"\n contextual-label=\"Additional contextual label\"\n :actions=\"modalActions\"\n :is-open=\"isOpen\"\n :active-page=\"activePage\"\n @update:active-page=\"activePage = $event\"\n @update:is-open=\"isOpen = $event\"\n >\n <bento-modal-fullscreen-page v-bind=\"intro\">\n <bento-typography style=\"padding: 24px\">\n {{ longContent }}\n <p>{{ longContent }}</p>\n <p>{{ longContent }}</p>\n <p>{{ longContent }}</p>\n <p>{{ longContent }}</p>\n </bento-typography>\n </bento-modal-fullscreen-page>\n <bento-modal-fullscreen-page v-bind=\"newProfile\">\n <bento-typography style=\"padding: 24px\">\n This page has some info about creating a new profile\n </bento-typography>\n </bento-modal-fullscreen-page>\n <bento-modal-fullscreen-page v-bind=\"editProfile\">\n <bento-typography style=\"padding: 24px\">This is where you edit your profile</bento-typography>\n </bento-modal-fullscreen-page>\n <bento-modal-fullscreen-page v-bind=\"newProfileForm\">\n <bento-typography style=\"padding: 24px\">This is where you create a new profile</bento-typography>\n </bento-modal-fullscreen-page>\n <bento-modal-fullscreen-page v-bind=\"success\">\n <bento-typography style=\"padding: 24px\">Your profile is created</bento-typography>\n </bento-modal-fullscreen-page>\n </bento-modal-fullscreen>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\n import { ref } from 'vue';\n import { BentoButton, BentoModalFullscreen, BentoModalFullscreenPage, BentoTypography } from '@adyen/bento-vue2';\n\n const isOpen = ref(false);\n const activePage = ref('intro');\n const longContent =\n 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum molestie gravida velit id fermentum.';\n const modalActions = [\n { title: 'Primary', event: () => true },\n { title: 'Secondary', event: () => true },\n ];\n const intro = {\n pageId: 'intro',\n title: 'Intro',\n contextualLabel: 'What do you wanna do?',\n actions: [\n { title: 'New profile', event: () => (activePage.value = 'newProfile') },\n { title: 'Edit profile', event: () => (activePage.value = 'editProfile') },\n ],\n };\n const newProfile = {\n pageId: 'newProfile',\n title: 'New profile',\n actions: [{ title: 'Go to form', event: () => (activePage.value = 'newProfileForm') }],\n };\n const editProfile = {\n pageId: 'editProfile',\n title: 'Edit profile',\n actions: [\n { title: 'Save', event: () => (activePage.value = 'success') },\n { title: 'Cancel', event: () => (isOpen.value = false) },\n ],\n };\n const newProfileForm = {\n pageId: 'newProfileForm',\n title: 'New profile form',\n actions: [\n { title: 'Save', event: () => (activePage.value = 'success') },\n { title: 'Cancel', event: () => (isOpen.value = false) },\n ],\n };\n const success = {\n pageId: 'success',\n title: 'Success!',\n actions: [\n { title: 'Delete', critical: true, event: () => (isOpen.value = false) },\n { title: 'Cancel', event: () => (isOpen.value = false) },\n ],\n previousPage: null,\n };\n</script>\n"; import { storybookDocsParameter } from '@/utils/ts/storybook'; import { action } from '@storybook/addon-actions'; import type { Meta, StoryObj } from '@storybook/vue'; import BentoModal from '../modal/modal.vue'; const meta: Meta = { title: 'Modal fullscreen', component: BentoModalFullscreen, argTypes: { // Slots default: { name: 'default', description: 'Content of the fullscreen modal', control: 'text', table: { type: { summary: 'VNode[]' }, }, }, header: { name: 'header', description: 'Header slot in the middle of the modal header', control: 'text', table: { type: { summary: 'VNode[]' }, }, }, }, }; export default meta; type Story = StoryObj<typeof BentoModalFullscreen>; const DEFAULT_PROPS = { title: 'Fullscreen modal title', contextualLabel: 'Additional contextual label', isOpen: false, actions: [ { title: 'Primary', event: () => true, }, { title: 'Secondary', event: () => true, }, ], }; const SEGMENTED_CONTROL_ITEMS = [ { label: 'Segment 1', value: 1 }, { label: 'Segment 2', value: 2 }, { label: 'Segment 3', value: 3 }, ]; const LONG_CONTENT = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum molestie gravida velit id fermentum. Sed posuere dapibus odio vel consectetur. Vivamus sapien erat, vulputate ut porttitor sit amet, congue vel enim. Nullam laoreet nulla elit, in elementum mauris hendrerit sit amet. Fusce a magna lobortis, fermentum sapien vel, hendrerit ex. Nam vel lectus quam. Ut non vulputate est. In hac habitasse platea dictumst. Integer at lectus vestibulum, pulvinar ante in, efficitur neque. Duis sodales libero a dui scelerisque, in auctor enim malesuada. Aenean vitae velit aliquet, viverra velit et, consectetur nulla. Nulla sagittis, enim nec lacinia sagittis, quam tortor dictum arcu, consequat sodales nisi turpis sit amet diam. Etiam varius porta pharetra. Curabitur vestibulum placerat purus. Aliquam erat volutpat.'; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoModalFullscreen, BentoButton, BentoSegmentedControl, BentoTypography }, props: Object.keys(argTypes), template: ` <div> <bento-button :aria-expanded="isOpen" @click="isOpen = true" > Open modal fullscreen </bento-button> <bento-modal-fullscreen v-bind="args" :is-open="isOpen" @update:is-open="isOpen = $event"> <template #header> <template v-if='args.header'>{{ args.header }}</template> <bento-segmented-control v-else :items="SEGMENTED_CONTROL_ITEMS" :model-value="selectedValue" @update:model-value="selectedValue = $event"/> </template> <template v-if='args.default'>{{ args.default }}</template> <div v-else style="display: flex; height: 100%"> <div style="border-right: 1px solid #dbdee2; padding: 2em; min-height: 100%; height: max-content"> <bento-typography> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> </bento-typography> </div> <div style="padding: 2em"> <bento-typography> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> </bento-typography> </div> </div> </bento-modal-fullscreen> </div> `, setup(props) { const isOpen = ref(false); const args = isVue2 ? props : _args; const selectedValue = ref(SEGMENTED_CONTROL_ITEMS[0].value); watch( () => args.isOpen, () => { isOpen.value = args.isOpen; } ); return { args, isOpen, selectedValue, LONG_CONTENT, SEGMENTED_CONTROL_ITEMS, }; }, }), args: DEFAULT_PROPS, parameters: storybookDocsParameter(ModalFullscreenDefaultExample), }; export const MultiplePages: Story = { render: (_args, { argTypes }) => ({ components: { BentoModalFullscreen, BentoModalFullscreenPage, BentoButton, BentoTypography }, props: Object.keys(argTypes), template: ` <div> <bento-button :aria-expanded="isOpen" @click="isOpen = true" > Open modal fullscreen </bento-button> <bento-modal-fullscreen v-bind="args" :is-open="isOpen" :active-page="activePage" @update:active-page="activePage = $event" @update:is-open='isOpen = $event'> <bento-modal-fullscreen-page v-bind="intro"> <bento-typography style="padding: 24px"> {{ LONG_CONTENT }} <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> <p>{{LONG_CONTENT}}</p> </bento-typography> </bento-modal-fullscreen-page> <bento-modal-fullscreen-page v-bind="newProfile" > <bento-typography style="padding: 24px"> This page has some info about creating a new profile </bento-typography> </bento-modal-fullscreen-page> <bento-modal-fullscreen-page v-bind="editProfile" > <bento-typography style="padding: 24px"> This is where you edit your profile </bento-typography> </bento-modal-fullscreen-page> <bento-modal-fullscreen-page v-bind="newProfileForm"> <bento-typography style="padding: 24px"> This is where you create a new profile </bento-typography> </bento-modal-fullscreen-page> <bento-modal-fullscreen-page v-bind="success"> <bento-typography style="padding: 24px"> Your profile is created </bento-typography> </bento-modal-fullscreen-page> </bento-modal-fullscreen> </div> `, setup(props) { const isOpen = ref(false); const activePage = ref('intro'); const args = isVue2 ? props : _args; watch( () => args.isOpen, () => { isOpen.value = args.isOpen; } ); watch( () => args.activePage, () => { activePage.value = args.activePage; } ); const intro = { pageId: 'intro', title: 'Intro', actions: [ { title: 'New profile', event: () => { activePage.value = 'newProfile'; }, }, { title: 'Edit profile', event: () => { activePage.value = 'editProfile'; }, }, ], contextualLabel: 'What do you wanna do?', }; const newProfile = { pageId: 'newProfile', title: 'New profile', actions: [ { title: 'Go to form', event: () => { activePage.value = 'newProfileForm'; }, }, ], }; const editProfile = { pageId: 'editProfile', title: 'Edit profile', actions: [ { title: 'Save', event: () => { activePage.value = 'success'; }, }, { title: 'Cancel', event: () => { isOpen.value = false; }, }, ], }; const newProfileForm = { pageId: 'newProfileForm', title: 'New profile form', actions: [ { title: 'Save', event: () => { activePage.value = 'success'; }, }, { title: 'Cancel', event: () => { isOpen.value = false; }, }, ], }; const success = { pageId: 'success', title: 'Success!', actions: [ { title: 'Delete', critical: true, event: () => { isOpen.value = false; action('delete')(); }, }, { title: 'Cancel', event: () => { isOpen.value = false; }, }, ], previousPage: null, }; return { args, activePage, intro, newProfile, newProfileForm, success, editProfile, isOpen, LONG_CONTENT, }; }, }), args: { ...DEFAULT_PROPS, activePage: 'intro' }, parameters: storybookDocsParameter(ModalFullscreenMultiplePagesExample), }; export const withBeforeClose: Story = { render: (_args, { argTypes }) => ({ components: { BentoModalFullscreen, BentoModalFullscreenPage, BentoButton, BentoTypography, BentoModal, BentoSegmentedControl, }, props: Object.keys(argTypes), template: ` <div> <bento-button :aria-expanded="isOpen" @click="isOpen = !isOpen"> Open modal fullscreen </bento-button> <bento-modal-fullscreen title="Fullscreen modal title" contextual-label="Click on the 'X' to get the confirmation modal" :is-open="isOpen" @before-close="onClose" @click="onClose" @update:is-open="isOpen = $event" > <div> <!-- Put the content of your modal here --> <p>This is the content of the fullscreen modal.</p> <p>Click on the "X" (close) button to get the confirmation modal.</p> </div> </bento-modal-fullscreen> <bento-modal content="Are you sure you want to proceed with this action?" variant="dialog" dialog-type="confirmation" :actions="dialogActions" :is-open="isConfirmationOpened" @close-modal="closeModal" > Modal Title </bento-modal> </div> `, setup() { const isOpen = ref(false); const isConfirmationOpened = ref(false); const onClose = () => { openModal(); }; const dialogActions: BentoButtonActionsList = [ { title: 'Confirm', event: () => { isOpen.value = false; closeModal(); }, }, ]; const closeModal = () => { isConfirmationOpened.value = false; }; const openModal = () => { isConfirmationOpened.value = true; }; return { dialogActions, isConfirmationOpened, isOpen, onClose, closeModal, openModal, }; }, }), };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<template> <dialog :id="modalFullscreenId" ref="modal" class="b-modal-fullscreen" :class="conditionalClasses" data-dialog-element="modal-fullscreen" :aria-labelledby="titleId" @animationend="closeModalAfterAnimation" @keydown.esc.prevent="closeModal" > <bento-focus-trap v-if="internalIsOpen" class="b-modal-fullscreen__wrapper"> <template v-if="props.activePage"> <slot /> </template> <bento-modal-fullscreen-page v-else :actions="actions" :contextual-label="contextualLabel" :title="title" :title-id="titleId" @close="closeModal" > <template v-if="hasSlot('default')" #default> <slot name="default"></slot> </template> <template v-if="hasSlot('header')" #header> <slot name="header"></slot> </template> </bento-modal-fullscreen-page> </bento-focus-trap> <!-- Enable the toast inside the fullscreen-modal --> <template v-if="isOpen"> <bento-toast /> </template> </dialog> </template> <script setup lang="ts"> import { computed, onMounted, onUnmounted, type PropType, provide, ref, toRefs, useSlots, watch } from 'vue'; import { isVue2 } from 'vue-demi'; import { BentoToast } from '@/components/toast'; import { type BentoButtonActionsList } from '@/components/button'; import { BentoFocusTrap } from '@/components/focus-trap'; import BentoModalFullscreenPage from './components/modal-fullscreen-page.vue'; import { generateUid } from '@/
|
|
1
|
+
<template> <dialog :id="modalFullscreenId" ref="modal" class="b-modal-fullscreen" :class="conditionalClasses" data-dialog-element="modal-fullscreen" :aria-labelledby="titleId" @animationend="closeModalAfterAnimation" @keydown.esc.prevent="closeModal" > <bento-focus-trap v-if="internalIsOpen" class="b-modal-fullscreen__wrapper"> <template v-if="props.activePage"> <slot /> </template> <bento-modal-fullscreen-page v-else :actions="actions" :contextual-label="contextualLabel" :title="title" :title-id="titleId" @close="closeModal" > <template v-if="hasSlot('default')" #default> <slot name="default"></slot> </template> <template v-if="hasSlot('header')" #header> <slot name="header"></slot> </template> </bento-modal-fullscreen-page> </bento-focus-trap> <!-- Enable the toast inside the fullscreen-modal --> <template v-if="isOpen"> <bento-toast /> </template> </dialog> </template> <script setup lang="ts"> import { computed, onMounted, onUnmounted, type PropType, provide, ref, toRefs, useSlots, watch } from 'vue'; import { isVue2 } from 'vue-demi'; import { BentoToast } from '@/components/toast'; import { type BentoButtonActionsList } from '@/components/button'; import { BentoFocusTrap } from '@/components/focus-trap'; import BentoModalFullscreenPage from './components/modal-fullscreen-page.vue'; import { generateUid } from '@/utils/ts/generate-uid'; import { useHasSlot } from '@/composables'; import { useListeners } from '@/composables/use-listeners'; import { MODAL_FULLSCREEN_CLOSE_INJECTION_KEY, MODAL_FULLSCREEN_DIALOG_ID_INJECTION_KEY, MODAL_FULLSCREEN_TITLE_ID_INJECTION_KEY, } from '@/components/modal-fullscreen/modal-fullscreen.keys'; import { BentoDialogPageAnimation, type BentoDialogPageConfigData, type BentoDialogPageRegisterPage, DIALOG_PAGE_CONFIG_INJECTION_KEY, DIALOG_PAGE_REGISTER_PAGE_INJECTION_KEY, } from '@/internal'; const props = defineProps({ /** * List of actions that will be used to render the buttons. * First element in the list will be rendered as "primary". * All elements after the first will be rendered as "secondary". * * Each object in the list should have a `title`, an `event` and * (optional) a Vue `icon` from the library `@adyen/ui-assets-icons-16`. * * @see BentoButton for a list of all the other props supported by each button action. */ actions: { type: Array as PropType<BentoButtonActionsList>, default: null, }, /** * The id of the current active page * Should be the same as the pageId of the BentoModalFullscreenPage to be displayed */ activePage: { type: String, default: null, }, /** * Label shown next to the modal actions */ contextualLabel: { type: String, default: null, }, /** * Controls the modal's state from the outside. Set it to true to open the modal */ isOpen: { type: Boolean, default: null, }, /** * Title of the modal */ title: { type: String, default: null, }, }); const emit = defineEmits<{ /** * Handles closing the modal. The behavior changes depending on whether a `before-close` event listener is present. * * - **When listening for the `before-close` event:** * The `before-close` event is emitted immediately, skipping the animation. This allows for logic to run before the modal closes. * The `isOpen` prop must then be set to `false` to trigger the closing animation. * * - **When not listening for the `before-close` event:** * The closing animation plays, then `update:is-open` is emitted with `false`. * This is the default behavior, compatible with `v-model` or `.sync` on the `isOpen` prop. */ (e: 'before-close'): void; /** * Emits update event when page is changed internally */ (e: 'update:active-page', page: string): void; /** * Emits 'update:is-open' event when the modal is closed */ (e: 'update:is-open', isOpen: boolean): void; }>(); // Refs const { activePage, isOpen } = toRefs(props); const modal = ref(null); const isClosing = ref(false); const modalFullscreenId = generateUid('modal-fullscreen'); const titleId = generateUid('modal-fullscreen-title'); const internalIsOpen = ref(false); const isMounted = ref(false); const listeners = useListeners(); const slots = useSlots(); const hasSlot = useHasSlot(slots); // Animation styling const conditionalClasses = computed(() => ({ 'b-modal-fullscreen--hide': isClosing.value, })); // Handle closing and closing animation for dialog element const closeModalAfterAnimation = () => { if (isClosing.value && modal.value) { modal.value.close(); if (previousPages.value[0]) { emit('update:active-page', previousPages.value[0]); } previousPages.value = []; isClosing.value = false; internalIsOpen.value = false; emit('update:is-open', false); } }; /** * Emits the `beforeClose` event, if it is being listened to, * before closing the modal and omits the closing animation. * The animation will be triggered by the change of the `isOpen` prop instead. * * If no listener for the `before-close`, then the animation will be triggered, * which will close the modal and emit the `update:is-open` event instead, after it was closed. */ function closeModal() { /** * Vue3 appends the prefix "on" and changes to camelCase */ const eventName = isVue2 ? 'before-close' : 'onBeforeClose'; if (listeners[eventName]) { emit('before-close'); return; } startCloseModalAnimation(); } const startCloseModalAnimation = () => { if (!modal.value || !modal.value.open) { return; } isClosing.value = true; }; onMounted(() => { isMounted.value = true; }); onUnmounted(() => { isMounted.value = false; }); // Watching isOpen prop to toggle open/close the dialog element watch( [() => isOpen.value, modal], ([newIsOpen, newModalValue]) => { if (!isMounted.value || !newModalValue) { return; } if (newIsOpen) { internalIsOpen.value = true; if (!newModalValue.open) { newModalValue.showModal(); } if (!previousPages.value.length) { previousPages.value.push(activePage.value); } } else if (newModalValue.open) { startCloseModalAnimation(); } }, { immediate: true, flush: 'post' } ); // lets children components know they are inside a Modal (dialog element) provide(MODAL_FULLSCREEN_DIALOG_ID_INJECTION_KEY, modalFullscreenId); provide(MODAL_FULLSCREEN_TITLE_ID_INJECTION_KEY, titleId); provide(MODAL_FULLSCREEN_CLOSE_INJECTION_KEY, closeModal); // Pages const animation = ref(BentoDialogPageAnimation.TRANSITION_LEVEL_DEEPER); const pages = ref<Array<string>>([]); const previousPages = ref([]); const updatePage = page => emit('update:active-page', page); provide<BentoDialogPageConfigData>(DIALOG_PAGE_CONFIG_INJECTION_KEY, { activePage, animation, isOpen: internalIsOpen, pages, previousPages, updatePage, }); // unregister page if removed / destroyed const unregisterPage = (pageIdToRemove: string) => () => { pages.value = pages.value?.filter(pageId => pageId !== pageIdToRemove); }; // Provide data and function to register page to subcomponent const registerPage: BentoDialogPageRegisterPage = pageId => { if (pageId) { pages.value.push(pageId); } return { unregisterPage: unregisterPage(pageId) }; }; provide(DIALOG_PAGE_REGISTER_PAGE_INJECTION_KEY, registerPage); </script> <script lang="ts"> /** * Fullscreen modal takes full available space (no content underneath is visible) and focuses the user's attention exclusively on one complex task or piece of complex information. * * @example * import { BentoModalFullscreen } from '@adyen/bento-vue2'; * * export default { * components: { BentoModalFullscreen }, * template: ` * <bento-modal-fullscreen * :is-open="isOpen" * @update:is-open="isOpen = $event" * title='Fullscreen modal title' * contextual-label='Contextual label' * :actions="[{ title: 'Action', event: () => {}]" * > * <template #header>{{ header slot }}</template> * {{ content }} * </bento-modal-fullscreen> * ` * } */ export default {}; </script> <style lang="scss" scoped src="./modal-fullscreen.scss" />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import type { Ref } from 'vue'; export interface BentoNavigationMenuItemRegistration { id: string; isSelected: () => boolean; } export interface BentoNavigationMenuGroupState { registerItem: (itemId: string, isSelected: () => boolean) => void; unregisterItem: (itemId: string) => void; isSemiCollapsed: Ref<boolean>; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
export interface BentoNavigationMenuGroupProps { /** * Whether the group is expanded */ isExpanded?: boolean; /** * Label text for the group */ label: string; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<template> <li class="b-navigation-menu-group"> <button :id="buttonId" type="button" class="b-navigation-menu-group__header" :class="{ ...headerClasses, 'b-navigation-menu-group__header--no-icon': !hasSlot('icon'), }" :aria-expanded="`${isOpen && !isSemiCollapsed}`" :aria-controls="contentId" :aria-description="headerAriaDescription" @click="toggleGroup" > <div v-if="hasSlot('icon')" class="b-navigation-menu-group__icon" aria-hidden="true"> <slot name="icon" /> </div> <bento-typography ref="labelRef" v-bento-tooltip-directive="isTruncated ? label : undefined" el="span" variant="body" stronger class="b-navigation-menu-group__label" > {{ label }} </bento-typography> <div class="b-navigation-menu-group__icon b-navigation-menu-group__icon--chevron" aria-hidden="true"> <chevron-up-icon v-if="isOpen && !isSemiCollapsed" /> <chevron-down-icon v-else /> </div> </button> <Transition name="b-navigation-menu-group__animation--content"> <div v-show="isOpen" :id="contentId" class="b-navigation-menu-group__content-wrapper" role="region" :aria-labelledby="buttonId" :style="contentMaxHeight" > <ul ref="contentDiv" class="b-navigation-menu-group__content"> <slot /> </ul> </div> </Transition> </li> </template> <script setup lang="ts"> import { computed, inject, onMounted, onUnmounted, provide, ref, useSlots, watch } from 'vue'; import { useResizeObserver } from '@vueuse/core'; import { BentoTypography } from '@/components/typography'; import { useExpandableContentHeight } from '@/composables/use-expandable-content-height/use-expandable-content-height'; import { useHasSlot } from '@/composables'; import { BentoTooltipDirective as vBentoTooltipDirective } from '@/directives/tooltip'; import { generateUid } from '@/
|
|
1
|
+
<template> <li class="b-navigation-menu-group"> <button :id="buttonId" type="button" class="b-navigation-menu-group__header" :class="{ ...headerClasses, 'b-navigation-menu-group__header--no-icon': !hasSlot('icon'), }" :aria-expanded="`${isOpen && !isSemiCollapsed}`" :aria-controls="contentId" :aria-description="headerAriaDescription" @click="toggleGroup" > <div v-if="hasSlot('icon')" class="b-navigation-menu-group__icon" aria-hidden="true"> <slot name="icon" /> </div> <bento-typography ref="labelRef" v-bento-tooltip-directive="isTruncated ? label : undefined" el="span" variant="body" stronger class="b-navigation-menu-group__label" > {{ label }} </bento-typography> <div class="b-navigation-menu-group__icon b-navigation-menu-group__icon--chevron" aria-hidden="true"> <chevron-up-icon v-if="isOpen && !isSemiCollapsed" /> <chevron-down-icon v-else /> </div> </button> <Transition name="b-navigation-menu-group__animation--content"> <div v-show="isOpen" :id="contentId" class="b-navigation-menu-group__content-wrapper" role="region" :aria-labelledby="buttonId" :style="contentMaxHeight" > <ul ref="contentDiv" class="b-navigation-menu-group__content"> <slot /> </ul> </div> </Transition> </li> </template> <script setup lang="ts"> import { computed, inject, onMounted, onUnmounted, provide, ref, useSlots, watch } from 'vue'; import { useResizeObserver } from '@vueuse/core'; import { BentoTypography } from '@/components/typography'; import { useExpandableContentHeight } from '@/composables/use-expandable-content-height/use-expandable-content-height'; import { useHasSlot } from '@/composables'; import { BentoTooltipDirective as vBentoTooltipDirective } from '@/directives/tooltip'; import { generateUid } from '@/utils/ts/generate-uid'; import { useI18n } from '@/utils/ts/i18n'; import ChevronDownIcon from '@adyen/ui-assets-icons-16/vue/chevron-down'; import ChevronUpIcon from '@adyen/ui-assets-icons-16/vue/chevron-up'; import type { BentoNavigationMenuGroupProps } from './navigation-menu-group.types'; import type { BentoNavigationMenuGroupState, BentoNavigationMenuItemRegistration, } from './navigation-menu-group.internal.types'; import { NAVIGATION_MENU_STATE_INJECTION_KEY } from '../../navigation-menu.keys'; import { NAVIGATION_MENU_GROUP_STATE_INJECTION_KEY } from './navigation-menu-group.keys'; import { type BentoNavigationMenuState } from '../../navigation-menu.internal.types'; import messages from '../../messages.json'; type MessageSchema = (typeof messages)['en-US']; const props = withDefaults(defineProps<BentoNavigationMenuGroupProps>(), { isExpanded: false, }); const slots = useSlots(); const hasSlot = useHasSlot(slots); const { t } = useI18n<{ message: MessageSchema }>({ messages }); const headerClasses = computed(() => ({ 'b-navigation-menu-group__header--expanded': isOpen.value && !isSemiCollapsed.value, })); const headerAriaDescription = computed(() => (isSemiCollapsed.value ? t('showingCurrentPage') : undefined)); const labelRef = ref(null); const isTruncated = ref(false); useResizeObserver(labelRef, () => { const el = labelRef.value?.$el ?? labelRef.value; if (el) { isTruncated.value = el.scrollWidth > el.clientWidth; } }); const groupId = generateUid('navigation-menu-group'); const buttonId = generateUid('navigation-menu-group-button'); const contentId = generateUid('navigation-menu-group-content'); const navigationMenuState = inject<BentoNavigationMenuState | null>(NAVIGATION_MENU_STATE_INJECTION_KEY, null); const nestedItems = ref<Array<BentoNavigationMenuItemRegistration>>([]); const registerItem = (itemId: string, isSelected: () => boolean) => { nestedItems.value.push({ id: itemId, isSelected }); }; const unregisterItem = (itemId: string) => { nestedItems.value = nestedItems.value.filter(item => item.id !== itemId); }; const isSemiCollapsed = ref(false); provide<BentoNavigationMenuGroupState>(NAVIGATION_MENU_GROUP_STATE_INJECTION_KEY, { registerItem, unregisterItem, isSemiCollapsed, }); const hasActiveItem = computed(() => nestedItems.value.some(item => item.isSelected())); const emit = defineEmits<{ /** * Emits update event when group is toggled */ (e: 'update:is-expanded', value: boolean): void; }>(); const isOpen = ref(props.isExpanded); const contentDiv = ref<HTMLUListElement>(null); const { contentHeight } = useExpandableContentHeight(contentDiv, isOpen); const contentMaxHeight = computed(() => (contentHeight.value ? { 'max-height': contentHeight.value } : {})); const toggleGroup = () => { if (isOpen.value && !isSemiCollapsed.value) { if (hasActiveItem.value) { isSemiCollapsed.value = true; } else { isOpen.value = false; } } else if (isSemiCollapsed.value) { isSemiCollapsed.value = false; } else { isOpen.value = true; } emit('update:is-expanded', isOpen.value && !isSemiCollapsed.value); }; const setOpen = (open: boolean) => { if (open) { isOpen.value = true; isSemiCollapsed.value = false; } else if (hasActiveItem.value) { isSemiCollapsed.value = true; } else { isSemiCollapsed.value = false; isOpen.value = false; } emit('update:is-expanded', open); }; watch( () => props.isExpanded, value => { if (!isSemiCollapsed.value) { isOpen.value = value; } } ); onMounted(() => { if (hasActiveItem.value && !isOpen.value) { isOpen.value = true; emit('update:is-expanded', true); } if (navigationMenuState) { navigationMenuState.registerGroup(groupId, setOpen, () => isOpen.value && !isSemiCollapsed.value); } }); onUnmounted(() => navigationMenuState?.unregisterGroup(groupId)); </script> <script lang="ts"> /** * Navigation menu group component for creating collapsible sections. * * @usage * import { BentoNavigationMenuGroup, BentoNavigationMenuItem } from '@adyen/bento-vue2'; * * export default { * components: { BentoNavigationMenuGroup, BentoNavigationMenuItem }, * template: ` * <bento-navigation-menu-group label="Section" :is-expanded="true"> * <template #icon><folder-icon /></template> * <bento-navigation-menu-item nested value="item-1" label="Item 1" :link="{ to: '/section/item-1' }" /> * <bento-navigation-menu-item nested value="item-2" label="Item 2" :link="{ to: '/section/item-2' }" /> * </bento-navigation-menu-group> * ` * } */ export default { name: 'bento-navigation-menu-group', i18n: { messages }, }; </script> <style lang="scss" scoped src="./navigation-menu-group.scss" />
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<template> <li class="b-navigation-menu-item" :class="{ ...conditionalClasses, 'b-navigation-menu-item--no-icon': !hasSlot('icon'), }" :aria-hidden="!isVisible ? 'true' : undefined" > <component :is="componentType" v-bind="componentProps" class="b-navigation-menu-item__link" :aria-current="isSelected && link ? 'page' : undefined" :tabindex="!isVisible ? -1 : undefined" :inert="!isVisible ? '' : undefined" @click="handleClick" > <div v-if="!nested && hasSlot('icon')" class="b-navigation-menu-item__icon" aria-hidden="true"> <slot name="icon" /> </div> <bento-typography ref="labelRef" v-bento-tooltip-directive="isTruncated ? label : undefined" el="span" variant="body" stronger class="b-navigation-menu-item__label" > {{ label }} </bento-typography> </component> <div v-if="hasSlot('action')" class="b-navigation-menu-item__action"> <slot name="action" /> </div> </li> </template> <script setup lang="ts"> import { computed, inject, onBeforeUnmount, onMounted, ref, useSlots } from 'vue'; import { useResizeObserver } from '@vueuse/core'; import { BentoLink } from '@/components/link'; import { BentoTypography } from '@/components/typography'; import { generateUid } from '@/
|
|
1
|
+
<template> <li class="b-navigation-menu-item" :class="{ ...conditionalClasses, 'b-navigation-menu-item--no-icon': !hasSlot('icon'), }" :aria-hidden="!isVisible ? 'true' : undefined" > <component :is="componentType" v-bind="componentProps" class="b-navigation-menu-item__link" :aria-current="isSelected && link ? 'page' : undefined" :tabindex="!isVisible ? -1 : undefined" :inert="!isVisible ? '' : undefined" @click="handleClick" > <div v-if="!nested && hasSlot('icon')" class="b-navigation-menu-item__icon" aria-hidden="true"> <slot name="icon" /> </div> <bento-typography ref="labelRef" v-bento-tooltip-directive="isTruncated ? label : undefined" el="span" variant="body" stronger class="b-navigation-menu-item__label" > {{ label }} </bento-typography> </component> <div v-if="hasSlot('action')" class="b-navigation-menu-item__action"> <slot name="action" /> </div> </li> </template> <script setup lang="ts"> import { computed, inject, onBeforeUnmount, onMounted, ref, useSlots } from 'vue'; import { useResizeObserver } from '@vueuse/core'; import { BentoLink } from '@/components/link'; import { BentoTypography } from '@/components/typography'; import { generateUid } from '@/utils/ts/generate-uid'; import { useHasSlot } from '@/composables'; import { BentoTooltipDirective as vBentoTooltipDirective } from '@/directives/tooltip'; import type { BentoNavigationMenuItemProps } from './navigation-menu-item.types'; import type { BentoNavigationMenuGroupState } from '../navigation-menu-group/navigation-menu-group.internal.types'; import { NAVIGATION_MENU_GROUP_STATE_INJECTION_KEY } from '../navigation-menu-group/navigation-menu-group.keys'; import type { BentoNavigationMenuState } from '../../navigation-menu.internal.types'; import { NAVIGATION_MENU_STATE_INJECTION_KEY } from '../../navigation-menu.keys'; const props = withDefaults(defineProps<BentoNavigationMenuItemProps>(), { nested: false, alwaysShowActions: false, }); const slots = useSlots(); const hasSlot = useHasSlot(slots); const componentType = computed(() => (props.link ? BentoLink : 'div')); const componentProps = computed(() => (props.link ? { ...props.link, disableTypography: true } : {})); const labelRef = ref(null); const isTruncated = ref(false); useResizeObserver(labelRef, () => { const el = labelRef.value?.$el ?? labelRef.value; if (el) { isTruncated.value = el.scrollWidth > el.clientWidth; } }); const itemId = generateUid('navigation-menu-item'); const groupState = inject<BentoNavigationMenuGroupState | null>(NAVIGATION_MENU_GROUP_STATE_INJECTION_KEY, null); const menuState = inject<BentoNavigationMenuState | null>(NAVIGATION_MENU_STATE_INJECTION_KEY, null); const isSelected = computed(() => menuState?.activePage?.value === props.value); const isVisible = computed(() => { if (!groupState) { return true; } if (!groupState.isSemiCollapsed.value) { return true; } return isSelected.value; }); const conditionalClasses = computed(() => ({ 'b-navigation-menu-item--selected': isSelected.value, 'b-navigation-menu-item--nested': props.nested, 'b-navigation-menu-item--hidden': !isVisible.value, 'b-navigation-menu-item--always-show-actions': props.alwaysShowActions, })); onMounted(() => { if (groupState && props.nested) { groupState.registerItem(itemId, () => isSelected.value); } }); const handleClick = () => { menuState?.updateActivePage(props.value); }; onBeforeUnmount(() => { if (groupState && props.nested) { groupState.unregisterItem(itemId); } }); </script> <script lang="ts"> /** * Navigation menu item component for rendering individual navigation links. * Can be used standalone or nested within a navigation-menu-group. * * @usage * import { BentoNavigationMenuItem } from '@adyen/bento-vue2'; * * export default { * components: { BentoNavigationMenuItem }, * template: ` * <bento-navigation-menu-item value="home" label="Home" :link="{ to: '/home' }"> * <template #icon><home-icon /></template> * <template #action><star-icon svg-title="Add to favorites" /></template> * </bento-navigation-menu-item> * ` * } */ export default { name: 'bento-navigation-menu-item', }; </script> <style lang="scss" scoped src="./navigation-menu-item.scss" />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { type Ref } from 'vue'; export interface BentoNavigationMenuEmits { /** * Emits update event when active page is changed */ (e: 'update:active-page', value: string): void; /** * Emits event when expand all button is clicked */ (e: 'expand-all'): void; /** * Emits event when collapse all button is clicked */ (e: 'collapse-all'): void; } export interface BentoNavigationMenuGroupRegistration { id: string; setOpen: (open: boolean) => void; getIsOpen: () => boolean; } export interface BentoNavigationMenuState { registerGroup: (groupId: string, setOpen: (open: boolean) => void, getIsOpen: () => boolean) => void; unregisterGroup: (groupId: string) => void; activePage: Ref<string | undefined>; updateActivePage: (value: string) => void; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import BentoNavigationMenu from './navigation-menu.vue'; import BentoNavigationMenuItem from './components/navigation-menu-item/navigation-menu-item.vue'; import BentoNavigationMenuGroup from './components/navigation-menu-group/navigation-menu-group.vue'; import { BentoButton } from '@/components/button'; import type { Meta, StoryObj } from '@storybook/vue'; import StarIcon from '@adyen/ui-assets-icons-16/vue/star'; import StarFilledIcon from '@adyen/ui-assets-icons-16/vue/star-filled'; import SearchIcon from '@adyen/ui-assets-icons-16/vue/search'; import NavHomeIcon from '@adyen/ui-assets-icons-16/vue/nav-home'; import NavPaymentsIcon from '@adyen/ui-assets-icons-16/vue/nav-payments'; import NavReportsIcon from '@adyen/ui-assets-icons-16/vue/nav-reports'; import NavSettingsIcon from '@adyen/ui-assets-icons-16/vue/nav-settings'; import NavAccountHoldersIcon from '@adyen/ui-assets-icons-16/vue/nav-account-holders'; import { ref } from 'vue'; import { action } from '@storybook/addon-actions'; import { isVue2 } from 'vue-demi'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import NavigationMenuEverythingBagelExample from './__tests__/navigation-menu-everything-bagel-example.vue?raw'; import NavigationMenuSimpleListExample from './__tests__/navigation-menu-simple-list-example.vue?raw'; export default { title: 'Navigation Menu', component: BentoNavigationMenu, argTypes: { default: { control: false, table: { type: { summary: 'Navigation items and groups' }, }, }, headerActions: { control: false, table: { type: { summary: 'Action buttons' }, }, }, }, } as Meta; type Story = StoryObj<typeof BentoNavigationMenu>; export const EverythingBagel: Story = { render: (_args, { argTypes }) => ({ components: { BentoNavigationMenu, BentoNavigationMenuItem, BentoNavigationMenuGroup, BentoButton, StarIcon, StarFilledIcon, SearchIcon, NavHomeIcon, NavPaymentsIcon, NavReportsIcon, NavSettingsIcon, NavAccountHoldersIcon, }, props: Object.keys(argTypes), setup(props) { const activePage = ref('home'); const paymentsExpanded = ref(true); const favorites = ref({}); const toggleFavorite = (value: string) => { favorites.value = { ...favorites.value, [value]: !favorites.value[value] }; }; const onExpandAll = () => action('expand-all')(); const onCollapseAll = () => action('collapse-all')(); return { activePage, paymentsExpanded, favorites, toggleFavorite, onExpandAll, onCollapseAll, args: isVue2 ? props : _args, }; }, template: ` <div style="width: 248px;"> <bento-navigation-menu v-bind="args" :active-page="activePage" @update:active-page="activePage = $event" @expand-all="onExpandAll" @collapse-all="onCollapseAll"> <template #headerActions> <bento-button variant="tertiary-with-background"> <template #iconLeft> <search-icon svg-title="Search" /> </template> </bento-button> </template> <bento-navigation-menu-item value="home" label="Home" :link="{ to: '#home', isNotRouting: true }" > <template #icon> <nav-home-icon /> </template> </bento-navigation-menu-item> <bento-navigation-menu-group label="Payments" :is-expanded="paymentsExpanded" @update:is-expanded="paymentsExpanded = $event" > <template #icon> <nav-payments-icon /> </template> <bento-navigation-menu-item nested value="payments" label="Payments" :link="{ to: '#payments', isNotRouting: true }" :always-show-actions="!!favorites.payments || activePage === 'payments'" > <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('payments')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.payments" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> <bento-navigation-menu-item nested value="preauth" label="Pre-authorized" :link="{ to: '#preauth', isNotRouting: true }" :always-show-actions="!!favorites.preauth || activePage === 'preauth'" > <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('preauth')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.preauth" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> <bento-navigation-menu-item nested value="links" label="Payment links" :link="{ to: '#links', isNotRouting: true }" :always-show-actions="!!favorites.links || activePage === 'links'" > <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('links')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.links" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> <bento-navigation-menu-item nested value="methods" label="Payment methods" :link="{ to: '#methods', isNotRouting: true }" :always-show-actions="!!favorites.methods || activePage === 'methods'" > <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('methods')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.methods" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> </bento-navigation-menu-group> <bento-navigation-menu-group label="Reports" > <template #icon> <nav-reports-icon /> </template> <bento-navigation-menu-item nested value="analytics" label="Analytics" :link="{ to: '#analytics', isNotRouting: true }" :always-show-actions="!!favorites.analytics || activePage === 'analytics'" > <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('analytics')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.analytics" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> <bento-navigation-menu-item nested value="transactions" label="Transactions" :link="{ to: '#transactions', isNotRouting: true }" :always-show-actions="!!favorites.transactions || activePage === 'transactions'" > <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('transactions')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.transactions" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> </bento-navigation-menu-group> <bento-navigation-menu-item value="settings" label="Settings" :link="{ to: '#settings', isNotRouting: true }" :always-show-actions="!!favorites.settings || activePage === 'settings'" > <template #icon> <nav-settings-icon /> </template> <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('settings')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.settings" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> <bento-navigation-menu-item value="profile" label="Profile" :link="{ to: '#profile', isNotRouting: true }" :always-show-actions="!!favorites.profile || activePage === 'profile'" > <template #icon> <nav-account-holders-icon /> </template> <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('profile')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.profile" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> </bento-navigation-menu> </div> `, }), args: { label: 'Pages', showExpandAllButton: true, }, parameters: storybookDocsParameter(NavigationMenuEverythingBagelExample), }; export const SimpleList: Story = { render: (_args, { argTypes }) => ({ components: { BentoNavigationMenu, BentoNavigationMenuItem, StarIcon, }, props: Object.keys(argTypes), setup(props) { const activePage = ref('home'); return { activePage, args: isVue2 ? props : _args }; }, template: ` <div style="width: 248px;"> <bento-navigation-menu v-bind="args" :active-page="activePage" @update:active-page="activePage = $event"> <bento-navigation-menu-item value="home" label="Home" :link="{ to: '#home', isNotRouting: true }" /> <bento-navigation-menu-item value="analytics" label="Analytics" :link="{ to: '#analytics', isNotRouting: true }" /> <bento-navigation-menu-item value="settings" label="Settings" :link="{ to: '#settings', isNotRouting: true }" /> <bento-navigation-menu-item value="profile" label="Profile" :link="{ to: '#profile', isNotRouting: true }" /> </bento-navigation-menu> </div> `, }), args: { label: 'Pages', }, parameters: storybookDocsParameter(NavigationMenuSimpleListExample), };
|
|
1
|
+
import BentoNavigationMenu from './navigation-menu.vue'; import BentoNavigationMenuItem from './components/navigation-menu-item/navigation-menu-item.vue'; import BentoNavigationMenuGroup from './components/navigation-menu-group/navigation-menu-group.vue'; import { BentoButton } from '@/components/button'; import type { Meta, StoryObj } from '@storybook/vue'; import StarIcon from '@adyen/ui-assets-icons-16/vue/star'; import StarFilledIcon from '@adyen/ui-assets-icons-16/vue/star-filled'; import SearchIcon from '@adyen/ui-assets-icons-16/vue/search'; import NavHomeIcon from '@adyen/ui-assets-icons-16/vue/nav-home'; import NavPaymentsIcon from '@adyen/ui-assets-icons-16/vue/nav-payments'; import NavReportsIcon from '@adyen/ui-assets-icons-16/vue/nav-reports'; import NavSettingsIcon from '@adyen/ui-assets-icons-16/vue/nav-settings'; import NavAccountHoldersIcon from '@adyen/ui-assets-icons-16/vue/nav-account-holders'; import { ref } from 'vue'; import { action } from '@storybook/addon-actions'; import { isVue2 } from 'vue-demi'; import { storybookDocsParameter } from '@/utils/ts/storybook'; const NavigationMenuEverythingBagelExample = "<template>\n <div class=\"b-navigation-menu-example\">\n <bento-navigation-menu\n label=\"Pages\"\n show-expand-all-button\n :active-page=\"activePage\"\n @update:active-page=\"activePage = $event\"\n @expand-all=\"onExpandAll\"\n @collapse-all=\"onCollapseAll\"\n >\n <template #headerActions>\n <bento-button variant=\"tertiary-with-background\">\n <template #iconLeft>\n <search-icon svg-title=\"Search\" />\n </template>\n </bento-button>\n </template>\n\n <bento-navigation-menu-item value=\"home\" label=\"Home\" :link=\"{ to: '#home', isNotRouting: true }\">\n <template #icon>\n <nav-home-icon />\n </template>\n </bento-navigation-menu-item>\n\n <bento-navigation-menu-group\n label=\"Payments\"\n :is-expanded=\"paymentsExpanded\"\n @update:is-expanded=\"paymentsExpanded = $event\"\n >\n <template #icon>\n <nav-payments-icon />\n </template>\n\n <bento-navigation-menu-item\n nested\n value=\"payments\"\n label=\"Payments\"\n :link=\"{ to: '#payments', isNotRouting: true }\"\n :always-show-actions=\"!!favorites.payments || activePage === 'payments'\"\n >\n <template #action>\n <bento-button variant=\"tertiary\" @click.stop.prevent=\"toggleFavorite('payments')\">\n <template #iconLeft>\n <star-filled-icon\n v-if=\"favorites.payments\"\n class=\"b-navigation-menu-example__favorite-icon\"\n svg-title=\"Remove from favorites\"\n />\n <star-icon v-else svg-title=\"Add to favorites\" />\n </template>\n </bento-button>\n </template>\n </bento-navigation-menu-item>\n <bento-navigation-menu-item\n nested\n value=\"preauth\"\n label=\"Pre-authorized\"\n :link=\"{ to: '#preauth', isNotRouting: true }\"\n :always-show-actions=\"!!favorites.preauth || activePage === 'preauth'\"\n >\n <template #action>\n <bento-button variant=\"tertiary\" @click.stop.prevent=\"toggleFavorite('preauth')\">\n <template #iconLeft>\n <star-filled-icon\n v-if=\"favorites.preauth\"\n class=\"b-navigation-menu-example__favorite-icon\"\n svg-title=\"Remove from favorites\"\n />\n <star-icon v-else svg-title=\"Add to favorites\" />\n </template>\n </bento-button>\n </template>\n </bento-navigation-menu-item>\n <bento-navigation-menu-item\n nested\n value=\"links\"\n label=\"Payment links\"\n :link=\"{ to: '#links', isNotRouting: true }\"\n :always-show-actions=\"!!favorites.links || activePage === 'links'\"\n >\n <template #action>\n <bento-button variant=\"tertiary\" @click.stop.prevent=\"toggleFavorite('links')\">\n <template #iconLeft>\n <star-filled-icon\n v-if=\"favorites.links\"\n class=\"b-navigation-menu-example__favorite-icon\"\n svg-title=\"Remove from favorites\"\n />\n <star-icon v-else svg-title=\"Add to favorites\" />\n </template>\n </bento-button>\n </template>\n </bento-navigation-menu-item>\n <bento-navigation-menu-item\n nested\n value=\"methods\"\n label=\"Payment methods\"\n :link=\"{ to: '#methods', isNotRouting: true }\"\n :always-show-actions=\"!!favorites.methods || activePage === 'methods'\"\n >\n <template #action>\n <bento-button variant=\"tertiary\" @click.stop.prevent=\"toggleFavorite('methods')\">\n <template #iconLeft>\n <star-filled-icon\n v-if=\"favorites.methods\"\n class=\"b-navigation-menu-example__favorite-icon\"\n svg-title=\"Remove from favorites\"\n />\n <star-icon v-else svg-title=\"Add to favorites\" />\n </template>\n </bento-button>\n </template>\n </bento-navigation-menu-item>\n </bento-navigation-menu-group>\n\n <bento-navigation-menu-group label=\"Reports\">\n <template #icon>\n <nav-reports-icon />\n </template>\n\n <bento-navigation-menu-item\n nested\n value=\"analytics\"\n label=\"Analytics\"\n :link=\"{ to: '#analytics', isNotRouting: true }\"\n :always-show-actions=\"!!favorites.analytics || activePage === 'analytics'\"\n >\n <template #action>\n <bento-button variant=\"tertiary\" @click.stop.prevent=\"toggleFavorite('analytics')\">\n <template #iconLeft>\n <star-filled-icon\n v-if=\"favorites.analytics\"\n class=\"b-navigation-menu-example__favorite-icon\"\n svg-title=\"Remove from favorites\"\n />\n <star-icon v-else svg-title=\"Add to favorites\" />\n </template>\n </bento-button>\n </template>\n </bento-navigation-menu-item>\n <bento-navigation-menu-item\n nested\n value=\"transactions\"\n label=\"Transactions\"\n :link=\"{ to: '#transactions', isNotRouting: true }\"\n :always-show-actions=\"!!favorites.transactions || activePage === 'transactions'\"\n >\n <template #action>\n <bento-button variant=\"tertiary\" @click.stop.prevent=\"toggleFavorite('transactions')\">\n <template #iconLeft>\n <star-filled-icon\n v-if=\"favorites.transactions\"\n class=\"b-navigation-menu-example__favorite-icon\"\n svg-title=\"Remove from favorites\"\n />\n <star-icon v-else svg-title=\"Add to favorites\" />\n </template>\n </bento-button>\n </template>\n </bento-navigation-menu-item>\n </bento-navigation-menu-group>\n\n <bento-navigation-menu-item\n value=\"settings\"\n label=\"Settings\"\n :link=\"{ to: '#settings', isNotRouting: true }\"\n :always-show-actions=\"!!favorites.settings || activePage === 'settings'\"\n >\n <template #icon>\n <nav-settings-icon />\n </template>\n <template #action>\n <bento-button variant=\"tertiary\" @click.stop.prevent=\"toggleFavorite('settings')\">\n <template #iconLeft>\n <star-filled-icon\n v-if=\"favorites.settings\"\n class=\"b-navigation-menu-example__favorite-icon\"\n svg-title=\"Remove from favorites\"\n />\n <star-icon v-else svg-title=\"Add to favorites\" />\n </template>\n </bento-button>\n </template>\n </bento-navigation-menu-item>\n\n <bento-navigation-menu-item\n value=\"profile\"\n label=\"Profile\"\n :link=\"{ to: '#profile', isNotRouting: true }\"\n :always-show-actions=\"!!favorites.profile || activePage === 'profile'\"\n >\n <template #icon>\n <nav-account-holders-icon />\n </template>\n <template #action>\n <bento-button variant=\"tertiary\" @click.stop.prevent=\"toggleFavorite('profile')\">\n <template #iconLeft>\n <star-filled-icon\n v-if=\"favorites.profile\"\n class=\"b-navigation-menu-example__favorite-icon\"\n svg-title=\"Remove from favorites\"\n />\n <star-icon v-else svg-title=\"Add to favorites\" />\n </template>\n </bento-button>\n </template>\n </bento-navigation-menu-item>\n </bento-navigation-menu>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\n import { ref } from 'vue';\n import {\n BentoButton,\n BentoNavigationMenu,\n BentoNavigationMenuGroup,\n BentoNavigationMenuItem,\n } from '@adyen/bento-vue2';\n import StarIcon from '@adyen/ui-assets-icons-16/vue/star';\n import StarFilledIcon from '@adyen/ui-assets-icons-16/vue/star-filled';\n import SearchIcon from '@adyen/ui-assets-icons-16/vue/search';\n import NavHomeIcon from '@adyen/ui-assets-icons-16/vue/nav-home';\n import NavPaymentsIcon from '@adyen/ui-assets-icons-16/vue/nav-payments';\n import NavReportsIcon from '@adyen/ui-assets-icons-16/vue/nav-reports';\n import NavSettingsIcon from '@adyen/ui-assets-icons-16/vue/nav-settings';\n import NavAccountHoldersIcon from '@adyen/ui-assets-icons-16/vue/nav-account-holders';\n\n const activePage = ref('home');\n const paymentsExpanded = ref(true);\n const favorites = ref<Record<string, boolean>>({});\n\n const toggleFavorite = (value: string) => {\n favorites.value = { ...favorites.value, [value]: !favorites.value[value] };\n };\n\n // eslint-disable-next-line no-console\n const onExpandAll = () => console.log('expand-all');\n // eslint-disable-next-line no-console\n const onCollapseAll = () => console.log('collapse-all');\n</script>\n\n<style scoped lang=\"scss\">\n .b-navigation-menu-example {\n width: 248px;\n }\n\n .b-navigation-menu-example__favorite-icon {\n color: var(--b-color-decorative-green);\n }\n</style>\n"; const NavigationMenuSimpleListExample = "<template>\n <div class=\"b-navigation-menu-example\">\n <bento-navigation-menu label=\"Pages\" :active-page=\"activePage\" @update:active-page=\"activePage = $event\">\n <bento-navigation-menu-item value=\"home\" label=\"Home\" :link=\"{ to: '#home', isNotRouting: true }\" />\n <bento-navigation-menu-item\n value=\"analytics\"\n label=\"Analytics\"\n :link=\"{ to: '#analytics', isNotRouting: true }\"\n />\n <bento-navigation-menu-item\n value=\"settings\"\n label=\"Settings\"\n :link=\"{ to: '#settings', isNotRouting: true }\"\n />\n <bento-navigation-menu-item\n value=\"profile\"\n label=\"Profile\"\n :link=\"{ to: '#profile', isNotRouting: true }\"\n />\n </bento-navigation-menu>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\n import { ref } from 'vue';\n import { BentoNavigationMenu, BentoNavigationMenuItem } from '@adyen/bento-vue2';\n\n const activePage = ref('home');\n</script>\n\n<style scoped lang=\"scss\">\n .b-navigation-menu-example {\n width: 248px;\n }\n</style>\n"; export default { title: 'Navigation Menu', component: BentoNavigationMenu, argTypes: { default: { control: false, table: { type: { summary: 'Navigation items and groups' }, }, }, headerActions: { control: false, table: { type: { summary: 'Action buttons' }, }, }, }, } as Meta; type Story = StoryObj<typeof BentoNavigationMenu>; export const EverythingBagel: Story = { render: (_args, { argTypes }) => ({ components: { BentoNavigationMenu, BentoNavigationMenuItem, BentoNavigationMenuGroup, BentoButton, StarIcon, StarFilledIcon, SearchIcon, NavHomeIcon, NavPaymentsIcon, NavReportsIcon, NavSettingsIcon, NavAccountHoldersIcon, }, props: Object.keys(argTypes), setup(props) { const activePage = ref('home'); const paymentsExpanded = ref(true); const favorites = ref({}); const toggleFavorite = (value: string) => { favorites.value = { ...favorites.value, [value]: !favorites.value[value] }; }; const onExpandAll = () => action('expand-all')(); const onCollapseAll = () => action('collapse-all')(); return { activePage, paymentsExpanded, favorites, toggleFavorite, onExpandAll, onCollapseAll, args: isVue2 ? props : _args, }; }, template: ` <div style="width: 248px;"> <bento-navigation-menu v-bind="args" :active-page="activePage" @update:active-page="activePage = $event" @expand-all="onExpandAll" @collapse-all="onCollapseAll"> <template #headerActions> <bento-button variant="tertiary-with-background"> <template #iconLeft> <search-icon svg-title="Search" /> </template> </bento-button> </template> <bento-navigation-menu-item value="home" label="Home" :link="{ to: '#home', isNotRouting: true }" > <template #icon> <nav-home-icon /> </template> </bento-navigation-menu-item> <bento-navigation-menu-group label="Payments" :is-expanded="paymentsExpanded" @update:is-expanded="paymentsExpanded = $event" > <template #icon> <nav-payments-icon /> </template> <bento-navigation-menu-item nested value="payments" label="Payments" :link="{ to: '#payments', isNotRouting: true }" :always-show-actions="!!favorites.payments || activePage === 'payments'" > <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('payments')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.payments" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> <bento-navigation-menu-item nested value="preauth" label="Pre-authorized" :link="{ to: '#preauth', isNotRouting: true }" :always-show-actions="!!favorites.preauth || activePage === 'preauth'" > <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('preauth')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.preauth" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> <bento-navigation-menu-item nested value="links" label="Payment links" :link="{ to: '#links', isNotRouting: true }" :always-show-actions="!!favorites.links || activePage === 'links'" > <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('links')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.links" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> <bento-navigation-menu-item nested value="methods" label="Payment methods" :link="{ to: '#methods', isNotRouting: true }" :always-show-actions="!!favorites.methods || activePage === 'methods'" > <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('methods')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.methods" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> </bento-navigation-menu-group> <bento-navigation-menu-group label="Reports" > <template #icon> <nav-reports-icon /> </template> <bento-navigation-menu-item nested value="analytics" label="Analytics" :link="{ to: '#analytics', isNotRouting: true }" :always-show-actions="!!favorites.analytics || activePage === 'analytics'" > <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('analytics')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.analytics" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> <bento-navigation-menu-item nested value="transactions" label="Transactions" :link="{ to: '#transactions', isNotRouting: true }" :always-show-actions="!!favorites.transactions || activePage === 'transactions'" > <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('transactions')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.transactions" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> </bento-navigation-menu-group> <bento-navigation-menu-item value="settings" label="Settings" :link="{ to: '#settings', isNotRouting: true }" :always-show-actions="!!favorites.settings || activePage === 'settings'" > <template #icon> <nav-settings-icon /> </template> <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('settings')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.settings" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> <bento-navigation-menu-item value="profile" label="Profile" :link="{ to: '#profile', isNotRouting: true }" :always-show-actions="!!favorites.profile || activePage === 'profile'" > <template #icon> <nav-account-holders-icon /> </template> <template #action> <bento-button variant="tertiary" @click.stop.prevent="toggleFavorite('profile')" > <template #iconLeft> <star-filled-icon style="color: var(--b-color-decorative-green);" v-if="favorites.profile" svg-title="Remove from favorites" /> <star-icon v-else svg-title="Add to favorites" /> </template> </bento-button> </template> </bento-navigation-menu-item> </bento-navigation-menu> </div> `, }), args: { label: 'Pages', showExpandAllButton: true, }, parameters: storybookDocsParameter(NavigationMenuEverythingBagelExample), }; export const SimpleList: Story = { render: (_args, { argTypes }) => ({ components: { BentoNavigationMenu, BentoNavigationMenuItem, StarIcon, }, props: Object.keys(argTypes), setup(props) { const activePage = ref('home'); return { activePage, args: isVue2 ? props : _args }; }, template: ` <div style="width: 248px;"> <bento-navigation-menu v-bind="args" :active-page="activePage" @update:active-page="activePage = $event"> <bento-navigation-menu-item value="home" label="Home" :link="{ to: '#home', isNotRouting: true }" /> <bento-navigation-menu-item value="analytics" label="Analytics" :link="{ to: '#analytics', isNotRouting: true }" /> <bento-navigation-menu-item value="settings" label="Settings" :link="{ to: '#settings', isNotRouting: true }" /> <bento-navigation-menu-item value="profile" label="Profile" :link="{ to: '#profile', isNotRouting: true }" /> </bento-navigation-menu> </div> `, }), args: { label: 'Pages', }, parameters: storybookDocsParameter(NavigationMenuSimpleListExample), };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
export interface BentoNavigationMenuProps { /** * Label text for the navigation menu header */ label?: string; /** * Whether to show the expand/collapse all button */ showExpandAllButton?: boolean; /** * The value of the currently active navigation item */ activePage?: string; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<template> <nav class="b-navigation-menu" :aria-labelledby="label ? titleId : undefined"> <div v-if="showHeader" class="b-navigation-menu__header"> <bento-typography v-if="label" :id="titleId" el="p" variant="caption" stronger class="b-navigation-menu__title" > {{ label }} </bento-typography> <div class="b-navigation-menu__actions-container"> <div v-if="hasSlot('headerActions')" class="b-navigation-menu__actions"> <slot name="headerActions" /> </div> <bento-button v-if="computedShowExpandAll" v-bento-tooltip-directive="expandButtonLabel" variant="tertiary-with-background" :aria-label="expandButtonLabel" @click="toggleAllGroups" > <template #iconLeft> <menu-collapse-icon v-if="allExpanded" aria-hidden="true" /> <menu-expand-icon v-else aria-hidden="true" /> </template> </bento-button> </div> </div> <ul class="b-navigation-menu__content"> <slot /> </ul> </nav> </template> <script setup lang="ts"> import { computed, provide, ref, toRef, useSlots } from 'vue'; import { BentoTypography } from '@/components/typography'; import { BentoButton } from '@/components/button'; import MenuCollapseIcon from '@adyen/ui-assets-icons-16/vue/menu-collapse'; import MenuExpandIcon from '@adyen/ui-assets-icons-16/vue/menu-expand'; import { useHasSlot } from '@/composables'; import { BentoTooltipDirective as vBentoTooltipDirective } from '@/directives/tooltip'; import { generateUid } from '@/
|
|
1
|
+
<template> <nav class="b-navigation-menu" :aria-labelledby="label ? titleId : undefined"> <div v-if="showHeader" class="b-navigation-menu__header"> <bento-typography v-if="label" :id="titleId" el="p" variant="caption" stronger class="b-navigation-menu__title" > {{ label }} </bento-typography> <div class="b-navigation-menu__actions-container"> <div v-if="hasSlot('headerActions')" class="b-navigation-menu__actions"> <slot name="headerActions" /> </div> <bento-button v-if="computedShowExpandAll" v-bento-tooltip-directive="expandButtonLabel" variant="tertiary-with-background" :aria-label="expandButtonLabel" @click="toggleAllGroups" > <template #iconLeft> <menu-collapse-icon v-if="allExpanded" aria-hidden="true" /> <menu-expand-icon v-else aria-hidden="true" /> </template> </bento-button> </div> </div> <ul class="b-navigation-menu__content"> <slot /> </ul> </nav> </template> <script setup lang="ts"> import { computed, provide, ref, toRef, useSlots } from 'vue'; import { BentoTypography } from '@/components/typography'; import { BentoButton } from '@/components/button'; import MenuCollapseIcon from '@adyen/ui-assets-icons-16/vue/menu-collapse'; import MenuExpandIcon from '@adyen/ui-assets-icons-16/vue/menu-expand'; import { useHasSlot } from '@/composables'; import { BentoTooltipDirective as vBentoTooltipDirective } from '@/directives/tooltip'; import { generateUid } from '@/utils/ts/generate-uid'; import { useI18n } from '@/utils/ts/i18n'; import type { BentoNavigationMenuProps } from './navigation-menu.types'; import type { BentoNavigationMenuEmits, BentoNavigationMenuGroupRegistration, BentoNavigationMenuState, } from './navigation-menu.internal.types'; import { NAVIGATION_MENU_STATE_INJECTION_KEY } from './navigation-menu.keys'; import messages from './messages.json'; type MessageSchema = (typeof messages)['en-US']; const props = withDefaults(defineProps<BentoNavigationMenuProps>(), { label: undefined, showExpandAllButton: false, activePage: undefined, }); const emit = defineEmits<BentoNavigationMenuEmits>(); const slots = useSlots(); const hasSlot = useHasSlot(slots); const titleId = generateUid('navigation-menu-title'); const { t } = useI18n<{ message: MessageSchema }>({ messages }); const groups = ref<Array<BentoNavigationMenuGroupRegistration>>([]); const registerGroup = (groupId: string, setOpen: (open: boolean) => void, getIsOpen: () => boolean) => { groups.value.push({ id: groupId, setOpen, getIsOpen }); }; const unregisterGroup = (groupId: string) => { groups.value = groups.value.filter(g => g.id !== groupId); }; const allExpanded = computed(() => groups.value.length > 0 && groups.value.every(group => group.getIsOpen())); const computedShowExpandAll = computed(() => groups.value.length > 0 && props.showExpandAllButton); const showHeader = computed(() => props.label || hasSlot('headerActions') || computedShowExpandAll.value); const expandButtonLabel = computed(() => (allExpanded.value ? t('hideAllPages') : t('showAllPages'))); const toggleAllGroups = () => { const shouldExpand = !allExpanded.value; groups.value.forEach(({ setOpen }) => setOpen(shouldExpand)); if (shouldExpand) { emit('expand-all'); } else { emit('collapse-all'); } }; const updateActivePage = (value: string) => { emit('update:active-page', value); }; provide<BentoNavigationMenuState>(NAVIGATION_MENU_STATE_INJECTION_KEY, { registerGroup, unregisterGroup, activePage: toRef(props, 'activePage'), updateActivePage, }); </script> <script lang="ts"> /** * Navigation menu container component with optional header and action buttons. * * @usage * import { BentoNavigationMenu, BentoNavigationMenuItem, BentoNavigationMenuGroup } from '@adyen/bento-vue2'; * * export default { * components: { BentoNavigationMenu, BentoNavigationMenuItem, BentoNavigationMenuGroup }, * template: ` * <bento-navigation-menu label="Pages" active-page="home"> * <template #headerActions> * <button>Search</button> * </template> * <bento-navigation-menu-item value="home" label="Home" :link="{ to: '/home' }"> * <template #icon><home-icon /></template> * </bento-navigation-menu-item> * <bento-navigation-menu-group label="Settings"> * <template #icon><folder-icon /></template> * <bento-navigation-menu-item nested value="general" label="General" :link="{ to: '/settings/general' }" /> * </bento-navigation-menu-group> * </bento-navigation-menu> * ` * } */ export default { i18n: { messages }, name: 'bento-navigation-menu', }; </script> <style lang="scss" scoped src="./navigation-menu.scss" />
|
package/dist/assets/components/pagination/components/pagination-context/pagination-context.vue
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<template> <div class="b-pagination-context"> <bento-typography v-if="totalPages > 1 && !hidePageSelection" el="div"> <component :is="i18nComponent" v-bind="getI18nProps('pageNumber')" tag="div"> <template #page> <bento-dropdown :id="dropdownId" :aria-label="t('pageNumber', { page: n(page) })" class="b-pagination-context__dropdown" condensed :items="listOfAvailablePages" :model-value="page" :virtual-scroll="virtualScroll" @update:model-value="onPageSelectChange" /> </template> </component> </bento-typography> <bento-typography v-else-if="showPageNumberOfTotal" el="span"> {{ t('pageNumberOfTotal', { page: n(page), totalPages: n(totalPages) }) }} </bento-typography> <bento-typography v-else el="span"> {{ t('pageNumber', { page: n(page) }) }} </bento-typography> </div> </template> <script setup lang="ts"> import { computed } from 'vue'; import { BentoTypography } from '@/components/typography'; import { BentoDropdown } from '@/components/dropdown'; import { type BentoListboxOptionItem } from '@/types/listbox'; import { generateUid } from '@/
|
|
1
|
+
<template> <div class="b-pagination-context"> <bento-typography v-if="totalPages > 1 && !hidePageSelection" el="div"> <component :is="i18nComponent" v-bind="getI18nProps('pageNumber')" tag="div"> <template #page> <bento-dropdown :id="dropdownId" :aria-label="t('pageNumber', { page: n(page) })" class="b-pagination-context__dropdown" condensed :items="listOfAvailablePages" :model-value="page" :virtual-scroll="virtualScroll" @update:model-value="onPageSelectChange" /> </template> </component> </bento-typography> <bento-typography v-else-if="showPageNumberOfTotal" el="span"> {{ t('pageNumberOfTotal', { page: n(page), totalPages: n(totalPages) }) }} </bento-typography> <bento-typography v-else el="span"> {{ t('pageNumber', { page: n(page) }) }} </bento-typography> </div> </template> <script setup lang="ts"> import { computed } from 'vue'; import { BentoTypography } from '@/components/typography'; import { BentoDropdown } from '@/components/dropdown'; import { type BentoListboxOptionItem } from '@/types/listbox'; import { generateUid } from '@/utils/ts/generate-uid'; import messages from './messages.json'; import { getI18nComponent, getI18nProps, useI18n } from '@/utils/ts/i18n'; type MessageSchema = (typeof messages)['en-US']; const props = withDefaults( defineProps<{ /** * Hides the page selection dropdown and displays a static "Page X of Y" text instead. * Useful for very large datasets where rendering all page options would cause performance issues. */ hidePageSelection?: boolean; /** * The current page number of the pager. */ page?: number; /** * The total number of items the pager is paging through. */ totalPages?: number; /** * Enables virtual scrolling on all dropdowns if set to true. */ virtualScroll?: boolean; }>(), { hidePageSelection: false, page: 1, totalPages: null, virtualScroll: false, } ); const emit = defineEmits<{ (e: 'page-selected', value: string | number); }>(); const { t, n } = useI18n<{ message: MessageSchema }>({ messages }); const dropdownId = generateUid('bento-pagination-context-current-page'); const onPageSelectChange = (selectedPage: string | number) => emit('page-selected', selectedPage); const i18nComponent = getI18nComponent(); // Generate a list of pages from 1 to "totalPages" const transformIntoOption = (value: number): BentoListboxOptionItem => ({ label: n(value), value, }); const transformToPageNumber = (_, index) => index + 1; const listOfAvailablePages = computed(() => Array.from(new Array(props.totalPages), transformToPageNumber).map(transformIntoOption) ); const showPageNumberOfTotal = computed( () => props.totalPages === 1 || (props.hidePageSelection && props.page <= props.totalPages) ); </script> <script lang="ts"> export default { i18n: { messages }, }; </script> <style lang="scss" scoped src="./pagination-context.scss" />
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<template> <div class="b-pagination-results-per-page"> <bento-typography el="div"> <component :is="i18nComponent" v-bind="getI18nProps(translationPathKey)" class="b-pagination-results-per-page__dropdown-container" tag="div" :plural="totalCount" > <template v-if="hidePageSizeSelection" #itemCount>{{ itemsPerPage }}</template> <template v-else #itemCount> <bento-dropdown :id="dropdownId" :aria-label="t(translationPathKey, { itemCount: itemsPerPage, totalCount })" class="b-pagination-results-per-page__dropdown" condensed :items="predefinedDropdownOptions" :model-value="itemsPerPage" @update:model-value="onSelectChange" /> </template> <template v-if="!!totalCount" #totalCount>{{ totalCount }}</template> </component> </bento-typography> </div> </template> <script setup lang="ts"> import { computed, watch } from 'vue'; import { BentoTypography } from '@/components/typography'; import { BentoDropdown } from '@/components/dropdown'; import { generateUid } from '@/
|
|
1
|
+
<template> <div class="b-pagination-results-per-page"> <bento-typography el="div"> <component :is="i18nComponent" v-bind="getI18nProps(translationPathKey)" class="b-pagination-results-per-page__dropdown-container" tag="div" :plural="totalCount" > <template v-if="hidePageSizeSelection" #itemCount>{{ itemsPerPage }}</template> <template v-else #itemCount> <bento-dropdown :id="dropdownId" :aria-label="t(translationPathKey, { itemCount: itemsPerPage, totalCount })" class="b-pagination-results-per-page__dropdown" condensed :items="predefinedDropdownOptions" :model-value="itemsPerPage" @update:model-value="onSelectChange" /> </template> <template v-if="!!totalCount" #totalCount>{{ totalCount }}</template> </component> </bento-typography> </div> </template> <script setup lang="ts"> import { computed, watch } from 'vue'; import { BentoTypography } from '@/components/typography'; import { BentoDropdown } from '@/components/dropdown'; import { generateUid } from '@/utils/ts/generate-uid'; import { getI18nComponent, getI18nProps, useI18n } from '@/utils/ts/i18n'; import { printDevelopmentWarning } from '@/utils/ts/print-development-warning'; import messages from './messages.json'; type MessageSchema = (typeof messages)['en-US']; const { t, n } = useI18n<{ message: MessageSchema }>({ messages }); const props = withDefaults( defineProps<{ /** * Determines whether to hide the dropdown that allows users to change the number of results per page. * When set to `true`, the current `itemsPerPage` value is displayed as plain static text. */ hidePageSizeSelection?: boolean; /** * The amount of items the pager is paging through. */ itemsPerPage?: number; /** * The total number of items the pager is paging through. */ totalCount?: number; /** * The predefined options for the results per page dropdown. */ pageSizeItems?: Array<number>; }>(), { hidePageSizeSelection: false, itemsPerPage: 50, totalCount: null, pageSizeItems: () => [10, 20, 50, 75, 100], } ); const emit = defineEmits<{ (e: 'select', value: number); }>(); const isValid = computed( () => Array.isArray(props.pageSizeItems) && props.pageSizeItems.every(option => Number.isInteger(option)) ); watch( isValid, valid => { if (!valid) { printDevelopmentWarning('BentoPagination: pageSizeItems must be an array of integers.'); } }, { immediate: true } ); const dropdownId = generateUid('b-pagination-context-number-elements'); const predefinedDropdownOptions = computed(() => props.pageSizeItems.map(option => ({ label: n(option), value: option, })) ); const i18nComponent = getI18nComponent(); const onSelectChange = (selectedNumberOfResults: number) => { emit('select', selectedNumberOfResults); }; const translationPathKey = computed(() => (props.totalCount ? 'showingItemsWithTotal' : 'showingItems')); </script> <script lang="ts"> export default { i18n: { messages }, }; </script> <style lang="scss" scoped src="./pagination-results-per-page.scss" />
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import { action } from '@storybook/addon-actions'; import { BentoPagination } from '@/components/pagination'; import { reactive, watch } from 'vue'; import { isVue2 } from 'vue-demi'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import type { Meta, StoryObj } from '@storybook/vue'; import './pagination.stories.scss?module'; // Override viewports const INITIAL_VIEWPORTS = { cellphone: { name: 'Cellphone', styles: { height: '812px', width: '375px', }, type: 'mobile', }, tablet: { name: 'Tablet', styles: { height: '360px', width: '640px', }, type: 'tablet', }, }; const meta: Meta = { title: 'Pagination', component: BentoPagination, parameters: { viewport: { viewports: INITIAL_VIEWPORTS, }, }, argTypes: { // Enum size: { control: { disable: true } }, page: { control: { disable: true } }, // Event 'items-page': { table: { type: { summary: '(itemsPerPage: number) => void' }, }, control: { disable: true }, }, navigate: { table: { type: { summary: '(pageNumber: number, size?: number) => void' }, }, control: { disable: true }, }, 'update:page': { table: { type: { summary: '(pageNumber: number) => void' }, }, control: { disable: true }, }, 'update:size': { table: { type: { summary: '(itemsPerPage: number) => void' }, }, control: { disable: true }, }, // Slots default: { control: { type: 'text' }, }, }, }; export default meta; type Story = StoryObj<typeof BentoPagination>;
|
|
1
|
+
import { action } from '@storybook/addon-actions'; import { BentoPagination } from '@/components/pagination'; import { reactive, watch } from 'vue'; import { isVue2 } from 'vue-demi'; import { storybookDocsParameter } from '@/utils/ts/storybook'; import type { Meta, StoryObj } from '@storybook/vue'; const PaginationAdvancedExample = "<template>\n <bento-pagination has-next :size=\"pageData.size\" :page=\"pageData.page\" :total-count=\"100\" @navigate=\"navigate\" />\n</template>\n\n<script lang=\"ts\" setup>\n import { reactive } from 'vue';\n import { BentoPagination } from '@adyen/bento-vue2';\n\n const pageData = reactive({ page: 2, size: 20 });\n const navigate = (page: number, size = pageData.size) => {\n pageData.page = page;\n pageData.size = size;\n };\n</script>\n"; const PaginationDefaultExample = "<template>\n <bento-pagination has-next :size=\"pageData.size\" :page=\"pageData.page\" @navigate=\"navigate\" />\n</template>\n\n<script lang=\"ts\" setup>\n import { reactive } from 'vue';\n import { BentoPagination } from '@adyen/bento-vue2';\n\n const pageData = reactive({ page: 2, size: 20 });\n const navigate = (page: number, size = pageData.size) => {\n pageData.page = page;\n pageData.size = size;\n };\n</script>\n"; import './pagination.stories.scss?module'; // Override viewports const INITIAL_VIEWPORTS = { cellphone: { name: 'Cellphone', styles: { height: '812px', width: '375px', }, type: 'mobile', }, tablet: { name: 'Tablet', styles: { height: '360px', width: '640px', }, type: 'tablet', }, }; const meta: Meta = { title: 'Pagination', component: BentoPagination, parameters: { viewport: { viewports: INITIAL_VIEWPORTS, }, }, argTypes: { // Enum size: { control: { disable: true } }, page: { control: { disable: true } }, // Event 'items-page': { table: { type: { summary: '(itemsPerPage: number) => void' }, }, control: { disable: true }, }, navigate: { table: { type: { summary: '(pageNumber: number, size?: number) => void' }, }, control: { disable: true }, }, 'update:page': { table: { type: { summary: '(pageNumber: number) => void' }, }, control: { disable: true }, }, 'update:size': { table: { type: { summary: '(itemsPerPage: number) => void' }, }, control: { disable: true }, }, // Slots default: { control: { type: 'text' }, }, }, }; export default meta; type Story = StoryObj<typeof BentoPagination>; export const Default: Story = { render: (_args, { argTypes }) => ({ components: { BentoPagination }, props: Object.keys(argTypes), setup(props) { const pageData = reactive({ page: 2, size: 20 }); const clickNavigate = (page: number, size: number) => { action('navigate')(page, size); pageData.page = page; pageData.size = size; }; const updateItemsPerPage = (size: number) => { action('items-page')(size); }; watch([() => pageData.page, () => pageData.size], () => { action('watch-make-api-call')(pageData); }); return { // Values args: isVue2 ? props : _args, pageData, // Methods clickNavigate, updateItemsPerPage, }; }, template: ` <div class="b-pagination-story"> <bento-pagination v-bind="args" :size="pageData.size" :page="pageData.page" @navigate="clickNavigate" @items-page="updateItemsPerPage" > <template v-if="args.default">{{ args.default }}</template> </bento-pagination> </div> `, }), args: { hasNext: true, }, parameters: storybookDocsParameter(PaginationDefaultExample), }; export const Advanced: Story = { ...Default, args: { hasNext: true, size: 20, totalCount: 100, }, parameters: storybookDocsParameter(PaginationAdvancedExample), };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export interface BentoPaginationProps { /** *
|
|
1
|
+
export interface BentoPaginationProps { /** * Use to determine if the pager has a "next page". */ hasNext?: boolean; /** * Hides the "navigate to the first page" and "navigate to the last page" buttons. * Useful for cursor-based pagination, where jumping directly to the first or last page is not supported. */ hideFirstLastPageButtons?: boolean; /** * Toggles the visibility of the "results per page" part of the pagination component. */ hidePageSize?: boolean; /** * Hides the page selection dropdown and displays a static "Page X of Y" text instead. * Useful for very large datasets where rendering all page options would cause performance issues. */ hidePageSelection?: boolean; /** * Determines whether to hide the dropdown that allows users to change the number of results per page. * When set to `true`, the current `itemsPerPage` value is displayed as plain static text. * This prop only takes effect if `hidePageSize` is `false`. */ hidePageSizeSelection?: boolean; /** * The current page number of the pager. */ page?: number; /** * The size of the items the pager is paging through. */ size?: number; /** * The total number of items the pager is paging through. */ totalCount?: number; /** * Enables virtual scrolling on all dropdowns if set to true. */ virtualScroll?: boolean; /** * The predefined list of numeric options available in the 'results per page' selection dropdown. */ pageSizeItems?: Array<number>; }
|