11# Functional Component
22
33This is an experiemental project. The goal is to build a rendering framework
4- leveraging the [ web components API] ( https://developer.mozilla.org/en-US/docs/Web/Web_Components ) .
4+ leveraging the
5+ [ web components API] ( https://developer.mozilla.org/en-US/docs/Web/Web_Components ) .
56If you don't know what to do with it... it's okay.
67
78## API
89
910### ` factorizeComponent `
1011
11- Factorizes a component given a render function, a state and an arbitrary number of composable functions.
12+ Factorizes a component given a render function, a state and an arbitrary number
13+ of composable functions.
1214
13- The first argument is a render function. The function is called once when the component is connected to the DOM.
14- The render function should accept two parameters, the first one is the element that is being rendered.
15- The second parameter is the current state that should be used to render the component.
15+ The first argument is a render function. The function is called once when the
16+ component is connected to the DOM. The render function should accept two
17+ parameters, the first one is the element that is being rendered. The second
18+ parameter is the current state that should be used to render the component.
1619
17- The second argument to the ` factorizeComponent ` function is an object that will be used as the inital state.
20+ The second argument to the ` factorizeComponent ` function is an object that will
21+ be used as the inital state.
1822
19- ` State :: Object `
20- ` R :: (DOMElement, State) -> void `
21- ` F :: (((Component, R, State) -> C) -> void, ((DOMElement) -> E) -> void) -> void `
22- ` factorizeComponent :: ((DOMElement, State) -> void, State, [...F]) -> Component `
23+ ` State :: Object ` \
24+ ` R :: (DOMElement, State) -> void ` \
25+ ` F :: (((Component, R, State) -> C) -> void, ((DOMElement) -> E) -> void) -> void ` \
26+ ` factorizeComponent :: ((DOMElement, State) -> void, State, [...F]) -> Component `
2327
2428``` js
2529window .customElements .define (
@@ -30,23 +34,24 @@ window.customElements.define(
3034 h1 .textContent = title;
3135 e .appendChild (e);
3236 },
33- { title: " Bluebird" }
34- )
37+ { title: " Bluebird" },
38+ ),
3539);
3640```
3741
3842#### Higher-order-function
3943
40- The ` factorizeComponent ` also accepts an arbitrary amount of functions as arguments.
41- Those higher-order-functions should accept 2 parameters; the first one is named ` factorize ` , the second is named
42- ` construct ` .
44+ The ` factorizeComponent ` also accepts an arbitrary amount of functions as
45+ arguments. Those higher-order-functions should accept 2 parameters; the first
46+ one is named ` factorize ` , the second is named ` construct ` .
4347
44- Both HOFs accepts a function that will be called, respectively, at the factory phase, before the component is
45- initialize, and, at the construction phase, when the component is being instantiated.
48+ Both HOFs accepts a function that will be called, respectively, at the factory
49+ phase, before the component is initialize, and, at the construction phase, when
50+ the component is being instantiated.
4651
47- The factorize function has three parameters; the first parameter is a Component constructor;
48- the second parameter is the render function which can be called to queue a render request;
49- the third parameter is the initial state.
52+ The factorize function has three parameters; the first parameter is a Component
53+ constructor; the second parameter is the render function which can be called to
54+ queue a render request; the third parameter is the initial state.
5055
5156``` js
5257window .customElements .define (
@@ -65,16 +70,16 @@ window.customElements.define(
6570 value () {
6671 render (this );
6772 },
68- }
73+ },
6974 );
7075
7176 return Component;
7277 });
7378 construct ((element ) => {
7479 element .dataset .forceRender = true ;
7580 });
76- }
77- )
81+ },
82+ ),
7883);
7984```
8085
@@ -92,33 +97,37 @@ fetchTemplate("/demo.html")()
9297
9398### ` useAttributes `
9499
95- Creates a reactive lifecycle with a simple state reducer.
96- When a user or a program sets an attribute of the component, the validation function is called which decides if the
97- component should be rendered again.
100+ Creates a reactive lifecycle with a simple state reducer. When a user or a
101+ program sets an attribute of the component, the validation function is called
102+ which decides if the component should be rendered again.
98103
99- The ` useAttributes ` function accepts a function to validate an observed attributes value and create a new state. The
100- validation function should have three parameters. The first one is an object representing the attribute that was
101- changed, the second is the element that is affected and the last is the current state of the element. The validation
102- function shoudl return a state fragment or false to cancel the render.
104+ The ` useAttributes ` function accepts a function to validate an observed
105+ attributes value and create a new state. The validation function should have
106+ three parameters. The first one is an object representing the attribute that was
107+ changed, the second is the element that is affected and the last is the current
108+ state of the element. The validation function shoudl return a state fragment or
109+ false to cancel the render.
103110
104- The hook function also takes a map object for all of the attributes to observe.The value is a function to transform
105- the value before the validation function called. If not transformation is needed, just pass the identity function.
106- ` (x) => x `
111+ The hook function also takes a map object for all of the attributes to
112+ observe.The value is a function to transform the value before the validation
113+ function called. If not transformation is needed, just pass the identity
114+ function. ` (x) => x `
107115
108116``` js
109117window .customElements .define (
110118 " iy-demo" ,
111119 factorizeComponent (
112120 (element , { value }) => {
113- const span = element .querySelector (" span" );
114- span .textContent = String (value);
121+ const span = element .querySelector (" span" );
122+ span .textContent = String (value);
115123 },
116124 { value: 0 },
117125 useAttributes (
118- ({ oldValue, value }) => (oldValue !== value && value >= 0 ) ? ({ value }) : false ,
126+ ({ oldValue, value }) =>
127+ (oldValue !== value && value >= 0 ) ? ({ value }) : false ,
119128 {
120- value: Number
121- }
129+ value: Number ,
130+ },
122131 ),
123132 (factorize ) => {
124133 factorize ((Component ) => {
@@ -143,24 +152,28 @@ window.customElements.define(
143152 );
144153 return Component;
145154 });
146- }
147- )
155+ },
156+ ),
148157);
149158```
150159
151160### ` useCallbacks `
152161
153- Hooks into the component's lifecycle. Learn more about [ lifecycle callbacks on MDN] ( https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#using_the_lifecycle_callbacks )
162+ Hooks into the component's lifecycle. Learn more about
163+ [ lifecycle callbacks on MDN] ( https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#using_the_lifecycle_callbacks )
154164
155- The function accepts as argument an object of function to hook into one of the following callback:
156- ` connectedCallback ` , ` disconnectedCallback ` , ` attributeChangedCallback ` and ` adoptedCallback ` .
165+ The function accepts as argument an object of function to hook into one of the
166+ following callback: ` connectedCallback ` , ` disconnectedCallback ` ,
167+ ` attributeChangedCallback ` and ` adoptedCallback ` .
157168
158- Each callback function will be called when appropriate with the element, the relevant options and a ` asyncRender `
159- function as arguments.
160- The ` asyncRender ` function can be called at any moment with a "state setter" function. This returns a thunk function
161- that may accept an argument. When the thunk function is called, the "state setter" function is called with the
162- current element and state as argument. This function should return a state fragment or false. The state fragment is
163- then merged with the current state and set the relevant component attributes. See ` useAttribute ` .
169+ Each callback function will be called when appropriate with the element, the
170+ relevant options and a ` asyncRender ` function as arguments. The ` asyncRender `
171+ function can be called at any moment with a "state setter" function. This
172+ returns a thunk function that may accept an argument. When the thunk function is
173+ called, the "state setter" function is called with the current element and state
174+ as argument. This function should return a state fragment or false. The state
175+ fragment is then merged with the current state and set the relevant component
176+ attributes. See ` useAttribute ` .
164177
165178``` js
166179window .customElements .define (
@@ -178,8 +191,11 @@ window.customElements.define(
178191 button .textContent = " Add" ;
179192 element .appendChild (span);
180193 element .appendChild (button);
181- button .addEventListener (" click" , render ((e , { value }) => ({ value: ++ value })));
182- }
194+ button .addEventListener (
195+ " click" ,
196+ render ((e , { value }) => ({ value: ++ value })),
197+ );
198+ },
183199 }),
184200 (factorize ) => {
185201 factorize ((Component , render ) => {
@@ -206,16 +222,16 @@ window.customElements.define(
206222
207223 return Component;
208224 });
209- }
210- )
225+ },
226+ ),
211227);
212228```
213229
214230### ` useShadow `
215231
216232Attaches a shadow root to every instance of the Component.
217-
218- ``` js
233+
234+ ``` js
219235window .customElements .define (
220236 " iy-demo" ,
221237 factorizeComponent (
@@ -224,21 +240,23 @@ window.customElements.define(
224240 span .textContent = String (value);
225241 },
226242 { value: 0 },
227- useShadow ({ mode: " open" })
228- )
243+ useShadow ({ mode: " open" }),
244+ ),
229245);
230- ```
246+ ```
231247
232248### ` useTemplate `
233249
234- Automatically appends a clone of a template to the element or the element's shadow root.
250+ Automatically appends a clone of a template to the element or the element's
251+ shadow root.
235252
236- The function accepts a function that must return a template instance or a Promise of a template instance.
237- Optionally, the function can also be passed an object as the second argument that is used to define
238- children that would be often queried during the render phase.
239- The object's values must be a function that will accept the component instance as the first parameter
240- and return a child element or node list.
241- The elements will be accessible as the ` elements ` property of the Component instance element.
253+ The function accepts a function that must return a template instance or a
254+ Promise of a template instance. Optionally, the function can also be passed an
255+ object as the second argument that is used to define children that would be
256+ often queried during the render phase. The object's values must be a function
257+ that will accept the component instance as the first parameter and return a
258+ child element or node list. The elements will be accessible as the ` elements `
259+ property of the Component instance element.
242260
243261``` js
244262window .customElements .define (
@@ -252,16 +270,15 @@ window.customElements.define(
252270 useTemplate (
253271 () => {
254272 const t = window .document .createElement (" template" );
255- t .innerHTML = ` <span >0</span ><button >Add</button >`
273+ t .innerHTML = ` <span >0</span ><button >Add</button >` ;
256274
257275 return t;
258276 },
259277 {
260278 number : (e ) => e .shadowRoot .querySelector (" span" ),
261- addButton : (e ) => e .shadowRoot .querySelector (" button" )
262- }
263- )
279+ addButton : (e ) => e .shadowRoot .querySelector (" button" ),
280+ },
281+ ),
264282 ),
265283);
266284```
267-
0 commit comments