Error when trying to load a my Aurelia custom element - aurelia

I am a newbie with Aurelia and I am trying to create my first custom element. I am coming from Angular 1 and as far as I could understand, custom elements seems to be similar to Angular 1 directives.
So, I am getting the following error:
I have checked my template looking for some bad written html, but I can't find it. Does anyone have any idea? Code is shown below:
src/views/login/login.html
<template>
<require from = "/resources/elements/login-form/login-form"></require>
<h1>Login</h1>
<login-form></login-form>
</template>
src/views/login/login.js
export class Login {}
src/resource/elements/login-form/login-form.html
<template>
<div>Here's gonna be a form</div>
</template>
src/resource/elements/login-form/login-form.js
import {customElement} from 'aurelia-framework';
#customElement('login-form')
export class LoginForm {
}

src/resource/elements/login-form/login-form.js as below
export class LoginFormCustomElement {
}
This will work Aurelia framework having naming Conventions. When ever you are using as a custom element better to pass class name with end of CustomElement.

Related

Vue3 Reactivity in script setup for translation

I am adding some DOM elements in the script setup side but I want the messages to change when I change the language. I am using vue-i18n plugin. It's easy to do it in the template section because I can basically use the useI18n().t method but how can I do this in the script setup section. Using the useI18n().t method doesn't ensure reactivity.
Example Code:
$(".time")[0].innerHTML = `
<div>0<span>${useI18n().t("details.hour")}</span></div>
<div>0<span>${useI18n().t("details.minute")}</span></div>
<div>0<span>${useI18n().t("details.second")}</span></div>
`
Manipulating DOM directly inside the script leads to inconsistence in your app, you should drive your component by different reactive data to achieve your goal.
In your current situation try to define a computed property based on the translation then render it inside the template based on its different properties :
<script setup>
const {t} =useI18n()
const time = computed(()=>{
return {
hour:t(""details.hour"),
minute:t(""details.minute"),
second:t(""details.second"),
}
})
</script>
<template>
<div class="time">
<div>0<span>{{time.hour}}</span></div>
<div>0<span>{{time.minute}}</span></div>
<div>0<span>{{time.second}}</span></div>
</div>
</template>

vue multiple components in a single file

in vue documents I saw "Namespaced Components" in "script setup" guide it writes:
You can use component tags with dots like <Foo.Bar> to refer to components nested under object properties. This is useful when you import multiple components from a single file:
<script setup>
import * as Form from './form-components'
</script>
<template>
<Form.Input>
<Form.Label>label</Form.Label>
</Form.Input>
</template>
I wanted to know in this example what will the form-component look like, and what is the correct use case for such a component, does it have anything to do with "slot" or not.
In this case, form-components refers to a .js file that seems to be exporting single-file components (.vue).
form-components.js
export { default as Label } from './form-label.vue'
export { default as Input } from './form-input.vue'
You can then access these components via:
import * as Form from './form-components'
However, I recommend using a destructuring assignment methodology, as it is better interpreted by IDEs.
import { Input, Label } from './form-components'

Is Tailwind class binding possible through Storyblok?

I'm trying to develop some components that will be used by our content editors in Storyblok and there's a use case where we would like to define layout properties (using Tailwind's classes) through props that will be coming from Storyblok components.
As an example,
I am passing the width prop through storyblok giving a value of w-1/2 which is a Tailwind class. As you see on the right the class is applied just fine to the element but there's no actual impact on the page. I have tried the same with many other classes (either for background or border colors or for text styling etc, tried to use Tailwind classes as props coming from Storyblok but didn't work).
My only guess is that Nuxt is a server side application and the CSS gets compiled on build time, therefore any new class binding to the DOM will not reflect the actual CSS that they represent. Is this right? If yes, is there a way to make this happen and work?
The code for the widthSetter component is as simple as that
<template>
{{blok.width}}
<div v-editable="blok" :class="[ blok.width ]">
<component
v-for="value in blok.blocks"
:key="value._uid"
:is="value.component"
:blok="value"
/>
</div>
</template>
<script lang="ts" setup>
const props = defineProps({
blok: {
type: Object,
required: true,
},
})
</script>
You need to add Complete Class Names.
As there is no w-1/2 in your code, TW won't generate the class.
You can workaround the issue by adding the class to safelist.
Doc: https://tailwindcss.com/docs/content-configuration#safelisting-classes
module.exports = {
safelist: ['w-1/2'],
//...
}
Then w-1/2 utility will be generated regardless if it shows up in your code or not.

Custom Attribute on Aurelia not working

I am a beginner by Aurelia. I want to program a Custom Attribute as you see here:
square.js:
/*jshint esversion: 6 */
import {bindable, inject} from 'aurelia-framework';
#inject(Element)
export class SquareCustomAttribute {
#bindable sideLength;
#bindable color;
constructor(element){
this.element = element;
}
sideLengthChanged(newValue, oldValue){
this.element.style.width = this.element.style.height = `${newValue}px`;
}
colorChanged(newValue, oldValue){
this.element.style.backgroundColor = newValue;
}
}
and you can see html in the following:
<template>
<require from="./square"></require>
<div square="color.bind: squareColor; side-length.bind: squareSize"></div>
</template>
I get an error:
ERROR [app-router] Error: (SystemJS) Unable to dynamically transpile ES module as SystemJS.transpiler set to false.
Could you please help me?
An easy way to do what you are trying to do (not purely an attribute) is this:
try this:
square.html
<template bindable="sideLength, color">
<div css.bind="height: ${sideLength}; width: ${sideLength}; background-color: ${color}"/>
</template>
now you just use it like this:
[any].html
<require from="[path]/[to]/square.html"></require>
.
.
.
<square side-length="50" color="red"></square>
.
.
.
There is almost an exact example of this under data binding in the docs:
Aurelia Docs: Cheat Sheet - Databinding
Creating an answer so this can be closed.
User had an error with his script file causing the transpiler to fail. Changing the file extension from .js to .ts solved the issue as the TypeScript file could be handled by SystemJS.

Binding to a Custom Element in a Template Part in Aurelia

I've created a plunkr to illustrate the problem I'm having.
I'm in the middle of creating a dashboard which at the moment contains four different items. Each of these items I'm creating as Custom Elements then wrapping them in a Custom Element called Widget to give them a frame, title and styling. Here's what that snippet looks like:
<widget title="A Widget" icon="fa-question">
<template replace-part="item-template">
<child-element text.bind="$parent.$parent.someText"></child-element>
</template>
</widget>
For reference the widget view looks like this:
<template>
<require from="./widget.css!"></require>
<div class="widget">
<div class="widget-header">
<i class="fa ${icon}"></i>
<h3>${title}</h3>
</div>
<div class="widget-content">
<template replaceable part="item-template"></template>
</div>
</div>
</template>
and the view model is:
import {bindable} from "aurelia-framework";
export class WidgetCustomElement {
#bindable title;
#bindable icon;
#bindable show; // This is something I want the child element
// to be able to bind to and control but haven't
// got there yet!!
}
But notice I'm trying to bind data from the ViewModel into the child-element where the child-element looks like this:
import {bindable} from "aurelia-framework";
export class ChildElementCustomElement {
#bindable text;
}
and the view:
<template>
<p>The widget passed us : ${text}</p>
</template>
The problem is no matter what expression I use (and here I'm currently trying $parent.$parent.someText) I can't get the binding to work.
Should this work? I've also tried defining the variable someText in the main ViewModel as `#bindable someText' but that throws the following exception:
Unhandled promise rejection TypeError: Cannot read property 'some-text' of null
at BindableProperty.initialize (https://cdn.rawgit.com/jdanyow/aurelia-plunker/v0.4.0/jspm_packages/github/aurelia/templating#0.14.4/aurelia-templating.js:2448:33)
at new BehaviorInstance (https://cdn.rawgit.com/jdanyow/aurelia-plunker/v0.4.0/jspm_packages/github/aurelia/templating#0.14.4/aurelia-templating.js:2199:23)
at HtmlBehaviorResource.create (https://cdn.rawgit.com/jdanyow/aurelia-plunker/v0.4.0/jspm_packages/github/aurelia/templating#0.14.4/aurelia-templating.js:2821:30)
at https://cdn.rawgit.com/jdanyow/aurelia-plunker/v0.4.0/jspm_packages/github/aurelia/templating#0.14.4/aurelia-templating.js:3385:27
at f (https://cdn.rawgit.com/jdanyow/aurelia-plunker/v0.4.0/jspm_packages/npm/core-js#0.9.18/client/shim.min.js:1415:56)
at https://cdn.rawgit.com/jdanyow/aurelia-plunker/v0.4.0/jspm_packages/npm/core-js#0.9.18/client/shim.min.js:1423:13
at b.exports (https://cdn.rawgit.com/jdanyow/aurelia-plunker/v0.4.0/jspm_packages/npm/core-js#0.9.18/client/shim.min.js:453:24)
at b.(anonymous function) (https://cdn.rawgit.com/jdanyow/aurelia-plunker/v0.4.0/jspm_packages/npm/core-js#0.9.18/client/shim.min.js:1625:11)
at Number.f (https://cdn.rawgit.com/jdanyow/aurelia-plunker/v0.4.0/jspm_packages/npm/core-js#0.9.18/client/shim.min.js:1596:24)
at q (https://cdn.rawgit.com/jdanyow/aurelia-plunker/v0.4.0/jspm_packages/npm/core-js#0.9.18/client/shim.min.js:1600:11)
I am not sure whether you are looking for this or not, however, introducing a #bindable text property in WidgetCustomElement makes this a whole lot easier. I worked on your plunk and introduced a #bindable wtext; in WidgetCustomElement, used this property to bind someText in app view like below:
<widget title="A Widget" icon="fa-question" wtext.bind="someText">
<template replace-part="item-template">
<child-element text.bind="wtext"></child-element>
<!--<child-element text.bind="$parent.$parent.someText"></child-element>-->
</template>
</widget>
And this works. However as I said I am not sure whether this approach works for you or not. What I have assumed is your widget will mostly contain one single child element and if this assumption is correct then this should work, however in case one-to-many mapping (many child element in single widget), something else is needed.
Hope this helps.
EDIT: I forked your plunk to make the changes and here is the link to that.
I have since stumbled across something in the Aurelia document detailing Template Parts. In example.js a bind() method is defined which assigns the bindingContext to a local member this.$parent.
This means all I have to do is defined the following in the view model for my widget:
bind(bindingContext) {
this.$parent = bindingContext;
}
Then the child-element is bound with the following:
<child-element text.bind="$parent.someText"></child-element>
I've forked my original plunkr to demonstrate it working.
Given repeat-for provides it's own $parent I had mistakenly believed there was one automatically defined here!!