@tylertech/forge-core 3.0.1 → 3.2.0

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.
@@ -14,6 +14,11 @@ export declare function defineCustomElements(components: any[]): void;
14
14
  * @param ctor The custom element constructor.
15
15
  */
16
16
  export declare function tryDefine(name: string, ctor: CustomElementConstructor, options?: ElementDefinitionOptions | undefined): void;
17
+ /**
18
+ * Checks to see if the custom element is defined in the registry.
19
+ * @param name The name of the custom element to query the registry with.
20
+ */
21
+ export declare function hasDefinedCustomElement(name: string): boolean;
17
22
  /**
18
23
  * Useful when capturing the value of a unupgraded component during the `connectedCallback` upon upgrade.
19
24
  *
@@ -44,19 +49,19 @@ export declare function attachLightTemplate<T extends HTMLElement>(componentInst
44
49
  * Attaches a shadow root to the given web component instance.
45
50
  * @param {T} componentInstance A component instance.
46
51
  * @param {string} elementName The name of the element the shadow root is to be attached to.
47
- * @param {string} template The shadow root template HTML string.
52
+ * @param {string | HTMLTemplateElement} template The shadow root template HTML string or element.
48
53
  * @param {string | string[]} styles The shadow root styles string to be encapsulated by this shadow root.
49
54
  * @param {boolean} [delegatesFocus=false] Should the component delegate focus.
50
55
  */
51
- export declare function attachShadowTemplate<T extends HTMLElement>(componentInstance: T, template: string, styles?: string | string[], delegatesFocus?: boolean): void;
56
+ export declare function attachShadowTemplate<T extends HTMLElement>(componentInstance: T, template: string | HTMLTemplateElement, styles?: string | string[], delegatesFocus?: boolean): void;
52
57
  /**
53
58
  * Replaces the template of an existing shadow root with the provided template.
54
59
  * @param {T} componentInstance A component instance.
55
60
  * @param {string} elementName The name of the element the shadow root is to be attached to.
56
- * @param {string} template The shadow root template HTML string.
61
+ * @param {string | HTMLTemplateElement} template The shadow root template HTML string or element.
57
62
  * @param {string | string[]} styles The shadow root styles string to be encapsulated by this shadow root.
58
63
  */
59
- export declare function replaceShadowTemplate<T extends HTMLElement>(componentInstance: T, template: string, styles?: string | string[]): void;
64
+ export declare function replaceShadowTemplate<T extends HTMLElement>(componentInstance: T, template: string | HTMLTemplateElement, styles?: string | string[]): void;
60
65
  /**
61
66
  * Creates and prepares an HTML template element for rendering within a shadow root.
62
67
  * @param {string} elementName The name of the element the shadow root is to be attached to.
@@ -67,9 +72,11 @@ export declare function prepareShadowTemplate(template: string, styles?: string
67
72
  /**
68
73
  * Appends a template to the provided components shadow root.
69
74
  * @param {T} componentInstance A component instance.
70
- * @param {HTMLTemplateElement} templateElement A template element to be cloned.
75
+ * @param {string | HTMLTemplateElement} template A template string or template element to be cloned.
71
76
  */
72
- export declare function setShadowTemplate<T extends HTMLElement>(componentInstance: T, templateElement: HTMLTemplateElement): void;
77
+ export declare function setShadowTemplate<T extends HTMLElement>(componentInstance: T, template: string | HTMLTemplateElement, { force }?: {
78
+ force: boolean;
79
+ }): void;
73
80
  /**
74
81
  * Applies styles to the shadow root of the provided element instance.
75
82
  * @param {T} componentInstance A component instance.
@@ -80,9 +87,9 @@ export declare function setShadowStyles<T extends HTMLElement>(componentInstance
80
87
  force: boolean;
81
88
  }): void;
82
89
  /**
83
- * Reapplies styles to the shadow root of the provided element instance. This function was
90
+ * Re-applies styles to the shadow root of the provided element instance. This function is
84
91
  * intended to be called after an element has been adopted by a new document to reconstruct the
85
- * adopted stylesheet instances within the context of the new document.
92
+ * adopted stylesheet instances within the context (view) of the new document.
86
93
  *
87
94
  * @param componentInstance The component instance to reapply styles to.
88
95
  */
