feat: initial utils distribution (#7)
This commit is contained in:
parent
1ae5fa7535
commit
703ef9e45d
7 changed files with 63 additions and 42 deletions
11
package.json
11
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "web-component-base",
|
"name": "web-component-base",
|
||||||
"version": "2.0.0-beta.1",
|
"version": "2.0.0-beta.2",
|
||||||
"description": "A zero-dependency, ~600 Bytes (minified & gzipped), JS base class for creating reactive custom elements easily",
|
"description": "A zero-dependency, ~600 Bytes (minified & gzipped), JS base class for creating reactive custom elements easily",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
|
@ -16,6 +16,10 @@
|
||||||
"types": "./attach-effect.d.ts",
|
"types": "./attach-effect.d.ts",
|
||||||
"import": "./attach-effect.js"
|
"import": "./attach-effect.js"
|
||||||
},
|
},
|
||||||
|
"./utils": {
|
||||||
|
"types": "./utils/index.d.ts",
|
||||||
|
"import": "./utils/index.js"
|
||||||
|
},
|
||||||
"./WebComponent.min.js": {
|
"./WebComponent.min.js": {
|
||||||
"types": "./WebComponent.d.ts",
|
"types": "./WebComponent.d.ts",
|
||||||
"import": "./WebComponent.min.js"
|
"import": "./WebComponent.min.js"
|
||||||
|
@ -26,12 +30,11 @@
|
||||||
"start": "npx simple-server .",
|
"start": "npx simple-server .",
|
||||||
"demo": "npx simple-server .",
|
"demo": "npx simple-server .",
|
||||||
"site": "npm start -w site",
|
"site": "npm start -w site",
|
||||||
"build": "npm run clean && npm run generate:types && npm run copy:meta && npm run copy:source && npm run minify",
|
"build": "npm run clean && tsc && npm run copy:meta && npm run copy:source && npm run minify",
|
||||||
"clean": "rm -rf dist",
|
"clean": "rm -rf dist",
|
||||||
"minify": "npx uglifyjs ./dist/WebComponent.js -o ./dist/WebComponent.min.js",
|
"minify": "npx uglifyjs ./dist/WebComponent.js -o ./dist/WebComponent.min.js",
|
||||||
"generate:types": "tsc --allowJs src/* --outDir dist --declaration --emitDeclarationOnly",
|
|
||||||
"copy:meta": "node prepare.js && cp README.md ./dist && cp LICENSE ./dist",
|
"copy:meta": "node prepare.js && cp README.md ./dist && cp LICENSE ./dist",
|
||||||
"copy:source": "cp ./src/* ./dist",
|
"copy:source": "cp -r ./src/* ./dist",
|
||||||
"pub": "npm run clean && npm run build && cd ./dist && npm publish",
|
"pub": "npm run clean && npm run build && cd ./dist && npm publish",
|
||||||
"pub:beta": "npm run clean && npm run build && cd ./dist && npm publish --tag beta",
|
"pub:beta": "npm run clean && npm run build && cd ./dist && npm publish --tag beta",
|
||||||
"publish:patch": "npm version patch && npm run pub",
|
"publish:patch": "npm version patch && npm run pub",
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import { getKebabCase } from "./utils/get-kebab-case";
|
||||||
|
import { getCamelCase } from "./utils/get-camel-case";
|
||||||
|
import { serialize, deserialize } from "./utils/parse";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A minimal base class to reduce the complexity of creating reactive custom elements
|
* A minimal base class to reduce the complexity of creating reactive custom elements
|
||||||
* @license MIT <https://opensource.org/licenses/MIT>
|
* @license MIT <https://opensource.org/licenses/MIT>
|
||||||
|
@ -89,7 +93,7 @@ export class WebComponent extends HTMLElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeChangedCallback(property, previousValue, currentValue) {
|
attributeChangedCallback(property, previousValue, currentValue) {
|
||||||
const camelCaps = this.#getCamelCaps(property);
|
const camelCaps = getCamelCase(property);
|
||||||
|
|
||||||
if (previousValue !== currentValue) {
|
if (previousValue !== currentValue) {
|
||||||
this[property] = currentValue === "" || currentValue;
|
this[property] = currentValue === "" || currentValue;
|
||||||
|
@ -103,26 +107,16 @@ export class WebComponent extends HTMLElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
#handleUpdateProp(key, stringifiedValue) {
|
#handleUpdateProp(key, stringifiedValue) {
|
||||||
const restored = this.#deserialize(stringifiedValue, this.#typeMap[key]);
|
const restored = deserialize(stringifiedValue, this.#typeMap[key]);
|
||||||
if (restored !== this.props[key]) this.props[key] = restored;
|
if (restored !== this.props[key]) this.props[key] = restored;
|
||||||
}
|
}
|
||||||
|
|
||||||
#getCamelCaps(kebab) {
|
|
||||||
return kebab.replace(/-./g, (x) => x[1].toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
#typeMap = {};
|
#typeMap = {};
|
||||||
#effectsMap = {};
|
#effectsMap = {};
|
||||||
|
|
||||||
#handler(setter, meta) {
|
#handler(setter, meta) {
|
||||||
const effectsMap = meta.#effectsMap;
|
const effectsMap = meta.#effectsMap;
|
||||||
const typeMap = meta.#typeMap;
|
const typeMap = meta.#typeMap;
|
||||||
const getKebab = (str) => {
|
|
||||||
return str.replace(
|
|
||||||
/[A-Z]+(?![a-z])|[A-Z]/g,
|
|
||||||
($, ofs) => (ofs ? "-" : "") + $.toLowerCase()
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
set(obj, prop, value) {
|
set(obj, prop, value) {
|
||||||
|
@ -140,9 +134,8 @@ export class WebComponent extends HTMLElement {
|
||||||
} else if (oldValue !== value) {
|
} else if (oldValue !== value) {
|
||||||
obj[prop] = value;
|
obj[prop] = value;
|
||||||
effectsMap[prop]?.forEach((f) => f(value));
|
effectsMap[prop]?.forEach((f) => f(value));
|
||||||
const kebab = getKebab(prop);
|
const kebab = getKebabCase(prop);
|
||||||
|
setter(kebab, serialize(value));
|
||||||
setter(kebab, meta.#serialize(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -158,29 +151,6 @@ export class WebComponent extends HTMLElement {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#deserialize(value, type){
|
|
||||||
switch (type) {
|
|
||||||
case 'number':
|
|
||||||
case 'boolean':
|
|
||||||
case 'object':
|
|
||||||
case 'undefined':
|
|
||||||
return JSON.parse(value);
|
|
||||||
default:
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#serialize(value) {
|
|
||||||
switch(typeof value) {
|
|
||||||
case 'number':
|
|
||||||
case 'boolean':
|
|
||||||
case 'object':
|
|
||||||
case 'undefined':
|
|
||||||
return JSON.stringify(value);
|
|
||||||
default: return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#initializeProps() {
|
#initializeProps() {
|
||||||
if (!this.#props) {
|
if (!this.#props) {
|
||||||
this.#props = new Proxy(
|
this.#props = new Proxy(
|
||||||
|
|
3
src/utils/get-camel-case.js
Normal file
3
src/utils/get-camel-case.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export function getCamelCase(kebab) {
|
||||||
|
return kebab.replace(/-./g, (x) => x[1].toUpperCase());
|
||||||
|
}
|
6
src/utils/get-kebab-case.js
Normal file
6
src/utils/get-kebab-case.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export function getKebabCase(str) {
|
||||||
|
return str.replace(
|
||||||
|
/[A-Z]+(?![a-z])|[A-Z]/g,
|
||||||
|
($, ofs) => (ofs ? "-" : "") + $.toLowerCase()
|
||||||
|
);
|
||||||
|
}
|
1
src/utils/index.js
Normal file
1
src/utils/index.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export {serialize, deserialize} from './parse.js';
|
23
src/utils/parse.js
Normal file
23
src/utils/parse.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
export function deserialize(value, type) {
|
||||||
|
switch (type) {
|
||||||
|
case "number":
|
||||||
|
case "boolean":
|
||||||
|
case "object":
|
||||||
|
case "undefined":
|
||||||
|
return JSON.parse(value);
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function serialize(value) {
|
||||||
|
switch (typeof value) {
|
||||||
|
case "number":
|
||||||
|
case "boolean":
|
||||||
|
case "object":
|
||||||
|
case "undefined":
|
||||||
|
return JSON.stringify(value);
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
15
tsconfig.json
Normal file
15
tsconfig.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowJs": true,
|
||||||
|
"outDir": "dist",
|
||||||
|
"declaration": true,
|
||||||
|
"emitDeclarationOnly": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/*",
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"src/utils"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in a new issue