zds-pickers 4.1.1 → 4.1.3
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/index.cjs.js.map +1 -1
- package/dist/index.es.js.map +1 -1
- package/dist/other/SoundFontProvider.js +4 -4
- package/dist/types/other/SoundFontProvider.d.ts +1 -1
- package/lib/soundfonts/acoustic_grand_piano-mp3.js +107 -0
- package/package.json +5 -1
- package/.editorconfig +0 -19
- package/.github/workflows/codeql-analysis.yml +0 -67
- package/.nvmrc +0 -1
- package/.prettierignore +0 -0
- package/.prettierrc +0 -13
- package/.storybook/main.ts +0 -42
- package/.storybook/manager.ts +0 -12
- package/.storybook/preview.tsx +0 -26
- package/.vscode/extensions.json +0 -32
- package/.vscode/javascript.code-snippets +0 -229
- package/.vscode/settings.json +0 -358
- package/biome.jsonc +0 -158
- package/lib/@types/nebiru-react-rotary-knob.d.ts +0 -20
- package/lib/@types/react-svgmt.d.ts +0 -74
- package/lib/@types/zds-mappings.d.ts +0 -55
- package/lib/@types/zds-react-piano.d.ts +0 -17
- package/lib/hooks/useComponentSize.ts +0 -52
- package/lib/hooks/useStateWithDynamicDefault.ts +0 -13
- package/lib/index.ts +0 -52
- package/lib/midi/ccValues.ts +0 -139
- package/lib/midi/export.ts +0 -88
- package/lib/other/DefaultTooltip.ts +0 -14
- package/lib/other/OctavePlayer.tsx +0 -139
- package/lib/other/SoundFontProvider.tsx +0 -214
- package/lib/other/SvgText.tsx +0 -221
- package/lib/pickers/CCPicker.tsx +0 -28
- package/lib/pickers/ChannelMappingPicker.tsx +0 -150
- package/lib/pickers/ChannelPicker.tsx +0 -84
- package/lib/pickers/KeyPicker.tsx +0 -55
- package/lib/pickers/Knob.tsx +0 -93
- package/lib/pickers/KnobPicker.tsx +0 -93
- package/lib/pickers/LatchPicker.tsx +0 -33
- package/lib/pickers/MappingPicker.tsx +0 -68
- package/lib/pickers/NotePicker.tsx +0 -95
- package/lib/pickers/PianoPicker.tsx +0 -81
- package/lib/pickers/PolarityPicker.tsx +0 -39
- package/lib/pickers/ResponseCurve.tsx +0 -251
- package/lib/pickers/ResponseCurvePicker.tsx +0 -75
- package/lib/pickers/Select.tsx +0 -268
- package/lib/pickers/StatusPicker.tsx +0 -30
- package/lib/pickers/ValuePicker.tsx +0 -67
- package/lib/pickers/knobSkin10.tsx +0 -112
- package/lib/rotaryKnob/InternalInput.tsx +0 -43
- package/lib/rotaryKnob/Types.ts +0 -6
- package/lib/rotaryKnob/helpers/DrawCircle.tsx +0 -41
- package/lib/rotaryKnob/helpers/DrawLine.tsx +0 -32
- package/lib/rotaryKnob/helpers/HelpersOverlay.tsx +0 -43
- package/lib/rotaryKnob/helpers/KnobVisualHelpers.tsx +0 -138
- package/lib/rotaryKnob/index.tsx +0 -417
- package/lib/rotaryKnob/knobdefaultskin.ts +0 -69
- package/lib/rotaryKnob/utils.ts +0 -112
- package/lib/utils.ts +0 -41
- package/stories/assets/sampleStyles.css +0 -365
- package/stories/assets/utils.js +0 -7
- package/stories/picker.stories.tsx +0 -432
- package/tsconfig.json +0 -35
- package/vite.config.ts +0 -41
- /package/{lib/temp → dist/soundfonts}/acoustic_grand_piano-mp3.js +0 -0
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { useCallback } from 'react'
|
|
2
|
-
import { OctavePlayer, type OctavePlayerProps } from '../other/OctavePlayer'
|
|
3
|
-
import { noSelection } from './Select'
|
|
4
|
-
|
|
5
|
-
type KeyPickerProps = Omit<OctavePlayerProps, 'selectedNotes' | 'onClick'> & {
|
|
6
|
-
value: number
|
|
7
|
-
onChange: (value: number) => void
|
|
8
|
-
disabled?: boolean
|
|
9
|
-
height?: number
|
|
10
|
-
width?: number
|
|
11
|
-
octave?: number
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const KeyPicker = (props: KeyPickerProps) => {
|
|
15
|
-
const {
|
|
16
|
-
value,
|
|
17
|
-
onChange,
|
|
18
|
-
disabled = false,
|
|
19
|
-
height = 100,
|
|
20
|
-
width = 300,
|
|
21
|
-
octave = 4,
|
|
22
|
-
...rest
|
|
23
|
-
} = props
|
|
24
|
-
|
|
25
|
-
const handleKeyClick = useCallback(
|
|
26
|
-
(note: number) => {
|
|
27
|
-
if (disabled) return
|
|
28
|
-
onChange(note)
|
|
29
|
-
},
|
|
30
|
-
[disabled, onChange],
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
// Only highlight the note if it's a valid selection and within the octave range
|
|
34
|
-
// Octave 4 = C4 (60) to B4 (71)
|
|
35
|
-
const octaveStart = 60 + (octave - 4) * 12
|
|
36
|
-
const octaveEnd = octaveStart + 11
|
|
37
|
-
const shouldHighlight =
|
|
38
|
-
value !== noSelection && value >= octaveStart && value <= octaveEnd
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<OctavePlayer
|
|
42
|
-
{...rest}
|
|
43
|
-
selectedNotes={shouldHighlight ? [value] : []}
|
|
44
|
-
disabled={disabled}
|
|
45
|
-
height={height}
|
|
46
|
-
width={width}
|
|
47
|
-
octave={octave}
|
|
48
|
-
onClick={handleKeyClick}
|
|
49
|
-
instrumentName="acoustic_grand_piano"
|
|
50
|
-
/>
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export { KeyPicker }
|
|
55
|
-
export type { KeyPickerProps }
|
package/lib/pickers/Knob.tsx
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { useCallback } from 'react'
|
|
2
|
-
import useStateWithDynamicDefault from '../hooks/useStateWithDynamicDefault'
|
|
3
|
-
import { RotaryKnob } from '../rotaryKnob'
|
|
4
|
-
import { assertRange } from '../utils'
|
|
5
|
-
import { knobSkin10 } from './knobSkin10'
|
|
6
|
-
|
|
7
|
-
type KnobProps = {
|
|
8
|
-
disabled?: boolean
|
|
9
|
-
max?: number
|
|
10
|
-
min?: number
|
|
11
|
-
onChange?: (value: number) => void
|
|
12
|
-
value?: number
|
|
13
|
-
wheelEnabled?: boolean
|
|
14
|
-
wheelSensitivity?: number
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const Knob = (props: KnobProps) => {
|
|
18
|
-
const {
|
|
19
|
-
disabled = false,
|
|
20
|
-
max = 127,
|
|
21
|
-
min = 0,
|
|
22
|
-
onChange,
|
|
23
|
-
value: initialValue = 0,
|
|
24
|
-
wheelEnabled = false,
|
|
25
|
-
wheelSensitivity = 0.1,
|
|
26
|
-
...rest
|
|
27
|
-
} = props
|
|
28
|
-
|
|
29
|
-
const [value, setValue] = useStateWithDynamicDefault(initialValue)
|
|
30
|
-
|
|
31
|
-
const handleChange = (val: number) => {
|
|
32
|
-
if (disabled) return
|
|
33
|
-
|
|
34
|
-
const newValue = assertRange(Number.parseInt(String(val), 10), max, min)
|
|
35
|
-
setValue(newValue)
|
|
36
|
-
if (onChange) {
|
|
37
|
-
onChange(newValue)
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const handleWheel = useCallback(
|
|
42
|
-
(event: React.WheelEvent<HTMLDivElement>) => {
|
|
43
|
-
if (!wheelEnabled || disabled) return
|
|
44
|
-
|
|
45
|
-
event.preventDefault()
|
|
46
|
-
const delta = -event.deltaY * wheelSensitivity
|
|
47
|
-
const newValue = assertRange(value + delta, max, min)
|
|
48
|
-
|
|
49
|
-
setValue(newValue)
|
|
50
|
-
if (onChange) {
|
|
51
|
-
onChange(newValue)
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
[
|
|
55
|
-
wheelEnabled,
|
|
56
|
-
disabled,
|
|
57
|
-
wheelSensitivity,
|
|
58
|
-
value,
|
|
59
|
-
max,
|
|
60
|
-
min,
|
|
61
|
-
onChange,
|
|
62
|
-
setValue,
|
|
63
|
-
],
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
return (
|
|
67
|
-
<RotaryKnob
|
|
68
|
-
clampMax={320}
|
|
69
|
-
clampMin={40}
|
|
70
|
-
className="zds-pickers__knob-container"
|
|
71
|
-
disabled={disabled}
|
|
72
|
-
onChange={handleChange}
|
|
73
|
-
onWheel={wheelEnabled ? handleWheel : undefined}
|
|
74
|
-
preciseMode={false}
|
|
75
|
-
rotateDegrees={180}
|
|
76
|
-
/**
|
|
77
|
-
* To see all skins:
|
|
78
|
-
* http://react-rotary-knob-skins-preview.surge.sh/
|
|
79
|
-
*
|
|
80
|
-
* NOTE: we've copied the one we use into this package because the skins
|
|
81
|
-
* pack package does not work in Electron.
|
|
82
|
-
*/
|
|
83
|
-
skin={knobSkin10}
|
|
84
|
-
style={{ opacity: disabled ? 0.4 : 1 }}
|
|
85
|
-
unlockDistance={0}
|
|
86
|
-
{...{ defaultValue: value, max, min, value, ...rest }}
|
|
87
|
-
/>
|
|
88
|
-
)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export { Knob }
|
|
92
|
-
|
|
93
|
-
export type { KnobProps }
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { forwardRef, useMemo } from 'react'
|
|
2
|
-
import type { GroupBase, SelectInstance } from 'react-select'
|
|
3
|
-
import { arraySequence } from '../utils'
|
|
4
|
-
import { Knob } from './Knob'
|
|
5
|
-
import { Select } from './Select'
|
|
6
|
-
import type { Option, SelectProps } from './Select'
|
|
7
|
-
|
|
8
|
-
type KnobPickerProps = SelectProps<number> & {
|
|
9
|
-
highToLow?: boolean
|
|
10
|
-
includeLabel?: boolean
|
|
11
|
-
includePicker?: boolean
|
|
12
|
-
knobProps?: Partial<KnobPickerProps>
|
|
13
|
-
max?: number
|
|
14
|
-
min?: number
|
|
15
|
-
wheelEnabled?: boolean
|
|
16
|
-
wheelSensitivity?: number
|
|
17
|
-
value: number
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
type KnobPickerRef = SelectInstance<
|
|
21
|
-
Option<number>,
|
|
22
|
-
false,
|
|
23
|
-
GroupBase<Option<number>>
|
|
24
|
-
>
|
|
25
|
-
|
|
26
|
-
const KnobPicker = forwardRef<
|
|
27
|
-
SelectInstance<Option<number>, false, GroupBase<Option<number>>>,
|
|
28
|
-
KnobPickerProps
|
|
29
|
-
>((props, ref) => {
|
|
30
|
-
const {
|
|
31
|
-
disabled,
|
|
32
|
-
highToLow,
|
|
33
|
-
includeLabel,
|
|
34
|
-
includePicker,
|
|
35
|
-
knobProps,
|
|
36
|
-
label,
|
|
37
|
-
max = 127,
|
|
38
|
-
min = 0,
|
|
39
|
-
onChange,
|
|
40
|
-
shrinkLabel,
|
|
41
|
-
value = 0,
|
|
42
|
-
wheelEnabled,
|
|
43
|
-
wheelSensitivity = 0.1,
|
|
44
|
-
...rest
|
|
45
|
-
} = props
|
|
46
|
-
|
|
47
|
-
const options = useMemo(() => {
|
|
48
|
-
const result = arraySequence(max - min + 1)
|
|
49
|
-
.map(i => min + i)
|
|
50
|
-
.map((i): Option<number> => ({ value: i, label: String(i) }))
|
|
51
|
-
return highToLow ? result.reverse() : result
|
|
52
|
-
}, [highToLow, max, min])
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<div className="zds-pickers__container">
|
|
56
|
-
{Boolean(!shrinkLabel && Boolean(label)) && (
|
|
57
|
-
<span className="zds-pickers__label">{label}</span>
|
|
58
|
-
)}
|
|
59
|
-
<div style={{ display: 'inline-flex', gap: 10, alignItems: 'center' }}>
|
|
60
|
-
{Boolean(includePicker) && (
|
|
61
|
-
<Select
|
|
62
|
-
{...{
|
|
63
|
-
...rest,
|
|
64
|
-
disabled,
|
|
65
|
-
isDisabled: disabled,
|
|
66
|
-
onChange,
|
|
67
|
-
options,
|
|
68
|
-
ref,
|
|
69
|
-
value,
|
|
70
|
-
}}
|
|
71
|
-
/>
|
|
72
|
-
)}
|
|
73
|
-
|
|
74
|
-
<Knob
|
|
75
|
-
{...{
|
|
76
|
-
disabled,
|
|
77
|
-
max,
|
|
78
|
-
min,
|
|
79
|
-
onChange,
|
|
80
|
-
value,
|
|
81
|
-
wheelEnabled,
|
|
82
|
-
wheelSensitivity,
|
|
83
|
-
...knobProps,
|
|
84
|
-
}}
|
|
85
|
-
/>
|
|
86
|
-
</div>
|
|
87
|
-
</div>
|
|
88
|
-
)
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
export { KnobPicker }
|
|
92
|
-
|
|
93
|
-
export type { KnobPickerProps, KnobPickerRef }
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { forwardRef } from 'react'
|
|
2
|
-
import type { GroupBase, SelectInstance } from 'react-select'
|
|
3
|
-
import type { Polarity } from './PolarityPicker'
|
|
4
|
-
import { Select } from './Select'
|
|
5
|
-
import type { Option, SelectProps } from './Select'
|
|
6
|
-
|
|
7
|
-
const options: Option<Polarity>[] = [
|
|
8
|
-
{ value: 0, label: 'Momentary' },
|
|
9
|
-
{ value: 1, label: 'Latching' },
|
|
10
|
-
]
|
|
11
|
-
|
|
12
|
-
type LatchPickerProps = Omit<SelectProps<Polarity>, 'options'>
|
|
13
|
-
|
|
14
|
-
type LatchPickerRef = SelectInstance<
|
|
15
|
-
Option<Polarity>,
|
|
16
|
-
false,
|
|
17
|
-
GroupBase<Option<Polarity>>
|
|
18
|
-
>
|
|
19
|
-
|
|
20
|
-
const LatchPicker = forwardRef<
|
|
21
|
-
SelectInstance<Option<Polarity>, false, GroupBase<Option<Polarity>>>,
|
|
22
|
-
LatchPickerProps
|
|
23
|
-
>((props, ref) => (
|
|
24
|
-
<Select
|
|
25
|
-
{...props}
|
|
26
|
-
options={options}
|
|
27
|
-
ref={ref}
|
|
28
|
-
/>
|
|
29
|
-
))
|
|
30
|
-
|
|
31
|
-
export { LatchPicker }
|
|
32
|
-
|
|
33
|
-
export type { LatchPickerProps, LatchPickerRef }
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { forwardRef, useMemo } from 'react'
|
|
2
|
-
import type { GroupBase, SelectInstance } from 'react-select'
|
|
3
|
-
import { getStockNames, getUserMappingNames } from 'zds-mappings'
|
|
4
|
-
import { Select } from './Select'
|
|
5
|
-
import type { Option, SelectProps } from './Select'
|
|
6
|
-
|
|
7
|
-
type MappingPickerProps = Omit<SelectProps<string>, 'options'> & {
|
|
8
|
-
allowClearing: boolean
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
type MappingPickerRef = SelectInstance<
|
|
12
|
-
Option<string>,
|
|
13
|
-
false,
|
|
14
|
-
GroupBase<Option<string>>
|
|
15
|
-
>
|
|
16
|
-
|
|
17
|
-
const MappingPicker = forwardRef<
|
|
18
|
-
SelectInstance<Option<string>, false, GroupBase<Option<string>>>,
|
|
19
|
-
MappingPickerProps
|
|
20
|
-
>(({ allowClearing, ...rest }, ref) => {
|
|
21
|
-
const stockMappings = getStockNames()
|
|
22
|
-
const userMappings = getUserMappingNames()
|
|
23
|
-
|
|
24
|
-
const options = useMemo(() => {
|
|
25
|
-
const result = allowClearing
|
|
26
|
-
? [
|
|
27
|
-
{
|
|
28
|
-
value: 'No Mapping',
|
|
29
|
-
label: (
|
|
30
|
-
<span className="zds-mappings-clear-mapping">No Mapping</span>
|
|
31
|
-
),
|
|
32
|
-
},
|
|
33
|
-
]
|
|
34
|
-
: []
|
|
35
|
-
|
|
36
|
-
return [
|
|
37
|
-
...result,
|
|
38
|
-
|
|
39
|
-
{
|
|
40
|
-
label: allowClearing ? <hr /> : '',
|
|
41
|
-
options: userMappings.map(label => ({
|
|
42
|
-
value: label,
|
|
43
|
-
label: <span className="zds-mappings-user-mapping">{label}</span>,
|
|
44
|
-
})),
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
{
|
|
48
|
-
label: userMappings.length ? <hr /> : allowClearing ? <hr /> : '',
|
|
49
|
-
options: stockMappings.map(label => ({
|
|
50
|
-
label,
|
|
51
|
-
value: label,
|
|
52
|
-
})),
|
|
53
|
-
},
|
|
54
|
-
] as Option<string>[]
|
|
55
|
-
}, [allowClearing, stockMappings, userMappings])
|
|
56
|
-
|
|
57
|
-
return (
|
|
58
|
-
<Select
|
|
59
|
-
{...rest}
|
|
60
|
-
options={options}
|
|
61
|
-
ref={ref}
|
|
62
|
-
/>
|
|
63
|
-
)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
export { MappingPicker }
|
|
67
|
-
|
|
68
|
-
export type { MappingPickerProps, MappingPickerRef }
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { forwardRef, useCallback, useMemo } from 'react'
|
|
2
|
-
import type { GroupBase, SelectInstance } from 'react-select'
|
|
3
|
-
import { Midi } from 'tonal'
|
|
4
|
-
import { type MapItem, type Mapping, emptyMapping } from 'zds-mappings'
|
|
5
|
-
import useStateWithDynamicDefault from '../hooks/useStateWithDynamicDefault'
|
|
6
|
-
import { assertRange } from '../utils'
|
|
7
|
-
import { Select } from './Select'
|
|
8
|
-
import type { Option, SelectProps } from './Select'
|
|
9
|
-
|
|
10
|
-
const { midiToNoteName } = Midi
|
|
11
|
-
|
|
12
|
-
const formattedMapEntry = ({ note, name }: MapItem) =>
|
|
13
|
-
`${note} ${name.length ? '-' : ''} ${name}`
|
|
14
|
-
const formattedListEntry = (label: string, idx: number) => ({
|
|
15
|
-
label,
|
|
16
|
-
value: idx + 1,
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
type NotePickerProps = Omit<SelectProps<number>, 'options'> & {
|
|
20
|
-
channel: number
|
|
21
|
-
disabled?: boolean
|
|
22
|
-
isMelodicMode?: boolean
|
|
23
|
-
mapping?: Mapping
|
|
24
|
-
onChange: (value: number) => void
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
type NotePickerRef = SelectInstance<
|
|
28
|
-
Option<number>,
|
|
29
|
-
false,
|
|
30
|
-
GroupBase<Option<number>>
|
|
31
|
-
>
|
|
32
|
-
|
|
33
|
-
const NotePicker = forwardRef<
|
|
34
|
-
SelectInstance<Option<number>, false, GroupBase<Option<number>>>,
|
|
35
|
-
NotePickerProps
|
|
36
|
-
>((props, ref) => {
|
|
37
|
-
const {
|
|
38
|
-
channel,
|
|
39
|
-
disabled = false,
|
|
40
|
-
isMelodicMode = false,
|
|
41
|
-
mapping,
|
|
42
|
-
onChange,
|
|
43
|
-
value: initialValue,
|
|
44
|
-
...rest
|
|
45
|
-
} = props
|
|
46
|
-
|
|
47
|
-
const options = useMemo(() => {
|
|
48
|
-
if (isMelodicMode) {
|
|
49
|
-
return emptyMapping()
|
|
50
|
-
.map(({ note }) => {
|
|
51
|
-
const midiNoteName = midiToNoteName(note, { sharps: false })
|
|
52
|
-
.replace('b', '♭')
|
|
53
|
-
.replace('#', '♯')
|
|
54
|
-
return `${midiNoteName} (#${note})`
|
|
55
|
-
})
|
|
56
|
-
.map(formattedListEntry)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return (mapping || emptyMapping())
|
|
60
|
-
.map(formattedMapEntry)
|
|
61
|
-
.map(formattedListEntry)
|
|
62
|
-
}, [isMelodicMode, mapping])
|
|
63
|
-
|
|
64
|
-
const [value, setValue] = useStateWithDynamicDefault(initialValue)
|
|
65
|
-
|
|
66
|
-
const handleChange = useCallback(
|
|
67
|
-
(v: number | string) => {
|
|
68
|
-
if (typeof v === 'string') return
|
|
69
|
-
|
|
70
|
-
const possibleNoteNumber = assertRange(v, 128, 0)
|
|
71
|
-
|
|
72
|
-
if (possibleNoteNumber > 0) {
|
|
73
|
-
onChange(possibleNoteNumber)
|
|
74
|
-
}
|
|
75
|
-
setValue(v)
|
|
76
|
-
},
|
|
77
|
-
[onChange, setValue],
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
return (
|
|
81
|
-
<Select
|
|
82
|
-
{...rest}
|
|
83
|
-
disabled={disabled}
|
|
84
|
-
// isDisabled={disabled}
|
|
85
|
-
onChange={handleChange}
|
|
86
|
-
options={options}
|
|
87
|
-
ref={ref}
|
|
88
|
-
value={value}
|
|
89
|
-
/>
|
|
90
|
-
)
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
export { NotePicker }
|
|
94
|
-
|
|
95
|
-
export type { NotePickerProps, NotePickerRef }
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { Piano as ReactPiano } from 'zds-react-piano'
|
|
2
|
-
import type { WithProviderProps } from '../other/OctavePlayer'
|
|
3
|
-
import { SoundfontProvider } from '../other/SoundFontProvider'
|
|
4
|
-
|
|
5
|
-
const firstNote = 21
|
|
6
|
-
const lastNote = 108
|
|
7
|
-
const numNotes = lastNote - firstNote - 1
|
|
8
|
-
|
|
9
|
-
const whiteNotes = numNotes * 0.7 // approx
|
|
10
|
-
|
|
11
|
-
const audioContext = new window.AudioContext()
|
|
12
|
-
|
|
13
|
-
type PianoProps = {
|
|
14
|
-
activeNotes?: number[]
|
|
15
|
-
selectedNotes?: number[]
|
|
16
|
-
disabled: boolean
|
|
17
|
-
height: number
|
|
18
|
-
width: number
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const BasePianoPicker = ({ height, width, ...rest }: PianoProps) => {
|
|
22
|
-
const keyWidth = width / whiteNotes + 2
|
|
23
|
-
const keyWidthToHeight = keyWidth / height
|
|
24
|
-
|
|
25
|
-
return (
|
|
26
|
-
<div>
|
|
27
|
-
<ReactPiano
|
|
28
|
-
keyWidthToHeight={keyWidthToHeight}
|
|
29
|
-
noteRange={{ first: firstNote, last: lastNote }}
|
|
30
|
-
width={width}
|
|
31
|
-
{...rest}
|
|
32
|
-
/>
|
|
33
|
-
</div>
|
|
34
|
-
)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const WithProvider = ({
|
|
38
|
-
format,
|
|
39
|
-
height,
|
|
40
|
-
hostname,
|
|
41
|
-
instrumentName,
|
|
42
|
-
onChange,
|
|
43
|
-
onClick,
|
|
44
|
-
onDoubleClick,
|
|
45
|
-
onKeyMouseEnter,
|
|
46
|
-
onKeyMouseLeave,
|
|
47
|
-
selectedNotes,
|
|
48
|
-
soundfont,
|
|
49
|
-
width,
|
|
50
|
-
}: WithProviderProps) => (
|
|
51
|
-
<SoundfontProvider
|
|
52
|
-
{...{
|
|
53
|
-
audioContext,
|
|
54
|
-
format,
|
|
55
|
-
hostname,
|
|
56
|
-
instrumentName,
|
|
57
|
-
onChange,
|
|
58
|
-
soundfont,
|
|
59
|
-
}}
|
|
60
|
-
render={({ isLoading, playNote, stopNote }) => (
|
|
61
|
-
<BasePianoPicker
|
|
62
|
-
disabled={isLoading}
|
|
63
|
-
{...{
|
|
64
|
-
height,
|
|
65
|
-
onClick,
|
|
66
|
-
onDoubleClick,
|
|
67
|
-
onKeyMouseEnter,
|
|
68
|
-
onKeyMouseLeave,
|
|
69
|
-
playNote,
|
|
70
|
-
selectedNotes,
|
|
71
|
-
stopNote,
|
|
72
|
-
width,
|
|
73
|
-
}}
|
|
74
|
-
/>
|
|
75
|
-
)}
|
|
76
|
-
/>
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
export { WithProvider as PianoPicker }
|
|
80
|
-
|
|
81
|
-
export type { PianoProps }
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { forwardRef } from 'react'
|
|
2
|
-
import type { GroupBase, SelectInstance } from 'react-select'
|
|
3
|
-
import { Select } from './Select'
|
|
4
|
-
import type { Option, SelectProps, noSelection } from './Select'
|
|
5
|
-
|
|
6
|
-
type Polarity = 0 | 1 | typeof noSelection
|
|
7
|
-
|
|
8
|
-
type PolarityPickerProps = Omit<SelectProps<Polarity>, 'options'> & {
|
|
9
|
-
labelOff?: string
|
|
10
|
-
labelOn?: string
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
type PolarityPickerRef = SelectInstance<
|
|
14
|
-
Option<Polarity>,
|
|
15
|
-
false,
|
|
16
|
-
GroupBase<Option<Polarity>>
|
|
17
|
-
>
|
|
18
|
-
|
|
19
|
-
const PolarityPicker = forwardRef<
|
|
20
|
-
SelectInstance<Option<Polarity>, false, GroupBase<Option<Polarity>>>,
|
|
21
|
-
PolarityPickerProps
|
|
22
|
-
>(({ labelOff = 'Normally Off', labelOn = 'Normally On', ...rest }, ref) => {
|
|
23
|
-
const options = [
|
|
24
|
-
{ value: 0, label: labelOff },
|
|
25
|
-
{ value: 1, label: labelOn },
|
|
26
|
-
] as Option<Polarity>[]
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<Select
|
|
30
|
-
{...rest}
|
|
31
|
-
options={options}
|
|
32
|
-
ref={ref}
|
|
33
|
-
/>
|
|
34
|
-
)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
export { PolarityPicker }
|
|
38
|
-
|
|
39
|
-
export type { Polarity, PolarityPickerProps, PolarityPickerRef }
|