@ionic/core 9.0.11-dev.11793792571.1765ff65 → 9.0.11-dev.11793874002.1c88a1d0

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.
@@ -1623,6 +1623,7 @@ const Toolbar = class {
1623
1623
  ];
1624
1624
  this.showClasses = ['show-start', 'show-end', 'show-primary', 'show-secondary'];
1625
1625
  this.slotSizeVars = ['--start-end-size', '--primary-secondary-size'];
1626
+ this.hasLoaded = false;
1626
1627
  }
1627
1628
  componentWillLoad() {
1628
1629
  const buttons = Array.from(this.el.querySelectorAll('ion-buttons'));
@@ -1641,9 +1642,23 @@ const Toolbar = class {
1641
1642
  }
1642
1643
  this.updateSlotClasses();
1643
1644
  }
1645
+ connectedCallback() {
1646
+ /**
1647
+ * The resize observer is stopped when the toolbar is removed from the DOM.
1648
+ * If the toolbar is added back (for example, when it is moved), start it again.
1649
+ * On the first connection the toolbar has not rendered yet, so this is left
1650
+ * to componentDidLoad.
1651
+ */
1652
+ if (this.hasLoaded) {
1653
+ this.updateSlotClasses();
1654
+ }
1655
+ }
1644
1656
  componentDidLoad() {
1657
+ this.hasLoaded = true;
1645
1658
  this.updateSlotClasses();
1646
- this.updateSlotWidths();
1659
+ }
1660
+ disconnectedCallback() {
1661
+ this.stopObservingSlotSizes();
1647
1662
  }
