UNPKG

@public-ui/components

Version:

Contains all web components that belong to KoliBri - The accessible HTML-Standard.

745 lines (744 loc) 28.5 kB
/*! * KoliBri - The accessible HTML-Standard */ import { h } from "@stencil/core"; import clsx from "../../utils/clsx"; import { createRelatedUniqueId, createUniqueId } from "../../utils/dev.utils"; import { delegateClick, setClick } from "../../utils/element-click"; import { delegateFocus, setFocus } from "../../utils/element-focus"; import { propagateSubmitEventToForm } from "../form/controller"; import { InputRadioController } from "./controller"; import KolFieldControlStateWrapperFc from "../../functional-component-wrappers/FieldControlStateWrapper/FieldControlStateWrapper"; import KolFormFieldStateWrapperFc from "../../functional-component-wrappers/FormFieldStateWrapper/FormFieldStateWrapper"; import KolRadioStateWrapperFc from "../../functional-component-wrappers/RadioStateWrapper/RadioStateWrapper"; export class KolInputRadio { async getValue() { return this._value; } async focus() { return delegateFocus(this.host, () => setFocus(this.getFocusableInput())); } async click() { return delegateClick(this.host, async () => setClick(this.inputRef)); } getFocusableInput() { const options = this.state._options; const isComponentDisabled = Boolean(this.state._disabled); const selectedIndex = options.findIndex((option) => option.value === this.state._value && !isComponentDisabled && !option.disabled); if (selectedIndex !== -1) { const input = this.inputRefs.get(selectedIndex); if (input) { return input; } } const firstEnabledIndex = options.findIndex((option) => !isComponentDisabled && !option.disabled); if (firstEnabledIndex !== -1) { return this.inputRefs.get(firstEnabledIndex); } return undefined; } getFormFieldProps() { return { state: this.state, component: 'fieldset', disabled: Boolean(this.state._disabled), class: clsx('kol-form-field--radio'), formFieldLabelProps: { component: 'legend', class: 'kol-form-field__label--legend', }, formFieldInputProps: { class: `kol-form-field__input--orientation-${this.state._orientation}`, }, tooltipAlign: this._tooltipAlign, alert: this.showAsAlert(), hideLabel: false, }; } render() { return (h(KolFormFieldStateWrapperFc, Object.assign({ key: 'a91aec572141cc4d7aa0f6024a2acf5091b89e28' }, this.getFormFieldProps()), this.state._options.map((option, index) => this.renderOption(option, index)))); } calculateDisabled(option) { return Boolean(this.state._disabled) || Boolean(option.disabled); } getOptionProps(option, id) { return { state: this.state, id: id, hint: option.hint, label: option.label, required: false, fieldControlLabelProps: { showBadge: false, }, disabled: this.calculateDisabled(option), }; } getInputProps(option, id, index, selected) { return { state: this.state, inputProps: Object.assign(Object.assign({ id: id, ref: (ref) => { this.setInputRefByIndex(index)(ref); if (selected) { this.setInputRef(ref); } }, 'aria-label': this.state._hideLabel && typeof option.label === 'string' ? option.label : undefined, type: 'radio', name: this.state._name || this.state._id, value: `-${index}`, checked: selected, disabled: this.calculateDisabled(option) }, this.controller.onFacade), { onChange: this.onChange, onClick: undefined, onInput: this.onInput, onKeyDown: this.onKeyDown.bind(this), onFocus: (event) => { this.controller.onFacade.onFocus(event); this.inputHasFocus = true; }, onBlur: (event) => { this.controller.onFacade.onBlur(event); this.inputHasFocus = false; } }), }; } renderOption(option, index) { const customId = createRelatedUniqueId(this.state._id, String(index)); const selected = this.state._value === option.value; return (h(KolFieldControlStateWrapperFc, Object.assign({ key: customId }, this.getOptionProps(option, customId)), h(KolRadioStateWrapperFc, Object.assign({}, this.getInputProps(option, customId, index, selected))))); } constructor() { this.inputRefs = new Map(); this.setInputRef = (ref) => { this.inputRef = ref; }; this.setInputRefByIndex = (index) => (ref) => { if (ref) { this.inputRefs.set(index, ref); } else { this.inputRefs.delete(index); } }; this._disabled = false; this._hideMsg = false; this._hideLabel = false; this._hint = ''; this._orientation = 'vertical'; this._required = false; this._tooltipAlign = 'top'; this._touched = false; this._value = null; this.state = { _hideMsg: false, _id: createUniqueId('input-radio'), _label: '', _options: [], _orientation: 'vertical', }; this.inputHasFocus = false; this.onInput = (event) => { if (event.target instanceof HTMLInputElement) { const option = this.controller.getOptionByKey(event.target.value); if (option !== undefined) { this.controller.onFacade.onInput(event, true, option.value); } } }; this.onChange = (event) => { if (event.target instanceof HTMLInputElement) { const option = this.controller.getOptionByKey(event.target.value); if (option !== undefined) { this.controller.onFacade.onChange(event, option.value); this._value = option.value; } } }; this.onKeyDown = (event) => { this.controller.onFacade.onKeyDown(event); if (event.code === 'Enter' || event.code === 'NumpadEnter') { propagateSubmitEventToForm({ form: this.host, ref: this.inputRef, }); } }; this.controller = new InputRadioController(this, 'radio', this.host); } showAsAlert() { return Boolean(this.state._touched) && !this.inputHasFocus; } validateTooltipAlign(value) { this.controller.validateTooltipAlign(value); } validateDisabled(value) { this.controller.validateDisabled(value); } validateHideLabel(value) { this.controller.validateHideLabel(value); } validateHideMsg(value) { this.controller.validateHideMsg(value); } validateHint(value) { this.controller.validateHint(value); } validateLabel(value) { this.controller.validateLabel(value); } validateMsg(value) { this.controller.validateMsg(value); } validateName(value) { this.controller.validateName(value); } validateOn(value) { this.controller.validateOn(value); } validateOptions(value) { this.controller.validateOptions(value); } validateOrientation(value) { this.controller.validateOrientation(value); } validateRequired(value) { this.controller.validateRequired(value); } validateSyncValueBySelector(value) { this.controller.validateSyncValueBySelector(value); } validateTouched(value) { this.controller.validateTouched(value); } validateValue(value) { this.controller.validateValue(value); } validateVariant(value) { this.controller.validateVariant(value); } componentWillLoad() { this._touched = this._touched === true; this.controller.componentWillLoad(); } static get is() { return "kol-input-radio"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "default": ["./style.scss"] }; } static get styleUrls() { return { "default": ["style.css"] }; } static get properties() { return { "_disabled": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "TODO", "text": ": Change type back to `DisabledPropType` after Stencil#4663 has been resolved." }], "text": "Makes the element not focusable and ignore all events." }, "getter": false, "setter": false, "reflect": false, "attribute": "_disabled", "defaultValue": "false" }, "_hideMsg": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "TODO", "text": ": Change type back to `HideMsgPropType` after Stencil#4663 has been resolved." }], "text": "Hides the error message but leaves it in the DOM for the input's aria-describedby." }, "getter": false, "setter": false, "reflect": false, "attribute": "_hide-msg", "defaultValue": "false" }, "_hideLabel": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "TODO", "text": ": Change type back to `HideLabelPropType` after Stencil#4663 has been resolved." }], "text": "Hides the caption by default and displays the caption text with a tooltip when the\ninteractive element is focused or the mouse is over it." }, "getter": false, "setter": false, "reflect": false, "attribute": "_hide-label", "defaultValue": "false" }, "_hint": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Defines the hint text." }, "getter": false, "setter": false, "reflect": false, "attribute": "_hint", "defaultValue": "''" }, "_label": { "type": "string", "mutable": false, "complexType": { "original": "LabelWithExpertSlotPropType", "resolved": "string", "references": { "LabelWithExpertSlotPropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::LabelWithExpertSlotPropType" } } }, "required": true, "optional": false, "docs": { "tags": [], "text": "Defines the visible or semantic label of the component (e.g. aria-label, label, headline, caption, summary, etc.). Set to `false` to enable the expert slot." }, "getter": false, "setter": false, "reflect": false, "attribute": "_label" }, "_msg": { "type": "string", "mutable": false, "complexType": { "original": "Stringified<MsgPropType>", "resolved": "Omit<AlertProps, \"_on\" | \"_label\" | \"_level\" | \"_variant\" | \"_hasCloser\"> & { _description: string; } | string | undefined", "references": { "Stringified": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::Stringified" }, "MsgPropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::MsgPropType" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Defines the properties for a message rendered as Alert component." }, "getter": false, "setter": false, "reflect": false, "attribute": "_msg" }, "_name": { "type": "string", "mutable": false, "complexType": { "original": "NamePropType", "resolved": "string | undefined", "references": { "NamePropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::NamePropType" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Defines the technical name of an input field." }, "getter": false, "setter": false, "reflect": false, "attribute": "_name" }, "_on": { "type": "unknown", "mutable": false, "complexType": { "original": "InputTypeOnDefault", "resolved": "InputTypeOnBlur & InputTypeOnClick & InputTypeOnChange & InputTypeOnFocus & InputTypeOnInput & InputTypeOnKeyDown | undefined", "references": { "InputTypeOnDefault": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::InputTypeOnDefault" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Gibt die EventCallback-Funktionen f\u00FCr das Input-Event an." }, "getter": false, "setter": false }, "_options": { "type": "string", "mutable": false, "complexType": { "original": "RadioOptionsPropType", "resolved": "RadioOption<StencilUnknown>[] | string | undefined", "references": { "RadioOptionsPropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::RadioOptionsPropType" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Options the user can choose from." }, "getter": false, "setter": false, "reflect": false, "attribute": "_options" }, "_orientation": { "type": "string", "mutable": false, "complexType": { "original": "OrientationPropType", "resolved": "\"horizontal\" | \"vertical\" | undefined", "references": { "OrientationPropType": { "location": "import", "path": "../../schema/props/orientation", "id": "src/schema/props/orientation.ts::OrientationPropType" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Defines whether the orientation of the component is horizontal or vertical." }, "getter": false, "setter": false, "reflect": false, "attribute": "_orientation", "defaultValue": "'vertical'" }, "_required": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "TODO", "text": ": Change type back to `RequiredPropType` after Stencil#4663 has been resolved." }], "text": "Makes the input element required." }, "getter": false, "setter": false, "reflect": false, "attribute": "_required", "defaultValue": "false" }, "_syncValueBySelector": { "type": "string", "mutable": false, "complexType": { "original": "SyncValueBySelectorPropType", "resolved": "string | undefined", "references": { "SyncValueBySelectorPropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::SyncValueBySelectorPropType" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "internal", "text": undefined }], "text": "Selector for synchronizing the value with another input element." }, "getter": false, "setter": false, "reflect": false, "attribute": "_sync-value-by-selector" }, "_tooltipAlign": { "type": "string", "mutable": false, "complexType": { "original": "TooltipAlignPropType", "resolved": "\"bottom\" | \"left\" | \"right\" | \"top\" | undefined", "references": { "TooltipAlignPropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::TooltipAlignPropType" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Defines where to show the Tooltip preferably: top, right, bottom or left." }, "getter": false, "setter": false, "reflect": false, "attribute": "_tooltip-align", "defaultValue": "'top'" }, "_touched": { "type": "boolean", "mutable": true, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "TODO", "text": ": Change type back to `TouchedPropType` after Stencil#4663 has been resolved." }], "text": "Shows if the input was touched by a user." }, "getter": false, "setter": false, "reflect": true, "attribute": "_touched", "defaultValue": "false" }, "_value": { "type": "any", "mutable": true, "complexType": { "original": "StencilUnknown", "resolved": "boolean | null | number | object | string | undefined", "references": { "StencilUnknown": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::StencilUnknown" } } }, "required": false, "optional": false, "docs": { "tags": [{ "name": "see", "text": "Known bug: https://github.com/ionic-team/stencil/issues/3902" }], "text": "Defines the value of the element." }, "getter": false, "setter": false, "reflect": true, "attribute": "_value", "defaultValue": "null" }, "_variant": { "type": "string", "mutable": false, "complexType": { "original": "VariantClassNamePropType", "resolved": "string | undefined", "references": { "VariantClassNamePropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::VariantClassNamePropType" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Defines which variant should be used for presentation." }, "getter": false, "setter": false, "reflect": false, "attribute": "_variant" } }; } static get states() { return { "state": {}, "inputHasFocus": {} }; } static get methods() { return { "getValue": { "complexType": { "signature": "() => Promise<StencilUnknown>", "parameters": [], "references": { "Promise": { "location": "global", "id": "global::Promise" }, "StencilUnknown": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::StencilUnknown" } }, "return": "Promise<StencilUnknown>" }, "docs": { "text": "Returns the current value.", "tags": [] } }, "focus": { "complexType": { "signature": "() => Promise<void>", "parameters": [], "references": { "Promise": { "location": "global", "id": "global::Promise" } }, "return": "Promise<void>" }, "docs": { "text": "Sets focus on the internal element.", "tags": [] } }, "click": { "complexType": { "signature": "() => Promise<void>", "parameters": [], "references": { "Promise": { "location": "global", "id": "global::Promise" } }, "return": "Promise<void>" }, "docs": { "text": "Clicks the primary interactive element inside this component.", "tags": [] } } }; } static get elementRef() { return "host"; } static get watchers() { return [{ "propName": "_tooltipAlign", "methodName": "validateTooltipAlign" }, { "propName": "_disabled", "methodName": "validateDisabled" }, { "propName": "_hideLabel", "methodName": "validateHideLabel" }, { "propName": "_hideMsg", "methodName": "validateHideMsg" }, { "propName": "_hint", "methodName": "validateHint" }, { "propName": "_label", "methodName": "validateLabel" }, { "propName": "_msg", "methodName": "validateMsg" }, { "propName": "_name", "methodName": "validateName" }, { "propName": "_on", "methodName": "validateOn" }, { "propName": "_options", "methodName": "validateOptions" }, { "propName": "_orientation", "methodName": "validateOrientation" }, { "propName": "_required", "methodName": "validateRequired" }, { "propName": "_syncValueBySelector", "methodName": "validateSyncValueBySelector" }, { "propName": "_touched", "methodName": "validateTouched" }, { "propName": "_value", "methodName": "validateValue" }, { "propName": "_variant", "methodName": "validateVariant" }]; } } //# sourceMappingURL=shadow.js.map