https://github.com/herudi/vanic
A small, Hook-based library for creating Reactive-UI in Vanilla.
https://github.com/herudi/vanic
Last synced: 3 months ago
JSON representation
A small, Hook-based library for creating Reactive-UI in Vanilla.
- Host: GitHub
- URL: https://github.com/herudi/vanic
- Owner: herudi
- License: mit
- Created: 2022-05-30T14:59:35.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2023-06-12T07:48:46.000Z (almost 2 years ago)
- Last Synced: 2025-01-10T19:57:04.971Z (5 months ago)
- Language: JavaScript
- Homepage:
- Size: 180 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
## Vanic
A small, Hook-based library for creating Reactive-UI.
Vanic is an `html-attribute` first.
[](https://github.com/herudi/vanic)
[](https://npmjs.org/package/vanic)
[](http://badges.mit-license.org)
[](https://npmjs.org/package/vanic)
[](https://github.com/herudi/vanic)## Features
- Small.
- Reactive-UI.
- Hooks.
- SSR via renderToString without external deps.
- More.## Examples
- [Counter](https://codesandbox.io/s/vanic-counter-9oc5r9?file=/src/index.jsx)
- [Todo App](https://codesandbox.io/s/vanic-todo-app-7e84xy?file=/src/index.jsx)
- [With Router](https://codesandbox.io/s/vanic-with-router-j10svs?file=/src/index.jsx)## Html-Attribute First
In vanic, event and more will convert to `html-attribute`.## Install
### NPM or Yarn
```bash
npm i vanic
// or
yarn add vanic
```### Browser
```html
```
### Deno```ts
import {...} from "https://deno.land/x/vanic/mod.ts";// more code
```## Usage Jsx
```jsx
/** @jsx h */
import { h, render, useEffect, useState } from "vanic";const Counter = () => {
const [count, setCount] = useState(0);useEffect(() => {
// log counter
console.log(count);
}, [count]);return (
setCount(count + 1)}>Increment
{count}
);
};render(, document.getElementById("app"));
```
## Usage Browser```js
const { html, comp, render, useEffect, useState } = Vanic;const Counter = comp(() => {
const [count, setCount] = useState(0);useEffect(() => {
// log counter
console.log(count);
}, [count]);return html`
Increment
${count}
`
});render(Counter, document.getElementById("app"));
```### Server Side
```jsx
/** @jsx h */
import { h, renderToString } from "vanic";const Home = () => {
returnHello Home
;
};const str = renderToString();
console.log(str);
// send str to server.
```## Hooks
### UseState
```js
const [state, setState] = useState(0);
// or
const [state, setState, getState] = useState(0);
```
> note: getState for live state.### UseEffect & UseLayoutEffect
```js
useEffect(() => {
// code
return () => {
// cleanup
};
}, [/* deps */]);
```### UseReducer
```js
const [state, dispatch] = useReducer(reducer, initial, /* initLazy */);
```### UseMemo
```js
const value = useMemo(() => expensiveFunc(a, b), [a, b]);
```### UseCallback
```js
const addTodo = useCallback(() => {
setTodos((prev) => [...prev, "New Todo"]);
}, [todos]);
```### UseRef
```js
const count = useRef(0);
```> Note: `useRef` for access DOM different from React.useRef.
Accesing DOM via useRef
```js
const Home = () => {
const input = useRef(null);return (
input.ref().focus()}>Focus Me
);
};
```### UseContext & CreateContext
> jsx only
```js
const ThemeContext = createContext();const Home = () => {
const theme = useContext(ThemeContext);return
Hello Home
;
};const App = () => {
return (
)
};render(, document.getElementById("app"));
```### Custom Hook
Very simple with custom hook.
Example handling input.
```jsx
/** @jsx h */
import { h, render, useState } from "vanic";// example hook for handling input form.
const useInput = (initState) => {
const [input, handle] = useState(initState);
return [
// object input
input,// handling
(e) =>
handle({
...input,
[e.target.id]: e.target.value,
}),// reset
(obj = {}) => handle({ ...input, ...obj }),
];
};const MyForm = () => {
const [input, handleInput, resetInput] = useInput({
name: "",
address: "",
});const onSubmit = (e) => {
e.preventDefault();
console.log(input);
// => { name: "foo", address: "bar" }// reset
resetInput({ name: "", address: "" });
};return (
Submit
);
};render(, document.getElementById("app"));
```## Style
Support style as object.
```js
...hello
...
```
## Fragment```jsx
/** @jsx h */
import { h, render, Fragment } from "vanic";const App = () => {
return (
Hello
)
}render(, document.getElementById("app"));
```## isValidElement
```jsx
/** @jsx h */
import { h, isValidElement } from "vanic";const App = () =>
Hello
;console.log(isValidElement()); // true
console.log(isValidElement("noop")); // false
console.log(isValidElement({ name: "john" })); // false
```