@omicronenergy/oscd-shell 0.0.12 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/landing-page/landing-page.js +3 -2
  2. package/dist/landing-page/landing-page.js.map +1 -1
  3. package/dist/landing-page/landing-page.spec.js +4 -2
  4. package/dist/landing-page/landing-page.spec.js.map +1 -1
  5. package/dist/locales/de.d.ts +8 -0
  6. package/dist/locales/de.js +9 -0
  7. package/dist/locales/de.js.map +1 -1
  8. package/dist/menus/files-menu.js +4 -5
  9. package/dist/menus/files-menu.js.map +1 -1
  10. package/dist/menus/plugins-menu.d.ts +6 -3
  11. package/dist/menus/plugins-menu.js +46 -5
  12. package/dist/menus/plugins-menu.js.map +1 -1
  13. package/dist/menus/plugins-menu.spec.js +1 -0
  14. package/dist/menus/plugins-menu.spec.js.map +1 -1
  15. package/dist/oscd-shell-design-tokens.js +134 -62
  16. package/dist/oscd-shell-design-tokens.js.map +1 -1
  17. package/dist/oscd-shell.d.ts +31 -22
  18. package/dist/oscd-shell.js +136 -72
  19. package/dist/oscd-shell.js.map +1 -1
  20. package/dist/side-panel/build-tree-nodes.spec.d.ts +1 -0
  21. package/dist/side-panel/build-tree-nodes.spec.js +50 -0
  22. package/dist/side-panel/build-tree-nodes.spec.js.map +1 -0
  23. package/dist/side-panel/editor-plugins-panel.d.ts +79 -7
  24. package/dist/side-panel/editor-plugins-panel.js +823 -92
  25. package/dist/side-panel/editor-plugins-panel.js.map +1 -1
  26. package/dist/side-panel/editor-plugins-panel.spec.js +469 -24
  27. package/dist/side-panel/editor-plugins-panel.spec.js.map +1 -1
  28. package/dist/utils/plugin-utils.d.ts +29 -5
  29. package/dist/utils/plugin-utils.js +73 -14
  30. package/dist/utils/plugin-utils.js.map +1 -1
  31. package/dist/utils/plugin-utils.spec.js +113 -4
  32. package/dist/utils/plugin-utils.spec.js.map +1 -1
  33. package/dist/utils/testing/plugin-helpers.d.ts +7 -3
  34. package/dist/utils/testing/plugin-helpers.js +21 -9
  35. package/dist/utils/testing/plugin-helpers.js.map +1 -1
  36. package/package.json +36 -37
@@ -46,9 +46,10 @@ LandingPage.scopedElements = {
46
46
  'oscd-elevation': OscdElevation,
47
47
  };
