@videojs/react 10.0.0-alpha.4 → 10.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/default/_virtual/_rolldown/runtime.js +1 -19
- package/dist/default/index.js +10 -33
- package/dist/default/player/context.js +11 -1
- package/dist/default/player/context.js.map +1 -1
- package/dist/default/presets/audio/index.js +2 -8
- package/dist/default/presets/audio/skin.css +1 -0
- package/dist/default/presets/background/index.js +2 -8
- package/dist/default/presets/background/skin.css +1 -0
- package/dist/default/presets/video/index.js +2 -8
- package/dist/default/presets/video/minimal-skin.css +178 -53
- package/dist/default/presets/video/minimal-skin.js +63 -90
- package/dist/default/presets/video/minimal-skin.js.map +1 -1
- package/dist/default/presets/video/minimal-skin.tailwind.js +126 -107
- package/dist/default/presets/video/minimal-skin.tailwind.js.map +1 -1
- package/dist/default/presets/video/skin.css +179 -54
- package/dist/default/presets/video/skin.js +61 -88
- package/dist/default/presets/video/skin.js.map +1 -1
- package/dist/default/presets/video/skin.tailwind.js +121 -104
- package/dist/default/presets/video/skin.tailwind.js.map +1 -1
- package/dist/default/skins/dist/default/video/default.tailwind.js +90 -0
- package/dist/default/skins/dist/default/video/default.tailwind.js.map +1 -0
- package/dist/default/skins/dist/default/video/minimal.tailwind.js +86 -0
- package/dist/default/skins/dist/default/video/minimal.tailwind.js.map +1 -0
- package/dist/default/ui/captions-button/captions-button.js +1 -16
- package/dist/default/ui/captions-button/captions-button.js.map +1 -1
- package/dist/default/ui/controls/context.js +16 -0
- package/dist/default/ui/controls/context.js.map +1 -0
- package/dist/default/ui/controls/controls-group.js +4 -1
- package/dist/default/ui/controls/controls-group.js.map +1 -1
- package/dist/default/ui/controls/controls-root.js +19 -10
- package/dist/default/ui/controls/controls-root.js.map +1 -1
- package/dist/default/ui/create-context-part.js +29 -0
- package/dist/default/ui/create-context-part.js.map +1 -0
- package/dist/default/ui/create-media-button.js +52 -0
- package/dist/default/ui/create-media-button.js.map +1 -0
- package/dist/default/ui/fullscreen-button/fullscreen-button.js +8 -33
- package/dist/default/ui/fullscreen-button/fullscreen-button.js.map +1 -1
- package/dist/default/ui/hooks/use-slider.js +75 -0
- package/dist/default/ui/hooks/use-slider.js.map +1 -0
- package/dist/default/ui/mute-button/mute-button.js +8 -36
- package/dist/default/ui/mute-button/mute-button.js.map +1 -1
- package/dist/default/ui/pip-button/pip-button.js +8 -33
- package/dist/default/ui/pip-button/pip-button.js.map +1 -1
- package/dist/default/ui/play-button/play-button.js +7 -33
- package/dist/default/ui/play-button/play-button.js.map +1 -1
- package/dist/default/ui/playback-rate-button/index.js +3 -0
- package/dist/default/ui/playback-rate-button/playback-rate-button.js +34 -0
- package/dist/default/ui/playback-rate-button/playback-rate-button.js.map +1 -0
- package/dist/default/ui/popover/context.js +16 -0
- package/dist/default/ui/popover/context.js.map +1 -0
- package/dist/default/ui/popover/index.js +4 -0
- package/dist/default/ui/popover/index.parts.js +17 -0
- package/dist/default/ui/popover/index.parts.js.map +1 -0
- package/dist/default/ui/popover/popover-arrow.js +17 -0
- package/dist/default/ui/popover/popover-arrow.js.map +1 -0
- package/dist/default/ui/popover/popover-popup.js +94 -0
- package/dist/default/ui/popover/popover-popup.js.map +1 -0
- package/dist/default/ui/popover/popover-root.js +69 -0
- package/dist/default/ui/popover/popover-root.js.map +1 -0
- package/dist/default/ui/popover/popover-trigger.js +43 -0
- package/dist/default/ui/popover/popover-trigger.js.map +1 -0
- package/dist/default/ui/poster/poster.js +2 -1
- package/dist/default/ui/poster/poster.js.map +1 -1
- package/dist/default/ui/seek-button/seek-button.js +7 -34
- package/dist/default/ui/seek-button/seek-button.js.map +1 -1
- package/dist/default/ui/slider/context.js +22 -0
- package/dist/default/ui/slider/context.js.map +1 -0
- package/dist/default/ui/slider/index.js +3 -0
- package/dist/default/ui/slider/index.parts.js +21 -0
- package/dist/default/ui/slider/index.parts.js.map +1 -0
- package/dist/default/ui/slider/slider-buffer.js +16 -0
- package/dist/default/ui/slider/slider-buffer.js.map +1 -0
- package/dist/default/ui/slider/slider-fill.js +16 -0
- package/dist/default/ui/slider/slider-fill.js.map +1 -0
- package/dist/default/ui/slider/slider-root.js +71 -0
- package/dist/default/ui/slider/slider-root.js.map +1 -0
- package/dist/default/ui/slider/slider-thumb.js +32 -0
- package/dist/default/ui/slider/slider-thumb.js.map +1 -0
- package/dist/default/ui/slider/slider-track.js +16 -0
- package/dist/default/ui/slider/slider-track.js.map +1 -0
- package/dist/default/ui/slider/slider-value.js +32 -0
- package/dist/default/ui/slider/slider-value.js.map +1 -0
- package/dist/default/ui/thumbnail/thumbnail.js +87 -0
- package/dist/default/ui/thumbnail/thumbnail.js.map +1 -0
- package/dist/default/ui/time/time-value.js +2 -1
- package/dist/default/ui/time/time-value.js.map +1 -1
- package/dist/default/ui/time-slider/index.js +3 -0
- package/dist/default/ui/time-slider/index.parts.js +21 -0
- package/dist/default/ui/time-slider/index.parts.js.map +1 -0
- package/dist/default/ui/time-slider/time-slider-root.js +96 -0
- package/dist/default/ui/time-slider/time-slider-root.js.map +1 -0
- package/dist/default/ui/volume-slider/index.js +3 -0
- package/dist/default/ui/volume-slider/index.parts.js +19 -0
- package/dist/default/ui/volume-slider/index.parts.js.map +1 -0
- package/dist/default/ui/volume-slider/volume-slider-root.js +86 -0
- package/dist/default/ui/volume-slider/volume-slider-root.js.map +1 -0
- package/dist/default/utils/use-force-render.js +13 -0
- package/dist/default/utils/use-force-render.js.map +1 -0
- package/dist/default/utils/use-latest-ref.js +20 -0
- package/dist/default/utils/use-latest-ref.js.map +1 -0
- package/dist/default/utils/use-safe-id.js +22 -0
- package/dist/default/utils/use-safe-id.js.map +1 -0
- package/dist/dev/_virtual/_rolldown/runtime.js +1 -19
- package/dist/dev/index.d.ts +20 -2
- package/dist/dev/index.js +10 -33
- package/dist/dev/player/context.d.ts.map +1 -1
- package/dist/dev/player/context.js +11 -1
- package/dist/dev/player/context.js.map +1 -1
- package/dist/dev/presets/audio/index.d.ts +2 -9
- package/dist/dev/presets/audio/index.js +2 -8
- package/dist/dev/presets/audio/skin.css +1 -0
- package/dist/dev/presets/background/index.d.ts +2 -9
- package/dist/dev/presets/background/index.js +2 -8
- package/dist/dev/presets/background/skin.css +1 -0
- package/dist/dev/presets/video/index.d.ts +2 -9
- package/dist/dev/presets/video/index.js +2 -8
- package/dist/dev/presets/video/minimal-skin.css +178 -53
- package/dist/dev/presets/video/minimal-skin.d.ts.map +1 -1
- package/dist/dev/presets/video/minimal-skin.js +61 -88
- package/dist/dev/presets/video/minimal-skin.js.map +1 -1
- package/dist/dev/presets/video/minimal-skin.tailwind.d.ts.map +1 -1
- package/dist/dev/presets/video/minimal-skin.tailwind.js +124 -105
- package/dist/dev/presets/video/minimal-skin.tailwind.js.map +1 -1
- package/dist/dev/presets/video/skin.css +179 -54
- package/dist/dev/presets/video/skin.d.ts.map +1 -1
- package/dist/dev/presets/video/skin.js +61 -88
- package/dist/dev/presets/video/skin.js.map +1 -1
- package/dist/dev/presets/video/skin.tailwind.d.ts.map +1 -1
- package/dist/dev/presets/video/skin.tailwind.js +121 -104
- package/dist/dev/presets/video/skin.tailwind.js.map +1 -1
- package/dist/dev/skins/dist/default/video/default.tailwind.js +90 -0
- package/dist/dev/skins/dist/default/video/default.tailwind.js.map +1 -0
- package/dist/dev/skins/dist/default/video/minimal.tailwind.js +86 -0
- package/dist/dev/skins/dist/default/video/minimal.tailwind.js.map +1 -0
- package/dist/dev/ui/captions-button/captions-button.d.ts.map +1 -1
- package/dist/dev/ui/captions-button/captions-button.js +1 -16
- package/dist/dev/ui/captions-button/captions-button.js.map +1 -1
- package/dist/dev/ui/controls/context.js +16 -0
- package/dist/dev/ui/controls/context.js.map +1 -0
- package/dist/dev/ui/controls/controls-group.d.ts +2 -2
- package/dist/dev/ui/controls/controls-group.d.ts.map +1 -1
- package/dist/dev/ui/controls/controls-group.js +4 -1
- package/dist/dev/ui/controls/controls-group.js.map +1 -1
- package/dist/dev/ui/controls/controls-root.d.ts.map +1 -1
- package/dist/dev/ui/controls/controls-root.js +19 -10
- package/dist/dev/ui/controls/controls-root.js.map +1 -1
- package/dist/dev/ui/create-context-part.js +29 -0
- package/dist/dev/ui/create-context-part.js.map +1 -0
- package/dist/dev/ui/create-media-button.js +55 -0
- package/dist/dev/ui/create-media-button.js.map +1 -0
- package/dist/dev/ui/fullscreen-button/fullscreen-button.d.ts +2 -1
- package/dist/dev/ui/fullscreen-button/fullscreen-button.d.ts.map +1 -1
- package/dist/dev/ui/fullscreen-button/fullscreen-button.js +9 -37
- package/dist/dev/ui/fullscreen-button/fullscreen-button.js.map +1 -1
- package/dist/dev/ui/hooks/use-slider.d.ts +36 -0
- package/dist/dev/ui/hooks/use-slider.d.ts.map +1 -0
- package/dist/dev/ui/hooks/use-slider.js +75 -0
- package/dist/dev/ui/hooks/use-slider.js.map +1 -0
- package/dist/dev/ui/mute-button/mute-button.d.ts +2 -4
- package/dist/dev/ui/mute-button/mute-button.d.ts.map +1 -1
- package/dist/dev/ui/mute-button/mute-button.js +9 -40
- package/dist/dev/ui/mute-button/mute-button.js.map +1 -1
- package/dist/dev/ui/pip-button/pip-button.d.ts +2 -1
- package/dist/dev/ui/pip-button/pip-button.d.ts.map +1 -1
- package/dist/dev/ui/pip-button/pip-button.js +9 -37
- package/dist/dev/ui/pip-button/pip-button.js.map +1 -1
- package/dist/dev/ui/play-button/play-button.d.ts +1 -1
- package/dist/dev/ui/play-button/play-button.d.ts.map +1 -1
- package/dist/dev/ui/play-button/play-button.js +8 -37
- package/dist/dev/ui/play-button/play-button.js.map +1 -1
- package/dist/dev/ui/playback-rate-button/index.d.ts +2 -0
- package/dist/dev/ui/playback-rate-button/index.js +3 -0
- package/dist/dev/ui/playback-rate-button/playback-rate-button.d.ts +30 -0
- package/dist/dev/ui/playback-rate-button/playback-rate-button.d.ts.map +1 -0
- package/dist/dev/ui/playback-rate-button/playback-rate-button.js +34 -0
- package/dist/dev/ui/playback-rate-button/playback-rate-button.js.map +1 -0
- package/dist/dev/ui/popover/context.d.ts +17 -0
- package/dist/dev/ui/popover/context.d.ts.map +1 -0
- package/dist/dev/ui/popover/context.js +16 -0
- package/dist/dev/ui/popover/context.js.map +1 -0
- package/dist/dev/ui/popover/index.d.ts +3 -0
- package/dist/dev/ui/popover/index.js +4 -0
- package/dist/dev/ui/popover/index.parts.d.ts +12 -0
- package/dist/dev/ui/popover/index.parts.d.ts.map +1 -0
- package/dist/dev/ui/popover/index.parts.js +17 -0
- package/dist/dev/ui/popover/index.parts.js.map +1 -0
- package/dist/dev/ui/popover/popover-arrow.d.ts +15 -0
- package/dist/dev/ui/popover/popover-arrow.d.ts.map +1 -0
- package/dist/dev/ui/popover/popover-arrow.js +17 -0
- package/dist/dev/ui/popover/popover-arrow.js.map +1 -0
- package/dist/dev/ui/popover/popover-popup.d.ts +15 -0
- package/dist/dev/ui/popover/popover-popup.d.ts.map +1 -0
- package/dist/dev/ui/popover/popover-popup.js +94 -0
- package/dist/dev/ui/popover/popover-popup.js.map +1 -0
- package/dist/dev/ui/popover/popover-root.d.ts +29 -0
- package/dist/dev/ui/popover/popover-root.d.ts.map +1 -0
- package/dist/dev/ui/popover/popover-root.js +69 -0
- package/dist/dev/ui/popover/popover-root.js.map +1 -0
- package/dist/dev/ui/popover/popover-trigger.d.ts +15 -0
- package/dist/dev/ui/popover/popover-trigger.d.ts.map +1 -0
- package/dist/dev/ui/popover/popover-trigger.js +43 -0
- package/dist/dev/ui/popover/popover-trigger.js.map +1 -0
- package/dist/dev/ui/poster/poster.d.ts.map +1 -1
- package/dist/dev/ui/poster/poster.js +2 -1
- package/dist/dev/ui/poster/poster.js.map +1 -1
- package/dist/dev/ui/seek-button/seek-button.d.ts +1 -1
- package/dist/dev/ui/seek-button/seek-button.d.ts.map +1 -1
- package/dist/dev/ui/seek-button/seek-button.js +8 -38
- package/dist/dev/ui/seek-button/seek-button.js.map +1 -1
- package/dist/dev/ui/slider/context.js +22 -0
- package/dist/dev/ui/slider/context.js.map +1 -0
- package/dist/dev/ui/slider/index.d.ts +2 -0
- package/dist/dev/ui/slider/index.js +3 -0
- package/dist/dev/ui/slider/index.parts.d.ts +14 -0
- package/dist/dev/ui/slider/index.parts.d.ts.map +1 -0
- package/dist/dev/ui/slider/index.parts.js +21 -0
- package/dist/dev/ui/slider/index.parts.js.map +1 -0
- package/dist/dev/ui/slider/slider-buffer.d.ts +14 -0
- package/dist/dev/ui/slider/slider-buffer.d.ts.map +1 -0
- package/dist/dev/ui/slider/slider-buffer.js +16 -0
- package/dist/dev/ui/slider/slider-buffer.js.map +1 -0
- package/dist/dev/ui/slider/slider-fill.d.ts +14 -0
- package/dist/dev/ui/slider/slider-fill.d.ts.map +1 -0
- package/dist/dev/ui/slider/slider-fill.js +16 -0
- package/dist/dev/ui/slider/slider-fill.js.map +1 -0
- package/dist/dev/ui/slider/slider-root.d.ts +19 -0
- package/dist/dev/ui/slider/slider-root.d.ts.map +1 -0
- package/dist/dev/ui/slider/slider-root.js +71 -0
- package/dist/dev/ui/slider/slider-root.js.map +1 -0
- package/dist/dev/ui/slider/slider-thumb.d.ts +14 -0
- package/dist/dev/ui/slider/slider-thumb.d.ts.map +1 -0
- package/dist/dev/ui/slider/slider-thumb.js +32 -0
- package/dist/dev/ui/slider/slider-thumb.js.map +1 -0
- package/dist/dev/ui/slider/slider-track.d.ts +14 -0
- package/dist/dev/ui/slider/slider-track.d.ts.map +1 -0
- package/dist/dev/ui/slider/slider-track.js +16 -0
- package/dist/dev/ui/slider/slider-track.js.map +1 -0
- package/dist/dev/ui/slider/slider-value.d.ts +19 -0
- package/dist/dev/ui/slider/slider-value.d.ts.map +1 -0
- package/dist/dev/ui/slider/slider-value.js +32 -0
- package/dist/dev/ui/slider/slider-value.js.map +1 -0
- package/dist/dev/ui/thumbnail/thumbnail.d.ts +17 -0
- package/dist/dev/ui/thumbnail/thumbnail.d.ts.map +1 -0
- package/dist/dev/ui/thumbnail/thumbnail.js +87 -0
- package/dist/dev/ui/thumbnail/thumbnail.js.map +1 -0
- package/dist/dev/ui/time/time-value.d.ts.map +1 -1
- package/dist/dev/ui/time/time-value.js +2 -1
- package/dist/dev/ui/time/time-value.js.map +1 -1
- package/dist/dev/ui/time-slider/index.d.ts +2 -0
- package/dist/dev/ui/time-slider/index.js +3 -0
- package/dist/dev/ui/time-slider/index.parts.d.ts +15 -0
- package/dist/dev/ui/time-slider/index.parts.d.ts.map +1 -0
- package/dist/dev/ui/time-slider/index.parts.js +21 -0
- package/dist/dev/ui/time-slider/index.parts.js.map +1 -0
- package/dist/dev/ui/time-slider/time-slider-root.d.ts +17 -0
- package/dist/dev/ui/time-slider/time-slider-root.d.ts.map +1 -0
- package/dist/dev/ui/time-slider/time-slider-root.js +99 -0
- package/dist/dev/ui/time-slider/time-slider-root.js.map +1 -0
- package/dist/dev/ui/volume-slider/index.d.ts +2 -0
- package/dist/dev/ui/volume-slider/index.js +3 -0
- package/dist/dev/ui/volume-slider/index.parts.d.ts +14 -0
- package/dist/dev/ui/volume-slider/index.parts.d.ts.map +1 -0
- package/dist/dev/ui/volume-slider/index.parts.js +19 -0
- package/dist/dev/ui/volume-slider/index.parts.js.map +1 -0
- package/dist/dev/ui/volume-slider/volume-slider-root.d.ts +17 -0
- package/dist/dev/ui/volume-slider/volume-slider-root.d.ts.map +1 -0
- package/dist/dev/ui/volume-slider/volume-slider-root.js +89 -0
- package/dist/dev/ui/volume-slider/volume-slider-root.js.map +1 -0
- package/dist/dev/utils/use-force-render.js +13 -0
- package/dist/dev/utils/use-force-render.js.map +1 -0
- package/dist/dev/utils/use-latest-ref.js +20 -0
- package/dist/dev/utils/use-latest-ref.js.map +1 -0
- package/dist/dev/utils/use-safe-id.js +22 -0
- package/dist/dev/utils/use-safe-id.js.map +1 -0
- package/package.json +6 -5
- package/dist/default/index.js.map +0 -1
- package/dist/default/presets/audio/index.js.map +0 -1
- package/dist/default/presets/background/index.js.map +0 -1
- package/dist/default/presets/video/index.js.map +0 -1
- package/dist/dev/index.js.map +0 -1
- package/dist/dev/presets/audio/index.d.ts.map +0 -1
- package/dist/dev/presets/audio/index.js.map +0 -1
- package/dist/dev/presets/background/index.d.ts.map +0 -1
- package/dist/dev/presets/background/index.js.map +0 -1
- package/dist/dev/presets/video/index.d.ts.map +0 -1
- package/dist/dev/presets/video/index.js.map +0 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { usePlayer } from "../player/context.js";
|
|
4
|
+
import { renderElement } from "../utils/use-render.js";
|
|
5
|
+
import { useButton } from "./hooks/use-button.js";
|
|
6
|
+
import "@videojs/core/dom";
|
|
7
|
+
import { forwardRef, useState } from "react";
|
|
8
|
+
|
|
9
|
+
//#region src/ui/create-media-button.tsx
|
|
10
|
+
/** Creates a media button React component from a core class and config. */
|
|
11
|
+
function createMediaButton(config) {
|
|
12
|
+
const { displayName, core: CoreClass, stateAttrMap, selector, action } = config;
|
|
13
|
+
const corePropKeys = new Set(Object.keys(CoreClass.defaultProps));
|
|
14
|
+
const Component = forwardRef(function MediaButton(componentProps, forwardedRef) {
|
|
15
|
+
const { render, className, style, ...rest } = componentProps;
|
|
16
|
+
const coreProps = {};
|
|
17
|
+
const elementProps = {};
|
|
18
|
+
for (const key of Object.keys(rest)) if (corePropKeys.has(key)) coreProps[key] = rest[key];
|
|
19
|
+
else elementProps[key] = rest[key];
|
|
20
|
+
const feature = usePlayer(selector);
|
|
21
|
+
const [core] = useState(() => new CoreClass());
|
|
22
|
+
core.setProps(coreProps);
|
|
23
|
+
const { getButtonProps, buttonRef } = useButton({
|
|
24
|
+
displayName,
|
|
25
|
+
onActivate: () => action(core, feature),
|
|
26
|
+
isDisabled: () => !!coreProps.disabled || !feature
|
|
27
|
+
});
|
|
28
|
+
if (!feature) return null;
|
|
29
|
+
core.setMedia(feature);
|
|
30
|
+
const state = core.getState();
|
|
31
|
+
return renderElement("button", {
|
|
32
|
+
render,
|
|
33
|
+
className,
|
|
34
|
+
style
|
|
35
|
+
}, {
|
|
36
|
+
state,
|
|
37
|
+
stateAttrMap,
|
|
38
|
+
ref: [forwardedRef, buttonRef],
|
|
39
|
+
props: [
|
|
40
|
+
core.getAttrs(state),
|
|
41
|
+
elementProps,
|
|
42
|
+
getButtonProps()
|
|
43
|
+
]
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
Component.displayName = displayName;
|
|
47
|
+
return Component;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
export { createMediaButton };
|
|
52
|
+
//# sourceMappingURL=create-media-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-media-button.js","names":[],"sources":["../../../src/ui/create-media-button.tsx"],"sourcesContent":["'use client';\n\nimport type { InferComponentState, InferMediaState, MediaUIComponent, StateAttrMap } from '@videojs/core';\nimport { logMissingFeature } from '@videojs/core/dom';\nimport type { Selector } from '@videojs/store';\nimport type { ForwardedRef, ForwardRefExoticComponent, RefAttributes } from 'react';\nimport { forwardRef, useState } from 'react';\n\nimport { usePlayer } from '../player/context';\nimport type { renderElement as renderElementFn } from '../utils/use-render';\nimport { renderElement } from '../utils/use-render';\nimport { useButton } from './hooks/use-button';\n\ninterface MediaButtonConfig<Core extends Required<MediaUIComponent>> {\n displayName: string;\n core: { new (): Core; defaultProps: Record<string, unknown> };\n stateAttrMap: StateAttrMap<InferComponentState<Core>>;\n selector: Selector<object, InferMediaState<Core> | undefined>;\n action: (core: Core, state: InferMediaState<Core>) => void;\n}\n\n/** Creates a media button React component from a core class and config. */\nexport function createMediaButton<Core extends Required<MediaUIComponent>, Props extends object>(\n config: MediaButtonConfig<Core>\n): ForwardRefExoticComponent<Props & RefAttributes<HTMLButtonElement>> {\n const { displayName, core: CoreClass, stateAttrMap, selector, action } = config;\n\n // Props that exist in the core's defaultProps are routed to setProps; the rest go to the DOM element.\n const corePropKeys = new Set(Object.keys(CoreClass.defaultProps));\n\n const Component = forwardRef(function MediaButton(\n componentProps: Record<string, unknown>,\n forwardedRef: ForwardedRef<HTMLButtonElement>\n ) {\n const { render, className, style, ...rest } = componentProps;\n\n const coreProps: Record<string, unknown> = {};\n const elementProps: Record<string, unknown> = {};\n\n for (const key of Object.keys(rest)) {\n if (corePropKeys.has(key)) {\n coreProps[key] = rest[key];\n } else {\n elementProps[key] = rest[key];\n }\n }\n\n const feature = usePlayer(selector);\n\n const [core] = useState(() => new CoreClass());\n core.setProps(coreProps);\n\n const { getButtonProps, buttonRef } = useButton({\n displayName,\n onActivate: () => action(core, feature!),\n isDisabled: () => !!coreProps.disabled || !feature,\n });\n\n if (!feature) {\n if (__DEV__) logMissingFeature(displayName, selector.displayName ?? displayName);\n return null;\n }\n\n type State = InferComponentState<Core>;\n\n core.setMedia(feature);\n const state = core.getState() as State;\n\n return renderElement(\n 'button',\n { render, className, style } as renderElementFn.ComponentProps<InferComponentState<Core>>,\n {\n state,\n stateAttrMap,\n ref: [forwardedRef, buttonRef],\n props: [core.getAttrs(state), elementProps, getButtonProps()],\n }\n );\n });\n\n Component.displayName = displayName;\n\n return Component as unknown as ForwardRefExoticComponent<Props & RefAttributes<HTMLButtonElement>>;\n}\n"],"mappings":";;;;;;;;;;AAsBA,SAAgB,kBACd,QACqE;CACrE,MAAM,EAAE,aAAa,MAAM,WAAW,cAAc,UAAU,WAAW;CAGzE,MAAM,eAAe,IAAI,IAAI,OAAO,KAAK,UAAU,aAAa,CAAC;CAEjE,MAAM,YAAY,WAAW,SAAS,YACpC,gBACA,cACA;EACA,MAAM,EAAE,QAAQ,WAAW,OAAO,GAAG,SAAS;EAE9C,MAAM,YAAqC,EAAE;EAC7C,MAAM,eAAwC,EAAE;AAEhD,OAAK,MAAM,OAAO,OAAO,KAAK,KAAK,CACjC,KAAI,aAAa,IAAI,IAAI,CACvB,WAAU,OAAO,KAAK;MAEtB,cAAa,OAAO,KAAK;EAI7B,MAAM,UAAU,UAAU,SAAS;EAEnC,MAAM,CAAC,QAAQ,eAAe,IAAI,WAAW,CAAC;AAC9C,OAAK,SAAS,UAAU;EAExB,MAAM,EAAE,gBAAgB,cAAc,UAAU;GAC9C;GACA,kBAAkB,OAAO,MAAM,QAAS;GACxC,kBAAkB,CAAC,CAAC,UAAU,YAAY,CAAC;GAC5C,CAAC;AAEF,MAAI,CAAC,QAEH,QAAO;AAKT,OAAK,SAAS,QAAQ;EACtB,MAAM,QAAQ,KAAK,UAAU;AAE7B,SAAO,cACL,UACA;GAAE;GAAQ;GAAW;GAAO,EAC5B;GACE;GACA;GACA,KAAK,CAAC,cAAc,UAAU;GAC9B,OAAO;IAAC,KAAK,SAAS,MAAM;IAAE;IAAc,gBAAgB;IAAC;GAC9D,CACF;GACD;AAEF,WAAU,cAAc;AAExB,QAAO"}
|
|
@@ -1,42 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { renderElement } from "../../utils/use-render.js";
|
|
5
|
-
import { useButton } from "../hooks/use-button.js";
|
|
3
|
+
import { createMediaButton } from "../create-media-button.js";
|
|
6
4
|
import { selectFullscreen } from "@videojs/core/dom";
|
|
7
|
-
import { forwardRef, useState } from "react";
|
|
8
5
|
import { FullscreenButtonCore, FullscreenButtonDataAttrs } from "@videojs/core";
|
|
9
6
|
|
|
10
7
|
//#region src/ui/fullscreen-button/fullscreen-button.tsx
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
});
|
|
19
|
-
const { getButtonProps, buttonRef } = useButton({
|
|
20
|
-
displayName: "FullscreenButton",
|
|
21
|
-
onActivate: () => core.toggle(fullscreen),
|
|
22
|
-
isDisabled: () => disabled || !fullscreen
|
|
23
|
-
});
|
|
24
|
-
if (!fullscreen) return null;
|
|
25
|
-
const state = core.getState(fullscreen);
|
|
26
|
-
return renderElement("button", {
|
|
27
|
-
render,
|
|
28
|
-
className,
|
|
29
|
-
style
|
|
30
|
-
}, {
|
|
31
|
-
state,
|
|
32
|
-
stateAttrMap: FullscreenButtonDataAttrs,
|
|
33
|
-
ref: [forwardedRef, buttonRef],
|
|
34
|
-
props: [
|
|
35
|
-
core.getAttrs(state),
|
|
36
|
-
elementProps,
|
|
37
|
-
getButtonProps()
|
|
38
|
-
]
|
|
39
|
-
});
|
|
8
|
+
/** A button that toggles fullscreen. */
|
|
9
|
+
const FullscreenButton = createMediaButton({
|
|
10
|
+
displayName: "FullscreenButton",
|
|
11
|
+
core: FullscreenButtonCore,
|
|
12
|
+
stateAttrMap: FullscreenButtonDataAttrs,
|
|
13
|
+
selector: selectFullscreen,
|
|
14
|
+
action: (core, state) => core.toggle(state)
|
|
40
15
|
});
|
|
41
16
|
|
|
42
17
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fullscreen-button.js","names":[],"sources":["../../../../src/ui/fullscreen-button/fullscreen-button.tsx"],"sourcesContent":["'use client';\n\nimport { FullscreenButtonCore, FullscreenButtonDataAttrs } from '@videojs/core';\nimport {
|
|
1
|
+
{"version":3,"file":"fullscreen-button.js","names":[],"sources":["../../../../src/ui/fullscreen-button/fullscreen-button.tsx"],"sourcesContent":["'use client';\n\nimport { FullscreenButtonCore, FullscreenButtonDataAttrs } from '@videojs/core';\nimport { selectFullscreen } from '@videojs/core/dom';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { createMediaButton } from '../create-media-button';\n\nexport interface FullscreenButtonProps\n extends UIComponentProps<'button', FullscreenButtonCore.State>,\n FullscreenButtonCore.Props {}\n\n/** A button that toggles fullscreen. */\nexport const FullscreenButton = createMediaButton<FullscreenButtonCore, FullscreenButtonProps>({\n displayName: 'FullscreenButton',\n core: FullscreenButtonCore,\n stateAttrMap: FullscreenButtonDataAttrs,\n selector: selectFullscreen,\n action: (core, state) => core.toggle(state),\n});\n\nexport namespace FullscreenButton {\n export type Props = FullscreenButtonProps;\n export type State = FullscreenButtonCore.State;\n}\n"],"mappings":";;;;;;;;AAaA,MAAa,mBAAmB,kBAA+D;CAC7F,aAAa;CACb,MAAM;CACN,cAAc;CACd,UAAU;CACV,SAAS,MAAM,UAAU,KAAK,OAAO,MAAM;CAC5C,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useForceRender } from "../../utils/use-force-render.js";
|
|
4
|
+
import { useLatestRef } from "../../utils/use-latest-ref.js";
|
|
5
|
+
import { createSlider } from "@videojs/core/dom";
|
|
6
|
+
import { useSnapshot } from "@videojs/store/react";
|
|
7
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
8
|
+
import { isRTL } from "@videojs/utils/dom";
|
|
9
|
+
|
|
10
|
+
//#region src/ui/hooks/use-slider.ts
|
|
11
|
+
/**
|
|
12
|
+
* Manages slider input lifecycle for React.
|
|
13
|
+
*
|
|
14
|
+
* Wraps `createSlider()` from `@videojs/core/dom` and subscribes to its
|
|
15
|
+
* input state via `useSnapshot`. Returns split props for the root
|
|
16
|
+
* (pointer events) and thumb (keyboard/focus) elements.
|
|
17
|
+
*/
|
|
18
|
+
function useSlider(options) {
|
|
19
|
+
const optionsRef = useLatestRef(options);
|
|
20
|
+
const rootElementRef = useRef(null);
|
|
21
|
+
const thumbElementRef = useRef(null);
|
|
22
|
+
const forceRender = useForceRender();
|
|
23
|
+
const [slider] = useState(() => {
|
|
24
|
+
return createSlider({
|
|
25
|
+
getElement: () => rootElementRef.current,
|
|
26
|
+
getThumbElement: () => thumbElementRef.current,
|
|
27
|
+
getOrientation: () => optionsRef.current.orientation ?? "horizontal",
|
|
28
|
+
isRTL: () => rootElementRef.current ? isRTL(rootElementRef.current) : false,
|
|
29
|
+
isDisabled: () => optionsRef.current.disabled ?? false,
|
|
30
|
+
getPercent: () => optionsRef.current.getPercent(),
|
|
31
|
+
getStepPercent: () => optionsRef.current.getStepPercent(),
|
|
32
|
+
getLargeStepPercent: () => optionsRef.current.getLargeStepPercent(),
|
|
33
|
+
commitThrottle: optionsRef.current.commitThrottle,
|
|
34
|
+
onValueChange: (percent) => optionsRef.current.onValueChange?.(percent),
|
|
35
|
+
onValueCommit: (percent) => optionsRef.current.onValueCommit?.(percent),
|
|
36
|
+
onDragStart: () => optionsRef.current.onDragStart?.(),
|
|
37
|
+
onDragEnd: () => optionsRef.current.onDragEnd?.()
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
useEffect(() => () => slider.destroy(), [slider]);
|
|
41
|
+
const input = useSnapshot(slider.input);
|
|
42
|
+
const state = options.computeState(input);
|
|
43
|
+
useLayoutEffect(() => {
|
|
44
|
+
if (state.thumbAlignment === "edge" && rootElementRef.current && thumbElementRef.current) forceRender();
|
|
45
|
+
}, [state.thumbAlignment]);
|
|
46
|
+
const rootEl = rootElementRef.current;
|
|
47
|
+
const thumbEl = thumbElementRef.current;
|
|
48
|
+
let cssState = state;
|
|
49
|
+
if (state.thumbAlignment === "edge" && rootEl && thumbEl && options.adjustPercent) {
|
|
50
|
+
const isHorizontal = state.orientation === "horizontal";
|
|
51
|
+
const thumbSize = isHorizontal ? thumbEl.offsetWidth : thumbEl.offsetHeight;
|
|
52
|
+
const trackSize = isHorizontal ? rootEl.offsetWidth : rootEl.offsetHeight;
|
|
53
|
+
cssState = {
|
|
54
|
+
...state,
|
|
55
|
+
fillPercent: options.adjustPercent(state.fillPercent, thumbSize, trackSize),
|
|
56
|
+
pointerPercent: options.adjustPercent(state.pointerPercent, thumbSize, trackSize)
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
state,
|
|
61
|
+
cssVars: options.getCSSVars(cssState),
|
|
62
|
+
rootRef: useCallback((element) => {
|
|
63
|
+
rootElementRef.current = element;
|
|
64
|
+
}, []),
|
|
65
|
+
thumbRef: useCallback((element) => {
|
|
66
|
+
thumbElementRef.current = element;
|
|
67
|
+
}, []),
|
|
68
|
+
rootProps: slider.rootProps,
|
|
69
|
+
thumbProps: slider.thumbProps
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//#endregion
|
|
74
|
+
export { useSlider };
|
|
75
|
+
//# sourceMappingURL=use-slider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-slider.js","names":[],"sources":["../../../../src/ui/hooks/use-slider.ts"],"sourcesContent":["'use client';\n\nimport type { SliderInput, SliderState } from '@videojs/core';\nimport {\n createSlider,\n type SliderApi,\n type SliderOptions,\n type SliderRootProps,\n type SliderThumbProps,\n} from '@videojs/core/dom';\nimport { useSnapshot } from '@videojs/store/react';\nimport { isRTL } from '@videojs/utils/dom';\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { useForceRender } from '../../utils/use-force-render';\nimport { useLatestRef } from '../../utils/use-latest-ref';\n\nexport interface UseSliderOptions<State extends SliderState = SliderState>\n extends Pick<\n SliderOptions,\n | 'getPercent'\n | 'getStepPercent'\n | 'getLargeStepPercent'\n | 'commitThrottle'\n | 'onValueChange'\n | 'onValueCommit'\n | 'onDragStart'\n | 'onDragEnd'\n > {\n computeState: (input: SliderInput) => State;\n orientation?: 'horizontal' | 'vertical' | undefined;\n disabled?: boolean | undefined;\n /** Adjust a raw 0–100 percent for thumb alignment. Called for fill and pointer percents. */\n adjustPercent?: ((rawPercent: number, thumbSize: number, trackSize: number) => number) | undefined;\n /** Compute CSS variable map from the (possibly alignment-adjusted) state. */\n getCSSVars: (state: State) => Record<string, string>;\n}\n\nexport interface UseSliderReturnValue<State extends SliderState = SliderState> {\n state: State;\n cssVars: Record<string, string>;\n rootRef: React.RefCallback<HTMLElement>;\n thumbRef: React.RefCallback<HTMLElement>;\n rootProps: SliderRootProps;\n thumbProps: SliderThumbProps;\n}\n\n/**\n * Manages slider input lifecycle for React.\n *\n * Wraps `createSlider()` from `@videojs/core/dom` and subscribes to its\n * input state via `useSnapshot`. Returns split props for the root\n * (pointer events) and thumb (keyboard/focus) elements.\n */\nexport function useSlider<State extends SliderState = SliderState>(\n options: UseSliderOptions<State>\n): UseSliderReturnValue<State> {\n const optionsRef = useLatestRef(options);\n\n const rootElementRef = useRef<HTMLElement | null>(null);\n const thumbElementRef = useRef<HTMLElement | null>(null);\n const forceRender = useForceRender();\n\n // Lazy-init the slider handle. Stable across re-renders.\n const [slider] = useState<SliderApi>(() => {\n const stableOptions: SliderOptions = {\n getElement: () => rootElementRef.current!,\n getThumbElement: () => thumbElementRef.current,\n getOrientation: () => optionsRef.current.orientation ?? 'horizontal',\n isRTL: () => (rootElementRef.current ? isRTL(rootElementRef.current) : false),\n isDisabled: () => optionsRef.current.disabled ?? false,\n getPercent: () => optionsRef.current.getPercent(),\n getStepPercent: () => optionsRef.current.getStepPercent(),\n getLargeStepPercent: () => optionsRef.current.getLargeStepPercent(),\n commitThrottle: optionsRef.current.commitThrottle,\n onValueChange: (percent) => optionsRef.current.onValueChange?.(percent),\n onValueCommit: (percent) => optionsRef.current.onValueCommit?.(percent),\n onDragStart: () => optionsRef.current.onDragStart?.(),\n onDragEnd: () => optionsRef.current.onDragEnd?.(),\n };\n\n return createSlider(stableOptions);\n });\n\n // Cleanup on unmount.\n useEffect(() => () => slider.destroy(), [slider]);\n\n // Subscribe to slider input state.\n const input = useSnapshot(slider.input);\n\n // Compute derived state from input + caller-provided projection.\n const state = options.computeState(input);\n\n // Force a synchronous re-render after mount so edge thumb alignment\n // can read DOM measurements from the now-populated element refs.\n useLayoutEffect(() => {\n if (state.thumbAlignment === 'edge' && rootElementRef.current && thumbElementRef.current) {\n forceRender();\n }\n }, [state.thumbAlignment]);\n\n // Adjust CSS var percents for edge thumb alignment when DOM elements are available.\n const rootEl = rootElementRef.current;\n const thumbEl = thumbElementRef.current;\n let cssState = state;\n\n if (state.thumbAlignment === 'edge' && rootEl && thumbEl && options.adjustPercent) {\n const isHorizontal = state.orientation === 'horizontal';\n const thumbSize = isHorizontal ? thumbEl.offsetWidth : thumbEl.offsetHeight;\n const trackSize = isHorizontal ? rootEl.offsetWidth : rootEl.offsetHeight;\n cssState = {\n ...state,\n fillPercent: options.adjustPercent(state.fillPercent, thumbSize, trackSize),\n pointerPercent: options.adjustPercent(state.pointerPercent, thumbSize, trackSize),\n };\n }\n\n const cssVars = options.getCSSVars(cssState);\n\n // Ref callbacks for root and thumb elements.\n const rootRef = useCallback((element: HTMLElement | null) => {\n rootElementRef.current = element;\n }, []);\n\n const thumbRef = useCallback((element: HTMLElement | null) => {\n thumbElementRef.current = element;\n }, []);\n\n return {\n state,\n cssVars,\n rootRef,\n thumbRef,\n rootProps: slider.rootProps,\n thumbProps: slider.thumbProps,\n };\n}\n\nexport namespace useSlider {\n export type Options = UseSliderOptions;\n export type ReturnValue = UseSliderReturnValue;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAqDA,SAAgB,UACd,SAC6B;CAC7B,MAAM,aAAa,aAAa,QAAQ;CAExC,MAAM,iBAAiB,OAA2B,KAAK;CACvD,MAAM,kBAAkB,OAA2B,KAAK;CACxD,MAAM,cAAc,gBAAgB;CAGpC,MAAM,CAAC,UAAU,eAA0B;AAiBzC,SAAO,aAhB8B;GACnC,kBAAkB,eAAe;GACjC,uBAAuB,gBAAgB;GACvC,sBAAsB,WAAW,QAAQ,eAAe;GACxD,aAAc,eAAe,UAAU,MAAM,eAAe,QAAQ,GAAG;GACvE,kBAAkB,WAAW,QAAQ,YAAY;GACjD,kBAAkB,WAAW,QAAQ,YAAY;GACjD,sBAAsB,WAAW,QAAQ,gBAAgB;GACzD,2BAA2B,WAAW,QAAQ,qBAAqB;GACnE,gBAAgB,WAAW,QAAQ;GACnC,gBAAgB,YAAY,WAAW,QAAQ,gBAAgB,QAAQ;GACvE,gBAAgB,YAAY,WAAW,QAAQ,gBAAgB,QAAQ;GACvE,mBAAmB,WAAW,QAAQ,eAAe;GACrD,iBAAiB,WAAW,QAAQ,aAAa;GAClD,CAEiC;GAClC;AAGF,uBAAsB,OAAO,SAAS,EAAE,CAAC,OAAO,CAAC;CAGjD,MAAM,QAAQ,YAAY,OAAO,MAAM;CAGvC,MAAM,QAAQ,QAAQ,aAAa,MAAM;AAIzC,uBAAsB;AACpB,MAAI,MAAM,mBAAmB,UAAU,eAAe,WAAW,gBAAgB,QAC/E,cAAa;IAEd,CAAC,MAAM,eAAe,CAAC;CAG1B,MAAM,SAAS,eAAe;CAC9B,MAAM,UAAU,gBAAgB;CAChC,IAAI,WAAW;AAEf,KAAI,MAAM,mBAAmB,UAAU,UAAU,WAAW,QAAQ,eAAe;EACjF,MAAM,eAAe,MAAM,gBAAgB;EAC3C,MAAM,YAAY,eAAe,QAAQ,cAAc,QAAQ;EAC/D,MAAM,YAAY,eAAe,OAAO,cAAc,OAAO;AAC7D,aAAW;GACT,GAAG;GACH,aAAa,QAAQ,cAAc,MAAM,aAAa,WAAW,UAAU;GAC3E,gBAAgB,QAAQ,cAAc,MAAM,gBAAgB,WAAW,UAAU;GAClF;;AAcH,QAAO;EACL;EACA,SAbc,QAAQ,WAAW,SAAS;EAc1C,SAXc,aAAa,YAAgC;AAC3D,kBAAe,UAAU;KACxB,EAAE,CAAC;EAUJ,UARe,aAAa,YAAgC;AAC5D,mBAAgB,UAAU;KACzB,EAAE,CAAC;EAOJ,WAAW,OAAO;EAClB,YAAY,OAAO;EACpB"}
|
|
@@ -1,45 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { renderElement } from "../../utils/use-render.js";
|
|
5
|
-
import { useButton } from "../hooks/use-button.js";
|
|
3
|
+
import { createMediaButton } from "../create-media-button.js";
|
|
6
4
|
import { selectVolume } from "@videojs/core/dom";
|
|
7
|
-
import { forwardRef, useState } from "react";
|
|
8
5
|
import { MuteButtonCore, MuteButtonDataAttrs } from "@videojs/core";
|
|
9
6
|
|
|
10
7
|
//#region src/ui/mute-button/mute-button.tsx
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
core.setProps({
|
|
19
|
-
label,
|
|
20
|
-
disabled
|
|
21
|
-
});
|
|
22
|
-
const { getButtonProps, buttonRef } = useButton({
|
|
23
|
-
displayName: "MuteButton",
|
|
24
|
-
onActivate: () => core.toggle(volume),
|
|
25
|
-
isDisabled: () => disabled || !volume
|
|
26
|
-
});
|
|
27
|
-
if (!volume) return null;
|
|
28
|
-
const state = core.getState(volume);
|
|
29
|
-
return renderElement("button", {
|
|
30
|
-
render,
|
|
31
|
-
className,
|
|
32
|
-
style
|
|
33
|
-
}, {
|
|
34
|
-
state,
|
|
35
|
-
stateAttrMap: MuteButtonDataAttrs,
|
|
36
|
-
ref: [forwardedRef, buttonRef],
|
|
37
|
-
props: [
|
|
38
|
-
core.getAttrs(state),
|
|
39
|
-
elementProps,
|
|
40
|
-
getButtonProps()
|
|
41
|
-
]
|
|
42
|
-
});
|
|
8
|
+
/** A button that toggles mute state. */
|
|
9
|
+
const MuteButton = createMediaButton({
|
|
10
|
+
displayName: "MuteButton",
|
|
11
|
+
core: MuteButtonCore,
|
|
12
|
+
stateAttrMap: MuteButtonDataAttrs,
|
|
13
|
+
selector: selectVolume,
|
|
14
|
+
action: (core, state) => core.toggle(state)
|
|
43
15
|
});
|
|
44
16
|
|
|
45
17
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mute-button.js","names":[],"sources":["../../../../src/ui/mute-button/mute-button.tsx"],"sourcesContent":["'use client';\n\nimport { MuteButtonCore, MuteButtonDataAttrs } from '@videojs/core';\nimport {
|
|
1
|
+
{"version":3,"file":"mute-button.js","names":[],"sources":["../../../../src/ui/mute-button/mute-button.tsx"],"sourcesContent":["'use client';\n\nimport { MuteButtonCore, MuteButtonDataAttrs } from '@videojs/core';\nimport { selectVolume } from '@videojs/core/dom';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { createMediaButton } from '../create-media-button';\n\nexport interface MuteButtonProps extends UIComponentProps<'button', MuteButtonCore.State>, MuteButtonCore.Props {}\n\n/** A button that toggles mute state. */\nexport const MuteButton = createMediaButton<MuteButtonCore, MuteButtonProps>({\n displayName: 'MuteButton',\n core: MuteButtonCore,\n stateAttrMap: MuteButtonDataAttrs,\n selector: selectVolume,\n action: (core, state) => core.toggle(state),\n});\n\nexport namespace MuteButton {\n export type Props = MuteButtonProps;\n export type State = MuteButtonCore.State;\n}\n"],"mappings":";;;;;;;;AAWA,MAAa,aAAa,kBAAmD;CAC3E,aAAa;CACb,MAAM;CACN,cAAc;CACd,UAAU;CACV,SAAS,MAAM,UAAU,KAAK,OAAO,MAAM;CAC5C,CAAC"}
|
|
@@ -1,42 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { renderElement } from "../../utils/use-render.js";
|
|
5
|
-
import { useButton } from "../hooks/use-button.js";
|
|
3
|
+
import { createMediaButton } from "../create-media-button.js";
|
|
6
4
|
import { selectPiP } from "@videojs/core/dom";
|
|
7
|
-
import { forwardRef, useState } from "react";
|
|
8
5
|
import { PiPButtonCore, PiPButtonDataAttrs } from "@videojs/core";
|
|
9
6
|
|
|
10
7
|
//#region src/ui/pip-button/pip-button.tsx
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
});
|
|
19
|
-
const { getButtonProps, buttonRef } = useButton({
|
|
20
|
-
displayName: "PiPButton",
|
|
21
|
-
onActivate: () => core.toggle(pip),
|
|
22
|
-
isDisabled: () => disabled || !pip
|
|
23
|
-
});
|
|
24
|
-
if (!pip) return null;
|
|
25
|
-
const state = core.getState(pip);
|
|
26
|
-
return renderElement("button", {
|
|
27
|
-
render,
|
|
28
|
-
className,
|
|
29
|
-
style
|
|
30
|
-
}, {
|
|
31
|
-
state,
|
|
32
|
-
stateAttrMap: PiPButtonDataAttrs,
|
|
33
|
-
ref: [forwardedRef, buttonRef],
|
|
34
|
-
props: [
|
|
35
|
-
core.getAttrs(state),
|
|
36
|
-
elementProps,
|
|
37
|
-
getButtonProps()
|
|
38
|
-
]
|
|
39
|
-
});
|
|
8
|
+
/** A button that toggles picture-in-picture. */
|
|
9
|
+
const PiPButton = createMediaButton({
|
|
10
|
+
displayName: "PiPButton",
|
|
11
|
+
core: PiPButtonCore,
|
|
12
|
+
stateAttrMap: PiPButtonDataAttrs,
|
|
13
|
+
selector: selectPiP,
|
|
14
|
+
action: (core, state) => core.toggle(state)
|
|
40
15
|
});
|
|
41
16
|
|
|
42
17
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pip-button.js","names":[],"sources":["../../../../src/ui/pip-button/pip-button.tsx"],"sourcesContent":["'use client';\n\nimport { PiPButtonCore, PiPButtonDataAttrs } from '@videojs/core';\nimport {
|
|
1
|
+
{"version":3,"file":"pip-button.js","names":[],"sources":["../../../../src/ui/pip-button/pip-button.tsx"],"sourcesContent":["'use client';\n\nimport { PiPButtonCore, PiPButtonDataAttrs } from '@videojs/core';\nimport { selectPiP } from '@videojs/core/dom';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { createMediaButton } from '../create-media-button';\n\nexport interface PiPButtonProps extends UIComponentProps<'button', PiPButtonCore.State>, PiPButtonCore.Props {}\n\n/** A button that toggles picture-in-picture. */\nexport const PiPButton = createMediaButton<PiPButtonCore, PiPButtonProps>({\n displayName: 'PiPButton',\n core: PiPButtonCore,\n stateAttrMap: PiPButtonDataAttrs,\n selector: selectPiP,\n action: (core, state) => core.toggle(state),\n});\n\nexport namespace PiPButton {\n export type Props = PiPButtonProps;\n export type State = PiPButtonCore.State;\n}\n"],"mappings":";;;;;;;;AAWA,MAAa,YAAY,kBAAiD;CACxE,aAAa;CACb,MAAM;CACN,cAAc;CACd,UAAU;CACV,SAAS,MAAM,UAAU,KAAK,OAAO,MAAM;CAC5C,CAAC"}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { renderElement } from "../../utils/use-render.js";
|
|
5
|
-
import { useButton } from "../hooks/use-button.js";
|
|
3
|
+
import { createMediaButton } from "../create-media-button.js";
|
|
6
4
|
import { selectPlayback } from "@videojs/core/dom";
|
|
7
|
-
import { forwardRef, useState } from "react";
|
|
8
5
|
import { PlayButtonCore, PlayButtonDataAttrs } from "@videojs/core";
|
|
9
6
|
|
|
10
7
|
//#region src/ui/play-button/play-button.tsx
|
|
@@ -24,35 +21,12 @@ import { PlayButtonCore, PlayButtonDataAttrs } from "@videojs/core";
|
|
|
24
21
|
* />
|
|
25
22
|
* ```
|
|
26
23
|
*/
|
|
27
|
-
const PlayButton =
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
disabled
|
|
34
|
-
});
|
|
35
|
-
const { getButtonProps, buttonRef } = useButton({
|
|
36
|
-
displayName: "PlayButton",
|
|
37
|
-
onActivate: () => core.toggle(playback),
|
|
38
|
-
isDisabled: () => disabled || !playback
|
|
39
|
-
});
|
|
40
|
-
if (!playback) return null;
|
|
41
|
-
const state = core.getState(playback);
|
|
42
|
-
return renderElement("button", {
|
|
43
|
-
render,
|
|
44
|
-
className,
|
|
45
|
-
style
|
|
46
|
-
}, {
|
|
47
|
-
state,
|
|
48
|
-
stateAttrMap: PlayButtonDataAttrs,
|
|
49
|
-
ref: [forwardedRef, buttonRef],
|
|
50
|
-
props: [
|
|
51
|
-
core.getAttrs(state),
|
|
52
|
-
elementProps,
|
|
53
|
-
getButtonProps()
|
|
54
|
-
]
|
|
55
|
-
});
|
|
24
|
+
const PlayButton = createMediaButton({
|
|
25
|
+
displayName: "PlayButton",
|
|
26
|
+
core: PlayButtonCore,
|
|
27
|
+
stateAttrMap: PlayButtonDataAttrs,
|
|
28
|
+
selector: selectPlayback,
|
|
29
|
+
action: (core, state) => core.toggle(state)
|
|
56
30
|
});
|
|
57
31
|
|
|
58
32
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"play-button.js","names":[],"sources":["../../../../src/ui/play-button/play-button.tsx"],"sourcesContent":["'use client';\n\nimport { PlayButtonCore, PlayButtonDataAttrs } from '@videojs/core';\nimport {
|
|
1
|
+
{"version":3,"file":"play-button.js","names":[],"sources":["../../../../src/ui/play-button/play-button.tsx"],"sourcesContent":["'use client';\n\nimport { PlayButtonCore, PlayButtonDataAttrs } from '@videojs/core';\nimport { selectPlayback } from '@videojs/core/dom';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { createMediaButton } from '../create-media-button';\n\nexport interface PlayButtonProps extends UIComponentProps<'button', PlayButtonCore.State>, PlayButtonCore.Props {}\n\n/**\n * A button that toggles playback.\n *\n * @example\n * ```tsx\n * <PlayButton />\n *\n * <PlayButton\n * render={(props, state) => (\n * <button {...props}>\n * {state.paused ? <PlayIcon /> : <PauseIcon />}\n * </button>\n * )}\n * />\n * ```\n */\nexport const PlayButton = createMediaButton<PlayButtonCore, PlayButtonProps>({\n displayName: 'PlayButton',\n core: PlayButtonCore,\n stateAttrMap: PlayButtonDataAttrs,\n selector: selectPlayback,\n action: (core, state) => core.toggle(state),\n});\n\nexport namespace PlayButton {\n export type Props = PlayButtonProps;\n export type State = PlayButtonCore.State;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAa,aAAa,kBAAmD;CAC3E,aAAa;CACb,MAAM;CACN,cAAc;CACd,UAAU;CACV,SAAS,MAAM,UAAU,KAAK,OAAO,MAAM;CAC5C,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { createMediaButton } from "../create-media-button.js";
|
|
4
|
+
import { selectPlaybackRate } from "@videojs/core/dom";
|
|
5
|
+
import { PlaybackRateButtonCore, PlaybackRateButtonDataAttrs } from "@videojs/core";
|
|
6
|
+
|
|
7
|
+
//#region src/ui/playback-rate-button/playback-rate-button.tsx
|
|
8
|
+
/**
|
|
9
|
+
* A button that cycles through playback rates.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <PlaybackRateButton />
|
|
14
|
+
*
|
|
15
|
+
* <PlaybackRateButton
|
|
16
|
+
* render={(props, state) => (
|
|
17
|
+
* <button {...props}>
|
|
18
|
+
* {state.rate}×
|
|
19
|
+
* </button>
|
|
20
|
+
* )}
|
|
21
|
+
* />
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
const PlaybackRateButton = createMediaButton({
|
|
25
|
+
displayName: "PlaybackRateButton",
|
|
26
|
+
core: PlaybackRateButtonCore,
|
|
27
|
+
stateAttrMap: PlaybackRateButtonDataAttrs,
|
|
28
|
+
selector: selectPlaybackRate,
|
|
29
|
+
action: (core, state) => core.cycle(state)
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
export { PlaybackRateButton };
|
|
34
|
+
//# sourceMappingURL=playback-rate-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playback-rate-button.js","names":[],"sources":["../../../../src/ui/playback-rate-button/playback-rate-button.tsx"],"sourcesContent":["'use client';\n\nimport { PlaybackRateButtonCore, PlaybackRateButtonDataAttrs } from '@videojs/core';\nimport { selectPlaybackRate } from '@videojs/core/dom';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { createMediaButton } from '../create-media-button';\n\nexport interface PlaybackRateButtonProps\n extends UIComponentProps<'button', PlaybackRateButtonCore.State>,\n PlaybackRateButtonCore.Props {}\n\n/**\n * A button that cycles through playback rates.\n *\n * @example\n * ```tsx\n * <PlaybackRateButton />\n *\n * <PlaybackRateButton\n * render={(props, state) => (\n * <button {...props}>\n * {state.rate}×\n * </button>\n * )}\n * />\n * ```\n */\nexport const PlaybackRateButton = createMediaButton<PlaybackRateButtonCore, PlaybackRateButtonProps>({\n displayName: 'PlaybackRateButton',\n core: PlaybackRateButtonCore,\n stateAttrMap: PlaybackRateButtonDataAttrs,\n selector: selectPlaybackRate,\n action: (core, state) => core.cycle(state),\n});\n\nexport namespace PlaybackRateButton {\n export type Props = PlaybackRateButtonProps;\n export type State = PlaybackRateButtonCore.State;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA4BA,MAAa,qBAAqB,kBAAmE;CACnG,aAAa;CACb,MAAM;CACN,cAAc;CACd,UAAU;CACV,SAAS,MAAM,UAAU,KAAK,MAAM,MAAM;CAC3C,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/ui/popover/context.tsx
|
|
6
|
+
const PopoverContext = createContext(null);
|
|
7
|
+
const PopoverContextProvider = PopoverContext.Provider;
|
|
8
|
+
function usePopoverContext() {
|
|
9
|
+
const ctx = useContext(PopoverContext);
|
|
10
|
+
if (!ctx) throw new Error("Popover compound components must be used within a Popover.Root");
|
|
11
|
+
return ctx;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
export { PopoverContextProvider, usePopoverContext };
|
|
16
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","names":[],"sources":["../../../../src/ui/popover/context.tsx"],"sourcesContent":["'use client';\n\nimport type { PopoverCore, StateAttrMap } from '@videojs/core';\nimport type { PopoverApi } from '@videojs/core/dom';\nimport { createContext, useContext } from 'react';\n\nexport interface PopoverContextValue {\n core: PopoverCore;\n popover: PopoverApi;\n state: PopoverCore.State;\n stateAttrMap: StateAttrMap<PopoverCore.State>;\n anchorName: string;\n popupId: string;\n}\n\nconst PopoverContext = createContext<PopoverContextValue | null>(null);\n\nexport const PopoverContextProvider = PopoverContext.Provider;\n\nexport function usePopoverContext(): PopoverContextValue {\n const ctx = useContext(PopoverContext);\n if (!ctx) throw new Error('Popover compound components must be used within a Popover.Root');\n return ctx;\n}\n"],"mappings":";;;;;AAeA,MAAM,iBAAiB,cAA0C,KAAK;AAEtE,MAAa,yBAAyB,eAAe;AAErD,SAAgB,oBAAyC;CACvD,MAAM,MAAM,WAAW,eAAe;AACtC,KAAI,CAAC,IAAK,OAAM,IAAI,MAAM,iEAAiE;AAC3F,QAAO"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { PopoverArrow } from "./popover-arrow.js";
|
|
3
|
+
import { PopoverPopup } from "./popover-popup.js";
|
|
4
|
+
import { PopoverRoot } from "./popover-root.js";
|
|
5
|
+
import { PopoverTrigger } from "./popover-trigger.js";
|
|
6
|
+
|
|
7
|
+
//#region src/ui/popover/index.parts.ts
|
|
8
|
+
var index_parts_exports = /* @__PURE__ */ __exportAll({
|
|
9
|
+
Arrow: () => PopoverArrow,
|
|
10
|
+
Popup: () => PopoverPopup,
|
|
11
|
+
Root: () => PopoverRoot,
|
|
12
|
+
Trigger: () => PopoverTrigger
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { index_parts_exports };
|
|
17
|
+
//# sourceMappingURL=index.parts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.parts.js","names":[],"sources":["../../../../src/ui/popover/index.parts.ts"],"sourcesContent":["export { PopoverArrow as Arrow, type PopoverArrowProps as ArrowProps } from './popover-arrow';\nexport { PopoverPopup as Popup, type PopoverPopupProps as PopupProps } from './popover-popup';\nexport { PopoverRoot as Root, type PopoverRootProps as RootProps } from './popover-root';\nexport { PopoverTrigger as Trigger, type PopoverTriggerProps as TriggerProps } from './popover-trigger';\n"],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { usePopoverContext } from "./context.js";
|
|
4
|
+
import { createContextPart } from "../create-context-part.js";
|
|
5
|
+
|
|
6
|
+
//#region src/ui/popover/popover-arrow.tsx
|
|
7
|
+
/** Decorative arrow pointing from the popup toward the trigger. Hidden from assistive technology. */
|
|
8
|
+
const PopoverArrow = createContextPart({
|
|
9
|
+
displayName: "PopoverArrow",
|
|
10
|
+
tag: "div",
|
|
11
|
+
useContext: usePopoverContext,
|
|
12
|
+
staticProps: { "aria-hidden": "true" }
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { PopoverArrow };
|
|
17
|
+
//# sourceMappingURL=popover-arrow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"popover-arrow.js","names":[],"sources":["../../../../src/ui/popover/popover-arrow.tsx"],"sourcesContent":["'use client';\n\nimport type { PopoverState } from '@videojs/core';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { createContextPart } from '../create-context-part';\nimport { usePopoverContext } from './context';\n\nexport interface PopoverArrowProps extends UIComponentProps<'div', PopoverState> {}\n\n/** Decorative arrow pointing from the popup toward the trigger. Hidden from assistive technology. */\nexport const PopoverArrow = createContextPart<PopoverArrowProps, PopoverState>({\n displayName: 'PopoverArrow',\n tag: 'div',\n useContext: usePopoverContext,\n staticProps: { 'aria-hidden': 'true' as const },\n});\n\nexport namespace PopoverArrow {\n export type Props = PopoverArrowProps;\n export type State = PopoverState;\n}\n"],"mappings":";;;;;;;AAWA,MAAa,eAAe,kBAAmD;CAC7E,aAAa;CACb,KAAK;CACL,YAAY;CACZ,aAAa,EAAE,eAAe,QAAiB;CAChD,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useComposedRefs } from "../../utils/use-composed-refs.js";
|
|
4
|
+
import { renderElement } from "../../utils/use-render.js";
|
|
5
|
+
import { usePopoverContext } from "./context.js";
|
|
6
|
+
import { getAnchorPositionStyle, resolveOffsets } from "@videojs/core/dom";
|
|
7
|
+
import { forwardRef, useCallback, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
8
|
+
import { supportsAnchorPositioning } from "@videojs/utils/dom";
|
|
9
|
+
|
|
10
|
+
//#region src/ui/popover/popover-popup.tsx
|
|
11
|
+
const POPOVER_RESET = {
|
|
12
|
+
position: "fixed",
|
|
13
|
+
inset: "auto",
|
|
14
|
+
margin: 0
|
|
15
|
+
};
|
|
16
|
+
/** Container for the popover content. Positioned relative to the trigger using CSS anchor positioning with a JavaScript fallback. */
|
|
17
|
+
const PopoverPopup = forwardRef(function PopoverPopup({ render, className, style, ...elementProps }, forwardedRef) {
|
|
18
|
+
const { core, popover, state, stateAttrMap, anchorName, popupId } = usePopoverContext();
|
|
19
|
+
const internalRef = useRef(null);
|
|
20
|
+
const composedRef = useComposedRefs(forwardedRef, useCallback((el) => {
|
|
21
|
+
popover.setPopupElement(el);
|
|
22
|
+
}, [popover]), internalRef);
|
|
23
|
+
const posOpts = useMemo(() => ({
|
|
24
|
+
side: state.side,
|
|
25
|
+
align: state.align
|
|
26
|
+
}), [state.side, state.align]);
|
|
27
|
+
const anchorStyle = useMemo(() => {
|
|
28
|
+
if (!supportsAnchorPositioning()) return null;
|
|
29
|
+
return getAnchorPositionStyle(anchorName, posOpts);
|
|
30
|
+
}, [anchorName, posOpts]);
|
|
31
|
+
const [manualStyle, setManualStyle] = useState(null);
|
|
32
|
+
useLayoutEffect(() => {
|
|
33
|
+
if (supportsAnchorPositioning()) return;
|
|
34
|
+
if (!state.open) {
|
|
35
|
+
setManualStyle(null);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
function measure() {
|
|
39
|
+
const triggerEl = popover.triggerElement;
|
|
40
|
+
const popupEl = internalRef.current;
|
|
41
|
+
if (!triggerEl || !popupEl) return;
|
|
42
|
+
setManualStyle(getAnchorPositionStyle(anchorName, posOpts, triggerEl.getBoundingClientRect(), popupEl.getBoundingClientRect(), document.documentElement.getBoundingClientRect(), resolveOffsets(popupEl)));
|
|
43
|
+
}
|
|
44
|
+
measure();
|
|
45
|
+
let rafId = 0;
|
|
46
|
+
function reposition() {
|
|
47
|
+
cancelAnimationFrame(rafId);
|
|
48
|
+
rafId = requestAnimationFrame(measure);
|
|
49
|
+
}
|
|
50
|
+
window.addEventListener("scroll", reposition, {
|
|
51
|
+
capture: true,
|
|
52
|
+
passive: true
|
|
53
|
+
});
|
|
54
|
+
window.addEventListener("resize", reposition);
|
|
55
|
+
return () => {
|
|
56
|
+
cancelAnimationFrame(rafId);
|
|
57
|
+
window.removeEventListener("scroll", reposition, true);
|
|
58
|
+
window.removeEventListener("resize", reposition);
|
|
59
|
+
};
|
|
60
|
+
}, [
|
|
61
|
+
state.open,
|
|
62
|
+
anchorName,
|
|
63
|
+
posOpts,
|
|
64
|
+
popover
|
|
65
|
+
]);
|
|
66
|
+
const positioningStyle = anchorStyle ?? manualStyle ?? POPOVER_RESET;
|
|
67
|
+
if (!state.open) return null;
|
|
68
|
+
const { onFocusOut, ...restPopupProps } = popover.popupProps;
|
|
69
|
+
return renderElement("div", {
|
|
70
|
+
render,
|
|
71
|
+
className,
|
|
72
|
+
style
|
|
73
|
+
}, {
|
|
74
|
+
state,
|
|
75
|
+
stateAttrMap,
|
|
76
|
+
ref: composedRef,
|
|
77
|
+
props: [
|
|
78
|
+
{
|
|
79
|
+
id: popupId,
|
|
80
|
+
style: positioningStyle,
|
|
81
|
+
...core.getPopupAttrs(state)
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
...restPopupProps,
|
|
85
|
+
onBlur: onFocusOut
|
|
86
|
+
},
|
|
87
|
+
elementProps
|
|
88
|
+
]
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
//#endregion
|
|
93
|
+
export { PopoverPopup };
|
|
94
|
+
//# sourceMappingURL=popover-popup.js.map
|