@fluentui/web-components 3.0.0-beta.121 → 3.0.0-beta.122

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.
@@ -1,6 +1,8 @@
1
1
  import { css } from '@microsoft/fast-element';
2
2
  import { display, forcedColorsStylesheetBehavior } from '../utils/index.js';
3
3
  import { colorBrandBackground2, colorBrandForeground1, colorNeutralBackground6, colorNeutralForeground1, colorPaletteMarigoldBackground2, colorPaletteMarigoldBorderActive, fontFamilyBase, fontSizeBase200, fontSizeBase300, fontWeightSemibold, lineHeightBase200, lineHeightBase300, spacingHorizontalSNudge, spacingHorizontalXS, spacingHorizontalXXS, } from '../theme/design-tokens.js';
4
+ import { svgToDataURI } from './rating-display.base.js';
5
+ import { defaultIconFilled, defaultIconOutlined } from './rating-display.template.js';
4
6
  /**
5
7
  * The styles for the Rating Display component.
6
8
  *
@@ -10,9 +12,16 @@ export const styles = css `
10
12
  ${display('inline-flex')}
11
13
 
12
14
  :host {
13
- --icon-size: 16px;
14
- --icon-color-filled: ${colorPaletteMarigoldBorderActive};
15
- --icon-color-empty: ${colorPaletteMarigoldBackground2};
15
+ --_icon-size: 16px;
16
+ --_icon-gradient-degree: 90deg;
17
+ --_icon-color-value: ${colorPaletteMarigoldBorderActive};
18
+ --_icon-color-empty: ${colorPaletteMarigoldBackground2};
19
+ --_default-value: 0;
20
+ --_default-max: 5;
21
+ --_mask-image-filled: url(${svgToDataURI(defaultIconFilled)});
22
+ --_mask-image-outlined: url(${svgToDataURI(defaultIconOutlined)});
23
+ --_mask-position-x: left;
24
+
16
25
  align-items: center;
17
26
  color: ${colorNeutralForeground1};
18
27
  font-family: ${fontFamilyBase};
@@ -22,12 +31,17 @@ export const styles = css `
22
31
  user-select: none;
23
32
  }
24
33
 
34
+ :host(:dir(rtl)) {
35
+ --_icon-gradient-degree: -90deg;
36
+ --_mask-position-x: right;
37
+ }
38
+
25
39
  :host([size='small']) {
26
- --icon-size: 12px;
40
+ --_icon-size: 12px;
27
41
  }
28
42
 
29
43
  :host([size='large']) {
30
- --icon-size: 20px;
44
+ --_icon-size: 20px;
31
45
  font-size: ${fontSizeBase300};
32
46
  line-height: ${lineHeightBase300};
33
47
  }
@@ -36,40 +50,48 @@ export const styles = css `
36
50
  display: none;
37
51
  }
38
52
 
39
- svg {
40
- width: var(--icon-size);
41
- height: var(--icon-size);
42
- fill: var(--icon-color-filled);
43
- margin-inline-end: ${spacingHorizontalXXS};
44
- }
45
-
46
- svg:nth-child(odd) {
47
- clip-path: inset(0 50% 0 0);
48
- margin-inline-end: calc(0px - var(--icon-size));
53
+ :host([color='neutral']) {
54
+ --_icon-color-value: ${colorNeutralForeground1};
55
+ --_icon-color-empty: ${colorNeutralBackground6};
49
56
  }
50
57
 
51
- :host([color='neutral']) svg {
52
- --icon-color-filled: ${colorNeutralForeground1};
58
+ :host([color='brand']) {
59
+ --_icon-color-value: ${colorBrandForeground1};
60
+ --_icon-color-empty: ${colorBrandBackground2};
53
61
  }
54
62
 
55
- :host([color='brand']) svg {
56
- --icon-color-filled: ${colorBrandForeground1};
63
+ @supports (width: attr(value type(<number>))) {
64
+ :host {
65
+ --_attr-value: attr(value type(<number>));
66
+ --_attr-max: attr(max type(<number>));
67
+ }
57
68
  }
58
69
 
59
- :host(:is([value^='-'], [value='0'])) svg,
60
- :host(:not([value])) svg,
61
- svg[selected] ~ svg {
62
- fill: var(--icon-color-empty);
70
+ :host([compact]) .display {
71
+ --_max: 1;
63
72
  }
64
73
 
65
- :host([color='neutral']:is([value^='-'], [value='0'], :not([value]))) svg,
66
- :host([color='neutral']) svg[selected] ~ svg {
67
- --icon-color-empty: ${colorNeutralBackground6};
68
- }
74
+ .display {
75
+ --_value: max(0, round(var(--_attr-value, var(--_default-value)) * 2) / 2);
76
+ --_max: max(1, var(--_attr-max, var(--_default-max)));
77
+ --_mask-inline-size: calc(var(--_icon-size) + ${spacingHorizontalXXS});
78
+ --_icon-gradient-stop-visual-adjustment: 0px;
79
+ --_icon-gradient-stop: calc(
80
+ var(--_mask-inline-size) * var(--_value) - var(--_icon-gradient-stop-visual-adjustment)
81
+ );
69
82
 
70
- :host([color='brand']:is([value^='-'], [value='0'], :not([value]))) svg,
71
- :host([color='brand']) svg[selected] ~ svg {
72
- --icon-color-empty: ${colorBrandBackground2};
83
+ background-image: linear-gradient(
84
+ var(--_icon-gradient-degree),
85
+ var(--_icon-color-value) var(--_icon-gradient-stop),
86
+ var(--_icon-color-empty) calc(var(--_icon-gradient-stop) + 0.5px)
87
+ );
88
+ block-size: var(--_icon-size);
89
+ display: grid;
90
+ inline-size: calc(var(--_max) * var(--_mask-inline-size) - ${spacingHorizontalXXS} / 2);
91
+ mask-image: var(--_mask-image-filled);
92
+ mask-repeat: repeat no-repeat;
93
+ mask-size: var(--_mask-inline-size) var(--_icon-size);
94
+ mask-position: var(--_mask-position-x) center;
73
95
  }
74
96
 
75
97
  .value-label,
@@ -109,15 +131,20 @@ export const styles = css `
109
131
  margin-inline: ${spacingHorizontalSNudge};
110
132
  }
111
133
  `.withBehaviors(forcedColorsStylesheetBehavior(css `
112
- :host([color]) svg {
113
- fill: CanvasText;
134
+ .display {
135
+ --_icon-color-value: CanvasText;
136
+ --_icon-color-empty: Canvas;
137
+ --_icon-gradient-stop-visual-adjustment: 0.5px;
138
+
139
+ forced-color-adjust: none;
114
140
  }
115
141
 
116
- :host([color]:is([value^='-'], [value='0'])) svg,
117
- :host(:not([value])) svg,
118
- :host([color]) svg[selected] ~ svg {
119
- fill: Canvas;
120
- stroke: CanvasText;
142
+ .display::before {
143
+ background-color: var(--_icon-color-value);
144
+ content: '';
145
+ grid-area: 1 / 1 / -1 / -1;
146
+ mask: inherit;
147
+ mask-image: var(--_mask-image-outlined);
121
148
  }
122
149
  `));
123
150
  //# sourceMappingURL=rating-display.styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rating-display.styles.js","sourceRoot":"","sources":["../../../src/rating-display/rating-display.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,+BAA+B,EAC/B,gCAAgC,EAChC,cAAc,EACd,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AAEnC;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;IACrB,OAAO,CAAC,aAAa,CAAC;;;;2BAIC,gCAAgC;0BACjC,+BAA+B;;aAE5C,uBAAuB;mBACjB,cAAc;iBAChB,eAAe;mBACb,iBAAiB;;;;;;;;;;;iBAWnB,eAAe;mBACb,iBAAiB;;;;;;;;;;;yBAWX,oBAAoB;;;;;;;;;2BASlB,uBAAuB;;;;2BAIvB,qBAAqB;;;;;;;;;;;0BAWtB,uBAAuB;;;;;0BAKvB,qBAAqB;;;;;;2BAMpB,mBAAmB;mBAC3B,kBAAkB;;;;;2BAKV,oBAAoB;;;;;2BAKpB,uBAAuB;;;;;;;;;;qBAU7B,mBAAmB;;;;;qBAKnB,oBAAoB;;;;;qBAKpB,uBAAuB;;CAE3C,CAAC,aAAa,CACb,8BAA8B,CAAC,GAAG,CAAA;;;;;;;;;;;GAWjC,CAAC,CACH,CAAC"}
1
+ {"version":3,"file":"rating-display.styles.js","sourceRoot":"","sources":["../../../src/rating-display/rating-display.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,+BAA+B,EAC/B,gCAAgC,EAChC,cAAc,EACd,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEtF;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;IACrB,OAAO,CAAC,aAAa,CAAC;;;;;2BAKC,gCAAgC;2BAChC,+BAA+B;;;gCAG1B,YAAY,CAAC,iBAAiB,CAAC;kCAC7B,YAAY,CAAC,mBAAmB,CAAC;;;;aAItD,uBAAuB;mBACjB,cAAc;iBAChB,eAAe;mBACb,iBAAiB;;;;;;;;;;;;;;;;iBAgBnB,eAAe;mBACb,iBAAiB;;;;;;;;2BAQT,uBAAuB;2BACvB,uBAAuB;;;;2BAIvB,qBAAqB;2BACrB,qBAAqB;;;;;;;;;;;;;;;;;oDAiBI,oBAAoB;;;;;;;;;;;;;iEAaP,oBAAoB;;;;;;;;;;2BAU1D,mBAAmB;mBAC3B,kBAAkB;;;;;2BAKV,oBAAoB;;;;;2BAKpB,uBAAuB;;;;;;;;;;qBAU7B,mBAAmB;;;;;qBAKnB,oBAAoB;;;;;qBAKpB,uBAAuB;;CAE3C,CAAC,aAAa,CACb,8BAA8B,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;GAgBjC,CAAC,CACH,CAAC"}
@@ -1,5 +1,8 @@
1
1
  import { type ElementViewTemplate } from '@microsoft/fast-element';
2
2
  import type { RatingDisplay } from './rating-display.js';
3
+ export declare const defaultIconPath = "<path d=\"M5.28347 1.54605C5.57692 0.951448 6.42479 0.951449 6.71825 1.54605L7.82997 3.79866L10.3159 4.15988C10.9721 4.25523 11.2341 5.0616 10.7592 5.52443L8.96043 7.27785L9.38507 9.7537C9.49716 10.4072 8.81122 10.9056 8.22431 10.597L6.00086 9.4281L3.7774 10.597C3.19049 10.9056 2.50455 10.4072 2.61664 9.7537L3.04128 7.27784L1.24246 5.52443C0.767651 5.0616 1.02966 4.25523 1.68584 4.15988L4.17174 3.79865L5.28347 1.54605Z\" />";
4
+ export declare const defaultIconFilled = "\n<svg viewBox=\"0 0 12 12\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.28347 1.54605C5.57692 0.951448 6.42479 0.951449 6.71825 1.54605L7.82997 3.79866L10.3159 4.15988C10.9721 4.25523 11.2341 5.0616 10.7592 5.52443L8.96043 7.27785L9.38507 9.7537C9.49716 10.4072 8.81122 10.9056 8.22431 10.597L6.00086 9.4281L3.7774 10.597C3.19049 10.9056 2.50455 10.4072 2.61664 9.7537L3.04128 7.27784L1.24246 5.52443C0.767651 5.0616 1.02966 4.25523 1.68584 4.15988L4.17174 3.79865L5.28347 1.54605Z\" /></svg>\n";
5
+ export declare const defaultIconOutlined = "\n<svg viewBox=\"0 0 12 12\" xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\" stroke=\"black\" stroke-width=\"2\"\n><path d=\"M5.28347 1.54605C5.57692 0.951448 6.42479 0.951449 6.71825 1.54605L7.82997 3.79866L10.3159 4.15988C10.9721 4.25523 11.2341 5.0616 10.7592 5.52443L8.96043 7.27785L9.38507 9.7537C9.49716 10.4072 8.81122 10.9056 8.22431 10.597L6.00086 9.4281L3.7774 10.597C3.19049 10.9056 2.50455 10.4072 2.61664 9.7537L3.04128 7.27784L1.24246 5.52443C0.767651 5.0616 1.02966 4.25523 1.68584 4.15988L4.17174 3.79865L5.28347 1.54605Z\" /></svg>\n";
3
6
  /**
4
7
  * Generates a template for the Rating Display component.
5
8
  *
@@ -1,16 +1,12 @@
1
- import { elements, html, slotted } from '@microsoft/fast-element';
2
- import { staticallyCompose } from '../utils/template-helpers.js';
3
- /**
4
- * Reusable star icon symbol
5
- */
6
- const star = html `
7
- <svg xmlns="http://www.w3.org/2000/svg" style="display: none">
8
- <symbol id="star">
9
- <path
10
- d="M9.10433 2.89874C9.47114 2.15549 10.531 2.1555 10.8978 2.89874L12.8282 6.81024L17.1448 7.43748C17.9651 7.55666 18.2926 8.56464 17.699 9.14317L14.5755 12.1878L15.3129 16.487C15.453 17.3039 14.5956 17.9269 13.8619 17.5412L10.0011 15.5114L6.14018 17.5412C5.40655 17.9269 4.54913 17.3039 4.68924 16.487L5.4266 12.1878L2.30308 9.14317C1.70956 8.56463 2.03708 7.55666 2.8573 7.43748L7.17389 6.81024L9.10433 2.89874Z"
11
- />
12
- </symbol>
13
- </svg>
1
+ import { html, ref } from '@microsoft/fast-element';
2
+ export const defaultIconPath = `<path d="M5.28347 1.54605C5.57692 0.951448 6.42479 0.951449 6.71825 1.54605L7.82997 3.79866L10.3159 4.15988C10.9721 4.25523 11.2341 5.0616 10.7592 5.52443L8.96043 7.27785L9.38507 9.7537C9.49716 10.4072 8.81122 10.9056 8.22431 10.597L6.00086 9.4281L3.7774 10.597C3.19049 10.9056 2.50455 10.4072 2.61664 9.7537L3.04128 7.27784L1.24246 5.52443C0.767651 5.0616 1.02966 4.25523 1.68584 4.15988L4.17174 3.79865L5.28347 1.54605Z" />`;
3
+ export const defaultIconFilled = `
4
+ <svg viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">${defaultIconPath}</svg>
5
+ `;
6
+ export const defaultIconOutlined = `
7
+ <svg viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"
8
+ fill="none" stroke="black" stroke-width="2"
9
+ >${defaultIconPath}</svg>
14
10
  `;
15
11
  /**
16
12
  * Generates a template for the Rating Display component.
@@ -19,8 +15,8 @@ const star = html `
19
15
  */
