fluentui-webcomponents 0.0.1

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.
Files changed (59) hide show
  1. package/AGENTS.md +212 -0
  2. package/README.md +99 -0
  3. package/components/avatar/fluent-avatar.css +481 -0
  4. package/components/avatar/fluent-avatar.js +80 -0
  5. package/components/badge/fluent-badge.css +289 -0
  6. package/components/badge/fluent-badge.js +20 -0
  7. package/components/breadcrumb/fluent-breadcrumb.css +29 -0
  8. package/components/breadcrumb/fluent-breadcrumb.js +33 -0
  9. package/components/breadcrumb-item/fluent-breadcrumb-item.css +70 -0
  10. package/components/breadcrumb-item/fluent-breadcrumb-item.js +77 -0
  11. package/components/button/fluent-button.css +265 -0
  12. package/components/button/fluent-button.js +326 -0
  13. package/components/card/fluent-card.css +85 -0
  14. package/components/card/fluent-card.js +21 -0
  15. package/components/checkbox/fluent-checkbox.css +171 -0
  16. package/components/checkbox/fluent-checkbox.js +294 -0
  17. package/components/dialog/fluent-dialog.css +82 -0
  18. package/components/dialog/fluent-dialog.js +137 -0
  19. package/components/divider/fluent-divider.css +124 -0
  20. package/components/divider/fluent-divider.js +14 -0
  21. package/components/image/fluent-image.css +73 -0
  22. package/components/image/fluent-image.js +36 -0
  23. package/components/label/fluent-label.css +49 -0
  24. package/components/label/fluent-label.js +61 -0
  25. package/components/link/fluent-link.css +72 -0
  26. package/components/link/fluent-link.js +109 -0
  27. package/components/menu/fluent-menu.css +57 -0
  28. package/components/menu/fluent-menu.js +202 -0
  29. package/components/menu-item/fluent-menu-item.css +152 -0
  30. package/components/menu-item/fluent-menu-item.js +177 -0
  31. package/components/popover/fluent-popover.css +95 -0
  32. package/components/popover/fluent-popover.js +93 -0
  33. package/components/radio/fluent-radio.css +123 -0
  34. package/components/radio/fluent-radio.js +257 -0
  35. package/components/select/fluent-select.css +194 -0
  36. package/components/select/fluent-select.js +245 -0
  37. package/components/slider/fluent-slider.css +199 -0
  38. package/components/slider/fluent-slider.js +438 -0
  39. package/components/spinner/fluent-spinner.css +160 -0
  40. package/components/spinner/fluent-spinner.js +30 -0
  41. package/components/switch/fluent-switch.css +154 -0
  42. package/components/switch/fluent-switch.js +260 -0
  43. package/components/text/fluent-text.css +128 -0
  44. package/components/text/fluent-text.js +21 -0
  45. package/components/text-input/fluent-text-input.css +227 -0
  46. package/components/text-input/fluent-text-input.js +298 -0
  47. package/components/textarea/fluent-textarea.css +227 -0
  48. package/components/textarea/fluent-textarea.js +400 -0
  49. package/components/tooltip/fluent-tooltip.css +65 -0
  50. package/components/tooltip/fluent-tooltip.js +102 -0
  51. package/components/tree/fluent-tree.css +16 -0
  52. package/components/tree/fluent-tree.js +167 -0
  53. package/components/tree-item/fluent-tree-item.css +147 -0
  54. package/components/tree-item/fluent-tree-item.js +163 -0
  55. package/core/fluent-element.js +34 -0
  56. package/gallery.html +492 -0
  57. package/package.json +19 -0
  58. package/theme/theme-picker.js +38 -0
  59. package/tokens.css +724 -0
