@public-ui/components
Version:
Contains all web components that belong to KoliBri - The accessible HTML-Standard.
745 lines (744 loc) • 28.5 kB
JavaScript
/*!
* 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