@ni/nimble-components 11.13.1 → 11.15.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.
@@ -11483,6 +11483,570 @@
11483
11483
  ], NumberField$1.prototype, "defaultSlottedNodes", void 0);
11484
11484
  applyMixins(NumberField$1, StartEnd, DelegatesARIATextbox);
11485
11485
 
11486
+ /**
11487
+ * The template for the {@link @microsoft/fast-foundation#RadioGroup} component.
11488
+ * @public
11489
+ */
11490
+ const radioGroupTemplate = (context, definition) => html `
11491
+ <template
11492
+ role="radiogroup"
11493
+ aria-disabled="${x => x.disabled}"
11494
+ aria-readonly="${x => x.readOnly}"
11495
+ @click="${(x, c) => x.clickHandler(c.event)}"
11496
+ @keydown="${(x, c) => x.keydownHandler(c.event)}"
11497
+ @focusout="${(x, c) => x.focusOutHandler(c.event)}"
11498
+ >
11499
+ <slot name="label"></slot>
11500
+ <div
11501
+ class="positioning-region ${x => x.orientation === Orientation.horizontal ? "horizontal" : "vertical"}"
11502
+ part="positioning-region"
11503
+ >
11504
+ <slot
11505
+ ${slotted({
11506
+ property: "slottedRadioButtons",
11507
+ filter: elements("[role=radio]"),
11508
+ })}
11509
+ ></slot>
11510
+ </div>
11511
+ </template>
11512
+ `;
11513
+
11514
+ /**
11515
+ * An Radio Group Custom HTML Element.
11516
+ * Implements the {@link https://www.w3.org/TR/wai-aria-1.1/#radiogroup | ARIA radiogroup }.
11517
+ *
11518
+ * @slot label - The slot for the label
11519
+ * @slot - The default slot for radio buttons
11520
+ * @csspart positioning-region - The positioning region for laying out the radios
11521
+ * @fires change - Fires a custom 'change' event when the value changes
11522
+ *
11523
+ * @public
11524
+ */
11525
+ class RadioGroup$1 extends FoundationElement {
11526
+ constructor() {
11527
+ super(...arguments);
11528
+ /**
11529
+ * The orientation of the group
11530
+ *
11531
+ * @public
11532
+ * @remarks
11533
+ * HTML Attribute: orientation
11534
+ */
11535
+ this.orientation = Orientation.horizontal;
11536
+ this.radioChangeHandler = (e) => {
11537
+ const changedRadio = e.target;
11538
+ if (changedRadio.checked) {
11539
+ this.slottedRadioButtons.forEach((radio) => {
11540
+ if (radio !== changedRadio) {
11541
+ radio.checked = false;
11542
+ if (!this.isInsideFoundationToolbar) {
11543
+ radio.setAttribute("tabindex", "-1");
11544
+ }
11545
+ }
11546
+ });
11547
+ this.selectedRadio = changedRadio;
11548
+ this.value = changedRadio.value;
11549
+ changedRadio.setAttribute("tabindex", "0");
11550
+ this.focusedRadio = changedRadio;
11551
+ }
11552
+ e.stopPropagation();
11553
+ };
11554
+ this.moveToRadioByIndex = (group, index) => {
11555
+ const radio = group[index];
11556
+ if (!this.isInsideToolbar) {
11557
+ radio.setAttribute("tabindex", "0");
11558
+ if (radio.readOnly) {
11559
+ this.slottedRadioButtons.forEach((nextRadio) => {
11560
+ if (nextRadio !== radio) {
11561
+ nextRadio.setAttribute("tabindex", "-1");
11562
+ }
11563
+ });
11564
+ }
11565
+ else {
11566
+ radio.checked = true;
11567
+ this.selectedRadio = radio;
11568
+ }
11569
+ }
11570
+ this.focusedRadio = radio;
11571
+ radio.focus();
11572
+ };
11573
+ this.moveRightOffGroup = () => {
11574
+ var _a;
11575
+ (_a = this.nextElementSibling) === null || _a === void 0 ? void 0 : _a.focus();
11576
+ };
11577
+ this.moveLeftOffGroup = () => {
11578
+ var _a;
11579
+ (_a = this.previousElementSibling) === null || _a === void 0 ? void 0 : _a.focus();
11580
+ };
11581
+ /**
11582
+ * @internal
11583
+ */
11584
+ this.focusOutHandler = (e) => {
11585
+ const group = this.slottedRadioButtons;
11586
+ const radio = e.target;
11587
+ const index = radio !== null ? group.indexOf(radio) : 0;
11588
+ const focusedIndex = this.focusedRadio
11589
+ ? group.indexOf(this.focusedRadio)
11590
+ : -1;
11591
+ if ((focusedIndex === 0 && index === focusedIndex) ||
11592
+ (focusedIndex === group.length - 1 && focusedIndex === index)) {
11593
+ if (!this.selectedRadio) {
11594
+ this.focusedRadio = group[0];
11595
+ this.focusedRadio.setAttribute("tabindex", "0");
11596
+ group.forEach((nextRadio) => {
11597
+ if (nextRadio !== this.focusedRadio) {
11598
+ nextRadio.setAttribute("tabindex", "-1");
11599
+ }
11600
+ });
11601
+ }
11602
+ else {
11603
+ this.focusedRadio = this.selectedRadio;
11604
+ if (!this.isInsideFoundationToolbar) {
11605
+ this.selectedRadio.setAttribute("tabindex", "0");
11606
+ group.forEach((nextRadio) => {
11607
+ if (nextRadio !== this.selectedRadio) {
11608
+ nextRadio.setAttribute("tabindex", "-1");
11609
+ }
11610
+ });
11611
+ }
11612
+ }
11613
+ }
11614
+ return true;
11615
+ };
11616
+ /**
11617
+ * @internal
11618
+ */
11619
+ this.clickHandler = (e) => {
11620
+ const radio = e.target;
11621
+ if (radio) {
11622
+ const group = this.slottedRadioButtons;
11623
+ if (radio.checked || group.indexOf(radio) === 0) {
11624
+ radio.setAttribute("tabindex", "0");
11625
+ this.selectedRadio = radio;
11626
+ }
11627
+ else {
11628
+ radio.setAttribute("tabindex", "-1");
11629
+ this.selectedRadio = null;
11630
+ }
11631
+ this.focusedRadio = radio;
11632
+ }
11633
+ e.preventDefault();
11634
+ };
11635
+ this.shouldMoveOffGroupToTheRight = (index, group, key) => {
11636
+ return index === group.length && this.isInsideToolbar && key === keyArrowRight;
11637
+ };
11638
+ this.shouldMoveOffGroupToTheLeft = (group, key) => {
11639
+ const index = this.focusedRadio ? group.indexOf(this.focusedRadio) - 1 : 0;
11640
+ return index < 0 && this.isInsideToolbar && key === keyArrowLeft;
11641
+ };
11642
+ this.checkFocusedRadio = () => {
11643
+ if (this.focusedRadio !== null &&
11644
+ !this.focusedRadio.readOnly &&
11645
+ !this.focusedRadio.checked) {
11646
+ this.focusedRadio.checked = true;
11647
+ this.focusedRadio.setAttribute("tabindex", "0");
11648
+ this.focusedRadio.focus();
11649
+ this.selectedRadio = this.focusedRadio;
11650
+ }
11651
+ };
11652
+ this.moveRight = (e) => {
11653
+ const group = this.slottedRadioButtons;
11654
+ let index = 0;
11655
+ index = this.focusedRadio ? group.indexOf(this.focusedRadio) + 1 : 1;
11656
+ if (this.shouldMoveOffGroupToTheRight(index, group, e.key)) {
11657
+ this.moveRightOffGroup();
11658
+ return;
11659
+ }
11660
+ else if (index === group.length) {
11661
+ index = 0;
11662
+ }
11663
+ /* looping to get to next radio that is not disabled */
11664
+ /* matching native radio/radiogroup which does not select an item if there is only 1 in the group */
11665
+ while (index < group.length && group.length > 1) {
11666
+ if (!group[index].disabled) {
11667
+ this.moveToRadioByIndex(group, index);
11668
+ break;
11669
+ }
11670
+ else if (this.focusedRadio && index === group.indexOf(this.focusedRadio)) {
11671
+ break;
11672
+ }
11673
+ else if (index + 1 >= group.length) {
11674
+ if (this.isInsideToolbar) {
11675
+ break;
11676
+ }
11677
+ else {
11678
+ index = 0;
11679
+ }
11680
+ }
11681
+ else {
11682
+ index += 1;
11683
+ }
11684
+ }
11685
+ };
11686
+ this.moveLeft = (e) => {
11687
+ const group = this.slottedRadioButtons;
11688
+ let index = 0;
11689
+ index = this.focusedRadio ? group.indexOf(this.focusedRadio) - 1 : 0;
11690
+ index = index < 0 ? group.length - 1 : index;
11691
+ if (this.shouldMoveOffGroupToTheLeft(group, e.key)) {
11692
+ this.moveLeftOffGroup();
11693
+ return;
11694
+ }
11695
+ /* looping to get to next radio that is not disabled */
11696
+ while (index >= 0 && group.length > 1) {
11697
+ if (!group[index].disabled) {
11698
+ this.moveToRadioByIndex(group, index);
11699
+ break;
11700
+ }
11701
+ else if (this.focusedRadio && index === group.indexOf(this.focusedRadio)) {
11702
+ break;
11703
+ }
11704
+ else if (index - 1 < 0) {
11705
+ index = group.length - 1;
11706
+ }
11707
+ else {
11708
+ index -= 1;
11709
+ }
11710
+ }
11711
+ };
11712
+ /**
11713
+ * keyboard handling per https://w3c.github.io/aria-practices/#for-radio-groups-not-contained-in-a-toolbar
11714
+ * navigation is different when there is an ancestor with role='toolbar'
11715
+ *
11716
+ * @internal
11717
+ */
11718
+ this.keydownHandler = (e) => {
11719
+ const key = e.key;
11720
+ if (key in ArrowKeys && this.isInsideFoundationToolbar) {
11721
+ return true;
11722
+ }
11723
+ switch (key) {
11724
+ case keyEnter: {
11725
+ this.checkFocusedRadio();
11726
+ break;
11727
+ }
11728
+ case keyArrowRight:
11729
+ case keyArrowDown: {
11730
+ if (this.direction === Direction.ltr) {
11731
+ this.moveRight(e);
11732
+ }
11733
+ else {
11734
+ this.moveLeft(e);
11735
+ }
11736
+ break;
11737
+ }
11738
+ case keyArrowLeft:
11739
+ case keyArrowUp: {
11740
+ if (this.direction === Direction.ltr) {
11741
+ this.moveLeft(e);
11742
+ }
11743
+ else {
11744
+ this.moveRight(e);
11745
+ }
11746
+ break;
11747
+ }
11748
+ default: {
11749
+ return true;
11750
+ }
11751
+ }
11752
+ };
11753
+ }
11754
+ readOnlyChanged() {
11755
+ if (this.slottedRadioButtons !== undefined) {
11756
+ this.slottedRadioButtons.forEach((radio) => {
11757
+ if (this.readOnly) {
11758
+ radio.readOnly = true;
11759
+ }
11760
+ else {
11761
+ radio.readOnly = false;
11762
+ }
11763
+ });
11764
+ }
11765
+ }
11766
+ disabledChanged() {
11767
+ if (this.slottedRadioButtons !== undefined) {
11768
+ this.slottedRadioButtons.forEach((radio) => {
11769
+ if (this.disabled) {
11770
+ radio.disabled = true;
11771
+ }
11772
+ else {
11773
+ radio.disabled = false;
11774
+ }
11775
+ });
11776
+ }
11777
+ }
11778
+ nameChanged() {
11779
+ if (this.slottedRadioButtons) {
11780
+ this.slottedRadioButtons.forEach((radio) => {
11781
+ radio.setAttribute("name", this.name);
11782
+ });
11783
+ }
11784
+ }
11785
+ valueChanged() {
11786
+ if (this.slottedRadioButtons) {
11787
+ this.slottedRadioButtons.forEach((radio) => {
11788
+ if (radio.value === this.value) {
11789
+ radio.checked = true;
11790
+ this.selectedRadio = radio;
11791
+ }
11792
+ });
11793
+ }
11794
+ this.$emit("change");
11795
+ }
11796
+ slottedRadioButtonsChanged(oldValue, newValue) {
11797
+ if (this.slottedRadioButtons && this.slottedRadioButtons.length > 0) {
11798
+ this.setupRadioButtons();
11799
+ }
11800
+ }
11801
+ get parentToolbar() {
11802
+ return this.closest('[role="toolbar"]');
11803
+ }
11804
+ get isInsideToolbar() {
11805
+ var _a;
11806
+ return ((_a = this.parentToolbar) !== null && _a !== void 0 ? _a : false);
11807
+ }
11808
+ get isInsideFoundationToolbar() {
11809
+ var _a;
11810
+ return !!((_a = this.parentToolbar) === null || _a === void 0 ? void 0 : _a["$fastController"]);
11811
+ }
11812
+ /**
11813
+ * @internal
11814
+ */
11815
+ connectedCallback() {
11816
+ super.connectedCallback();
11817
+ this.direction = getDirection(this);
11818
+ this.setupRadioButtons();
11819
+ }
11820
+ disconnectedCallback() {
11821
+ this.slottedRadioButtons.forEach((radio) => {
11822
+ radio.removeEventListener("change", this.radioChangeHandler);
11823
+ });
11824
+ }
11825
+ setupRadioButtons() {
11826
+ const checkedRadios = this.slottedRadioButtons.filter((radio) => {
11827
+ return radio.hasAttribute("checked");
11828
+ });
11829
+ const numberOfCheckedRadios = checkedRadios ? checkedRadios.length : 0;
11830
+ if (numberOfCheckedRadios > 1) {
11831
+ const lastCheckedRadio = checkedRadios[numberOfCheckedRadios - 1];
11832
+ lastCheckedRadio.checked = true;
11833
+ }
11834
+ let foundMatchingVal = false;
11835
+ this.slottedRadioButtons.forEach((radio) => {
11836
+ if (this.name !== undefined) {
11837
+ radio.setAttribute("name", this.name);
11838
+ }
11839
+ if (this.disabled) {
11840
+ radio.disabled = true;
11841
+ }
11842
+ if (this.readOnly) {
11843
+ radio.readOnly = true;
11844
+ }
11845
+ if (this.value && this.value === radio.value) {
11846
+ this.selectedRadio = radio;
11847
+ this.focusedRadio = radio;
11848
+ radio.checked = true;
11849
+ radio.setAttribute("tabindex", "0");
11850
+ foundMatchingVal = true;
11851
+ }
11852
+ else {
11853
+ if (!this.isInsideFoundationToolbar) {
11854
+ radio.setAttribute("tabindex", "-1");
11855
+ }
11856
+ radio.checked = false;
11857
+ }
11858
+ radio.addEventListener("change", this.radioChangeHandler);
11859
+ });
11860
+ if (this.value === undefined && this.slottedRadioButtons.length > 0) {
11861
+ const checkedRadios = this.slottedRadioButtons.filter((radio) => {
11862
+ return radio.hasAttribute("checked");
11863
+ });
11864
+ const numberOfCheckedRadios = checkedRadios !== null ? checkedRadios.length : 0;
11865
+ if (numberOfCheckedRadios > 0 && !foundMatchingVal) {
11866
+ const lastCheckedRadio = checkedRadios[numberOfCheckedRadios - 1];
11867
+ lastCheckedRadio.checked = true;
11868
+ this.focusedRadio = lastCheckedRadio;
11869
+ lastCheckedRadio.setAttribute("tabindex", "0");
11870
+ }
11871
+ else {
11872
+ this.slottedRadioButtons[0].setAttribute("tabindex", "0");
11873
+ this.focusedRadio = this.slottedRadioButtons[0];
11874
+ }
11875
+ }
11876
+ }
11877
+ }
11878
+ __decorate$1([
11879
+ attr({ attribute: "readonly", mode: "boolean" })
11880
+ ], RadioGroup$1.prototype, "readOnly", void 0);
11881
+ __decorate$1([
11882
+ attr({ attribute: "disabled", mode: "boolean" })
11883
+ ], RadioGroup$1.prototype, "disabled", void 0);
11884
+ __decorate$1([
11885
+ attr
11886
+ ], RadioGroup$1.prototype, "name", void 0);
11887
+ __decorate$1([
11888
+ attr
11889
+ ], RadioGroup$1.prototype, "value", void 0);
11890
+ __decorate$1([
11891
+ attr
11892
+ ], RadioGroup$1.prototype, "orientation", void 0);
11893
+ __decorate$1([
11894
+ observable
11895
+ ], RadioGroup$1.prototype, "childItems", void 0);
11896
+ __decorate$1([
11897
+ observable
11898
+ ], RadioGroup$1.prototype, "slottedRadioButtons", void 0);
11899
+
11900
+ /**
11901
+ * The template for the {@link @microsoft/fast-foundation#(Radio:class)} component.
11902
+ * @public
11903
+ */
11904
+ const radioTemplate = (context, definition) => html `
11905
+ <template
11906
+ role="radio"
11907
+ class="${x => (x.checked ? "checked" : "")} ${x => x.readOnly ? "readonly" : ""}"
11908
+ aria-checked="${x => x.checked}"
11909
+ aria-required="${x => x.required}"
11910
+ aria-disabled="${x => x.disabled}"
11911
+ aria-readonly="${x => x.readOnly}"
11912
+ @keypress="${(x, c) => x.keypressHandler(c.event)}"
11913
+ @click="${(x, c) => x.clickHandler(c.event)}"
11914
+ >
11915
+ <div part="control" class="control">
11916
+ <slot name="checked-indicator">
11917
+ ${definition.checkedIndicator || ""}
11918
+ </slot>
11919
+ </div>
11920
+ <label
11921
+ part="label"
11922
+ class="${x => x.defaultSlottedNodes && x.defaultSlottedNodes.length
11923
+ ? "label"
11924
+ : "label label__hidden"}"
11925
+ >
11926
+ <slot ${slotted("defaultSlottedNodes")}></slot>
11927
+ </label>
11928
+ </template>
11929
+ `;
11930
+
11931
+ class _Radio extends FoundationElement {
11932
+ }
11933
+ /**
11934
+ * A form-associated base class for the {@link @microsoft/fast-foundation#(Radio:class)} component.
11935
+ *
11936
+ * @internal
11937
+ */
11938
+ class FormAssociatedRadio extends CheckableFormAssociated(_Radio) {
11939
+ constructor() {
11940
+ super(...arguments);
11941
+ this.proxy = document.createElement("input");
11942
+ }
11943
+ }
11944
+
11945
+ /**
11946
+ * A Radio Custom HTML Element.
11947
+ * Implements the {@link https://www.w3.org/TR/wai-aria-1.1/#radio | ARIA radio }.
11948
+ *
11949
+ * @slot checked-indicator - The checked indicator
11950
+ * @slot - The default slot for the label
11951
+ * @csspart control - The element representing the visual radio control
11952
+ * @csspart label - The label
11953
+ * @fires change - Emits a custom change event when the checked state changes
11954
+ *
11955
+ * @public
11956
+ */
11957
+ class Radio extends FormAssociatedRadio {
11958
+ constructor() {
11959
+ super();
11960
+ /**
11961
+ * The element's value to be included in form submission when checked.
11962
+ * Default to "on" to reach parity with input[type="radio"]
11963
+ *
11964
+ * @internal
11965
+ */
11966
+ this.initialValue = "on";
11967
+ /**
11968
+ * @internal
11969
+ */
11970
+ this.keypressHandler = (e) => {
11971
+ switch (e.key) {
11972
+ case keySpace:
11973
+ if (!this.checked && !this.readOnly) {
11974
+ this.checked = true;
11975
+ }
11976
+ return;
11977
+ }
11978
+ return true;
11979
+ };
11980
+ this.proxy.setAttribute("type", "radio");
11981
+ }
11982
+ readOnlyChanged() {
11983
+ if (this.proxy instanceof HTMLInputElement) {
11984
+ this.proxy.readOnly = this.readOnly;
11985
+ }
11986
+ }
11987
+ /**
11988
+ * @internal
11989
+ */
11990
+ defaultCheckedChanged() {
11991
+ var _a;
11992
+ if (this.$fastController.isConnected && !this.dirtyChecked) {
11993
+ // Setting this.checked will cause us to enter a dirty state,
11994
+ // but if we are clean when defaultChecked is changed, we want to stay
11995
+ // in a clean state, so reset this.dirtyChecked
11996
+ if (!this.isInsideRadioGroup()) {
11997
+ this.checked = (_a = this.defaultChecked) !== null && _a !== void 0 ? _a : false;
11998
+ this.dirtyChecked = false;
11999
+ }
12000
+ }
12001
+ }
12002
+ /**
12003
+ * @internal
12004
+ */
12005
+ connectedCallback() {
12006
+ var _a, _b;
12007
+ super.connectedCallback();
12008
+ this.validate();
12009
+ if (((_a = this.parentElement) === null || _a === void 0 ? void 0 : _a.getAttribute("role")) !== "radiogroup" &&
12010
+ this.getAttribute("tabindex") === null) {
12011
+ if (!this.disabled) {
12012
+ this.setAttribute("tabindex", "0");
12013
+ }
12014
+ }
12015
+ if (this.checkedAttribute) {
12016
+ if (!this.dirtyChecked) {
12017
+ // Setting this.checked will cause us to enter a dirty state,
12018
+ // but if we are clean when defaultChecked is changed, we want to stay
12019
+ // in a clean state, so reset this.dirtyChecked
12020
+ if (!this.isInsideRadioGroup()) {
12021
+ this.checked = (_b = this.defaultChecked) !== null && _b !== void 0 ? _b : false;
12022
+ this.dirtyChecked = false;
12023
+ }
12024
+ }
12025
+ }
12026
+ }
12027
+ isInsideRadioGroup() {
12028
+ const parent = this.closest("[role=radiogroup]");
12029
+ return parent !== null;
12030
+ }
12031
+ /**
12032
+ * @internal
12033
+ */
12034
+ clickHandler(e) {
12035
+ if (!this.disabled && !this.readOnly && !this.checked) {
12036
+ this.checked = true;
12037
+ }
12038
+ }
12039
+ }
12040
+ __decorate$1([
12041
+ attr({ attribute: "readonly", mode: "boolean" })
12042
+ ], Radio.prototype, "readOnly", void 0);
12043
+ __decorate$1([
12044
+ observable
12045
+ ], Radio.prototype, "name", void 0);
12046
+ __decorate$1([
12047
+ observable
12048
+ ], Radio.prototype, "defaultSlottedNodes", void 0);
12049
+
11486
12050
  /**
11487
12051
  * a method to filter out any whitespace _only_ nodes, to be used inside a template
11488
12052
  * @param value - The Node that is being inspected
@@ -14250,7 +14814,7 @@
14250
14814
  */
