@limetech/lime-elements
Version:
336 lines (335 loc) • 10.2 kB
JavaScript
import { h, } from '@stencil/core';
import { createRandomString } from '../../util/random-string';
import { CheckboxTemplate } from './checkbox.template';
/**
* The Checkbox component is a classic and essential element in UI design that allows
* users to make multiple selections from a predefined list of options. The Checkbox component is commonly used in forms and settings interfaces to enable users to
* select one or more items from a list of choices.
*
* ## States of a Checkbox
* When a user clicks or taps on the box, it toggles between two states:
* Checked and Unchecked.
*
* However, a Checkbox can visualize a third state called the "Indeterminate" state.
* In this state, the checkbox appears as a filled box with a horizontal line or dash inside it.
*
* The Indeterminate state is typically used when dealing with checkbox groups
* that have hierarchical relationships or when the group contains sub-items.
* This state is used to indicate that that some, but not all, of the items in a group are selected.
*
* :::important
* Checkboxes are sometimes used interchangeably with switches in user interfaces.
* But there is an important difference between the two! Please read our guidelines about
* [Switch vs. Checkbox](/#/DesignGuidelines/switch-vs-checkbox.md/).
*
* @exampleComponent limel-example-checkbox
* @exampleComponent limel-example-checkbox-helper-text
* @exampleComponent limel-example-checkbox-readonly
*/
export class Checkbox {
constructor() {
this.shouldReinitialize = false;
this.id = createRandomString();
this.helperTextId = createRandomString();
this.destroyMDCInstances = () => {
const input = this.getCheckboxElement();
if (input) {
delete input.dataset['indeterminate'];
input.indeterminate = false;
}
};
this.isInvalid = () => {
if (this.invalid) {
return true;
}
if (this.required && this.modified && !this.checked) {
return true;
}
};
this.initialize = () => {
const input = this.getCheckboxElement();
if (!input) {
return;
}
input.indeterminate = this.indeterminate;
input.checked = this.checked || this.indeterminate;
};
this.getCheckboxElement = () => {
var _a, _b;
return (((_b = (_a = this.limelCheckbox) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('input[type="checkbox"]')) || null);
};
this.onChange = (event) => {
var _a;
event.stopPropagation();
const input = event.currentTarget;
const isChecked = (_a = input === null || input === void 0 ? void 0 : input.checked) !== null && _a !== void 0 ? _a : this.checked;
this.change.emit(isChecked);
this.modified = true;
};
this.disabled = false;
this.readonly = false;
this.invalid = undefined;
this.label = undefined;
this.helperText = undefined;
this.checked = false;
this.indeterminate = false;
this.required = false;
this.readonlyLabels = [];
this.modified = false;
}
handleCheckedChange(newValue) {
const input = this.getCheckboxElement();
if (!input) {
return;
}
input.checked = newValue || this.indeterminate;
}
handleIndeterminateChange(newValue) {
const input = this.getCheckboxElement();
if (!input) {
return;
}
input.checked = this.checked || newValue;
input.indeterminate = newValue;
}
handleReadonlyChange() {
this.destroyMDCInstances();
this.shouldReinitialize = true;
}
componentDidRender() {
if (this.shouldReinitialize) {
this.initialize();
this.shouldReinitialize = false;
}
}
connectedCallback() {
this.initialize();
}
componentDidLoad() {
this.initialize();
}
disconnectedCallback() {
this.destroyMDCInstances();
}
render() {
return (h(CheckboxTemplate, { disabled: this.disabled || this.readonly, label: this.label, readonlyLabels: this.readonlyLabels, helperText: this.helperText, helperTextId: this.helperTextId, checked: this.checked || this.indeterminate, indeterminate: this.indeterminate, required: this.required, readonly: this.readonly, invalid: this.isInvalid(), onChange: this.onChange, id: this.id }));
}
static get is() { return "limel-checkbox"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"$": ["checkbox.scss"]
};
}
static get styleUrls() {
return {
"$": ["checkbox.css"]
};
}
static get properties() {
return {
"disabled": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Disables the checkbox when `true`. Works exactly the same as `readonly`.\nIf either property is `true`, the checkbox will be disabled."
},
"attribute": "disabled",
"reflect": true,
"defaultValue": "false"
},
"readonly": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Disables the checkbox when `true`. This visualizes the checkbox slightly differently.\nBut shows no visual sign indicating that the checkbox is disabled\nor can ever become interactable."
},
"attribute": "readonly",
"reflect": true,
"defaultValue": "false"
},
"invalid": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Set to `true` to indicate that the current value is invalid."
},
"attribute": "invalid",
"reflect": true
},
"label": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "The checkbox label."
},
"attribute": "label",
"reflect": true
},
"helperText": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Optional helper text to display below the checkbox"
},
"attribute": "helper-text",
"reflect": true
},
"checked": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "The value of the checkbox. Set to `true` to make the checkbox checked."
},
"attribute": "checked",
"reflect": true,
"defaultValue": "false"
},
"indeterminate": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Enables indeterminate state. Set to `true` to signal indeterminate check."
},
"attribute": "indeterminate",
"reflect": true,
"defaultValue": "false"
},
"required": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Set to `true` to indicate that the checkbox must be checked."
},
"attribute": "required",
"reflect": true,
"defaultValue": "false"
},
"readonlyLabels": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "Array<Label<boolean>>",
"resolved": "Label<boolean>[]",
"references": {
"Array": {
"location": "global"
},
"Label": {
"location": "import",
"path": "../dynamic-label/label.types"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "The labels to use to clarify what kind of data is being visualized,\nwhen the component is `readonly`."
},
"defaultValue": "[]"
}
};
}
static get states() {
return {
"modified": {}
};
}
static get events() {
return [{
"method": "change",
"name": "change",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted when the input value is changed."
},
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
}
}];
}
static get elementRef() { return "limelCheckbox"; }
static get watchers() {
return [{
"propName": "checked",
"methodName": "handleCheckedChange"
}, {
"propName": "indeterminate",
"methodName": "handleIndeterminateChange"
}, {
"propName": "readonly",
"methodName": "handleReadonlyChange"
}];
}
}
//# sourceMappingURL=checkbox.js.map