react-select-media-devices-modal 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -0
- package/dist/react-select-media-devices-modal.mjs +182 -72
- package/dist/react-select-media-devices-modal.umd.js +1 -1
- package/dist/style.css +1 -1
- package/dist/types/SelectMediaDevicesModal/index.d.ts +0 -1
- package/dist/types/SelectMediaDevicesPreviewModal/index.d.ts +20 -0
- package/dist/types/{SelectMediaDevicesModal/components → components}/deviceItem/index.d.ts +0 -1
- package/dist/types/{SelectMediaDevicesModal/components → components}/deviceList/index.d.ts +0 -1
- package/dist/types/hooks/useGetMediaStream.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +4 -3
- /package/dist/types/{SelectMediaDevicesModal/components → components}/button/index.d.ts +0 -0
- /package/dist/types/{SelectMediaDevicesModal/hooks → hooks}/useGetDevices.d.ts +0 -0
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@ A React component library for select media devices.
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
14
|
- Select audio input, audio output, and video input device.
|
|
15
|
+
- Show preview media stream get from selected device.
|
|
15
16
|
|
|
16
17
|
## Demo
|
|
17
18
|
|
|
@@ -25,6 +26,8 @@ npm install --save react-select-media-devices-modal
|
|
|
25
26
|
|
|
26
27
|
## Usage
|
|
27
28
|
|
|
29
|
+
### SelectMediaDevicesModal
|
|
30
|
+
|
|
28
31
|
```jsx
|
|
29
32
|
import { useState } from 'react';
|
|
30
33
|
import { SelectMediaDevicesModal } from 'react-select-media-devices-modal';
|
|
@@ -65,6 +68,48 @@ function App() {
|
|
|
65
68
|
export default App;
|
|
66
69
|
```
|
|
67
70
|
|
|
71
|
+
### SelectMediaDevicesPreviewModal
|
|
72
|
+
|
|
73
|
+
```jsx
|
|
74
|
+
import { useState } from 'react';
|
|
75
|
+
import { SelectMediaDevicesPreviewModal } from 'react-select-media-devices-modal';
|
|
76
|
+
|
|
77
|
+
function App() {
|
|
78
|
+
const [modalOpen, setModalOpen] = useState(false);
|
|
79
|
+
|
|
80
|
+
const handleDeviceSelected = (devices) => {
|
|
81
|
+
setModalOpen(false);
|
|
82
|
+
console.log(devices);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const handleDeviceSelectCanceled = () => {
|
|
86
|
+
setModalOpen(false);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<div>
|
|
91
|
+
<button onClick={() => setModalOpen((current) => !current)}>Select Device</button>
|
|
92
|
+
<SelectMediaDevicesPreviewModal
|
|
93
|
+
isSelectAudioInput
|
|
94
|
+
isSelectAudioOutput
|
|
95
|
+
isSelectVideoInput
|
|
96
|
+
open={modalOpen}
|
|
97
|
+
audioInputDeviceLabel="Audio input device"
|
|
98
|
+
audioOutputDeviceLabel="Audio output device"
|
|
99
|
+
videoInputDeviceLabel="Video input device"
|
|
100
|
+
confirmButtonText="Confirm"
|
|
101
|
+
cancelButtonText="Cancel"
|
|
102
|
+
allowOutsideClick={false}
|
|
103
|
+
onDeviceSelected={handleDeviceSelected}
|
|
104
|
+
onDeviceSelectCanceled={handleDeviceSelectCanceled}
|
|
105
|
+
></SelectMediaDevicesPreviewModal>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export default App;
|
|
111
|
+
```
|
|
112
|
+
|
|
68
113
|
## Props
|
|
69
114
|
|
|
70
115
|
### `SelectMediaDevicesModalProps`
|
|
@@ -84,6 +129,23 @@ export default App;
|
|
|
84
129
|
| onDeviceSelected | `function` | `(devices: { audioInput?: MediaDeviceInfo; audioOutput?: MediaDeviceInfo; videoInput?: MediaDeviceInfo; }) => void` | Handler function called when devices are selected. |
|
|
85
130
|
| onDeviceSelectCanceled | `function` | `() => void` | Handler function called when selection canceled. |
|
|
86
131
|
|
|
132
|
+
### `SelectMediaDevicesPreviewModalProps`
|
|
133
|
+
|
|
134
|
+
| Name | Type | Default | Description |
|
|
135
|
+
| :--- | :--- | :------ | :---------- |
|
|
136
|
+
| isSelectAudioInput | `boolean` | `true` | Flag that select an audio input device or not. |
|
|
137
|
+
| isSelectAudioOutput | `boolean` | `true` | Flag that select an audio output device or not. |
|
|
138
|
+
| isSelectVideoInput | `boolean` | `true` | Flag that select a video input device or not. |
|
|
139
|
+
| open | `boolean` | `false` | Flag that open the modal or not. |
|
|
140
|
+
| audioInputDeviceLabel | `string` | `'audio input device'` | Label for list of audio input devices. |
|
|
141
|
+
| audioOutputDeviceLabel | `string` | `'audio output device'` | Label for list of audio output devices. |
|
|
142
|
+
| videoInputDeviceLabel | `string` | `'video input device'` | Label for list of video input devices. |
|
|
143
|
+
| confirmButtonText | `string` | `'Confirm'` | Label for the confirm button. |
|
|
144
|
+
| cancelButtonText | `string` | `'Cancel'` | Label for the cancel button. |
|
|
145
|
+
| allowOutsideClick | `boolean` | `true` | Flag that cancel selection when clicking outside of the modal. |
|
|
146
|
+
| onDeviceSelected | `function` | `(devices: { audioInput?: MediaDeviceInfo; audioOutput?: MediaDeviceInfo; videoInput?: MediaDeviceInfo; }) => void` | Handler function called when devices are selected. |
|
|
147
|
+
| onDeviceSelectCanceled | `function` | `() => void` | Handler function called when selection canceled. |
|
|
148
|
+
|
|
87
149
|
## LICENSE
|
|
88
150
|
|
|
89
151
|
[MIT](https://github.com/kadoshita/react-select-media-devices-modal/blob/master/LICENSE)
|
|
@@ -1,99 +1,209 @@
|
|
|
1
|
-
import e, { useState as
|
|
2
|
-
const
|
|
3
|
-
background:
|
|
4
|
-
modal:
|
|
5
|
-
deviceLists:
|
|
6
|
-
buttons:
|
|
7
|
-
chancelButton:
|
|
8
|
-
confirmButton:
|
|
9
|
-
},
|
|
10
|
-
const [
|
|
11
|
-
return [
|
|
1
|
+
import e, { useState as m, useEffect as O, useRef as z, useMemo as T } from "react";
|
|
2
|
+
const H = "_background_1djbv_1", J = "_modal_1djbv_13", K = "_deviceLists_1djbv_20", Q = "_buttons_1djbv_24", W = "_chancelButton_1djbv_31", X = "_confirmButton_1djbv_33", g = {
|
|
3
|
+
background: H,
|
|
4
|
+
modal: J,
|
|
5
|
+
deviceLists: K,
|
|
6
|
+
buttons: Q,
|
|
7
|
+
chancelButton: W,
|
|
8
|
+
confirmButton: X
|
|
9
|
+
}, G = () => {
|
|
10
|
+
const [i, o] = m([]);
|
|
11
|
+
return [i, () => {
|
|
12
12
|
(async () => {
|
|
13
|
-
const
|
|
14
|
-
|
|
13
|
+
const n = await navigator.mediaDevices.getUserMedia({ audio: !0, video: !0 }), a = await navigator.mediaDevices.enumerateDevices();
|
|
14
|
+
o(a), n.getTracks().forEach((s) => s.stop());
|
|
15
15
|
})();
|
|
16
16
|
}];
|
|
17
|
-
},
|
|
18
|
-
deviceList:
|
|
19
|
-
select:
|
|
20
|
-
},
|
|
21
|
-
if (
|
|
17
|
+
}, Y = ({ name: i, value: o }) => /* @__PURE__ */ e.createElement("option", { value: o }, i), Z = "_deviceList_1bfq1_1", ee = "_select_1bfq1_5", q = {
|
|
18
|
+
deviceList: Z,
|
|
19
|
+
select: ee
|
|
20
|
+
}, k = ({ devices: i, label: o, onChange: u }) => {
|
|
21
|
+
if (i === void 0)
|
|
22
22
|
return /* @__PURE__ */ e.createElement(e.Fragment, null);
|
|
23
|
-
const
|
|
24
|
-
s
|
|
25
|
-
}, a = `device-select-${
|
|
26
|
-
return /* @__PURE__ */ e.createElement("div", { className:
|
|
27
|
-
},
|
|
28
|
-
button:
|
|
29
|
-
},
|
|
30
|
-
isSelectAudioInput:
|
|
31
|
-
isSelectAudioOutput:
|
|
32
|
-
isSelectVideoInput:
|
|
33
|
-
open:
|
|
23
|
+
const n = (s) => {
|
|
24
|
+
u(s.target.value);
|
|
25
|
+
}, a = `device-select-${o.toLowerCase().replace(/\s/g, "-")}`;
|
|
26
|
+
return /* @__PURE__ */ e.createElement("div", { className: q.deviceList }, /* @__PURE__ */ e.createElement("label", { htmlFor: a }, o), /* @__PURE__ */ e.createElement("select", { className: q.select, id: a, onChange: n }, i.map((s, h) => /* @__PURE__ */ e.createElement(Y, { value: s.deviceId, name: s.label, key: h }))));
|
|
27
|
+
}, te = "_button_keu24_1", ne = {
|
|
28
|
+
button: te
|
|
29
|
+
}, S = ({ className: i, children: o, onClick: u }) => /* @__PURE__ */ e.createElement("button", { onClick: u, className: [ne.button, i].filter(Boolean).join(" ") }, o), pe = ({
|
|
30
|
+
isSelectAudioInput: i = !0,
|
|
31
|
+
isSelectAudioOutput: o = !0,
|
|
32
|
+
isSelectVideoInput: u = !0,
|
|
33
|
+
open: n,
|
|
34
34
|
audioInputDeviceLabel: a = "audio input device",
|
|
35
|
-
audioOutputDeviceLabel:
|
|
36
|
-
videoInputDeviceLabel:
|
|
37
|
-
confirmButtonText:
|
|
38
|
-
cancelButtonText:
|
|
39
|
-
allowOutsideClick:
|
|
40
|
-
onDeviceSelected:
|
|
35
|
+
audioOutputDeviceLabel: s = "audio output device",
|
|
36
|
+
videoInputDeviceLabel: h = "video input device",
|
|
37
|
+
confirmButtonText: w = "Confirm",
|
|
38
|
+
cancelButtonText: M = "Cancel",
|
|
39
|
+
allowOutsideClick: C = !0,
|
|
40
|
+
onDeviceSelected: j,
|
|
41
41
|
onDeviceSelectCanceled: D
|
|
42
42
|
}) => {
|
|
43
|
-
const [
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}, [
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
audioInput:
|
|
50
|
-
audioOutput:
|
|
51
|
-
videoInput:
|
|
43
|
+
const [d, $] = G(), [E, V] = m(), [I, A] = m(), [B, y] = m(), _ = d.filter((c) => c.kind === "audioinput"), b = d.filter((c) => c.kind === "audiooutput"), f = d.filter((c) => c.kind === "videoinput");
|
|
44
|
+
O(() => {
|
|
45
|
+
n && $();
|
|
46
|
+
}, [n]);
|
|
47
|
+
const N = () => {
|
|
48
|
+
j({
|
|
49
|
+
audioInput: E !== void 0 ? E : _[0],
|
|
50
|
+
audioOutput: I !== void 0 ? I : b[0],
|
|
51
|
+
videoInput: B !== void 0 ? B : f[0]
|
|
52
52
|
});
|
|
53
|
-
},
|
|
53
|
+
}, L = () => {
|
|
54
54
|
D();
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
},
|
|
55
|
+
}, l = (c) => {
|
|
56
|
+
V(_.find((p) => p.deviceId === c));
|
|
57
|
+
}, P = (c) => {
|
|
58
|
+
A(b.find((p) => p.deviceId === c));
|
|
59
|
+
}, F = (c) => {
|
|
60
|
+
y(f.find((p) => p.deviceId === c));
|
|
61
|
+
}, R = () => {
|
|
62
62
|
D();
|
|
63
63
|
};
|
|
64
|
-
return
|
|
64
|
+
return n ? /* @__PURE__ */ e.createElement("div", { className: g.background, ...C ? { onClick: R } : {} }, /* @__PURE__ */ e.createElement(
|
|
65
65
|
"div",
|
|
66
66
|
{
|
|
67
|
-
className:
|
|
68
|
-
...
|
|
69
|
-
onClick: (
|
|
67
|
+
className: g.modal,
|
|
68
|
+
...C ? {
|
|
69
|
+
onClick: (c) => c.stopPropagation()
|
|
70
70
|
} : {}
|
|
71
71
|
},
|
|
72
|
-
/* @__PURE__ */ e.createElement("div", { className:
|
|
73
|
-
|
|
72
|
+
/* @__PURE__ */ e.createElement("div", { className: g.deviceLists }, i && /* @__PURE__ */ e.createElement(
|
|
73
|
+
k,
|
|
74
74
|
{
|
|
75
75
|
label: a,
|
|
76
|
-
devices:
|
|
77
|
-
onChange:
|
|
76
|
+
devices: _,
|
|
77
|
+
onChange: l
|
|
78
78
|
}
|
|
79
|
-
),
|
|
80
|
-
|
|
79
|
+
), o && /* @__PURE__ */ e.createElement(
|
|
80
|
+
k,
|
|
81
81
|
{
|
|
82
|
-
label:
|
|
83
|
-
devices:
|
|
84
|
-
onChange:
|
|
82
|
+
label: s,
|
|
83
|
+
devices: b,
|
|
84
|
+
onChange: P
|
|
85
85
|
}
|
|
86
|
-
),
|
|
87
|
-
|
|
86
|
+
), u && /* @__PURE__ */ e.createElement(
|
|
87
|
+
k,
|
|
88
88
|
{
|
|
89
|
-
label:
|
|
90
|
-
devices:
|
|
91
|
-
onChange:
|
|
89
|
+
label: h,
|
|
90
|
+
devices: f,
|
|
91
|
+
onChange: F
|
|
92
92
|
}
|
|
93
93
|
)),
|
|
94
|
-
/* @__PURE__ */ e.createElement("div", { className:
|
|
94
|
+
/* @__PURE__ */ e.createElement("div", { className: g.buttons }, /* @__PURE__ */ e.createElement(S, { className: g.cancelButton, onClick: L }, M), /* @__PURE__ */ e.createElement(S, { className: g.confirmButton, onClick: N }, w))
|
|
95
|
+
)) : /* @__PURE__ */ e.createElement(e.Fragment, null);
|
|
96
|
+
}, ie = "_background_kb025_1", ce = "_modal_kb025_13", oe = "_deviceSelectContainer_kb025_19", ae = "_preview_kb025_31", se = "_previewVideo_kb025_39", de = "_deviceLists_kb025_44", ue = "_buttons_kb025_50", re = "_chancelButton_kb025_57", le = "_confirmButton_kb025_59", r = {
|
|
97
|
+
background: ie,
|
|
98
|
+
modal: ce,
|
|
99
|
+
deviceSelectContainer: oe,
|
|
100
|
+
preview: ae,
|
|
101
|
+
previewVideo: se,
|
|
102
|
+
deviceLists: de,
|
|
103
|
+
buttons: ue,
|
|
104
|
+
chancelButton: re,
|
|
105
|
+
confirmButton: le
|
|
106
|
+
}, ve = () => {
|
|
107
|
+
const [i, o] = m();
|
|
108
|
+
return O(() => () => {
|
|
109
|
+
i !== void 0 && i.getTracks().forEach((n) => n.stop());
|
|
110
|
+
}, []), [i, (n) => {
|
|
111
|
+
n.kind !== "audiooutput" && (async () => {
|
|
112
|
+
const a = await navigator.mediaDevices.getUserMedia(
|
|
113
|
+
n.kind === "audioinput" ? { video: !1, audio: { deviceId: n.deviceId } } : { video: { deviceId: n.deviceId }, audio: !1 }
|
|
114
|
+
);
|
|
115
|
+
o(a);
|
|
116
|
+
})();
|
|
117
|
+
}];
|
|
118
|
+
}, _e = ({
|
|
119
|
+
isSelectAudioInput: i = !0,
|
|
120
|
+
isSelectAudioOutput: o = !0,
|
|
121
|
+
isSelectVideoInput: u = !0,
|
|
122
|
+
open: n,
|
|
123
|
+
audioInputDeviceLabel: a = "audio input device",
|
|
124
|
+
audioOutputDeviceLabel: s = "audio output device",
|
|
125
|
+
videoInputDeviceLabel: h = "video input device",
|
|
126
|
+
confirmButtonText: w = "Confirm",
|
|
127
|
+
cancelButtonText: M = "Cancel",
|
|
128
|
+
allowOutsideClick: C = !0,
|
|
129
|
+
onDeviceSelected: j,
|
|
130
|
+
onDeviceSelectCanceled: D
|
|
131
|
+
}) => {
|
|
132
|
+
const [d, $] = G(), [E, V] = m(), [I, A] = m(), [B, y] = m(), [_, b] = ve(), f = z(), N = T(() => d.filter((t) => t.kind === "audioinput"), [d]), L = T(() => d.filter((t) => t.kind === "audiooutput"), [d]), l = T(() => d.filter((t) => t.kind === "videoinput"), [d]);
|
|
133
|
+
O(() => {
|
|
134
|
+
n && $();
|
|
135
|
+
}, [n]), O(() => {
|
|
136
|
+
if (l.length < 1)
|
|
137
|
+
return;
|
|
138
|
+
const [t] = l;
|
|
139
|
+
b(t);
|
|
140
|
+
}, [l]);
|
|
141
|
+
const P = () => {
|
|
142
|
+
j({
|
|
143
|
+
audioInput: E !== void 0 ? E : N[0],
|
|
144
|
+
audioOutput: I !== void 0 ? I : L[0],
|
|
145
|
+
videoInput: B !== void 0 ? B : l[0]
|
|
146
|
+
});
|
|
147
|
+
}, F = () => {
|
|
148
|
+
D();
|
|
149
|
+
}, R = (t) => {
|
|
150
|
+
V(N.find((v) => v.deviceId === t));
|
|
151
|
+
}, c = (t) => {
|
|
152
|
+
A(L.find((v) => v.deviceId === t));
|
|
153
|
+
}, p = (t) => {
|
|
154
|
+
const v = l.find((x) => x.deviceId === t);
|
|
155
|
+
y(v), b(v);
|
|
156
|
+
};
|
|
157
|
+
O(() => {
|
|
158
|
+
const { current: t } = f;
|
|
159
|
+
t !== void 0 && (t.srcObject !== null && t.srcObject instanceof MediaStream && (t.srcObject.getTracks().forEach((v) => v.stop()), t.pause()), t.srcObject = _, t.play());
|
|
160
|
+
}, [_]);
|
|
161
|
+
const U = () => {
|
|
162
|
+
D();
|
|
163
|
+
};
|
|
164
|
+
return n ? /* @__PURE__ */ e.createElement("div", { className: r.background, ...C ? { onClick: U } : {} }, /* @__PURE__ */ e.createElement(
|
|
165
|
+
"div",
|
|
166
|
+
{
|
|
167
|
+
className: r.modal,
|
|
168
|
+
...C ? {
|
|
169
|
+
onClick: (t) => t.stopPropagation()
|
|
170
|
+
} : {}
|
|
171
|
+
},
|
|
172
|
+
/* @__PURE__ */ e.createElement("div", { className: r.deviceSelectContainer }, /* @__PURE__ */ e.createElement("div", { className: r.preview }, /* @__PURE__ */ e.createElement(
|
|
173
|
+
"video",
|
|
174
|
+
{
|
|
175
|
+
className: r.previewVideo,
|
|
176
|
+
ref: f,
|
|
177
|
+
autoPlay: !0,
|
|
178
|
+
muted: !0,
|
|
179
|
+
playsInline: !0
|
|
180
|
+
}
|
|
181
|
+
)), /* @__PURE__ */ e.createElement("div", { className: r.deviceLists }, i && /* @__PURE__ */ e.createElement(
|
|
182
|
+
k,
|
|
183
|
+
{
|
|
184
|
+
label: a,
|
|
185
|
+
devices: N,
|
|
186
|
+
onChange: R
|
|
187
|
+
}
|
|
188
|
+
), o && /* @__PURE__ */ e.createElement(
|
|
189
|
+
k,
|
|
190
|
+
{
|
|
191
|
+
label: s,
|
|
192
|
+
devices: L,
|
|
193
|
+
onChange: c
|
|
194
|
+
}
|
|
195
|
+
), u && /* @__PURE__ */ e.createElement(
|
|
196
|
+
k,
|
|
197
|
+
{
|
|
198
|
+
label: h,
|
|
199
|
+
devices: l,
|
|
200
|
+
onChange: p
|
|
201
|
+
}
|
|
202
|
+
))),
|
|
203
|
+
/* @__PURE__ */ e.createElement("div", { className: r.buttons }, /* @__PURE__ */ e.createElement(S, { className: r.cancelButton, onClick: F }, M), /* @__PURE__ */ e.createElement(S, { className: r.confirmButton, onClick: P }, w))
|
|
95
204
|
)) : /* @__PURE__ */ e.createElement(e.Fragment, null);
|
|
96
205
|
};
|
|
97
206
|
export {
|
|
98
|
-
|
|
207
|
+
pe as SelectMediaDevicesModal,
|
|
208
|
+
_e as SelectMediaDevicesPreviewModal
|
|
99
209
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(l,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],e):(l=typeof globalThis<"u"?globalThis:l||self,e(l.ReactSelectMediaDevicesModal={},l.React))})(this,function(l,e){"use strict";const p={background:"_background_1djbv_1",modal:"_modal_1djbv_13",deviceLists:"_deviceLists_1djbv_20",buttons:"_buttons_1djbv_24",chancelButton:"_chancelButton_1djbv_31",confirmButton:"_confirmButton_1djbv_33"},F=()=>{const[i,c]=e.useState([]);return[i,()=>{(async()=>{const n=await navigator.mediaDevices.getUserMedia({audio:!0,video:!0}),s=await navigator.mediaDevices.enumerateDevices();c(s),n.getTracks().forEach(d=>d.stop())})()}]},G=({name:i,value:c})=>e.createElement("option",{value:c},i),q={deviceList:"_deviceList_1bfq1_1",select:"_select_1bfq1_5"},b=({devices:i,label:c,onChange:r})=>{if(i===void 0)return e.createElement(e.Fragment,null);const n=d=>{r(d.target.value)},s=`device-select-${c.toLowerCase().replace(/\s/g,"-")}`;return e.createElement("div",{className:q.deviceList},e.createElement("label",{htmlFor:s},c),e.createElement("select",{className:q.select,id:s,onChange:n},i.map((d,h)=>e.createElement(G,{value:d.deviceId,name:d.label,key:h}))))},U={button:"_button_keu24_1"},L=({className:i,children:c,onClick:r})=>e.createElement("button",{onClick:r,className:[U.button,i].filter(Boolean).join(" ")},c),x=({isSelectAudioInput:i=!0,isSelectAudioOutput:c=!0,isSelectVideoInput:r=!0,open:n,audioInputDeviceLabel:s="audio input device",audioOutputDeviceLabel:d="audio output device",videoInputDeviceLabel:h="video input device",confirmButtonText:N="Confirm",cancelButtonText:$="Cancel",allowOutsideClick:D=!0,onDeviceSelected:w,onDeviceSelectCanceled:C})=>{const[u,O]=F(),[E,j]=e.useState(),[I,y]=e.useState(),[S,V]=e.useState(),_=u.filter(o=>o.kind==="audioinput"),g=u.filter(o=>o.kind==="audiooutput"),k=u.filter(o=>o.kind==="videoinput");e.useEffect(()=>{n&&O()},[n]);const B=()=>{w({audioInput:E!==void 0?E:_[0],audioOutput:I!==void 0?I:g[0],videoInput:S!==void 0?S:k[0]})},M=()=>{C()},v=o=>{j(_.find(f=>f.deviceId===o))},A=o=>{y(g.find(f=>f.deviceId===o))},P=o=>{V(k.find(f=>f.deviceId===o))},T=()=>{C()};return n?e.createElement("div",{className:p.background,...D?{onClick:T}:{}},e.createElement("div",{className:p.modal,...D?{onClick:o=>o.stopPropagation()}:{}},e.createElement("div",{className:p.deviceLists},i&&e.createElement(b,{label:s,devices:_,onChange:v}),c&&e.createElement(b,{label:d,devices:g,onChange:A}),r&&e.createElement(b,{label:h,devices:k,onChange:P})),e.createElement("div",{className:p.buttons},e.createElement(L,{className:p.cancelButton,onClick:M},$),e.createElement(L,{className:p.confirmButton,onClick:B},N)))):e.createElement(e.Fragment,null)},a={background:"_background_kb025_1",modal:"_modal_kb025_13",deviceSelectContainer:"_deviceSelectContainer_kb025_19",preview:"_preview_kb025_31",previewVideo:"_previewVideo_kb025_39",deviceLists:"_deviceLists_kb025_44",buttons:"_buttons_kb025_50",chancelButton:"_chancelButton_kb025_57",confirmButton:"_confirmButton_kb025_59"},z=()=>{const[i,c]=e.useState();return e.useEffect(()=>()=>{i!==void 0&&i.getTracks().forEach(n=>n.stop())},[]),[i,n=>{n.kind!=="audiooutput"&&(async()=>{const s=await navigator.mediaDevices.getUserMedia(n.kind==="audioinput"?{video:!1,audio:{deviceId:n.deviceId}}:{video:{deviceId:n.deviceId},audio:!1});c(s)})()}]},H=({isSelectAudioInput:i=!0,isSelectAudioOutput:c=!0,isSelectVideoInput:r=!0,open:n,audioInputDeviceLabel:s="audio input device",audioOutputDeviceLabel:d="audio output device",videoInputDeviceLabel:h="video input device",confirmButtonText:N="Confirm",cancelButtonText:$="Cancel",allowOutsideClick:D=!0,onDeviceSelected:w,onDeviceSelectCanceled:C})=>{const[u,O]=F(),[E,j]=e.useState(),[I,y]=e.useState(),[S,V]=e.useState(),[_,g]=z(),k=e.useRef(),B=e.useMemo(()=>u.filter(t=>t.kind==="audioinput"),[u]),M=e.useMemo(()=>u.filter(t=>t.kind==="audiooutput"),[u]),v=e.useMemo(()=>u.filter(t=>t.kind==="videoinput"),[u]);e.useEffect(()=>{n&&O()},[n]),e.useEffect(()=>{if(v.length<1)return;const[t]=v;g(t)},[v]);const A=()=>{w({audioInput:E!==void 0?E:B[0],audioOutput:I!==void 0?I:M[0],videoInput:S!==void 0?S:v[0]})},P=()=>{C()},T=t=>{j(B.find(m=>m.deviceId===t))},o=t=>{y(M.find(m=>m.deviceId===t))},f=t=>{const m=v.find(K=>K.deviceId===t);V(m),g(m)};e.useEffect(()=>{const{current:t}=k;t!==void 0&&(t.srcObject!==null&&t.srcObject instanceof MediaStream&&(t.srcObject.getTracks().forEach(m=>m.stop()),t.pause()),t.srcObject=_,t.play())},[_]);const J=()=>{C()};return n?e.createElement("div",{className:a.background,...D?{onClick:J}:{}},e.createElement("div",{className:a.modal,...D?{onClick:t=>t.stopPropagation()}:{}},e.createElement("div",{className:a.deviceSelectContainer},e.createElement("div",{className:a.preview},e.createElement("video",{className:a.previewVideo,ref:k,autoPlay:!0,muted:!0,playsInline:!0})),e.createElement("div",{className:a.deviceLists},i&&e.createElement(b,{label:s,devices:B,onChange:T}),c&&e.createElement(b,{label:d,devices:M,onChange:o}),r&&e.createElement(b,{label:h,devices:v,onChange:f}))),e.createElement("div",{className:a.buttons},e.createElement(L,{className:a.cancelButton,onClick:P},$),e.createElement(L,{className:a.confirmButton,onClick:A},N)))):e.createElement(e.Fragment,null)};l.SelectMediaDevicesModal=x,l.SelectMediaDevicesPreviewModal=H,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
._background_1djbv_1{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0000004d;display:flex;align-items:center;justify-content:center}._modal_1djbv_13{background:white;padding:16px;border-radius:8px;min-width:270px}._deviceLists_1djbv_20{display:grid}._buttons_1djbv_24{padding-top:16px;display:flex;align-items:center;justify-content:right}._confirmButton_1djbv_33{margin-left:4px}._deviceList_1bfq1_1{padding-top:8px}._select_1bfq1_5{margin-top:4px;border-radius:4px;height:32px;display:flex;align-items:center;justify-content:right;width:100%}._button_keu24_1{border-radius:4px;height:32px;padding-left:16px;padding-right:16px;background-color:#fff;border-width:1px}
|
|
1
|
+
._background_1djbv_1{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0000004d;display:flex;align-items:center;justify-content:center}._modal_1djbv_13{background:white;padding:16px;border-radius:8px;min-width:270px}._deviceLists_1djbv_20{display:grid}._buttons_1djbv_24{padding-top:16px;display:flex;align-items:center;justify-content:right}._confirmButton_1djbv_33{margin-left:4px}._deviceList_1bfq1_1{padding-top:8px}._select_1bfq1_5{margin-top:4px;border-radius:4px;height:32px;display:flex;align-items:center;justify-content:right;width:100%}._button_keu24_1{border-radius:4px;height:32px;padding-left:16px;padding-right:16px;background-color:#fff;border-width:1px}._background_kb025_1{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0000004d;display:flex;align-items:center;justify-content:center}._modal_kb025_13{background:white;padding:16px;border-radius:8px}._deviceSelectContainer_kb025_19{display:grid;grid-template-columns:50% 50%}@media (max-width: 640px){._deviceSelectContainer_kb025_19{display:grid;grid-template-columns:100%}}._preview_kb025_31{min-width:270px;min-height:180px;max-width:270px;max-height:180px;margin-right:4px}._previewVideo_kb025_39{width:270px;height:180px}._deviceLists_kb025_44{display:grid;min-width:270px;margin-left:8px}._buttons_kb025_50{padding-top:16px;display:flex;align-items:center;justify-content:right}._confirmButton_kb025_59{margin-left:4px}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface SelectMediaDevicesPreviewModalProps {
|
|
2
|
+
isSelectAudioInput: boolean;
|
|
3
|
+
isSelectAudioOutput: boolean;
|
|
4
|
+
isSelectVideoInput: boolean;
|
|
5
|
+
open: boolean;
|
|
6
|
+
audioInputDeviceLabel: string;
|
|
7
|
+
audioOutputDeviceLabel: string;
|
|
8
|
+
videoInputDeviceLabel: string;
|
|
9
|
+
confirmButtonText: string;
|
|
10
|
+
cancelButtonText: string;
|
|
11
|
+
allowOutsideClick: boolean;
|
|
12
|
+
onDeviceSelected: (devices: {
|
|
13
|
+
audioInput?: MediaDeviceInfo;
|
|
14
|
+
audioOutput?: MediaDeviceInfo;
|
|
15
|
+
videoInput?: MediaDeviceInfo;
|
|
16
|
+
}) => void;
|
|
17
|
+
onDeviceSelectCanceled: () => void;
|
|
18
|
+
}
|
|
19
|
+
declare const SelectMediaDevicesPreviewModal: ({ isSelectAudioInput, isSelectAudioOutput, isSelectVideoInput, open, audioInputDeviceLabel, audioOutputDeviceLabel, videoInputDeviceLabel, confirmButtonText, cancelButtonText, allowOutsideClick, onDeviceSelected, onDeviceSelectCanceled, }: SelectMediaDevicesPreviewModalProps) => JSX.Element;
|
|
20
|
+
export default SelectMediaDevicesPreviewModal;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useGetMediaStream: () => [MediaStream, (device: MediaDeviceInfo) => void];
|
package/dist/types/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-select-media-devices-modal",
|
|
3
3
|
"description": "A React component library for select media devices",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.10",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -34,9 +34,10 @@
|
|
|
34
34
|
"scripts": {
|
|
35
35
|
"dev": "vite serve example",
|
|
36
36
|
"build": "vite build",
|
|
37
|
-
"test": "vitest",
|
|
37
|
+
"test": "vitest run",
|
|
38
38
|
"coverage": "vitest run --coverage",
|
|
39
|
-
"test:e2e": "vitest run -c vitest.e2e.config.ts"
|
|
39
|
+
"test:e2e": "vitest run -c vitest.e2e.config.ts",
|
|
40
|
+
"test:e2e:watch": "vitest watch -c vitest.e2e.config.ts"
|
|
40
41
|
},
|
|
41
42
|
"dependencies": {
|
|
42
43
|
"react": "^18.2.0",
|
|
File without changes
|
|
File without changes
|