@furystack/shades 12.4.0 → 13.0.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.
Files changed (66) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +3 -3
  3. package/esm/component-factory.spec.js +3 -3
  4. package/esm/component-factory.spec.js.map +1 -1
  5. package/esm/components/lazy-load.js +1 -1
  6. package/esm/components/lazy-load.js.map +1 -1
  7. package/esm/components/link-to-route.js +1 -1
  8. package/esm/components/link-to-route.js.map +1 -1
  9. package/esm/components/nested-route-link.d.ts.map +1 -1
  10. package/esm/components/nested-route-link.js +2 -1
  11. package/esm/components/nested-route-link.js.map +1 -1
  12. package/esm/components/nested-router.js +1 -1
  13. package/esm/components/nested-router.js.map +1 -1
  14. package/esm/components/route-link.d.ts.map +1 -1
  15. package/esm/components/route-link.js +2 -1
  16. package/esm/components/route-link.js.map +1 -1
  17. package/esm/components/router.js +1 -1
  18. package/esm/components/router.js.map +1 -1
  19. package/esm/css-generator.d.ts +1 -1
  20. package/esm/css-generator.js +1 -1
  21. package/esm/services/location-service.d.ts +13 -0
  22. package/esm/services/location-service.d.ts.map +1 -1
  23. package/esm/services/location-service.js +21 -1
  24. package/esm/services/location-service.js.map +1 -1
  25. package/esm/services/screen-service.d.ts.map +1 -1
  26. package/esm/services/screen-service.js +4 -0
  27. package/esm/services/screen-service.js.map +1 -1
  28. package/esm/shade-host-props-ref.integration.spec.js +13 -13
  29. package/esm/shade-host-props-ref.integration.spec.js.map +1 -1
  30. package/esm/shade-resources.integration.spec.js +5 -5
  31. package/esm/shade-resources.integration.spec.js.map +1 -1
  32. package/esm/shade.d.ts +1 -1
  33. package/esm/shade.d.ts.map +1 -1
  34. package/esm/shade.js +2 -3
  35. package/esm/shade.js.map +1 -1
  36. package/esm/shade.spec.js +15 -14
  37. package/esm/shade.spec.js.map +1 -1
  38. package/esm/shades.integration.spec.js +17 -17
  39. package/esm/shades.integration.spec.js.map +1 -1
  40. package/esm/style-manager.d.ts +4 -4
  41. package/esm/style-manager.d.ts.map +1 -1
  42. package/esm/style-manager.js +9 -9
  43. package/esm/style-manager.js.map +1 -1
  44. package/esm/style-manager.spec.js +3 -3
  45. package/esm/style-manager.spec.js.map +1 -1
  46. package/esm/vnode.integration.spec.js +18 -16
  47. package/esm/vnode.integration.spec.js.map +1 -1
  48. package/package.json +5 -5
  49. package/src/component-factory.spec.tsx +3 -3
  50. package/src/components/lazy-load.tsx +1 -1
  51. package/src/components/link-to-route.tsx +1 -1
  52. package/src/components/nested-route-link.tsx +2 -1
  53. package/src/components/nested-router.tsx +1 -1
  54. package/src/components/route-link.tsx +2 -1
  55. package/src/components/router.tsx +1 -1
  56. package/src/css-generator.ts +1 -1
  57. package/src/services/location-service.tsx +22 -1
  58. package/src/services/screen-service.ts +4 -0
  59. package/src/shade-host-props-ref.integration.spec.tsx +13 -13
  60. package/src/shade-resources.integration.spec.tsx +6 -5
  61. package/src/shade.spec.tsx +15 -14
  62. package/src/shade.ts +3 -4
  63. package/src/shades.integration.spec.tsx +17 -17
  64. package/src/style-manager.spec.ts +3 -3
  65. package/src/style-manager.ts +9 -9
  66. package/src/vnode.integration.spec.tsx +18 -16
