@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
585 lines (579 loc) • 16.8 kB
JavaScript
import {
argTypesDefault,
} from '.';
import debounce from 'lodash/debounce';
import {
MDropdown,
MDropdownItem,
MDropdownMenu,
MDropdownSearch,
MDropdownTrigger,
MFormCheckbox,
MFormInput,
MIcon,
MInputGroup,
} from '@/src';
export const TemplateDefault = args => ({ // eslint-disable-line no-unused-vars
data: () => ({
inputValue: '',
toggleShowDropdown: false,
isLoading: false,
}),
methods: {
checkSelected(value) {
this.inputValue = value.content;
this.toggleShowDropdown = false;
},
resetLoading: debounce(function () {
this.isLoading = false;
this.content = [
...this.content,
{
id: this.content.length,
content: `Content of dropdown ${this.content.length}`,
},
{
id: this.content.length + 1,
content: `Content of dropdown ${this.content.length + 1}`,
},
];
}, 1000), // eslint-disable-line no-magic-numbers
refreshContent() {
this.isLoading = true;
this.resetLoading();
},
resetToggleShowDropdown() {
this.inputValue = '';
this.toggleShowDropdown = false;
},
},
template: `
<m-dropdown
:placement="placement"
:children-placement="childrenPlacement"
:content="content"
:enable-search="true"
:trigger-label="triggerLabel"
:trigger-variant="triggerVariant"
:trigger-icon-variant="triggerIconVariant"
:trigger-theme="triggerTheme"
:trigger-size="triggerSize"
:trigger-disabled="triggerDisabled"
:height-limit="heightLimit"
:width="width"
:state="state"
:placeholder="placeholder"
:empty-dropdown-text="emptyDropdownText"
:enable-multi-level="enableMultiLevel"
:toggle-show-dropdown="toggleShowDropdown"
:debounce="debounce"
-dropdown="checkSelected"
-dropdown="toggleShowDropdown = false"
-bottom="refreshContent"
>
<template #dropdown-trigger>
<m-input-group>
<m-form-input
class="text-dark"
:value="inputValue"
placeholder="Placeholder of input"
.native="toggleShowDropdown = true"
.enter="toggleShowDropdown = true"
readonly
clickable-readonly
has-double-suffix-icon
has-suffix-icon
/>
<m-icon
variant="chevron-bottom"
is-suffix-icon
/>
<m-icon
v-show="inputValue"
variant="reset-fill"
is-suffix-icon
is-double-suffix-icon
.native="resetToggleShowDropdown"
/>
</m-input-group>
</template>
<template #default="{
content,
menuNumber,
setItemAction
}">
<m-dropdown-item
v-if="content.length > 0"
v-for="item in content"
:key="item.id + item.content"
:disabled="item.disabled"
:isGroupTitle="item.isGroupTitle"
="setItemAction(item, menuNumber, $event, {
isSelectingItem: true
})"
>
{{ item.content }}
</m-dropdown-item>
<m-dropdown-item v-if="content.length === 0" class="text-center text-muted">
No data found
</m-dropdown-item>
<m-dropdown-item v-if="isLoading" class="text-center text-muted">
Loading...
</m-dropdown-item>
</template>
</m-dropdown>
`,
props: Object.keys(argTypesDefault),
components: {
MFormInput,
MIcon,
MInputGroup,
MDropdown,
MDropdownTrigger,
MDropdownMenu,
MDropdownSearch,
MDropdownItem,
},
});
export const TemplateMultiLevel = args => ({ // eslint-disable-line no-unused-vars
data: () => ({
toggleShowDropdown: false,
isLoading: false,
}),
methods: {
// this is just example. You should not change props directly
// You can pass to parent component, and edit the content there
// Before passed as props
reconstructContent(content, selectedItem) {
return content.map(el => {
if (el.id === selectedItem.id) {
el.checked = !el.checked;
}
if (el.children) {
this.reconstructContent(el.children, selectedItem);
}
return el;
});
},
updateContent(selectedItem) {
// this is just example. You should not change props directly
// You can pass to parent component, and edit the content there
// Before passed as props
this.content = this.reconstructContent(this.content, selectedItem);
},
getGlobalCheckedCount(content) {
let count = 0;
content.forEach(el => {
if (el.checked) {
count += 1;
}
if (el.children) {
count += this.getGlobalCheckedCount(el.children);
}
});
return count;
},
getGlobalChecked() {
const checkedChildren = this.getGlobalCheckedCount(this.content);
return checkedChildren ? `Filter (${checkedChildren})` : 'Filter';
},
countChildrenChecked(content) {
let checkedChildren = 0;
content.forEach(el => {
if (el.checked === true) {
checkedChildren += 1;
}
});
return checkedChildren;
},
getCountCopy(content) {
const count = this.countChildrenChecked(content);
return count ? `(${count})` : '';
},
},
template: `
<m-dropdown
:placement="placement"
:children-placement="childrenPlacement"
:content="content"
:enable-search="enableSearch"
:hide-dropdown-on-action="false"
:trigger-label="triggerLabel"
:trigger-variant="triggerVariant"
:trigger-icon-variant="triggerIconVariant"
:trigger-theme="triggerTheme"
:trigger-size="triggerSize"
:trigger-disabled="triggerDisabled"
:height-limit="heightLimit"
:width="width"
:state="state"
:placeholder="placeholder"
:empty-dropdown-text="emptyDropdownText"
:enable-multi-level="enableMultiLevel"
:toggle-show-dropdown="toggleShowDropdown"
:debounce="debounce"
-dropdown="updateContent"
-dropdown="toggleShowDropdown = false"
>
<template #dropdown-trigger>
<m-input-group>
<m-form-input
class="text-dark"
:value="getGlobalChecked()"
placeholder="Select Filter"
.native="toggleShowDropdown = !toggleShowDropdown"
.enter="toggleShowDropdown = true"
readonly
clickable-readonly
has-suffix-icon
/>
<m-icon
variant="chevron-bottom"
is-suffix-icon
/>
</m-input-group>
</template>
<template
v-for="slotNumber in $dropdownPlugin.getContentDepth(content)"
#[$dropdownPlugin.getSlotName(slotNumber)]="{
content,
setItemAction,
menuNumber,
activeItemId,
isChildrenActive
}"
>
<m-dropdown-item
v-for="item in content"
:key="item.id"
:isActive="isChildrenActive && item.id === activeItemId"
="setItemAction(item, menuNumber, $event)"
>
<m-input-group class="my-0">
<m-form-checkbox
v-if="menuNumber !== 1"
class="mb-0"
:checked="!!item.checked"
:disabled="!!item.disabled"
="setItemAction(item, menuNumber, $event, {
isSelectingItem: true
})"
>
{{ item.content }}
</m-form-checkbox>
<div v-else>
{{ item.content }}
{{
item.children && item.children.length && countChildrenChecked(item.children)
? getCountCopy(item.children)
: ''
}}
</div>
<m-icon
v-if="item.children && item.children.length"
class="ml-auto"
size="small"
variant="chevron-right"
/>
</m-input-group>
</m-dropdown-item>
<m-dropdown-item v-if="content.length === 0" class="text-center text-muted">
No data found
</m-dropdown-item>
</template>
</m-dropdown>
`,
props: Object.keys(argTypesDefault),
components: {
MFormInput,
MIcon,
MInputGroup,
MFormCheckbox,
MDropdown,
MDropdownTrigger,
MDropdownMenu,
MDropdownSearch,
MDropdownItem,
},
});
export const TemplateDefaultString = `
data: () => ({
inputValue: '',
toggleShowDropdown: false,
isLoading: false,
}),
methods: {
checkSelected(value) {
this.inputValue = value.content;
this.toggleShowDropdown = false;
},
resetLoading: debounce(function () {
this.isLoading = false;
this.content = [
...this.content,
{
id: this.content.length,
content: \`Content of dropdown \${this.content.length}\`,
},
{
id: this.content.length + 1,
content: \`Content of dropdown \${this.content.length + 1}\`,
},
];
}, 1000), // eslint-disable-line no-magic-numbers
refreshContent() {
this.isLoading = true;
this.resetLoading();
},
resetToggleShowDropdown() {
this.inputValue = '';
this.toggleShowDropdown = false;
},
},
template: \`
<m-dropdown
:placement="placement"
:children-placement="childrenPlacement"
:content="content"
:enable-search="true"
:trigger-label="triggerLabel"
:trigger-variant="triggerVariant"
:trigger-icon-variant="triggerIconVariant"
:trigger-theme="triggerTheme"
:trigger-size="triggerSize"
:height-limit="heightLimit"
:width="width"
:state="state"
:placeholder="placeholder"
:empty-dropdown-text="emptyDropdownText"
:enable-multi-level="enableMultiLevel"
:toggle-show-dropdown="toggleShowDropdown"
:debounce="debounce"
-dropdown="checkSelected"
-dropdown="toggleShowDropdown = false"
-bottom="refreshContent"
>
<template #dropdown-trigger>
<m-input-group>
<m-form-input
class="text-dark"
:value="inputValue"
placeholder="Placeholder of input"
.native="toggleShowDropdown = true"
.enter="toggleShowDropdown = true"
readonly
clickable-readonly
has-double-suffix-icon
has-suffix-icon
/>
<m-icon
variant="chevron-bottom"
is-suffix-icon
/>
<m-icon
v-show="inputValue"
variant="reset-fill"
is-suffix-icon
is-double-suffix-icon
.native="resetToggleShowDropdown"
/>
</m-input-group>
</template>
<template #default="{
content,
menuNumber,
setItemAction
}">
<m-dropdown-item
v-if="content.length > 0"
v-for="item in content"
:key="item.id + item.content"
:disabled="item.disabled"
:isGroupTitle="item.isGroupTitle"
="setItemAction(item, menuNumber, $event, {
isSelectingItem: true
})"
>
{{ item.content }}
</m-dropdown-item>
<m-dropdown-item v-if="content.length === 0" class="text-center text-muted">
No data found
</m-dropdown-item>
<m-dropdown-item v-if="isLoading" class="text-center text-muted">
Loading...
</m-dropdown-item>
</template>
</m-dropdown>
\`,
props: Object.keys(argTypesDefault),
components: {
MFormInput,
MIcon,
MInputGroup,
MDropdown,
MDropdownTrigger,
MDropdownMenu,
MDropdownSearch,
MDropdownItem,
},
`;
export const TemplateMultilevelString = `
data: () => ({
toggleShowDropdown: false,
isLoading: false
}),
methods: {
// this is just example. You should not change props directly
// You can pass to parent component, and edit the content there
// Before passed as props
reconstructContent(content, selectedItem) {
return content.map(el => {
if (el.id === selectedItem.id) {
el.checked = el.checked ? false : true;
}
if (el.children) {
this.reconstructContent(el.children, selectedItem);
}
return el;
});
},
updateContent(selectedItem) {
// this is just example. You should not change props directly
// You can pass to parent component, and edit the content there
// Before passed as props
this.content = this.reconstructContent(this.content, selectedItem);
},
getGlobalCheckedCount(content) {
let count = 0;
content.forEach(el => {
if (el.checked) {
count += 1;
}
if (el.children) {
count += this.getGlobalCheckedCount(el.children);
}
});
return count;
},
getGlobalChecked() {
let checkedChildren = this.getGlobalCheckedCount(this.content);
return checkedChildren ? \`Filter (\${checkedChildren})\` : 'Filter';
},
countChildrenChecked(content) {
let checkedChildren = 0;
content.forEach(el => {
if (el.checked === true) {
checkedChildren += 1;
}
})
return checkedChildren;
},
getCountCopy(content) {
const count = this.countChildrenChecked(content);
return count ? \`(\${count})\` : '';
}
},
template: \`
<m-dropdown
:placement="placement"
:children-placement="childrenPlacement"
:content="content"
:enable-search="enableSearch"
:hide-dropdown-on-action="false"
:trigger-label="triggerLabel"
:trigger-variant="triggerVariant"
:trigger-icon-variant="triggerIconVariant"
:trigger-theme="triggerTheme"
:trigger-size="triggerSize"
:height-limit="heightLimit"
:width="width"
:state="state"
:placeholder="placeholder"
:empty-dropdown-text="emptyDropdownText"
:enable-multi-level="enableMultiLevel"
:toggle-show-dropdown="toggleShowDropdown"
:debounce="debounce"
-dropdown="updateContent"
-dropdown="toggleShowDropdown = false"
>
<template #dropdown-trigger>
<m-input-group>
<m-form-input
class="text-dark"
:value="getGlobalChecked()"
placeholder="Select Filter"
.native="toggleShowDropdown = !toggleShowDropdown"
.enter="toggleShowDropdown = true"
readonly
clickable-readonly
has-suffix-icon
/>
<m-icon
variant="chevron-bottom"
is-suffix-icon
/>
</m-input-group>
</template>
<template
v-for="slotNumber in $dropdownPlugin.getContentDepth(content)"
#[$dropdownPlugin.getSlotName(slotNumber)]="{
content,
setItemAction,
menuNumber,
activeItemId,
isChildrenActive
}"
>
<m-dropdown-item
v-for="item in content"
:key="item.id"
:isActive="isChildrenActive && item.id === activeItemId"
="setItemAction(item, menuNumber, $event)"
>
<m-input-group class="my-0">
<m-form-checkbox
v-if="menuNumber !== 1"
class="mb-0"
:checked="!!item.checked"
:disabled="!!item.disabled"
="setItemAction(item, menuNumber, $event, {
isSelectingItem: true
})"
>
{{ item.content }}
</m-form-checkbox>
<div v-else>
{{ item.content }}
{{
item.children.length && countChildrenChecked(item.children)
? getCountCopy(item.children)
: ''
}}
</div>
<m-icon
v-if="item.children.length"
class="ml-auto"
size="small"
variant="chevron-right"
/>
</m-input-group>
</m-dropdown-item>
<m-dropdown-item v-if="content.length === 0" class="text-center text-muted">
No data found
</m-dropdown-item>
</template>
</m-dropdown>
\`,
props: Object.keys(argTypesDefault),
components: {
MFormInput,
MIcon,
MInputGroup,
MFormCheckbox,
MDropdown,
MDropdownTrigger,
MDropdownMenu,
MDropdownSearch,
MDropdownItem,
},
`;