Skip to content

Latest commit

 

History

History
executable file
·
151 lines (112 loc) · 4.09 KB

cpx-tag-attributes.md

File metadata and controls

executable file
·
151 lines (112 loc) · 4.09 KB
id title
tag-attributes
Tag Attributes

Attributes (attributes, props, and callbacks) can be set as string literals with double quotes just like in XML:

<img src="hello.png" />

or you can assign an expression inside curly brackets:

// std::string filename = "hello";
// std::string extension = "png";

<img src={filename + "." + extension} />

Differently from JSX, you can set any attribute just like in html, you don't have to use for example className or camel case identifiers:

// in JSX:
<div className="css-class" tabIndex="0" />

// in CPX:
<div class="css-class" tabindex="0" />

Attributes

Attributes corresponds to asmdom::Attrs, they are std::string and are set using domNode.setAttribute(attr, val). Here is the syntax:

<image
  attribute="this is an attribute"
  class="css-class"
  data-id="foo" // dataset attribute
  xlink:href="link" // namespaced attribute
/>

However there are some special identifiers that are automatically interpreted as props like value or checked. This is particularly convenient to avoid a code like <input [value]={variable} /> every time. In addition, ref and every attribute that starts with on is automatically interpreted as callbacks and rendered lowercase, for example:

<button onClick={callback} />
<button ref={callback} />

// is equal to

<button (onclick)={callback}>
<button (ref)={callback}>

If you want to declare an attribute that stars with on, ref, value or checked, so, you want to ignore these rules, you can surround it with curly brackets:

<button onClick={callback} /> // this is an "onclick" callback
<button {onClick}="callback" /> // this is an "onClick" attribute

Props

Props corresponds to asmdom::Props, they are emscripten::val and are set using the dot notation node.prop = val. You can specify that an attribute is a prop surrounding it with square brackets:

<div
  attribute="this is a attribute"
  [prop]="this is a prop"
/>

Using gccx you don't have to care about the type, values are automatically passed to emscripten::val constructor, so, you can do something like this:

// you can provide any type:
// int foo = 7;

// or emscripten::val
// emscripten::val bar = emscripten::val::undefined();

<div
  [foo]={foo}
  [bar]={bar}
/>

Callbacks

Callbacks corresponds to asmdom::Callbacks and they are std::function<bool(emscripten::val)>. You can specify that an attribute is a callback surrounding it with parens:

<button (onclick)={handler} />

You can provide to callbacks a std::function<bool(emscripten::val)>, a pointer to a function or a lambda:

/*
bool onChange(emscripten::val event) {
	// do stuff...
	return true;
};
*/

<input
  (onchange)={onChange}
  (onkeydown)={[&](emscripten::val e) -> bool {
    // do stuff...
    return false;
  }}
/>

Default to true

If you pass no value for an attribute or a prop, it defaults to true:

<input [booleanVal] readonly>
// is equal to
<input [booleanVal]={true} readonly="true">

// falsy values can be used as follows:
<input [booleanVal]={false} readonly="false">

Spread attributes

If you already have an asmdom::Data object, and you want to pass it in CPX, you can use ... as a spread operator to pass the whole object:

/*
asmdom::Data data(
  Attrs {
    {"class", "css-class"},
    {"style", "font-weight: bold"}
  }
)
*/

<div attribute="foo" {...data} />
// is equal to
<div attribute="foo" class="css-class" style="font-weight: bold" />

// you can overwrite values in spread putting them after it
<div attribute="foo" {...data} class="another-css-class"/>
// <div attribute="foo" style="font-weight: bold" class="another-css-class" />