48
48
  LandingPage.styles = css `
49
- .host {
49
+ :host {
50
+ background-color: var(--landing-background-color);
50
51
  display: flex;
51
- flex-direction: row;
52
+ flex-direction: column;
52
53
  align-items: center;
53
54
  justify-content: center;
54
55
  gap: 8px;
@@ -1 +1 @@
1
- {"version":3,"file":"landing-page.js","sourceRoot":"","sources":["../../src/landing-page/landing-page.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,iDAAiD,CAAC;AAIjF,OAAO,EAAE,aAAa,EAAE,MAAM,mDAAmD,CAAC;AAQ3E,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,mBAAmB,CAAC,UAAU,CAAC;IAAzD;;QAOL,gBAAgB;QAGhB,YAAO,GAAW,EAAE,CAAC;QAGrB,eAAU,GAAW,EAAE,CAAC;QAExB,gBAAW,GAAkB,EAAE,CAAC;IAuIlC,CAAC;IAlIC,MAAM;QACJ,OAAO,IAAI,CAAA;4BACa,IAAI,CAAC,OAAO;gCACR,IAAI,CAAC,UAAU;;UAErC,IAAI,CAAC,WAAW,CAAC,GAAG,CACpB,MAAM,CAAC,EAAE,CACP,IAAI,CAAA;;uBAEO,GAAG,EAAE;YACZ,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,oBAAoB,EAAE;gBACpC,MAAM,EAAE,EAAE,MAAM,EAAE;gBAClB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;aACf,CAAC,CACH,CAAC;QACJ,CAAC;;;;6BAIc,MAAM,CAAC,IAAI;wBAChB,MAAM,CAAC,IAAI;;;iCAGF,CACxB;;KAEJ,CAAC;IACJ,CAAC;;AAhDM,0BAAc,GAAG;IACtB,WAAW,EAAE,QAAQ;IACrB,kBAAkB,EAAE,cAAc;IAClC,gBAAgB,EAAE,aAAa;CAChC,AAJoB,CAInB;AA8CK,kBAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkGlB,AAlGY,CAkGX;AA3IF;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CACN;AAGrB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CACH;AAExB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;gDACM;AAGhC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;2CACvB;AAlBR,WAAW;IADvB,SAAS,EAAE;GACC,WAAW,CAsJvB","sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js';\nimport { localized } from '@lit/localize';\n\nimport { OscdIcon } from '@omicronenergy/oscd-ui/icon/OscdIcon.js';\nimport { OscdTextButton } from '@omicronenergy/oscd-ui/button/OscdTextButton.js';\n\nimport { PluginEntry } from '../oscd-shell.js';\nimport { LocaleTag } from '../localization.js';\nimport { OscdElevation } from '@omicronenergy/oscd-ui/elevation/OscdElevation.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'landing-page': LandingPage;\n }\n}\n@localized()\nexport class LandingPage extends ScopedElementsMixin(LitElement) {\n static scopedElements = {\n 'oscd-icon': OscdIcon,\n 'oscd-text-button': OscdTextButton,\n 'oscd-elevation': OscdElevation,\n };\n\n /* Properties */\n\n @property({ type: String })\n heading: string = '';\n\n @property({ type: String })\n subHeading: string = '';\n @property({ type: Array })\n menuPlugins: PluginEntry[] = [];\n\n @property({ type: String, reflect: true })\n locale!: LocaleTag;\n\n render() {\n return html`\n <h1 class=\"heading\">${this.heading}</h1>\n <h2 class=\"sub-heading\">${this.subHeading}</h2>\n <div class=\"menu-plugins-grid\">\n ${this.menuPlugins.map(\n plugin =>\n html`<oscd-text-button\n class=\"menu-plugin-item\"\n @click=${() => {\n this.dispatchEvent(\n new CustomEvent('menu-plugin-select', {\n detail: { plugin },\n bubbles: true,\n composed: true,\n }),\n );\n }}\n >\n <oscd-elevation></oscd-elevation>\n <div class=\"menu-plugin-item-content\">\n <oscd-icon>${plugin.icon}</oscd-icon>\n <span>${plugin.name}</span>\n <div class=\"menu-plugin-item-corner-wedge\"></div>\n </div>\n </oscd-text-button> `,\n )}\n </div>\n `;\n }\n\n static styles = css`\n .host {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n gap: 8px;\n }\n\n .heading {\n color: var(--landing-heading-color);\n text-align: center;\n font-family: var(--landing-heading-font-family);\n font-size: var(--landing-heading-size);\n font-style: var(--landing-heading-style);\n font-weight: var(--landing-heading-weight);\n line-height: var(--landing-heading-line-height);\n\n margin-block-start: 64px;\n margin-block-end: 8px;\n\n --md-icon-size: 50px;\n }\n\n .sub-heading {\n color: var(--landing-subheading-color);\n text-align: center;\n font-family: var(--landing-subheading-font-family);\n font-size: var(--landing-subheading-size);\n font-style: var(--landing-subheading-style);\n font-weight: var(--landing-subheading-weight);\n line-height: var(--landing-subheading-line-height);\n\n margin-block-end: 168px;\n }\n\n .menu-plugins-grid {\n width: var(--landing-grid-width);\n display: flex;\n flex-wrap: wrap;\n gap: var(--landing-grid-gap);\n justify-content: center;\n margin: 0 auto;\n padding: 16px 0;\n }\n\n .menu-plugin-item {\n --md-text-button-container-shape: var(--landing-card-radius);\n display: flex;\n flex-direction: row;\n align-items: center;\n text-align: center;\n padding: 8px;\n color: var(--landing-card-text-color);\n background: var(--landing-card-background);\n transition: background-color 0.3s;\n cursor: pointer;\n }\n\n .menu-plugin-item:hover {\n --md-elevation-level: 2;\n }\n\n .menu-plugin-item-content {\n color: var(--landing-card-text-color);\n width: var(--landing-card-width);\n height: var(--landing-card-height);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 24px;\n font-family: var(--landing-heading-font-family);\n }\n\n .menu-plugin-item-content oscd-icon {\n --md-icon-size: var(--landing-card-icon-size);\n }\n\n .menu-plugin-item-content span {\n font-size: 16px;\n font-style: normal;\n font-weight: 500;\n line-height: 22px; /* 135% */\n }\n\n .menu-plugin-item-corner-wedge {\n position: absolute;\n bottom: 0;\n right: 0;\n width: 50px;\n height: 50px;\n background: linear-gradient(\n to top left,\n var(--landing-card-corner-accent) 50%,\n transparent 50%\n );\n }\n `;\n}\n"]}
1
+ {"version":3,"file":"landing-page.js","sourceRoot":"","sources":["../../src/landing-page/landing-page.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,iDAAiD,CAAC;AAIjF,OAAO,EAAE,aAAa,EAAE,MAAM,mDAAmD,CAAC;AAQ3E,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,mBAAmB,CAAC,UAAU,CAAC;IAAzD;;QAOL,gBAAgB;QAGhB,YAAO,GAAW,EAAE,CAAC;QAGrB,eAAU,GAAW,EAAE,CAAC;QAExB,gBAAW,GAAkB,EAAE,CAAC;IAwIlC,CAAC;IAnIC,MAAM;QACJ,OAAO,IAAI,CAAA;4BACa,IAAI,CAAC,OAAO;gCACR,IAAI,CAAC,UAAU;;UAErC,IAAI,CAAC,WAAW,CAAC,GAAG,CACpB,MAAM,CAAC,EAAE,CACP,IAAI,CAAA;;uBAEO,GAAG,EAAE;YACZ,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,oBAAoB,EAAE;gBACpC,MAAM,EAAE,EAAE,MAAM,EAAE;gBAClB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;aACf,CAAC,CACH,CAAC;QACJ,CAAC;;;;6BAIc,MAAM,CAAC,IAAI;wBAChB,MAAM,CAAC,IAAI;;;iCAGF,CACxB;;KAEJ,CAAC;IACJ,CAAC;;AAhDM,0BAAc,GAAG;IACtB,WAAW,EAAE,QAAQ;IACrB,kBAAkB,EAAE,cAAc;IAClC,gBAAgB,EAAE,aAAa;CAChC,AAJoB,CAInB;AA8CK,kBAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmGlB,AAnGY,CAmGX;AA5IF;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CACN;AAGrB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CACH;AAExB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;gDACM;AAGhC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;2CACvB;AAlBR,WAAW;IADvB,SAAS,EAAE;GACC,WAAW,CAuJvB","sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js';\nimport { localized } from '@lit/localize';\n\nimport { OscdIcon } from '@omicronenergy/oscd-ui/icon/OscdIcon.js';\nimport { OscdTextButton } from '@omicronenergy/oscd-ui/button/OscdTextButton.js';\n\nimport { PluginEntry } from '../oscd-shell.js';\nimport { LocaleTag } from '../localization.js';\nimport { OscdElevation } from '@omicronenergy/oscd-ui/elevation/OscdElevation.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'landing-page': LandingPage;\n }\n}\n@localized()\nexport class LandingPage extends ScopedElementsMixin(LitElement) {\n static scopedElements = {\n 'oscd-icon': OscdIcon,\n 'oscd-text-button': OscdTextButton,\n 'oscd-elevation': OscdElevation,\n };\n\n /* Properties */\n\n @property({ type: String })\n heading: string = '';\n\n @property({ type: String })\n subHeading: string = '';\n @property({ type: Array })\n menuPlugins: PluginEntry[] = [];\n\n @property({ type: String, reflect: true })\n locale!: LocaleTag;\n\n render() {\n return html`\n <h1 class=\"heading\">${this.heading}</h1>\n <h2 class=\"sub-heading\">${this.subHeading}</h2>\n <div class=\"menu-plugins-grid\">\n ${this.menuPlugins.map(\n plugin =>\n html`<oscd-text-button\n class=\"menu-plugin-item\"\n @click=${() => {\n this.dispatchEvent(\n new CustomEvent('menu-plugin-select', {\n detail: { plugin },\n bubbles: true,\n composed: true,\n }),\n );\n }}\n >\n <oscd-elevation></oscd-elevation>\n <div class=\"menu-plugin-item-content\">\n <oscd-icon>${plugin.icon}</oscd-icon>\n <span>${plugin.name}</span>\n <div class=\"menu-plugin-item-corner-wedge\"></div>\n </div>\n </oscd-text-button> `,\n )}\n </div>\n `;\n }\n\n static styles = css`\n :host {\n background-color: var(--landing-background-color);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n }\n\n .heading {\n color: var(--landing-heading-color);\n text-align: center;\n font-family: var(--landing-heading-font-family);\n font-size: var(--landing-heading-size);\n font-style: var(--landing-heading-style);\n font-weight: var(--landing-heading-weight);\n line-height: var(--landing-heading-line-height);\n\n margin-block-start: 64px;\n margin-block-end: 8px;\n\n --md-icon-size: 50px;\n }\n\n .sub-heading {\n color: var(--landing-subheading-color);\n text-align: center;\n font-family: var(--landing-subheading-font-family);\n font-size: var(--landing-subheading-size);\n font-style: var(--landing-subheading-style);\n font-weight: var(--landing-subheading-weight);\n line-height: var(--landing-subheading-line-height);\n\n margin-block-end: 168px;\n }\n\n .menu-plugins-grid {\n width: var(--landing-grid-width);\n display: flex;\n flex-wrap: wrap;\n gap: var(--landing-grid-gap);\n justify-content: center;\n margin: 0 auto;\n padding: 16px 0;\n }\n\n .menu-plugin-item {\n --md-text-button-container-shape: var(--landing-card-radius);\n display: flex;\n flex-direction: row;\n align-items: center;\n text-align: center;\n padding: 8px;\n color: var(--landing-card-text-color);\n background: var(--landing-card-background);\n transition: background-color 0.3s;\n cursor: pointer;\n }\n\n .menu-plugin-item:hover {\n --md-elevation-level: 2;\n }\n\n .menu-plugin-item-content {\n color: var(--landing-card-text-color);\n width: var(--landing-card-width);\n height: var(--landing-card-height);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 24px;\n font-family: var(--landing-heading-font-family);\n }\n\n .menu-plugin-item-content oscd-icon {\n --md-icon-size: var(--landing-card-icon-size);\n }\n\n .menu-plugin-item-content span {\n font-size: 16px;\n font-style: normal;\n font-weight: 500;\n line-height: 22px; /* 135% */\n }\n\n .menu-plugin-item-corner-wedge {\n position: absolute;\n bottom: 0;\n right: 0;\n width: 50px;\n height: 50px;\n background: linear-gradient(\n to top left,\n var(--landing-card-corner-accent) 50%,\n transparent 50%\n );\n }\n `;\n}\n"]}
@@ -5,6 +5,7 @@ import { newOpenEvent } from '@openscd/oscd-api/utils.js';
5
5
  import { createSclDocument } from '../utils/testing/test-doc-helpers.js';
6
6
  import { sampleMenuPlugins, waitForAllPluginsToInstantiate, } from '../utils/testing/plugin-helpers.js';
7
7
  import sinon from 'sinon';
8
+ import { flattenPluginEntries } from '../utils/plugin-utils.js';
8
9
  const testHeading = 'Test Heading';
9
10
  const testSubHeading = 'Test Subheading';
