UNPKG

@conectate/ct-radio

Version:

HTML Radio web component based on Material design

214 lines (209 loc) 5.73 kB
import { __decorate } from "tslib"; import { CtLit, customElement, property, query } from "@conectate/ct-lit"; import { css, html } from "lit"; /** * ## `ct-radio` * radio element * * @group ct-elements * @element ct-radio * @attr {boolean} checked */ let CtRadio = class CtRadio extends CtLit { constructor() { super(...arguments); this.disabled = false; this.checked = false; } static { this.styles = [ css ` :host { display: inline-flex; position: relative; --ct-checkbox-box-size: 24px; --ct-checkbox-box-border-radius: 50%; --ct-checkbox-height: var(--ct-checkbox-box-size); --ct-checkbox-box-border-size: 3px; } #input:focus-visible + .c { box-shadow: 0 0 0 1px var(--color-primary); border-radius: 8px; } :host([disabled]) { pointer-events: none; opacity: 0.33; } .c { display: flex; flex-direction: row; align-items: center; } #input { font-family: inherit; font-size: 100%; line-height: 1.15; margin: 0px; overflow: visible; box-sizing: border-box; padding: 0px; position: absolute; width: 100%; height: 100%; opacity: 0.0001; z-index: 1; cursor: pointer; } `, // Checkmark css ` #checkmark { opacity: 0; transform: scale(0); transition: opacity 0.13s ease-in-out, transform 0.13s ease-in-out; height: 10px; width: 10px; overflow: hidden; background: var(--color-primary, #2cb5e8); border-radius: 50%; } #input:checked + .c > #box #checkmark { transform: scale(1); opacity: 1; } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } #checkmark.rotate { animation: rotate 0.3s none ease-out; animation: rotate 0.3s none cubic-bezier(0.6, 0.49, 0.46, 0.85); } `, // Box css ` #box { display: flex; align-items: center; justify-content: center; position: relative; box-sizing: border-box; width: var(--ct-checkbox-box-size); height: var(--ct-checkbox-box-size); margin: calc((var(--ct-checkbox-height) - var(--ct-checkbox-box-size)) / 2) 0; flex-grow: 0; color: var(--color-on-primary, #fff); flex-shrink: 0; margin: 8px; } #box::before { display: block; z-index: 0; inset: 0; content: ""; box-sizing: border-box; position: absolute; width: var(--ct-checkbox-box-size); height: var(--ct-checkbox-box-size); border-radius: var(--ct-checkbox-box-border-radius); border-width: var(--ct-checkbox-box-border-size); border-style: solid; border-color: var(--color-on-background, #535353); transition: border 0.13s ease-in-out, box-shadow 0.13s ease-in-out; } #input:checked + .c > #box::before { /* border-width: calc(var(--ct-checkbox-box-size) / 2); */ } #input:checked + .c > #box::before { border-color: var(--color-primary, #2cb5e8); color: var(--color-on-primary, #fff); } ` ]; } render() { return html ` <input id="input" type="checkbox" @click=${this.toogleCheck} .checked=${this.checked} .disabled=${this.disabled} @change=${this.handleChange} /> <div class="c"> <span id="box"> <div id="checkmark" dir="ltr"></div> </span> <label id="label" for="input"><slot></slot></label> </div> `; } updated(_changedProperties) { if (_changedProperties.has("checked") && _changedProperties.get("checked") != undefined) { // @ts-ignore this.change(); } } click() { this.$input.click(); } toogleCheck() { this.checked = !this.checked; } isFn(obj) { return !!(obj && obj.constructor && obj.call && obj.apply); } handleChange(event) { const target = event.target; this.checked = target.checked; redispatchEvent(this, event); } change() { let parent = (this.isFn(this.parent) ? this.parent() : false) || this.parent || this.parentElement || this.parentNode; if (this.name && parent?.querySelectorAll) { if (this.checked) { let radios = parent.querySelectorAll("ct-radio"); radios.forEach(radio => { if (radio.name == this.name && radio != this && this.checked) { radio.checked = false; } }); this.dispatchEvent(new CustomEvent("checked", { detail: { checked: this.checked } })); } } else { this.dispatchEvent(new CustomEvent("checked", { detail: { checked: this.checked } })); } } }; __decorate([ property({ type: Boolean, reflect: true }) ], CtRadio.prototype, "disabled", void 0); __decorate([ property({ type: Boolean, reflect: true }) ], CtRadio.prototype, "checked", void 0); __decorate([ property({ type: Object }) ], CtRadio.prototype, "value", void 0); __decorate([ property({ type: Object }) ], CtRadio.prototype, "parent", void 0); __decorate([ property({ type: String }) ], CtRadio.prototype, "name", void 0); __decorate([ query("#input") ], CtRadio.prototype, "$input", void 0); CtRadio = __decorate([ customElement("ct-radio") ], CtRadio); export { CtRadio }; function redispatchEvent(wc, event) { if (event.bubbles && (!wc.shadowRoot || event.composed)) event.stopPropagation(); const copy = Reflect.construct(event.constructor, [event.type, event]); const dispatched = wc.dispatchEvent(copy); if (!dispatched) event.preventDefault(); return dispatched; }