@hh.ru/magritte-ui-video 1.0.3 → 1.1.1

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/Video.js CHANGED
@@ -13,7 +13,7 @@ import '@hh.ru/magritte-ui-icon/icon';
13
13
  import '@hh.ru/magritte-ui-typography';
14
14
  import './internal/ControlButton.js';
15
15
  import '@hh.ru/magritte-ui-tooltip';
16
- import './video-B0giLQLN.js';
16
+ import './video-DR4YYLmP.js';
17
17
  import './internal/Scrubber.js';
18
18
  import './internal/formatTime.js';
19
19
  import './internal/useSliderPointer.js';
package/VideoControls.js CHANGED
@@ -5,7 +5,7 @@ import { createPortal } from 'react-dom';
5
5
  import classnames from 'classnames';
6
6
  import { useTranslation } from '@hh.ru/magritte-common-use-translation';
7
7
  import { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';
8
- import { SpeakerCrossedOutlinedSize24, SpeakerWaveOutlinedSize24, DashedSquareInOutlinedSize24, DashedSquareOutOutlinedSize24, PlayFilledSize24, ArrowPathClockwiseOutlinedSize24, PauseFilledSize24 } from '@hh.ru/magritte-ui-icon/icon';
8
+ import { DashedSquareInOutlinedSize24, PlayFilledSize24, ArrowPathClockwiseOutlinedSize24, PauseFilledSize24, SpeakerCrossedOutlinedSize16, SpeakerCrossedOutlinedSize24, SpeakerWaveOutlinedSize16, SpeakerWaveOutlinedSize24, DashedSquareOutOutlinedSize16, DashedSquareOutOutlinedSize24 } from '@hh.ru/magritte-ui-icon/icon';
9
9
  import { Text } from '@hh.ru/magritte-ui-typography';
10
10
  import { ControlButton } from './internal/ControlButton.js';
11
11
  import { Scrubber } from './internal/Scrubber.js';
@@ -15,7 +15,7 @@ import { useVideoContext, VideoPlayerContext, useVideoState } from './internal/c
15
15
  import { findFocusableControl, CONTROL_KEY_ATTRIBUTE } from './internal/controlKey.js';
16
16
  import { useInert } from './internal/useInert.js';
17
17
  import { useVideoHotkeys } from './internal/useVideoHotkeys.js';
18
- import { s as styles } from './video-B0giLQLN.js';
18
+ import { s as styles } from './video-DR4YYLmP.js';
19
19
  import '@hh.ru/magritte-ui-tooltip';
20
20
  import './internal/formatTime.js';
21
21
  import './internal/useSliderPointer.js';
@@ -83,6 +83,7 @@ const VideoControls = ({ "data-qa": dataQa = "video-controls" }) => {
83
83
  return null;
84
84
  }
85
85
  const withTooltip = !isMobile && visible;
86
+ const compact = isMobile && !fullscreen;
86
87
  const showScrubber = !live || status === "loading";
87
88
  const onFocus = (event) => {
88
89
  focusedControlRef.current = event.target.closest(`[${CONTROL_KEY_ATTRIBUTE}]`)?.getAttribute(CONTROL_KEY_ATTRIBUTE) ?? null;
@@ -110,6 +111,9 @@ const VideoControls = ({ "data-qa": dataQa = "video-controls" }) => {
110
111
  } else if (status === "playing") {
111
112
  playPause = { label: pauseTrl, icon: PauseFilledSize24 };
112
113
  }
114
+ const SpeakerCrossedIcon = compact ? SpeakerCrossedOutlinedSize16 : SpeakerCrossedOutlinedSize24;
115
+ const SpeakerWaveIcon = compact ? SpeakerWaveOutlinedSize16 : SpeakerWaveOutlinedSize24;
116
+ const EnterFullscreenIcon = compact ? DashedSquareOutOutlinedSize16 : DashedSquareOutOutlinedSize24;
113
117
  const renderResult = /* @__PURE__ */ jsxs(
114
118
  "div",
115
119
  {
@@ -118,6 +122,7 @@ const VideoControls = ({ "data-qa": dataQa = "video-controls" }) => {
118
122
  "aria-label": controlsTrl,
119
123
  className: classnames(styles.controls, {
120
124
  [styles.controlsMobile]: isMobile,
125
+ [styles.controlsCompact]: compact,
121
126
  [styles.controlsOverlay]: fullscreen || insidePlayer && !container,
122
127
  [styles.controlsHidden]: !visible
123
128
  }),
@@ -151,7 +156,7 @@ const VideoControls = ({ "data-qa": dataQa = "video-controls" }) => {
151
156
  "data-qa": "video-play-pause"
152
157
  }
153
158
  ),
154
- /* @__PURE__ */ jsx("div", { className: styles.controlsTime, children: /* @__PURE__ */ jsx(TimeLabel, { store, live: live && status !== "loading" }) })
159
+ /* @__PURE__ */ jsx("div", { className: styles.controlsTime, children: /* @__PURE__ */ jsx(TimeLabel, { store, live: live && status !== "loading", compact }) })
155
160
  ] }),
156
161
  /* @__PURE__ */ jsxs("div", { className: styles.controlsGroupEnd, children: [
157
162
  /* @__PURE__ */ jsx(
@@ -163,9 +168,10 @@ const VideoControls = ({ "data-qa": dataQa = "video-controls" }) => {
163
168
  store.notifyActivity();
164
169
  },
165
170
  withTooltip,
171
+ compact,
166
172
  control: "playback-rate",
167
173
  "data-qa": "video-playback-rate",
168
- children: /* @__PURE__ */ jsx(Text, { typography: "subtitle-2-semibold", style: "constant", children: `${rate}x` })
174
+ children: /* @__PURE__ */ jsx(Text, { typography: compact ? "subtitle-3-semibold" : "subtitle-2-semibold", style: "constant", children: `${rate}x` })
169
175
  }
170
176
  ),
171
177
  /* @__PURE__ */ jsxs("div", { className: styles.controlsVolume, children: [
@@ -173,7 +179,7 @@ const VideoControls = ({ "data-qa": dataQa = "video-controls" }) => {
173
179
  ControlButton,
174
180
  {
175
181
  label: muted ? unmuteTrl : muteTrl,
176
- icon: muted ? SpeakerCrossedOutlinedSize24 : SpeakerWaveOutlinedSize24,
182
+ icon: muted ? SpeakerCrossedIcon : SpeakerWaveIcon,
177
183
  onClick: () => {
178
184
  store.setMuted(!muted);
179
185
  store.notifyActivity();
@@ -190,12 +196,13 @@ const VideoControls = ({ "data-qa": dataQa = "video-controls" }) => {
190
196
  ControlButton,
191
197
  {
192
198
  label: fullscreen ? exitFullscreenTrl : enterFullscreenTrl,
193
- icon: fullscreen ? DashedSquareInOutlinedSize24 : DashedSquareOutOutlinedSize24,
199
+ icon: fullscreen ? DashedSquareInOutlinedSize24 : EnterFullscreenIcon,
194
200
  onClick: () => {
195
201
  store.toggleFullscreen();
196
202
  store.notifyActivity();
197
203
  },
198
204
  withTooltip,
205
+ compact,
199
206
  control: "fullscreen",
200
207
  "data-qa": "video-fullscreen"
201
208
  }
@@ -1 +1 @@
1
- {"version":3,"file":"VideoControls.js","sources":["src/VideoControls.tsx"],"sourcesContent":["import { type FC, type FocusEvent, useContext, useEffect, useLayoutEffect, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport classnames from 'classnames';\n\nimport { useTranslation } from '@hh.ru/magritte-common-use-translation';\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport {\n ArrowPathClockwiseOutlinedSize24,\n DashedSquareInOutlinedSize24,\n DashedSquareOutOutlinedSize24,\n PauseFilledSize24,\n PlayFilledSize24,\n SpeakerCrossedOutlinedSize24,\n SpeakerWaveOutlinedSize24,\n} from '@hh.ru/magritte-ui-icon/icon';\nimport { Text } from '@hh.ru/magritte-ui-typography';\nimport { ControlButton } from '@hh.ru/magritte-ui-video/internal/ControlButton';\nimport { Scrubber } from '@hh.ru/magritte-ui-video/internal/Scrubber';\nimport { TimeLabel } from '@hh.ru/magritte-ui-video/internal/TimeLabel';\nimport { VolumeSlider } from '@hh.ru/magritte-ui-video/internal/VolumeSlider';\nimport { useVideoContext, useVideoState, VideoPlayerContext } from '@hh.ru/magritte-ui-video/internal/context';\nimport { CONTROL_KEY_ATTRIBUTE, findFocusableControl } from '@hh.ru/magritte-ui-video/internal/controlKey';\nimport { useInert } from '@hh.ru/magritte-ui-video/internal/useInert';\nimport { useVideoHotkeys } from '@hh.ru/magritte-ui-video/internal/useVideoHotkeys';\nimport { type VideoControlsProps, type VideoStatus } from '@hh.ru/magritte-ui-video/types';\n\nimport styles from './video.less';\n\n/** Контролы есть только после запуска: в default и при ошибке их нет */\nconst STATUSES_WITH_CONTROLS: VideoStatus[] = ['loading', 'playing', 'paused', 'ended'];\n\n/**\n * Видеоконтролы: перемотка, время, play/pause (desktop), скорость, громкость, fullscreen.\n * Внутри `Video.Player` раскладываются поверх видео у нижнего края, снаружи — в потоке.\n * Стор может перенести их в другой контейнер (`setControlsContainer`), в fullscreen — всегда внутрь плеера\n */\nexport const VideoControls: FC<VideoControlsProps> = ({ 'data-qa': dataQa = 'video-controls' }) => {\n const { store, interactive } = useVideoContext('Video.Controls');\n const insidePlayer = useContext(VideoPlayerContext);\n const { isMobile } = useBreakpoint();\n\n const status = useVideoState(store, (state) => state.status);\n const visible = useVideoState(store, (state) => state.controlsVisible);\n const live = useVideoState(store, (state) => state.duration === null);\n const rate = useVideoState(store, (state) => state.rate);\n const muted = useVideoState(store, (state) => state.muted);\n const fullscreen = useVideoState(store, (state) => state.fullscreen);\n const container = useVideoState(store, (state) => state.controlsContainer);\n const rootRef = useRef<HTMLDivElement>(null);\n const pointerFocusRef = useRef(false);\n const holdingRef = useRef(false);\n // имя контрола с фокусом (`data-video-control`) — по нему фокус возвращается, если узел под ним подменили\n const focusedControlRef = useRef<string | null>(null);\n const restoringFocusRef = useRef(false);\n useInert(rootRef, !visible);\n // контролы бывают вне плеера (в потоке, во вьювере) — фокус в них тоже «фокус в видео»\n const onKeyDown = useVideoHotkeys(store);\n\n // в неинтерактивном режиме контролов нет\n const hasControls = interactive && STATUSES_WITH_CONTROLS.includes(status);\n\n // Удержание (фокус с клавиатуры внутри) снимается по blur. Но если контролы пропали вместе с фокусом —\n // ошибка или смена источника (компонент рендерит null) либо размонтирование, — blur не придёт:\n // отпускаем удержание сами, иначе контролы больше никогда не спрячутся\n useEffect(\n () => () => {\n if (holdingRef.current) {\n holdingRef.current = false;\n store.holdControls(false);\n }\n },\n [store, hasControls]\n );\n\n // Кнопка со сменой иконки (звук, play/pause, fullscreen) пересоздаётся: у каждой иконки свой компонент.\n // Вход и выход из fullscreen переносит контролы в портал и обратно — пересоздаются все. Фокус в обоих случаях\n // падает на body без blur: возвращаем его на тот же контрол, чтобы клавиатурная навигация продолжалась с места\n useLayoutEffect(() => {\n const root = rootRef.current;\n if (!root || !visible) {\n focusedControlRef.current = null;\n return;\n }\n const key = focusedControlRef.current;\n const active = document.activeElement;\n if (!key || (active && active !== document.body)) {\n return;\n }\n const control = findFocusableControl(root, key);\n if (!control) {\n focusedControlRef.current = null;\n return;\n }\n // фокус не новый — удержание контролов остаётся как было\n restoringFocusRef.current = true;\n control.focus({ preventScroll: true });\n restoringFocusRef.current = false;\n });\n\n const controlsTrl = useTranslation('Video', 'controls');\n const playTrl = useTranslation('Video', 'play');\n const pauseTrl = useTranslation('Video', 'pause');\n const replayTrl = useTranslation('Video', 'replay');\n const playbackRateTrl = useTranslation('Video', 'playbackRate');\n const muteTrl = useTranslation('Video', 'mute');\n const unmuteTrl = useTranslation('Video', 'unmute');\n const enterFullscreenTrl = useTranslation('Video', 'enterFullscreen');\n const exitFullscreenTrl = useTranslation('Video', 'exitFullscreen');\n\n if (!hasControls) {\n return null;\n }\n\n const withTooltip = !isMobile && visible;\n // live до загрузки метаданных не отличить от обычного видео — ползунок прячем только когда длительность так и не появилась\n const showScrubber = !live || status === 'loading';\n\n // фокус с клавиатуры внутри контролов — взаимодействие: пока он там, контролы не прячутся.\n // Фокус после клика мышью не держит контролы, иначе они не спрячутся никогда\n const onFocus = (event: FocusEvent<HTMLDivElement>) => {\n focusedControlRef.current =\n (event.target as HTMLElement).closest(`[${CONTROL_KEY_ATTRIBUTE}]`)?.getAttribute(CONTROL_KEY_ATTRIBUTE) ??\n null;\n const pointerFocus = pointerFocusRef.current;\n pointerFocusRef.current = false;\n if (\n restoringFocusRef.current ||\n pointerFocus ||\n holdingRef.current ||\n event.currentTarget.contains(event.relatedTarget)\n ) {\n return;\n }\n holdingRef.current = true;\n store.holdControls(true);\n };\n const onBlur = (event: FocusEvent<HTMLDivElement>) => {\n if (!event.currentTarget.contains(event.relatedTarget)) {\n focusedControlRef.current = null;\n }\n if (!holdingRef.current || event.currentTarget.contains(event.relatedTarget)) {\n return;\n }\n holdingRef.current = false;\n store.holdControls(false);\n };\n\n let playPause = { label: playTrl, icon: PlayFilledSize24 };\n if (status === 'ended') {\n playPause = { label: replayTrl, icon: ArrowPathClockwiseOutlinedSize24 };\n } else if (status === 'playing') {\n playPause = { label: pauseTrl, icon: PauseFilledSize24 };\n }\n\n const renderResult = (\n <div\n ref={rootRef}\n role=\"group\"\n aria-label={controlsTrl}\n className={classnames(styles.controls, {\n [styles.controlsMobile]: isMobile,\n [styles.controlsOverlay]: fullscreen || (insidePlayer && !container),\n [styles.controlsHidden]: !visible,\n })}\n // холст игнорирует события из контролов по этому атрибуту\n data-video-controls\n data-qa={dataQa}\n onPointerDownCapture={() => {\n pointerFocusRef.current = true;\n }}\n // фокус от клика приходит до pointerup; если его не было — сбрасываем флаг\n onPointerUpCapture={() => {\n pointerFocusRef.current = false;\n }}\n onPointerMove={(event) => event.pointerType === 'mouse' && store.notifyActivity()}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={onKeyDown}\n >\n {showScrubber && <Scrubber store={store} />}\n <div className={styles.controlsRow}>\n <div className={styles.controlsGroupStart}>\n {!isMobile && (\n <ControlButton\n label={playPause.label}\n icon={playPause.icon}\n onClick={() => {\n store.toggle();\n store.notifyActivity();\n }}\n withTooltip={withTooltip}\n control=\"play-pause\"\n data-qa=\"video-play-pause\"\n />\n )}\n <div className={styles.controlsTime}>\n <TimeLabel store={store} live={live && status !== 'loading'} />\n </div>\n </div>\n <div className={styles.controlsGroupEnd}>\n <ControlButton\n label={`${playbackRateTrl ?? ''}: ${rate}x`}\n onClick={() => {\n store.cycleRate();\n store.notifyActivity();\n }}\n withTooltip={withTooltip}\n control=\"playback-rate\"\n data-qa=\"video-playback-rate\"\n >\n <Text typography=\"subtitle-2-semibold\" style=\"constant\">\n {`${rate}x`}\n </Text>\n </ControlButton>\n <div className={styles.controlsVolume}>\n <ControlButton\n label={muted ? unmuteTrl : muteTrl}\n icon={muted ? SpeakerCrossedOutlinedSize24 : SpeakerWaveOutlinedSize24}\n onClick={() => {\n store.setMuted(!muted);\n store.notifyActivity();\n }}\n withTooltip={withTooltip}\n bare\n control=\"mute\"\n data-qa=\"video-mute\"\n />\n {!isMobile && <VolumeSlider store={store} />}\n </div>\n <ControlButton\n label={fullscreen ? exitFullscreenTrl : enterFullscreenTrl}\n icon={fullscreen ? DashedSquareInOutlinedSize24 : DashedSquareOutOutlinedSize24}\n onClick={() => {\n store.toggleFullscreen();\n store.notifyActivity();\n }}\n withTooltip={withTooltip}\n control=\"fullscreen\"\n data-qa=\"video-fullscreen\"\n />\n </div>\n </div>\n </div>\n );\n\n // в fullscreen разворачивается плеер — контролы переезжают в него; иначе — в заданный контейнер, если он есть\n const target = (fullscreen && store.getRoot()) || container;\n return target ? createPortal(renderResult, target) : renderResult;\n};\n\nVideoControls.displayName = 'VideoControls';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"VideoControls.js","sources":["src/VideoControls.tsx"],"sourcesContent":["import { type FC, type FocusEvent, useContext, useEffect, useLayoutEffect, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport classnames from 'classnames';\n\nimport { useTranslation } from '@hh.ru/magritte-common-use-translation';\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport {\n ArrowPathClockwiseOutlinedSize24,\n DashedSquareInOutlinedSize24,\n DashedSquareOutOutlinedSize16,\n DashedSquareOutOutlinedSize24,\n PauseFilledSize24,\n PlayFilledSize24,\n SpeakerCrossedOutlinedSize16,\n SpeakerCrossedOutlinedSize24,\n SpeakerWaveOutlinedSize16,\n SpeakerWaveOutlinedSize24,\n} from '@hh.ru/magritte-ui-icon/icon';\nimport { Text } from '@hh.ru/magritte-ui-typography';\nimport { ControlButton } from '@hh.ru/magritte-ui-video/internal/ControlButton';\nimport { Scrubber } from '@hh.ru/magritte-ui-video/internal/Scrubber';\nimport { TimeLabel } from '@hh.ru/magritte-ui-video/internal/TimeLabel';\nimport { VolumeSlider } from '@hh.ru/magritte-ui-video/internal/VolumeSlider';\nimport { useVideoContext, useVideoState, VideoPlayerContext } from '@hh.ru/magritte-ui-video/internal/context';\nimport { CONTROL_KEY_ATTRIBUTE, findFocusableControl } from '@hh.ru/magritte-ui-video/internal/controlKey';\nimport { useInert } from '@hh.ru/magritte-ui-video/internal/useInert';\nimport { useVideoHotkeys } from '@hh.ru/magritte-ui-video/internal/useVideoHotkeys';\nimport { type VideoControlsProps, type VideoStatus } from '@hh.ru/magritte-ui-video/types';\n\nimport styles from './video.less';\n\n/** Контролы есть только после запуска: в default и при ошибке их нет */\nconst STATUSES_WITH_CONTROLS: VideoStatus[] = ['loading', 'playing', 'paused', 'ended'];\n\n/**\n * Видеоконтролы: перемотка, время, play/pause (desktop), скорость, громкость, fullscreen.\n * Внутри `Video.Player` раскладываются поверх видео у нижнего края, снаружи — в потоке.\n * Стор может перенести их в другой контейнер (`setControlsContainer`), в fullscreen — всегда внутрь плеера\n */\nexport const VideoControls: FC<VideoControlsProps> = ({ 'data-qa': dataQa = 'video-controls' }) => {\n const { store, interactive } = useVideoContext('Video.Controls');\n const insidePlayer = useContext(VideoPlayerContext);\n const { isMobile } = useBreakpoint();\n\n const status = useVideoState(store, (state) => state.status);\n const visible = useVideoState(store, (state) => state.controlsVisible);\n const live = useVideoState(store, (state) => state.duration === null);\n const rate = useVideoState(store, (state) => state.rate);\n const muted = useVideoState(store, (state) => state.muted);\n const fullscreen = useVideoState(store, (state) => state.fullscreen);\n const container = useVideoState(store, (state) => state.controlsContainer);\n const rootRef = useRef<HTMLDivElement>(null);\n const pointerFocusRef = useRef(false);\n const holdingRef = useRef(false);\n // имя контрола с фокусом (`data-video-control`) — по нему фокус возвращается, если узел под ним подменили\n const focusedControlRef = useRef<string | null>(null);\n const restoringFocusRef = useRef(false);\n useInert(rootRef, !visible);\n // контролы бывают вне плеера (в потоке, во вьювере) — фокус в них тоже «фокус в видео»\n const onKeyDown = useVideoHotkeys(store);\n\n // в неинтерактивном режиме контролов нет\n const hasControls = interactive && STATUSES_WITH_CONTROLS.includes(status);\n\n // Удержание (фокус с клавиатуры внутри) снимается по blur. Но если контролы пропали вместе с фокусом —\n // ошибка или смена источника (компонент рендерит null) либо размонтирование, — blur не придёт:\n // отпускаем удержание сами, иначе контролы больше никогда не спрячутся\n useEffect(\n () => () => {\n if (holdingRef.current) {\n holdingRef.current = false;\n store.holdControls(false);\n }\n },\n [store, hasControls]\n );\n\n // Кнопка со сменой иконки (звук, play/pause, fullscreen) пересоздаётся: у каждой иконки свой компонент.\n // Вход и выход из fullscreen переносит контролы в портал и обратно — пересоздаются все. Фокус в обоих случаях\n // падает на body без blur: возвращаем его на тот же контрол, чтобы клавиатурная навигация продолжалась с места\n useLayoutEffect(() => {\n const root = rootRef.current;\n if (!root || !visible) {\n focusedControlRef.current = null;\n return;\n }\n const key = focusedControlRef.current;\n const active = document.activeElement;\n if (!key || (active && active !== document.body)) {\n return;\n }\n const control = findFocusableControl(root, key);\n if (!control) {\n focusedControlRef.current = null;\n return;\n }\n // фокус не новый — удержание контролов остаётся как было\n restoringFocusRef.current = true;\n control.focus({ preventScroll: true });\n restoringFocusRef.current = false;\n });\n\n const controlsTrl = useTranslation('Video', 'controls');\n const playTrl = useTranslation('Video', 'play');\n const pauseTrl = useTranslation('Video', 'pause');\n const replayTrl = useTranslation('Video', 'replay');\n const playbackRateTrl = useTranslation('Video', 'playbackRate');\n const muteTrl = useTranslation('Video', 'mute');\n const unmuteTrl = useTranslation('Video', 'unmute');\n const enterFullscreenTrl = useTranslation('Video', 'enterFullscreen');\n const exitFullscreenTrl = useTranslation('Video', 'exitFullscreen');\n\n if (!hasControls) {\n return null;\n }\n\n const withTooltip = !isMobile && visible;\n // на mobile вне fullscreen видео небольшое — контролы компактные (кнопки 32px), в fullscreen — крупные (48px)\n const compact = isMobile && !fullscreen;\n // live до загрузки метаданных не отличить от обычного видео — ползунок прячем только когда длительность так и не появилась\n const showScrubber = !live || status === 'loading';\n\n // фокус с клавиатуры внутри контролов — взаимодействие: пока он там, контролы не прячутся.\n // Фокус после клика мышью не держит контролы, иначе они не спрячутся никогда\n const onFocus = (event: FocusEvent<HTMLDivElement>) => {\n focusedControlRef.current =\n (event.target as HTMLElement).closest(`[${CONTROL_KEY_ATTRIBUTE}]`)?.getAttribute(CONTROL_KEY_ATTRIBUTE) ??\n null;\n const pointerFocus = pointerFocusRef.current;\n pointerFocusRef.current = false;\n if (\n restoringFocusRef.current ||\n pointerFocus ||\n holdingRef.current ||\n event.currentTarget.contains(event.relatedTarget)\n ) {\n return;\n }\n holdingRef.current = true;\n store.holdControls(true);\n };\n const onBlur = (event: FocusEvent<HTMLDivElement>) => {\n if (!event.currentTarget.contains(event.relatedTarget)) {\n focusedControlRef.current = null;\n }\n if (!holdingRef.current || event.currentTarget.contains(event.relatedTarget)) {\n return;\n }\n holdingRef.current = false;\n store.holdControls(false);\n };\n\n let playPause = { label: playTrl, icon: PlayFilledSize24 };\n if (status === 'ended') {\n playPause = { label: replayTrl, icon: ArrowPathClockwiseOutlinedSize24 };\n } else if (status === 'playing') {\n playPause = { label: pauseTrl, icon: PauseFilledSize24 };\n }\n\n // компактные иконки — 16, только вне fullscreen (выход из fullscreen всегда крупный)\n const SpeakerCrossedIcon = compact ? SpeakerCrossedOutlinedSize16 : SpeakerCrossedOutlinedSize24;\n const SpeakerWaveIcon = compact ? SpeakerWaveOutlinedSize16 : SpeakerWaveOutlinedSize24;\n const EnterFullscreenIcon = compact ? DashedSquareOutOutlinedSize16 : DashedSquareOutOutlinedSize24;\n\n const renderResult = (\n <div\n ref={rootRef}\n role=\"group\"\n aria-label={controlsTrl}\n className={classnames(styles.controls, {\n [styles.controlsMobile]: isMobile,\n [styles.controlsCompact]: compact,\n [styles.controlsOverlay]: fullscreen || (insidePlayer && !container),\n [styles.controlsHidden]: !visible,\n })}\n // холст игнорирует события из контролов по этому атрибуту\n data-video-controls\n data-qa={dataQa}\n onPointerDownCapture={() => {\n pointerFocusRef.current = true;\n }}\n // фокус от клика приходит до pointerup; если его не было — сбрасываем флаг\n onPointerUpCapture={() => {\n pointerFocusRef.current = false;\n }}\n onPointerMove={(event) => event.pointerType === 'mouse' && store.notifyActivity()}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={onKeyDown}\n >\n {showScrubber && <Scrubber store={store} />}\n <div className={styles.controlsRow}>\n <div className={styles.controlsGroupStart}>\n {!isMobile && (\n <ControlButton\n label={playPause.label}\n icon={playPause.icon}\n onClick={() => {\n store.toggle();\n store.notifyActivity();\n }}\n withTooltip={withTooltip}\n control=\"play-pause\"\n data-qa=\"video-play-pause\"\n />\n )}\n <div className={styles.controlsTime}>\n <TimeLabel store={store} live={live && status !== 'loading'} compact={compact} />\n </div>\n </div>\n <div className={styles.controlsGroupEnd}>\n <ControlButton\n label={`${playbackRateTrl ?? ''}: ${rate}x`}\n onClick={() => {\n store.cycleRate();\n store.notifyActivity();\n }}\n withTooltip={withTooltip}\n compact={compact}\n control=\"playback-rate\"\n data-qa=\"video-playback-rate\"\n >\n <Text typography={compact ? 'subtitle-3-semibold' : 'subtitle-2-semibold'} style=\"constant\">\n {`${rate}x`}\n </Text>\n </ControlButton>\n <div className={styles.controlsVolume}>\n <ControlButton\n label={muted ? unmuteTrl : muteTrl}\n icon={muted ? SpeakerCrossedIcon : SpeakerWaveIcon}\n onClick={() => {\n store.setMuted(!muted);\n store.notifyActivity();\n }}\n withTooltip={withTooltip}\n bare\n control=\"mute\"\n data-qa=\"video-mute\"\n />\n {!isMobile && <VolumeSlider store={store} />}\n </div>\n <ControlButton\n label={fullscreen ? exitFullscreenTrl : enterFullscreenTrl}\n icon={fullscreen ? DashedSquareInOutlinedSize24 : EnterFullscreenIcon}\n onClick={() => {\n store.toggleFullscreen();\n store.notifyActivity();\n }}\n withTooltip={withTooltip}\n compact={compact}\n control=\"fullscreen\"\n data-qa=\"video-fullscreen\"\n />\n </div>\n </div>\n </div>\n );\n\n // в fullscreen разворачивается плеер — контролы переезжают в него; иначе — в заданный контейнер, если он есть\n const target = (fullscreen && store.getRoot()) || container;\n return target ? createPortal(renderResult, target) : renderResult;\n};\n\nVideoControls.displayName = 'VideoControls';\n"],"names":[],"mappings":"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"}
package/VideoPlayer.js CHANGED
@@ -19,7 +19,7 @@ import { useCanvasGestures } from './internal/useCanvasGestures.js';
19
19
  import { useInert } from './internal/useInert.js';
20
20
  import { useVideoHotkeys } from './internal/useVideoHotkeys.js';
21
21
  import { useViewportVisibility } from './internal/useViewportVisibility.js';
22
- import { s as styles } from './video-B0giLQLN.js';
22
+ import { s as styles } from './video-DR4YYLmP.js';
23
23
  import '@hh.ru/magritte-common-keyboard';
24
24
 
25
25
  const ERROR_PLACEHOLDER_MAX_WIDTH = 343;
package/index.css CHANGED
@@ -21,7 +21,7 @@
21
21
  .magritte-zp-day-theme{
22
22
  --magritte-color-background-accent-v26-0-2:#7195AF;
23
23
  }
24
- .magritte-player___IHHy5_1-0-3{
24
+ .magritte-player___IHHy5_1-1-1{
25
25
  position:relative;
26
26
  width:100%;
27
27
  overflow:hidden;
@@ -32,23 +32,23 @@
32
32
  -webkit-user-select:none;
33
33
  -webkit-touch-callout:none;
34
34
  }
35
- .magritte-player-fit___TX-6X_1-0-3{
35
+ .magritte-player-fit___TX-6X_1-1-1{
36
36
  height:100%;
37
37
  }
38
- .magritte-player-embedded___GNvRb_1-0-3{
38
+ .magritte-player-embedded___GNvRb_1-1-1{
39
39
  overflow:visible;
40
40
  background-color:transparent;
41
41
  }
42
- .magritte-video___4cS-u_1-0-3{
42
+ .magritte-video___4cS-u_1-1-1{
43
43
  display:block;
44
44
  width:100%;
45
45
  height:100%;
46
46
  object-fit:contain;
47
47
  }
48
- .magritte-video-hidden___agqVq_1-0-3{
48
+ .magritte-video-hidden___agqVq_1-1-1{
49
49
  visibility:hidden;
50
50
  }
51
- .magritte-overlay-button___MIRAP_1-0-3{
51
+ .magritte-overlay-button___MIRAP_1-1-1{
52
52
  position:absolute;
53
53
  top:50%;
54
54
  left:50%;
@@ -58,7 +58,7 @@
58
58
  backdrop-filter:blur(24px);
59
59
  transition:opacity var(--magritte-semantic-animation-time-m-duration-v26-0-2) var(--magritte-semantic-animation-ease-base-timing-function-v26-0-2);
60
60
  }
61
- .magritte-duration___ND1ei_1-0-3{
61
+ .magritte-duration___ND1ei_1-1-1{
62
62
  position:absolute;
63
63
  right:16px;
64
64
  bottom:16px;
@@ -69,7 +69,7 @@
69
69
  backdrop-filter:blur(24px);
70
70
  pointer-events:none;
71
71
  }
72
- .magritte-seek-indicator___VJQBC_1-0-3{
72
+ .magritte-seek-indicator___VJQBC_1-1-1{
73
73
  position:absolute;
74
74
  top:50%;
75
75
  display:flex;
@@ -78,25 +78,25 @@
78
78
  transform:translateY(-50%);
79
79
  pointer-events:none;
80
80
  }
81
- .magritte-seek-indicator-forward___9C5gD_1-0-3{
81
+ .magritte-seek-indicator-forward___9C5gD_1-1-1{
82
82
  right:40px;
83
83
  }
84
- .magritte-seek-indicator-backward___gIZ0E_1-0-3{
84
+ .magritte-seek-indicator-backward___gIZ0E_1-1-1{
85
85
  left:40px;
86
86
  flex-direction:row-reverse;
87
87
  --magritte-ui-video-seek-arrow-shift:16px;
88
88
  }
89
- .magritte-seek-arrows___Ql1eP_1-0-3{
89
+ .magritte-seek-arrows___Ql1eP_1-1-1{
90
90
  position:relative;
91
91
  display:flex;
92
92
  }
93
- .magritte-seek-arrow-incoming___oZxww_1-0-3{
93
+ .magritte-seek-arrow-incoming___oZxww_1-1-1{
94
94
  position:absolute;
95
95
  inset:0;
96
96
  display:flex;
97
- animation:magritte-seek-arrow-in___CB4-s_1-0-3 var(--magritte-semantic-animation-time-m-duration-v26-0-2) var(--magritte-semantic-animation-ease-base-timing-function-v26-0-2) both;
97
+ animation:magritte-seek-arrow-in___CB4-s_1-1-1 var(--magritte-semantic-animation-time-m-duration-v26-0-2) var(--magritte-semantic-animation-ease-base-timing-function-v26-0-2) both;
98
98
  }
99
- @keyframes magritte-seek-arrow-in___CB4-s_1-0-3{
99
+ @keyframes magritte-seek-arrow-in___CB4-s_1-1-1{
100
100
  from{
101
101
  transform:translateX(var(--magritte-ui-video-seek-arrow-shift, -16px));
102
102
  }
@@ -104,7 +104,7 @@
104
104
  transform:translateX(0);
105
105
  }
106
106
  }
107
- .magritte-boost-indicator___ujllx_1-0-3{
107
+ .magritte-boost-indicator___ujllx_1-1-1{
108
108
  position:absolute;
109
109
  top:24px;
110
110
  left:50%;
@@ -118,7 +118,7 @@
118
118
  transform:translateX(-50%);
119
119
  pointer-events:none;
120
120
  }
121
- .magritte-loader___qVu0P_1-0-3{
121
+ .magritte-loader___qVu0P_1-1-1{
122
122
  position:absolute;
123
123
  top:50%;
124
124
  left:50%;
@@ -126,7 +126,7 @@
126
126
  display:flex;
127
127
  pointer-events:none;
128
128
  }
129
- .magritte-error___Rm7uG_1-0-3{
129
+ .magritte-error___Rm7uG_1-1-1{
130
130
  position:absolute;
131
131
  inset:0;
132
132
  display:flex;
@@ -135,15 +135,15 @@
135
135
  padding:16px;
136
136
  overflow:auto;
137
137
  }
138
- .magritte-player-embedded___GNvRb_1-0-3 .magritte-error___Rm7uG_1-0-3{
138
+ .magritte-player-embedded___GNvRb_1-1-1 .magritte-error___Rm7uG_1-1-1{
139
139
  touch-action:none;
140
140
  }
141
- .magritte-overlay-button-hidden___AoGFc_1-0-3,
142
- .magritte-controls___pKoSN_1-0-3.magritte-controls-hidden___bePTD_1-0-3{
141
+ .magritte-overlay-button-hidden___AoGFc_1-1-1,
142
+ .magritte-controls___pKoSN_1-1-1.magritte-controls-hidden___bePTD_1-1-1{
143
143
  opacity:0;
144
144
  pointer-events:none;
145
145
  }
146
- .magritte-controls___pKoSN_1-0-3{
146
+ .magritte-controls___pKoSN_1-1-1{
147
147
  display:flex;
148
148
  flex-direction:column;
149
149
  gap:4px;
@@ -151,52 +151,56 @@
151
151
  pointer-events:auto;
152
152
  transition:opacity var(--magritte-semantic-animation-time-m-duration-v26-0-2) var(--magritte-semantic-animation-ease-base-timing-function-v26-0-2);
153
153
  }
154
- .magritte-controls-mobile___tdKGT_1-0-3{
154
+ .magritte-controls-mobile___tdKGT_1-1-1{
155
155
  gap:6px;
156
156
  padding:4px 16px 8px;
157
157
  }
158
- .magritte-controls-overlay___mRsJL_1-0-3{
158
+ .magritte-controls-mobile___tdKGT_1-1-1.magritte-controls-compact___WC9tB_1-1-1{
159
+ gap:4px;
160
+ padding:4px 8px 8px;
161
+ }
162
+ .magritte-controls-overlay___mRsJL_1-1-1{
159
163
  position:absolute;
160
164
  right:0;
161
165
  bottom:0;
162
166
  left:0;
163
167
  }
164
- .magritte-controls-row___2sdJg_1-0-3{
168
+ .magritte-controls-row___2sdJg_1-1-1{
165
169
  display:flex;
166
170
  align-items:center;
167
171
  justify-content:space-between;
168
172
  gap:8px;
169
173
  }
170
- .magritte-controls-group-start___yY9ZA_1-0-3,
171
- .magritte-controls-group-end___ziIm8_1-0-3{
174
+ .magritte-controls-group-start___yY9ZA_1-1-1,
175
+ .magritte-controls-group-end___ziIm8_1-1-1{
172
176
  display:flex;
173
177
  align-items:center;
174
178
  min-width:0;
175
179
  }
176
- .magritte-controls-group-start___yY9ZA_1-0-3{
180
+ .magritte-controls-group-start___yY9ZA_1-1-1{
177
181
  gap:12px;
178
182
  }
179
- .magritte-controls-group-end___ziIm8_1-0-3{
183
+ .magritte-controls-group-end___ziIm8_1-1-1{
180
184
  gap:8px;
181
185
  }
182
- .magritte-controls-mobile___tdKGT_1-0-3 .magritte-controls-group-end___ziIm8_1-0-3{
186
+ .magritte-controls-mobile___tdKGT_1-1-1 .magritte-controls-group-end___ziIm8_1-1-1{
183
187
  gap:4px;
184
188
  }
185
- .magritte-control-pill___hK8Mv_1-0-3,
186
- .magritte-controls-time___e9zoz_1-0-3,
187
- .magritte-controls-volume___o4ajR_1-0-3{
189
+ .magritte-control-pill___hK8Mv_1-1-1,
190
+ .magritte-controls-time___e9zoz_1-1-1,
191
+ .magritte-controls-volume___o4ajR_1-1-1{
188
192
  display:flex;
189
193
  align-items:center;
190
194
  justify-content:center;
191
195
  border-radius:999px;
192
196
  backdrop-filter:blur(24px);
193
197
  }
194
- .magritte-control-pill-bare___lU9ev_1-0-3{
198
+ .magritte-control-pill-bare___lU9ev_1-1-1{
195
199
  backdrop-filter:none;
196
200
  }
197
- .magritte-control-button___VJ2Qr_1-0-3,
198
- .magritte-controls-time___e9zoz_1-0-3,
199
- .magritte-controls-volume___o4ajR_1-0-3{
201
+ .magritte-control-button___VJ2Qr_1-1-1,
202
+ .magritte-controls-time___e9zoz_1-1-1,
203
+ .magritte-controls-volume___o4ajR_1-1-1{
200
204
  box-sizing:border-box;
201
205
  min-width:48px;
202
206
  min-height:48px;
@@ -204,27 +208,47 @@
204
208
  border-radius:999px;
205
209
  background-color:var(--magritte-color-background-overlay-v26-0-2);
206
210
  }
207
- .magritte-control-button___VJ2Qr_1-0-3{
211
+ .magritte-control-button___VJ2Qr_1-1-1{
208
212
  display:flex;
209
213
  align-items:center;
210
214
  justify-content:center;
215
+ width:48px;
216
+ height:48px;
217
+ padding:0;
211
218
  border-width:0;
219
+ white-space:nowrap;
212
220
  cursor:pointer;
213
221
  }
214
- .magritte-control-button___VJ2Qr_1-0-3.focus-visible{
222
+ .magritte-control-button___VJ2Qr_1-1-1.focus-visible{
215
223
  outline:4px solid var(--magritte-color-stroke-state-focused-accessible-v26-0-2);
216
224
  }
217
- .magritte-controls-time___e9zoz_1-0-3{
225
+ .magritte-controls-time___e9zoz_1-1-1{
218
226
  padding:12px 16px;
219
227
  white-space:nowrap;
220
228
  }
221
- .magritte-controls-mobile___tdKGT_1-0-3 .magritte-controls-time___e9zoz_1-0-3{
229
+ .magritte-controls-mobile___tdKGT_1-1-1 .magritte-controls-time___e9zoz_1-1-1{
222
230
  padding:12px;
223
231
  }
224
- .magritte-controls-volume___o4ajR_1-0-3{
232
+ .magritte-controls-volume___o4ajR_1-1-1{
225
233
  gap:6px;
226
234
  }
227
- .magritte-scrubber___-K3ik_1-0-3{
235
+ .magritte-controls-compact___WC9tB_1-1-1 .magritte-controls-time___e9zoz_1-1-1,
236
+ .magritte-controls-compact___WC9tB_1-1-1 .magritte-controls-volume___o4ajR_1-1-1{
237
+ min-width:32px;
238
+ min-height:32px;
239
+ padding:8px;
240
+ }
241
+ .magritte-controls-compact___WC9tB_1-1-1 .magritte-controls-time___e9zoz_1-1-1{
242
+ height:32px;
243
+ padding-block:0;
244
+ }
245
+ .magritte-control-button-compact___WaR9x_1-1-1{
246
+ width:32px;
247
+ min-width:0;
248
+ height:32px;
249
+ min-height:0;
250
+ }
251
+ .magritte-scrubber___-K3ik_1-1-1{
228
252
  position:relative;
229
253
  display:flex;
230
254
  align-items:center;
@@ -235,32 +259,35 @@
235
259
  --magritte-ui-video-scrubber-track-height:4px;
236
260
  --magritte-ui-video-scrubber-thumb-size:8px;
237
261
  }
238
- .magritte-controls-mobile___tdKGT_1-0-3 .magritte-scrubber___-K3ik_1-0-3::before{
262
+ .magritte-controls-mobile___tdKGT_1-1-1 .magritte-scrubber___-K3ik_1-1-1::before{
239
263
  content:'';
240
264
  position:absolute;
241
265
  inset:calc(-1 * 20px) 0 calc(-1 * 6px);
242
266
  }
243
- .magritte-scrubber___-K3ik_1-0-3.focus-visible{
267
+ .magritte-controls-compact___WC9tB_1-1-1 .magritte-scrubber___-K3ik_1-1-1::before{
268
+ bottom:calc(-1 * 4px);
269
+ }
270
+ .magritte-scrubber___-K3ik_1-1-1.focus-visible{
244
271
  outline:4px solid var(--magritte-color-stroke-state-focused-accessible-v26-0-2);
245
272
  border-radius:4px;
246
273
  }
247
- .magritte-scrubber___-K3ik_1-0-3[data-scrubbing]{
274
+ .magritte-scrubber___-K3ik_1-1-1[data-scrubbing]{
248
275
  --magritte-ui-video-scrubber-track-height:6px;
249
276
  --magritte-ui-video-scrubber-thumb-size:12px;
250
277
  }
251
278
  @media (min-width: 1020px){
252
- body.magritte-old-layout .magritte-scrubber___-K3ik_1-0-3:hover{
279
+ body.magritte-old-layout .magritte-scrubber___-K3ik_1-1-1:hover{
253
280
  --magritte-ui-video-scrubber-track-height:6px;
254
281
  --magritte-ui-video-scrubber-thumb-size:12px;
255
282
  }
256
283
  }
257
284
  @media (min-width: 1024px){
258
- body:not(.magritte-old-layout) .magritte-scrubber___-K3ik_1-0-3:hover{
285
+ body:not(.magritte-old-layout) .magritte-scrubber___-K3ik_1-1-1:hover{
259
286
  --magritte-ui-video-scrubber-track-height:6px;
260
287
  --magritte-ui-video-scrubber-thumb-size:12px;
261
288
  }
262
289
  }
263
- .magritte-scrubber-track___ki1zV_1-0-3{
290
+ .magritte-scrubber-track___ki1zV_1-1-1{
264
291
  position:relative;
265
292
  flex-grow:1;
266
293
  height:var(--magritte-ui-video-scrubber-track-height);
@@ -268,21 +295,21 @@
268
295
  border-radius:999px;
269
296
  background-color:var(--magritte-color-background-overlay-v26-0-2);
270
297
  }
271
- .magritte-scrubber-buffered___ufvLe_1-0-3,
272
- .magritte-scrubber-progress___ZIyew_1-0-3{
298
+ .magritte-scrubber-buffered___ufvLe_1-1-1,
299
+ .magritte-scrubber-progress___ZIyew_1-1-1{
273
300
  position:absolute;
274
301
  inset:0;
275
302
  transform-origin:left;
276
303
  }
277
- .magritte-scrubber-buffered___ufvLe_1-0-3{
304
+ .magritte-scrubber-buffered___ufvLe_1-1-1{
278
305
  background-color:var(--magritte-color-stroke-neutral-v26-0-2);
279
306
  transform:scaleX(var(--magritte-ui-video-scrubber-buffered, 0));
280
307
  }
281
- .magritte-scrubber-progress___ZIyew_1-0-3{
308
+ .magritte-scrubber-progress___ZIyew_1-1-1{
282
309
  background-color:var(--magritte-color-background-accent-v26-0-2);
283
310
  transform:scaleX(var(--magritte-ui-video-scrubber-progress, 0));
284
311
  }
285
- .magritte-scrubber-thumb___VXyPP_1-0-3{
312
+ .magritte-scrubber-thumb___VXyPP_1-1-1{
286
313
  position:absolute;
287
314
  top:50%;
288
315
  left:calc(var(--magritte-ui-video-scrubber-progress, 0) * 100%);
@@ -293,7 +320,7 @@
293
320
  transform:translate(-50%, -50%);
294
321
  pointer-events:none;
295
322
  }
296
- .magritte-scrubber-timecode___M-syA_1-0-3{
323
+ .magritte-scrubber-timecode___M-syA_1-1-1{
297
324
  position:absolute;
298
325
  bottom:calc(100% + 8px);
299
326
  left:calc(var(--magritte-ui-video-scrubber-timecode, 0) * 100%);
@@ -305,20 +332,20 @@
305
332
  white-space:nowrap;
306
333
  pointer-events:none;
307
334
  }
308
- .magritte-scrubber___-K3ik_1-0-3[data-scrubbing] .magritte-scrubber-timecode___M-syA_1-0-3{
335
+ .magritte-scrubber___-K3ik_1-1-1[data-scrubbing] .magritte-scrubber-timecode___M-syA_1-1-1{
309
336
  display:flex;
310
337
  }
311
338
  @media (min-width: 1020px){
312
- body.magritte-old-layout .magritte-scrubber___-K3ik_1-0-3:hover .magritte-scrubber-timecode___M-syA_1-0-3{
339
+ body.magritte-old-layout .magritte-scrubber___-K3ik_1-1-1:hover .magritte-scrubber-timecode___M-syA_1-1-1{
313
340
  display:flex;
314
341
  }
315
342
  }
316
343
  @media (min-width: 1024px){
317
- body:not(.magritte-old-layout) .magritte-scrubber___-K3ik_1-0-3:hover .magritte-scrubber-timecode___M-syA_1-0-3{
344
+ body:not(.magritte-old-layout) .magritte-scrubber___-K3ik_1-1-1:hover .magritte-scrubber-timecode___M-syA_1-1-1{
318
345
  display:flex;
319
346
  }
320
347
  }
321
- .magritte-volume-slider___qE2P7_1-0-3{
348
+ .magritte-volume-slider___qE2P7_1-1-1{
322
349
  display:flex;
323
350
  align-items:center;
324
351
  width:64px;
@@ -327,25 +354,25 @@
327
354
  touch-action:none;
328
355
  outline:none;
329
356
  }
330
- .magritte-volume-slider___qE2P7_1-0-3.focus-visible{
357
+ .magritte-volume-slider___qE2P7_1-1-1.focus-visible{
331
358
  outline:4px solid var(--magritte-color-stroke-state-focused-accessible-v26-0-2);
332
359
  border-radius:4px;
333
360
  }
334
- .magritte-volume-track___up8nd_1-0-3{
361
+ .magritte-volume-track___up8nd_1-1-1{
335
362
  position:relative;
336
363
  flex-grow:1;
337
364
  height:4px;
338
365
  border-radius:999px;
339
366
  background-color:var(--magritte-color-background-overlay-v26-0-2);
340
367
  }
341
- .magritte-volume-value___aUSuU_1-0-3{
368
+ .magritte-volume-value___aUSuU_1-1-1{
342
369
  position:relative;
343
370
  width:calc(var(--magritte-ui-video-volume, 1) * 100%);
344
371
  height:100%;
345
372
  border-radius:999px;
346
373
  background-color:var(--magritte-color-stroke-neutral-v26-0-2);
347
374
  }
348
- .magritte-volume-value___aUSuU_1-0-3::after{
375
+ .magritte-volume-value___aUSuU_1-1-1::after{
349
376
  content:'';
350
377
  position:absolute;
351
378
  top:50%;
package/index.js CHANGED
@@ -11,7 +11,7 @@ import '@hh.ru/magritte-ui-icon/icon';
11
11
  import '@hh.ru/magritte-ui-typography';
12
12
  import './internal/ControlButton.js';
13
13
  import '@hh.ru/magritte-ui-tooltip';
14
- import './video-B0giLQLN.js';
14
+ import './video-DR4YYLmP.js';
15
15
  import './internal/Scrubber.js';
16
16
  import './internal/formatTime.js';
17
17
  import './internal/useSliderPointer.js';
@@ -1,5 +1,5 @@
1
1
  import { type FC, type ReactNode } from 'react';
2
- import { type IconWrapperComponentSize24 } from '@hh.ru/magritte-ui-icon';
2
+ import { type IconWrapperComponentSize16, type IconWrapperComponentSize24 } from '@hh.ru/magritte-ui-icon';
3
3
  interface ControlButtonBaseProps {
4
4
  /** Имя контрола: по нему контролы находят кнопку (вернуть фокус после подмены). Не путать с `data-qa` */
5
5
  control: string;
@@ -8,11 +8,13 @@ interface ControlButtonBaseProps {
8
8
  onClick: VoidFunction;
9
9
  /** Подсказка при наведении — только на desktop и пока контролы видны */
10
10
  withTooltip: boolean;
11
+ /** Компактные кнопки 32px (mobile вне fullscreen): иконка 16 и отступы 8 */
12
+ compact?: boolean;
11
13
  'data-qa'?: string;
12
14
  }
13
15
  interface IconControlButtonProps extends ControlButtonBaseProps {
14
16
  /** Иконка-кнопка: подложку, отступы, скругление и состояния даёт сама иконка */
15
- icon: IconWrapperComponentSize24;
17
+ icon: IconWrapperComponentSize24 | IconWrapperComponentSize16;
16
18
  /** Без собственной подложки — внутри общей «таблетки» (громкость) */
17
19
  bare?: boolean;
18
20
  children?: never;
@@ -1,15 +1,16 @@
1
1
  import './../index.css';
2
- import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import { useRef } from 'react';
4
4
  import classnames from 'classnames';
5
5
  import { TooltipHover } from '@hh.ru/magritte-ui-tooltip';
6
- import { s as styles } from '../video-B0giLQLN.js';
6
+ import { s as styles } from '../video-DR4YYLmP.js';
7
7
 
8
8
  const ControlButton = ({
9
9
  control,
10
10
  label,
11
11
  onClick,
12
12
  withTooltip,
13
+ compact = false,
13
14
  icon: Icon,
14
15
  bare = false,
15
16
  children,
@@ -22,7 +23,7 @@ const ControlButton = ({
22
23
  "button",
23
24
  {
24
25
  type: "button",
25
- className: styles.controlButton,
26
+ className: classnames(styles.controlButton, { [styles.controlButtonCompact]: compact }),
26
27
  "aria-label": label,
27
28
  onClick,
28
29
  "data-qa": dataQa,
@@ -36,7 +37,7 @@ const ControlButton = ({
36
37
  Icon,
37
38
  {
38
39
  initialColor: "constant",
39
- padding: 12,
40
+ padding: compact ? 8 : 12,
40
41
  borderRadius: "halfHeight",
41
42
  backgroundStyle: "overlay",
42
43
  "aria-label": label,
@@ -1 +1 @@
1
- {"version":3,"file":"ControlButton.js","sources":["src/internal/ControlButton.tsx"],"sourcesContent":["import { type FC, type ReactNode, useRef } from 'react';\nimport classnames from 'classnames';\n\nimport { type IconWrapperComponentSize24 } from '@hh.ru/magritte-ui-icon';\nimport { TooltipHover } from '@hh.ru/magritte-ui-tooltip';\n\nimport styles from '../video.less';\n\ninterface ControlButtonBaseProps {\n /** Имя контрола: по нему контролы находят кнопку (вернуть фокус после подмены). Не путать с `data-qa` */\n control: string;\n /** aria-label и текст подсказки */\n label?: string;\n onClick: VoidFunction;\n /** Подсказка при наведении — только на desktop и пока контролы видны */\n withTooltip: boolean;\n 'data-qa'?: string;\n}\n\ninterface IconControlButtonProps extends ControlButtonBaseProps {\n /** Иконка-кнопка: подложку, отступы, скругление и состояния даёт сама иконка */\n icon: IconWrapperComponentSize24;\n /** Без собственной подложки — внутри общей «таблетки» (громкость) */\n bare?: boolean;\n children?: never;\n}\n\ninterface TextControlButtonProps extends ControlButtonBaseProps {\n icon?: never;\n bare?: never;\n /** Текстовое содержимое кнопки (скорость воспроизведения) */\n children: ReactNode;\n}\n\ntype ControlButtonProps = IconControlButtonProps | TextControlButtonProps;\n\nexport const ControlButton: FC<ControlButtonProps> = ({\n control,\n label,\n onClick,\n withTooltip,\n icon: Icon,\n bare = false,\n children,\n 'data-qa': dataQa,\n}) => {\n // активатор подсказки — обёртка: наведение на кнопку внутри неё тоже считается\n const ref = useRef<HTMLSpanElement>(null);\n\n let button: ReactNode;\n if (!Icon) {\n button = (\n <button\n type=\"button\"\n className={styles.controlButton}\n aria-label={label}\n onClick={onClick}\n data-qa={dataQa}\n >\n {children}\n </button>\n );\n } else if (bare) {\n button = <Icon initialColor=\"constant\" aria-label={label} onClick={onClick} data-qa={dataQa} />;\n } else {\n button = (\n <Icon\n initialColor=\"constant\"\n padding={12}\n borderRadius=\"halfHeight\"\n backgroundStyle=\"overlay\"\n aria-label={label}\n onClick={onClick}\n data-qa={dataQa}\n />\n );\n }\n\n return (\n <>\n {/* иконка-кнопка отдаёт свои атрибуты svg, а не кнопке — имя контрола на обёртке */}\n <span\n ref={ref}\n className={classnames(styles.controlPill, { [styles.controlPillBare]: bare })}\n data-video-control={control}\n >\n {button}\n </span>\n {withTooltip && label && (\n <TooltipHover activatorRef={ref} placement=\"top-center\" size=\"small\">\n {label}\n </TooltipHover>\n )}\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;AAoCO,MAAM,gBAAwC,CAAC;AAAA,EAClD,OAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EACA,IAAM,EAAA,IAAA;AAAA,EACN,IAAO,GAAA,KAAA;AAAA,EACP,QAAA;AAAA,EACA,SAAW,EAAA,MAAA;AACf,CAAM,KAAA;AAEF,EAAM,MAAA,GAAA,GAAM,OAAwB,IAAI,CAAA,CAAA;AAExC,EAAI,IAAA,MAAA,CAAA;AACJ,EAAA,IAAI,CAAC,IAAM,EAAA;AACP,IACI,MAAA,mBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACG,IAAK,EAAA,QAAA;AAAA,QACL,WAAW,MAAO,CAAA,aAAA;AAAA,QAClB,YAAY,EAAA,KAAA;AAAA,QACZ,OAAA;AAAA,QACA,SAAS,EAAA,MAAA;AAAA,QAER,QAAA;AAAA,OAAA;AAAA,KACL,CAAA;AAAA,aAEG,IAAM,EAAA;AACb,IAAS,MAAA,mBAAA,GAAA,CAAC,QAAK,YAAa,EAAA,UAAA,EAAW,cAAY,KAAO,EAAA,OAAA,EAAkB,WAAS,MAAQ,EAAA,CAAA,CAAA;AAAA,GAC1F,MAAA;AACH,IACI,MAAA,mBAAA,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACG,YAAa,EAAA,UAAA;AAAA,QACb,OAAS,EAAA,EAAA;AAAA,QACT,YAAa,EAAA,YAAA;AAAA,QACb,eAAgB,EAAA,SAAA;AAAA,QAChB,YAAY,EAAA,KAAA;AAAA,QACZ,OAAA;AAAA,QACA,SAAS,EAAA,MAAA;AAAA,OAAA;AAAA,KACb,CAAA;AAAA,GAER;AAEA,EAAA,uBAGQ,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACG,GAAA;AAAA,QACA,SAAA,EAAW,UAAW,CAAA,MAAA,CAAO,WAAa,EAAA,EAAE,CAAC,MAAO,CAAA,eAAe,GAAG,IAAA,EAAM,CAAA;AAAA,QAC5E,oBAAoB,EAAA,OAAA;AAAA,QAEnB,QAAA,EAAA,MAAA;AAAA,OAAA;AAAA,KACL;AAAA,IACC,WAAA,IAAe,KACZ,oBAAA,GAAA,CAAC,YAAa,EAAA,EAAA,YAAA,EAAc,KAAK,SAAU,EAAA,YAAA,EAAa,IAAK,EAAA,OAAA,EACxD,QACL,EAAA,KAAA,EAAA,CAAA;AAAA,GAER,EAAA,CAAA,CAAA;AAER;;;;"}
1
+ {"version":3,"file":"ControlButton.js","sources":["src/internal/ControlButton.tsx"],"sourcesContent":["import { type FC, type ReactNode, useRef } from 'react';\nimport classnames from 'classnames';\n\nimport { type IconWrapperComponentSize16, type IconWrapperComponentSize24 } from '@hh.ru/magritte-ui-icon';\nimport { TooltipHover } from '@hh.ru/magritte-ui-tooltip';\n\nimport styles from '../video.less';\n\ninterface ControlButtonBaseProps {\n /** Имя контрола: по нему контролы находят кнопку (вернуть фокус после подмены). Не путать с `data-qa` */\n control: string;\n /** aria-label и текст подсказки */\n label?: string;\n onClick: VoidFunction;\n /** Подсказка при наведении — только на desktop и пока контролы видны */\n withTooltip: boolean;\n /** Компактные кнопки 32px (mobile вне fullscreen): иконка 16 и отступы 8 */\n compact?: boolean;\n 'data-qa'?: string;\n}\n\ninterface IconControlButtonProps extends ControlButtonBaseProps {\n /** Иконка-кнопка: подложку, отступы, скругление и состояния даёт сама иконка */\n icon: IconWrapperComponentSize24 | IconWrapperComponentSize16;\n /** Без собственной подложки — внутри общей «таблетки» (громкость) */\n bare?: boolean;\n children?: never;\n}\n\ninterface TextControlButtonProps extends ControlButtonBaseProps {\n icon?: never;\n bare?: never;\n /** Текстовое содержимое кнопки (скорость воспроизведения) */\n children: ReactNode;\n}\n\ntype ControlButtonProps = IconControlButtonProps | TextControlButtonProps;\n\nexport const ControlButton: FC<ControlButtonProps> = ({\n control,\n label,\n onClick,\n withTooltip,\n compact = false,\n icon: Icon,\n bare = false,\n children,\n 'data-qa': dataQa,\n}) => {\n // активатор подсказки — обёртка: наведение на кнопку внутри неё тоже считается\n const ref = useRef<HTMLSpanElement>(null);\n\n let button: ReactNode;\n if (!Icon) {\n button = (\n <button\n type=\"button\"\n className={classnames(styles.controlButton, { [styles.controlButtonCompact]: compact })}\n aria-label={label}\n onClick={onClick}\n data-qa={dataQa}\n >\n {children}\n </button>\n );\n } else if (bare) {\n button = <Icon initialColor=\"constant\" aria-label={label} onClick={onClick} data-qa={dataQa} />;\n } else {\n button = (\n <Icon\n initialColor=\"constant\"\n padding={compact ? 8 : 12}\n borderRadius=\"halfHeight\"\n backgroundStyle=\"overlay\"\n aria-label={label}\n onClick={onClick}\n data-qa={dataQa}\n />\n );\n }\n\n return (\n <>\n {/* иконка-кнопка отдаёт свои атрибуты svg, а не кнопке — имя контрола на обёртке */}\n <span\n ref={ref}\n className={classnames(styles.controlPill, { [styles.controlPillBare]: bare })}\n data-video-control={control}\n >\n {button}\n </span>\n {withTooltip && label && (\n <TooltipHover activatorRef={ref} placement=\"top-center\" size=\"small\">\n {label}\n </TooltipHover>\n )}\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;AAsCO,MAAM,gBAAwC,CAAC;AAAA,EAClD,OAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAU,GAAA,KAAA;AAAA,EACV,IAAM,EAAA,IAAA;AAAA,EACN,IAAO,GAAA,KAAA;AAAA,EACP,QAAA;AAAA,EACA,SAAW,EAAA,MAAA;AACf,CAAM,KAAA;AAEF,EAAM,MAAA,GAAA,GAAM,OAAwB,IAAI,CAAA,CAAA;AAExC,EAAI,IAAA,MAAA,CAAA;AACJ,EAAA,IAAI,CAAC,IAAM,EAAA;AACP,IACI,MAAA,mBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACG,IAAK,EAAA,QAAA;AAAA,QACL,SAAA,EAAW,UAAW,CAAA,MAAA,CAAO,aAAe,EAAA,EAAE,CAAC,MAAO,CAAA,oBAAoB,GAAG,OAAA,EAAS,CAAA;AAAA,QACtF,YAAY,EAAA,KAAA;AAAA,QACZ,OAAA;AAAA,QACA,SAAS,EAAA,MAAA;AAAA,QAER,QAAA;AAAA,OAAA;AAAA,KACL,CAAA;AAAA,aAEG,IAAM,EAAA;AACb,IAAS,MAAA,mBAAA,GAAA,CAAC,QAAK,YAAa,EAAA,UAAA,EAAW,cAAY,KAAO,EAAA,OAAA,EAAkB,WAAS,MAAQ,EAAA,CAAA,CAAA;AAAA,GAC1F,MAAA;AACH,IACI,MAAA,mBAAA,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACG,YAAa,EAAA,UAAA;AAAA,QACb,OAAA,EAAS,UAAU,CAAI,GAAA,EAAA;AAAA,QACvB,YAAa,EAAA,YAAA;AAAA,QACb,eAAgB,EAAA,SAAA;AAAA,QAChB,YAAY,EAAA,KAAA;AAAA,QACZ,OAAA;AAAA,QACA,SAAS,EAAA,MAAA;AAAA,OAAA;AAAA,KACb,CAAA;AAAA,GAER;AAEA,EAAA,uBAGQ,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACG,GAAA;AAAA,QACA,SAAA,EAAW,UAAW,CAAA,MAAA,CAAO,WAAa,EAAA,EAAE,CAAC,MAAO,CAAA,eAAe,GAAG,IAAA,EAAM,CAAA;AAAA,QAC5E,oBAAoB,EAAA,OAAA;AAAA,QAEnB,QAAA,EAAA,MAAA;AAAA,OAAA;AAAA,KACL;AAAA,IACC,WAAA,IAAe,KACZ,oBAAA,GAAA,CAAC,YAAa,EAAA,EAAA,YAAA,EAAc,KAAK,SAAU,EAAA,YAAA,EAAa,IAAK,EAAA,OAAA,EACxD,QACL,EAAA,KAAA,EAAA,CAAA;AAAA,GAER,EAAA,CAAA,CAAA;AAER;;;;"}
@@ -6,7 +6,7 @@ import { Text } from '@hh.ru/magritte-ui-typography';
6
6
  import { formatTime, formatDuration } from './formatTime.js';
7
7
  import { useSliderPointer } from './useSliderPointer.js';
8
8
  import { SEEK_STEP_SECONDS } from './useVideoHotkeys.js';
9
- import { s as styles } from '../video-B0giLQLN.js';
9
+ import { s as styles } from '../video-DR4YYLmP.js';
10
10
  import '@hh.ru/magritte-common-keyboard';
11
11
 
12
12
  const KEYBOARD_SEEK_STEP = SEEK_STEP_SECONDS;
@@ -3,7 +3,7 @@ import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import classnames from 'classnames';
4
4
  import { ChevronRightOutlinedSize24, ChevronLeftOutlinedSize24 } from '@hh.ru/magritte-ui-icon/icon';
5
5
  import { Text } from '@hh.ru/magritte-ui-typography';
6
- import { s as styles } from '../video-B0giLQLN.js';
6
+ import { s as styles } from '../video-DR4YYLmP.js';
7
7
 
8
8
  const SeekIndicator = ({ direction, seconds, count }) => {
9
9
  const forward = direction > 0;
@@ -7,4 +7,5 @@ import { type VideoStore } from '../internal/store';
7
7
  export declare const TimeLabel: FC<{
8
8
  store: VideoStore;
9
9
  live: boolean;
10
+ compact: boolean;
10
11
  }>;
@@ -4,7 +4,7 @@ import { useRef, useEffect } from 'react';
4
4
  import { Text } from '@hh.ru/magritte-ui-typography';
5
5
  import { formatTime } from './formatTime.js';
6
6
 
7
- const TimeLabel = ({ store, live }) => {
7
+ const TimeLabel = ({ store, live, compact }) => {
8
8
  const ref = useRef(null);
9
9
  useEffect(
10
10
  () => store.subscribeTime(({ current, duration, origin }) => {
@@ -15,7 +15,7 @@ const TimeLabel = ({ store, live }) => {
15
15
  }),
16
16
  [store, live]
17
17
  );
18
- return /* @__PURE__ */ jsx(Text, { typography: "paragraph-3-regular", style: "constant", children: /* @__PURE__ */ jsx("span", { ref, "data-qa": "video-time" }) });
18
+ return /* @__PURE__ */ jsx(Text, { typography: compact ? "paragraph-4-regular" : "paragraph-3-regular", style: "constant", children: /* @__PURE__ */ jsx("span", { ref, "data-qa": "video-time" }) });
19
19
  };
20
20
 
21
21
  export { TimeLabel };
@@ -1 +1 @@
1
- {"version":3,"file":"TimeLabel.js","sources":["src/internal/TimeLabel.tsx"],"sourcesContent":["import { type FC, useEffect, useRef } from 'react';\n\nimport { Text } from '@hh.ru/magritte-ui-typography';\nimport { formatTime } from '@hh.ru/magritte-ui-video/internal/formatTime';\nimport { type VideoStore } from '@hh.ru/magritte-ui-video/internal/store';\n\n/**\n * Время `текущее / длительность`. Для live (длительность неизвестна) — только прошедшее время от старта воспроизведения.\n * Текст пишется прямо в DOM из `subscribeTime`, без React-рендеров на каждом кадре\n */\nexport const TimeLabel: FC<{ store: VideoStore; live: boolean }> = ({ store, live }) => {\n const ref = useRef<HTMLSpanElement>(null);\n\n useEffect(\n () =>\n store.subscribeTime(({ current, duration, origin }) => {\n if (!ref.current) {\n return;\n }\n ref.current.textContent = live\n ? formatTime(current - origin)\n : `${formatTime(current)} / ${formatTime(duration)}`;\n }),\n [store, live]\n );\n\n return (\n <Text typography=\"paragraph-3-regular\" style=\"constant\">\n <span ref={ref} data-qa=\"video-time\" />\n </Text>\n );\n};\n"],"names":[],"mappings":";;;;;AAUO,MAAM,SAAsD,GAAA,CAAC,EAAE,KAAA,EAAO,MAAW,KAAA;AACpF,EAAM,MAAA,GAAA,GAAM,OAAwB,IAAI,CAAA,CAAA;AAExC,EAAA,SAAA;AAAA,IACI,MACI,MAAM,aAAc,CAAA,CAAC,EAAE,OAAS,EAAA,QAAA,EAAU,QAAa,KAAA;AACnD,MAAI,IAAA,CAAC,IAAI,OAAS,EAAA;AACd,QAAA,OAAA;AAAA,OACJ;AACA,MAAA,GAAA,CAAI,OAAQ,CAAA,WAAA,GAAc,IACpB,GAAA,UAAA,CAAW,UAAU,MAAM,CAAA,GAC3B,CAAG,EAAA,UAAA,CAAW,OAAO,CAAC,CAAM,GAAA,EAAA,UAAA,CAAW,QAAQ,CAAC,CAAA,CAAA,CAAA;AAAA,KACzD,CAAA;AAAA,IACL,CAAC,OAAO,IAAI,CAAA;AAAA,GAChB,CAAA;AAEA,EACI,uBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,UAAA,EAAW,qBAAsB,EAAA,KAAA,EAAM,UACzC,EAAA,QAAA,kBAAA,GAAA,CAAC,MAAK,EAAA,EAAA,GAAA,EAAU,SAAQ,EAAA,YAAA,EAAa,CACzC,EAAA,CAAA,CAAA;AAER;;;;"}
1
+ {"version":3,"file":"TimeLabel.js","sources":["src/internal/TimeLabel.tsx"],"sourcesContent":["import { type FC, useEffect, useRef } from 'react';\n\nimport { Text } from '@hh.ru/magritte-ui-typography';\nimport { formatTime } from '@hh.ru/magritte-ui-video/internal/formatTime';\nimport { type VideoStore } from '@hh.ru/magritte-ui-video/internal/store';\n\n/**\n * Время `текущее / длительность`. Для live (длительность неизвестна) — только прошедшее время от старта воспроизведения.\n * Текст пишется прямо в DOM из `subscribeTime`, без React-рендеров на каждом кадре\n */\nexport const TimeLabel: FC<{ store: VideoStore; live: boolean; compact: boolean }> = ({ store, live, compact }) => {\n const ref = useRef<HTMLSpanElement>(null);\n\n useEffect(\n () =>\n store.subscribeTime(({ current, duration, origin }) => {\n if (!ref.current) {\n return;\n }\n ref.current.textContent = live\n ? formatTime(current - origin)\n : `${formatTime(current)} / ${formatTime(duration)}`;\n }),\n [store, live]\n );\n\n return (\n <Text typography={compact ? 'paragraph-4-regular' : 'paragraph-3-regular'} style=\"constant\">\n <span ref={ref} data-qa=\"video-time\" />\n </Text>\n );\n};\n"],"names":[],"mappings":";;;;;AAUO,MAAM,YAAwE,CAAC,EAAE,KAAO,EAAA,IAAA,EAAM,SAAc,KAAA;AAC/G,EAAM,MAAA,GAAA,GAAM,OAAwB,IAAI,CAAA,CAAA;AAExC,EAAA,SAAA;AAAA,IACI,MACI,MAAM,aAAc,CAAA,CAAC,EAAE,OAAS,EAAA,QAAA,EAAU,QAAa,KAAA;AACnD,MAAI,IAAA,CAAC,IAAI,OAAS,EAAA;AACd,QAAA,OAAA;AAAA,OACJ;AACA,MAAA,GAAA,CAAI,OAAQ,CAAA,WAAA,GAAc,IACpB,GAAA,UAAA,CAAW,UAAU,MAAM,CAAA,GAC3B,CAAG,EAAA,UAAA,CAAW,OAAO,CAAC,CAAM,GAAA,EAAA,UAAA,CAAW,QAAQ,CAAC,CAAA,CAAA,CAAA;AAAA,KACzD,CAAA;AAAA,IACL,CAAC,OAAO,IAAI,CAAA;AAAA,GAChB,CAAA;AAEA,EAAA,uBACK,GAAA,CAAA,IAAA,EAAA,EAAK,UAAY,EAAA,OAAA,GAAU,qBAAwB,GAAA,qBAAA,EAAuB,KAAM,EAAA,UAAA,EAC7E,QAAC,kBAAA,GAAA,CAAA,MAAA,EAAA,EAAK,GAAU,EAAA,SAAA,EAAQ,cAAa,CACzC,EAAA,CAAA,CAAA;AAER;;;;"}
@@ -3,7 +3,7 @@ import { jsx } from 'react/jsx-runtime';
3
3
  import { useTranslation } from '@hh.ru/magritte-common-use-translation';
4
4
  import { useVideoState } from './context.js';
5
5
  import { useSliderPointer } from './useSliderPointer.js';
6
- import { s as styles } from '../video-B0giLQLN.js';
6
+ import { s as styles } from '../video-DR4YYLmP.js';
7
7
  import 'react';
8
8
 
9
9
  const KEYBOARD_VOLUME_STEP = 0.1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hh.ru/magritte-ui-video",
3
- "version": "1.0.3",
3
+ "version": "1.1.1",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "sideEffects": [
@@ -24,13 +24,13 @@
24
24
  "@hh.ru/magritte-common-use-translation": "3.8.0",
25
25
  "@hh.ru/magritte-design-tokens": "26.0.2",
26
26
  "@hh.ru/magritte-ui-breakpoint": "6.1.3",
27
- "@hh.ru/magritte-ui-button": "7.3.9",
28
- "@hh.ru/magritte-ui-button-stack": "4.0.38",
29
- "@hh.ru/magritte-ui-icon": "15.1.6",
30
- "@hh.ru/magritte-ui-loader": "4.1.7",
27
+ "@hh.ru/magritte-ui-button": "7.4.0",
28
+ "@hh.ru/magritte-ui-button-stack": "4.1.0",
29
+ "@hh.ru/magritte-ui-icon": "15.2.0",
30
+ "@hh.ru/magritte-ui-loader": "4.2.0",
31
31
  "@hh.ru/magritte-ui-mock-component": "1.1.9",
32
- "@hh.ru/magritte-ui-placeholder": "11.1.52",
33
- "@hh.ru/magritte-ui-tooltip": "11.0.54",
32
+ "@hh.ru/magritte-ui-placeholder": "11.2.0",
33
+ "@hh.ru/magritte-ui-tooltip": "11.1.0",
34
34
  "@hh.ru/magritte-ui-typography": "5.3.17"
35
35
  },
36
36
  "peerDependencies": {
@@ -41,5 +41,5 @@
41
41
  "publishConfig": {
42
42
  "access": "public"
43
43
  },
44
- "gitHead": "17a448d4bbe9f55b342f0b1ba7612bfe7acd76d7"
44
+ "gitHead": "4cd5113b854b80bce029febd28c0bfdf4773da7c"
45
45
  }
@@ -0,0 +1,5 @@
1
+ import './index.css';
2
+ var styles = {"player":"magritte-player___IHHy5_1-1-1","player-fit":"magritte-player-fit___TX-6X_1-1-1","playerFit":"magritte-player-fit___TX-6X_1-1-1","player-embedded":"magritte-player-embedded___GNvRb_1-1-1","playerEmbedded":"magritte-player-embedded___GNvRb_1-1-1","video":"magritte-video___4cS-u_1-1-1","video-hidden":"magritte-video-hidden___agqVq_1-1-1","videoHidden":"magritte-video-hidden___agqVq_1-1-1","overlay-button":"magritte-overlay-button___MIRAP_1-1-1","overlayButton":"magritte-overlay-button___MIRAP_1-1-1","duration":"magritte-duration___ND1ei_1-1-1","seek-indicator":"magritte-seek-indicator___VJQBC_1-1-1","seekIndicator":"magritte-seek-indicator___VJQBC_1-1-1","seek-indicator-forward":"magritte-seek-indicator-forward___9C5gD_1-1-1","seekIndicatorForward":"magritte-seek-indicator-forward___9C5gD_1-1-1","seek-indicator-backward":"magritte-seek-indicator-backward___gIZ0E_1-1-1","seekIndicatorBackward":"magritte-seek-indicator-backward___gIZ0E_1-1-1","seek-arrows":"magritte-seek-arrows___Ql1eP_1-1-1","seekArrows":"magritte-seek-arrows___Ql1eP_1-1-1","seek-arrow-incoming":"magritte-seek-arrow-incoming___oZxww_1-1-1","seekArrowIncoming":"magritte-seek-arrow-incoming___oZxww_1-1-1","seek-arrow-in":"magritte-seek-arrow-in___CB4-s_1-1-1","seekArrowIn":"magritte-seek-arrow-in___CB4-s_1-1-1","boost-indicator":"magritte-boost-indicator___ujllx_1-1-1","boostIndicator":"magritte-boost-indicator___ujllx_1-1-1","loader":"magritte-loader___qVu0P_1-1-1","error":"magritte-error___Rm7uG_1-1-1","overlay-button-hidden":"magritte-overlay-button-hidden___AoGFc_1-1-1","overlayButtonHidden":"magritte-overlay-button-hidden___AoGFc_1-1-1","controls":"magritte-controls___pKoSN_1-1-1","controls-hidden":"magritte-controls-hidden___bePTD_1-1-1","controlsHidden":"magritte-controls-hidden___bePTD_1-1-1","controls-mobile":"magritte-controls-mobile___tdKGT_1-1-1","controlsMobile":"magritte-controls-mobile___tdKGT_1-1-1","controls-compact":"magritte-controls-compact___WC9tB_1-1-1","controlsCompact":"magritte-controls-compact___WC9tB_1-1-1","controls-overlay":"magritte-controls-overlay___mRsJL_1-1-1","controlsOverlay":"magritte-controls-overlay___mRsJL_1-1-1","controls-row":"magritte-controls-row___2sdJg_1-1-1","controlsRow":"magritte-controls-row___2sdJg_1-1-1","controls-group-start":"magritte-controls-group-start___yY9ZA_1-1-1","controlsGroupStart":"magritte-controls-group-start___yY9ZA_1-1-1","controls-group-end":"magritte-controls-group-end___ziIm8_1-1-1","controlsGroupEnd":"magritte-controls-group-end___ziIm8_1-1-1","control-pill":"magritte-control-pill___hK8Mv_1-1-1","controlPill":"magritte-control-pill___hK8Mv_1-1-1","controls-time":"magritte-controls-time___e9zoz_1-1-1","controlsTime":"magritte-controls-time___e9zoz_1-1-1","controls-volume":"magritte-controls-volume___o4ajR_1-1-1","controlsVolume":"magritte-controls-volume___o4ajR_1-1-1","control-pill-bare":"magritte-control-pill-bare___lU9ev_1-1-1","controlPillBare":"magritte-control-pill-bare___lU9ev_1-1-1","control-button":"magritte-control-button___VJ2Qr_1-1-1","controlButton":"magritte-control-button___VJ2Qr_1-1-1","control-button-compact":"magritte-control-button-compact___WaR9x_1-1-1","controlButtonCompact":"magritte-control-button-compact___WaR9x_1-1-1","scrubber":"magritte-scrubber___-K3ik_1-1-1","scrubber-track":"magritte-scrubber-track___ki1zV_1-1-1","scrubberTrack":"magritte-scrubber-track___ki1zV_1-1-1","scrubber-buffered":"magritte-scrubber-buffered___ufvLe_1-1-1","scrubberBuffered":"magritte-scrubber-buffered___ufvLe_1-1-1","scrubber-progress":"magritte-scrubber-progress___ZIyew_1-1-1","scrubberProgress":"magritte-scrubber-progress___ZIyew_1-1-1","scrubber-thumb":"magritte-scrubber-thumb___VXyPP_1-1-1","scrubberThumb":"magritte-scrubber-thumb___VXyPP_1-1-1","scrubber-timecode":"magritte-scrubber-timecode___M-syA_1-1-1","scrubberTimecode":"magritte-scrubber-timecode___M-syA_1-1-1","volume-slider":"magritte-volume-slider___qE2P7_1-1-1","volumeSlider":"magritte-volume-slider___qE2P7_1-1-1","volume-track":"magritte-volume-track___up8nd_1-1-1","volumeTrack":"magritte-volume-track___up8nd_1-1-1","volume-value":"magritte-volume-value___aUSuU_1-1-1","volumeValue":"magritte-volume-value___aUSuU_1-1-1"};
3
+
4
+ export { styles as s };
5
+ //# sourceMappingURL=video-DR4YYLmP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-DR4YYLmP.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
package/video-B0giLQLN.js DELETED
@@ -1,5 +0,0 @@
1
- import './index.css';
2
- var styles = {"player":"magritte-player___IHHy5_1-0-3","player-fit":"magritte-player-fit___TX-6X_1-0-3","playerFit":"magritte-player-fit___TX-6X_1-0-3","player-embedded":"magritte-player-embedded___GNvRb_1-0-3","playerEmbedded":"magritte-player-embedded___GNvRb_1-0-3","video":"magritte-video___4cS-u_1-0-3","video-hidden":"magritte-video-hidden___agqVq_1-0-3","videoHidden":"magritte-video-hidden___agqVq_1-0-3","overlay-button":"magritte-overlay-button___MIRAP_1-0-3","overlayButton":"magritte-overlay-button___MIRAP_1-0-3","duration":"magritte-duration___ND1ei_1-0-3","seek-indicator":"magritte-seek-indicator___VJQBC_1-0-3","seekIndicator":"magritte-seek-indicator___VJQBC_1-0-3","seek-indicator-forward":"magritte-seek-indicator-forward___9C5gD_1-0-3","seekIndicatorForward":"magritte-seek-indicator-forward___9C5gD_1-0-3","seek-indicator-backward":"magritte-seek-indicator-backward___gIZ0E_1-0-3","seekIndicatorBackward":"magritte-seek-indicator-backward___gIZ0E_1-0-3","seek-arrows":"magritte-seek-arrows___Ql1eP_1-0-3","seekArrows":"magritte-seek-arrows___Ql1eP_1-0-3","seek-arrow-incoming":"magritte-seek-arrow-incoming___oZxww_1-0-3","seekArrowIncoming":"magritte-seek-arrow-incoming___oZxww_1-0-3","seek-arrow-in":"magritte-seek-arrow-in___CB4-s_1-0-3","seekArrowIn":"magritte-seek-arrow-in___CB4-s_1-0-3","boost-indicator":"magritte-boost-indicator___ujllx_1-0-3","boostIndicator":"magritte-boost-indicator___ujllx_1-0-3","loader":"magritte-loader___qVu0P_1-0-3","error":"magritte-error___Rm7uG_1-0-3","overlay-button-hidden":"magritte-overlay-button-hidden___AoGFc_1-0-3","overlayButtonHidden":"magritte-overlay-button-hidden___AoGFc_1-0-3","controls":"magritte-controls___pKoSN_1-0-3","controls-hidden":"magritte-controls-hidden___bePTD_1-0-3","controlsHidden":"magritte-controls-hidden___bePTD_1-0-3","controls-mobile":"magritte-controls-mobile___tdKGT_1-0-3","controlsMobile":"magritte-controls-mobile___tdKGT_1-0-3","controls-overlay":"magritte-controls-overlay___mRsJL_1-0-3","controlsOverlay":"magritte-controls-overlay___mRsJL_1-0-3","controls-row":"magritte-controls-row___2sdJg_1-0-3","controlsRow":"magritte-controls-row___2sdJg_1-0-3","controls-group-start":"magritte-controls-group-start___yY9ZA_1-0-3","controlsGroupStart":"magritte-controls-group-start___yY9ZA_1-0-3","controls-group-end":"magritte-controls-group-end___ziIm8_1-0-3","controlsGroupEnd":"magritte-controls-group-end___ziIm8_1-0-3","control-pill":"magritte-control-pill___hK8Mv_1-0-3","controlPill":"magritte-control-pill___hK8Mv_1-0-3","controls-time":"magritte-controls-time___e9zoz_1-0-3","controlsTime":"magritte-controls-time___e9zoz_1-0-3","controls-volume":"magritte-controls-volume___o4ajR_1-0-3","controlsVolume":"magritte-controls-volume___o4ajR_1-0-3","control-pill-bare":"magritte-control-pill-bare___lU9ev_1-0-3","controlPillBare":"magritte-control-pill-bare___lU9ev_1-0-3","control-button":"magritte-control-button___VJ2Qr_1-0-3","controlButton":"magritte-control-button___VJ2Qr_1-0-3","scrubber":"magritte-scrubber___-K3ik_1-0-3","scrubber-track":"magritte-scrubber-track___ki1zV_1-0-3","scrubberTrack":"magritte-scrubber-track___ki1zV_1-0-3","scrubber-buffered":"magritte-scrubber-buffered___ufvLe_1-0-3","scrubberBuffered":"magritte-scrubber-buffered___ufvLe_1-0-3","scrubber-progress":"magritte-scrubber-progress___ZIyew_1-0-3","scrubberProgress":"magritte-scrubber-progress___ZIyew_1-0-3","scrubber-thumb":"magritte-scrubber-thumb___VXyPP_1-0-3","scrubberThumb":"magritte-scrubber-thumb___VXyPP_1-0-3","scrubber-timecode":"magritte-scrubber-timecode___M-syA_1-0-3","scrubberTimecode":"magritte-scrubber-timecode___M-syA_1-0-3","volume-slider":"magritte-volume-slider___qE2P7_1-0-3","volumeSlider":"magritte-volume-slider___qE2P7_1-0-3","volume-track":"magritte-volume-track___up8nd_1-0-3","volumeTrack":"magritte-volume-track___up8nd_1-0-3","volume-value":"magritte-volume-value___aUSuU_1-0-3","volumeValue":"magritte-volume-value___aUSuU_1-0-3"};
3
-
4
- export { styles as s };
5
- //# sourceMappingURL=video-B0giLQLN.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"video-B0giLQLN.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}