@@ -32,15 +32,19 @@ export interface ISidebarContext {
3232 * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_components
3333 * @see https://vuejs.org/guide/extras/web-components#building-custom-elements-with-vue
3434 */
35- export interface SidebarComponent extends HTMLElement , ISidebarContext {
35+ export interface SidebarTabComponent extends ISidebarContext {
3636 /**
37- * This method is called by the files app if the sidebar tab state changes.
38- *
39- * @param active - The new active state
37+ * The active state of the sidebar tab.
38+ * It will be set to true if this component is the currently active tab.
4039 */
41- setActive ( active : boolean ) : Promise < void >
40+ active : boolean
4241}
4342
43+ /**
44+ * The instance type of a sidebar tab web component.
45+ */
46+ export type SidebarTabComponentInstance = SidebarTabComponent & HTMLElement
47+
4448/**
4549 * Implementation of a custom sidebar tab within the files app.
4650 */
@@ -69,7 +73,10 @@ export interface ISidebarTab {
6973
7074 /**
7175 * The tag name of the web component.
72- * The web component must already be registered under that tag name with `CustomElementRegistry.define()`.
76+ *
77+ * The web component must be defined using this name with `CustomElementRegistry.define()`,
78+ * either on initialization or within the `onInit` callback (preferred).
79+ * When rendering the sidebar tab, the files app will wait for the component to be defined in the registry (`customElements.whenDefined()`).
7380 *
7481 * To avoid name clashes the name has to start with your appid (e.g. `your_app`).
7582 * So in addition with the web component naming rules a good name would be `your_app-files-sidebar-tab`.
@@ -79,9 +86,20 @@ export interface ISidebarTab {
7986 /**
8087 * Callback to check if the sidebar tab should be shown for the selected node.
8188 *
89+ * If not provided, the tab will always be shown.
90+ *
8291 * @param context - The current context of the files app
8392 */
84- enabled : ( context : ISidebarContext ) => boolean
93+ enabled ?: ( context : ISidebarContext ) => boolean
94+
95+ /**
96+ * Called when the sidebar tab is active and rendered the first time in the sidebar.
97+ * This should be used to register the web componen (`CustomElementRegistry.define()`).
98+ *
99+ * The sidebar itself will anyways wait for the component to be defined in the registry (`customElements.whenDefined()`).
100+ * But also will wait for the promise returned by this method to resolve before rendering the tab.
101+ */
102+ onInit ?: ( ) => Promise < void >
85103}
86104
87105/**
@@ -132,7 +150,7 @@ function validateSidebarTab(tab: ISidebarTab): void {
132150 }
133151
134152 if ( ! tab . tagName . match ( / ^ [ a - z ] [ a - z 0 - 9 - _ ] + $ / ) ) {
135- throw new Error ( 'Sidebar tabs tagName name is invalid' )
153+ throw new Error ( 'Sidebar tab " tagName" is invalid' )
136154 }
137155
138156 if ( ! tab . displayName || typeof tab . displayName !== 'string' ) {
@@ -147,7 +165,11 @@ function validateSidebarTab(tab: ISidebarTab): void {
147165 throw new Error ( 'Sidebar tabs need to have a numeric order set' )
148166 }
149167
150- if ( typeof tab . enabled !== 'function' ) {
151- throw new Error ( 'Sidebar tabs need to have an "enabled" method' )
168+ if ( tab . enabled && typeof tab . enabled !== 'function' ) {
169+ throw new Error ( 'Sidebar tab "enabled" is not a function' )
170+ }
171+
172+ if ( tab . onInit && typeof tab . onInit !== 'function' ) {
173+ throw new Error ( 'Sidebar tab "onInit" is not a function' )
152174 }
153175}
0 commit comments