14251
14815
  const focusVisible$1 = canUseFocusVisible() ? "focus-visible" : "focus";
14252
14816
 
14253
- const styles$v = css `
14817
+ const styles$x = css `
14254
14818
  :host {
14255
14819
  contain: layout;
14256
14820
  display: block;
@@ -14274,7 +14838,7 @@
14274
14838
  baseName: 'anchored-region',
14275
14839
  baseClass: AnchoredRegion$1,
14276
14840
  template: anchoredRegionTemplate,
14277
- styles: styles$v
14841
+ styles: styles$x
14278
14842
  });
14279
14843
  DesignSystem.getOrCreate()
14280
14844
  .withPrefix('nimble')
@@ -14635,7 +15199,7 @@
14635
15199
 
14636
15200
  const template$7 = html `<slot></slot>`;
14637
15201
 
14638
- const styles$u = css `
15202
+ const styles$w = css `
14639
15203
  :host {
14640
15204
  display: contents;
14641
15205
  }
@@ -14691,7 +15255,7 @@
14691
15255
  ], ThemeProvider.prototype, "theme", void 0);
14692
15256
  const nimbleDesignSystemProvider = ThemeProvider.compose({
14693
15257
  baseName: 'theme-provider',
14694
- styles: styles$u,
15258
+ styles: styles$w,
14695
15259
  template: template$7
14696
15260
  });
