@material/web 1.0.2-nightly.f7a66a8.0 → 1.1.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.
- package/checkbox/internal/checkbox.d.ts +1 -0
- package/checkbox/internal/checkbox.js +6 -1
- package/checkbox/internal/checkbox.js.map +1 -1
- package/chips/internal/_shared.scss +16 -3
- package/chips/internal/_trailing-icon.scss +2 -1
- package/chips/internal/assist-styles.css.js +1 -1
- package/chips/internal/assist-styles.css.js.map +1 -1
- package/chips/internal/chip-set.js +2 -6
- package/chips/internal/chip-set.js.map +1 -1
- package/chips/internal/chip.d.ts +8 -0
- package/chips/internal/chip.js +17 -2
- package/chips/internal/chip.js.map +1 -1
- package/chips/internal/filter-chip.d.ts +8 -0
- package/chips/internal/filter-chip.js +17 -4
- package/chips/internal/filter-chip.js.map +1 -1
- package/chips/internal/filter-styles.css.js +1 -1
- package/chips/internal/filter-styles.css.js.map +1 -1
- package/chips/internal/input-styles.css.js +1 -1
- package/chips/internal/input-styles.css.js.map +1 -1
- package/chips/internal/shared-styles.css.js +1 -1
- package/chips/internal/shared-styles.css.js.map +1 -1
- package/chips/internal/suggestion-styles.css.js +1 -1
- package/chips/internal/suggestion-styles.css.js.map +1 -1
- package/chips/internal/trailing-icon-styles.css.js +1 -1
- package/chips/internal/trailing-icon-styles.css.js.map +1 -1
- package/chips/internal/trailing-icons.js +8 -4
- package/chips/internal/trailing-icons.js.map +1 -1
- package/fab/internal/_shared.scss +1 -0
- package/fab/internal/shared-styles.css.js +1 -1
- package/fab/internal/shared-styles.css.js.map +1 -1
- package/field/internal/_content.scss +3 -1
- package/field/internal/shared-styles.css.js +1 -1
- package/field/internal/shared-styles.css.js.map +1 -1
- package/internal/aria/aria.d.ts +0 -29
- package/internal/aria/aria.js +0 -141
- package/internal/aria/aria.js.map +1 -1
- package/internal/controller/form-submitter.js +2 -2
- package/internal/controller/form-submitter.js.map +1 -1
- package/labs/behaviors/constraint-validation.d.ts +2 -2
- package/labs/behaviors/constraint-validation.js +18 -1
- package/labs/behaviors/constraint-validation.js.map +1 -1
- package/labs/behaviors/element-internals.js +1 -5
- package/labs/behaviors/element-internals.js.map +1 -1
- package/labs/behaviors/focusable.js +20 -7
- package/labs/behaviors/focusable.js.map +1 -1
- package/labs/behaviors/on-report-validity.d.ts +70 -0
- package/labs/behaviors/on-report-validity.js +185 -0
- package/labs/behaviors/on-report-validity.js.map +1 -0
- package/labs/behaviors/validators/checkbox-validator.d.ts +6 -3
- package/labs/behaviors/validators/checkbox-validator.js.map +1 -1
- package/labs/behaviors/validators/radio-validator.d.ts +38 -0
- package/labs/behaviors/validators/radio-validator.js +65 -0
- package/labs/behaviors/validators/radio-validator.js.map +1 -0
- package/labs/behaviors/validators/select-validator.d.ts +35 -0
- package/labs/behaviors/validators/select-validator.js +33 -0
- package/labs/behaviors/validators/select-validator.js.map +1 -0
- package/labs/behaviors/validators/text-field-validator.d.ts +110 -0
- package/labs/behaviors/validators/text-field-validator.js +146 -0
- package/labs/behaviors/validators/text-field-validator.js.map +1 -0
- package/labs/behaviors/validators/validator.d.ts +4 -0
- package/labs/behaviors/validators/validator.js.map +1 -1
- package/labs/card/internal/_outlined-card.scss +1 -1
- package/labs/card/internal/_shared.scss +10 -2
- package/labs/card/internal/outlined-styles.css.js +1 -1
- package/labs/card/internal/outlined-styles.css.js.map +1 -1
- package/labs/card/internal/shared-styles.css.js +1 -1
- package/labs/card/internal/shared-styles.css.js.map +1 -1
- package/labs/segmentedbutton/internal/_shared.scss +1 -0
- package/labs/segmentedbutton/internal/shared-styles.css.js +1 -1
- package/labs/segmentedbutton/internal/shared-styles.css.js.map +1 -1
- package/list/internal/list.js +2 -6
- package/list/internal/list.js.map +1 -1
- package/list/internal/listitem/_list-item.scss +2 -0
- package/list/internal/listitem/list-item-styles.css.js +1 -1
- package/list/internal/listitem/list-item-styles.css.js.map +1 -1
- package/menu/internal/controllers/menuItemController.d.ts +13 -1
- package/menu/internal/controllers/menuItemController.js +32 -6
- package/menu/internal/controllers/menuItemController.js.map +1 -1
- package/menu/internal/menu.js +7 -8
- package/menu/internal/menu.js.map +1 -1
- package/menu/internal/menuitem/menu-item.d.ts +2 -0
- package/menu/internal/menuitem/menu-item.js +13 -1
- package/menu/internal/menuitem/menu-item.js.map +1 -1
- package/package.json +1 -1
- package/radio/internal/radio.d.ts +11 -1
- package/radio/internal/radio.js +28 -2
- package/radio/internal/radio.js.map +1 -1
- package/radio/internal/single-selection-controller.d.ts +5 -5
- package/radio/internal/single-selection-controller.js +16 -14
- package/radio/internal/single-selection-controller.js.map +1 -1
- package/select/internal/_shared.scss +5 -0
- package/select/internal/select.d.ts +21 -72
- package/select/internal/select.js +106 -184
- package/select/internal/select.js.map +1 -1
- package/select/internal/selectoption/select-option.d.ts +2 -0
- package/select/internal/selectoption/select-option.js +13 -1
- package/select/internal/selectoption/select-option.js.map +1 -1
- package/select/internal/selectoption/selectOptionController.d.ts +7 -3
- package/select/internal/selectoption/selectOptionController.js +8 -11
- package/select/internal/selectoption/selectOptionController.js.map +1 -1
- package/select/internal/shared-styles.css.js +1 -1
- package/select/internal/shared-styles.css.js.map +1 -1
- package/switch/internal/_icon.scss +14 -10
- package/switch/internal/switch-styles.css.js +1 -1
- package/switch/internal/switch-styles.css.js.map +1 -1
- package/switch/internal/switch.js +12 -8
- package/switch/internal/switch.js.map +1 -1
- package/tabs/internal/tab.js +2 -6
- package/tabs/internal/tab.js.map +1 -1
- package/tabs/internal/tabs.js +2 -6
- package/tabs/internal/tabs.js.map +1 -1
- package/textfield/internal/text-field.d.ts +9 -74
- package/textfield/internal/text-field.js +34 -150
- package/textfield/internal/text-field.js.map +1 -1
- package/tokens/_md-comp-assist-chip.scss +11 -0
- package/tokens/_md-comp-filter-chip.scss +14 -0
- package/tokens/_md-comp-input-chip.scss +14 -0
- package/tokens/_md-comp-suggestion-chip.scss +11 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"single-selection-controller.js","sourceRoot":"","sources":["single-selection-controller.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ReactiveController} from 'lit';\n\n/**\n * An element that supports single-selection with `SingleSelectionController`.\n */\nexport interface SingleSelectionElement extends HTMLElement {\n /**\n * Whether or not the element is selected.\n */\n checked: boolean;\n}\n\n/**\n * A `ReactiveController` that provides root node-scoped single selection for\n * elements, similar to native `<input type=\"radio\">` selection.\n *\n * To use, elements should add the controller and call\n * `selectionController.handleCheckedChange()` in a getter/setter. This must\n * be synchronous to match native behavior.\n *\n * @example\n * const CHECKED = Symbol('checked');\n *\n * class MyToggle extends LitElement {\n * get checked() { return this[CHECKED]; }\n * set checked(checked: boolean) {\n * const oldValue = this.checked;\n * if (oldValue === checked) {\n * return;\n * }\n *\n * this[CHECKED] = checked;\n * this.selectionController.handleCheckedChange();\n * this.requestUpdate('checked', oldValue);\n * }\n *\n * [CHECKED] = false;\n *\n * private selectionController = new SingleSelectionController(this);\n *\n * constructor() {\n * super();\n * this.addController(this.selectionController);\n * }\n * }\n */\nexport class SingleSelectionController implements ReactiveController {\n private focused = false;\n private root: ParentNode | null = null;\n\n constructor(private readonly host: SingleSelectionElement) {}\n\n hostConnected() {\n this.root = this.host.getRootNode() as ParentNode;\n this.host.addEventListener('keydown', this.handleKeyDown);\n this.host.addEventListener('focusin', this.handleFocusIn);\n this.host.addEventListener('focusout', this.handleFocusOut);\n if (this.host.checked) {\n // Uncheck other siblings when attached if already checked. This mimics\n // native <input type=\"radio\"> behavior.\n this.uncheckSiblings();\n }\n\n // Update for the newly added host.\n this.updateTabIndices();\n }\n\n hostDisconnected() {\n this.host.removeEventListener('keydown', this.handleKeyDown);\n this.host.removeEventListener('focusin', this.handleFocusIn);\n this.host.removeEventListener('focusout', this.handleFocusOut);\n // Update for siblings that are still connected.\n this.updateTabIndices();\n this.root = null;\n }\n\n /**\n * Should be called whenever the host's `checked` property changes\n * synchronously.\n */\n handleCheckedChange() {\n if (!this.host.checked) {\n return;\n }\n\n this.uncheckSiblings();\n this.updateTabIndices();\n }\n\n private readonly handleFocusIn = () => {\n this.focused = true;\n this.updateTabIndices();\n };\n\n private readonly handleFocusOut = () => {\n this.focused = false;\n this.updateTabIndices();\n };\n\n private uncheckSiblings() {\n for (const sibling of this.getNamedSiblings()) {\n if (sibling !== this.host) {\n sibling.checked = false;\n }\n }\n }\n\n /**\n * Updates the `tabindex` of the host and its siblings.\n */\n private updateTabIndices() {\n // There are three tabindex states for a group of elements:\n // 1. If any are checked, that element is focusable.\n const siblings = this.getNamedSiblings();\n const checkedSibling = siblings.find((sibling) => sibling.checked);\n // 2. If an element is focused, the others are no longer focusable.\n if (checkedSibling || this.focused) {\n const focusable = checkedSibling || this.host;\n focusable.tabIndex = 0;\n\n for (const sibling of siblings) {\n if (sibling !== focusable) {\n sibling.tabIndex = -1;\n }\n }\n return;\n }\n\n // 3. If none are checked or focused, all are focusable.\n for (const sibling of siblings) {\n sibling.tabIndex = 0;\n }\n }\n\n /**\n * Retrieves all siblings in the host element's root with the same `name`\n * attribute.\n */\n private getNamedSiblings() {\n const name = this.host.getAttribute('name');\n if (!name || !this.root) {\n return [];\n }\n\n return Array.from(\n this.root.querySelectorAll<SingleSelectionElement>(`[name=\"${name}\"]`),\n );\n }\n\n /**\n * Handles arrow key events from the host. Using the arrow keys will\n * select and check the next or previous sibling with the host's\n * `name` attribute.\n */\n private readonly handleKeyDown = (event: KeyboardEvent) => {\n const isDown = event.key === 'ArrowDown';\n const isUp = event.key === 'ArrowUp';\n const isLeft = event.key === 'ArrowLeft';\n const isRight = event.key === 'ArrowRight';\n // Ignore non-arrow keys\n if (!isLeft && !isRight && !isDown && !isUp) {\n return;\n }\n\n // Don't try to select another sibling if there aren't any.\n const siblings = this.getNamedSiblings();\n if (!siblings.length) {\n return;\n }\n\n // Prevent default interactions on the element for arrow keys,\n // since this controller will introduce new behavior.\n event.preventDefault();\n\n // Check if moving forwards or backwards\n const isRtl = getComputedStyle(this.host).direction === 'rtl';\n const forwards = isRtl ? isLeft || isDown : isRight || isDown;\n\n const hostIndex = siblings.indexOf(this.host);\n let nextIndex = forwards ? hostIndex + 1 : hostIndex - 1;\n // Search for the next sibling that is not disabled to select.\n // If we return to the host index, there is nothing to select.\n while (nextIndex !== hostIndex) {\n if (nextIndex >= siblings.length) {\n // Return to start if moving past the last item.\n nextIndex = 0;\n } else if (nextIndex < 0) {\n // Go to end if moving before the first item.\n nextIndex = siblings.length - 1;\n }\n\n // Check if the next sibling is disabled. If so,\n // move the index and continue searching.\n const nextSibling = siblings[nextIndex];\n if (nextSibling.hasAttribute('disabled')) {\n if (forwards) {\n nextIndex++;\n } else {\n nextIndex--;\n }\n\n continue;\n }\n\n // Uncheck and remove focusability from other siblings.\n for (const sibling of siblings) {\n if (sibling !== nextSibling) {\n sibling.checked = false;\n sibling.tabIndex = -1;\n sibling.blur();\n }\n }\n\n // The next sibling should be checked, focused and dispatch a change event\n nextSibling.checked = true;\n nextSibling.tabIndex = 0;\n nextSibling.focus();\n // Fire a change event since the change is triggered by a user action.\n // This matches native <input type=\"radio\"> behavior.\n nextSibling.dispatchEvent(new Event('change', {bubbles: true}));\n\n break;\n }\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"single-selection-controller.js","sourceRoot":"","sources":["single-selection-controller.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,OAAO,yBAAyB;IACpC;;;OAGG;IACH,IAAI,QAAQ;QACV,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YACjD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACpB;QAED,0EAA0E;QAC1E,6DAA6D;QAC7D,OAAO,KAAK,CAAC,IAAI,CACf,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAyB,UAAU,IAAI,IAAI,CAAC,CACH,CAAC;IACxE,CAAC;IAKD,YAA6B,IAA4B;QAA5B,SAAI,GAAJ,IAAI,CAAwB;QAHjD,YAAO,GAAG,KAAK,CAAC;QAChB,SAAI,GAAsB,IAAI,CAAC;QAyCtB,kBAAa,GAAG,GAAG,EAAE;YACpC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,CAAC,CAAC;QAEe,mBAAc,GAAG,GAAG,EAAE;YACrC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,CAAC,CAAC;QAqCF;;;;WAIG;QACc,kBAAa,GAAG,CAAC,KAAoB,EAAE,EAAE;YACxD,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,KAAK,WAAW,CAAC;YACzC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC;YACrC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,KAAK,WAAW,CAAC;YACzC,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,KAAK,YAAY,CAAC;YAC3C,wBAAwB;YACxB,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE;gBAC3C,OAAO;aACR;YAED,2DAA2D;YAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC/B,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;gBACpB,OAAO;aACR;YAED,8DAA8D;YAC9D,qDAAqD;YACrD,KAAK,CAAC,cAAc,EAAE,CAAC;YAEvB,wCAAwC;YACxC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC;YAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC;YAE9D,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9C,IAAI,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;YACzD,8DAA8D;YAC9D,8DAA8D;YAC9D,OAAO,SAAS,KAAK,SAAS,EAAE;gBAC9B,IAAI,SAAS,IAAI,QAAQ,CAAC,MAAM,EAAE;oBAChC,gDAAgD;oBAChD,SAAS,GAAG,CAAC,CAAC;iBACf;qBAAM,IAAI,SAAS,GAAG,CAAC,EAAE;oBACxB,6CAA6C;oBAC7C,SAAS,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;iBACjC;gBAED,gDAAgD;gBAChD,yCAAyC;gBACzC,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;gBACxC,IAAI,WAAW,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE;oBACxC,IAAI,QAAQ,EAAE;wBACZ,SAAS,EAAE,CAAC;qBACb;yBAAM;wBACL,SAAS,EAAE,CAAC;qBACb;oBAED,SAAS;iBACV;gBAED,uDAAuD;gBACvD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;oBAC9B,IAAI,OAAO,KAAK,WAAW,EAAE;wBAC3B,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC;wBACxB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;wBACtB,OAAO,CAAC,IAAI,EAAE,CAAC;qBAChB;iBACF;gBAED,0EAA0E;gBAC1E,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;gBAC3B,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACzB,WAAW,CAAC,KAAK,EAAE,CAAC;gBACpB,sEAAsE;gBACtE,qDAAqD;gBACrD,WAAW,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC;gBAEhE,MAAM;aACP;QACH,CAAC,CAAC;IA9J0D,CAAC;IAE7D,aAAa;QACX,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAgB,CAAC;QAClD,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5D,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACrB,uEAAuE;YACvE,wCAAwC;YACxC,IAAI,CAAC,eAAe,EAAE,CAAC;SACxB;QAED,mCAAmC;QACnC,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAED,gBAAgB;QACd,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/D,gDAAgD;QAChD,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;OAGG;IACH,mBAAmB;QACjB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACtB,OAAO;SACR;QAED,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAYO,eAAe;QACrB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE;YACnC,IAAI,OAAO,KAAK,IAAI,CAAC,IAAI,EAAE;gBACzB,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC;aACzB;SACF;IACH,CAAC;IAED;;OAEG;IACK,gBAAgB;QACtB,2DAA2D;QAC3D,oDAAoD;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,MAAM,cAAc,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnE,mEAAmE;QACnE,IAAI,cAAc,IAAI,IAAI,CAAC,OAAO,EAAE;YAClC,MAAM,SAAS,GAAG,cAAc,IAAI,IAAI,CAAC,IAAI,CAAC;YAC9C,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC;YAEvB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;gBAC9B,IAAI,OAAO,KAAK,SAAS,EAAE;oBACzB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;iBACvB;aACF;YACD,OAAO;SACR;QAED,wDAAwD;QACxD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;SACtB;IACH,CAAC;CA6EF","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ReactiveController} from 'lit';\n\n/**\n * An element that supports single-selection with `SingleSelectionController`.\n */\nexport interface SingleSelectionElement extends HTMLElement {\n /**\n * Whether or not the element is selected.\n */\n checked: boolean;\n}\n\n/**\n * A `ReactiveController` that provides root node-scoped single selection for\n * elements, similar to native `<input type=\"radio\">` selection.\n *\n * To use, elements should add the controller and call\n * `selectionController.handleCheckedChange()` in a getter/setter. This must\n * be synchronous to match native behavior.\n *\n * @example\n * const CHECKED = Symbol('checked');\n *\n * class MyToggle extends LitElement {\n * get checked() { return this[CHECKED]; }\n * set checked(checked: boolean) {\n * const oldValue = this.checked;\n * if (oldValue === checked) {\n * return;\n * }\n *\n * this[CHECKED] = checked;\n * this.selectionController.handleCheckedChange();\n * this.requestUpdate('checked', oldValue);\n * }\n *\n * [CHECKED] = false;\n *\n * private selectionController = new SingleSelectionController(this);\n *\n * constructor() {\n * super();\n * this.addController(this.selectionController);\n * }\n * }\n */\nexport class SingleSelectionController implements ReactiveController {\n /**\n * All single selection elements in the host element's root with the same\n * `name` attribute, including the host element.\n */\n get controls(): [SingleSelectionElement, ...SingleSelectionElement[]] {\n const name = this.host.getAttribute('name');\n if (!name || !this.root || !this.host.isConnected) {\n return [this.host];\n }\n\n // Cast as unknown since there is not enough information for typescript to\n // know that there is always at least one element (the host).\n return Array.from(\n this.root.querySelectorAll<SingleSelectionElement>(`[name=\"${name}\"]`),\n ) as unknown as [SingleSelectionElement, ...SingleSelectionElement[]];\n }\n\n private focused = false;\n private root: ParentNode | null = null;\n\n constructor(private readonly host: SingleSelectionElement) {}\n\n hostConnected() {\n this.root = this.host.getRootNode() as ParentNode;\n this.host.addEventListener('keydown', this.handleKeyDown);\n this.host.addEventListener('focusin', this.handleFocusIn);\n this.host.addEventListener('focusout', this.handleFocusOut);\n if (this.host.checked) {\n // Uncheck other siblings when attached if already checked. This mimics\n // native <input type=\"radio\"> behavior.\n this.uncheckSiblings();\n }\n\n // Update for the newly added host.\n this.updateTabIndices();\n }\n\n hostDisconnected() {\n this.host.removeEventListener('keydown', this.handleKeyDown);\n this.host.removeEventListener('focusin', this.handleFocusIn);\n this.host.removeEventListener('focusout', this.handleFocusOut);\n // Update for siblings that are still connected.\n this.updateTabIndices();\n this.root = null;\n }\n\n /**\n * Should be called whenever the host's `checked` property changes\n * synchronously.\n */\n handleCheckedChange() {\n if (!this.host.checked) {\n return;\n }\n\n this.uncheckSiblings();\n this.updateTabIndices();\n }\n\n private readonly handleFocusIn = () => {\n this.focused = true;\n this.updateTabIndices();\n };\n\n private readonly handleFocusOut = () => {\n this.focused = false;\n this.updateTabIndices();\n };\n\n private uncheckSiblings() {\n for (const sibling of this.controls) {\n if (sibling !== this.host) {\n sibling.checked = false;\n }\n }\n }\n\n /**\n * Updates the `tabindex` of the host and its siblings.\n */\n private updateTabIndices() {\n // There are three tabindex states for a group of elements:\n // 1. If any are checked, that element is focusable.\n const siblings = this.controls;\n const checkedSibling = siblings.find((sibling) => sibling.checked);\n // 2. If an element is focused, the others are no longer focusable.\n if (checkedSibling || this.focused) {\n const focusable = checkedSibling || this.host;\n focusable.tabIndex = 0;\n\n for (const sibling of siblings) {\n if (sibling !== focusable) {\n sibling.tabIndex = -1;\n }\n }\n return;\n }\n\n // 3. If none are checked or focused, all are focusable.\n for (const sibling of siblings) {\n sibling.tabIndex = 0;\n }\n }\n\n /**\n * Handles arrow key events from the host. Using the arrow keys will\n * select and check the next or previous sibling with the host's\n * `name` attribute.\n */\n private readonly handleKeyDown = (event: KeyboardEvent) => {\n const isDown = event.key === 'ArrowDown';\n const isUp = event.key === 'ArrowUp';\n const isLeft = event.key === 'ArrowLeft';\n const isRight = event.key === 'ArrowRight';\n // Ignore non-arrow keys\n if (!isLeft && !isRight && !isDown && !isUp) {\n return;\n }\n\n // Don't try to select another sibling if there aren't any.\n const siblings = this.controls;\n if (!siblings.length) {\n return;\n }\n\n // Prevent default interactions on the element for arrow keys,\n // since this controller will introduce new behavior.\n event.preventDefault();\n\n // Check if moving forwards or backwards\n const isRtl = getComputedStyle(this.host).direction === 'rtl';\n const forwards = isRtl ? isLeft || isDown : isRight || isDown;\n\n const hostIndex = siblings.indexOf(this.host);\n let nextIndex = forwards ? hostIndex + 1 : hostIndex - 1;\n // Search for the next sibling that is not disabled to select.\n // If we return to the host index, there is nothing to select.\n while (nextIndex !== hostIndex) {\n if (nextIndex >= siblings.length) {\n // Return to start if moving past the last item.\n nextIndex = 0;\n } else if (nextIndex < 0) {\n // Go to end if moving before the first item.\n nextIndex = siblings.length - 1;\n }\n\n // Check if the next sibling is disabled. If so,\n // move the index and continue searching.\n const nextSibling = siblings[nextIndex];\n if (nextSibling.hasAttribute('disabled')) {\n if (forwards) {\n nextIndex++;\n } else {\n nextIndex--;\n }\n\n continue;\n }\n\n // Uncheck and remove focusability from other siblings.\n for (const sibling of siblings) {\n if (sibling !== nextSibling) {\n sibling.checked = false;\n sibling.tabIndex = -1;\n sibling.blur();\n }\n }\n\n // The next sibling should be checked, focused and dispatch a change event\n nextSibling.checked = true;\n nextSibling.tabIndex = 0;\n nextSibling.focus();\n // Fire a change event since the change is triggered by a user action.\n // This matches native <input type=\"radio\"> behavior.\n nextSibling.dispatchEvent(new Event('change', {bubbles: true}));\n\n break;\n }\n };\n}\n"]}
|
|
@@ -6,10 +6,14 @@
|
|
|
6
6
|
import '../../menu/menu.js';
|
|
7
7
|
import { LitElement, PropertyValues } from 'lit';
|
|
8
8
|
import { StaticValue } from 'lit/static-html.js';
|
|
9
|
+
import { Field } from '../../field/internal/field.js';
|
|
10
|
+
import { createValidator, getValidityAnchor } from '../../labs/behaviors/constraint-validation.js';
|
|
9
11
|
import { getFormValue } from '../../labs/behaviors/form-associated.js';
|
|
12
|
+
import { onReportValidity } from '../../labs/behaviors/on-report-validity.js';
|
|
13
|
+
import { SelectValidator } from '../../labs/behaviors/validators/select-validator.js';
|
|
10
14
|
import { SelectOption } from './selectoption/selectOptionController.js';
|
|
11
15
|
declare const VALUE: unique symbol;
|
|
12
|
-
declare const selectBaseClass: import("../../labs/behaviors/mixin.js").MixinReturn<(abstract new (...args: any[]) => import("../../labs/behaviors/element-internals.js").WithElementInternals) & typeof LitElement & import("../../labs/behaviors/form-associated.js").FormAssociatedConstructor, import("../../labs/behaviors/form-associated.js").FormAssociated>;
|
|
16
|
+
declare const selectBaseClass: import("../../labs/behaviors/mixin.js").MixinReturn<import("../../labs/behaviors/mixin.js").MixinReturn<import("../../labs/behaviors/mixin.js").MixinReturn<(abstract new (...args: any[]) => import("../../labs/behaviors/element-internals.js").WithElementInternals) & typeof LitElement & import("../../labs/behaviors/form-associated.js").FormAssociatedConstructor, import("../../labs/behaviors/form-associated.js").FormAssociated>, import("../../labs/behaviors/constraint-validation.js").ConstraintValidation>, import("../../labs/behaviors/on-report-validity.js").OnReportValidity>;
|
|
13
17
|
/**
|
|
14
18
|
* @fires change {Event} The native `change` event on
|
|
15
19
|
* [`<input>`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event)
|
|
@@ -25,6 +29,12 @@ declare const selectBaseClass: import("../../labs/behaviors/mixin.js").MixinRetu
|
|
|
25
29
|
* and closed.
|
|
26
30
|
*/
|
|
27
31
|
export declare abstract class Select extends selectBaseClass {
|
|
32
|
+
/** @nocollapse */
|
|
33
|
+
static shadowRootOptions: {
|
|
34
|
+
delegatesFocus: boolean;
|
|
35
|
+
mode: ShadowRootMode;
|
|
36
|
+
slotAssignment?: SlotAssignmentMode;
|
|
37
|
+
};
|
|
28
38
|
/**
|
|
29
39
|
* Opens the menu synchronously with no animation.
|
|
30
40
|
*/
|
|
@@ -66,6 +76,10 @@ export declare abstract class Select extends selectBaseClass {
|
|
|
66
76
|
* element with stacking context and hidden overflows such as `md-dialog`.
|
|
67
77
|
*/
|
|
68
78
|
menuPositioning: 'absolute' | 'fixed' | 'popover';
|
|
79
|
+
/**
|
|
80
|
+
* Clamps the menu-width to the width of the select.
|
|
81
|
+
*/
|
|
82
|
+
clampMenuWidth: boolean;
|
|
69
83
|
/**
|
|
70
84
|
* The max time between the keystrokes of the typeahead select / menu behavior
|
|
71
85
|
* before it clears the typeahead buffer.
|
|
@@ -104,27 +118,6 @@ export declare abstract class Select extends selectBaseClass {
|
|
|
104
118
|
* NOTE: md-select only suppoprts single selection.
|
|
105
119
|
*/
|
|
106
120
|
get selectedOptions(): SelectOption[];
|
|
107
|
-
/**
|
|
108
|
-
* Returns a ValidityState object that represents the validity states of the
|
|
109
|
-
* checkbox.
|
|
110
|
-
*
|
|
111
|
-
* Note that selects will only set `valueMissing` if unselected and
|
|
112
|
-
* `required`.
|
|
113
|
-
*/
|
|
114
|
-
get validity(): ValidityState;
|
|
115
|
-
/**
|
|
116
|
-
* Returns the native validation error message.
|
|
117
|
-
*
|
|
118
|
-
* https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation#constraint_validation_process
|
|
119
|
-
*/
|
|
120
|
-
get validationMessage(): string;
|
|
121
|
-
/**
|
|
122
|
-
* Returns whether an element will successfully validate based on forms
|
|
123
|
-
* validation rules and constraints.
|
|
124
|
-
*
|
|
125
|
-
* https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation#constraint_validation_process
|
|
126
|
-
*/
|
|
127
|
-
get willValidate(): boolean;
|
|
128
121
|
protected abstract readonly fieldTag: StaticValue;
|
|
129
122
|
/**
|
|
130
123
|
* Used for initializing select when the user sets the `value` directly.
|
|
@@ -156,9 +149,9 @@ export declare abstract class Select extends selectBaseClass {
|
|
|
156
149
|
private readonly menu;
|
|
157
150
|
private readonly labelEl;
|
|
158
151
|
private readonly leadingIcons;
|
|
159
|
-
private
|
|
160
|
-
private
|
|
161
|
-
|
|
152
|
+
private prevOpen;
|
|
153
|
+
private selectWidth;
|
|
154
|
+
constructor();
|
|
162
155
|
/**
|
|
163
156
|
* Selects an option given the value of the option, and updates MdSelect's
|
|
164
157
|
* value.
|
|
@@ -173,50 +166,9 @@ export declare abstract class Select extends selectBaseClass {
|
|
|
173
166
|
* Reset the select to its default value.
|
|
174
167
|
*/
|
|
175
168
|
reset(): void;
|
|
176
|
-
|
|
177
|
-
* Checks the select's native validation and returns whether or not the
|
|
178
|
-
* element is valid.
|
|
179
|
-
*
|
|
180
|
-
* If invalid, this method will dispatch the `invalid` event.
|
|
181
|
-
*
|
|
182
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/checkValidity
|
|
183
|
-
*
|
|
184
|
-
* @return true if the select is valid, or false if not.
|
|
185
|
-
*/
|
|
186
|
-
checkValidity(): boolean;
|
|
187
|
-
/**
|
|
188
|
-
* Checks the select's native validation and returns whether or not the
|
|
189
|
-
* element is valid.
|
|
190
|
-
*
|
|
191
|
-
* If invalid, this method will dispatch the `invalid` event.
|
|
192
|
-
*
|
|
193
|
-
* This method will display or clear an error text message equal to the
|
|
194
|
-
* select's `validationMessage`, unless the invalid event is canceled.
|
|
195
|
-
*
|
|
196
|
-
* Use `setCustomValidity()` to customize the `validationMessage`.
|
|
197
|
-
*
|
|
198
|
-
* This method can also be used to re-announce error messages to screen
|
|
199
|
-
* readers.
|
|
200
|
-
*
|
|
201
|
-
* @return true if the select is valid, or false if not.
|
|
202
|
-
*/
|
|
203
|
-
reportValidity(): boolean;
|
|
204
|
-
private showErrorMessage;
|
|
205
|
-
/**
|
|
206
|
-
* Sets the select's native validation error message. This is used to
|
|
207
|
-
* customize `validationMessage`.
|
|
208
|
-
*
|
|
209
|
-
* When the error is not an empty string, the select is considered invalid
|
|
210
|
-
* and `validity.customError` will be true.
|
|
211
|
-
*
|
|
212
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/setCustomValidity
|
|
213
|
-
*
|
|
214
|
-
* @param error The error message to display.
|
|
215
|
-
*/
|
|
216
|
-
setCustomValidity(error: string): void;
|
|
169
|
+
[onReportValidity](invalidEvent: Event | null): void;
|
|
217
170
|
protected update(changed: PropertyValues<Select>): void;
|
|
218
171
|
protected render(): import("lit-html").TemplateResult<1>;
|
|
219
|
-
protected updated(changed: PropertyValues<Select>): void;
|
|
220
172
|
protected firstUpdated(changed: PropertyValues<Select>): Promise<void>;
|
|
221
173
|
private getRenderClasses;
|
|
222
174
|
private renderField;
|
|
@@ -290,15 +242,12 @@ export declare abstract class Select extends selectBaseClass {
|
|
|
290
242
|
*/
|
|
291
243
|
private dispatchInteractionEvents;
|
|
292
244
|
private getErrorText;
|
|
293
|
-
private syncValidity;
|
|
294
|
-
private getRequiredValidationMessage;
|
|
295
|
-
private readonly onInvalid;
|
|
296
|
-
connectedCallback(): void;
|
|
297
|
-
disconnectedCallback(): void;
|
|
298
245
|
disabled: boolean;
|
|
299
246
|
name: string;
|
|
300
247
|
[getFormValue](): string;
|
|
301
248
|
formResetCallback(): void;
|
|
302
249
|
formStateRestoreCallback(state: string): void;
|
|
250
|
+
[createValidator](): SelectValidator;
|
|
251
|
+
[getValidityAnchor](): Field;
|
|
303
252
|
}
|
|
304
253
|
export {};
|
|
@@ -9,11 +9,15 @@ import '../../menu/menu.js';
|
|
|
9
9
|
import { html, isServer, LitElement, nothing } from 'lit';
|
|
10
10
|
import { property, query, queryAssignedElements, state } from 'lit/decorators.js';
|
|
11
11
|
import { classMap } from 'lit/directives/class-map.js';
|
|
12
|
+
import { styleMap } from 'lit/directives/style-map.js';
|
|
12
13
|
import { html as staticHtml } from 'lit/static-html.js';
|
|
13
14
|
import { requestUpdateOnAriaChange } from '../../internal/aria/delegate.js';
|
|
14
15
|
import { redispatchEvent } from '../../internal/controller/events.js';
|
|
15
|
-
import {
|
|
16
|
+
import { createValidator, getValidityAnchor, mixinConstraintValidation, } from '../../labs/behaviors/constraint-validation.js';
|
|
17
|
+
import { mixinElementInternals } from '../../labs/behaviors/element-internals.js';
|
|
16
18
|
import { getFormValue, mixinFormAssociated, } from '../../labs/behaviors/form-associated.js';
|
|
19
|
+
import { mixinOnReportValidity, onReportValidity, } from '../../labs/behaviors/on-report-validity.js';
|
|
20
|
+
import { SelectValidator } from '../../labs/behaviors/validators/select-validator.js';
|
|
17
21
|
import { getActiveItem } from '../../list/internal/list-navigation-helpers.js';
|
|
18
22
|
import { isElementInSubtree, isSelectableKey, } from '../../menu/internal/controllers/shared.js';
|
|
19
23
|
import { TYPEAHEAD_RECORD } from '../../menu/internal/controllers/typeaheadController.js';
|
|
@@ -21,7 +25,7 @@ import { DEFAULT_TYPEAHEAD_BUFFER_TIME } from '../../menu/internal/menu.js';
|
|
|
21
25
|
import { getSelectedItems } from './shared.js';
|
|
22
26
|
const VALUE = Symbol('value');
|
|
23
27
|
// Separate variable needed for closure.
|
|
24
|
-
const selectBaseClass = mixinFormAssociated(mixinElementInternals(LitElement));
|
|
28
|
+
const selectBaseClass = mixinOnReportValidity(mixinConstraintValidation(mixinFormAssociated(mixinElementInternals(LitElement))));
|
|
25
29
|
/**
|
|
26
30
|
* @fires change {Event} The native `change` event on
|
|
27
31
|
* [`<input>`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event)
|
|
@@ -37,8 +41,54 @@ const selectBaseClass = mixinFormAssociated(mixinElementInternals(LitElement));
|
|
|
37
41
|
* and closed.
|
|
38
42
|
*/
|
|
39
43
|
export class Select extends selectBaseClass {
|
|
44
|
+
/**
|
|
45
|
+
* The value of the currently selected option.
|
|
46
|
+
*
|
|
47
|
+
* Note: For SSR, set `[selected]` on the requested option and `displayText`
|
|
48
|
+
* rather than setting `value` setting `value` will incur a DOM query.
|
|
49
|
+
*/
|
|
50
|
+
get value() {
|
|
51
|
+
return this[VALUE];
|
|
52
|
+
}
|
|
53
|
+
set value(value) {
|
|
54
|
+
if (isServer)
|
|
55
|
+
return;
|
|
56
|
+
this.lastUserSetValue = value;
|
|
57
|
+
this.select(value);
|
|
58
|
+
}
|
|
59
|
+
get options() {
|
|
60
|
+
// NOTE: this does a DOM query.
|
|
61
|
+
return (this.menu?.items ?? []);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The index of the currently selected option.
|
|
65
|
+
*
|
|
66
|
+
* Note: For SSR, set `[selected]` on the requested option and `displayText`
|
|
67
|
+
* rather than setting `selectedIndex` setting `selectedIndex` will incur a
|
|
68
|
+
* DOM query.
|
|
69
|
+
*/
|
|
70
|
+
get selectedIndex() {
|
|
71
|
+
// tslint:disable-next-line:enforce-name-casing
|
|
72
|
+
const [_option, index] = (this.getSelectedOptions() ?? [])[0] ?? [];
|
|
73
|
+
return index ?? -1;
|
|
74
|
+
}
|
|
75
|
+
set selectedIndex(index) {
|
|
76
|
+
this.lastUserSetSelectedIndex = index;
|
|
77
|
+
this.selectIndex(index);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns an array of selected options.
|
|
81
|
+
*
|
|
82
|
+
* NOTE: md-select only suppoprts single selection.
|
|
83
|
+
*/
|
|
84
|
+
get selectedOptions() {
|
|
85
|
+
return (this.getSelectedOptions() ?? []).map(([option]) => option);
|
|
86
|
+
}
|
|
87
|
+
get hasError() {
|
|
88
|
+
return this.error || this.nativeError;
|
|
89
|
+
}
|
|
40
90
|
constructor() {
|
|
41
|
-
super(
|
|
91
|
+
super();
|
|
42
92
|
/**
|
|
43
93
|
* Opens the menu synchronously with no animation.
|
|
44
94
|
*/
|
|
@@ -80,6 +130,10 @@ export class Select extends selectBaseClass {
|
|
|
80
130
|
* element with stacking context and hidden overflows such as `md-dialog`.
|
|
81
131
|
*/
|
|
82
132
|
this.menuPositioning = 'popover';
|
|
133
|
+
/**
|
|
134
|
+
* Clamps the menu-width to the width of the select.
|
|
135
|
+
*/
|
|
136
|
+
this.clampMenuWidth = false;
|
|
83
137
|
/**
|
|
84
138
|
* The max time between the keystrokes of the typeahead select / menu behavior
|
|
85
139
|
* before it clears the typeahead buffer.
|
|
@@ -120,91 +174,15 @@ export class Select extends selectBaseClass {
|
|
|
120
174
|
this.nativeErrorText = '';
|
|
121
175
|
this.focused = false;
|
|
122
176
|
this.open = false;
|
|
123
|
-
|
|
124
|
-
this.
|
|
125
|
-
this.
|
|
126
|
-
this.
|
|
127
|
-
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
this.showErrorMessage(false, invalidEvent);
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* The value of the currently selected option.
|
|
135
|
-
*
|
|
136
|
-
* Note: For SSR, set `[selected]` on the requested option and `displayText`
|
|
137
|
-
* rather than setting `value` setting `value` will incur a DOM query.
|
|
138
|
-
*/
|
|
139
|
-
get value() {
|
|
140
|
-
return this[VALUE];
|
|
141
|
-
}
|
|
142
|
-
set value(value) {
|
|
143
|
-
if (isServer)
|
|
177
|
+
// Have to keep track of previous open because it's state and private and thus
|
|
178
|
+
// cannot be tracked in PropertyValues<this> map.
|
|
179
|
+
this.prevOpen = this.open;
|
|
180
|
+
this.selectWidth = 0;
|
|
181
|
+
if (isServer) {
|
|
144
182
|
return;
|
|
145
|
-
|
|
146
|
-
this.
|
|
147
|
-
|
|
148
|
-
get options() {
|
|
149
|
-
// NOTE: this does a DOM query.
|
|
150
|
-
return (this.menu?.items ?? []);
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* The index of the currently selected option.
|
|
154
|
-
*
|
|
155
|
-
* Note: For SSR, set `[selected]` on the requested option and `displayText`
|
|
156
|
-
* rather than setting `selectedIndex` setting `selectedIndex` will incur a
|
|
157
|
-
* DOM query.
|
|
158
|
-
*/
|
|
159
|
-
get selectedIndex() {
|
|
160
|
-
// tslint:disable-next-line:enforce-name-casing
|
|
161
|
-
const [_option, index] = (this.getSelectedOptions() ?? [])[0] ?? [];
|
|
162
|
-
return index ?? -1;
|
|
163
|
-
}
|
|
164
|
-
set selectedIndex(index) {
|
|
165
|
-
this.lastUserSetSelectedIndex = index;
|
|
166
|
-
this.selectIndex(index);
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Returns an array of selected options.
|
|
170
|
-
*
|
|
171
|
-
* NOTE: md-select only suppoprts single selection.
|
|
172
|
-
*/
|
|
173
|
-
get selectedOptions() {
|
|
174
|
-
return (this.getSelectedOptions() ?? []).map(([option]) => option);
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Returns a ValidityState object that represents the validity states of the
|
|
178
|
-
* checkbox.
|
|
179
|
-
*
|
|
180
|
-
* Note that selects will only set `valueMissing` if unselected and
|
|
181
|
-
* `required`.
|
|
182
|
-
*/
|
|
183
|
-
get validity() {
|
|
184
|
-
this.syncValidity();
|
|
185
|
-
return this[internals].validity;
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Returns the native validation error message.
|
|
189
|
-
*
|
|
190
|
-
* https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation#constraint_validation_process
|
|
191
|
-
*/
|
|
192
|
-
get validationMessage() {
|
|
193
|
-
this.syncValidity();
|
|
194
|
-
return this[internals].validationMessage;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Returns whether an element will successfully validate based on forms
|
|
198
|
-
* validation rules and constraints.
|
|
199
|
-
*
|
|
200
|
-
* https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation#constraint_validation_process
|
|
201
|
-
*/
|
|
202
|
-
get willValidate() {
|
|
203
|
-
this.syncValidity();
|
|
204
|
-
return this[internals].willValidate;
|
|
205
|
-
}
|
|
206
|
-
get hasError() {
|
|
207
|
-
return this.error || this.nativeError;
|
|
183
|
+
}
|
|
184
|
+
this.addEventListener('focus', this.handleFocus.bind(this));
|
|
185
|
+
this.addEventListener('blur', this.handleBlur.bind(this));
|
|
208
186
|
}
|
|
209
187
|
/**
|
|
210
188
|
* Selects an option given the value of the option, and updates MdSelect's
|
|
@@ -237,76 +215,22 @@ export class Select extends selectBaseClass {
|
|
|
237
215
|
this.nativeError = false;
|
|
238
216
|
this.nativeErrorText = '';
|
|
239
217
|
}
|
|
240
|
-
|
|
241
|
-
* Checks the select's native validation and returns whether or not the
|
|
242
|
-
* element is valid.
|
|
243
|
-
*
|
|
244
|
-
* If invalid, this method will dispatch the `invalid` event.
|
|
245
|
-
*
|
|
246
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/checkValidity
|
|
247
|
-
*
|
|
248
|
-
* @return true if the select is valid, or false if not.
|
|
249
|
-
*/
|
|
250
|
-
checkValidity() {
|
|
251
|
-
this.isCheckingValidity = true;
|
|
252
|
-
this.syncValidity();
|
|
253
|
-
const isValid = this[internals].checkValidity();
|
|
254
|
-
this.isCheckingValidity = false;
|
|
255
|
-
return isValid;
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Checks the select's native validation and returns whether or not the
|
|
259
|
-
* element is valid.
|
|
260
|
-
*
|
|
261
|
-
* If invalid, this method will dispatch the `invalid` event.
|
|
262
|
-
*
|
|
263
|
-
* This method will display or clear an error text message equal to the
|
|
264
|
-
* select's `validationMessage`, unless the invalid event is canceled.
|
|
265
|
-
*
|
|
266
|
-
* Use `setCustomValidity()` to customize the `validationMessage`.
|
|
267
|
-
*
|
|
268
|
-
* This method can also be used to re-announce error messages to screen
|
|
269
|
-
* readers.
|
|
270
|
-
*
|
|
271
|
-
* @return true if the select is valid, or false if not.
|
|
272
|
-
*/
|
|
273
|
-
reportValidity() {
|
|
274
|
-
this.isReportingValidity = true;
|
|
275
|
-
let invalidEvent;
|
|
276
|
-
this.addEventListener('invalid', (event) => {
|
|
277
|
-
invalidEvent = event;
|
|
278
|
-
}, { once: true });
|
|
279
|
-
const valid = this.checkValidity();
|
|
280
|
-
this.showErrorMessage(valid, invalidEvent);
|
|
281
|
-
this.isReportingValidity = false;
|
|
282
|
-
return valid;
|
|
283
|
-
}
|
|
284
|
-
showErrorMessage(valid, invalidEvent) {
|
|
218
|
+
[(_a = VALUE, onReportValidity)](invalidEvent) {
|
|
285
219
|
if (invalidEvent?.defaultPrevented) {
|
|
286
|
-
return
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (invalidEvent) {
|
|
223
|
+
// Prevent default pop-up behavior. This also prevents focusing, so we
|
|
224
|
+
// manually focus.
|
|
225
|
+
invalidEvent.preventDefault();
|
|
226
|
+
this.focus();
|
|
287
227
|
}
|
|
288
228
|
const prevMessage = this.getErrorText();
|
|
289
|
-
this.nativeError =
|
|
229
|
+
this.nativeError = !!invalidEvent;
|
|
290
230
|
this.nativeErrorText = this.validationMessage;
|
|
291
231
|
if (prevMessage === this.getErrorText()) {
|
|
292
232
|
this.field?.reannounceError();
|
|
293
233
|
}
|
|
294
|
-
return valid;
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* Sets the select's native validation error message. This is used to
|
|
298
|
-
* customize `validationMessage`.
|
|
299
|
-
*
|
|
300
|
-
* When the error is not an empty string, the select is considered invalid
|
|
301
|
-
* and `validity.customError` will be true.
|
|
302
|
-
*
|
|
303
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/setCustomValidity
|
|
304
|
-
*
|
|
305
|
-
* @param error The error message to display.
|
|
306
|
-
*/
|
|
307
|
-
setCustomValidity(error) {
|
|
308
|
-
this.customValidationMessage = error;
|
|
309
|
-
this.syncValidity();
|
|
310
234
|
}
|
|
311
235
|
update(changed) {
|
|
312
236
|
// In SSR the options will be ready to query, so try to figure out what
|
|
@@ -314,6 +238,16 @@ export class Select extends selectBaseClass {
|
|
|
314
238
|
if (!this.hasUpdated) {
|
|
315
239
|
this.initUserSelection();
|
|
316
240
|
}
|
|
241
|
+
// We have just opened the menu.
|
|
242
|
+
// We are only able to check for the select's rect in `update()` instead of
|
|
243
|
+
// having to wait for `updated()` because the menu can never be open on
|
|
244
|
+
// first render since it is not settable and Lit SSR does not support click
|
|
245
|
+
// events which would open the menu.
|
|
246
|
+
if (this.prevOpen !== this.open && this.open) {
|
|
247
|
+
const selectRect = this.getBoundingClientRect();
|
|
248
|
+
this.selectWidth = selectRect.width;
|
|
249
|
+
}
|
|
250
|
+
this.prevOpen = this.open;
|
|
317
251
|
super.update(changed);
|
|
318
252
|
}
|
|
319
253
|
render() {
|
|
@@ -325,11 +259,6 @@ export class Select extends selectBaseClass {
|
|
|
325
259
|
</span>
|
|
326
260
|
`;
|
|
327
261
|
}
|
|
328
|
-
updated(changed) {
|
|
329
|
-
if (changed.has('required')) {
|
|
330
|
-
this.syncValidity();
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
262
|
async firstUpdated(changed) {
|
|
334
263
|
await this.menu?.updateComplete;
|
|
335
264
|
// If this has been handled on update already due to SSR, try again.
|
|
@@ -379,9 +308,7 @@ export class Select extends selectBaseClass {
|
|
|
379
308
|
supporting-text=${this.supportingText}
|
|
380
309
|
error-text=${this.getErrorText()}
|
|
381
310
|
@keydown=${this.handleKeydown}
|
|
382
|
-
@click=${this.handleClick}
|
|
383
|
-
@focus=${this.handleFocus}
|
|
384
|
-
@blur=${this.handleBlur}>
|
|
311
|
+
@click=${this.handleClick}>
|
|
385
312
|
${this.renderFieldContent()}
|
|
386
313
|
<div id="description" slot="aria-describedby"></div>
|
|
387
314
|
</${this.fieldTag}>`;
|
|
@@ -437,6 +364,12 @@ export class Select extends selectBaseClass {
|
|
|
437
364
|
part="menu"
|
|
438
365
|
exportparts="focus-ring: menu-focus-ring"
|
|
439
366
|
anchor="field"
|
|
367
|
+
style=${styleMap({
|
|
368
|
+
'--__menu-min-width': `${this.selectWidth}px`,
|
|
369
|
+
'--__menu-max-width': this.clampMenuWidth
|
|
370
|
+
? `${this.selectWidth}px`
|
|
371
|
+
: undefined,
|
|
372
|
+
})}
|
|
440
373
|
.open=${this.open}
|
|
441
374
|
.quick=${this.quick}
|
|
442
375
|
.positioning=${this.menuPositioning}
|
|
@@ -554,7 +487,6 @@ export class Select extends selectBaseClass {
|
|
|
554
487
|
this[VALUE] = '';
|
|
555
488
|
this.displayText = '';
|
|
556
489
|
}
|
|
557
|
-
this.syncValidity();
|
|
558
490
|
return hasSelectedOptionChanged;
|
|
559
491
|
}
|
|
560
492
|
/**
|
|
@@ -683,31 +615,7 @@ export class Select extends selectBaseClass {
|
|
|
683
615
|
getErrorText() {
|
|
684
616
|
return this.error ? this.errorText : this.nativeErrorText;
|
|
685
617
|
}
|
|
686
|
-
|
|
687
|
-
const valueMissing = this.required && !this.value;
|
|
688
|
-
const customError = !!this.customValidationMessage;
|
|
689
|
-
const validationMessage = this.customValidationMessage ||
|
|
690
|
-
(valueMissing && this.getRequiredValidationMessage()) ||
|
|
691
|
-
'';
|
|
692
|
-
this[internals].setValidity({ valueMissing, customError }, validationMessage, this.field ?? undefined);
|
|
693
|
-
}
|
|
694
|
-
// Returns the platform `<select>` validation message for i18n.
|
|
695
|
-
getRequiredValidationMessage() {
|
|
696
|
-
const select = document.createElement('select');
|
|
697
|
-
select.required = true;
|
|
698
|
-
return select.validationMessage;
|
|
699
|
-
}
|
|
700
|
-
connectedCallback() {
|
|
701
|
-
super.connectedCallback();
|
|
702
|
-
// Handles the case where the user submits the form and native validation
|
|
703
|
-
// error pops up. We want the error styles to show.
|
|
704
|
-
this.addEventListener('invalid', this.onInvalid);
|
|
705
|
-
}
|
|
706
|
-
disconnectedCallback() {
|
|
707
|
-
super.disconnectedCallback();
|
|
708
|
-
this.removeEventListener('invalid', this.onInvalid);
|
|
709
|
-
}
|
|
710
|
-
[(_a = VALUE, getFormValue)]() {
|
|
618
|
+
[getFormValue]() {
|
|
711
619
|
return this.value;
|
|
712
620
|
}
|
|
713
621
|
formResetCallback() {
|
|
@@ -716,10 +624,21 @@ export class Select extends selectBaseClass {
|
|
|
716
624
|
formStateRestoreCallback(state) {
|
|
717
625
|
this.value = state;
|
|
718
626
|
}
|
|
627
|
+
[createValidator]() {
|
|
628
|
+
return new SelectValidator(() => this);
|
|
629
|
+
}
|
|
630
|
+
[getValidityAnchor]() {
|
|
631
|
+
return this.field;
|
|
632
|
+
}
|
|
719
633
|
}
|
|
720
634
|
(() => {
|
|
721
635
|
requestUpdateOnAriaChange(Select);
|
|
722
636
|
})();
|
|
637
|
+
/** @nocollapse */
|
|
638
|
+
Select.shadowRootOptions = {
|
|
639
|
+
...LitElement.shadowRootOptions,
|
|
640
|
+
delegatesFocus: true,
|
|
641
|
+
};
|
|
723
642
|
__decorate([
|
|
724
643
|
property({ type: Boolean })
|
|
725
644
|
], Select.prototype, "quick", void 0);
|
|
@@ -741,6 +660,9 @@ __decorate([
|
|
|
741
660
|
__decorate([
|
|
742
661
|
property({ attribute: 'menu-positioning' })
|
|
743
662
|
], Select.prototype, "menuPositioning", void 0);
|
|
663
|
+
__decorate([
|
|
664
|
+
property({ type: Boolean, attribute: 'clamp-menu-width' })
|
|
665
|
+
], Select.prototype, "clampMenuWidth", void 0);
|
|
744
666
|
__decorate([
|
|
745
667
|
property({ type: Number, attribute: 'typeahead-delay' })
|
|
746
668
|
], Select.prototype, "typeaheadDelay", void 0);
|