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',
};