Skip to content

Commit

Permalink
Merge pull request #220 from github/remove-autoshadowroot
Browse files Browse the repository at this point in the history
remove autoshadowroot
  • Loading branch information
keithamus authored May 4, 2022
2 parents 92e357a + 3cbdd46 commit d239a05
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 125 deletions.
34 changes: 28 additions & 6 deletions docs/_guide/rendering.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ Remember to _always_ make your JavaScript progressively enhanced, where possible

By leveraging the native [`ShadowDOM`](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM) feature, Catalyst components can render complex sub-trees, fully encapsulated from the rest of the page.

Catalyst will automatically look for elements that match the `template[data-shadowroot]` selector, within your controller. If it finds one as a direct-child of your controller, it will use that to create a shadowRoot.
[Actions]({{ site.baseurl }}/guide/actions) and [Targets]({{ site.baseurl }}/guide/targets) all work within an elements ShadowRoot.

Catalyst Controllers will search for a direct child of `template[data-shadowroot]` and load its contents as the `shadowRoot` of the element. [Actions]({{ site.baseurl }}/guide/actions) and [Targets]({{ site.baseurl }}/guide/targets) all work within an elements ShadowRoot.
You can also leverage the [declarative shadow DOM](https://web.dev/declarative-shadow-dom/) and render a template inline to your HTML, which will automatically be attached (this may require a polyfill for browsers which are yet to support this feature).

### Example

```html
<hello-world>
<template data-shadowroot>
<template shadowroot="open">
<p>
Hello <span data-target="hello-world.nameEl">World</span>
</p>
Expand All @@ -41,12 +41,34 @@ class HelloWorldElement extends HTMLElement {
}
```

Providing the `<template data-shadowroot>` element as a direct child of the `hello-world` element tells Catalyst to render the templates contents automatically, and so all `HelloWorldElements` with this template will be rendered with the contents.

{% capture callout %}
Remember that _all_ instances of your controller _must_ add the `<template data-shadowroot>` HTML. If an instance does not have the `<template data-shadowroot>` as a direct child, then the shadow DOM won't be rendered for it!
Remember that _all_ instances of your controller _must_ add the `<template shadowroot>` HTML. If an instance does not have the `<template data-shadowroot>` as a direct child, then the shadow DOM won't be rendered for it!
{% endcapture %}{% include callout.md %}


It is also possible to attach a shadowRoot to your element during the `connectedCallback`, like so:

```typescript
import { controller, target } from "@github/catalyst"

@controller
class HelloWorldElement extends HTMLElement {
@target nameEl: HTMLElement
get name() {
return this.nameEl.textContent
}
set name(value: string) {
this.nameEl.textContent = value
}

connectedCallback() {
this.attachShadow({ mode: 'open' }).innerHTML = `<p>
Hello <span data-target="hello-world.nameEl">World</span>
</p>`
}
}
```

### Updating a Template element using JS templates

Sometimes you wont have a template that is server rendered, and instead want to make a template using JS. Catalyst does not support this out of the box, but it is possible to use another library: `@github/jtml`. This library can be used to write declarative templates using JS. Let's re-work the above example using `@github/jtml`:
Expand Down
4 changes: 1 addition & 3 deletions docs/_guide/your-first-component.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,14 @@ The `@controller` decorator ties together the various other decorators within Ca
- Calls `defineObservedAttributes` with the class to add map any `@attr` decorators. See [attrs]({{ site.baseurl }}/guide/attrs) for more on this.
- Injects the following code inside of the `connectedCallback()` function of your class:
- `bind(this)`; ensures that as your element connects it picks up any `data-action` handlers. See [actions]({{ site.baseurl }}/guide/actions) for more on this.
- `autoShadowRoot(this)`; ensures that your element loads any `data-shadowroot` templates. See [rendering]({{ site.baseurl }}/guide/rendering) for more on this.
- `initializeAttrs(this)`; ensures that your element binds any `data-*` attributes to props. See [attrs]({{ site.baseurl }}/guide/attrs) for more on this.

You can do all of this manually; for example here's the above `HelloWorldElement`, written without the `@controller` annotation:

```js
import {bind, autoShadowRoot, initializeAttrs, defineObservedAttributes} from '@github/catalyst'
import {bind, initializeAttrs, defineObservedAttributes} from '@github/catalyst'
class HelloWorldElement extends HTMLElement {
connectedCallback() {
autoShadowRoot(this)
initializeAttrs(this)
this.innerHTML = 'Hello World!'
bind(this)
Expand Down
11 changes: 0 additions & 11 deletions src/auto-shadow-root.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/core.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {register} from './register.js'
import {bind, bindShadow} from './bind.js'
import {autoShadowRoot} from './auto-shadow-root.js'
import {defineObservedAttributes, initializeAttrs} from './attr.js'
import type {CustomElement} from './custom-element.js'

Expand Down Expand Up @@ -53,7 +52,6 @@ export class CatalystDelegate {
connectedCallback(instance: HTMLElement, connectedCallback: () => void) {
instance.toggleAttribute('data-catalyst', true)
customElements.upgrade(instance)
autoShadowRoot(instance)
initializeAttrs(instance)
bind(instance)
connectedCallback?.call(instance)
Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ export {findTarget, findTargets} from './findtarget.js'
export {target, targets} from './target.js'
export {controller} from './controller.js'
export {attr, initializeAttrs, defineObservedAttributes} from './attr.js'
export {autoShadowRoot} from './auto-shadow-root.js'
77 changes: 0 additions & 77 deletions test/auto-shadow-root.ts

This file was deleted.

25 changes: 0 additions & 25 deletions test/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,31 +67,6 @@ describe('controller', () => {
expect(instance.foo).to.have.callCount(1)
})

it('binds auto shadowRoots', async () => {
@controller
// eslint-disable-next-line @typescript-eslint/no-unused-vars
class ControllerBindAutoShadowElement extends HTMLElement {
foo() {
return 'foo'
}
}
instance = await fixture(html`
<controller-bind-auto-shadow>
<template data-shadowroot="open">
<button data-action="click:controller-bind-auto-shadow#foo" />
</template>
</controller-bind-auto-shadow>
`)
replace(instance, 'foo', fake(instance.foo))

expect(instance.shadowRoot).to.exist
expect(instance).to.have.property('shadowRoot').not.equal(null)
expect(instance.shadowRoot.children).to.have.lengthOf(1)
instance.shadowRoot.querySelector('button').click()

expect(instance.foo).to.have.callCount(1)
})

it('upgrades child decendants when connected', async () => {
@controller
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down

0 comments on commit d239a05

Please sign in to comment.