{"version":3,"sources":["lib/littleDropDown/littleDropDown.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,YAAY,mDAAmD,CAAC;AA2K7E,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,qBAAa,kBAAmB,SAAQ,WAAW;IAEjD,IAAI,YAAY,IAAI,aAAa,CAShC;IAED,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAAsB;IAExD,wBAAwB,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAM1F,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,OAAO,CAAC,QAAQ,CAAuB;IAGvC,OAAO,CAAC,GAAG,CAAQ;IAEnB,IAAI,KAAK,IAAI,aAAa,CAA0B;IAEpD,IAAI,KAAK,CAAC,GAAG,EAAE,aAAa,EAG3B;IAED;;;;;SAKK;IACE,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC;IA4BpC,WAAW,CAChB,OAAO,EAAE,CAAC,aAAa,KAAA,KAAK,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,GACjE,OAAO,CAAC,IAAI,CAAC;IAYT,iBAAiB,IAAI,IAAI;IAIzB,oBAAoB,IAAI,IAAI;IAMnC,OAAO,CAAC,MAAM;CAQf;AAwBD,eAAe,kBAAkB,CAAC","file":"../../../lib/littleDropDown/littleDropDown.d.ts","sourcesContent":["import { singletonProvider } from '../../common/provider.js';\nimport { html, render, TemplateResult } from '../../../../../lit-html/lit-html.js';\nimport AppContext, { getTools } from '../../common/appContext/appContext.js';\nimport { aliasName as loggerAlias, Logger } from '../../common/appContext/logging.js';\nimport { Ii18n, providerName as i18nProvider } from '../appContext/i18n.js';\nimport styleHelper from '../styleGuide/styleGuide.js';\nimport { css } from './littleDropDown.css.js';\n\ninterface Tools {\n  i18n: Ii18n;\n  log: Logger;\n}\n\nlet tools: Tools = null; // initialized below\n\nexport const providerName = 'driver/littleware/little-elements/lw-drop-down';\n\n/* eslint-disable */\nconst PREFIX = 'pure-';\nconst ACTIVE_CLASS_NAME = `${PREFIX}menu-active`;\nconst ARIA_ROLE = 'role';\nconst ARIA_HIDDEN = 'aria-hidden';\nconst MENU_OPEN = 0;\nconst MENU_CLOSED = 1;\nconst MENU_LINK_SELECTOR = '.pure-menu-link';\nconst MENU_SELECTOR = '.pure-menu-children';\nconst DISMISS_EVENT = (window.hasOwnProperty\n        && window.hasOwnProperty('ontouchstart'))\n  ? 'touchstart' : 'mousedown';\n\n/* eslint-enable */\n\n/**\n * littleDropDown dropdown handler - originally from:\n *     https://purecss.io/js/menus.js\n * TODO - add mechanism to remove listeners when\n * a drop down is removed from the page.\n *\n * Enable drop-down menus in Pure\n * Inspired by YUI3 gallery-simple-menu by Julien LeComte\n * [https://github.com/yui/yui3-gallery/blob/master/src/gallery-simple-menu/js/simple-menu.js]\n *\n * TODO: port this stuff to just change properties on the element,\n *  then re-render, and let lit-html handle the property changes.\n */\nclass PureDropdown {\n  public static build(menu: LittleDropDownMenu): PureDropdown {\n    const dropdownParent = menu.querySelector('.pure-menu-has-children');\n    if (!dropdownParent) { return null; }\n    const ddm = new PureDropdown(dropdownParent); // drop down menu\n\n    // Set ARIA attributes\n    ddm._link.setAttribute('aria-haspopup', 'true');\n    ddm._menu.setAttribute(ARIA_ROLE, 'menu');\n    ddm._menu.setAttribute('aria-labelledby', ddm._link.getAttribute('id'));\n    ddm._menu.setAttribute('aria-hidden', 'true');\n    [].forEach.call(\n      ddm._menu.querySelectorAll('li'),\n      (el) => {\n        el.setAttribute(ARIA_ROLE, 'presentation');\n      },\n    );\n    [].forEach.call(\n      ddm._menu.querySelectorAll('a'),\n      (el) => {\n        el.setAttribute(ARIA_ROLE, 'menuitem');\n      },\n    );\n\n    // Toggle on click\n    ddm._link.addEventListener('click', (e) => {\n      e.stopPropagation();\n      // tools.log.debug(`lw-drop-down click on ${e.target.href}`);\n      e.preventDefault();\n      ddm.toggle();\n    });\n\n    // Dismiss an open menu on outside event\n    // TODO - Adding a listener at the document level is prone\n    // to memory leak if these components are dynamically\n    // created and destroyed ....\n    document.addEventListener(DISMISS_EVENT, (e) => {\n      const { target } = e;\n      if (target !== ddm._link && !ddm._dropdownParent.contains(target as Element)) {\n        ddm.hide();\n        ddm._link.blur();\n      }\n    });\n\n    return ddm;\n  }\n\n  // eslint-disable\n  private _state = MENU_CLOSED;\n\n  private _dropdownParent: HTMLElement;\n\n  private _link: HTMLElement;\n\n  private _menu: HTMLElement;\n  // eslint-enable\n\n  constructor(dropdownParent) {\n    this._dropdownParent = dropdownParent;\n    this._link = this._dropdownParent.querySelector(MENU_LINK_SELECTOR);\n    this._menu = this._dropdownParent.querySelector(MENU_SELECTOR);\n  }\n\n  public show() {\n    if (this._state !== MENU_OPEN) {\n      this._dropdownParent.classList.add(ACTIVE_CLASS_NAME);\n      this._menu.setAttribute(ARIA_HIDDEN, 'false');\n      this._state = MENU_OPEN;\n      this._dropdownParent.querySelectorAll('.lw-drop-down__hambun').forEach(\n        (bun) => {\n          bun.classList.add('lw-drop-down__hambun_x');\n        },\n      );\n    }\n  }\n\n  public hide() {\n    if (this._state !== MENU_CLOSED) {\n      this._dropdownParent.classList.remove(ACTIVE_CLASS_NAME);\n      this._menu.setAttribute(ARIA_HIDDEN, 'true');\n      this._link.blur();\n      this._state = MENU_CLOSED;\n      this._dropdownParent.querySelectorAll('.lw-drop-down__hambun').forEach(\n        (bun) => {\n          bun.classList.remove('lw-drop-down__hambun_x');\n        },\n      );\n    }\n  }\n\n  public toggle() {\n    if (this._state === MENU_CLOSED) {\n      this.show();\n    } else {\n      this.hide();\n    }\n  }\n\n  public halt(e) {\n    e.stopPropagation();\n    e.preventDefault();\n  }\n}\n\nlet idCounter = 0;\n\n/**\n *\n * @param model for instrumenting the template\n */\nfunction templateFactory(model: DropDownModel): TemplateResult {\n  const isHamburger = model.root.labelKey === 'little-hamburger';\n  return html`\n<div class=\"pure-menu pure-menu-horizontal lw-drop-down ${model.root.className}\">\n    <ul class=\"pure-menu-list\">\n        <li class=\"pure-menu-item pure-menu-has-children\">\n            ${\n  !isHamburger\n    ? html`\n                        <a href=\"${model.root.href}\" id=\"ldd${idCounter++}\" class=\"pure-menu-link\">${tools.i18n.t(model.root.labelKey)}</a>\n                        `\n    : html`\n                    <a href=\"${model.root.href}\" id=\"ldd${idCounter++}\" class=\"pure-menu-link lw-drop-down__hamburger\">\n                    <span class=\"lw-drop-down__hambun\"></span>\n                    <span class=\"lw-drop-down__hambun\"></span>\n                    <span class=\"lw-drop-down__hambun\"></span>\n                    </a>`\n}\n            <ul class=\"pure-menu-children lw-nav-block lw-nav-block_gradient ${isHamburger ? 'lw-drop-down__hamburger-menu' : 'lw-drop-down__menu'}\">\n                ${model.items.map(\n    (it) => html`<li class=\"pure-menu-item ${it.className}\">\n                    <a href=\"${it.href}\" id=\"ldd${idCounter++}\" class=\"pure-menu-link\">${tools.i18n.t(it.labelKey)}</a>\n                </li>`,\n  )}\n            </ul>\n        </li>\n    </ul>\n</div>\n    `;\n}\n\nexport interface MenuItem {\n  className: string;\n  labelKey: string;\n  href: string;\n}\n\nexport interface DropDownModel {\n  root: MenuItem;\n  items: MenuItem[];\n}\n\nexport class LittleDropDownMenu extends HTMLElement {\n  // Gets a copy of the default model\n  get defaultModel(): DropDownModel {\n    return {\n      items: [],\n      root: {\n        className: 'lw-drop-down_uninitialized',\n        href: '#ignore',\n        labelKey: 'uninitialized',\n      },\n    };\n  }\n\n  static get observedAttributes(): string[] { return ['model']; }\n\n  public attributeChangedCallback(attrName?: string, oldVal?: string, newVal?: string): void {\n    if (attrName === 'model' && newVal && oldVal !== newVal) {\n      this.model = JSON.parse(newVal);\n    }\n  }\n\n  get contextPath(): string {\n    return this.getAttribute('context');\n  }\n\n  private modelVal: DropDownModel = null;\n\n  // drop-down manager\n  private ddm = null;\n\n  get model(): DropDownModel { return this.modelVal; }\n\n  set model(val: DropDownModel) {\n    this.modelVal = val;\n    this.render();\n  }\n\n  /**\n     * Helper initializes the  model property from the\n     * context path if not already set\n     *\n     * @returns\n     */\n  public fetchModel(): Promise<DropDownModel> {\n    if (!this.modelVal) {\n      const cxPath = this.contextPath;\n      if (cxPath) {\n        return AppContext.get().then(\n          (cx) => cx.getConfig(this.contextPath),\n        ).then(\n          (entry) => (\n            {\n              ...this.defaultModel,\n              ...entry.defaults,\n              ...entry.overrides,\n            } as DropDownModel\n          ),\n        ).then(\n          (newModel: DropDownModel) => {\n            if (!this.modelVal) {\n              this.modelVal = newModel;\n            }\n            return this.modelVal;\n          },\n        );\n      }\n      this.modelVal = this.defaultModel;\n    }\n    return Promise.resolve(this.modelVal);\n  }\n\n  public changeModel(\n    handler: (DropDownModel) => DropDownModel | Promise<DropDownModel>,\n  ): Promise<void> {\n    return this.fetchModel().then(\n      (model) => handler(model),\n    ).then(\n      (newModel) => {\n        if (newModel) {\n          this.model = newModel;\n        }\n      },\n    );\n  }\n\n  public connectedCallback(): void {\n    this.render();\n  }\n\n  public disconnectedCallback(): void {\n    // console.log( \"Disconnected!\" );\n  }\n\n  // Render element DOM by returning a `lit-html` template.\n  // Wired to run once only - static configuration.\n  private render() {\n    return this.fetchModel().then(\n      (model) => {\n        render(templateFactory(model), this);\n        this.ddm = PureDropdown.build(this);\n      },\n    );\n  }\n}\n\n//\n// Note that the customElement is not defined\n// until the tools have been loaded here, so\n// we can avoid asynchronously\n// loading tools from the code above\n//\nAppContext.get().then(\n  (cx) => {\n    cx.putProvider(providerName,\n      { i18n: i18nProvider, log: loggerAlias },\n      async (toolBox) => {\n        tools = await getTools(toolBox) as Tools;\n        window.customElements.define('lw-drop-down', LittleDropDownMenu);\n        styleHelper.componentCss.push(css);\n        styleHelper.render();\n        return singletonProvider(() => 'lw-drop-down');\n      });\n    // force instantiation - otherwise default is lazy\n    cx.onStart({ 'lw-drop-down': providerName }, () => {});\n  },\n);\n\nexport default LittleDropDownMenu;\n"]}