The Wayback Machine - http://web.archive.org/web/20201105102946/https://github.com/atomicojs/atomico/issues/25
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run method in constructor #25

Open
ManzDev opened this issue Dec 28, 2019 · 3 comments
Open

Run method in constructor #25

ManzDev opened this issue Dec 28, 2019 · 3 comments

Comments

@ManzDev
Copy link

@ManzDev ManzDev commented Dec 28, 2019

Hello,

I want run a "user-custom method" on native WebComponent constructor lifecycle.
What is the best way to do this with atomico?

My problem is that I need extract content of WebComponent markup before mount.

I have the same doubt for events like connectedCallback, disconnectedCallback or adoptedCallback.

Great work, I like Atomico!

@UpperCod
Copy link
Member

@UpperCod UpperCod commented Dec 30, 2019

Hi, the Atomico render cycle is released only after mount, this with the aim of correctly synchronizing properties (reflecting default values) or events (allowing a synchronization between component indifferent to the mounted order).

You can follow the component state through promises, eg:

let WebComponent = document.createElement("web-component");

await WebComponent.mounted // before render  == connectedCallback 

await WebComponent.rendered // after render

WebComponent.props1 = 10;
WebComponent.props2 = 20;
WebComponent.props3 = 30;

await WebComponent.rendered // after render 

await WebComponent.unmounted // disconnectedCallback

https://github.com/atomicojs/atomico/blob/master/src/core/element/element.js#L134-L160

you can comment on your need in more detail, for a better solution or improvement of Atomico... I have been thinking of associating the life cycle with an event, so as not to depend on a previous definition of the webComponent

@ManzDev
Copy link
Author

@ManzDev ManzDev commented Dec 30, 2019

First of all, sorry for my lack of knowledge. I'm new at hooks and maybe something is nonsense.

I'm trying to find a solution to "fallback" components + nice reuse:

  1. Empty web-component, resolve into fallback content (defined into webcomponent)
  2. Web-component with tags inside, resolve into clone this markup and style (from inside component). This solution is SEO-friendly and WC-friendly.

For example:

<web-component>
  <h2>Title</h2>
   <p>Content with <strong>markup</strong></p>
</web-component>

I want to get component's content before mount it, to reuse it inside.

I try this with slots, but use styles from light dom, and I want copy markup but apply styles from inside component. I think that clone content (from constructor), I can get it.

@UpperCod
Copy link
Member

@UpperCod UpperCod commented Dec 30, 2019

Thanks for your Issue, it has motivated me to generate this update at Atomico@0.17.0 that allows a better interaction with lightDom, eg:

This allows to homologize the behavior of the shadowDom, but it is recommended to use only in cases where the DOM comes from HTML, eg:

html

<web-component>
    <h2 slot="title">Title</h2>
    <p>Content with <strong>markup</strong></p>
</web-component>

JS

import { h, customElement, useMemo, useHost, useState } from "atomico@0.17.0";

const WebComponent = () => {
  // use Host allows to obtain the reference of the webcomponent
  // without the need for the first render
  let ref = useHost();

  let [state, setState] = useState(0);
  // using useMemo you can generate a map of the existing
  // nodes before the render replaces them
  let { Title } = useMemo(() => {
    return {
      Title: ref.current.querySelector("[slot='title']")
    };
  }, []);

  return (
    <host>
      <strong>inside web-component</strong>, the example takes the existing node
      in the document to reuse it within the webcomponent like any other vnode.
      <br />
      <br />
      <strong>counter = {state}</strong>
      <Title
        onclick={() => {
          setState(state => state + 1);
        }}
        style={{ color: "red" }}
      />
      ...end
    </host>
  );
};

export default customElement(WebComponent);

Where :

  • Title[onclick] : add the onclick event to the recycled node for use within the web-component
  • Title[style]: manipulate the style of the component

https://webcomponents.dev/embed/h67bGeTp2qKdb26ZgmkU

subRender and LightDom.

You can manipulate the state of a node through the render function, eg

import { h, render, useHost } from "atomico";

function useFocusRender(callback, selector) {
  let ref = useHost();
  render(callback(), ref.current.querySelector(selector));
}

function WebComponent() {
  useFocusRender(
    () => (
      <host
        style={{ color: "red" }}
        onclick={() => {
          console.log("click!");
        }}
      ></host>
    ),
    "h2"
  );

  return <host></host>;
}

example

Atomico and shadowDom

::slotted() , It allows you to manipulate the style of a slot from inside the webComponent, but this does not help with the association of events.
seo, currently the google robot should process the shadowDom without any problems since it is based on crhome 74, source.

I hope this is useful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.