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,481 @@
1
+ @import url('../../tokens.css');
2
+
3
+ :host { display: inline-grid; }
4
+
5
+ :host([hidden]) .root {
6
+ display: none;
7
+ }
8
+
9
+ .root {
10
+ display: inline-grid;
11
+ position: relative;
12
+ place-items: center;
13
+ place-content: center;
14
+ grid-template: 1fr / 1fr;
15
+ flex-shrink: 0;
16
+ width: 32px;
17
+ height: 32px;
18
+ font-family: var(--fontFamilyBase);
19
+ font-weight: var(--fontWeightSemibold);
20
+ font-size: var(--fontSizeBase300);
21
+ border-radius: var(--borderRadiusCircular);
22
+ color: var(--colorNeutralForeground3);
23
+ background-color: var(--colorNeutralBackground6);
24
+ }
25
+
26
+ .monogram,
27
+ .default-icon {
28
+ grid-area: 1 / 1 / -1 / -1;
29
+ }
30
+
31
+ .monogram:empty {
32
+ display: none;
33
+ }
34
+
35
+ .default-slot:is(.has-slotted, :has-slotted) ~ .default-icon,
36
+ .default-slot:is(.has-slotted, :has-slotted) ~ .monogram,
37
+ :host(:is([name]):not([name=''])) .root .default-icon,
38
+ :host(:is([initials]):not([initials=''])) .root .default-icon {
39
+ display: none;
40
+ }
41
+
42
+ .default-icon,
43
+ ::slotted(svg) {
44
+ width: 20px;
45
+ height: 20px;
46
+ font-size: 20px;
47
+ }
48
+
49
+ ::slotted(img) {
50
+ box-sizing: border-box;
51
+ width: 100%;
52
+ height: 100%;
53
+ border-radius: var(--borderRadiusCircular);
54
+ }
55
+
56
+ ::slotted([slot='badge']) {
57
+ position: absolute;
58
+ bottom: 0;
59
+ right: 0;
60
+ box-shadow: 0 0 0 var(--strokeWidthThin) var(--colorNeutralBackground1);
61
+ }
62
+
63
+ :host([size='64']) .root ::slotted([slot='badge']),
64
+ :host([size='72']) .root ::slotted([slot='badge']),
65
+ :host([size='96']) .root ::slotted([slot='badge']),
66
+ :host([size='120']) .root ::slotted([slot='badge']),
67
+ :host([size='128']) .root ::slotted([slot='badge']) {
68
+ box-shadow: 0 0 0 var(--strokeWidthThick) var(--colorNeutralBackground1);
69
+ }
70
+
71
+ :host([size='16']) .root,
72
+ :host([size='20']) .root,
73
+ :host([size='24']) .root {
74
+ font-size: var(--fontSizeBase100);
75
+ font-weight: var(--fontWeightRegular);
76
+ }
77
+
78
+ :host([size='16']) .root {
79
+ width: 16px;
80
+ height: 16px;
81
+ }
82
+
83
+ :host([size='20']) .root {
84
+ width: 20px;
85
+ height: 20px;
86
+ }
87
+
88
+ :host([size='24']) .root {
89
+ width: 24px;
90
+ height: 24px;
91
+ }
92
+
93
+ :host([size='16']) .root .default-icon,
94
+ :host([size='16']) .root ::slotted(svg) {
95
+ width: 12px;
96
+ height: 12px;
97
+ font-size: 12px;
98
+ }
99
+
100
+ :host([size='20']) .root .default-icon,
101
+ :host([size='24']) .root .default-icon,
102
+ :host([size='20']) .root ::slotted(svg),
103
+ :host([size='24']) .root ::slotted(svg) {
104
+ width: 16px;
105
+ height: 16px;
106
+ font-size: 16px;
107
+ }
108
+
109
+ :host([size='28']) .root {
110
+ width: 28px;
111
+ height: 28px;
112
+ font-size: var(--fontSizeBase200);
113
+ }
114
+
115
+ :host([size='36']) .root {
116
+ width: 36px;
117
+ height: 36px;
118
+ }
119
+
120
+ :host([size='40']) .root {
121
+ width: 40px;
122
+ height: 40px;
123
+ }
124
+
125
+ :host([size='48']) .root,
126
+ :host([size='56']) .root {
127
+ font-size: var(--fontSizeBase400);
128
+ }
129
+
130
+ :host([size='48']) .root {
131
+ width: 48px;
132
+ height: 48px;
133
+ }
134
+
135
+ :host([size='48']) .root .default-icon,
136
+ :host([size='48']) .root ::slotted(svg) {
137
+ width: 24px;
138
+ height: 24px;
139
+ font-size: 24px;
140
+ }
141
+
142
+ :host([size='56']) .root {
143
+ width: 56px;
144
+ height: 56px;
145
+ }
146
+
147
+ :host([size='56']) .root .default-icon,
148
+ :host([size='56']) .root ::slotted(svg) {
149
+ width: 28px;
150
+ height: 28px;
151
+ font-size: 28px;
152
+ }
153
+
154
+ :host([size='64']) .root,
155
+ :host([size='72']) .root,
156
+ :host([size='96']) .root {
157
+ font-size: var(--fontSizeBase500);
158
+ }
159
+
160
+ :host([size='64']) .root .default-icon,
161
+ :host([size='72']) .root .default-icon,
162
+ :host([size='64']) .root ::slotted(svg),
163
+ :host([size='72']) .root ::slotted(svg) {
164
+ width: 32px;
165
+ height: 32px;
166
+ font-size: 32px;
167
+ }
168
+
169
+ :host([size='64']) .root {
170
+ width: 64px;
171
+ height: 64px;
172
+ }
173
+
174
+ :host([size='72']) .root {
175
+ width: 72px;
176
+ height: 72px;
177
+ }
178
+
179
+ :host([size='96']) .root {
180
+ width: 96px;
181
+ height: 96px;
182
+ }
183
+
184
+ :host([size='96']) .root .default-icon,
185
+ :host([size='120']) .root .default-icon,
186
+ :host([size='128']) .root .default-icon,
187
+ :host([size='96']) .root ::slotted(svg),
188
+ :host([size='120']) .root ::slotted(svg),
189
+ :host([size='128']) .root ::slotted(svg) {
190
+ width: 48px;
191
+ height: 48px;
192
+ font-size: 48px;
193
+ }
194
+
195
+ :host([size='120']) .root,
196
+ :host([size='128']) .root {
197
+ font-size: var(--fontSizeBase600);
198
+ }
199
+
200
+ :host([size='120']) .root {
201
+ width: 120px;
202
+ height: 120px;
203
+ }
204
+
205
+ :host([size='128']) .root {
206
+ width: 128px;
207
+ height: 128px;
208
+ }
209
+
210
+ :host([shape='square']) .root {
211
+ border-radius: var(--borderRadiusMedium);
212
+ }
213
+
214
+ :host([shape='square'][size='20']) .root,
215
+ :host([shape='square'][size='24']) .root {
216
+ border-radius: var(--borderRadiusSmall);
217
+ }
218
+
219
+ :host([shape='square'][size='56']) .root,
220
+ :host([shape='square'][size='64']) .root,
221
+ :host([shape='square'][size='72']) .root {
222
+ border-radius: var(--borderRadiusLarge);
223
+ }
224
+ :host([shape='square'][size='96']) .root,
225
+ :host([shape='square'][size='120']) .root,
226
+ :host([shape='square'][size='128']) .root {
227
+ border-radius: var(--borderRadiusXLarge);
228
+ }
229
+
230
+ :host([data-color='brand']) .root {
231
+ color: var(--colorNeutralForegroundStaticInverted);
232
+ background-color: var(--colorBrandBackgroundStatic);
233
+ }
234
+
235
+ :host([data-color='dark-red']) .root {
236
+ color: var(--colorPaletteDarkRedForeground2);
237
+ background-color: var(--colorPaletteDarkRedBackground2);
238
+ }
239
+
240
+ :host([data-color='cranberry']) .root {
241
+ color: var(--colorPaletteCranberryForeground2);
242
+ background-color: var(--colorPaletteCranberryBackground2);
243
+ }
244
+
245
+ :host([data-color='red']) .root {
246
+ color: var(--colorPaletteRedForeground2);
247
+ background-color: var(--colorPaletteRedBackground2);
248
+ }
249
+
250
+ :host([data-color='pumpkin']) .root {
251
+ color: var(--colorPalettePumpkinForeground2);
252
+ background-color: var(--colorPalettePumpkinBackground2);
253
+ }
254
+
255
+ :host([data-color='peach']) .root {
256
+ color: var(--colorPalettePeachForeground2);
257
+ background-color: var(--colorPalettePeachBackground2);
258
+ }
259
+
260
+ :host([data-color='marigold']) .root {
261
+ color: var(--colorPaletteMarigoldForeground2);
262
+ background-color: var(--colorPaletteMarigoldBackground2);
263
+ }
264
+
265
+ :host([data-color='gold']) .root {
266
+ color: var(--colorPaletteGoldForeground2);
267
+ background-color: var(--colorPaletteGoldBackground2);
268
+ }
269
+
270
+ :host([data-color='brass']) .root {
271
+ color: var(--colorPaletteBrassForeground2);
272
+ background-color: var(--colorPaletteBrassBackground2);
273
+ }
274
+
275
+ :host([data-color='brown']) .root {
276
+ color: var(--colorPaletteBrownForeground2);
277
+ background-color: var(--colorPaletteBrownBackground2);
278
+ }
279
+
280
+ :host([data-color='forest']) .root {
281
+ color: var(--colorPaletteForestForeground2);
282
+ background-color: var(--colorPaletteForestBackground2);
283
+ }
284
+
285
+ :host([data-color='seafoam']) .root {
286
+ color: var(--colorPaletteSeafoamForeground2);
287
+ background-color: var(--colorPaletteSeafoamBackground2);
288
+ }
289
+
290
+ :host([data-color='dark-green']) .root {
291
+ color: var(--colorPaletteDarkGreenForeground2);
292
+ background-color: var(--colorPaletteDarkGreenBackground2);
293
+ }
294
+
295
+ :host([data-color='light-teal']) .root {
296
+ color: var(--colorPaletteLightTealForeground2);
297
+ background-color: var(--colorPaletteLightTealBackground2);
298
+ }
299
+
300
+ :host([data-color='teal']) .root {
301
+ color: var(--colorPaletteTealForeground2);
302
+ background-color: var(--colorPaletteTealBackground2);
303
+ }
304
+
305
+ :host([data-color='steel']) .root {
306
+ color: var(--colorPaletteSteelForeground2);
307
+ background-color: var(--colorPaletteSteelBackground2);
308
+ }
309
+
310
+ :host([data-color='blue']) .root {
311
+ color: var(--colorPaletteBlueForeground2);
312
+ background-color: var(--colorPaletteBlueBackground2);
313
+ }
314
+
315
+ :host([data-color='royal-blue']) .root {
316
+ color: var(--colorPaletteRoyalBlueForeground2);
317
+ background-color: var(--colorPaletteRoyalBlueBackground2);
318
+ }
319
+
320
+ :host([data-color='cornflower']) .root {
321
+ color: var(--colorPaletteCornflowerForeground2);
322
+ background-color: var(--colorPaletteCornflowerBackground2);
323
+ }
324
+
325
+ :host([data-color='navy']) .root {
326
+ color: var(--colorPaletteNavyForeground2);
327
+ background-color: var(--colorPaletteNavyBackground2);
328
+ }
329
+
330
+ :host([data-color='lavender']) .root {
331
+ color: var(--colorPaletteLavenderForeground2);
332
+ background-color: var(--colorPaletteLavenderBackground2);
333
+ }
334
+
335
+ :host([data-color='purple']) .root {
336
+ color: var(--colorPalettePurpleForeground2);
337
+ background-color: var(--colorPalettePurpleBackground2);
338
+ }
339
+
340
+ :host([data-color='grape']) .root {
341
+ color: var(--colorPaletteGrapeForeground2);
342
+ background-color: var(--colorPaletteGrapeBackground2);
343
+ }
344
+
345
+ :host([data-color='lilac']) .root {
346
+ color: var(--colorPaletteLilacForeground2);
347
+ background-color: var(--colorPaletteLilacBackground2);
348
+ }
349
+
350
+ :host([data-color='pink']) .root {
351
+ color: var(--colorPalettePinkForeground2);
352
+ background-color: var(--colorPalettePinkBackground2);
353
+ }
354
+
355
+ :host([data-color='magenta']) .root {
356
+ color: var(--colorPaletteMagentaForeground2);
357
+ background-color: var(--colorPaletteMagentaBackground2);
358
+ }
359
+
360
+ :host([data-color='plum']) .root {
361
+ color: var(--colorPalettePlumForeground2);
362
+ background-color: var(--colorPalettePlumBackground2);
363
+ }
364
+
365
+ :host([data-color='beige']) .root {
366
+ color: var(--colorPaletteBeigeForeground2);
367
+ background-color: var(--colorPaletteBeigeBackground2);
368
+ }
369
+
370
+ :host([data-color='mink']) .root {
371
+ color: var(--colorPaletteMinkForeground2);
372
+ background-color: var(--colorPaletteMinkBackground2);
373
+ }
374
+
375
+ :host([data-color='platinum']) .root {
376
+ color: var(--colorPalettePlatinumForeground2);
377
+ background-color: var(--colorPalettePlatinumBackground2);
378
+ }
379
+
380
+ :host([data-color='anchor']) .root {
381
+ color: var(--colorPaletteAnchorForeground2);
382
+ background-color: var(--colorPaletteAnchorBackground2);
383
+ }
384
+
385
+ :host([active]) .root {
386
+ transform: perspective(1px);
387
+ transition-property: transform, opacity;
388
+ transition-duration: var(--durationUltraSlow), var(--durationFaster);
389
+ transition-delay: var(--curveEasyEaseMax), var(--curveLinear);
390
+ }
391
+
392
+ :host([active]) .root::before {
393
+ content: '';
394
+ position: absolute;
395
+ top: 0;
396
+ left: 0;
397
+ bottom: 0;
398
+ right: 0;
399
+ border-radius: inherit;
400
+ transition-property: margin, opacity;
401
+ transition-duration: var(--durationUltraSlow), var(--durationSlower);
402
+ transition-delay: var(--curveEasyEaseMax), var(--curveLinear);
403
+ }
404
+ :host([active]) .root::before {
405
+ box-shadow: var(--shadow8);
406
+ border-style: solid;
407
+ border-color: var(--colorBrandBackgroundStatic);
408
+ }
409
+
410
+ :host([active][appearance='shadow']) .root::before {
411
+ border-style: none;
412
+ border-color: none;
413
+ }
414
+
415
+ :host([active]:not([appearance='shadow'])) .root::before {
416
+ margin: calc(-2 * var(--strokeWidthThick));
417
+ border-width: var(--strokeWidthThick);
418
+ }
419
+
420
+ :host([size='56'][active]:not([appearance='shadow'])) .root::before,
421
+ :host([size='64'][active]:not([appearance='shadow'])) .root::before {
422
+ margin: calc(-2 * var(--strokeWidthThicker));
423
+ border-width: var(--strokeWidthThicker);
424
+ }
425
+
426
+ :host([size='72'][active]:not([appearance='shadow'])) .root::before,
427
+ :host([size='96'][active]:not([appearance='shadow'])) .root::before,
428
+ :host([size='120'][active]:not([appearance='shadow'])) .root::before,
429
+ :host([size='128'][active]:not([appearance='shadow'])) .root::before {
430
+ margin: calc(-2 * var(--strokeWidthThickest));
431
+ border-width: var(--strokeWidthThickest);
432
+ }
433
+
434
+ :host([size='20'][active][appearance]) .root::before,
435
+ :host([size='24'][active][appearance]) .root::before,
436
+ :host([size='28'][active][appearance]) .root::before {
437
+ box-shadow: var(--shadow4);
438
+ }
439
+
440
+ :host([size='56'][active][appearance]) .root::before,
441
+ :host([size='64'][active][appearance]) .root::before {
442
+ box-shadow: var(--shadow16);
443
+ }
444
+
445
+ :host([size='72'][active][appearance]) .root::before,
446
+ :host([size='96'][active][appearance]) .root::before,
447
+ :host([size='120'][active][appearance]) .root::before,
448
+ :host([size='128'][active][appearance]) .root::before {
449
+ box-shadow: var(--shadow28);
450
+ }
451
+
452
+ :host([active][appearance='ring']) .root::before {
453
+ box-shadow: none;
454
+ }
455
+
456
+ :host([active='inactive']) .root {
457
+ opacity: 0.8;
458
+ transform: scale(0.875);
459
+ transition-property: transform, opacity;
460
+ transition-duration: var(--durationUltraSlow), var(--durationFaster);
461
+ transition-delay: var(--curveDecelerateMin), var(--curveLinear);
462
+ }
463
+
464
+ :host([active='inactive']) .root::before {
465
+ margin: 0;
466
+ opacity: 0;
467
+ transition-property: margin, opacity;
468
+ transition-duration: var(--durationUltraSlow), var(--durationSlower);
469
+ transition-delay: var(--curveDecelerateMin), var(--curveLinear);
470
+ }
471
+
472
+ @media screen and (prefers-reduced-motion: reduce) {
473
+ :host([active]) .root {
474
+ transition-duration: 0.01ms;
475
+ }
476
+
477
+ :host([active]) .root::before {
478
+ transition-duration: 0.01ms;
479
+ transition-delay: 0.01ms;
480
+ }
481
+ }
@@ -0,0 +1,80 @@
1
+ import { FluentElement } from '../../core/fluent-element.js';
2
+
3
+ const stylesUrl = new URL('./fluent-avatar.css', import.meta.url).href;
4
+
5
+ class FluentAvatar extends FluentElement {
6
+ static stylesUrl = stylesUrl;
7
+ static template = `
8
+ <div class="root">
9
+ <slot class="default-slot"></slot>
10
+ <span class="monogram" part="monogram"></span>
11
+ <svg width="1em" height="1em" viewBox="0 0 20 20" class="default-icon" fill="currentcolor" aria-hidden="true">
12
+ <path d="M10 2a4 4 0 100 8 4 4 0 000-8zM7 6a3 3 0 116 0 3 3 0 01-6 0zm-2 5a2 2 0 00-2 2c0 1.7.83 2.97 2.13 3.8A9.14 9.14 0 0010 18c1.85 0 3.58-.39 4.87-1.2A4.35 4.35 0 0017 13a2 2 0 00-2-2H5zm-1 2a1 1 0 011-1h10a1 1 0 011 1c0 1.3-.62 2.28-1.67 2.95A8.16 8.16 0 0110 17a8.16 8.16 0 01-4.33-1.05A3.36 3.36 0 014 13z"></path>
13
+ </svg>
14
+ <slot name="badge"></slot>
15
+ </div>
16
+ `;
17
+
18
+ static get observedAttributes() {
19
+ return ['name', 'initials', 'active', 'shape', 'appearance', 'size', 'color', 'color-id'];
20
+ }
21
+
22
+ connectedCallback() {
23
+ super.connectedCallback();
24
+ this._updateMonogram();
25
+ this._updateAriaLabel();
26
+ }
27
+
28
+ changed(name, oldVal, newVal) {
29
+ if (name === 'initials' || name === 'name') {
30
+ this._updateMonogram();
31
+ this._updateAriaLabel();
32
+ }
33
+ if (name === 'active') {
34
+ this._root.querySelector('.monogram')?.classList.toggle('active', this.hasAttribute('active'));
35
+ }
36
+ if (name === 'color' || name === 'color-id') {
37
+ this._updateColor();
38
+ }
39
+ }
40
+
41
+ _updateMonogram() {
42
+ const monogram = this._root.querySelector('.monogram');
43
+ if (!monogram) return;
44
+ const initials = this.getAttribute('initials');
45
+ if (initials) {
46
+ monogram.textContent = initials;
47
+ return;
48
+ }
49
+ const name = this.getAttribute('name');
50
+ if (name) {
51
+ const parts = name.split(/\s+/).filter(Boolean);
52
+ const text = parts.length === 1
53
+ ? parts[0].charAt(0)
54
+ : parts[0].charAt(0) + parts[parts.length - 1].charAt(0);
55
+ monogram.textContent = text.toUpperCase();
56
+ return;
57
+ }
58
+ monogram.textContent = '';
59
+ }
60
+
61
+ _updateAriaLabel() {
62
+ const name = this.getAttribute('name');
63
+ if (name) {
64
+ this.setAttribute('aria-label', name);
65
+ this.setAttribute('role', 'img');
66
+ }
67
+ }
68
+
69
+ _updateColor() {
70
+ const color = this.getAttribute('color');
71
+ const colorId = this.getAttribute('color-id');
72
+ if (color === 'colorful' && colorId) {
73
+ this.setAttribute('data-color', colorId);
74
+ } else if (color && color !== 'colorful') {
75
+ this.setAttribute('data-color', color);
76
+ }
77
+ }
78
+ }
79
+
80
+ customElements.define('fluent-avatar', FluentAvatar);