@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
220 lines (212 loc) • 18.6 kB
JavaScript
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 };