@trimble-oss/moduswebcomponents-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +337 -0
- package/package.json +39 -0
- package/versions/1.0.0/component-docs/_all_components.json +56 -0
- package/versions/1.0.0/component-docs/modus-wc-autocomplete.json +415 -0
- package/versions/1.0.0/component-docs/modus-wc-date.json +227 -0
- package/versions/1.0.0/component-docs/modus-wc-dropdown-menu.json +164 -0
- package/versions/1.0.0/component-docs/modus-wc-logo.json +61 -0
- package/versions/1.0.0/component-docs/modus-wc-menu-item.json +165 -0
- package/versions/1.0.0/component-docs/modus-wc-menu.json +106 -0
- package/versions/1.0.0/component-docs/modus-wc-navbar.json +290 -0
- package/versions/1.0.0/component-docs/modus-wc-profile-menu.json +64 -0
- package/versions/1.0.0/component-docs/modus-wc-side-navigation.json +102 -0
- package/versions/1.0.0/component-docs/modus-wc-table.json +202 -0
- package/versions/1.0.0/component-docs/modus-wc-tooltip.json +94 -0
- package/versions/1.0.0/component-docs/modus-wc-typography.json +78 -0
- package/versions/1.0.0/docs/_all_docs.json +15 -0
- package/versions/1.0.0/docs/angular.mdx +374 -0
- package/versions/1.0.0/docs/getting-started.mdx +131 -0
- package/versions/1.0.7/component-docs/_all_components.json +55 -0
- package/versions/1.0.7/component-docs/modus-wc-autocomplete.json +405 -0
- package/versions/1.0.7/component-docs/modus-wc-table.json +202 -0
- package/versions/1.0.7/component-docs/modus-wc-tooltip.json +94 -0
- package/versions/1.0.7/docs/_all_docs.json +15 -0
- package/versions/1.0.7/docs/angular.mdx +374 -0
- package/versions/1.1.0/component-docs/_all_components.json +56 -0
- package/versions/1.1.0/component-docs/modus-wc-autocomplete.json +405 -0
- package/versions/1.1.0/component-docs/modus-wc-navbar.json +290 -0
- package/versions/1.1.0/component-docs/modus-wc-profile-menu.json +64 -0
- package/versions/1.1.0/component-docs/modus-wc-side-navigation.json +102 -0
- package/versions/1.1.0/component-docs/modus-wc-table.json +202 -0
- package/versions/1.1.0/component-docs/modus-wc-tooltip.json +94 -0
- package/versions/1.1.0/component-docs/modus-wc-typography.json +78 -0
- package/versions/1.1.0/docs/_all_docs.json +15 -0
- package/versions/1.1.0/docs/angular.mdx +374 -0
- package/versions/1.1.0/docs/getting-started.mdx +131 -0
- package/versions/1.1.1/component-docs/_all_components.json +56 -0
- package/versions/1.1.1/component-docs/modus-wc-autocomplete.json +405 -0
- package/versions/1.1.1/component-docs/modus-wc-navbar.json +290 -0
- package/versions/1.1.1/component-docs/modus-wc-profile-menu.json +64 -0
- package/versions/1.1.1/component-docs/modus-wc-side-navigation.json +102 -0
- package/versions/1.1.1/component-docs/modus-wc-table.json +202 -0
- package/versions/1.1.1/component-docs/modus-wc-tooltip.json +94 -0
- package/versions/1.1.1/component-docs/modus-wc-typography.json +78 -0
- package/versions/1.1.1/docs/_all_docs.json +15 -0
- package/versions/1.1.1/docs/angular.mdx +374 -0
- package/versions/1.1.1/docs/getting-started.mdx +131 -0
- package/versions/base/component-docs/_all_components.json +55 -0
- package/versions/base/component-docs/modus-wc-accordion.json +48 -0
- package/versions/base/component-docs/modus-wc-alert.json +112 -0
- package/versions/base/component-docs/modus-wc-autocomplete.json +397 -0
- package/versions/base/component-docs/modus-wc-avatar.json +83 -0
- package/versions/base/component-docs/modus-wc-badge.json +68 -0
- package/versions/base/component-docs/modus-wc-breadcrumbs.json +63 -0
- package/versions/base/component-docs/modus-wc-button-group.json +100 -0
- package/versions/base/component-docs/modus-wc-button.json +130 -0
- package/versions/base/component-docs/modus-wc-card.json +98 -0
- package/versions/base/component-docs/modus-wc-checkbox.json +149 -0
- package/versions/base/component-docs/modus-wc-chip.json +132 -0
- package/versions/base/component-docs/modus-wc-collapse.json +90 -0
- package/versions/base/component-docs/modus-wc-date.json +227 -0
- package/versions/base/component-docs/modus-wc-divider.json +85 -0
- package/versions/base/component-docs/modus-wc-dropdown-menu.json +154 -0
- package/versions/base/component-docs/modus-wc-file-dropzone.json +155 -0
- package/versions/base/component-docs/modus-wc-handle.json +135 -0
- package/versions/base/component-docs/modus-wc-icon.json +722 -0
- package/versions/base/component-docs/modus-wc-input-feedback.json +71 -0
- package/versions/base/component-docs/modus-wc-input-label.json +84 -0
- package/versions/base/component-docs/modus-wc-loader.json +65 -0
- package/versions/base/component-docs/modus-wc-logo.json +61 -0
- package/versions/base/component-docs/modus-wc-menu-item.json +173 -0
- package/versions/base/component-docs/modus-wc-menu.json +86 -0
- package/versions/base/component-docs/modus-wc-modal.json +108 -0
- package/versions/base/component-docs/modus-wc-navbar.json +280 -0
- package/versions/base/component-docs/modus-wc-number-input.json +219 -0
- package/versions/base/component-docs/modus-wc-pagination.json +103 -0
- package/versions/base/component-docs/modus-wc-panel.json +76 -0
- package/versions/base/component-docs/modus-wc-progress.json +86 -0
- package/versions/base/component-docs/modus-wc-radio.json +139 -0
- package/versions/base/component-docs/modus-wc-rating.json +117 -0
- package/versions/base/component-docs/modus-wc-select.json +159 -0
- package/versions/base/component-docs/modus-wc-side-navigation.json +102 -0
- package/versions/base/component-docs/modus-wc-skeleton.json +65 -0
- package/versions/base/component-docs/modus-wc-slider.json +163 -0
- package/versions/base/component-docs/modus-wc-stepper.json +47 -0
- package/versions/base/component-docs/modus-wc-switch.json +149 -0
- package/versions/base/component-docs/modus-wc-table.json +202 -0
- package/versions/base/component-docs/modus-wc-tabs.json +86 -0
- package/versions/base/component-docs/modus-wc-text-input.json +278 -0
- package/versions/base/component-docs/modus-wc-textarea.json +215 -0
- package/versions/base/component-docs/modus-wc-theme-switcher.json +49 -0
- package/versions/base/component-docs/modus-wc-time-input.json +211 -0
- package/versions/base/component-docs/modus-wc-toast.json +56 -0
- package/versions/base/component-docs/modus-wc-toolbar.json +44 -0
- package/versions/base/component-docs/modus-wc-tooltip.json +94 -0
- package/versions/base/component-docs/modus-wc-typography.json +73 -0
- package/versions/base/component-docs/modus-wc-utility-panel.json +86 -0
- package/versions/base/docs/_all_docs.json +15 -0
- package/versions/base/docs/accessibility.mdx +32 -0
- package/versions/base/docs/angular.mdx +346 -0
- package/versions/base/docs/form-inputs.mdx +86 -0
- package/versions/base/docs/getting-started.mdx +91 -0
- package/versions/base/docs/modus-figma-mcp-integration-guide.mdx +254 -0
- package/versions/base/docs/modus-icon-usage.mdx +210 -0
- package/versions/base/docs/react.mdx +129 -0
- package/versions/base/docs/styling.mdx +107 -0
- package/versions/base/docs/testing.mdx +18 -0
- package/versions/base/docs/vue.mdx +159 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "",
|
|
3
|
+
"properties": [
|
|
4
|
+
{
|
|
5
|
+
"name": "editable",
|
|
6
|
+
"type": "boolean | ((row: Record<string, unknown>)",
|
|
7
|
+
"description": "Enable cell editing. Either a boolean (all rows) or a predicate per row.",
|
|
8
|
+
"default": "> boolean) = false",
|
|
9
|
+
"mutable": false,
|
|
10
|
+
"end_line": 94
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "columns",
|
|
14
|
+
"type": "ITableColumn[]",
|
|
15
|
+
"description": "An array of column definitions.",
|
|
16
|
+
"default": null,
|
|
17
|
+
"mutable": false,
|
|
18
|
+
"end_line": 97
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "customClass",
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Custom CSS class to apply to the inner div.",
|
|
24
|
+
"default": "''",
|
|
25
|
+
"mutable": false,
|
|
26
|
+
"end_line": 100
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "data",
|
|
30
|
+
"type": "Record<string, unknown>[]",
|
|
31
|
+
"description": "An array of data objects.",
|
|
32
|
+
"default": null,
|
|
33
|
+
"mutable": false,
|
|
34
|
+
"end_line": 103
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "density",
|
|
38
|
+
"type": "Density",
|
|
39
|
+
"description": "The density of the table, used to save space or increase readability.",
|
|
40
|
+
"default": "'comfortable'",
|
|
41
|
+
"mutable": false,
|
|
42
|
+
"end_line": 106
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "hover",
|
|
46
|
+
"type": "boolean",
|
|
47
|
+
"description": "Enable hover effect on table rows.",
|
|
48
|
+
"default": "true",
|
|
49
|
+
"mutable": false,
|
|
50
|
+
"end_line": 109
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"name": "currentPage",
|
|
54
|
+
"type": "number",
|
|
55
|
+
"description": "The current page number in pagination (1-based index).",
|
|
56
|
+
"default": "1",
|
|
57
|
+
"mutable": false,
|
|
58
|
+
"end_line": 112
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "paginated",
|
|
62
|
+
"type": "boolean",
|
|
63
|
+
"description": "Enable pagination for the table.",
|
|
64
|
+
"default": "false",
|
|
65
|
+
"mutable": false,
|
|
66
|
+
"end_line": 115
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"name": "pageSizeOptions",
|
|
70
|
+
"type": "number[]",
|
|
71
|
+
"description": "Available options for the number of rows per page.",
|
|
72
|
+
"default": "[5, 10, 15]",
|
|
73
|
+
"mutable": false,
|
|
74
|
+
"end_line": 118
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "showPageSizeSelector",
|
|
78
|
+
"type": "boolean",
|
|
79
|
+
"description": "Show/hide the page size selector in pagination.",
|
|
80
|
+
"default": "true",
|
|
81
|
+
"mutable": false,
|
|
82
|
+
"end_line": 121
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "sortable",
|
|
86
|
+
"type": "boolean",
|
|
87
|
+
"description": "Enable sorting functionality for sortable columns.",
|
|
88
|
+
"default": "true",
|
|
89
|
+
"mutable": false,
|
|
90
|
+
"end_line": 124
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"name": "selectable",
|
|
94
|
+
"type": "'none' | 'single' | 'multi'",
|
|
95
|
+
"description": "Row selection mode: 'none' for no selection, 'single' for single row, 'multi' for multiple rows.",
|
|
96
|
+
"default": "'none'",
|
|
97
|
+
"mutable": false,
|
|
98
|
+
"end_line": 127
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"name": "selectedRowIds",
|
|
102
|
+
"type": "string[]",
|
|
103
|
+
"description": "Array of selected row IDs. Used for controlled selection state.",
|
|
104
|
+
"default": null,
|
|
105
|
+
"mutable": false,
|
|
106
|
+
"end_line": 130
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "zebra",
|
|
110
|
+
"type": "boolean",
|
|
111
|
+
"description": "Zebra striped tables differentiate rows by styling them in an alternating fashion.",
|
|
112
|
+
"default": "false",
|
|
113
|
+
"mutable": false,
|
|
114
|
+
"end_line": 133
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"name": "caption",
|
|
118
|
+
"type": "string",
|
|
119
|
+
"description": "Accessibility caption for the table (visually hidden but available to screen readers).",
|
|
120
|
+
"default": null,
|
|
121
|
+
"mutable": false,
|
|
122
|
+
"end_line": 136
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
"events": [
|
|
126
|
+
{
|
|
127
|
+
"name": "cellEditStart",
|
|
128
|
+
"detail": "{ rowIndex: number; colId: string; }",
|
|
129
|
+
"description": "Emits when cell editing starts.",
|
|
130
|
+
"end_line": 145
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"name": "cellEditCommit",
|
|
134
|
+
"detail": "{ rowIndex: number; colId: string; newValue: unknown; updatedRow: Record<string, unknown",
|
|
135
|
+
"description": "Emits when cell editing is committed with the new value.",
|
|
136
|
+
"end_line": 152
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"name": "rowClick",
|
|
140
|
+
"detail": "{ row: Record<string, unknown",
|
|
141
|
+
"description": "Emits when a row is clicked.",
|
|
142
|
+
"end_line": 169
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"name": "sortChange",
|
|
146
|
+
"detail": "SortingState",
|
|
147
|
+
"description": "Emits when sorting changes with the new sorting state.",
|
|
148
|
+
"end_line": 174
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"name": "paginationChange",
|
|
152
|
+
"detail": "IPaginationChangeEventDetail",
|
|
153
|
+
"description": "Emits when pagination changes with the new pagination state.",
|
|
154
|
+
"end_line": 177
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"name": "rowSelectionChange",
|
|
158
|
+
"detail": "{ selectedRows: Record<string, unknown",
|
|
159
|
+
"description": "Emits when row selection changes with the selected rows and their IDs.",
|
|
160
|
+
"end_line": 183
|
|
161
|
+
}
|
|
162
|
+
],
|
|
163
|
+
"methods": [],
|
|
164
|
+
"slots": [],
|
|
165
|
+
"examples": {
|
|
166
|
+
"basic": "<modus-wc-table\n .columns=${columns}\n .data=${data}\n .density=${args.density}\n .hover=${args.hover}\n .sortable=${args.sortable}\n .paginated=${args.paginated}\n .showPageSizeSelector=${args['show-page-size-selector']}\n .customClass=${args['custom-class']}\n .selectable=${args.selectable}\n .zebra=${args.zebra}\n .currentPage=${args['current-page']}\n .pageSizeOptions=${args['page-size-options']}\n .selectedRowIds=${args['selected-row-ids']}\n .editable=${args.editable}\n .caption=${args.caption}\n @rowClick=${action('rowClick')}\n @sortChange=${action('sortChange')}\n @paginationChange=${action('paginationChange')}\n @rowSelectionChange=${action('rowSelectionChange')}\n @cellEditStart=${action('cellEditStart')}\n @cellEditCommit=${action('cellEditCommit')}\n ></modus-wc-table>\n <script>\n // This script provides sample data and configuration for the modus-wc-table demonstration.\n // const createDemoColumns = () => [\n // {\n // id: 'id',\n // header: 'ID',\n // accessor: 'id',\n // width: '60px',\n // },\n // {\n // id: 'name',\n // header: 'Name',\n // accessor: 'name',\n // width: '100px',\n // },\n // {\n // id: 'email',\n // header: 'Email',\n // accessor: 'email',\n // },\n // {\n // id: 'role',\n // header: 'Role',\n // accessor: 'role',\n // },\n // ];\n\n // const createDemoData = (count = 5) => {\n // const data = [];\n // for (let i = 1; i <= count; i++) {\n // data.push({\n // id: i.toString(),\n // name: \\",
|
|
167
|
+
"variations": [],
|
|
168
|
+
"args": {
|
|
169
|
+
"density": "'comfortable'",
|
|
170
|
+
"hover": "false",
|
|
171
|
+
"sortable": "true",
|
|
172
|
+
"paginated": "false",
|
|
173
|
+
"show-page-size-selector": "true",
|
|
174
|
+
"custom-class": "''",
|
|
175
|
+
"selectable": "'none'",
|
|
176
|
+
"zebra": "false",
|
|
177
|
+
"current-page": "1",
|
|
178
|
+
"editable": "false"
|
|
179
|
+
},
|
|
180
|
+
"argTypes": {},
|
|
181
|
+
"usage": []
|
|
182
|
+
},
|
|
183
|
+
"tag": "modus-wc-table",
|
|
184
|
+
"storyExample": {
|
|
185
|
+
"template": "<modus-wc-table\n .columns=${columns}\n .data=${data}\n .density=${args.density}\n .hover=${args.hover}\n .sortable=${args.sortable}\n .paginated=${args.paginated}\n .showPageSizeSelector=${args['show-page-size-selector']}\n .customClass=${args['custom-class']}\n .selectable=${args.selectable}\n .zebra=${args.zebra}\n .currentPage=${args['current-page']}\n .pageSizeOptions=${args['page-size-options']}\n .selectedRowIds=${args['selected-row-ids']}\n .editable=${args.editable}\n .caption=${args.caption}\n @rowClick=${action('rowClick')}\n @sortChange=${action('sortChange')}\n @paginationChange=${action('paginationChange')}\n @rowSelectionChange=${action('rowSelectionChange')}\n @cellEditStart=${action('cellEditStart')}\n @cellEditCommit=${action('cellEditCommit')}\n ></modus-wc-table>\n <script>\n // This script provides sample data and configuration for the modus-wc-table demonstration.\n // const createDemoColumns = () => [\n // {\n // id: 'id',\n // header: 'ID',\n // accessor: 'id',\n // width: '60px',\n // },\n // {\n // id: 'name',\n // header: 'Name',\n // accessor: 'name',\n // width: '100px',\n // },\n // {\n // id: 'email',\n // header: 'Email',\n // accessor: 'email',\n // },\n // {\n // id: 'role',\n // header: 'Role',\n // accessor: 'role',\n // },\n // ];\n\n // const createDemoData = (count = 5) => {\n // const data = [];\n // for (let i = 1; i <= count; i++) {\n // data.push({\n // id: i.toString(),\n // name: \\",
|
|
186
|
+
"args": {
|
|
187
|
+
"density": "'comfortable'",
|
|
188
|
+
"hover": "false",
|
|
189
|
+
"sortable": "true",
|
|
190
|
+
"paginated": "false",
|
|
191
|
+
"show-page-size-selector": "true",
|
|
192
|
+
"custom-class": "''",
|
|
193
|
+
"selectable": "'none'",
|
|
194
|
+
"zebra": "false",
|
|
195
|
+
"current-page": "1",
|
|
196
|
+
"editable": "false"
|
|
197
|
+
},
|
|
198
|
+
"argTypes": {},
|
|
199
|
+
"events": [],
|
|
200
|
+
"fullContent": "/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { action } from '@storybook/addon-actions';\nimport { Meta, StoryObj } from '@storybook/web-components';\nimport { html } from 'lit';\nimport { ITableColumn } from './modus-wc-table';\nimport { IAutocompleteItem } from '../types';\nimport { Density } from '../types';\n\ninterface TableStoryArgs {\n 'custom-class'?: string;\n 'current-page'?: number;\n 'page-size-options'?: number[];\n 'selected-row-ids'?: string[];\n 'show-page-size-selector'?: boolean;\n caption?: string;\n columns?: ITableColumn[];\n data?: Record<string, unknown>[];\n density?: Density;\n editable?: boolean;\n hover?: boolean;\n paginated?: boolean;\n selectable?: 'none' | 'single' | 'multi';\n sortable?: boolean;\n zebra?: boolean;\n}\n\nconst meta: Meta<TableStoryArgs> = {\n title: 'Components/Table',\n component: 'modus-wc-table',\n\n argTypes: {\n columns: {\n control: 'object',\n description: 'An array of column definitions.',\n table: {\n type: {\n detail: `\n Interface: ITableColumn\n Properties:\n - accessor (string): Key to access data from row object\n - cellRenderer? (function): Custom cell renderer (value, row) => string | HTMLElement\n - className? (string): Class names for the column\n - header (string | HTMLElement): Header content\n - id (string): Unique identifier for the column\n - width? (string): Width style (e.g., '200px', '50%')\n - sortable? (boolean): Whether the column is sortable\n - editor? ('text' | 'number' | 'autocomplete' | 'date' | 'custom'): Built-in editor type\n - editorProps? (object): Extra props specific to the editor component\n - customEditorRenderer? (function): Custom renderer for 'custom' editor\n - editorTemplate? (string): Raw HTML string for editor, with \\`\\${value}\\` placeholder\n - editorSetup? (function): Runs after the editor element is added to the DOM\n `,\n },\n },\n },\n data: {\n control: 'object',\n description: 'An array of data objects.',\n table: {\n type: {\n detail: `\n Data should be an array of objects, where each object represents a row and each key matches a column accessor.\n\n Example:\n [\n { id: '1', name: 'Alice', email: 'alice@example.com', role: 'Admin' },\n { id: '2', name: 'Bob', email: 'bob@example.com', role: 'User' }\n ]\n\n - Each property in the object should correspond to a column's accessor value.\n - The 'id' property is recommended for row identification and selection.\n `,\n },\n },\n },\n density: {\n control: {\n type: 'select',\n },\n options: ['condensed', 'comfortable', 'relaxed'],\n description:\n 'The density of the table, used to save space or increase readability.',\n },\n hover: {\n control: 'boolean',\n description: 'Enable hover effect on table rows.',\n defaultValue: true,\n },\n sortable: {\n control: 'boolean',\n description: 'Enable sorting functionality for sortable columns.',\n defaultValue: true,\n },\n paginated: {\n control: 'boolean',\n description: 'Enable pagination for the table.',\n defaultValue: false,\n },\n 'show-page-size-selector': {\n control: 'boolean',\n description: 'Show/hide the page size selector in pagination.',\n defaultValue: true,\n },\n caption: {\n control: 'text',\n description:\n 'Accessibility caption for the table that is visually hidden but available to screen readers.',\n },\n 'custom-class': {\n control: 'text',\n description: 'Custom CSS class to apply to the inner div.',\n },\n selectable: {\n control: {\n type: 'select',\n },\n options: ['none', 'single', 'multi'],\n description:\n \"Row selection mode: 'none' for no selection, 'single' for single row, 'multi' for multiple rows.\",\n defaultValue: 'none',\n },\n zebra: {\n control: 'boolean',\n description:\n 'Zebra striped tables differentiate rows by styling them in an alternating fashion.',\n defaultValue: false,\n },\n 'current-page': {\n control: 'number',\n description: 'The current page number in pagination (1-based index).',\n defaultValue: 1,\n },\n 'page-size-options': {\n control: 'object',\n description: 'Available options for the number of rows per page.',\n defaultValue: [5, 10, 15],\n },\n 'selected-row-ids': {\n control: 'object',\n description:\n 'Array of selected row IDs. Used for controlled selection state.',\n defaultValue: [],\n },\n editable: {\n control: 'boolean',\n description:\n 'Enable cell editing. Either a boolean (all rows) or a predicate per row.',\n defaultValue: false,\n },\n },\n};\n\nexport default meta;\ntype Story = StoryObj<TableStoryArgs>;\n\n// Helper functions\nconst createDemoColumns = (): ITableColumn[] => [\n {\n id: 'id',\n header: 'ID',\n accessor: 'id',\n width: '60px',\n },\n {\n id: 'name',\n header: 'Name',\n accessor: 'name',\n width: '100px',\n },\n {\n id: 'email',\n header: 'Email',\n accessor: 'email',\n },\n {\n id: 'role',\n header: 'Role',\n accessor: 'role',\n },\n];\n\nconst createSortableColumns = (): ITableColumn[] => {\n const columns = createDemoColumns();\n return columns.map((col) => ({ ...col, sortable: true }));\n};\n\nconst createDemoData = (count = 5): Record<string, any>[] => {\n const data: Record<string, any>[] = [];\n for (let i = 1; i <= count; i++) {\n data.push({\n id: i.toString(),\n name: `User ${i}`,\n email: `user${i}@example.com`,\n role: i % 2 === 0 ? 'Admin' : 'User',\n });\n }\n return data;\n};\n\nexport const Default: Story = {\n render: (args) => {\n const columns = args.columns || createDemoColumns();\n const data = args.data || createDemoData();\n return html`\n <modus-wc-table\n .columns=${columns}\n .data=${data}\n .density=${args.density}\n .hover=${args.hover}\n .sortable=${args.sortable}\n .paginated=${args.paginated}\n .showPageSizeSelector=${args['show-page-size-selector']}\n .customClass=${args['custom-class']}\n .selectable=${args.selectable}\n .zebra=${args.zebra}\n .currentPage=${args['current-page']}\n .pageSizeOptions=${args['page-size-options']}\n .selectedRowIds=${args['selected-row-ids']}\n .editable=${args.editable}\n .caption=${args.caption}\n @rowClick=${action('rowClick')}\n @sortChange=${action('sortChange')}\n @paginationChange=${action('paginationChange')}\n @rowSelectionChange=${action('rowSelectionChange')}\n @cellEditStart=${action('cellEditStart')}\n @cellEditCommit=${action('cellEditCommit')}\n ></modus-wc-table>\n <script>\n // This script provides sample data and configuration for the modus-wc-table demonstration.\n // const createDemoColumns = () => [\n // {\n // id: 'id',\n // header: 'ID',\n // accessor: 'id',\n // width: '60px',\n // },\n // {\n // id: 'name',\n // header: 'Name',\n // accessor: 'name',\n // width: '100px',\n // },\n // {\n // id: 'email',\n // header: 'Email',\n // accessor: 'email',\n // },\n // {\n // id: 'role',\n // header: 'Role',\n // accessor: 'role',\n // },\n // ];\n\n // const createDemoData = (count = 5) => {\n // const data = [];\n // for (let i = 1; i <= count; i++) {\n // data.push({\n // id: i.toString(),\n // name: \\`User \\${i}\\`,\n // email: \\`user\\${i}@example.com\\`,\n // role: i % 2 === 0 ? 'Admin' : 'User',\n // });\n // }\n // return data;\n // };\n\n // const table = document.querySelector('modus-wc-table');\n // table.columns = createDemoColumns();\n // table.data = createDemoData();\n // table.hover = 'false';\n </script>\n `;\n },\n args: {\n density: 'comfortable',\n hover: false,\n sortable: true,\n paginated: false,\n 'show-page-size-selector': true,\n 'custom-class': '',\n selectable: 'none',\n zebra: false,\n 'current-page': 1,\n 'page-size-options': [5, 10, 15],\n 'selected-row-ids': [],\n editable: false,\n },\n};\n\nexport const Hover: Story = {\n render: (args) => {\n const columns = args.columns || createDemoColumns();\n const data = args.data || createDemoData();\n return html`\n <modus-wc-table\n .columns=${columns}\n .data=${data}\n .density=${args.density}\n .hover=${args.hover}\n .sortable=${args.sortable}\n .paginated=${args.paginated}\n .showPageSizeSelector=${args['show-page-size-selector']}\n .customClass=${args['custom-class']}\n .selectable=${args.selectable}\n .zebra=${args.zebra}\n .currentPage=${args['current-page']}\n .pageSizeOptions=${args['page-size-options']}\n .selectedRowIds=${args['selected-row-ids']}\n .editable=${args.editable}\n @rowClick=${action('rowClick')}\n ></modus-wc-table>\n <script>\n // This script provides sample data and configuration for the modus-wc-table demonstration.\n // const createDemoColumns = () => [\n // {\n // id: 'id',\n // header: 'ID',\n // accessor: 'id',\n // width: '60px',\n // },\n // {\n // id: 'name',\n // header: 'Name',\n // accessor: 'name',\n // width: '100px',\n // },\n // {\n // id: 'email',\n // header: 'Email',\n // accessor: 'email',\n // },\n // {\n // id: 'role',\n // header: 'Role',\n // accessor: 'role',\n // },\n // ];\n\n // const createDemoData = (count = 5) => {\n // const data = [];\n // for (let i = 1; i <= count; i++) {\n // data.push({\n // id: i.toString(),\n // name: \\`User \\${i}\\`,\n // email: \\`user\\${i}@example.com\\`,\n // role: i % 2 === 0 ? 'Admin' : 'User',\n // });\n // }\n // return data;\n // };\n // const table = document.querySelector('modus-wc-table');\n // table.columns = createDemoColumns();\n // table.data = createDemoData();\n </script>\n `;\n },\n args: {\n density: 'comfortable',\n hover: true,\n },\n};\n\nexport const Sorting: Story = {\n render: (args) => {\n const columns = args.columns || createSortableColumns();\n const data = args.data || createDemoData();\n return html`\n <modus-wc-table\n .columns=${columns}\n .data=${data}\n .density=${args.density}\n .hover=${args.hover}\n .sortable=${args.sortable}\n .paginated=${args.paginated}\n .showPageSizeSelector=${args['show-page-size-selector']}\n .customClass=${args['custom-class']}\n .selectable=${args.selectable}\n .zebra=${args.zebra}\n .currentPage=${args['current-page']}\n .pageSizeOptions=${args['page-size-options']}\n .selectedRowIds=${args['selected-row-ids']}\n .editable=${args.editable}\n @sortChange=${action('sortChange')}\n ></modus-wc-table>\n <script>\n // This script provides sample data and configuration for the modus-wc-table demonstration.\n // const createDemoColumns = () => [\n // {\n // id: 'id',\n // header: 'ID',\n // accessor: 'id',\n // width: '60px',\n // },\n // {\n // id: 'name',\n // header: 'Name',\n // accessor: 'name',\n // width: '100px',\n // },\n // {\n // id: 'email',\n // header: 'Email',\n // accessor: 'email',\n // },\n // {\n // id: 'role',\n // header: 'Role',\n // accessor: 'role',\n // },\n // ];\n\n // const createSortableColumns = () => {\n // const columns = createDemoColumns();\n // return columns.map((col) => ({ ...col, sortable: true }));\n // };\n\n // const createDemoData = (count = 5) => {\n // const data = [];\n // for (let i = 1; i <= count; i++) {\n // data.push({\n // id: i.toString(),\n // name: \\`User \\${i}\\`,\n // email: \\`user\\${i}@example.com\\`,\n // role: i % 2 === 0 ? 'Admin' : 'User',\n // });\n // }\n // return data;\n // };\n\n // const table = document.querySelector('modus-wc-table');\n // table.columns = createSortableColumns();\n // table.data = createDemoData();\n </script>\n `;\n },\n args: {\n density: 'comfortable',\n sortable: true,\n },\n};\n\nexport const Pagination: Story = {\n render: (args) => {\n const columns = args.columns || createDemoColumns();\n const data = args.data || createDemoData(15);\n return html`\n <modus-wc-table\n .columns=${columns}\n .data=${data}\n .density=${args.density}\n .hover=${args.hover}\n .sortable=${args.sortable}\n .paginated=${args.paginated}\n .showPageSizeSelector=${args['show-page-size-selector']}\n .customClass=${args['custom-class']}\n .selectable=${args.selectable}\n .zebra=${args.zebra}\n .currentPage=${args['current-page']}\n .pageSizeOptions=${args['page-size-options']}\n .selectedRowIds=${args['selected-row-ids']}\n .editable=${args.editable}\n @paginationChange=${action('paginationChange')}\n ></modus-wc-table>\n <script>\n // This script provides sample data and configuration for the modus-wc-table demonstration.\n // const createDemoColumns = () => [\n // {\n // id: 'id',\n // header: 'ID',\n // accessor: 'id',\n // width: '60px',\n // },\n // {\n // id: 'name',\n // header: 'Name',\n // accessor: 'name',\n // width: '100px',\n // },\n // {\n // id: 'email',\n // header: 'Email',\n // accessor: 'email',\n // },\n // {\n // id: 'role',\n // header: 'Role',\n // accessor: 'role',\n // },\n // ];\n\n // const createDemoData = (count = 5) => {\n // const data = [];\n // for (let i = 1; i <= count; i++) {\n // data.push({\n // id: i.toString(),\n // name: \\`User \\${i}\\`,\n // email: \\`user\\${i}@example.com\\`,\n // role: i % 2 === 0 ? 'Admin' : 'User',\n // });\n // }\n // return data;\n // };\n\n // const table = document.querySelector('modus-wc-table');\n // table.columns = createDemoColumns();\n // table.data = createDemoData(15);\n // table.paginated = true;\n </script>\n `;\n },\n args: {\n density: 'comfortable',\n paginated: true,\n 'show-page-size-selector': true,\n },\n};\n\nexport const CheckBoxRowSelection: Story = {\n render: (args) => {\n const columns = args.columns || createDemoColumns();\n const data = args.data || createDemoData();\n return html`\n <modus-wc-table\n .columns=${columns}\n .data=${data}\n .density=${args.density}\n .hover=${args.hover}\n .sortable=${args.sortable}\n .paginated=${args.paginated}\n .showPageSizeSelector=${args['show-page-size-selector']}\n .customClass=${args['custom-class']}\n .selectable=${args.selectable}\n .zebra=${args.zebra}\n .currentPage=${args['current-page']}\n .pageSizeOptions=${args['page-size-options']}\n .selectedRowIds=${args['selected-row-ids']}\n .editable=${args.editable}\n @rowSelectionChange=${action('rowSelectionChange')}\n ></modus-wc-table>\n <script>\n // This script provides sample data and configuration for the modus-wc-table demonstration.\n // const createDemoColumns = () => [\n // {\n // id: 'id',\n // header: 'ID',\n // accessor: 'id',\n // width: '60px',\n // },\n // {\n // id: 'name',\n // header: 'Name',\n // accessor: 'name',\n // width: '100px',\n // },\n // {\n // id: 'email',\n // header: 'Email',\n // accessor: 'email',\n // },\n // {\n // id: 'role',\n // header: 'Role',\n // accessor: 'role',\n // },\n // ];\n\n // const createDemoData = (count = 5) => {\n // const data = [];\n // for (let i = 1; i <= count; i++) {\n // data.push({\n // id: i.toString(),\n // name: \\`User \\${i}\\`,\n // email: \\`user\\${i}@example.com\\`,\n // role: i % 2 === 0 ? 'Admin' : 'User',\n // });\n // }\n // return data;\n // };\n\n // const table = document.querySelector('modus-wc-table');\n // table.columns = createDemoColumns();\n // table.data = createDemoData();\n // table.selectable = 'multi';\n </script>\n `;\n },\n args: {\n density: 'comfortable',\n selectable: 'multi',\n },\n};\n\nexport const InlineEditing: Story = {\n render: (args) => {\n const columns: ITableColumn[] = [\n {\n id: 'id',\n header: 'ID',\n accessor: 'id',\n width: '20px',\n },\n {\n id: 'name',\n header: 'Name',\n accessor: 'name',\n editor: 'text',\n },\n {\n id: 'status',\n header: 'Status',\n accessor: 'status',\n editor: 'custom',\n customEditorRenderer: (value, onCommit) => {\n const container = document.createElement('div');\n container.style.width = '100%';\n\n const autocomplete = document.createElement('modus-wc-autocomplete');\n autocomplete.items = [\n { label: 'Active', value: 'Active', visibleInMenu: true },\n { label: 'Inactive', value: 'Inactive', visibleInMenu: true },\n { label: 'Pending', value: 'Pending', visibleInMenu: true },\n ];\n autocomplete.value = value as string;\n autocomplete.style.width = '100%';\n\n const handleItemSelect = (e: CustomEvent<IAutocompleteItem>) => {\n onCommit(e.detail.value);\n };\n\n autocomplete.addEventListener(\n 'itemSelect',\n handleItemSelect as EventListener\n );\n container.appendChild(autocomplete);\n\n setTimeout(() => {\n const input = autocomplete.querySelector('input');\n input?.focus();\n }, 0);\n\n return container;\n },\n cellRenderer: (value) => {\n const statusColors = {\n Active: 'green',\n Inactive: 'gray',\n Pending: 'blue',\n };\n const color = statusColors[value as string] || 'black';\n const span = document.createElement('span');\n span.textContent = value as string;\n span.style.color = color;\n span.style.fontWeight = 'bold';\n return span;\n },\n },\n {\n id: 'dueDate',\n header: 'Due Date',\n accessor: 'dueDate',\n editor: 'custom',\n customEditorRenderer: (value, onCommit) => {\n const container = document.createElement('div');\n container.style.width = '100%';\n\n const datePicker = document.createElement('modus-wc-date');\n datePicker.value = value as string;\n datePicker.style.width = '100%';\n datePicker.bordered = false;\n\n let isCommitting = false;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n const input = datePicker.querySelector('input');\n if (input && input.value && !isCommitting) {\n isCommitting = true;\n onCommit(input.value);\n }\n } else if (e.key === 'Escape') {\n e.preventDefault();\n if (!isCommitting) {\n isCommitting = true;\n onCommit(value || '');\n }\n } else if (e.key === 'Tab') {\n // Allow Tab to commit and move to next cell\n const input = datePicker.querySelector('input');\n if (input && input.value && !isCommitting) {\n isCommitting = true;\n onCommit(input.value);\n }\n }\n };\n\n // Only commit when focus leaves the entire container (not just the input)\n const handleContainerBlur = (e: FocusEvent) => {\n const relatedTarget = e.relatedTarget as HTMLElement;\n\n // If focus is moving within the container or date picker, don't commit\n if (\n relatedTarget &&\n (container.contains(relatedTarget) ||\n datePicker.shadowRoot?.contains(relatedTarget))\n ) {\n return;\n }\n\n const calendar = datePicker.shadowRoot?.querySelector(\n '[class*=\"calendar\"]'\n );\n if (calendar) {\n return;\n }\n\n const input = datePicker.querySelector('input');\n if (input && input.value && !isCommitting) {\n isCommitting = true;\n setTimeout(() => onCommit(input.value), 50);\n }\n };\n\n container.addEventListener('keydown', handleKeyDown);\n container.addEventListener('focusout', handleContainerBlur);\n container.appendChild(datePicker);\n\n setTimeout(() => {\n const input = datePicker.querySelector('input');\n input?.focus();\n }, 0);\n\n return container;\n },\n cellRenderer: (value): string => {\n if (!value) return '-';\n\n // Parse dd-mm-yyyy format from date picker\n const dateString = value as string;\n const parts = dateString.split(/[-/]/);\n\n let date: Date;\n if (parts.length === 3 && parts[0].length <= 2) {\n // Assume dd-mm-yyyy or dd/mm/yyyy format\n const day = parseInt(parts[0], 10);\n const month = parseInt(parts[1], 10) - 1; // Month is 0-indexed\n const year = parseInt(parts[2], 10);\n date = new Date(year, month, day);\n } else {\n // Fallback to default parsing\n date = new Date(dateString);\n }\n\n // Check if date is valid\n if (isNaN(date.getTime())) {\n return dateString; // Return original value if parsing fails\n }\n\n // Format date with dashes: dd-mm-yyyy\n const formattedDay = date.getDate().toString().padStart(2, '0');\n const formattedMonth = (date.getMonth() + 1)\n .toString()\n .padStart(2, '0');\n const formattedYear = date.getFullYear();\n\n return `${formattedDay}-${formattedMonth}-${formattedYear}`;\n },\n },\n ];\n\n const data = [\n {\n id: '1',\n name: 'John Doe',\n status: 'Active',\n dueDate: '15-10-2025',\n },\n {\n id: '2',\n name: 'Jane Smith',\n status: 'Inactive',\n dueDate: '20-11-2025',\n },\n {\n id: '3',\n name: 'Bob Johnson',\n status: 'Pending',\n dueDate: '05-12-2025',\n },\n ];\n\n return html`\n <modus-wc-table\n .columns=${columns}\n .data=${data}\n .density=${args.density}\n .hover=${args.hover}\n .sortable=${args.sortable}\n .paginated=${args.paginated}\n .showPageSizeSelector=${args['show-page-size-selector']}\n .customClass=${args['custom-class']}\n .selectable=${args.selectable}\n .zebra=${args.zebra}\n .currentPage=${args['current-page']}\n .pageSizeOptions=${args['page-size-options']}\n .selectedRowIds=${args['selected-row-ids']}\n .editable=${true}\n @cellEditStart=${action('cellEditStart')}\n @cellEditCommit=${action('cellEditCommit')}\n ></modus-wc-table>\n <script>\n // This script provides sample data and configuration for the modus-wc-table demonstration.\n // const columns = [\n // {\n // id: 'id',\n // header: 'ID',\n // accessor: 'id',\n // width: '20px',\n // },\n // {\n // id: 'name',\n // header: 'Name',\n // accessor: 'name',\n // editor: 'text',\n // },\n // {\n // id: 'status',\n // header: 'Status',\n // accessor: 'status',\n // editor: 'custom',\n // customEditorRenderer: (value, onCommit) => {\n // const container = document.createElement('div');\n // container.style.width = '100%';\n\n // const autocomplete = document.createElement('modus-wc-autocomplete');\n // autocomplete.items = [\n // { label: 'Active', value: 'Active', visibleInMenu: true },\n // { label: 'Inactive', value: 'Inactive', visibleInMenu: true },\n // { label: 'Pending', value: 'Pending', visibleInMenu: true },\n // ];\n // autocomplete.value = value;\n // autocomplete.style.width = '100%';\n\n // const handleItemSelect = (e) => {\n // onCommit(e.detail.value);\n // };\n\n // autocomplete.addEventListener(\n // 'itemSelect',\n // handleItemSelect\n // );\n // container.appendChild(autocomplete);\n\n // setTimeout(() => {\n // const input = autocomplete.querySelector('input');\n // input?.focus();\n // }, 0);\n\n // return container;\n // },\n // cellRenderer: (value) => {\n // const statusColors = {\n // Active: 'green',\n // Inactive: 'gray',\n // Pending: 'blue',\n // };\n // const color = statusColors[value] || 'black';\n // const span = document.createElement('span');\n // span.textContent = value;\n // span.style.color = color;\n // span.style.fontWeight = 'bold';\n // return span;\n // },\n // },\n // {\n // id: 'dueDate',\n // header: 'Due Date',\n // accessor: 'dueDate',\n // editor: 'custom',\n // customEditorRenderer: (value, onCommit) => {\n // const container = document.createElement('div');\n // container.style.width = '100%';\n\n // const datePicker = document.createElement('modus-wc-date');\n // datePicker.value = value;\n // datePicker.style.width = '100%';\n // datePicker.bordered = false;\n\n // let isCommitting = false;\n\n // const handleKeyDown = (e) => {\n // if (e.key === 'Enter') {\n // e.preventDefault();\n // const input = datePicker.querySelector('input');\n // if (input && input.value && !isCommitting) {\n // isCommitting = true;\n // onCommit(input.value);\n // }\n // } else if (e.key === 'Escape') {\n // e.preventDefault();\n // if (!isCommitting) {\n // isCommitting = true;\n // onCommit(value || '');\n // }\n // } else if (e.key === 'Tab') {\n // const input = datePicker.querySelector('input');\n // if (input && input.value && !isCommitting) {\n // isCommitting = true;\n // onCommit(input.value);\n // }\n // }\n // };\n\n // const handleContainerBlur = (e) => {\n // const relatedTarget = e.relatedTarget;\n\n // if (relatedTarget && (container.contains(relatedTarget) || datePicker.shadowRoot?.contains(relatedTarget))) {\n // return;\n // }\n\n // const calendar = datePicker.shadowRoot?.querySelector('[class*=\"calendar\"]');\n // if (calendar) {\n // return;\n // }\n\n // const input = datePicker.querySelector('input');\n // if (input && input.value && !isCommitting) {\n // isCommitting = true;\n // setTimeout(() => onCommit(input.value), 50);\n // }\n // };\n\n // container.addEventListener('keydown', handleKeyDown);\n // container.addEventListener('focusout', handleContainerBlur);\n // container.appendChild(datePicker);\n\n // setTimeout(() => {\n // const input = datePicker.querySelector('input');\n // input?.focus();\n // }, 0);\n\n // return container;\n // },\n // cellRenderer: (value) => {\n // if (!value) return '-';\n\n // // Parse dd-mm-yyyy format from date picker\n // const dateString = value;\n // const parts = dateString.split(/[-/]/);\n\n // let date;\n // if (parts.length === 3 && parts[0].length <= 2) {\n // // Assume dd-mm-yyyy or dd/mm/yyyy format\n // const day = parseInt(parts[0], 10);\n // const month = parseInt(parts[1], 10) - 1; // Month is 0-indexed\n // const year = parseInt(parts[2], 10);\n // date = new Date(year, month, day);\n // } else {\n // // Fallback to default parsing\n // date = new Date(dateString);\n // }\n\n // // Check if date is valid\n // if (isNaN(date.getTime())) {\n // return dateString; // Return original value if parsing fails\n // }\n\n // // Format date with dashes: dd-mm-yyyy\n // const formattedDay = date.getDate().toString().padStart(2, '0');\n // const formattedMonth = (date.getMonth() + 1).toString().padStart(2, '0');\n // const formattedYear = date.getFullYear();\n\n // return \\`\\${formattedDay}-\\${formattedMonth}-\\${formattedYear}\\`;\n // },\n // },\n // ];\n\n // const data = [\n // {\n // id: '1',\n // name: 'John Doe',\n // status: 'Active',\n // dueDate: '15-10-2025',\n // },\n // {\n // id: '2',\n // name: 'Jane Smith',\n // status: 'Inactive',\n // dueDate: '20-11-2025',\n // },\n // {\n // id: '3',\n // name: 'Bob Johnson',\n // status: 'Pending',\n // dueDate: '05-12-2025',\n // },\n // ];\n // const table = document.querySelector('modus-wc-table');\n // table.columns = columns;\n // table.data = data;\n // table.editable = true;\n </script>\n `;\n },\n args: {\n density: 'comfortable',\n hover: true,\n sortable: true,\n paginated: false,\n 'show-page-size-selector': true,\n 'custom-class': '',\n selectable: 'none',\n zebra: false,\n 'current-page': 1,\n 'page-size-options': [5, 10, 15],\n 'selected-row-ids': [],\n },\n};\n"
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "A customizable tabs component used to create groups of tabs. The component supports a `<slot>` for injecting custom tab content.",
|
|
3
|
+
"properties": [
|
|
4
|
+
{
|
|
5
|
+
"name": "activeTabIndex",
|
|
6
|
+
"type": "number",
|
|
7
|
+
"description": "The current active tab",
|
|
8
|
+
"default": "0",
|
|
9
|
+
"mutable": true,
|
|
10
|
+
"end_line": 54
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "customClass",
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "Custom CSS class to apply to the inner div.",
|
|
16
|
+
"default": "''",
|
|
17
|
+
"mutable": false,
|
|
18
|
+
"end_line": 57
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "size",
|
|
22
|
+
"type": "ModusSize",
|
|
23
|
+
"description": "The size of the tabs.",
|
|
24
|
+
"default": "'md'",
|
|
25
|
+
"mutable": false,
|
|
26
|
+
"end_line": 60
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "tabs",
|
|
30
|
+
"type": "ITab[]",
|
|
31
|
+
"description": "The tabs to display.",
|
|
32
|
+
"default": "[]",
|
|
33
|
+
"mutable": false,
|
|
34
|
+
"end_line": 63
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "tabStyle",
|
|
38
|
+
"type": "'boxed' | 'bordered' | 'lifted' | 'none'",
|
|
39
|
+
"description": "Additional styling for the tabs.",
|
|
40
|
+
"default": "'bordered'",
|
|
41
|
+
"mutable": false,
|
|
42
|
+
"end_line": 66
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"events": [
|
|
46
|
+
{
|
|
47
|
+
"name": "tabChange",
|
|
48
|
+
"detail": "{ previousTab: number; newTab: number; }",
|
|
49
|
+
"description": "When a tab is switched to, this event outputs the relevant indices",
|
|
50
|
+
"end_line": 72
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"methods": [],
|
|
54
|
+
"slots": [
|
|
55
|
+
{
|
|
56
|
+
"name": "default",
|
|
57
|
+
"description": "Slot for default content"
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"examples": {
|
|
61
|
+
"basic": "<modus-wc-tabs\n active-tab-index=\"${ifDefined(args.activeTabIndex)}\"\n aria-label=\"Tab group\"\n tab-style=\"${ifDefined(args['tab-style'])}\"\n .tabs=${args.tabs}\n size=\"${ifDefined(args.size)}\"\n>\n</modus-wc-tabs>",
|
|
62
|
+
"variations": [],
|
|
63
|
+
"args": {
|
|
64
|
+
"size": "'md'",
|
|
65
|
+
"tab-style": "'bordered'"
|
|
66
|
+
},
|
|
67
|
+
"argTypes": {},
|
|
68
|
+
"usage": [],
|
|
69
|
+
"events": [
|
|
70
|
+
"tabChange"
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
"tag": "modus-wc-tabs",
|
|
74
|
+
"storyExample": {
|
|
75
|
+
"template": "<modus-wc-tabs\n active-tab-index=\"${ifDefined(args.activeTabIndex)}\"\n aria-label=\"Tab group\"\n tab-style=\"${ifDefined(args['tab-style'])}\"\n .tabs=${args.tabs}\n size=\"${ifDefined(args.size)}\"\n>\n</modus-wc-tabs>",
|
|
76
|
+
"args": {
|
|
77
|
+
"size": "'md'",
|
|
78
|
+
"tab-style": "'bordered'"
|
|
79
|
+
},
|
|
80
|
+
"argTypes": {},
|
|
81
|
+
"events": [
|
|
82
|
+
"tabChange"
|
|
83
|
+
],
|
|
84
|
+
"fullContent": "import { withActions } from '@storybook/addon-actions/decorator';\nimport { Meta, StoryObj } from '@storybook/web-components';\nimport { html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { ITab } from './modus-wc-tabs';\nimport { DaisySize } from '../types';\n\ninterface TabsArgs {\n activeTabIndex?: number;\n 'custom-class'?: string;\n size?: DaisySize;\n tabs: ITab[];\n 'tab-style': 'boxed' | 'bordered' | 'lifted' | 'none';\n}\n\nconst meta: Meta<TabsArgs> = {\n title: 'Components/Tabs',\n component: 'modus-wc-tabs',\n args: {\n size: 'md',\n tabs: [\n { label: 'Tab 1' },\n { label: 'Tab 2' },\n { label: 'Tab 3', disabled: true },\n { icon: 'home' },\n ],\n 'tab-style': 'bordered',\n },\n argTypes: {\n tabs: {\n description: 'Array of tab objects defining the tabs to display',\n table: {\n type: {\n detail: `\n Interface: ITab\n Properties:\n - customClass (string, optional): Custom CSS class for the inner button\n - disabled (boolean, optional): Whether the tab is disabled\n - icon (string, optional): A Modus Icon name to display\n - iconPosition ('left' | 'right', optional): The position of the icon\n - label (string, optional): The content to display in the tab\n - slotName (string, optional): The slot name to use for custom tab header content\n `,\n },\n },\n },\n 'tab-style': {\n control: { type: 'select' },\n options: ['boxed', 'bordered', 'lifted', 'none'],\n },\n size: {\n control: { type: 'select' },\n options: ['xs', 'sm', 'md', 'lg'],\n },\n },\n decorators: [\n withActions,\n (story, context) => {\n // Normalize tabs before rendering the story\n const { tabs } = context.args ?? {};\n\n if (Array.isArray(tabs)) {\n context.args.tabs = normalizeTabs(tabs);\n }\n\n return story();\n },\n ],\n parameters: {\n actions: {\n handles: ['tabChange'],\n },\n },\n};\n\nexport default meta;\n\n// Shared normalization function used by both decorator and source code\nconst normalizeTabs = (tabs: ITab[]) => {\n return tabs.map((tab) => {\n const normalized = { ...tab };\n // Only keep disabled when it is explicitly true\n if (normalized.disabled !== true) {\n delete normalized.disabled;\n }\n return normalized;\n });\n};\n\nconst getSourceCode = (tabs: ITab[]) => {\n const normalizedTabs = normalizeTabs(tabs);\n return `\n<script>\n const tabs = ${JSON.stringify(normalizedTabs, null, 2)};\n const tabElement = document.querySelector('modus-wc-tabs');\n tabElement.tabs = tabs;\n</script>`;\n};\n\ntype Story = StoryObj<TabsArgs>;\n\nconst Template: Story = {\n parameters: {\n docs: {\n source: {\n transform: (_src, { args }) => `<modus-wc-tabs\n aria-label=\"Tab group\"\n tab-style=\"${ifDefined(args['tab-style'])}\"\n size=\"${ifDefined(args.size)}\">\n</modus-wc-tabs>${getSourceCode(args.tabs as ITab[])}`,\n },\n },\n },\n render: (args) => {\n // prettier-ignore\n return html`\n<modus-wc-tabs\n active-tab-index=\"${ifDefined(args.activeTabIndex)}\"\n aria-label=\"Tab group\"\n tab-style=\"${ifDefined(args['tab-style'])}\"\n .tabs=${args.tabs}\n size=\"${ifDefined(args.size)}\"\n>\n</modus-wc-tabs>\n `;\n },\n};\n\nexport const Default: Story = { ...Template };\n\nexport const CustomContent: Story = {\n args: {\n tabs: [\n {\n icon: 'home',\n iconPosition: 'left',\n label: 'Home',\n slotName: 'home-tab-content',\n },\n {\n icon: 'clipboard',\n iconPosition: 'right',\n label: 'Tasks',\n },\n {\n slotName: 'actions-tab-content',\n },\n {\n slotName: 'notifications-tab-content',\n },\n ],\n },\n parameters: {\n docs: {\n description: {\n story:\n 'Tabs now include slots, offering a flexible approach for users to add relevant components within the tab for more complex use cases.',\n },\n source: {\n transform: (_src, { args }) => `<style>\n .red-icon {\n color: red;\n }\n /* Style for disabled badge and icon components */\n modus-wc-badge[disabled=\"true\"],\n modus-wc-icon[disabled=\"true\"] ,\n button[disabled] modus-wc-badge,\n button[disabled] modus-wc-icon {\n opacity: 0.3;\n pointer-events: none;\n }\n</style>\n<modus-wc-tabs\n size=\"md\"\n tab-style=\"bordered\"\n aria-label=\"Custom tab group\"\n>\n <span\n slot=\"home-tab-content\"\n style=\"display: inline-flex; align-items: center;padding-top: 6px\"\n >\n <modus-wc-badge\n color=\"warning\"\n size=\"md\"\n variant=\"filled\"\n >\n <modus-wc-icon decorative=\"\" name=\"home\" size=\"xs\"></modus-wc-icon>\n Home\n </modus-wc-badge>\n </span>\n <span\n slot=\"actions-tab-content\"\n style=\"display: inline-flex; align-items: center; gap: 8px;\"\n >\n Actions\n <modus-wc-icon\n name=\"warning\"\n variant=\"solid\"\n size=\"md\"\n custom-class=\"red-icon\"\n ></modus-wc-icon>\n </span>\n <span\n slot=\"notifications-tab-content\"\n style=\"display: inline-flex; align-items: center; gap: 8px;\"\n >\n Notifications\n <modus-wc-badge\n color=\"primary\"\n size=\"md\"\n variant=\"counter\"\n >5</modus-wc-badge\n >\n </span>\n</modus-wc-tabs>${getSourceCode(args.tabs as ITab[])}`,\n },\n },\n },\n\n // prettier-ignore\n render: (args) => {\n return html`\n <style>\n .red-icon {\n color: red;\n }\n /* Style for disabled badge and icon components */\n modus-wc-badge[disabled=\"true\"],\n modus-wc-icon[disabled=\"true\"] ,\n button[disabled] modus-wc-badge,\n button[disabled] modus-wc-icon {\n opacity: 0.3;\n pointer-events: none;\n }\n </style>\n <modus-wc-tabs\n .tabs=${args.tabs}\n size=\"${ifDefined(args.size)}\"\n tab-style=\"${ifDefined(args['tab-style'])}\"\n active-tab-index=\"${ifDefined(args.activeTabIndex)}\"\n aria-label=\"Custom tab group\"\n >\n <span\n slot=\"home-tab-content\"\n style=\"display: inline-flex; align-items: center;padding-top: 6px\"\n >\n <modus-wc-badge\n color=\"warning\"\n size=\"${ifDefined(args.size)}\"\n variant=\"filled\"\n >\n <modus-wc-icon decorative=\"\" name=\"home\" size=\"xs\"></modus-wc-icon>\n Home\n </modus-wc-badge>\n </span>\n <span\n slot=\"actions-tab-content\"\n style=\"display: inline-flex; align-items: center; gap: 8px;\"\n >\n Actions\n <modus-wc-icon\n name=\"warning\"\n variant=\"solid\"\n size=\"${ifDefined(args.size)}\"\n custom-class=\"red-icon\"\n ></modus-wc-icon>\n </span>\n <span\n slot=\"notifications-tab-content\"\n style=\"display: inline-flex; align-items: center; gap: 8px;\"\n >\n Notifications\n <modus-wc-badge\n color=\"primary\"\n size=\"${ifDefined(args.size)}\"\n variant=\"counter\"\n >5</modus-wc-badge\n >\n </span>\n </modus-wc-tabs>\n \n `;\n },\n};\n\nexport const ActiveAndDisabled: Story = {\n ...Template,\n args: {\n activeTabIndex: 1,\n tabs: [\n { label: 'Normal' },\n { label: 'Active' },\n { label: 'Disabled', disabled: true },\n ],\n },\n};\n\nexport const Icons: Story = {\n ...Template,\n args: {\n tabs: [\n { icon: 'home' },\n { icon: 'settings', iconPosition: 'left', label: 'Settings' },\n {\n icon: 'alert',\n iconPosition: 'right',\n label: 'Alerts',\n },\n ],\n },\n};\n\nexport const TabsWithPanel: Story = {\n parameters: {\n docs: {\n source: {\n transform: (_src, { args }) => `<modus-wc-tabs\n aria-label=\"Tab group\"\n tab-style=\"bordered\"\n size=\"md\"\n>\n <p slot=\"tab-0\">\n Modus (noun) : a mode of procedure : a way of doing something\n </p>\n <p slot=\"tab-1\">\n input (noun) : information fed into a data processing system or computer\n </p>\n <p slot=\"tab-2\">\n secret (noun) : kept from knowledge or view : hidden\n </p>\n <p slot=\"tab-3\">\n snapshot (noun) : an impression or view of something brief or transitory\n </p>\n</modus-wc-tabs>${getSourceCode(args.tabs as ITab[])}`,\n },\n },\n },\n render: (args) => {\n // prettier-ignore\n return html`\n<modus-wc-tabs\n active-tab-index=\"${ifDefined(args.activeTabIndex)}\"\n aria-label=\"Tab group\"\n custom-class=\"${ifDefined(args['custom-class'])}\"\n ?img-src=\"${args['img-src']}\"\n tab-style=\"${ifDefined(args['tab-style'])}\"\n .tabs=${args.tabs}\n size=\"${ifDefined(args.size)}\"\n>\n <p slot=\"tab-0\">\n Modus (noun) : a mode of procedure : a way of doing something\n </p>\n <p slot=\"tab-1\">\n input (noun) : information fed into a data processing system or computer\n </p>\n <p slot=\"tab-2\">\n secret (noun) : kept from knowledge or view : hidden\n </p>\n <p slot=\"tab-3\">\n snapshot (noun) : an impression or view of something brief or transitory\n </p>\n</modus-wc-tabs>\n `;\n },\n};\n\nexport const Migration: Story = {\n parameters: {\n docs: {\n description: {\n story: `\n#### Breaking Changes\n\n - In 2.0 tabs use the \\`ITab\\` interface, see details of interface changes below.\n - Size values have changed from verbose names (\\`small\\`, \\`medium\\`) to abbreviations (\\`xs\\`, \\`sm\\`, \\`md\\`, \\`lg\\`).\n - The \\`tabChange\\` event now emits an object with both previous and new tab indices, rather than just the tab ID.\n\n#### Prop Mapping\n\n| 1.0 Prop | 2.0 Prop | Notes |\n|--------------|--------------------|----------------------------------------------------------------|\n| aria-label | aria-label | |\n| full-width | | Not carried over, use CSS instead |\n| size | size | \\`small\\` → \\`sm\\`, \\`medium\\` → \\`md\\` |\n| tabs | tabs | Tab object structure has changed. See Interface changes below. |\n\n#### Event Mapping\n\n| 1.0 Event | 2.0 Event | Notes |\n|-------------|-----------|-------------------------------------------------------|\n| tabChange | tabChange | Now emits \\`{ previousTab: number; newTab: number }\\` |\n\n#### Interfaces\n\n##### 1.0\n\n\\`\\`\\`typescript\nexport interface Tab {\n active?: boolean;\n iconOnly?: string;\n id: string;\n label?: string;\n leftIcon?: string;\n rightIcon?: string;\n}\n\\`\\`\\`\n\n##### 2.0\n\n\\`\\`\\`typescript\nexport interface ITab {\n customClass?: string;\n disabled?: boolean;\n icon?: string;\n iconPosition?: 'left' | 'right';\n label?: string;\n}\n\\`\\`\\`\n `,\n },\n },\n controls: { disable: true },\n canvas: { disable: true },\n },\n render: () => html`<div></div>`,\n};\n"
|
|
85
|
+
}
|
|
86
|
+
}
|