UNPKG

@limetech/lime-elements

Version:
283 lines (276 loc) • 17.7 kB
import { r as registerInstance, c as createEvent, h, H as Host, a as getElement } from './index-DBTJNfo7.js'; import { t as translate } from './translations-DVRaJQvC.js'; import { i as isItem } from './is-item-CrvUOVvg.js'; import { c as createRandomString } from './random-string-JbKhhoXs.js'; import { m as makeEnterClickable, r as removeEnterClickable } from './make-enter-clickable-BgTwPGeH.js'; import { b as getIconColor, d as getIconTitle, g as getIconName } from './get-icon-props-CgNJbSP4.js'; const actionBarCss = () => `@charset "UTF-8";:host(limel-action-bar){--action-bar-item-height:2rem;--limel-action-bar-item-text-color:var( --action-bar-item-text-color, rgb(var(--contrast-1100)) );box-sizing:border-box;display:inline-flex;align-items:center;padding:0.125rem 0.25rem;max-width:100%;border-radius:var(--action-bar-border-radius);background-color:var(--action-bar-background-color, rgb(var(--contrast-100)));transition:max-width 0.3s ease}:host(limel-action-bar),.items{gap:0.25rem}@media (pointer: coarse){:host(limel-action-bar),.items{gap:0.5rem}}.items{display:inline-flex;max-width:100%;min-width:0}:host(limel-action-bar.is-shrunk) .items{opacity:0}:host(limel-action-bar:not(.is-shrunk)) .items{opacity:1}:host(limel-action-bar.is-full-width){width:100%}:host(limel-action-bar.is-floating){--action-bar-border-radius:100vw;border:1px solid rgb(var(--contrast-400));padding-right:0.125rem;padding-left:0.125rem;max-width:calc(100% - 2rem);box-shadow:var(--shadow-depth-16), var(--shadow-depth-8)}:host(limel-action-bar.is-shrunk){max-width:5rem;transition:max-width 0.3s ease-in-out}:host(limel-action-bar.is-shrunk) .expand-shrink{transition:transform 0.3s ease;transform:rotateY(180deg)}:host(limel-action-bar:not(.is-shrunk)){max-width:100%;transition:max-width 0.3s ease-in-out}:host(limel-action-bar:not(.is-shrunk)) .expand-shrink{transition:transform 0.3s ease;transform:rotateY(0deg)}:host(limel-action-bar.can-be-shrunk.is-full-width) .expand-shrink{margin-left:auto}.expand-shrink{all:unset;box-sizing:border-box;border-radius:50%;transition:color var(--limel-clickable-transition-speed, 0.4s) ease, background-color var(--limel-clickable-transition-speed, 0.4s) ease, box-shadow var(--limel-clickable-transform-speed, 0.4s) ease, transform var(--limel-clickable-transform-speed, 0.4s) var(--limel-clickable-transform-timing-function, ease);cursor:pointer;color:var(--limel-theme-on-surface-color);background-color:transparent}.expand-shrink:hover,.expand-shrink:focus,.expand-shrink:focus-visible{will-change:color, background-color, box-shadow, transform}.expand-shrink:hover,.expand-shrink:focus-visible{transform:translate3d(0, 0.01rem, 0);color:var(--limel-theme-on-surface-color);background-color:var(--lime-elevated-surface-background-color)}.expand-shrink:hover{box-shadow:var(--button-shadow-hovered)}.expand-shrink:active{--limel-clickable-transform-timing-function:cubic-bezier( 0.83, -0.15, 0.49, 1.16 );transform:translate3d(0, 0.05rem, 0);box-shadow:var(--button-shadow-pressed)}.expand-shrink:hover,.expand-shrink:active{--limel-clickable-transition-speed:0.2s;--limel-clickable-transform-speed:0.16s}.expand-shrink:focus{outline:none}.expand-shrink:focus-visible{outline:none;box-shadow:var(--shadow-depth-8-focused)}.expand-shrink{display:flex;justify-content:center;align-items:center}.expand-shrink limel-icon{width:1.5rem;height:1.5rem;padding:0.125rem;color:var(--action-bar-shrink-icon-color, rgb(var(--contrast-1000)))}`; const ActionBar = class { constructor(hostRef) { registerInstance(this, hostRef); this.itemSelected = createEvent(this, "itemSelected"); /** * Items that are placed in the action bar. * These represent primary actions. */ this.actions = []; /** * Defines the language for translations. */ this.language = document.documentElement.lang; /** * When set to `true`, the action bar will be collapsible. */ this.collapsible = false; this.overflowCutoff = this.actions.length; /** * Indicates whether the action bar is currently in a collapsed state. */ this.actionBarIsShrunk = false; this.hasRendered = false; this.isFirstIntersectionCheck = true; this.actionBarItems = []; this.renderActionBarItem = (item, index) => { return (h("limel-action-bar-item", { item: item, onSelect: this.handleSelect, isVisible: this.isVisible(index), role: "gridcell" })); }; this.renderOverflowMenu = (items) => { if (!(this.actions.length - this.overflowCutoff)) { return; } const shrunkOverFlowIcon = { name: 'more', color: 'rgb(var(--contrast-1000))', title: this.getTranslation('action-bar.actions'), }; return (h("limel-action-bar-overflow-menu", { openDirection: this.openDirection, items: items, onSelect: this.handleSelect, role: "gridcell", overFlowIcon: this.actionBarIsShrunk ? shrunkOverFlowIcon : undefined })); }; this.handleCollapseExpandClick = () => { this.actionBarIsShrunk = !this.actionBarIsShrunk; }; this.handleSelect = (event) => { event.stopPropagation(); if (isItem(event.detail)) { this.itemSelected.emit(event.detail); } }; this.getTranslation = (key) => { return translate.get(key, this.language); }; this.handleIntersection = (entries) => { const intersectingItems = entries.filter((entry) => entry.isIntersecting); const notIntersectingItems = entries.filter((entry) => !entry.isIntersecting); if (this.isFirstIntersectionCheck) { this.overflowCutoff = intersectingItems.length; } else { this.overflowCutoff = this.overflowCutoff + intersectingItems.length - notIntersectingItems.length; } this.isFirstIntersectionCheck = false; }; } connectedCallback() { if (this.hasRendered) { this.createIntersectionObserver(); } } componentDidRender() { var _a; if (this.haveItemsChanged()) { (_a = this.intersectionObserver) === null || _a === void 0 ? void 0 : _a.disconnect(); this.createIntersectionObserver(); } } disconnectedCallback() { var _a; (_a = this.intersectionObserver) === null || _a === void 0 ? void 0 : _a.disconnect(); this.intersectionObserver = undefined; this.actionBarItems = []; } render() { this.hasRendered = true; let overflowActions = []; if (this.actions.length > 0) { overflowActions = this.actions.slice(this.overflowCutoff); } return (h(Host, { key: 'f81d3acb912e7191889f7b8e4462c6e1a1db692b', "aria-label": this.accessibleLabel, class: { 'is-full-width': this.layout === 'fullWidth', 'is-floating': this.layout === 'floating', 'is-shrunk': this.actionBarIsShrunk && this.collapsible, 'can-be-shrunk': !!this.collapsible, }, role: "grid" }, h("div", { key: 'd6d96d43a7dd278f1f65033b070213cd1c6b963e', class: "items", role: "rowgroup" }, this.actions.map(this.renderActionBarItem)), this.renderOverflowMenu(overflowActions), this.renderCollapseExpandButton())); } renderCollapseExpandButton() { if (!this.collapsible || this.actions.length <= 1) { return; } return (h("button", { class: { 'expand-shrink': true, }, "aria-label": this.tooltipLabel, type: "button", onClick: this.handleCollapseExpandClick }, h("limel-icon", { name: "double_left", id: "tooltip-expand-shrink-button" }), h("limel-tooltip", { label: this.tooltipLabel, elementId: "tooltip-expand-shrink-button" }))); } isVisible(index) { return index < this.overflowCutoff; } get tooltipLabel() { let key = 'action-bar.collapse'; if (this.actionBarIsShrunk) { key = 'action-bar.expand'; } return this.getTranslation(key); } createIntersectionObserver() { const options = { root: this.host.shadowRoot.querySelector('.items'), rootMargin: '0px', threshold: 1, }; this.overflowCutoff = this.actions.length; this.isFirstIntersectionCheck = true; this.actionBarItems = []; this.intersectionObserver = new IntersectionObserver(this.handleIntersection, options); for (const actionBarItem of this.host.shadowRoot.querySelectorAll('limel-action-bar-item')) { this.observe(actionBarItem); } } observe(actionBarItem) { this.intersectionObserver.observe(actionBarItem); this.actionBarItems.push(actionBarItem); } haveItemsChanged() { const someItemRemoved = this.actionBarItems.some((actionBarItem) => !this.host.shadowRoot.contains(actionBarItem)); const someItemAdded = [ ...this.host.shadowRoot.querySelectorAll('limel-action-bar-item'), ].some((actionBarItem) => !this.actionBarItems.includes(actionBarItem)); return someItemRemoved || someItemAdded; } get host() { return getElement(this); } }; ActionBar.style = actionBarCss(); const actionBarItemCss = () => `@charset "UTF-8";limel-action-bar-item{transition:opacity 0.2s ease-in-out;position:relative;display:flex;align-items:center}limel-action-bar-item:not([is-visible]){opacity:0;pointer-events:none}button{all:unset}button:not([disabled]){transition:color var(--limel-clickable-transition-speed, 0.4s) ease, background-color var(--limel-clickable-transition-speed, 0.4s) ease, box-shadow var(--limel-clickable-transform-speed, 0.4s) ease, transform var(--limel-clickable-transform-speed, 0.4s) var(--limel-clickable-transform-timing-function, ease);cursor:pointer;color:var(--limel-action-bar-item-text-color);background-color:var(--action-bar-background-color)}button:not([disabled]):hover,button:not([disabled]):focus,button:not([disabled]):focus-visible{will-change:color, background-color, box-shadow, transform}button:not([disabled]):hover,button:not([disabled]):focus-visible{transform:translate3d(0, -0.04rem, 0);color:var(--limel-action-bar-item-text-color);background-color:var(--action-bar-background-color)}button:not([disabled]):hover{box-shadow:var(--button-shadow-hovered)}button:not([disabled]):active{--limel-clickable-transform-timing-function:cubic-bezier( 0.83, -0.15, 0.49, 1.16 );transform:translate3d(0, 0.05rem, 0);background-color:var(--action-bar-background-color);box-shadow:var(--button-shadow-inset-pressed)}button:not([disabled]):hover,button:not([disabled]):active{--limel-clickable-transition-speed:0.2s;--limel-clickable-transform-speed:0.16s}button:not([disabled]):focus{outline:none}button:not([disabled]):focus-visible{outline:none;box-shadow:var(--shadow-depth-8-focused)}button{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:0.25rem;width:100%;min-width:var(--action-bar-item-height);max-width:var(--action-bar-item-max-width, 10rem);height:var(--action-bar-item-height);color:var(--limel-action-bar-item-text-color);border-radius:var(--action-bar-item-height);font-size:var(--limel-theme-default-font-size);padding:0 0.25rem}button:has(.text){padding:0 0.5rem}button[disabled]{opacity:0.4}button.is-selected:not(:hover){box-shadow:var(--button-shadow-inset)}button.is-selected{color:var(--lime-primary-color, var(--limel-theme-primary-color)) !important}.text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding:0 0.25rem}limel-icon{flex-shrink:0;width:calc(var(--action-bar-item-height) - 0.75rem);height:calc(var(--action-bar-item-height) - 0.75rem);color:var(--action-bar-item-icon-color, var(--limel-action-bar-item-text-color))}hr{all:unset;width:1px;height:1.5rem;border-radius:var(--action-bar-item-height);background-color:var(--limel-action-bar-item-text-color);opacity:0.2}@media (pointer: fine){hr{margin-right:0.5rem;margin-left:0.5rem}}limel-menu{--notification-badge-background-color:rgb(var(--contrast-600));--notification-badge-text-color:rgb(var(--contrast-1200))}limel-menu[open] button{box-shadow:var(--button-shadow-inset)}button[slot=trigger]{animation:fade-in ease-out 0.25s;font-size:0.75rem;font-weight:bold;transform:translate3d(0, 0, 0)}@keyframes fade-in{0%{scale:0.8;opacity:0}100%{scale:1;opacity:1}}`; const ActionBarButton = class { constructor(hostRef) { registerInstance(this, hostRef); this.select = createEvent(this, "select"); /** * When the item is displayed in the available width, * this will be `false`. */ this.isVisible = true; /** * When the item is selected, this will be `true`. */ this.selected = false; this.handleClick = (event) => { event.stopPropagation(); this.select.emit(this.item); }; this.tooltipId = createRandomString(); } componentWillLoad() { makeEnterClickable(this.host); } componentDidLoad() { this.triggerIconColorWarning(); } disconnectedCallback() { removeEnterClickable(this.host); } render() { if (!this.isItem(this.item) && this.item.separator) { return h("hr", null); } return (h("button", { id: this.tooltipId, type: "button", onClick: this.handleClick, disabled: this.isDisabled(), class: { 'is-selected': this.isItem(this.item) && this.item.selected, } }, this.renderIcon(), this.renderLabel(), this.renderTooltip())); } isItem(item) { return !('separator' in item); } isDisabled() { if (this.isItem(this.item) && this.item.disabled) { return true; } if (!this.isVisible) { return true; } } renderIcon() { if (this.isItem(this.item) && !this.item.icon) { return; } if ('icon' in this.item) { const name = getIconName(this.item.icon); const color = getIconColor(this.item.icon, this.item.iconColor); const title = getIconTitle(this.item.icon); return (h("limel-icon", { name: name, "aria-label": title, "aria-hidden": title ? null : 'true', style: { '--action-bar-item-icon-color': `${color}`, } })); } } renderLabel() { if (!this.isItem(this.item) || this.item.iconOnly) { return; } return h("span", { class: "text" }, this.item.text); } renderTooltip() { if (!this.isItem(this.item)) { return; } return (h("limel-tooltip", { elementId: this.tooltipId, label: this.getTooltipLabel(this.item), helperLabel: this.item.commandText })); } getTooltipLabel(item) { const iconTitle = getIconTitle(item.icon); const tooltipLabel = item.text; if (iconTitle && tooltipLabel) { return `${iconTitle} ${tooltipLabel}`; } return tooltipLabel; } triggerIconColorWarning() { if (this.isItem(this.item) && this.item.iconColor) { console.warn("The `iconColor` prop is deprecated now! Use the new `Icon` interface and instead of `iconColor: 'color-name'` write `icon {name: 'icon-name', color: 'color-name'}`."); } } get host() { return getElement(this); } }; ActionBarButton.style = actionBarItemCss(); const ActionBarOverflowMenu = class { constructor(hostRef) { registerInstance(this, hostRef); this.select = createEvent(this, "select"); /** * Defines the location that the content of the overflow menu * appears, in relation to its trigger. * It defaults to `bottom-end`, since in normal scenarios * (for example when the action bar is not floating at the bottom of the screen) * this menu is the right-most item in the user interface of the component. */ this.openDirection = 'bottom-end'; this.getOverflowTriggerContent = () => { if (this.overFlowIcon) { const { color, name, title } = this.overFlowIcon; return (h("limel-icon", { style: { color: color, }, name: name, "aria-label": title })); } return `+${this.numberOfMenuItems}`; }; this.handleSelect = (event) => { event.stopPropagation(); this.select.emit(event.detail); }; } render() { return (h(Host, { key: '5a993a11b77a6b9c268444ea6903df602ae832ea' }, h("limel-menu", { key: 'bb6c54b88d20dc54ad86099e67facbd2656d6a9f', openDirection: this.openDirection, items: this.items, onSelect: this.handleSelect }, h("button", { key: '618587121d8dfd16b5e495ab53b251be42d98f01', type: "button", slot: "trigger" }, this.getOverflowTriggerContent())))); } get numberOfMenuItems() { return this.items.filter((item) => this.isMenuItem(item)).length; } isMenuItem(item) { return !('separator' in item); } }; export { ActionBar as limel_action_bar, ActionBarButton as limel_action_bar_item, ActionBarOverflowMenu as limel_action_bar_overflow_menu };