@momentum-design/components 0.134.7 → 0.134.8

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.
@@ -58,9 +58,26 @@ declare class Tooltip extends Popover {
58
58
  */
59
59
  private setTooltipType;
60
60
  /**
61
- * Updates the tooltip id if it is empty.
61
+ * Cached auto-generated id so that if the consumer (or a React wrapper that re-passes props
62
+ * on every render) clears the id we restore the same value instead of minting a fresh UUID
63
+ * on every cycle.
62
64
  */
63
- private onIdUpdated;
65
+ private autoGeneratedId;
66
+ /**
67
+ * Ensures the tooltip has a non-empty id. Called from `willUpdate` so the assignment is folded
68
+ * into the in-flight update cycle (no extra render pass, no risk of an update loop).
69
+ *
70
+ * - If the consumer provides an explicit id, we drop the cached auto id so a future clear can
71
+ * regenerate a fresh one.
72
+ * - If the id is empty, we reuse the cached auto id when present, otherwise generate one.
73
+ */
74
+ private ensureId;
75
+ /**
76
+ * Writes the appropriate aria attribute on the trigger element based on the current tooltipType.
77
+ * Used when only the id changed (tooltipType-driven aria updates are handled in
78
+ * `onTooltipTypeUpdated`).
79
+ */
80
+ private syncTriggerAriaForId;
64
81
  /**
65
82
  * Updates the placement attribute if it is not a valid placement.
66
83
  * Overriding the default from Popover
@@ -72,7 +89,7 @@ declare class Tooltip extends Popover {
72
89
  */
73
90
  private onTooltipTypeUpdated;
74
91
  protected isOpenUpdated(oldValue: boolean, newValue: boolean): Promise<void>;
75
- update(changedProperties: PropertyValues<this>): Promise<void>;
92
+ protected willUpdate(changedProperties: PropertyValues<this>): void;
76
93
  show(): void;
77
94
  static styles: Array<CSSResult>;
78
95
  }
@@ -63,6 +63,12 @@ class Tooltip extends Popover {
63
63
  * @default false
64
64
  */
65
65
  this.onlyShowWhenTriggerOverflows = DEFAULTS.ONLY_SHOW_WHEN_TRIGGER_OVERFLOWS;
66
+ /**
67
+ * Cached auto-generated id so that if the consumer (or a React wrapper that re-passes props
68
+ * on every render) clears the id we restore the same value instead of minting a fresh UUID
69
+ * on every cycle.
70
+ */
71
+ this.autoGeneratedId = null;
66
72
  }
