chains of thought

This commit is contained in:
“chrisshank” 2024-10-23 11:26:50 -07:00
parent 11018f55ed
commit dc1b389428
3 changed files with 58 additions and 55 deletions

View File

@ -3,8 +3,8 @@
{ {
"id": "1", "id": "1",
"text": "Blindfold chess requires internalizing chess structures.", "text": "Blindfold chess requires internalizing chess structures.",
"x": 398, "x": 392,
"y": 166 "y": 157
}, },
{ {
"id": "2", "id": "2",

View File

@ -24,6 +24,18 @@
width: 100%; width: 100%;
} }
button {
background: white;
border-radius: 0.25rem;
border: solid 1px black;
color: black;
&:hover {
background: black;
color: white;
}
}
spatial-connection { spatial-connection {
display: block; display: block;
position: absolute; position: absolute;
@ -42,14 +54,25 @@
} }
spatial-thought { spatial-thought {
display: block;
width: 100%;
height: 100%;
background-color: white; background-color: white;
border: solid 1px light-dark(rgb(118, 118, 118), rgb(133, 133, 133));
padding: 0.5em 0.25em;
text-align: center;
border-radius: 6px; border-radius: 6px;
border: solid 1px light-dark(rgb(118, 118, 118), rgb(133, 133, 133));
display: block;
height: 100%;
padding: 0.5em 0.25em;
position: relative;
text-align: center;
width: 100%;
> button[name='delete'] {
font-size: 2rem;
line-height: 0.6;
padding: 0;
position: absolute;
top: 0%;
left: 100%;
transform: translate(-50%, -50%);
}
} }
} }
</style> </style>

View File

@ -15,50 +15,26 @@ class SpatialThought extends HTMLElement {
customElements.define(this.tagName, this); customElements.define(this.tagName, this);
} }
#deleteButton = this.querySelector('button[name="delete"]') as HTMLButtonElement;
#text = this.querySelector('span[name="text"]') as HTMLSpanElement;
#geometry = this.parentElement as SpatialGeometry;
constructor() { constructor() {
super(); super();
this.addEventListener('pointerdown', this); this.addEventListener('click', this);
}
#textarea = this.querySelector('textarea')!;
#geometry = this.querySelector('spatial-geometry')!;
#identifier = this.getAttribute('identifier') || '';
get identifier() {
return this.#identifier;
}
set identifier(id) {
this.#identifier = id;
} }
get text() { get text() {
return this.#textarea.value; return this.#text.innerText;
}
set text(text) {
this.#textarea.value = text;
} }
get x() { handleEvent(event: PointerEvent): void {
return this.#geometry.x; if (event.type === 'click' && event.target === this.#deleteButton) {
this.#geometry.remove();
}
} }
set x(x) {
this.#geometry.x = x;
}
get y() {
return this.#geometry.y;
}
set y(y) {
this.#geometry.y = y;
}
focusTextArea() {
this.#textarea.focus();
}
handleEvent(event: PointerEvent): void {}
} }
SpatialGeometry.register(); SpatialGeometry.register();
@ -88,16 +64,19 @@ function parseHTML(html: string): Element {
return document.createRange().createContextualFragment(html).firstElementChild!; return document.createRange().createContextualFragment(html).firstElementChild!;
} }
function renderThought(thought: Thought) { function renderThought({ id, x, y, text }: Thought) {
return html`<spatial-geometry x="${thought.x}" y="${thought.y}" width="200" height="100"> return html`<spatial-geometry id="${id}" x="${x}" y="${y}" width="200" height="100">
<spatial-thought contenteditable="true" identifier="${thought.id}">${thought.text}</spatial-thought> <spatial-thought contenteditable="true">
<span name="text">${text}</span>
<button name="delete"></button>
</spatial-thought>
</spatial-geometry>`; </spatial-geometry>`;
} }
function renderConnection({ sourceId, targetId }: Connection) { function renderConnection({ sourceId, targetId }: Connection) {
return html`<spatial-connection return html`<spatial-connection
source="spatial-geometry:has(spatial-thought[identifier='${sourceId}'])" source="spatial-geometry[id='${sourceId}']"
target="spatial-geometry:has(spatial-thought[identifier='${targetId}'])" target="spatial-geometry[id='${targetId}']"
></spatial-connection>`; ></spatial-connection>`;
} }
@ -107,15 +86,15 @@ function renderChainOfThought({ thoughts, connections }: ChainOfThought) {
function parseChainOfThought(): ChainOfThought { function parseChainOfThought(): ChainOfThought {
return { return {
thoughts: Array.from(document.querySelectorAll('spatial-thought')).map((el) => ({ thoughts: Array.from(document.querySelectorAll('spatial-geometry')).map((el) => ({
id: el.identifier, id: el.id,
text: el.text, text: (el.firstElementChild as SpatialThought).text,
x: el.x, x: el.x,
y: el.y, y: el.y,
})), })),
connections: Array.from(document.querySelectorAll('spatial-connection')).map((el) => ({ connections: Array.from(document.querySelectorAll('spatial-connection')).map((el) => ({
sourceId: (el.sourceElement as SpatialThought).identifier, sourceId: (el.sourceElement as SpatialGeometry).id,
targetId: (el.targetElement as SpatialThought).identifier, targetId: (el.targetElement as SpatialGeometry).id,
})), })),
}; };
} }
@ -153,7 +132,8 @@ async function openFile(showPicker = true) {
} }
async function saveFile(promptNewFile = false) { async function saveFile(promptNewFile = false) {
fileSaver.save(JSON.stringify(parseChainOfThought(), null, 2), promptNewFile); const file = JSON.stringify(parseChainOfThought(), null, 2);
fileSaver.save(file, promptNewFile);
} }
openButton.addEventListener('click', () => { openButton.addEventListener('click', () => {