UNPKG

duoyun-ui

Version:

A lightweight desktop UI component library, implemented using Gem

343 lines (338 loc) 13.7 kB
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); var _, done = false; for (var i = decorators.length - 1; i >= 0; i--) { var context = {}; for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; for (var p in contextIn.access) context.access[p] = contextIn.access[p]; context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); if (kind === "accessor") { if (result === void 0) continue; if (result === null || typeof result !== "object") throw new TypeError("Object expected"); if (_ = accept(result.get)) descriptor.get = _; if (_ = accept(result.set)) descriptor.set = _; if (_ = accept(result.init)) initializers.unshift(_); } else if (_ = accept(result)) { if (kind === "field") initializers.unshift(_); else descriptor[key] = _; } } if (target) Object.defineProperty(target, contextIn.name, descriptor); done = true; }; var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) { var useValue = arguments.length > 2; for (var i = 0; i < initializers.length; i++) { value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); } return useValue ? value : void 0; }; import { mediaQuery } from '@mantou/gem/helper/mediaquery'; import { adoptedStyle, attribute, connectStore, customElement, effect, mounted, property, state, } from '@mantou/gem/lib/decorators'; import { createState, css, GemElement, html } from '@mantou/gem/lib/element'; import { history } from '@mantou/gem/lib/history'; import { addListener, classMap } from '@mantou/gem/lib/utils'; import { icons } from '../lib/icons'; import { focusStyle } from '../lib/styles'; import { theme } from '../lib/theme'; import { isRemoteIcon } from '../lib/utils'; import '../elements/use'; const style = css ` :scope { display: flex; align-items: center; gap: 2em; background: ${theme.backgroundColor}; box-shadow: rgba(0, 0, 0, calc(${theme.maskAlpha} - 0.1)) 0px 0px 8px; } :scope, .drawer-brand { padding: 0.6em 1em; } .drawer-brand { display: none; } li { list-style: none; } dy-use:not(.menu) { width: 1.2em; } .menu { display: none; } :where(.brand, .navbar, .navbar-top-link, dy-link) { display: flex; align-items: center; } .brand { gap: 0.5em; } .logo { height: 2.6em; } .name { font-size: 1.35em; opacity: 0.65; } .navbar { gap: 0.5em; } :where(.nav-list) { display: contents; } .navbar-item-wrap { position: relative; } .navbar-top-link { cursor: pointer; gap: 0.3em; padding-inline: 0.5em; line-height: 2.4; border-radius: ${theme.normalRound}; opacity: 0.65; } .navbar-item-wrap:hover .navbar-top-link { background: ${theme.lightBackgroundColor}; } .dropdown { display: none; position: absolute; flex-direction: column; gap: 0.3em; top: 100%; left: 0; min-width: max(100%, 10em); width: max-content; margin: 0; padding: 0.5em; line-height: 1.7; background: ${theme.backgroundColor}; border-radius: ${theme.normalRound}; filter: drop-shadow(${theme.borderColor} 0px 0px 1px) drop-shadow(rgba(0, 0, 0, calc(${theme.maskAlpha} - 0.1)) 0px 7px 10px); } :scope:where(:not(:state(switching))) :where(.navbar-item-wrap:where(:hover, :focus-within)) .dropdown { display: flex; } .dropdown dy-link { border-radius: ${theme.normalRound}; padding: 0.5em; gap: 0.3em; opacity: 0.65; } .dropdown dy-link:hover { background: ${theme.lightBackgroundColor}; } `; const mobileStyle = css(mediaQuery.PHONE, /*css*/ ` :scope { gap: 1em; } .drawer-brand { display: block; position: sticky; top: 0; background: ${theme.backgroundColor}; z-index: 1; border-block-end: 1px solid ${theme.borderColor}; margin-block-end: 1em; } .menu { display: block; width: 1.5em; padding: 0.5em; margin: -0.5em; border-radius: 10em; } .navbar:not(.open) { display: none; } .navbar { position: fixed; z-index: ${theme.popupZIndex}; inset: 0; background: rgba(0, 0, 0, calc(${theme.maskAlpha})); align-items: stretch; } .nav-list { display: block; width: 20em; height: 100%; margin: 0; padding: 0; background: ${theme.backgroundColor}; overflow: auto; overscroll-behavior: none; } .nav-list > li { padding-inline: 1em; } .nav-list > li:last-of-type { margin-block-end: 3em; } .open-dropdown + .dropdown { display: block; padding-inline-start: 2em; } .dropdown { position: relative; display: none; width: 100%; box-sizing: border-box; padding: 0; min-width: auto; filter: none; } .dropdown::before { position: absolute; content: ''; width: 1px; height: 100%; left: 1.2em; top: 0; background: ${theme.borderColor}; } `); let DyPatNavElement = (() => { let _classDecorators = [customElement('dy-pat-nav'), adoptedStyle(style), adoptedStyle(mobileStyle), adoptedStyle(focusStyle), connectStore(history.store)]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _classSuper = GemElement; let _name_decorators; let _name_initializers = []; let _name_extraInitializers = []; let _links_decorators; let _links_initializers = []; let _links_extraInitializers = []; let _logo_decorators; let _logo_initializers = []; let _logo_extraInitializers = []; let _switching_decorators; let _switching_initializers = []; let _switching_extraInitializers = []; let _private_blur_decorators; let _private_blur_initializers = []; let _private_blur_extraInitializers = []; let _private_autoBlur_decorators; let _private_autoBlur_initializers = []; let _private_autoBlur_extraInitializers = []; var DyPatNavElement = class extends _classSuper { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; _name_decorators = [attribute]; _links_decorators = [property]; _logo_decorators = [property]; _switching_decorators = [state]; _private_blur_decorators = [effect(() => [location.href])]; _private_autoBlur_decorators = [mounted()]; __esDecorate(null, null, _name_decorators, { kind: "field", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers); __esDecorate(null, null, _links_decorators, { kind: "field", name: "links", static: false, private: false, access: { has: obj => "links" in obj, get: obj => obj.links, set: (obj, value) => { obj.links = value; } }, metadata: _metadata }, _links_initializers, _links_extraInitializers); __esDecorate(null, null, _logo_decorators, { kind: "field", name: "logo", static: false, private: false, access: { has: obj => "logo" in obj, get: obj => obj.logo, set: (obj, value) => { obj.logo = value; } }, metadata: _metadata }, _logo_initializers, _logo_extraInitializers); __esDecorate(null, null, _switching_decorators, { kind: "field", name: "switching", static: false, private: false, access: { has: obj => "switching" in obj, get: obj => obj.switching, set: (obj, value) => { obj.switching = value; } }, metadata: _metadata }, _switching_initializers, _switching_extraInitializers); __esDecorate(null, null, _private_blur_decorators, { kind: "field", name: "#blur", static: false, private: true, access: { has: obj => #blur in obj, get: obj => obj.#blur, set: (obj, value) => { obj.#blur = value; } }, metadata: _metadata }, _private_blur_initializers, _private_blur_extraInitializers); __esDecorate(null, null, _private_autoBlur_decorators, { kind: "field", name: "#autoBlur", static: false, private: true, access: { has: obj => #autoBlur in obj, get: obj => obj.#autoBlur, set: (obj, value) => { obj.#autoBlur = value; } }, metadata: _metadata }, _private_autoBlur_initializers, _private_autoBlur_extraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); DyPatNavElement = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } name = __runInitializers(this, _name_initializers, void 0); links = (__runInitializers(this, _name_extraInitializers), __runInitializers(this, _links_initializers, void 0)); logo = (__runInitializers(this, _links_extraInitializers), __runInitializers(this, _logo_initializers, void 0)); switching = (__runInitializers(this, _logo_extraInitializers), __runInitializers(this, _switching_initializers, void 0)); navSlot = __runInitializers(this, _switching_extraInitializers); #state = createState({ drawerOpen: false, }); #onMobileItemClick = (evt) => { evt.currentTarget.classList.toggle('open-dropdown'); }; #isOutwardLink(href) { return new URL(href, location.origin).origin !== location.origin; } #renderBrand = () => { return html ` <dy-link class="brand" title=${this.name} href="/"> ${!this.logo ? '' : isRemoteIcon(this.logo) ? html `<img class="logo" alt="Logo" src=${this.logo}></img>` : html `<dy-use class="logo" aria-label="Logo" .element=${this.logo}></dy-use>`} <span class="name">${this.name}</span> </dy-link> `; }; #blur = __runInitializers(this, _private_blur_initializers, () => { this.#state({ drawerOpen: false }); this.getRootNode().activeElement?.blur(); this.switching = true; setTimeout(() => (this.switching = false), 60); }); #autoBlur = (__runInitializers(this, _private_blur_extraInitializers), __runInitializers(this, _private_autoBlur_initializers, () => { return addListener(document, 'visibilitychange', () => { if (document.visibilityState === 'hidden') { this.#blur(); } }); })); render = (__runInitializers(this, _private_autoBlur_extraInitializers), () => { return html ` <dy-use class="menu" tabindex="0" .element=${icons.menu} @click=${() => this.#state({ drawerOpen: true })} ></dy-use> ${this.#renderBrand()} <nav class=${classMap({ navbar: true, open: this.#state.drawerOpen })}> <ul class="nav-list"> <li class="drawer-brand">${this.#renderBrand()}</li> ${this.links?.map(({ label, items, href }) => html ` <li class="navbar-item-wrap"> <dy-active-link v-if=${!!href} @click=${this.#onMobileItemClick} tabindex="0" class="navbar-top-link" href=${href} >${label}</dy-active-link > <div v-else @click=${this.#onMobileItemClick} tabindex="0" class="navbar-top-link"> ${label}<dy-use .element=${icons.expand}></dy-use> </div> <ul v-if=${!!items} class="dropdown"> ${items?.map((item) => html ` <li> <dy-link href=${item.href}> ${item.label} <dy-use v-if=${this.#isOutwardLink(item.href)} class="outward" .element=${icons.outward} ></dy-use> </dy-link> </li> `)} </ul> </li> `)} </ul> <div style="flex-grow: 1" @click=${() => this.#state({ drawerOpen: false })}></div> </nav> ${this.navSlot} `; }); }; return DyPatNavElement = _classThis; })(); export { DyPatNavElement }; //# sourceMappingURL=nav.js.map