Create npm package and add typescript. Add Declaform skeleton.
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
dist/
|
||||||
|
node_modules/
|
||||||
29
package-lock.json
generated
Normal file
29
package-lock.json
generated
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "web-components",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "web-components",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.9.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "5.9.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
|
||||||
|
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
package.json
Normal file
14
package.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "web-components",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A collection of useful web components and functionality.",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Austin Smith",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.9.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/declaform/README.md
Normal file
1
src/declaform/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# Declaform
|
||||||
68
src/declaform/declaform.ts
Normal file
68
src/declaform/declaform.ts
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
export class Declaform extends HTMLElement {
|
||||||
|
|
||||||
|
static observedAttributes = [
|
||||||
|
'customInputs', // Lets user specify additional inputs to be considered "fields" by the form. Example: <object-list>
|
||||||
|
]
|
||||||
|
|
||||||
|
private _fields: Field[];
|
||||||
|
private _form: HTMLFormElement;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.attachInternals();
|
||||||
|
this.attachShadow({ mode: 'open' });
|
||||||
|
this.shadowRoot!.innerHTML = '<form><slot></slot></form>';
|
||||||
|
this._fields = [];
|
||||||
|
this._form = this.shadowRoot!.querySelector('form')!;
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
const customInputs = this.getAttribute('customInputs')?.split(',').map(x => x.trim()) ?? [];
|
||||||
|
const selectors = ['input', 'select'].concat(customInputs).map(x => `${x}[name]`).join(',');
|
||||||
|
const inputs = Array.from(this.querySelectorAll(selectors));
|
||||||
|
// group inputs by name
|
||||||
|
const inputGroups = new Map<string, Element[]>();
|
||||||
|
for (const input of inputs) {
|
||||||
|
const name = input.getAttribute('name');
|
||||||
|
if (name) {
|
||||||
|
const group = inputGroups.get(name);
|
||||||
|
if (group) {
|
||||||
|
inputGroups.set(name, group.concat(input))
|
||||||
|
} else {
|
||||||
|
inputGroups.set(name, [input]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [name, inputs] of inputGroups.entries()) {
|
||||||
|
this._fields.push(new Field(name, inputs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get form() {
|
||||||
|
return this._form;
|
||||||
|
}
|
||||||
|
|
||||||
|
get fields() {
|
||||||
|
return this._fields;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('decla-form', Declaform);
|
||||||
|
|
||||||
|
class Field {
|
||||||
|
constructor(private name: string, private _inputs: Element[]) {
|
||||||
|
}
|
||||||
|
|
||||||
|
get value() {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
set value(x: any) {
|
||||||
|
}
|
||||||
|
|
||||||
|
get type() {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
44
tsconfig.json
Normal file
44
tsconfig.json
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
// Visit https://aka.ms/tsconfig to read more about this file
|
||||||
|
"compilerOptions": {
|
||||||
|
// File Layout
|
||||||
|
"rootDir": "./src",
|
||||||
|
"outDir": "./dist",
|
||||||
|
|
||||||
|
// Environment Settings
|
||||||
|
// See also https://aka.ms/tsconfig/module
|
||||||
|
"module": "esnext",
|
||||||
|
"target": "es6",
|
||||||
|
"types": [],
|
||||||
|
// For nodejs:
|
||||||
|
// "lib": ["esnext"],
|
||||||
|
// "types": ["node"],
|
||||||
|
// and npm install -D @types/node
|
||||||
|
|
||||||
|
// Other Outputs
|
||||||
|
"sourceMap": true,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
|
||||||
|
// Stricter Typechecking Options
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"exactOptionalPropertyTypes": true,
|
||||||
|
|
||||||
|
// Style Options
|
||||||
|
// "noImplicitReturns": true,
|
||||||
|
// "noImplicitOverride": true,
|
||||||
|
// "noUnusedLocals": true,
|
||||||
|
// "noUnusedParameters": true,
|
||||||
|
// "noFallthroughCasesInSwitch": true,
|
||||||
|
// "noPropertyAccessFromIndexSignature": true,
|
||||||
|
|
||||||
|
// Recommended Options
|
||||||
|
"strict": true,
|
||||||
|
// "jsx": "react-jsx",
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noUncheckedSideEffectImports": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user