zds-pickers 4.0.5 → 4.0.7
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.cjs.js +13 -12
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.es.js +638 -644
- package/dist/index.es.js.map +1 -0
- package/dist/types/index.d.ts +34 -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/index.ts +51 -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.json +34 -0
- package/vite.config.ts +48 -0
- package/dist/index.d.ts +0 -244
- package/dist/types/main.d.ts +0 -19
package/lib/utils.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// this just creates and fills a zero-indexed array array; 0, 1, 2, 3, etc
|
|
2
|
+
const arraySequence = (numberOfElements: number) =>
|
|
3
|
+
Array.from(new Array(numberOfElements).keys())
|
|
4
|
+
|
|
5
|
+
const assertRange = (value: number | string, max = 127, min = 0) => {
|
|
6
|
+
let result: number =
|
|
7
|
+
typeof value === 'string' ? Number.parseInt(value, 10) : value
|
|
8
|
+
|
|
9
|
+
if (Number.isNaN(result) || result === null) {
|
|
10
|
+
result = min
|
|
11
|
+
}
|
|
12
|
+
return result >= min ? (result <= max ? result : max) : min
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const findObj =
|
|
16
|
+
<T>(key: keyof T, value: T[keyof T]) =>
|
|
17
|
+
(arr: T[]) =>
|
|
18
|
+
arr?.find(item => item?.[key] === value)
|
|
19
|
+
|
|
20
|
+
const omit =
|
|
21
|
+
<T extends Record<string, unknown>>(...keys: string[]) =>
|
|
22
|
+
(obj: T) =>
|
|
23
|
+
Object.entries(obj)
|
|
24
|
+
.filter(([key]) => !keys.flat().map(String).includes(key))
|
|
25
|
+
.reduce((_obj, [key, val]) => Object.assign(_obj, { [key]: val }), {})
|
|
26
|
+
|
|
27
|
+
const pick =
|
|
28
|
+
<T extends object>(...keys: (keyof T)[]) =>
|
|
29
|
+
(obj: T) =>
|
|
30
|
+
Object.entries(obj)
|
|
31
|
+
.filter(([key]) => keys.flat().map(String).includes(key))
|
|
32
|
+
.reduce((_obj, [key, val]) => Object.assign(_obj, { [key]: val }), {})
|
|
33
|
+
|
|
34
|
+
const set =
|
|
35
|
+
<T>(key: keyof T, value: T[keyof T]) =>
|
|
36
|
+
(obj: T) => ({
|
|
37
|
+
...obj,
|
|
38
|
+
[key]: value,
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
export { arraySequence, assertRange, findObj, omit, pick, set }
|
package/package.json
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zds-pickers",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.7",
|
|
4
4
|
"main": "./dist/index.cjs.js",
|
|
5
5
|
"module": "./dist/index.es.js",
|
|
6
|
-
"types": "dist/types/index.d.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"dist",
|
|
9
|
-
"dist/types"
|
|
10
|
-
],
|
|
6
|
+
"types": "./dist/types/index.d.ts",
|
|
11
7
|
"exports": {
|
|
12
8
|
".": {
|
|
13
9
|
"types": "./dist/types/index.d.ts",
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
@import url('https://fonts.googleapis.com/css2?family=Open+Sans&display=swap');
|
|
2
|
+
|
|
3
|
+
body {
|
|
4
|
+
background: #333;
|
|
5
|
+
font-family: 'Open Sans', sans-serif;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
body .zds-pickers__label {
|
|
9
|
+
color: #fff;
|
|
10
|
+
min-width: 100px;
|
|
11
|
+
height: 100%;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
body .zds-pickers__container > span,
|
|
15
|
+
body .zds-pickers__container > div {
|
|
16
|
+
display: inline-block;
|
|
17
|
+
margin-bottom: 3px;
|
|
18
|
+
}
|
|
19
|
+
/* body .zds-pickers__container > span { max-width: 100px; } */
|
|
20
|
+
body .zds-pickers__container > div { min-width: 300px; }
|
|
21
|
+
|
|
22
|
+
body .zds-pickers__input { color: #fff; }
|
|
23
|
+
|
|
24
|
+
body .zds-pickers__control {
|
|
25
|
+
background: #222;
|
|
26
|
+
min-width: 120px;
|
|
27
|
+
min-height: 20px;
|
|
28
|
+
border-color: #4b4a4b;
|
|
29
|
+
}
|
|
30
|
+
body .zds-pickers__control div[class$="singleValue"] { color: #fff; }
|
|
31
|
+
body .zds-pickers__control .zds-pickers__indicator-separator { display: none; }
|
|
32
|
+
body .zds-pickers__control .zds-pickers__dropdown-indicator { padding: 0 4px; }
|
|
33
|
+
body .zds-pickers--is-disabled,
|
|
34
|
+
body .zds-pickers__single-value--is-disabled,
|
|
35
|
+
body .zds-pickers--is-disabled input,
|
|
36
|
+
body .zds-pickers--is-disabled div[class$="singleValue"],
|
|
37
|
+
body .zds-pickers--is-disabled .zds-pickers__dropdown-indicator {
|
|
38
|
+
font-style: italic !important;
|
|
39
|
+
color: grey !important;
|
|
40
|
+
text-shadow: none !important;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
body .zds-pickers__placeholder {color: grey}
|
|
44
|
+
body .zds-pickers__placeholder.shrunk {color: #fff}
|
|
45
|
+
|
|
46
|
+
body .zds-pickers__menu { color: #4b4a4b; }
|
|
47
|
+
/* .zds-pickers__menu .zds-pickers__menu-list { }
|
|
48
|
+
.zds-pickers__menu .zds-pickers__option{ } */
|
|
49
|
+
|
|
50
|
+
body .channel-picker .zds-pickers__menu {
|
|
51
|
+
width: 160px;
|
|
52
|
+
min-width: 160px;
|
|
53
|
+
max-width: 160px;
|
|
54
|
+
margin: 0;
|
|
55
|
+
}
|
|
56
|
+
body .channel-picker .zds-pickers__menu .zds-pickers__menu-list {
|
|
57
|
+
display: flex;
|
|
58
|
+
flex-flow: row wrap;
|
|
59
|
+
padding: 0;
|
|
60
|
+
}
|
|
61
|
+
body .channel-picker .zds-pickers__menu .zds-pickers__option {
|
|
62
|
+
width: 40px;
|
|
63
|
+
min-width: 40px;
|
|
64
|
+
max-width: 40px;
|
|
65
|
+
padding: 0;
|
|
66
|
+
border: 1px solid #e1e1e1;
|
|
67
|
+
text-align: center;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
body .channel-mapping-picker .empty-mapping-entry .mapping-entry-label {
|
|
71
|
+
font-style: italic;
|
|
72
|
+
color: grey;
|
|
73
|
+
}
|
|
74
|
+
body .channel-mapping-picker .mapping-entry b {
|
|
75
|
+
display: inline-block;
|
|
76
|
+
width: 25px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
body .value-picker__label {
|
|
80
|
+
position: relative;
|
|
81
|
+
top: -12px;
|
|
82
|
+
}
|
|
83
|
+
body .value-picker .zds-pickers__control {
|
|
84
|
+
border-radius: 4px;
|
|
85
|
+
border-style: solid;
|
|
86
|
+
border-width: 1px;
|
|
87
|
+
box-sizing: border-box;
|
|
88
|
+
}
|
|
89
|
+
body .value-picker .zds-pickers__control:hover {
|
|
90
|
+
border-color: #e1e1e1;
|
|
91
|
+
}
|
|
92
|
+
body .value-picker .zds-pickers__control:focus-within {
|
|
93
|
+
border-color: #2684ff;
|
|
94
|
+
}
|
|
95
|
+
body .value-picker .zds-pickers__control:focus-within:hover {
|
|
96
|
+
border-color: #2684ff;
|
|
97
|
+
/* border-width: 2px; */
|
|
98
|
+
}
|
|
99
|
+
body .value-picker .zds-pickers__value-container {
|
|
100
|
+
height: 36px;
|
|
101
|
+
}
|
|
102
|
+
body .value-picker .zds-pickers__value-container .react-numeric-input {
|
|
103
|
+
position: absolute !important;
|
|
104
|
+
right: 0;
|
|
105
|
+
left: 0;
|
|
106
|
+
}
|
|
107
|
+
body .value-picker .zds-pickers__value-container .react-numeric-input input {
|
|
108
|
+
border: unset !important;
|
|
109
|
+
color: #fff;
|
|
110
|
+
height: 36px;
|
|
111
|
+
background-color: inherit;
|
|
112
|
+
outline: none;
|
|
113
|
+
padding-left: 10px !important;
|
|
114
|
+
width: 100% !important;
|
|
115
|
+
}
|
|
116
|
+
body .value-picker .zds-pickers__value-container .react-numeric-input b:nth-of-type(1) i {
|
|
117
|
+
border-color: transparent transparent #fff !important;
|
|
118
|
+
}
|
|
119
|
+
body .value-picker .zds-pickers__value-container .react-numeric-input b:nth-of-type(2) i {
|
|
120
|
+
border-color: #fff transparent transparent !important;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
body .response-curve-picker rect.container { fill: #e6e6e8 }
|
|
124
|
+
body .response-curve-picker text.axis {
|
|
125
|
+
font-size: 10pt;
|
|
126
|
+
font-style: italic;
|
|
127
|
+
fill: #12131b;
|
|
128
|
+
}
|
|
129
|
+
body .response-curve-picker line.axis { stroke: #12131b }
|
|
130
|
+
body .response-curve-picker path.curve {
|
|
131
|
+
stroke: #4d505b;
|
|
132
|
+
stroke-dasharray: 8;
|
|
133
|
+
fill: transparent;
|
|
134
|
+
pointer-events: visibleStroke;
|
|
135
|
+
}
|
|
136
|
+
body .response-curve-picker path.curve-selected {
|
|
137
|
+
stroke: #222;
|
|
138
|
+
stroke-dasharray: 0;
|
|
139
|
+
fill: transparent;
|
|
140
|
+
}
|
|
141
|
+
body .response-curve-picker rect.button {
|
|
142
|
+
fill: #ddd;
|
|
143
|
+
stroke: #4d505b;
|
|
144
|
+
cursor: pointer;
|
|
145
|
+
}
|
|
146
|
+
body .response-curve-picker rect.button:hover {
|
|
147
|
+
fill: #666;
|
|
148
|
+
stroke: #222;
|
|
149
|
+
}
|
|
150
|
+
body .response-curve-picker rect.button-selected { fill: #222 }
|
|
151
|
+
body .response-curve-picker text.button {
|
|
152
|
+
font-size: 8pt;
|
|
153
|
+
pointer-events: none;
|
|
154
|
+
}
|
|
155
|
+
body .response-curve-picker text.button-selected {
|
|
156
|
+
font-size: 8pt;
|
|
157
|
+
fill: white;
|
|
158
|
+
font-weight: bold;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* **************************************************************** */
|
|
162
|
+
|
|
163
|
+
.Knob {
|
|
164
|
+
background: #eee;
|
|
165
|
+
border-radius: 50%;
|
|
166
|
+
display: flex;
|
|
167
|
+
justify-content: center;
|
|
168
|
+
align-items: center;
|
|
169
|
+
position: relative;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.Knob-label {
|
|
173
|
+
flex: none;
|
|
174
|
+
width: 100%;
|
|
175
|
+
height: 100%;
|
|
176
|
+
z-index: 2;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.Knob-value {
|
|
180
|
+
width: 100%;
|
|
181
|
+
height: 100%;
|
|
182
|
+
background: transparent;
|
|
183
|
+
border: none;
|
|
184
|
+
text-align: center;
|
|
185
|
+
position: relative;
|
|
186
|
+
left: -1px;
|
|
187
|
+
}
|
|
188
|
+
.Knob-value.no-label::selection {
|
|
189
|
+
background: transparent;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.Knob-value::-webkit-inner-spin-button,
|
|
193
|
+
.Knob-value::-webkit-outer-spin-button {
|
|
194
|
+
-webkit-appearance: none;
|
|
195
|
+
margin: 0;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.Knob-spinner {
|
|
199
|
+
display: flex;
|
|
200
|
+
position: absolute;
|
|
201
|
+
width: 100%;
|
|
202
|
+
height: 100%;
|
|
203
|
+
top: 0;
|
|
204
|
+
right: 0;
|
|
205
|
+
bottom: 0;
|
|
206
|
+
left: 0;
|
|
207
|
+
background: rgb(243, 243, 243);
|
|
208
|
+
border: 1px solid rgb(232, 232, 232);
|
|
209
|
+
border-radius: 50%;
|
|
210
|
+
z-index: 1;
|
|
211
|
+
align-items: center;
|
|
212
|
+
justify-content: flex-start;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.Knob-spinner::before {
|
|
216
|
+
content: "";
|
|
217
|
+
width: 4px;
|
|
218
|
+
height: 4px;
|
|
219
|
+
margin: 4px;
|
|
220
|
+
border-radius: 50%;
|
|
221
|
+
background: #000;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* ************************************************************************** */
|
|
225
|
+
|
|
226
|
+
.ReactPiano__Keyboard {
|
|
227
|
+
/* Used for absolute positioning of .ReactPiano__Key--accidental elements */
|
|
228
|
+
position: relative;
|
|
229
|
+
/* Used to lay out .ReactPiano__Key--natural elements */
|
|
230
|
+
display: flex;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.ReactPiano__Key {
|
|
234
|
+
/* Used for flexbox layout of the child .ReactPiano__NoteLabelContainer elements */
|
|
235
|
+
display: flex;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/*
|
|
239
|
+
* Styles of accidental notes (flat or sharp)
|
|
240
|
+
*/
|
|
241
|
+
.ReactPiano__Key--accidental {
|
|
242
|
+
background: #000;
|
|
243
|
+
/* border: 1px solid #fff; */
|
|
244
|
+
/* border-top: 1px solid transparent; */
|
|
245
|
+
border-radius: 0 0 4px 4px;
|
|
246
|
+
cursor: pointer;
|
|
247
|
+
height: 66%;
|
|
248
|
+
/* Overlay on top of natural keys */
|
|
249
|
+
z-index: 1;
|
|
250
|
+
/* Use absolute positioning along with inline styles specified in JS to put keys in correct locations. */
|
|
251
|
+
position: absolute;
|
|
252
|
+
top: 0;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/*
|
|
256
|
+
* Styles of natural notes (white keys)
|
|
257
|
+
*/
|
|
258
|
+
.ReactPiano__Key--natural {
|
|
259
|
+
background: #f6f5f3;
|
|
260
|
+
border: 1px solid #000;
|
|
261
|
+
border-radius: 0 0 3px 3px;
|
|
262
|
+
cursor: pointer;
|
|
263
|
+
z-index: 0;
|
|
264
|
+
/*
|
|
265
|
+
* Uses flexbox with margin instead of absolute positioning to have more consistent margin rendering.
|
|
266
|
+
* This causes inline styles to be ignored.
|
|
267
|
+
*/
|
|
268
|
+
flex: 1;
|
|
269
|
+
/* margin-right: 1px; */
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.ReactPiano__Key--natural:last-child {
|
|
273
|
+
/* Don't render extra margin on the last natural note */
|
|
274
|
+
margin-right: 0;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/*
|
|
278
|
+
* Styles of "active" or pressed-down keys
|
|
279
|
+
*/
|
|
280
|
+
.ReactPiano__Key--active {
|
|
281
|
+
background: #3ac8da;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.ReactPiano__Key--active.ReactPiano__Key--accidental {
|
|
285
|
+
/* border: 1px solid #fff; */
|
|
286
|
+
border-top: 1px solid #3ac8da;
|
|
287
|
+
/* Slight height reduction for "pushed-down" effect */
|
|
288
|
+
height: 65%;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.ReactPiano__Key--active.ReactPiano__Key--natural {
|
|
292
|
+
border: 1px solid #3ac8da;
|
|
293
|
+
/* Slight height reduction for "pushed-down" effect */
|
|
294
|
+
height: 98%;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.ReactPiano__Key--middleC > div::before {
|
|
298
|
+
content: "◆";
|
|
299
|
+
position: absolute;
|
|
300
|
+
top: 30%;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/*
|
|
304
|
+
* Styles for disabled state
|
|
305
|
+
*/
|
|
306
|
+
.ReactPiano__Key--disabled.ReactPiano__Key--accidental {
|
|
307
|
+
background: #ddd;
|
|
308
|
+
border: 1px solid #999;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.ReactPiano__Key--disabled.ReactPiano__Key--natural {
|
|
312
|
+
background: #eee;
|
|
313
|
+
border: 1px solid #aaa;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/*
|
|
317
|
+
* Styles for the note label inside a piano key
|
|
318
|
+
*/
|
|
319
|
+
.ReactPiano__NoteLabelContainer {
|
|
320
|
+
flex: 1;
|
|
321
|
+
/* Align children .ReactPiano__NoteLabel to the bottom of the key */
|
|
322
|
+
align-self: flex-end;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.ReactPiano__NoteLabel {
|
|
326
|
+
font-size: 12px;
|
|
327
|
+
text-align: center;
|
|
328
|
+
text-transform: capitalize;
|
|
329
|
+
/* Disable text selection */
|
|
330
|
+
-webkit-user-select: none;
|
|
331
|
+
-moz-user-select: none;
|
|
332
|
+
-ms-user-select: none;
|
|
333
|
+
user-select: none;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.ReactPiano__NoteLabel--accidental {
|
|
337
|
+
color: #f8e8d5;
|
|
338
|
+
margin-bottom: 3px;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.ReactPiano__NoteLabel--natural {
|
|
342
|
+
color: #888;
|
|
343
|
+
margin-bottom: 3px;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.ReactPiano__NoteLabel--natural.ReactPiano__NoteLabel--active {
|
|
347
|
+
color: #f8e8d5;
|
|
348
|
+
}
|
|
349
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/* ---------------------------- Arrays -------------------------------------- */
|
|
2
|
+
|
|
3
|
+
// this just creates and fills a zero-indexed array array; 0, 1, 2, 3, etc
|
|
4
|
+
export const arraySequence = numberOfElements =>
|
|
5
|
+
Array.from(new Array(numberOfElements).keys())
|
|
6
|
+
|
|
7
|
+
export default arraySequence
|