14697
15261
  DesignSystem.getOrCreate()
@@ -14916,7 +15480,7 @@
14916
15480
  */
14917
15481
  const themeBehavior = (theme, styles) => new ThemeStyleSheetBehavior(theme, styles);
14918
15482
 
14919
- const styles$t = css `
15483
+ const styles$v = css `
14920
15484
  ${display('inline-block')}
14921
15485
 
14922
15486
  :host {
@@ -14976,7 +15540,7 @@
14976
15540
  baseName: 'breadcrumb',
14977
15541
  baseClass: Breadcrumb$1,
14978
15542
  template: breadcrumbTemplate,
14979
- styles: styles$t
15543
+ styles: styles$v
14980
15544
  });
14981
15545
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleBreadcrumb());
14982
15546
 
@@ -15582,7 +16146,7 @@
15582
16146
  */
15583
16147
  const focusVisible = `:${focusVisible$1}`;
15584
16148
 
15585
- const styles$s = css `
16149
+ const styles$u = css `
15586
16150
  ${display('inline-flex')}
15587
16151
 
15588
16152
  :host {
@@ -15662,7 +16226,7 @@
15662
16226
  baseName: 'breadcrumb-item',
15663
16227
  baseClass: BreadcrumbItem$1,
15664
16228
  template: breadcrumbItemTemplate,
15665
- styles: styles$s,
16229
+ styles: styles$u,
15666
16230
  separator: forwardSlash16X16.data
15667
16231
  });
