@omicronenergy/oscd-shell 0.0.14 → 0.0.16

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 (34) hide show
  1. package/README.md +11 -6
  2. package/dist/landing-page/landing-page.d.ts +3 -3
  3. package/dist/landing-page/landing-page.js.map +1 -1
  4. package/dist/landing-page/landing-page.spec.js +1 -1
  5. package/dist/landing-page/landing-page.spec.js.map +1 -1
  6. package/dist/localization.js +1 -1
  7. package/dist/localization.js.map +1 -1
  8. package/dist/menus/files-menu.d.ts +1 -1
  9. package/dist/menus/plugins-menu.d.ts +5 -5
  10. package/dist/menus/plugins-menu.js +2 -2
  11. package/dist/menus/plugins-menu.js.map +1 -1
  12. package/dist/oscd-shell-design-tokens.d.ts +1 -1
  13. package/dist/oscd-shell-design-tokens.js +12 -1
  14. package/dist/oscd-shell-design-tokens.js.map +1 -1
  15. package/dist/oscd-shell.d.ts +45 -17
  16. package/dist/oscd-shell.js +36 -12
  17. package/dist/oscd-shell.js.map +1 -1
  18. package/dist/side-panel/build-tree-nodes.spec.js.map +1 -1
  19. package/dist/side-panel/editor-plugins-panel.d.ts +6 -6
  20. package/dist/side-panel/editor-plugins-panel.js +6 -0
  21. package/dist/side-panel/editor-plugins-panel.js.map +1 -1
  22. package/dist/side-panel/editor-plugins-panel.spec.js +10 -7
  23. package/dist/side-panel/editor-plugins-panel.spec.js.map +1 -1
  24. package/dist/utils/plugin-utils.d.ts +28 -21
  25. package/dist/utils/plugin-utils.js +12 -19
  26. package/dist/utils/plugin-utils.js.map +1 -1
  27. package/dist/utils/plugin-utils.spec.js +30 -5
  28. package/dist/utils/plugin-utils.spec.js.map +1 -1
  29. package/dist/utils/testing/plugin-helpers.d.ts +6 -15
  30. package/dist/utils/testing/plugin-helpers.js +3 -3
  31. package/dist/utils/testing/plugin-helpers.js.map +1 -1
  32. package/dist/utils/testing/test-plugins.js +1 -1
  33. package/dist/utils/testing/test-plugins.js.map +1 -1
  34. package/package.json +18 -58
package/README.md CHANGED
@@ -34,9 +34,9 @@ To automatically fix linting and formatting errors, run
34
34
  npm run format
35
35
  ```
36
36
 
37
- We use ESLint and Prettier for linting and formatting. Plugins for automatic
38
- formatting and linting during editing are available for vim, emacs, VSCode,
39
- and all popular IDEs.
37
+ Linting and formatting are centralized in
38
+ [`@omicronenergy/oscd-tooling`](https://github.com/OMICRONEnergyOSS/oscd-tooling),
39
+ which runs ESLint (with `@stylistic` for formatting) via the `oscd` CLI.
40
40
 
41
41
  ## Testing with Web Test Runner
42
42
 
@@ -52,10 +52,15 @@ To run the tests in interactive watch mode run:
52
52
  npm run test:watch
53
53
  ```
54
54
 
55
- ## Tooling configs
55
+ ## Tooling
56
56
 
