-
Notifications
You must be signed in to change notification settings - Fork 378
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
Element Behaviors, and the has="" attribute. A useful alternative to Custom Elements in many cases! #727
Comments
… and shared the idea to W3C at WICG/webcomponents#727
(Updated the description in the previous comment) |
@trusktr: Thanks for the invite! This is interesting. I think it's really starting to try and move us to looking at individual HTML elements as actual class definitions from the OOP world. As such, this response might turn into something a bit longer than expected or requested. :)
For me it's not a question of "more than" - it's a question of language (communication not programming) and intent.
<div is="my-custom-block-element"></div> class Div {
// block element definitions and properties
}
class MyCustomBlockElement extends Div {
// my overrides and extensions
} The So, the following would also be analogous - using PHP traits - not JS. <div has="bar baz"></div> trait Bar {}
trait Baz {}
class Div {
has Bar, Baz;
} I like to write code that is explicit in its intent; I can figure out what's going on by reading it...that's why I still mark things as It seems like we are trying to do for So, why not both? <div is="my-cool-contact-card" has="customHover customClick" class="rounded blue"></div> This is much easier to read and doesn't assume the existence of custom elements support on the client. <my-cool-contact-card has="customHover customClick" class="rounded blue"></div> And, it removes the clutter of literal JS and CSS in the element. In all honesty, I like I like Let's pretend It's possible that Could be crazy talk, but that's how my mind is mapping these things - taking on the voice of the element itself for a second:
I've been toying with the notion of HTML as a language being less about the web and more about giving authors the ability to describe their intent - otherwise, we would only need |
There's no interest in this, but custom attributes (with callbacks) might solve this. JavaScript mixins might make this easier going forward too. |
@trusktr: Sorry. I think you and I might be on the same page though at a higher level...could be wrong. Shameless plug: https://m.8fold.pub/on-constraints-internet-bandwidth-eab05c20e218 - see highlight midway down the page. |
@annevk What is the current alternative to the ideas proposed here. These would assist us with some of the issues we're encountering. But yet, |
@stefsullrew custom attributes are discussed in whatwg/html#2271. Not sure if there's a concrete API proposal yet, don't think so. Not sure what you mean about |
the "has" attribute idea is clever but not necessary when ES7 lands. In ES7 we would be able to easily define traits on a class using a custom @traits class-level decorator. Problem solved at the class level. C'mon, keeps the html clean and lean. I think you've seen the abuse that can occur in Angular just because of an ng-if....Oh gosh! |
@annevk @Nashorn Hey
In other words, the declarative power of being able to add/remove JS features to/from elements, declaratively, is really nice.
How do you gauge that? (@joshbruce I liked your ideas in your above reply 👍) |
Please use inclusive language: https://notapattern.net/2014/10/14/ways-men-in-tech-are-unintentionally-sexist/. As for determining interest, I wrote that comment during a face-to-face meeting, minutes available at #713 (comment). |
Sorry. Based on @Nashorn's GitHub profile, I can not tell whether Nashorn is a guy or gal. I should've used "guys" only if I'd known you both were under the "he/him" pronouns.
Can you quickly summarize that part? Now that you have examples of how I'm using Maybe there is not any interest because it simply doesn't exist and people aren't aware of it? As far as I know, A-Frame is the only big library out there that has anything similar to this, they call it "entity-components" instead of "element-behaviors", but they are the same things. Theirs is only slightly different from behaviors: theirs is more like custom-attributes, and their custom attribute values accept As far as I can tell, people who use A-Frame love it. In my case, element-behaviors is not tied to a specific library (f.e. A-Frame's entity-components are specific to A-Frame, not usable on any elements), and behaviors can be used on any elements.
|
I am already forseeing that I will mostly use my |
This is what it looks like to define a new Custom Element with a set of default behaviors in Lume: import Node from './Node.js'
export default
class ObjModel extends Node {
static elementName = 'lume-obj-model'
static defaultBehaviors = [ 'obj-model' ]
} That defines a Here's how we'd use the <!-- a lume-node element with an obj-model behavior. The obj-model
behavior observes the obj and mtl attributes. -->
<lume-node id="model"
rotation="0 40 0"
align="0.5 0.5 0"
size="0 0 0"
scale="200 200 200"
has="obj-model"
obj="./models/spaceship/ship.obj"
mtl="./models/spaceship/ship.mtl"
>
</lume-node> And with the simple Custom Element definition above, here's how we'd use the <!-- alternatively, the lume-obj-model is a node element that
implicitly has an obj-model behavior. We've omitted the mtl, so the
model will have a solid color material: -->
<lume-obj-model id="model2"
rotation="0 20 0"
align="0.5 0.5 0"
size="0 0 0"
scale="200 200 200"
obj="./models/spaceship/ship.obj"
>
</lume-obj-model> This opens up a door for composability of functionalities on an element; ability to compose JS features dynamically (add or remove them any time). Imagine this, <red-monster ...> then a user gets close enough to the monster, so we make it have rage: <red-monster has="rage-mode" ...> Then the user gets far enough away, so we remove the rage: <red-monster ...> |
That monster example is more behavioral, but you can see in my previous examples how materials and obj-models can be more traits/characteristics and not implying verbs. |
Agreed. Also, thanks for the compliment on the article @trusktr. Gonna leave an updated link as I begin to retool my digital world, which is including changing the 8fold domains and figure out where the writing should live for real. Of course, you coulda just been talking about the comment not the long-winded article. In either case, I'm tired and needed to update the link anyway. :) Your last couple of comments reminds me of what we used to do in Flash-based games. What is the defined line between action and state? |
@trusktr - the females are cows and young ones are calfs |
Exactly. My thought is that something like "traits/characteristics/features" must include at least state, while "behavior" seems to want to include more. |
This is a really great idea and a very constructive feedback. @annevk |
Based on #509, #662, and #663, I've released a standalone implementation of "Element Behaviors", published to NPM as element-behaviors.
I currently use Element Behaviors in Lume to implement various rendering behaviors for custom 3D elements, and I plan to use element behaviors to define mixable functionalities useful in interactive apps like 3D games or decorated web sites.
Additionally, I've implemented a "default behavior" system in Lume, on top of element-behaviors (not published as standalone yet) that makes it easy to define Custom Element classes that ship with default sets of behaviors, as well as makes it easy to add/remove behaviors in the same way that it is easy to add/remove classes with
el.classList.add/remove
.What is it?
For all intents and purposes, this is an "entity-component" system, but in this case called "element behaviors" which avoids conflict with widely-used term "component" in the web these days.
Element behaviors allow us to add any number of functionalities ("behaviors") to any number of elements, using interfaces similar to Custom Elements, and a new
has=""
attribute. See the README for more details, examples, and API.This is an alternative to the
is=""
attribute, where instead of using anis-a
design pattern we're using ahas-a
design pattern which is less complicated and more flexible.Basic Example
The first example from the README is on codepen:
https://codepen.io/trusktr/pen/3abb3ab634d1171954fb00fbc188b9e7.
Not shown in that demo, also apply any number of behaviors to any number of elements:
mixin-like "element behaviors", without extending builtins
The idea uses a
has=""
attribute to apply more than one behavior/functionality to an element (is=""
can only apply a single behavior/functionality to an element), using lifecycle methods similar to Custom Elements.For example:
In a variety of cases, this has advantages over Custom Elements (with and without
is=""
and):table/tr
problem)is=""
!)augment existing HTML applications
Suppose we have an HTML app:
With Custom Elements, we could enhance it like the following, but it requires changing the names of the elements, which can cause conflicts with CSS and JS code:
With Element Behaviors, we can more easily add the functionality without modifying existing markup, CSS, or JS:
Of course, the implementation of a behavior that doesn't extend from the target element might require a different sort of implementation than a Custom Element that extends from the target element. Nothings perfect, and one way may be a little more work than the other way depending on scenario. But overall, the utility is improved (f.e. mix behaviors together, and some behaviors might even team up to do certain things when combined together on a single element), avoid strange parser problems, stay out of the way of existing CSS/JS, and more.
The text was updated successfully, but these errors were encountered: