UNPKG

@mekari/mekari-ui-vue

Version:

--- General web components in Mekari. The components are made using vue.js as its framework. Styling of components on Mekari UI Vue uses [Mekari UI Toolkit](https://bitbucket.org/mid-kelola-indonesia/mekari-ui-toolkit/src/master/). Don't forget to import

305 lines (269 loc) 9.28 kB
import { Meta, Story, Canvas, ArgsTable, Anchor } from '@storybook/addon-docs/blocks'; import { action } from '@storybook/addon-actions'; import DropdownIntroduction from './content/DropdownIntroduction.mdx'; import { MDropdown, MDropdownItem, MDropdownMenu, MDropdownSearch, MDropdownTrigger, MIcon, MButton, MButtonGroup } from '@/src'; import { modifiedParameters, argTypesDefault, } from './config'; import { TemplateDefaultString, TemplateMultilevelString, TemplateDefault, TemplateMultiLevel, } from './config/template.js'; <Meta title="Dropdown" component={MDropdown} /> # Dropdown <DropdownIntroduction /> <Anchor storyId="dropdown--default-story"></Anchor> export const DefaultSlots = (args) => ({ components: { MDropdown, MDropdownItem, }, template: ` <m-dropdown placement="right-end" > <m-dropdown-item> Item 1 </m-dropdown-item> </m-dropdown> ` }) ## Slots This Dropdown component rely heavily on its slots. You can custom it based on your needs. Here is the slots that can be used: ### default Slot `#default`: For simple dropdown components, you can just list your items inside the default slots. Here is the example: <Canvas> <Story name="example-dropdown-slots" > {DefaultSlots.bind({})} </Story> </Canvas> ### menu-${number} Slot `#menu-${number}`: Dropdown components support for nested dropdown. You can place the level of your dropdown in slots `#menu-${number}`. The number indicates the level of dropdown starting from 1. On this scoped slot, you can have data and function like: - `content`: Basically it is Array of item of your dropdown. Indicates the `content` of its level. Example: content on level 1, must be placed on menu-1. - `setItemAction`: The item on the menu supposed to have some kind of action. This function will bridge the item's actoin in slot inside `#menu-${number}` with root of dropdown component. This action will also emit the `selected-item` to root of dropdown component if you give permission to do so. For example: if you want the item to have click action, you can just use `@click="setItemAction(content, menuNumber, $event, options)"`. - `item`: Object with keys: `{id, content, disabled, children, checked}`. Basically, it is the item object that you have selected. - `menuNumber`: Number of menu where the item is located. For example: 1, if the slot name is `#menu-1`. - `$event`: Event of action on dropdown item. If you click the dropdown item, then the event click will be used. - `options`: The additional parameter to make the action can behave as expected. The options are: - `isSelectingItem`: If set `true`, after the action will emit `selected-dropdown` to root of Dropdown component. With this, you can further give the action what will you do after `selected-dropdown`. - `isHiddenAfterAction`: If set `true`, after the action on the item fired, the Dropdown Menu will be hidden. - `menuNumber`: The `menuNumber` that will be used in `setItemAction` as second paremeter, and will help to mark the visibility of menu. - `activeItemId`: Act as flag whether current item is active or not. This data helps to add styling on some active state. - `isChildrenActive`: Act as flag whther the children of current item is active or not. This data helps to add styling on some active state. The component example can be seen on Multi Level Dropdown Component section. ### dropdown-trigger Slot `#dropdown-trigger`: The dropdown trigger on Dropdown component can be customized to follow your needs. The default dropdown trigger is a Button with caret just like in default slot example above. For the customized version of dropdown trigger can be seen on Default Dropdown and Multi Level Dropdown sections. ## Plugin ### Directive The is some of dropdown directive in Dropdown plugin. Here is the list: - `v-dropdown-mouseleave`: This directive will set the data or props of `toggleShowDropdown` to `false` when the element fire `mouseleave` event. - `v-dropdown-mouseout`: This directive will set the data or props of `toggleShowDropdown` to `false` when the element fire `mouseout` event. - `v-dropdown-click`: This directive will set the data or props of `toggleShowDropdown` to `true` when the element fire `click` event. - `v-dropdown-mousedown`: This directive will set the data or props of `toggleShowDropdown` to `true` when the element fire `mousedown` event. - `v-dropdown-mouseover`: This directive will set the data or props of `toggleShowDropdown` to `true` when the element fire `mouseover` event. - `v-dropdown-mouseenter`: This directive will set the data or props of `toggleShowDropdown` to `true` when the element fire `mouseenter` event. export const HoverTrigger = (args) => ({ data: () => ({ toggleShowDropdown: false, }), components: { MDropdown, MDropdownItem, MButton, MButtonGroup, MIcon }, template: ` <m-dropdown class="mb-4" :dropdown-distance="0" :toggle-show-dropdown="toggleShowDropdown" @blur-dropdown="toggleShowDropdown = false" v-dropdown-mouseleave > <template #dropdown-trigger> <m-button class="btn-with-icon px-2" v-dropdown-mouseover > <m-icon variant="dropdown" /> </m-button> </template> <m-dropdown-item> Item 1 </m-dropdown-item> </m-dropdown> ` }) export const HoverTriggerString = ` data: () => (${JSON.stringify(HoverTrigger.bind({})().data())}), components: { ${Object.keys(HoverTrigger.bind({})().components)} }, template: \`${HoverTrigger.bind({})().template}\` ` #### Example Using Directive (mouseover and mouseleave) <Canvas> <Story name="example-dropdown-using-directive" parameters={{ docs: { source: { code: HoverTriggerString } } }} > {HoverTrigger.bind({})} </Story> </Canvas> ### Helper The plugin of Dropdown component has a couple of helper function that can be used on your needs. Currently, the helpers are: - `getContentDepth`: Get the depth of the content. This will help you to dynamically generate the menu from `content`. The usage example can be seen on Multi Level Dropdown section. - `getSlotName`: For nested dropdown, you need to set the slot name with format `menu-${slotNumber}`. This function will help you to generate the name with slotNumber as parameter. The usage example can be seen on Multi Level Dropdown section. ## Default Dropdown <Canvas> <Story name="Default" args={{ placement: 'bottom-start', }} argTypes={{ ...argTypesDefault }} parameters={{ docs: { source: { code: TemplateDefaultString } } }} > {TemplateDefault.bind({})} </Story> </Canvas> <ArgsTable story="Default" /> <Anchor storyId="dropdown--nested"></Anchor> ## Nested Dropdown <Canvas> <Story name="Nested" args={{ enableMultiLevel: true, placement: 'bottom-start', width: 'lg', }} argTypes={{ ...argTypesDefault }} parameters={{ docs: { source: { code: TemplateMultilevelString } } }} > {TemplateMultiLevel.bind({})} </Story> </Canvas> <ArgsTable story="Nested" /> export const ButtonWithSplit = (args) => ({ data: () => ({ toggleShowDropdown: false, }), components: { MDropdown, MDropdownItem, MButton, MButtonGroup, MIcon }, template: ` <m-dropdown class="pb-2" :toggle-show-dropdown="toggleShowDropdown" placement="bottom-end" v-dropdown-mouseleave > <template #dropdown-trigger> <m-button-group> <m-button class="pr-3">Button</m-button> <m-button class="btn-with-icon px-2" v-dropdown-mouseover > <m-icon variant="dropdown" /> </m-button> </m-button-group> </template> <m-dropdown-item> Item 1 </m-dropdown-item> </m-dropdown> ` }) export const ButtonWithSplitString = ` data: () => (${JSON.stringify(ButtonWithSplit.bind({})().data())}), components: { ${Object.keys(ButtonWithSplit.bind({})().components)} }, template: \`${ButtonWithSplit.bind({})().template}\` ` ## Another Example ### Trigger With Button Split <Canvas> <Story name="example-dropdown-button-split-trigger" parameters={{ docs: { source: { code: ButtonWithSplitString } } }} > {ButtonWithSplit.bind({})} </Story> </Canvas> export const ItemWithTitle = (args) => ({ components: { MDropdown, MDropdownItem, }, template: ` <m-dropdown class="pb-7 mb-7" > <m-dropdown-item :is-group-title="true" > Header 1 </m-dropdown-item> <m-dropdown-item> Dropdown Item 1 </m-dropdown-item> <m-dropdown-item :is-group-title="true" > Header 2 </m-dropdown-item> <m-dropdown-item> Dropdown Item 1 </m-dropdown-item> </m-dropdown> ` }) ### Dropdown Item with Title <Canvas> <Story name="example-dropdown-item-with-title"> {ItemWithTitle.bind({})} </Story> </Canvas>