UNPKG

@gitlab/ui

Version:
575 lines (548 loc) • 15.5 kB
import iconSpriteInfo from '@gitlab/svgs/dist/icons.json'; import GlAvatar from '../avatar/avatar.vue'; import GlIcon from '../icon/icon.vue'; import GlButton from '../button/button.vue'; import GlSearchBoxByType from '../search_box_by_type/search_box_by_type.vue'; import { buttonCategoryOptions, buttonSizeOptions, dropdownVariantOptions, } from '../../../utils/constants'; import GlDropdownDivider from './dropdown_divider.vue'; import GlDropdownSectionHeader from './dropdown_section_header.vue'; import GlDropdownItem from './dropdown_item.vue'; import GlDropdownText from './dropdown_text.vue'; import GlDropdownForm from './dropdown_form.vue'; import GlDropdown from './dropdown.vue'; import readme from './dropdown.md'; const components = { GlAvatar, GlIcon, GlDropdown, GlDropdownDivider, GlDropdownSectionHeader, GlDropdownItem, GlDropdownText, GlDropdownForm, }; function addClass(component) { component.$el.querySelectorAll('.btn').forEach((el) => el.classList.add('gl-button')); } const defaultValue = (prop) => GlDropdown.props[prop].default; const generateProps = ({ headerText = defaultValue('headerText'), hideHeaderBorder = defaultValue('hideHeaderBorder'), showClearAll = defaultValue('showClearAll'), clearAllText = defaultValue('clearAllText'), clearAllTextClass = defaultValue('clearAllTextClass'), text = defaultValue('text'), showHighlightedItemsTitle = defaultValue('showHighlightedItemsTitle'), highlightedItemsTitle = defaultValue('highlightedItemsTitle'), highlightedItemsTitleClass = defaultValue('highlightedItemsTitleClass'), textSrOnly = defaultValue('textSrOnly'), split = defaultValue('split'), category = defaultValue('category'), variant = defaultValue('variant'), size = defaultValue('size'), icon = defaultValue('icon'), block = defaultValue('block'), disabled = defaultValue('disabled'), loading = defaultValue('loading'), toggleClass = defaultValue('toggleClass'), right = defaultValue('right'), } = {}) => ({ headerText, hideHeaderBorder, showClearAll, clearAllText, clearAllTextClass, text, showHighlightedItemsTitle, highlightedItemsTitle, highlightedItemsTitleClass, textSrOnly, split, category, variant, size, icon, block, disabled, loading, toggleClass, right, }); const withContainer = (template, containerHeight = 150) => ` <div style="height: ${containerHeight}px;"> ${template} </div>`; function wrap(template, containerHeight, cssClass) { return withContainer( ` <gl-dropdown ref="dropdown" :category="category" :variant="variant" :size="size" :block="block" :disabled="disabled" :text="text" :text-sr-only="textSrOnly" :icon="icon" :split="split" :toggle-class="toggleClass" :header-text="headerText" :hide-header-border="hideHeaderBorder" :show-clear-all="showClearAll" :clear-all-text="clearAllText" :clear-all-text-class="clearAllTextClass" :show-highlighted-items-title="showHighlightedItemsTitle" :highlighted-items-title="highlightedItemsTitle" :highlighted-items-title-class="highlightedItemsTitleClass" :loading="loading" :right="right" class="${cssClass}" > ${template} </gl-dropdown>`, containerHeight ); } function clickDropdown(component) { component.$nextTick(() => component.$el.querySelector('.dropdown-toggle').click()); } export const Default = (_args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap( ` <gl-dropdown-item>First item</gl-dropdown-item> <gl-dropdown-item>Second item</gl-dropdown-item> <gl-dropdown-item>Third item</gl-dropdown-item> <gl-dropdown-item>Fourth item</gl-dropdown-item> <gl-dropdown-item>Fifth item</gl-dropdown-item> <gl-dropdown-item>Sixth item</gl-dropdown-item> <gl-dropdown-item>Seventh item</gl-dropdown-item> <gl-dropdown-item>Eighth item</gl-dropdown-item> <gl-dropdown-item>Ninth item</gl-dropdown-item> <gl-dropdown-item>Tenth item</gl-dropdown-item> <gl-dropdown-item>Eleventh item</gl-dropdown-item>`, 340 ), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); Default.args = generateProps({ text: 'Some dropdown' }); export const Secondary = (_args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap(` <gl-dropdown-item>First item</gl-dropdown-item> <gl-dropdown-item>Second item</gl-dropdown-item> <gl-dropdown-item>Third item</gl-dropdown-item>`), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); Secondary.args = generateProps({ text: 'Some dropdown', category: buttonCategoryOptions.secondary, variant: dropdownVariantOptions.confirm, }); export const WithForm = (_args, { argTypes }) => ({ props: Object.keys(argTypes), components: { ...components, GlButton }, template: wrap(` <gl-dropdown-form class="gl-px-4"> <gl-button>One</gl-button> <gl-button>Two</gl-button> <gl-button>Three</gl-button> </gl-dropdown-form>`), mounted() { clickDropdown(this); }, }); WithForm.args = generateProps({ text: 'Some dropdown' }); export const WithDivider = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap( ` <gl-dropdown-item>First item</gl-dropdown-item> <gl-dropdown-item>Second item</gl-dropdown-item> <gl-dropdown-divider /> <gl-dropdown-item>Third item</gl-dropdown-item> <gl-dropdown-item>Fourth item</gl-dropdown-item>`, 200 ), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); WithDivider.args = generateProps({ text: 'Some dropdown' }); export const WithHeaderAndFooter = (args, { argTypes }) => ({ props: Object.keys(argTypes), components: { ...components, GlSearchBoxByType }, template: wrap( ` <template #header> <gl-search-box-by-type /> </template> <gl-dropdown-item>First item</gl-dropdown-item> <gl-dropdown-item>Second item</gl-dropdown-item> <gl-dropdown-item>Third item</gl-dropdown-item> <gl-dropdown-item>Fourth item</gl-dropdown-item> <gl-dropdown-item>Fifth item</gl-dropdown-item> <gl-dropdown-item>Sixth item</gl-dropdown-item> <gl-dropdown-item>Seventh item</gl-dropdown-item> <gl-dropdown-item>Eighth item</gl-dropdown-item> <template #footer> <gl-dropdown-item>First footer item</gl-dropdown-item> <gl-dropdown-item>Second footer item</gl-dropdown-item> </template>`, 340 ), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); WithHeaderAndFooter.args = generateProps({ text: 'Some dropdown', headerText: 'Header', hideHeaderBorder: true, }); export const WithSectionHeader = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap( ` <gl-dropdown-section-header>Header title</gl-dropdown-section-header> <gl-dropdown-item>First item</gl-dropdown-item> <gl-dropdown-item>Second item</gl-dropdown-item> <gl-dropdown-section-header>I am a really long header title which should wrap</gl-dropdown-section-header> <gl-dropdown-item>Third item</gl-dropdown-item> <gl-dropdown-item>Fourth item</gl-dropdown-item>`, 300 ), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); WithSectionHeader.args = generateProps({ text: 'Some dropdown' }); export const WithCheckedItems = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap(` <gl-dropdown-item :is-check-item="true" :is-checked="true">Checked item</gl-dropdown-item> <gl-dropdown-item :is-check-item="true">Unchecked item</gl-dropdown-item>`), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); WithCheckedItems.args = generateProps({ text: 'Some dropdown' }); export const WithAvatarAndSecondaryText = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap(` <gl-dropdown-item avatar-url="./img/avatar.png" secondary-text="@sytses" > Sid Sijbrandij </gl-dropdown-item>`), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); WithAvatarAndSecondaryText.args = generateProps({ text: 'Some dropdown' }); export const WithIcons = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap( ` <gl-dropdown-item icon-color="info" icon-name="status_running" icon-right-name="retry" icon-right-aria-label="Retry" > Status running </gl-dropdown-item> <gl-dropdown-item icon-color="success" icon-name="status_success" icon-right-name="cancel" icon-right-aria-label="Cancel" > Status success </gl-dropdown-item> <gl-dropdown-item icon-color="warning" icon-name="status_warning" icon-right-name="cancel" icon-right-aria-label="Cancel" > Status warning </gl-dropdown-item> <gl-dropdown-item icon-color="danger" icon-name="status_failed" icon-right-name="cancel" icon-right-aria-label="Cancel" > Status failed </gl-dropdown-item> <gl-dropdown-item icon-name="status_manual" icon-right-name="cancel" icon-right-aria-label="Cancel" > Status manual </gl-dropdown-item>`, 200 ), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); WithIcons.args = generateProps({ text: 'Some dropdown' }); export const FullWidth = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap(` <gl-dropdown-item>First item</gl-dropdown-item> <gl-dropdown-item>Second item</gl-dropdown-item> <gl-dropdown-item>Last item</gl-dropdown-item>`), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); FullWidth.args = generateProps({ text: 'Some dropdown', block: true }); export const WithShortTextAndWideWidth = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: withContainer(` <gl-dropdown text="Some dropdown" :category="category" :variant="variant" :size="size" :block="block" :disabled="disabled" style="width: 300px;" > <gl-dropdown-item>First item</gl-dropdown-item> <gl-dropdown-item>Last item</gl-dropdown-item> </gl-dropdown>`), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); WithShortTextAndWideWidth.args = generateProps(); export const WithLongTextAndNarrowWidth = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: withContainer(` <gl-dropdown text="Truncated text dropdown" :category="category" :variant="variant" :size="size" :block="block" :disabled="disabled" style="width: 160px;" > <gl-dropdown-item>First item</gl-dropdown-item> <gl-dropdown-item>Last item</gl-dropdown-item> </gl-dropdown>`), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); WithLongTextAndNarrowWidth.args = generateProps({ block: true }); export const WithItemTextThatDoesNotWrap = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap(` <gl-dropdown-item icon-right-name="star" icon-right-aria-label="Some action"> Normal item </gl-dropdown-item> <gl-dropdown-item icon-right-name="star" icon-right-aria-label="Some action"> <div class="gl-text-truncate">ellipsis/should/truncate/this/item</div> </gl-dropdown-item>`), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); WithItemTextThatDoesNotWrap.args = generateProps({ text: 'Some dropdown' }); export const IconOnly = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap(` <gl-dropdown-item>First item</gl-dropdown-item> <gl-dropdown-item>Second item</gl-dropdown-item> <gl-dropdown-item>Last item</gl-dropdown-item>`), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); IconOnly.args = generateProps({ icon: 'ellipsis_v', text: 'More actions', textSrOnly: true }); export const WithLoadingState = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap(` <gl-dropdown-item>First item</gl-dropdown-item> <gl-dropdown-item>Last item</gl-dropdown-item>`), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); WithLoadingState.args = generateProps({ text: 'Some dropdown', loading: true }); export const WithClearAll = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap(` <gl-dropdown-item :is-check-item="true" :is-checked="true">First item</gl-dropdown-item> <gl-dropdown-item :is-check-item="true" :is-checked="true">Second item</gl-dropdown-item> <gl-dropdown-item :is-check-item="true" :is-checked="true">Third item</gl-dropdown-item>`), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); WithClearAll.args = generateProps({ text: 'Some dropdown', showClearAll: true, clearAllText: 'Clear all', clearAllTextClass: 'gl-px-5', }); export const WithHighlightedItems = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap( ` <template #highlighted-items> <gl-dropdown-item :is-check-item="true" :is-checked="true">First item</gl-dropdown-item> <gl-dropdown-item :is-check-item="true" :is-checked="true">Second item</gl-dropdown-item> </template> <gl-dropdown-item>Third item</gl-dropdown-item> <gl-dropdown-item>Fourth item</gl-dropdown-item> `, 200 ), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); WithHighlightedItems.args = generateProps({ text: 'Some dropdown', showHighlightedItemsTitle: true, highlightedItemsTitle: 'Highlights', highlightedItemsTitleClass: 'gl-px-5', }); export const OnRightEdge = (args, { argTypes }) => ({ props: Object.keys(argTypes), components, template: wrap( ` <gl-dropdown-item>First item</gl-dropdown-item> <gl-dropdown-item>Second item</gl-dropdown-item> <gl-dropdown-item>Third item</gl-dropdown-item> <gl-dropdown-item>Fourth item</gl-dropdown-item> `, 200, 'gl-display-block gl-text-right' ), mounted() { clickDropdown(this); }, updated() { addClass(this); }, }); OnRightEdge.args = generateProps({ text: 'Some dropdown' }); export default { title: 'base/dropdown/deprecated', component: GlDropdown, subcomponents: { GlDropdownDivider, GlDropdownForm, GlDropdownItem, GlDropdownSectionHeader, GlDropdownText, }, parameters: { bootstrapComponent: 'b-dropdown', docs: { description: { component: readme, }, }, }, argTypes: { category: { options: Object.keys(buttonCategoryOptions), control: 'select', }, variant: { options: Object.keys(dropdownVariantOptions), control: 'select', }, size: { options: Object.keys(buttonSizeOptions), control: 'select', }, icon: { options: iconSpriteInfo.icons, control: 'select', }, }, };