Skip to content

Commit b8e2f13

Browse files
renamed library to build
1 parent 9b32a30 commit b8e2f13

File tree

1 file changed

+372
-0
lines changed

1 file changed

+372
-0
lines changed

build/index.html

Lines changed: 372 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,372 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
8+
<title>Build : : ModComps</title>
9+
<link rel="stylesheet" href="../css/reset.css">
10+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
11+
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
12+
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/[email protected]/slick/slick.css" />
13+
<link rel="stylesheet" href="../css/style.css">
14+
</head>
15+
16+
<body>
17+
<header id="site-header">
18+
<nav class="navbar navbar-expand-lg bg-body-tertiary">
19+
<div class="container">
20+
<a class="navbar-brand" href="/">ModComps</a>
21+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
22+
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
23+
<span class="navbar-toggler-icon"></span>
24+
</button>
25+
<div class="collapse navbar-collapse" id="navbarNav">
26+
<ul class="navbar-nav">
27+
<li class="nav-item">
28+
<a class="nav-link" aria-current="page" href="/">Home</a>
29+
</li>
30+
<li class="nav-item">
31+
<a class="nav-link active" href="/build">Build</a>
32+
</li>
33+
<li class="nav-item">
34+
<a class="nav-link" href="/docs">Docs</a>
35+
</li>
36+
<li class="nav-item">
37+
<a class="nav-link" href="/contact">Contact</a>
38+
</li>
39+
</ul>
40+
</div>
41+
</div>
42+
</nav>
43+
</header>
44+
<main id="site-content">
45+
<section class="content library">
46+
<div class="row">
47+
<div class="col-2">
48+
<div id="category-list" class="list-group sticky-top">
49+
<a class="list-group-item list-group-item-action" href="#banners">Banners</a>
50+
<a class="list-group-item list-group-item-action" href="#splits">Splits</a>
51+
<a class="list-group-item list-group-item-action" href="#pods">Pods</a>
52+
<a class="list-group-item list-group-item-action" href="#strips">Strips</a>
53+
<a class="list-group-item list-group-item-action" href="#galleries">Galleries</a>
54+
<a class="list-group-item list-group-item-action" href="#carousels">Carousels</a>
55+
</div>
56+
</div>
57+
<div class="col-8 collection">
58+
<div data-bs-spy="scroll" data-bs-target="#category-list" data-bs-smooth-scroll="true"
59+
class="scrollspy-example" tabindex="0">
60+
<ul id="source-list" class="row list-unstyled">
61+
<h2 id="banners">Banners</h2>
62+
<li class="col-6 item">
63+
<img src="../images/banners.jpg" />
64+
<code>
65+
<h1>Hello, world!</h1>
66+
</code>
67+
</li>
68+
<li class="col-6 item">
69+
<img src="../images/banners.jpg" />
70+
<code>
71+
<h1>Whaddup, world!</h1>
72+
</code>
73+
</li>
74+
<li class="col-6 item">
75+
<img src="../images/banners.jpg" />
76+
<code>
77+
<h1>Sup, world!</h1>
78+
</code>
79+
</li>
80+
<li class="col-6 item">
81+
<img src="../images/banners.jpg" />
82+
<code>
83+
<h1>Asuh, world!</h1>
84+
</code>
85+
</li>
86+
<h2 id="splits">Splits</h2>
87+
<li class="col-6 item">
88+
<img src="../images/splits.jpg" />
89+
</li>
90+
<li class="col-6 item">
91+
<img src="../images/splits.jpg" />
92+
</li>
93+
<li class="col-6 item">
94+
<img src="../images/splits.jpg" />
95+
</li>
96+
<li class="col-6 item">
97+
<img src="../images/splits.jpg" />
98+
</li>
99+
<h2 id="pods">Pods</h2>
100+
<li class="col-6 item">
101+
<img src="../images/pods.jpg" />
102+
</li>
103+
<li class="col-6 item">
104+
<img src="../images/pods.jpg" />
105+
</li>
106+
<li class="col-6 item">
107+
<img src="../images/pods.jpg" />
108+
</li>
109+
<li class="col-6 item">
110+
<img src="../images/pods.jpg" />
111+
</li>
112+
<h2 id="strips">Strips</h2>
113+
<li class="col-6 item">
114+
<img src="../images/strips.jpg" />
115+
</li>
116+
<li class="col-6 item">
117+
<img src="../images/strips.jpg" />
118+
</li>
119+
<li class="col-6 item">
120+
<img src="../images/strips.jpg" />
121+
</li>
122+
<li class="col-6 item">
123+
<img src="../images/strips.jpg" />
124+
</li>
125+
<h2 id="galleries">Galleries</h2>
126+
<li class="col-6 item">
127+
<img src="../images/galleries.jpg" />
128+
</li>
129+
<li class="col-6 item">
130+
<img src="../images/galleries.jpg" />
131+
</li>
132+
<li class="col-6 item">
133+
<img src="../images/galleries.jpg" />
134+
</li>
135+
<li class="col-6 item">
136+
<img src="../images/galleries.jpg" />
137+
</li>
138+
<h2 id="carousels">Carousels</h2>
139+
<li class="col-6 item">
140+
<img src="../images/carousels.jpg" />
141+
</li>
142+
<li class="col-6 item">
143+
<img src="../images/carousels.jpg" />
144+
</li>
145+
<li class="col-6 item">
146+
<img src="../images/carousels.jpg" />
147+
</li>
148+
<li class="col-6 item">
149+
<img src="../images/carousels.jpg" />
150+
</li>
151+
</ul>
152+
</div>
153+
</div>
154+
<div class="col-2">
155+
<nav>
156+
<div class="nav nav-tabs" id="nav-tab" role="tablist">
157+
<button class="nav-link active" id="nav-mockup-tab" data-bs-toggle="tab" data-bs-target="#nav-mockup" type="button"
158+
role="tab" aria-controls="nav-mockup" aria-selected="true">Mockup</button>
159+
<button class="nav-link" id="nav-code-tab" data-bs-toggle="tab" data-bs-target="#nav-code" type="button"
160+
role="tab" aria-controls="nav-code" aria-selected="false">View Code</button>
161+
</div>
162+
</nav>
163+
<div class="tab-content" id="nav-tabContent">
164+
<div class="tab-content" id="nav-tabContent">
165+
<div class="tab-pane fade show active" id="nav-mockup" role="tabpanel" aria-labelledby="nav-mockup-tab" tabindex="0">
166+
<p class="small">Click/drag to rearrange your components.</p>
167+
168+
<button id="download-mockup-btn" class="btn btn-primary btn-sm mb-3">
169+
Download Mockup (JPG)
170+
</button>
171+
172+
<ul id="selected-list" class="list-unstyled">
173+
</ul>
174+
</div>
175+
<div class="tab-pane fade" id="nav-code" role="tabpanel" aria-labelledby="nav-code-tab" tabindex="0">
176+
<ul id="selected-code-list" class="list-unstyled">
177+
</ul>
178+
</div>
179+
</div>
180+
</div>
181+
</div>
182+
</div>
183+
</section>
184+
</main>
185+
186+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
187+
integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI"
188+
crossorigin="anonymous"></script>
189+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/html2canvas.min.js"></script>
190+
<script type="text/javascript" src="//cdn.jsdelivr.net/npm/[email protected]/slick/slick.min.js"></script>
191+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/Sortable.min.js"></script>
192+
<script>
193+
document.addEventListener('DOMContentLoaded', () => {
194+
const sourceList = document.getElementById('source-list');
195+
const selectedList = document.getElementById('selected-list');
196+
const selectedCodeList = document.getElementById('selected-code-list'); // Get the code list
197+
198+
// --- New Download Feature Logic ---
199+
const downloadBtn = document.getElementById('download-mockup-btn');
200+
// const selectedList = document.getElementById('selected-list');
201+
202+
if (downloadBtn) {
203+
downloadBtn.addEventListener('click', () => {
204+
// Check if the list has any items before attempting to download
205+
if (selectedList.children.length === 0) {
206+
alert("The Mockup list is empty. Add some components first!");
207+
return;
208+
}
209+
210+
// Options for html2canvas
211+
const options = {
212+
// Ignore the remove buttons from the final image
213+
ignoreElements: (element) => {
214+
return element.classList.contains('remove-item');
215+
},
216+
// Use a white background (important for JPEGs)
217+
backgroundColor: '#ffffff',
218+
// Enable image cross-origin access if needed (optional)
219+
useCORS: true
220+
};
221+
222+
// Convert the list content to a canvas
223+
html2canvas(selectedList, options).then(canvas => {
224+
// 1. Convert the canvas to a JPEG data URL (quality 0.9)
225+
const imageURL = canvas.toDataURL('image/jpeg', 0.9);
226+
227+
// 2. Create a temporary link element for the download
228+
const link = document.createElement('a');
229+
230+
// 3. Set the download filename and image source
231+
link.download = `mockup-${new Date().toISOString().split('T')[0]}.jpg`;
232+
link.href = imageURL;
233+
234+
// 4. Trigger the download and clean up
235+
document.body.appendChild(link);
236+
link.click();
237+
document.body.removeChild(link);
238+
});
239+
});
240+
}
241+
242+
// Initialize SortableJS on the target list to make it draggable
243+
// NOTE: SortableJS is only initialized on the Mockup list.
244+
// The code list will be updated based on the Mockup list's order.
245+
new Sortable(selectedList, {
246+
animation: 150,
247+
ghostClass: 'sortable-ghost',
248+
chosenClass: 'sortable-chosen',
249+
dragClass: 'sortable-drag',
250+
251+
// This 'onEnd' function is the key to keeping the code list mirrored
252+
onEnd: function (evt) {
253+
// Get all items in the reordered selectedList
254+
const mockupItems = Array.from(selectedList.children);
255+
256+
// Reorder the selectedCodeList to match the new order of selectedList
257+
const fragment = document.createDocumentFragment();
258+
mockupItems.forEach(mockupItem => {
259+
// Get the unique ID from the mockup item (added in the 'click' listener)
260+
const uniqueId = mockupItem.dataset.uniqueId;
261+
262+
// Find the corresponding code item using the unique ID
263+
const codeItem = selectedCodeList.querySelector(`[data-unique-id="${uniqueId}"]`);
264+
265+
if (codeItem) {
266+
fragment.appendChild(codeItem);
267+
}
268+
});
269+
selectedCodeList.appendChild(fragment);
270+
}
271+
});
272+
273+
// Variable to generate unique IDs for mirrored elements
274+
let uniqueItemId = 0;
275+
276+
// --- Add Item Logic (Mirrors to both lists) ---
277+
sourceList.addEventListener('click', (event) => {
278+
const clickedItem = event.target.closest('.item');
279+
if (!clickedItem) return;
280+
281+
// 1. Generate a unique ID for the pair of list items
282+
const currentUniqueId = uniqueItemId++;
283+
284+
// --- Mockup List Item ---
285+
const newItemMockup = clickedItem.cloneNode(true);
286+
newItemMockup.classList.remove('item-selected');
287+
// Add the unique ID to the mockup item
288+
newItemMockup.dataset.uniqueId = currentUniqueId;
289+
290+
// Add a visual indicator (like a trash icon) for easy removal
291+
const removeButton = document.createElement('span');
292+
removeButton.classList.add('remove-item', 'btn', 'btn-danger', 'btn-sm', 'ms-2');
293+
removeButton.textContent = 'X';
294+
// Append the button to a div/span within the clone that will be visible
295+
const contentContainer = document.createElement('div');
296+
contentContainer.style.display = 'flex';
297+
contentContainer.style.alignItems = 'center';
298+
contentContainer.innerHTML = newItemMockup.querySelector('img') ? newItemMockup.querySelector('img').outerHTML : '';
299+
contentContainer.appendChild(removeButton);
300+
301+
// Replace the content of the list item
302+
newItemMockup.innerHTML = '';
303+
newItemMockup.appendChild(contentContainer);
304+
305+
306+
// --- Code List Item ---
307+
const newItemCode = document.createElement('li');
308+
newItemCode.classList.add('item', 'col-12'); // Use col-12 for full width in the code tab
309+
// Add the unique ID to the code item
310+
newItemCode.dataset.uniqueId = currentUniqueId;
311+
312+
// Get the HTML code from the original item's <code> tag
313+
const codeElement = clickedItem.querySelector('code');
314+
if (codeElement) {
315+
// Create a new <code> element for the code list
316+
const newCodeBlock = document.createElement('code');
317+
newCodeBlock.textContent = codeElement.textContent.trim();
318+
newCodeBlock.style.display = 'block'; // Ensure the code block takes up space
319+
newCodeBlock.style.whiteSpace = 'pre'; // Preserve formatting
320+
newCodeBlock.style.backgroundColor = '#f4f4f4';
321+
newCodeBlock.style.padding = '5px';
322+
newCodeBlock.style.marginBottom = '10px';
323+
newItemCode.appendChild(newCodeBlock);
324+
} else {
325+
// If no <code> tag, just add a placeholder text
326+
newItemCode.textContent = clickedItem.textContent.trim();
327+
}
328+
329+
// 3. Add to both lists
330+
selectedList.appendChild(newItemMockup);
331+
selectedCodeList.appendChild(newItemCode);
332+
});
333+
334+
// --- Remove Item Logic (Mirrors to both lists) ---
335+
selectedList.addEventListener('click', (event) => {
336+
// Check if the actual remove button or the list item itself was clicked
337+
const clickedRemoveButton = event.target.closest('.remove-item');
338+
const clickedMockupItem = event.target.closest('.item');
339+
340+
// Only proceed if a remove button or an item in the *selected list* was clicked
341+
if (!clickedMockupItem || !selectedList.contains(clickedMockupItem)) return;
342+
343+
// Determine if we should remove the item
344+
let itemToRemove = null;
345+
if (clickedRemoveButton) {
346+
// If the explicit remove button was clicked, use its parent item
347+
itemToRemove = clickedRemoveButton.closest('.item');
348+
} else {
349+
// If the item itself was clicked (and no explicit button), remove it
350+
itemToRemove = clickedMockupItem;
351+
}
352+
353+
if (itemToRemove) {
354+
const uniqueIdToRemove = itemToRemove.dataset.uniqueId;
355+
356+
// 1. Remove from the Mockup list
357+
itemToRemove.remove();
358+
359+
// 2. Find and remove the corresponding item from the Code list using the unique ID
360+
const codeItemToRemove = selectedCodeList.querySelector(`[data-unique-id="${uniqueIdToRemove}"]`);
361+
if (codeItemToRemove) {
362+
codeItemToRemove.remove();
363+
}
364+
// console.log(`Removed pair with ID: ${uniqueIdToRemove}`);
365+
}
366+
});
367+
368+
});
369+
</script>
370+
</body>
371+
372+
</html>

0 commit comments

Comments
 (0)