57
- For most of the tools, the configuration is in the `package.json` to reduce the
58
- amount of files in the project.
57
+ Build, lint, test, bundle, and deploy tooling is centralized in
58
+ [`@omicronenergy/oscd-tooling`](https://github.com/OMICRONEnergyOSS/oscd-tooling)
59
+ and run via the `oscd` CLI (see `package.json` scripts). This project keeps
60
+ its own `rollup.config.js` and `web-test-runner.config.js` because its build
61
+ has needs (multi-entry bundling, a custom test harness) that diverge from the
62
+ shared defaults — `oscd` automatically prefers a project-local config file of
63
+ the same name over its own default.
59
64
 
60
65
  ## Local Demo with `web-dev-server`
61
66
 
@@ -1,7 +1,7 @@
1
1
  import { LitElement } from 'lit';
2
2
  import { OscdIcon } from '@omicronenergy/oscd-ui/icon/OscdIcon.js';
3
3
  import { OscdTextButton } from '@omicronenergy/oscd-ui/button/OscdTextButton.js';
4
- import { PluginEntry } from '../oscd-shell.js';
4
+ import { ResolvedPlugin } from '../oscd-shell.js';
5
5
  import { LocaleTag } from '../localization.js';
6
6
  import { OscdElevation } from '@omicronenergy/oscd-ui/elevation/OscdElevation.js';
7
7
  declare global {
@@ -9,7 +9,7 @@ declare global {
9
9
  'landing-page': LandingPage;
10
10
  }
11
11
  }
12
- declare const LandingPage_base: typeof LitElement & import("@open-wc/scoped-elements/lit-element.js").ScopedElementsHostConstructor;
12
+ declare const LandingPage_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost> & import("@open-wc/scoped-elements/types.js").ScopedElementsHostConstructor;
13
13
  export declare class LandingPage extends LandingPage_base {
14
14
  static scopedElements: {
15
15
  'oscd-icon': typeof OscdIcon;
@@ -18,7 +18,7 @@ export declare class LandingPage extends LandingPage_base {
18
18
  };
19
19
  heading: string;
20
20
  subHeading: string;
21
- menuPlugins: PluginEntry[];
21
+ menuPlugins: ResolvedPlugin[];
22
22
  locale: LocaleTag;
23
23
  render(): import("lit-html").TemplateResult<1>;
24
24
  static styles: import("lit").CSSResult;
@@ -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;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"]}
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,GAAqB,EAAE,CAAC;IAwIrC,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;gDACS;AAGnC;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 { ResolvedPlugin } 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: ResolvedPlugin[] = [];\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"]}
@@ -46,7 +46,7 @@ describe('default landing-page', () => {
46
46
  expect(landingPageAfterOpen).to.be.null;
47
47
  });
48
48
  it('renders all menu plugins, not requiring a document, as large tiles (buttons)', async () => {
49
- const menuPluginsNotRequiringDoc = flattenPluginEntries(oscdShell.plugins.menu).filter(plugin => !plugin.requireDoc);
49
+ const menuPluginsNotRequiringDoc = flattenPluginEntries(oscdShell._resolvedPlugins.menu).filter(plugin => !plugin.requireDoc);
50
50
  const menuPluginElements = landingPage.shadowRoot.querySelectorAll('.menu-plugin-item');
51
51
  expect(menuPluginElements.length).to.equal(menuPluginsNotRequiringDoc.length);
52
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, 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
+ {"version":3,"file":"landing-page.spec.js","sourceRoot":"","sources":["../../src/landing-page/landing-page.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGzD,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,EACL,iBAAiB,EACjB,8BAA8B,GAC/B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,MAAM,WAAW,GAAG,cAAc,CAAC;AACnC,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAEzC,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,IAAI,SAAoB,CAAC;IACzB,IAAI,WAAwB,CAAC;IAE7B,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,SAAS,GAAG,MAAM,OAAO,CACvB,IAAI,CAAA;6BACmB,WAAW;gCACR,cAAc;qBACzB,CAChB,CAAC;QACF,MAAM,sBAAsB,GAAI,iBAAiB,CAAC,CAAC,CAAoB;aACpE,OAAQ,CAAC;QACZ,MAAM,CAAC,sBAAsB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC;QACnD,IAAI,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,sBAAsB,CAAC,KAAK,SAAS,EAAE,CAAC;YACnE,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,sBAAuB,EAAE,eAAe,CAAC,CAAC;QACxE,CAAC;QACD,SAAS,CAAC,OAAO,GAAG;YAClB,IAAI,EAAE,iBAAiB;SACxB,CAAC;QACF,MAAM,8BAA8B,CAAC,SAAS,CAAC,CAAC;QAChD,WAAW,GAAG,SAAS,CAAC,UAAW,CAAC,aAAa,CAAC,cAAc,CAAE,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wFAAwF,EAAE,KAAK,IAAI,EAAE;QACtG,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,cAAc,GAAG,WAAW,CAAC,UAAW,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACzE,MAAM,CAAC,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,iBAAiB,GACrB,WAAW,CAAC,UAAW,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;QACxD,MAAM,CAAC,iBAAiB,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,SAAS,CAAC,aAAa,CAAC,YAAY,CAAC,iBAAiB,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;QACvE,MAAM,SAAS,CAAC,cAAc,CAAC;QAC/B,MAAM,oBAAoB,GACxB,SAAS,CAAC,UAAW,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;QACtD,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;QAC5F,MAAM,0BAA0B,GAAG,oBAAoB,CACrD,SAAS,CAAC,gBAAgB,CAAC,IAAI,CAChC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,kBAAkB,GACtB,WAAW,CAAC,UAAW,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;QAEhE,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CACxC,0BAA0B,CAAC,MAAM,CAClC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,IAAI,CAC/C,MAAM,CAAC,EAAE,CAAE,MAAyB,CAAC,OAAO,KAAK,mBAAmB,CACrE,CAAC;QACF,MAAM,kBAAkB,GACtB,WAAW,CAAC,UAAW,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;QAEhE,MAAM,uBAAuB,GAAG,SAAS,CAAC,UAAU,EAAE,aAAa,CACjE,mBAAmB,CACD,CAAC;QACrB,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QAEhE,MAAM,qBAAqB,GAAG,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAC/D,OAAO,CAAC,EAAE,CACR,OAAO;aACJ,aAAa,CAAC,gCAAgC,CAAC;YAChD,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,kBAAkB,EAAE,IAAI,CACrC,CAAC;QACpB,qBAAqB,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,SAAS,CAAC,cAAc,CAAC;QAE/B,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAI,SAAoB,CAAC;IACzB,gCAAgC;IAEhC,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,SAAS,GAAc,MAAM,OAAO,CAClC,IAAI,CAAA;;;;oBAIU,CACf,CAAC;QACF,MAAM,8BAA8B,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,eAAe,GAAG,SAAS,CAAC,UAAW,CAAC,aAAa,CACzD,2BAA2B,CACT,CAAC;QACrB,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QACjC,MAAM,CAAC,eAAe,EAAE,gBAAgB,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/D,MAAM,iBAAiB,GAAG,eAAe,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,kBAAkB,GACtB,SAAS,CAAC,UAAW,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;QACtD,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect, fixture, html } from '@open-wc/testing';\nimport type { OscdShell, ResolvedPlugin } 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 ResolvedPlugin)\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._resolvedPlugins.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 ResolvedPlugin).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"]}
@@ -4,7 +4,7 @@ const { getLocale, setLocale } = window.localization ??
4
4
  configureLocalization({
5
5
  sourceLocale,
6
6
  targetLocales,
7
- loadLocale: _locale => {
7
+ loadLocale: (_locale) => {
8
8
  return import(new URL(`./locales/de.js`, import.meta.url).href);
9
9
  },
10
10
  });
@@ -1 +1 @@
1
- {"version":3,"file":"localization.js","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAcvE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAC5B,MAAM,CAAC,YAAY;IACnB,qBAAqB,CAAC;QACpB,YAAY;QACZ,aAAa;QACb,UAAU,EAAE,OAAO,CAAC,EAAE;YACpB,OAAO,MAAM,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;QAClE,CAAC;KACF,CAAC,CAAC;AAEL;;;;;GAKG;AACH,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;IACzB,MAAM,CAAC,YAAY,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AACjD,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC","sourcesContent":["import { configureLocalization } from '@lit/localize';\nimport { allLocales, sourceLocale, targetLocales } from './locales.js';\nexport type LocaleTag = (typeof allLocales)[number];\nexport type Translation = (typeof targetLocales)[number];\nexport type Translations = Record<Translation, string>;\n\ndeclare global {\n interface Window {\n localization?: {\n getLocale: () => string;\n setLocale: (locale: string) => void;\n };\n }\n}\n\nconst { getLocale, setLocale } =\n window.localization ??\n configureLocalization({\n sourceLocale,\n targetLocales,\n loadLocale: _locale => {\n return import(new URL(`./locales/de.js`, import.meta.url).href);\n },\n });\n\n/*\n * To prevent multiple calls to configureLocalization,\n * we store the getLocale and setLocale functions on the window object.\n * This happens now and again in development mode with HMR, perhaps\n * we should wrap this in a check for dev mode only?\n */\nif (!window.localization) {\n window.localization = { getLocale, setLocale };\n}\n\nexport { getLocale, setLocale };\nexport { allLocales, sourceLocale, targetLocales };\n"]}
1
+ {"version":3,"file":"localization.js","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAcvE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAC5B,MAAM,CAAC,YAAY;IACnB,qBAAqB,CAAC;QACpB,YAAY;QACZ,aAAa;QACb,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE;YACtB,OAAO,MAAM,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;QAClE,CAAC;KACF,CAAC,CAAC;AAEL;;;;;GAKG;AACH,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;IACzB,MAAM,CAAC,YAAY,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AACjD,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC","sourcesContent":["import { configureLocalization } from '@lit/localize';\nimport { allLocales, sourceLocale, targetLocales } from './locales.js';\nexport type LocaleTag = (typeof allLocales)[number];\nexport type Translation = (typeof targetLocales)[number];\nexport type Translations = Record<Translation, string>;\n\ndeclare global {\n interface Window {\n localization?: {\n getLocale: () => string;\n setLocale: (locale: string) => void;\n };\n }\n}\n\nconst { getLocale, setLocale } =\n window.localization ??\n configureLocalization({\n sourceLocale,\n targetLocales,\n loadLocale: (_locale) => {\n return import(new URL(`./locales/de.js`, import.meta.url).href);\n },\n });\n\n/*\n * To prevent multiple calls to configureLocalization,\n * we store the getLocale and setLocale functions on the window object.\n * This happens now and again in development mode with HMR, perhaps\n * we should wrap this in a check for dev mode only?\n */\nif (!window.localization) {\n window.localization = { getLocale, setLocale };\n}\n\nexport { getLocale, setLocale };\nexport { allLocales, sourceLocale, targetLocales };\n"]}
@@ -9,7 +9,7 @@ declare global {
9
9
  'files-menu': FilesMenu;
10
10
  }
11
11
  }
12
- declare const FilesMenu_base: typeof LitElement & import("@open-wc/scoped-elements/lit-element.js").ScopedElementsHostConstructor;
12
+ declare const FilesMenu_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost> & import("@open-wc/scoped-elements/types.js").ScopedElementsHostConstructor;
13
13
  export declare class FilesMenu extends FilesMenu_base {
14
14
  static scopedElements: {
15
15
  'oscd-text-button': typeof OscdTextButton;
@@ -5,13 +5,13 @@ import { OscdMenu } from '@omicronenergy/oscd-ui/menu/OscdMenu.js';
5
5
  import { OscdSubMenu } from '@omicronenergy/oscd-ui/menu/OscdSubMenu.js';
6
6
  import { OscdMenuItem } from '@omicronenergy/oscd-ui/menu/OscdMenuItem.js';
7
7
  import { LocaleTag } from '../localization.js';
8
- import { PluginEntry, PluginGroup } from '../oscd-shell.js';
8
+ import { PluginGroup, ResolvedPlugin } from '../oscd-shell.js';
9
9
  declare global {
10
10
  interface HTMLElementTagNameMap {
11
11
  'plugins-menu': PluginsMenu;
12
12
  }
13
13
  }
14
- declare const PluginsMenu_base: typeof LitElement & import("@open-wc/scoped-elements/lit-element.js").ScopedElementsHostConstructor;
14
+ declare const PluginsMenu_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost> & import("@open-wc/scoped-elements/types.js").ScopedElementsHostConstructor;
15
15
  export declare class PluginsMenu extends PluginsMenu_base {
16
16
  static scopedElements: {
17
17
  'oscd-filled-icon-button': typeof OscdFilledIconButton;
@@ -21,14 +21,14 @@ export declare class PluginsMenu extends PluginsMenu_base {
21
21
  'oscd-menu-item': typeof OscdMenuItem;
22
22
  };
23
23
  editableDocs: string[];
24
- menuPlugins: PluginEntry[];
24
+ menuPlugins: ResolvedPlugin[];
25
25
  appIcon: string;
26
26
  appTitle: string;
27
27
  locale: LocaleTag;
28
28
  open: () => void;
29
29
  menu: OscdMenu;
30
- renderMenuGroup(plugin: PluginGroup<PluginEntry>, hasDoc: boolean): import("lit-html").TemplateResult<1>;
31
- renderMenuItem(plugin: PluginEntry, hasDoc: boolean): import("lit-html").TemplateResult<1>;
30
+ renderMenuGroup(plugin: PluginGroup<ResolvedPlugin>, hasDoc: boolean): import("lit-html").TemplateResult<1>;
31
+ renderMenuItem(plugin: ResolvedPlugin, hasDoc: boolean): import("lit-html").TemplateResult<1>;
32
32
  render(): import("lit-html").TemplateResult<1>;
33
33
  static styles: import("lit").CSSResult;
34
34
  }
@@ -30,7 +30,7 @@ let PluginsMenu = class PluginsMenu extends ScopedElementsMixin(LitElement) {
30
30
  <oscd-icon slot="end">arrow_right</oscd-icon>
31
31
  </oscd-menu-item>
32
32
  <oscd-menu slot="menu">
33
- ${plugin.plugins.map(plugin => {
33
+ ${plugin.plugins.map((plugin) => {
34
34
  return this.renderMenuItem(plugin, hasDoc);
35
35
  })}
36
36
  </oscd-menu>
@@ -81,7 +81,7 @@ let PluginsMenu = class PluginsMenu extends ScopedElementsMixin(LitElement) {
81
81
  menuCorner="START_END"
82
82
  anchorCorner="START_END"
83
83
  >
84
- ${this.menuPlugins.map(plugin => {
84
+ ${this.menuPlugins.map((plugin) => {
85
85
  const hasDoc = (this.editableDocs ?? []).length > 0;
86
86
  if (isPluginGroup(plugin)) {
87
87
  return this.renderMenuGroup(plugin, hasDoc);
@@ -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 { 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"]}
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 { PluginGroup, ResolvedPlugin } 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: ResolvedPlugin[] = [];\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<ResolvedPlugin>, 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: ResolvedPlugin, 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"]}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * This block contains:
5
5
  * 1) Internal base tokens and fallbacks
6
- * 2) Public token -> internal token mappings
6
+ * 2) Public token -\> internal token mappings
7
7
  *
8
8
  * Keep this as an all-or-nothing layer so mappings can safely reference
9
9
  * internal base tokens (e.g. --oscd-base*).
@@ -4,7 +4,7 @@ import { css } from 'lit';
4
4
  *
5
5
  * This block contains:
6
6
  * 1) Internal base tokens and fallbacks
7
- * 2) Public token -> internal token mappings
7
+ * 2) Public token -\> internal token mappings
8
8
  *
9
9
  * Keep this as an all-or-nothing layer so mappings can safely reference
10
10
  * internal base tokens (e.g. --oscd-base*).
@@ -33,6 +33,7 @@ export const oscdShellDesignTokens = css `
33
33
  --oscd-base3: var(--oscd-theme-base3, #fdf6e3);
34
34
  --oscd-error: var(--oscd-theme-error, #dc322f);
35
35
  --oscd-warning: var(--oscd-theme-warning, #b58900);
36
+ --oscd-shape: var(--oscd-theme-shape, 8px);
36
37
  --oscd-text-font: var(--oscd-theme-text-font, 'Roboto');
37
38
  --oscd-text-font-mono: var(--oscd-theme-text-font-mono, 'Roboto Mono');
38
39
  --oscd-icon-font: var(--oscd-theme-icon-font, 'Material Symbols Outlined');
@@ -57,6 +58,16 @@ export const oscdShellDesignTokens = css `
57
58
  --md-sys-color-on-error: var(--oscd-base3);
58
59
  --md-icon-button-disabled-icon-color: var(--oscd-base3);
59
60
 
61
+ /* Material shape scale, derived from --oscd-shape (the Material
62
+ * "small" corner size) per the ratios documented in oscd-api's
63
+ * theming.md: none=0, extra-small=0.5x, small=1x, medium=1.5x, large=2x.
64
+ */
65
+ --md-sys-shape-corner-none: 0;
66
+ --md-sys-shape-corner-extra-small: calc(0.5 * var(--oscd-shape));
67
+ --md-sys-shape-corner-small: var(--oscd-shape);
68
+ --md-sys-shape-corner-medium: calc(1.5 * var(--oscd-shape));
69
+ --md-sys-shape-corner-large: calc(2 * var(--oscd-shape));
70
+
60
71
  /* MD3 has no single generic "system font" token (unlike color); its
61
72
  * closest reference-tier equivalent is --md-ref-typeface-plain. Icon
62
73
  * fonts (--oscd-icon-font) and monospace fonts (--oscd-text-font-mono)
@@ -1 +1 @@
1
- {"version":3,"file":"oscd-shell-design-tokens.js","sourceRoot":"","sources":["../src/oscd-shell-design-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmXvC,CAAC","sourcesContent":["import { css } from 'lit';\n\n/**\n * Single source of truth for oscd-shell design tokens.\n *\n * This block contains:\n * 1) Internal base tokens and fallbacks\n * 2) Public token -> internal token mappings\n *\n * Keep this as an all-or-nothing layer so mappings can safely reference\n * internal base tokens (e.g. --oscd-base*).\n */\nexport const oscdShellDesignTokens = css`\n /* Internal base theme tokens and defaults.\n *\n * Defaults are the Solarized (https://ethanschoonover.com/solarized/)\n * light palette used by the legacy OpenSCD shell, so oscd-shell is\n * brand-neutral out of the box: consumers who set none of the\n * --oscd-theme-* variables get the classic OpenSCD look. Distro-specific\n * branding (e.g. Omicron colors) is applied entirely by overriding the\n * --oscd-theme-* variables from outside; nothing brand-specific belongs\n * in this file.\n */\n :host {\n --oscd-primary: var(--oscd-theme-primary, #2aa198);\n --oscd-secondary: var(--oscd-theme-secondary, #6c71c4);\n --oscd-base03: var(--oscd-theme-base03, #002b36);\n --oscd-base02: var(--oscd-theme-base02, #073642);\n --oscd-base01: var(--oscd-theme-base01, #586e75);\n --oscd-base00: var(--oscd-theme-base00, #657b83);\n --oscd-base0: var(--oscd-theme-base0, #839496);\n --oscd-base1: var(--oscd-theme-base1, #93a1a1);\n --oscd-base2: var(--oscd-theme-base2, #eee8d5);\n --oscd-base3: var(--oscd-theme-base3, #fdf6e3);\n --oscd-error: var(--oscd-theme-error, #dc322f);\n --oscd-warning: var(--oscd-theme-warning, #b58900);\n --oscd-text-font: var(--oscd-theme-text-font, 'Roboto');\n --oscd-text-font-mono: var(--oscd-theme-text-font-mono, 'Roboto Mono');\n --oscd-icon-font: var(--oscd-theme-icon-font, 'Material Symbols Outlined');\n\n /* Fallbacks for Material Design variables */\n --md-sys-color-primary: var(--oscd-primary);\n --md-sys-color-on-primary: var(--oscd-base3);\n --md-sys-color-secondary: var(--oscd-secondary);\n --md-sys-color-on-secondary: var(--oscd-base3);\n --md-sys-color-secondary-container: var(--oscd-base2);\n --md-sys-color-surface: var(--oscd-base3);\n --md-sys-color-on-surface: var(--oscd-base00);\n --md-sys-color-surface-variant: var(--oscd-base3);\n --md-sys-color-on-surface-variant: var(--oscd-base00);\n --md-sys-color-surface-bright: var(--oscd-base2);\n --md-sys-color-surface-container: var(--oscd-base3);\n --md-sys-color-surface-container-high: var(--oscd-base3);\n --md-sys-color-surface-container-highest: var(--oscd-base3);\n --md-sys-color-outline-variant: var(--oscd-primary);\n --md-sys-color-scrim: #000000;\n --md-sys-color-error: var(--oscd-error);\n --md-sys-color-on-error: var(--oscd-base3);\n --md-icon-button-disabled-icon-color: var(--oscd-base3);\n\n /* MD3 has no single generic \"system font\" token (unlike color); its\n * closest reference-tier equivalent is --md-ref-typeface-plain. Icon\n * fonts (--oscd-icon-font) and monospace fonts (--oscd-text-font-mono)\n * have no MD3 system-token equivalent at all, so they are referenced\n * directly where needed instead of through an --md-* mapping.\n */\n --md-ref-typeface-plain: var(--oscd-text-font);\n\n /* MDC Theme Colors\n * Needed for supporting any pluggins still using the depricated MWC Components\n */\n --mdc-theme-primary: var(--oscd-primary);\n --mdc-theme-secondary: var(--oscd-secondary);\n --mdc-theme-background: var(--oscd-base3);\n --mdc-theme-surface: var(--oscd-base3);\n --mdc-theme-on-primary: var(--oscd-base2);\n --mdc-theme-on-secondary: var(--oscd-base2);\n --mdc-theme-on-background: var(--oscd-base00);\n --mdc-theme-on-surface: var(--oscd-base00);\n --mdc-theme-text-primary-on-background: var(--oscd-base01);\n --mdc-theme-text-secondary-on-background: var(--oscd-base00);\n --mdc-theme-text-icon-on-background: var(--oscd-base00);\n --mdc-theme-error: var(--oscd-error);\n --mdc-button-disabled-ink-color: var(--oscd-base1);\n --mdc-drawer-heading-ink-color: var(--oscd-base00);\n --mdc-dialog-heading-ink-color: var(--oscd-base00);\n --mdc-text-field-fill-color: var(--oscd-base2);\n --mdc-text-field-disabled-fill-color: var(--oscd-base3);\n --mdc-text-field-ink-color: var(--oscd-base00);\n --mdc-text-field-label-ink-color: var(--oscd-base00);\n --mdc-text-field-idle-line-color: var(--oscd-base00);\n --mdc-text-field-hover-line-color: var(--oscd-base02);\n --mdc-select-fill-color: var(--oscd-base2);\n --mdc-select-disabled-fill-color: var(--oscd-base3);\n --mdc-select-ink-color: var(--oscd-base00);\n --mdc-select-label-ink-color: var(--oscd-base00);\n --mdc-select-idle-line-color: var(--oscd-base00);\n --mdc-select-hover-line-color: var(--oscd-base02);\n --mdc-select-dropdown-icon-color: var(--oscd-base01);\n --mdc-typography-font-family: var(--oscd-text-font);\n --mdc-icon-font: var(--oscd-icon-font);\n --mdc-theme-text-disabled-on-light: rgba(255, 255, 255, 0.38);\n }\n\n /*\n * Public token -> internal token mappings\n *\n * Example pattern:\n * --internal-variable-name: var(--oscd-shell-public-token, <default>);\n */\n :host {\n /* Shell root */\n --shell-background-color: var(\n --oscd-shell-background-color,\n var(--md-sys-color-surface)\n );\n\n /* App bar */\n --app-bar-color: var(\n --oscd-shell-app-bar-color,\n var(--md-sys-color-on-primary)\n );\n --app-bar-background-color: var(\n --oscd-shell-app-bar-background-color,\n var(--md-sys-color-primary)\n );\n --app-bar-height: var(--oscd-shell-app-bar-height, 54px);\n --app-bar-small-height: var(--oscd-shell-app-bar-small-height, 48px);\n --app-bar-elevation: var(\n --oscd-shell-app-bar-elevation,\n var(--md-sys-elevation-level-2)\n );\n --app-bar-app-icon-height: var(--oscd-shell-app-bar-icon-height, 34.4px);\n --app-bar-app-icon-width: var(--oscd-shell-app-bar-icon-width, auto);\n --app-bar-logo-gap: var(--oscd-shell-app-bar-logo-gap, 16px);\n --app-bar-title-menu-gap: var(--oscd-shell-app-bar-title-menu-gap, 4px);\n --app-bar-title-text-font-family: var(\n --oscd-shell-app-bar-title-font-family,\n var(--md-ref-typeface-plain)\n );\n --app-bar-title-text-color: var(\n --oscd-shell-app-bar-title-color,\n var(--app-bar-color)\n );\n --app-bar-title-text-font-size: var(\n --oscd-shell-app-bar-title-font-size,\n 22.114px\n );\n --app-bar-title-text-font-weight: var(\n --oscd-shell-app-bar-title-font-weight,\n 400\n );\n --app-bar-title-text-font-style: var(\n --oscd-shell-app-bar-title-font-style,\n normal\n );\n --app-bar-title-text-line-height: var(\n --oscd-shell-app-bar-title-line-height,\n normal\n );\n --app-bar-title-text-letter-spacing: var(\n --oscd-shell-app-bar-title-letter-spacing,\n inherit\n );\n --app-bar-current-editor-font-family: var(\n --oscd-shell-app-bar-current-editor-font-family,\n var(--md-ref-typeface-plain)\n );\n --app-bar-current-editor-font-size: var(\n --oscd-shell-app-bar-current-editor-font-size,\n 16px\n );\n --app-bar-current-editor-font-weight: var(\n --oscd-shell-app-bar-current-editor-font-weight,\n 500\n );\n --app-bar-current-editor-font-style: var(\n --oscd-shell-app-bar-current-editor-font-style,\n normal\n );\n --app-bar-current-editor-line-height: var(\n --oscd-shell-app-bar-current-editor-line-height,\n normal\n );\n --app-bar-current-editor-color: var(\n --oscd-shell-app-bar-current-editor-color,\n var(--app-bar-color)\n );\n --app-bar-action-icon-size: var(\n --oscd-shell-app-bar-action-icon-size,\n 24px\n );\n --app-bar-action-icon-color: var(\n --oscd-shell-app-bar-action-icon-color,\n var(--md-sys-color-on-primary)\n );\n --app-bar-action-icon-disabled-color: var(\n --oscd-shell-app-bar-action-icon-disabled-color,\n var(--md-sys-color-on-primary)\n );\n --app-bar-action-icon-disabled-container-opacity: var(\n --oscd-shell-app-bar-action-icon-disabled-container-opacity,\n 0\n );\n --app-bar-separator-color: var(\n --oscd-shell-app-bar-separator-color,\n currentColor\n );\n --app-bar-separator-opacity: var(\n --oscd-shell-app-bar-separator-opacity,\n 0.38\n );\n\n /* Bridge to oscd-ui app bar tokens */\n --oscd-app-bar-color: var(--app-bar-color);\n --oscd-app-bar-background-color: var(--app-bar-background-color);\n --oscd-app-bar-elevation: var(--app-bar-elevation);\n --oscd-app-bar-title-font-family: var(--app-bar-title-text-font-family);\n --oscd-app-bar-title-font-size: var(--app-bar-title-text-font-size);\n --oscd-app-bar-title-font-weight: var(--app-bar-title-text-font-weight);\n --oscd-app-bar-title-line-height: var(--app-bar-title-text-line-height);\n\n /* Files menu */\n --file-menu-text-font-family: var(\n --oscd-shell-file-menu-text-font-family,\n var(--md-ref-typeface-plain)\n );\n --file-menu-text-size: var(--oscd-shell-file-menu-text-size, 16px);\n --file-menu-text-weight: var(--oscd-shell-file-menu-text-weight, 500);\n --file-menu-text-color: var(\n --oscd-shell-file-menu-text-color,\n var(--md-sys-color-on-primary)\n );\n\n /* Plugins menu */\n --plugins-menu-button-size: var(\n --oscd-shell-plugins-menu-button-size,\n 24px\n );\n --plugins-menu-button-color: var(\n --oscd-shell-plugins-menu-button-color,\n var(--md-sys-color-on-primary)\n );\n --plugins-menu-min-width: var(--oscd-shell-plugins-menu-min-width, 350px);\n --plugins-menu-padding: var(--oscd-shell-plugins-menu-padding, 12px);\n --plugins-menu-container-color: var(\n --oscd-shell-plugins-menu-container-color,\n var(--md-sys-color-surface)\n );\n --plugins-menu-item-label-color: var(\n --oscd-shell-plugins-menu-item-label-color,\n var(--md-sys-color-on-surface)\n );\n --plugins-menu-item-leading-icon-color: var(\n --oscd-shell-plugins-menu-item-leading-icon-color,\n var(--md-sys-color-on-surface)\n );\n --plugins-menu-item-selected-container-color: var(\n --oscd-shell-plugins-menu-item-selected-container-color,\n var(--md-sys-color-secondary-container)\n );\n --plugins-menu-item-selected-label-color: var(\n --oscd-shell-plugins-menu-item-selected-label-color,\n var(--md-sys-color-on-surface)\n );\n\n /* Editor plugins panel */\n --editor-plugins-panel-width: var(\n --oscd-shell-editor-plugins-panel-width,\n 308px\n );\n --editor-plugins-panel-collapsed-width: var(\n --oscd-shell-editor-plugins-panel-collapsed-width,\n 76px\n );\n --editor-plugins-panel-padding-top: var(\n --oscd-shell-editor-plugins-panel-padding-top,\n 20px\n );\n --editor-plugins-panel-item-icon-size: var(\n --oscd-shell-editor-plugins-panel-item-icon-size,\n 28px\n );\n --editor-plugins-panel-background-color: var(\n --oscd-shell-editor-plugins-panel-background-color,\n var(--md-sys-color-surface)\n );\n --editor-plugins-panel-item-text-color: var(\n --oscd-shell-editor-plugins-panel-item-text-color,\n var(--md-sys-color-on-surface)\n );\n --editor-plugins-panel-item-icon-color: var(\n --oscd-shell-editor-plugins-panel-item-icon-color,\n var(--md-sys-color-on-surface)\n );\n --editor-plugins-panel-item-active-bg: var(\n --oscd-shell-editor-plugins-panel-item-active-bg,\n var(--md-sys-color-primary)\n );\n --editor-plugins-panel-item-active-color: var(\n --oscd-shell-editor-plugins-panel-item-active-color,\n var(--md-sys-color-on-primary)\n );\n --editor-plugins-panel-divider-color: var(\n --oscd-shell-editor-plugins-panel-divider-color,\n #d0d5dc40\n );\n --editor-plugins-panel-flyout-header-text-color: var(\n --oscd-shell-editor-plugins-panel-flyout-header-text-color,\n var(--md-sys-color-secondary)\n );\n\n /* Main editor container */\n --editor-background-color: var(\n --oscd-shell-editor-background-color,\n var(--md-sys-color-surface)\n );\n --editor-padding: var(--oscd-shell-editor-padding, 8px);\n\n /* Landing page */\n --landing-background-color: var(\n --oscd-shell-landing-background-color,\n var(--md-sys-color-surface)\n );\n --landing-heading-color: var(\n --oscd-shell-landing-heading-color,\n var(--md-sys-color-on-surface)\n );\n --landing-heading-font-family: var(\n --oscd-shell-landing-heading-font-family,\n var(--md-ref-typeface-plain)\n );\n --landing-heading-size: var(--oscd-shell-landing-heading-size, 50px);\n --landing-heading-style: var(--oscd-shell-landing-heading-style, normal);\n --landing-heading-weight: var(--oscd-shell-landing-heading-weight, 600);\n --landing-heading-line-height: var(\n --oscd-shell-landing-heading-line-height,\n normal\n );\n\n --landing-subheading-color: var(\n --oscd-shell-landing-subheading-color,\n var(--md-sys-color-on-surface)\n );\n --landing-subheading-font-family: var(\n --oscd-shell-landing-subheading-font-family,\n var(--md-ref-typeface-plain)\n );\n --landing-subheading-size: var(\n --oscd-shell-landing-subheading-size,\n 16.909px\n );\n --landing-subheading-style: var(\n --oscd-shell-landing-subheading-style,\n normal\n );\n --landing-subheading-weight: var(\n --oscd-shell-landing-subheading-weight,\n 400\n );\n --landing-subheading-line-height: var(\n --oscd-shell-landing-subheading-line-height,\n 65.194px\n );\n --landing-grid-width: var(--oscd-shell-landing-grid-width, 60%);\n --landing-grid-gap: var(--oscd-shell-landing-grid-gap, 95px);\n --landing-card-width: var(--oscd-shell-landing-card-width, 240px);\n --landing-card-height: var(--oscd-shell-landing-card-height, 180px);\n --landing-card-background: var(\n --oscd-shell-landing-card-background,\n var(--md-sys-color-secondary)\n );\n --landing-card-text-color: var(\n --oscd-shell-landing-card-text-color,\n var(--md-sys-color-on-secondary)\n );\n --landing-card-radius: var(--oscd-shell-landing-card-radius, 2px);\n --landing-card-icon-size: var(--oscd-shell-landing-card-icon-size, 54px);\n --landing-card-corner-accent: var(\n --oscd-shell-landing-card-corner-accent,\n transparent\n );\n }\n`;\n"]}
1
+ {"version":3,"file":"oscd-shell-design-tokens.js","sourceRoot":"","sources":["../src/oscd-shell-design-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8XvC,CAAC","sourcesContent":["import { css } from 'lit';\n\n/**\n * Single source of truth for oscd-shell design tokens.\n *\n * This block contains:\n * 1) Internal base tokens and fallbacks\n * 2) Public token -\\> internal token mappings\n *\n * Keep this as an all-or-nothing layer so mappings can safely reference\n * internal base tokens (e.g. --oscd-base*).\n */\nexport const oscdShellDesignTokens = css`\n /* Internal base theme tokens and defaults.\n *\n * Defaults are the Solarized (https://ethanschoonover.com/solarized/)\n * light palette used by the legacy OpenSCD shell, so oscd-shell is\n * brand-neutral out of the box: consumers who set none of the\n * --oscd-theme-* variables get the classic OpenSCD look. Distro-specific\n * branding (e.g. Omicron colors) is applied entirely by overriding the\n * --oscd-theme-* variables from outside; nothing brand-specific belongs\n * in this file.\n */\n :host {\n --oscd-primary: var(--oscd-theme-primary, #2aa198);\n --oscd-secondary: var(--oscd-theme-secondary, #6c71c4);\n --oscd-base03: var(--oscd-theme-base03, #002b36);\n --oscd-base02: var(--oscd-theme-base02, #073642);\n --oscd-base01: var(--oscd-theme-base01, #586e75);\n --oscd-base00: var(--oscd-theme-base00, #657b83);\n --oscd-base0: var(--oscd-theme-base0, #839496);\n --oscd-base1: var(--oscd-theme-base1, #93a1a1);\n --oscd-base2: var(--oscd-theme-base2, #eee8d5);\n --oscd-base3: var(--oscd-theme-base3, #fdf6e3);\n --oscd-error: var(--oscd-theme-error, #dc322f);\n --oscd-warning: var(--oscd-theme-warning, #b58900);\n --oscd-shape: var(--oscd-theme-shape, 8px);\n --oscd-text-font: var(--oscd-theme-text-font, 'Roboto');\n --oscd-text-font-mono: var(--oscd-theme-text-font-mono, 'Roboto Mono');\n --oscd-icon-font: var(--oscd-theme-icon-font, 'Material Symbols Outlined');\n\n /* Fallbacks for Material Design variables */\n --md-sys-color-primary: var(--oscd-primary);\n --md-sys-color-on-primary: var(--oscd-base3);\n --md-sys-color-secondary: var(--oscd-secondary);\n --md-sys-color-on-secondary: var(--oscd-base3);\n --md-sys-color-secondary-container: var(--oscd-base2);\n --md-sys-color-surface: var(--oscd-base3);\n --md-sys-color-on-surface: var(--oscd-base00);\n --md-sys-color-surface-variant: var(--oscd-base3);\n --md-sys-color-on-surface-variant: var(--oscd-base00);\n --md-sys-color-surface-bright: var(--oscd-base2);\n --md-sys-color-surface-container: var(--oscd-base3);\n --md-sys-color-surface-container-high: var(--oscd-base3);\n --md-sys-color-surface-container-highest: var(--oscd-base3);\n --md-sys-color-outline-variant: var(--oscd-primary);\n --md-sys-color-scrim: #000000;\n --md-sys-color-error: var(--oscd-error);\n --md-sys-color-on-error: var(--oscd-base3);\n --md-icon-button-disabled-icon-color: var(--oscd-base3);\n\n /* Material shape scale, derived from --oscd-shape (the Material\n * \"small\" corner size) per the ratios documented in oscd-api's\n * theming.md: none=0, extra-small=0.5x, small=1x, medium=1.5x, large=2x.\n */\n --md-sys-shape-corner-none: 0;\n --md-sys-shape-corner-extra-small: calc(0.5 * var(--oscd-shape));\n --md-sys-shape-corner-small: var(--oscd-shape);\n --md-sys-shape-corner-medium: calc(1.5 * var(--oscd-shape));\n --md-sys-shape-corner-large: calc(2 * var(--oscd-shape));\n\n /* MD3 has no single generic \"system font\" token (unlike color); its\n * closest reference-tier equivalent is --md-ref-typeface-plain. Icon\n * fonts (--oscd-icon-font) and monospace fonts (--oscd-text-font-mono)\n * have no MD3 system-token equivalent at all, so they are referenced\n * directly where needed instead of through an --md-* mapping.\n */\n --md-ref-typeface-plain: var(--oscd-text-font);\n\n /* MDC Theme Colors\n * Needed for supporting any pluggins still using the depricated MWC Components\n */\n --mdc-theme-primary: var(--oscd-primary);\n --mdc-theme-secondary: var(--oscd-secondary);\n --mdc-theme-background: var(--oscd-base3);\n --mdc-theme-surface: var(--oscd-base3);\n --mdc-theme-on-primary: var(--oscd-base2);\n --mdc-theme-on-secondary: var(--oscd-base2);\n --mdc-theme-on-background: var(--oscd-base00);\n --mdc-theme-on-surface: var(--oscd-base00);\n --mdc-theme-text-primary-on-background: var(--oscd-base01);\n --mdc-theme-text-secondary-on-background: var(--oscd-base00);\n --mdc-theme-text-icon-on-background: var(--oscd-base00);\n --mdc-theme-error: var(--oscd-error);\n --mdc-button-disabled-ink-color: var(--oscd-base1);\n --mdc-drawer-heading-ink-color: var(--oscd-base00);\n --mdc-dialog-heading-ink-color: var(--oscd-base00);\n --mdc-text-field-fill-color: var(--oscd-base2);\n --mdc-text-field-disabled-fill-color: var(--oscd-base3);\n --mdc-text-field-ink-color: var(--oscd-base00);\n --mdc-text-field-label-ink-color: var(--oscd-base00);\n --mdc-text-field-idle-line-color: var(--oscd-base00);\n --mdc-text-field-hover-line-color: var(--oscd-base02);\n --mdc-select-fill-color: var(--oscd-base2);\n --mdc-select-disabled-fill-color: var(--oscd-base3);\n --mdc-select-ink-color: var(--oscd-base00);\n --mdc-select-label-ink-color: var(--oscd-base00);\n --mdc-select-idle-line-color: var(--oscd-base00);\n --mdc-select-hover-line-color: var(--oscd-base02);\n --mdc-select-dropdown-icon-color: var(--oscd-base01);\n --mdc-typography-font-family: var(--oscd-text-font);\n --mdc-icon-font: var(--oscd-icon-font);\n --mdc-theme-text-disabled-on-light: rgba(255, 255, 255, 0.38);\n }\n\n /*\n * Public token -> internal token mappings\n *\n * Example pattern:\n * --internal-variable-name: var(--oscd-shell-public-token, <default>);\n */\n :host {\n /* Shell root */\n --shell-background-color: var(\n --oscd-shell-background-color,\n var(--md-sys-color-surface)\n );\n\n /* App bar */\n --app-bar-color: var(\n --oscd-shell-app-bar-color,\n var(--md-sys-color-on-primary)\n );\n --app-bar-background-color: var(\n --oscd-shell-app-bar-background-color,\n var(--md-sys-color-primary)\n );\n --app-bar-height: var(--oscd-shell-app-bar-height, 54px);\n --app-bar-small-height: var(--oscd-shell-app-bar-small-height, 48px);\n --app-bar-elevation: var(\n --oscd-shell-app-bar-elevation,\n var(--md-sys-elevation-level-2)\n );\n --app-bar-app-icon-height: var(--oscd-shell-app-bar-icon-height, 34.4px);\n --app-bar-app-icon-width: var(--oscd-shell-app-bar-icon-width, auto);\n --app-bar-logo-gap: var(--oscd-shell-app-bar-logo-gap, 16px);\n --app-bar-title-menu-gap: var(--oscd-shell-app-bar-title-menu-gap, 4px);\n --app-bar-title-text-font-family: var(\n --oscd-shell-app-bar-title-font-family,\n var(--md-ref-typeface-plain)\n );\n --app-bar-title-text-color: var(\n --oscd-shell-app-bar-title-color,\n var(--app-bar-color)\n );\n --app-bar-title-text-font-size: var(\n --oscd-shell-app-bar-title-font-size,\n 22.114px\n );\n --app-bar-title-text-font-weight: var(\n --oscd-shell-app-bar-title-font-weight,\n 400\n );\n --app-bar-title-text-font-style: var(\n --oscd-shell-app-bar-title-font-style,\n normal\n );\n --app-bar-title-text-line-height: var(\n --oscd-shell-app-bar-title-line-height,\n normal\n );\n --app-bar-title-text-letter-spacing: var(\n --oscd-shell-app-bar-title-letter-spacing,\n inherit\n );\n --app-bar-current-editor-font-family: var(\n --oscd-shell-app-bar-current-editor-font-family,\n var(--md-ref-typeface-plain)\n );\n --app-bar-current-editor-font-size: var(\n --oscd-shell-app-bar-current-editor-font-size,\n 16px\n );\n --app-bar-current-editor-font-weight: var(\n --oscd-shell-app-bar-current-editor-font-weight,\n 500\n );\n --app-bar-current-editor-font-style: var(\n --oscd-shell-app-bar-current-editor-font-style,\n normal\n );\n --app-bar-current-editor-line-height: var(\n --oscd-shell-app-bar-current-editor-line-height,\n normal\n );\n --app-bar-current-editor-color: var(\n --oscd-shell-app-bar-current-editor-color,\n var(--app-bar-color)\n );\n --app-bar-action-icon-size: var(\n --oscd-shell-app-bar-action-icon-size,\n 24px\n );\n --app-bar-action-icon-color: var(\n --oscd-shell-app-bar-action-icon-color,\n var(--md-sys-color-on-primary)\n );\n --app-bar-action-icon-disabled-color: var(\n --oscd-shell-app-bar-action-icon-disabled-color,\n var(--md-sys-color-on-primary)\n );\n --app-bar-action-icon-disabled-container-opacity: var(\n --oscd-shell-app-bar-action-icon-disabled-container-opacity,\n 0\n );\n --app-bar-separator-color: var(\n --oscd-shell-app-bar-separator-color,\n currentColor\n );\n --app-bar-separator-opacity: var(\n --oscd-shell-app-bar-separator-opacity,\n 0.38\n );\n\n /* Bridge to oscd-ui app bar tokens */\n --oscd-app-bar-color: var(--app-bar-color);\n --oscd-app-bar-background-color: var(--app-bar-background-color);\n --oscd-app-bar-elevation: var(--app-bar-elevation);\n --oscd-app-bar-title-font-family: var(--app-bar-title-text-font-family);\n --oscd-app-bar-title-font-size: var(--app-bar-title-text-font-size);\n --oscd-app-bar-title-font-weight: var(--app-bar-title-text-font-weight);\n --oscd-app-bar-title-line-height: var(--app-bar-title-text-line-height);\n\n /* Files menu */\n --file-menu-text-font-family: var(\n --oscd-shell-file-menu-text-font-family,\n var(--md-ref-typeface-plain)\n );\n --file-menu-text-size: var(--oscd-shell-file-menu-text-size, 16px);\n --file-menu-text-weight: var(--oscd-shell-file-menu-text-weight, 500);\n --file-menu-text-color: var(\n --oscd-shell-file-menu-text-color,\n var(--md-sys-color-on-primary)\n );\n\n /* Plugins menu */\n --plugins-menu-button-size: var(\n --oscd-shell-plugins-menu-button-size,\n 24px\n );\n --plugins-menu-button-color: var(\n --oscd-shell-plugins-menu-button-color,\n var(--md-sys-color-on-primary)\n );\n --plugins-menu-min-width: var(--oscd-shell-plugins-menu-min-width, 350px);\n --plugins-menu-padding: var(--oscd-shell-plugins-menu-padding, 12px);\n --plugins-menu-container-color: var(\n --oscd-shell-plugins-menu-container-color,\n var(--md-sys-color-surface)\n );\n --plugins-menu-item-label-color: var(\n --oscd-shell-plugins-menu-item-label-color,\n var(--md-sys-color-on-surface)\n );\n --plugins-menu-item-leading-icon-color: var(\n --oscd-shell-plugins-menu-item-leading-icon-color,\n var(--md-sys-color-on-surface)\n );\n --plugins-menu-item-selected-container-color: var(\n --oscd-shell-plugins-menu-item-selected-container-color,\n var(--md-sys-color-secondary-container)\n );\n --plugins-menu-item-selected-label-color: var(\n --oscd-shell-plugins-menu-item-selected-label-color,\n var(--md-sys-color-on-surface)\n );\n\n /* Editor plugins panel */\n --editor-plugins-panel-width: var(\n --oscd-shell-editor-plugins-panel-width,\n 308px\n );\n --editor-plugins-panel-collapsed-width: var(\n --oscd-shell-editor-plugins-panel-collapsed-width,\n 76px\n );\n --editor-plugins-panel-padding-top: var(\n --oscd-shell-editor-plugins-panel-padding-top,\n 20px\n );\n --editor-plugins-panel-item-icon-size: var(\n --oscd-shell-editor-plugins-panel-item-icon-size,\n 28px\n );\n --editor-plugins-panel-background-color: var(\n --oscd-shell-editor-plugins-panel-background-color,\n var(--md-sys-color-surface)\n );\n --editor-plugins-panel-item-text-color: var(\n --oscd-shell-editor-plugins-panel-item-text-color,\n var(--md-sys-color-on-surface)\n );\n --editor-plugins-panel-item-icon-color: var(\n --oscd-shell-editor-plugins-panel-item-icon-color,\n var(--md-sys-color-on-surface)\n );\n --editor-plugins-panel-item-active-bg: var(\n --oscd-shell-editor-plugins-panel-item-active-bg,\n var(--md-sys-color-primary)\n );\n --editor-plugins-panel-item-active-color: var(\n --oscd-shell-editor-plugins-panel-item-active-color,\n var(--md-sys-color-on-primary)\n );\n --editor-plugins-panel-divider-color: var(\n --oscd-shell-editor-plugins-panel-divider-color,\n #d0d5dc40\n );\n --editor-plugins-panel-flyout-header-text-color: var(\n --oscd-shell-editor-plugins-panel-flyout-header-text-color,\n var(--md-sys-color-secondary)\n );\n\n /* Main editor container */\n --editor-background-color: var(\n --oscd-shell-editor-background-color,\n var(--md-sys-color-surface)\n );\n --editor-padding: var(--oscd-shell-editor-padding, 8px);\n\n /* Landing page */\n --landing-background-color: var(\n --oscd-shell-landing-background-color,\n var(--md-sys-color-surface)\n );\n --landing-heading-color: var(\n --oscd-shell-landing-heading-color,\n var(--md-sys-color-on-surface)\n );\n --landing-heading-font-family: var(\n --oscd-shell-landing-heading-font-family,\n var(--md-ref-typeface-plain)\n );\n --landing-heading-size: var(--oscd-shell-landing-heading-size, 50px);\n --landing-heading-style: var(--oscd-shell-landing-heading-style, normal);\n --landing-heading-weight: var(--oscd-shell-landing-heading-weight, 600);\n --landing-heading-line-height: var(\n --oscd-shell-landing-heading-line-height,\n normal\n );\n\n --landing-subheading-color: var(\n --oscd-shell-landing-subheading-color,\n var(--md-sys-color-on-surface)\n );\n --landing-subheading-font-family: var(\n --oscd-shell-landing-subheading-font-family,\n var(--md-ref-typeface-plain)\n );\n --landing-subheading-size: var(\n --oscd-shell-landing-subheading-size,\n 16.909px\n );\n --landing-subheading-style: var(\n --oscd-shell-landing-subheading-style,\n normal\n );\n --landing-subheading-weight: var(\n --oscd-shell-landing-subheading-weight,\n 400\n );\n --landing-subheading-line-height: var(\n --oscd-shell-landing-subheading-line-height,\n 65.194px\n );\n --landing-grid-width: var(--oscd-shell-landing-grid-width, 60%);\n --landing-grid-gap: var(--oscd-shell-landing-grid-gap, 95px);\n --landing-card-width: var(--oscd-shell-landing-card-width, 240px);\n --landing-card-height: var(--oscd-shell-landing-card-height, 180px);\n --landing-card-background: var(\n --oscd-shell-landing-card-background,\n var(--md-sys-color-secondary)\n );\n --landing-card-text-color: var(\n --oscd-shell-landing-card-text-color,\n var(--md-sys-color-on-secondary)\n );\n --landing-card-radius: var(--oscd-shell-landing-card-radius, 2px);\n --landing-card-icon-size: var(--oscd-shell-landing-card-icon-size, 54px);\n --landing-card-corner-accent: var(\n --oscd-shell-landing-card-corner-accent,\n transparent\n );\n }\n`;\n"]}
@@ -11,34 +11,51 @@ import { FilesMenu } from './menus/files-menu.js';
11
11
  import { OscdAppBar } from '@omicronenergy/oscd-ui/app-bar/OscdAppBar.js';
12
12
  import { OscdDivider } from '@omicronenergy/oscd-ui/divider/OscdDivider.js';
13
13
  import { OscdIcon } from '@omicronenergy/oscd-ui/icon/OscdIcon.js';
14
- export interface PluginBase {
14
+ /** Fields shared by plugin entries and the groups that contain them. */
15
+ export interface PluginMetadata {
15
16
  name: string;
16
17
  translations?: Record<string, string>;
17
18
  icon: string;
18
19
  }
19
- export interface SourcedPluginEntry extends PluginBase {
20
- src: string;
20
+ /** Fields common to actual plugins (not groups)
21
+ * require a document. */
22
+ export interface OscdPluginBase extends PluginMetadata {
21
23
  requireDoc?: boolean;
22
24
  }
23
- export interface PluginEntry extends PluginBase {
25
+ /** A plugin dynamically imported at runtime from a URL, defined by the `src` field.
26
+ * The shell will load the plugin and assign it a unique tagName generated from hashing the `src` url. */
27
+ export interface SourcedPlugin extends OscdPluginBase {
28
+ src: string;
29
+ }
30
+ /** A plugin already defined in the registry under `tagName`. */
31
+ export interface TaggedPlugin extends OscdPluginBase {
24
32
  tagName: string;
25
- requireDoc?: boolean;
26
33
  }
34
+ /** A declared plugin, either sourced or already registered. */
35
+ export type OscdPlugin = SourcedPlugin | TaggedPlugin;
27
36
  /**
28
- * The unvalidated plugin shape accepted at the `plugins` setter boundary.
29
- * Fields are optional and either `tagName` or `src` may be present; the
30
- * concrete kind is resolved and validated later by `loadSourcedPlugins`.
37
+ * The shell's internal object for all plugins. Here `tagName` is guaranteed because
38
+ * resolution has already happened, and `src` is deliberately absent - it has
39
+ * served its purpose and nothing downstream reads it.
40
+ * Currently its the same shape as TaggedPlugin, their purposes are
41
+ * different and clarity is favored over brevity.
31
42
  */
32
- export type InputPluginEntry = Partial<PluginEntry & SourcedPluginEntry>;
33
- export interface PluginGroup<P extends Partial<PluginBase> = PluginEntry> extends PluginBase {
43
+ export interface ResolvedPlugin extends OscdPluginBase {
44
+ tagName: string;
45
+ }
46
+ /** A group of plugins. */
47
+ export interface PluginGroup<P extends PluginMetadata = OscdPlugin> extends PluginMetadata {
34
48
  plugins: P[];
35
49
  }
36
- export interface PluginSet<P extends Partial<PluginBase> = PluginEntry> {
50
+ /**
51
+ * The root object representing the plugins property (and the resolved plugins).
52
+ */
53
+ export interface PluginSet<P extends PluginMetadata = OscdPlugin> {
37
54
  menu: (P | PluginGroup<P>)[];
38
55
  editor: (P | PluginGroup<P>)[];
39
56
  background: P[];
40
57
  }
41
- declare const OscdShell_base: typeof LitElement & import("@open-wc/scoped-elements/lit-element.js").ScopedElementsHostConstructor;
58
+ declare const OscdShell_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost> & import("@open-wc/scoped-elements/types.js").ScopedElementsHostConstructor;
42
59
  export declare class OscdShell extends OscdShell_base {
43
60
  static scopedElements: {
44
61
  'oscd-app-bar': typeof OscdAppBar;
@@ -61,12 +78,23 @@ export declare class OscdShell extends OscdShell_base {
61
78
  editable: string[];
62
79
  get locale(): LocaleTag;
63
80
  set locale(tag: LocaleTag);
64
- _plugins: PluginSet;
65
- get plugins(): PluginSet;
66
- set plugins(plugins: Partial<PluginSet<InputPluginEntry>>);
81
+ _plugins: PluginSet<OscdPlugin>;
82
+ /** Internal representation of processed `_plugins`. These plugins have been validated and the
83
+ * `tagName` here is guaranteed, sourced entries imported into the registry & tagged. This copy of the
84
+ * plugins is kept separate from the _plugins, which remain an unmodified single source of truth.
85
+ */
86
+ _resolvedPlugins: PluginSet<ResolvedPlugin>;
87
+ /**
88
+ * The plugin set as declared. Deliberately symmetric: what you assign is
89
+ * what you read back, untouched. Resolution (deriving `tagName` from `src`,
90
+ * validating, importing) happens into `_resolvedPlugins`, so the hashed
91
+ * tag names it invents stay an implementation detail.
92
+ */
93
+ get plugins(): PluginSet<OscdPlugin>;
94
+ set plugins(plugins: Partial<PluginSet<OscdPlugin>>);
67
95
  get canRedo(): boolean;
68
96
  get canUndo(): boolean;
69
- selectedEditor?: PluginEntry;
97
+ selectedEditor?: ResolvedPlugin;
70
98
  get doc(): XMLDocument;
71
99
  /** The name of the [[`doc`]] currently being edited */
72
100
  docName: string;
@@ -100,7 +128,7 @@ export declare class OscdShell extends OscdShell_base {
100
128
  redo: (n?: number) => void;
101
129
  private hotkeys;
102
130
  isEditable(docName: string): boolean;
103
- renderPlugin(plugin: PluginEntry): import("lit-html").TemplateResult;
131
+ renderPlugin(plugin: ResolvedPlugin): import("lit-html").TemplateResult;
104
132
  renderOffScreenPlugins(): import("lit-html").TemplateResult<1>;
105
133
  renderDefaultLandingPage(): import("lit-html").TemplateResult<1>;
106
134
  render(): import("lit-html").TemplateResult<1>;
@@ -30,15 +30,26 @@ let OscdShell = class OscdShell extends ScopedElementsMixin(LitElement) {
30
30
  // don't change locale if tag is invalid
31
31
  }
32
32
  }
33
+ /**
34
+ * The plugin set as declared. Deliberately symmetric: what you assign is
35
+ * what you read back, untouched. Resolution (deriving `tagName` from `src`,
36
+ * validating, importing) happens into `_resolvedPlugins`, so the hashed
37
+ * tag names it invents stay an implementation detail.
38
+ */
33
39
  get plugins() {
34
40
  return this._plugins;
35
41
  }
36
42
  set plugins(plugins) {
37
- this._plugins = Object.entries(plugins).reduce((acc, [pluginType, kind]) => {
38
- const convertedPlugins = loadSourcedPlugins(kind, this.registry);
39
- acc[pluginType] = convertedPlugins;
40
- return acc;
41
- }, { menu: [], editor: [], background: [] });
43
+ this._plugins = {
44
+ menu: plugins.menu ?? [],
45
+ editor: plugins.editor ?? [],
46
+ background: plugins.background ?? [],
47
+ };
48
+ this._resolvedPlugins = {
49
+ menu: loadSourcedPlugins(this._plugins.menu, this.registry),
50
+ editor: loadSourcedPlugins(this._plugins.editor, this.registry),
51
+ background: loadSourcedPlugins(this._plugins.background, this.registry),
52
+ };
42
53
  }
43
54
  /*
44
55
  * States
@@ -89,7 +100,20 @@ let OscdShell = class OscdShell extends ScopedElementsMixin(LitElement) {
89
100
  'sed',
90
101
  'ssd',
91
102
  ];
92
- this._plugins = { menu: [], editor: [], background: [] };
103
+ this._plugins = {
104
+ menu: [],
105
+ editor: [],
106
+ background: [],
107
+ };
108
+ /** Internal representation of processed `_plugins`. These plugins have been validated and the
109
+ * `tagName` here is guaranteed, sourced entries imported into the registry & tagged. This copy of the
110
+ * plugins is kept separate from the _plugins, which remain an unmodified single source of truth.
111
+ */
112
+ this._resolvedPlugins = {
113
+ menu: [],
114
+ editor: [],
115
+ background: [],
116
+ };
93
117
  /** The name of the [[`doc`]] currently being edited */
94
118
  this.docName = '';
95
119
  /** The set of `XMLDocument`s currently loaded */
@@ -199,7 +223,7 @@ let OscdShell = class OscdShell extends ScopedElementsMixin(LitElement) {
199
223
  }
200
224
  willUpdate(changedProperties) {
201
225
  if (changedProperties.has('docName') || changedProperties.has('plugins')) {
202
- const firstEditor = flattenPluginEntries(this.plugins.editor)[0];
226
+ const firstEditor = flattenPluginEntries(this._resolvedPlugins.editor)[0];
203
227
  if (this.docName && firstEditor && !this.selectedEditor) {
204
228
  this.selectedEditor = firstEditor;
205
229
  }
@@ -251,12 +275,12 @@ let OscdShell = class OscdShell extends ScopedElementsMixin(LitElement) {
251
275
  return html `
252
276
  <section class="off-screen-plugin-container" aria-hidden="true">
253
277
  <div class="menu-plugins">
254
- ${flattenPluginEntries(this.plugins.menu)
278
+ ${flattenPluginEntries(this._resolvedPlugins.menu)
255
279
  .filter(plugin => !plugin.requireDoc || !!this.docName)
256
280
  .map(plugin => this.renderPlugin(plugin))}
257
281
  </div>
258
282
  <div class="background-plugins">
259
- ${this.plugins.background
283
+ ${this._resolvedPlugins.background
260
284
  .filter(plugin => !plugin.requireDoc || !!this.docName)
261
285
  .map(plugin => this.renderPlugin(plugin))}
262
286
  </div>
@@ -268,7 +292,7 @@ let OscdShell = class OscdShell extends ScopedElementsMixin(LitElement) {
268
292
  <landing-page
269
293
  heading=${this.landingPageHeading}
270
294
  subHeading=${this.landingPageSubHeading}
271
- .menuPlugins=${flattenPluginEntries(this.plugins.menu).filter(plugin => !plugin.requireDoc || !!this.docName)}
295
+ .menuPlugins=${flattenPluginEntries(this._resolvedPlugins.menu).filter(plugin => !plugin.requireDoc || !!this.docName)}
272
296
  .locale=${this.locale}
273
297
  @menu-plugin-select=${(event) => this.handlePluginMenuSelect(event)}
274
298
  >
@@ -293,7 +317,7 @@ let OscdShell = class OscdShell extends ScopedElementsMixin(LitElement) {
293
317
  appTitle=${this.appTitle}
294
318
  appIcon=${this.appIcon}
295
319
  .editableDocs=${this.editableDocs}
296
- .menuPlugins=${this.plugins.menu}
320
+ .menuPlugins=${this._resolvedPlugins.menu}
297
321
  .locale=${this.locale}
298
322
  @menu-plugin-select=${(event) => this.handlePluginMenuSelect(event)}
299
323
  ></plugins-menu>
@@ -349,7 +373,7 @@ let OscdShell = class OscdShell extends ScopedElementsMixin(LitElement) {
349
373
  <main>
350
374
  <section class="editors-side-panel-section">
351
375
  <editor-plugins-panel
352
- .editors=${this.plugins.editor}
376
+ .editors=${this._resolvedPlugins.editor}
353
377
  .selectedEditor=${this.selectedEditor}
354
378
  .locale=${this.locale}
355
379
  @editor-select=${(e) => {