Skip to content

Commit 5122aca

Browse files
committed
Replaced test-integration.html with client/example_app
1 parent 5f295c0 commit 5122aca

File tree

6 files changed

+544
-163
lines changed

6 files changed

+544
-163
lines changed

client/example-app/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Example App
2+
3+
This directory contains an example application that demonstrates how to use the Bespoke Simulation template and its design system components. The example app showcases a simple interactive counter application that uses buttons, inputs, dropdowns, tags, and other design system components to illustrate the template's features and usage patterns. Accessible via the development server at `http://localhost:3000/example-app/index.html`.
4+
5+
**Important:** This example app is included for reference and testing purposes only. When customizing this template for your own application, you should remove this entire `example-app` directory and replace it with your own application code:
6+
7+
```bash
8+
rm -rf client/example-app
9+
```
10+

client/example-app/example-app.css

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/* Example App Styles - Interactive Component Showcase */
2+
3+
.bespoke .sidebar {
4+
padding: var(--UI-Spacing-spacing-xl);
5+
overflow-y: auto;
6+
}
7+
8+
.bespoke .sidebar-section {
9+
display: flex;
10+
flex-direction: column;
11+
gap: var(--UI-Spacing-spacing-xl);
12+
}
13+
14+
.bespoke .sidebar-section h2 {
15+
font-size: var(--Fonts-Headlines-sm);
16+
font-weight: 600;
17+
color: var(--Colors-Text-Body-Strongest);
18+
margin: 0 0 var(--UI-Spacing-spacing-ml) 0;
19+
}
20+
21+
.bespoke .control-group {
22+
display: flex;
23+
flex-direction: column;
24+
gap: var(--UI-Spacing-spacing-s);
25+
}
26+
27+
.bespoke .control-group label {
28+
font-size: var(--Fonts-Body-Default-sm);
29+
font-weight: 500;
30+
color: var(--Colors-Text-Body-Strong);
31+
}
32+
33+
.bespoke .control-group .button {
34+
width: 100%;
35+
}
36+
37+
.bespoke .control-group-buttons {
38+
flex-direction: row;
39+
gap: var(--UI-Spacing-spacing-s);
40+
}
41+
42+
.bespoke .control-group-buttons .button {
43+
flex: 1;
44+
}
45+
46+
.bespoke .content-area {
47+
overflow-y: auto;
48+
padding: var(--UI-Spacing-spacing-xl);
49+
}
50+
51+
.bespoke .display-container {
52+
max-width: 800px;
53+
margin: 0 auto;
54+
display: flex;
55+
flex-direction: column;
56+
gap: var(--UI-Spacing-spacing-xl);
57+
}
58+
59+
.bespoke .counter-display {
60+
flex-direction: column;
61+
align-items: center;
62+
justify-content: center;
63+
padding: var(--UI-Spacing-spacing-2xl);
64+
text-align: center;
65+
}
66+
67+
.bespoke .counter-display h2 {
68+
font-size: var(--Fonts-Headlines-sm);
69+
font-weight: 600;
70+
color: var(--Colors-Text-Body-Strong);
71+
margin: 0 0 var(--UI-Spacing-spacing-ml) 0;
72+
text-align: center;
73+
}
74+
75+
.bespoke .counter-value {
76+
font-size: 4rem;
77+
font-weight: 700;
78+
font-family: var(--heading-family);
79+
color: var(--Colors-Text-Body-Strongest);
80+
line-height: 1;
81+
text-align: center;
82+
}
83+
84+
.bespoke .tags-container {
85+
display: flex;
86+
gap: var(--UI-Spacing-spacing-ml);
87+
justify-content: center;
88+
flex-wrap: wrap;
89+
}
90+
91+
.bespoke .settings-display {
92+
flex-direction: column;
93+
align-items: flex-start;
94+
justify-content: flex-start;
95+
padding: var(--UI-Spacing-spacing-xl);
96+
}
97+
98+
.bespoke .settings-display h3 {
99+
font-size: var(--Fonts-Headlines-xs);
100+
font-weight: 600;
101+
color: var(--Colors-Text-Body-Strong);
102+
margin: 0 0 var(--UI-Spacing-spacing-ml) 0;
103+
width: 100%;
104+
}
105+
106+
.bespoke .setting-item {
107+
font-size: var(--Fonts-Body-Default-sm);
108+
color: var(--Colors-Text-Body-Default);
109+
margin-bottom: var(--UI-Spacing-spacing-s);
110+
width: 100%;
111+
}
112+
113+
.bespoke .setting-item:last-child {
114+
margin-bottom: 0;
115+
}
116+
117+
.bespoke .setting-item strong {
118+
color: var(--Colors-Text-Body-Strong);
119+
margin-right: var(--UI-Spacing-spacing-xs);
120+
}

