Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/pin705/cona
Web Component Nano Simple API inspired from Vue typescript friendly
https://github.com/pin705/cona
webcomponent
Last synced: about 1 month ago
JSON representation
Web Component Nano Simple API inspired from Vue typescript friendly
- Host: GitHub
- URL: https://github.com/pin705/cona
- Owner: pin705
- License: mit
- Created: 2024-07-15T04:41:49.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2024-07-29T13:27:19.000Z (4 months ago)
- Last Synced: 2024-10-01T02:41:47.834Z (about 2 months ago)
- Topics: webcomponent
- Language: TypeScript
- Homepage:
- Size: 94.7 KB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# **Cona**
[![npm version](https://img.shields.io/npm/v/@pinjs/cona?color=yellow)](https://www.npmjs.com/package/@pinjs/cona)
[![npm downloads](https://img.shields.io/npm/dm/@pinjs/cona?color=yellow)](https://www.npmjs.com/package/@pinjs/cona)**Web Component Nano Simple API inspired from Vue typescript friendly**
## **Table of Contents**
- [Why Cona?](#why-cona)
- [Features](#features)
- [Usage](#usage)
- [Installation](#installation)
- [Using CDN](#using-cdn)
- [Example](#example)
- [Development](#development)## **Why Cona?**
- Writing a Web Component (WC) using vanilla JavaScript can be tedious. Alternatively, popular WC libraries can be overkill and overweight (4KB+) for creating small components like a `"Buy now" button` or a `cart listing`.
- `Cona` simplifies the process by staying lightweight, removing unnecessary APIs, and using a simple DOM diffing algorithm.## **Features**
- No dependencies
- **1.3KB** gzipped.
- Simple API inspired by `Vue`.## **Usage**
### **Installation**
```sh
# ✨ Auto-detect
npx nypm install @pinjs/cona# npm
npm install @pinjs/cona# yarn
yarn add @pinjs/cona# pnpm
pnpm install @pinjs/cona# bun
bun install @pinjs/cona
```## Using CDN
First, add the script to the HTML file:
``````
Then, add your component script:
```htmllet Cona = cona.Cona;
class MyCounterChild extends Cona {}```
```htmllet Cona = cona.Cona;
class MyCounterChild extends Cona {}```
## Example
```js
/* main.js *//* Declare global style. Styles will be injected to all Cona Elements */
Cona.style = `
.box {
background: blue;
color: yellow;
}
`class MyCounterChild extends Cona {
render(h) {
/* Bind value from props */
return h`Child: ${this.props.count}`
}
}class MyCounter extends Cona {
setup() {
/* This method runs before mount *//* Create component state using "this.reactive", state must be an object */
this.state = this.reactive({ count: 1 });/* Only use ref for storing DOM reference */
this.pRef = this.ref();/* Effect */
this.effect(
// Effect value: fn -> value
() => this.state.count,
// Effect callback: fn(old value, new value)
(oldValue, newValue) => {
console.log(oldValue, newValue)
}
)/* Watch */
this.watch(
() => this.state.count,
(newValue, oldValue) => {
console.log(`Count changed from ${oldValue} to ${newValue}`);
}
);
}onMounted() {
/* This method runs after mount */
console.log('Mounted');
}onUpdated() {
/* This method runs after each update. */
console.log('Updated');/* P tag ref */
console.log('P Ref', this.pRef?.current);
}onUnmounted() {
/* This method runs before unmount */
console.log('Before unmount');
}addCount() {
/* Update state by redeclaring its key-value. Avoid updating the whole state. */
this.state.count += 1;
}render(h) {
/* This method is used to render *//*
JSX template alike
- Must have only 1 root element
- Bind state / event using value in literal string
- Pass state to child element using props with 'p:' prefix
*/
return h`
Name: ${this.state.count}
Add count
`
}
}customElements.define("my-counter", MyCounter);
customElements.define("my-counter-child", MyCounterChild);
```
```html
/* index.html */```
## Computed
```js
class CounterComponent extends Cona {
private state: { count: number; doubleCount: () => number };constructor() {
super();
this.state = this.reactive({ count: 0 });
this.state.doubleCount = this.computed(() => this.state.count * 2);
}setup() {
// Watching the state.count property
this.watch(
() => this.state.count,
(newValue, oldValue) => {
console.log(`Count changed from ${oldValue} to ${newValue}`);
}
);// Watching the computed doubleCount property
this.watch(
this.state.doubleCount,
(newValue, oldValue) => {
console.log(`DoubleCount changed from ${oldValue} to ${newValue}`);
}
);
}render() {
return this._render`
Increment
Count: ${this.state.count}
Double Count: ${this.state.doubleCount()}
`;
}private increment() {
this.state.count++;
}
}// Define the custom element
customElements.define('counter-component', CounterComponent);```
## Development
local development
- Clone this repository
- Install latest LTS version of [Node.js](https://nodejs.org/en/)
- Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable`
- Install dependencies using `pnpm install`
- Run interactive tests using `pnpm dev`## License
Published under the [MIT](https://github.com/pin705/cf-scraper-bypass/blob/main/LICENSE) license.
Made by [community](https://github.com/pin705/cf-scraper-bypass/graphs/contributors) 💛