tamb / domponent Goto Github PK
View Code? Open in Web Editor NEWBuild UI Components with the HTML You Already Have
Home Page: https://tamb.github.io/domponent/
License: MIT License
Build UI Components with the HTML You Already Have
Home Page: https://tamb.github.io/domponent/
License: MIT License
Scoping works with nested components of same type.
Refs and ref arrays get picked up from other components.
This becomes an issue with larger applications. But there is an initialization hit in performance for resolving this.
Possible solutions:
Need to test that state and props and dependents wire up correctly.
Would prefer to stick with Jest.
DOM state should overwrite component state. But the component should have a fallback state to whatever is specified in the constructor
data-state="{"count": 5}"
overwrites
this.state = {
count: 4
};
data-state="{"count": 5}"
and
this.state = {
count: 4,
name: 'Joe'
};
Should retain default of Joe and have count of 5.
This could be written off as "it's a feature not a flaw", but the decision needs to be made DOM > JS. The DOM passes the props and state.
Create ref-array
to call document.querySelectorAll()
and return as an array.
Converts nodelist to array.
Renaming the data attribute should be added as well.
Methods like propsWillUpdate
should be ternary checked before firing. It's up to the Component instance to decide if those methods exist. Otherwise each component is being bloated with unused lifecycle methods.
Trying to figure out a sane way to incorporate Hooks into the project.
Hooks should:
Should this be baked into the library or treated as something to be sprinkled into components?
class Counter extends Component{
constructor(props){
super(props)
}
...myHookObject
}
This should simply be doable without code changes and would require documentation changes.
Add a component to toggle the display of HTML and JS for that component. Code previews should have syntax highlighting.
Couple small fixes in example site.
Docs need example of es5 version
var App = new Domponent.Init({
selector: document.body,
components: {}
});
Then adding, removing, registering, unregistering components.
Support data-ref="fieldName"
in html.
Then access it in the Component via this.fieldName
.
This will simplify selecting. I guess it's nice to have.
Currently bind
is being used to preserve context when using addEventListener
. The bound function created is then stored in an object $b
per component instance. Would like to improve this.
Make Codesandbox for practical examples
Problem
How to share variables or reusable methods between components.
Solution:
Mixins
Basic idea is to add a this.$mixins
to Scope
or Exponent
class, exposing it to everything. The mixin property will store references to different mixin objects and change the execution context of that object when one of the methods are called upon.
Possible issues are with this
within a mixin method.
Possible solutions:
Possibly a $mixinCall
method to wrap every property and method reference in? (Talk about performance hit there)
Creating this[mixinKey]
within the class. It would equal either a value or the mixin method with bind
. Mixins are shared. Mixin methods take new execution context. Mixin properties are copied by value.
Exponent
and Component
should contain or allow composition for an optional render
method that outputs HTML
. The HTML should be template agnostic (handlebars, hyperstache, mustache, html, etc).
The benefit would be that the developer could leverage client-side templating and still have a small library available to bind data changes and events.
// handlebars example
render(props, state){
// compile the template
const template = Handlebars.compile(`
<div data-component="MyComponent" name<-parentComponent: name>
<p data-bind="state:MyComponent.count"> {{state.count}} </p>
<p data-bind="props:MyComponent.count"> {{props.name}} </p>
<p> {{additionalData}} </p>
<button type="button" data-action="click->MyComponent.increment">
+1
</button>
</div>
`);
return template({
props,
state,
additionalData: 'Howdy',
somethingElse: 'aloha'
});
}
This would be fired before the component is wired up:
** Must be compatible with mustache and handlebars! **
handlebars: https://handlebarsjs.com/guide/#installation
mustache: http://mustache.github.io/mustache.5.html
{ render }
imported separately.tags: [ 'my-component', 'another-thing']
render
will be it's own function.didMount
willMount
willUnmount
and didUnmount
<!-- potential usage-->
<my-component data-state='{name: "Michael Scott"}'></my-component>
<!-- JSP example -->
<c:forEach items="${dunderMifflinEmployees}" var="employee">
<my-component data-state='{name: ${employee.name}}'></my-component>
</c:forEach>
This would then have to match up with a MyComponent
class. The class could then contain a render method.
The purpose of this library is to leverage template-languages already in use. It's meant to add a declarative syntax to your HTML in order to bind data changes and events. Implementing client-side rendering would slow down the library and add to size. Also, we can easily call the templates before we initiate the components or the application.
Adding support for client-side rendering will possibly only add to the complexity of the library without much gain. If templating is already happening on the server, is there a need for this?
Ideally version 2 should have much simpler constructors for Component
and Exponent
classes.
They should accept the root node only.
Use of $app
should be entirely optional.
propsWillUpdate
stateWillUpdate
should receive previous and future props and state
Currently working on a Pug + Domponent test to rerender 124 divs individually at 10ms intervals:
Should finished tests against React, Inferno, Preact
Post results on README.md
Tests are in this repo https://github.com/tamb/pug-domponent
Operations per second. JS execution time.
Page load time.
Include dataAttributes, etc.
Thinking in v3 of adding data-attr-bind
To be used like this:
<p data-attr-bind=attributeName:Component.field|attributeName2:Component.field>
<p>
Any HTMLElement
attribute that exists can be set this way.
class
attribute will have to function by removing first value and then adding new value.
This will only support int
, string
and DOMTokenList
values
Add Jest unit tests for all src files.
Exponent
could be given API to update, add, or remove data-ref
.
Exponent
could be given API to update, add, or remove data-ref-array
.
Exponent
could be given API to update, add, or remove data-action
.
This would increase the size of the framework.
helper methods for creating refs, etc could be added to actual Exponent
class and could accept query string parameter for updating only specific refs, etc.
This could apply to adding/removing event handlers (data-action
) methods to nodes.
Add an option to have custom syntax in addition the option for custom data
attributes.
Example:
{
actions: '=>',
stateAndProps: '.',
inheritProps: '<=',
}
Then the syntax is customizable
data-bind="state.Counter.count"
data-action="click=>Counter.increment"
Currently this.$root
elements cannot accept a data-action
.
Components must be wrapped in a div
or another element and component $root
needs to be the wrapper div
in order to attach event listeners.
Rewrite helper functions to check $root
node for additional data-
attributes.
v2 watchers
should apply to props
as well
Should add types to this. At the very least, some interfaces.
ref
and ref-array
elements will be nested inside of $refs
object
Event listeners bound during component creation should be unbound before component deletion.
Document the component mounting process. And the unmounting process.
The example page is not too clear with what it's purpose is. It should be a demo that links to library and documentation.
Component highlighting should be a dotted border and not a box shadow.
I am working on a similar thing called dom99 The docs are a bit out of date, but check the examples.
After skimming through your project:
data-state
You basically evented yet another data format, consider instead using something native of the platform like
data-state="{count:24, isEven:true}"
or
data-state-count="24" data-state-isEven="true"
data-key
it is optional, must be unique , but what does it do ?
Component Fields
why prefix things with $ ?
do not commit domponent-1.0.0-alpha.18.tgz
Otherwise very interesting project, I give more detailed feedback later
The ES5 output files need to be renamed to something standard. They should have .min
because over cdn they will be minified.
For es5 components
For cdn links
For npm install
For demo setup
Need to add custom syntax to docs
Docs need a section with an example of how to use default states
Would like addHTML
, removeHTML
class methods to wire up and tear down newer elements and bindings to components.
Was considering client-side components.
class MyCounter extends Renderer
and it allows you to pass a custom render
method which must return a string of html.
Then it fires the wiring up automatically.
So your actual DOM can look like this:
<my-counter data-props="..." data-key="..." data-state="..."/>
One concern is with nested custom elements:
<my-card>
<my-counter/>
</my-card>
Ideally this could work. And you could pass attributes and state just like regular DOM-based components.
Ideas:
common-tags
and use the safeHTML
tag. This way I can force the render
method to be a tagged template literal. This would safely allow HMTL to be created. And you could create templates.this.state.field
or this.field
, then I would wire up the component as a regular Component
instance.render(){
const state = {
name: "Mario"
};
return (
`<div data-component="SayHello"
data-state='${JSON.stringify(state)}'>
Hello, {this.name}!
</div>`
);
}
At this point should the user consider Polymer? React?
Need to add something similar
"main":
"dist/preact.js",
"module": "dist/preact.module.js",
"umd:main": "dist/preact.umd.js",
Need to transpile CDN code to es5
<button data-action="click->Component.save:{once: true}">Save</button>
Needs documentation as well
Should the initial setState
be removed when rendering components. The connection should just be in memory so no DOM rerenders happen.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.