UNPKG

carbon-custom-elements

Version:

A Carbon Design System variant that's as easy to use as native HTML elements, with no framework tax, no framework silo.

1 lines 9.55 kB
{"version":3,"sources":["components/radio-button/radio-button.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAwC,UAAU,EAAE,MAAM,aAAa,CAAC;AAO/E,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAKhE;;GAEG;AACH,oBAAY,2BAA2B;IACrC;;OAEG;IACH,IAAI,SAAS;IAEb;;OAEG;IACH,KAAK,UAAU;CAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4ED;;;;GAIG;AACH,cACM,aAAc,SAAQ,kBAAyC;IACnE;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAkC;IAElD;;OAEG;IACH,OAAO,CAAC,oBAAoB,CAAuB;IAEnD;;OAEG;IAEH,OAAO,CAAC,UAAU,CAAoB;IAEtC;;OAEG;IAGH,OAAO,CAAC,YAAY,CAQlB;IAEF;;OAEG;IAGH,OAAO,CAAC,cAAc,CAgBpB;IAEF;;OAEG;IAEH,OAAO,UAAS;IAEhB;;OAEG;IAEH,QAAQ,UAAS;IAEjB;;OAEG;IAEH,SAAS,UAAS;IAElB;;OAEG;IAEH,aAAa,8BAAqC;IAElD;;OAEG;IAEH,SAAS,SAAM;IAEf;;OAEG;IAEH,IAAI,EAAG,MAAM,CAAC;IAEd;;OAEG;IAEH,WAAW,2BAAuC;IAElD;;OAEG;IAEH,KAAK,EAAG,MAAM,CAAC;IAEf,gBAAgB;IAIhB,oBAAoB;IAOpB,YAAY;IAIZ,OAAO,CAAC,iBAAiB,KAAA;IAiBzB,MAAM;IAqBN;;OAEG;IACH,MAAM,KAAK,WAAW,WAErB;IAED,MAAM,CAAC,MAAM,MAAU;CACxB;AAED,eAAe,aAAa,CAAC","file":"radio-button.d.ts","sourcesContent":["/**\n * @license\n *\n * Copyright IBM Corp. 2019, 2020\n *\n * This source code is licensed under the Apache-2.0 license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { classMap } from 'lit-html/directives/class-map';\nimport { html, property, query, customElement, LitElement } from 'lit-element';\nimport settings from 'carbon-components/es/globals/js/settings';\nimport ifNonNull from '../../globals/directives/if-non-null';\nimport HostListener from '../../globals/decorators/host-listener';\nimport FocusMixin from '../../globals/mixins/focus';\nimport HostListenerMixin from '../../globals/mixins/host-listener';\nimport RadioGroupManager, { NAVIGATION_DIRECTION, ManagedRadioButtonDelegate } from '../../globals/internal/radio-group-manager';\nimport { RADIO_BUTTON_ORIENTATION } from './radio-button-group';\nimport styles from './radio-button.scss';\n\nconst { prefix } = settings;\n\n/**\n * The label position of radio button.\n */\nexport enum RADIO_BUTTON_LABEL_POSITION {\n /**\n * Placed at left.\n */\n LEFT = 'left',\n\n /**\n * Placed at right.\n */\n RIGHT = 'right',\n}\n\n/**\n * Map of navigation direction by key for horizontal alignment.\n */\nconst navigationDirectionForKeyHorizontal = {\n ArrowLeft: NAVIGATION_DIRECTION.BACKWARD,\n Left: NAVIGATION_DIRECTION.BACKWARD, // IE\n ArrowRight: NAVIGATION_DIRECTION.FORWARD,\n Right: NAVIGATION_DIRECTION.FORWARD, // IE\n};\n\n/**\n * Map of navigation direction by key for vertical alignment.\n */\nconst navigationDirectionForKeyVertical = {\n ArrowUp: NAVIGATION_DIRECTION.BACKWARD,\n Up: NAVIGATION_DIRECTION.BACKWARD, // IE\n ArrowDown: NAVIGATION_DIRECTION.FORWARD,\n Down: NAVIGATION_DIRECTION.FORWARD, // IE\n};\n\n/**\n * The interface for `RadioGroupManager` for radio button.\n */\nclass RadioButtonDelegate implements ManagedRadioButtonDelegate {\n /**\n * The radio button to target.\n */\n private _radio: HTMLInputElement;\n\n constructor(radio: HTMLInputElement) {\n this._radio = radio;\n }\n\n get checked() {\n return this._radio.checked;\n }\n\n set checked(checked) {\n const { host } = this._radio.getRootNode() as ShadowRoot;\n const { eventChange } = host.constructor as typeof BXRadioButton; // eslint-disable-line no-use-before-define\n (host as BXRadioButton).checked = checked;\n this._radio.tabIndex = checked ? 0 : -1;\n host.dispatchEvent(\n new CustomEvent(eventChange, {\n bubbles: true,\n composed: true,\n detail: {\n checked,\n },\n })\n );\n }\n\n get tabIndex() {\n return this._radio.tabIndex;\n }\n\n set tabIndex(tabIndex) {\n this._radio.tabIndex = tabIndex;\n }\n\n get name() {\n return this._radio.name;\n }\n\n compareDocumentPosition(other: RadioButtonDelegate) {\n return this._radio.compareDocumentPosition(other._radio);\n }\n\n focus() {\n this._radio.focus();\n }\n}\n\n/**\n * Radio button.\n * @element bx-radio-button\n * @fires bx-radio-button-changed - The custom event fired after this radio button changes its checked state.\n */\n@customElement(`${prefix}-radio-button`)\nclass BXRadioButton extends HostListenerMixin(FocusMixin(LitElement)) {\n /**\n * The radio group manager associated with the radio button.\n */\n private _manager: RadioGroupManager | null = null;\n\n /**\n * The interface for `RadioGroupManager` for radio button.\n */\n private _radioButtonDelegate!: RadioButtonDelegate;\n\n /**\n * The hidden radio button.\n */\n @query('#input')\n private _inputNode!: HTMLInputElement;\n\n /**\n * Handles `click` event on this element.\n */\n @HostListener('click')\n // @ts-ignore: The decorator refers to this method but TS thinks this method is not referred to\n private _handleClick = () => {\n const { _radioButtonDelegate: radioButtonDelegate } = this;\n if (radioButtonDelegate) {\n this.checked = true;\n if (this._manager) {\n this._manager.select(radioButtonDelegate);\n }\n }\n };\n\n /**\n * Handles `keydown` event on this element.\n */\n @HostListener('keydown')\n // @ts-ignore: The decorator refers to this method but TS thinks this method is not referred to\n private _handleKeydown = (event: KeyboardEvent) => {\n const { orientation, _radioButtonDelegate: radioButtonDelegate } = this;\n const manager = this._manager;\n if (radioButtonDelegate && manager) {\n const navigationDirectionForKey =\n orientation === RADIO_BUTTON_ORIENTATION.HORIZONTAL\n ? navigationDirectionForKeyHorizontal\n : navigationDirectionForKeyVertical;\n const navigationDirection = navigationDirectionForKey[event.key];\n if (navigationDirection) {\n manager.select(manager.navigate(radioButtonDelegate, navigationDirection));\n }\n if (event.key === ' ' || event.key === 'Enter') {\n manager.select(radioButtonDelegate);\n }\n }\n };\n\n /**\n * `true` if this radio button should be checked.\n */\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n /**\n * `true` if the check box should be disabled.\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * `true` if the label should be hidden.\n */\n @property({ type: Boolean, reflect: true, attribute: 'hide-label' })\n hideLabel = false;\n\n /**\n * The label position.\n */\n @property({ reflect: true, attribute: 'label-position' })\n labelPosition = RADIO_BUTTON_LABEL_POSITION.RIGHT;\n\n /**\n * The label text.\n */\n @property({ attribute: 'label-text' })\n labelText = '';\n\n /**\n * The `name` attribute for the `<input>` for selection.\n */\n @property()\n name!: string;\n\n /**\n * The orientation to lay out radio buttons.\n */\n @property({ reflect: true })\n orientation = RADIO_BUTTON_ORIENTATION.HORIZONTAL;\n\n /**\n * The `value` attribute for the `<input>` for selection.\n */\n @property()\n value!: string;\n\n createRenderRoot() {\n return this.attachShadow({ mode: 'open', delegatesFocus: true });\n }\n\n disconnectedCallback() {\n if (this._manager) {\n this._manager.delete(this._radioButtonDelegate);\n }\n super.disconnectedCallback();\n }\n\n firstUpdated() {\n this._radioButtonDelegate = new RadioButtonDelegate(this._inputNode);\n }\n\n updated(changedProperties) {\n const { _inputNode: inputNode, _radioButtonDelegate: radioButtonDelegate, name } = this;\n if (changedProperties.has('checked') || changedProperties.has('name')) {\n if (!this._manager) {\n this._manager = RadioGroupManager.get(this.getRootNode({ composed: true }) as Document);\n }\n const { _manager: manager } = this;\n if (changedProperties.has('name')) {\n manager!.delete(radioButtonDelegate, changedProperties.get('name'));\n if (name) {\n manager!.add(radioButtonDelegate);\n }\n }\n inputNode.setAttribute('tabindex', !name || !manager || !manager.shouldBeFocusable(radioButtonDelegate) ? '-1' : '0');\n }\n }\n\n render() {\n const { checked, hideLabel, labelText, name, value } = this;\n const innerLabelClasses = classMap({\n [`${prefix}--visually-hidden`]: hideLabel,\n });\n return html`\n <input\n id=\"input\"\n type=\"radio\"\n class=\"${prefix}--radio-button\"\n .checked=${checked}\n name=${ifNonNull(name)}\n value=${ifNonNull(value)}\n />\n <label for=\"input\" class=\"${prefix}--radio-button__label\">\n <span class=\"${prefix}--radio-button__appearance\"></span>\n <span class=\"${innerLabelClasses}\"><slot>${labelText}</slot></span>\n </label>\n `;\n }\n\n /**\n * The name of the custom event fired after this radio button changes its checked state.\n */\n static get eventChange() {\n return `${prefix}-radio-button-changed`;\n }\n\n static styles = styles;\n}\n\nexport default BXRadioButton;\n"]}