15668
16232
  DesignSystem.getOrCreate()
@@ -15747,7 +16311,7 @@
15747
16311
  block: 'block'
15748
16312
  };
15749
16313
 
15750
- const styles$r = css `
16314
+ const styles$t = css `
15751
16315
  ${display('inline-flex')}
15752
16316
 
15753
16317
  :host {
@@ -15954,7 +16518,7 @@
15954
16518
  `));
15955
16519
 
15956
16520
  // prettier-ignore
15957
- const styles$q = styles$r
16521
+ const styles$s = styles$t
15958
16522
  .withBehaviors(appearanceBehavior(ButtonAppearance.outline, css `
15959
16523
  :host(.primary) .control {
15960
16524
  box-shadow: 0px 0px 0px ${borderWidth} rgba(${actionRgbPartialColor}, 0.3) inset;
@@ -16068,7 +16632,7 @@
16068
16632
  baseName: 'button',
16069
16633
  baseClass: Button$1,
16070
16634
  template: buttonTemplate,
16071
- styles: styles$q,
16635
+ styles: styles$s,
16072
16636
  shadowOptions: {
16073
16637
  delegatesFocus: true
16074
16638
  }
@@ -16076,7 +16640,7 @@
16076
16640
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleButton());
16077
16641
 
16078
16642
  // prettier-ignore
16079
- const styles$p = css `
16643
+ const styles$r = css `
16080
16644
  ${display('inline-flex')}
16081
16645
 
16082
16646
  :host {
@@ -16235,14 +16799,14 @@
16235
16799
  const nimbleCardButton = CardButton.compose({
16236
16800
  baseName: 'card-button',
16237
16801
  template: buttonTemplate,
16238
- styles: styles$p,
16802
+ styles: styles$r,
16239
16803
  shadowOptions: {
16240
16804
  delegatesFocus: true
16241
16805
  }
16242
16806
  });
16243
16807
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleCardButton());
16244
16808
 
16245
- const styles$o = css `
16809
+ const styles$q = css `
16246
16810
  ${display('inline-flex')}
16247
16811
 
16248
16812
  :host {
@@ -16295,7 +16859,7 @@
16295
16859
  :host(${focusVisible}) .control {
16296
16860
  border-color: ${borderHoverColor};
16297
16861
  outline: 2px solid ${borderHoverColor};
16298
- outline-offset: 2px;
16862
+ outline-offset: 1px;
16299
16863
  }
16300
16864
 
16301
16865
  .label {
@@ -16360,7 +16924,7 @@
16360
16924
  baseName: 'checkbox',
16361
16925
  baseClass: Checkbox$1,
16362
16926
  template: checkboxTemplate,
16363
- styles: styles$o,
16927
+ styles: styles$q,
16364
16928
  checkedIndicator: check16X16.data,
16365
16929
  indeterminateIndicator: minus16X16.data
16366
16930
  });
@@ -16378,7 +16942,7 @@
16378
16942
  </template
16379
16943
  `;
16380
16944
 
16381
- const styles$n = css `
16945
+ const styles$p = css `
16382
16946
  ${display('inline-flex')}
16383
16947
 
16384
16948
  :host {
@@ -16429,7 +16993,7 @@
16429
16993
  const composedIcon = iconClass.compose({
16430
16994
  baseName,
16431
16995
  template: template$6,
16432
- styles: styles$n,
16996
+ styles: styles$p,
16433
16997
  baseClass: iconClass
16434
16998
  });
16435
16999
  DesignSystem.getOrCreate().withPrefix('nimble').register(composedIcon());
@@ -16467,7 +17031,7 @@
16467
17031
  block: 'block'
16468
17032
  };
16469
17033
 
16470
- const styles$m = css `
17034
+ const styles$o = css `
16471
17035
  ${display('inline-flex')}
16472
17036
 
16473
17037
  :host {
@@ -16681,7 +17245,7 @@
16681
17245
  }
16682
17246
  `));
