Skip to content

Commit 9c0a077

Browse files
committed
bedtime UI
1 parent 134fa71 commit 9c0a077

File tree

21 files changed

+866
-22
lines changed

21 files changed

+866
-22
lines changed

examples/bedtime-story-teller/assets/app.js

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,132 @@ function initSocketIO() {
2121
});
2222
}
2323

24+
function setupChipSelection(container) {
25+
const chips = container.querySelectorAll('.chip');
26+
const selectedValue = container.querySelector('.selected-value');
27+
28+
chips.forEach(chip => {
29+
chip.addEventListener('click', (event) => {
30+
event.stopPropagation(); // Prevent the container from toggling
31+
32+
// Remove selected class from all chips in this container
33+
chips.forEach(c => c.classList.remove('selected'));
34+
35+
// Add selected class to the clicked chip
36+
chip.classList.add('selected');
37+
38+
// Update the selected value display
39+
if (selectedValue) {
40+
selectedValue.textContent = chip.textContent;
41+
selectedValue.style.display = 'inline-block';
42+
}
43+
});
44+
});
45+
}
46+
47+
function setupStoryTypeSelection(container) {
48+
const paragraphs = container.querySelectorAll('.story-type-paragraph');
49+
const optionalText = container.querySelector('.optional-text');
50+
51+
paragraphs.forEach(paragraph => {
52+
const chips = paragraph.querySelectorAll('.chip');
53+
chips.forEach(chip => {
54+
chip.addEventListener('click', (event) => {
55+
event.stopPropagation();
56+
57+
// Single selection within the paragraph
58+
chips.forEach(c => c.classList.remove('selected'));
59+
chip.classList.add('selected');
60+
61+
updateStoryTypeHeader(container);
62+
});
63+
});
64+
});
65+
}
66+
67+
function updateStoryTypeHeader(container) {
68+
const optionalText = container.querySelector('.optional-text');
69+
const selectedChips = container.querySelectorAll('.chip.selected');
70+
const content = container.querySelector('.parameter-content');
71+
const isOpen = content.style.display === 'block';
72+
73+
if (selectedChips.length === 0) {
74+
optionalText.textContent = '(optional)';
75+
return;
76+
}
77+
78+
if (isOpen) {
79+
optionalText.textContent = Array.from(selectedChips).map(c => c.textContent).join(', ');
80+
} else {
81+
const firstTwo = Array.from(selectedChips).slice(0, 2).map(c => c.textContent).join(', ');
82+
const remaining = selectedChips.length - 2;
83+
if (remaining > 0) {
84+
optionalText.innerHTML = `${firstTwo} <span class="plus-x">+${remaining}</span>`;
85+
} else {
86+
optionalText.textContent = firstTwo;
87+
}
88+
}
89+
}
90+
2491
// Start the application
2592
document.addEventListener('DOMContentLoaded', () => {
2693
initSocketIO();
94+
95+
const parameterContainers = document.querySelectorAll('.parameter-container');
96+
97+
parameterContainers.forEach(container => {
98+
const title = container.querySelector('.parameter-title').textContent;
99+
100+
container.addEventListener('click', () => {
101+
const content = container.querySelector('.parameter-content');
102+
const arrow = container.querySelector('.arrow-icon');
103+
104+
arrow.classList.toggle('rotated');
105+
if (content.style.display === 'block') {
106+
content.style.display = 'none';
107+
} else {
108+
content.style.display = 'block';
109+
}
110+
111+
if (title === 'Story type') {
112+
updateStoryTypeHeader(container);
113+
} else if (title === 'Other') {
114+
const textarea = container.querySelector('.other-textarea');
115+
const charCounter = container.querySelector('.char-counter');
116+
const generateButton = document.querySelector('.generate-story-button');
117+
const maxLength = textarea.maxLength;
118+
119+
textarea.addEventListener('input', () => {
120+
const currentLength = textarea.value.length;
121+
charCounter.textContent = `${currentLength} / ${maxLength}`;
122+
});
123+
124+
// Toggle button visibility based on container content display
125+
if (content.style.display === 'block') {
126+
generateButton.style.display = 'flex';
127+
} else {
128+
generateButton.style.display = 'none';
129+
}
130+
} else {
131+
setupChipSelection(container);
132+
}
133+
});
134+
135+
if (title === 'Story type') {
136+
setupStoryTypeSelection(container);
137+
} else if (title === 'Other') {
138+
// Initial state for the button when the page loads
139+
const generateButton = document.querySelector('.generate-story-button');
140+
const content = container.querySelector('.parameter-content');
141+
if (content.style.display === 'block') {
142+
generateButton.style.display = 'flex';
143+
} else {
144+
generateButton.style.display = 'none';
145+
}
146+
} else {
147+
setupChipSelection(container);
148+
}
149+
});
27150
});
28151

29152
function generateStory(msg) {
Lines changed: 20 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 18 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)