10
11
  describe('default landing-page', () => {
@@ -15,7 +16,8 @@ describe('default landing-page', () => {
15
16
  landingPageHeading=${testHeading}
16
17
  landingPageSubHeading=${testSubHeading}
17
18
  ></oscd-shell>`);
18
- const testMenuPlugin1TagName = sampleMenuPlugins[0].tagName;
19
+ const testMenuPlugin1TagName = sampleMenuPlugins[0]
20
+ .tagName;
19
21
  expect(testMenuPlugin1TagName).to.not.be.undefined;
20
22
  if (oscdShell?.registry?.get(testMenuPlugin1TagName) === undefined) {
21
23
  oscdShell?.registry?.define(testMenuPlugin1TagName, TestMenuPlugin1);
@@ -44,7 +46,7 @@ describe('default landing-page', () => {
44
46
  expect(landingPageAfterOpen).to.be.null;
45
47
  });
46
48
  it('renders all menu plugins, not requiring a document, as large tiles (buttons)', async () => {
47
- const menuPluginsNotRequiringDoc = oscdShell.plugins.menu.filter(plugin => !plugin.requireDoc);
49
+ const menuPluginsNotRequiringDoc = flattenPluginEntries(oscdShell.plugins.menu).filter(plugin => !plugin.requireDoc);
48
50
  const menuPluginElements = landingPage.shadowRoot.querySelectorAll('.menu-plugin-item');
49
51
  expect(menuPluginElements.length).to.equal(menuPluginsNotRequiringDoc.length);
50
52
  });
@@ -1 +1 @@
1
- {"version":3,"file":"landing-page.spec.js","sourceRoot":"","sources":["../../src/landing-page/landing-page.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture, html } from '@open-wc/testing';\nimport type { OscdShell } from '../oscd-shell.js';\n\nimport '../oscd-shell.js';\nimport { TestMenuPlugin1 } from '../utils/testing/test-plugins.js';\nimport { LandingPage } from './landing-page.js';\nimport { newOpenEvent } from '@openscd/oscd-api/utils.js';\nimport { createSclDocument } from '../utils/testing/test-doc-helpers.js';\nimport {\n sampleMenuPlugins,\n waitForAllPluginsToInstantiate,\n} from '../utils/testing/plugin-helpers.js';\nimport sinon from 'sinon';\nimport { OscdTextButton } from '@omicronenergy/oscd-ui/button/OscdTextButton.js';\n\nconst testHeading = 'Test Heading';\nconst testSubHeading = 'Test Subheading';\n\ndescribe('default landing-page', () => {\n let oscdShell: OscdShell;\n let landingPage: LandingPage;\n\n beforeEach(async () => {\n oscdShell = await fixture(\n html`<oscd-shell\n landingPageHeading=${testHeading}\n landingPageSubHeading=${testSubHeading}\n ></oscd-shell>`,\n );\n const testMenuPlugin1TagName = sampleMenuPlugins[0].tagName!;\n expect(testMenuPlugin1TagName).to.not.be.undefined;\n if (oscdShell?.registry?.get(testMenuPlugin1TagName) === undefined) {\n oscdShell?.registry?.define(testMenuPlugin1TagName!, TestMenuPlugin1);\n }\n oscdShell.plugins = {\n menu: sampleMenuPlugins,\n };\n await waitForAllPluginsToInstantiate(oscdShell);\n landingPage = oscdShell.shadowRoot!.querySelector('landing-page')!;\n });\n\n it('loads the default landing-page if no landing-page slot is used and not document loaded', async () => {\n expect(landingPage).to.exist;\n });\n\n it('renders the landingPageHeading', async () => {\n const headingElement = landingPage.shadowRoot!.querySelector('.heading');\n expect(headingElement?.textContent?.trim()).to.equal(testHeading);\n });\n\n it('renders the landingPageSubHeading', async () => {\n const subHeadingElement =\n landingPage.shadowRoot!.querySelector('.sub-heading');\n expect(subHeadingElement?.textContent?.trim()).to.equal(testSubHeading);\n });\n\n it('does not load the default landing page as soon as a document is loaded', async () => {\n oscdShell.dispatchEvent(newOpenEvent(createSclDocument(), 'test.scd'));\n await oscdShell.updateComplete;\n const landingPageAfterOpen =\n oscdShell.shadowRoot!.querySelector('landing-page');\n expect(landingPageAfterOpen).to.be.null;\n });\n\n it('renders all menu plugins, not requiring a document, as large tiles (buttons)', async () => {\n const menuPluginsNotRequiringDoc = oscdShell.plugins.menu.filter(\n plugin => !plugin.requireDoc,\n );\n const menuPluginElements =\n landingPage.shadowRoot!.querySelectorAll('.menu-plugin-item');\n\n expect(menuPluginElements.length).to.equal(\n menuPluginsNotRequiringDoc.length,\n );\n });\n\n it('triggers the run method of the plugin when a menu tile is clicked', async () => {\n const testMenuPlugin1Def = sampleMenuPlugins.find(\n plugin => plugin.tagName === 'test-menu-plugin1',\n );\n const menuPluginElements =\n landingPage.shadowRoot!.querySelectorAll('.menu-plugin-item');\n\n const testMenuPlugin1Instance = oscdShell.shadowRoot?.querySelector(\n 'test-menu-plugin1',\n ) as TestMenuPlugin1;\n const menuPluginSpy = sinon.spy(testMenuPlugin1Instance, 'run');\n\n const testMenuPlugin1Button = Array.from(menuPluginElements).find(\n element =>\n element\n .querySelector('.menu-plugin-item-content span')\n ?.textContent?.trim() === testMenuPlugin1Def?.name,\n ) as OscdTextButton;\n testMenuPlugin1Button.click();\n await oscdShell.updateComplete;\n\n expect(menuPluginSpy.calledOnce).to.be.true;\n });\n});\n\ndescribe('custom landing-page', () => {\n let oscdShell: OscdShell;\n // let landingPage: LandingPage;\n\n beforeEach(async () => {\n oscdShell = <OscdShell>await fixture(\n html`<oscd-shell>\n <div slot=\"landing-page\" class=\"my-custom-landing-page\">\n <h1>Custom Landing Page</h1>\n </div>\n </oscd-shell>`,\n );\n await waitForAllPluginsToInstantiate(oscdShell);\n });\n\n it('loads a custom landing page if no document is loaded', async () => {\n const landingPageSlot = oscdShell.shadowRoot!.querySelector(\n 'slot[name=\"landing-page\"]',\n ) as HTMLSlotElement;\n expect(landingPageSlot).to.exist;\n expect(landingPageSlot?.assignedElements().length).to.equal(1);\n const customLandingPage = landingPageSlot?.assignedElements()[0];\n expect(customLandingPage).to.exist;\n });\n\n it('it no longer loads the landing page when a document is loaded', async () => {\n const defaultLandingPage =\n oscdShell.shadowRoot!.querySelector('landing-page');\n expect(defaultLandingPage).to.be.null;\n });\n});\n"]}
1
+ {"version":3,"file":"landing-page.spec.js","sourceRoot":"","sources":["../../src/landing-page/landing-page.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture, html } from '@open-wc/testing';\nimport type { OscdShell, PluginEntry } from '../oscd-shell.js';\n\nimport '../oscd-shell.js';\nimport { TestMenuPlugin1 } from '../utils/testing/test-plugins.js';\nimport { LandingPage } from './landing-page.js';\nimport { newOpenEvent } from '@openscd/oscd-api/utils.js';\nimport { createSclDocument } from '../utils/testing/test-doc-helpers.js';\nimport {\n sampleMenuPlugins,\n waitForAllPluginsToInstantiate,\n} from '../utils/testing/plugin-helpers.js';\nimport sinon from 'sinon';\nimport { OscdTextButton } from '@omicronenergy/oscd-ui/button/OscdTextButton.js';\nimport { flattenPluginEntries } from '../utils/plugin-utils.js';\n\nconst testHeading = 'Test Heading';\nconst testSubHeading = 'Test Subheading';\n\ndescribe('default landing-page', () => {\n let oscdShell: OscdShell;\n let landingPage: LandingPage;\n\n beforeEach(async () => {\n oscdShell = await fixture(\n html`<oscd-shell\n landingPageHeading=${testHeading}\n landingPageSubHeading=${testSubHeading}\n ></oscd-shell>`,\n );\n const testMenuPlugin1TagName = (sampleMenuPlugins[0] as PluginEntry)\n .tagName!;\n expect(testMenuPlugin1TagName).to.not.be.undefined;\n if (oscdShell?.registry?.get(testMenuPlugin1TagName) === undefined) {\n oscdShell?.registry?.define(testMenuPlugin1TagName!, TestMenuPlugin1);\n }\n oscdShell.plugins = {\n menu: sampleMenuPlugins,\n };\n await waitForAllPluginsToInstantiate(oscdShell);\n landingPage = oscdShell.shadowRoot!.querySelector('landing-page')!;\n });\n\n it('loads the default landing-page if no landing-page slot is used and not document loaded', async () => {\n expect(landingPage).to.exist;\n });\n\n it('renders the landingPageHeading', async () => {\n const headingElement = landingPage.shadowRoot!.querySelector('.heading');\n expect(headingElement?.textContent?.trim()).to.equal(testHeading);\n });\n\n it('renders the landingPageSubHeading', async () => {\n const subHeadingElement =\n landingPage.shadowRoot!.querySelector('.sub-heading');\n expect(subHeadingElement?.textContent?.trim()).to.equal(testSubHeading);\n });\n\n it('does not load the default landing page as soon as a document is loaded', async () => {\n oscdShell.dispatchEvent(newOpenEvent(createSclDocument(), 'test.scd'));\n await oscdShell.updateComplete;\n const landingPageAfterOpen =\n oscdShell.shadowRoot!.querySelector('landing-page');\n expect(landingPageAfterOpen).to.be.null;\n });\n\n it('renders all menu plugins, not requiring a document, as large tiles (buttons)', async () => {\n const menuPluginsNotRequiringDoc = flattenPluginEntries(\n oscdShell.plugins.menu,\n ).filter(plugin => !plugin.requireDoc);\n const menuPluginElements =\n landingPage.shadowRoot!.querySelectorAll('.menu-plugin-item');\n\n expect(menuPluginElements.length).to.equal(\n menuPluginsNotRequiringDoc.length,\n );\n });\n\n it('triggers the run method of the plugin when a menu tile is clicked', async () => {\n const testMenuPlugin1Def = sampleMenuPlugins.find(\n plugin => (plugin as PluginEntry).tagName === 'test-menu-plugin1',\n );\n const menuPluginElements =\n landingPage.shadowRoot!.querySelectorAll('.menu-plugin-item');\n\n const testMenuPlugin1Instance = oscdShell.shadowRoot?.querySelector(\n 'test-menu-plugin1',\n ) as TestMenuPlugin1;\n const menuPluginSpy = sinon.spy(testMenuPlugin1Instance, 'run');\n\n const testMenuPlugin1Button = Array.from(menuPluginElements).find(\n element =>\n element\n .querySelector('.menu-plugin-item-content span')\n ?.textContent?.trim() === testMenuPlugin1Def?.name,\n ) as OscdTextButton;\n testMenuPlugin1Button.click();\n await oscdShell.updateComplete;\n\n expect(menuPluginSpy.calledOnce).to.be.true;\n });\n});\n\ndescribe('custom landing-page', () => {\n let oscdShell: OscdShell;\n // let landingPage: LandingPage;\n\n beforeEach(async () => {\n oscdShell = <OscdShell>await fixture(\n html`<oscd-shell>\n <div slot=\"landing-page\" class=\"my-custom-landing-page\">\n <h1>Custom Landing Page</h1>\n </div>\n </oscd-shell>`,\n );\n await waitForAllPluginsToInstantiate(oscdShell);\n });\n\n it('loads a custom landing page if no document is loaded', async () => {\n const landingPageSlot = oscdShell.shadowRoot!.querySelector(\n 'slot[name=\"landing-page\"]',\n ) as HTMLSlotElement;\n expect(landingPageSlot).to.exist;\n expect(landingPageSlot?.assignedElements().length).to.equal(1);\n const customLandingPage = landingPageSlot?.assignedElements()[0];\n expect(customLandingPage).to.exist;\n });\n\n it('it no longer loads the landing page when a document is loaded', async () => {\n const defaultLandingPage =\n oscdShell.shadowRoot!.querySelector('landing-page');\n expect(defaultLandingPage).to.be.null;\n });\n});\n"]}
@@ -1,5 +1,13 @@
1
1
  export declare const templates: {
2
+ s44851a8adf059eef: string;
3
+ s5d929ff1619ac0c9: string;
2
4
  s6d8c02aee480af7a: string;
5
+ s7293d04c5979a8ad: string;
3
6
  s7417792bbe720149: string;
7
+ s8f10b4e57121e256: string;
4
8
  s8f4be9f086eb530f: string;
9
+ sd1fdd3cc8714d686: import("@lit/localize").StrResult;
10
+ sf8256ec799969cb7: import("@lit/localize").StrResult;
11
+ s3e2b2947e76caf9c: string;
12
+ s5f4586bc1e2740e6: string;
5
13
  };
@@ -1,10 +1,19 @@
1
1
  // Do not modify this file by hand!
2
2
  // Re-generate this file by running lit-localize
3
+ import { str } from '@lit/localize';
3
4
  /* eslint-disable no-irregular-whitespace */
4
5
  /* eslint-disable @typescript-eslint/no-explicit-any */
5
6
  export const templates = {
7
+ 's44851a8adf059eef': `Angeheftet`,
8
+ 's5d929ff1619ac0c9': `Suche`,
6
9
  's6d8c02aee480af7a': `Menü`,
10
+ 's7293d04c5979a8ad': `Seitenleiste ausklappen`,
7
11
  's7417792bbe720149': `Wiederholen`,
12
+ 's8f10b4e57121e256': `Seitenleiste einklappen`,
8
13
  's8f4be9f086eb530f': `Rückgängig`,
14
+ 'sd1fdd3cc8714d686': str `${0} anheften`,
15
+ 'sf8256ec799969cb7': str `${0} lösen`,
16
+ 's3e2b2947e76caf9c': `Items you pin will appear here`,
17
+ 's5f4586bc1e2740e6': `Clear search`,
9
18
  };
10
19
  //# sourceMappingURL=de.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"de.js","sourceRoot":"","sources":["../../src/locales/de.ts"],"names":[],"mappings":"AACI,mCAAmC;AACnC,gDAAgD;AAKhD,4CAA4C;AAC5C,uDAAuD;AAEvD,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,mBAAmB,EAAE,MAAM;IACjC,mBAAmB,EAAE,aAAa;IAClC,mBAAmB,EAAE,YAAY;CAC5B,CAAC","sourcesContent":["\n // Do not modify this file by hand!\n // Re-generate this file by running lit-localize\n\n \n \n\n /* eslint-disable no-irregular-whitespace */\n /* eslint-disable @typescript-eslint/no-explicit-any */\n\n export const templates = {\n 's6d8c02aee480af7a': `Menü`,\n's7417792bbe720149': `Wiederholen`,\n's8f4be9f086eb530f': `Rückgängig`,\n };\n "]}
1
+ {"version":3,"file":"de.js","sourceRoot":"","sources":["../../src/locales/de.ts"],"names":[],"mappings":"AACI,mCAAmC;AACnC,gDAAgD;AAGhD,OAAO,EAAC,GAAG,EAAC,MAAM,eAAe,CAAC;AAElC,4CAA4C;AAC5C,uDAAuD;AAEvD,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,mBAAmB,EAAE,YAAY;IACvC,mBAAmB,EAAE,OAAO;IAC5B,mBAAmB,EAAE,MAAM;IAC3B,mBAAmB,EAAE,yBAAyB;IAC9C,mBAAmB,EAAE,aAAa;IAClC,mBAAmB,EAAE,yBAAyB;IAC9C,mBAAmB,EAAE,YAAY;IACjC,mBAAmB,EAAE,GAAG,CAAA,GAAG,CAAC,WAAW;IACvC,mBAAmB,EAAE,GAAG,CAAA,GAAG,CAAC,QAAQ;IACpC,mBAAmB,EAAE,gCAAgC;IACrD,mBAAmB,EAAE,cAAc;CAC9B,CAAC","sourcesContent":["\n // Do not modify this file by hand!\n // Re-generate this file by running lit-localize\n\n \n import {str} from '@lit/localize';\n\n /* eslint-disable no-irregular-whitespace */\n /* eslint-disable @typescript-eslint/no-explicit-any */\n\n export const templates = {\n 's44851a8adf059eef': `Angeheftet`,\n's5d929ff1619ac0c9': `Suche`,\n's6d8c02aee480af7a': `Menü`,\n's7293d04c5979a8ad': `Seitenleiste ausklappen`,\n's7417792bbe720149': `Wiederholen`,\n's8f10b4e57121e256': `Seitenleiste einklappen`,\n's8f4be9f086eb530f': `Rückgängig`,\n'sd1fdd3cc8714d686': str`${0} anheften`,\n'sf8256ec799969cb7': str`${0} lösen`,\n's3e2b2947e76caf9c': `Items you pin will appear here`,\n's5f4586bc1e2740e6': `Clear search`,\n };\n "]}
@@ -21,7 +21,7 @@ let FilesMenu = class FilesMenu extends ScopedElementsMixin(LitElement) {
21
21
  trailing-icon
22
22
  >
23
23
  ${this.selectedDocName}
24
- <oscd-icon slot="icon">code</oscd-icon></oscd-filled-icon-button
24
+ <oscd-icon slot="icon">arrow_drop_down</oscd-icon></oscd-filled-icon-button
25
25
  >
26
26
  </oscd-text-button>
27
27
 
@@ -66,14 +66,13 @@ FilesMenu.styles = css `
66
66
  --md-text-button-label-text-weight: var(--file-menu-text-weight);
67
67
  --md-text-button-label-text-size: var(--file-menu-text-size);
68
68
  --md-text-button-label-text-style: normal;
69
+ /* Local colour scheme: the text button derives its label, icon and
70
+ state-layer colours from the system primary colour. */
69
71
  --md-sys-color-primary: var(--file-menu-text-color);
72
+ --md-text-button-icon-size: 24px;
70
73
  display: inline;
71
74
  }
72
75
 
73
- :host oscd-text-button oscd-icon {
74
- transform: rotate(90deg);
75
- }
76
-
77
76
  oscd-menu {
78
77
  min-width: var(--plugins-menu-min-width);
79
78
  padding: var(--plugins-menu-padding);
@@ -1 +1 @@
1
- {"version":3,"file":"files-menu.js","sourceRoot":"","sources":["../../src/menus/files-menu.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,6CAA6C,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,iDAAiD,CAAC;AAU1E,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,mBAAmB,CAAC,UAAU,CAAC;IAAvD;;QAQL,gBAAgB;QAGhB,iBAAY,GAAa,EAAE,CAAC;IA6F9B,CAAC;IAhFC,MAAM;QACJ,OAAO,IAAI,CAAA;;;mBAGI,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;;;YAG7B,IAAI,CAAC,eAAe;;;;;;;;;;;UAWtB,IAAI,CAAC,YAAY,CAAC,GAAG,CACrB,IAAI,CAAC,EAAE,CACL,IAAI,CAAA;uBACO,GAAG,EAAE;YACZ,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,QAAQ,EAAE;gBACxB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,EAAE,IAAI,EAAE;aACjB,CAAC,CACH,CAAC;QACJ,CAAC;0BACW,IAAI,CAAC,eAAe,KAAK,IAAI;iBACtC,IAAI;cACP,CACL;;KAEJ,CAAC;IACJ,CAAC;;AA3DM,wBAAc,GAAG;IACtB,kBAAkB,EAAE,cAAc;IAClC,WAAW,EAAE,QAAQ;IACrB,WAAW,EAAE,QAAQ;IACrB,gBAAgB,EAAE,YAAY;CAC/B,AALoB,CAKnB;AAwDK,gBAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyClB,AAzCY,CAyCX;AA5FF;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;+CACE;AAG5B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;kDACS;AAGpC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;yCACvB;AAKnB;IADC,KAAK,CAAC,WAAW,CAAC;uCACH;AAtBL,SAAS;IADrB,SAAS,EAAE;GACC,SAAS,CAwGrB","sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js';\nimport { localized } from '@lit/localize';\n\nimport { OscdIcon } from '@omicronenergy/oscd-ui/icon/OscdIcon.js';\nimport { OscdMenu } from '@omicronenergy/oscd-ui/menu/OscdMenu.js';\nimport { OscdMenuItem } from '@omicronenergy/oscd-ui/menu/OscdMenuItem.js';\nimport { OscdTextButton } from '@omicronenergy/oscd-ui/button/OscdTextButton.js';\n\nimport { LocaleTag } from '../localization.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'files-menu': FilesMenu;\n }\n}\n@localized()\nexport class FilesMenu extends ScopedElementsMixin(LitElement) {\n static scopedElements = {\n 'oscd-text-button': OscdTextButton,\n 'oscd-icon': OscdIcon,\n 'oscd-menu': OscdMenu,\n 'oscd-menu-item': OscdMenuItem,\n };\n\n /* Properties */\n\n @property({ type: Array })\n editableDocs: string[] = [];\n\n @property({ type: String })\n selectedDocName: string | undefined;\n\n @property({ type: String, reflect: true })\n locale!: LocaleTag;\n\n /* Queries */\n\n @query('#fileMenu')\n menu!: OscdMenu;\n\n render() {\n return html`\n <oscd-text-button\n id=\"fileMenuButton\"\n @click=${() => this.menu.show()}\n trailing-icon\n >\n ${this.selectedDocName}\n <oscd-icon slot=\"icon\">code</oscd-icon></oscd-filled-icon-button\n >\n </oscd-text-button>\n\n <oscd-menu\n fixed\n id=\"fileMenu\"\n anchor=\"fileMenuButton\"\n corner=\"BOTTOM_END\"\n >\n ${this.editableDocs.map(\n name =>\n html`<oscd-menu-item\n @click=${() => {\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: { name },\n }),\n );\n }}\n ?selected=${this.selectedDocName === name}\n >${name}</oscd-menu-item\n >`,\n )}\n </oscd-menu>\n `;\n }\n\n static styles = css`\n :host {\n position: relative;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n :host oscd-text-button {\n --md-text-button-label-text-line-height: normal;\n --md-text-button-label-text-family: var(--file-menu-text-font-family);\n --md-text-button-label-text-weight: var(--file-menu-text-weight);\n --md-text-button-label-text-size: var(--file-menu-text-size);\n --md-text-button-label-text-style: normal;\n --md-sys-color-primary: var(--file-menu-text-color);\n display: inline;\n }\n\n :host oscd-text-button oscd-icon {\n transform: rotate(90deg);\n }\n\n oscd-menu {\n min-width: var(--plugins-menu-min-width);\n padding: var(--plugins-menu-padding);\n --md-menu-container-color: var(--plugins-menu-container-color);\n }\n\n oscd-menu-item {\n width: 100%;\n --md-menu-item-label-text-color: var(--plugins-menu-item-label-color);\n --md-menu-item-leading-icon-color: var(\n --plugins-menu-item-leading-icon-color\n );\n --md-menu-item-selected-container-color: var(\n --plugins-menu-item-selected-container-color\n );\n --md-menu-item-selected-label-text-color: var(\n --plugins-menu-item-selected-label-color\n );\n }\n `;\n}\n"]}
1
+ {"version":3,"file":"files-menu.js","sourceRoot":"","sources":["../../src/menus/files-menu.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,6CAA6C,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,iDAAiD,CAAC;AAU1E,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,mBAAmB,CAAC,UAAU,CAAC;IAAvD;;QAQL,gBAAgB;QAGhB,iBAAY,GAAa,EAAE,CAAC;IA4F9B,CAAC;IA/EC,MAAM;QACJ,OAAO,IAAI,CAAA;;;mBAGI,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;;;YAG7B,IAAI,CAAC,eAAe;;;;;;;;;;;UAWtB,IAAI,CAAC,YAAY,CAAC,GAAG,CACrB,IAAI,CAAC,EAAE,CACL,IAAI,CAAA;uBACO,GAAG,EAAE;YACZ,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,QAAQ,EAAE;gBACxB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,EAAE,IAAI,EAAE;aACjB,CAAC,CACH,CAAC;QACJ,CAAC;0BACW,IAAI,CAAC,eAAe,KAAK,IAAI;iBACtC,IAAI;cACP,CACL;;KAEJ,CAAC;IACJ,CAAC;;AA3DM,wBAAc,GAAG;IACtB,kBAAkB,EAAE,cAAc;IAClC,WAAW,EAAE,QAAQ;IACrB,WAAW,EAAE,QAAQ;IACrB,gBAAgB,EAAE,YAAY;CAC/B,AALoB,CAKnB;AAwDK,gBAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwClB,AAxCY,CAwCX;AA3FF;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;+CACE;AAG5B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;kDACS;AAGpC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;yCACvB;AAKnB;IADC,KAAK,CAAC,WAAW,CAAC;uCACH;AAtBL,SAAS;IADrB,SAAS,EAAE;GACC,SAAS,CAuGrB","sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js';\nimport { localized } from '@lit/localize';\n\nimport { OscdIcon } from '@omicronenergy/oscd-ui/icon/OscdIcon.js';\nimport { OscdMenu } from '@omicronenergy/oscd-ui/menu/OscdMenu.js';\nimport { OscdMenuItem } from '@omicronenergy/oscd-ui/menu/OscdMenuItem.js';\nimport { OscdTextButton } from '@omicronenergy/oscd-ui/button/OscdTextButton.js';\n\nimport { LocaleTag } from '../localization.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'files-menu': FilesMenu;\n }\n}\n@localized()\nexport class FilesMenu extends ScopedElementsMixin(LitElement) {\n static scopedElements = {\n 'oscd-text-button': OscdTextButton,\n 'oscd-icon': OscdIcon,\n 'oscd-menu': OscdMenu,\n 'oscd-menu-item': OscdMenuItem,\n };\n\n /* Properties */\n\n @property({ type: Array })\n editableDocs: string[] = [];\n\n @property({ type: String })\n selectedDocName: string | undefined;\n\n @property({ type: String, reflect: true })\n locale!: LocaleTag;\n\n /* Queries */\n\n @query('#fileMenu')\n menu!: OscdMenu;\n\n render() {\n return html`\n <oscd-text-button\n id=\"fileMenuButton\"\n @click=${() => this.menu.show()}\n trailing-icon\n >\n ${this.selectedDocName}\n <oscd-icon slot=\"icon\">arrow_drop_down</oscd-icon></oscd-filled-icon-button\n >\n </oscd-text-button>\n\n <oscd-menu\n fixed\n id=\"fileMenu\"\n anchor=\"fileMenuButton\"\n corner=\"BOTTOM_END\"\n >\n ${this.editableDocs.map(\n name =>\n html`<oscd-menu-item\n @click=${() => {\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: { name },\n }),\n );\n }}\n ?selected=${this.selectedDocName === name}\n >${name}</oscd-menu-item\n >`,\n )}\n </oscd-menu>\n `;\n }\n\n static styles = css`\n :host {\n position: relative;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n :host oscd-text-button {\n --md-text-button-label-text-line-height: normal;\n --md-text-button-label-text-family: var(--file-menu-text-font-family);\n --md-text-button-label-text-weight: var(--file-menu-text-weight);\n --md-text-button-label-text-size: var(--file-menu-text-size);\n --md-text-button-label-text-style: normal;\n /* Local colour scheme: the text button derives its label, icon and\n state-layer colours from the system primary colour. */\n --md-sys-color-primary: var(--file-menu-text-color);\n --md-text-button-icon-size: 24px;\n display: inline;\n }\n\n oscd-menu {\n min-width: var(--plugins-menu-min-width);\n padding: var(--plugins-menu-padding);\n --md-menu-container-color: var(--plugins-menu-container-color);\n }\n\n oscd-menu-item {\n width: 100%;\n --md-menu-item-label-text-color: var(--plugins-menu-item-label-color);\n --md-menu-item-leading-icon-color: var(\n --plugins-menu-item-leading-icon-color\n );\n --md-menu-item-selected-container-color: var(\n --plugins-menu-item-selected-container-color\n );\n --md-menu-item-selected-label-text-color: var(\n --plugins-menu-item-selected-label-color\n );\n }\n `;\n}\n"]}
@@ -2,12 +2,13 @@ import { LitElement } from 'lit';
2
2
  import { OscdFilledIconButton } from '@omicronenergy/oscd-ui/iconbutton/OscdFilledIconButton.js';
3
3
  import { OscdIcon } from '@omicronenergy/oscd-ui/icon/OscdIcon.js';
4
4
  import { OscdMenu } from '@omicronenergy/oscd-ui/menu/OscdMenu.js';
5
+ import { OscdSubMenu } from '@omicronenergy/oscd-ui/menu/OscdSubMenu.js';
5
6
  import { OscdMenuItem } from '@omicronenergy/oscd-ui/menu/OscdMenuItem.js';
6
7
  import { LocaleTag } from '../localization.js';
7
- import { PluginEntry } from '../oscd-shell.js';
8
+ import { PluginEntry, PluginGroup } from '../oscd-shell.js';
8
9
  declare global {
9
10
  interface HTMLElementTagNameMap {
10
- 'plugin-menu': PluginsMenu;
11
+ 'plugins-menu': PluginsMenu;
11
12
  }
12
13
  }
13
14
  declare const PluginsMenu_base: typeof LitElement & import("@open-wc/scoped-elements/lit-element.js").ScopedElementsHostConstructor;
@@ -16,6 +17,7 @@ export declare class PluginsMenu extends PluginsMenu_base {
16
17
  'oscd-filled-icon-button': typeof OscdFilledIconButton;
17
18
  'oscd-icon': typeof OscdIcon;
18
19
  'oscd-menu': typeof OscdMenu;
20
+ 'oscd-sub-menu': typeof OscdSubMenu;
19
21
  'oscd-menu-item': typeof OscdMenuItem;
20
22
  };
21
23
  editableDocs: string[];
@@ -25,7 +27,8 @@ export declare class PluginsMenu extends PluginsMenu_base {
25
27
  locale: LocaleTag;
26
28
  open: () => void;
27
29
  menu: OscdMenu;
28
- renderMenuItem(plugin: PluginEntry, disabled: boolean): import("lit-html").TemplateResult<1>;
30
+ renderMenuGroup(plugin: PluginGroup<PluginEntry>, hasDoc: boolean): import("lit-html").TemplateResult<1>;
31
+ renderMenuItem(plugin: PluginEntry, hasDoc: boolean): import("lit-html").TemplateResult<1>;
29
32
  render(): import("lit-html").TemplateResult<1>;
30
33
  static styles: import("lit").CSSResult;
31
34
  }
@@ -6,7 +6,9 @@ import { localized, msg } from '@lit/localize';
6
6
  import { OscdFilledIconButton } from '@omicronenergy/oscd-ui/iconbutton/OscdFilledIconButton.js';
7
7
  import { OscdIcon } from '@omicronenergy/oscd-ui/icon/OscdIcon.js';
8
8
  import { OscdMenu } from '@omicronenergy/oscd-ui/menu/OscdMenu.js';
9
+ import { OscdSubMenu } from '@omicronenergy/oscd-ui/menu/OscdSubMenu.js';
9
10
  import { OscdMenuItem } from '@omicronenergy/oscd-ui/menu/OscdMenuItem.js';
11
+ import { isPluginGroup } from '../utils/plugin-utils.js';
10
12
  let PluginsMenu = class PluginsMenu extends ScopedElementsMixin(LitElement) {
11
13
  constructor() {
12
14
  super(...arguments);
@@ -17,10 +19,28 @@ let PluginsMenu = class PluginsMenu extends ScopedElementsMixin(LitElement) {
17
19
  this.menu.show();
18
20
  };
19
21
  }
20
- renderMenuItem(plugin, disabled) {
22
+ renderMenuGroup(plugin, hasDoc) {
23
+ return html `
24
+ <oscd-sub-menu>
25
+ <oscd-menu-item slot="item">
26
+ <oscd-icon slot="start">${plugin.icon}</oscd-icon>
27
+ <div slot="headline">
28
+ ${plugin.translations?.[this.locale] || plugin.name}
29
+ </div>
30
+ <oscd-icon slot="end">arrow_right</oscd-icon>
31
+ </oscd-menu-item>
32
+ <oscd-menu slot="menu">
33
+ ${plugin.plugins.map(plugin => {
34
+ return this.renderMenuItem(plugin, hasDoc);
35
+ })}
36
+ </oscd-menu>
37
+ </oscd-sub-menu>
38
+ `;
39
+ }
40
+ renderMenuItem(plugin, hasDoc) {
21
41
  return html `
22
42
  <oscd-menu-item
23
- .disabled=${disabled}
43
+ .disabled=${!!plugin.requireDoc && !hasDoc}
24
44
  @click=${() => {
25
45
  this.dispatchEvent(new CustomEvent('menu-plugin-select', {
26
46
  detail: { plugin },
@@ -52,15 +72,22 @@ let PluginsMenu = class PluginsMenu extends ScopedElementsMixin(LitElement) {
52
72
  this.menu.show();
53
73
  }
54
74
  }}
55
- ><oscd-icon>arrow_drop_down_circle</oscd-icon></oscd-filled-icon-button
75
+ ><oscd-icon>arrow_drop_down</oscd-icon></oscd-filled-icon-button
56
76
  >
57
77
  <oscd-menu
78
+ has-overflow
58
79
  quick
59
80
  anchor="menu-button"
60
81
  menuCorner="START_END"
61
82
  anchorCorner="START_END"
62
83
  >
63
- ${this.menuPlugins.map(plugin => this.renderMenuItem(plugin, !!(plugin.requireDoc && (this.editableDocs ?? []).length === 0)))}
84
+ ${this.menuPlugins.map(plugin => {
85
+ const hasDoc = (this.editableDocs ?? []).length > 0;
86
+ if (isPluginGroup(plugin)) {
87
+ return this.renderMenuGroup(plugin, hasDoc);
88
+ }
89
+ return this.renderMenuItem(plugin, hasDoc);
90
+ })}
64
91
  </oscd-menu>
65
92
  `;
66
93
  }
@@ -69,18 +96,20 @@ PluginsMenu.scopedElements = {
69
96
  'oscd-filled-icon-button': OscdFilledIconButton,
70
97
  'oscd-icon': OscdIcon,
71
98
  'oscd-menu': OscdMenu,
99
+ 'oscd-sub-menu': OscdSubMenu,
72
100
  'oscd-menu-item': OscdMenuItem,
73
101
  };
74
102
  PluginsMenu.styles = css `
75
103
  :host {
76
104
  display: flex;
77
105
  align-items: center;
78
- gap: 4px;
79
106
  }
80
107
 
81
108
  img {
82
109
  height: var(--app-bar-app-icon-height);
83
110
  width: var(--app-bar-app-icon-width);
111
+ /* Logical property so the spacing follows the writing direction. */
112
+ margin-inline-end: var(--app-bar-logo-gap);
84
113
  }
85
114
 
86
115
  :host h1.app-title {
@@ -91,8 +120,20 @@ PluginsMenu.styles = css `
91
120
  line-height: var(--app-bar-title-text-line-height);
92
121
  letter-spacing: var(--app-bar-title-text-letter-spacing);
93
122
  color: var(--app-bar-title-text-color);
123
+ /* As a flex item the h1 is blockified, so its UA block margins would
124
+ otherwise apply; the app bar owns this element's spacing. */
125
+ margin-block: 0;
126
+ margin-inline: 0 var(--app-bar-title-menu-gap);
94
127
  display: inline;
95
128
  }
129
+
130
+ oscd-filled-icon-button {
131
+ /* Local colour scheme: icon colour and all derived state layers follow
132
+ from the system colour, so only the size needs setting explicitly. */
133
+ --md-sys-color-on-primary: var(--plugins-menu-button-color);
134
+ --md-filled-icon-button-icon-size: var(--plugins-menu-button-size);
135
+ }
136
+
96
137
  oscd-menu {
97
138
  min-width: var(--plugins-menu-min-width);
98
139
  padding: var(--plugins-menu-padding);
@@ -1 +1 @@
1
- {"version":3,"file":"plugins-menu.js","sourceRoot":"","sources":["../../src/menus/plugins-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, nothing } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js';\nimport { localized, msg } from '@lit/localize';\n\nimport { OscdFilledIconButton } from '@omicronenergy/oscd-ui/iconbutton/OscdFilledIconButton.js';\nimport { OscdIcon } from '@omicronenergy/oscd-ui/icon/OscdIcon.js';\nimport { OscdMenu } from '@omicronenergy/oscd-ui/menu/OscdMenu.js';\nimport { OscdMenuItem } from '@omicronenergy/oscd-ui/menu/OscdMenuItem.js';\n\nimport { LocaleTag, Translation } from '../localization.js';\nimport { PluginEntry } from '../oscd-shell.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'plugin-menu': PluginsMenu;\n }\n}\n\n@localized()\nexport class PluginsMenu extends ScopedElementsMixin(LitElement) {\n static scopedElements = {\n 'oscd-filled-icon-button': OscdFilledIconButton,\n 'oscd-icon': OscdIcon,\n 'oscd-menu': OscdMenu,\n 'oscd-menu-item': OscdMenuItem,\n };\n\n /* Properties */\n @property({ type: Array })\n editableDocs: string[] = [];\n\n @property({ type: Array })\n menuPlugins: PluginEntry[] = [];\n\n @property({ type: String })\n appIcon!: string;\n\n @property({ type: String })\n appTitle!: string;\n\n @property({ type: String, reflect: true })\n locale!: LocaleTag;\n\n @property({ type: String, reflect: true })\n open = () => {\n this.menu.show();\n };\n\n /* Queries */\n @query('oscd-menu')\n menu!: OscdMenu;\n\n renderMenuItem(plugin: PluginEntry, disabled: boolean) {\n return html`\n <oscd-menu-item\n .disabled=${disabled}\n @click=${() => {\n this.dispatchEvent(\n new CustomEvent('menu-plugin-select', {\n detail: { plugin },\n bubbles: true,\n composed: true,\n }),\n );\n this.menu.close();\n }}\n >\n <oscd-icon slot=\"start\">${plugin.icon}</oscd-icon>\n <div slot=\"headline\">\n ${plugin.translations?.[this.locale as Translation] || plugin.name}\n </div>\n </oscd-menu-item>\n `;\n }\n\n render() {\n return html`\n ${this.appIcon ? html`<img src=${this.appIcon} alt=\"logo\" />` : nothing}\n <h1 class=\"app-title\">${this.appTitle}</h1>\n <oscd-filled-icon-button\n id=\"menu-button\"\n aria-label=\"${msg('Menu')}\"\n @click=${async () => {\n if (this.menu.open) {\n this.menu.close();\n } else {\n this.menu.show();\n }\n }}\n ><oscd-icon>arrow_drop_down_circle</oscd-icon></oscd-filled-icon-button\n >\n <oscd-menu\n quick\n anchor=\"menu-button\"\n menuCorner=\"START_END\"\n anchorCorner=\"START_END\"\n >\n ${this.menuPlugins.map(plugin =>\n this.renderMenuItem(\n plugin,\n !!(plugin.requireDoc && (this.editableDocs ?? []).length === 0),\n ),\n )}\n </oscd-menu>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n img {\n height: var(--app-bar-app-icon-height);\n width: var(--app-bar-app-icon-width);\n }\n\n :host h1.app-title {\n font-family: var(--app-bar-title-text-font-family);\n font-size: var(--app-bar-title-text-font-size);\n font-style: var(--app-bar-title-text-font-style);\n font-weight: var(--app-bar-title-text-font-weight);\n line-height: var(--app-bar-title-text-line-height);\n letter-spacing: var(--app-bar-title-text-letter-spacing);\n color: var(--app-bar-title-text-color);\n display: inline;\n }\n oscd-menu {\n min-width: var(--plugins-menu-min-width);\n padding: var(--plugins-menu-padding);\n --md-menu-container-color: var(--plugins-menu-container-color);\n }\n\n oscd-menu-item {\n width: 100%;\n --md-menu-item-label-text-color: var(--plugins-menu-item-label-color);\n --md-menu-item-leading-icon-color: var(\n --plugins-menu-item-leading-icon-color\n );\n --md-menu-item-selected-container-color: var(\n --plugins-menu-item-selected-container-color\n );\n --md-menu-item-selected-label-text-color: var(\n --plugins-menu-item-selected-label-color\n );\n }\n `;\n}\n"]}
1
+ {"version":3,"file":"plugins-menu.js","sourceRoot":"","sources":["../../src/menus/plugins-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, nothing } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js';\nimport { localized, msg } from '@lit/localize';\n\nimport { OscdFilledIconButton } from '@omicronenergy/oscd-ui/iconbutton/OscdFilledIconButton.js';\nimport { OscdIcon } from '@omicronenergy/oscd-ui/icon/OscdIcon.js';\nimport { OscdMenu } from '@omicronenergy/oscd-ui/menu/OscdMenu.js';\nimport { OscdSubMenu } from '@omicronenergy/oscd-ui/menu/OscdSubMenu.js';\nimport { OscdMenuItem } from '@omicronenergy/oscd-ui/menu/OscdMenuItem.js';\n\nimport { LocaleTag, Translation } from '../localization.js';\nimport { PluginEntry, PluginGroup } from '../oscd-shell.js';\nimport { isPluginGroup } from '../utils/plugin-utils.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'plugins-menu': PluginsMenu;\n }\n}\n\n@localized()\nexport class PluginsMenu extends ScopedElementsMixin(LitElement) {\n static scopedElements = {\n 'oscd-filled-icon-button': OscdFilledIconButton,\n 'oscd-icon': OscdIcon,\n 'oscd-menu': OscdMenu,\n 'oscd-sub-menu': OscdSubMenu,\n 'oscd-menu-item': OscdMenuItem,\n };\n\n /* Properties */\n @property({ type: Array })\n editableDocs: string[] = [];\n\n @property({ type: Array })\n menuPlugins: PluginEntry[] = [];\n\n @property({ type: String })\n appIcon!: string;\n\n @property({ type: String })\n appTitle!: string;\n\n @property({ type: String, reflect: true })\n locale!: LocaleTag;\n\n @property({ type: String, reflect: true })\n open = () => {\n this.menu.show();\n };\n\n /* Queries */\n @query('oscd-menu')\n menu!: OscdMenu;\n\n renderMenuGroup(plugin: PluginGroup<PluginEntry>, hasDoc: boolean) {\n return html`\n <oscd-sub-menu>\n <oscd-menu-item slot=\"item\">\n <oscd-icon slot=\"start\">${plugin.icon}</oscd-icon>\n <div slot=\"headline\">\n ${plugin.translations?.[this.locale as Translation] || plugin.name}\n </div>\n <oscd-icon slot=\"end\">arrow_right</oscd-icon>\n </oscd-menu-item>\n <oscd-menu slot=\"menu\">\n ${plugin.plugins.map(plugin => {\n return this.renderMenuItem(plugin, hasDoc);\n })}\n </oscd-menu>\n </oscd-sub-menu>\n `;\n }\n\n renderMenuItem(plugin: PluginEntry, hasDoc: boolean) {\n return html`\n <oscd-menu-item\n .disabled=${!!plugin.requireDoc && !hasDoc}\n @click=${() => {\n this.dispatchEvent(\n new CustomEvent('menu-plugin-select', {\n detail: { plugin },\n bubbles: true,\n composed: true,\n }),\n );\n this.menu.close();\n }}\n >\n <oscd-icon slot=\"start\">${plugin.icon}</oscd-icon>\n <div slot=\"headline\">\n ${plugin.translations?.[this.locale as Translation] || plugin.name}\n </div>\n </oscd-menu-item>\n `;\n }\n\n render() {\n return html`\n ${this.appIcon ? html`<img src=${this.appIcon} alt=\"logo\" />` : nothing}\n <h1 class=\"app-title\">${this.appTitle}</h1>\n <oscd-filled-icon-button\n id=\"menu-button\"\n aria-label=\"${msg('Menu')}\"\n @click=${async () => {\n if (this.menu.open) {\n this.menu.close();\n } else {\n this.menu.show();\n }\n }}\n ><oscd-icon>arrow_drop_down</oscd-icon></oscd-filled-icon-button\n >\n <oscd-menu\n has-overflow\n quick\n anchor=\"menu-button\"\n menuCorner=\"START_END\"\n anchorCorner=\"START_END\"\n >\n ${this.menuPlugins.map(plugin => {\n const hasDoc = (this.editableDocs ?? []).length > 0;\n\n if (isPluginGroup(plugin)) {\n return this.renderMenuGroup(plugin, hasDoc);\n }\n return this.renderMenuItem(plugin, hasDoc);\n })}\n </oscd-menu>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n align-items: center;\n }\n\n img {\n height: var(--app-bar-app-icon-height);\n width: var(--app-bar-app-icon-width);\n /* Logical property so the spacing follows the writing direction. */\n margin-inline-end: var(--app-bar-logo-gap);\n }\n\n :host h1.app-title {\n font-family: var(--app-bar-title-text-font-family);\n font-size: var(--app-bar-title-text-font-size);\n font-style: var(--app-bar-title-text-font-style);\n font-weight: var(--app-bar-title-text-font-weight);\n line-height: var(--app-bar-title-text-line-height);\n letter-spacing: var(--app-bar-title-text-letter-spacing);\n color: var(--app-bar-title-text-color);\n /* As a flex item the h1 is blockified, so its UA block margins would\n otherwise apply; the app bar owns this element's spacing. */\n margin-block: 0;\n margin-inline: 0 var(--app-bar-title-menu-gap);\n display: inline;\n }\n\n oscd-filled-icon-button {\n /* Local colour scheme: icon colour and all derived state layers follow\n from the system colour, so only the size needs setting explicitly. */\n --md-sys-color-on-primary: var(--plugins-menu-button-color);\n --md-filled-icon-button-icon-size: var(--plugins-menu-button-size);\n }\n\n oscd-menu {\n min-width: var(--plugins-menu-min-width);\n padding: var(--plugins-menu-padding);\n --md-menu-container-color: var(--plugins-menu-container-color);\n }\n\n oscd-menu-item {\n width: 100%;\n --md-menu-item-label-text-color: var(--plugins-menu-item-label-color);\n --md-menu-item-leading-icon-color: var(\n --plugins-menu-item-leading-icon-color\n );\n --md-menu-item-selected-container-color: var(\n --plugins-menu-item-selected-container-color\n );\n --md-menu-item-selected-label-text-color: var(\n --plugins-menu-item-selected-label-color\n );\n }\n `;\n}\n"]}
@@ -16,6 +16,7 @@ describe('plugins-menu', () => {
16
16
  beforeEach(async () => {
17
17
  docs = createTestDocs(1);
18
18
  oscdShell = (await fixture(html `<oscd-shell
19
+ appIcon="none"
19
20
  .docs=${docs}
20
21
  docName=${Object.keys(docs)[0]}
21
22
  ></oscd-shell>`));
@@ -1 +1 @@
1
- {"version":3,"file":"plugins-menu.spec.js","sourceRoot":"","sources":["../../src/menus/plugins-menu.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture, html } from '@open-wc/testing';\nimport { OscdMenuItem } from '@omicronenergy/oscd-ui/menu/OscdMenuItem.js';\nimport type { OscdShell } from '../oscd-shell.js';\nimport '../oscd-shell.js';\nimport { PluginsMenu } from './plugins-menu.js';\nimport { createTestDocs } from '../utils/testing/test-doc-helpers.js';\nimport { OscdFilledIconButton } from '@omicronenergy/oscd-ui/iconbutton/OscdFilledIconButton.js';\nimport sinon from 'sinon';\nimport { LitElement } from 'lit';\nimport { sampleMenuPlugins } from '../utils/testing/plugin-helpers.js';\nimport { TestMenuPlugin1 } from '../utils/testing/test-plugins.js';\n\nconst findMenuOpenButton = (pluginsMenu: PluginsMenu) => {\n const menuOpenButton = pluginsMenu.shadowRoot?.querySelector(\n 'oscd-filled-icon-button',\n ) as OscdFilledIconButton;\n expect(menuOpenButton).to.exist;\n return menuOpenButton;\n};\n\ndescribe('plugins-menu', () => {\n let oscdShell: OscdShell;\n let pluginsMenu: PluginsMenu;\n let docs: Record<string, XMLDocument>;\n\n beforeEach(async () => {\n docs = createTestDocs(1);\n oscdShell = <OscdShell>(\n await fixture(\n html`<oscd-shell\n .docs=${docs}\n docName=${Object.keys(docs)[0]}\n ></oscd-shell>`,\n )\n );\n if (!oscdShell.registry?.get('test-menu-plugin1')) {\n oscdShell.registry?.define('test-menu-plugin1', TestMenuPlugin1);\n }\n oscdShell.plugins = {\n menu: sampleMenuPlugins,\n };\n pluginsMenu = oscdShell.shadowRoot!.querySelector('plugins-menu')!;\n await oscdShell.updateComplete;\n await pluginsMenu.updateComplete;\n });\n\n it('displays a menu item for each menu plugin', async () => {\n const menuOpenButton = findMenuOpenButton(pluginsMenu);\n menuOpenButton?.click();\n await pluginsMenu.updateComplete;\n expect(pluginsMenu.menu).to.have.property('open', true);\n expect(pluginsMenu.menu.children).to.have.length(\n oscdShell.plugins!.menu.length,\n );\n });\n\n it('executes the run() function of the associated plugin, when the plugin menu item is clicked', async () => {\n const menuPluginSelectSpy = sinon.spy();\n pluginsMenu.addEventListener('menu-plugin-select', menuPluginSelectSpy);\n\n const pluginRunSpy = sinon.spy();\n const menuPluginEntry = pluginsMenu.menuPlugins[0];\n const firstMenuPlugin = oscdShell.shadowRoot!.querySelector(\n menuPluginEntry.tagName,\n )! as unknown as LitElement & {\n run: () => void;\n };\n firstMenuPlugin.run = pluginRunSpy;\n\n const menuOpenButton = findMenuOpenButton(pluginsMenu);\n menuOpenButton?.click();\n await pluginsMenu.updateComplete;\n\n const firstMenuItem = pluginsMenu.menu.firstElementChild as OscdMenuItem;\n firstMenuItem.click();\n await pluginsMenu.updateComplete;\n\n expect(pluginRunSpy.calledOnce).to.be.true;\n });\n\n it('closes when clicking on the menu button, if its currently open', async () => {\n const menuOpenButton = findMenuOpenButton(pluginsMenu);\n menuOpenButton?.click();\n await pluginsMenu.updateComplete;\n expect(pluginsMenu.menu).to.have.property('open', true);\n\n // Click again to close\n menuOpenButton?.click();\n await pluginsMenu.updateComplete;\n expect(pluginsMenu.menu).to.have.property('open', false);\n });\n});\n"]}
1
+ {"version":3,"file":"plugins-menu.spec.js","sourceRoot":"","sources":["../../src/menus/plugins-menu.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture, html } from '@open-wc/testing';\nimport { OscdMenuItem } from '@omicronenergy/oscd-ui/menu/OscdMenuItem.js';\nimport type { OscdShell } from '../oscd-shell.js';\nimport '../oscd-shell.js';\nimport { PluginsMenu } from './plugins-menu.js';\nimport { createTestDocs } from '../utils/testing/test-doc-helpers.js';\nimport { OscdFilledIconButton } from '@omicronenergy/oscd-ui/iconbutton/OscdFilledIconButton.js';\nimport sinon from 'sinon';\nimport { LitElement } from 'lit';\nimport { sampleMenuPlugins } from '../utils/testing/plugin-helpers.js';\nimport { TestMenuPlugin1 } from '../utils/testing/test-plugins.js';\n\nconst findMenuOpenButton = (pluginsMenu: PluginsMenu) => {\n const menuOpenButton = pluginsMenu.shadowRoot?.querySelector(\n 'oscd-filled-icon-button',\n ) as OscdFilledIconButton;\n expect(menuOpenButton).to.exist;\n return menuOpenButton;\n};\n\ndescribe('plugins-menu', () => {\n let oscdShell: OscdShell;\n let pluginsMenu: PluginsMenu;\n let docs: Record<string, XMLDocument>;\n\n beforeEach(async () => {\n docs = createTestDocs(1);\n oscdShell = <OscdShell>(\n await fixture(\n html`<oscd-shell\n appIcon=\"none\"\n .docs=${docs}\n docName=${Object.keys(docs)[0]}\n ></oscd-shell>`,\n )\n );\n if (!oscdShell.registry?.get('test-menu-plugin1')) {\n oscdShell.registry?.define('test-menu-plugin1', TestMenuPlugin1);\n }\n oscdShell.plugins = {\n menu: sampleMenuPlugins,\n };\n pluginsMenu = oscdShell.shadowRoot!.querySelector('plugins-menu')!;\n await oscdShell.updateComplete;\n await pluginsMenu.updateComplete;\n });\n\n it('displays a menu item for each menu plugin', async () => {\n const menuOpenButton = findMenuOpenButton(pluginsMenu);\n menuOpenButton?.click();\n await pluginsMenu.updateComplete;\n expect(pluginsMenu.menu).to.have.property('open', true);\n expect(pluginsMenu.menu.children).to.have.length(\n oscdShell.plugins!.menu.length,\n );\n });\n\n it('executes the run() function of the associated plugin, when the plugin menu item is clicked', async () => {\n const menuPluginSelectSpy = sinon.spy();\n pluginsMenu.addEventListener('menu-plugin-select', menuPluginSelectSpy);\n\n const pluginRunSpy = sinon.spy();\n const menuPluginEntry = pluginsMenu.menuPlugins[0];\n const firstMenuPlugin = oscdShell.shadowRoot!.querySelector(\n menuPluginEntry.tagName,\n )! as unknown as LitElement & {\n run: () => void;\n };\n firstMenuPlugin.run = pluginRunSpy;\n\n const menuOpenButton = findMenuOpenButton(pluginsMenu);\n menuOpenButton?.click();\n await pluginsMenu.updateComplete;\n\n const firstMenuItem = pluginsMenu.menu.firstElementChild as OscdMenuItem;\n firstMenuItem.click();\n await pluginsMenu.updateComplete;\n\n expect(pluginRunSpy.calledOnce).to.be.true;\n });\n\n it('closes when clicking on the menu button, if its currently open', async () => {\n const menuOpenButton = findMenuOpenButton(pluginsMenu);\n menuOpenButton?.click();\n await pluginsMenu.updateComplete;\n expect(pluginsMenu.menu).to.have.property('open', true);\n\n // Click again to close\n menuOpenButton?.click();\n await pluginsMenu.updateComplete;\n expect(pluginsMenu.menu).to.have.property('open', false);\n });\n});\n"]}