UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

210 lines (209 loc) • 14.6 kB
/*! All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://github.com/Esri/calcite-design-system/blob/dev/LICENSE.md for details. v3.2.1 */ import { c as customElement } from "../../chunks/runtime.js"; import { html } from "lit"; import { LitElement, createEvent, safeClassMap } from "@arcgis/lumina"; import { g as guid } from "../../chunks/guid.js"; import { u as updateHostInteraction, I as InteractiveContainer } from "../../chunks/interactive.js"; import { c as componentFocusable } from "../../chunks/component.js"; import { l as logger } from "../../chunks/logger.js"; import { css } from "@lit/reactive-element/css-tag.js"; const CSS = { description: "description", descriptionOnly: "description-only", heading: "heading", headingOnly: "heading-only", icon: "icon", iconOnly: "icon-only", inputAlignmentEnd: "input-alignment-end", inputAlignmentStart: "input-alignment-start", inputEnabled: "input-enabled", largeVisual: "large-visual", tile: "tile", tileContentContainer: "tile-content-container", tileContent: "tile-content", tileDescription: "tile-description", tileHeading: "tile-heading", tileLargeVisual: "tile--large-visual", widthAuto: "width-auto", widthFull: "width-full" }; const styles = css`:host([disabled]){cursor:default;-webkit-user-select:none;user-select:none;opacity:var(--calcite-opacity-disabled)}:host([disabled]) *,:host([disabled]) ::slotted(*){pointer-events:none}:host{display:block}:host .container{background-color:var(--calcite-color-foreground-1);box-shadow:0 0 0 1px var(--calcite-color-border-2);box-sizing:border-box;cursor:pointer;display:inline-block;block-size:100%;max-inline-size:300px;padding:.75rem;position:relative;vertical-align:top;transition-property:background-color,block-size,border-color,box-shadow,color,inset-block-end,inset-block-start,inset-inline-end,inset-inline-start,inset-size,opacity,outline-color,transform;transition-duration:var(--calcite-animation-timing);transition-timing-function:ease-in-out}:host .container.checked{z-index:var(--calcite-z-index);box-shadow:0 0 0 1px var(--calcite-color-brand)}:host .container.heading-only{align-items:center}:host .container:not(.input-enabled) ::slotted(calcite-checkbox),:host .container:not(.input-enabled) ::slotted(calcite-radio-button){position:absolute;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}:host .container.focused{outline-color:transparent}:host .container.focused:not(.disabled):not(.input-enabled){outline:2px solid var(--calcite-color-focus, var(--calcite-ui-focus-color, var(--calcite-color-brand)));outline-offset:calc(-2px*(1 - (2*clamp(0,var(--calcite-offset-invert-focus),1))));outline-offset:-4px;box-shadow:0 0 0 1px var(--calcite-color-brand),inset 0 0 0 2px var(--calcite-color-foreground-1)}:host .container.input-enabled.input-alignment-start.width-auto.heading-only,:host .container.input-enabled.input-alignment-start.width-auto.icon-only,:host .container.input-enabled.input-alignment-start.width-auto.description-only,:host .container.input-enabled.input-alignment-start.width-auto.heading.description,:host .container.input-enabled.input-alignment-start.width-auto.icon.description,:host .container.input-enabled.input-alignment-start.width-auto.heading.icon.description{display:inline-grid;grid-template-columns:max-content 1fr}:host .container.input-enabled.input-alignment-start.heading-only,:host .container.input-enabled.input-alignment-start.icon-only,:host .container.input-enabled.input-alignment-start.description-only,:host .container.input-enabled.input-alignment-start.heading.description,:host .container.input-enabled.input-alignment-start.icon.description,:host .container.input-enabled.input-alignment-start.heading.icon.description{gap:.75rem}:host .container.input-enabled.input-alignment-start .tile{order:1}:host .container.input-enabled.input-alignment-start.large-visual ::slotted(calcite-checkbox),:host .container.input-enabled.input-alignment-start.large-visual ::slotted(calcite-radio-button){position:absolute;inset-block-start:.75rem;inset-inline-start:.75rem}:host .container.input-enabled.input-alignment-end.width-auto.heading-only,:host .container.input-enabled.input-alignment-end.width-auto.icon-only{display:inline-grid;grid-gap:.75rem;grid-template-columns:max-content 1fr}:host .container.input-enabled.input-alignment-end.heading-only,:host .container.input-enabled.input-alignment-end.icon-only{gap:.75rem}:host .container.input-enabled.input-alignment-end.description-only ::slotted(calcite-checkbox),:host .container.input-enabled.input-alignment-end.description-only ::slotted(calcite-radio-button),:host .container.input-enabled.input-alignment-end.heading.description ::slotted(calcite-checkbox),:host .container.input-enabled.input-alignment-end.heading.description ::slotted(calcite-radio-button),:host .container.input-enabled.input-alignment-end.icon.description ::slotted(calcite-checkbox),:host .container.input-enabled.input-alignment-end.icon.description ::slotted(calcite-radio-button),:host .container.input-enabled.input-alignment-end.heading.icon.description ::slotted(calcite-checkbox),:host .container.input-enabled.input-alignment-end.heading.icon.description ::slotted(calcite-radio-button){position:absolute;inset-block-start:.75rem;inset-inline-end:.75rem}:host .container.input-enabled.input-alignment-end.large-visual ::slotted(calcite-checkbox),:host .container.input-enabled.input-alignment-end.large-visual ::slotted(calcite-radio-button){position:absolute;inset-block-start:.75rem;inset-inline-end:.75rem}:host .container.width-full{display:flex;max-inline-size:none}:host .container.width-full .tile{flex:1 1 auto}.tile{pointer-events:none;box-sizing:border-box;display:flex;-webkit-user-select:none;user-select:none;flex-direction:column;gap:.5rem;background-color:var(--calcite-color-foreground-1);color:var(--calcite-color-text-3);transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.tile-content-container{display:flex;inline-size:100%;align-items:stretch;padding:0;color:var(--calcite-color-text-2);outline-color:transparent}.tile-content{display:flex;flex:1 1 auto;flex-direction:column;gap:.5rem;inline-size:10%}.tile-heading{pointer-events:none;overflow-wrap:break-word;font-size:var(--calcite-font-size--1);line-height:1.375;font-weight:var(--calcite-font-weight-medium);color:var(--calcite-color-text-2);transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.tile-description{pointer-events:none;overflow-wrap:break-word;font-size:var(--calcite-font-size--2);line-height:1.375;color:var(--calcite-color-text-3);transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.tile--large-visual{display:grid;justify-content:center;text-align:center;min-block-size:12rem}.tile--large-visual .icon{align-self:flex-end}.tile--large-visual calcite-icon{block-size:64px;inline-size:64px}.tile--large-visual .tile-content-container{align-self:center}:host(:hover) .container:not(.input-enabled){box-shadow:0 0 0 1px var(--calcite-color-brand)}:host(:hover) .tile-heading,.checked .tile-heading{color:var(--calcite-color-text-1)}:host(:hover) .tile-description,.checked .tile-description{color:var(--calcite-color-text-2)}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}.interaction-container{display:contents}:host([hidden]){display:none}[hidden]{display:none}`; class TileSelect extends LitElement { constructor() { super(); this.guid = `calcite-tile-select-${guid()}`; this.focused = false; this.checked = false; this.disabled = false; this.iconFlipRtl = false; this.inputAlignment = "start"; this.inputEnabled = false; this.type = "radio"; this.width = "auto"; this.calciteTileSelectChange = createEvent({ cancelable: false }); this.listen("calciteCheckboxChange", this.checkboxChangeHandler); this.listen("calciteInternalCheckboxFocus", this.checkboxFocusBlurHandler); this.listen("calciteInternalCheckboxBlur", this.checkboxFocusBlurHandler); this.listen("calciteRadioButtonChange", this.radioButtonChangeHandler); this.listen("calciteInternalRadioButtonCheckedChange", this.radioButtonCheckedChangeHandler); this.listen("calciteInternalRadioButtonFocus", this.radioButtonFocusBlurHandler); this.listen("calciteInternalRadioButtonBlur", this.radioButtonFocusBlurHandler); this.listen("click", this.clickHandler); this.listen("pointerenter", this.pointerEnterHandler); this.listen("pointerleave", this.pointerLeaveHandler); } static { this.properties = { focused: [16, {}, { state: true }], checked: [7, {}, { reflect: true, type: Boolean }], description: [3, {}, { reflect: true }], disabled: [7, {}, { reflect: true, type: Boolean }], heading: [3, {}, { reflect: true }], icon: [3, {}, { reflect: true }], iconFlipRtl: [7, {}, { reflect: true, type: Boolean }], inputAlignment: [3, {}, { reflect: true }], inputEnabled: [7, {}, { reflect: true, type: Boolean }], name: [3, {}, { reflect: true }], type: [3, {}, { reflect: true }], value: 1, width: [3, {}, { reflect: true }] }; } static { this.styles = styles; } async setFocus() { await componentFocusable(this); return this.input?.setFocus(); } connectedCallback() { super.connectedCallback(); this.renderInput(); } load() { logger.deprecated("component", { name: "tile-select", removalVersion: 4, suggested: ["tile", "tile-group"] }); } willUpdate(changes) { if (changes.has("checked") && (this.hasUpdated || this.checked !== false)) { this.input.checked = this.checked; } if (changes.has("name")) { this.input.name = this.name; } } updated() { updateHostInteraction(this); } disconnectedCallback() { super.disconnectedCallback(); this.input?.remove(); } checkboxChangeHandler(event) { const checkbox = event.target; if (checkbox === this.input) { this.checked = checkbox.checked; } event.stopPropagation(); this.calciteTileSelectChange.emit(); } checkboxFocusBlurHandler(event) { const checkbox = event.target; if (checkbox === this.input) { this.focused = event.detail; } event.stopPropagation(); } radioButtonChangeHandler(event) { const radioButton = event.target; if (radioButton === this.input) { this.checked = radioButton.checked; } event.stopPropagation(); this.calciteTileSelectChange.emit(); } radioButtonCheckedChangeHandler(event) { const radioButton = event.target; if (radioButton === this.input) { this.checked = radioButton.checked; } event.stopPropagation(); } radioButtonFocusBlurHandler(event) { const radioButton = event.target; if (radioButton === this.input) { this.focused = radioButton.focused; } event.stopPropagation(); } clickHandler(event) { if (this.disabled) { return; } const target = event.target; const targets = ["calcite-tile", "calcite-tile-select"]; if (targets.includes(target.localName)) { this.input.click(); } } pointerEnterHandler() { if (this.disabled) { return; } const { localName } = this.input; if (localName === "calcite-radio-button" || localName === "calcite-checkbox") { this.input.hovered = true; } } pointerLeaveHandler() { if (this.disabled) { return; } const { localName } = this.input; if (localName === "calcite-radio-button" || localName === "calcite-checkbox") { this.input.hovered = false; } } renderInput() { this.input = this.type === "radio" ? ( /* we need to call createElement(x) separately to ensure supporting components are properly bundled */ document.createElement( // TODO: [MIGRATION] If this is dynamically creating a web component, please read the docs: https://qawebgis.esri.com/arcgis-components/?path=/docs/lumina-jsx--docs#rendering-jsx-outside-the-component "calcite-radio-button" ) ) : document.createElement( // TODO: [MIGRATION] If this is dynamically creating a web component, please read the docs: https://qawebgis.esri.com/arcgis-components/?path=/docs/lumina-jsx--docs#rendering-jsx-outside-the-component "calcite-checkbox" ); this.input.checked = this.checked; this.input.disabled = this.disabled; this.input.hidden = this.el.hidden; this.input.id = this.guid; this.input.label = this.heading || this.name || ""; if (this.name) { this.input.name = this.name; } if (this.value) { this.input.value = this.value != null ? this.value.toString() : ""; } this.el.insertAdjacentElement("beforeend", this.input); } render() { const { checked, description, disabled, focused, heading, icon, inputAlignment, inputEnabled, width, iconFlipRtl } = this; const isLargeVisual = heading && icon && !description; const renderIcon = Boolean(icon); return InteractiveContainer({ disabled, children: html`<div class=${safeClassMap({ checked, container: true, [CSS.description]: Boolean(description), [CSS.descriptionOnly]: Boolean(!heading && !icon && description), disabled, focused, [CSS.heading]: Boolean(heading), [CSS.headingOnly]: heading && !icon && !description, [CSS.icon]: renderIcon, [CSS.iconOnly]: !heading && icon && !description, [CSS.inputAlignmentEnd]: inputAlignment === "end", [CSS.inputAlignmentStart]: inputAlignment === "start", [CSS.inputEnabled]: inputEnabled, [CSS.largeVisual]: isLargeVisual, [CSS.widthAuto]: width === "auto", [CSS.widthFull]: width === "full" })}><div class=${safeClassMap({ [CSS.tile]: true, [CSS.tileLargeVisual]: isLargeVisual })}>${icon && html`<div class=${safeClassMap({ [CSS.icon]: renderIcon })}><calcite-icon .flipRtl=${iconFlipRtl} .icon=${icon} scale=l></calcite-icon></div>` || ""}<div class=${safeClassMap(CSS.tileContentContainer)}><div class=${safeClassMap(CSS.tileContent)}>${heading && html`<div class=${safeClassMap(CSS.tileHeading)}>${heading}</div>` || ""}${description && html`<div class=${safeClassMap(CSS.tileDescription)}>${description}</div>` || ""}</div></div></div><slot></slot></div>` }); } } customElement("calcite-tile-select", TileSelect); export { TileSelect };