refactor: convert volume slider CSS to Tailwind utilities
This commit is contained in:
@@ -59,7 +59,7 @@ templ WatchPage(anime jikan.Anime, data WatchPageData) {
|
|||||||
<div
|
<div
|
||||||
hx-get={ string(templ.URL(fmt.Sprintf("/api/anime/%d/episodes?current=%s", anime.MalID, data.CurrentEpisode))) }
|
hx-get={ string(templ.URL(fmt.Sprintf("/api/anime/%d/episodes?current=%s", anime.MalID, data.CurrentEpisode))) }
|
||||||
hx-trigger="load"
|
hx-trigger="load"
|
||||||
class="watch-episodes-scroll overflow-y-auto flex-1"
|
class="scrollbar-hidden overflow-y-auto flex-1"
|
||||||
>
|
>
|
||||||
@LoadingIndicatorSmall()
|
@LoadingIndicatorSmall()
|
||||||
</div>
|
</div>
|
||||||
@@ -256,9 +256,9 @@ templ VideoPlayer(data WatchPageData) {
|
|||||||
<line x1="15" y1="6" x2="15" y2="18" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
<line x1="15" y1="6" x2="15" y2="18" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<div data-volume-wrap class="volume-wrap relative flex h-9 w-9 items-center justify-center overflow-visible sm:h-10 sm:w-10">
|
<div data-volume-wrap class="relative flex h-9 w-9 items-center justify-center overflow-visible sm:h-10 sm:w-10">
|
||||||
<span data-volume-bridge class="absolute inset-x-0 bottom-full h-[calc(100%+26px)]"></span>
|
<span data-volume-bridge class="volume-bridge-off absolute inset-x-0 bottom-full h-[calc(100%+26px)]"></span>
|
||||||
<div class="volume-panel pointer-events-none absolute bottom-[calc(100%+26px)] left-1/2 z-30 -translate-x-1/2 opacity-0 invisible transition-opacity">
|
<div data-volume-panel class="volume-panel pointer-events-none absolute bottom-[calc(100%+26px)] left-1/2 z-30 -translate-x-1/2 opacity-0 invisible transition-opacity">
|
||||||
<input
|
<input
|
||||||
data-volume-range
|
data-volume-range
|
||||||
type="range"
|
type="range"
|
||||||
@@ -266,7 +266,7 @@ templ VideoPlayer(data WatchPageData) {
|
|||||||
max="100"
|
max="100"
|
||||||
step="1"
|
step="1"
|
||||||
value="100"
|
value="100"
|
||||||
class="volume-range h-24 w-4 cursor-pointer appearance-none bg-transparent"
|
class="volume-range volume-track volume-thumb h-24 w-4 cursor-pointer appearance-none bg-transparent"
|
||||||
aria-label="Volume"
|
aria-label="Volume"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const initPlayer = (): void => {
|
|||||||
const iconPause = container.querySelector('[data-icon-pause]') as SVGElement
|
const iconPause = container.querySelector('[data-icon-pause]') as SVGElement
|
||||||
const muteBtn = container.querySelector('[data-mute]') as HTMLButtonElement
|
const muteBtn = container.querySelector('[data-mute]') as HTMLButtonElement
|
||||||
const volumeWrap = container.querySelector('[data-volume-wrap]') as HTMLElement
|
const volumeWrap = container.querySelector('[data-volume-wrap]') as HTMLElement
|
||||||
const volumePanel = container.querySelector('.volume-panel') as HTMLElement
|
const volumePanel = container.querySelector('[data-volume-panel]') as HTMLElement
|
||||||
const volumeRange = container.querySelector('[data-volume-range]') as HTMLInputElement
|
const volumeRange = container.querySelector('[data-volume-range]') as HTMLInputElement
|
||||||
const iconVolume = container.querySelector('[data-icon-volume]') as SVGElement
|
const iconVolume = container.querySelector('[data-icon-volume]') as SVGElement
|
||||||
const iconMuted = container.querySelector('[data-icon-muted]') as SVGElement
|
const iconMuted = container.querySelector('[data-icon-muted]') as SVGElement
|
||||||
@@ -854,7 +854,7 @@ const initPlayer = (): void => {
|
|||||||
|
|
||||||
const setVolumePanelOpen = (isOpen: boolean): void => {
|
const setVolumePanelOpen = (isOpen: boolean): void => {
|
||||||
if (volumePanel) {
|
if (volumePanel) {
|
||||||
volumePanel.classList.toggle('is-visible', isOpen)
|
volumePanel.classList.toggle('volume-panel-visible', isOpen)
|
||||||
}
|
}
|
||||||
volumeWrap?.classList.toggle('is-volume-open', isOpen)
|
volumeWrap?.classList.toggle('is-volume-open', isOpen)
|
||||||
isHoveringVolume = isOpen
|
isHoveringVolume = isOpen
|
||||||
|
|||||||
@@ -34,71 +34,79 @@
|
|||||||
--font: 'Verdana', 'Tahoma', 'Segoe UI', sans-serif;
|
--font: 'Verdana', 'Tahoma', 'Segoe UI', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.volume-range {
|
@utility volume-range {
|
||||||
writing-mode: vertical-lr;
|
writing-mode: vertical-lr;
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
accent-color: #ffffff;
|
accent-color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.volume-range::-webkit-slider-runnable-track {
|
@utility volume-track {
|
||||||
width: 4px;
|
&::-webkit-slider-runnable-track {
|
||||||
border-radius: 9999px;
|
width: 4px;
|
||||||
background: rgba(255, 255, 255, 0.55);
|
border-radius: 9999px;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.45);
|
background: rgba(255, 255, 255, 0.55);
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
|
&::-moz-range-track {
|
||||||
|
width: 4px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
background: rgba(255, 255, 255, 0.55);
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.volume-range::-webkit-slider-thumb {
|
@utility volume-thumb {
|
||||||
-webkit-appearance: none;
|
&::-webkit-slider-thumb {
|
||||||
appearance: none;
|
-webkit-appearance: none;
|
||||||
width: 14px;
|
appearance: none;
|
||||||
height: 14px;
|
width: 14px;
|
||||||
border-radius: 9999px;
|
height: 14px;
|
||||||
background: #ffffff;
|
border-radius: 9999px;
|
||||||
border: 0;
|
background: #ffffff;
|
||||||
margin-left: -5px;
|
border: 0;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.55);
|
margin-left: -5px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.55);
|
||||||
|
}
|
||||||
|
&::-moz-range-thumb {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 0;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.55);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.volume-range::-moz-range-track {
|
@utility volume-panel-visible {
|
||||||
width: 4px;
|
|
||||||
border-radius: 9999px;
|
|
||||||
background: rgba(255, 255, 255, 0.55);
|
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.45);
|
|
||||||
}
|
|
||||||
|
|
||||||
.volume-range::-moz-range-thumb {
|
|
||||||
width: 14px;
|
|
||||||
height: 14px;
|
|
||||||
border-radius: 9999px;
|
|
||||||
background: #ffffff;
|
|
||||||
border: 0;
|
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.55);
|
|
||||||
}
|
|
||||||
|
|
||||||
.volume-panel.is-visible {
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.volume-wrap[data-volume-wrap] [data-volume-bridge] {
|
@utility volume-bridge-off {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.volume-wrap.is-volume-open[data-volume-wrap] [data-volume-bridge] {
|
@utility volume-underline-visible {
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.volume-wrap:has(.volume-panel.is-visible) .volume-underline,
|
|
||||||
.volume-wrap:focus-within .volume-underline {
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.watch-episodes-scroll {
|
[data-volume-wrap]:is(.is-volume-open, :has(.volume-panel.volume-panel-visible)) [data-volume-bridge] {
|
||||||
scrollbar-width: none;
|
pointer-events: auto;
|
||||||
-ms-overflow-style: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.watch-episodes-scroll::-webkit-scrollbar {
|
.volume-underline {
|
||||||
display: none;
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-volume-wrap]:is(.is-volume-open, :has(.volume-panel.volume-panel-visible)) .volume-underline {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@utility scrollbar-hidden {
|
||||||
|
scrollbar-width: none;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user