20
16
  export function ratingDisplayTemplate() {
21
17
  return html `
22
- ${x => html `${staticallyCompose(x.generateIcons())}`}
23
- <slot name="icon" ${slotted({ property: 'slottedIcon', filter: elements('svg') })}>${star}</slot>
18
+ <div ${ref('display')} class="display" aria-hidden="true"></div>
19
+ <slot name="icon" ${ref('iconSlot')} @slotchange="${x => x.handleSlotChange()}"></slot>
24
20
  <slot name="value"><span class="value-label" aria-hidden="true">${x => x.value}</span></slot>
25
21
  <slot name="count"><span class="count-label" aria-hidden="true">${x => x.formattedCount}</span></slot>
26
22
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"rating-display.template.js","sourceRoot":"","sources":["../../../src/rating-display/rating-display.template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAA4B,IAAI,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGjE;;GAEG;AACH,MAAM,IAAI,GAAG,IAAI,CAAA;;;;;;;;CAQhB,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,IAAI,CAAG;MACV,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA,GAAG,iBAAiB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,EAAE;wBAChC,OAAO,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,IAAI;sEACvB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;sEACZ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc;GACxF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAuC,qBAAqB,EAAE,CAAC"}
1
+ {"version":3,"file":"rating-display.template.js","sourceRoot":"","sources":["../../../src/rating-display/rating-display.template.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,IAAI,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAG9E,MAAM,CAAC,MAAM,eAAe,GAAG,2aAA2a,CAAC;AAE3c,MAAM,CAAC,MAAM,iBAAiB,GAAG;8DAC6B,eAAe;CAC5E,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;GAGhC,eAAe;CACjB,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,IAAI,CAAG;WACL,GAAG,CAAC,SAAS,CAAC;wBACD,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,EAAE;sEACX,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;sEACZ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc;GACxF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAuC,qBAAqB,EAAE,CAAC"}
@@ -2274,12 +2274,21 @@ export declare class BaseProgressBar extends FASTElement {
2274
2274
  * @public
2275
2275
  */
2276
2276
  export declare class BaseRatingDisplay extends FASTElement {
2277
+ private numberFormatter;
2277
2278
  /**
2278
2279
  * The internal {@link https://developer.mozilla.org/docs/Web/API/ElementInternals | `ElementInternals`} instance for the component.
2279
2280
  *
2280
2281
  * @internal
2281
2282
  */
2282
2283
  elementInternals: ElementInternals;
2284
+ /** @internal */
2285
+ iconSlot: HTMLSlotElement;
2286
+ protected defaultCustomIconViewBox: string;
2287
+ /**
2288
+ * The element that displays the rating icons.
2289
+ * @internal
2290
+ */
2291
+ display: HTMLElement;
2283
2292
  /**
2284
2293
  * The number of ratings.
2285
2294
  *
@@ -2292,9 +2301,9 @@ export declare class BaseRatingDisplay extends FASTElement {
2292
2301
  * The `viewBox` attribute of the icon <svg> element.
2293
2302
  *
2294
2303
  * @public
2295
- * @default `0 0 20 20`
2296
2304
  * @remarks
2297
2305
  * HTML Attribute: `icon-view-box`
2306
+ * @deprecated Add `viewBox` attribute on the custom SVG directly.
2298
2307
  */
2299
2308
  iconViewBox?: string;
2300
2309
  /**
@@ -2307,6 +2316,7 @@ export declare class BaseRatingDisplay extends FASTElement {
2307
2316
  * HTML Attribute: `max`
2308
2317
  */
2309
2318
  max?: number;
2319
+ protected maxChanged(): void;
2310
2320
  /**
2311
2321
  * The value of the rating.
2312
2322
  *
@@ -2315,44 +2325,19 @@ export declare class BaseRatingDisplay extends FASTElement {
2315
2325
  * HTML Attribute: `value`
2316
2326
  */
2317
2327
  value?: number;
2318
- /**
2319
- * @internal
2320
- */
2321
- slottedIcon: HTMLElement[];
2322
- /**
2323
- * @internal
2324
- */
2325
- slottedIconChanged(): void;
2326
- /**
2327
- * @internal
2328
- */
2329
- private customIcon?;
2330
- private intlNumberFormatter;
2328
+ protected valueChanged(): void;
2331
2329
  constructor();
2330
+ connectedCallback(): void;
2332
2331
  /**
2333
2332
  * Returns "count" as string, formatted according to the locale.
2334
2333
  *
2335
2334
  * @internal
2336
2335
  */
2337
2336
  get formattedCount(): string;
2338
- /**
2339
- * Gets the selected value
2340
- *
2341
- * @protected
2342
- */
2343
- protected getSelectedValue(): number;
2344
- /**
2345
- * Gets the maximum icons to render
2346
- *
2347
- * @protected
2348
- */
2349
- protected getMaxIcons(): number;
2350
- /**
2351
- * Generates the icon SVG elements based on the "max" attribute.
2352
- *
2353
- * @internal
2354
- */
2355
- generateIcons(): string;
2337
+ /** @internal */
2338
+ handleSlotChange(): void;
2339
+ protected renderSlottedIcon(svg: SVGSVGElement | null): void;
2340
+ protected setCustomPropertyValue(propertyName: PropertyNameForCalculation): void;
2356
2341
  }
2357
2342
 
2358
2343
  /**
@@ -8776,6 +8761,8 @@ export declare const ProgressBarValidationState: {
8776
8761
  */
8777
8762
  export declare type ProgressBarValidationState = ValuesOf<typeof ProgressBarValidationState>;
8778
8763
 
8764
+ declare type PropertyNameForCalculation = 'max' | 'value';
8765
+
8779
8766
  /**
8780
8767
  * A Radio Custom HTML Element.
8781
8768
  * Implements the {@link https://w3c.github.io/aria/#radio | ARIA `radio` role}.
@@ -9208,18 +9195,6 @@ export declare class RatingDisplay extends BaseRatingDisplay {
9208
9195
  * HTML Attribute: `compact`
9209
9196
  */
9210
9197
  compact: boolean;
9211
- /**
9212
- * Overrides the selected value and returns 1 if compact is true.
9213
- *
9214
- * @override
9215
- */
9216
- protected getSelectedValue(): number;
9217
- /**
9218
- * Overrides the maximum icons and returns a max of 1 if compact is true.
9219
- *
9220
- * @override
9221
- */
9222
- protected getMaxIcons(): number;
9223
9198
  }
9224
9199
 
9225
9200
  /**
@@ -10396,6 +10396,19 @@ var __decorateClass$j = (decorators, target, key, kind) => {
10396
10396
  if (kind && result) __defProp$j(target, key, result);
10397
10397
  return result;
10398
10398
  };
10399
+ const SUPPORTS_ATTR_TYPE = CSS.supports("width: attr(value type(<number>))");
10400
+ const CUSTOM_PROPERTY_NAME = {
10401
+ max: "--_attr-max",
10402
+ value: "--_attr-value",
10403
+ maskImageFilled: "--_mask-image-filled",
10404
+ maskImageOutlined: "--_mask-image-outlined"
10405
+ };
10406
+ function svgToDataURI(svg) {
10407
+ if (!svg) {
10408
+ return "";
10409
+ }
10410
+ return ["data:image/svg+xml", encodeURIComponent(svg.replace(/\n/g, "").replace(/\s+/g, " "))].join(",");
10411
+ }
10399
10412
  class BaseRatingDisplay extends FASTElement {
10400
10413
  constructor() {
10401
10414
  super();
@@ -10405,16 +10418,20 @@ class BaseRatingDisplay extends FASTElement {
10405
10418
  * @internal
10406
10419
  */
10407
10420
  this.elementInternals = this.attachInternals();
10408
- this.intlNumberFormatter = new Intl.NumberFormat();
10421
+ this.defaultCustomIconViewBox = "0 0 20 20";
10409
10422
  this.elementInternals.role = "img";
10423
+ this.numberFormatter = new Intl.NumberFormat();
10410
10424
  }
10411
- /**
10412
- * @internal
10413
- */
10414
- slottedIconChanged() {
10415
- if (this.$fastController.isConnected) {
10416
- this.customIcon = this.slottedIcon[0]?.outerHTML;
10417
- }
10425
+ maxChanged() {
10426
+ this.setCustomPropertyValue("max");
10427
+ }
10428
+ valueChanged() {
10429
+ this.setCustomPropertyValue("value");
10430
+ }
10431
+ connectedCallback() {
10432
+ super.connectedCallback();
10433
+ this.setCustomPropertyValue("value");
10434
+ this.setCustomPropertyValue("max");
10418
10435
  }
10419
10436
  /**
10420
10437
  * Returns "count" as string, formatted according to the locale.
@@ -10422,41 +10439,47 @@ class BaseRatingDisplay extends FASTElement {
10422
10439
  * @internal
10423
10440
  */
10424
10441
  get formattedCount() {
10425
- return this.count ? this.intlNumberFormatter.format(this.count) : "";
10442
+ return this.count ? this.numberFormatter.format(this.count) : "";
10426
10443
  }
10427
- /**
10428
- * Gets the selected value
10429
- *
10430
- * @protected
10431
- */
10432
- getSelectedValue() {
10433
- return Math.round((this.value ?? 0) * 2) / 2;
10434
- }
10435
- /**
10436
- * Gets the maximum icons to render
10437
- *
10438
- * @protected
10439
- */
10440
- getMaxIcons() {
10441
- return (this.max ?? 5) * 2;
10442
- }
10443
- /**
10444
- * Generates the icon SVG elements based on the "max" attribute.
10445
- *
10446
- * @internal
10447
- */
10448
- generateIcons() {
10449
- let htmlString = "";
10450
- let customIcon;
10451
- if (this.customIcon) {
10452
- customIcon = /<svg[^>]*>([\s\S]*?)<\/svg>/.exec(this.customIcon)?.[1] ?? "";
10444
+ /** @internal */
10445
+ handleSlotChange() {
10446
+ const icon = this.iconSlot.assignedElements()?.find(el => el.nodeName.toLowerCase() === "svg");
10447
+ this.renderSlottedIcon(icon ?? null);
10448
+ }
10449
+ renderSlottedIcon(svg) {
10450
+ if (!svg) {
10451
+ this.display.style.removeProperty(CUSTOM_PROPERTY_NAME.maskImageFilled);
10452
+ this.display.style.removeProperty(CUSTOM_PROPERTY_NAME.maskImageOutlined);
10453
+ return;
10453
10454
  }
10454
- const selectedValue = this.getSelectedValue();
10455
- for (let i = 0; i < this.getMaxIcons(); i++) {
10456
- const iconValue = (i + 1) / 2;
10457
- htmlString += `<svg aria-hidden="true" viewBox="${this.iconViewBox ?? "0 0 20 20"}" ${iconValue === selectedValue ? "selected" : ""}>${customIcon ?? '<use href="#star"></use>'}</svg>`;
10455
+ const innerSvg = svg.innerHTML;
10456
+ const viewBox = svg.getAttribute("viewBox") ?? this.iconViewBox ?? this.defaultCustomIconViewBox;
10457
+ const customSvgFilled = `
10458
+ <svg
10459
+ viewBox="${viewBox}"
10460
+ xmlns="http://www.w3.org/2000/svg"
10461
+ >${innerSvg}</svg>`;
10462
+ const customSvgOutlined = `
10463
+ <svg
10464
+ viewBox="${viewBox}"
10465
+ xmlns="http://www.w3.org/2000/svg"
10466
+ fill="none"
10467
+ stroke="black"
10468
+ stroke-width="2"
10469
+ >${innerSvg}</svg>`;
10470
+ this.display.style.setProperty(CUSTOM_PROPERTY_NAME.maskImageFilled, `url(${svgToDataURI(customSvgFilled)})`);
10471
+ this.display.style.setProperty(CUSTOM_PROPERTY_NAME.maskImageOutlined, `url(${svgToDataURI(customSvgOutlined)})`);
10472
+ }
10473
+ setCustomPropertyValue(propertyName) {
10474
+ if (!this.display || SUPPORTS_ATTR_TYPE) {
10475
+ return;
10476
+ }
10477
+ const propertyValue = this[propertyName];
10478
+ if (typeof propertyValue !== "number" || Number.isNaN(propertyValue)) {
10479
+ this.display.style.removeProperty(CUSTOM_PROPERTY_NAME[propertyName]);
10480
+ } else {
10481
+ this.display.style.setProperty(CUSTOM_PROPERTY_NAME[propertyName], `${propertyValue}`);
10458
10482
  }
10459
- return htmlString;
10460
10483
  }
10461
10484
  }
10462
10485
  __decorateClass$j([attr({
@@ -10471,8 +10494,6 @@ __decorateClass$j([attr({
10471
10494
  __decorateClass$j([attr({
10472
10495
  converter: nullableNumberConverter
10473
10496
  })], BaseRatingDisplay.prototype, "value", 2);
10474
- __decorateClass$j([observable], BaseRatingDisplay.prototype, "slottedIcon", 2);
10475
- __decorateClass$j([observable], BaseRatingDisplay.prototype, "customIcon", 2);
10476
10497
 
10477
10498
  var __defProp$i = Object.defineProperty;
10478
10499
  var __getOwnPropDesc$i = Object.getOwnPropertyDescriptor;
@@ -10487,22 +10508,6 @@ class RatingDisplay extends BaseRatingDisplay {
10487
10508
  super(...arguments);
10488
10509
  this.compact = false;
10489
10510
  }
10490
- /**
10491
- * Overrides the selected value and returns 1 if compact is true.
10492
- *
10493
- * @override
10494
- */
10495
- getSelectedValue() {
10496
- return Math.round((this.compact ? 1 : this.value ?? 0) * 2) / 2;
10497
- }
10498
- /**
10499
- * Overrides the maximum icons and returns a max of 1 if compact is true.
10500
- *
10501
- * @override
10502
- */
10503
- getMaxIcons() {
10504
- return (this.compact ? 1 : this.max ?? 5) * 2;
10505
- }
10506
10511
  }
10507
10512
  __decorateClass$i([attr], RatingDisplay.prototype, "color", 2);
10508
10513
  __decorateClass$i([attr], RatingDisplay.prototype, "size", 2);
@@ -10510,21 +10515,30 @@ __decorateClass$i([attr({
10510
10515
  mode: "boolean"
10511
10516
  })], RatingDisplay.prototype, "compact", 2);
10512
10517
 
10513
- const styles$e = css`
10514
- ${display("inline-flex")}
10515
-
10516
- :host{--icon-size:16px;--icon-color-filled:${colorPaletteMarigoldBorderActive};--icon-color-empty:${colorPaletteMarigoldBackground2};align-items:center;color:${colorNeutralForeground1};font-family:${fontFamilyBase};font-size:${fontSizeBase200};line-height:${lineHeightBase200};contain:layout style;user-select:none}:host([size='small']){--icon-size:12px}:host([size='large']){--icon-size:20px;font-size:${fontSizeBase300};line-height:${lineHeightBase300}}::slotted([slot='icon']){display:none}svg{width:var(--icon-size);height:var(--icon-size);fill:var(--icon-color-filled);margin-inline-end:${spacingHorizontalXXS}}svg:nth-child(odd){clip-path:inset(0 50% 0 0);margin-inline-end:calc(0px - var(--icon-size))}:host([color='neutral']) svg{--icon-color-filled:${colorNeutralForeground1}}:host([color='brand']) svg{--icon-color-filled:${colorBrandForeground1}}:host(:is([value^='-'],[value='0'])) svg,:host(:not([value])) svg,svg[selected] ~ svg{fill:var(--icon-color-empty)}:host([color='neutral']:is([value^='-'],[value='0'],:not([value]))) svg,:host([color='neutral']) svg[selected] ~ svg{--icon-color-empty:${colorNeutralBackground6}}:host([color='brand']:is([value^='-'],[value='0'],:not([value]))) svg,:host([color='brand']) svg[selected] ~ svg{--icon-color-empty:${colorBrandBackground2}}.value-label,::slotted([slot='value']){display:block;margin-inline-start:${spacingHorizontalXS};font-weight:${fontWeightSemibold}}:host([size='small']) .value-label,:host([size='small']) ::slotted([slot='value']){margin-inline-start:${spacingHorizontalXXS}}:host([size='large']) .value-label,:host([size='large']) ::slotted([slot='value']){margin-inline-start:${spacingHorizontalSNudge}}:host(:not([count])) .count-label{display:none}.count-label::before,::slotted([slot='count'])::before{content:'·';margin-inline:${spacingHorizontalXS}}:host([size='small']) .count-label::before,:host([size='small']) ::slotted([slot='count'])::before{margin-inline:${spacingHorizontalXXS}}:host([size='large']) .count-label::before,:host([size='large']) ::slotted([slot='count'])::before{margin-inline:${spacingHorizontalSNudge}}`.withBehaviors(forcedColorsStylesheetBehavior(css`
10517
- :host([color]) svg{fill:CanvasText}:host([color]:is([value^='-'],[value='0'])) svg,:host(:not([value])) svg,:host([color]) svg[selected] ~ svg{fill:Canvas;stroke:CanvasText}`));
10518
-
10519
- const star = html`<svg xmlns="http://www.w3.org/2000/svg" style="display: none"><symbol id="star"><path d="M9.10433 2.89874C9.47114 2.15549 10.531 2.1555 10.8978 2.89874L12.8282 6.81024L17.1448 7.43748C17.9651 7.55666 18.2926 8.56464 17.699 9.14317L14.5755 12.1878L15.3129 16.487C15.453 17.3039 14.5956 17.9269 13.8619 17.5412L10.0011 15.5114L6.14018 17.5412C5.40655 17.9269 4.54913 17.3039 4.68924 16.487L5.4266 12.1878L2.30308 9.14317C1.70956 8.56463 2.03708 7.55666 2.8573 7.43748L7.17389 6.81024L9.10433 2.89874Z" /></symbol></svg>`;
10518
+ const defaultIconPath = `<path d="M5.28347 1.54605C5.57692 0.951448 6.42479 0.951449 6.71825 1.54605L7.82997 3.79866L10.3159 4.15988C10.9721 4.25523 11.2341 5.0616 10.7592 5.52443L8.96043 7.27785L9.38507 9.7537C9.49716 10.4072 8.81122 10.9056 8.22431 10.597L6.00086 9.4281L3.7774 10.597C3.19049 10.9056 2.50455 10.4072 2.61664 9.7537L3.04128 7.27784L1.24246 5.52443C0.767651 5.0616 1.02966 4.25523 1.68584 4.15988L4.17174 3.79865L5.28347 1.54605Z" />`;
10519
+ const defaultIconFilled = `
10520
+ <svg viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">${defaultIconPath}</svg>
10521
+ `;
10522
+ const defaultIconOutlined = `
10523
+ <svg viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"
10524
+ fill="none" stroke="black" stroke-width="2"
10525
+ >${defaultIconPath}</svg>
10526
+ `;
10520
10527
  function ratingDisplayTemplate() {
10521
- return html` ${x => html`${staticallyCompose(x.generateIcons())}`}<slot name="icon" ${slotted({
10522
- property: "slottedIcon",
10523
- filter: elements("svg")
10524
- })}>${star}</slot><slot name="value"><span class="value-label" aria-hidden="true">${x => x.value}</span></slot><slot name="count"><span class="count-label" aria-hidden="true">${x => x.formattedCount}</span></slot>`;
10528
+ return html`<div ${ref("display")} class="display" aria-hidden="true"></div><slot name="icon" ${ref("iconSlot")} @slotchange="${x => x.handleSlotChange()}"></slot><slot name="value"><span class="value-label" aria-hidden="true">${x => x.value}</span></slot><slot name="count"><span class="count-label" aria-hidden="true">${x => x.formattedCount}</span></slot>`;
10525
10529
  }
10526
10530
  const template$e = ratingDisplayTemplate();
10527
10531
 
10532
+ const styles$e = css`
10533
+ ${display("inline-flex")}
10534
+
10535
+ :host{--_icon-size:16px;--_icon-gradient-degree:90deg;--_icon-color-value:${colorPaletteMarigoldBorderActive};--_icon-color-empty:${colorPaletteMarigoldBackground2};--_default-value:0;--_default-max:5;--_mask-image-filled:url(${svgToDataURI(defaultIconFilled)});--_mask-image-outlined:url(${svgToDataURI(defaultIconOutlined)});--_mask-position-x:left;align-items:center;color:${colorNeutralForeground1};font-family:${fontFamilyBase};font-size:${fontSizeBase200};line-height:${lineHeightBase200};contain:layout style;user-select:none}:host(:dir(rtl)){--_icon-gradient-degree:-90deg;--_mask-position-x:right}:host([size='small']){--_icon-size:12px}:host([size='large']){--_icon-size:20px;font-size:${fontSizeBase300};line-height:${lineHeightBase300}}::slotted([slot='icon']){display:none}:host([color='neutral']){--_icon-color-value:${colorNeutralForeground1};--_icon-color-empty:${colorNeutralBackground6}}:host([color='brand']){--_icon-color-value:${colorBrandForeground1};--_icon-color-empty:${colorBrandBackground2}}@supports (width:attr(value type(<number>))){:host{--_attr-value:attr(value type(<number>));--_attr-max:attr(max type(<number>))}}:host([compact]) .display{--_max:1}.display{--_value:max(0,round(var(--_attr-value,var(--_default-value)) * 2) / 2);--_max:max(1,var(--_attr-max,var(--_default-max)));--_mask-inline-size:calc(var(--_icon-size) + ${spacingHorizontalXXS});--_icon-gradient-stop-visual-adjustment:0px;--_icon-gradient-stop:calc(
10536
+ var(--_mask-inline-size) * var(--_value) - var(--_icon-gradient-stop-visual-adjustment)
10537
+ );background-image:linear-gradient(
10538
+ var(--_icon-gradient-degree),var(--_icon-color-value) var(--_icon-gradient-stop),var(--_icon-color-empty) calc(var(--_icon-gradient-stop) + 0.5px)
10539
+ );block-size:var(--_icon-size);display:grid;inline-size:calc(var(--_max) * var(--_mask-inline-size) - ${spacingHorizontalXXS} / 2);mask-image:var(--_mask-image-filled);mask-repeat:repeat no-repeat;mask-size:var(--_mask-inline-size) var(--_icon-size);mask-position:var(--_mask-position-x) center}.value-label,::slotted([slot='value']){display:block;margin-inline-start:${spacingHorizontalXS};font-weight:${fontWeightSemibold}}:host([size='small']) .value-label,:host([size='small']) ::slotted([slot='value']){margin-inline-start:${spacingHorizontalXXS}}:host([size='large']) .value-label,:host([size='large']) ::slotted([slot='value']){margin-inline-start:${spacingHorizontalSNudge}}:host(:not([count])) .count-label{display:none}.count-label::before,::slotted([slot='count'])::before{content:'·';margin-inline:${spacingHorizontalXS}}:host([size='small']) .count-label::before,:host([size='small']) ::slotted([slot='count'])::before{margin-inline:${spacingHorizontalXXS}}:host([size='large']) .count-label::before,:host([size='large']) ::slotted([slot='count'])::before{margin-inline:${spacingHorizontalSNudge}}`.withBehaviors(forcedColorsStylesheetBehavior(css`
10540
+ .display{--_icon-color-value:CanvasText;--_icon-color-empty:Canvas;--_icon-gradient-stop-visual-adjustment:0.5px;forced-color-adjust:none}.display::before{background-color:var(--_icon-color-value);content:'';grid-area:1 / 1 / -1 / -1;mask:inherit;mask-image:var(--_mask-image-outlined)}`));
10541
+
10528
10542
  const definition$e = RatingDisplay.compose({
10529
10543
  name: `${FluentDesignSystem.prefix}-rating-display`,
10530
10544
  template: template$e,