first draft but not working yet
This commit is contained in:
commit
b54c89c9c4
10 changed files with 380 additions and 0 deletions
111
components/page-items.js
Normal file
111
components/page-items.js
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
// components/page-items.js
|
||||
import { LitElement, html, css } from 'lit'
|
||||
import { store } from '../store/index.js'
|
||||
import { StoreController } from '../controllers/store.js'
|
||||
|
||||
class PageItems extends LitElement {
|
||||
#items = new StoreController(this, store, s => s.items)
|
||||
|
||||
static properties = {
|
||||
_draft: { type: String, state: true }
|
||||
}
|
||||
|
||||
_draft = ''
|
||||
|
||||
static styles = css`
|
||||
:host { display: block; padding: 2rem 1.5rem; }
|
||||
h1 { font-size: 1.5rem; margin: 0 0 1.5rem; }
|
||||
.add-form {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
input {
|
||||
flex: 1;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 6px;
|
||||
font-size: 0.9rem;
|
||||
outline: none;
|
||||
}
|
||||
input:focus { border-color: #94a3b8; }
|
||||
button {
|
||||
padding: 0.5rem 1rem;
|
||||
background: #0f172a;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
button:hover { background: #1e293b; }
|
||||
ul { list-style: none; padding: 0; margin: 0; }
|
||||
li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.75rem 0;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.remove {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #cbd5e1;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
padding: 0;
|
||||
}
|
||||
.remove:hover { color: #ef4444; }
|
||||
.empty { color: #94a3b8; font-size: 0.9rem; }
|
||||
`
|
||||
|
||||
#add() {
|
||||
const name = this._draft.trim()
|
||||
if (!name) return
|
||||
store.getState().addItem({ id: crypto.randomUUID(), name })
|
||||
this._draft = ''
|
||||
}
|
||||
|
||||
#remove(id) {
|
||||
store.getState().removeItem(id)
|
||||
}
|
||||
|
||||
#onKeydown(e) {
|
||||
if (e.key === 'Enter') this.#add()
|
||||
}
|
||||
|
||||
render() {
|
||||
const items = this.#items.value
|
||||
|
||||
return html`
|
||||
<h1>Items</h1>
|
||||
|
||||
<div class="add-form">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="New item…"
|
||||
.value=${this._draft}
|
||||
@input=${e => this._draft = e.target.value}
|
||||
@keydown=${this.#onKeydown}
|
||||
/>
|
||||
<button @click=${this.#add}>Add</button>
|
||||
</div>
|
||||
|
||||
${items.length === 0
|
||||
? html`<p class="empty">No items yet.</p>`
|
||||
: html`
|
||||
<ul>
|
||||
${items.map(item => html`
|
||||
<li>
|
||||
<span>${item.name}</span>
|
||||
<button class="remove" @click=${() => this.#remove(item.id)}>✕</button>
|
||||
</li>
|
||||
`)}
|
||||
</ul>
|
||||
`}
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('page-items', PageItems)
|
||||
Loading…
Add table
Add a link
Reference in a new issue