import { html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { bind } from "@supersoniks/concorde/decorators";
import { DataProviderKey } from "@supersoniks/concorde/core/utils/dataProviderKey";
import { sub } from "@supersoniks/concorde/directives";
import {
PublisherManager,
PublisherProxy,
} from "@supersoniks/concorde/core/utils/PublisherProxy";
import { Objects } from "@supersoniks/concorde/utils";
import { tailwind } from "../tailwind";
import "./decorators-demo-init";
@customElement("demo-bind")
export class DemoBind extends LitElement {
static styles = [tailwind];
@bind("demoData.firstName")
@state()
firstName = "";
@bind("demoData.lastName")
@state()
lastName: string = "";
@bind("demoData.count")
@state()
count: number = 0;
render() {
return html`
Update Data
Title: ${this.firstName || "Not set"}
User Name: ${this.lastName || "Not set"}
Number of updates: ${this.count}
`;
}
updateData() {
const demoData = PublisherManager.get("demoData");
const demoUsers = PublisherManager.get("demoUsers");
const randomIndex = Math.floor(Math.random() * demoUsers.get().length);
const randomUser = demoUsers.get()[randomIndex];
demoData.set({
firstName: randomUser.firstName,
lastName: randomUser.lastName,
count: (demoData.count.get() || 0) + 1,
});
}
}
@customElement("demo-bind-reflect")
export class DemoBindReflect extends LitElement {
static styles = [tailwind];
@bind("bindReflectDemo.count", { reflect: true })
@state()
withReflect: number = 0;
@bind("bindReflectDemo.count")
@state()
withoutReflect: number = 0;
connectedCallback() {
super.connectedCallback();
this.resetData();
}
resetData() {
PublisherManager.get("bindReflectDemo").set({ count: 0 });
}
render() {
return html`
from publisher : ${sub("bindReflectDemo.count")}
from component with reflect : ${this.withReflect}
from component without reflect : ${this.withoutReflect}
this.withReflect++}
>Increment with reflect
this.withoutReflect++}
>Increment without reflect
Reset publisher data
`;
}
}
type BindReflectDemoData = { count: number };
const bindReflectDemoKey = new DataProviderKey("bindReflectDemo");
@customElement("demo-bind-key")
export class DemoBindKey extends LitElement {
static styles = [tailwind];
@bind(bindReflectDemoKey.count, { reflect: true })
@state()
count: number = 0;
connectedCallback() {
super.connectedCallback();
PublisherManager.get("bindReflectDemo").set({ count: 0 });
}
render() {
return html`
@bind with DataProviderKey<number> (type-safe): ${this.count}
this.count++}>Increment
`;
}
}
@customElement("demo-bind-dynamic")
export class DemoBindDynamic extends LitElement {
static styles = [tailwind];
@property({ type: String })
dataProvider: "demoUsers" | "demoUsersAlt" = "demoUsers";
@property({ type: Number })
userIndex: number = 1;
@bind("${dataProvider}.${userIndex}")
@state()
user: any = {};
updateUserIndex(e: Event) {
this.userIndex = parseInt((e.target as HTMLInputElement).value);
}
updateDataProvider(e: Event) {
this.dataProvider = (e.target as HTMLSelectElement).value as
| "demoUsers"
| "demoUsersAlt";
}
updateCurrentUserData() {
const usersPublisher = PublisherManager.get(this.dataProvider);
const userPublisher = Objects.traverse(usersPublisher, [
String(this.userIndex),
]) as PublisherProxy;
if (userPublisher) {
const randomNames = [
{ firstName: "Alice", lastName: "Wonder" },
{ firstName: "Bob", lastName: "Builder" },
{ firstName: "Charlie", lastName: "Chaplin" },
{ firstName: "Diana", lastName: "Prince" },
{ firstName: "Eve", lastName: "Adams" },
];
const randomName =
randomNames[Math.floor(Math.random() * randomNames.length)];
const randomEmail = `${randomName.firstName.toLowerCase()}.${randomName.lastName.toLowerCase()}@example.com`;
const currentUser = userPublisher.get() || {};
userPublisher.set({
...currentUser,
firstName: randomName.firstName,
lastName: randomName.lastName,
email: randomEmail,
});
}
}
render() {
return html`
First set of users
Second set of users
Update current user data
${this.user?.firstName} ${this.user?.lastName}
${this.user?.email}
`;
}
}