UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

220 lines (212 loc) • 18.6 kB
import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-aa8afca4.js'; import { b as getSlotted, g as getElementDir, C as CSS_UTILITY } from './dom-466af3c7.js'; import { C as CalciteHeading } from './CalciteHeading-63c82bed.js'; import './guid-09142681.js'; const CSS$1 = { article: "article", content: "content", headerContainer: "header-container", icon: "icon", statusIcon: "status-icon", toggle: "toggle", toggleIcon: "toggle-icon", title: "title", heading: "heading", header: "header", button: "button", summary: "summary", controlContainer: "control-container", valid: "valid", invalid: "invalid" }; const TEXT$1 = { collapse: "Collapse", expand: "Expand", loading: "Loading" }; const SLOTS = { icon: "icon", control: "control" }; const ICONS$1 = { opened: "chevron-up", closed: "chevron-down", valid: "check-circle", invalid: "exclamation-mark-triangle" }; const HEADING_LEVEL = 4; const calciteBlockCss = "@-webkit-keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}@keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}:host{-webkit-box-sizing:border-box;box-sizing:border-box;background-color:var(--calcite-ui-foreground-1);color:var(--calcite-ui-text-2);font-size:var(--calcite-font-size--1)}:host *{-webkit-box-sizing:border-box;box-sizing:border-box}:host{--calcite-icon-size:1rem;--calcite-spacing-eighth:0.125rem;--calcite-spacing-quarter:0.25rem;--calcite-spacing-half:0.5rem;--calcite-spacing-three-quarters:0.75rem;--calcite-spacing:1rem;--calcite-spacing-plus-quarter:1.25rem;--calcite-spacing-plus-half:1.5rem;--calcite-spacing-double:2rem;--calcite-menu-min-width:10rem;--calcite-header-min-height:3rem;--calcite-footer-min-height:3rem}:root{--calcite-popper-transition:150ms ease-in-out}:host([hidden]){display:none}:host{display:-ms-flexbox;display:flex;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;-ms-flex-direction:column;flex-direction:column;padding:0;-webkit-transition-property:margin;transition-property:margin;-webkit-transition-duration:150ms;transition-duration:150ms;-webkit-transition-timing-function:cubic-bezier(0.215, 0.440, 0.420, 0.880);transition-timing-function:cubic-bezier(0.215, 0.440, 0.420, 0.880);border-width:0;border-bottom-width:1px;border-color:var(--calcite-ui-border-3);border-style:solid;-ms-flex-preferred-size:auto;flex-basis:auto}.header{margin:0;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;color:var(--calcite-ui-text-2);fill:var(--calcite-ui-text-2)}.heading{padding:0;margin:0;font-weight:var(--calcite-font-weight-medium);line-height:1.5}.header .heading{-ms-flex:1 0 auto;flex:1 0 auto;padding:var(--calcite-spacing-half) var(--calcite-spacing-half)}h1.heading{font-size:var(--calcite-font-size-2)}h2.heading{font-size:var(--calcite-font-size-1)}h3.heading{font-size:var(--calcite-font-size-0)}h4.heading,h5.heading{font-size:var(--calcite-font-size--1)}.header{-ms-flex-pack:start;justify-content:flex-start;padding:0}.header,.toggle{grid-area:header}.header-container{display:grid;-ms-flex-align:stretch;align-items:stretch;grid-template:auto/auto 1fr auto;grid-template-areas:\"handle header control\";grid-column:header-start/control-end;grid-row:1/2}.header-container>.header{padding-top:0.75rem;padding-bottom:0.75rem;padding-left:0;padding-right:0}.toggle{display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-ms-flex-pack:justify;justify-content:space-between;font-family:inherit;-ms-flex-align:center;align-items:center;margin:0;padding-top:0.75rem;padding-bottom:0.75rem;padding-left:0;padding-right:0;border-style:none;cursor:pointer;text-align:left;outline-offset:0;outline-color:transparent;-webkit-transition:outline-offset 100ms ease-in-out, outline-color 100ms ease-in-out;transition:outline-offset 100ms ease-in-out, outline-color 100ms ease-in-out;background-color:transparent}.toggle:hover{background-color:var(--calcite-ui-foreground-2)}.toggle:focus{outline:2px solid var(--calcite-ui-brand);outline-offset:-2px}calcite-loader[inline]{grid-area:control;align-self:center}calcite-handle{grid-area:handle}.title{margin:0;padding-left:1rem;padding-right:1rem;padding-top:0;padding-bottom:0}.header .title .heading{padding:0;font-size:var(--calcite-font-size--1);color:var(--calcite-ui-text-3);font-weight:var(--calcite-font-weight-medium);word-wrap:break-word;word-break:break-word;line-height:1.25;-webkit-transition-property:color;transition-property:color;-webkit-transition-duration:150ms;transition-duration:150ms;-webkit-transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1)}.summary{padding:0;font-size:var(--calcite-font-size--2);color:var(--calcite-ui-text-3);word-wrap:break-word;word-break:break-word}.icon{margin-left:0.75rem}.status-icon.valid{color:var(--calcite-ui-success)}.status-icon.invalid{color:var(--calcite-ui-danger)}.toggle-icon{margin-right:1rem;-ms-flex-item-align:center;align-self:center;color:var(--calcite-ui-text-3);-webkit-transition-property:color;transition-property:color;-webkit-transition-duration:150ms;transition-duration:150ms;-webkit-transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1)}.toggle:hover .toggle-icon{color:var(--calcite-ui-text-1)}.content{padding-left:0.75rem;padding-right:0.75rem;padding-top:0.5rem;padding-bottom:0.5rem;position:relative;-webkit-animation:in 300ms ease-in-out;animation:in 300ms ease-in-out}.control-container{display:-ms-flexbox;display:flex;margin:0;grid-area:control}.calcite--rtl .toggle-icon{margin-right:0;margin-left:1rem}.calcite--rtl .icon{margin-left:0;margin-right:0.75rem}:host([open]){margin-top:0.5rem;margin-bottom:0.5rem}:host([open]) .header .title .heading{color:var(--calcite-ui-text-1)}:host([disabled]){pointer-events:none;-webkit-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;pointer-events:none;user-select:none}:host([disabled]) .header-container{opacity:0.5}:host([drag-handle]) .calcite--rtl .title{padding-left:0;padding-right:0.25rem}"; const CalciteBlock = class { constructor(hostRef) { registerInstance(this, hostRef); this.calciteBlockToggle = createEvent(this, "calciteBlockToggle", 7); // -------------------------------------------------------------------------- // // Properties // // -------------------------------------------------------------------------- /** * When true, this block will be collapsible. */ this.collapsible = false; /** * When true, disabled prevents interaction. This state shows items with lower opacity/grayed. */ this.disabled = false; /** * When true, displays a drag handle in the header. */ this.dragHandle = false; /** string to override English loading text */ this.intlLoading = TEXT$1.loading; /** * When true, content is waiting to be loaded. This state shows a busy indicator. */ this.loading = false; /** * When true, the block's content will be displayed. */ this.open = false; // -------------------------------------------------------------------------- // // Private Methods // // -------------------------------------------------------------------------- this.onHeaderClick = () => { this.open = !this.open; this.calciteBlockToggle.emit(); }; } // -------------------------------------------------------------------------- // // Render Methods // // -------------------------------------------------------------------------- renderScrim() { const { disabled, loading } = this; const defaultSlot = h("slot", null); return [loading || disabled ? h("calcite-scrim", { loading: loading }) : null, defaultSlot]; } renderIcon() { var _a; const { el, status } = this; const icon = (_a = ICONS$1[status]) !== null && _a !== void 0 ? _a : false; const hasIcon = getSlotted(el, SLOTS.icon) || icon; const iconEl = !icon ? (h("slot", { name: SLOTS.icon })) : (h("calcite-icon", { class: { [CSS$1.statusIcon]: true, [CSS$1.valid]: status == "valid", [CSS$1.invalid]: status == "invalid" }, icon: icon, scale: "m" })); return hasIcon ? h("div", { class: CSS$1.icon }, iconEl) : null; } render() { const { collapsible, disabled, el, heading, intlCollapse, intlExpand, loading, open, summary, intlLoading, headingLevel } = this; const toggleLabel = open ? intlCollapse || TEXT$1.collapse : intlExpand || TEXT$1.expand; const headerContent = (h("header", { class: CSS$1.header }, this.renderIcon(), h("div", { class: CSS$1.title }, h(CalciteHeading, { class: CSS$1.heading, level: headingLevel || HEADING_LEVEL }, heading), summary ? h("div", { class: CSS$1.summary }, summary) : null))); const hasControl = !!getSlotted(el, SLOTS.control); const collapseIcon = open ? ICONS$1.opened : ICONS$1.closed; const headerNode = (h("div", { class: CSS$1.headerContainer }, this.dragHandle ? h("calcite-handle", null) : null, collapsible ? (h("button", { "aria-expanded": collapsible ? open.toString() : null, "aria-label": toggleLabel, class: CSS$1.toggle, onClick: this.onHeaderClick, title: toggleLabel }, headerContent, !hasControl ? (h("calcite-icon", { "aria-hidden": "true", class: CSS$1.toggleIcon, icon: collapseIcon, scale: "s" })) : null)) : (headerContent), loading ? (h("calcite-loader", { inline: true, "is-active": true, label: intlLoading })) : hasControl ? (h("div", { class: CSS$1.controlContainer }, h("slot", { name: SLOTS.control }))) : null)); const rtl = getElementDir(el) === "rtl"; return (h(Host, { tabIndex: disabled ? -1 : null }, h("article", { "aria-busy": loading.toString(), class: { [CSS$1.article]: true, [CSS_UTILITY.rtl]: rtl } }, headerNode, h("div", { class: CSS$1.content, hidden: !open }, this.renderScrim())))); } get el() { return getElement(this); } }; CalciteBlock.style = calciteBlockCss; const CSS = { content: "content", invalid: "invalid", toggle: "toggle", toggleSwitch: "toggle--switch", toggleSwitchContent: "toggle--switch__content", toggleSwitchText: "toggle--switch__text", sectionHeader: "section-header", sectionHeaderText: "section-header__text", statusIcon: "status-icon", valid: "valid" }; const TEXT = { collapse: "Collapse", expand: "Expand" }; const ICONS = { menuOpen: "chevron-down", menuClosedLeft: "chevron-left", menuClosedRight: "chevron-right", valid: "check-circle", invalid: "exclamation-mark-triangle" }; const calciteBlockSectionCss = "@-webkit-keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}@keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}:root{--calcite-popper-transition:150ms ease-in-out}:host([hidden]){display:none}:host{-webkit-box-sizing:border-box;box-sizing:border-box;background-color:var(--calcite-ui-foreground-1);color:var(--calcite-ui-text-2);font-size:var(--calcite-font-size--1);display:block}:host([open]){border-style:solid;border-width:0;border-bottom-color:var(--calcite-ui-border-3);border-bottom-width:1px}:host(:last-child){border-bottom-width:0}.toggle{background-color:transparent;border-width:0;color:var(--calcite-ui-text-2);font-family:var(--calcite-sans-family);font-weight:var(--calcite-font-weight-normal);width:100%}.toggle--switch,.section-header{-ms-flex-align:center;align-items:center;cursor:pointer;display:-ms-flexbox;display:flex;margin-left:0;margin-right:0;margin-top:0.25rem;margin-bottom:0.25rem;padding-left:0;padding-right:0.25rem;padding-top:0.5rem;padding-bottom:0.5rem;-webkit-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;font-size:var(--calcite-font-size--1);outline-offset:0;outline-color:transparent;-webkit-transition:outline-offset 100ms ease-in-out, outline-color 100ms ease-in-out;transition:outline-offset 100ms ease-in-out, outline-color 100ms ease-in-out}.toggle--switch:focus,.section-header:focus{outline:2px solid var(--calcite-ui-brand);outline-offset:2px}.toggle--switch:hover,.section-header:hover{color:var(--calcite-ui-text-1)}.section-header .status-icon{-ms-flex-item-align:end;align-self:flex-end}.section-header__text{-ms-flex:1 1 auto;flex:1 1 auto;margin-left:0.75rem;margin-right:0.75rem;margin-top:0;margin-bottom:0;text-align:initial}.toggle--switch calcite-switch{pointer-events:none;margin-left:0.25rem;margin-right:0.25rem}.toggle--switch .status-icon{margin-left:0.25rem;margin-right:0.25rem}.toggle--switch__content{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex:1 1 auto;flex:1 1 auto}.status-icon.valid{color:var(--calcite-ui-success)}.status-icon.invalid{color:var(--calcite-ui-danger)}.calcite--rtl .toggle--switch{padding-right:0;padding-left:0.5rem}.calcite--rtl .toggle--switch calcite-switch{margin-left:0;margin-right:0.5rem}.calcite--rtl .section-header{padding-right:0;padding-left:0.25rem}"; const CalciteBlockSection = class { constructor(hostRef) { registerInstance(this, hostRef); this.calciteBlockSectionToggle = createEvent(this, "calciteBlockSectionToggle", 7); /** * When true, the block's section content will be displayed. */ this.open = false; /** * This property determines the look of the section toggle. * If the value is "switch", a toggle-switch will be displayed. * If the value is "button", a clickable header is displayed. * * @todo revisit doc */ this.toggleDisplay = "button"; this.toggleSection = () => { this.open = !this.open; this.calciteBlockSectionToggle.emit(); }; } // -------------------------------------------------------------------------- // // Private Methods // // -------------------------------------------------------------------------- handleHeaderLabelKeyDown(event) { if (event.key === " " || event.key === "Enter") { event.preventDefault(); event.stopPropagation(); this.click(); } } // -------------------------------------------------------------------------- // // Render Methods // // -------------------------------------------------------------------------- renderStatusIcon() { var _a; const { status } = this; const statusIcon = (_a = ICONS[status]) !== null && _a !== void 0 ? _a : false; const statusIconClasses = { [CSS.statusIcon]: true, [CSS.valid]: status == "valid", [CSS.invalid]: status == "invalid" }; return !!statusIcon ? (h("calcite-icon", { class: statusIconClasses, icon: statusIcon, scale: "s" })) : null; } render() { const { el, intlCollapse, intlExpand, open, text, toggleDisplay } = this; const dir = getElementDir(el); const arrowIcon = open ? ICONS.menuOpen : dir === "rtl" ? ICONS.menuClosedLeft : ICONS.menuClosedRight; const toggleLabel = open ? intlCollapse || TEXT.collapse : intlExpand || TEXT.expand; const headerNode = toggleDisplay === "switch" ? (h("label", { "aria-label": toggleLabel, class: { [CSS.toggle]: true, [CSS.toggleSwitch]: true }, onKeyDown: this.handleHeaderLabelKeyDown, tabIndex: 0, title: toggleLabel }, h("div", { class: CSS.toggleSwitchContent }, h("span", { class: CSS.toggleSwitchText }, text)), h("calcite-switch", { onCalciteSwitchChange: this.toggleSection, scale: "s", switched: open, tabIndex: -1 }), this.renderStatusIcon())) : (h("button", { "aria-label": toggleLabel, class: { [CSS.sectionHeader]: true, [CSS.toggle]: true }, name: toggleLabel, onClick: this.toggleSection, onKeyDown: this.handleHeaderLabelKeyDown }, h("calcite-icon", { icon: arrowIcon, scale: "s" }), h("span", { class: CSS.sectionHeaderText }, text), this.renderStatusIcon())); return (h("section", { "aria-expanded": open.toString(), class: { [CSS_UTILITY.rtl]: dir === "rtl" } }, headerNode, h("div", { class: CSS.content, hidden: !open }, h("slot", null)))); } get el() { return getElement(this); } }; CalciteBlockSection.style = calciteBlockSectionCss; export { CalciteBlock as calcite_block, CalciteBlockSection as calcite_block_section };