component
component
in ftd
is similar to "react component". Components are
independent and reusable bits of code. component
s have "arguments", these are
the data that must be passed to them, and using component
s we construct the
user interface.component
keyword followed by component
name:heading
-- component heading:
-- ftd.text: My Heading
color: red
-- end: heading
heading
. This component is using
ftd.text
, a kernel component, as a definition. We have created a
custom-component which shows given text in red
color.So, how is ftd.text
implemented? ftd
comes with some "kernel components",
these are the lowest level components that every other component uses directly
or indirectly.
heading
. Now to invoke or render
this component in your ftd
application, we can do the following:-- heading:
My Heading
is fixed text displayed by heading
component. We can
make it customisable by using attributes.if
keyword.-- integer num: 10
-- heading:
if: { num <= 10 }
-- integer num: 10
-- heading:
if: { num > 10 }
-- ftd.text: Heading not shown!!
Component "arguments" refer to the inputs that are passed into a component when it is called or invoked. These arguments provide the component with the necessary data that is helpful to configure or customize the component's behavior or appearance.
Component arguments are like function arguments, and you send them into the component as attributes.
The arguments inftd
components creates variables for each component
invocation. These variables have local scope. This means that these variables
can be accessed only inside the component definition in which they are declared.Component arguments starts with argument type follow by argument name, in our
component we can define one such argument, title
.
title
argument is string
.title
argument in the component-- component heading:
string title:
-- ftd.text: $heading.title
color: red
-- end: heading
title
can be passed in as an attribute of the component:-- heading:
title: I love `ftd`!
ftd
!We can use special types like caption
,
body
or caption or body
that give us flexibility to pass
attributes in different location of ftd::p1
"section".
caption or body
type using which we can pass attributes in either
caption
or body
area.caption or body
type for title
argument-- component heading:
caption or body title:
-- ftd.text: $heading.title
color: red
-- end: heading
-- heading: I am in caption area.
-- heading:
I am in body area.
Since I am long description, it's better to pass it here. Isn't it?
I am in body area.
Since I am long description, it's better to pass it here. Isn't it?caption
or body
is alias for string
but if you want to pass
types other than string
you can do the following:-- component show-number:
caption integer number:
-- ftd.integer: $show-number.number
-- end: show-number
-- show-number: 45
-- component heading:
caption or body title:
ftd.color text-color: red
-- ftd.text: $heading.title
color: $heading.text-color
-- end: heading
text-color
defined by the heading
. On the other hand, if an argument is
provided, it supersedes the default value.heading
with default text-color
-- heading: hello
heading
with text-color
value as green
-- heading: this is nice
text-color: green
ftd-title
-- string ftd-title: I love `ftd`!
-- component heading:
caption or body title: $ftd-title
ftd.color text-color: red
-- ftd.text: $heading.title
color: $heading.text-color
-- end: heading
-- heading:
ftd
!-- component heading-with-detail:
caption title:
body detail: $heading-with-detail.title
-- ftd.column:
spacing.fixed.px: 20
color: $inherited.colors.text
-- ftd.text: $heading-with-detail.title
role: $inherited.types.heading-small
-- ftd.text: $heading-with-detail.detail
role: $inherited.types.label-small
-- end: ftd.column
-- end: heading-with-detail
-- heading-with-detail: Title same as detail
-- integer num: 10
-- heading:
title if { num <= 10 }: `num` is less than equal to 10
title: Default Title
num
is less than equal to 10-- heading:
title if { num > 10 }: `num` is less than equal to 10
title: Default Title
ftd
provides some container type kernel component like
ftd.row
and ftd.column
. The container component
accepts the components as an attribute.-- component show-ui:
caption title:
ftd.ui list uis:
-- ftd.column:
spacing.fixed.px: 10
color: $inherited.colors.text
-- ftd.text: $show-ui.title
-- ftd.column:
children: $show-ui.uis
border-width.px: 1
padding.px: 10
border-color: $inherited.colors.border
-- end: ftd.column
-- end: ftd.column
-- end: show-ui
uis
of type ftd.ui list
. We have also pass
this to children
attribute of ftd.column
.-- show-ui: My UIs
-- show-ui.uis:
-- ftd.text: My First UI
-- heading: Using Heading Too
-- end: show-ui.uis
-- component show-ui:
caption title:
children uis:
-- ftd.column:
spacing.fixed.px: 10
color: $inherited.colors.text
-- ftd.text: $show-ui.title
-- ftd.column:
children: $show-ui.uis
border-width.px: 1
padding.px: 10
border-color: $inherited.colors.border
-- end: ftd.column
-- end: ftd.column
-- end: show-ui
-- show-ui: My UIs
-- ftd.text: My First UI
-- heading: Using Heading Too
-- end: show-ui
In ftd
, we can define a component argument as mutable by using the $
prefix
before its name. A mutable argument can be modified within the component and can
take mutable variables as input, which can be modified outside the component's
scope too. Any changes made to a mutable argument will be reflected in the
component's output.
-- component toggle-ui:
caption title:
body description:
boolean $open: true
-- ftd.column:
-- ftd.text: $toggle-ui.title
-- ftd.text: $toggle-ui.description
if: { toggle-ui.open }
-- end: ftd.column
-- end: toggle-ui
$open
argument is mutable, which means it can be
modified both within and outside the toggle-ui
component. Any changes made to
the $open
argument will be immediately reflected in the component's output.-- toggle-ui: My Title
$open: false
My Description
-- toggle-ui: My Title
My Description
-- boolean $global-open: true
-- ftd.text: I change global-open
$on-click$: $ftd.toggle($a = $global-open)
-- toggle-ui: My Title
$open: $global-open
My Description
We have added an $on-click$
event here and used ftd
built-in
function ftd.toggle
. The function toggles the boolean value whenever event
occurs.
global-open
to open
attribute. So the
change in global-open
value changes the open
attribute too.I change global-open
and see the effect.toggle-ui
component, now lets add event to this.-- component toggle-ui:
caption title:
body description:
boolean $open: true
-- ftd.column:
$on-click$: $ftd.toggle($a = $toggle-ui.open)
-- ftd.text: $toggle-ui.title
-- ftd.text: $toggle-ui.description
if: { toggle-ui.open }
-- end: ftd.column
-- end: toggle-ui
$on-click$
event and ftd.toggle
action in ftd.column
component and pass toggle-ui.open
argument.-- toggle-ui: Click me!
My Description