@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,374 @@
|
|
|
1
|
+
import { Meta } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
<Meta title="Documentation/Frameworks/Angular" />
|
|
4
|
+
|
|
5
|
+
# Angular Framework Integration
|
|
6
|
+
|
|
7
|
+
This guide will help you get started with consuming the Modus Angular Web Component library in your Angular project.
|
|
8
|
+
|
|
9
|
+
We highly recommend using the Modus Angular Components library for Angular based projects.
|
|
10
|
+
These components are automatically generated using the Stencil Angular Framework Integration.
|
|
11
|
+
|
|
12
|
+
Follow the steps outlined below to integrate and use Modus Angular Web Components effectively.
|
|
13
|
+
|
|
14
|
+
Please refer to the [official stencil documentation](https://stenciljs.com/docs/angular#consumer-usage) for more information on how to integrate with your Angular project.
|
|
15
|
+
|
|
16
|
+
## Angular with modules
|
|
17
|
+
|
|
18
|
+
Modus Angular Components have a peer dependency with Modus Web Components and require the
|
|
19
|
+
installation of both packages.
|
|
20
|
+
|
|
21
|
+
### 1. Install both `modus-wc` and `modus-wc-angular` dependencies:
|
|
22
|
+
|
|
23
|
+
Ensure that you specify the target version of Angular for the `modus-wc-angular` package (e.g., `ng18` for Angular 18).
|
|
24
|
+
|
|
25
|
+
<b>
|
|
26
|
+
Lock the installed package versions to avoid unintended breakages on future
|
|
27
|
+
npm installs.
|
|
28
|
+
</b>
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install @trimble-oss/moduswebcomponents @trimble-oss/moduswebcomponents-angular@<latest-version>-ng<target-version>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 2. Set up the styling:
|
|
35
|
+
|
|
36
|
+
You will need to import our styling in your main JavaScript or CSS file:
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
import '@trimble-oss/moduswebcomponents/modus-wc-styles.css';
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 3. Configure asset copying in `angular.json`:
|
|
43
|
+
|
|
44
|
+
For components that use static assets (like `modus-wc-logo`), you need to configure Angular to copy the assets to your build output.
|
|
45
|
+
|
|
46
|
+
Add this to your `angular.json` under `projects > your-app > architect > build > options`:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"projects": {
|
|
51
|
+
"your-app": {
|
|
52
|
+
"architect": {
|
|
53
|
+
"build": {
|
|
54
|
+
"options": {
|
|
55
|
+
"assets": [
|
|
56
|
+
{
|
|
57
|
+
"glob": "**/*",
|
|
58
|
+
"input": "node_modules/@trimble-oss/moduswebcomponents/assets",
|
|
59
|
+
"output": "/assets"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 4. Import Modus Angular Web Components library into your Angular app's module:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
// app.module.ts
|
|
74
|
+
import { ModusAngularComponentsModule } from '@trimble-oss/moduswebcomponents-angular';
|
|
75
|
+
|
|
76
|
+
@NgModule({
|
|
77
|
+
...
|
|
78
|
+
imports: [ComponentLibraryModule],
|
|
79
|
+
...
|
|
80
|
+
})
|
|
81
|
+
export class AppModule {}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 4. Use Modus Angular Web Components while leveraging Angular template binding syntax:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
// app.component.html
|
|
88
|
+
<modus-wc-button label="Click Me" />
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Angular with standalone components
|
|
92
|
+
|
|
93
|
+
Modus Angular Components have a peer dependency with Modus Web Components and require the
|
|
94
|
+
installation of both packages.
|
|
95
|
+
|
|
96
|
+
### 1. Install both `modus-wc` and `modus-wc-angular` dependencies:
|
|
97
|
+
|
|
98
|
+
Ensure that you specify the target version of Angular for the `modus-wc-angular` package (e.g., `ng18` for Angular 18).
|
|
99
|
+
|
|
100
|
+
<b>
|
|
101
|
+
Lock the installed package versions to avoid unintended breakages on future
|
|
102
|
+
npm installs.
|
|
103
|
+
</b>
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm install @trimble-oss/moduswebcomponents @trimble-oss/moduswebcomponents-angular@<latest-version>-ng<target-version>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 2. Set up the styling:
|
|
110
|
+
|
|
111
|
+
You will need to import our styling in your main JavaScript or CSS file:
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
import '@trimble-oss/moduswebcomponents/modus-wc-styles.css';
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 3. Import your component library into your component.
|
|
118
|
+
|
|
119
|
+
You must distribute your components through a primary `NgModule` to use your components in a standalone component.
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
// app.component.ts
|
|
123
|
+
import { Component } from '@angular/core';
|
|
124
|
+
import { ModusAngularComponentsModule } from '@trimble-oss/moduswebcomponents-angular';
|
|
125
|
+
|
|
126
|
+
@Component({
|
|
127
|
+
selector: 'app-root',
|
|
128
|
+
standalone: true,
|
|
129
|
+
imports: [ModusAngularComponentsModule],
|
|
130
|
+
templateUrl: './app.component.html',
|
|
131
|
+
})
|
|
132
|
+
export class AppComponent {}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 4. Use Modus Angular Web Components while leveraging Angular template binding syntax:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
// app.component.html
|
|
139
|
+
<modus-wc-button label="Click Me" />
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Custom Elements Schema
|
|
143
|
+
|
|
144
|
+
In the `app.module.ts` file, you need to tell angular that you are using custom element schemas
|
|
145
|
+
so that it does not throw errors when unknown element names are used in the markup.
|
|
146
|
+
|
|
147
|
+
Import `CUSTOM_ELEMENTS_SCHEMA` and add it to your `@NgModule`'s schemas:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
|
151
|
+
|
|
152
|
+
@NgModule({
|
|
153
|
+
...
|
|
154
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
|
155
|
+
...
|
|
156
|
+
})
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Wrapping Components
|
|
160
|
+
|
|
161
|
+
When using Modus Web Components directly, it is recommended to wrap it in corresponding Angular components within your application. This will abstract away from the library dependency, allowing more flexibility for you and your application in the future. Each part of the component is able to be abstracted, leaving you with an Angular-native component.
|
|
162
|
+
|
|
163
|
+
Notice Angular allows `[]` and `()` markup syntax for the web component's inputs and outputs, respectively.
|
|
164
|
+
|
|
165
|
+
Wrapped Modus Button Example:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
169
|
+
|
|
170
|
+
@Component({
|
|
171
|
+
selector: 'button-component',
|
|
172
|
+
template: `
|
|
173
|
+
<modus-wc-button
|
|
174
|
+
[buttonStyle]="buttonStyle"
|
|
175
|
+
[color]="color"
|
|
176
|
+
[disabled]="disabled"
|
|
177
|
+
[size]="size"
|
|
178
|
+
(buttonClick)="onButtonClick.emit()"
|
|
179
|
+
>
|
|
180
|
+
<ng-content></ng-content>
|
|
181
|
+
</modus-wc-button>
|
|
182
|
+
`,
|
|
183
|
+
})
|
|
184
|
+
export class ButtonComponent {
|
|
185
|
+
@Input() buttonStyle: 'borderless' | 'fill' | 'outline' = 'fill';
|
|
186
|
+
@Input() color: 'danger' | 'default' | 'primary' | 'secondary' | 'warning' =
|
|
187
|
+
'default';
|
|
188
|
+
@Input() disabled: boolean;
|
|
189
|
+
@Input() size: 'small' | 'medium' | 'large' = 'medium';
|
|
190
|
+
|
|
191
|
+
@Output() onButtonClick = new EventEmitter();
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Reactive Forms
|
|
196
|
+
|
|
197
|
+
Working with a web component's inputs/outputs works great but these components do not integrate with Angular's reactive forms quite as easily. Since web components do not know about Angular's form APIs, we must extend form-compatible components' behavior with simple directives. These directives are applied to the web component selectors, giving the components Angular form functionality.
|
|
198
|
+
|
|
199
|
+
Let's take a look at a directive implementation for a Modus Select's form functionality.
|
|
200
|
+
|
|
201
|
+
#### Wrapper
|
|
202
|
+
|
|
203
|
+
You'll notice the `modus-select` in the markup is taking extra inputs, such as `formControl` and `optionsDisplayProp`, these inputs are provided by the directive below. Here is what our wrapper looks like:
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
207
|
+
import { FormControl } from '@angular/forms';
|
|
208
|
+
|
|
209
|
+
@Component({
|
|
210
|
+
selector: 'select-component',
|
|
211
|
+
template: `
|
|
212
|
+
<modus-wc-select
|
|
213
|
+
#select
|
|
214
|
+
[disabled]="disabled"
|
|
215
|
+
[errorText]="errorText"
|
|
216
|
+
[formControl]="formControl"
|
|
217
|
+
[helperText]="helperText"
|
|
218
|
+
[label]="label"
|
|
219
|
+
[options]="options"
|
|
220
|
+
[optionsDisplayProp]="optionsDisplayProp"
|
|
221
|
+
[required]="required"
|
|
222
|
+
[selectValue]="value"
|
|
223
|
+
[size]="size"
|
|
224
|
+
[validText]="validText"
|
|
225
|
+
(valueChange)="onSelectValueChange.emit(select.value)"
|
|
226
|
+
>
|
|
227
|
+
</modus-wc-select>
|
|
228
|
+
`,
|
|
229
|
+
})
|
|
230
|
+
export class SelectComponent {
|
|
231
|
+
@Input() disabled: boolean;
|
|
232
|
+
@Input() errorText: string;
|
|
233
|
+
@Input() formControl: FormControl;
|
|
234
|
+
@Input() helperText: string;
|
|
235
|
+
@Input() label: string;
|
|
236
|
+
@Input() options: unknown[] = [];
|
|
237
|
+
@Input() optionsDisplayProp: string;
|
|
238
|
+
@Input() required: boolean;
|
|
239
|
+
@Input() size: 'medium' | 'large' = 'medium';
|
|
240
|
+
@Input() validText: string;
|
|
241
|
+
@Input() value: unknown;
|
|
242
|
+
|
|
243
|
+
@Output() onSelectValueChange = new EventEmitter<unknown>();
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### Directive
|
|
248
|
+
|
|
249
|
+
Moving onto the directive, there are a few things to keep in mind.
|
|
250
|
+
|
|
251
|
+
- The directive's selector is set to the web component's tag, not the wrapper's.
|
|
252
|
+
- Implementing the `ControlValueAccessor` interface helps Angular understand when the form control has been updated or changed.
|
|
253
|
+
- When the value is set, `onChange()` notifies that the control has been updated.
|
|
254
|
+
- Calling `onTouched()` lets Angular know the component has been touched, which is needed for form validation.
|
|
255
|
+
- The `get value()`, and `set value()` are used by Angular's form control.
|
|
256
|
+
- Using the `@HostListener` decorator lets you listen to events from the web component, and execute appropriate logic.
|
|
257
|
+
|
|
258
|
+
Here is what our directive looks like:
|
|
259
|
+
|
|
260
|
+
```ts
|
|
261
|
+
import {
|
|
262
|
+
Directive,
|
|
263
|
+
forwardRef,
|
|
264
|
+
ElementRef,
|
|
265
|
+
HostListener,
|
|
266
|
+
Input,
|
|
267
|
+
OnInit,
|
|
268
|
+
Output,
|
|
269
|
+
EventEmitter,
|
|
270
|
+
} from '@angular/core';
|
|
271
|
+
import {
|
|
272
|
+
ControlValueAccessor,
|
|
273
|
+
FormControl,
|
|
274
|
+
NG_VALUE_ACCESSOR,
|
|
275
|
+
} from '@angular/forms';
|
|
276
|
+
|
|
277
|
+
@Directive({
|
|
278
|
+
selector: 'modus-wc-select',
|
|
279
|
+
providers: [
|
|
280
|
+
{
|
|
281
|
+
provide: NG_VALUE_ACCESSOR,
|
|
282
|
+
useExisting: forwardRef(() => ModusSelectDirective),
|
|
283
|
+
multi: true,
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
})
|
|
287
|
+
export class ModusSelectDirective implements ControlValueAccessor, OnInit {
|
|
288
|
+
@Input() disabled: boolean;
|
|
289
|
+
@Input() errorText: string;
|
|
290
|
+
@Input() formControl: FormControl;
|
|
291
|
+
@Input() helperText: string;
|
|
292
|
+
@Input() label: string;
|
|
293
|
+
@Input() options: unknown[];
|
|
294
|
+
@Input() optionsDisplayProp: string;
|
|
295
|
+
@Input() required: boolean;
|
|
296
|
+
@Input() selectValue: unknown;
|
|
297
|
+
@Input() size: 'medium' | 'large';
|
|
298
|
+
@Input() validText: string;
|
|
299
|
+
|
|
300
|
+
@Output() valueChange = new EventEmitter<string>();
|
|
301
|
+
|
|
302
|
+
onChange: any = () => {};
|
|
303
|
+
onTouched: any = () => {};
|
|
304
|
+
|
|
305
|
+
private _value: string;
|
|
306
|
+
|
|
307
|
+
get value() {
|
|
308
|
+
return this._value;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
set value(value) {
|
|
312
|
+
if (value !== this._value) {
|
|
313
|
+
this._value = value;
|
|
314
|
+
this.onChange(this._value);
|
|
315
|
+
this.onTouched();
|
|
316
|
+
this.elementRef.nativeElement.value = value;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
constructor(private elementRef: ElementRef) {}
|
|
321
|
+
|
|
322
|
+
ngOnInit(): void {
|
|
323
|
+
const modusSelect = this.elementRef.nativeElement as HTMLModusSelectElement;
|
|
324
|
+
modusSelect.disabled = this.disabled;
|
|
325
|
+
modusSelect.errorText = this.errorText;
|
|
326
|
+
modusSelect.helperText = this.helperText;
|
|
327
|
+
modusSelect.label = this.label;
|
|
328
|
+
modusSelect.options = this.options;
|
|
329
|
+
modusSelect.optionsDisplayProp = this.optionsDisplayProp;
|
|
330
|
+
modusSelect.required = this.required;
|
|
331
|
+
modusSelect.size = this.size;
|
|
332
|
+
modusSelect.validText = this.validText;
|
|
333
|
+
modusSelect.value = this.selectValue;
|
|
334
|
+
|
|
335
|
+
if (!this.formControl) {
|
|
336
|
+
this.formControl = new FormControl(null);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
@HostListener('valueChange', ['$event.detail'])
|
|
341
|
+
listenForValueChange(value: string): void {
|
|
342
|
+
this.value = value;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
registerOnChange(fn: Function): void {
|
|
346
|
+
this.onChange = fn;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
registerOnTouched(fn: Function): void {
|
|
350
|
+
this.onTouched = fn;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
setDisabledState(isDisabled: boolean): void {
|
|
354
|
+
this.disabled = isDisabled;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
writeValue(value: string): void {
|
|
358
|
+
if (value) {
|
|
359
|
+
this.value = value;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Now adding the Modus Select as a form control is as easy as:
|
|
366
|
+
|
|
367
|
+
```ts
|
|
368
|
+
<select-component
|
|
369
|
+
[formControl]="$any(form).controls['select1']"
|
|
370
|
+
[label]="'Select Form Demo'"
|
|
371
|
+
[options]="options"
|
|
372
|
+
[optionsDisplayProp]="'display'">
|
|
373
|
+
</select-component>
|
|
374
|
+
```
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Meta } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
<Meta title="Documentation/Getting Started" />
|
|
4
|
+
|
|
5
|
+
# Getting Started
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
<b>
|
|
10
|
+
Lock the installed package version to avoid unintended breakages on future npm
|
|
11
|
+
installs.
|
|
12
|
+
</b>
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @trimble-oss/moduswebcomponents
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### 1. Set up the styling:
|
|
21
|
+
|
|
22
|
+
You will need to import our styling in your main JavaScript or CSS file:
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
import '@trimble-oss/moduswebcomponents/modus-wc-styles.css';
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
#### Variables-Only CSS
|
|
29
|
+
|
|
30
|
+
If you want Modus styling to apply only to your components and **not affect the rest of your application**, you can import the lightweight variables-only file instead:
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
import '@trimble-oss/moduswebcomponents/modus-wc-variables.css';
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Modus components inside Shadow DOM will automatically inject their own class rules via `handleShadowDOMStyles()`, so they render correctly without the full stylesheet being loaded globally.
|
|
37
|
+
|
|
38
|
+
> **Note:** Both imports work with Shadow DOM. We recommend `modus-wc-styles.css` for new applications. Consider `modus-wc-variables.css` for existing applications where you want to avoid global style changes.
|
|
39
|
+
|
|
40
|
+
### 2. Set the theme:
|
|
41
|
+
|
|
42
|
+
The theme can be set manually or by using the `ThemeSwitcher` component. See the "Use a Theme" section of [Styling](/docs/documentation-styling--docs) for guidance.
|
|
43
|
+
|
|
44
|
+
Available themes are:
|
|
45
|
+
|
|
46
|
+
- `modus-modern-light` (default)
|
|
47
|
+
- `modus-modern-dark`
|
|
48
|
+
- `modus-classic-light`
|
|
49
|
+
- `modus-classic-dark`
|
|
50
|
+
- `connect-light`
|
|
51
|
+
- `connect-dark`
|
|
52
|
+
|
|
53
|
+
### 3. Register custom elements:
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
import { defineCustomElements } from '@trimble-oss/moduswebcomponents/loader';
|
|
57
|
+
|
|
58
|
+
// Call during the initial loading of your application
|
|
59
|
+
const Root = () => {
|
|
60
|
+
defineCustomElements();
|
|
61
|
+
|
|
62
|
+
return <App />;
|
|
63
|
+
};
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 4. Use the components:
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
// Use in HTML
|
|
70
|
+
<modus-wc-button variant="primary">Click me</modus-wc-button>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Types
|
|
74
|
+
|
|
75
|
+
Types are a crucial part of our component library, providing robust type safety and enhanced developer experience through comprehensive TypeScript definitions for all components.
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
import { ISelectOption, ModusWcSelectCustomEvent } from '@trimble-oss/moduswebcomponents';
|
|
79
|
+
|
|
80
|
+
const options: ISelectOption[] = [
|
|
81
|
+
{
|
|
82
|
+
label: 'Option 1',
|
|
83
|
+
value: '1',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
label: 'Option 2',
|
|
87
|
+
value: '2',
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
const handleEvent = (e: ModusWcSelectCustomEvent<ISelectOption>) => {}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Testing with Jest
|
|
95
|
+
|
|
96
|
+
If you are using the React integration package (`@trimble-oss/moduswebcomponents-react`), this package is published as ES modules. To use it in a Jest environment you need to configure Babel to transpile it.
|
|
97
|
+
|
|
98
|
+
Add `transformIgnorePatterns` to your Jest config (`package.json` or `jest.config.js`):
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"jest": {
|
|
103
|
+
"transformIgnorePatterns": ["/node_modules/(?!(@trimble-oss|@stencil))"]
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Ensure your `babel.config.js` includes these presets:
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
module.exports = {
|
|
112
|
+
presets: [
|
|
113
|
+
['@babel/preset-env', { targets: { node: 'current' } }],
|
|
114
|
+
['@babel/preset-react', { runtime: 'automatic' }],
|
|
115
|
+
'@babel/preset-typescript',
|
|
116
|
+
],
|
|
117
|
+
};
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Framework Integrations
|
|
121
|
+
|
|
122
|
+
- ### [Angular](?path=/docs/documentation-frameworks-angular--docs)
|
|
123
|
+
|
|
124
|
+
- ### [React](?path=/docs/documentation-frameworks-react--docs)
|
|
125
|
+
|
|
126
|
+
- ### [Vue](?path=/docs/documentation-frameworks-vue--docs)
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
Need help? Check out our [GitHub repository](https://github.com/trimble-oss/modus-wc-2.0)
|
|
131
|
+
or [raise an issue](https://github.com/trimble-oss/modus-wc-2.0/issues).
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"total": 49,
|
|
3
|
+
"components": [
|
|
4
|
+
"modus-wc-accordion",
|
|
5
|
+
"modus-wc-alert",
|
|
6
|
+
"modus-wc-autocomplete",
|
|
7
|
+
"modus-wc-avatar",
|
|
8
|
+
"modus-wc-badge",
|
|
9
|
+
"modus-wc-breadcrumbs",
|
|
10
|
+
"modus-wc-button",
|
|
11
|
+
"modus-wc-button-group",
|
|
12
|
+
"modus-wc-card",
|
|
13
|
+
"modus-wc-checkbox",
|
|
14
|
+
"modus-wc-chip",
|
|
15
|
+
"modus-wc-collapse",
|
|
16
|
+
"modus-wc-date",
|
|
17
|
+
"modus-wc-divider",
|
|
18
|
+
"modus-wc-dropdown-menu",
|
|
19
|
+
"modus-wc-file-dropzone",
|
|
20
|
+
"modus-wc-handle",
|
|
21
|
+
"modus-wc-icon",
|
|
22
|
+
"modus-wc-input-feedback",
|
|
23
|
+
"modus-wc-input-label",
|
|
24
|
+
"modus-wc-loader",
|
|
25
|
+
"modus-wc-logo",
|
|
26
|
+
"modus-wc-menu",
|
|
27
|
+
"modus-wc-menu-item",
|
|
28
|
+
"modus-wc-modal",
|
|
29
|
+
"modus-wc-navbar",
|
|
30
|
+
"modus-wc-number-input",
|
|
31
|
+
"modus-wc-pagination",
|
|
32
|
+
"modus-wc-panel",
|
|
33
|
+
"modus-wc-progress",
|
|
34
|
+
"modus-wc-radio",
|
|
35
|
+
"modus-wc-rating",
|
|
36
|
+
"modus-wc-select",
|
|
37
|
+
"modus-wc-side-navigation",
|
|
38
|
+
"modus-wc-skeleton",
|
|
39
|
+
"modus-wc-slider",
|
|
40
|
+
"modus-wc-stepper",
|
|
41
|
+
"modus-wc-switch",
|
|
42
|
+
"modus-wc-table",
|
|
43
|
+
"modus-wc-tabs",
|
|
44
|
+
"modus-wc-text-input",
|
|
45
|
+
"modus-wc-textarea",
|
|
46
|
+
"modus-wc-theme-switcher",
|
|
47
|
+
"modus-wc-time-input",
|
|
48
|
+
"modus-wc-toast",
|
|
49
|
+
"modus-wc-toolbar",
|
|
50
|
+
"modus-wc-tooltip",
|
|
51
|
+
"modus-wc-typography",
|
|
52
|
+
"modus-wc-utility-panel"
|
|
53
|
+
],
|
|
54
|
+
"last_updated": "1774599201.21"
|
|
55
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "A customizable accordion component used for showing and hiding related groups of content. The component supports a `<slot>` called 'content' for injecting `<modus-wc-collapse>` elements. See [Collapse](/docs/components-collapse--docs) docs for additional info.",
|
|
3
|
+
"properties": [
|
|
4
|
+
{
|
|
5
|
+
"name": "customClass",
|
|
6
|
+
"type": "string",
|
|
7
|
+
"description": "Custom CSS class to apply to the inner div.",
|
|
8
|
+
"default": "''",
|
|
9
|
+
"mutable": false,
|
|
10
|
+
"end_line": 29
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"events": [
|
|
14
|
+
{
|
|
15
|
+
"name": "expandedChange",
|
|
16
|
+
"detail": "{ expanded: boolean; index: number; }",
|
|
17
|
+
"description": "When a collapse expanded state is changed, this event outputs the relevant index and state",
|
|
18
|
+
"end_line": 35
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"methods": [],
|
|
22
|
+
"slots": [
|
|
23
|
+
{
|
|
24
|
+
"name": "default",
|
|
25
|
+
"description": "Slot for default content"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"examples": {
|
|
29
|
+
"basic": "<div style=\"padding: 20px;\">\n <modus-wc-accordion custom-class=${ifDefined(args['custom-class'])}>\n <modus-wc-collapse .options=${collapseOptions[0]}>\n <div slot=\"content\">Collapse content</div>\n </modus-wc-collapse>\n <modus-wc-collapse .options=${collapseOptions[1]}>\n <div slot=\"content\">Collapse content</div>\n </modus-wc-collapse>\n <modus-wc-collapse .options=${collapseOptions[2]}>\n <div slot=\"content\">Collapse content</div>\n </modus-wc-collapse>\n </modus-wc-accordion>\n</div>\n<script>\n const collapseOptions = [\n {\n description: 'Item one description',\n icon: 'alert',\n iconAriaLabel: 'Alert',\n title: 'Item One',\n },\n {\n description: 'Item two description',\n icon: 'alert',\n iconAriaLabel: 'Alert',\n title: 'Item Two',\n },\n {\n description: 'Item three description',\n icon: 'alert',\n iconAriaLabel: 'Alert',\n title: 'Item Three',\n },\n ];\n // Adding this block to show how to set options via JS \n // const items = document.querySelectorAll('modus-wc-collapse');\n // items.forEach((item, index) => {\n // item.options = collapseOptions[index];\n // });\n</script>",
|
|
30
|
+
"variations": [],
|
|
31
|
+
"args": {},
|
|
32
|
+
"argTypes": {},
|
|
33
|
+
"usage": [],
|
|
34
|
+
"events": [
|
|
35
|
+
"expandedChange"
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
"tag": "modus-wc-accordion",
|
|
39
|
+
"storyExample": {
|
|
40
|
+
"template": "<div style=\"padding: 20px;\">\n <modus-wc-accordion custom-class=${ifDefined(args['custom-class'])}>\n <modus-wc-collapse .options=${collapseOptions[0]}>\n <div slot=\"content\">Collapse content</div>\n </modus-wc-collapse>\n <modus-wc-collapse .options=${collapseOptions[1]}>\n <div slot=\"content\">Collapse content</div>\n </modus-wc-collapse>\n <modus-wc-collapse .options=${collapseOptions[2]}>\n <div slot=\"content\">Collapse content</div>\n </modus-wc-collapse>\n </modus-wc-accordion>\n</div>\n<script>\n const collapseOptions = [\n {\n description: 'Item one description',\n icon: 'alert',\n iconAriaLabel: 'Alert',\n title: 'Item One',\n },\n {\n description: 'Item two description',\n icon: 'alert',\n iconAriaLabel: 'Alert',\n title: 'Item Two',\n },\n {\n description: 'Item three description',\n icon: 'alert',\n iconAriaLabel: 'Alert',\n title: 'Item Three',\n },\n ];\n // Adding this block to show how to set options via JS \n // const items = document.querySelectorAll('modus-wc-collapse');\n // items.forEach((item, index) => {\n // item.options = collapseOptions[index];\n // });\n</script>",
|
|
41
|
+
"args": {},
|
|
42
|
+
"argTypes": {},
|
|
43
|
+
"events": [
|
|
44
|
+
"expandedChange"
|
|
45
|
+
],
|
|
46
|
+
"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 { createShadowHostClass } from '../../providers/shadow-dom/shadow-host-helper';\nimport { ICollapseOptions } from '../modus-wc-collapse/modus-wc-collapse';\n\ninterface AccordionArgs {\n 'custom-class'?: string;\n}\n\nconst collapseOptions: ICollapseOptions[] = [\n {\n description: 'Item one description',\n icon: 'alert',\n iconAriaLabel: 'Alert',\n title: 'Item One',\n },\n {\n description: 'Item two description',\n icon: 'alert',\n iconAriaLabel: 'Alert',\n title: 'Item Two',\n },\n {\n description: 'Item three description',\n icon: 'alert',\n iconAriaLabel: 'Alert',\n title: 'Item Three',\n },\n];\n\nconst meta: Meta<AccordionArgs> = {\n title: 'Components/Accordion',\n component: 'modus-wc-accordion',\n decorators: [withActions],\n parameters: {\n actions: {\n handles: ['expandedChange'],\n },\n layout: {\n padded: true,\n },\n },\n};\n\nexport default meta;\n\ntype Story = StoryObj<AccordionArgs>;\n\nconst Template: Story = {\n render: (args) => {\n // prettier-ignore\n return html`\n<div style=\"padding: 20px;\">\n <modus-wc-accordion custom-class=${ifDefined(args['custom-class'])}>\n <modus-wc-collapse .options=${collapseOptions[0]}>\n <div slot=\"content\">Collapse content</div>\n </modus-wc-collapse>\n <modus-wc-collapse .options=${collapseOptions[1]}>\n <div slot=\"content\">Collapse content</div>\n </modus-wc-collapse>\n <modus-wc-collapse .options=${collapseOptions[2]}>\n <div slot=\"content\">Collapse content</div>\n </modus-wc-collapse>\n </modus-wc-accordion>\n</div>\n<script>\n const collapseOptions = [\n {\n description: 'Item one description',\n icon: 'alert',\n iconAriaLabel: 'Alert',\n title: 'Item One',\n },\n {\n description: 'Item two description',\n icon: 'alert',\n iconAriaLabel: 'Alert',\n title: 'Item Two',\n },\n {\n description: 'Item three description',\n icon: 'alert',\n iconAriaLabel: 'Alert',\n title: 'Item Three',\n },\n ];\n // Adding this block to show how to set options via JS \n // const items = document.querySelectorAll('modus-wc-collapse');\n // items.forEach((item, index) => {\n // item.options = collapseOptions[index];\n // });\n</script>\n `;\n },\n};\n\nexport const Default: Story = { ...Template };\n\nexport const ShadowDomParent: Story = {\n render: () => {\n // Create a unique shadow host for accordion component\n if (!customElements.get('accordion-shadow-host')) {\n const AccordionShadowHost = createShadowHostClass<AccordionArgs>({\n componentTag: 'modus-wc-accordion',\n propsMapper: (v: AccordionArgs, el: HTMLElement) => {\n const accordionEl = el as unknown as {\n customClass: string;\n };\n accordionEl.customClass = v['custom-class'] || '';\n\n // Create and append collapse elements (no whitespace between to avoid gaps)\n el.innerHTML = '';\n collapseOptions.forEach((options) => {\n const collapse = document.createElement('modus-wc-collapse');\n (collapse as unknown as { options: ICollapseOptions }).options =\n options;\n const contentDiv = document.createElement('div');\n contentDiv.setAttribute('slot', 'content');\n contentDiv.textContent = 'Collapse content';\n collapse.appendChild(contentDiv);\n el.appendChild(collapse);\n });\n },\n });\n customElements.define('accordion-shadow-host', AccordionShadowHost);\n }\n\n return html`<accordion-shadow-host\n style=\"display: block; padding: 20px;\"\n .props=${{}}\n ></accordion-shadow-host>`;\n },\n};\n\nexport const Migration: Story = {\n parameters: {\n docs: {\n description: {\n story: `\n#### Breaking Changes\n\n - In 1.0 the accordion was composed of child accordion-item components. In 2.0 accordion children are collapse\n components.\n - The new accordion supports \\`header\\` and \\`content\\` slots to provide maximum flexibility.\n - Size values have changed from (\\`condensed\\`, \\`standard\\`) in 1.0 accordion-item to abbreviations (\\`xs\\`, \\`sm\\`, \\`md\\`, \\`lg\\`) in 2.0 collapse.\n\n#### Prop Mapping\n\n##### accordion\n\n| 1.0 Prop | 2.0 Prop | Notes |\n|--------------------|--------------------|------------------|\n| aria-label | aria-label | |\n\n##### accordion-item → collapse\n\n| 1.0 Prop | 2.0 Prop | Notes |\n|--------------------|---------------------|------------------|\n| aria-label | aria-label | |\n| disabled | | Not carried over |\n| expand-button-type | | Not carried over |\n| expanded | expanded | |\n| header-text | options.title | |\n| icon | options.icon | |\n| supporting-label | options.description | |\n| size | options.size | |\n\n#### Event Mapping\n\n##### accordion-item → accordion\n\nThe new accordion and collapse have their own events. We recommend using the\naccordion events to migrate.\n\n| 1.0 Event | 2.0 Event | Notes |\n|-----------|----------------|------------------|\n| closed | expandedChange | |\n| opened | expandedChange | |\n `,\n },\n },\n // To hide the actual story rendering and only show docs:\n controls: { disable: true },\n canvas: { disable: true },\n },\n // Simple render function or leave it empty\n render: () => html`<div></div>`,\n};\n"
|
|
47
|
+
}
|
|
48
|
+
}
|