Setting a Widget's Properties
A widget's properties are exposed from a custom element automatically as either attributes, events, or properties.
The following EmailSignup
widget contains several different property types.
src/widgets/EmailSignup.tsx
import { tsx, create } from '@dojo/framework/core/vdom';
import * as css from './styles/EmailSignup.m.css';
import icache from '@dojo/framework/core/middleware/icache';
export interface EmailSignupProperties {
title?: string;
onSignUp?: () => void;
signUpBonusDate?: Date;
successMessages?: string[];
}
function randomEntry(arr: string[]) {
return arr[Math.floor(Math.random() * arr.length)];
}
const factory = create({ icache }).properties<EmailSignupProperties>();
export default factory(function EmailSignup({ middleware: { icache }, properties }) {
const { title, signUpBonusDate, successMessages } = properties();
const signedUp = icache.getOrSet('signedUp', false);
const signUp = () => {
const { onSignUp } = properties();
// post email address to a server
icache.set('signedUp', true);
icache.set('successMessage', successMessages ? randomEntry(successMessages) : 'Thank you for signing up!');
onSignUp && onSignUp();
};
return (
<div key="root" classes={css.root}>
<div key="title" classes={css.title}>
{title || 'Subscribe Now'}
</div>
{signedUp ? (
<div key="confirmation" classes={css.thanks}>
{icache.get('successMessage')}
</div>
) : (
<div key="signup" classes={css.signup}>
{signUpBonusDate && <div>Sign up by {signUpBonusDate.toLocaleDateString()}</div>}
<input type="text" />
<button onclick={signUp}>Sign Up</button>
</div>
)}
</div>
);
});
Attributes
string
and object typed widget properties are automatically added as HTML attributes to your custom element. Continuing with the email subscription example, the title
property ({ title?: string }
) can be customized by adding a title
attribute to the HTML. Since title
is a string property, the value of the HTML attribute is used as the value of the title property with no transformation.
<ref-email-signup id="emailSignup" title="Subscribe to Our Newsletter"></ref-email-signup>
Other serializable properties, like arrays and configuration objects, can be set via HTML attributes by passing in serialized JSON. The sucessMessages
property ({ successMessages?: string[] }
) can be set by adding a successmessages
attribute to the HTML.
<ref-email-signup
id="emailSignup"
title="Subscribe to Our Newsletter"
successmessages='["Thanks!","Thank you for signing up","You are the best!"]'
></ref-email-signup>
Here, the value of the successmessages
attribute will be deserialized and set as the successMessages
property.
Note that if the attribute's value is not valid JSON, the property will not be set.
Events
Widget properties that start with on
and have a function signature are exposed as events. The emitted event is the lower cased part of the property name without the "on." Listening for the onSignUp property ({ onSignUp?: () => void }
) would look like this.
<script>
emailSignup.addEventListener('signup', () => {
// start confetti animation 🎉
});
</script>
Properties
All non-event widget properties are automatically created as properties on the custom element. These properties can be fully controlled by JavaScript. In the email subscription widget, both the title
and signUpBonusDate
properties can be set programmatically as properties.
<script>
const now = new Date();
emailSignup.signUpBonusDate = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate() + 1
);
</script>