client/example-app/example-app.js

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
// example-app.js
2+
// Interactive Component Showcase Application
3+
4+
(function() {
5+
const status = document.getElementById('status');
6+
7+
// App state
8+
let counterValue = 0;
9+
let incrementAmount = 1;
10+
let counterLabel = 'Counter';
11+
let dropdownInstance = null;
12+
13+
function setStatus(msg) {
14+
if (status) {
15+
status.textContent = msg;
16+
}
17+
}
18+
19+
// Update counter display
20+
function updateCounterDisplay() {
21+
const counterDisplay = document.getElementById('counter-value');
22+
const labelDisplay = document.getElementById('display-label');
23+
const labelValueDisplay = document.getElementById('display-label-value');
24+
const incrementValueDisplay = document.getElementById('display-increment-value');
25+
26+
if (counterDisplay) {
27+
counterDisplay.textContent = counterValue;
28+
}
29+
30+
if (labelDisplay) {
31+
labelDisplay.textContent = counterLabel;
32+
}
33+
34+
if (labelValueDisplay) {
35+
labelValueDisplay.textContent = counterLabel;
36+
}
37+
38+
if (incrementValueDisplay) {
39+
incrementValueDisplay.textContent = incrementAmount;
40+
}
41+
42+
// Update status tags
43+
updateStatusTags();
44+
}
45+
46+
// Update status tags based on counter value
47+
function updateStatusTags() {
48+
const primaryTag = document.getElementById('status-tag-primary');
49+
const positiveTag = document.getElementById('status-tag-positive');
50+
const negativeTag = document.getElementById('status-tag-negative');
51+
52+
if (counterValue > 0) {
53+
if (primaryTag) primaryTag.style.display = 'none';
54+
if (positiveTag) positiveTag.style.display = 'inline-block';
55+
if (negativeTag) negativeTag.style.display = 'none';
56+
} else if (counterValue < 0) {
57+
if (primaryTag) primaryTag.style.display = 'none';
58+
if (positiveTag) positiveTag.style.display = 'none';
59+
if (negativeTag) negativeTag.style.display = 'inline-block';
60+
} else {
61+
if (primaryTag) primaryTag.style.display = 'inline-block';
62+
if (positiveTag) positiveTag.style.display = 'none';
63+
if (negativeTag) negativeTag.style.display = 'none';
64+
}
65+
}
66+
67+
// Increment counter
68+
function incrementCounter() {
69+
counterValue += incrementAmount;
70+
updateCounterDisplay();
71+
setStatus('Counter incremented');
72+
}
73+
74+
// Decrement counter
75+
function decrementCounter() {
76+
counterValue -= incrementAmount;
77+
updateCounterDisplay();
78+
setStatus('Counter decremented');
79+
}
80+
81+
// Reset counter
82+
function resetCounter() {
83+
counterValue = 0;
84+
updateCounterDisplay();
85+
setStatus('Counter reset');
86+
}
87+
88+
// Initialize dropdown component
89+
function initializeDropdown() {
90+
if (typeof window.Dropdown === 'undefined') {
91+
console.error('Dropdown class not found. Make sure dropdown.js is loaded.');
92+
return;
93+
}
94+
95+
const dropdownItems = [
96+
{ value: '1', label: '1' },
97+
{ value: '5', label: '5' },
98+
{ value: '10', label: '10' },
99+
{ value: '25', label: '25' }
100+
];
101+
102+
try {
103+
dropdownInstance = new window.Dropdown('#increment-dropdown', {
104+
items: dropdownItems,
105+
selectedValue: '1',
106+
placeholder: 'Select increment amount',
107+
onSelect: (value) => {
108+
incrementAmount = parseInt(value, 10);
109+
updateCounterDisplay();
110+
setStatus(`Increment amount set to ${incrementAmount}`);
111+
}
112+
});
113+
} catch (error) {
114+
console.error('Error initializing dropdown:', error);
115+
}
116+
}
117+
118+
// Initialize event listeners
119+
function initializeEventListeners() {
120+
// Sidebar controls
121+
const btnIncrement = document.getElementById('btn-increment');
122+
const btnDecrement = document.getElementById('btn-decrement');
123+
const btnReset = document.getElementById('btn-reset');
124+
const counterLabelInput = document.getElementById('counter-label');
125+
126+
// Increment button
127+
if (btnIncrement) {
128+
btnIncrement.addEventListener('click', incrementCounter);
129+
}
130+
131+
// Decrement button
132+
if (btnDecrement) {
133+
btnDecrement.addEventListener('click', decrementCounter);
134+
}
135+
136+
// Reset button
137+
if (btnReset) {
138+
btnReset.addEventListener('click', resetCounter);
139+
}
140+
141+
// Label input
142+
if (counterLabelInput) {
143+
counterLabelInput.addEventListener('input', (e) => {
144+
counterLabel = e.target.value || 'Counter';
145+
updateCounterDisplay();
146+
setStatus('Label updated');
147+
});
148+
}
149+
}
150+
151+
// Initialize help modal
152+
async function initializeHelpModal() {
153+
try {
154+
const response = await fetch('./help-content.html');
155+
const helpContent = await response.text();
156+
157+
if (typeof HelpModal !== 'undefined') {
158+
HelpModal.init({
159+
triggerSelector: '#btn-help',
160+
content: helpContent,
161+
theme: 'auto'
162+
});
163+
} else {
164+
console.error('HelpModal not found. Make sure help-modal.js is loaded.');
165+
}
166+
} catch (error) {
167+
console.error('Failed to load help content:', error);
168+
if (typeof HelpModal !== 'undefined') {
169+
HelpModal.init({
170+
triggerSelector: '#btn-help',
171+
content: '<p>Help content could not be loaded. Please check that help-content.html exists.</p>',
172+
theme: 'auto'
173+
});
174+
}
175+
}
176+
}
177+
178+
// Initialize everything when DOM is ready
179+
function initialize() {
180+
setStatus('Loading...');
181+
182+
// Initialize event listeners
183+
initializeEventListeners();
184+
185+
// Initialize help modal
186+
initializeHelpModal();
187+
188+
// Initialize dropdown after a short delay to ensure Dropdown class is loaded
189+
setTimeout(() => {
190+
initializeDropdown();
191+
updateCounterDisplay();
192+
setStatus('Ready');
193+
}, 100);
194+
}
195+
196+
if (document.readyState === 'loading') {
197+
document.addEventListener('DOMContentLoaded', initialize);
198+
} else {
199+
initialize();
200+
}
201+
})();

0 commit comments

Comments
 (0)