@trimble-oss/moduswebcomponents
Version:
Modus Web Components is a modern, accessible UI library built with Stencil JS that provides reusable web components following Trimble's Modus design system. This updated version focuses on improved flexibility, enhanced theming options, comprehensive cust
207 lines (206 loc) • 7.39 kB
JavaScript
import { withActions } from "@storybook/addon-actions/decorator";
import { html } from "lit";
import { ifDefined } from "lit/directives/if-defined.js";
import { ref } from "lit/directives/ref.js";
import { createShadowHostClass } from "../../providers/shadow-dom/shadow-host-helper";
import { treeMenuCollapsibleMenuSourceCode, treeMenuDefaultSourceCode, treeMenuMultiSelectSourceCode, treeMenuShadowDomParentSourceCode, } from "./modus-wc-tree-menu.story-source";
const meta = {
title: 'Components/Tree Menu',
component: 'modus-wc-tree-menu',
args: {
orientation: 'vertical',
'selection-mode': 'single',
size: 'md',
},
argTypes: {
orientation: {
control: { type: 'select' },
options: ['horizontal', 'vertical'],
},
'selection-mode': {
control: { type: 'select' },
options: ['single', 'multiple'],
},
size: {
control: { type: 'select' },
options: ['xs', 'sm', 'md', 'lg'],
},
},
decorators: [withActions],
parameters: {
actions: {
handles: ['menuFocusout', 'menuSelectionChange', 'itemSelect'],
},
},
};
export default meta;
export const Default = {
parameters: {
docs: { source: { code: treeMenuDefaultSourceCode } },
},
render: (args) => {
// prettier-ignore
return html `
<modus-wc-tree-menu
aria-label="Tree menu"
?bordered=${args.bordered}
custom-class=${ifDefined(args['custom-class'])}
orientation=${ifDefined(args.orientation)}
selection-mode=${ifDefined(args['selection-mode'])}
size=${ifDefined(args.size)}
>
<modus-wc-tree-item
label="Small"
value="1"
size="sm"
></modus-wc-tree-item>
<modus-wc-tree-item label="Medium" value="2"></modus-wc-tree-item>
<modus-wc-tree-item
label="Large"
value="3"
size="lg"
></modus-wc-tree-item>
<modus-wc-tree-item
label="Bordered"
value="4"
bordered="true"
></modus-wc-tree-item>
<modus-wc-tree-item
label="With Sub-label"
value="5"
sub-label="Sub-label"
></modus-wc-tree-item>
<modus-wc-tree-item
label="Selected"
value="6"
selected="true"
></modus-wc-tree-item>
<modus-wc-tree-item label="With Start Icon" value="7">
<modus-wc-icon slot="start" name="info"></modus-wc-icon>
</modus-wc-tree-item>
<modus-wc-tree-item label="With End Action" value="8">
<div slot="end" style="display: flex; align-items: center;">
<modus-wc-button
variant="borderless"
size="sm"
shape="circle"
color="primary"
aria-label="More options"
>
<modus-wc-icon name="more_vertical" size="sm"></modus-wc-icon>
</modus-wc-button>
</div>
</modus-wc-tree-item>
<modus-wc-tree-item
label="Disabled"
value="9"
disabled="true"
></modus-wc-tree-item>
</modus-wc-tree-menu>
`;
},
};
export const MultiSelect = {
args: {
'selection-mode': 'multiple',
},
parameters: {
docs: { source: { code: treeMenuMultiSelectSourceCode } },
},
render: (args) => {
let outputEl;
const handleSelectionChange = (e) => {
if (!outputEl)
return;
const { selectedItems } = e.detail;
outputEl.textContent =
selectedItems.length > 0
? `Selected: ${selectedItems.map((i) => i.getAttribute('value')).join(', ')}`
: 'Selected: none';
};
// prettier-ignore
return html `
<modus-wc-tree-menu
aria-label="Tree menu"
selection-mode=${ifDefined(args['selection-mode'])}
@menuSelectionChange=${handleSelectionChange}
>
<modus-wc-tree-item label="Item 1" value="1"></modus-wc-tree-item>
<modus-wc-tree-item label="Item 2" value="2"></modus-wc-tree-item>
<modus-wc-tree-item label="Item 3" value="3"></modus-wc-tree-item>
</modus-wc-tree-menu>
<p ${ref((el) => (outputEl = el !== null && el !== void 0 ? el : undefined))}>Selected: none</p>
`;
},
};
export const CollapsibleMenu = {
parameters: {
docs: { source: { code: treeMenuCollapsibleMenuSourceCode } },
},
render: () => {
// prettier-ignore
return html `
<modus-wc-tree-menu aria-label="Tree menu">
<modus-wc-tree-item label="Parent Item" value="parent" has-submenu="true">
<modus-wc-tree-menu is-sub-menu="true">
<modus-wc-tree-item label="Child 1" value="child-1"></modus-wc-tree-item>
<modus-wc-tree-item label="Child 2" value="child-2"></modus-wc-tree-item>
</modus-wc-tree-menu>
</modus-wc-tree-item>
<modus-wc-tree-item label="Sibling Item" value="sibling"></modus-wc-tree-item>
</modus-wc-tree-menu>
`;
},
};
export const ShadowDomParent = {
parameters: {
docs: { source: { code: treeMenuShadowDomParentSourceCode } },
},
render: (args) => {
if (!customElements.get('tree-menu-shadow-host')) {
const TreeMenuShadowHost = createShadowHostClass({
componentTag: 'modus-wc-tree-menu',
propsMapper: (v, el) => {
const treeMenuEl = el;
treeMenuEl.ariaLabel = 'Tree menu';
treeMenuEl.bordered = Boolean(v.bordered);
treeMenuEl.customClass = v['custom-class'] || '';
treeMenuEl.orientation = v.orientation || 'vertical';
treeMenuEl.selectionMode = v['selection-mode'] || 'single';
treeMenuEl.size = v.size || 'md';
if (!el.querySelector('modus-wc-tree-item')) {
el.innerHTML = `
<modus-wc-tree-item label="Small" value="1" size="sm"></modus-wc-tree-item>
<modus-wc-tree-item label="Medium" value="2"></modus-wc-tree-item>
<modus-wc-tree-item label="Large" value="3" size="lg"></modus-wc-tree-item>
<modus-wc-tree-item label="Bordered" value="4" bordered="true"></modus-wc-tree-item>
<modus-wc-tree-item label="With Sub-label" value="5" sub-label="Sub-label"></modus-wc-tree-item>
<modus-wc-tree-item label="Selected" value="6" selected="true"></modus-wc-tree-item>
<modus-wc-tree-item label="With Start Icon" value="7">
<modus-wc-icon slot="start" name="info"></modus-wc-icon>
</modus-wc-tree-item>
<modus-wc-tree-item label="With End Action" value="8">
<div slot="end" style="display: flex; align-items: center;">
<modus-wc-button
variant="borderless"
size="sm"
shape="circle"
color="primary"
aria-label="More options"
>
<modus-wc-icon name="more_vertical" size="sm"></modus-wc-icon>
</modus-wc-button>
</div>
</modus-wc-tree-item>
<modus-wc-tree-item label="Disabled" value="9" disabled="true"></modus-wc-tree-item>
`;
}
},
});
customElements.define('tree-menu-shadow-host', TreeMenuShadowHost);
}
return html `<tree-menu-shadow-host
.props=${Object.assign({}, args)}
></tree-menu-shadow-host>`;
},
};