@dskripchenko/ui 1.13.0 → 1.15.0
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/README.md +5 -2
- package/dist/components/Audio/UidAudio.vue.d.ts +127 -0
- package/dist/components/Audio/index.d.ts +2 -0
- package/dist/components/Gauge/UidGauge.vue.d.ts +1 -1
- package/dist/components/Grid/UidGrid.vue.d.ts +1 -1
- package/dist/components/Markdown/UidMarkdownLiveBlock.vue.d.ts +10 -0
- package/dist/components/Markdown/blockRenderers.d.ts +21 -0
- package/dist/components/Markdown/index.d.ts +1 -1
- package/dist/components/Media/UidMediaMenu.vue.d.ts +63 -0
- package/dist/components/Media/UidMediaScrubber.vue.d.ts +38 -0
- package/dist/components/Media/index.d.ts +6 -0
- package/dist/components/Media/mediaUtils.d.ts +47 -0
- package/dist/components/Media/useMediaController.d.ts +80 -0
- package/dist/components/Media/useMediaLocale.d.ts +3 -0
- package/dist/components/Media/waveform.d.ts +27 -0
- package/dist/components/Menu/UidMenu.vue.d.ts +17 -3
- package/dist/components/Pagination/UidPaginationCursor.vue.d.ts +2 -2
- package/dist/components/Progress/UidProgress.vue.d.ts +1 -1
- package/dist/components/ProgressRing/UidProgressRing.vue.d.ts +1 -1
- package/dist/components/Stack/UidStack.vue.d.ts +1 -1
- package/dist/components/Video/UidVideo.vue.d.ts +106 -0
- package/dist/components/Video/index.d.ts +2 -0
- package/dist/composables/useLocale.d.ts +2 -1
- package/dist/hls/abr.d.ts +36 -0
- package/dist/hls/aes.d.ts +5 -0
- package/dist/hls/engine.d.ts +86 -0
- package/dist/hls/index.cjs +3 -0
- package/dist/hls/index.d.ts +11 -0
- package/dist/hls/index.mjs +1500 -0
- package/dist/hls/mp4.d.ts +21 -0
- package/dist/hls/playlist.d.ts +76 -0
- package/dist/hls/transmux.d.ts +27 -0
- package/dist/hls/ts/adts.d.ts +16 -0
- package/dist/hls/ts/demux.d.ts +26 -0
- package/dist/hls/ts/h264.d.ts +30 -0
- package/dist/hls/ts/id3.d.ts +10 -0
- package/dist/hls/ts/mp4mux.d.ts +32 -0
- package/dist/hls/ts/transmuxer.d.ts +22 -0
- package/dist/index.cjs +12 -8
- package/dist/index.d.ts +7 -1
- package/dist/index.mjs +4537 -2398
- package/dist/locales/index.d.ts +1 -1
- package/dist/locales/types.d.ts +46 -0
- package/dist/styles/all.css +1 -1
- package/dist/styles/index.css +1 -1
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@ A Vue 3 component, token, and theme library on CSS custom properties.
|
|
|
23
23
|
- **i18n** — built-in `ru` + `en` locales, `UidLocaleProvider` for partial overrides or custom locales
|
|
24
24
|
- **~1500 icons** — `lucide-vue-next` under the hood + `@dskripchenko/ui/icons` sub-export
|
|
25
25
|
- **Zero runtime chart deps** — built-in SVG primitives (Sparkline, ProgressRing, Gauge, Heatmap)
|
|
26
|
+
- **Media players without dependencies** — video and audio on the native elements, in-browser waveform, HLS (fMP4 and MPEG-TS) in a lazily loaded entry
|
|
26
27
|
|
|
27
28
|
## Install
|
|
28
29
|
|
|
@@ -95,19 +96,21 @@ A short selection — the full catalog is in [Storybook](https://dskripchenko.gi
|
|
|
95
96
|
|
|
96
97
|
**Charts:** Sparkline, ProgressRing, Gauge, Heatmap
|
|
97
98
|
|
|
99
|
+
**Media:** Video, Audio (waveform, mini, playlist), HLS adapter (`@dskripchenko/ui/hls`)
|
|
100
|
+
|
|
98
101
|
**Wizards:** Stepper, Wizard, WizardStep
|
|
99
102
|
|
|
100
103
|
**Patterns:** Header, Footer, Sidebar, PageHeader, EmptyState, ErrorState, Result
|
|
101
104
|
|
|
102
105
|
**Layouts:** SimpleLayout, SidebarLayout, AuthLayout, WizardLayout
|
|
103
106
|
|
|
104
|
-
**Composables:** useTheme, useLocale, useField, useToast, useWizard, useSidebar, useCommandPalette, useFocusTrap, useScrollLock, usePopover
|
|
107
|
+
**Composables:** useMediaController, useTheme, useLocale, useField, useToast, useWizard, useSidebar, useCommandPalette, useFocusTrap, useScrollLock, usePopover
|
|
105
108
|
|
|
106
109
|
## Documentation
|
|
107
110
|
|
|
108
111
|
User docs are translated into four languages — pick yours:
|
|
109
112
|
|
|
110
|
-
- 🇬🇧 **English** (default): [getting-started](./docs/en/getting-started.md), [theming](./docs/en/theming.md), [tokens](./docs/en/tokens.md), [icons](./docs/en/icons.md), [patterns](./docs/en/patterns.md), [validation](./docs/en/validation.md), [charts](./docs/en/charts.md), [markdown](./docs/en/markdown.md), [i18n](./docs/en/i18n.md)
|
|
113
|
+
- 🇬🇧 **English** (default): [getting-started](./docs/en/getting-started.md), [theming](./docs/en/theming.md), [tokens](./docs/en/tokens.md), [icons](./docs/en/icons.md), [patterns](./docs/en/patterns.md), [validation](./docs/en/validation.md), [charts](./docs/en/charts.md), [markdown](./docs/en/markdown.md), [video](./docs/en/video.md), [audio](./docs/en/audio.md), [i18n](./docs/en/i18n.md)
|
|
111
114
|
- 🇷🇺 **Русский**: [docs/ru/](./docs/ru/)
|
|
112
115
|
- 🇩🇪 **Deutsch**: [docs/de/](./docs/de/)
|
|
113
116
|
- 🇨🇳 **中文**: [docs/zh/](./docs/zh/)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { UidMediaErrorInfo } from '../Media/useMediaController.js';
|
|
2
|
+
import { HlsOptions } from '../../hls/index.js';
|
|
3
|
+
import { UidHlsModule } from '../Video/UidVideo.vue';
|
|
4
|
+
export interface UidAudioTrack {
|
|
5
|
+
src: string;
|
|
6
|
+
type?: string;
|
|
7
|
+
title?: string;
|
|
8
|
+
artist?: string;
|
|
9
|
+
/** Precomputed waveform peaks (0..1). */
|
|
10
|
+
peaks?: number[];
|
|
11
|
+
/** Known duration in seconds, shown in the playlist before metadata loads. */
|
|
12
|
+
duration?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface UidAudioProps {
|
|
15
|
+
src?: string;
|
|
16
|
+
type?: string;
|
|
17
|
+
title?: string;
|
|
18
|
+
artist?: string;
|
|
19
|
+
/** Playlist: next / previous buttons, a track list and auto-advance. */
|
|
20
|
+
tracks?: UidAudioTrack[];
|
|
21
|
+
/** `mini` — a compact inline player for tables and lists. */
|
|
22
|
+
variant?: 'default' | 'mini';
|
|
23
|
+
/** Draws the waveform as the scrub bar, decoded in the browser. */
|
|
24
|
+
waveform?: boolean;
|
|
25
|
+
/** Precomputed peaks (0..1); implies the waveform without decoding. */
|
|
26
|
+
peaks?: number[];
|
|
27
|
+
/** Files larger than this are not decoded for the waveform (bytes). */
|
|
28
|
+
waveformMaxBytes?: number;
|
|
29
|
+
/** Audio longer than this is not decoded for the waveform (seconds). */
|
|
30
|
+
waveformMaxDuration?: number;
|
|
31
|
+
/** Plays the next playlist track when one ends. */
|
|
32
|
+
autoAdvance?: boolean;
|
|
33
|
+
/** Repeats the track, or the whole playlist. */
|
|
34
|
+
loop?: boolean;
|
|
35
|
+
preload?: 'none' | 'metadata' | 'auto';
|
|
36
|
+
crossorigin?: '' | 'anonymous' | 'use-credentials';
|
|
37
|
+
exclusive?: boolean;
|
|
38
|
+
resumeKey?: string;
|
|
39
|
+
rates?: number[];
|
|
40
|
+
hotkeys?: boolean;
|
|
41
|
+
showVolume?: boolean;
|
|
42
|
+
showRate?: boolean;
|
|
43
|
+
/** Shows the track list in playlist mode. */
|
|
44
|
+
showPlaylist?: boolean;
|
|
45
|
+
hlsOptions?: Omit<HlsOptions, 'onError'>;
|
|
46
|
+
/** Loads the HLS adapter for `.m3u8` sources; defaults to the lazily imported `@dskripchenko/ui/hls`. */
|
|
47
|
+
hlsLoader?: () => Promise<UidHlsModule>;
|
|
48
|
+
}
|
|
49
|
+
type __VLS_Props = UidAudioProps;
|
|
50
|
+
declare function prev(): void;
|
|
51
|
+
declare function next(): void;
|
|
52
|
+
type __VLS_PublicProps = {
|
|
53
|
+
'index'?: number;
|
|
54
|
+
} & __VLS_Props;
|
|
55
|
+
declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {
|
|
56
|
+
play: () => Promise<void>;
|
|
57
|
+
pause: () => void;
|
|
58
|
+
toggle: () => void;
|
|
59
|
+
seek: (time: number) => void;
|
|
60
|
+
next: typeof next;
|
|
61
|
+
prev: typeof prev;
|
|
62
|
+
state: {
|
|
63
|
+
playing: boolean;
|
|
64
|
+
paused: boolean;
|
|
65
|
+
ended: boolean;
|
|
66
|
+
waiting: boolean;
|
|
67
|
+
stalled: boolean;
|
|
68
|
+
seeking: boolean;
|
|
69
|
+
ready: boolean;
|
|
70
|
+
currentTime: number;
|
|
71
|
+
duration: number;
|
|
72
|
+
live: boolean;
|
|
73
|
+
buffered: [number, number][];
|
|
74
|
+
volume: number;
|
|
75
|
+
muted: boolean;
|
|
76
|
+
rate: number;
|
|
77
|
+
fullscreen: boolean;
|
|
78
|
+
pip: boolean;
|
|
79
|
+
error: {
|
|
80
|
+
kind: import('../Media').UidMediaErrorKind;
|
|
81
|
+
detail?: string | undefined;
|
|
82
|
+
} | null;
|
|
83
|
+
};
|
|
84
|
+
media: import('vue').Ref<HTMLAudioElement | null, HTMLAudioElement | null>;
|
|
85
|
+
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
86
|
+
error: (error: UidMediaErrorInfo) => any;
|
|
87
|
+
play: () => any;
|
|
88
|
+
pause: () => any;
|
|
89
|
+
ended: () => any;
|
|
90
|
+
trackchange: (index: number) => any;
|
|
91
|
+
"update:index": (value: number) => any;
|
|
92
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
93
|
+
onError?: ((error: UidMediaErrorInfo) => any) | undefined;
|
|
94
|
+
onPlay?: (() => any) | undefined;
|
|
95
|
+
onPause?: (() => any) | undefined;
|
|
96
|
+
onEnded?: (() => any) | undefined;
|
|
97
|
+
onTrackchange?: ((index: number) => any) | undefined;
|
|
98
|
+
"onUpdate:index"?: ((value: number) => any) | undefined;
|
|
99
|
+
}>, {
|
|
100
|
+
type: string;
|
|
101
|
+
variant: "default" | "mini";
|
|
102
|
+
title: string;
|
|
103
|
+
src: string;
|
|
104
|
+
peaks: number[];
|
|
105
|
+
tracks: UidAudioTrack[];
|
|
106
|
+
loop: boolean;
|
|
107
|
+
preload: "none" | "metadata" | "auto";
|
|
108
|
+
crossorigin: "" | "anonymous" | "use-credentials";
|
|
109
|
+
exclusive: boolean;
|
|
110
|
+
resumeKey: string;
|
|
111
|
+
rates: number[];
|
|
112
|
+
hotkeys: boolean;
|
|
113
|
+
hlsOptions: Omit<HlsOptions, "onError">;
|
|
114
|
+
hlsLoader: () => Promise<UidHlsModule>;
|
|
115
|
+
artist: string;
|
|
116
|
+
waveform: boolean;
|
|
117
|
+
waveformMaxBytes: number;
|
|
118
|
+
waveformMaxDuration: number;
|
|
119
|
+
autoAdvance: boolean;
|
|
120
|
+
showVolume: boolean;
|
|
121
|
+
showRate: boolean;
|
|
122
|
+
showPlaylist: boolean;
|
|
123
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
124
|
+
root: HTMLDivElement;
|
|
125
|
+
audio: HTMLAudioElement;
|
|
126
|
+
}, HTMLDivElement>;
|
|
127
|
+
export default _default;
|
|
@@ -26,9 +26,9 @@ export interface UidGaugeProps {
|
|
|
26
26
|
declare const _default: import('vue').DefineComponent<UidGaugeProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<UidGaugeProps> & Readonly<{}>, {
|
|
27
27
|
size: number;
|
|
28
28
|
strokeWidth: number;
|
|
29
|
+
value: number;
|
|
29
30
|
min: number;
|
|
30
31
|
max: number;
|
|
31
|
-
value: number;
|
|
32
32
|
locale: string;
|
|
33
33
|
showValue: boolean;
|
|
34
34
|
precision: number;
|
|
@@ -21,9 +21,9 @@ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
|
|
|
21
21
|
declare const __VLS_component: import('vue').DefineComponent<UidGridProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<UidGridProps> & Readonly<{}>, {
|
|
22
22
|
as: string;
|
|
23
23
|
justify: "start" | "center" | "end" | "stretch";
|
|
24
|
+
align: "start" | "center" | "end" | "stretch";
|
|
24
25
|
gap: string;
|
|
25
26
|
cols: number | string;
|
|
26
|
-
align: "start" | "center" | "end" | "stretch";
|
|
27
27
|
rowGap: string;
|
|
28
28
|
colGap: string;
|
|
29
29
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { UidMarkdownBlockResult } from './blockRenderers.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
code: string;
|
|
4
|
+
language: string;
|
|
5
|
+
mount: NonNullable<UidMarkdownBlockResult['mount']>;
|
|
6
|
+
};
|
|
7
|
+
declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
8
|
+
el: HTMLDivElement;
|
|
9
|
+
}, HTMLDivElement>;
|
|
10
|
+
export default _default;
|
|
@@ -12,6 +12,27 @@ export interface UidMarkdownBlockResult {
|
|
|
12
12
|
html?: string;
|
|
13
13
|
/** Why the block could not be rendered; the block is then shown as code with this message. */
|
|
14
14
|
error?: string;
|
|
15
|
+
/**
|
|
16
|
+
* A live block: the host's widget (an API console, a chart with controls)
|
|
17
|
+
* is mounted into the block's element instead of static markup. Return a
|
|
18
|
+
* handle or a cleanup function: `update` takes a changed source without
|
|
19
|
+
* remounting, `destroy` runs when the block goes away.
|
|
20
|
+
*/
|
|
21
|
+
mount?: (el: HTMLElement, ctx: UidMarkdownBlockMountContext) => UidMarkdownBlockMountHandle | (() => void) | void;
|
|
22
|
+
}
|
|
23
|
+
/** What a live block's `mount` is told. The contract is the WYSIWYG editor's too. */
|
|
24
|
+
export interface UidMarkdownBlockMountContext {
|
|
25
|
+
/** The block's source. */
|
|
26
|
+
code: string;
|
|
27
|
+
language: string;
|
|
28
|
+
/** Always false here: rendered markdown is read-only. */
|
|
29
|
+
editable: boolean;
|
|
30
|
+
/** Ignored here — rendered markdown has no source to write to. */
|
|
31
|
+
setCode(code: string): void;
|
|
32
|
+
}
|
|
33
|
+
export interface UidMarkdownBlockMountHandle {
|
|
34
|
+
update?(code: string): void;
|
|
35
|
+
destroy?(): void;
|
|
15
36
|
}
|
|
16
37
|
/**
|
|
17
38
|
* Renders a fenced code block of one language (```mermaid, ```chart, …)
|
|
@@ -3,4 +3,4 @@ export type { UidMarkdownProps } from './UidMarkdown.vue';
|
|
|
3
3
|
export { createSlugger, escapeHtml, renderMarkdown, resolveAgainst, splitMarkdown, } from './markdown.js';
|
|
4
4
|
export type { MarkdownHeading, MarkdownOptions, MarkdownSegment, Slugger, UidMarkdownCalloutKind, } from './markdown.js';
|
|
5
5
|
export { markdownBlockRenderersKey, provideMarkdownBlockRenderers, useMarkdownBlockRenderers, } from './blockRenderers.js';
|
|
6
|
-
export type { UidMarkdownBlockRenderer, UidMarkdownBlockRenderers, UidMarkdownBlockResult, } from './blockRenderers.js';
|
|
6
|
+
export type { UidMarkdownBlockRenderer, UidMarkdownBlockRenderers, UidMarkdownBlockResult, UidMarkdownBlockMountContext, UidMarkdownBlockMountHandle, } from './blockRenderers.js';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export interface UidMediaMenuOption {
|
|
2
|
+
value: string | number;
|
|
3
|
+
label: string;
|
|
4
|
+
hint?: string;
|
|
5
|
+
/** Shorter label for the compact sheet (`1×` instead of `Normal`). */
|
|
6
|
+
short?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface UidMediaMenuGroup {
|
|
9
|
+
id: string;
|
|
10
|
+
label?: string;
|
|
11
|
+
value: string | number | null;
|
|
12
|
+
options: UidMediaMenuOption[];
|
|
13
|
+
}
|
|
14
|
+
type __VLS_Props = {
|
|
15
|
+
label: string;
|
|
16
|
+
groups: UidMediaMenuGroup[];
|
|
17
|
+
align?: 'start' | 'end';
|
|
18
|
+
buttonClass?: string;
|
|
19
|
+
closeLabel?: string;
|
|
20
|
+
};
|
|
21
|
+
declare function show(focus?: 'checked' | 'first' | 'last'): Promise<void>;
|
|
22
|
+
declare function hide(returnFocus?: boolean): void;
|
|
23
|
+
declare function __VLS_template(): {
|
|
24
|
+
attrs: Partial<{}>;
|
|
25
|
+
slots: Readonly<{
|
|
26
|
+
default(): unknown;
|
|
27
|
+
}> & {
|
|
28
|
+
default(): unknown;
|
|
29
|
+
};
|
|
30
|
+
refs: {
|
|
31
|
+
root: HTMLDivElement;
|
|
32
|
+
button: HTMLButtonElement;
|
|
33
|
+
panel: HTMLDivElement;
|
|
34
|
+
};
|
|
35
|
+
rootEl: HTMLDivElement;
|
|
36
|
+
};
|
|
37
|
+
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
|
|
38
|
+
declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {
|
|
39
|
+
show: typeof show;
|
|
40
|
+
hide: typeof hide;
|
|
41
|
+
open: import('vue').Ref<boolean, boolean>;
|
|
42
|
+
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
43
|
+
select: (group: string, value: string | number) => any;
|
|
44
|
+
"update:open": (open: boolean) => any;
|
|
45
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
46
|
+
onSelect?: ((group: string, value: string | number) => any) | undefined;
|
|
47
|
+
"onUpdate:open"?: ((open: boolean) => any) | undefined;
|
|
48
|
+
}>, {
|
|
49
|
+
align: "start" | "end";
|
|
50
|
+
buttonClass: string;
|
|
51
|
+
closeLabel: string;
|
|
52
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
53
|
+
root: HTMLDivElement;
|
|
54
|
+
button: HTMLButtonElement;
|
|
55
|
+
panel: HTMLDivElement;
|
|
56
|
+
}, HTMLDivElement>;
|
|
57
|
+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
|
|
58
|
+
export default _default;
|
|
59
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
60
|
+
new (): {
|
|
61
|
+
$slots: S;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { UidMediaCue, UidMediaRange, UidMediaThumbnail } from './mediaUtils.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
currentTime: number;
|
|
4
|
+
duration: number;
|
|
5
|
+
buffered?: UidMediaRange[];
|
|
6
|
+
chapters?: UidMediaCue[];
|
|
7
|
+
peaks?: number[] | null;
|
|
8
|
+
thumbnailAt?: (time: number) => UidMediaThumbnail | null;
|
|
9
|
+
label: string;
|
|
10
|
+
valueText: (current: string, total: string) => string;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
step?: number;
|
|
13
|
+
/** A waveform is on its way: show a placeholder instead of a bar that looks final. */
|
|
14
|
+
pending?: boolean;
|
|
15
|
+
/** Hides the hover preview (e.g. while a menu is open over the bar). */
|
|
16
|
+
suppressPreview?: boolean;
|
|
17
|
+
};
|
|
18
|
+
declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
19
|
+
seek: (time: number) => any;
|
|
20
|
+
scrubstart: () => any;
|
|
21
|
+
scrubend: () => any;
|
|
22
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
23
|
+
onSeek?: ((time: number) => any) | undefined;
|
|
24
|
+
onScrubstart?: (() => any) | undefined;
|
|
25
|
+
onScrubend?: (() => any) | undefined;
|
|
26
|
+
}>, {
|
|
27
|
+
disabled: boolean;
|
|
28
|
+
step: number;
|
|
29
|
+
pending: boolean;
|
|
30
|
+
chapters: UidMediaCue[];
|
|
31
|
+
buffered: UidMediaRange[];
|
|
32
|
+
peaks: number[] | null;
|
|
33
|
+
thumbnailAt: (time: number) => UidMediaThumbnail | null;
|
|
34
|
+
suppressPreview: boolean;
|
|
35
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
36
|
+
root: HTMLDivElement;
|
|
37
|
+
}, HTMLDivElement>;
|
|
38
|
+
export default _default;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { useMediaController } from './useMediaController.js';
|
|
2
|
+
export type { UseMediaControllerOptions, UidMediaController, UidMediaState, UidMediaErrorInfo, UidMediaErrorKind, } from './useMediaController.js';
|
|
3
|
+
export { formatTime, parseVtt, cueText, cueAt, parseThumbnail, isHlsSource, orderSources, PLAYBACK_RATES, } from './mediaUtils.js';
|
|
4
|
+
export type { UidMediaSource, UidMediaTrack, UidMediaCue, UidMediaRange, UidMediaThumbnail, } from './mediaUtils.js';
|
|
5
|
+
export { computePeaks, resamplePeaks, normalizePeaks, peaksToPath, getWaveform, clearWaveformCache } from './waveform.js';
|
|
6
|
+
export type { ComputePeaksOptions, WaveformOptions } from './waveform.js';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export interface UidMediaSource {
|
|
2
|
+
src: string;
|
|
3
|
+
/** MIME type, e.g. `video/mp4`, `video/webm; codecs="vp9,opus"`, `application/x-mpegURL`. */
|
|
4
|
+
type?: string;
|
|
5
|
+
/** Quality label shown in the quality menu (`1080p`, `720p`…). */
|
|
6
|
+
label?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface UidMediaTrack {
|
|
9
|
+
src: string;
|
|
10
|
+
kind?: 'subtitles' | 'captions' | 'chapters';
|
|
11
|
+
srclang?: string;
|
|
12
|
+
label?: string;
|
|
13
|
+
default?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface UidMediaCue {
|
|
16
|
+
start: number;
|
|
17
|
+
end: number;
|
|
18
|
+
text: string;
|
|
19
|
+
}
|
|
20
|
+
export type UidMediaRange = [number, number];
|
|
21
|
+
export declare function formatTime(value: number, withHours?: boolean): string;
|
|
22
|
+
export declare function toRanges(ranges: TimeRanges | null | undefined): UidMediaRange[];
|
|
23
|
+
/** End of the buffered range that contains `time` (with a small gap tolerance), or `time` itself. */
|
|
24
|
+
export declare function bufferedEndAt(ranges: UidMediaRange[], time: number, gap?: number): number;
|
|
25
|
+
export declare function isHlsSource(source: UidMediaSource): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Candidates in the order the browser should try them: the ones `canPlay` vouches for first,
|
|
28
|
+
* HLS sources count as playable when `hlsPlayable` says so (native or MSE).
|
|
29
|
+
*/
|
|
30
|
+
export declare function orderSources(sources: UidMediaSource[], canPlay: (type: string) => string, hlsPlayable: boolean): UidMediaSource[];
|
|
31
|
+
/** Minimal WebVTT parser: cue timings and text (settings, styles and regions are ignored). */
|
|
32
|
+
export declare function parseVtt(text: string): UidMediaCue[];
|
|
33
|
+
/** Plain text of a cue: VTT tags (`<v Bob>`, `<i>`, timestamps) dropped, entities decoded. */
|
|
34
|
+
export declare function cueText(raw: string): string;
|
|
35
|
+
export declare function cueAt(cues: UidMediaCue[], time: number): UidMediaCue | undefined;
|
|
36
|
+
export interface UidMediaThumbnail {
|
|
37
|
+
url: string;
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
w: number;
|
|
41
|
+
h: number;
|
|
42
|
+
}
|
|
43
|
+
/** A thumbnails-VTT cue body: `sprite.jpg#xywh=0,0,160,90` (or a whole image), resolved against `base`. */
|
|
44
|
+
export declare function parseThumbnail(text: string, base: string): UidMediaThumbnail | null;
|
|
45
|
+
export declare function resolveUrl(path: string, base: string): string;
|
|
46
|
+
export declare const PLAYBACK_RATES: number[];
|
|
47
|
+
export declare function clamp(v: number, min: number, max: number): number;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { MaybeRefOrGetter, Ref } from 'vue';
|
|
2
|
+
import { UidMediaRange } from './mediaUtils.js';
|
|
3
|
+
export type UidMediaErrorKind = 'aborted' | 'network' | 'decode' | 'unsupported' | 'mse' | 'manifest' | 'encrypted' | 'codec' | 'unknown';
|
|
4
|
+
export interface UidMediaErrorInfo {
|
|
5
|
+
kind: UidMediaErrorKind;
|
|
6
|
+
/** Technical detail (browser message, HTTP status) — not localised. */
|
|
7
|
+
detail?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface UseMediaControllerOptions {
|
|
10
|
+
/** Starting this player pauses other exclusive players on the page (default `true`). */
|
|
11
|
+
exclusive?: MaybeRefOrGetter<boolean>;
|
|
12
|
+
/** Element that goes full screen; defaults to the media element. */
|
|
13
|
+
fullscreenTarget?: Ref<HTMLElement | null>;
|
|
14
|
+
/** localStorage key to remember the playback position under. */
|
|
15
|
+
resumeKey?: MaybeRefOrGetter<string | undefined>;
|
|
16
|
+
/** Seconds a hotkey arrow moves (default 5); j/l move twice as far. */
|
|
17
|
+
seekStep?: number;
|
|
18
|
+
onCaptionsToggle?: () => void;
|
|
19
|
+
}
|
|
20
|
+
export interface UidMediaState {
|
|
21
|
+
playing: boolean;
|
|
22
|
+
paused: boolean;
|
|
23
|
+
ended: boolean;
|
|
24
|
+
waiting: boolean;
|
|
25
|
+
stalled: boolean;
|
|
26
|
+
seeking: boolean;
|
|
27
|
+
ready: boolean;
|
|
28
|
+
currentTime: number;
|
|
29
|
+
duration: number;
|
|
30
|
+
live: boolean;
|
|
31
|
+
buffered: UidMediaRange[];
|
|
32
|
+
volume: number;
|
|
33
|
+
muted: boolean;
|
|
34
|
+
rate: number;
|
|
35
|
+
fullscreen: boolean;
|
|
36
|
+
pip: boolean;
|
|
37
|
+
error: UidMediaErrorInfo | null;
|
|
38
|
+
}
|
|
39
|
+
export declare function useMediaController(media: Ref<HTMLMediaElement | null>, options?: UseMediaControllerOptions): {
|
|
40
|
+
state: {
|
|
41
|
+
playing: boolean;
|
|
42
|
+
paused: boolean;
|
|
43
|
+
ended: boolean;
|
|
44
|
+
waiting: boolean;
|
|
45
|
+
stalled: boolean;
|
|
46
|
+
seeking: boolean;
|
|
47
|
+
ready: boolean;
|
|
48
|
+
currentTime: number;
|
|
49
|
+
duration: number;
|
|
50
|
+
live: boolean;
|
|
51
|
+
buffered: [number, number][];
|
|
52
|
+
volume: number;
|
|
53
|
+
muted: boolean;
|
|
54
|
+
rate: number;
|
|
55
|
+
fullscreen: boolean;
|
|
56
|
+
pip: boolean;
|
|
57
|
+
error: {
|
|
58
|
+
kind: UidMediaErrorKind;
|
|
59
|
+
detail?: string | undefined;
|
|
60
|
+
} | null;
|
|
61
|
+
};
|
|
62
|
+
bufferedEnd: import('vue').ComputedRef<number>;
|
|
63
|
+
canFullscreen: import('vue').ComputedRef<boolean>;
|
|
64
|
+
canPip: import('vue').ComputedRef<boolean>;
|
|
65
|
+
play: () => Promise<void>;
|
|
66
|
+
pause: () => void;
|
|
67
|
+
toggle: () => void;
|
|
68
|
+
seek: (time: number) => void;
|
|
69
|
+
skip: (delta: number) => void;
|
|
70
|
+
setVolume: (v: number) => void;
|
|
71
|
+
changeVolume: (delta: number) => void;
|
|
72
|
+
setMuted: (value: boolean) => void;
|
|
73
|
+
toggleMute: () => void;
|
|
74
|
+
setRate: (rate: number) => void;
|
|
75
|
+
toggleFullscreen: () => Promise<void>;
|
|
76
|
+
togglePip: () => Promise<void>;
|
|
77
|
+
setError: (error: UidMediaErrorInfo | null) => void;
|
|
78
|
+
handleKey: (e: KeyboardEvent) => boolean;
|
|
79
|
+
};
|
|
80
|
+
export type UidMediaController = ReturnType<typeof useMediaController>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface ComputePeaksOptions {
|
|
2
|
+
/** Samples processed between yields to the event loop. */
|
|
3
|
+
chunkSize?: number;
|
|
4
|
+
/** Yields between chunks; defaults to requestIdleCallback / setTimeout. */
|
|
5
|
+
yieldFn?: () => Promise<void>;
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
}
|
|
8
|
+
export interface WaveformOptions {
|
|
9
|
+
/** Number of peaks to compute (default 1024). */
|
|
10
|
+
count?: number;
|
|
11
|
+
/** Skip files larger than this many bytes (default 40 MB). */
|
|
12
|
+
maxBytes?: number;
|
|
13
|
+
/** Skip audio longer than this many seconds (default 30 min). */
|
|
14
|
+
maxDuration?: number;
|
|
15
|
+
fetchInit?: RequestInit;
|
|
16
|
+
}
|
|
17
|
+
export declare function idleYield(): Promise<void>;
|
|
18
|
+
/** Max absolute amplitude per bucket across all channels, normalised to 0..1, processed in chunks. */
|
|
19
|
+
export declare function computePeaks(channels: ArrayLike<number>[], count: number, options?: ComputePeaksOptions): Promise<number[]>;
|
|
20
|
+
export declare function normalizePeaks(peaks: number[]): number[];
|
|
21
|
+
/** Reduces (max) or stretches (nearest) peaks to `n` bars for drawing. */
|
|
22
|
+
export declare function resamplePeaks(peaks: number[], n: number): number[];
|
|
23
|
+
/** SVG path of centred bars (viewBox `0 0 n*step 100`), heights clamped to a visible minimum. */
|
|
24
|
+
export declare function peaksToPath(peaks: number[], step?: number, bar?: number, minHeight?: number): string;
|
|
25
|
+
/** Peaks of an audio file decoded in the browser; `null` when skipped or impossible. Cached per src. */
|
|
26
|
+
export declare function getWaveform(src: string, options?: WaveformOptions): Promise<number[] | null>;
|
|
27
|
+
export declare function clearWaveformCache(): void;
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
declare function close(): void;
|
|
2
|
+
declare function toggle(): Promise<void>;
|
|
3
|
+
declare function openAt(x: number, y: number): void;
|
|
4
|
+
type __VLS_PublicProps = {
|
|
5
|
+
'open'?: boolean;
|
|
6
|
+
};
|
|
1
7
|
declare function __VLS_template(): {
|
|
2
8
|
attrs: Partial<{}>;
|
|
3
9
|
slots: Readonly<{
|
|
4
|
-
trigger(): unknown;
|
|
10
|
+
trigger?(): unknown;
|
|
5
11
|
default(): unknown;
|
|
6
12
|
}> & {
|
|
7
|
-
trigger(): unknown;
|
|
13
|
+
trigger?(): unknown;
|
|
8
14
|
default(): unknown;
|
|
9
15
|
};
|
|
10
16
|
refs: {
|
|
@@ -14,7 +20,15 @@ declare function __VLS_template(): {
|
|
|
14
20
|
rootEl: any;
|
|
15
21
|
};
|
|
16
22
|
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
|
|
17
|
-
declare const __VLS_component: import('vue').DefineComponent<
|
|
23
|
+
declare const __VLS_component: import('vue').DefineComponent<__VLS_PublicProps, {
|
|
24
|
+
openAt: typeof openAt;
|
|
25
|
+
close: typeof close;
|
|
26
|
+
toggle: typeof toggle;
|
|
27
|
+
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
28
|
+
"update:open": (value: boolean) => any;
|
|
29
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
30
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
31
|
+
}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
18
32
|
triggerRef: HTMLDivElement;
|
|
19
33
|
menuRef: HTMLDivElement;
|
|
20
34
|
}, any>;
|
|
@@ -5,11 +5,11 @@ export interface UidPaginationCursorProps {
|
|
|
5
5
|
nextLabel?: string;
|
|
6
6
|
}
|
|
7
7
|
declare const _default: import('vue').DefineComponent<UidPaginationCursorProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
8
|
-
prev: () => any;
|
|
9
8
|
next: () => any;
|
|
9
|
+
prev: () => any;
|
|
10
10
|
}, string, import('vue').PublicProps, Readonly<UidPaginationCursorProps> & Readonly<{
|
|
11
|
-
onPrev?: (() => any) | undefined;
|
|
12
11
|
onNext?: (() => any) | undefined;
|
|
12
|
+
onPrev?: (() => any) | undefined;
|
|
13
13
|
}>, {
|
|
14
14
|
hasPrev: boolean;
|
|
15
15
|
hasNext: boolean;
|
|
@@ -12,8 +12,8 @@ declare const _default: import('vue').DefineComponent<UidProgressProps, {}, {},
|
|
|
12
12
|
size: "sm" | "md" | "lg";
|
|
13
13
|
label: string;
|
|
14
14
|
variant: UidProgressVariant;
|
|
15
|
-
max: number;
|
|
16
15
|
value: number;
|
|
16
|
+
max: number;
|
|
17
17
|
showValue: boolean;
|
|
18
18
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
|
|
19
19
|
export default _default;
|
|
@@ -25,8 +25,8 @@ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
|
|
|
25
25
|
declare const __VLS_component: import('vue').DefineComponent<UidProgressRingProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<UidProgressRingProps> & Readonly<{}>, {
|
|
26
26
|
size: number;
|
|
27
27
|
strokeWidth: number;
|
|
28
|
-
max: number;
|
|
29
28
|
value: number;
|
|
29
|
+
max: number;
|
|
30
30
|
indeterminate: boolean;
|
|
31
31
|
tone: RingTone;
|
|
32
32
|
showLabel: boolean;
|
|
@@ -24,8 +24,8 @@ declare const __VLS_component: import('vue').DefineComponent<UidStackProps, {},
|
|
|
24
24
|
as: string;
|
|
25
25
|
wrap: boolean;
|
|
26
26
|
justify: "start" | "center" | "end" | "between" | "around" | "evenly";
|
|
27
|
-
gap: string;
|
|
28
27
|
align: "start" | "center" | "end" | "stretch" | "baseline";
|
|
28
|
+
gap: string;
|
|
29
29
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
30
30
|
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
|
|
31
31
|
export default _default;
|