Skip to content

Commit e4ce50e

Browse files
committed
refactor: add optional random infix to generated id
1 parent 022dba9 commit e4ce50e

File tree

9 files changed

+17
-15
lines changed

9 files changed

+17
-15
lines changed

src/aria/accordion/accordion.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class AccordionPanel {
5454
private readonly _deferredContentAware = inject(DeferredContentAware);
5555

5656
/** A global unique identifier for the panel. */
57-
private readonly _id = inject(_IdGenerator).getId('accordion-trigger-');
57+
private readonly _id = inject(_IdGenerator).getId('accordion-trigger-', true);
5858

5959
/** A local unique identifier for the panel, used to match with its trigger's value. */
6060
value = input.required<string>();
@@ -102,7 +102,7 @@ export class AccordionPanel {
102102
})
103103
export class AccordionTrigger {
104104
/** A global unique identifier for the trigger. */
105-
private readonly _id = inject(_IdGenerator).getId('ng-accordion-trigger-');
105+
private readonly _id = inject(_IdGenerator).getId('ng-accordion-trigger-', true);
106106

107107
/** A reference to the trigger element. */
108108
private readonly _elementRef = inject(ElementRef);

src/aria/grid/grid.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ export class GridCell {
184184
private readonly _row = inject(GridRow);
185185

186186
/** A unique identifier for the cell. */
187-
private readonly _id = inject(_IdGenerator).getId('ng-grid-cell-');
187+
private readonly _id = inject(_IdGenerator).getId('ng-grid-cell-', true);
188188

189189
/** The host native element. */
190190
readonly element = computed(() => this._elementRef.nativeElement);

src/aria/listbox/listbox.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ import {ComboboxPopup} from '../combobox';
6060
})
6161
export class Listbox<V> {
6262
/** A unique identifier for the listbox. */
63-
private readonly _generatedId = inject(_IdGenerator).getId('ng-listbox-');
63+
private readonly _generatedId = inject(_IdGenerator).getId('ng-listbox-', true);
6464

6565
// TODO(wagnermaciel): https://github.com/angular/components/pull/30495#discussion_r1972601144.
6666
/** A unique identifier for the listbox. */
@@ -207,7 +207,7 @@ export class Option<V> {
207207
private readonly _listbox = inject(Listbox);
208208

209209
/** A unique identifier for the option. */
210-
private readonly _generatedId = inject(_IdGenerator).getId('ng-option-');
210+
private readonly _generatedId = inject(_IdGenerator).getId('ng-option-', true);
211211

212212
// TODO(wagnermaciel): https://github.com/angular/components/pull/30495#discussion_r1972601144.
213213
/** A unique identifier for the option. */

src/aria/menu/menu.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
MenuPattern,
2828
MenuTriggerPattern,
2929
} from '@angular/aria/private';
30+
import {_IdGenerator} from '@angular/cdk/a11y';
3031
import {toSignal} from '@angular/core/rxjs-interop';
3132
import {Directionality} from '@angular/cdk/bidi';
3233

@@ -132,7 +133,7 @@ export class Menu<V> {
132133
readonly submenu = input<Menu<V> | undefined>(undefined);
133134

134135
/** The unique ID of the menu. */
135-
readonly id = input<string>(Math.random().toString(36).substring(2, 10));
136+
readonly id = input<string>(inject(_IdGenerator).getId('ng-menu-', true));
136137

137138
/** Whether the menu should wrap its items. */
138139
readonly wrap = input<boolean>(true);
@@ -325,7 +326,7 @@ export class MenuItem<V> {
325326
readonly element: HTMLElement = this._elementRef.nativeElement;
326327

327328
/** The unique ID of the menu item. */
328-
readonly id = input<string>(Math.random().toString(36).substring(2, 10));
329+
readonly id = input<string>(inject(_IdGenerator).getId('ng-menu-item-', true));
329330

330331
/** The value of the menu item. */
331332
readonly value = input.required<V>();

src/aria/radio-group/radio-group.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export class RadioButton<V> {
221221
private readonly _radioGroup = inject(RadioGroup);
222222

223223
/** A unique identifier for the radio button. */
224-
private readonly _generatedId = inject(_IdGenerator).getId('ng-radio-button-');
224+
private readonly _generatedId = inject(_IdGenerator).getId('ng-radio-button-', true);
225225

226226
/** A unique identifier for the radio button. */
227227
readonly id = computed(() => this._generatedId);

src/aria/tabs/tabs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ export class TabPanel implements OnInit, OnDestroy {
315315
private readonly _Tabs = inject(Tabs);
316316

317317
/** A global unique identifier for the tab. */
318-
private readonly _id = inject(_IdGenerator).getId('ng-tabpanel-');
318+
private readonly _id = inject(_IdGenerator).getId('ng-tabpanel-', true);
319319

320320
/** The Tab UIPattern associated with the tabpanel */
321321
readonly tab = computed(() => this._Tabs.tabs()?.find(tab => tab.value() === this.value()));

src/aria/toolbar/toolbar.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export class ToolbarWidget<V> implements OnInit, OnDestroy {
185185
private readonly _toolbar = inject(Toolbar);
186186

187187
/** A unique identifier for the widget. */
188-
private readonly _generatedId = inject(_IdGenerator).getId('ng-toolbar-widget-');
188+
private readonly _generatedId = inject(_IdGenerator).getId('ng-toolbar-widget-', true);
189189

190190
/** A unique identifier for the widget. */
191191
readonly id = computed(() => this._generatedId);
@@ -236,7 +236,7 @@ export class ToolbarWidgetGroup<V> implements OnInit, OnDestroy {
236236
private readonly _toolbar = inject(Toolbar, {optional: true});
237237

238238
/** A unique identifier for the widget. */
239-
private readonly _generatedId = inject(_IdGenerator).getId('ng-toolbar-widget-group-');
239+
private readonly _generatedId = inject(_IdGenerator).getId('ng-toolbar-widget-group-', true);
240240

241241
/** A unique identifier for the widget. */
242242
readonly id = computed(() => this._generatedId);

src/aria/tree/tree.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ function sortDirectives(a: HasElement, b: HasElement) {
8282
})
8383
export class Tree<V> {
8484
/** A unique identifier for the tree. */
85-
private readonly _generatedId = inject(_IdGenerator).getId('ng-tree-');
85+
private readonly _generatedId = inject(_IdGenerator).getId('ng-tree-', true);
8686

8787
// TODO(wagnermaciel): https://github.com/angular/components/pull/30495#discussion_r1972601144.
8888
/** A unique identifier for the tree. */
@@ -229,7 +229,7 @@ export class TreeItem<V> extends DeferredContentAware implements OnInit, OnDestr
229229
private readonly _elementRef = inject(ElementRef);
230230

231231
/** A unique identifier for the tree item. */
232-
private readonly _id = inject(_IdGenerator).getId('ng-tree-item-');
232+
private readonly _id = inject(_IdGenerator).getId('ng-tree-item-', true);
233233

234234
/** The owned tree item group. */
235235
private readonly _group = signal<TreeItemGroup<V> | undefined>(undefined);

src/cdk/a11y/id-generator.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ const counters: Record<string, number> = {};
1919
@Injectable({providedIn: 'root'})
2020
export class _IdGenerator {
2121
private _appId = inject(APP_ID);
22+
private _infix = Math.floor(Math.random() * 100000).toString();
2223

2324
/**
2425
* Generates a unique ID with a specific prefix.
2526
* @param prefix Prefix to add to the ID.
2627
*/
27-
getId(prefix: string): string {
28+
getId(prefix: string, randomize: boolean = false): string {
2829
// Omit the app ID if it's the default `ng`. Since the vast majority of pages have one
2930
// Angular app on them, we can reduce the amount of breakages by not adding it.
3031
if (this._appId !== 'ng') {
@@ -35,6 +36,6 @@ export class _IdGenerator {
3536
counters[prefix] = 0;
3637
}
3738

38-
return `${prefix}${counters[prefix]++}`;
39+
return `${prefix}${randomize ? this._infix + '-' : ''}${counters[prefix]++}`;
3940
}
4041
}

0 commit comments

Comments
 (0)