diff --git a/packages/html/src/define/audio/ui.ts b/packages/html/src/define/audio/ui.ts index 4a56e71f..63789684 100644 --- a/packages/html/src/define/audio/ui.ts +++ b/packages/html/src/define/audio/ui.ts @@ -16,7 +16,7 @@ import { SeekButtonElement } from '../../ui/seek-button/seek-button-element'; import { TooltipElement } from '../../ui/tooltip/tooltip-element'; import { TooltipGroupElement } from '../../ui/tooltip/tooltip-group-element'; import { safeDefine } from '../safe-define'; -import { defineErrorDialog, defineMenu, defineTime, defineTimeSlider, defineVolumeSlider } from '../ui/compounds'; +import { defineErrorDialog, defineMenu, defineSliders, defineTime } from '../ui/compounds'; // Value import — player.ts body runs before this module's body. import { AudioPlayerElement } from './player'; @@ -28,8 +28,7 @@ safeDefine(MediaContainerElement); // Compound groups. defineErrorDialog(); -defineTimeSlider(); -defineVolumeSlider(); +defineSliders(); defineTime(); defineMenu(); diff --git a/packages/html/src/define/live-video/ui.ts b/packages/html/src/define/live-video/ui.ts index 4ae369b9..fff8932c 100644 --- a/packages/html/src/define/live-video/ui.ts +++ b/packages/html/src/define/live-video/ui.ts @@ -18,14 +18,7 @@ import { PosterElement } from '../../ui/poster/poster-element'; import { TooltipElement } from '../../ui/tooltip/tooltip-element'; import { TooltipGroupElement } from '../../ui/tooltip/tooltip-group-element'; import { safeDefine } from '../safe-define'; -import { - defineControls, - defineErrorDialog, - defineInputIndicators, - defineTime, - defineTimeSlider, - defineVolumeSlider, -} from '../ui/compounds'; +import { defineControls, defineErrorDialog, defineInputIndicators, defineSliders, defineTime } from '../ui/compounds'; // Value import — player.ts body runs before this module's body. import { LiveVideoPlayerElement } from './player'; @@ -39,8 +32,7 @@ safeDefine(MediaContainerElement); defineControls(); defineErrorDialog(); defineInputIndicators(); -defineTimeSlider(); -defineVolumeSlider(); +defineSliders(); defineTime(); // Standalone elements. diff --git a/packages/html/src/define/tests/video-ui-ejected.test.ts b/packages/html/src/define/tests/video-ui-ejected.test.ts new file mode 100644 index 00000000..812dadd0 --- /dev/null +++ b/packages/html/src/define/tests/video-ui-ejected.test.ts @@ -0,0 +1,53 @@ +import { describe, expect, it } from 'vitest'; + +async function waitForUpdates(elements: Element[]): Promise { + for (const element of elements) { + const maybeReactive = element as Element & { updateComplete?: Promise }; + await maybeReactive.updateComplete; + } +} + +describe('video/ui ejected registration', () => { + it('updates volume slider child parts when light DOM exists before registration', async () => { + document.body.innerHTML = /*html*/ ` + + + + + + + + + + + + + + + + + + + + + `; + + await import('../video/ui'); + + const volumeSlider = document.querySelector('media-volume-slider')! as HTMLElement & { orientation: string }; + const volumeTrack = volumeSlider.querySelector('media-slider-track')!; + const volumeFill = volumeSlider.querySelector('media-slider-fill')!; + const volumeThumb = volumeSlider.querySelector('media-slider-thumb')!; + + volumeSlider.orientation = 'vertical'; + + await Promise.resolve(); + await waitForUpdates([volumeSlider, volumeTrack, volumeFill, volumeThumb]); + + expect(volumeSlider.getAttribute('data-orientation')).toBe('vertical'); + expect(volumeTrack.getAttribute('data-orientation')).toBe('vertical'); + expect(volumeFill.getAttribute('data-orientation')).toBe('vertical'); + expect(volumeThumb.getAttribute('data-orientation')).toBe('vertical'); + expect(volumeThumb.getAttribute('aria-orientation')).toBe('vertical'); + }); +}); diff --git a/packages/html/src/define/ui/compounds.ts b/packages/html/src/define/ui/compounds.ts index f1aa652e..c757a4db 100644 --- a/packages/html/src/define/ui/compounds.ts +++ b/packages/html/src/define/ui/compounds.ts @@ -110,3 +110,11 @@ export function defineVolumeSlider(): void { safeDefine(VolumeSliderElement); defineSliderParts(); } + +export function defineSliders(): void { + safeDefine(TimeSliderElement); + safeDefine(VolumeSliderElement); + defineSliderParts(); + safeDefine(SliderBufferElement); + safeDefine(SliderThumbnailElement); +} diff --git a/packages/html/src/define/video/ui.ts b/packages/html/src/define/video/ui.ts index de098bfa..a87ae021 100644 --- a/packages/html/src/define/video/ui.ts +++ b/packages/html/src/define/video/ui.ts @@ -28,9 +28,8 @@ import { defineErrorDialog, defineInputIndicators, defineMenu, + defineSliders, defineTime, - defineTimeSlider, - defineVolumeSlider, } from '../ui/compounds'; // Value import — player.ts body runs before this module's body. @@ -45,8 +44,7 @@ safeDefine(MediaContainerElement); defineControls(); defineErrorDialog(); defineInputIndicators(); -defineTimeSlider(); -defineVolumeSlider(); +defineSliders(); defineTime(); defineMenu(); diff --git a/packages/skins/src/default/css/components/button.css b/packages/skins/src/default/css/components/button.css index 57852c5d..f9ff9beb 100644 --- a/packages/skins/src/default/css/components/button.css +++ b/packages/skins/src/default/css/components/button.css @@ -78,6 +78,10 @@ scale: 0.9; } + & .media-icon__container { + display: grid; + } + & .media-icon { grid-area: 1 / 1; transition-behavior: allow-discrete; @@ -95,8 +99,9 @@ right: -1px; bottom: -3px; font-size: 10px; - font-weight: 480; + font-weight: 500; font-variant-numeric: tabular-nums; + letter-spacing: -0.05em; } &:has(.media-icon--flipped) .media-icon__label { diff --git a/packages/skins/src/default/css/components/icons.css b/packages/skins/src/default/css/components/icons.css index d11bbb28..d8bcb05c 100644 --- a/packages/skins/src/default/css/components/icons.css +++ b/packages/skins/src/default/css/components/icons.css @@ -5,6 +5,7 @@ .media-default-skin .media-icon__container { position: relative; } + .media-default-skin .media-icon { flex-shrink: 0; width: var(--media-icon-size); diff --git a/packages/skins/src/default/tailwind/components/icon.ts b/packages/skins/src/default/tailwind/components/icon.ts index 22051a8b..8fc1b33e 100644 --- a/packages/skins/src/default/tailwind/components/icon.ts +++ b/packages/skins/src/default/tailwind/components/icon.ts @@ -8,4 +8,4 @@ export const icon = cn( export const iconHidden = 'hidden opacity-0'; export const iconFlipped = '[scale:-1_1]'; -export const iconContainer = 'relative'; +export const iconContainer = 'relative grid'; diff --git a/packages/skins/src/default/tailwind/components/seek.ts b/packages/skins/src/default/tailwind/components/seek.ts index 2b319821..f4b14949 100644 --- a/packages/skins/src/default/tailwind/components/seek.ts +++ b/packages/skins/src/default/tailwind/components/seek.ts @@ -1,5 +1,5 @@ export const seek = { - label: 'text-[10px] font-[480] tabular-nums', + label: 'text-[10px] font-medium tracking-tighter tabular-nums', labelForward: 'absolute -right-px -bottom-0.75', labelBackward: 'absolute -left-px -bottom-0.75', }; diff --git a/packages/skins/src/minimal/css/components/button.css b/packages/skins/src/minimal/css/components/button.css index e015370d..9e418dfb 100644 --- a/packages/skins/src/minimal/css/components/button.css +++ b/packages/skins/src/minimal/css/components/button.css @@ -84,6 +84,10 @@ scale: 0.9; } + & .media-icon__container { + display: grid; + } + & .media-icon { grid-area: 1 / 1; transition-behavior: allow-discrete; @@ -101,8 +105,9 @@ right: -1px; bottom: -3px; font-size: 10px; /* Hard coded due to size limitations. */ - font-weight: 480; + font-weight: 500; font-variant-numeric: tabular-nums; + letter-spacing: -0.05em; } &:has(.media-icon--flipped) .media-icon__label { diff --git a/packages/skins/src/minimal/css/components/icons.css b/packages/skins/src/minimal/css/components/icons.css index 6c56b4bb..aaa0d8f5 100644 --- a/packages/skins/src/minimal/css/components/icons.css +++ b/packages/skins/src/minimal/css/components/icons.css @@ -5,6 +5,7 @@ .media-minimal-skin .media-icon__container { position: relative; } + .media-minimal-skin .media-icon { flex-shrink: 0; width: var(--media-icon-size); diff --git a/packages/skins/src/minimal/tailwind/components/icon.ts b/packages/skins/src/minimal/tailwind/components/icon.ts index 17312da6..9ffaae6e 100644 --- a/packages/skins/src/minimal/tailwind/components/icon.ts +++ b/packages/skins/src/minimal/tailwind/components/icon.ts @@ -8,4 +8,4 @@ export const icon = cn( export const iconHidden = 'hidden opacity-0'; export const iconFlipped = '[scale:-1_1]'; -export const iconContainer = 'relative'; +export const iconContainer = 'relative grid'; diff --git a/packages/skins/src/minimal/tailwind/components/seek.ts b/packages/skins/src/minimal/tailwind/components/seek.ts index 2b319821..f4b14949 100644 --- a/packages/skins/src/minimal/tailwind/components/seek.ts +++ b/packages/skins/src/minimal/tailwind/components/seek.ts @@ -1,5 +1,5 @@ export const seek = { - label: 'text-[10px] font-[480] tabular-nums', + label: 'text-[10px] font-medium tracking-tighter tabular-nums', labelForward: 'absolute -right-px -bottom-0.75', labelBackward: 'absolute -left-px -bottom-0.75', };