@tremolo-ui/svelte 0.7.0 → 0.9.0
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/actions/drag-value.d.ts.map +1 -1
- package/dist/actions/drag-value.js +2 -1
- package/dist/actions/drag.d.ts.map +1 -1
- package/dist/actions/drag.js +2 -1
- package/dist/actions/drop-zone.d.ts.map +1 -1
- package/dist/actions/drop-zone.js +2 -1
- package/dist/actions/long-press.d.ts.map +1 -1
- package/dist/actions/long-press.js +2 -1
- package/dist/actions/wheel.d.ts +1 -4
- package/dist/actions/wheel.d.ts.map +1 -1
- package/dist/actions/wheel.js +3 -14
- package/dist/components/AnimationCanvas/types.d.ts +4 -11
- package/dist/components/AnimationCanvas/types.d.ts.map +1 -1
- package/dist/components/FileInput/Root.svelte +1 -1
- package/dist/components/Knob/Root.svelte +31 -10
- package/dist/components/Knob/Root.svelte.d.ts.map +1 -1
- package/dist/components/Knob/Thumb.svelte +11 -11
- package/dist/components/Knob/types.d.ts +30 -19
- package/dist/components/Knob/types.d.ts.map +1 -1
- package/dist/components/NumberInput/InputField.svelte +4 -2
- package/dist/components/NumberInput/InputField.svelte.d.ts.map +1 -1
- package/dist/components/NumberInput/Root.svelte +55 -5
- package/dist/components/NumberInput/Root.svelte.d.ts.map +1 -1
- package/dist/components/NumberInput/Stepper.svelte +27 -4
- package/dist/components/NumberInput/Stepper.svelte.d.ts.map +1 -1
- package/dist/components/NumberInput/StepperButton.svelte +9 -1
- package/dist/components/NumberInput/StepperButton.svelte.d.ts.map +1 -1
- package/dist/components/NumberInput/context.d.ts +10 -0
- package/dist/components/NumberInput/context.d.ts.map +1 -1
- package/dist/components/NumberInput/context.js +3 -0
- package/dist/components/NumberInput/types.d.ts +25 -1
- package/dist/components/NumberInput/types.d.ts.map +1 -1
- package/dist/components/Piano/Root.svelte +6 -4
- package/dist/components/Piano/Root.svelte.d.ts.map +1 -1
- package/dist/components/PointsEditor/Container.svelte +2 -6
- package/dist/components/PointsEditor/Container.svelte.d.ts.map +1 -1
- package/dist/components/PointsEditor/Point.svelte +24 -10
- package/dist/components/PointsEditor/Point.svelte.d.ts.map +1 -1
- package/dist/components/PointsEditor/Root.svelte +7 -5
- package/dist/components/PointsEditor/Root.svelte.d.ts.map +1 -1
- package/dist/components/PointsEditor/context.d.ts +1 -1
- package/dist/components/PointsEditor/context.d.ts.map +1 -1
- package/dist/components/PointsEditor/types.d.ts +21 -7
- package/dist/components/PointsEditor/types.d.ts.map +1 -1
- package/dist/components/Slider/Marks.svelte +5 -3
- package/dist/components/Slider/Marks.svelte.d.ts.map +1 -1
- package/dist/components/Slider/MarksOption.svelte +7 -6
- package/dist/components/Slider/MarksOption.svelte.d.ts.map +1 -1
- package/dist/components/Slider/Root.svelte +30 -17
- package/dist/components/Slider/Root.svelte.d.ts.map +1 -1
- package/dist/components/Slider/Thumb.svelte +3 -3
- package/dist/components/Slider/Track.svelte +9 -7
- package/dist/components/Slider/Track.svelte.d.ts.map +1 -1
- package/dist/components/Slider/context.d.ts +1 -1
- package/dist/components/Slider/context.d.ts.map +1 -1
- package/dist/components/Slider/types.d.ts +30 -17
- package/dist/components/Slider/types.d.ts.map +1 -1
- package/dist/components/XYPad/Root.svelte +30 -16
- package/dist/components/XYPad/Root.svelte.d.ts.map +1 -1
- package/dist/components/XYPad/Thumb.svelte +1 -1
- package/dist/components/XYPad/types.d.ts +21 -7
- package/dist/components/XYPad/types.d.ts.map +1 -1
- package/dist/components/_util/change-gesture.svelte.d.ts +18 -0
- package/dist/components/_util/change-gesture.svelte.d.ts.map +1 -0
- package/dist/components/_util/change-gesture.svelte.js +26 -0
- package/dist/components/_util/check-steps.svelte.d.ts +1 -1
- package/dist/components/_util/check-steps.svelte.d.ts.map +1 -1
- package/dist/components/_util/check-steps.svelte.js +1 -1
- package/dist/components/_util/style.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/package.json +9 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drag-value.d.ts","sourceRoot":"","sources":["../../src/actions/drag-value.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"drag-value.d.ts","sourceRoot":"","sources":["../../src/actions/drag-value.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAGxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE3C;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,gBAAgB,CAUvD,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { createDragValue
|
|
1
|
+
import { createDragValue } from '@tremolo-ui/dom';
|
|
2
|
+
import { replaceOptions } from '@tremolo-ui/dom/internal';
|
|
2
3
|
/**
|
|
3
4
|
* Drive a value with a pointer drag. See `createDragValue` in
|
|
4
5
|
* `@tremolo-ui/dom` for the options; `elementMapping` and `relativeMapping`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drag.d.ts","sourceRoot":"","sources":["../../src/actions/drag.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"drag.d.ts","sourceRoot":"","sources":["../../src/actions/drag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAG9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE3C;;;;;;;;;GASG;AACH,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,CAazD,CAAA"}
|
package/dist/actions/drag.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { createDrag
|
|
1
|
+
import { createDrag } from '@tremolo-ui/dom';
|
|
2
|
+
import { replaceOptions } from '@tremolo-ui/dom/internal';
|
|
2
3
|
/**
|
|
3
4
|
* Track a pointer drag on the element. See `createDrag` in `@tremolo-ui/dom`
|
|
4
5
|
* for the options.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drop-zone.d.ts","sourceRoot":"","sources":["../../src/actions/drop-zone.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"drop-zone.d.ts","sourceRoot":"","sources":["../../src/actions/drop-zone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAGtE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE3C;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,eAAe,GAAG,SAAS,CAajE,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { createDropZone
|
|
1
|
+
import { createDropZone } from '@tremolo-ui/dom';
|
|
2
|
+
import { replaceOptions } from '@tremolo-ui/dom/internal';
|
|
2
3
|
/**
|
|
3
4
|
* Take files dropped on the element. See `createDropZone` in
|
|
4
5
|
* `@tremolo-ui/dom` for the options; `onStateChange` reports whether files
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"long-press.d.ts","sourceRoot":"","sources":["../../src/actions/long-press.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"long-press.d.ts","sourceRoot":"","sources":["../../src/actions/long-press.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAGxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE3C;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAkB3D,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { createLongPress
|
|
1
|
+
import { createLongPress } from '@tremolo-ui/dom';
|
|
2
|
+
import { replaceOptions } from '@tremolo-ui/dom/internal';
|
|
2
3
|
/**
|
|
3
4
|
* Repeat `onPress` while the element is held down: once on the press, then
|
|
4
5
|
* every `interval` after `delay`. See `createLongPress` in `@tremolo-ui/dom`.
|
package/dist/actions/wheel.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { type WheelOptions } from '@tremolo-ui/dom';
|
|
2
2
|
import type { Action } from 'svelte/action';
|
|
3
|
-
export interface WheelActionOptions extends WheelOptions {
|
|
4
|
-
onWheel: (event: WheelEvent) => void;
|
|
5
|
-
}
|
|
6
3
|
/**
|
|
7
4
|
* Listen to the wheel on the element, as a non-passive listener so that
|
|
8
5
|
* `preventDefault()` can keep the page from scrolling. See `createWheel` in
|
|
@@ -11,5 +8,5 @@ export interface WheelActionOptions extends WheelOptions {
|
|
|
11
8
|
* @example
|
|
12
9
|
* <div use:wheel={{ onWheel: (e) => { e.preventDefault(); … }, requireFocus: true }}></div>
|
|
13
10
|
*/
|
|
14
|
-
export declare const wheel: Action<Element,
|
|
11
|
+
export declare const wheel: Action<Element, WheelOptions>;
|
|
15
12
|
//# sourceMappingURL=wheel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wheel.d.ts","sourceRoot":"","sources":["../../src/actions/wheel.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"wheel.d.ts","sourceRoot":"","sources":["../../src/actions/wheel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAGhE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE3C;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,YAAY,CAU/C,CAAA"}
|
package/dist/actions/wheel.js
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
-
t[p] = s[p];
|
|
5
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
-
t[p[i]] = s[p[i]];
|
|
9
|
-
}
|
|
10
|
-
return t;
|
|
11
|
-
};
|
|
12
|
-
import { createWheel, replaceOptions } from '@tremolo-ui/dom';
|
|
1
|
+
import { createWheel } from '@tremolo-ui/dom';
|
|
2
|
+
import { replaceOptions } from '@tremolo-ui/dom/internal';
|
|
13
3
|
/**
|
|
14
4
|
* Listen to the wheel on the element, as a non-passive listener so that
|
|
15
5
|
* `preventDefault()` can keep the page from scrolling. See `createWheel` in
|
|
@@ -19,8 +9,7 @@ import { createWheel, replaceOptions } from '@tremolo-ui/dom';
|
|
|
19
9
|
* <div use:wheel={{ onWheel: (e) => { e.preventDefault(); … }, requireFocus: true }}></div>
|
|
20
10
|
*/
|
|
21
11
|
export const wheel = (node, options) => {
|
|
22
|
-
const
|
|
23
|
-
const instance = createWheel(node, onWheel, rest);
|
|
12
|
+
const instance = createWheel(node, options);
|
|
24
13
|
let current = options;
|
|
25
14
|
return {
|
|
26
15
|
update: (next) => {
|
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
/** Called once the canvas is ready, and again whenever it is resized. */
|
|
3
|
-
export type InitFunction = (context: CanvasRenderingContext2D, size: {
|
|
4
|
-
width: number;
|
|
5
|
-
height: number;
|
|
6
|
-
}) => void;
|
|
7
|
-
/** Called on every frame while `animate` is on, and once otherwise. */
|
|
8
|
-
export type DrawFunction = (context: CanvasRenderingContext2D, frame: AnimationFrame) => void;
|
|
1
|
+
import type { CanvasDrawFunction, CanvasInitFunction } from '@tremolo-ui/dom';
|
|
9
2
|
export interface AnimationCanvasProps {
|
|
10
3
|
/** Draws a frame. */
|
|
11
|
-
draw:
|
|
12
|
-
/** Sets the canvas up before the first frame
|
|
13
|
-
init?:
|
|
4
|
+
draw: CanvasDrawFunction;
|
|
5
|
+
/** Sets the canvas up, once, before the first frame. */
|
|
6
|
+
init?: CanvasInitFunction;
|
|
14
7
|
/**
|
|
15
8
|
* Draw on every animation frame. Off, `draw` runs once and again after a
|
|
16
9
|
* resize.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/AnimationCanvas/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/AnimationCanvas/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAE7E,MAAM,WAAW,oBAAoB;IACnC,qBAAqB;IACrB,IAAI,EAAE,kBAAkB,CAAA;IACxB,wDAAwD;IACxD,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,gCAAgC,CAAA;IAC1C;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,yCAAyC;IACzC,GAAG,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAA;CAC/B"}
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import {
|
|
3
|
-
applyDelta,
|
|
4
|
-
arrowKeyDirection,
|
|
5
|
-
cssLength,
|
|
6
3
|
DEFAULT_DRAG_SENSITIVITY,
|
|
7
4
|
DEFAULT_KEYBOARD_OPTIONS,
|
|
8
5
|
DEFAULT_WHEEL_OPTIONS,
|
|
9
6
|
knobAngles,
|
|
10
7
|
relativeMapping,
|
|
11
|
-
selectModifier,
|
|
12
|
-
wheelDirection,
|
|
13
8
|
type AxisOptions,
|
|
14
9
|
type XY,
|
|
15
10
|
} from '@tremolo-ui/dom'
|
|
11
|
+
import {
|
|
12
|
+
applyDelta,
|
|
13
|
+
arrowKeyDirection,
|
|
14
|
+
cssLength,
|
|
15
|
+
selectModifier,
|
|
16
|
+
wheelDirection,
|
|
17
|
+
} from '@tremolo-ui/dom/internal'
|
|
16
18
|
import { linearScale, type ValueRange } from '@tremolo-ui/functions'
|
|
17
19
|
|
|
18
20
|
import { dragValue } from '../../actions/drag-value.js'
|
|
19
21
|
import { wheel as wheelAction } from '../../actions/wheel.js'
|
|
22
|
+
import { useChangeGesture } from '../_util/change-gesture.svelte.js'
|
|
20
23
|
import { useCheckSteps } from '../_util/check-steps.svelte.js'
|
|
21
24
|
|
|
22
25
|
import { setKnobContext } from './context.js'
|
|
@@ -32,19 +35,21 @@
|
|
|
32
35
|
max,
|
|
33
36
|
step = 1,
|
|
34
37
|
scale = linearScale,
|
|
35
|
-
|
|
38
|
+
resetValue,
|
|
36
39
|
startValue,
|
|
37
40
|
size,
|
|
38
|
-
|
|
41
|
+
dragCursor = 'grabbing',
|
|
39
42
|
wheel = DEFAULT_WHEEL_OPTIONS,
|
|
40
43
|
keyboard = DEFAULT_KEYBOARD_OPTIONS,
|
|
41
44
|
dragSensitivity = DEFAULT_DRAG_SENSITIVITY,
|
|
42
45
|
pointerLock = false,
|
|
43
|
-
enableDoubleClickDefault = true,
|
|
44
46
|
disabled = false,
|
|
45
47
|
readonly = false,
|
|
46
48
|
angleRange = 270,
|
|
47
49
|
onChange,
|
|
50
|
+
onChangeStart,
|
|
51
|
+
onChangeEnd,
|
|
52
|
+
changeEndDelay,
|
|
48
53
|
ref = $bindable(null),
|
|
49
54
|
children,
|
|
50
55
|
style,
|
|
@@ -101,6 +106,14 @@
|
|
|
101
106
|
onChange?.(next)
|
|
102
107
|
}
|
|
103
108
|
|
|
109
|
+
const gesture = useChangeGesture(() => ({
|
|
110
|
+
value,
|
|
111
|
+
inactive,
|
|
112
|
+
onChangeStart,
|
|
113
|
+
onChangeEnd,
|
|
114
|
+
changeEndDelay,
|
|
115
|
+
}))
|
|
116
|
+
|
|
104
117
|
// The knob has no travel of its own: the value moves away from where it
|
|
105
118
|
// stood when the drag started, 100px of movement spanning the whole range.
|
|
106
119
|
// Only the vertical axis carries a value, reversed so that dragging up
|
|
@@ -115,7 +128,7 @@
|
|
|
115
128
|
}),
|
|
116
129
|
getValue: (): XY<number> => [value, value],
|
|
117
130
|
threshold: 1,
|
|
118
|
-
cursor: inactive ? undefined :
|
|
131
|
+
cursor: inactive ? undefined : dragCursor,
|
|
119
132
|
pointerLock: inactive ? false : pointerLock,
|
|
120
133
|
shouldStart: () => !inactive,
|
|
121
134
|
onChange: (v: XY<number>) => {
|
|
@@ -123,9 +136,11 @@
|
|
|
123
136
|
},
|
|
124
137
|
onDragStart: () => {
|
|
125
138
|
dragging = true
|
|
139
|
+
if (!inactive) gesture.hold('pointer')
|
|
126
140
|
},
|
|
127
141
|
onDragEnd: () => {
|
|
128
142
|
dragging = false
|
|
143
|
+
gesture.end()
|
|
129
144
|
},
|
|
130
145
|
})
|
|
131
146
|
|
|
@@ -138,6 +153,7 @@
|
|
|
138
153
|
const direction = wheelDirection(event)
|
|
139
154
|
if (direction === null) return
|
|
140
155
|
event.preventDefault()
|
|
156
|
+
gesture.pulse('wheel')
|
|
141
157
|
change(applyDelta(value, direction, wheel, range, event))
|
|
142
158
|
},
|
|
143
159
|
})
|
|
@@ -174,13 +190,18 @@
|
|
|
174
190
|
const direction = arrowKeyDirection(event.key)
|
|
175
191
|
if (direction !== null) {
|
|
176
192
|
event.preventDefault()
|
|
193
|
+
gesture.pulse('keyboard')
|
|
177
194
|
change(applyDelta(value, direction, keyboard, range, event))
|
|
178
195
|
}
|
|
179
196
|
}
|
|
180
197
|
onkeydown?.(event)
|
|
181
198
|
}}
|
|
182
199
|
ondblclick={(event) => {
|
|
183
|
-
if (!inactive &&
|
|
200
|
+
if (!inactive && resetValue !== null) {
|
|
201
|
+
gesture.instant('doubleClick', () =>
|
|
202
|
+
change(resetValue ?? startValue ?? min),
|
|
203
|
+
)
|
|
204
|
+
}
|
|
184
205
|
ondblclick?.(event)
|
|
185
206
|
}}
|
|
186
207
|
{...rest}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Root.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/Knob/Root.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Root.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/Knob/Root.svelte.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,KAAK,GAAG,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,SAAS,CAAC,CAAC;AAoLjF,QAAA,MAAM,IAAI;;;mBAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
Omit<SVGAttributes<SVGSVGElement>, keyof KnobThumbProps>
|
|
14
14
|
|
|
15
15
|
let {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
color = 'currentColor',
|
|
17
|
+
lineColor = 'currentColor',
|
|
18
|
+
size = 84,
|
|
19
|
+
lineWeight = 6,
|
|
20
|
+
lineLength = 35,
|
|
21
21
|
classes,
|
|
22
22
|
...rest
|
|
23
23
|
}: Props = $props()
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
</script>
|
|
29
29
|
|
|
30
30
|
<svg {...rest}>
|
|
31
|
-
<circle cx="50%" cy="50%" r="{
|
|
31
|
+
<circle cx="50%" cy="50%" r="{size / 2}%" fill={color} />
|
|
32
32
|
<line
|
|
33
|
-
class={classes?.
|
|
33
|
+
class={classes?.line}
|
|
34
34
|
x1="50%"
|
|
35
|
-
y1="{(KNOB_VIEWBOX_SIZE - clamp(
|
|
35
|
+
y1="{(KNOB_VIEWBOX_SIZE - clamp(size, 0, 100)) / 2}%"
|
|
36
36
|
x2="50%"
|
|
37
|
-
y2="{
|
|
38
|
-
stroke={
|
|
39
|
-
stroke-width="{
|
|
37
|
+
y2="{lineLength}%"
|
|
38
|
+
stroke={lineColor}
|
|
39
|
+
stroke-width="{lineWeight}%"
|
|
40
40
|
style:transform="rotate({angle}deg)"
|
|
41
41
|
style:transform-origin="50% 50%"
|
|
42
42
|
/>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { InputEventOption, ModifierValue } from '@tremolo-ui/dom';
|
|
1
|
+
import type { ChangeSource, InputEventOption, ModifierValue } from '@tremolo-ui/dom';
|
|
2
2
|
import type { Scale } from '@tremolo-ui/functions';
|
|
3
3
|
import type { Snippet } from 'svelte';
|
|
4
4
|
export interface KnobProps {
|
|
@@ -25,10 +25,10 @@ export interface KnobProps {
|
|
|
25
25
|
*/
|
|
26
26
|
scale?: Scale;
|
|
27
27
|
/**
|
|
28
|
-
* The value a double click restores
|
|
29
|
-
* @default
|
|
28
|
+
* The value a double click restores. `null` turns the double click off.
|
|
29
|
+
* @default startValue
|
|
30
30
|
*/
|
|
31
|
-
|
|
31
|
+
resetValue?: number | null;
|
|
32
32
|
/**
|
|
33
33
|
* Where the active arc starts. Put it at the centre of a bipolar control,
|
|
34
34
|
* such as a pan knob, so that the arc grows from there either way.
|
|
@@ -42,11 +42,9 @@ export interface KnobProps {
|
|
|
42
42
|
size?: number | string;
|
|
43
43
|
/**
|
|
44
44
|
* The cursor to show while dragging.
|
|
45
|
-
* @default
|
|
45
|
+
* @default 'grabbing'
|
|
46
46
|
*/
|
|
47
|
-
|
|
48
|
-
cursor?: string;
|
|
49
|
-
};
|
|
47
|
+
dragCursor?: string;
|
|
50
48
|
/**
|
|
51
49
|
* How much one notch of the wheel moves the value, while the focus is
|
|
52
50
|
* inside. `null` turns the wheel off.
|
|
@@ -71,11 +69,6 @@ export interface KnobProps {
|
|
|
71
69
|
* @default { default: ['raw', 1], shift: ['raw', 0.1] }
|
|
72
70
|
*/
|
|
73
71
|
keyboard?: ModifierValue<InputEventOption> | null;
|
|
74
|
-
/**
|
|
75
|
-
* Restore `defaultValue` on a double click.
|
|
76
|
-
* @default true
|
|
77
|
-
*/
|
|
78
|
-
enableDoubleClickDefault?: boolean;
|
|
79
72
|
/**
|
|
80
73
|
* Make the knob unchangeable and remove it from the tab order.
|
|
81
74
|
* The parts carry `data-disabled` while it is set.
|
|
@@ -97,6 +90,24 @@ export interface KnobProps {
|
|
|
97
90
|
* double click moves it.
|
|
98
91
|
*/
|
|
99
92
|
onChange?: (value: number) => void;
|
|
93
|
+
/**
|
|
94
|
+
* Called when a change of the value starts — a drag, a double
|
|
95
|
+
* click, the first wheel notch or arrow key — with the value before it and
|
|
96
|
+
* what it is made with. A host recording automation can treat the control
|
|
97
|
+
* as touched from here until `onChangeEnd`.
|
|
98
|
+
*/
|
|
99
|
+
onChangeStart?: (value: number, source: ChangeSource) => void;
|
|
100
|
+
/**
|
|
101
|
+
* Called when the change ends, with the value it ended on: on release, or
|
|
102
|
+
* `changeEndDelay` after the last wheel notch or arrow key.
|
|
103
|
+
*/
|
|
104
|
+
onChangeEnd?: (value: number, source: ChangeSource) => void;
|
|
105
|
+
/**
|
|
106
|
+
* How long after the last wheel notch or arrow key the change counts as
|
|
107
|
+
* over, in milliseconds.
|
|
108
|
+
* @default 500
|
|
109
|
+
*/
|
|
110
|
+
changeEndDelay?: number;
|
|
100
111
|
/** The root element, bound with `bind:ref`. */
|
|
101
112
|
ref?: HTMLDivElement | null;
|
|
102
113
|
/**
|
|
@@ -110,30 +121,30 @@ export interface KnobThumbProps {
|
|
|
110
121
|
* Fill colour of the circle.
|
|
111
122
|
* @default 'currentColor'
|
|
112
123
|
*/
|
|
113
|
-
|
|
124
|
+
color?: string;
|
|
114
125
|
/**
|
|
115
126
|
* Colour of the line that points at the value.
|
|
116
127
|
* @default 'currentColor'
|
|
117
128
|
*/
|
|
118
|
-
|
|
129
|
+
lineColor?: string;
|
|
119
130
|
/**
|
|
120
131
|
* Diameter of the circle, as a percentage of the knob.
|
|
121
132
|
* @default 84
|
|
122
133
|
*/
|
|
123
|
-
|
|
134
|
+
size?: number;
|
|
124
135
|
/**
|
|
125
136
|
* Thickness of the line, as a percentage of the knob.
|
|
126
137
|
* @default 6
|
|
127
138
|
*/
|
|
128
|
-
|
|
139
|
+
lineWeight?: number;
|
|
129
140
|
/**
|
|
130
141
|
* How far down the line reaches, as a percentage of the knob from its top.
|
|
131
142
|
* @default 35
|
|
132
143
|
*/
|
|
133
|
-
|
|
144
|
+
lineLength?: number;
|
|
134
145
|
/** Classes for the line that points at the value. */
|
|
135
146
|
classes?: {
|
|
136
|
-
|
|
147
|
+
line?: string;
|
|
137
148
|
};
|
|
138
149
|
}
|
|
139
150
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/Knob/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/Knob/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACd,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAElD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAErC,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,uDAAuD;IACvD,GAAG,EAAE,MAAM,CAAA;IACX,qDAAqD;IACrD,GAAG,EAAE,MAAM,CAAA;IACX;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,KAAK,CAAC,EAAE,KAAK,CAAA;IACb;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAA;IAC9C;;;;OAIG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACvC;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAA;IACjD;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,CAAA;IAC7D;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,CAAA;IAC3D;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,+CAA+C;IAC/C,GAAG,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IAC3B;;;OAGG;IACH,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qDAAqD;IACrD,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5B"}
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
caretAtDecimalOffset,
|
|
4
4
|
caretDecimalOffset,
|
|
5
5
|
numberSpan,
|
|
6
|
-
} from '@tremolo-ui/dom'
|
|
6
|
+
} from '@tremolo-ui/dom/internal'
|
|
7
7
|
import { tick } from 'svelte'
|
|
8
8
|
|
|
9
|
-
import { useNumberInputContext } from './context.js'
|
|
9
|
+
import { useNumberInputContext, useNumberInputGesture } from './context.js'
|
|
10
10
|
|
|
11
11
|
import type { HTMLInputAttributes } from 'svelte/elements'
|
|
12
12
|
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
}: Props = $props()
|
|
26
26
|
|
|
27
27
|
const field = useNumberInputContext()
|
|
28
|
+
const gesture = useNumberInputGesture()
|
|
28
29
|
|
|
29
30
|
$effect(() => {
|
|
30
31
|
field.setInput(ref)
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
field.keepCaretOnStep && input.selectionStart !== null
|
|
63
64
|
? caretDecimalOffset(from, input.selectionStart)
|
|
64
65
|
: null
|
|
66
|
+
gesture?.key()
|
|
65
67
|
field.nudge(direction, field.keyboard!, event)
|
|
66
68
|
if (offset === null) return
|
|
67
69
|
await tick()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputField.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/NumberInput/InputField.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAIzD,KAAK,KAAK,GAAG,IAAI,CAAC,mBAAmB,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG;IACzD,GAAG,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAC9B,CAAC;
|
|
1
|
+
{"version":3,"file":"InputField.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/NumberInput/InputField.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAIzD,KAAK,KAAK,GAAG,IAAI,CAAC,mBAAmB,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG;IACzD,GAAG,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAC9B,CAAC;AAyGJ,QAAA,MAAM,UAAU,8CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
|
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import {
|
|
3
|
-
commitNumberInputText,
|
|
4
3
|
DEFAULT_DRAG_SENSITIVITY,
|
|
5
4
|
DEFAULT_KEYBOARD_OPTIONS,
|
|
6
5
|
DEFAULT_WHEEL_OPTIONS,
|
|
6
|
+
} from '@tremolo-ui/dom'
|
|
7
|
+
import {
|
|
8
|
+
commitNumberInputText,
|
|
7
9
|
numberInputBounds,
|
|
8
10
|
numberInputRanges,
|
|
9
11
|
nudgeNumberInput,
|
|
10
12
|
parseNumberText,
|
|
11
13
|
wheelDirection,
|
|
12
|
-
} from '@tremolo-ui/dom'
|
|
14
|
+
} from '@tremolo-ui/dom/internal'
|
|
13
15
|
import { linearScale } from '@tremolo-ui/functions'
|
|
14
16
|
|
|
15
17
|
import { wheel as wheelAction } from '../../actions/wheel.js'
|
|
18
|
+
import { useChangeGesture } from '../_util/change-gesture.svelte.js'
|
|
16
19
|
import { useCheckSteps } from '../_util/check-steps.svelte.js'
|
|
17
20
|
|
|
18
|
-
import { setNumberInputContext } from './context.js'
|
|
21
|
+
import { setNumberInputContext, setNumberInputGesture } from './context.js'
|
|
19
22
|
import type { NumberInputProps } from './types.js'
|
|
20
23
|
|
|
21
24
|
import type { HTMLAttributes } from 'svelte/elements'
|
|
@@ -37,6 +40,7 @@
|
|
|
37
40
|
drag = 1,
|
|
38
41
|
dragSensitivity = DEFAULT_DRAG_SENSITIVITY,
|
|
39
42
|
pointerLock = false,
|
|
43
|
+
dragCursor = 'ns-resize',
|
|
40
44
|
selectOnFocus = 'none',
|
|
41
45
|
unformatOnFocus = false,
|
|
42
46
|
keepCaretOnStep = false,
|
|
@@ -44,6 +48,9 @@
|
|
|
44
48
|
disabled = false,
|
|
45
49
|
readonly = false,
|
|
46
50
|
onChange,
|
|
51
|
+
onChangeStart,
|
|
52
|
+
onChangeEnd,
|
|
53
|
+
changeEndDelay,
|
|
47
54
|
ref = $bindable(null),
|
|
48
55
|
children,
|
|
49
56
|
...rest
|
|
@@ -75,6 +82,14 @@
|
|
|
75
82
|
format,
|
|
76
83
|
}))
|
|
77
84
|
|
|
85
|
+
const gesture = useChangeGesture(() => ({
|
|
86
|
+
value,
|
|
87
|
+
inactive,
|
|
88
|
+
onChangeStart,
|
|
89
|
+
onChangeEnd,
|
|
90
|
+
changeEndDelay,
|
|
91
|
+
}))
|
|
92
|
+
|
|
78
93
|
function changeValue(next: number) {
|
|
79
94
|
if (inactive) return
|
|
80
95
|
draft = null
|
|
@@ -114,6 +129,9 @@
|
|
|
114
129
|
get pointerLock() {
|
|
115
130
|
return pointerLock
|
|
116
131
|
},
|
|
132
|
+
get dragCursor() {
|
|
133
|
+
return dragCursor
|
|
134
|
+
},
|
|
117
135
|
get selectOnFocus() {
|
|
118
136
|
return selectOnFocus
|
|
119
137
|
},
|
|
@@ -151,6 +169,7 @@
|
|
|
151
169
|
// to type into an input whose max is 100.
|
|
152
170
|
const parsed = parse(next)
|
|
153
171
|
if (Number.isFinite(parsed)) {
|
|
172
|
+
if (parsed !== value) gesture.pulse('keyboard')
|
|
154
173
|
value = parsed
|
|
155
174
|
onChange?.(parsed)
|
|
156
175
|
}
|
|
@@ -164,8 +183,14 @@
|
|
|
164
183
|
})
|
|
165
184
|
// Text with no number is not a value: the field goes back to what it
|
|
166
185
|
// was showing.
|
|
167
|
-
if (committed === null)
|
|
168
|
-
|
|
186
|
+
if (committed === null) {
|
|
187
|
+
draft = null
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
// The typing was a gesture of its own, and committing is where it ends.
|
|
191
|
+
if (committed !== value) gesture.pulse('keyboard')
|
|
192
|
+
changeValue(committed)
|
|
193
|
+
gesture.end()
|
|
169
194
|
},
|
|
170
195
|
changeValue,
|
|
171
196
|
nudge: (direction, option, modifiers) =>
|
|
@@ -177,12 +202,37 @@
|
|
|
177
202
|
},
|
|
178
203
|
})
|
|
179
204
|
|
|
205
|
+
let pressed = false
|
|
206
|
+
setNumberInputGesture({
|
|
207
|
+
press: () => {
|
|
208
|
+
if (inactive) return
|
|
209
|
+
gesture.hold('pointer')
|
|
210
|
+
// Called again by every repeat of a held stepper; one release will do.
|
|
211
|
+
if (pressed) return
|
|
212
|
+
pressed = true
|
|
213
|
+
// Released wherever the pointer ends up: the stepper drag captures it,
|
|
214
|
+
// and a press that wanders off the button still ends.
|
|
215
|
+
const release = () => {
|
|
216
|
+
pressed = false
|
|
217
|
+
gesture.end()
|
|
218
|
+
window.removeEventListener('pointerup', release)
|
|
219
|
+
window.removeEventListener('pointercancel', release)
|
|
220
|
+
}
|
|
221
|
+
window.addEventListener('pointerup', release)
|
|
222
|
+
window.addEventListener('pointercancel', release)
|
|
223
|
+
},
|
|
224
|
+
key: () => {
|
|
225
|
+
if (!inactive) gesture.pulse('keyboard')
|
|
226
|
+
},
|
|
227
|
+
})
|
|
228
|
+
|
|
180
229
|
const wheelOptions = $derived({
|
|
181
230
|
requireFocus: true,
|
|
182
231
|
onWheel: (event: WheelEvent) => {
|
|
183
232
|
const direction = wheelDirection(event)
|
|
184
233
|
if (!wheel || inactive || direction === null) return
|
|
185
234
|
event.preventDefault()
|
|
235
|
+
gesture.pulse('wheel')
|
|
186
236
|
changeValue(nudgeNumberInput(value, direction, wheel, ranges, event))
|
|
187
237
|
},
|
|
188
238
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Root.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/NumberInput/Root.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Root.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/NumberInput/Root.svelte.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,KAAK,GAAG,gBAAgB,GAC3B,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,gBAAgB,CAAC,CAAC;AAoPjE,QAAA,MAAM,IAAI;;;mBAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
createStepperDrag,
|
|
4
|
+
type StepperDragInstance,
|
|
5
|
+
} from '@tremolo-ui/dom/internal'
|
|
3
6
|
import { untrack } from 'svelte'
|
|
4
7
|
|
|
5
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
setStepperContext,
|
|
10
|
+
useNumberInputContext,
|
|
11
|
+
useNumberInputGesture,
|
|
12
|
+
} from './context.js'
|
|
6
13
|
|
|
7
14
|
import type { Snippet } from 'svelte'
|
|
8
15
|
import type { HTMLAttributes } from 'svelte/elements'
|
|
@@ -12,9 +19,15 @@
|
|
|
12
19
|
children?: Snippet
|
|
13
20
|
}
|
|
14
21
|
|
|
15
|
-
let {
|
|
22
|
+
let {
|
|
23
|
+
ref = $bindable(null),
|
|
24
|
+
children,
|
|
25
|
+
onpointerdown,
|
|
26
|
+
...rest
|
|
27
|
+
}: Props = $props()
|
|
16
28
|
|
|
17
29
|
const field = useNumberInputContext()
|
|
30
|
+
const gesture = useNumberInputGesture()
|
|
18
31
|
|
|
19
32
|
// Only attached while it can do something: `createDrag` puts
|
|
20
33
|
// `touch-action: none` on the element, and a stepper that cannot be dragged
|
|
@@ -27,6 +40,7 @@
|
|
|
27
40
|
pixels: field.drag ?? 1,
|
|
28
41
|
sensitivity: field.dragSensitivity,
|
|
29
42
|
pointerLock: field.pointerLock,
|
|
43
|
+
cursor: field.dragCursor,
|
|
30
44
|
})
|
|
31
45
|
|
|
32
46
|
let instance: StepperDragInstance | null = null
|
|
@@ -56,6 +70,15 @@
|
|
|
56
70
|
|
|
57
71
|
<!-- The area the steppers sit in, and a drag handle in its own right:
|
|
58
72
|
dragging it up and down moves the value one `step` every `drag` pixels. -->
|
|
59
|
-
<div
|
|
73
|
+
<div
|
|
74
|
+
bind:this={ref}
|
|
75
|
+
onpointerdown={(event) => {
|
|
76
|
+
// A drag on the stepper is a press like any other: held from here until
|
|
77
|
+
// the pointer is released.
|
|
78
|
+
if (enabled) gesture?.press()
|
|
79
|
+
onpointerdown?.(event)
|
|
80
|
+
}}
|
|
81
|
+
{...rest}
|
|
82
|
+
>
|
|
60
83
|
{@render children?.()}
|
|
61
84
|
</div>
|