16683
17247
 
16684
- const styles$l = css `
17248
+ const styles$n = css `
16685
17249
  .error-icon {
16686
17250
  display: none;
16687
17251
  }
@@ -16719,9 +17283,9 @@
16719
17283
  }
16720
17284
  `;
16721
17285
 
16722
- const styles$k = css `
16723
- ${styles$m}
16724
- ${styles$l}
17286
+ const styles$m = css `
17287
+ ${styles$o}
17288
+ ${styles$n}
16725
17289
 
16726
17290
  :host {
16727
17291
  --ni-private-hover-bottom-border-width: 2px;
@@ -16970,7 +17534,7 @@
16970
17534
  baseName: 'combobox',
16971
17535
  baseClass: Combobox$1,
16972
17536
  template: comboboxTemplate,
16973
- styles: styles$k,
17537
+ styles: styles$m,
16974
17538
  shadowOptions: {
16975
17539
  delegatesFocus: true
16976
17540
  },
@@ -17007,7 +17571,7 @@
17007
17571
  });
17008
17572
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleCombobox());
17009
17573
 
17010
- const styles$j = css `
17574
+ const styles$l = css `
17011
17575
  ${display('grid')}
17012
17576
 
17013
17577
  dialog {
@@ -17122,7 +17686,7 @@
17122
17686
  const nimbleDialog = Dialog.compose({
17123
17687
  baseName: 'dialog',
17124
17688
  template: template$5,
17125
- styles: styles$j,
17689
+ styles: styles$l,
17126
17690
  baseClass: Dialog
17127
17691
  });
17128
17692
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleDialog());
@@ -18216,7 +18780,7 @@
18216
18780
  slideOutOptions
18217
18781
  };
18218
18782
 
18219
- const styles$i = css `
18783
+ const styles$k = css `
18220
18784
  ${display('block')}
18221
18785
 
18222
18786
  :host {
@@ -18528,7 +19092,7 @@
18528
19092
  const nimbleDrawer = Drawer.compose({
18529
19093
  baseName: 'drawer',
18530
19094
  template: dialogTemplate,
18531
- styles: styles$i
19095
+ styles: styles$k
18532
19096
  });
18533
19097
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleDrawer());
18534
19098
 
@@ -20127,7 +20691,7 @@
20127
20691
  }
20128
20692
  registerIcon('icon-xmark-check', IconXmarkCheck);
20129
20693
 
20130
- const styles$h = css `
20694
+ const styles$j = css `
20131
20695
  ${display('flex')}
20132
20696
 
20133
20697
  :host {
@@ -20207,11 +20771,11 @@
20207
20771
  baseName: 'list-option',
20208
20772
  baseClass: ListboxOption,
20209
20773
  template: listboxOptionTemplate,
20210
- styles: styles$h
20774
+ styles: styles$j
20211
20775
  });
20212
20776
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleListOption());
20213
20777
 
20214
- const styles$g = css `
20778
+ const styles$i = css `
20215
20779
  ${display('grid')}
20216
20780
 
20217
20781
  :host {
@@ -20266,11 +20830,11 @@
20266
20830
  baseName: 'menu',
20267
20831
  baseClass: Menu$1,
20268
20832
  template: menuTemplate,
20269
- styles: styles$g
20833
+ styles: styles$i
20270
20834
  });
20271
20835
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleMenu());
20272
20836
 
20273
- const styles$f = css `
20837
+ const styles$h = css `
20274
20838
  ${display('inline-block')}
20275
20839
 
20276
20840
  :host {
@@ -20288,8 +20852,8 @@
20288
20852
  }
20289
20853
  `;
