Git Product home page Git Product logo

component-elements's Introduction

component-elements

These packages provide the ability to use an HTML custom element as the root for your components. In addition, it allows the use of async code resolution if your custom element isn't immediately used, which is a great strategy for reducing code weight.

Getting Started

Depending on your component library, visit the relevant package below and follow setup instructions:

Library Package
Preact preactement
React reactement
Vue supported natively!

Acknowledgement

This function takes heavy inspiration from the excellent preact-custom-element. That library served as a starting point for this package, and all of the Preact guys deserve a massive dose of gratitude. I had slightly different needs, so decided to build this as part solution, part learning excersize.

component-elements's People

Contributors

freshly-pressed-trousers avatar jahilldev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

component-elements's Issues

Support Node 18.x

I noticed that the package.json requires Node 16, but 18 has been LTS for a while. This presumably needs testing & updating.

Unable to render child elements inside my component

Hi, I'm having a hell of a time trying to get the content of my custom component in the HTML side to render in the component. I've broken it down to a very small example, and it's still not working. There don't appear to be any logs in the JS side, so I want to check I'm using this properly.

import { define } from 'preactement';
import PropTypes from 'prop-types';

export default function CFPost({ title, children }) {
	return <>
                    <div className="cf-post-header">
			<h2 className="page-title-overlay">{ title }</h2>
		    </div>
	            <div className="cf-post-content wordpress-content charcoal-wp-content pt-3">
		        <hr className="header-hr"/>
		        {children}
	            </div>
	</>;
}

CFPost.tagName = 'cf-post';
CFPost.propTypes = {
	title: PropTypes.string.isRequired,
}
CFPost.attributes = ['title'];

define(CFPost.tagName, () => CFPost, { attributes: CFPost.attributes });
<div class="content-main wooshIn">
  <cf-post
  title="Guests of Honour"
  datetime="2018-09-15T15:56:00+00:00"
  posttype="page">
    <p> Hello there </p>
  </cf-post>
</div>

I'd expect an output of:

<div className="cf-post-header">
    <h2 className="page-title-overlay">Guests of Honour</h2>
</div>
<div className="cf-post-content wordpress-content charcoal-wp-content pt-3">
  <hr className="header-hr"/>
  <p> Hello there </p>
</div>

but the <p> is missing entirely. Is there something obvious I need to do to enable child element rendering? I did also try with named slots with no success.

props.children raise error for unpair tags

Hi James, first of all thank you for very interesting library!

I figure our we found bug in when combine unpaired tags in component (<br>, <hr>, <img>...) and props.children. This combination raise "error on line 7 at column 15: Opening and ending tag mismatch: br line 5 and div". Is there any way how to fix this?

Screenshot 2022-01-12 at 9 06 25

index.js

import { define } from 'preactement';

class MyComponent extends Component {
    render(props, state) {
        return <div>
            {props.children}
        </div>
    }
}

define('x-mycomponent', () => MyComponent, { attributes: ['name'] });

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>Parcel Webcomponent test 2</h1>

    <x-mycomponent name="value">
        <div>
            Lorem ipsum
            <br>
            Lorem ipsum
        </div>
    </x-mycomponent>

    <script type="module" src="./index.js"></script>
</body>
</html>

Whitespace being trimmed when rendering children

We've been using this with some great success for a while now but have come across an issue where whitespace seems to be trimmed in places when run through it. I've managed to replicate it fairly minimally.

The issue manifests itself like this:
image

The component itself is just:

import { define } from 'preactement';
import PropTypes from 'prop-types';

export default function TestComponent({ children }) {
	return children;
}

TestComponent.propTypes = {
	children: PropTypes.node.isRequired,
}

TestComponent.tagName = 'test-component'
TestComponent.attributes = [];

define(TestComponent.tagName, () => TestComponent, { attributes: TestComponent.attributes });

Before the JS is run the page is provided to the browser as:

image

And once it kicks in it seems to have a cheeky nibble at some of the whitespace:

image

Children props are lost when custom element is moved in the DOM

Components are hydrated each time they are appended to the document.

var c = document.createElement("my-test");
document.body.appendChild(c);
document.body.appendChild(c);

The render() function is called twice. The second time e.g. this.props.children does not work any more.

Slot support?

Hello,

preactement supports the slots?

Example:

In the HTML (DOM):

<slot name="test">test1</slot>

In the component JSX:

<slot name="test">test2</slot>

Both are displayed.

Children props and event handlers are lost when rendered to DOM

I have some code that defines a Tabs component like tab-list. I am using it like this:

<tab-list>
    <div data-key="mouse" title="Mouse">
      <DemoContent />
    </div>
    <div data-key="keyboard" title="Keyboard">Keyboard Settings</div>
    <div data-key="gamepad" title="Gamepad">Gamepad Settings</div>
</tab-list>

function DemoContent() {
  return (
    <div>
      <h2>Sample title</h2>
      <button onClick={() => alert()}>Submit</button>
    </div>
  )
}

This does not work because the children passed to the Tabs component is just an empty element without any props or children.

However, if I you the children inside a slot, they slot is a node with the correct children and props BUT the event listeners don't fire. So this renders the static content, but it is not interactive.

  1. Can we avoid using the slot and parse any children correctly?
  2. How can we get the event listeners for nested components to work?

Slot casing

Hey,

If I add an attribute to my web component eg: foo-bar="123", it will be available in the components props as fooBar.

If I pass through a slot eg: <p slot="hello-world">Hello</p>, it will be available in the components props as hello-world. Is it possible to get slot attributes coming through in camelcase?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.