Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 49 additions & 41 deletions typescript/packages/common-ui/src/components/common-input.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import { LitElement, html, css } from "lit";
import { customElement, property } from "lit/decorators.js";
import { baseStyles } from "./style.js";
import { view } from "../hyperscript/render.js";
import { eventProps } from "../hyperscript/schema-helpers.js";

export const commonInput = view("common-input", {
...eventProps(),
value: { type: "string" },
placeholder: { type: "string" },
appearance: { type: "string" },
});

export type CommonInput = {
id: string;
value: string;
}
};

export class CommonInputEvent extends Event {
detail: CommonInput;
Expand All @@ -21,35 +30,35 @@ export class CommonInputElement extends LitElement {
static override styles = [
baseStyles,
css`
:host {
display: block;
--height: 24px;
}

.input-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
}
:host {
display: block;
--height: 24px;
}

.input {
appearance: none;
border: 0;
outline: 0;
box-sizing: border-box;
font-size: var(--body-size);
width: 100%;
height: var(--height);
}
.input-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
}

:host([appearance="rounded"]) .input {
--height: 40px;
background-color: var(--input-background);
border-radius: calc(var(--height) / 2);
padding: 8px 16px;
height: var(--height);
}
`
.input {
appearance: none;
border: 0;
outline: 0;
box-sizing: border-box;
font-size: var(--body-size);
width: 100%;
height: var(--height);
}

:host([appearance="rounded"]) .input {
--height: 40px;
background-color: var(--input-background);
border-radius: calc(var(--height) / 2);
padding: 8px 16px;
height: var(--height);
}
`,
];

@property({ type: String }) value = "";
Expand All @@ -61,20 +70,19 @@ export class CommonInputElement extends LitElement {
const value = (event.target as HTMLInputElement).value;
this.value = value;

this.dispatchEvent(
new CommonInputEvent({ id: this.id, value })
);
}
this.dispatchEvent(new CommonInputEvent({ id: this.id, value }));
};

return html`
<div class="input-wrapper">
<input
class="input"
@input="${oninput}"
.value="${this.value}"
.placeholder="${this.placeholder}"
type="text" />
</div>
<div class="input-wrapper">
<input
class="input"
@input="${oninput}"
.value="${this.value}"
.placeholder="${this.placeholder}"
type="text"
/>
</div>
`;
}
}
}
2 changes: 1 addition & 1 deletion typescript/packages/common-ui/src/components/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ export const fileInput = (props: Props) => input({ ...props, type: "file" });
export const imageInput = (props: Props) => input({ ...props, type: "image" });
export const password = (props: Props) => input({ ...props, type: "password" });
export const searchInput = (props: Props) =>
input({ ...props, type: "search" });
input({ ...props, type: "search" });
1 change: 1 addition & 0 deletions typescript/packages/common-ui/src/hyperscript/tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export { navpanel } from "../components/common-navpanel.js";
export { record } from "../components/common-record.js";
export { dict } from "../components/common-dict.js";
export { datatable } from "../components/common-datatable.js";
export { commonInput } from "../components/common-input.js";
export { list } from "../components/common-list.js";
export { suggestions } from "../components/common-suggestions.js";
export { unibox } from "../components/common-unibox.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { LitElement, html, css } from "lit";
import { customElement, property } from "lit/decorators.js";
import { render } from "@commontools/common-ui";
import { signal, Cancel } from "@commontools/common-frp";
import { Gem, ID, NAME } from "../recipe.js";

export const sagaLink = render.view("common-saga-link", {
saga: { type: "object" },
name: { tyoe: "string" },
name: { type: "string" },
});

@customElement("common-saga-link")
Expand All @@ -26,6 +27,9 @@ export class CommonSagaLink extends LitElement {
@property({ type: String })
name: string | undefined = undefined;

private nameEffect: Cancel | undefined;
private nameFromGem: string | undefined;

handleClick(e: Event) {
e.preventDefault();
this.dispatchEvent(
Expand All @@ -37,13 +41,41 @@ export class CommonSagaLink extends LitElement {
);
}

override connectedCallback() {
super.connectedCallback();
this.maybeListenToName();
}

override disconnectedCallback() {
super.disconnectedCallback();
this.nameEffect?.();
}

override updated(changedProperties: Map<string | number | symbol, unknown>) {
super.updated(changedProperties);
if (changedProperties.has("saga")) {
this.maybeListenToName(true);
}
}

private maybeListenToName(skipUpdate = false) {
if (signal.isSignal(this.saga?.[NAME])) {
this.nameEffect = signal.effect([this.saga[NAME]], (name: string) => {
this.nameFromGem = name;
if (!skipUpdate) this.requestUpdate();
skipUpdate = false;
});
} else {
this.nameEffect?.();
this.nameFromGem = this.saga?.[NAME];
}
}

override render() {
console.log("rendering saga link", this.saga, this.name);
if (!this.saga) return html``;
const name = this.name ?? this.nameFromGem;
return html`
<a href="#${this.saga[ID]}" @click="${this.handleClick}">
${this.name ?? this.saga[NAME]}
</a>
<a href="#${this.saga[ID]}" @click="${this.handleClick}">🔮 ${name}</a>
`;
}
}
34 changes: 15 additions & 19 deletions typescript/packages/lookslike-high-level/src/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,37 @@ const { state } = signal;

import { todoList, todoTask } from "./recipes/todo-list.js";
import "./recipes/todo-list-as-task.js"; // Necessary, so that suggestions are indexed.
import { sagaList } from "./recipes/saga-list.js";

export const keywords: { [key: string]: string[] } = {
groceries: ["grocery list"],
};

export const dataGems = state<{ [key: string]: Gem }>({});

export function addGems(gems: { [key: string]: Gem }) {
Object.entries(gems).forEach(([name, gem]) => (gem[NAME] = name));
dataGems.send({ ...dataGems.get(), ...gems });
}
export const dataGems = state<Gem[]>([]);

export function getGemByName(name: string): Gem | undefined {
return dataGems.get()[name];
export function addGems(gems: Gem[]) {
dataGems.send([...dataGems.get(), ...gems]);
}

const recipes: { [name: string]: Gem } = {
"todo list": todoList({
addGems([
todoList({
title: "My TODOs",
items: ["Buy groceries", "Walk the dog", "Wash the car"].map((item) =>
todoTask({
title: item,
done: false,
})
),
}),
"grocery list": todoList({
todoList({
title: "My grocery shopping list",
items: ["milk", "eggs", "bread"].map((item) =>
todoTask({
title: item,
done: false,
})
),
}),
home: sagaList({ sagas: dataGems }),
};
]);

addGems(recipes);
export const recipes = {
"Create a new TODO list": {
recipe: todoList,
inputs: { title: "", items: [] },
},
};
6 changes: 3 additions & 3 deletions typescript/packages/lookslike-high-level/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export { components } from "@commontools/common-ui";
import { CommonWindowManager } from "./components/window-manager.js";
export { components as myComponents } from "./components.js";
import { getGemByName } from "./data.js";
import { dataGems } from "./data.js";
import { home } from "./recipes/home.js";

document.addEventListener("DOMContentLoaded", () => {
const windowManager = document.getElementById(
"window-manager"
)! as CommonWindowManager;
console.log(getGemByName("home"));
windowManager.openSaga(getGemByName("home")!);
windowManager.openSaga(home({ sagas: dataGems }));
});
13 changes: 6 additions & 7 deletions typescript/packages/lookslike-high-level/src/recipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export type Recipe = (inputs: RecipeInputs) => Gem;
let id = 0;

export const recipe = (
name: string,
type: string,
impl: (inputs: Bindings) => Bindings
): Recipe => {
return (inputs: Bindings) => {
Expand All @@ -45,7 +45,7 @@ export const recipe = (
])
);
const outputs = impl(inputsAsSignals);
return { [ID]: id++, [TYPE]: name, ...outputs };
return { [ID]: id++, [TYPE]: type, ...outputs };
};
};

Expand All @@ -63,12 +63,11 @@ export type Suggestion = {
dataGems: { [key: string]: string };
};

export const suggestions = signal.state<Suggestion[]>([]);
export const suggestions: Suggestion[] = [];
export function addSuggestion(suggestion: Suggestion) {
suggestions.push(suggestion);
}

export function description(strings: TemplateStringsArray, ...values: any[]) {
return strings.map((string, i) => [string, values[i]]).flat();
}

export function addSuggestion(suggestion: Suggestion) {
setTimeout(() => suggestions.send([...suggestions.get(), suggestion]));
}
Loading