67
73
  connectedCallback() {
68
74
  super.connectedCallback();
@@ -99,26 +105,42 @@ class Tooltip extends Popover {
99
105
  this.setAttribute('tooltip-type', Object.values(TOOLTIP_TYPES).includes(type) ? type : DEFAULTS.TOOLTIP_TYPE);
100
106
  }
101
107
  /**
102
- * Updates the tooltip id if it is empty.
108
+ * Ensures the tooltip has a non-empty id. Called from `willUpdate` so the assignment is folded
109
+ * into the in-flight update cycle (no extra render pass, no risk of an update loop).
110
+ *
111
+ * - If the consumer provides an explicit id, we drop the cached auto id so a future clear can
112
+ * regenerate a fresh one.
113
+ * - If the id is empty, we reuse the cached auto id when present, otherwise generate one.
103
114
  */
104
- async onIdUpdated() {
105
- // Set tooltip ID if not set.
106
- if (this.id.length === 0) {
107
- this.id = `mdc-tooltip-${uuidv4()}`;
108
- }
109
- await this.updateComplete;
110
- // Update the aria props on the trigger component to updated tooltip id.
111
- if (this.triggerElement) {
112
- switch (this.tooltipType) {
113
- case TOOLTIP_TYPES.DESCRIPTION:
114
- this.triggerElement.setAttribute('aria-describedby', this.id);
115
- break;
116
- case TOOLTIP_TYPES.LABEL:
117
- this.triggerElement.setAttribute('aria-labelledby', this.id);
118
- break;
119
- default:
120
- break;
115
+ ensureId() {
116
+ if (this.id.length > 0) {
117
+ if (this.autoGeneratedId && this.id !== this.autoGeneratedId) {
118
+ this.autoGeneratedId = null;
121
119
  }
120
+ return;
121
+ }
122
+ if (!this.autoGeneratedId) {
123
+ this.autoGeneratedId = `mdc-tooltip-${uuidv4()}`;
124
+ }
125
+ this.id = this.autoGeneratedId;
126
+ }
127
+ /**
128
+ * Writes the appropriate aria attribute on the trigger element based on the current tooltipType.
129
+ * Used when only the id changed (tooltipType-driven aria updates are handled in
130
+ * `onTooltipTypeUpdated`).
131
+ */
132
+ syncTriggerAriaForId() {
133
+ if (!this.triggerElement)
134
+ return;
135
+ switch (this.tooltipType) {
136
+ case TOOLTIP_TYPES.DESCRIPTION:
137
+ this.triggerElement.setAttribute('aria-describedby', this.id);
138
+ break;
139
+ case TOOLTIP_TYPES.LABEL:
140
+ this.triggerElement.setAttribute('aria-labelledby', this.id);
141
+ break;
142
+ default:
143
+ break;
122
144
  }
123
145
  }
124
146
  /**
@@ -181,17 +203,26 @@ class Tooltip extends Popover {
181
203
  }
182
204
  await super.isOpenUpdated(oldValue, newValue);
183
205
  }
184
- async update(changedProperties) {
185
- super.update(changedProperties);
186
- if (changedProperties.has('id')) {
187
- await this.onIdUpdated();
206
+ willUpdate(changedProperties) {
207
+ super.willUpdate(changedProperties);
208
+ // Ensure an id exists before render. Assigning `this.id` inside willUpdate is folded into
209
+ // the current update cycle, so there is no extra render and no loop risk (the previous
210
+ // implementation set the id from inside `update()` and awaited `updateComplete`, which
211
+ // produced an infinite re-render loop under @lit/react wrappers that keep clearing the id).
212
+ const idChanged = changedProperties.has('id');
213
+ if (idChanged) {
214
+ this.ensureId();
188
215
  }
189
216
  if (changedProperties.has('placement')) {
190
217
  this.onPlacementUpdated();
191
218
  }
192
219
  if (changedProperties.has('tooltipType')) {
220
+ // onTooltipTypeUpdated also refreshes the trigger aria attribute, so it covers the id sync.
193
221
  this.onTooltipTypeUpdated(changedProperties);
194
222
  }
223
+ else if (idChanged) {
224
+ this.syncTriggerAriaForId();
225
+ }
195
226
  }
196
227
  show() {
197
228
  if (this.onlyShowWhenTriggerOverflows && this.triggerElement && hasOverflowMixin(this.triggerElement)) {
@@ -53149,6 +53149,16 @@
53149
53149
  "module": "components/popover/popover.component.js"
53150
53150
  }
53151
53151
  },
53152
+ {
53153
+ "kind": "field",
53154
+ "name": "autoGeneratedId",
53155
+ "type": {
53156
+ "text": "string | null"
53157
+ },
53158
+ "privacy": "private",
53159
+ "default": "null",
53160
+ "description": "Cached auto-generated id so that if the consumer (or a React wrapper that re-passes props\non every render) clears the id we restore the same value instead of minting a fresh UUID\non every cycle."
53161
+ },
53152
53162
  {
53153
53163
  "kind": "field",
53154
53164
  "name": "backdrop",
@@ -53338,6 +53348,17 @@
53338
53348
  "module": "components/popover/popover.component.js"
53339
53349
  }
53340
53350
  },
53351
+ {
53352
+ "kind": "method",
53353
+ "name": "ensureId",
53354
+ "privacy": "private",
53355
+ "return": {
53356
+ "type": {
53357
+ "text": "void"
53358
+ }
53359
+ },
53360
+ "description": "Ensures the tooltip has a non-empty id. Called from `willUpdate` so the assignment is folded\ninto the in-flight update cycle (no extra render pass, no risk of an update loop).\n\n- If the consumer provides an explicit id, we drop the cached auto id so a future clear can\n regenerate a fresh one.\n- If the id is empty, we reuse the cached auto id when present, otherwise generate one."
53361
+ },
53341
53362
  {
53342
53363
  "kind": "field",
53343
53364
  "name": "focusBackToTrigger",
@@ -53558,17 +53579,6 @@
53558
53579
  "module": "components/popover/popover.component.js"
53559
53580
  }
53560
53581
  },
53561
- {
53562
- "kind": "method",
53563
- "name": "onIdUpdated",
53564
- "privacy": "private",
53565
- "return": {
53566
- "type": {
53567
- "text": "Promise<void>"
53568
- }
53569
- },
53570
- "description": "Updates the tooltip id if it is empty."
53571
- },
53572
53582
  {
53573
53583
  "kind": "field",
53574
53584
  "name": "onlyShowWhenTriggerOverflows",
@@ -53761,6 +53771,17 @@
53761
53771
  "module": "components/popover/popover.component.js"
53762
53772
  }
53763
53773
  },
53774
+ {
53775
+ "kind": "method",
53776
+ "name": "syncTriggerAriaForId",
53777
+ "privacy": "private",
53778
+ "return": {
53779
+ "type": {
53780
+ "text": "void"
53781
+ }
53782
+ },
53783
+ "description": "Writes the appropriate aria attribute on the trigger element based on the current tooltipType.\nUsed when only the id changed (tooltipType-driven aria updates are handled in\n`onTooltipTypeUpdated`)."
53784
+ },
53764
53785
  {
53765
53786
  "kind": "field",
53766
53787
  "name": "togglePopoverVisible",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@momentum-design/components",
3
3
  "packageManager": "yarn@3.2.4",
4
- "version": "0.134.7",
4
+ "version": "0.134.8",
5
5
  "engines": {
6
6
  "node": ">=20.0.0",
7
7
  "npm": ">=8.0.0"