@@ -0,0 +1,93 @@
1
+ import { FluentElement } from '../../core/fluent-element.js';
2
+
3
+ const stylesUrl = new URL('./fluent-popover.css', import.meta.url).href;
4
+
5
+ class FluentPopover extends FluentElement {
6
+ static stylesUrl = stylesUrl;
7
+ static template = `
8
+ <div class="root">
9
+ <slot name="trigger"></slot>
10
+ <div class="popover" part="popover">
11
+ <div class="arrow"></div>
12
+ <slot></slot>
13
+ </div>
14
+ </div>
15
+ `;
16
+
17
+ static get observedAttributes() {
18
+ return ['open', 'anchor', 'positioning'];
19
+ }
20
+
21
+ connectedCallback() {
22
+ super.connectedCallback();
23
+ this._popover = this._root.querySelector('.popover');
24
+ this._arrow = this._root.querySelector('.arrow');
25
+ this._triggerSlot = this._root.querySelector('slot[name="trigger"]');
26
+
27
+ this._triggerSlot.addEventListener('slotchange', () => {
28
+ this._setupTrigger();
29
+ });
30
+ this._setupTrigger();
31
+
32
+ this._popover.addEventListener('click', (e) => e.stopPropagation());
33
+ document.addEventListener('click', this._documentClickHandler);
34
+ }
35
+
36
+ disconnectedCallback() {
37
+ super.disconnectedCallback();
38
+ document.removeEventListener('click', this._documentClickHandler);
39
+ }
40
+
41
+ _setupTrigger() {
42
+ const assigned = this._triggerSlot.assignedElements();
43
+ if (assigned.length > 0) {
44
+ const trigger = assigned[0];
45
+ trigger.setAttribute('aria-haspopup', 'true');
46
+ trigger.addEventListener('click', (e) => {
47
+ e.stopPropagation();
48
+ this.toggle();
49
+ });
50
+ trigger.addEventListener('keydown', (e) => {
51
+ if (e.key === 'Escape') {
52
+ this.close();
53
+ trigger.focus();
54
+ }
55
+ });
56
+ }
57
+ }
58
+
59
+ toggle() {
60
+ const isOpen = this.hasAttribute('open');
61
+ if (isOpen) {
62
+ this.close();
63
+ } else {
64
+ this.open();
65
+ }
66
+ }
67
+
68
+ open() {
69
+ this.setAttribute('open', '');
70
+ this._popover.style.display = 'block';
71
+ this._triggerSlot.assignedElements().forEach(el => {
72
+ el.setAttribute('aria-expanded', 'true');
73
+ });
74
+ }
75
+
76
+ close() {
77
+ this.removeAttribute('open');
78
+ this._popover.style.display = 'none';
79
+ this._triggerSlot.assignedElements().forEach(el => {
80
+ el.setAttribute('aria-expanded', 'false');
81
+ });
82
+ }
83
+
84
+ _documentClickHandler = (e) => {
85
+ if (!this.hasAttribute('open')) return;
86
+ const path = e.composedPath();
87
+ if (!path.includes(this)) {
88
+ this.close();
89
+ }
90
+ };
91
+ }
92
+
93
+ customElements.define('fluent-popover', FluentPopover);
@@ -0,0 +1,123 @@
1
+ @import url('../../tokens.css');
2
+
3
+ :host { display: inline-flex; }
4
+
5
+ :host([hidden]) .root {
6
+ display: none;
7
+ }
8
+
9
+ .root {
10
+ --size: 16px;
11
+ aspect-ratio: 1;
12
+ background-color: var(--colorNeutralBackground1);
13
+ border: var(--strokeWidthThin) solid var(--colorNeutralStrokeAccessible);
14
+ border-radius: var(--borderRadiusCircular);
15
+ box-sizing: border-box;
16
+ position: relative;
17
+ width: var(--size);
18
+ display: inline-flex;
19
+ cursor: pointer;
20
+ }
21
+
22
+ :host([size='large']) .root {
23
+ --size: 20px;
24
+ }
25
+
26
+ .checked-indicator {
27
+ aspect-ratio: 1;
28
+ border-radius: var(--borderRadiusCircular);
29
+ color: var(--colorNeutralForegroundInverted);
30
+ inset: 0;
31
+ margin: auto;
32
+ position: absolute;
33
+ width: calc(var(--size) * 0.625);
34
+ }
35
+
36
+ :host(:not([slot='input'])) .root::after {
37
+ content: '';
38
+ position: absolute;
39
+ display: block;
40
+ inset: -8px;
41
+ box-sizing: border-box;
42
+ outline: none;
43
+ border: var(--strokeWidthThick) solid var(--colorTransparentStroke);
44
+ border-radius: var(--borderRadiusMedium);
45
+ }
46
+
47
+ :host(:not([slot='input'])) .root:focus-visible::after {
48
+ border-color: var(--colorStrokeFocus2);
49
+ }
50
+
51
+ .root:hover {
52
+ border-color: var(--colorNeutralStrokeAccessibleHover);
53
+ }
54
+
55
+ :host([checked]) .root {
56
+ border-color: var(--colorCompoundBrandStroke);
57
+ }
58
+
59
+ :host([checked]) .root .checked-indicator {
60
+ background-color: var(--colorCompoundBrandBackground);
61
+ }
62
+
63
+ :host([checked]) .root:hover .checked-indicator {
64
+ background-color: var(--colorCompoundBrandBackgroundHover);
65
+ }
66
+
67
+ .root:active {
68
+ border-color: var(--colorNeutralStrokeAccessiblePressed);
69
+ }
70
+
71
+ :host([checked]) .root:active .checked-indicator {
72
+ background-color: var(--colorCompoundBrandBackgroundPressed);
73
+ }
74
+
75
+ .root:focus-visible {
76
+ outline: none;
77
+ }
78
+
79
+ :host([disabled]) .root {
80
+ background-color: var(--colorNeutralBackgroundDisabled);
81
+ border-color: var(--colorNeutralStrokeDisabled);
82
+ cursor: unset;
83
+ }
84
+
85
+ :host([checked][disabled]) .root .checked-indicator {
86
+ background-color: var(--colorNeutralStrokeDisabled);
87
+ }
88
+
89
+ @media (forced-colors: active) {
90
+ .root {
91
+ border-color: FieldText;
92
+ }
93
+
94
+ :host(:not([slot='input']:focus-visible)) .root::after {
95
+ border-color: Canvas;
96
+ }
97
+
98
+ :host(:not([disabled])) .root:hover,
99
+ :host(:not([slot='input'])) .root:focus-visible::after {
100
+ border-color: Highlight;
101
+ }
102
+
103
+ .checked-indicator {
104
+ color: HighlightText;
105
+ }
106
+
107
+ :host([checked]) .root .checked-indicator {
108
+ background-color: FieldText;
109
+ }
110
+
111
+ :host([checked]:not([disabled])) .root:hover .checked-indicator {
112
+ background-color: Highlight;
113
+ }
114
+
115
+ :host([disabled]) .root {
116
+ border-color: GrayText;
117
+ color: GrayText;
118
+ }
119
+
120
+ :host([disabled][checked]) .root .checked-indicator {
121
+ background-color: GrayText;
122
+ }
123
+ }
@@ -0,0 +1,257 @@
1
+ import { FluentElement } from '../../core/fluent-element.js';
2
+
3
+ const stylesUrl = new URL('./fluent-radio.css', import.meta.url).href;
4
+
5
+ class FluentRadio extends FluentElement {
6
+ static stylesUrl = stylesUrl;
7
+ static formAssociated = true;
8
+
9
+ static template = `
10
+ <div class="root">
11
+ <slot name="checked-indicator">
12
+ <span part="checked-indicator" class="checked-indicator" role="presentation"></span>
13
+ </slot>
14
+ </div>
15
+ `;
16
+
17
+ static get observedAttributes() {
18
+ return ['checked', 'disabled', 'required', 'value', 'name', 'size', 'shape', 'autofocus'];
19
+ }
20
+
21
+ constructor() {
22
+ super();
23
+ this._internals = this.attachInternals();
24
+ this._internals.role = 'radio';
25
+ this._checked = false;
26
+ this._dirtyChecked = false;
27
+ this._keydownPressed = false;
28
+ this._value = 'on';
29
+ this._name = '';
30
+ this._size = 'medium';
31
+ this._shape = 'circular';
32
+ }
33
+
34
+ connectedCallback() {
35
+ super.connectedCallback();
36
+ this._updateDisabled();
37
+ this._setAriaChecked();
38
+ this.addEventListener('click', this._clickHandler.bind(this));
39
+ this.addEventListener('keydown', this._keydownHandler.bind(this));
40
+ this.addEventListener('keyup', this._keyupHandler.bind(this));
41
+ }
42
+
43
+ changed(name, oldVal, newVal) {
44
+ switch (name) {
45
+ case 'checked':
46
+ if (!this._dirtyChecked) {
47
+ this._checked = newVal !== null;
48
+ this._setAriaChecked();
49
+ if (this._checked) {
50
+ this._uncheckSiblings();
51
+ }
52
+ }
53
+ break;
54
+ case 'disabled':
55
+ this._updateDisabled();
56
+ this.dispatchEvent(new Event('disabled', { bubbles: true }));
57
+ break;
58
+ case 'required':
59
+ this._internals.ariaRequired = this.required ? 'true' : 'false';
60
+ this._setValidity();
61
+ break;
62
+ case 'value':
63
+ this._value = newVal || 'on';
64
+ break;
65
+ case 'name':
66
+ this._name = newVal || '';
67
+ if (this._name) {
68
+ this.setAttribute('name', this._name);
69
+ } else {
70
+ this.removeAttribute('name');
71
+ }
72
+ break;
73
+ case 'size':
74
+ this._size = newVal || 'medium';
75
+ break;
76
+ case 'shape':
77
+ this._shape = newVal || 'circular';
78
+ break;
79
+ case 'autofocus':
80
+ if (newVal !== null && !this.disabled) {
81
+ this.focus();
82
+ }
83
+ break;
84
+ }
85
+ }
86
+
87
+ get checked() {
88
+ return this._checked;
89
+ }
90
+
91
+ set checked(val) {
92
+ this._checked = !!val;
93
+ this._setAriaChecked();
94
+ if (this._checked) {
95
+ this.setAttribute('checked', '');
96
+ this._uncheckSiblings();
97
+ } else {
98
+ this.removeAttribute('checked');
99
+ }
100
+ }
101
+
102
+ get disabled() {
103
+ return this.hasAttribute('disabled');
104
+ }
105
+
106
+ set disabled(val) {
107
+ if (val) {
108
+ this.setAttribute('disabled', '');
109
+ } else {
110
+ this.removeAttribute('disabled');
111
+ }
112
+ }
113
+
114
+ get required() {
115
+ return this.hasAttribute('required');
116
+ }
117
+
118
+ get value() {
119
+ return this._value || 'on';
120
+ }
121
+
122
+ set value(val) {
123
+ this._value = val;
124
+ }
125
+
126
+ get name() {
127
+ return this._name;
128
+ }
129
+
130
+ set name(val) {
131
+ this._name = val;
132
+ if (val) {
133
+ this.setAttribute('name', val);
134
+ } else {
135
+ this.removeAttribute('name');
136
+ }
137
+ }
138
+
139
+ get form() {
140
+ return this._internals.form;
141
+ }
142
+
143
+ get labels() {
144
+ return Object.freeze(Array.from(this._internals.labels));
145
+ }
146
+
147
+ get validity() {
148
+ return this._internals.validity;
149
+ }
150
+
151
+ get validationMessage() {
152
+ return this._internals.validationMessage;
153
+ }
154
+
155
+ get willValidate() {
156
+ return this._internals.willValidate;
157
+ }
158
+
159
+ toggleChecked(force) {
160
+ this._checked = typeof force === 'boolean' ? force : true;
161
+ this._dirtyChecked = true;
162
+ this._setAriaChecked();
163
+ if (this._checked) {
164
+ this.setAttribute('checked', '');
165
+ this._uncheckSiblings();
166
+ } else {
167
+ this.removeAttribute('checked');
168
+ }
169
+ }
170
+
171
+ checkValidity() {
172
+ return this._internals.checkValidity();
173
+ }
174
+
175
+ reportValidity() {
176
+ return this._internals.reportValidity();
177
+ }
178
+
179
+ setCustomValidity(message) {
180
+ this._internals.setValidity({ customError: !!message }, message);
181
+ this._setValidity();
182
+ }
183
+
184
+ _clickHandler(e) {
185
+ if (this.disabled || this._checked) return;
186
+ this._dirtyChecked = true;
187
+ this.toggleChecked(true);
188
+ this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
189
+ this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
190
+ }
191
+
192
+ _keydownHandler(e) {
193
+ if (e.key === ' ') {
194
+ e.preventDefault();
195
+ this._keydownPressed = true;
196
+ }
197
+ }
198
+
199
+ _keyupHandler(e) {
200
+ if (!this._keydownPressed || e.key !== ' ') return;
201
+ this._keydownPressed = false;
202
+ this.click();
203
+ }
204
+
205
+ _updateDisabled() {
206
+ const d = this.hasAttribute('disabled');
207
+ if (d) {
208
+ this.removeAttribute('tabindex');
209
+ } else {
210
+ const t = this.getAttribute('tabindex');
211
+ this.tabIndex = Number(t ?? 0) < 0 ? -1 : 0;
212
+ }
213
+ this._internals.ariaDisabled = d ? 'true' : 'false';
214
+ }
215
+
216
+ _setAriaChecked() {
217
+ this._internals.ariaChecked = this._checked ? 'true' : 'false';
218
+ }
219
+
220
+ _setValidity() {
221
+ if (this.disabled || !this.required) {
222
+ this._internals.setValidity({});
223
+ return;
224
+ }
225
+ this._internals.setValidity(
226
+ { valueMissing: !!this.required && !this._checked },
227
+ this.validationMessage || undefined
228
+ );
229
+ }
230
+
231
+ _uncheckSiblings() {
232
+ if (!this.name) return;
233
+ const root = this.getRootNode();
234
+ const radios = root.querySelectorAll(`fluent-radio[name="${this.name}"]`);
235
+ radios.forEach(radio => {
236
+ if (radio !== this && radio._checked) {
237
+ radio._checked = false;
238
+ radio._setAriaChecked();
239
+ radio.removeAttribute('checked');
240
+ radio._setFormValue(null);
241
+ }
242
+ });
243
+ }
244
+
245
+ _setFormValue(value) {
246
+ this._internals.setFormValue(value, value);
247
+ }
248
+
249
+ formResetCallback() {
250
+ this._checked = this.hasAttribute('checked');
251
+ this._dirtyChecked = false;
252
+ this._setAriaChecked();
253
+ this._setValidity();
254
+ }
255
+ }
256
+
257
+ customElements.define('fluent-radio', FluentRadio);
@@ -0,0 +1,194 @@
1
+ @import url('../../tokens.css');
2
+
3
+ :host { display: inline-flex; }
4
+
5
+ label {
6
+ display: flex;
7
+ color: var(--colorNeutralForeground1);
8
+ padding-bottom: var(--spacingVerticalXS);
9
+ flex-shrink: 0;
10
+ padding-inline-end: var(--spacingHorizontalXS);
11
+ }
12
+
13
+ label[hidden],
14
+ :host(:empty) label {
15
+ display: none;
16
+ }
17
+
18
+ .root {
19
+ align-items: center;
20
+ background-color: var(--colorNeutralBackground1);
21
+ border: var(--strokeWidthThin) solid var(--colorNeutralStroke1);
22
+ border-bottom-color: var(--colorNeutralStrokeAccessible);
23
+ border-radius: var(--borderRadiusMedium);
24
+ box-sizing: border-box;
25
+ height: 32px;
26
+ display: inline-flex;
27
+ flex-direction: row;
28
+ font-family: var(--fontFamilyBase);
29
+ font-size: var(--fontSizeBase300);
30
+ font-weight: var(--fontWeightRegular);
31
+ gap: var(--spacingHorizontalXXS);
32
+ line-height: var(--lineHeightBase300);
33
+ max-width: 400px;
34
+ padding: 0 var(--spacingHorizontalMNudge);
35
+ position: relative;
36
+ width: 100%;
37
+ }
38
+
39
+ .root::after {
40
+ box-sizing: border-box;
41
+ content: '';
42
+ position: absolute;
43
+ left: -1px;
44
+ bottom: 0px;
45
+ right: -1px;
46
+ height: max(2px, var(--borderRadiusMedium));
47
+ border-radius: 0 0 var(--borderRadiusMedium) var(--borderRadiusMedium);
48
+ border-bottom: 2px solid var(--colorCompoundBrandStroke);
49
+ clip-path: inset(calc(100% - 2px) 1px 0px);
50
+ transform: scaleX(0);
51
+ transition-property: transform;
52
+ transition-duration: var(--durationUltraFast);
53
+ transition-delay: var(--curveAccelerateMid);
54
+ }
55
+
56
+ .root:focus-within::after {
57
+ transform: scaleX(1);
58
+ transition-property: transform;
59
+ transition-duration: var(--durationNormal);
60
+ transition-delay: var(--curveDecelerateMid);
61
+ }
62
+
63
+ .control {
64
+ appearance: none;
65
+ width: 100%;
66
+ height: 100%;
67
+ box-sizing: border-box;
68
+ color: var(--colorNeutralForeground1);
69
+ border-radius: var(--borderRadiusMedium);
70
+ background: var(--colorTransparentBackground);
71
+ font-family: var(--fontFamilyBase);
72
+ font-weight: var(--fontWeightRegular);
73
+ font-size: var(--fontSizeBase300);
74
+ border: none;
75
+ outline: none;
76
+ cursor: pointer;
77
+ padding-right: 24px;
78
+ }
79
+
80
+ .control:focus-visible {
81
+ outline: 0;
82
+ }
83
+
84
+ .icon {
85
+ position: absolute;
86
+ right: var(--spacingHorizontalMNudge);
87
+ top: 50%;
88
+ transform: translateY(-50%);
89
+ display: flex;
90
+ align-items: center;
91
+ justify-content: center;
92
+ color: var(--colorNeutralForeground3);
93
+ pointer-events: none;
94
+ font-size: var(--fontSizeBase500);
95
+ }
96
+
97
+ .root:hover {
98
+ border-color: var(--colorNeutralStroke1Hover);
99
+ border-bottom-color: var(--colorNeutralStrokeAccessibleHover);
100
+ }
101
+
102
+ .root:active {
103
+ border-color: var(--colorNeutralStroke1Pressed);
104
+ }
105
+
106
+ .root:focus-within {
107
+ outline: transparent solid 2px;
108
+ border-bottom: 0;
109
+ }
110
+
111
+ :host([disabled]) .root {
112
+ background: var(--colorTransparentBackground);
113
+ border: var(--strokeWidthThin) solid var(--colorNeutralStrokeDisabled);
114
+ }
115
+
116
+ :host([disabled]) .control {
117
+ color: var(--colorNeutralForegroundDisabled);
118
+ cursor: not-allowed;
119
+ }
120
+
121
+ :host([disabled]) .icon {
122
+ color: var(--colorNeutralForegroundDisabled);
123
+ }
124
+
125
+ :host([control-size='small']) .control {
126
+ font-size: var(--fontSizeBase200);
127
+ font-weight: var(--fontWeightRegular);
128
+ line-height: var(--lineHeightBase200);
129
+ }
130
+
131
+ :host([control-size='small']) .root {
132
+ height: 24px;
133
+ gap: var(--spacingHorizontalXXS);
134
+ padding: 0 var(--spacingHorizontalSNudge);
135
+ }
136
+
137
+ :host([control-size='large']) .control {
138
+ font-size: var(--fontSizeBase400);
139
+ font-weight: var(--fontWeightRegular);
140
+ line-height: var(--lineHeightBase400);
141
+ }
142
+
143
+ :host([control-size='large']) .root {
144
+ height: 40px;
145
+ gap: var(--spacingHorizontalS);
146
+ padding: 0 var(--spacingHorizontalM);
147
+ }
148
+
149
+ :host([appearance='underline']) .root {
150
+ background: var(--colorTransparentBackground);
151
+ border: 0;
152
+ border-radius: 0;
153
+ border-bottom: var(--strokeWidthThin) solid var(--colorNeutralStrokeAccessible);
154
+ }
155
+
156
+ :host([appearance='underline']) .root:hover {
157
+ border-bottom-color: var(--colorNeutralStrokeAccessibleHover);
158
+ }
159
+
160
+ :host([appearance='underline']) .root:active {
161
+ border-bottom-color: var(--colorNeutralStrokeAccessiblePressed);
162
+ }
163
+
164
+ :host([appearance='underline']) .root:focus-within {
165
+ border: 0;
166
+ border-bottom-color: var(--colorNeutralStrokeAccessiblePressed);
167
+ }
168
+
169
+ :host([appearance='underline'][disabled]) .root {
170
+ border-bottom-color: var(--colorNeutralStrokeDisabled);
171
+ }
172
+
173
+ :host([appearance='filled-lighter']) .root {
174
+ background: var(--colorNeutralBackground1);
175
+ border: var(--strokeWidthThin) solid var(--colorTransparentStroke);
176
+ box-shadow: var(--shadow2);
177
+ }
178
+
179
+ :host([appearance='filled-darker']) .root {
180
+ background: var(--colorNeutralBackground3);
181
+ border: var(--strokeWidthThin) solid var(--colorTransparentStroke);
182
+ box-shadow: var(--shadow2);
183
+ }
184
+
185
+ :host([appearance='filled-lighter']) .root:hover,
186
+ :host([appearance='filled-darker']) .root:hover {
187
+ border-color: var(--colorTransparentStrokeInteractive);
188
+ }
189
+
190
+ :host([appearance='filled-lighter']) .root:active,
191
+ :host([appearance='filled-darker']) .root:active {
192
+ border-color: var(--colorTransparentStrokeInteractive);
193
+ background: var(--colorNeutralBackground3);
194
+ }