Gem
Github
import { todoData, addItem } from './store';
@customElement('app-root')
@connectStore(todoData)
export class AppRootElement extends GemElement {
#state = createState({ input: '' });
#onChange = (e: CustomEvent<string>) => {
this.#state({ input: e.detail });
};
#onSubmit = () => {
addItem(this.#state.input);
this.#state({ input: '' });
};
render = () => {
return html`
<dy-heading>待办事项列表</dy-heading>
<todo-list></todo-list>
<dy-heading lv="3">需要做什么?</dy-heading>
<dy-input-group>
<dy-input id="new-todo" @change=${this.#onChange} .value=${this.#state.input}></dy-input>
<dy-button style="flex-grow: 3" @click=${this.#onSubmit}>添加 #${todoData.items.length + 1}</dy-button>
</dy-input-group>
`;
};
}import { icons } from 'duoyun-ui/lib/icons';
import { todoData, deleteItem } from './store';
const styles = css`
li:not(:hover) dy-use {
opacity: 0;
}
`;
@customElement('todo-list')
@connectStore(todoData)
@adoptedStyle(styles)
export class TodoListElement extends GemElement {
render = () => {
return html`
<ul class="p-0">
${todoData.items.map(
(item) => html`
<li class="flex items-center justify-between py-1 border-t border-gray-300 last:border-b">
<span>${item}</span>
<dy-use class="w-5 p-1 hover:bg-gray-200" .element=${icons.close} @click=${() => deleteItem(item)}></dy-use>
</li>
`,
)}
</ul>
`;
};
}type Store = { items: string[] };
export const todoData = createStore<Store>({ items: [] });
export const addItem = (item: string) => {
todoData({ items: [...todoData.items, item] });
};
export const deleteItem = (item: string) => {
todoData({ items: todoData.items.filter((e) => e !== item) });
}; 在 Github 编辑此页上次更新:2025/06/09 15:30:31
通过 GemBook 生成CONTENTS