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

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.
@@ -7101,7 +7101,8 @@ function requestIdleCallback(callback, options) {
7101
7101
  const start = Date.now();
7102
7102
  return setTimeout(() => {
7103
7103
  callback({
7104
- didTimeout: options?.timeout ? Date.now() - start >= options.timeout : false
7104
+ didTimeout: options?.timeout ? Date.now() - start >= options.timeout : false,
7105
+ timeRemaining: () => 0
7105
7106
  });
7106
7107
  }, 1);
7107
7108
  }
@@ -7112,25 +7113,22 @@ function cancelIdleCallback(id) {
7112
7113
  clearTimeout(id);
7113
7114
  }
7114
7115
  }
7115
- function waitForConnectedDescendants(target, callback, options = {
7116
- shallow: false,
7117
- timeout: 50
7118
- }) {
7116
+ function waitForConnectedDescendants(target, callback, options) {
7119
7117
  let idleCallbackId;
7120
- const query = options.shallow ? ":scope > *" : "*";
7121
- if (!target.isConnected) {
7122
- return;
7123
- }
7124
- const scheduleCheck = () => {
7118
+ const shallow = options?.shallow ?? false;
7119
+ const query = `${shallow ? ":scope > " : ""}:not(:defined)`;
7120
+ const timeout = options?.timeout ?? 50;
7121
+ const scheduleCheck = deadline => {
7125
7122
  if (idleCallbackId) {
7126
- idleCallbackId = cancelIdleCallback(idleCallbackId);
7123
+ cancelIdleCallback(idleCallbackId);
7124
+ idleCallbackId = void 0;
7127
7125
  }
7128
- if (Array.from(target.querySelectorAll(query)).filter(el => el.tagName.includes("-")).every(el => el.isConnected)) {
7126
+ if (!target.querySelector(query) || deadline && deadline.timeRemaining() <= 0) {
7129
7127
  callback();
7130
7128
  return;
7131
7129
  }
7132
7130
  idleCallbackId = requestIdleCallback(scheduleCheck, {
7133
- timeout: options.timeout
7131
+ timeout
7134
7132
  });
7135
7133
  };
7136
7134
  scheduleCheck();
@@ -8453,8 +8451,9 @@ class Listbox extends FASTElement {
8453
8451
  * @public
8454
8452
  */
8455
8453
  slotchangeHandler(e) {
8454
+ const target = e.target;
8456
8455
  waitForConnectedDescendants(this, () => {
8457
- const options = e.target.assignedElements().filter(option => isDropdownOption(option));
8456
+ const options = target.assignedElements().filter(option => isDropdownOption(option));
8458
8457
  this.options = options;
8459
8458
  });
8460
8459
  }
@@ -10396,6 +10395,19 @@ var __decorateClass$j = (decorators, target, key, kind) => {
10396
10395
  if (kind && result) __defProp$j(target, key, result);
10397
10396
  return result;
10398
10397
  };
10398
+ const SUPPORTS_ATTR_TYPE = CSS.supports("width: attr(value type(<number>))");
10399
+ const CUSTOM_PROPERTY_NAME = {
10400
+ max: "--_attr-max",
10401
+ value: "--_attr-value",
10402
+ maskImageFilled: "--_mask-image-filled",
10403
+ maskImageOutlined: "--_mask-image-outlined"
10404
+ };
10405
+ function svgToDataURI(svg) {
10406
+ if (!svg) {
10407
+ return "";
10408
+ }
10409
+ return ["data:image/svg+xml", encodeURIComponent(svg.replace(/\n/g, "").replace(/\s+/g, " "))].join(",");
10410
+ }
10399
10411
  class BaseRatingDisplay extends FASTElement {
10400
10412
  constructor() {
10401
10413
  super();
@@ -10405,16 +10417,20 @@ class BaseRatingDisplay extends FASTElement {
10405
10417
  * @internal
10406
10418
  */
10407
10419
  this.elementInternals = this.attachInternals();
10408
- this.intlNumberFormatter = new Intl.NumberFormat();
10420
+ this.defaultCustomIconViewBox = "0 0 20 20";
10409
10421
  this.elementInternals.role = "img";
10422
+ this.numberFormatter = new Intl.NumberFormat();
10410
10423
  }
10411
- /**
10412
- * @internal
10413
- */
10414
- slottedIconChanged() {
10415
- if (this.$fastController.isConnected) {
10416
- this.customIcon = this.slottedIcon[0]?.outerHTML;
10417
- }
10424
+ maxChanged() {
10425
+ this.setCustomPropertyValue("max");
10426
+ }
10427
+ valueChanged() {
10428
+ this.setCustomPropertyValue("value");
10429
+ }
10430
+ connectedCallback() {
10431
+ super.connectedCallback();
10432
+ this.setCustomPropertyValue("value");
10433
+ this.setCustomPropertyValue("max");
10418
10434
  }
10419
10435
  /**
10420
10436
  * Returns "count" as string, formatted according to the locale.
@@ -10422,41 +10438,47 @@ class BaseRatingDisplay extends FASTElement {
10422
10438
  * @internal
10423
10439
  */
10424
10440
  get formattedCount() {
10425
- return this.count ? this.intlNumberFormatter.format(this.count) : "";
10426
- }
10427
- /**
10428
- * Gets the selected value
10429
- *
10430
- * @protected
10431
- */
10432
- getSelectedValue() {
10433
- return Math.round((this.value ?? 0) * 2) / 2;
10441
+ return this.count ? this.numberFormatter.format(this.count) : "";
10434
10442
  }
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] ?? "";
10443
+ /** @internal */
10444
+ handleSlotChange() {
10445
+ const icon = this.iconSlot.assignedElements()?.find(el => el.nodeName.toLowerCase() === "svg");
10446
+ this.renderSlottedIcon(icon ?? null);
10447
+ }
10448
+ renderSlottedIcon(svg) {
10449
+ if (!svg) {
10450
+ this.display.style.removeProperty(CUSTOM_PROPERTY_NAME.maskImageFilled);
10451
+ this.display.style.removeProperty(CUSTOM_PROPERTY_NAME.maskImageOutlined);
10452
+ return;
10453
10453
  }
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>`;
10454
+ const innerSvg = svg.innerHTML;
10455
+ const viewBox = svg.getAttribute("viewBox") ?? this.iconViewBox ?? this.defaultCustomIconViewBox;
10456
+ const customSvgFilled = `
10457
+ <svg
10458
+ viewBox="${viewBox}"
10459
+ xmlns="http://www.w3.org/2000/svg"
10460
+ >${innerSvg}</svg>`;
10461
+ const customSvgOutlined = `
10462
+ <svg
10463
+ viewBox="${viewBox}"
10464
+ xmlns="http://www.w3.org/2000/svg"
10465
+ fill="none"
10466
+ stroke="black"
10467
+ stroke-width="2"
10468
+ >${innerSvg}</svg>`;
10469
+ this.display.style.setProperty(CUSTOM_PROPERTY_NAME.maskImageFilled, `url(${svgToDataURI(customSvgFilled)})`);
10470
+ this.display.style.setProperty(CUSTOM_PROPERTY_NAME.maskImageOutlined, `url(${svgToDataURI(customSvgOutlined)})`);
10471
+ }
10472
+ setCustomPropertyValue(propertyName) {
10473
+ if (!this.display || SUPPORTS_ATTR_TYPE) {
10474
+ return;
10475
+ }
10476
+ const propertyValue = this[propertyName];
10477
+ if (typeof propertyValue !== "number" || Number.isNaN(propertyValue)) {
10478
+ this.display.style.removeProperty(CUSTOM_PROPERTY_NAME[propertyName]);
10479
+ } else {
10480
+ this.display.style.setProperty(CUSTOM_PROPERTY_NAME[propertyName], `${propertyValue}`);
10458
10481
  }
10459
- return htmlString;
10460
10482
  }
10461
10483
  }
10462
10484
  __decorateClass$j([attr({
@@ -10471,8 +10493,6 @@ __decorateClass$j([attr({
10471
10493
  __decorateClass$j([attr({
10472
10494
  converter: nullableNumberConverter
10473
10495
  })], BaseRatingDisplay.prototype, "value", 2);
10474
- __decorateClass$j([observable], BaseRatingDisplay.prototype, "slottedIcon", 2);
10475
- __decorateClass$j([observable], BaseRatingDisplay.prototype, "customIcon", 2);
10476
10496
 
10477
10497
  var __defProp$i = Object.defineProperty;
10478
10498
  var __getOwnPropDesc$i = Object.getOwnPropertyDescriptor;
@@ -10487,22 +10507,6 @@ class RatingDisplay extends BaseRatingDisplay {
10487
10507
  super(...arguments);
10488
10508
  this.compact = false;
10489
10509
  }
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
10510
  }
10507
10511
  __decorateClass$i([attr], RatingDisplay.prototype, "color", 2);
10508
10512
  __decorateClass$i([attr], RatingDisplay.prototype, "size", 2);
@@ -10510,21 +10514,30 @@ __decorateClass$i([attr({
10510
10514
  mode: "boolean"
10511
10515
  })], RatingDisplay.prototype, "compact", 2);
10512
10516
 
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>`;
10517
+ 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" />`;
10518
+ const defaultIconFilled = `
10519
+ <svg viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">${defaultIconPath}</svg>
10520
+ `;
10521
+ const defaultIconOutlined = `
10522
+ <svg viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"
10523
+ fill="none" stroke="black" stroke-width="2"
10524
+ >${defaultIconPath}</svg>
10525
+ `;
10520
10526
  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>`;
10527
+ 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
10528
  }
10526
10529
  const template$e = ratingDisplayTemplate();
10527
10530
 
10531
+ const styles$e = css`
10532
+ ${display("inline-flex")}
10533
+
10534
+ :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(
10535
+ var(--_mask-inline-size) * var(--_value) - var(--_icon-gradient-stop-visual-adjustment)
10536
+ );background-image:linear-gradient(
10537
+ var(--_icon-gradient-degree),var(--_icon-color-value) var(--_icon-gradient-stop),var(--_icon-color-empty) calc(var(--_icon-gradient-stop) + 0.5px)
10538
+ );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`
10539
+ .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)}`));
10540
+
10528
10541
  const definition$e = RatingDisplay.compose({
10529
10542
  name: `${FluentDesignSystem.prefix}-rating-display`,
10530
10543
  template: template$e,