@angular/material
Version:
Angular Material
85 lines • 12.6 kB
JavaScript
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { ChangeDetectionStrategy, Component, InjectionToken, Input, ViewEncapsulation, Directive, Inject, Optional } from '@angular/core';
import { mixinDisabled } from '../common-behaviors/disabled';
import { MAT_OPTION_PARENT_COMPONENT } from './option-parent';
// Notes on the accessibility pattern used for `mat-optgroup`.
// The option group has two different "modes": regular and inert. The regular mode uses the
// recommended a11y pattern which has `role="group"` on the group element with `aria-labelledby`
// pointing to the label. This works for `mat-select`, but it seems to hit a bug for autocomplete
// under VoiceOver where the group doesn't get read out at all. The bug appears to be that if
// there's __any__ a11y-related attribute on the group (e.g. `role` or `aria-labelledby`),
// VoiceOver on Safari won't read it out.
// We've introduced the `inert` mode as a workaround. Under this mode, all a11y attributes are
// removed from the group, and we get the screen reader to read out the group label by mirroring it
// inside an invisible element in the option. This is sub-optimal, because the screen reader will
// repeat the group label on each navigation, whereas the default pattern only reads the group when
// the user enters a new group. The following alternate approaches were considered:
// 1. Reading out the group label using the `LiveAnnouncer` solves the problem, but we can't control
// when the text will be read out so sometimes it comes in too late or never if the user
// navigates quickly.
// 2. `<mat-option aria-describedby="groupLabel"` - This works on Safari, but VoiceOver in Chrome
// won't read out the description at all.
// 3. `<mat-option aria-labelledby="optionLabel groupLabel"` - This works on Chrome, but Safari
// doesn't read out the text at all. Furthermore, on
// Boilerplate for applying mixins to MatOptgroup.
/** @docs-private */
class MatOptgroupBase {
}
const _MatOptgroupMixinBase = mixinDisabled(MatOptgroupBase);
// Counter for unique group ids.
let _uniqueOptgroupIdCounter = 0;
export class _MatOptgroupBase extends _MatOptgroupMixinBase {
constructor(parent) {
var _a;
super();
/** Unique id for the underlying label. */
this._labelId = `mat-optgroup-label-${_uniqueOptgroupIdCounter++}`;
this._inert = (_a = parent === null || parent === void 0 ? void 0 : parent.inertGroups) !== null && _a !== void 0 ? _a : false;
}
}
_MatOptgroupBase.decorators = [
{ type: Directive }
];
_MatOptgroupBase.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [MAT_OPTION_PARENT_COMPONENT,] }, { type: Optional }] }
];
_MatOptgroupBase.propDecorators = {
label: [{ type: Input }]
};
/**
* Injection token that can be used to reference instances of `MatOptgroup`. It serves as
* alternative token to the actual `MatOptgroup` class which could cause unnecessary
* retention of the class and its component metadata.
*/
export const MAT_OPTGROUP = new InjectionToken('MatOptgroup');
/**
* Component that is used to group instances of `mat-option`.
*/
export class MatOptgroup extends _MatOptgroupBase {
}
MatOptgroup.decorators = [
{ type: Component, args: [{
selector: 'mat-optgroup',
exportAs: 'matOptgroup',
template: "<span class=\"mat-optgroup-label\" aria-hidden=\"true\" [id]=\"_labelId\">{{ label }} <ng-content></ng-content></span>\n<ng-content select=\"mat-option, ng-container\"></ng-content>\n",
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
inputs: ['disabled'],
host: {
'class': 'mat-optgroup',
'[attr.role]': '_inert ? null : "group"',
'[attr.aria-disabled]': '_inert ? null : disabled.toString()',
'[attr.aria-labelledby]': '_inert ? null : _labelId',
'[class.mat-optgroup-disabled]': 'disabled',
},
providers: [{ provide: MAT_OPTGROUP, useExisting: MatOptgroup }],
styles: [".mat-optgroup-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;line-height:48px;height:48px;padding:0 16px;text-align:left;text-decoration:none;max-width:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.mat-optgroup-label[disabled]{cursor:default}[dir=rtl] .mat-optgroup-label{text-align:right}.mat-optgroup-label .mat-icon{margin-right:16px;vertical-align:middle}.mat-optgroup-label .mat-icon svg{vertical-align:top}[dir=rtl] .mat-optgroup-label .mat-icon{margin-left:16px;margin-right:0}\n"]
},] }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0Z3JvdXAuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbWF0ZXJpYWwvY29yZS9vcHRpb24vb3B0Z3JvdXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBR0gsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsY0FBYyxFQUNkLEtBQUssRUFDTCxpQkFBaUIsRUFDakIsU0FBUyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQzVCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBNkIsYUFBYSxFQUFDLE1BQU0sOEJBQThCLENBQUM7QUFDdkYsT0FBTyxFQUEyQiwyQkFBMkIsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBRXRGLDhEQUE4RDtBQUM5RCwyRkFBMkY7QUFDM0YsZ0dBQWdHO0FBQ2hHLGlHQUFpRztBQUNqRyw2RkFBNkY7QUFDN0YsMEZBQTBGO0FBQzFGLHlDQUF5QztBQUN6Qyw4RkFBOEY7QUFDOUYsbUdBQW1HO0FBQ25HLGlHQUFpRztBQUNqRyxtR0FBbUc7QUFDbkcsbUZBQW1GO0FBQ25GLG9HQUFvRztBQUNwRywyRkFBMkY7QUFDM0Ysd0JBQXdCO0FBQ3hCLGlHQUFpRztBQUNqRyw0Q0FBNEM7QUFDNUMsK0ZBQStGO0FBQy9GLHdEQUF3RDtBQUV4RCxrREFBa0Q7QUFDbEQsb0JBQW9CO0FBQ3BCLE1BQU0sZUFBZTtDQUFJO0FBQ3pCLE1BQU0scUJBQXFCLEdBQ3ZCLGFBQWEsQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUVuQyxnQ0FBZ0M7QUFDaEMsSUFBSSx3QkFBd0IsR0FBRyxDQUFDLENBQUM7QUFHakMsTUFBTSxPQUFPLGdCQUFpQixTQUFRLHFCQUFxQjtJQVV6RCxZQUE2RCxNQUFpQzs7UUFDNUYsS0FBSyxFQUFFLENBQUM7UUFQViwwQ0FBMEM7UUFDMUMsYUFBUSxHQUFXLHNCQUFzQix3QkFBd0IsRUFBRSxFQUFFLENBQUM7UUFPcEUsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFBLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxXQUFXLG1DQUFJLEtBQUssQ0FBQztJQUM3QyxDQUFDOzs7WUFkRixTQUFTOzs7NENBV0ssTUFBTSxTQUFDLDJCQUEyQixjQUFHLFFBQVE7OztvQkFSekQsS0FBSzs7QUFnQlI7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxJQUFJLGNBQWMsQ0FBYyxhQUFhLENBQUMsQ0FBQztBQUUzRTs7R0FFRztBQWtCSCxNQUFNLE9BQU8sV0FBWSxTQUFRLGdCQUFnQjs7O1lBakJoRCxTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLGNBQWM7Z0JBQ3hCLFFBQVEsRUFBRSxhQUFhO2dCQUN2QixtTUFBNEI7Z0JBQzVCLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJO2dCQUNyQyxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtnQkFDL0MsTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDO2dCQUVwQixJQUFJLEVBQUU7b0JBQ0osT0FBTyxFQUFFLGNBQWM7b0JBQ3ZCLGFBQWEsRUFBRSx5QkFBeUI7b0JBQ3hDLHNCQUFzQixFQUFFLHFDQUFxQztvQkFDN0Qsd0JBQXdCLEVBQUUsMEJBQTBCO29CQUNwRCwrQkFBK0IsRUFBRSxVQUFVO2lCQUM1QztnQkFDRCxTQUFTLEVBQUUsQ0FBQyxFQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBQyxDQUFDOzthQUMvRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0Jvb2xlYW5JbnB1dH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvZXJjaW9uJztcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIEluamVjdGlvblRva2VuLFxuICBJbnB1dCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIERpcmVjdGl2ZSwgSW5qZWN0LCBPcHRpb25hbFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Q2FuRGlzYWJsZSwgQ2FuRGlzYWJsZUN0b3IsIG1peGluRGlzYWJsZWR9IGZyb20gJy4uL2NvbW1vbi1iZWhhdmlvcnMvZGlzYWJsZWQnO1xuaW1wb3J0IHtNYXRPcHRpb25QYXJlbnRDb21wb25lbnQsIE1BVF9PUFRJT05fUEFSRU5UX0NPTVBPTkVOVH0gZnJvbSAnLi9vcHRpb24tcGFyZW50JztcblxuLy8gTm90ZXMgb24gdGhlIGFjY2Vzc2liaWxpdHkgcGF0dGVybiB1c2VkIGZvciBgbWF0LW9wdGdyb3VwYC5cbi8vIFRoZSBvcHRpb24gZ3JvdXAgaGFzIHR3byBkaWZmZXJlbnQgXCJtb2Rlc1wiOiByZWd1bGFyIGFuZCBpbmVydC4gVGhlIHJlZ3VsYXIgbW9kZSB1c2VzIHRoZVxuLy8gcmVjb21tZW5kZWQgYTExeSBwYXR0ZXJuIHdoaWNoIGhhcyBgcm9sZT1cImdyb3VwXCJgIG9uIHRoZSBncm91cCBlbGVtZW50IHdpdGggYGFyaWEtbGFiZWxsZWRieWBcbi8vIHBvaW50aW5nIHRvIHRoZSBsYWJlbC4gVGhpcyB3b3JrcyBmb3IgYG1hdC1zZWxlY3RgLCBidXQgaXQgc2VlbXMgdG8gaGl0IGEgYnVnIGZvciBhdXRvY29tcGxldGVcbi8vIHVuZGVyIFZvaWNlT3ZlciB3aGVyZSB0aGUgZ3JvdXAgZG9lc24ndCBnZXQgcmVhZCBvdXQgYXQgYWxsLiBUaGUgYnVnIGFwcGVhcnMgdG8gYmUgdGhhdCBpZlxuLy8gdGhlcmUncyBfX2FueV9fIGExMXktcmVsYXRlZCBhdHRyaWJ1dGUgb24gdGhlIGdyb3VwIChlLmcuIGByb2xlYCBvciBgYXJpYS1sYWJlbGxlZGJ5YCksXG4vLyBWb2ljZU92ZXIgb24gU2FmYXJpIHdvbid0IHJlYWQgaXQgb3V0LlxuLy8gV2UndmUgaW50cm9kdWNlZCB0aGUgYGluZXJ0YCBtb2RlIGFzIGEgd29ya2Fyb3VuZC4gVW5kZXIgdGhpcyBtb2RlLCBhbGwgYTExeSBhdHRyaWJ1dGVzIGFyZVxuLy8gcmVtb3ZlZCBmcm9tIHRoZSBncm91cCwgYW5kIHdlIGdldCB0aGUgc2NyZWVuIHJlYWRlciB0byByZWFkIG91dCB0aGUgZ3JvdXAgbGFiZWwgYnkgbWlycm9yaW5nIGl0XG4vLyBpbnNpZGUgYW4gaW52aXNpYmxlIGVsZW1lbnQgaW4gdGhlIG9wdGlvbi4gVGhpcyBpcyBzdWItb3B0aW1hbCwgYmVjYXVzZSB0aGUgc2NyZWVuIHJlYWRlciB3aWxsXG4vLyByZXBlYXQgdGhlIGdyb3VwIGxhYmVsIG9uIGVhY2ggbmF2aWdhdGlvbiwgd2hlcmVhcyB0aGUgZGVmYXVsdCBwYXR0ZXJuIG9ubHkgcmVhZHMgdGhlIGdyb3VwIHdoZW5cbi8vIHRoZSB1c2VyIGVudGVycyBhIG5ldyBncm91cC4gVGhlIGZvbGxvd2luZyBhbHRlcm5hdGUgYXBwcm9hY2hlcyB3ZXJlIGNvbnNpZGVyZWQ6XG4vLyAxLiBSZWFkaW5nIG91dCB0aGUgZ3JvdXAgbGFiZWwgdXNpbmcgdGhlIGBMaXZlQW5ub3VuY2VyYCBzb2x2ZXMgdGhlIHByb2JsZW0sIGJ1dCB3ZSBjYW4ndCBjb250cm9sXG4vLyAgICB3aGVuIHRoZSB0ZXh0IHdpbGwgYmUgcmVhZCBvdXQgc28gc29tZXRpbWVzIGl0IGNvbWVzIGluIHRvbyBsYXRlIG9yIG5ldmVyIGlmIHRoZSB1c2VyXG4vLyAgICBuYXZpZ2F0ZXMgcXVpY2tseS5cbi8vIDIuIGA8bWF0LW9wdGlvbiBhcmlhLWRlc2NyaWJlZGJ5PVwiZ3JvdXBMYWJlbFwiYCAtIFRoaXMgd29ya3Mgb24gU2FmYXJpLCBidXQgVm9pY2VPdmVyIGluIENocm9tZVxuLy8gICAgd29uJ3QgcmVhZCBvdXQgdGhlIGRlc2NyaXB0aW9uIGF0IGFsbC5cbi8vIDMuIGA8bWF0LW9wdGlvbiBhcmlhLWxhYmVsbGVkYnk9XCJvcHRpb25MYWJlbCBncm91cExhYmVsXCJgIC0gVGhpcyB3b3JrcyBvbiBDaHJvbWUsIGJ1dCBTYWZhcmlcbi8vICAgICBkb2Vzbid0IHJlYWQgb3V0IHRoZSB0ZXh0IGF0IGFsbC4gRnVydGhlcm1vcmUsIG9uXG5cbi8vIEJvaWxlcnBsYXRlIGZvciBhcHBseWluZyBtaXhpbnMgdG8gTWF0T3B0Z3JvdXAuXG4vKiogQGRvY3MtcHJpdmF0ZSAqL1xuY2xhc3MgTWF0T3B0Z3JvdXBCYXNlIHsgfVxuY29uc3QgX01hdE9wdGdyb3VwTWl4aW5CYXNlOiBDYW5EaXNhYmxlQ3RvciAmIHR5cGVvZiBNYXRPcHRncm91cEJhc2UgPVxuICAgIG1peGluRGlzYWJsZWQoTWF0T3B0Z3JvdXBCYXNlKTtcblxuLy8gQ291bnRlciBmb3IgdW5pcXVlIGdyb3VwIGlkcy5cbmxldCBfdW5pcXVlT3B0Z3JvdXBJZENvdW50ZXIgPSAwO1xuXG5ARGlyZWN0aXZlKClcbmV4cG9ydCBjbGFzcyBfTWF0T3B0Z3JvdXBCYXNlIGV4dGVuZHMgX01hdE9wdGdyb3VwTWl4aW5CYXNlIGltcGxlbWVudHMgQ2FuRGlzYWJsZSB7XG4gIC8qKiBMYWJlbCBmb3IgdGhlIG9wdGlvbiBncm91cC4gKi9cbiAgQElucHV0KCkgbGFiZWw6IHN0cmluZztcblxuICAvKiogVW5pcXVlIGlkIGZvciB0aGUgdW5kZXJseWluZyBsYWJlbC4gKi9cbiAgX2xhYmVsSWQ6IHN0cmluZyA9IGBtYXQtb3B0Z3JvdXAtbGFiZWwtJHtfdW5pcXVlT3B0Z3JvdXBJZENvdW50ZXIrK31gO1xuXG4gIC8qKiBXaGV0aGVyIHRoZSBncm91cCBpcyBpbiBpbmVydCBhMTF5IG1vZGUuICovXG4gIF9pbmVydDogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihASW5qZWN0KE1BVF9PUFRJT05fUEFSRU5UX0NPTVBPTkVOVCkgQE9wdGlvbmFsKCkgcGFyZW50PzogTWF0T3B0aW9uUGFyZW50Q29tcG9uZW50KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl9pbmVydCA9IHBhcmVudD8uaW5lcnRHcm91cHMgPz8gZmFsc2U7XG4gIH1cblxuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfZGlzYWJsZWQ6IEJvb2xlYW5JbnB1dDtcbn1cblxuLyoqXG4gKiBJbmplY3Rpb24gdG9rZW4gdGhhdCBjYW4gYmUgdXNlZCB0byByZWZlcmVuY2UgaW5zdGFuY2VzIG9mIGBNYXRPcHRncm91cGAuIEl0IHNlcnZlcyBhc1xuICogYWx0ZXJuYXRpdmUgdG9rZW4gdG8gdGhlIGFjdHVhbCBgTWF0T3B0Z3JvdXBgIGNsYXNzIHdoaWNoIGNvdWxkIGNhdXNlIHVubmVjZXNzYXJ5XG4gKiByZXRlbnRpb24gb2YgdGhlIGNsYXNzIGFuZCBpdHMgY29tcG9uZW50IG1ldGFkYXRhLlxuICovXG5leHBvcnQgY29uc3QgTUFUX09QVEdST1VQID0gbmV3IEluamVjdGlvblRva2VuPE1hdE9wdGdyb3VwPignTWF0T3B0Z3JvdXAnKTtcblxuLyoqXG4gKiBDb21wb25lbnQgdGhhdCBpcyB1c2VkIHRvIGdyb3VwIGluc3RhbmNlcyBvZiBgbWF0LW9wdGlvbmAuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ21hdC1vcHRncm91cCcsXG4gIGV4cG9ydEFzOiAnbWF0T3B0Z3JvdXAnLFxuICB0ZW1wbGF0ZVVybDogJ29wdGdyb3VwLmh0bWwnLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgaW5wdXRzOiBbJ2Rpc2FibGVkJ10sXG4gIHN0eWxlVXJsczogWydvcHRncm91cC5jc3MnXSxcbiAgaG9zdDoge1xuICAgICdjbGFzcyc6ICdtYXQtb3B0Z3JvdXAnLFxuICAgICdbYXR0ci5yb2xlXSc6ICdfaW5lcnQgPyBudWxsIDogXCJncm91cFwiJyxcbiAgICAnW2F0dHIuYXJpYS1kaXNhYmxlZF0nOiAnX2luZXJ0ID8gbnVsbCA6IGRpc2FibGVkLnRvU3RyaW5nKCknLFxuICAgICdbYXR0ci5hcmlhLWxhYmVsbGVkYnldJzogJ19pbmVydCA/IG51bGwgOiBfbGFiZWxJZCcsXG4gICAgJ1tjbGFzcy5tYXQtb3B0Z3JvdXAtZGlzYWJsZWRdJzogJ2Rpc2FibGVkJyxcbiAgfSxcbiAgcHJvdmlkZXJzOiBbe3Byb3ZpZGU6IE1BVF9PUFRHUk9VUCwgdXNlRXhpc3Rpbmc6IE1hdE9wdGdyb3VwfV0sXG59KVxuZXhwb3J0IGNsYXNzIE1hdE9wdGdyb3VwIGV4dGVuZHMgX01hdE9wdGdyb3VwQmFzZSB7XG59XG4iXX0=