@@ -39,10 +39,11 @@ export class LocationService implements Disposable {
39
39
  public [Symbol.dispose]() {
40
40
  window.removeEventListener('popstate', this.popStateListener)
41
41
  window.removeEventListener('hashchange', this.hashChangeListener)
42
- this.onLocationPathChanged[Symbol.dispose]()
43
42
  this.onLocationSearchChanged[Symbol.dispose]()
44
43
  this.onDeserializedLocationSearchChanged[Symbol.dispose]()
45
44
  this.locationDeserializerObserver[Symbol.dispose]()
45
+ this.onLocationPathChanged[Symbol.dispose]()
46
+ this.onLocationHashChanged[Symbol.dispose]()
46
47
 
47
48
  window.history.pushState = this.originalPushState
48
49
  window.history.replaceState = this.originalReplaceState
@@ -69,6 +70,10 @@ export class LocationService implements Disposable {
69
70
  this.onDeserializedLocationSearchChanged.setValue(this.deserializeQueryString(search))
70
71
  })
71
72
 
73
+ /**
74
+ * Synchronizes the observable state with the current browser location.
75
+ * Called internally after navigation events and history state changes.
76
+ */
72
77
  public updateState = (() => {
73
78
  this.onLocationPathChanged.setValue(location.pathname)
74
79
  this.onLocationHashChanged.setValue(location.hash.replace('#', ''))
@@ -80,10 +85,25 @@ export class LocationService implements Disposable {
80
85
  * The LocationService interceptor ensures routing state is updated correctly.
81
86
  */
82
87
  public navigate(path: string): void {
88
+ // eslint-disable-next-line furystack/prefer-location-service -- This IS the LocationService.navigate() implementation.
83
89
  history.pushState(null, '', path)
84
90
  this.updateState()
85
91
  }
86
92
 
93
+ /**
94
+ * Replace the current history entry with a new path. Use this instead of
95
+ * raw history.replaceState for SPA redirects (e.g. the intermediate URL
96
+ * should not appear in the browser's back/forward stack).
97
+ */
98
+ public replace(path: string): void {
99
+ // eslint-disable-next-line furystack/prefer-location-service -- This IS the LocationService.replace() implementation.
100
+ history.replaceState(null, '', path)
101
+ this.updateState()
102
+ }
103
+
104
+ /**
105
+ * Internal cache of per-key search parameter observables created by {@link useSearchParam}.
106
+ */
87
107
  public readonly searchParamObservables = new Map<string, ObservableValue<any>>()
88
108
 
89
109
  /**
@@ -110,6 +130,7 @@ export class LocationService implements Disposable {
110
130
  if (currentQueryStringObject[key] !== value) {
111
131
  const params = this.serializeToQueryString({ ...currentQueryStringObject, [key]: value })
112
132
  const newUrl = `${location.pathname}?${params}`
133
+ // eslint-disable-next-line furystack/prefer-location-service -- Internal LocationService plumbing for search param sync.
113
134
  history.pushState({}, '', newUrl)
114
135
  }
115
136
  })
@@ -83,6 +83,10 @@ export class ScreenService implements Disposable {
83
83
  */
84
84
  public [Symbol.dispose]() {
85
85
  window.removeEventListener('resize', this.onResizeListener)
86
+ this.orientation[Symbol.dispose]()
87
+ Object.values(this.screenSize.atLeast).forEach((observable) => {
88
+ observable[Symbol.dispose]()
89
+ })
86
90
  }
87
91
 
88
92
  /**
@@ -18,7 +18,7 @@ describe('useHostProps integration tests', () => {
18
18
  const rootElement = document.getElementById('root') as HTMLDivElement
19
19
 
20
20
  const ExampleComponent = Shade<{ variant: string }>({
21
- shadowDomName: 'host-props-data-attr-test',
21
+ customElementName: 'host-props-data-attr-test',
22
22
  render: ({ props, useHostProps }) => {
23
23
  useHostProps({
24
24
  'data-variant': props.variant,
@@ -45,7 +45,7 @@ describe('useHostProps integration tests', () => {
45
45
  const rootElement = document.getElementById('root') as HTMLDivElement
46
46
 
47
47
  const ExampleComponent = Shade({
48
- shadowDomName: 'host-props-aria-test',
48
+ customElementName: 'host-props-aria-test',
49
49
  render: ({ useHostProps }) => {
50
50
  useHostProps({
51
51
  role: 'progressbar',
@@ -77,7 +77,7 @@ describe('useHostProps integration tests', () => {
77
77
  const rootElement = document.getElementById('root') as HTMLDivElement
78
78
 
79
79
  const ExampleComponent = Shade({
80
- shadowDomName: 'host-props-css-vars-test',
80
+ customElementName: 'host-props-css-vars-test',
81
81
  render: ({ useHostProps }) => {
82
82
  useHostProps({
83
83
  style: {
@@ -107,7 +107,7 @@ describe('useHostProps integration tests', () => {
107
107
  const rootElement = document.getElementById('root') as HTMLDivElement
108
108
 
109
109
  const ExampleComponent = Shade({
110
- shadowDomName: 'host-props-inline-style-test',
110
+ customElementName: 'host-props-inline-style-test',
111
111
  render: ({ useHostProps }) => {
112
112
  useHostProps({
113
113
  style: {
@@ -137,7 +137,7 @@ describe('useHostProps integration tests', () => {
137
137
  const rootElement = document.getElementById('root') as HTMLDivElement
138
138
 
139
139
  const ExampleComponent = Shade({
140
- shadowDomName: 'host-props-merge-test',
140
+ customElementName: 'host-props-merge-test',
141
141
  render: ({ useHostProps }) => {
142
142
  useHostProps({
143
143
  'data-first': 'one',
@@ -172,7 +172,7 @@ describe('useHostProps integration tests', () => {
172
172
  const showExtra = new ObservableValue(true)
173
173
 
174
174
  const ExampleComponent = Shade({
175
- shadowDomName: 'host-props-remove-attr-test',
175
+ customElementName: 'host-props-remove-attr-test',
176
176
  render: ({ useHostProps, useObservable }) => {
177
177
  const [show] = useObservable('showExtra', showExtra)
178
178
  useHostProps({
@@ -208,7 +208,7 @@ describe('useHostProps integration tests', () => {
208
208
  const showColor = new ObservableValue(true)
209
209
 
210
210
  const ExampleComponent = Shade({
211
- shadowDomName: 'host-props-remove-css-var-test',
211
+ customElementName: 'host-props-remove-css-var-test',
212
212
  render: ({ useHostProps, useObservable }) => {
213
213
  const [show] = useObservable('showColor', showColor)
214
214
  useHostProps({
@@ -246,7 +246,7 @@ describe('useHostProps integration tests', () => {
246
246
  let clicked = false
247
247
 
248
248
  const ExampleComponent = Shade({
249
- shadowDomName: 'host-props-event-test',
249
+ customElementName: 'host-props-event-test',
250
250
  render: ({ useHostProps }) => {
251
251
  useHostProps({
252
252
  onclick: () => {
@@ -286,7 +286,7 @@ describe('useRef integration tests', () => {
286
286
  let capturedRef: { readonly current: HTMLDivElement | null } | undefined
287
287
 
288
288
  const ExampleComponent = Shade({
289
- shadowDomName: 'use-ref-basic-test',
289
+ customElementName: 'use-ref-basic-test',
290
290
  render: ({ useRef }) => {
291
291
  const divRef = useRef<HTMLDivElement>('myDiv')
292
292
  capturedRef = divRef
@@ -320,7 +320,7 @@ describe('useRef integration tests', () => {
320
320
  const capturedRefs: Array<{ readonly current: Element | null }> = []
321
321
 
322
322
  const ExampleComponent = Shade({
323
- shadowDomName: 'use-ref-stable-test',
323
+ customElementName: 'use-ref-stable-test',
324
324
  render: ({ useRef, useObservable }) => {
325
325
  const [count] = useObservable('counter', counter)
326
326
  const divRef = useRef('myDiv')
@@ -355,7 +355,7 @@ describe('useRef integration tests', () => {
355
355
  let capturedInputRef: { readonly current: HTMLInputElement | null } | undefined
356
356
 
357
357
  const ExampleComponent = Shade({
358
- shadowDomName: 'use-ref-nested-test',
358
+ customElementName: 'use-ref-nested-test',
359
359
  render: ({ useRef }) => {
360
360
  const inputRef = useRef<HTMLInputElement>('input')
361
361
  capturedInputRef = inputRef
@@ -391,7 +391,7 @@ describe('useRef integration tests', () => {
391
391
  let capturedRef: { readonly current: HTMLSpanElement | null } | undefined
392
392
 
393
393
  const ExampleComponent = Shade({
394
- shadowDomName: 'use-ref-unmount-test',
394
+ customElementName: 'use-ref-unmount-test',
395
395
  render: ({ useRef, useObservable }) => {
396
396
  const [show] = useObservable('showChild', showChild)
397
397
  const spanRef = useRef<HTMLSpanElement>('span')
@@ -423,7 +423,7 @@ describe('useRef integration tests', () => {
423
423
  const counter = new ObservableValue(0)
424
424
 
425
425
  const ExampleComponent = Shade({
426
- shadowDomName: 'use-ref-onchange-test',
426
+ customElementName: 'use-ref-onchange-test',
427
427
  render: ({ useRef, useObservable }) => {
428
428
  const spanRef = useRef<HTMLSpanElement>('counterSpan')
429
429
  useObservable('counter', counter, {
@@ -35,7 +35,7 @@ describe('Shade Resources integration tests', () => {
35
35
  </div>
36
36
  )
37
37
  },
38
- shadowDomName: 'shades-example-resource',
38
+ customElementName: 'shades-example-resource',
39
39
  })
40
40
 
41
41
  expect(obs1.getObservers().length).toBe(0)
@@ -99,7 +99,7 @@ describe('Shade Resources integration tests', () => {
99
99
  renderCounter()
100
100
  return <div id="val">{value}</div>
101
101
  },
102
- shadowDomName: 'shades-example-custom-onchange',
102
+ customElementName: 'shades-example-custom-onchange',
103
103
  })
104
104
 
105
105
  initializeShadeRoot({
@@ -162,11 +162,12 @@ describe('Shade Resources integration tests', () => {
162
162
  renderCounter()
163
163
  return (
164
164
  <div ref={valRef} id="manual-val">
165
+ {/* eslint-disable-next-line furystack/no-direct-get-value-in-render -- Test: verifying manual DOM update pattern with onChange callback */}
165
166
  {obs.getValue()}
166
167
  </div>
167
168
  )
168
169
  },
169
- shadowDomName: 'shades-example-manual-dom-update',
170
+ customElementName: 'shades-example-manual-dom-update',
170
171
  })
