feat: add compact view mode and integrate CardTiny component for logo display

This commit is contained in:
sHa
2025-05-29 01:36:07 +03:00
parent d8c2c02dac
commit 5a5202eb80
6 changed files with 326 additions and 104 deletions

View File

@@ -100,6 +100,7 @@
setSearchQuery,
setGridView,
setListView,
setCompactView,
setTheme,
toggleDropdown,
addTag,
@@ -197,13 +198,11 @@
const searchParam = params.get("search");
if (searchParam) {
searchQuery = searchParam;
}
// Restore view mode and compact mode from localStorage
const savedViewMode = localStorage.getItem("viewMode");
if (savedViewMode === "grid" || savedViewMode === "list") {
viewMode = savedViewMode;
}
} // Restore view mode and compact mode from localStorage
const savedViewMode = localStorage.getItem("viewMode");
if (savedViewMode === "grid" || savedViewMode === "list" || savedViewMode === "compact") {
viewMode = savedViewMode;
}
const savedCompact = localStorage.getItem("compactMode");
if (savedCompact === "true" || savedCompact === "false") {
setCompactMode(savedCompact === "true");
@@ -277,6 +276,7 @@
setSearchQuery,
setGridView,
setListView,
setCompactView,
setTheme: (newTheme) => {
console.log("window.appData.setTheme called with:", newTheme);
setTheme(newTheme);
@@ -325,6 +325,18 @@
}
}
function setCompactView() {
console.log("Setting view mode to: compact");
viewMode = "compact";
localStorage.setItem("viewMode", "compact");
// Update window.appData immediately on view change
if (typeof window !== "undefined" && window.appData) {
window.appData.viewMode = "compact";
console.log("App: Updated viewMode in window.appData to compact");
}
}
function copyUrl(logoPath) {
const url = `${window.location.origin}/${logoPath}`;
// Try modern clipboard API first

View File

@@ -0,0 +1,108 @@
<script>
import InlineSvg from './InlineSvg.svelte';
import { getDefaultLogoColor } from '../utils/colorTheme.js';
export let logo;
export let theme;
function openPreview(logo) {
// Navigate to preview page using router
const routerPath = `/preview/${encodeURIComponent(logo.name.replace(/\s+/g, '-').toLowerCase())}`;
window.location.hash = routerPath;
}
function handleClick() {
console.log('CardTiny: Logo clicked, calling openPreview');
openPreview(logo);
}
function handleKeydown(event) {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
handleClick();
}
}
function isSvgLogo(logo) {
return logo && logo.format && logo.format.toLowerCase() === 'svg';
}
$: getLogoThemeColor = (logo) => getDefaultLogoColor(logo.colors, theme);
</script>
<div
class="card-tiny"
on:click={handleClick}
on:keydown={handleKeydown}
role="button"
tabindex="0"
aria-label={`View ${logo.name} logo`}
>
<div class="image-container">
{#if isSvgLogo(logo)}
<InlineSvg
path={logo.path}
color={logo.colors ? (logo._activeColor || getLogoThemeColor(logo)) : undefined}
colorConfig={logo.colors ? logo.colorConfig : undefined}
targets={logo.targets}
sets={logo.sets}
colors={logo.colors}
activeSet={logo._activeSet}
alt={logo.name}
/>
{:else}
<img src={logo.path} alt={logo.name} />
{/if}
</div>
<div class="name">{logo.name}</div>
</div>
<style>
.card-tiny {
width: 200px;
height: 200px;
background: var(--color-card);
border: 1px solid var(--color-border);
border-radius: 8px;
padding: 12px;
cursor: pointer;
transition: background 0.2s, color 0.2s, transform 0.2s, box-shadow 0.2s;
display: flex;
flex-direction: column;
gap: 8px;
}
.card-tiny:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.card-tiny:focus {
outline: 2px solid var(--color-accent);
outline-offset: 2px;
}
.image-container {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.image-container img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.name {
font-weight: 500;
color: var(--color-text);
text-align: center;
font-size: 0.875rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>

View File

@@ -8,6 +8,7 @@
export let viewMode;
export let setGridView;
export let setListView;
export let setCompactView;
export let searchQuery;
export let setSearchQuery;
export let allTags = [];
@@ -275,52 +276,89 @@
/>
</svg>
</button>
<button
class:active={viewMode === "grid"}
on:click={setGridView}
aria-label="Grid view"
>
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
><rect x="3" y="3" width="6" height="6" fill="currentColor" /><rect
x="11"
y="3"
width="6"
height="6"
fill="currentColor"
/><rect x="3" y="11" width="6" height="6" fill="currentColor" /><rect
x="11"
y="11"
width="6"
height="6"
fill="currentColor"
/></svg
<div class="view-mode-group">
<button
class:active={viewMode === "compact"}
on:click={setCompactView}
aria-label="Compact view"
>
</button>
<button
class:active={viewMode === "list"}
on:click={setListView}
aria-label="List view"
>
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
><rect x="4" y="5" width="12" height="2" fill="currentColor" /><rect
x="4"
y="9"
width="12"
height="2"
fill="currentColor"
/><rect x="4" y="13" width="12" height="2" fill="currentColor" /></svg
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect x="2" y="2" width="4" height="4" fill="currentColor" />
<rect x="8" y="2" width="4" height="4" fill="currentColor" />
<rect x="14" y="2" width="4" height="4" fill="currentColor" />
<rect x="2" y="8" width="4" height="4" fill="currentColor" />
<rect x="8" y="8" width="4" height="4" fill="currentColor" />
<rect x="14" y="8" width="4" height="4" fill="currentColor" />
<rect x="2" y="14" width="4" height="4" fill="currentColor" />
<rect x="8" y="14" width="4" height="4" fill="currentColor" />
<rect x="14" y="14" width="4" height="4" fill="currentColor" />
</svg>
</button>
<button
class:active={viewMode === "grid"}
on:click={setGridView}
aria-label="Grid view"
>
</button>
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
><rect x="3" y="3" width="6" height="6" fill="currentColor" /><rect
x="11"
y="3"
width="6"
height="6"
fill="currentColor"
/><rect
x="3"
y="11"
width="6"
height="6"
fill="currentColor"
/><rect
x="11"
y="11"
width="6"
height="6"
fill="currentColor"
/></svg
>
</button>
<button
class:active={viewMode === "list"}
on:click={setListView}
aria-label="List view"
>
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
><rect x="4" y="5" width="12" height="2" fill="currentColor" /><rect
x="4"
y="9"
width="12"
height="2"
fill="currentColor"
/><rect
x="4"
y="13"
width="12"
height="2"
fill="currentColor"
/></svg
>
</button>
</div>
</div>
</div>
</header>
@@ -410,6 +448,58 @@
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.theme-switcher {
display: flex;
align-items: center;
gap: 0.2rem;
margin-left: auto;
}
.theme-switch-group {
display: flex;
border-radius: 6px;
overflow: hidden;
border: 1px solid var(--color-border);
background: var(--color-card);
}
.theme-switch-group button {
background: none;
border: none;
color: var(--color-text);
padding: 0.2em 0.7em;
font-size: 1.1rem;
border-radius: 0;
transition:
background 0.2s,
color 0.2s;
display: flex;
align-items: center;
justify-content: center;
}
.theme-switch-group button:first-child {
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}
.theme-switch-group button:last-child {
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
.theme-switch-group button.active,
.theme-switch-group button:focus {
background: var(--color-accent);
color: var(--white);
font-weight: bold;
}
.theme-switch-group button:hover {
background: var(--color-accent);
color: var(--color-accent-text);
}
.compact-switch-btn {
background: none;
border: none;
@@ -430,4 +520,37 @@
background: var(--color-accent, #4f8cff);
color: #fff;
}
.view-mode-group {
display: inline-flex;
border: 1px solid var(--color-border);
border-radius: 8px;
overflow: hidden;
background: var(--color-background);
}
.view-mode-group button {
background: none;
border: none;
color: var(--color-text);
cursor: pointer;
padding: 0.5em 0.7em;
transition:
background 0.2s,
color 0.2s;
display: flex;
align-items: center;
justify-content: center;
border-right: 1px solid var(--color-border);
border-radius: 0;
}
.view-mode-group button:hover {
background: var(--color-card);
}
.view-mode-group button.active {
background: var(--color-accent, #4f8cff);
color: #fff;
}
</style>

View File

@@ -1,6 +1,7 @@
<script>
import CardSmall from './CardSmall.svelte';
import CardMiddle from './CardMiddle.svelte';
import CardTiny from './CardTiny.svelte';
import { getDefaultLogoColor } from '../utils/colorTheme.js';
export let logos = [];
@@ -27,6 +28,14 @@
{allLogos}
{setTheme}
/>
{:else if viewMode === "compact"}
<CardTiny
{logo}
{theme}
{setSearchQuery}
{allLogos}
{setTheme}
/>
{:else}
<CardSmall
{logo}
@@ -60,6 +69,20 @@
gap: 0.75rem;
}
.compact-view {
display: grid;
grid-template-columns: repeat(auto-fill, 200px);
gap: 1rem;
justify-content: space-between;
}
@media (max-width: 600px) {
.compact-view {
grid-template-columns: repeat(auto-fill, 160px);
gap: 0.75rem;
}
}
.no-results {
text-align: center;
padding: 2rem;

View File

@@ -94,6 +94,12 @@
}
}
function setCompactView() {
if (typeof window !== 'undefined' && window.appData && window.appData.setCompactView) {
window.appData.setCompactView();
}
}
function toggleDropdown() {
tagDropdownOpen = !tagDropdownOpen;
console.log("Home: Toggle dropdown to:", tagDropdownOpen);
@@ -135,6 +141,7 @@
{setTheme}
{setGridView}
{setListView}
{setCompactView}
logos={allLogos}
displayLogos={logos}
{toggleDropdown}