20290
20854
 
20291
- const styles$e = css `
20292
- ${styles$r}
20855
+ const styles$g = css `
20856
+ ${styles$t}
20293
20857
 
20294
20858
  .control[aria-pressed='true'] {
20295
20859
  background-color: ${fillSelectedColor};
@@ -20391,7 +20955,7 @@
20391
20955
  const nimbleToggleButton = ToggleButton.compose({
20392
20956
  baseName: 'toggle-button',
20393
20957
  template: template$4,
20394
- styles: styles$e,
20958
+ styles: styles$g,
20395
20959
  shadowOptions: {
20396
20960
  delegatesFocus: true
20397
20961
  }
@@ -20608,14 +21172,14 @@
20608
21172
  const nimbleMenuButton = MenuButton.compose({
20609
21173
  baseName: 'menu-button',
20610
21174
  template: template$3,
20611
- styles: styles$f,
21175
+ styles: styles$h,
20612
21176
  shadowOptions: {
20613
21177
  delegatesFocus: true
20614
21178
  }
20615
21179
  });
20616
21180
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleMenuButton());
20617
21181
 
20618
- const styles$d = css `
21182
+ const styles$f = css `
20619
21183
  ${display('grid')}
20620
21184
 
20621
21185
  :host {
@@ -20713,7 +21277,7 @@
20713
21277
  baseName: 'menu-item',
20714
21278
  baseClass: MenuItem$1,
20715
21279
  template: menuItemTemplate,
20716
- styles: styles$d,
21280
+ styles: styles$f,
20717
21281
  expandCollapseGlyph: arrowExpanderRight16X16.data
20718
21282
  });
20719
21283
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleMenuItem());
@@ -20727,9 +21291,9 @@
20727
21291
  block: 'block'
