UNPKG

5.78 kBMarkdownView Raw
1# fuco
2
3[![npm](https://img.shields.io/npm/v/fuco.svg)](https://www.npmjs.com/package/fuco)
4[![install size](https://packagephobia.now.sh/badge?p=fuco)](https://packagephobia.now.sh/result?p=fuco)
5[![Build Status](https://travis-ci.com/wtnbass/fuco.svg?branch=master)](https://travis-ci.com/wtnbass/fuco)
6[![codecov](https://codecov.io/gh/wtnbass/fuco/branch/master/graph/badge.svg)](https://codecov.io/gh/wtnbass/fuco)
7
8Functional Component like React, but for Web Components.
9
10```html
11<!DOCTYPE html>
12<html lang="en">
13 <body>
14 <counter-app></counter-app>
15 <script type="module">
16 import { html, defineElement, useState } from "//unpkg.com/fuco?module";
17
18 function Counter() {
19 const [count, setCount] = useState(0);
20 return html`
21 <div>${count}</div>
22 <button @click=${() => setCount(count + 1)}>+</button>
23 <button @click=${() => setCount(count - 1)}>-</button>
24 `;
25 }
26
27 defineElement("counter-app", Counter);
28 </script>
29 </body>
30</html>
31```
32
33- [Installation](#Installation)
34- [Hooks](#Hooks)
35 - [useAttribute](#useAttribute)
36 - [useProperty](#useProperty)
37 - [useDispatchEvent](#useDispatchEvent)
38 - [useStyle](#useStyle)
39 - [useState](#useState)
40 - [useReducer](#useReducer)
41 - [useRef](#useRef)
42 - [useContext](#useContext)
43 - [useEffect](#useEffect)
44 - [useMemo](#useMemo)
45 - [useCallback](#useCallback)
46
47## Installation
48
49```sh
50npm install fuco
51# or use yarn
52yarn add fuco
53```
54
55## Hooks
56
57- Original Hooks
58
59 - [useAttribute](#useAttribute)
60 - [useProperty](#useProperty)
61 - [useDispatchEvent](#useDispatchEvent)
62 - [useStyle](#useStyle)
63
64- React Hooks compatible
65
66 - [useState](#useState)
67 - [useReducer](#useReducer)
68 - [useRef](#useRef)
69 - [useContext](#useContext)
70 - [useEffect](#useEffect)
71 - [useMemo](#useMemo)
72 - [useCallback](#useCallback)
73
74### useAttribute
75
76`useAttribute` returens attribute value, and updates the component when the attribute specified by the first argument is changed.
77
78```js
79defineElement("greet-element", () => {
80 const name = useAttribute("name");
81 const hidden = useAttribute("hidden", value => value != null);
82 if (hidden) {
83 return html``;
84 }
85 return html`
86 <div>Hello, ${name}</div>
87 `;
88});
89
90html`
91 <greet-element name="World"></greet-element>
92`;
93// => `<div>Hello, World</div>`
94
95html`
96 <greet-element name="WebComponent" hidden></greet-element>
97`;
98// => ``
99```
100
101### useProperty
102
103`useProperty` returns element's property value, and updates the component when the property values is changed.
104
105```js
106defineElement("card-element", () => {
107 const card = useProperty("card");
108 return html`
109 <div>${card.mark} ${card.value}</div>
110 `;
111});
112
113const heartAce = { mark: "♥", value: 1 };
114html`
115 <card-element .card=${heartAce}></card-element>
116`;
117```
118
119### useDispatchEvent
120
121`useDispatchEvent` offers `dispatch` function like `dispatchEvent` to use CustomEvent.
122
123```js
124defineElement("send-message", () => {
125 const dispatch = useDispatchEvent("some-message", {
126 bubbles: true,
127 composed: true
128 });
129 return html`
130 <button @click=${() => dispatch("Hi!")}>Send</button>
131 `;
132});
133
134// You can listen custom event using `@` prefix.
135html`
136 <send-message @some-message=${e => console.log(e.detail)}></send-message>
137`;
138```
139
140### useStyle
141
142`useStyle` can adapt a StyleSheet to the component.
143
144```js
145function HelloWorld() {
146 useStyle(
147 () => css`
148 div {
149 color: red;
150 }
151 `
152 );
153 return html`
154 <div>Hello, world</div>
155 `;
156}
157```
158
159### useState
160
161`useState` returns a pair of state and setter function, and upadates the component by updating state using setter function.
162
163```js
164function Counter() {
165 const [count, setCount] = useState(0);
166 return html`
167 <div>${count}</div>
168 <button @click=${() => setCount(count + 1)}>PLUS</button>
169 `;
170}
171```
172
173### useReducer
174
175`useReducer` returns a pair of state and dispatch function.
176
177```js
178function Counter() {
179 const [count, dispatch] = useReducer((state, action) => state + action, 0);
180 return html`
181 <div>${count}</div>
182 <button @click=${() => dispatch(1)}>PLUS</button>
183 `;
184}
185```
186
187### useRef
188
189`useRef` returned a ref object like React's, and you can recieve a DOM by setting ref object to attribute.
190
191```js
192function Input() {
193 const [value, setValue] = useState("");
194 const inputRef = useRef(null);
195 return html`
196 <input ref=${inputRef} />
197 <button @click=${() => setValue(inputRef.current.value)}>push</button>
198 `;
199}
200```
201
202### useContext
203
204`createContext` offers `Context`, and using`Context.defineProvider` to define provider, and you can consume it using `useContext(Context)`.
205
206```js
207const ThemeContext = createContext();
208
209// define a custom element as Provider
210ThemeContext.defineProvider("theme-provider");
211
212const App = () => html`
213 <theme-provider .value=${"dark"}>
214 <theme-comsumer></theme-comsumer>
215 </theme-provider>
216`;
217
218// consume context
219defineElement("theme-consumer", () => {
220 const theme = useContext(ThemeContext);
221 return html`
222 <div>theme is ${theme}</div>
223 `;
224});
225```
226
227### useEffect
228
229`useEffect` gives you a side effects. it will run after rendering the component.
230
231```js
232function Timer() {
233 useEffect(() => {
234 const id = setInterval(() => console.log("interval"));
235 return () => clearInterval(id);
236 }, []);
237 return html``;
238}
239```
240
241### useMemo
242
243`useMemo` returns a memorized value. the value will update when deps given as the second argument.
244
245```js
246function Plus() {
247 const value = useMemo(() => a + b, [a, b]);
248 return html`
249 ${value}
250 `;
251}
252```
253
254### useCallback
255
256`useCallback` returns memorized callback as same as `useMemo`.
257
258```js
259function Greet() {
260 const greet = useCallback(() => alert("Hello"));
261 return html`
262 <button @click=${greet}>hello</button>
263 `;
264}
265```
266
267## License
268
269MIT