diff --git a/.gitignore b/.gitignore index 36b13f1..128fc01 100644 --- a/.gitignore +++ b/.gitignore @@ -174,3 +174,6 @@ cython_debug/ # PyPI configuration file .pypirc +node_modules/ +dist/ +.vite/ diff --git a/README.md b/README.md index fcd7b8f..f2d84d2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,16 @@ -# repo-seed +# ๐Ÿงช TestDrive UI -A git repository template to bootstrap coulomb projects from. \ No newline at end of file +Baseline scaffold for test-driven browser UI component development with **Lit**, **Mocha**, and **jsdom**. + +### Commands + +| Command | Description | +|----------|-------------| +| `npm install` | Install dependencies | +| `npm test` | Run all Mocha tests headlessly | +| `npm run dev` | Start Vite dev server and preview components | + +### Folder layout +- `src/components/` โ€” individual components (each with .js, .test.js, .stories.js) +- `test/setup.js` โ€” shared JSDOM environment +- `vite.config.js` โ€” dev preview config diff --git a/package.json b/package.json new file mode 100644 index 0000000..40f4149 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "testdrive-ui", + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "vite", + "test": "mocha --require test/setup.js \"src/**/*.test.js\"" + }, + "devDependencies": { + "chai": "^5.1.0", + "jsdom": "^24.0.0", + "lit": "^3.1.0", + "mocha": "^11.0.0", + "vite": "^6.0.0" + } +} diff --git a/src/components/ui-edit-button/ui-edit-button.js b/src/components/ui-edit-button/ui-edit-button.js new file mode 100644 index 0000000..c4a609f --- /dev/null +++ b/src/components/ui-edit-button/ui-edit-button.js @@ -0,0 +1,32 @@ +import { LitElement, html, css } from "lit"; + +export class UiEditButton extends LitElement { + static styles = css` + button { + position: fixed; + top: 50%; + right: 20px; + transform: translateY(-50%); + background: #007acc; + color: white; + border: none; + border-radius: 8px; + padding: 10px 16px; + cursor: pointer; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); + } + button:hover { + background: #005fa3; + } + `; + + render() { + return html``; + } + + _onClick() { + alert("Edit button clicked!"); + } +} + +customElements.define("ui-edit-button", UiEditButton); diff --git a/src/components/ui-edit-button/ui-edit-button.stories.js b/src/components/ui-edit-button/ui-edit-button.stories.js new file mode 100644 index 0000000..c002a96 --- /dev/null +++ b/src/components/ui-edit-button/ui-edit-button.stories.js @@ -0,0 +1,7 @@ +import "./ui-edit-button.js"; + +export default { + title: "UI/Edit Button", +}; + +export const Default = () => ``; diff --git a/src/components/ui-edit-button/ui-edit-button.test.js b/src/components/ui-edit-button/ui-edit-button.test.js new file mode 100644 index 0000000..4f50e03 --- /dev/null +++ b/src/components/ui-edit-button/ui-edit-button.test.js @@ -0,0 +1,24 @@ +import "../ui-edit-button/ui-edit-button.js"; + +describe("", () => { + it("renders a button element", () => { + const el = document.createElement("ui-edit-button"); + document.body.appendChild(el); + const button = el.shadowRoot.querySelector("button"); + expect(button).to.exist; + expect(button.textContent).to.include("Edit"); + }); + + it("triggers a click handler", () => { + const el = document.createElement("ui-edit-button"); + document.body.appendChild(el); + + let clicked = false; + el._onClick = () => (clicked = true); + + const button = el.shadowRoot.querySelector("button"); + button.click(); + + expect(clicked).to.be.true; + }); +}); diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..7394fbc --- /dev/null +++ b/src/index.html @@ -0,0 +1,12 @@ + + + + + TestDrive UI + + + +

Hello TestDrive UI

+ + + diff --git a/test/setup.js b/test/setup.js new file mode 100644 index 0000000..ecc7b99 --- /dev/null +++ b/test/setup.js @@ -0,0 +1,12 @@ +import { JSDOM } from "jsdom"; +import { expect } from "chai"; + +const dom = new JSDOM(``, { + url: "http://localhost" +}); + +global.window = dom.window; +global.document = dom.window.document; +global.customElements = dom.window.customElements; +global.HTMLElement = dom.window.HTMLElement; +global.expect = expect; diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..eb17b1d --- /dev/null +++ b/vite.config.js @@ -0,0 +1,8 @@ +import { defineConfig } from "vite"; + +export default defineConfig({ + root: "src", + server: { + open: true + } +});