ftd
is a great language to build UI components in. fastn
is easy to learn
and author. fastn
has a design system, dark mode support. fastn
websites are
fast as we do server side rendering etc. And we are just getting started, lot
more is yet to come.
And yet JS ecosystem is huge. There are far too many ready made components
available that we do not want to miss out on them when using fastn-stack
.
FASTN.ftd
:FASTN.ftd
-- fastn.dependency: fastn-stack.github.io/ftd-web-component-example
-- import: fastn-stack.github.io/ftd-web-component-example
-- ftd-web-component-example.demo:
-- ftd-web-component-example.demo:
line, the JS would no
longer be needed and would be gone from dependency.First job is to create the web component itself that you want to use. There is plenty of resource on internet to teach you how to do it, checkout the official React web component guide.
We will start with the MDN tutorial.class WordCount extends HTMLParagraphElement {
constructor() {
super(); // Always call super first in constructor
// Element functionality written in here
}
}
customElements.define("word-count", WordCount, { extends: "p" });
ftd
you have
to declare it in a ftd
file:-- web-component word-count:
js: [$assets.files.word-count.js]
What this does is tell ftd
about existence of the web-component. Further it
tells ftd
in what JS file is the web-component
is defined. We have used
fastn
's' assets feature to refer to the JS file.
-- word-count:
somewhere and ftd
will do the right thing, JS will get auto incldued, and web component will get
rendered.ftd
WorldsA web-component that takes no parameters is not very useful. You would want to pass data to web-component. You would also want to possibly mutate the data from the web-component or JS world, and want fastn world to see the mutations. You may also want to continue to mutate the data in fastn world after web component have been rendered, and have web-component respond to those changes.
All this are possible, the way to think about it is that data that you want to
share between the two worlds is "managed" / "owned" by fastn, and from your JS
you use fastn
APIs to mutate the fastn owned data.
-- web-component todo-list-display:
string name:
todo-item list $todo_list:
js: [$assets.files.todo.js]
Here we have an argument named name
, whose type is string
, and the next
argument is todo_list
of type todo-item list
.
As you see todo_list
is defined as $todo_list
, this means todo_list
is
a mutable variable. name
on the other hand is immutable. So ftd
creates a
mutable list and an immutable string for the two and passes these to JS.
class Todo extends HTMLElement {
constructor() {
super(); // Always call super first in constructor
// get access to arguments passed to this component
let data = window.ftd.component_data(this);
// ...
}
}
Now you have access to component data, and you can now use data.<var>.get ()
, .set()
functions to manage data from the JS world. You can listen for
changes in data on fastn
side by using .on_change(function(){ * some code here * })
. Checkout the full [source code of our demo]
(https://github.com/fastn-stack/ftd-web-component-example/blob/main/todo.js)
for more detailed usage.