{"action":"created","issue":{"url":"https://api.github.com/repos/w3c/webcomponents/issues/509","repository_url":"https://api.github.com/repos/w3c/webcomponents","labels_url":"https://api.github.com/repos/w3c/webcomponents/issues/509/labels{/name}","comments_url":"https://api.github.com/repos/w3c/webcomponents/issues/509/comments","events_url":"https://api.github.com/repos/w3c/webcomponents/issues/509/events","html_url":"https://github.com/w3c/webcomponents/issues/509","id":157746490,"node_id":"MDU6SXNzdWUxNTc3NDY0OTA=","number":509,"title":"The is=\"\" attribute is confusing? Maybe we should encourage only ES6 class-based extension.","user":{"login":"trusktr","id":297678,"node_id":"MDQ6VXNlcjI5NzY3OA==","avatar_url":"https://avatars3.githubusercontent.com/u/297678?v=4","gravatar_id":"","url":"https://api.github.com/users/trusktr","html_url":"https://github.com/trusktr","followers_url":"https://api.github.com/users/trusktr/followers","following_url":"https://api.github.com/users/trusktr/following{/other_user}","gists_url":"https://api.github.com/users/trusktr/gists{/gist_id}","starred_url":"https://api.github.com/users/trusktr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/trusktr/subscriptions","organizations_url":"https://api.github.com/users/trusktr/orgs","repos_url":"https://api.github.com/users/trusktr/repos","events_url":"https://api.github.com/users/trusktr/events{/privacy}","received_events_url":"https://api.github.com/users/trusktr/received_events","type":"User","site_admin":false},"labels":[{"id":228779701,"node_id":"MDU6TGFiZWwyMjg3Nzk3MDE=","url":"https://api.github.com/repos/w3c/webcomponents/labels/custom-elements","name":"custom-elements","color":"5319e7","default":false}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":464,"created_at":"2016-05-31T19:06:24Z","updated_at":"2018-07-06T12:04:33Z","closed_at":"2016-07-19T10:15:02Z","author_association":"NONE","body":"The `is=\"\"` API can be confusing, and awkward. For example (in current v1 API):\r\n\r\n### inheritance currently has to be specified three times: \r\n\r\n```js\r\nclass MyButton extends HTMLButtonElement {} // 1st time\r\ncustomElements.define('my-button', MyButton, { extends: 'button' }) // 2nd time\r\n```\r\n```html\r\n<button is=\"my-button\"></button> <!-- 3rd time -->\r\n```\r\n\r\nBut, I believe it could be better:\r\n\r\n### inheritance specified once, easier non-awkward API:\r\n\r\n```js\r\nclass MyButton extends HTMLButtonElement {} // 1st and only time\r\ncustomElements.define('my-button', MyButton)\r\n<my-button></my-button>\r\n```\r\n\r\nBut, there's problems that the `is=\"\"` attribute solves, like making it easy to specify that a `<tr>` element `is` actually a `my-row` element, without tripping up legacy parser behavior (among other problems). So, after discussing in this issue, I've implemented an idea in #727:\r\n\r\n> ### mixin-like \"element behaviors\", without extending builtins\r\n> \r\n> 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.\r\n> \r\n> #### For example:\r\n> \r\n> ```js\r\n> // define behaviors\r\n> elementBehaviors.define('foo', class { // no inheritance necessary\r\n>   connectedCallback(el) { ... }\r\n>   disconnectedCallback(el) { ... }\r\n>   static get observedAttributes() { return ['some-attribute'] }\r\n>   attributeChangedCallback(el, attr, oldVal, newVal) { ... }\r\n> })\r\n> elementBehaviors.define('bar', class { ... })\r\n> elementBehaviors.define('baz', class { ... })\r\n> ```\r\n> \r\n> ```html\r\n> <!-- apply any number of behaviors to any number of elements: -->\r\n> <div has=\"bar baz\"></div>\r\n> <table>\r\n>   <tr has=\"foo baz\" some-attribute=\"lorem\"></tr> <!-- yay! -->\r\n> </table>\r\n> <button has=\"bar foo\" some-attribute=\"ipsum\"></button>\r\n> <input has=\"foo bar baz\" some-attribute=\"dolor\"></input>\r\n> ```\r\n> \r\n> In a variety of cases, this has advantages over Custom Elements (with and without `is=\"\"` and):\r\n> \r\n> 1. No problems with parsing (f.e. the `table/tr` example)\r\n> 2. No inheritance, just simple classes\r\n> 3. Works alongside Custom Elements (even if they use `is=\"\"`!)\r\n> 4. \"element behaviors\" is similar to \"entity components\" (but the word \"component\" is already used in Web Components and many other web frameworks, so \"behaviors\" was a better fit).\r\n> 5. Lastly, \"element behaviors\" makes it easier to augment existing HTML applications without having to change the tags in an HTML document.\r\n\r\nSee #727 for more details.\r\n\r\n---\r\n\r\n## Original Post:\r\n\r\nThe [spec](https://w3c.github.io/webcomponents/spec/custom/#custom-elements-customized-builtin-example) says:\r\n\r\n> Trying to use a customized built-in element as an autonomous custom element will not work; that is, `<plastic-button>Click me?</plastic-button>` will simply create an `HTMLElement` with no special behaviour.\r\n\r\nBut, in my mind, that's just what the _spec says_, but not that it has to be that way. Why has it been decided for it to be that way?\r\n\r\nI believe that we can specify this type of information in the `customElement.define()` call rather than in the markup. For example, that very same document shows this example:\r\n\r\n``` js\r\ncustomElements.define(\"plastic-button\", PlasticButton, { extends: \"button\" });\r\n```\r\n\r\nObviously, `plastic-button` extends `button` as defined right there in that call to `define()`, so why do we need a redundant `is=\"\"` attribute to be applied onto `button`? I think the following HTML and JavaScript is much nicer:\r\n\r\n``` html\r\n<!-- before: <button is=\"plastic-button\">Click me</button> -->\r\n<plastic-button>Click me</plastic-button>\r\n```\r\n\r\n``` js\r\n// before: const plasticButton = document.createElement(\"button\", { is: \"plastic-button\" });\r\nconst plasticButton = document.createElement(\"plastic-button\");\r\n```\r\n\r\nThe necessary info for the HTML engine to upgrade that element properly is right there, in `{ extends: \"button\" }`. I do believe there's some way to make this work (as there always is with software, because we make it, it is ours, we make software do what we want, and this is absolutely true without me having to read a single line of browser source code to know it), and that `is=\"\"` is not required and can be completely removed from the spec because it seems like a hack to some limitation that can be solved somehow else (I don't know what that \"somehow\" is specifically, but I do know that the \"somehow\" exists because there's always some way to modify software to make it behave how we want within the limitations of current hardware where current hardware is not imposing any limitation on this feature).\r\n"},"comment":{"url":"https://api.github.com/repos/w3c/webcomponents/issues/comments/403014314","html_url":"https://github.com/w3c/webcomponents/issues/509#issuecomment-403014314","issue_url":"https://api.github.com/repos/w3c/webcomponents/issues/509","id":403014314,"node_id":"MDEyOklzc3VlQ29tbWVudDQwMzAxNDMxNA==","user":{"login":"hax","id":159840,"node_id":"MDQ6VXNlcjE1OTg0MA==","avatar_url":"https://avatars0.githubusercontent.com/u/159840?v=4","gravatar_id":"","url":"https://api.github.com/users/hax","html_url":"https://github.com/hax","followers_url":"https://api.github.com/users/hax/followers","following_url":"https://api.github.com/users/hax/following{/other_user}","gists_url":"https://api.github.com/users/hax/gists{/gist_id}","starred_url":"https://api.github.com/users/hax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hax/subscriptions","organizations_url":"https://api.github.com/users/hax/orgs","repos_url":"https://api.github.com/users/hax/repos","events_url":"https://api.github.com/users/hax/events{/privacy}","received_events_url":"https://api.github.com/users/hax/received_events","type":"User","site_admin":false},"created_at":"2018-07-06T12:04:33Z","updated_at":"2018-07-06T12:04:33Z","author_association":"CONTRIBUTOR","body":"@oleersoy \r\nRepeat again, default export is simply a \"syntax sugar\", so I don't think it will need \"ton of education\" in this simple case.\r\n\r\nAnd default export definitely has the benefit -- follow the convention of node.js. Note, there is NO default export in the early ES6 draft, it is added because the node.js community gave the feedbacks. It may \"zero upside\" to you (and I admit I myself can live without it because I prefer AMD than CommonJS before ES module is standardized), but you can't deny node.js is a very important part of the js community so that default export have the benefit for the whole ecosystem.\r\n\r\nLast, compare `is` attribute to default export is not suitable. Because `is` attribute is not a \"syntax sugar\". Without `is`, you have no way to utilize webcomponents on many builtin elements.\r\n\r\nOn the other side, if I need to ban a feature in a large engineer team, I would choose to ban the normal custom element, and only use `is` to extend. Because most average developers do not have enough knowledge and experiences on components design, which means they are very likely to produce a leaky abstraction, or do something wrong (for example, raise a11y issue). And `is` way is much safer for them. 😂"}}
{"actor":{"display_login":"hax"}}