1648
1663
  titlePlacementChanged() {
1649
1664
  this.updateSlotClasses();
@@ -1663,26 +1678,67 @@ const Toolbar = class {
1663
1678
  * Updates the CSS custom properties for slot widths
1664
1679
  * This ensures that slots shown by their met conditions
1665
1680
  * have a minimum width matching their required slot
1681
+ *
1682
+ * The slotted content is watched with a ResizeObserver instead of being
1683
+ * measured after a timeout:
1684
+ * - The observer callback runs after layout and before paint, so the slot
1685
+ * widths are set in the same frame the content is first laid out. The
1686
+ * title is already centered when it is first painted and does not move.
1687
+ * - The callback runs again whenever the slotted content changes size,
1688
+ * for example when a button is added or removed, or when a hidden
1689
+ * toolbar becomes visible.
1666
1690
  */
1667
- updateSlotWidths(tries = 0) {
1668
- // Set timeout to try to execute after everything is rendered
1669
- setTimeout(() => {
1670
- // Attempt to measure and update
1671
- const success = this.measureAndUpdateSlots();
1672
- // If not all measurements were successful, try again in 100 ms
1673
- // cap recursion at 5 tries for safety
1674
- if (!success && tries < 5) {
1675
- setTimeout(() => {
1676
- this.updateSlotWidths(tries + 1);
1677
- }, 100);
1691
+ updateSlotWidths() {
1692
+ // Stop watching the previous content before watching the current one.
1693
+ this.stopObservingSlotSizes();
1694
+ // Browsers without ResizeObserver can only measure once.
1695
+ if (typeof ResizeObserver === 'undefined') {
1696
+ this.measureAndUpdateSlots();
1697
+ return;
1698
+ }
1699
+ const elementsToObserve = [];
1700
+ const slots = ['start', 'end', 'primary', 'secondary'];
1701
+ slots.forEach((slot) => {
1702
+ if (this.el.classList.contains(`has-${slot}-content`)) {
1703
+ elementsToObserve.push(...this.getSlottedElements(slot));
1678
1704
  }
1679
1705
  });
1706
+ if (elementsToObserve.length === 0) {
1707
+ return;
1708
+ }
1709
+ /**
1710
+ * The observer also calls the callback once right after observing
1711
+ * an element, which takes care of the first measurement.
1712
+ */
1713
+ const observer = new ResizeObserver(() => this.measureAndUpdateSlots());
1714
+ elementsToObserve.forEach((element) => observer.observe(element));
1715
+ this.slotResizeObserver = observer;
1716
+ }
1717
+ /**
1718
+ * Stops watching the slotted content for size changes.
1719
+ */
1720
+ stopObservingSlotSizes() {
1721
+ if (this.slotResizeObserver) {
1722
+ this.slotResizeObserver.disconnect();
1723
+ this.slotResizeObserver = undefined;
1724
+ }
1725
+ }
1726
+ /**
1727
+ * Returns the elements assigned to the given slot of the toolbar.
1728
+ */
1729
+ getSlottedElements(slotName) {
1730
+ const slotElement = this.el.shadowRoot?.querySelector(`slot[name="${slotName}"]`);
1731
+ if (!slotElement) {
1732
+ return [];
1733
+ }
1734
+ return slotElement.assignedElements({ flatten: true });
1680
1735
  }
1681
1736
  /**
1682
1737
  * Measure the widths of the slots and update the CSS custom properties
1683
1738
  * for the minimum width of each pair of slots based on the largest width in each pair.
1684
1739
  * Returns whether we successfully measured all of the slots we expect to have content.
1685
- * If not, the content probably hasn't rendered yet and we need to try again.
1740
+ * If not, the content probably hasn't rendered yet, and the ResizeObserver
1741
+ * measures again once it does.
1686
1742
  */
1687
1743
  measureAndUpdateSlots() {
1688
1744
  // Define the relationship between slots based on the conditions array
@@ -1691,6 +1747,13 @@ const Toolbar = class {
1691
1747
  { name: 'start-end', slots: ['start', 'end'] },
1692
1748
  { name: 'primary-secondary', slots: ['primary', 'secondary'] },
1693
1749
  ];
1750
+ /**
1751
+ * Once a size property is set, the slots cannot be narrower than it.
1752
+ * Remove the properties first so each slot is measured at the width of
1753
+ * its content, which lets the slots shrink when their content does.
1754
+ * This runs before paint, so the slots are never painted without a size.
1755
+ */
1756
+ this.slotSizeVars.forEach((cssVar) => this.el.style.removeProperty(cssVar));
1694
1757
  // First, measure all slot widths
1695
1758
  const slotWidths = new Map();
1696
1759
  let allMeasurementsSuccessful = true;
@@ -1749,6 +1812,8 @@ const Toolbar = class {
1749
1812
  * Removes all slot visibility classes and slot width CSS variables.
1750
1813
  */
1751
1814
  removeSlotClasses() {
1815
+ // The slot widths are no longer used, so there is nothing to watch.
1816
+ this.stopObservingSlotSizes();
1752
1817
  this.el.classList.remove(...this.slotClasses, ...this.showClasses);
1753
1818
  this.slotSizeVars.forEach((cssVar) => this.el.style.removeProperty(cssVar));
1754
1819
  }
@@ -1833,14 +1898,14 @@ const Toolbar = class {
1833
1898
  Object.assign(childStyles, style);
1834
1899
  });
1835
1900
  const titlePlacement = this.getTitlePlacement();
1836
- return (index.h(index.Host, { key: '3b97d3de5b1910257170355995eb7a50a2b6dcc4', class: {
1901
+ return (index.h(index.Host, { key: '2ee4ee2329ba499bd3fe24eb58f8954c86d39b01', class: {
1837
1902
  ...theme.createColorClasses(this.color, {
1838
1903
  [theme$1]: true,
1839
1904
  'in-toolbar': theme.hostContext('ion-toolbar', this.el),
1840
1905
  [`toolbar-title-placement-${titlePlacement}`]: true,
1841
1906
  }),
1842
1907
  ...childStyles,
1843
- } }, index.h("div", { key: '26f85390aa62f118e585fd8560fba0620b30fd51', class: "toolbar-background", part: "background" }), index.h("div", { key: '57e32773d5642dde7f5d7cca9aaceb41b4d800bd', class: "toolbar-container", part: "container" }, index.h("slot", { key: '5429b3f898703339749a55af6bb28d7e4d969679', name: "start", onSlotchange: () => this.updateSlotClasses }), index.h("slot", { key: 'c5565f7020f52a1f075d9c6908ace042d488642f', name: "secondary", onSlotchange: () => this.updateSlotClasses }), index.h("div", { key: '2d083bcd57512041321a68b43d6b90144eb20166', class: "toolbar-content", part: "content" }, index.h("slot", { key: 'eb8abc0b9b96c699355891fbd0d284094cde7632' })), index.h("slot", { key: 'ca66f2dcce1f5382ed40a120cf32f759597a11ad', name: "primary", onSlotchange: () => this.updateSlotClasses }), index.h("slot", { key: '19e3eb792d45c21404fe48f119d68248b5d7dca7', name: "end", onSlotchange: () => this.updateSlotClasses }))));
1908
+ } }, index.h("div", { key: '68da02a622db1ed136a31700421c5da005ae3884', class: "toolbar-background", part: "background" }), index.h("div", { key: 'cefcad22e28e1468de024a0cbe477464a872dc66', class: "toolbar-container", part: "container" }, index.h("slot", { key: '9ebfc464b5c32c6d2b5c81a0a0c415effa15ce3c', name: "start", onSlotchange: () => this.updateSlotClasses() }), index.h("slot", { key: '55a07aa0000e1b02814f7a01ad1610d1d723f442', name: "secondary", onSlotchange: () => this.updateSlotClasses() }), index.h("div", { key: '51d1e06e0463788b5f794831faadd305aa8bca75', class: "toolbar-content", part: "content" }, index.h("slot", { key: '6982cc6886f76cf43d78e3f0e9243dc05f67d34c' })), index.h("slot", { key: 'b00b9b9b28c1637a04781ef88b5d9474fb5c0647', name: "primary", onSlotchange: () => this.updateSlotClasses() }), index.h("slot", { key: '4fce3b9b17f7775d0ba14cd5185e500753b4976e', name: "end", onSlotchange: () => this.updateSlotClasses() }))));
1844
1909
  }
1845
1910
  get el() { return index.getElement(this); }
1846
1911
  static get watchers() { return {
@@ -29,6 +29,7 @@ export class Toolbar {
29
29
  ];
30
30
  this.showClasses = ['show-start', 'show-end', 'show-primary', 'show-secondary'];
31
31
  this.slotSizeVars = ['--start-end-size', '--primary-secondary-size'];
32
+ this.hasLoaded = false;
32
33
  }
33
34
  componentWillLoad() {
34
35
  const buttons = Array.from(this.el.querySelectorAll('ion-buttons'));
@@ -47,9 +48,23 @@ export class Toolbar {
47
48
  }
48
49
  this.updateSlotClasses();
49
50
  }
51
+ connectedCallback() {
52
+ /**
53
+ * The resize observer is stopped when the toolbar is removed from the DOM.
54
+ * If the toolbar is added back (for example, when it is moved), start it again.
55
+ * On the first connection the toolbar has not rendered yet, so this is left
56
+ * to componentDidLoad.
57
+ */
58
+ if (this.hasLoaded) {
59
+ this.updateSlotClasses();
60
+ }
61
+ }
50
62
  componentDidLoad() {
63
+ this.hasLoaded = true;
51
64
  this.updateSlotClasses();
52
- this.updateSlotWidths();
65
+ }
66
+ disconnectedCallback() {
67
+ this.stopObservingSlotSizes();
53
68
  }
54
69
  titlePlacementChanged() {
55
70
  this.updateSlotClasses();
@@ -69,26 +84,67 @@ export class Toolbar {
69
84
  * Updates the CSS custom properties for slot widths
70
85
  * This ensures that slots shown by their met conditions
71
86
  * have a minimum width matching their required slot
87
+ *
88
+ * The slotted content is watched with a ResizeObserver instead of being
89
+ * measured after a timeout:
90
+ * - The observer callback runs after layout and before paint, so the slot
91
+ * widths are set in the same frame the content is first laid out. The
92
+ * title is already centered when it is first painted and does not move.
93
+ * - The callback runs again whenever the slotted content changes size,
94
+ * for example when a button is added or removed, or when a hidden
95
+ * toolbar becomes visible.
72
96
  */
73
- updateSlotWidths(tries = 0) {
74
- // Set timeout to try to execute after everything is rendered
75
- setTimeout(() => {
76
- // Attempt to measure and update
77
- const success = this.measureAndUpdateSlots();
78
- // If not all measurements were successful, try again in 100 ms
79
- // cap recursion at 5 tries for safety
80
- if (!success && tries < 5) {
81
- setTimeout(() => {
82
- this.updateSlotWidths(tries + 1);
83
- }, 100);
97
+ updateSlotWidths() {
98
+ // Stop watching the previous content before watching the current one.
99
+ this.stopObservingSlotSizes();
100
+ // Browsers without ResizeObserver can only measure once.
101
+ if (typeof ResizeObserver === 'undefined') {
102
+ this.measureAndUpdateSlots();
103
+ return;
104
+ }
105
+ const elementsToObserve = [];
106
+ const slots = ['start', 'end', 'primary', 'secondary'];
107
+ slots.forEach((slot) => {
108
+ if (this.el.classList.contains(`has-${slot}-content`)) {
109
+ elementsToObserve.push(...this.getSlottedElements(slot));
84
110
  }
85
111
  });
112
+ if (elementsToObserve.length === 0) {
113
+ return;
114
+ }
115
+ /**
116
+ * The observer also calls the callback once right after observing
117
+ * an element, which takes care of the first measurement.
118
+ */
119
+ const observer = new ResizeObserver(() => this.measureAndUpdateSlots());
120
+ elementsToObserve.forEach((element) => observer.observe(element));
121
+ this.slotResizeObserver = observer;
122
+ }
123
+ /**
124
+ * Stops watching the slotted content for size changes.
125
+ */
126
+ stopObservingSlotSizes() {
127
+ if (this.slotResizeObserver) {
128
+ this.slotResizeObserver.disconnect();
129
+ this.slotResizeObserver = undefined;
130
+ }
131
+ }
132
+ /**
133
+ * Returns the elements assigned to the given slot of the toolbar.
134
+ */
135
+ getSlottedElements(slotName) {
136
+ const slotElement = this.el.shadowRoot?.querySelector(`slot[name="${slotName}"]`);
137
+ if (!slotElement) {
138
+ return [];
139
+ }
140
+ return slotElement.assignedElements({ flatten: true });
86
141
  }
87
142
  /**
88
143
  * Measure the widths of the slots and update the CSS custom properties
89
144
  * for the minimum width of each pair of slots based on the largest width in each pair.
90
145
  * Returns whether we successfully measured all of the slots we expect to have content.
91
- * If not, the content probably hasn't rendered yet and we need to try again.
146
+ * If not, the content probably hasn't rendered yet, and the ResizeObserver
147
+ * measures again once it does.
92
148
  */
93
149
  measureAndUpdateSlots() {
94
150
  // Define the relationship between slots based on the conditions array
@@ -97,6 +153,13 @@ export class Toolbar {
97
153
  { name: 'start-end', slots: ['start', 'end'] },
98
154
  { name: 'primary-secondary', slots: ['primary', 'secondary'] },
99
155
  ];
156
+ /**
157
+ * Once a size property is set, the slots cannot be narrower than it.
158
+ * Remove the properties first so each slot is measured at the width of
159
+ * its content, which lets the slots shrink when their content does.
160
+ * This runs before paint, so the slots are never painted without a size.
161
+ */
162
+ this.slotSizeVars.forEach((cssVar) => this.el.style.removeProperty(cssVar));
100
163
  // First, measure all slot widths
101
164
  const slotWidths = new Map();
102
165
  let allMeasurementsSuccessful = true;
@@ -155,6 +218,8 @@ export class Toolbar {
155
218
  * Removes all slot visibility classes and slot width CSS variables.
156
219
  */
157
220
  removeSlotClasses() {
221
+ // The slot widths are no longer used, so there is nothing to watch.
222
+ this.stopObservingSlotSizes();
158
223
  this.el.classList.remove(...this.slotClasses, ...this.showClasses);
159
224
  this.slotSizeVars.forEach((cssVar) => this.el.style.removeProperty(cssVar));
160
225
  }
@@ -239,14 +304,14 @@ export class Toolbar {
239
304
  Object.assign(childStyles, style);
240
305
  });
241
306
  const titlePlacement = this.getTitlePlacement();
242
- return (h(Host, { key: '3b97d3de5b1910257170355995eb7a50a2b6dcc4', class: {
307
+ return (h(Host, { key: '2ee4ee2329ba499bd3fe24eb58f8954c86d39b01', class: {
243
308
  ...createColorClasses(this.color, {
244
309
  [theme]: true,
245
310
  'in-toolbar': hostContext('ion-toolbar', this.el),
246
311
  [`toolbar-title-placement-${titlePlacement}`]: true,
247
312
  }),
248
313
  ...childStyles,
249
- } }, h("div", { key: '26f85390aa62f118e585fd8560fba0620b30fd51', class: "toolbar-background", part: "background" }), h("div", { key: '57e32773d5642dde7f5d7cca9aaceb41b4d800bd', class: "toolbar-container", part: "container" }, h("slot", { key: '5429b3f898703339749a55af6bb28d7e4d969679', name: "start", onSlotchange: () => this.updateSlotClasses }), h("slot", { key: 'c5565f7020f52a1f075d9c6908ace042d488642f', name: "secondary", onSlotchange: () => this.updateSlotClasses }), h("div", { key: '2d083bcd57512041321a68b43d6b90144eb20166', class: "toolbar-content", part: "content" }, h("slot", { key: 'eb8abc0b9b96c699355891fbd0d284094cde7632' })), h("slot", { key: 'ca66f2dcce1f5382ed40a120cf32f759597a11ad', name: "primary", onSlotchange: () => this.updateSlotClasses }), h("slot", { key: '19e3eb792d45c21404fe48f119d68248b5d7dca7', name: "end", onSlotchange: () => this.updateSlotClasses }))));
314
+ } }, h("div", { key: '68da02a622db1ed136a31700421c5da005ae3884', class: "toolbar-background", part: "background" }), h("div", { key: 'cefcad22e28e1468de024a0cbe477464a872dc66', class: "toolbar-container", part: "container" }, h("slot", { key: '9ebfc464b5c32c6d2b5c81a0a0c415effa15ce3c', name: "start", onSlotchange: () => this.updateSlotClasses() }), h("slot", { key: '55a07aa0000e1b02814f7a01ad1610d1d723f442', name: "secondary", onSlotchange: () => this.updateSlotClasses() }), h("div", { key: '51d1e06e0463788b5f794831faadd305aa8bca75', class: "toolbar-content", part: "content" }, h("slot", { key: '6982cc6886f76cf43d78e3f0e9243dc05f67d34c' })), h("slot", { key: 'b00b9b9b28c1637a04781ef88b5d9474fb5c0647', name: "primary", onSlotchange: () => this.updateSlotClasses() }), h("slot", { key: '4fce3b9b17f7775d0ba14cd5185e500753b4976e', name: "end", onSlotchange: () => this.updateSlotClasses() }))));
250
315
  }
251
316
  static get is() { return "ion-toolbar"; }
252
317
  static get encapsulation() { return "shadow"; }
package/dist/docs.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-11-04T11:44:59",
2
+ "timestamp": "2026-11-05T10:23:02",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.45.2",
@@ -1621,6 +1621,7 @@ const Toolbar = class {
1621
1621
  ];
1622
1622
  this.showClasses = ['show-start', 'show-end', 'show-primary', 'show-secondary'];
1623
1623
  this.slotSizeVars = ['--start-end-size', '--primary-secondary-size'];
1624
+ this.hasLoaded = false;
1624
1625
  }
1625
1626
  componentWillLoad() {
1626
1627
  const buttons = Array.from(this.el.querySelectorAll('ion-buttons'));
@@ -1639,9 +1640,23 @@ const Toolbar = class {
1639
1640
  }
1640
1641
  this.updateSlotClasses();
1641
1642
  }
1643
+ connectedCallback() {
1644
+ /**
1645
+ * The resize observer is stopped when the toolbar is removed from the DOM.
1646
+ * If the toolbar is added back (for example, when it is moved), start it again.
1647
+ * On the first connection the toolbar has not rendered yet, so this is left
1648
+ * to componentDidLoad.
1649
+ */
1650
+ if (this.hasLoaded) {
1651
+ this.updateSlotClasses();
1652
+ }
1653
+ }
1642
1654
  componentDidLoad() {
1655
+ this.hasLoaded = true;
1643
1656
  this.updateSlotClasses();
1644
- this.updateSlotWidths();
1657
+ }
1658
+ disconnectedCallback() {
1659
+ this.stopObservingSlotSizes();
1645
1660
  }
1646
1661
  titlePlacementChanged() {
1647
1662
  this.updateSlotClasses();
@@ -1661,26 +1676,67 @@ const Toolbar = class {
1661
1676
  * Updates the CSS custom properties for slot widths
1662
1677
  * This ensures that slots shown by their met conditions
1663
1678
  * have a minimum width matching their required slot
1679
+ *
1680
+ * The slotted content is watched with a ResizeObserver instead of being
1681
+ * measured after a timeout:
1682
+ * - The observer callback runs after layout and before paint, so the slot
1683
+ * widths are set in the same frame the content is first laid out. The
1684
+ * title is already centered when it is first painted and does not move.
1685
+ * - The callback runs again whenever the slotted content changes size,
1686
+ * for example when a button is added or removed, or when a hidden
1687
+ * toolbar becomes visible.
1664
1688
  */
1665
- updateSlotWidths(tries = 0) {
1666
- // Set timeout to try to execute after everything is rendered
1667
- setTimeout(() => {
1668
- // Attempt to measure and update
1669
- const success = this.measureAndUpdateSlots();
1670
- // If not all measurements were successful, try again in 100 ms
1671
- // cap recursion at 5 tries for safety
1672
- if (!success && tries < 5) {
1673
- setTimeout(() => {
1674
- this.updateSlotWidths(tries + 1);
1675
- }, 100);
1689
+ updateSlotWidths() {
1690
+ // Stop watching the previous content before watching the current one.
1691
+ this.stopObservingSlotSizes();
1692
+ // Browsers without ResizeObserver can only measure once.
1693
+ if (typeof ResizeObserver === 'undefined') {
1694
+ this.measureAndUpdateSlots();
1695
+ return;
1696
+ }
1697
+ const elementsToObserve = [];
1698
+ const slots = ['start', 'end', 'primary', 'secondary'];
1699
+ slots.forEach((slot) => {
1700
+ if (this.el.classList.contains(`has-${slot}-content`)) {
1701
+ elementsToObserve.push(...this.getSlottedElements(slot));
1676
1702
  }
1677
1703
  });
1704
+ if (elementsToObserve.length === 0) {
1705
+ return;
1706
+ }
1707
+ /**
1708
+ * The observer also calls the callback once right after observing
1709
+ * an element, which takes care of the first measurement.
1710
+ */
1711
+ const observer = new ResizeObserver(() => this.measureAndUpdateSlots());
1712
+ elementsToObserve.forEach((element) => observer.observe(element));
1713
+ this.slotResizeObserver = observer;
1714
+ }
1715
+ /**
1716
+ * Stops watching the slotted content for size changes.
1717
+ */
1718
+ stopObservingSlotSizes() {
1719
+ if (this.slotResizeObserver) {
1720
+ this.slotResizeObserver.disconnect();
1721
+ this.slotResizeObserver = undefined;
1722
+ }
1723
+ }
1724
+ /**
1725
+ * Returns the elements assigned to the given slot of the toolbar.
1726
+ */
1727
+ getSlottedElements(slotName) {
1728
+ const slotElement = this.el.shadowRoot?.querySelector(`slot[name="${slotName}"]`);
1729
+ if (!slotElement) {
1730
+ return [];
1731
+ }
1732
+ return slotElement.assignedElements({ flatten: true });
1678
1733
  }
1679
1734
  /**
1680
1735
  * Measure the widths of the slots and update the CSS custom properties
1681
1736
  * for the minimum width of each pair of slots based on the largest width in each pair.
1682
1737
  * Returns whether we successfully measured all of the slots we expect to have content.
1683
- * If not, the content probably hasn't rendered yet and we need to try again.
1738
+ * If not, the content probably hasn't rendered yet, and the ResizeObserver
1739
+ * measures again once it does.
1684
1740
  */
1685
1741
  measureAndUpdateSlots() {
1686
1742
  // Define the relationship between slots based on the conditions array
@@ -1689,6 +1745,13 @@ const Toolbar = class {
1689
1745
  { name: 'start-end', slots: ['start', 'end'] },
1690
1746
  { name: 'primary-secondary', slots: ['primary', 'secondary'] },
1691
1747
  ];
1748
+ /**
1749
+ * Once a size property is set, the slots cannot be narrower than it.
1750
+ * Remove the properties first so each slot is measured at the width of
1751
+ * its content, which lets the slots shrink when their content does.
1752
+ * This runs before paint, so the slots are never painted without a size.
1753
+ */
1754
+ this.slotSizeVars.forEach((cssVar) => this.el.style.removeProperty(cssVar));
1692
1755
  // First, measure all slot widths
1693
1756
  const slotWidths = new Map();
1694
1757
  let allMeasurementsSuccessful = true;
@@ -1747,6 +1810,8 @@ const Toolbar = class {
1747
1810
  * Removes all slot visibility classes and slot width CSS variables.
1748
1811
  */
1749
1812
  removeSlotClasses() {
1813
+ // The slot widths are no longer used, so there is nothing to watch.
1814
+ this.stopObservingSlotSizes();
1750
1815
  this.el.classList.remove(...this.slotClasses, ...this.showClasses);
1751
1816
  this.slotSizeVars.forEach((cssVar) => this.el.style.removeProperty(cssVar));
1752
1817
  }
@@ -1831,14 +1896,14 @@ const Toolbar = class {
1831
1896
  Object.assign(childStyles, style);
1832
1897
  });
1833
1898
  const titlePlacement = this.getTitlePlacement();
1834
- return (h(Host, { key: '3b97d3de5b1910257170355995eb7a50a2b6dcc4', class: {
1899
+ return (h(Host, { key: '2ee4ee2329ba499bd3fe24eb58f8954c86d39b01', class: {
1835
1900
  ...createColorClasses(this.color, {
1836
1901
  [theme]: true,
1837
1902
  'in-toolbar': hostContext('ion-toolbar', this.el),
1838
1903
  [`toolbar-title-placement-${titlePlacement}`]: true,
1839
1904
  }),
1840
1905
  ...childStyles,
1841
- } }, h("div", { key: '26f85390aa62f118e585fd8560fba0620b30fd51', class: "toolbar-background", part: "background" }), h("div", { key: '57e32773d5642dde7f5d7cca9aaceb41b4d800bd', class: "toolbar-container", part: "container" }, h("slot", { key: '5429b3f898703339749a55af6bb28d7e4d969679', name: "start", onSlotchange: () => this.updateSlotClasses }), h("slot", { key: 'c5565f7020f52a1f075d9c6908ace042d488642f', name: "secondary", onSlotchange: () => this.updateSlotClasses }), h("div", { key: '2d083bcd57512041321a68b43d6b90144eb20166', class: "toolbar-content", part: "content" }, h("slot", { key: 'eb8abc0b9b96c699355891fbd0d284094cde7632' })), h("slot", { key: 'ca66f2dcce1f5382ed40a120cf32f759597a11ad', name: "primary", onSlotchange: () => this.updateSlotClasses }), h("slot", { key: '19e3eb792d45c21404fe48f119d68248b5d7dca7', name: "end", onSlotchange: () => this.updateSlotClasses }))));
1906
+ } }, h("div", { key: '68da02a622db1ed136a31700421c5da005ae3884', class: "toolbar-background", part: "background" }), h("div", { key: 'cefcad22e28e1468de024a0cbe477464a872dc66', class: "toolbar-container", part: "container" }, h("slot", { key: '9ebfc464b5c32c6d2b5c81a0a0c415effa15ce3c', name: "start", onSlotchange: () => this.updateSlotClasses() }), h("slot", { key: '55a07aa0000e1b02814f7a01ad1610d1d723f442', name: "secondary", onSlotchange: () => this.updateSlotClasses() }), h("div", { key: '51d1e06e0463788b5f794831faadd305aa8bca75', class: "toolbar-content", part: "content" }, h("slot", { key: '6982cc6886f76cf43d78e3f0e9243dc05f67d34c' })), h("slot", { key: 'b00b9b9b28c1637a04781ef88b5d9474fb5c0647', name: "primary", onSlotchange: () => this.updateSlotClasses() }), h("slot", { key: '4fce3b9b17f7775d0ba14cd5185e500753b4976e', name: "end", onSlotchange: () => this.updateSlotClasses() }))));
1842
1907
  }
1843
1908
  get el() { return getElement(this); }
1844
1909
  static get watchers() { return {