web-components
web-components copied to clipboard
feat(ce): ability to extend built-in elements
cc @EisenbergEffect @peitschie
Ability to have the following work:
<button is=my-button2>
with declaration:
class MyButton2 {
static extends = 'button';
static $view = '<template>One';
@bindable icon;
}
@peitschie Can you try this out 😃
UPDATE: seems to be something with my environment. For some reason, the instanceof check within register is not detecting that this is a HtmlBehaviourBase... I'll keep digging
@bigopon I've been having a play, but am having difficulty getting this to function for some reason. I've created a default aurelia app, installed the aurelia-web-components version from your branch & regenerated the dists folder, but I am getting this error thrown when I attempt to reproduce the example from the readme:
Error: class MyButton is already associated with a different type of resource. Cannot register as a custom element.
at CustomElementRegistry.register (custom-element-registry.ts?335e:97)
at eval (main.js?56d7:28)
at eval (index.js?07f7:57)
at run (setImmediate.js?6017:40)
at runIfPresent (setImmediate.js?6017:69)
at onGlobalMessage (setImmediate.js?6017:109)
For reference, the index.ejs is:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%- htmlWebpackPlugin.options.metadata.title %></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<base href="<%- htmlWebpackPlugin.options.metadata.baseUrl %>">
<!-- imported CSS are concatenated and added automatically -->
</head>
<body aurelia-app="main">
<span>non-replaced content</span>
<button is=my-button icon=♥></button>
</body>
</html>
and main.js is:
// regenerator-runtime is to support async/await syntax in ESNext.
// If you don't use async/await, you can remove regenerator-runtime.
import 'regenerator-runtime/runtime';
import environment from './environment';
import {PLATFORM} from 'aurelia-pal';
import { CustomElementRegistry } from 'aurelia-web-components';
import { bindable } from 'aurelia-templating';
class MyButton {
static extends = 'button';
static $view = '<template>my button ${icon}</template>';
@bindable icon;
}
export function configure(aurelia) {
aurelia.use
.standardConfiguration();
// this doesn't seem to help much - .globalResources([MyButton]);
aurelia.use.developmentLogging(environment.debug ? 'debug' : 'warn');
if (environment.testing) {
aurelia.use.plugin(PLATFORM.moduleName('aurelia-testing'));
}
aurelia.start().then(() => {
const registry = aurelia.container.get(CustomElementRegistry);
return registry.register(MyButton)
});
}
Everything else is as per aurelia-cli new web-components-test would setup 😺
Apologies in advance if this is my own PEBKAC!
Okay.. back again. I've updated the aurelia-web-components dist this time by just coping the js files over an install to avoid the hassles that seemed to be a side-effect of the linking to a local built version of the module.
Now, with the above file, I'm seeing a different error, which can be reproduced by the following test:
it('should work with "is" attribute', async () => {
const { host, registry, dispose } = await bootstrapAurelia({
root: class RootViewModel {
static $view = '<template><button is=my-button2></button></template>';
}
});
class MyButton2 {
static extends = 'button';
static $view = '<template>One';
@bindable icon;
}
await registry.register(MyButton2);
// host.innerHTML = '<button is=my-button2>';
await waitForTimeout(50);
expect(host.textContent).toBe('One');
return dispose();
});
Any thoughts? 🤔
The stack trace from a similar setup in Chrome is:
VM19790 SkM8:3458 Uncaught TypeError: Cannot read property 'getOrCreateObserversLookup' of undefined
at new Controller (VM19790 SkM8:3458)
at HtmlBehaviorResource.create (VM19790 SkM8:4146)
at HTMLButtonElement.auInit (VM19796 0na4:70)
at HTMLButtonElement.attributeChangedCallback (VM19796 0na4:90)
at CustomElementRegistry.registerBehavior (VM19796 0na4:209)
at CustomElementRegistry.register (VM19796 0na4:227)
at eval (VM19793 main:47)
at eval (VM19771 eG:59)
at run (VM19773 YBdB:40)
at runIfPresent (VM19773 YBdB:69)
The error Cannot read property 'getOrCreateObserversLookup' of undefined is because it gets connected too quickly, before MyButton has a chance to initialize. I guess we can try to initialize earlier, if you wait until app start and start adding html, it will work