summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Kingsley <josh@joshkingsley.me>2025-10-25 16:24:53 +0300
committerJosh Kingsley <josh@joshkingsley.me>2025-10-25 22:09:35 +0300
commita658e571ef245a200884ea96198c54188ae650da (patch)
tree636039604c7ccd84913c9f17a5a38bbbeb1c83b0
parent1e15fcceddfd2710c84fee0d68988a8eacce7453 (diff)
feat(web): setup components
-rw-r--r--package.json1
-rw-r--r--pnpm-lock.yaml57
-rw-r--r--prettier.config.ts2
-rw-r--r--web/components/app/index.ts13
-rw-r--r--web/components/grid/index.ts14
-rw-r--r--web/components/index.ts2
-rw-r--r--web/global.d.ts9
-rw-r--r--web/html.ts26
-rw-r--r--web/index.css10
-rw-r--r--web/index.html4
-rw-r--r--web/index.ts38
-rw-r--r--web/package.json3
-rw-r--r--web/tsconfig.json12
13 files changed, 186 insertions, 5 deletions
diff --git a/package.json b/package.json
index 5bd7887..d5a1cb5 100644
--- a/package.json
+++ b/package.json
@@ -4,6 +4,7 @@
"type": "module",
"devDependencies": {
"prettier": "^3.6.2",
+ "prettier-plugin-css-order": "^2.1.2",
"prettier-plugin-packagejson": "^2.5.19",
"turbo": "^2.5.8",
"typescript": "^5.9.3"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c7c7c6b..6a01457 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,6 +11,9 @@ importers:
prettier:
specifier: ^3.6.2
version: 3.6.2
+ prettier-plugin-css-order:
+ specifier: ^2.1.2
+ version: 2.1.2(postcss@8.5.6)(prettier@3.6.2)
prettier-plugin-packagejson:
specifier: ^2.5.19
version: 2.5.19(prettier@3.6.2)
@@ -22,6 +25,10 @@ importers:
version: 5.9.3
web:
+ dependencies:
+ open-color:
+ specifier: ^1.9.1
+ version: 1.9.1
devDependencies:
vite:
specifier: ^7.1.12
@@ -302,6 +309,12 @@ packages:
'@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+ css-declaration-sorter@7.3.0:
+ resolution: {integrity: sha512-LQF6N/3vkAMYF4xoHLJfG718HRJh34Z8BnNhd6bosOMIVjMlhuZK5++oZa3uYAgrI5+7x2o27gUqTR2U/KjUOQ==}
+ engines: {node: ^14 || ^16 || >=18}
+ peerDependencies:
+ postcss: ^8.0.9
+
detect-indent@7.0.2:
resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==}
engines: {node: '>=12.20'}
@@ -341,6 +354,9 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
+ open-color@1.9.1:
+ resolution: {integrity: sha512-vCseG/EQ6/RcvxhUcGJiHViOgrtz4x0XbZepXvKik66TMGkvbmjeJrKFyBEx6daG5rNyyd14zYXhz0hZVwQFOw==}
+
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@@ -348,10 +364,28 @@ packages:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
+ postcss-less@6.0.0:
+ resolution: {integrity: sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==}
+ engines: {node: '>=12'}
+ peerDependencies:
+ postcss: ^8.3.5
+
+ postcss-scss@4.0.9:
+ resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.4.29
+
postcss@8.5.6:
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
engines: {node: ^10 || ^12 || >=14}
+ prettier-plugin-css-order@2.1.2:
+ resolution: {integrity: sha512-vomxPjHI6pOMYcBuouSJHxxQClJXaUpU9rsV9IAO2wrSTZILRRlrxAAR8t9UF6wtczLkLfNRFUwM+ZbGXOONUA==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ prettier: 3.x
+
prettier-plugin-packagejson@2.5.19:
resolution: {integrity: sha512-Qsqp4+jsZbKMpEGZB1UP1pxeAT8sCzne2IwnKkr+QhUe665EXUo3BAvTf1kAPCqyMv9kg3ZmO0+7eOni/C6Uag==}
peerDependencies:
@@ -624,6 +658,10 @@ snapshots:
'@types/estree@1.0.8': {}
+ css-declaration-sorter@7.3.0(postcss@8.5.6):
+ dependencies:
+ postcss: 8.5.6
+
detect-indent@7.0.2: {}
detect-newline@4.0.1: {}
@@ -670,16 +708,35 @@ snapshots:
nanoid@3.3.11: {}
+ open-color@1.9.1: {}
+
picocolors@1.1.1: {}
picomatch@4.0.3: {}
+ postcss-less@6.0.0(postcss@8.5.6):
+ dependencies:
+ postcss: 8.5.6
+
+ postcss-scss@4.0.9(postcss@8.5.6):
+ dependencies:
+ postcss: 8.5.6
+
postcss@8.5.6:
dependencies:
nanoid: 3.3.11
picocolors: 1.1.1
source-map-js: 1.2.1
+ prettier-plugin-css-order@2.1.2(postcss@8.5.6)(prettier@3.6.2):
+ dependencies:
+ css-declaration-sorter: 7.3.0(postcss@8.5.6)
+ postcss-less: 6.0.0(postcss@8.5.6)
+ postcss-scss: 4.0.9(postcss@8.5.6)
+ prettier: 3.6.2
+ transitivePeerDependencies:
+ - postcss
+
prettier-plugin-packagejson@2.5.19(prettier@3.6.2):
dependencies:
sort-package-json: 3.4.0
diff --git a/prettier.config.ts b/prettier.config.ts
index a097245..b7b1bc5 100644
--- a/prettier.config.ts
+++ b/prettier.config.ts
@@ -1,7 +1,7 @@
import { type Config } from "prettier";
const config: Config = {
- plugins: ["prettier-plugin-packagejson"],
+ plugins: ["prettier-plugin-packagejson", "prettier-plugin-css-order"],
};
export default config;
diff --git a/web/components/app/index.ts b/web/components/app/index.ts
new file mode 100644
index 0000000..f4eaff1
--- /dev/null
+++ b/web/components/app/index.ts
@@ -0,0 +1,13 @@
+import ntvGrid from "../grid";
+
+class NotiveAppElement extends HTMLElement {
+ connectedCallback() {
+ this.append(
+ ...window.notive.doc.grids.map((_grid) => {
+ return ntvGrid({ foo: "1" });
+ }),
+ );
+ }
+}
+
+customElements.define("ntv-app", NotiveAppElement);
diff --git a/web/components/grid/index.ts b/web/components/grid/index.ts
new file mode 100644
index 0000000..7faf6b1
--- /dev/null
+++ b/web/components/grid/index.ts
@@ -0,0 +1,14 @@
+import h, { type CreateElement } from "../../html";
+
+class NotiveGridElement extends HTMLElement {
+ foo: string;
+
+ connectedCallback() {
+ this.appendChild(h.p("OK: " + this.foo));
+ }
+}
+
+customElements.define("ntv-grid", NotiveGridElement);
+
+export default ((...args: any[]): NotiveGridElement =>
+ (h as any)["ntv-grid"](...args)) as CreateElement<NotiveGridElement>;
diff --git a/web/components/index.ts b/web/components/index.ts
new file mode 100644
index 0000000..8bc14e7
--- /dev/null
+++ b/web/components/index.ts
@@ -0,0 +1,2 @@
+import "./app";
+import "./grid";
diff --git a/web/global.d.ts b/web/global.d.ts
new file mode 100644
index 0000000..3b6d980
--- /dev/null
+++ b/web/global.d.ts
@@ -0,0 +1,9 @@
+import type Notive from "./index";
+
+declare global {
+ interface Window {
+ notive: Notive;
+ }
+}
+
+export {};
diff --git a/web/html.ts b/web/html.ts
new file mode 100644
index 0000000..5bfff21
--- /dev/null
+++ b/web/html.ts
@@ -0,0 +1,26 @@
+export type CreateElement<T extends HTMLElement> = {
+ (...children: (Node | string)[]): T;
+ (attrs: Partial<T>, ...children: (Node | string)[]): T;
+};
+
+type ElementCreator = {
+ [K in keyof HTMLElementTagNameMap]: CreateElement<HTMLElementTagNameMap[K]>;
+};
+
+const h = new Proxy({} as ElementCreator, {
+ get:
+ (_, tag: string) =>
+ (...args: any[]) => {
+ const el = document.createElement(tag);
+
+ if (typeof args[0] === "object") {
+ Object.assign(el, args.shift());
+ }
+
+ el.append(...args.flat());
+
+ return el;
+ },
+});
+
+export default h;
diff --git a/web/index.css b/web/index.css
new file mode 100644
index 0000000..f578562
--- /dev/null
+++ b/web/index.css
@@ -0,0 +1,10 @@
+@import "open-color";
+
+body {
+ background: var(--oc-gray-9);
+ color: var(--oc-white);
+ font-weight: normal;
+ font-family:
+ Seravek, "Gill Sans Nova", Ubuntu, Calibri, "DejaVu Sans", source-sans-pro,
+ sans-serif;
+}
diff --git a/web/index.html b/web/index.html
index b7231ea..846f5be 100644
--- a/web/index.html
+++ b/web/index.html
@@ -3,9 +3,11 @@
<head>
<meta charset="utf-8" />
<title>Notive</title>
+ <link rel="stylesheet" href="index.css" />
<script type="module" src="index.ts"></script>
+ <script type="module" src="components/index.ts"></script>
</head>
<body>
- <p>Hello, World!</p>
+ <ntv-app></ntv-app>
</body>
</html>
diff --git a/web/index.ts b/web/index.ts
index a34c8b4..1524b04 100644
--- a/web/index.ts
+++ b/web/index.ts
@@ -1,5 +1,37 @@
-console.log("OK");
+interface Cell {
+ value: string;
+}
+
+interface Row {
+ cells: Cell[];
+}
+
+interface Part {
+ rows: Row[];
+}
+
+interface Grid {
+ parts: Part[];
+}
-function foo() {
- return "foo";
+interface Doc {
+ grids: Grid[];
}
+
+function defaultDoc(): Doc {
+ const defaultCells = Array(16).map(() => ({ value: "1" }));
+
+ return {
+ grids: [
+ { parts: [{ rows: Array(4).map(() => ({ cells: [...defaultCells] })) }] },
+ ],
+ };
+}
+
+export default class Notive {
+ doc: Doc = defaultDoc();
+}
+
+window.notive = new Notive();
+
+window.dispatchEvent(new CustomEvent("ntv:initialized"));
diff --git a/web/package.json b/web/package.json
index bc3b744..e0b674d 100644
--- a/web/package.json
+++ b/web/package.json
@@ -6,5 +6,8 @@
},
"devDependencies": {
"vite": "^7.1.12"
+ },
+ "dependencies": {
+ "open-color": "^1.9.1"
}
}
diff --git a/web/tsconfig.json b/web/tsconfig.json
new file mode 100644
index 0000000..7ef66ad
--- /dev/null
+++ b/web/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "module": "ESNext",
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "moduleResolution": "bundler",
+ "strict": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true
+ },
+ "include": ["*.ts", "**/*.ts"]
+}