UNPKG

@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

246 lines (234 loc) 8.68 kB
import { html, unsafeCSS } from "lit"; import { ifDefined } from "lit/directives/if-defined.js"; import { keyed } from "lit/directives/keyed.js"; // Shared styles for story demos const storyStyles = unsafeCSS(` .handle-demo-container { display: flex; gap: 0; } .handle-demo-container.horizontal { height: 300px; } .handle-demo-container.vertical { flex-direction: column; height: 500px; } .handle-demo-panel { background-color: var(--modus-wc-color-base-100); overflow: auto; } .handle-demo-panel.initial-size-200 { width: 200px; } .handle-demo-panel.initial-height-200 { height: 200px; } .handle-demo-panel.initial-size-400 { width: 400px; } .handle-demo-panel.flex-fill { flex: 1; } .handle-demo-right-container { flex: 1; display: flex; flex-direction: column; gap: 0; } `); const meta = { title: 'Components/Handle', component: 'modus-wc-handle', args: { 'button-color': 'tertiary', 'button-size': 'md', 'button-variant': 'filled', 'custom-class': '', 'default-split': 50, density: 'comfortable', 'left-target': '', orientation: 'vertical', 'right-target': '', size: 'default', type: 'bar', }, argTypes: { 'custom-class': { control: 'text', }, 'default-split': { control: { type: 'range', min: 1, max: 100, step: 1 }, }, density: { control: { type: 'select' }, options: ['compact', 'comfortable', 'relaxed'], }, 'button-size': { control: { type: 'select' }, options: ['sm', 'md', 'lg', 'xl'], }, 'button-color': { control: { type: 'select' }, options: ['primary', 'secondary', 'tertiary', 'warning', 'danger'], }, 'button-variant': { control: { type: 'select' }, options: ['borderless', 'filled', 'outlined'], }, 'left-target': { control: 'text', }, orientation: { control: { type: 'select' }, options: ['horizontal', 'vertical'], }, 'right-target': { control: 'text', }, size: { control: { type: 'select' }, options: ['default', 'lg', 'xl', '2xl'], }, type: { control: { type: 'select' }, options: ['bar', 'button'], }, }, parameters: { layout: 'padded', }, }; export default meta; const HandleTemplate = (args) => // prettier-ignore html ` <modus-wc-handle custom-class="${ifDefined(args === null || args === void 0 ? void 0 : args['custom-class'])}" default-split="${args === null || args === void 0 ? void 0 : args['default-split']}" density="${args === null || args === void 0 ? void 0 : args.density}" button-size="${args === null || args === void 0 ? void 0 : args['button-size']}" button-color="${args === null || args === void 0 ? void 0 : args['button-color']}" button-variant="${args === null || args === void 0 ? void 0 : args['button-variant']}" left-target="${ifDefined(args === null || args === void 0 ? void 0 : args['left-target'])}" orientation="${ifDefined(args === null || args === void 0 ? void 0 : args.orientation)}" right-target="${ifDefined(args === null || args === void 0 ? void 0 : args['right-target'])}" size="${args === null || args === void 0 ? void 0 : args.size}" type="${args === null || args === void 0 ? void 0 : args.type}" ></modus-wc-handle> `; // Helper templates for panels const PanelTemplate = (id, title, content, className = '') => // prettier-ignore html ` <div id="${id}" class="handle-demo-panel ${className}"> <h3>${title}</h3> <p>${content}</p> </div> `; const PanelWithKeyboardInfo = (id, title, content, keyboardInfo, className = '') => // prettier-ignore html ` <div id="${id}" class="handle-demo-panel ${className}"> <h3>${title}</h3> <p>${content}</p> <p><strong>Keyboard:</strong> ${keyboardInfo}</p> </div> `; // Generate unique ID for each render to avoid conflicts on docs page const generateUniqueId = () => Math.random().toString(36).substring(2, 9); // Reusable render function for demos const Template = (args) => { var _a, _b, _c, _d, _e; const orientation = (_a = args === null || args === void 0 ? void 0 : args.orientation) !== null && _a !== void 0 ? _a : 'horizontal'; const type = (_b = args === null || args === void 0 ? void 0 : args.type) !== null && _b !== void 0 ? _b : 'bar'; const isHorizontal = orientation === 'horizontal'; const uniqueId = generateUniqueId(); const leftId = `panel-left-${uniqueId}`; const rightId = `panel-right-${uniqueId}`; // prettier-ignore return html ` <style>${storyStyles}</style> ${keyed(orientation, html ` <div class="handle-demo-container ${isHorizontal ? 'horizontal' : 'vertical'}"> ${PanelWithKeyboardInfo(leftId, isHorizontal ? 'Left Panel' : 'Top Panel', 'Drag the handle to resize this panel.', `Focus the handle and use ${isHorizontal ? 'Left/Right' : 'Up/Down'} arrow keys to resize (5px per press, 15px with Shift).`, isHorizontal ? 'initial-size-200' : 'initial-height-200')} ${HandleTemplate({ orientation: orientation, size: (_c = args === null || args === void 0 ? void 0 : args.size) !== null && _c !== void 0 ? _c : 'default', density: (_d = args === null || args === void 0 ? void 0 : args.density) !== null && _d !== void 0 ? _d : 'comfortable', type: type, 'default-split': (_e = args === null || args === void 0 ? void 0 : args['default-split']) !== null && _e !== void 0 ? _e : 50, 'custom-class': args === null || args === void 0 ? void 0 : args['custom-class'], 'button-size': args === null || args === void 0 ? void 0 : args['button-size'], 'button-color': args === null || args === void 0 ? void 0 : args['button-color'], 'button-variant': args === null || args === void 0 ? void 0 : args['button-variant'], 'left-target': `#${leftId}`, 'right-target': `#${rightId}`, })} ${PanelTemplate(rightId, isHorizontal ? 'Right Panel' : 'Bottom Panel', 'This panel will resize automatically when you drag the handle.', 'flex-fill')} </div> `)}`; }; export const Default = { render: (args) => Template(args), }; export const ButtonVariant = { render: (args) => { var _a, _b, _c; return Template(Object.assign(Object.assign({}, args), { orientation: (_a = args === null || args === void 0 ? void 0 : args.orientation) !== null && _a !== void 0 ? _a : 'horizontal', size: (_b = args === null || args === void 0 ? void 0 : args.size) !== null && _b !== void 0 ? _b : 'default', density: (_c = args === null || args === void 0 ? void 0 : args.density) !== null && _c !== void 0 ? _c : 'comfortable', type: 'button' })); }, args: { type: 'button', }, parameters: { docs: { description: { story: ` Button type handle with customizable button properties. **Button Properties Available:** - \`button-size\`: sm, md, lg - \`button-color\`: primary, secondary, tertiary, warning, danger - \`button-variant\`: borderless, filled, outlined **Keyboard Navigation:** - Arrow keys: Move 5px per press - Shift + Arrow keys: Move 15px per press The button handle provides a more prominent visual indicator compared to the bar type. `, }, }, }, }; export const MultipleHandlesNested = { render: () => { // prettier-ignore return html ` <style>${storyStyles}</style> <div class="handle-demo-container" style="height: 600px;"> ${PanelTemplate('panel-one', 'One', 'Large left panel', 'initial-size-400')} ${HandleTemplate({ orientation: 'horizontal', size: 'default', density: 'comfortable', type: 'bar', 'left-target': '#panel-one', 'right-target': '#right-container', })} <div id="right-container" class="handle-demo-right-container"> ${PanelTemplate('panel-two', 'Two', 'Top right panel', 'initial-height-200')} ${HandleTemplate({ orientation: 'vertical', size: 'default', density: 'comfortable', type: 'bar', 'left-target': '#panel-two', 'right-target': '#panel-three', })} ${PanelTemplate('panel-three', 'Three', 'Bottom right panel', 'flex-fill')} </div> </div> `; }, }; export const ShadowDomParent = { render: (args) => Template(args), };