LogoLogo
GithubTwitterDiscordPlayground
English
English
  • 👋Atomico
  • 🚀Getting started with Atomico
  • ⚛️Getting started with Atomico for React users
  • 💡What can you do with Atomico?
    • You can create amazing webcomponents
    • You can create design systems
    • You can create websites
    • You can create mobile applications
    • You can create web applications
  • API
    • 🧬Props(Properties)
      • Value cycle as prop
      • Is it advisable to declare events using the props API?
    • 🧩VirtualDOM
      • Advanced
    • 🎣Hooks
      • useProp
      • useEvent
      • useRef
      • useHost
      • useState
      • useReducer
      • useEffect, useLayoutEffect and useInsertionEffect
      • useMemo and useCallback
      • useUpdate
      • useId
      • useContext
        • useProvider
      • usePromise
      • useAsync and useSuspense
      • useAbortController
    • 🔬Testing
      • Render cycle
      • atomico/test-hooks
      • atomico/test-dom
  • Guides
    • 🤔Frequent questions
      • Is it advisable to declare events using the props API?
      • How to declare events for your component at the type level for TSX?
      • When and why to use shadowDom?
      • Can I use Atomico in browsers without ESM support?
    • 🤩Component
      • Naming
      • CSS Styles with Shadow DOM
    • 🛡️Atomico with Typescript
      • Props
      • Component
      • Meta-types
        • Type
        • Event declaration
        • Method declaration
      • Check the correct use of hooks
    • 🤝Atomico and React
      • Integrating Atomico in React
      • From React to Atomico
        • Rendering Differences
        • VirtualDOM api differences
    • ⏳Atomico and Asynchrony
    • 🧠Atomico design patterns
      • ♻️Webcomponents with hybrid rendering
      • 🔗Slot as templates
      • 🔀Slot
    • 📖Atomico and Storybook
      • Frequent questions
    • 💧SSR / SSG
    • 🗃️Archives
      • Class inheritance
      • Forms and shadowDOM
      • Tips
      • Design systems
      • Atomico style guide
        • File structure
          • Monorepo
          • Design systems
  • packages
    • @atomico/hooks
      • useCurrentValue
      • use-intersection-observer
      • use-ref-values
      • use-script
      • use-attributes
      • use-prop-proxy
      • use-click-press
      • use-dollars
      • use-reflect-event
      • use-keyboar
      • use-click-coordinates
      • use-copy
      • use-debounce-state
      • use-form
      • use-listener
      • use-disabled
      • use-css
      • use-channel
      • use-promise
      • use-responsive-state
      • use-parent
      • use-resize-observer
      • use-slot
        • useSlot
        • useProxySlot
      • use-render
      • use-mutation-observer
      • use-css-light-dom
      • use-controller
      • use-router
      • use-async-effect
      • use-child-nodes
      • use-force-render
    • @atomico/store
      • Store
    • @atomico/storybook
    • @atomico/router
    • @atomico/vite
      • ⚙️Process CSS tag template blocks with PostCSS.
      • 🏗️Compile your code to be distributed optimally as a package.
      • 📕Use the JSX/TSX syntax of Atomico when using Storybook.
      • 🤖Automatically create customElements.define
      • ☑️Support for Vitest for Atomico.
      • 🧙‍♂️Server actions
    • @atomico/exports
      • 🚩CLI and Flags
      • 🤖Wrapper for React
    • @atomico/components
      • @atomico/keen-slider
      • @atomico/modal
      • @atomico/lottie
      • @atomico/table
    • @atomico/react
    • @atomico/postcss-tokens
      • Example with @atomico/vite
    • @atomico/wrapper
    • 🚫Deprecated
      • @atomico/magic-form
        • MagicFormProvider | <magic-form-provider>
        • MagicForm | <magic-form>
        • MagicForm Hooks
        • MagicForm in React and Preact
        • MagicForm in Microfrontend
        • MagicForm Patterns
      • @atomico/design-tokens
        • @atomico/design-tokens api
  • Support
    • Discord
    • Github
    • Twitter
Powered by GitBook
On this page
  • Introduction
  • Slot pattern as a template
  • Example

Was this helpful?

Edit on GitHub
Export as PDF
  1. Guides
  2. Atomico design patterns

Slot as templates

Introduction

Slots are a powerful feature when working with webcomponents that use the shadowDOM. And thanks to the hook @atomico/hooks/use-slot you will be able to observe the state of the slot and know the childNodes of this to manage the logic of the template. For example:

import { useRef } from "atomico";
import { useSlot } from "@atomico/hooks/use-slot";

function component() {
  const refSlotIcon = useRef();
  const slotIcon = useSlot(refSlotIcon);
  return (
    <host shadowDom>
      <slot
        name="icon"
        ref={refSlotIcon}
        style={slotIcon.length ? null : "display: none"}
      />
      <slot />
    </host>
  );
}

Thus managing to easily condition parts of our template to define the slots.

Another trick that useSlot allows us is the interaction at the DOM level, example:

import { useRef, useEffect } from "atomico";
import { useSlot } from "@atomico/hooks/use-slot";

function component() {
  const refSlotSlides = useRef();
  const slotSlides = useSlot(refSlotSlides);

  slotSlides.forEach((slide) => {
    slide.style.width = "100%";
    slide.style.height = "300px";
  });

  return (
    <host shadowDom>
      <slot name="slides" />
    </host>
  );
}

We can even apply filters per instance for a better identification of the node, example:

useSlot(refSlotSlides).filter(
  (childNode) => childNode instanceof HTMLDivElement
);

⚠️ In case of high ui computation use prefer to use slot modifiers inside a useEffect.

Slot pattern as a template

Slots are not only limited to a static definition, you can use them to identify a node and use it to create new nodes according to the logic of the webcomponent, example:

import { useRef, usePromise } from "atomico";
import { useSlot } from "@atomico/hooks/use-slot";

function userFetch() {
  const refSlotTemplateUser = useRef();
  const [Template] = useSlot(refSlotTemplateUser);
  const promise = usePromise(
    () =>
      fetch("https://jsonplaceholder.typicode.com/users").then((res) =>
        res.json()
      ),
    [],
    true
  );

  return (
    <host shadowDom>
      <slot name="template" ref={refSlotTemplateUser} />
      <div class="list">
        {promise.fulfilled
          ? !!Template &&
            promise.result.map((props) => <Template {...props} cloneNode />)
          : "Pending..."}
      </div>
    </host>
  );
}

Thanks to useSlot(refSlotTemplateUser) we get the first node of the Template slot to be used in the iteration of the results obtained by fetch, with this we have eliminated the leverage of the webcomponent in charge of rendering the user at the level of our webcomponent userFetch

Example

⚠️ the cloneNode property is available from version atomico@1.37.0

PreviousWebcomponents with hybrid renderingNextSlot

Last updated 1 year ago

Was this helpful?

🧠
🔗
LogoWebComponents.devWebComponents.dev