@@ -1,5 +1,5 @@
1
1
  import { replaceElement, isArray, removeAllChildren, walkUpUntil } from '../utils';
2
- import { CUSTOM_ELEMENT_CSS_PROPERTY, CUSTOM_ELEMENT_DEPENDENCIES_PROPERTY, CUSTOM_ELEMENT_NAME_PROPERTY, CUSTOM_ELEMENT_STYLESHEETS_PROPERTY, supportsConstructableStyleSheets } from './constants';
2
+ import { CUSTOM_ELEMENT_CSS_PROPERTY, CUSTOM_ELEMENT_DEPENDENCIES_PROPERTY, CUSTOM_ELEMENT_NAME_PROPERTY, CUSTOM_ELEMENT_STYLESHEETS_PROPERTY, CUSTOM_ELEMENT_TEMPLATE_PROPERTY, supportsConstructableStyleSheets } from './constants';
3
3
  /**
4
4
  * Recursively defines a component as a custom elements and all of its dependencies.
5
5
  * @param component The component to import.
@@ -23,11 +23,18 @@ export function defineCustomElements(components) {
23
23
  * @param ctor The custom element constructor.
24
24
  */
25
25
  export function tryDefine(name, ctor, options) {
26
- if (window?.customElements?.get(name)) {
26
+ if (hasDefinedCustomElement(name)) {
27
27
  return;
28
28
  }
29
29
  window.customElements.define(name, ctor, options);
30
30
  }
31
+ /**
32
+ * Checks to see if the custom element is defined in the registry.
33
+ * @param name The name of the custom element to query the registry with.
34
+ */
35
+ export function hasDefinedCustomElement(name) {
36
+ return window?.customElements?.get(name) !== undefined;
37
+ }
31
38
  /**
32
39
  * Useful when capturing the value of a unupgraded component during the `connectedCallback` upon upgrade.
33
40
  *
@@ -81,37 +88,35 @@ export function attachLightTemplate(componentInstance, template) {
81
88
  * Attaches a shadow root to the given web component instance.
82
89
  * @param {T} componentInstance A component instance.
83
90
  * @param {string} elementName The name of the element the shadow root is to be attached to.
84
- * @param {string} template The shadow root template HTML string.
91
+ * @param {string | HTMLTemplateElement} template The shadow root template HTML string or element.
85
92
  * @param {string | string[]} styles The shadow root styles string to be encapsulated by this shadow root.
86
93
  * @param {boolean} [delegatesFocus=false] Should the component delegate focus.
87
94
  */
88
95
  export function attachShadowTemplate(componentInstance, template, styles, delegatesFocus = false) {
89
- const templateElement = prepareShadowTemplate(template);
90
96
  componentInstance.attachShadow({ mode: 'open', delegatesFocus });
91
97
  if (styles) {
92
98
  setShadowStyles(componentInstance, styles);
93
99
  }
94
- setShadowTemplate(componentInstance, templateElement);
100
+ setShadowTemplate(componentInstance, template);
95
101
  }
96
102
  /**
97
103
  * Replaces the template of an existing shadow root with the provided template.
98
104
  * @param {T} componentInstance A component instance.
99
105
  * @param {string} elementName The name of the element the shadow root is to be attached to.
100
- * @param {string} template The shadow root template HTML string.
106
+ * @param {string | HTMLTemplateElement} template The shadow root template HTML string or element.
101
107
  * @param {string | string[]} styles The shadow root styles string to be encapsulated by this shadow root.
102
108
  */
103
109
  export function replaceShadowTemplate(componentInstance, template, styles) {
104
110
  if (!componentInstance.shadowRoot) {
105
111
  throw new Error('This element does not contain a shadow root. Did you mean to call `attachShadowTemplate`?');
106
112
  }
107
- const templateElement = prepareShadowTemplate(template);
108
113
  if (componentInstance.shadowRoot.children.length) {
109
114
  removeAllChildren(componentInstance.shadowRoot);
110
115
  }
111
116
  if (styles) {
112
117
  setShadowStyles(componentInstance, styles, { force: true });
113
118
  }
114
- setShadowTemplate(componentInstance, templateElement);
119
+ setShadowTemplate(componentInstance, template, { force: true });
115
120
  }
116
121
  /**
117
122
  * Creates and prepares an HTML template element for rendering within a shadow root.
@@ -139,10 +144,16 @@ export function prepareShadowTemplate(template, styles) {
139
144
  /**
140
145
  * Appends a template to the provided components shadow root.
141
146
  * @param {T} componentInstance A component instance.
142
- * @param {HTMLTemplateElement} templateElement A template element to be cloned.
147
+ * @param {string | HTMLTemplateElement} template A template string or template element to be cloned.
143
148
  */
144
- export function setShadowTemplate(componentInstance, templateElement) {
145
- componentInstance.shadowRoot.appendChild(templateElement.content.cloneNode(true));
149
+ export function setShadowTemplate(componentInstance, template, { force } = { force: false }) {
150
+ const ctor = componentInstance.constructor;
151
+ if (force || !ctor[CUSTOM_ELEMENT_TEMPLATE_PROPERTY]) {
152
+ const templateElement = template instanceof HTMLTemplateElement ? template : parseTemplateString(template);
153
+ ctor[CUSTOM_ELEMENT_TEMPLATE_PROPERTY] = templateElement;
154
+ }
155
+ const resolvedTemplate = ctor[CUSTOM_ELEMENT_TEMPLATE_PROPERTY];
156
+ componentInstance.shadowRoot.appendChild(resolvedTemplate.content.cloneNode(true));
146
157
  }
147
158
  /**
148
159
  * Applies styles to the shadow root of the provided element instance.
@@ -187,22 +198,21 @@ export function setShadowStyles(componentInstance, styles, { force } = { force:
187
198
  }
188
199
  }
189
200
  /**
190
- * Reapplies styles to the shadow root of the provided element instance. This function was
201
+ * Re-applies styles to the shadow root of the provided element instance. This function is
191
202
  * intended to be called after an element has been adopted by a new document to reconstruct the
192
- * adopted stylesheet instances within the context of the new document.
203
+ * adopted stylesheet instances within the context (view) of the new document.
193
204
  *
194
205
  * @param componentInstance The component instance to reapply styles to.
195
206
  */
196
207
  export function readoptStyles(componentInstance) {
197
208
  if (!supportsConstructableStyleSheets ||
198
209
  !componentInstance.shadowRoot ||
199
- !componentInstance.constructor[CUSTOM_ELEMENT_CSS_PROPERTY]) {
210
+ !componentInstance.constructor[CUSTOM_ELEMENT_CSS_PROPERTY] ||
211
+ !componentInstance.ownerDocument.defaultView) {
200
212
  return;
201
213
  }
202
- const cssText = componentInstance.constructor[CUSTOM_ELEMENT_CSS_PROPERTY];
203
- const context = componentInstance.ownerDocument.defaultView ?? window;
204
- const sheet = new context.CSSStyleSheet();
205
- sheet.replaceSync(cssText);
214
+ const sheet = new componentInstance.ownerDocument.defaultView.CSSStyleSheet();
215
+ sheet.replaceSync(componentInstance.constructor[CUSTOM_ELEMENT_CSS_PROPERTY]);
206
216
  componentInstance.shadowRoot.adoptedStyleSheets = [sheet];
207
217
  }
208
218
  /**
@@ -1,5 +1,6 @@
1
1
  export declare const CUSTOM_ELEMENT_NAME_PROPERTY: unique symbol;
2
2
  export declare const CUSTOM_ELEMENT_DEPENDENCIES_PROPERTY: unique symbol;
3
+ export declare const CUSTOM_ELEMENT_TEMPLATE_PROPERTY: unique symbol;
3
4
  export declare const CUSTOM_ELEMENT_CSS_PROPERTY: unique symbol;
4
5
  export declare const CUSTOM_ELEMENT_STYLESHEETS_PROPERTY: unique symbol;
5
6
  /** Whether the browser supports constructable stylesheets */
@@ -1,5 +1,6 @@
1
1
  export const CUSTOM_ELEMENT_NAME_PROPERTY = Symbol('Forge custom element tag name');
2
2
  export const CUSTOM_ELEMENT_DEPENDENCIES_PROPERTY = Symbol('Forge custom element dependencies');
3
+ export const CUSTOM_ELEMENT_TEMPLATE_PROPERTY = Symbol('Forge custom element parsed template');
3
4
  export const CUSTOM_ELEMENT_CSS_PROPERTY = Symbol('Forge custom element CSS text');
4
5
  export const CUSTOM_ELEMENT_STYLESHEETS_PROPERTY = Symbol('Forge custom element CSSStyleSheet instances');
5
6
  /** Whether the browser supports constructable stylesheets */
@@ -3,6 +3,7 @@ export class Subject {
3
3
  return this.source;
4
4
  }
5
5
  constructor(value) {
6
+ // eslint-disable-next-line @tylertech-eslint/require-private-modifier
6
7
  this.subscribers = [];
7
8
  this.source = value;
8
9
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tylertech/forge-core",
3
- "version": "3.0.1",
3
+ "version": "3.2.0",
4
4
  "description": "A library of core web utilities that support Tyler Forge™ based libraries.",
5
5
  "author": "Tyler Technologies, Inc.",
6
6
  "license": "Apache-2.0",
@@ -24,28 +24,28 @@
24
24
  "release": "auto shipit"
25
25
  },
26
26
  "dependencies": {
27
- "tslib": "^2.6.3"
27
+ "tslib": "^2.8.1"
28
28
  },
29
29
  "devDependencies": {
30
- "@auto-it/conventional-commits": "^11.1.6",
31
- "@auto-it/first-time-contributor": "^11.1.6",
32
- "@auto-it/npm": "^11.1.6",
33
- "@commitlint/cli": "^19.3.0",
34
- "@commitlint/config-conventional": "^19.2.2",
30
+ "@auto-it/conventional-commits": "^11.3.0",
31
+ "@auto-it/first-time-contributor": "^11.3.0",
32
+ "@auto-it/npm": "^11.3.0",
33
+ "@commitlint/cli": "^19.8.1",
34
+ "@commitlint/config-conventional": "^19.8.1",
35
35
  "@esm-bundle/chai": "^4.3.4-fix.0",
36
- "@tylertech-eslint/eslint-plugin": "^1.0.12",
37
- "@types/mocha": "^10.0.6",
38
- "@types/node": "^20.14.2",
39
- "@types/sinon": "^17.0.3",
40
- "@web/dev-server-esbuild": "^1.0.2",
41
- "@web/test-runner": "^0.18.2",
42
- "auto": "^11.1.6",
43
- "commitlint": "^19.3.0",
36
+ "@tylertech-eslint/eslint-plugin": "^2.1.0",
37
+ "@types/mocha": "^10.0.10",
38
+ "@types/node": "^22.15.21",
39
+ "@types/sinon": "^17.0.4",
40
+ "@web/dev-server-esbuild": "^1.0.4",
41
+ "@web/test-runner": "^0.20.2",
42
+ "auto": "^11.3.0",
43
+ "commitlint": "^19.8.1",
44
44
  "http-server": "^14.1.1",
45
- "husky": "^9.0.11",
46
- "rimraf": "^5.0.7",
47
- "sinon": "^18.0.0",
48
- "typescript": "~5.4.5"
45
+ "husky": "^9.1.7",
46
+ "rimraf": "^6.0.1",
47
+ "sinon": "^20.0.0",
48
+ "typescript": "~5.8.3"
49
49
  },
50
50
  "overrides": {
51
51
  "@typescript-eslint/typescript-estree": "^7.12.0"