zds-pickers 4.0.5 → 4.0.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/.editorconfig +19 -0
- package/.github/workflows/codeql-analysis.yml +67 -0
- package/.nvmrc +1 -0
- package/.prettierignore +0 -0
- package/.prettierrc +13 -0
- package/.storybook/main.ts +42 -0
- package/.storybook/manager.ts +12 -0
- package/.storybook/preview.tsx +26 -0
- package/.vscode/extensions.json +32 -0
- package/.vscode/javascript.code-snippets +229 -0
- package/.vscode/settings.json +358 -0
- package/biome.jsonc +158 -0
- package/dist/index.es.js +3 -1
- package/dist/types/index.d.ts +266 -2
- package/dist/types/pickers/CCPicker.d.ts +2 -1
- package/dist/types/pickers/ChannelMappingPicker.d.ts +2 -1
- package/dist/types/pickers/ChannelPicker.d.ts +5 -3
- package/dist/types/pickers/LatchPicker.d.ts +5 -3
- package/dist/types/pickers/MappingPicker.d.ts +2 -1
- package/dist/types/pickers/NotePicker.d.ts +2 -1
- package/dist/types/pickers/PolarityPicker.d.ts +6 -4
- package/dist/types/pickers/ResponseCurve.d.ts +14 -5
- package/dist/types/pickers/ResponseCurvePicker.d.ts +6 -4
- package/dist/types/pickers/StatusPicker.d.ts +2 -1
- package/dist/types/pickers/ValuePicker.d.ts +2 -1
- package/lib/@types/nebiru-react-rotary-knob.d.ts +20 -0
- package/lib/@types/react-svgmt.d.ts +74 -0
- package/lib/@types/zds-mappings.d.ts +55 -0
- package/lib/@types/zds-react-piano.d.ts +17 -0
- package/lib/hooks/useComponentSize.ts +52 -0
- package/lib/hooks/useStateWithDynamicDefault.ts +13 -0
- package/lib/main.ts +34 -0
- package/lib/midi/ccValues.ts +139 -0
- package/lib/midi/export.ts +54 -0
- package/lib/other/DefaultTooltip.ts +14 -0
- package/lib/other/OctavePlayer.tsx +141 -0
- package/lib/other/SVGText.tsx +221 -0
- package/lib/other/SoundFontProvider.tsx +130 -0
- package/lib/pickers/CCPicker.tsx +28 -0
- package/lib/pickers/ChannelMappingPicker.tsx +135 -0
- package/lib/pickers/ChannelPicker.tsx +76 -0
- package/lib/pickers/Knob.tsx +93 -0
- package/lib/pickers/KnobPicker.tsx +93 -0
- package/lib/pickers/LatchPicker.tsx +33 -0
- package/lib/pickers/MappingPicker.tsx +68 -0
- package/lib/pickers/NotePicker.tsx +95 -0
- package/lib/pickers/PianoPicker.tsx +77 -0
- package/lib/pickers/PolarityPicker.tsx +39 -0
- package/lib/pickers/ResponseCurve.tsx +304 -0
- package/lib/pickers/ResponseCurvePicker.tsx +74 -0
- package/lib/pickers/Select.tsx +248 -0
- package/lib/pickers/StatusPicker.tsx +28 -0
- package/lib/pickers/ValuePicker.tsx +67 -0
- package/lib/pickers/knobSkin10.tsx +94 -0
- package/lib/rotaryKnob/InternalInput.tsx +43 -0
- package/lib/rotaryKnob/Types.ts +6 -0
- package/lib/rotaryKnob/helpers/DrawCircle.tsx +41 -0
- package/lib/rotaryKnob/helpers/DrawLine.tsx +32 -0
- package/lib/rotaryKnob/helpers/HelpersOverlay.tsx +43 -0
- package/lib/rotaryKnob/helpers/KnobVisualHelpers.tsx +138 -0
- package/lib/rotaryKnob/index.tsx +417 -0
- package/lib/rotaryKnob/knobdefaultskin.ts +56 -0
- package/lib/rotaryKnob/utils.ts +112 -0
- package/lib/temp/acoustic_grand_piano-mp3.js +94 -0
- package/lib/utils.ts +41 -0
- package/package.json +2 -6
- package/stories/assets/sampleStyles.css +349 -0
- package/stories/assets/utils.js +7 -0
- package/stories/picker.stories.tsx +313 -0
- package/tsconfig.app.json +26 -0
- package/tsconfig.json +34 -0
- package/tsconfig.node.json +24 -0
- package/vite.config.ts +45 -0
- package/dist/index.d.ts +0 -244
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Children,
|
|
3
|
+
type JSX,
|
|
4
|
+
forwardRef,
|
|
5
|
+
isValidElement,
|
|
6
|
+
useCallback,
|
|
7
|
+
useMemo,
|
|
8
|
+
} from 'react'
|
|
9
|
+
import ReactSelect, {
|
|
10
|
+
type GroupBase,
|
|
11
|
+
type IndicatorsContainerProps,
|
|
12
|
+
components as originalComponents,
|
|
13
|
+
type PlaceholderProps,
|
|
14
|
+
type SelectInstance,
|
|
15
|
+
type SingleValue,
|
|
16
|
+
type StylesConfig,
|
|
17
|
+
type ValueContainerProps,
|
|
18
|
+
} from 'react-select'
|
|
19
|
+
import { omit } from '../utils'
|
|
20
|
+
|
|
21
|
+
const { IndicatorsContainer, Placeholder, ValueContainer } = originalComponents
|
|
22
|
+
|
|
23
|
+
type Option<T> = {
|
|
24
|
+
label: React.ReactNode
|
|
25
|
+
value: T
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface CustomIndicatorsContainerProps<T>
|
|
29
|
+
extends Omit<IndicatorsContainerProps<Option<T>, false>, 'selectProps'> {
|
|
30
|
+
children: React.ReactNode
|
|
31
|
+
selectProps: IndicatorsContainerProps<Option<T>, false>['selectProps'] & {
|
|
32
|
+
actionButton?: React.ReactNode
|
|
33
|
+
inputValue?: string
|
|
34
|
+
placeholder?: React.ReactNode
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const CustomIndicatorsContainer = <T,>({
|
|
39
|
+
children,
|
|
40
|
+
...rest
|
|
41
|
+
}: CustomIndicatorsContainerProps<T>) => {
|
|
42
|
+
const actionButton = rest.selectProps?.actionButton
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<IndicatorsContainer {...rest}>
|
|
46
|
+
<div
|
|
47
|
+
onMouseDown={e => {
|
|
48
|
+
e.stopPropagation()
|
|
49
|
+
e.preventDefault()
|
|
50
|
+
}}
|
|
51
|
+
style={{ display: 'flex' }}>
|
|
52
|
+
{actionButton}
|
|
53
|
+
{children}
|
|
54
|
+
</div>
|
|
55
|
+
</IndicatorsContainer>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
type CustomValueContainerProps<T> = (
|
|
60
|
+
| ValueContainerProps<Option<T>, false>
|
|
61
|
+
| PlaceholderProps<Option<T>, false>
|
|
62
|
+
) & {
|
|
63
|
+
children: React.ReactNode
|
|
64
|
+
hasValue?: boolean
|
|
65
|
+
isFocused?: boolean
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const CustomValueContainer = <T,>({
|
|
69
|
+
children,
|
|
70
|
+
...props
|
|
71
|
+
}: CustomValueContainerProps<T>) => (
|
|
72
|
+
<ValueContainer {...props}>
|
|
73
|
+
<Placeholder
|
|
74
|
+
{...props}
|
|
75
|
+
innerProps={props.innerProps || {}}
|
|
76
|
+
className={props.hasValue || props.selectProps.inputValue ? 'shrunk' : ''}
|
|
77
|
+
isFocused={props.isFocused ?? false}>
|
|
78
|
+
{props.selectProps.placeholder}
|
|
79
|
+
</Placeholder>
|
|
80
|
+
{Children.map(children, child =>
|
|
81
|
+
isValidElement(child) && child.type !== Placeholder ? child : null,
|
|
82
|
+
)}
|
|
83
|
+
</ValueContainer>
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
type SelectProps<T> = {
|
|
87
|
+
className?: string
|
|
88
|
+
components?: object
|
|
89
|
+
disabled?: boolean
|
|
90
|
+
filterOptions?: (candidate: Option<T>, inputValue: string) => boolean
|
|
91
|
+
formatOptionLabel?: (
|
|
92
|
+
option: Option<unknown>,
|
|
93
|
+
{ context }: { context: 'menu' | 'value' },
|
|
94
|
+
) => React.ReactNode
|
|
95
|
+
isSearchable?: boolean
|
|
96
|
+
label?: string
|
|
97
|
+
onChange: (value: Option<T>['value']) => void
|
|
98
|
+
options: Option<T>[] | { entries: Option<T>[] }[]
|
|
99
|
+
preserveMenuWidth?: boolean
|
|
100
|
+
shrinkLabel?: boolean
|
|
101
|
+
value: Option<T>['value']
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const Select = forwardRef(
|
|
105
|
+
<T,>(
|
|
106
|
+
props: SelectProps<T>,
|
|
107
|
+
ref: React.ForwardedRef<
|
|
108
|
+
SelectInstance<Option<T>, false, GroupBase<Option<T>>>
|
|
109
|
+
>,
|
|
110
|
+
) => {
|
|
111
|
+
const {
|
|
112
|
+
components,
|
|
113
|
+
disabled,
|
|
114
|
+
label,
|
|
115
|
+
onChange,
|
|
116
|
+
options = [],
|
|
117
|
+
preserveMenuWidth,
|
|
118
|
+
shrinkLabel,
|
|
119
|
+
value,
|
|
120
|
+
...rest
|
|
121
|
+
} = props
|
|
122
|
+
|
|
123
|
+
const handleChange = useCallback(
|
|
124
|
+
(option: SingleValue<Option<unknown>>) => {
|
|
125
|
+
if (option) {
|
|
126
|
+
onChange((option as Option<T>).value)
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
[onChange],
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
const flatOptionsList = options.reduce<Option<T>[]>((acc, entry) => {
|
|
133
|
+
if ('entries' in entry) {
|
|
134
|
+
return acc.concat(entry.entries)
|
|
135
|
+
}
|
|
136
|
+
return acc.concat(entry)
|
|
137
|
+
}, [])
|
|
138
|
+
|
|
139
|
+
const selectedOption =
|
|
140
|
+
flatOptionsList.find(option => value === option.value) || undefined
|
|
141
|
+
|
|
142
|
+
const styles: unknown = useMemo(() => {
|
|
143
|
+
const base = preserveMenuWidth
|
|
144
|
+
? {
|
|
145
|
+
menu: (base: Record<string, unknown>) => omit('width')(base),
|
|
146
|
+
menuList: (base: object) => ({
|
|
147
|
+
...base,
|
|
148
|
+
overflowX: 'hidden',
|
|
149
|
+
}),
|
|
150
|
+
option: (base: object) => ({
|
|
151
|
+
...base,
|
|
152
|
+
whiteSpace: 'nowrap',
|
|
153
|
+
paddingRight: 10,
|
|
154
|
+
}),
|
|
155
|
+
}
|
|
156
|
+
: {}
|
|
157
|
+
|
|
158
|
+
return shrinkLabel
|
|
159
|
+
? {
|
|
160
|
+
...base,
|
|
161
|
+
container: (provided: object /* , state */) => ({
|
|
162
|
+
...provided,
|
|
163
|
+
marginTop: 10,
|
|
164
|
+
}),
|
|
165
|
+
placeholder: (
|
|
166
|
+
_provided: object,
|
|
167
|
+
state: PlaceholderProps<Option<T>, false>,
|
|
168
|
+
) => ({
|
|
169
|
+
position: 'absolute',
|
|
170
|
+
left: state.hasValue || state.selectProps.inputValue ? -2 : '4%',
|
|
171
|
+
top: state.hasValue || state.selectProps.inputValue ? -12 : '50%',
|
|
172
|
+
transition: 'top 0.1s, font-size 0.1s, color 0.1s',
|
|
173
|
+
fontSize: (state.hasValue || state.selectProps.inputValue) && 13,
|
|
174
|
+
}),
|
|
175
|
+
valueContainer: (provided: object /* , state */) => ({
|
|
176
|
+
...provided,
|
|
177
|
+
overflow: 'visible',
|
|
178
|
+
}),
|
|
179
|
+
}
|
|
180
|
+
: {
|
|
181
|
+
...base,
|
|
182
|
+
}
|
|
183
|
+
}, [preserveMenuWidth, shrinkLabel])
|
|
184
|
+
|
|
185
|
+
return shrinkLabel ? (
|
|
186
|
+
<div className="zds-pickers__container">
|
|
187
|
+
<ReactSelect
|
|
188
|
+
{...rest}
|
|
189
|
+
classNamePrefix="zds-pickers"
|
|
190
|
+
components={{
|
|
191
|
+
IndicatorsContainer: CustomIndicatorsContainer,
|
|
192
|
+
ValueContainer: CustomValueContainer,
|
|
193
|
+
...components,
|
|
194
|
+
}}
|
|
195
|
+
isDisabled={disabled}
|
|
196
|
+
onChange={handleChange}
|
|
197
|
+
options={flatOptionsList}
|
|
198
|
+
placeholder={label}
|
|
199
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
200
|
+
ref={ref as React.Ref<any>}
|
|
201
|
+
styles={
|
|
202
|
+
styles as StylesConfig<
|
|
203
|
+
Option<unknown>,
|
|
204
|
+
false,
|
|
205
|
+
GroupBase<Option<unknown>>
|
|
206
|
+
>
|
|
207
|
+
}
|
|
208
|
+
value={selectedOption}
|
|
209
|
+
/>
|
|
210
|
+
</div>
|
|
211
|
+
) : (
|
|
212
|
+
<div className="zds-pickers__container">
|
|
213
|
+
{Boolean(label) && <span className="zds-pickers__label">{label}</span>}
|
|
214
|
+
<ReactSelect
|
|
215
|
+
{...rest}
|
|
216
|
+
classNamePrefix="zds-pickers"
|
|
217
|
+
components={{
|
|
218
|
+
IndicatorsContainer: CustomIndicatorsContainer,
|
|
219
|
+
...components,
|
|
220
|
+
}}
|
|
221
|
+
isDisabled={disabled}
|
|
222
|
+
onChange={handleChange}
|
|
223
|
+
options={flatOptionsList}
|
|
224
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
225
|
+
ref={ref as React.Ref<any>}
|
|
226
|
+
styles={
|
|
227
|
+
styles as StylesConfig<
|
|
228
|
+
Option<unknown>,
|
|
229
|
+
false,
|
|
230
|
+
GroupBase<Option<unknown>>
|
|
231
|
+
>
|
|
232
|
+
}
|
|
233
|
+
value={selectedOption}
|
|
234
|
+
/>
|
|
235
|
+
</div>
|
|
236
|
+
)
|
|
237
|
+
},
|
|
238
|
+
) as <T>(
|
|
239
|
+
props: SelectProps<T> & {
|
|
240
|
+
ref?: React.ForwardedRef<
|
|
241
|
+
SelectInstance<Option<T>, false, GroupBase<Option<T>>>
|
|
242
|
+
>
|
|
243
|
+
},
|
|
244
|
+
) => JSX.Element
|
|
245
|
+
|
|
246
|
+
export default Select
|
|
247
|
+
|
|
248
|
+
export type { Option, SelectProps }
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Status } from 'lib/midi/export'
|
|
2
|
+
import { forwardRef } from 'react'
|
|
3
|
+
import type { GroupBase, SelectInstance } from 'react-select'
|
|
4
|
+
import Select from './Select'
|
|
5
|
+
import type { Option, SelectProps } from './Select'
|
|
6
|
+
|
|
7
|
+
type StatusPickerProps = SelectProps<Status> & { statuses: Option<Status>[] }
|
|
8
|
+
|
|
9
|
+
type StatusPickerRef = SelectInstance<
|
|
10
|
+
Option<Status>,
|
|
11
|
+
false,
|
|
12
|
+
GroupBase<Option<Status>>
|
|
13
|
+
>
|
|
14
|
+
|
|
15
|
+
const StatusPicker = forwardRef<
|
|
16
|
+
SelectInstance<Option<Status>, false, GroupBase<Option<Status>>>,
|
|
17
|
+
StatusPickerProps
|
|
18
|
+
>(({ statuses, ...rest }, ref) => (
|
|
19
|
+
<Select<Status>
|
|
20
|
+
{...rest}
|
|
21
|
+
options={statuses}
|
|
22
|
+
ref={ref}
|
|
23
|
+
/>
|
|
24
|
+
))
|
|
25
|
+
|
|
26
|
+
export default StatusPicker
|
|
27
|
+
|
|
28
|
+
export type { StatusPickerProps, StatusPickerRef }
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { forwardRef, useCallback, useMemo } from 'react'
|
|
2
|
+
import type { GroupBase, SelectInstance } from 'react-select'
|
|
3
|
+
import useStateWithDynamicDefault from '../hooks/useStateWithDynamicDefault'
|
|
4
|
+
import { arraySequence, assertRange } from '../utils'
|
|
5
|
+
import Select from './Select'
|
|
6
|
+
import type { Option, SelectProps } from './Select'
|
|
7
|
+
|
|
8
|
+
type ValuePickerProps = SelectProps<number> & {
|
|
9
|
+
highToLow?: boolean
|
|
10
|
+
max?: number
|
|
11
|
+
min?: number
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type ValuePickerRef = SelectInstance<
|
|
15
|
+
Option<number>,
|
|
16
|
+
false,
|
|
17
|
+
GroupBase<Option<number>>
|
|
18
|
+
>
|
|
19
|
+
|
|
20
|
+
const ValuePicker = forwardRef<
|
|
21
|
+
SelectInstance<Option<number>, false, GroupBase<Option<number>>>,
|
|
22
|
+
ValuePickerProps
|
|
23
|
+
>((props, ref) => {
|
|
24
|
+
const {
|
|
25
|
+
disabled,
|
|
26
|
+
highToLow,
|
|
27
|
+
max = 127,
|
|
28
|
+
min = 0,
|
|
29
|
+
onChange,
|
|
30
|
+
value: initialValue = 0,
|
|
31
|
+
...rest
|
|
32
|
+
} = props
|
|
33
|
+
const options = useMemo(() => {
|
|
34
|
+
const result = arraySequence(max - min + 1)
|
|
35
|
+
.map(i => min + i)
|
|
36
|
+
.map(value => ({ value, label: value }))
|
|
37
|
+
return (highToLow
|
|
38
|
+
? result.reverse()
|
|
39
|
+
: result) as unknown as Option<number>[]
|
|
40
|
+
}, [highToLow, max, min])
|
|
41
|
+
|
|
42
|
+
const [value, setValue] = useStateWithDynamicDefault(initialValue)
|
|
43
|
+
|
|
44
|
+
const handleChange = useCallback(
|
|
45
|
+
(v: number | string) => {
|
|
46
|
+
onChange(assertRange(v, max, min))
|
|
47
|
+
|
|
48
|
+
setValue(Number.parseInt(String(v), 10))
|
|
49
|
+
},
|
|
50
|
+
[max, min, onChange, setValue],
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<Select
|
|
55
|
+
{...rest}
|
|
56
|
+
disabled={disabled}
|
|
57
|
+
onChange={handleChange}
|
|
58
|
+
options={options}
|
|
59
|
+
ref={ref}
|
|
60
|
+
value={value}
|
|
61
|
+
/>
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
export default ValuePicker
|
|
66
|
+
|
|
67
|
+
export type { ValuePickerProps, ValuePickerRef }
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const knobSkin10 = {
|
|
2
|
+
knobX: 71.44,
|
|
3
|
+
knobY: 71.44,
|
|
4
|
+
svg: `
|
|
5
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="207px" height="207px" viewBox="0 0 207 207" version="1.1">
|
|
6
|
+
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
|
|
7
|
+
<desc>Created with Sketch.</desc>
|
|
8
|
+
<defs>
|
|
9
|
+
<linearGradient x1="50%" y1="50%" x2="50%" y2="100%" id="27c61b0f-392f-962d-de12-cb9da898274b">
|
|
10
|
+
<stop stop-color="#444040" stop-opacity="0.51098279" offset="0%"/>
|
|
11
|
+
<stop stop-color="#131111" stop-opacity="0.893200861" offset="100%"/>
|
|
12
|
+
</linearGradient>
|
|
13
|
+
<circle id="e966567b-3869-4bcd-76b6-2cf084e45390" cx="100.497487" cy="100.497487" r="99.4974874"/>
|
|
14
|
+
<filter x="-3.3%" y="-3.3%" width="106.5%" height="106.5%" filterUnits="objectBoundingBox" id="e2e6829f-0086-96b2-e92a-6f3809b8ac61">
|
|
15
|
+
<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"/>
|
|
16
|
+
<feOffset dx="0" dy="0" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/>
|
|
17
|
+
<feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"/>
|
|
18
|
+
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/>
|
|
19
|
+
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0" type="matrix" in="shadowBlurOuter1"/>
|
|
20
|
+
</filter>
|
|
21
|
+
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="0facd5c9-8e04-e83f-4842-8ba16f949942">
|
|
22
|
+
<stop stop-color="#FFFFFF" stop-opacity="0.5" offset="0%"/>
|
|
23
|
+
<stop stop-color="#000000" stop-opacity="0.5" offset="100%"/>
|
|
24
|
+
</linearGradient>
|
|
25
|
+
<circle id="c54189ed-7ea3-956c-f040-f0207548b268" cx="100.432161" cy="100.432161" r="86.4321608"/>
|
|
26
|
+
<filter x="-4.0%" y="-3.5%" width="108.1%" height="108.1%" filterUnits="objectBoundingBox" id="dedf2e7e-f008-c315-f682-e424d670f210">
|
|
27
|
+
<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"/>
|
|
28
|
+
<feOffset dx="0" dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/>
|
|
29
|
+
<feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"/>
|
|
30
|
+
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/>
|
|
31
|
+
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0" type="matrix" in="shadowBlurOuter1"/>
|
|
32
|
+
</filter>
|
|
33
|
+
|
|
34
|
+
<filter x="-5.3%" y="-11.3%" width="110.7%" height="122.6%" filterUnits="objectBoundingBox" id="12f618f7-e258-b597-3ed6-242484ddad8f">
|
|
35
|
+
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"/>
|
|
36
|
+
<feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"/>
|
|
37
|
+
<feColorMatrix values="0 0 0 0 0.915577168 0 0 0 0 0.797591325 0 0 0 0 0.601479722 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"/>
|
|
38
|
+
</filter>
|
|
39
|
+
<pattern id="3cc0e5b8-1f0a-886b-f635-8fcb19212870" width="8.04411765" height="8.04411765" x="21.9558824" y="21.9558824" patternUnits="userSpaceOnUse">
|
|
40
|
+
<use xlink:href="#2b8719c1-286b-ebf8-a488-ac66a6598fc5" transform="scale(0.167585784,0.167585784)"/>
|
|
41
|
+
</pattern>
|
|
42
|
+
<image id="2b8719c1-286b-ebf8-a488-ac66a6598fc5" width="48" height="48" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAEGWlDQ1BrQ0dDb2xvclNwYWNlR2VuZXJpY1JHQgAAOI2NVV1oHFUUPrtzZyMkzlNsNIV0qD8NJQ2TVjShtLp/3d02bpZJNtoi6GT27s6Yyc44M7v9oU9FUHwx6psUxL+3gCAo9Q/bPrQvlQol2tQgKD60+INQ6Ium65k7M5lpurHeZe58853vnnvuuWfvBei5qliWkRQBFpquLRcy4nOHj4g9K5CEh6AXBqFXUR0rXalMAjZPC3e1W99Dwntf2dXd/p+tt0YdFSBxH2Kz5qgLiI8B8KdVy3YBevqRHz/qWh72Yui3MUDEL3q44WPXw3M+fo1pZuQs4tOIBVVTaoiXEI/MxfhGDPsxsNZfoE1q66ro5aJim3XdoLFw72H+n23BaIXzbcOnz5mfPoTvYVz7KzUl5+FRxEuqkp9G/Ajia219thzg25abkRE/BpDc3pqvphHvRFys2weqvp+krbWKIX7nhDbzLOItiM8358pTwdirqpPFnMF2xLc1WvLyOwTAibpbmvHHcvttU57y5+XqNZrLe3lE/Pq8eUj2fXKfOe3pfOjzhJYtB/yll5SDFcSDiH+hRkH25+L+sdxKEAMZahrlSX8ukqMOWy/jXW2m6M9LDBc31B9LFuv6gVKg/0Szi3KAr1kGq1GMjU/aLbnq6/lRxc4XfJ98hTargX++DbMJBSiYMIe9Ck1YAxFkKEAG3xbYaKmDDgYyFK0UGYpfoWYXG+fAPPI6tJnNwb7ClP7IyF+D+bjOtCpkhz6CFrIa/I6sFtNl8auFXGMTP34sNwI/JhkgEtmDz14ySfaRcTIBInmKPE32kxyyE2Tv+thKbEVePDfW/byMM1Kmm0XdObS7oGD/MypMXFPXrCwOtoYjyyn7BV29/MZfsVzpLDdRtuIZnbpXzvlf+ev8MvYr/Gqk4H/kV/G3csdazLuyTMPsbFhzd1UabQbjFvDRmcWJxR3zcfHkVw9GfpbJmeev9F08WW8uDkaslwX6avlWGU6NRKz0g/SHtCy9J30o/ca9zX3Kfc19zn3BXQKRO8ud477hLnAfc1/G9mrzGlrfexZ5GLdn6ZZrrEohI2wVHhZywjbhUWEy8icMCGNCUdiBlq3r+xafL549HQ5jH+an+1y+LlYBifuxAvRN/lVVVOlwlCkdVm9NOL5BE4wkQ2SMlDZU97hX86EilU/lUmkQUztTE6mx1EEPh7OmdqBtAvv8HdWpbrJS6tJj3n0CWdM6busNzRV3S9KTYhqvNiqWmuroiKgYhshMjmhTh9ptWhsF7970j/SbMrsPE1suR5z7DMC+P/Hs+y7ijrQAlhyAgccjbhjPygfeBTjzhNqy28EdkUh8C+DU9+z2v/oyeH791OncxHOs5y2AtTc7nb/f73TWPkD/qwBnjX8BoJ98VQNcC+8AAAFFSURBVGgF7djbDYMwDAXQBjEMYqyqY1WMxTppLiJIQIA8ariWkp8IPuweO60am67r7MstY8wwjuPH7dMz3uUua63p+/7r9rePIRW/9QmQzCV9ub0YgSIgzhxvQkjFb1EZBAdEKolkfJTqtnb7bv/zOJm58moRE0AzYgFoRawAGhE7gDZEEKAJcQjQgjgFaEBcAtgRUQBmRDSAFZEEYEQkA9gQWQAmRDaABVEEYEAUAx5H4EaGOyw+SMl66mbXzNOD4k6gCPNUY/CFwF1YOn5zRxJJRINqaUbUuZA/79sd3wm3xIdbdS60rXzo2XVCbO60/HxKJgFKKv4CkEziuyKBWAE0InYAbYggQBPiEKAFcQrQgLgEsCOiAMyIaAArIgnAiEgGsCGyAEyIbAALogjAgCgGPI7AX9w6F3JtqHMhnMWLFSrSD9jOnakVHpZYAAAAAElFTkSuQmCC"/>
|
|
43
|
+
</defs>
|
|
44
|
+
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
45
|
+
<g id="s10" transform="translate(3.000000, 3.000000)">
|
|
46
|
+
<g id="container">
|
|
47
|
+
<g id="Oval-2">
|
|
48
|
+
<use fill="black" fill-opacity="1" filter="url(#e2e6829f-0086-96b2-e92a-6f3809b8ac61)" xlink:href="#e966567b-3869-4bcd-76b6-2cf084e45390"/>
|
|
49
|
+
<use stroke="#979797" stroke-width="1" fill="url(#27c61b0f-392f-962d-de12-cb9da898274b)" fill-rule="evenodd" xlink:href="#e966567b-3869-4bcd-76b6-2cf084e45390"/>
|
|
50
|
+
</g>
|
|
51
|
+
<g id="Oval-2">
|
|
52
|
+
<use fill="black" fill-opacity="1" filter="url(#dedf2e7e-f008-c315-f682-e424d670f210)" xlink:href="#c54189ed-7ea3-956c-f040-f0207548b268"/>
|
|
53
|
+
<use fill="" fill-rule="evenodd" xlink:href="#c54189ed-7ea3-956c-f040-f0207548b268"/>
|
|
54
|
+
<use stroke="#4A4A4A" stroke-width="1" fill="url(#0facd5c9-8e04-e83f-4842-8ba16f949942)" fill-rule="evenodd" xlink:href="#c54189ed-7ea3-956c-f040-f0207548b268"/>
|
|
55
|
+
</g>
|
|
56
|
+
<g id="knob" transform="translate(28.574244, 28.574244)">
|
|
57
|
+
<circle id="Oval-5" fill="#322E2E" cx="71.4356094" cy="71.4356094" r="71.4356094"/>
|
|
58
|
+
<path d="M72.4209282,3.63066376 L88.6786876,16.869789 C81.585496,18.1548295 76.1662428,18.7973498 72.4209282,18.7973498 C68.6756135,18.7973498 63.2563604,18.1548295 56.1631688,16.869789 L72.4209282,3.63066376 Z" id="Rectangle" fill="#E6D7D7" transform="translate(72.420928, 11.214007) scale(1, -1) translate(-72.420928, -11.214007) "/>
|
|
59
|
+
</g>
|
|
60
|
+
<g id="label">
|
|
61
|
+
<g id="labeltext" fill-opacity="1" fill="#E6D7D7">
|
|
62
|
+
<text id="534f4e02-5541-3607-0966-af0b025d80e0" font-family="Helvetica" font-size="44" font-weight="normal" fill="#E6D7D7" class="text-7" filter="url(#12f618f7-e258-b597-3ed6-242484ddad8f)">
|
|
63
|
+
<tspan x="45.3246625" y="117.884225">10.10</tspan>
|
|
64
|
+
</text>
|
|
65
|
+
<text id="92ebe866-c281-70c7-7b0e-a373cee013a9" font-family="Helvetica" font-size="44" font-weight="normal" fill="#E6D7D7" class="text-7">
|
|
66
|
+
<tspan x="45.3246625" y="117.884225">10.10</tspan>
|
|
67
|
+
</text>
|
|
68
|
+
</g>
|
|
69
|
+
<circle id="Oval-6" stroke="#979797" fill-opacity="0.730000019" fill="url(#3cc0e5b8-1f0a-886b-f635-8fcb19212870)" transform="translate(100.351759, 100.351759) rotate(-45.000000) translate(-100.351759, -100.351759) " cx="100.351759" cy="100.351759" r="70.3517588"/>
|
|
70
|
+
</g>
|
|
71
|
+
</g>
|
|
72
|
+
</g>
|
|
73
|
+
</g>
|
|
74
|
+
</svg>
|
|
75
|
+
`,
|
|
76
|
+
updateAttributes: [
|
|
77
|
+
{
|
|
78
|
+
element: '#labeltext text tspan',
|
|
79
|
+
content: (_props: React.CSSProperties, value: number) => value.toFixed(0),
|
|
80
|
+
attrs: [
|
|
81
|
+
{
|
|
82
|
+
name: 'text-anchor',
|
|
83
|
+
value: (/* props, value */) => 'middle',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'x',
|
|
87
|
+
value: (/* props, value */) => '100',
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default knobSkin10
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
type InternalInputProps = {
|
|
4
|
+
disabled?: boolean
|
|
5
|
+
min: number
|
|
6
|
+
max: number
|
|
7
|
+
value: number
|
|
8
|
+
step?: number
|
|
9
|
+
inputRef: React.RefObject<HTMLInputElement>
|
|
10
|
+
onChange: (val: number) => void
|
|
11
|
+
style?: React.CSSProperties
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
class InternalInput extends React.Component<InternalInputProps> {
|
|
15
|
+
static defaultProps = {
|
|
16
|
+
step: 1,
|
|
17
|
+
}
|
|
18
|
+
render() {
|
|
19
|
+
const props = this.props
|
|
20
|
+
const hideStyle = {}
|
|
21
|
+
|
|
22
|
+
function onValChange(event: React.ChangeEvent<HTMLInputElement>) {
|
|
23
|
+
props.onChange(Number(event.target.value))
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const { value, min, max, step, onChange, inputRef, ...rest } = props
|
|
27
|
+
return (
|
|
28
|
+
<input
|
|
29
|
+
ref={inputRef}
|
|
30
|
+
value={value}
|
|
31
|
+
step={step}
|
|
32
|
+
onChange={onValChange}
|
|
33
|
+
style={hideStyle}
|
|
34
|
+
type="range"
|
|
35
|
+
min={min}
|
|
36
|
+
max={max}
|
|
37
|
+
{...rest}
|
|
38
|
+
/>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default InternalInput
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Draws a circle with radius = r
|
|
5
|
+
* position must be handled by parent
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
type DrawCircleProps = React.SVGProps<SVGCircleElement> & {
|
|
9
|
+
r: number
|
|
10
|
+
borderColor?: string
|
|
11
|
+
fillColor?: string
|
|
12
|
+
borderWidth?: number
|
|
13
|
+
fillOpacity: number
|
|
14
|
+
cx: number
|
|
15
|
+
cy: number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class DrawCircle extends React.Component<DrawCircleProps> {
|
|
19
|
+
render() {
|
|
20
|
+
const {
|
|
21
|
+
r,
|
|
22
|
+
borderColor = 'black',
|
|
23
|
+
fillColor = 'transparent',
|
|
24
|
+
borderWidth = 2,
|
|
25
|
+
fillOpacity = 1,
|
|
26
|
+
...rest
|
|
27
|
+
} = this.props
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<circle
|
|
31
|
+
stroke={borderColor}
|
|
32
|
+
fill={fillColor}
|
|
33
|
+
fillOpacity={fillOpacity}
|
|
34
|
+
r={r}
|
|
35
|
+
{...rest}
|
|
36
|
+
/>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export default DrawCircle
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { Point } from '../Types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Draws a line from p1 to p2
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
type DrawLineProps = React.SVGProps<SVGLineElement> & {
|
|
9
|
+
width?: number
|
|
10
|
+
color?: string
|
|
11
|
+
p1: Point
|
|
12
|
+
p2: Point
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class DrawLine extends React.Component<DrawLineProps> {
|
|
16
|
+
render() {
|
|
17
|
+
const { width = 2, color = 'black', p1, p2, ...rest } = this.props
|
|
18
|
+
return (
|
|
19
|
+
<line
|
|
20
|
+
{...rest}
|
|
21
|
+
stroke={color}
|
|
22
|
+
strokeWidth={width}
|
|
23
|
+
x1={p1.x}
|
|
24
|
+
y1={p1.y}
|
|
25
|
+
x2={p2.x}
|
|
26
|
+
y2={p2.y}
|
|
27
|
+
/>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default DrawLine
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import ReactDOM from 'react-dom'
|
|
3
|
+
|
|
4
|
+
type HelpersOverlayProps = React.PropsWithChildren & {
|
|
5
|
+
overlayStyle?: React.CSSProperties
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Draws the overlay and the children
|
|
10
|
+
*/
|
|
11
|
+
class HelpersOverlay extends React.Component<HelpersOverlayProps> {
|
|
12
|
+
render() {
|
|
13
|
+
const { children, ...rest } = this.props
|
|
14
|
+
|
|
15
|
+
const styles = {
|
|
16
|
+
overlay: Object.assign(
|
|
17
|
+
{
|
|
18
|
+
width: '100%',
|
|
19
|
+
height: '100vh',
|
|
20
|
+
top: 0,
|
|
21
|
+
left: 0,
|
|
22
|
+
zIndex: 2147483647,
|
|
23
|
+
margin: '0',
|
|
24
|
+
padding: '0',
|
|
25
|
+
boxSizing: 'border-box',
|
|
26
|
+
position: 'fixed',
|
|
27
|
+
},
|
|
28
|
+
this.props.overlayStyle,
|
|
29
|
+
),
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return ReactDOM.createPortal(
|
|
33
|
+
<div
|
|
34
|
+
style={styles.overlay}
|
|
35
|
+
{...rest}>
|
|
36
|
+
{children}
|
|
37
|
+
</div>,
|
|
38
|
+
document.body,
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default HelpersOverlay
|