UNPKG

sober

Version:

Sober is a library of UI components designed with reference to Material You.

115 lines (114 loc) 3.36 kB
import { useElement, useProps } from './core/element.js'; import './ripple.js'; const name = 's-checkbox'; const props = useProps({ disabled: false, checked: false, indeterminate: false }); const style = /*css*/ ` :host{ display: inline-flex; align-items: center; vertical-align: middle; cursor: pointer; position: relative; height: 40px; color: var(--s-color-on-surface-variant, ${"#40484C" /* Theme.colorOnSurfaceVariant */}); } :host([checked=true]){ color: var(--s-color-primary, ${"#006782" /* Theme.colorPrimary */}); } :host([disabled=true]){ pointer-events: none; } .container{ position: relative; height: 100%; aspect-ratio: 1; -webkit-aspect-ratio: 1; border-radius: 50%; overflow: hidden; flex-shrink: 0; } :host([disabled=true]) .container{ color: var(--s-color-on-surface, ${"#191C1E" /* Theme.colorOnSurface */}) !important; opacity: .38 !important; } .unchecked, .checked, .indeterminate{ display: flex; align-items: center; justify-content: center; position: absolute; inset: 0; width: 100%; height: 100%; } .checked, .indeterminate{ position: absolute; transform: scale(.5); opacity: 0; transition-property: transform, opacity; transition-timing-function: var(--s-motion-easing-emphasized, ${"cubic-bezier(0.2, 0, 0, 1.0)" /* Theme.motionEasingEmphasized */}); transition-duration: var(--s-motion-duration-short4, ${"200ms" /* Theme.motionDurationShort4 */}); } :host([indeterminate=true]) .unchecked{ opacity: 0; } :host([checked=true]:not([indeterminate=true])) .checked, :host([indeterminate=true]) .indeterminate{ opacity: 1; transform: scale(1); } .ripple{ aspect-ratio: 1; -webkit-aspect-ratio: 1; height: 100%; width: auto; border-radius: 50%; } svg, ::slotted(:is([slot=checked], [slot=unchecked], [slot=indeterminate])){ color: currentColor; fill: currentColor; width: 60%; height: 60%; } `; const template = /*html*/ ` <div class="container" part="container"> <slot class="unchecked" name="unchecked"> <svg viewBox="0 -960 960 960"> <path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Z"></path> </svg> </slot> <slot class="checked" name="checked"> <svg viewBox="0 -960 960 960"> <path d="m424-312 282-282-56-56-226 226-114-114-56 56 170 170ZM200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Z"></path> </svg> </slot> <slot class="indeterminate" name="indeterminate"> <svg viewBox="0 -960 960 960"> <path d="M280-440h400v-80H280v80Zm-80 320q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Z"></path> </svg> </slot> </div> <slot></slot> <s-ripple class="ripple" attached="true" part="ripple"></s-ripple> `; export class Checkbox extends useElement({ style, template, props, setup() { this.addEventListener('click', () => { if (this.indeterminate) this.indeterminate = false; this.checked = !this.checked; this.dispatchEvent(new Event('change')); }); } }) { } Checkbox.define(name);