20728
21292
  };
20729
21293
 
20730
- const styles$c = css `
21294
+ const styles$e = css `
20731
21295
  ${display('inline-block')}
20732
- ${styles$l}
21296
+ ${styles$n}
20733
21297
 
20734
21298
  :host {
20735
21299
  font: ${bodyFont};
@@ -20939,7 +21503,7 @@
20939
21503
  baseName: 'number-field',
20940
21504
  baseClass: NumberField$1,
20941
21505
  template: numberFieldTemplate,
20942
- styles: styles$c,
21506
+ styles: styles$e,
20943
21507
  shadowOptions: {
20944
21508
  delegatesFocus: true
20945
21509
  },
@@ -20974,8 +21538,155 @@
20974
21538
  });
20975
21539
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleNumberField());
20976
21540
 
21541
+ const styles$d = css `
21542
+ ${display('inline-flex')}
21543
+
21544
+ :host {
21545
+ font: ${buttonLabelFont};
21546
+ align-items: center;
21547
+ outline: none;
21548
+ width: fit-content;
21549
+ cursor: pointer;
21550
+ }
21551
+
21552
+ :host([disabled]) {
21553
+ cursor: default;
21554
+ }
21555
+
21556
+ .control {
21557
+ width: calc(${controlHeight} / 2);
21558
+ height: calc(${controlHeight} / 2);
21559
+ box-sizing: border-box;
21560
+ flex-shrink: 0;
21561
+ border: ${borderWidth} solid ${borderColor};
21562
+ border-radius: 100%;
21563
+ display: inline-flex;
21564
+ align-items: center;
21565
+ justify-content: center;
21566
+ transition: box-shadow ${smallDelay};
21567
+ ${
21568
+ /*
21569
+ * Firefox includes the line height in the outline height calculation (not sure if intended or accidental).
21570
+ * Set it to 0 to ensure the outline is just as high as the control.
21571
+ */ ''}
21572
+ line-height: 0;
21573
+ }
21574
+
21575
+ :host([disabled]) .control {
21576
+ background-color: rgba(${borderRgbPartialColor}, 0.1);
21577
+ border-color: rgba(${borderRgbPartialColor}, 0.2);
21578
+ }
21579
+
21580
+ :host(:not([disabled]):not(:active):hover) .control {
21581
+ border-color: ${borderHoverColor};
21582
+ box-shadow: 0px 0px 0px ${borderWidth} ${borderHoverColor} inset;
21583
+ }
21584
+
21585
+ :host(${focusVisible}) .control {
21586
+ border-color: ${borderHoverColor};
21587
+ }
21588
+
21589
+ :host(${focusVisible}) .control::after {
21590
+ content: '';
21591
+ position: absolute;
21592
+ width: calc(2px + ${controlHeight} / 2);
21593
+ height: calc(2px + ${controlHeight} / 2);
21594
+ border: 2px solid ${borderHoverColor};
21595
+ border-radius: 100%;
21596
+ }
21597
+
21598
+ .label {
21599
+ font: inherit;
21600
+ color: ${bodyFontColor};
21601
+ padding-left: 1ch;
21602
+ cursor: inherit;
21603
+ }
21604
+
21605
+ :host([disabled]) .label {
21606
+ color: ${bodyDisabledFontColor};
21607
+ }
21608
+
21609
+ slot[name='checked-indicator'] {
21610
+ display: none;
21611
+ }
21612
+
21613
+ slot[name='checked-indicator'] svg {
21614
+ height: ${iconSize};
21615
+ width: ${iconSize};
21616
+ overflow: visible;
21617
+ }
21618
+
21619
+ :host(.checked) slot[name='checked-indicator'] {
21620
+ display: contents;
21621
+ }
21622
+
21623
+ slot[name='checked-indicator'] circle {
21624
+ fill: ${borderColor};
21625
+ }
21626
+
21627
+ :host([disabled]) slot[name='checked-indicator'] circle {
21628
+ fill: rgba(${borderRgbPartialColor}, 0.3);
21629
+ }
21630
+ `;
21631
+
21632
+ /**
21633
+ * A nimble-styled radio button
21634
+ */
21635
+ class RadioButton extends Radio {
21636
+ }
21637
+ const nimbleRadioButton = RadioButton.compose({
21638
+ baseName: 'radio-button',
21639
+ baseClass: Radio,
21640
+ template: radioTemplate,
21641
+ styles: styles$d,
21642
+ checkedIndicator: circleFilled16X16.data
21643
+ });
21644
+ DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleRadioButton());
21645
+
21646
+ const styles$c = css `
21647
+ ${display('inline-block')}
21648
+
21649
+ .positioning-region {
21650
+ display: flex;
21651
+ gap: ${standardPadding};
21652
+ }
21653
+
21654
+ :host([orientation='vertical']) .positioning-region {
21655
+ flex-direction: column;
21656
+ }
21657
+
21658
+ :host([orientation='horizontal']) .positioning-region {
21659
+ flex-direction: row;
21660
+ }
21661
+
21662
+ slot[name='label'] {
21663
+ font: ${controlLabelFont};
21664
+ color: ${controlLabelFontColor};
21665
+ }
21666
+
21667
+ :host([disabled]) slot[name='label'] {
21668
+ color: ${controlLabelDisabledFontColor};
21669
+ }
21670
+ `;
21671
+
21672
+ /**
21673
+ * A nimble-styled grouping element for radio buttons
21674
+ */
21675
+ class RadioGroup extends RadioGroup$1 {
21676
+ }
21677
+ const nimbleRadioGroup = RadioGroup.compose({
21678
+ baseName: 'radio-group',
21679
+ baseClass: RadioGroup$1,
21680
+ template: radioGroupTemplate,
21681
+ styles: styles$c,
21682
+ shadowOptions: {
21683
+ delegatesFocus: true
21684
+ }
21685
+ });
21686
+ DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleRadioGroup());
21687
+
20977
21688
  const styles$b = css `
20978
- ${styles$m}
21689
+ ${styles$o}
20979
21690
  `;
20980
21691
 
20981
21692
  /**
@@ -21612,7 +22323,7 @@
21612
22323
  /* eslint-disable @typescript-eslint/indent */
21613
22324
  const styles$4 = css `
21614
22325
  ${display('inline-block')}
21615
- ${styles$l}
22326
+ ${styles$n}
21616
22327
 
21617
22328
  :host {
21618
22329
  font: ${bodyFont};