mirror of
https://github.com/shadoll/sLogos.git
synced 2026-02-04 11:03:24 +00:00
feat: add compact view mode and integrate CardTiny component for logo display
This commit is contained in:
@@ -413,57 +413,6 @@ div.logo-image img {
|
|||||||
padding-top: 0.9rem;
|
padding-top: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.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;
|
|
||||||
outline: 2px solid var(--color-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-switch-group button:hover {
|
|
||||||
background: var(--color-accent);
|
|
||||||
color: var(--color-accent-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.logos-container {
|
.logos-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
@@ -595,8 +544,8 @@ footer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.set-circle {
|
.set-circle {
|
||||||
|
|||||||
@@ -100,6 +100,7 @@
|
|||||||
setSearchQuery,
|
setSearchQuery,
|
||||||
setGridView,
|
setGridView,
|
||||||
setListView,
|
setListView,
|
||||||
|
setCompactView,
|
||||||
setTheme,
|
setTheme,
|
||||||
toggleDropdown,
|
toggleDropdown,
|
||||||
addTag,
|
addTag,
|
||||||
@@ -197,13 +198,11 @@
|
|||||||
const searchParam = params.get("search");
|
const searchParam = params.get("search");
|
||||||
if (searchParam) {
|
if (searchParam) {
|
||||||
searchQuery = searchParam;
|
searchQuery = searchParam;
|
||||||
}
|
} // Restore view mode and compact mode from localStorage
|
||||||
|
const savedViewMode = localStorage.getItem("viewMode");
|
||||||
// Restore view mode and compact mode from localStorage
|
if (savedViewMode === "grid" || savedViewMode === "list" || savedViewMode === "compact") {
|
||||||
const savedViewMode = localStorage.getItem("viewMode");
|
viewMode = savedViewMode;
|
||||||
if (savedViewMode === "grid" || savedViewMode === "list") {
|
}
|
||||||
viewMode = savedViewMode;
|
|
||||||
}
|
|
||||||
const savedCompact = localStorage.getItem("compactMode");
|
const savedCompact = localStorage.getItem("compactMode");
|
||||||
if (savedCompact === "true" || savedCompact === "false") {
|
if (savedCompact === "true" || savedCompact === "false") {
|
||||||
setCompactMode(savedCompact === "true");
|
setCompactMode(savedCompact === "true");
|
||||||
@@ -277,6 +276,7 @@
|
|||||||
setSearchQuery,
|
setSearchQuery,
|
||||||
setGridView,
|
setGridView,
|
||||||
setListView,
|
setListView,
|
||||||
|
setCompactView,
|
||||||
setTheme: (newTheme) => {
|
setTheme: (newTheme) => {
|
||||||
console.log("window.appData.setTheme called with:", newTheme);
|
console.log("window.appData.setTheme called with:", newTheme);
|
||||||
setTheme(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) {
|
function copyUrl(logoPath) {
|
||||||
const url = `${window.location.origin}/${logoPath}`;
|
const url = `${window.location.origin}/${logoPath}`;
|
||||||
// Try modern clipboard API first
|
// Try modern clipboard API first
|
||||||
|
|||||||
108
src/components/CardTiny.svelte
Normal file
108
src/components/CardTiny.svelte
Normal 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>
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
export let viewMode;
|
export let viewMode;
|
||||||
export let setGridView;
|
export let setGridView;
|
||||||
export let setListView;
|
export let setListView;
|
||||||
|
export let setCompactView;
|
||||||
export let searchQuery;
|
export let searchQuery;
|
||||||
export let setSearchQuery;
|
export let setSearchQuery;
|
||||||
export let allTags = [];
|
export let allTags = [];
|
||||||
@@ -275,52 +276,89 @@
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<div class="view-mode-group">
|
||||||
class:active={viewMode === "grid"}
|
<button
|
||||||
on:click={setGridView}
|
class:active={viewMode === "compact"}
|
||||||
aria-label="Grid view"
|
on:click={setCompactView}
|
||||||
>
|
aria-label="Compact 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
|
|
||||||
>
|
>
|
||||||
</button>
|
<svg
|
||||||
<button
|
width="20"
|
||||||
class:active={viewMode === "list"}
|
height="20"
|
||||||
on:click={setListView}
|
viewBox="0 0 20 20"
|
||||||
aria-label="List view"
|
fill="none"
|
||||||
>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<svg
|
>
|
||||||
width="20"
|
<rect x="2" y="2" width="4" height="4" fill="currentColor" />
|
||||||
height="20"
|
<rect x="8" y="2" width="4" height="4" fill="currentColor" />
|
||||||
viewBox="0 0 20 20"
|
<rect x="14" y="2" width="4" height="4" fill="currentColor" />
|
||||||
fill="none"
|
<rect x="2" y="8" width="4" height="4" fill="currentColor" />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<rect x="8" y="8" width="4" height="4" fill="currentColor" />
|
||||||
><rect x="4" y="5" width="12" height="2" fill="currentColor" /><rect
|
<rect x="14" y="8" width="4" height="4" fill="currentColor" />
|
||||||
x="4"
|
<rect x="2" y="14" width="4" height="4" fill="currentColor" />
|
||||||
y="9"
|
<rect x="8" y="14" width="4" height="4" fill="currentColor" />
|
||||||
width="12"
|
<rect x="14" y="14" width="4" height="4" fill="currentColor" />
|
||||||
height="2"
|
</svg>
|
||||||
fill="currentColor"
|
</button>
|
||||||
/><rect x="4" y="13" width="12" height="2" fill="currentColor" /></svg
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
@@ -410,6 +448,58 @@
|
|||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
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 {
|
.compact-switch-btn {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
@@ -430,4 +520,37 @@
|
|||||||
background: var(--color-accent, #4f8cff);
|
background: var(--color-accent, #4f8cff);
|
||||||
color: #fff;
|
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>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import CardSmall from './CardSmall.svelte';
|
import CardSmall from './CardSmall.svelte';
|
||||||
import CardMiddle from './CardMiddle.svelte';
|
import CardMiddle from './CardMiddle.svelte';
|
||||||
|
import CardTiny from './CardTiny.svelte';
|
||||||
import { getDefaultLogoColor } from '../utils/colorTheme.js';
|
import { getDefaultLogoColor } from '../utils/colorTheme.js';
|
||||||
|
|
||||||
export let logos = [];
|
export let logos = [];
|
||||||
@@ -27,6 +28,14 @@
|
|||||||
{allLogos}
|
{allLogos}
|
||||||
{setTheme}
|
{setTheme}
|
||||||
/>
|
/>
|
||||||
|
{:else if viewMode === "compact"}
|
||||||
|
<CardTiny
|
||||||
|
{logo}
|
||||||
|
{theme}
|
||||||
|
{setSearchQuery}
|
||||||
|
{allLogos}
|
||||||
|
{setTheme}
|
||||||
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<CardSmall
|
<CardSmall
|
||||||
{logo}
|
{logo}
|
||||||
@@ -60,6 +69,20 @@
|
|||||||
gap: 0.75rem;
|
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 {
|
.no-results {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
|
|||||||
@@ -94,6 +94,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setCompactView() {
|
||||||
|
if (typeof window !== 'undefined' && window.appData && window.appData.setCompactView) {
|
||||||
|
window.appData.setCompactView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function toggleDropdown() {
|
function toggleDropdown() {
|
||||||
tagDropdownOpen = !tagDropdownOpen;
|
tagDropdownOpen = !tagDropdownOpen;
|
||||||
console.log("Home: Toggle dropdown to:", tagDropdownOpen);
|
console.log("Home: Toggle dropdown to:", tagDropdownOpen);
|
||||||
@@ -135,6 +141,7 @@
|
|||||||
{setTheme}
|
{setTheme}
|
||||||
{setGridView}
|
{setGridView}
|
||||||
{setListView}
|
{setListView}
|
||||||
|
{setCompactView}
|
||||||
logos={allLogos}
|
logos={allLogos}
|
||||||
displayLogos={logos}
|
displayLogos={logos}
|
||||||
{toggleDropdown}
|
{toggleDropdown}
|
||||||
|
|||||||
Reference in New Issue
Block a user