171
172
 
172
173
  initializeShadeRoot({
@@ -227,7 +228,7 @@ describe('Shade Resources integration tests', () => {
227
228
  </div>
228
229
  )
229
230
  },
230
- shadowDomName: 'shades-example-batching',
231
+ customElementName: 'shades-example-batching',
231
232
  })
232
233
 
233
234
  initializeShadeRoot({
@@ -272,7 +273,7 @@ describe('Shade Resources integration tests', () => {
272
273
  renderCounter()
273
274
  return <div>content</div>
274
275
  },
275
- shadowDomName: 'shades-example-update-batching',
276
+ customElementName: 'shades-example-update-batching',
276
277
  })
277
278
 
278
279
  initializeShadeRoot({
@@ -13,18 +13,18 @@ describe('Shade edge cases', () => {
13
13
  document.body.innerHTML = ''
14
14
  })
15
15
 
16
- describe('duplicate shadowDomName error', () => {
17
- it('should throw an error when registering a duplicate shadowDomName', () => {
16
+ describe('duplicate customElementName error', () => {
17
+ it('should throw an error when registering a duplicate customElementName', () => {
18
18
  // First registration should succeed
19
19
  Shade({
20
- shadowDomName: 'shade-duplicate-test',
20
+ customElementName: 'shade-duplicate-test',
21
21
  render: () => <div>First</div>,
22
22
  })
23
23
 
24
24
  // Second registration with the same name should throw
25
25
  expect(() => {
26
26
  Shade({
27
- shadowDomName: 'shade-duplicate-test',
27
+ customElementName: 'shade-duplicate-test',
28
28
  render: () => <div>Second</div>,
29
29
  })
30
30
  }).toThrow("A custom shade with name 'shade-duplicate-test' has already been registered!")
@@ -34,13 +34,13 @@ describe('Shade edge cases', () => {
34
34
  const uniqueName = `shade-duplicate-name-in-error-${Date.now()}`
35
35
 
36
36
  Shade({
37
- shadowDomName: uniqueName,
37
+ customElementName: uniqueName,
38
38
  render: () => <div>First</div>,
39
39
  })
40
40
 
41
41
  try {
42
42
  Shade({
43
- shadowDomName: uniqueName,
43
+ customElementName: uniqueName,
44
44
  render: () => <div>Second</div>,
45
45
  })
46
46
  // Should not reach here
@@ -61,7 +61,7 @@ describe('Shade edge cases', () => {
61
61
  let childCapturedInjector: Injector | undefined
62
62
 
63
63
  const ChildComponent = Shade<{ injector?: Injector }>({
64
- shadowDomName: 'shade-injector-child-props-test',
64
+ customElementName: 'shade-injector-child-props-test',
65
65
  render: ({ injector }) => {
66
66
  childCapturedInjector = injector
67
67
  return <div>Child</div>
@@ -69,7 +69,7 @@ describe('Shade edge cases', () => {
69
69
  })
70
70
 
71
71
  const ParentComponent = Shade({
72
- shadowDomName: 'shade-injector-parent-props-test',
72
+ customElementName: 'shade-injector-parent-props-test',
73
73
  render: ({ injector, children }) => {
74
74
  parentCapturedInjector = injector
75
75
  return <div>{children}</div>
@@ -105,7 +105,7 @@ describe('Shade edge cases', () => {
105
105
  const renderCounter = vi.fn()
106
106
 
107
107
  const ExampleComponent = Shade({
108
- shadowDomName: 'shade-no-render-after-disconnect',
108
+ customElementName: 'shade-no-render-after-disconnect',
109
109
  render: () => {
110
110
  renderCounter()
111
111
  return <div>content</div>
@@ -140,7 +140,7 @@ describe('Shade edge cases', () => {
140
140
  const renderCounter = vi.fn()
141
141
 
142
142
  const ExampleComponent = Shade({
143
- shadowDomName: 'shade-no-sync-render-after-disconnect',
143
+ customElementName: 'shade-no-sync-render-after-disconnect',
144
144
  render: () => {
145
145
  renderCounter()
146
146
  return <div>content</div>
@@ -174,7 +174,7 @@ describe('Shade edge cases', () => {
174
174
  const obs = new ObservableValue(0)
175
175
 
176
176
  const ExampleComponent = Shade({
177
- shadowDomName: 'shade-no-render-during-disposal',
177
+ customElementName: 'shade-no-render-during-disposal',
178
178
  render: ({ useObservable, useDisposable }) => {
179
179
  useObservable('obs', obs)
180
180
  useDisposable('cleanup', () => ({
@@ -183,6 +183,7 @@ describe('Shade edge cases', () => {
183
183
  },
184
184
  }))
185
185
  renderCounter()
186
+ // eslint-disable-next-line furystack/no-direct-get-value-in-render -- Test: verifying no re-render during disposal; already subscribed via useObservable above
186
187
  return <div>{obs.getValue()}</div>
187
188
  },
188
189
  })
@@ -226,7 +227,7 @@ describe('Shade edge cases', () => {
226
227
  const stateKey = 'broadcast-test-key'
227
228
 
228
229
  const ExampleComponent = Shade({
229
- shadowDomName: 'shade-broadcast-channel-test',
230
+ customElementName: 'shade-broadcast-channel-test',
230
231
  render: ({ useStoredState }) => {
231
232
  const [value] = useStoredState(stateKey, 'initial', store)
232
233
  return <div id="value">{value}</div>
@@ -270,7 +271,7 @@ describe('Shade edge cases', () => {
270
271
  const stateKey = 'broadcast-filter-test-key'
271
272
 
272
273
  const ExampleComponent = Shade({
273
- shadowDomName: 'shade-broadcast-channel-filter-test',
274
+ customElementName: 'shade-broadcast-channel-filter-test',
274
275
  render: ({ useStoredState }) => {
275
276
  const [value] = useStoredState(stateKey, 'initial', store)
276
277
  return <div id="value">{value}</div>
@@ -315,7 +316,7 @@ describe('Shade edge cases', () => {
315
316
  const stateKey = 'broadcast-cleanup-test-key'
316
317
 
317
318
  const ExampleComponent = Shade({
318
- shadowDomName: 'shade-broadcast-channel-cleanup-test',
319
+ customElementName: 'shade-broadcast-channel-cleanup-test',
319
320
  render: ({ useStoredState }) => {
320
321
  const [value] = useStoredState(stateKey, 'initial', store)
321
322
  return <div id="value">{value}</div>
package/src/shade.ts CHANGED
@@ -17,7 +17,7 @@ export type ShadeOptions<TProps, TElementBase extends HTMLElement> = {
17
17
  *
18
18
  * @example 'my-button', 'shade-dialog', 'app-header'
19
19
  */
20
- shadowDomName: string
20
+ customElementName: string
21
21
 
22
22
  /**
23
23
  * Render hook, this method will be executed on each and every render.
@@ -68,8 +68,7 @@ export type ShadeOptions<TProps, TElementBase extends HTMLElement> = {
68
68
  export const Shade = <TProps, TElementBase extends HTMLElement = HTMLElement>(
69
69
  o: ShadeOptions<TProps, TElementBase>,
70
70
  ) => {
71
- // Register custom element
72
- const customElementName = o.shadowDomName
71
+ const { customElementName } = o
73
72
 
74
73
  const existing = customElements.get(customElementName)
75
74
  if (!existing) {
@@ -438,7 +437,7 @@ export const Shade = <TProps, TElementBase extends HTMLElement = HTMLElement>(
438
437
  o.elementBaseName ? { extends: o.elementBaseName } : undefined,
439
438
  )
440
439
  } else {
441
- throw Error(`A custom shade with name '${o.shadowDomName}' has already been registered!`)
440
+ throw Error(`A custom shade with name '${o.customElementName}' has already been registered!`)
442
441
  }
443
442
 
444
443
  return (props: TProps & PartialElement<TElementBase>, children?: ChildrenList) => {
@@ -18,7 +18,7 @@ describe('Shades integration tests', () => {
18
18
  await usingAsync(new Injector(), async (injector) => {
19
19
  const rootElement = document.getElementById('root') as HTMLDivElement
20
20
 
21
- const ExampleComponent = Shade({ render: () => <div>Hello</div>, shadowDomName: 'shades-example' })
21
+ const ExampleComponent = Shade({ render: () => <div>Hello</div>, customElementName: 'shades-example' })
22
22
 
23
23
  initializeShadeRoot({
24
24
  injector,
@@ -34,7 +34,7 @@ describe('Shades integration tests', () => {
34
34
  await usingAsync(new Injector(), async (injector) => {
35
35
  const rootElement = document.getElementById('root') as HTMLDivElement
36
36
 
37
- const ExampleComponent = Shade({ render: () => 'Hello', shadowDomName: 'shades-string-render-result' })
37
+ const ExampleComponent = Shade({ render: () => 'Hello', customElementName: 'shades-string-render-result' })
38
38
 
39
39
  initializeShadeRoot({
40
40
  injector,
@@ -52,7 +52,7 @@ describe('Shades integration tests', () => {
52
52
  await usingAsync(new Injector(), async (injector) => {
53
53
  const rootElement = document.getElementById('root') as HTMLDivElement
54
54
 
55
- const ExampleComponent = Shade({ render: () => null, shadowDomName: 'shades-null-render-result' })
55
+ const ExampleComponent = Shade({ render: () => null, customElementName: 'shades-null-render-result' })
56
56
 
57
57
  initializeShadeRoot({
58
58
  injector,
@@ -77,7 +77,7 @@ describe('Shades integration tests', () => {
77
77
  <p>2</p>
78
78
  </>
79
79
  ),
80
- shadowDomName: 'shades-fragment-render-result',
80
+ customElementName: 'shades-fragment-render-result',
81
81
  })
82
82
 
83
83
  initializeShadeRoot({
@@ -105,7 +105,7 @@ describe('Shades integration tests', () => {
105
105
  </>
106
106
  </p>
107
107
  ),
108
- shadowDomName: 'shades-fragment-render-result-nested',
108
+ customElementName: 'shades-fragment-render-result-nested',
109
109
  })
110
110
 
111
111
  initializeShadeRoot({
@@ -125,7 +125,7 @@ describe('Shades integration tests', () => {
125
125
  const rootElement = document.getElementById('root') as HTMLDivElement
126
126
 
127
127
  const CustomComponent = Shade({
128
- shadowDomName: 'shades-fragment-test-custom-component',
128
+ customElementName: 'shades-fragment-test-custom-component',
129
129
  render: () => <p>Hello</p>,
130
130
  })
131
131
 
@@ -136,7 +136,7 @@ describe('Shades integration tests', () => {
136
136
  <CustomComponent />
137
137
  </>
138
138
  ),
139
- shadowDomName: 'shades-fragment-render-result-2',
139
+ customElementName: 'shades-fragment-render-result-2',
140
140
  })
141
141
 
142
142
  initializeShadeRoot({
@@ -157,12 +157,12 @@ describe('Shades integration tests', () => {
157
157
 
158
158
  const ExampleComponent = Shade({
159
159
  render: ({ children }) => <div>{children}</div>,
160
- shadowDomName: 'shades-example-2',
160
+ customElementName: 'shades-example-2',
161
161
  })
162
162
 
163
163
  const ExampleSubs = Shade<{ no: number }>({
164
164
  render: ({ props }) => <div>{props.no}</div>,
165
- shadowDomName: 'shades-example-sub',
165
+ customElementName: 'shades-example-sub',
166
166
  })
167
167
 
168
168
  initializeShadeRoot({
@@ -190,7 +190,7 @@ describe('Shades integration tests', () => {
190
190
  const setup = vi.fn()
191
191
 
192
192
  const ExampleComponent = Shade({
193
- shadowDomName: 'example-component-1',
193
+ customElementName: 'example-component-1',
194
194
  render: ({ useDisposable }) => {
195
195
  useDisposable('test', () => {
196
196
  setup()
@@ -219,7 +219,7 @@ describe('Shades integration tests', () => {
219
219
  const rootElement = document.getElementById('root') as HTMLDivElement
220
220
 
221
221
  const ExampleComponent = Shade({
222
- shadowDomName: 'example-component-3',
222
+ customElementName: 'example-component-3',
223
223
  render: ({ useState }) => {
224
224
  const [count, setCount] = useState('count', 0)
225
225
  return (
@@ -290,7 +290,7 @@ describe('Shades integration tests', () => {
290
290
  const rootElement = document.getElementById('root') as HTMLDivElement
291
291
 
292
292
  const ExampleComponent = Shade({
293
- shadowDomName: 'example-component-3-stored-state',
293
+ customElementName: 'example-component-3-stored-state',
294
294
  render: ({ useStoredState }) => {
295
295
  const [count, setCount] = useStoredState('count', 0, store)
296
296
  return (
@@ -348,7 +348,7 @@ describe('Shades integration tests', () => {
348
348
  const rootElement = document.getElementById('root') as HTMLDivElement
349
349
 
350
350
  const ExampleComponent = Shade({
351
- shadowDomName: 'example-component-3-search-state',
351
+ customElementName: 'example-component-3-search-state',
352
352
  render: ({ useSearchState }) => {
353
353
  const [count, setCount] = useSearchState('count', 0)
354
354
  return (
@@ -403,7 +403,7 @@ describe('Shades integration tests', () => {
403
403
  await usingAsync(new Injector(), async (injector) => {
404
404
  const rootElement = document.getElementById('root') as HTMLDivElement
405
405
  const Parent = Shade({
406
- shadowDomName: 'shade-remount-parent',
406
+ customElementName: 'shade-remount-parent',
407
407
  render: ({ children, useState }) => {
408
408
  const [areChildrenVisible, setAreChildrenVisible] = useState('areChildrenVisible', true)
409
409
  return (
@@ -423,7 +423,7 @@ describe('Shades integration tests', () => {
423
423
  })
424
424
 
425
425
  const Child = Shade({
426
- shadowDomName: 'example-remount-child',
426
+ customElementName: 'example-remount-child',
427
427
  render: ({ useState }) => {
428
428
  const [count, setCount] = useState('count', 0)
429
429
 
@@ -493,14 +493,14 @@ describe('Shades integration tests', () => {
493
493
  const rootElement = document.getElementById('root') as HTMLDivElement
494
494
 
495
495
  const ChildComponent = Shade<{ isDisabled: boolean }>({
496
- shadowDomName: 'shade-prop-child',
496
+ customElementName: 'shade-prop-child',
497
497
  render: ({ props }) => {
498
498
  return <input type="checkbox" disabled={props.isDisabled} data-testid="inner-input" />
499
499
  },
500
500
  })
501
501
 
502
502
  const ParentComponent = Shade({
503
- shadowDomName: 'shade-prop-parent',
503
+ customElementName: 'shade-prop-parent',
504
504
  render: ({ useState }) => {
505
505
  const [isDisabled, setIsDisabled] = useState('isDisabled', false)
506
506
  return (
@@ -181,7 +181,7 @@ describe('StyleManager', () => {
181
181
  describe('Shade integration', () => {
182
182
  it('should register CSS styles when Shade component is created with css property', () => {
183
183
  Shade({
184
- shadowDomName: 'shade-css-test-component',
184
+ customElementName: 'shade-css-test-component',
185
185
  css: {
186
186
  color: 'red',
187
187
  padding: '10px',
@@ -200,7 +200,7 @@ describe('StyleManager', () => {
200
200
 
201
201
  it('should register CSS with attribute selector for customized built-in elements', () => {
202
202
  Shade({
203
- shadowDomName: 'shade-css-test-button',
203
+ customElementName: 'shade-css-test-button',
204
204
  elementBase: HTMLButtonElement,
205
205
  elementBaseName: 'button',
206
206
  css: {
@@ -219,7 +219,7 @@ describe('StyleManager', () => {
219
219
 
220
220
  it('should not register styles when Shade component has no css property', () => {
221
221
  Shade({
222
- shadowDomName: 'shade-no-css-component',
222
+ customElementName: 'shade-no-css-component',
223
223
  render: () => null,
224
224
  })
225
225
 
@@ -27,7 +27,7 @@ class StyleManagerClass {
27
27
  * Registers CSS styles for a component.
28
28
  * Styles are only injected once per component (based on the custom element name).
29
29
  *
30
- * @param shadowDomName - The custom element tag name (used as CSS selector)
30
+ * @param customElementName - The custom element tag name (used as CSS selector)
31
31
  * @param cssObject - The CSSObject containing styles and nested selectors
32
32
  * @param elementBaseName - Optional base element name for customized built-in elements (e.g., 'a', 'button').
33
33
  * When provided, generates selector like `a[is="component-name"]` instead of `component-name`
@@ -49,17 +49,17 @@ class StyleManagerClass {
49
49
  * // Generates: a[is="my-link"] { color: blue; }
50
50
  * ```
51
51
  */
52
- public registerComponentStyles(shadowDomName: string, cssObject: CSSObject, elementBaseName?: string): boolean {
53
- if (this.registeredComponents.has(shadowDomName)) {
52
+ public registerComponentStyles(customElementName: string, cssObject: CSSObject, elementBaseName?: string): boolean {
53
+ if (this.registeredComponents.has(customElementName)) {
54
54
  return false
55
55
  }
56
56
 
57
- const selector = elementBaseName ? `${elementBaseName}[is="${shadowDomName}"]` : shadowDomName
57
+ const selector = elementBaseName ? `${elementBaseName}[is="${customElementName}"]` : customElementName
58
58
  const css = generateCSS(selector, cssObject)
59
59
  if (css) {
60
60
  const styleElement = this.getStyleElement()
61
- styleElement.textContent += `\n/* ${shadowDomName} */\n${css}\n`
62
- this.registeredComponents.add(shadowDomName)
61
+ styleElement.textContent += `\n/* ${customElementName} */\n${css}\n`
62
+ this.registeredComponents.add(customElementName)
63
63
  return true
64
64
  }
65
65
 
@@ -68,11 +68,11 @@ class StyleManagerClass {
68
68
 
69
69
  /**
70
70
  * Checks if a component's styles have already been registered
71
- * @param shadowDomName - The component identifier to check
71
+ * @param customElementName - The component identifier to check
72
72
  * @returns True if styles are already registered
73
73
  */
74
- public isRegistered(shadowDomName: string): boolean {
75
- return this.registeredComponents.has(shadowDomName)
74
+ public isRegistered(customElementName: string): boolean {
75
+ return this.registeredComponents.has(customElementName)
76
76
  }
77
77
 
78
78
  /**