@x-plat/design-system 0.5.4 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Table/index.cjs +8 -2
- package/dist/components/Table/index.css +15 -0
- package/dist/components/Table/index.d.cts +2 -0
- package/dist/components/Table/index.d.ts +2 -0
- package/dist/components/Table/index.js +8 -2
- package/dist/components/Video/index.cjs +580 -37
- package/dist/components/Video/index.css +202 -20
- package/dist/components/Video/index.d.cts +11 -0
- package/dist/components/Video/index.d.ts +11 -0
- package/dist/components/Video/index.js +580 -37
- package/dist/components/index.cjs +440 -38
- package/dist/components/index.css +217 -20
- package/dist/components/index.js +440 -38
- package/dist/index.cjs +324 -38
- package/dist/index.css +217 -20
- package/dist/index.js +324 -38
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -3609,6 +3609,7 @@
|
|
|
3609
3609
|
width: 100%;
|
|
3610
3610
|
height: 100%;
|
|
3611
3611
|
position: relative;
|
|
3612
|
+
overflow: auto;
|
|
3612
3613
|
}
|
|
3613
3614
|
.lib-xplat-table-wrapper > .lib-xplat-table {
|
|
3614
3615
|
width: 100%;
|
|
@@ -3681,6 +3682,20 @@
|
|
|
3681
3682
|
min-width: 80px;
|
|
3682
3683
|
padding: var(--spacing-space-2);
|
|
3683
3684
|
vertical-align: middle;
|
|
3685
|
+
word-break: keep-all;
|
|
3686
|
+
overflow-wrap: anywhere;
|
|
3687
|
+
}
|
|
3688
|
+
.lib-xplat-table-wrapper > .lib-xplat-table > thead > tr > td.nowrap,
|
|
3689
|
+
.lib-xplat-table-wrapper > .lib-xplat-table > thead > tr > th.nowrap,
|
|
3690
|
+
.lib-xplat-table-wrapper > .lib-xplat-table > tbody > tr > td.nowrap,
|
|
3691
|
+
.lib-xplat-table-wrapper > .lib-xplat-table > tbody > tr > th.nowrap {
|
|
3692
|
+
white-space: nowrap;
|
|
3693
|
+
overflow-wrap: normal;
|
|
3694
|
+
}
|
|
3695
|
+
.lib-xplat-table-wrapper > .lib-xplat-table > thead > tr > td,
|
|
3696
|
+
.lib-xplat-table-wrapper > .lib-xplat-table > thead > tr > th,
|
|
3697
|
+
.lib-xplat-table-wrapper > .lib-xplat-table > tbody > tr > td,
|
|
3698
|
+
.lib-xplat-table-wrapper > .lib-xplat-table > tbody > tr > th {
|
|
3684
3699
|
transition: background-color 0.28s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
3685
3700
|
}
|
|
3686
3701
|
.lib-xplat-table-wrapper > .lib-xplat-table > thead > tr > td.clickable,
|
|
@@ -4064,11 +4079,9 @@
|
|
|
4064
4079
|
max-height: 100%;
|
|
4065
4080
|
object-fit: contain;
|
|
4066
4081
|
vertical-align: middle;
|
|
4067
|
-
}
|
|
4068
|
-
.lib-xplat-video.custom-overlay > video {
|
|
4069
4082
|
cursor: pointer;
|
|
4070
4083
|
}
|
|
4071
|
-
.lib-xplat-video
|
|
4084
|
+
.lib-xplat-video > .center-play {
|
|
4072
4085
|
position: absolute;
|
|
4073
4086
|
top: 0;
|
|
4074
4087
|
left: 0;
|
|
@@ -4082,9 +4095,10 @@
|
|
|
4082
4095
|
cursor: pointer;
|
|
4083
4096
|
padding: 0;
|
|
4084
4097
|
color: var(--semantic-icon-inverse);
|
|
4085
|
-
transition: opacity 0.2s ease
|
|
4098
|
+
transition: opacity 0.2s ease;
|
|
4099
|
+
pointer-events: none;
|
|
4086
4100
|
}
|
|
4087
|
-
.lib-xplat-video
|
|
4101
|
+
.lib-xplat-video > .center-play::before {
|
|
4088
4102
|
content: "";
|
|
4089
4103
|
position: absolute;
|
|
4090
4104
|
inset: 0;
|
|
@@ -4092,34 +4106,217 @@
|
|
|
4092
4106
|
opacity: 0;
|
|
4093
4107
|
transition: opacity 0.2s ease;
|
|
4094
4108
|
}
|
|
4095
|
-
.lib-xplat-video.
|
|
4096
|
-
.lib-xplat-video.custom-overlay > .play-overlay:focus-visible::before {
|
|
4097
|
-
opacity: 1;
|
|
4098
|
-
}
|
|
4099
|
-
.lib-xplat-video.custom-overlay > .play-overlay:focus-visible {
|
|
4100
|
-
outline: 2px solid var(--semantic-interaction-focus-ring);
|
|
4101
|
-
outline-offset: 2px;
|
|
4102
|
-
}
|
|
4103
|
-
.lib-xplat-video.custom-overlay > .play-overlay > .play-icon {
|
|
4109
|
+
.lib-xplat-video > .center-play > .center-play-icon {
|
|
4104
4110
|
position: relative;
|
|
4105
4111
|
z-index: 1;
|
|
4106
4112
|
display: flex;
|
|
4107
|
-
align-items: center;
|
|
4108
|
-
justify-content: center;
|
|
4109
4113
|
font-size: 64px;
|
|
4110
4114
|
filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.4));
|
|
4111
4115
|
}
|
|
4112
|
-
.lib-xplat-video
|
|
4116
|
+
.lib-xplat-video > .center-play.is-playing {
|
|
4113
4117
|
opacity: 0;
|
|
4114
|
-
pointer-events: none;
|
|
4115
4118
|
}
|
|
4116
|
-
.lib-xplat-video
|
|
4119
|
+
.lib-xplat-video > .center-play.is-loading .center-play-icon {
|
|
4117
4120
|
opacity: 0.6;
|
|
4118
4121
|
}
|
|
4119
|
-
.lib-xplat-video
|
|
4122
|
+
.lib-xplat-video > .controls {
|
|
4123
|
+
position: absolute;
|
|
4124
|
+
left: 0;
|
|
4125
|
+
right: 0;
|
|
4126
|
+
bottom: 0;
|
|
4127
|
+
padding: var(--spacing-space-2) var(--spacing-space-3);
|
|
4128
|
+
display: flex;
|
|
4129
|
+
flex-direction: column;
|
|
4130
|
+
gap: var(--spacing-space-1);
|
|
4131
|
+
background:
|
|
4132
|
+
linear-gradient(
|
|
4133
|
+
to top,
|
|
4134
|
+
rgba(0, 0, 0, 0.7),
|
|
4135
|
+
rgba(0, 0, 0, 0));
|
|
4136
|
+
color: var(--semantic-icon-inverse);
|
|
4137
|
+
opacity: 0;
|
|
4138
|
+
transition: opacity 0.2s ease;
|
|
4139
|
+
pointer-events: none;
|
|
4140
|
+
}
|
|
4141
|
+
.lib-xplat-video:hover > .controls,
|
|
4142
|
+
.lib-xplat-video:focus-within > .controls {
|
|
4120
4143
|
opacity: 1;
|
|
4121
4144
|
pointer-events: auto;
|
|
4122
4145
|
}
|
|
4146
|
+
.lib-xplat-video .controls-row {
|
|
4147
|
+
display: flex;
|
|
4148
|
+
align-items: center;
|
|
4149
|
+
gap: var(--spacing-space-2);
|
|
4150
|
+
}
|
|
4151
|
+
.lib-xplat-video .control-btn {
|
|
4152
|
+
display: inline-flex;
|
|
4153
|
+
align-items: center;
|
|
4154
|
+
justify-content: center;
|
|
4155
|
+
width: 32px;
|
|
4156
|
+
height: 32px;
|
|
4157
|
+
padding: 0;
|
|
4158
|
+
border: none;
|
|
4159
|
+
background: transparent;
|
|
4160
|
+
color: inherit;
|
|
4161
|
+
cursor: pointer;
|
|
4162
|
+
border-radius: var(--spacing-radius-sm);
|
|
4163
|
+
transition: background-color 0.15s ease;
|
|
4164
|
+
}
|
|
4165
|
+
.lib-xplat-video .control-btn:hover {
|
|
4166
|
+
background-color: rgba(255, 255, 255, 0.15);
|
|
4167
|
+
}
|
|
4168
|
+
.lib-xplat-video .control-btn:focus-visible {
|
|
4169
|
+
outline: 2px solid var(--semantic-interaction-focus-ring);
|
|
4170
|
+
outline-offset: 2px;
|
|
4171
|
+
}
|
|
4172
|
+
.lib-xplat-video .controls-spacer {
|
|
4173
|
+
margin-left: auto;
|
|
4174
|
+
}
|
|
4175
|
+
.lib-xplat-video .control-btn.is-active {
|
|
4176
|
+
background-color: rgba(255, 255, 255, 0.25);
|
|
4177
|
+
}
|
|
4178
|
+
.lib-xplat-video .rate-group {
|
|
4179
|
+
position: relative;
|
|
4180
|
+
}
|
|
4181
|
+
.lib-xplat-video .rate-group .rate-btn {
|
|
4182
|
+
width: auto;
|
|
4183
|
+
padding: 0 var(--spacing-space-2);
|
|
4184
|
+
font-size: 12px;
|
|
4185
|
+
font-weight: 600;
|
|
4186
|
+
font-variant-numeric: tabular-nums;
|
|
4187
|
+
}
|
|
4188
|
+
.lib-xplat-video .rate-group .rate-menu {
|
|
4189
|
+
position: absolute;
|
|
4190
|
+
bottom: calc(100% + var(--spacing-space-1));
|
|
4191
|
+
right: 0;
|
|
4192
|
+
margin: 0;
|
|
4193
|
+
padding: var(--spacing-space-1);
|
|
4194
|
+
list-style: none;
|
|
4195
|
+
background-color: rgba(0, 0, 0, 0.85);
|
|
4196
|
+
border-radius: var(--spacing-radius-sm);
|
|
4197
|
+
min-width: 64px;
|
|
4198
|
+
}
|
|
4199
|
+
.lib-xplat-video .rate-group .rate-menu .rate-item {
|
|
4200
|
+
width: 100%;
|
|
4201
|
+
padding: var(--spacing-space-1) var(--spacing-space-2);
|
|
4202
|
+
border: none;
|
|
4203
|
+
background: transparent;
|
|
4204
|
+
color: inherit;
|
|
4205
|
+
text-align: left;
|
|
4206
|
+
cursor: pointer;
|
|
4207
|
+
border-radius: var(--spacing-radius-xs);
|
|
4208
|
+
font-size: 12px;
|
|
4209
|
+
font-variant-numeric: tabular-nums;
|
|
4210
|
+
}
|
|
4211
|
+
.lib-xplat-video .rate-group .rate-menu .rate-item:hover {
|
|
4212
|
+
background-color: rgba(255, 255, 255, 0.15);
|
|
4213
|
+
}
|
|
4214
|
+
.lib-xplat-video .rate-group .rate-menu .rate-item.is-active {
|
|
4215
|
+
color: var(--semantic-surface-brand-default);
|
|
4216
|
+
font-weight: 600;
|
|
4217
|
+
}
|
|
4218
|
+
.lib-xplat-video .time {
|
|
4219
|
+
font-size: 12px;
|
|
4220
|
+
font-variant-numeric: tabular-nums;
|
|
4221
|
+
white-space: nowrap;
|
|
4222
|
+
}
|
|
4223
|
+
.lib-xplat-video .volume-group {
|
|
4224
|
+
display: flex;
|
|
4225
|
+
align-items: center;
|
|
4226
|
+
}
|
|
4227
|
+
.lib-xplat-video .volume-group .volume-slider {
|
|
4228
|
+
width: 0;
|
|
4229
|
+
opacity: 0;
|
|
4230
|
+
transition: width 0.2s ease, opacity 0.2s ease;
|
|
4231
|
+
}
|
|
4232
|
+
.lib-xplat-video .volume-group:hover .volume-slider,
|
|
4233
|
+
.lib-xplat-video .volume-group:focus-within .volume-slider {
|
|
4234
|
+
width: 80px;
|
|
4235
|
+
opacity: 1;
|
|
4236
|
+
margin-left: var(--spacing-space-1);
|
|
4237
|
+
}
|
|
4238
|
+
.lib-xplat-video .seekbar,
|
|
4239
|
+
.lib-xplat-video .volume-slider {
|
|
4240
|
+
-webkit-appearance: none;
|
|
4241
|
+
appearance: none;
|
|
4242
|
+
background: transparent;
|
|
4243
|
+
cursor: pointer;
|
|
4244
|
+
}
|
|
4245
|
+
.lib-xplat-video .seekbar:focus,
|
|
4246
|
+
.lib-xplat-video .volume-slider:focus {
|
|
4247
|
+
outline: none;
|
|
4248
|
+
}
|
|
4249
|
+
.lib-xplat-video .seekbar::-webkit-slider-thumb,
|
|
4250
|
+
.lib-xplat-video .volume-slider::-webkit-slider-thumb {
|
|
4251
|
+
-webkit-appearance: none;
|
|
4252
|
+
appearance: none;
|
|
4253
|
+
width: 12px;
|
|
4254
|
+
height: 12px;
|
|
4255
|
+
border-radius: 50%;
|
|
4256
|
+
background: #fff;
|
|
4257
|
+
border: none;
|
|
4258
|
+
cursor: pointer;
|
|
4259
|
+
}
|
|
4260
|
+
.lib-xplat-video .seekbar::-moz-range-thumb,
|
|
4261
|
+
.lib-xplat-video .volume-slider::-moz-range-thumb {
|
|
4262
|
+
width: 12px;
|
|
4263
|
+
height: 12px;
|
|
4264
|
+
border-radius: 50%;
|
|
4265
|
+
background: #fff;
|
|
4266
|
+
border: none;
|
|
4267
|
+
cursor: pointer;
|
|
4268
|
+
}
|
|
4269
|
+
.lib-xplat-video .seekbar {
|
|
4270
|
+
width: 100%;
|
|
4271
|
+
height: 4px;
|
|
4272
|
+
}
|
|
4273
|
+
.lib-xplat-video .seekbar::-webkit-slider-runnable-track {
|
|
4274
|
+
height: 4px;
|
|
4275
|
+
border-radius: 2px;
|
|
4276
|
+
background:
|
|
4277
|
+
linear-gradient(
|
|
4278
|
+
to right,
|
|
4279
|
+
var(--semantic-surface-brand-default) 0%,
|
|
4280
|
+
var(--semantic-surface-brand-default) var(--progress, 0%),
|
|
4281
|
+
rgba(255, 255, 255, 0.4) var(--progress, 0%),
|
|
4282
|
+
rgba(255, 255, 255, 0.4) var(--buffered, 0%),
|
|
4283
|
+
rgba(255, 255, 255, 0.2) var(--buffered, 0%),
|
|
4284
|
+
rgba(255, 255, 255, 0.2) 100%);
|
|
4285
|
+
}
|
|
4286
|
+
.lib-xplat-video .seekbar::-moz-range-track {
|
|
4287
|
+
height: 4px;
|
|
4288
|
+
border-radius: 2px;
|
|
4289
|
+
background: rgba(255, 255, 255, 0.2);
|
|
4290
|
+
}
|
|
4291
|
+
.lib-xplat-video .seekbar::-moz-range-progress {
|
|
4292
|
+
height: 4px;
|
|
4293
|
+
border-radius: 2px;
|
|
4294
|
+
background: var(--semantic-surface-brand-default);
|
|
4295
|
+
}
|
|
4296
|
+
.lib-xplat-video .volume-slider {
|
|
4297
|
+
height: 4px;
|
|
4298
|
+
}
|
|
4299
|
+
.lib-xplat-video .volume-slider::-webkit-slider-runnable-track {
|
|
4300
|
+
height: 4px;
|
|
4301
|
+
border-radius: 2px;
|
|
4302
|
+
background:
|
|
4303
|
+
linear-gradient(
|
|
4304
|
+
to right,
|
|
4305
|
+
#fff 0%,
|
|
4306
|
+
#fff var(--volume, 0%),
|
|
4307
|
+
rgba(255, 255, 255, 0.3) var(--volume, 0%),
|
|
4308
|
+
rgba(255, 255, 255, 0.3) 100%);
|
|
4309
|
+
}
|
|
4310
|
+
.lib-xplat-video .volume-slider::-moz-range-track {
|
|
4311
|
+
height: 4px;
|
|
4312
|
+
border-radius: 2px;
|
|
4313
|
+
background: rgba(255, 255, 255, 0.3);
|
|
4314
|
+
}
|
|
4315
|
+
.lib-xplat-video .volume-slider::-moz-range-progress {
|
|
4316
|
+
height: 4px;
|
|
4317
|
+
border-radius: 2px;
|
|
4318
|
+
background: #fff;
|
|
4319
|
+
}
|
|
4123
4320
|
|
|
4124
4321
|
/* src/layout/Grid/FullGrid/fullgrid.scss */
|
|
4125
4322
|
.lib-xplat-full-grid {
|
package/dist/index.js
CHANGED
|
@@ -8577,6 +8577,8 @@ var TableCell = React33.memo((props) => {
|
|
|
8577
8577
|
children,
|
|
8578
8578
|
align = "center",
|
|
8579
8579
|
isSticky = false,
|
|
8580
|
+
width,
|
|
8581
|
+
nowrap = false,
|
|
8580
8582
|
onClick
|
|
8581
8583
|
} = props;
|
|
8582
8584
|
const { registerStickyCell, stickyCells } = useTableRowContext();
|
|
@@ -8620,9 +8622,13 @@ var TableCell = React33.memo((props) => {
|
|
|
8620
8622
|
isSticky && "table-sticky",
|
|
8621
8623
|
isLastSticky && stickyShadow && "right-shadow",
|
|
8622
8624
|
onClick && "clickable",
|
|
8623
|
-
enableHover && "cell-hover"
|
|
8625
|
+
enableHover && "cell-hover",
|
|
8626
|
+
nowrap && "nowrap"
|
|
8624
8627
|
),
|
|
8625
|
-
style:
|
|
8628
|
+
style: {
|
|
8629
|
+
...isSticky ? { left } : null,
|
|
8630
|
+
...width != null ? { width: typeof width === "number" ? `${width}px` : width } : null
|
|
8631
|
+
},
|
|
8626
8632
|
onClick,
|
|
8627
8633
|
children
|
|
8628
8634
|
}
|
|
@@ -8878,6 +8884,16 @@ var Tooltip_default = Tooltip;
|
|
|
8878
8884
|
// src/components/Video/Video.tsx
|
|
8879
8885
|
import React38 from "react";
|
|
8880
8886
|
import { jsx as jsx346, jsxs as jsxs221 } from "react/jsx-runtime";
|
|
8887
|
+
var PipIcon = () => /* @__PURE__ */ jsxs221("svg", { viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
8888
|
+
/* @__PURE__ */ jsx346("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2" }),
|
|
8889
|
+
/* @__PURE__ */ jsx346("rect", { x: "12", y: "11", width: "7", height: "6", rx: "1", fill: "currentColor" })
|
|
8890
|
+
] });
|
|
8891
|
+
var formatTime = (sec) => {
|
|
8892
|
+
if (!Number.isFinite(sec) || sec < 0) return "0:00";
|
|
8893
|
+
const m = Math.floor(sec / 60);
|
|
8894
|
+
const s = Math.floor(sec % 60);
|
|
8895
|
+
return `${m}:${s.toString().padStart(2, "0")}`;
|
|
8896
|
+
};
|
|
8881
8897
|
var Video = React38.forwardRef((props, ref) => {
|
|
8882
8898
|
const {
|
|
8883
8899
|
src,
|
|
@@ -8886,13 +8902,36 @@ var Video = React38.forwardRef((props, ref) => {
|
|
|
8886
8902
|
muted,
|
|
8887
8903
|
loop,
|
|
8888
8904
|
playsInline,
|
|
8905
|
+
showControls = true,
|
|
8906
|
+
showCenterPlay = true,
|
|
8907
|
+
playbackRates,
|
|
8908
|
+
showCaptions = false,
|
|
8909
|
+
showPip = false,
|
|
8910
|
+
showDownload = false,
|
|
8911
|
+
downloadFileName,
|
|
8889
8912
|
onPlay,
|
|
8890
8913
|
onPause,
|
|
8914
|
+
onTimeUpdate,
|
|
8915
|
+
onVolumeChange,
|
|
8916
|
+
onLoadedMetadata,
|
|
8917
|
+
onRateChange,
|
|
8918
|
+
children,
|
|
8891
8919
|
...rest
|
|
8892
8920
|
} = props;
|
|
8921
|
+
const containerRef = React38.useRef(null);
|
|
8893
8922
|
const videoRef = React38.useRef(null);
|
|
8894
8923
|
const [isPlaying, setIsPlaying] = React38.useState(Boolean(autoPlay));
|
|
8895
8924
|
const [isLoaded, setIsLoaded] = React38.useState(false);
|
|
8925
|
+
const [currentTime, setCurrentTime] = React38.useState(0);
|
|
8926
|
+
const [duration, setDuration] = React38.useState(0);
|
|
8927
|
+
const [buffered, setBuffered] = React38.useState(0);
|
|
8928
|
+
const [volume, setVolume] = React38.useState(1);
|
|
8929
|
+
const [isMuted, setIsMuted] = React38.useState(Boolean(muted));
|
|
8930
|
+
const [isFullscreen, setIsFullscreen] = React38.useState(false);
|
|
8931
|
+
const [playbackRate, setPlaybackRate] = React38.useState(1);
|
|
8932
|
+
const [rateMenuOpen, setRateMenuOpen] = React38.useState(false);
|
|
8933
|
+
const [captionsOn, setCaptionsOn] = React38.useState(false);
|
|
8934
|
+
const [isPip, setIsPip] = React38.useState(false);
|
|
8896
8935
|
const setRefs = React38.useCallback(
|
|
8897
8936
|
(el) => {
|
|
8898
8937
|
videoRef.current = el;
|
|
@@ -8901,6 +8940,25 @@ var Video = React38.forwardRef((props, ref) => {
|
|
|
8901
8940
|
},
|
|
8902
8941
|
[ref]
|
|
8903
8942
|
);
|
|
8943
|
+
React38.useEffect(() => {
|
|
8944
|
+
const onFsChange = () => {
|
|
8945
|
+
setIsFullscreen(document.fullscreenElement === containerRef.current);
|
|
8946
|
+
};
|
|
8947
|
+
document.addEventListener("fullscreenchange", onFsChange);
|
|
8948
|
+
return () => document.removeEventListener("fullscreenchange", onFsChange);
|
|
8949
|
+
}, []);
|
|
8950
|
+
React38.useEffect(() => {
|
|
8951
|
+
const v = videoRef.current;
|
|
8952
|
+
if (!v) return;
|
|
8953
|
+
const onEnter = () => setIsPip(true);
|
|
8954
|
+
const onLeave = () => setIsPip(false);
|
|
8955
|
+
v.addEventListener("enterpictureinpicture", onEnter);
|
|
8956
|
+
v.addEventListener("leavepictureinpicture", onLeave);
|
|
8957
|
+
return () => {
|
|
8958
|
+
v.removeEventListener("enterpictureinpicture", onEnter);
|
|
8959
|
+
v.removeEventListener("leavepictureinpicture", onLeave);
|
|
8960
|
+
};
|
|
8961
|
+
}, []);
|
|
8904
8962
|
const handlePlay = (e) => {
|
|
8905
8963
|
setIsPlaying(true);
|
|
8906
8964
|
onPlay?.(e);
|
|
@@ -8909,50 +8967,278 @@ var Video = React38.forwardRef((props, ref) => {
|
|
|
8909
8967
|
setIsPlaying(false);
|
|
8910
8968
|
onPause?.(e);
|
|
8911
8969
|
};
|
|
8912
|
-
const
|
|
8970
|
+
const handleLoadedMetadata = (e) => {
|
|
8971
|
+
const v = e.currentTarget;
|
|
8972
|
+
setDuration(v.duration);
|
|
8913
8973
|
setIsLoaded(true);
|
|
8974
|
+
onLoadedMetadata?.(e);
|
|
8975
|
+
};
|
|
8976
|
+
const handleTimeUpdate = (e) => {
|
|
8977
|
+
const v = e.currentTarget;
|
|
8978
|
+
setCurrentTime(v.currentTime);
|
|
8979
|
+
if (v.buffered.length > 0) {
|
|
8980
|
+
setBuffered(v.buffered.end(v.buffered.length - 1));
|
|
8981
|
+
}
|
|
8982
|
+
onTimeUpdate?.(e);
|
|
8983
|
+
};
|
|
8984
|
+
const handleVolumeChange = (e) => {
|
|
8985
|
+
const v = e.currentTarget;
|
|
8986
|
+
setVolume(v.volume);
|
|
8987
|
+
setIsMuted(v.muted);
|
|
8988
|
+
onVolumeChange?.(e);
|
|
8989
|
+
};
|
|
8990
|
+
const handleRateChange = (e) => {
|
|
8991
|
+
setPlaybackRate(e.currentTarget.playbackRate);
|
|
8992
|
+
onRateChange?.(e);
|
|
8914
8993
|
};
|
|
8915
8994
|
const togglePlay = () => {
|
|
8916
|
-
|
|
8917
|
-
if (
|
|
8918
|
-
|
|
8995
|
+
const v = videoRef.current;
|
|
8996
|
+
if (!v) return;
|
|
8997
|
+
if (v.paused) v.play();
|
|
8998
|
+
else v.pause();
|
|
8999
|
+
};
|
|
9000
|
+
const toggleMute = () => {
|
|
9001
|
+
const v = videoRef.current;
|
|
9002
|
+
if (!v) return;
|
|
9003
|
+
v.muted = !v.muted;
|
|
9004
|
+
};
|
|
9005
|
+
const toggleFullscreen = () => {
|
|
9006
|
+
const el = containerRef.current;
|
|
9007
|
+
if (!el) return;
|
|
9008
|
+
if (document.fullscreenElement === el) {
|
|
9009
|
+
document.exitFullscreen();
|
|
8919
9010
|
} else {
|
|
8920
|
-
|
|
9011
|
+
el.requestFullscreen?.();
|
|
8921
9012
|
}
|
|
8922
9013
|
};
|
|
8923
|
-
|
|
8924
|
-
|
|
8925
|
-
|
|
8926
|
-
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
|
-
|
|
8930
|
-
|
|
8931
|
-
muted,
|
|
8932
|
-
loop,
|
|
8933
|
-
playsInline: playsInline ?? true,
|
|
8934
|
-
onPlay: handlePlay,
|
|
8935
|
-
onPause: handlePause,
|
|
8936
|
-
onLoadedData: handleLoadedData,
|
|
8937
|
-
onClick: togglePlay,
|
|
8938
|
-
...rest
|
|
9014
|
+
const togglePip = async () => {
|
|
9015
|
+
const v = videoRef.current;
|
|
9016
|
+
if (!v) return;
|
|
9017
|
+
try {
|
|
9018
|
+
if (document.pictureInPictureElement === v) {
|
|
9019
|
+
await document.exitPictureInPicture?.();
|
|
9020
|
+
} else {
|
|
9021
|
+
await v.requestPictureInPicture?.();
|
|
8939
9022
|
}
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
"aria-label": isPlaying ? "\uC77C\uC2DC\uC815\uC9C0" : "\uC7AC\uC0DD",
|
|
8952
|
-
children: isPlaying ? /* @__PURE__ */ jsx346(PauseIcon_default, {}) : /* @__PURE__ */ jsx346("span", { className: "play-icon", children: /* @__PURE__ */ jsx346(PlayCircleIcon_default, {}) })
|
|
9023
|
+
} catch {
|
|
9024
|
+
}
|
|
9025
|
+
};
|
|
9026
|
+
const toggleCaptions = () => {
|
|
9027
|
+
const v = videoRef.current;
|
|
9028
|
+
if (!v) return;
|
|
9029
|
+
const next = !captionsOn;
|
|
9030
|
+
for (let i = 0; i < v.textTracks.length; i++) {
|
|
9031
|
+
const t = v.textTracks[i];
|
|
9032
|
+
if (t.kind === "captions" || t.kind === "subtitles") {
|
|
9033
|
+
t.mode = next ? "showing" : "hidden";
|
|
8953
9034
|
}
|
|
8954
|
-
|
|
8955
|
-
|
|
9035
|
+
}
|
|
9036
|
+
setCaptionsOn(next);
|
|
9037
|
+
};
|
|
9038
|
+
const selectRate = (rate) => {
|
|
9039
|
+
const v = videoRef.current;
|
|
9040
|
+
if (!v) return;
|
|
9041
|
+
v.playbackRate = rate;
|
|
9042
|
+
setRateMenuOpen(false);
|
|
9043
|
+
};
|
|
9044
|
+
const handleSeek = (e) => {
|
|
9045
|
+
const v = videoRef.current;
|
|
9046
|
+
if (!v) return;
|
|
9047
|
+
const next = Number(e.target.value);
|
|
9048
|
+
v.currentTime = next;
|
|
9049
|
+
setCurrentTime(next);
|
|
9050
|
+
};
|
|
9051
|
+
const handleVolumeSlider = (e) => {
|
|
9052
|
+
const v = videoRef.current;
|
|
9053
|
+
if (!v) return;
|
|
9054
|
+
const next = Number(e.target.value);
|
|
9055
|
+
v.volume = next;
|
|
9056
|
+
if (next > 0 && v.muted) v.muted = false;
|
|
9057
|
+
if (next === 0) v.muted = true;
|
|
9058
|
+
};
|
|
9059
|
+
const progressPct = duration > 0 ? currentTime / duration * 100 : 0;
|
|
9060
|
+
const bufferedPct = duration > 0 ? buffered / duration * 100 : 0;
|
|
9061
|
+
const volumePct = (isMuted ? 0 : volume) * 100;
|
|
9062
|
+
const VolumeGlyph = isMuted || volume === 0 ? VolumeXIcon_default : volume < 0.5 ? VolumeIcon_default : Volume2Icon_default;
|
|
9063
|
+
const pipSupported = typeof document !== "undefined" && "pictureInPictureEnabled" in document && document.pictureInPictureEnabled;
|
|
9064
|
+
return /* @__PURE__ */ jsxs221(
|
|
9065
|
+
"div",
|
|
9066
|
+
{
|
|
9067
|
+
ref: containerRef,
|
|
9068
|
+
className: clsx_default("lib-xplat-video", showControls && "has-controls"),
|
|
9069
|
+
children: [
|
|
9070
|
+
/* @__PURE__ */ jsx346(
|
|
9071
|
+
"video",
|
|
9072
|
+
{
|
|
9073
|
+
ref: setRefs,
|
|
9074
|
+
src,
|
|
9075
|
+
poster,
|
|
9076
|
+
autoPlay,
|
|
9077
|
+
muted,
|
|
9078
|
+
loop,
|
|
9079
|
+
playsInline: playsInline ?? true,
|
|
9080
|
+
onPlay: handlePlay,
|
|
9081
|
+
onPause: handlePause,
|
|
9082
|
+
onLoadedMetadata: handleLoadedMetadata,
|
|
9083
|
+
onTimeUpdate: handleTimeUpdate,
|
|
9084
|
+
onVolumeChange: handleVolumeChange,
|
|
9085
|
+
onRateChange: handleRateChange,
|
|
9086
|
+
onClick: togglePlay,
|
|
9087
|
+
...rest,
|
|
9088
|
+
children
|
|
9089
|
+
}
|
|
9090
|
+
),
|
|
9091
|
+
showCenterPlay && /* @__PURE__ */ jsx346(
|
|
9092
|
+
"button",
|
|
9093
|
+
{
|
|
9094
|
+
type: "button",
|
|
9095
|
+
className: clsx_default(
|
|
9096
|
+
"center-play",
|
|
9097
|
+
isPlaying && "is-playing",
|
|
9098
|
+
!isLoaded && "is-loading"
|
|
9099
|
+
),
|
|
9100
|
+
onClick: togglePlay,
|
|
9101
|
+
"aria-label": isPlaying ? "\uC77C\uC2DC\uC815\uC9C0" : "\uC7AC\uC0DD",
|
|
9102
|
+
tabIndex: -1,
|
|
9103
|
+
children: /* @__PURE__ */ jsx346("span", { className: "center-play-icon", children: /* @__PURE__ */ jsx346(PlayCircleIcon_default, {}) })
|
|
9104
|
+
}
|
|
9105
|
+
),
|
|
9106
|
+
showControls && /* @__PURE__ */ jsxs221("div", { className: "controls", onClick: (e) => e.stopPropagation(), children: [
|
|
9107
|
+
/* @__PURE__ */ jsx346(
|
|
9108
|
+
"input",
|
|
9109
|
+
{
|
|
9110
|
+
type: "range",
|
|
9111
|
+
className: "seekbar",
|
|
9112
|
+
min: 0,
|
|
9113
|
+
max: duration || 0,
|
|
9114
|
+
step: 0.1,
|
|
9115
|
+
value: currentTime,
|
|
9116
|
+
onChange: handleSeek,
|
|
9117
|
+
"aria-label": "\uC7AC\uC0DD \uC704\uCE58",
|
|
9118
|
+
style: {
|
|
9119
|
+
["--progress"]: `${progressPct}%`,
|
|
9120
|
+
["--buffered"]: `${bufferedPct}%`
|
|
9121
|
+
}
|
|
9122
|
+
}
|
|
9123
|
+
),
|
|
9124
|
+
/* @__PURE__ */ jsxs221("div", { className: "controls-row", children: [
|
|
9125
|
+
/* @__PURE__ */ jsx346(
|
|
9126
|
+
"button",
|
|
9127
|
+
{
|
|
9128
|
+
type: "button",
|
|
9129
|
+
className: "control-btn",
|
|
9130
|
+
onClick: togglePlay,
|
|
9131
|
+
"aria-label": isPlaying ? "\uC77C\uC2DC\uC815\uC9C0" : "\uC7AC\uC0DD",
|
|
9132
|
+
children: isPlaying ? /* @__PURE__ */ jsx346(PauseIcon_default, {}) : /* @__PURE__ */ jsx346(PlayIcon_default, {})
|
|
9133
|
+
}
|
|
9134
|
+
),
|
|
9135
|
+
/* @__PURE__ */ jsxs221("div", { className: "volume-group", children: [
|
|
9136
|
+
/* @__PURE__ */ jsx346(
|
|
9137
|
+
"button",
|
|
9138
|
+
{
|
|
9139
|
+
type: "button",
|
|
9140
|
+
className: "control-btn",
|
|
9141
|
+
onClick: toggleMute,
|
|
9142
|
+
"aria-label": isMuted ? "\uC74C\uC18C\uAC70 \uD574\uC81C" : "\uC74C\uC18C\uAC70",
|
|
9143
|
+
children: /* @__PURE__ */ jsx346(VolumeGlyph, {})
|
|
9144
|
+
}
|
|
9145
|
+
),
|
|
9146
|
+
/* @__PURE__ */ jsx346(
|
|
9147
|
+
"input",
|
|
9148
|
+
{
|
|
9149
|
+
type: "range",
|
|
9150
|
+
className: "volume-slider",
|
|
9151
|
+
min: 0,
|
|
9152
|
+
max: 1,
|
|
9153
|
+
step: 0.05,
|
|
9154
|
+
value: isMuted ? 0 : volume,
|
|
9155
|
+
onChange: handleVolumeSlider,
|
|
9156
|
+
"aria-label": "\uBCFC\uB968",
|
|
9157
|
+
style: { ["--volume"]: `${volumePct}%` }
|
|
9158
|
+
}
|
|
9159
|
+
)
|
|
9160
|
+
] }),
|
|
9161
|
+
/* @__PURE__ */ jsxs221("span", { className: "time", children: [
|
|
9162
|
+
formatTime(currentTime),
|
|
9163
|
+
" / ",
|
|
9164
|
+
formatTime(duration)
|
|
9165
|
+
] }),
|
|
9166
|
+
/* @__PURE__ */ jsx346("div", { className: "controls-spacer" }),
|
|
9167
|
+
playbackRates && playbackRates.length > 0 && /* @__PURE__ */ jsxs221("div", { className: clsx_default("rate-group", rateMenuOpen && "is-open"), children: [
|
|
9168
|
+
/* @__PURE__ */ jsxs221(
|
|
9169
|
+
"button",
|
|
9170
|
+
{
|
|
9171
|
+
type: "button",
|
|
9172
|
+
className: "control-btn rate-btn",
|
|
9173
|
+
onClick: () => setRateMenuOpen((o) => !o),
|
|
9174
|
+
"aria-label": "\uC7AC\uC0DD \uC18D\uB3C4",
|
|
9175
|
+
"aria-expanded": rateMenuOpen,
|
|
9176
|
+
children: [
|
|
9177
|
+
playbackRate,
|
|
9178
|
+
"x"
|
|
9179
|
+
]
|
|
9180
|
+
}
|
|
9181
|
+
),
|
|
9182
|
+
rateMenuOpen && /* @__PURE__ */ jsx346("ul", { className: "rate-menu", role: "menu", children: playbackRates.map((r2) => /* @__PURE__ */ jsx346("li", { children: /* @__PURE__ */ jsxs221(
|
|
9183
|
+
"button",
|
|
9184
|
+
{
|
|
9185
|
+
type: "button",
|
|
9186
|
+
role: "menuitem",
|
|
9187
|
+
className: clsx_default("rate-item", r2 === playbackRate && "is-active"),
|
|
9188
|
+
onClick: () => selectRate(r2),
|
|
9189
|
+
children: [
|
|
9190
|
+
r2,
|
|
9191
|
+
"x"
|
|
9192
|
+
]
|
|
9193
|
+
}
|
|
9194
|
+
) }, r2)) })
|
|
9195
|
+
] }),
|
|
9196
|
+
showCaptions && /* @__PURE__ */ jsx346(
|
|
9197
|
+
"button",
|
|
9198
|
+
{
|
|
9199
|
+
type: "button",
|
|
9200
|
+
className: clsx_default("control-btn", captionsOn && "is-active"),
|
|
9201
|
+
onClick: toggleCaptions,
|
|
9202
|
+
"aria-label": captionsOn ? "\uC790\uB9C9 \uB044\uAE30" : "\uC790\uB9C9 \uCF1C\uAE30",
|
|
9203
|
+
"aria-pressed": captionsOn,
|
|
9204
|
+
children: /* @__PURE__ */ jsx346(TypeIcon_default, {})
|
|
9205
|
+
}
|
|
9206
|
+
),
|
|
9207
|
+
showPip && pipSupported && /* @__PURE__ */ jsx346(
|
|
9208
|
+
"button",
|
|
9209
|
+
{
|
|
9210
|
+
type: "button",
|
|
9211
|
+
className: clsx_default("control-btn", isPip && "is-active"),
|
|
9212
|
+
onClick: togglePip,
|
|
9213
|
+
"aria-label": isPip ? "PIP \uC885\uB8CC" : "PIP",
|
|
9214
|
+
children: /* @__PURE__ */ jsx346(PipIcon, {})
|
|
9215
|
+
}
|
|
9216
|
+
),
|
|
9217
|
+
showDownload && /* @__PURE__ */ jsx346(
|
|
9218
|
+
"a",
|
|
9219
|
+
{
|
|
9220
|
+
className: "control-btn",
|
|
9221
|
+
href: src,
|
|
9222
|
+
download: downloadFileName ?? true,
|
|
9223
|
+
"aria-label": "\uB2E4\uC6B4\uB85C\uB4DC",
|
|
9224
|
+
children: /* @__PURE__ */ jsx346(DownloadIcon_default, {})
|
|
9225
|
+
}
|
|
9226
|
+
),
|
|
9227
|
+
/* @__PURE__ */ jsx346(
|
|
9228
|
+
"button",
|
|
9229
|
+
{
|
|
9230
|
+
type: "button",
|
|
9231
|
+
className: "control-btn",
|
|
9232
|
+
onClick: toggleFullscreen,
|
|
9233
|
+
"aria-label": isFullscreen ? "\uC804\uCCB4\uD654\uBA74 \uC885\uB8CC" : "\uC804\uCCB4\uD654\uBA74",
|
|
9234
|
+
children: isFullscreen ? /* @__PURE__ */ jsx346(MinimizeIcon_default, {}) : /* @__PURE__ */ jsx346(MaximizeIcon_default, {})
|
|
9235
|
+
}
|
|
9236
|
+
)
|
|
9237
|
+
] })
|
|
9238
|
+
] })
|
|
9239
|
+
]
|
|
9240
|
+
}
|
|
9241
|
+
);
|
|
8956
9242
|
});
|
|
8957
9243
|
Video.displayName = "Video";
|
|
8958
9244
|
var Video_default = Video;
|