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

249 lines (241 loc) 8.19 kB
import { withActions } from "@storybook/addon-actions/decorator"; import { html } from "lit"; import { ifDefined } from "lit/directives/if-defined.js"; import { createShadowHostClass } from "../../providers/shadow-dom/shadow-host-helper"; const meta = { title: 'Components/Button', component: 'modus-wc-button', args: { color: 'primary', disabled: false, 'full-width': false, pressed: false, shape: 'rectangle', size: 'md', type: 'button', variant: 'filled', }, argTypes: { color: { control: { type: 'select' }, options: [ 'primary', 'secondary', 'tertiary', 'warning', 'danger', 'neutral', ], }, shape: { control: { type: 'select' }, options: ['circle', 'ellipse', 'rectangle', 'square'], }, size: { control: { type: 'select' }, options: ['xs', 'sm', 'md', 'lg', 'xl'], }, type: { control: { type: 'select' }, options: ['button', 'submit', 'reset'], }, variant: { control: { type: 'select' }, options: ['borderless', 'filled', 'outlined'], }, }, decorators: [withActions], parameters: { actions: { handles: ['buttonClick'], }, }, }; export default meta; const Template = { render: (args) => { // prettier-ignore return html ` <modus-wc-button color="${args.color}" custom-class="${ifDefined(args['custom-class'])}" ?disabled="${args.disabled}" ?full-width="${args['full-width']}" ?pressed="${args.pressed}" shape="${args.shape}" size="${args.size}" type="${args.type}" variant="${args.variant}" > Click me </modus-wc-button> `; }, }; export const Default = Object.assign({}, Template); export const ButtonShapes = { render: () => { // prettier-ignore return html ` <modus-wc-button shape="rectangle" > Rectangle </modus-wc-button> <modus-wc-button shape="circle" > Circle </modus-wc-button> <modus-wc-button shape="square" > Square </modus-wc-button> <modus-wc-button shape="ellipse" > Ellipse </modus-wc-button> `; }, }; export const DynamicTextUpdate = { render: () => { const updateButtonText = () => { const btnText = document.getElementById('btn-text'); const input = document.getElementById('btn-text-input'); btnText.textContent = input.value; }; // prettier-ignore return html ` <script> function updateButtonText() { const btnText = document.getElementById('btn-text'); const input = document.getElementById('btn-text-input'); btnText.textContent = input.value; } // Call updateButtonText function using the button's click event // Example: <modus-wc-button color="primary" variant="filled" buttonClick="updateButtonText()"></modus-wc-button> </script> <div> <modus-wc-button id="text-update-btn" color="primary" variant="filled" @buttonClick=${updateButtonText}> <modus-wc-icon decorative name="shopping_cart"></modus-wc-icon><span id="btn-text">Press button to update content</span> <modus-wc-icon decorative name="shopping_cart"></modus-wc-icon> </modus-wc-button> <div style="margin-top: 8px; display: flex; gap: 8px; align-items: center;"> <modus-wc-text-input id="btn-text-input" type="text" value="Updated Text" style="padding: 4px 8px;" /> </div> </div> `; }, }; export const IconOnlyButton = { render: () => { // prettier-ignore return html ` <modus-wc-button aria-label="Notification button"> <modus-wc-icon decorative name="notifications"></modus-wc-icon> </modus-wc-button> `; }, }; export const IconLeftButton = { render: () => { // prettier-ignore return html ` <modus-wc-button> <modus-wc-icon decorative name="download"></modus-wc-icon> Download </modus-wc-button> `; }, }; export const IconRightButton = { render: () => { // prettier-ignore return html ` <modus-wc-button> Details <modus-wc-icon decorative name="launch"></modus-wc-icon> </modus-wc-button> `; }, }; export const IconLeftAndRightButton = { render: () => { // prettier-ignore return html ` <modus-wc-button> <modus-wc-icon decorative name="shopping_cart"></modus-wc-icon> Checkout <modus-wc-icon decorative name="shopping_cart"></modus-wc-icon> </modus-wc-button> `; }, }; export const ShadowDomParent = { render: (args) => { // Create a unique shadow host for button component if (!customElements.get('button-shadow-host')) { const ButtonShadowHost = createShadowHostClass({ componentTag: 'modus-wc-button', propsMapper: (v, el) => { const buttonEl = el; buttonEl.ariaLabel = 'Click me button'; buttonEl.color = v.color; buttonEl.shape = v.shape; buttonEl.size = v.size; buttonEl.type = v.type; buttonEl.variant = v.variant; buttonEl.customClass = v['custom-class'] || ''; buttonEl.disabled = Boolean(v.disabled); buttonEl.fullWidth = Boolean(v['full-width']); buttonEl.pressed = Boolean(v.pressed); // DO NOT set textContent - it destroys the component's internal structure! // Button content should be set via defaultContent in the helper config }, defaultContent: 'Click me', // Set content here instead }); customElements.define('button-shadow-host', ButtonShadowHost); } return html `<button-shadow-host .props=${Object.assign({}, args)} ></button-shadow-host>`; }, }; export const Migration = { parameters: { docs: { description: { story: ` #### Breaking Changes - In 1.0 buttons had specific properties for adding icons (\`icon-only\`, \`left-icon\`, \`right-icon\`). In 2.0, icons are added via slots using the \`modus-wc-icon\` component. - The \`button-style\` property has been renamed to \`variant\` with similar options. - Size values have changed from verbose names (\`small\`, \`medium\`, \`large\`) to abbreviations (\`sm\`, \`md\`, \`lg\`). #### Prop Mapping | 1.0 Prop | 2.0 Prop | Notes | |-----------------|------------|-------------------------------------------------------------| | aria-label | aria-label | | | button-style | variant | \`fill\` → \`filled\`, \`outline\` → \`outlined\` | | color | color | \`dark\` and \`special\` removed, \`warning\` added | | critical-action | | Not carried over | | disabled | disabled | | | icon-only | | Not carried over, use \`icon\` slot | | left-icon | | Not carried over, use \`icon\` slot | | right-icon | | Not carried over, use \`icon\` slot | | show-caret | | Not carried over | | size | size | \`small\` → \`sm\`, \`medium\` → \`md\`, \`large\` → \`lg\` | | type | type | | #### Event Mapping | 1.0 Event | 2.0 Event | Notes | |--------------|--------------|------------------| | buttonClick | buttonClick | | `, }, }, controls: { disable: true }, canvas: { disable: true }, }, render: () => html `<div></div>`, };