227 lines
7.9 KiB
Plaintext
227 lines
7.9 KiB
Plaintext
---
|
|
interface Props {
|
|
showSizeSelector?: boolean;
|
|
showViewSelector?: boolean;
|
|
className?: string;
|
|
}
|
|
|
|
const {
|
|
showSizeSelector = true,
|
|
showViewSelector = true,
|
|
className = "",
|
|
} = Astro.props;
|
|
---
|
|
|
|
<div class={`flex items-center gap-4 ${className}`}>
|
|
{showSizeSelector && (
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-sm zag-text-muted hidden sm:inline">Size:</span>
|
|
<div class="size-selector flex flex-col items-center border-2 border-solid zag-border-b rounded-lg p-2 zag-bg zag-transition">
|
|
<input
|
|
type="range"
|
|
min="1"
|
|
max="3"
|
|
step="1"
|
|
x-model="iconSizeValue"
|
|
@input="updateIconSizeFromSlider()"
|
|
class="size-slider w-full"
|
|
aria-label="Icon size slider"
|
|
title="Adjust icon size (Alt+1: Small, Alt+2: Medium, Alt+3: Large)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Display options selector */}
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-sm zag-text-muted hidden sm:inline">Display:</span>
|
|
<div class="display-selector flex items-center gap-1 border-2 border-solid zag-border-b rounded-lg p-1 zag-bg zag-transition">
|
|
<button
|
|
@click="setDisplayMode('both')"
|
|
:class="displayMode === 'both' ? 'active-display' : 'inactive-display'"
|
|
class="p-1.5 transition-all rounded-md focus:outline-none focus:ring-2 focus:ring-current"
|
|
aria-label="Show both image and name"
|
|
title="Show both image and name (Alt+B)"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<rect x="3" y="3" width="18" height="12" rx="2" ry="2"></rect>
|
|
<line x1="3" y1="19" x2="21" y2="19"></line>
|
|
<line x1="3" y1="23" x2="21" y2="23"></line>
|
|
</svg>
|
|
</button>
|
|
<button
|
|
@click="setDisplayMode('image')"
|
|
:class="displayMode === 'image' ? 'active-display' : 'inactive-display'"
|
|
class="p-1.5 transition-all rounded-md focus:outline-none focus:ring-2 focus:ring-current"
|
|
aria-label="Show image only"
|
|
title="Show image only (Alt+I)"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
<circle cx="8.5" cy="8.5" r="1.5"></circle>
|
|
<polyline points="21 15 16 10 5 21"></polyline>
|
|
</svg>
|
|
</button>
|
|
<button
|
|
@click="setDisplayMode('name')"
|
|
:class="displayMode === 'name' ? 'active-display' : 'inactive-display'"
|
|
class="p-1.5 transition-all rounded-md focus:outline-none focus:ring-2 focus:ring-current"
|
|
aria-label="Show name only"
|
|
title="Show name only (Alt+N)"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<line x1="3" y1="12" x2="21" y2="12"></line>
|
|
<line x1="3" y1="6" x2="21" y2="6"></line>
|
|
<line x1="3" y1="18" x2="21" y2="18"></line>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{showViewSelector && (
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-sm zag-text-muted hidden sm:inline">View:</span>
|
|
<div class="view-selector border-2 border-solid zag-border-b rounded-lg p-1 zag-bg zag-transition">
|
|
<button
|
|
@click="toggleViewMode"
|
|
:class="viewMode === 'grid' ? 'active-view' : 'inactive-view'"
|
|
class="p-1.5 transition-all rounded-md focus:outline-none focus:ring-2 focus:ring-current"
|
|
aria-label="Toggle view mode"
|
|
:title="viewMode === 'grid' ? 'Switch to list view (Alt+G)' : 'Switch to grid view (Alt+G)'"
|
|
>
|
|
<svg x-show="viewMode === 'grid'" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<rect x="3" y="3" width="7" height="7"></rect>
|
|
<rect x="14" y="3" width="7" height="7"></rect>
|
|
<rect x="14" y="14" width="7" height="7"></rect>
|
|
<rect x="3" y="14" width="7" height="7"></rect>
|
|
</svg>
|
|
<svg x-show="viewMode === 'list'" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<line x1="8" y1="6" x2="21" y2="6"></line>
|
|
<line x1="8" y1="12" x2="21" y2="12"></line>
|
|
<line x1="8" y1="18" x2="21" y2="18"></line>
|
|
<line x1="3" y1="6" x2="3.01" y2="6"></line>
|
|
<line x1="3" y1="12" x2="3.01" y2="12"></line>
|
|
<line x1="3" y1="18" x2="3.01" y2="18"></line>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<style>
|
|
.size-selector, .view-selector, .display-selector {
|
|
box-shadow: 2px 2px 0 var(--color-zag-dark);
|
|
:where(.dark, .dark *) & {
|
|
box-shadow: 2px 2px 0 var(--color-zag-light);
|
|
}
|
|
}
|
|
|
|
.active-size, .active-view, .active-display {
|
|
color: var(--color-zag-dark);
|
|
background-color: var(--color-zag-light);
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
:where(.dark, .dark *) & {
|
|
color: var(--color-zag-dark);
|
|
}
|
|
}
|
|
|
|
.inactive-size, .inactive-view, .inactive-display {
|
|
color: var(--color-zag-dark-muted);
|
|
:where(.dark, .dark *) & {
|
|
color: var(--color-zag-light-muted);
|
|
}
|
|
}
|
|
|
|
.inactive-size:hover, .inactive-view:hover, .inactive-display:hover {
|
|
background-color: var(--color-zag-light-muted);
|
|
color: var(--color-zag-dark);
|
|
:where(.dark, .dark *) & {
|
|
background-color: var(--color-zag-dark-muted);
|
|
color: var(--color-zag-light);
|
|
}
|
|
}
|
|
|
|
/* Slider styles */
|
|
.size-slider {
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
height: 6px;
|
|
border-radius: 3px;
|
|
background: var(--color-zag-light-muted);
|
|
outline: none;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
|
|
:where(.dark, .dark *) & {
|
|
background: var(--color-zag-dark-muted);
|
|
}
|
|
}
|
|
|
|
/* Slider thumb */
|
|
.size-slider::-webkit-slider-thumb {
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
width: 16px;
|
|
height: 16px;
|
|
border-radius: 50%;
|
|
background: var(--color-zag-dark);
|
|
cursor: pointer;
|
|
border: 2px solid var(--color-zag-light);
|
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
transition: all 0.2s;
|
|
|
|
:where(.dark, .dark *) & {
|
|
background: var(--color-zag-light);
|
|
border: 2px solid var(--color-zag-dark);
|
|
}
|
|
}
|
|
|
|
.size-slider::-moz-range-thumb {
|
|
width: 16px;
|
|
height: 16px;
|
|
border-radius: 50%;
|
|
background: var(--color-zag-dark);
|
|
cursor: pointer;
|
|
border: 2px solid var(--color-zag-light);
|
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
transition: all 0.2s;
|
|
|
|
:where(.dark, .dark *) & {
|
|
background: var(--color-zag-light);
|
|
border: 2px solid var(--color-zag-dark);
|
|
}
|
|
}
|
|
|
|
/* Hover state */
|
|
.size-slider:hover::-webkit-slider-thumb {
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
.size-slider:hover::-moz-range-thumb {
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
/* Focus state */
|
|
.size-slider:focus {
|
|
outline: none;
|
|
}
|
|
|
|
.size-slider:focus::-webkit-slider-thumb {
|
|
box-shadow: 0 0 0 3px var(--color-zag-light), 0 0 0 5px var(--color-zag-dark-muted);
|
|
|
|
:where(.dark, .dark *) & {
|
|
box-shadow: 0 0 0 3px var(--color-zag-dark), 0 0 0 5px var(--color-zag-light-muted);
|
|
}
|
|
}
|
|
|
|
.size-slider:focus::-moz-range-thumb {
|
|
box-shadow: 0 0 0 3px var(--color-zag-light), 0 0 0 5px var(--color-zag-dark-muted);
|
|
|
|
:where(.dark, .dark *) & {
|
|
box-shadow: 0 0 0 3px var(--color-zag-dark), 0 0 0 5px var(--color-zag-light-muted);
|
|
}
|
|
}
|
|
</style>
|