svelte-tweakpane-ui 1.4.0 → 1.5.1
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/control/CubicBezier.svelte +0 -7
- package/dist/control/File.svelte +55 -0
- package/dist/control/File.svelte.d.ts +204 -0
- package/dist/control/Image.svelte +36 -2
- package/dist/control/Image.svelte.d.ts +14 -11
- package/dist/control/Slider.svelte +2 -1
- package/dist/control/Stepper.svelte +30 -0
- package/dist/control/Stepper.svelte.d.ts +194 -0
- package/dist/core/Binding.svelte +18 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -5
- package/package.json +46 -36
- package/readme.md +5 -1
|
@@ -82,10 +82,3 @@
|
|
|
82
82
|
<ClsPad keysAdd={fillWith('containerUnitSpacing', 2)} theme={$$props.theme} />
|
|
83
83
|
{/if}
|
|
84
84
|
{/if}
|
|
85
|
-
|
|
86
|
-
<style>
|
|
87
|
-
/* Fix overflow bug from the plugin TODO PR */
|
|
88
|
-
:global(div.svelte-tweakpane-ui div.tp-cbzv:not(tp-cbzv-expanded) div.tp-cbzv_p) {
|
|
89
|
-
overflow: hidden !important;
|
|
90
|
-
}
|
|
91
|
-
</style>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script context="module"></script>
|
|
2
|
+
|
|
3
|
+
<script>
|
|
4
|
+
import ClsPad from '../internal/ClsPad.svelte';
|
|
5
|
+
import GenericInput from '../internal/GenericInput.svelte';
|
|
6
|
+
import { fillWith } from '../utils';
|
|
7
|
+
import * as pluginModule from '@kitschpatrol/tweakpane-plugin-file-import';
|
|
8
|
+
import { BROWSER } from 'esm-env';
|
|
9
|
+
import { shallowEqual } from 'fast-equals';
|
|
10
|
+
export let value = void 0;
|
|
11
|
+
export let rows = void 0;
|
|
12
|
+
export let invalidExtensionMessage = void 0;
|
|
13
|
+
export let extensions = void 0;
|
|
14
|
+
let internalValue;
|
|
15
|
+
function updateInternalValueFromValue() {
|
|
16
|
+
const newInternalValue = value ?? '';
|
|
17
|
+
if (!shallowEqual(internalValue, newInternalValue)) {
|
|
18
|
+
internalValue = newInternalValue;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function updateValueFromInternalValue() {
|
|
22
|
+
if (internalValue instanceof File) {
|
|
23
|
+
if (!shallowEqual(value, internalValue)) {
|
|
24
|
+
value = internalValue;
|
|
25
|
+
}
|
|
26
|
+
} else if (value !== void 0) {
|
|
27
|
+
value = void 0;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
let options;
|
|
31
|
+
$: options = {
|
|
32
|
+
extensions,
|
|
33
|
+
filetypes: extensions,
|
|
34
|
+
invalidFiletypeMessage: invalidExtensionMessage,
|
|
35
|
+
lineCount: rows,
|
|
36
|
+
view: 'file-input'
|
|
37
|
+
};
|
|
38
|
+
$: value, updateInternalValueFromValue();
|
|
39
|
+
$: internalValue, updateValueFromInternalValue();
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<GenericInput
|
|
43
|
+
bind:value={internalValue}
|
|
44
|
+
on:change
|
|
45
|
+
{options}
|
|
46
|
+
plugin={pluginModule}
|
|
47
|
+
{...$$restProps}
|
|
48
|
+
/>
|
|
49
|
+
{#if !BROWSER}
|
|
50
|
+
{#if rows}
|
|
51
|
+
<ClsPad keysAdd={fillWith('containerUnitSize', rows)} theme={$$props.theme} />
|
|
52
|
+
{:else}
|
|
53
|
+
<ClsPad keysAdd={fillWith('containerUnitSize', 3)} theme={$$props.theme} />
|
|
54
|
+
{/if}
|
|
55
|
+
{/if}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { SvelteComponent } from 'svelte';
|
|
2
|
+
import type { ValueChangeEvent } from '../utils.js';
|
|
3
|
+
export type FileValue = File | undefined;
|
|
4
|
+
export type FileChangeEvent = ValueChangeEvent<FileValue>;
|
|
5
|
+
declare const __propDef: {
|
|
6
|
+
props: {
|
|
7
|
+
/**
|
|
8
|
+
* File data, or `undefined` to clear the file input.
|
|
9
|
+
* @default `undefined`
|
|
10
|
+
* @bindable
|
|
11
|
+
*/
|
|
12
|
+
value?: FileValue;
|
|
13
|
+
/**
|
|
14
|
+
* Array of valid file extensions.
|
|
15
|
+
* @default Any file extension
|
|
16
|
+
*/
|
|
17
|
+
extensions?: string[] | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* String shown when the user tries to upload an invalid filetype.
|
|
20
|
+
* @default `'Unaccepted file type.'`
|
|
21
|
+
*/
|
|
22
|
+
invalidExtensionMessage?: string | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Height of the file input drop zone, in rows.
|
|
25
|
+
* @default `3`
|
|
26
|
+
*/
|
|
27
|
+
rows?: number | undefined;
|
|
28
|
+
} & Omit<
|
|
29
|
+
{
|
|
30
|
+
/**
|
|
31
|
+
* File data, or `undefined` to clear the file input.
|
|
32
|
+
* @default `undefined`
|
|
33
|
+
* @bindable
|
|
34
|
+
*/
|
|
35
|
+
value: string | File | null;
|
|
36
|
+
} & Omit<
|
|
37
|
+
{
|
|
38
|
+
/**
|
|
39
|
+
* The binding's target object with values to manipulate.
|
|
40
|
+
* @bindable
|
|
41
|
+
*/
|
|
42
|
+
object: import('@tweakpane/core').Bindable & Record<string, string | File | null>;
|
|
43
|
+
/** The key for the value in the target `object` that the control should manipulate. */
|
|
44
|
+
key: string;
|
|
45
|
+
/**
|
|
46
|
+
* Prevent interactivity and gray out the control.
|
|
47
|
+
* @default `false`
|
|
48
|
+
*/
|
|
49
|
+
disabled?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Text displayed next to control.
|
|
52
|
+
* @default `undefined`
|
|
53
|
+
*/
|
|
54
|
+
label?: string | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Tweakpane's internal options object.
|
|
57
|
+
*
|
|
58
|
+
* See [`BindingParams`](https://tweakpane.github.io/docs/api/types/BindingParams.html).
|
|
59
|
+
*
|
|
60
|
+
* Valid types are contingent on the type of the value `key` points to in `object`.
|
|
61
|
+
*
|
|
62
|
+
* This is intended internal use, when implementing convenience components wrapping Binding's
|
|
63
|
+
* functionality. Options of interest are instead exposed as top-level props in _Svelte
|
|
64
|
+
* Tweakpane UI_.
|
|
65
|
+
* @default `undefined`
|
|
66
|
+
*/
|
|
67
|
+
options?: import('@tweakpane/core').BaseInputParams | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Custom color scheme.
|
|
70
|
+
*
|
|
71
|
+
* @default `undefined` \
|
|
72
|
+
* Inherits default Tweakpane theme equivalent to `ThemeUtils.presets.standard`, or the theme
|
|
73
|
+
* set with `setGlobalDefaultTheme()`.
|
|
74
|
+
*/
|
|
75
|
+
theme?: import('..').Theme | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Reference to internal Tweakpane
|
|
78
|
+
* [`BindingApi`](https://tweakpane.github.io/docs/api/classes/_internal_.BindingApi.html) for
|
|
79
|
+
* this control.
|
|
80
|
+
*
|
|
81
|
+
* This property is exposed for advanced use cases only, such as when implementing convenience
|
|
82
|
+
* components wrapping `<Binding>`'s functionality.
|
|
83
|
+
*
|
|
84
|
+
* Direct manipulation of Tweakpane's internals can break _Svelte Tweakpane UI_ abstractions.
|
|
85
|
+
*
|
|
86
|
+
* @bindable
|
|
87
|
+
* @readonly
|
|
88
|
+
*/
|
|
89
|
+
ref?: import('../internal/GenericInput.svelte').GenericInputRef | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Imported Tweakpane `TpPluginBundle` (aliased as `Plugin`) module to automatically register in
|
|
92
|
+
* the `<Binding>`'s containing `<Pane>`.
|
|
93
|
+
*
|
|
94
|
+
* This property is exposed for advanced use cases only, such as when implementing convenience
|
|
95
|
+
* components wrapping `<Binding>`'s functionality in combination with a Tweakpane plugin.
|
|
96
|
+
*
|
|
97
|
+
* Direct manipulation of Tweakpane's internals can break _Svelte Tweakpane UI_ abstractions.
|
|
98
|
+
*
|
|
99
|
+
* @default `undefined`
|
|
100
|
+
*/
|
|
101
|
+
plugin?: import('../utils.js').Plugin | undefined;
|
|
102
|
+
},
|
|
103
|
+
'object' | 'key'
|
|
104
|
+
>,
|
|
105
|
+
'ref' | 'plugin' | 'value'
|
|
106
|
+
>;
|
|
107
|
+
slots: {};
|
|
108
|
+
events: {
|
|
109
|
+
/**
|
|
110
|
+
* Fires when `value` changes.
|
|
111
|
+
*
|
|
112
|
+
* _This event is provided for advanced use cases. It's usually preferred to bind to the `value` prop instead._
|
|
113
|
+
*
|
|
114
|
+
* The `event.details` payload includes a copy of the value and an `origin` field to distinguish between user-interactive changes (`internal`)
|
|
115
|
+
* and changes resulting from programmatic manipulation of the `value` (`external`).
|
|
116
|
+
*
|
|
117
|
+
* @extends ValueChangeEvent
|
|
118
|
+
* @event
|
|
119
|
+
* */
|
|
120
|
+
change: FileChangeEvent;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
export type FileProps = typeof __propDef.props;
|
|
124
|
+
export type FileEvents = typeof __propDef.events;
|
|
125
|
+
export type FileSlots = typeof __propDef.slots;
|
|
126
|
+
/**
|
|
127
|
+
* A file input control.
|
|
128
|
+
*
|
|
129
|
+
* _Important: This component has some rough edges, and should be considered experimental._
|
|
130
|
+
*
|
|
131
|
+
* Integrates the [File Input](https://github.com/LuchoTurtle/tweakpane-plugin-file-import/blob/main/src/plugin.ts) control from [LuchoTurtle's](https://github.com/LuchoTurtle) [tweakpane-plugin-file-import](https://github.com/LuchoTurtle/tweakpane-plugin-file-import) plugin. Some of the control's parameter names have been changed for consistency with the `<Image>` CompositionEvent.
|
|
132
|
+
*
|
|
133
|
+
* Use the `<Image>` control instead if you're working with images and want to see a thumbnail preview of the image.
|
|
134
|
+
*
|
|
135
|
+
* There is currently a known bug where change events' `origin` values are sometimes incorrect. (This issue is limited to this component.)
|
|
136
|
+
*
|
|
137
|
+
* Usage outside of a `<Pane>` component will implicitly wrap the image control in `<Pane position="inline">`.
|
|
138
|
+
*
|
|
139
|
+
* Note that _Svelte Tweakpane UI_ embeds a functionally identical [fork](https://github.com/kitschpatrol/tweakpane-plugin-file-import) of the plugin with build optimizations.
|
|
140
|
+
*
|
|
141
|
+
*
|
|
142
|
+
* @emits {FileChangeEvent} change - When `value` changes. (This event is provided for advanced use cases. Prefer binding to `value`.)
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```svelte
|
|
146
|
+
* <script lang="ts">
|
|
147
|
+
* import { File, type FileValue } from '..';
|
|
148
|
+
*
|
|
149
|
+
* let file: FileValue;
|
|
150
|
+
*
|
|
151
|
+
* async function getFileBase64(file: FileValue): Promise<string> {
|
|
152
|
+
* if (file === undefined) return 'Your bytes here...';
|
|
153
|
+
* return new Promise((resolve, reject) => {
|
|
154
|
+
* const reader = new FileReader();
|
|
155
|
+
* reader.addEventListener('load', () => {
|
|
156
|
+
* const { result } = reader;
|
|
157
|
+
* if (result && typeof result === 'string') resolve(result);
|
|
158
|
+
* else reject(new Error('Empty result'));
|
|
159
|
+
* });
|
|
160
|
+
* reader.addEventListener('error', reject);
|
|
161
|
+
* reader.readAsDataURL(file);
|
|
162
|
+
* });
|
|
163
|
+
* }
|
|
164
|
+
*
|
|
165
|
+
* function truncate(text: string, length: number) {
|
|
166
|
+
* return text.length > length ? text.slice(0, length - 1) + '...' : text;
|
|
167
|
+
* }
|
|
168
|
+
* </script>
|
|
169
|
+
*
|
|
170
|
+
* <File bind:value={file} label="File" />
|
|
171
|
+
*
|
|
172
|
+
* <div class="demo">
|
|
173
|
+
* <p>
|
|
174
|
+
* {#await getFileBase64(file)}
|
|
175
|
+
* Loading...
|
|
176
|
+
* {:then value}
|
|
177
|
+
* {truncate(value, 512)}
|
|
178
|
+
* {/await}
|
|
179
|
+
* </p>
|
|
180
|
+
* </div>
|
|
181
|
+
*
|
|
182
|
+
* <style>
|
|
183
|
+
* .demo {
|
|
184
|
+
* width: 100%;
|
|
185
|
+
* background: linear-gradient(45deg, orange, magenta);
|
|
186
|
+
* }
|
|
187
|
+
*
|
|
188
|
+
* .demo > p {
|
|
189
|
+
* margin: 0;
|
|
190
|
+
* padding: 0.5rem;
|
|
191
|
+
* font-family: monospace;
|
|
192
|
+
* line-height: 1.2;
|
|
193
|
+
* color: white;
|
|
194
|
+
* word-break: break-all;
|
|
195
|
+
* white-space: pre-wrap;
|
|
196
|
+
* }
|
|
197
|
+
* </style>
|
|
198
|
+
* ```
|
|
199
|
+
*
|
|
200
|
+
* @sourceLink
|
|
201
|
+
* [File.svelte](https://github.com/kitschpatrol/svelte-tweakpane-ui/blob/main/src/lib/control/File.svelte)
|
|
202
|
+
*/
|
|
203
|
+
export default class File extends SvelteComponent<FileProps, FileEvents, FileSlots> {}
|
|
204
|
+
export {};
|
|
@@ -6,18 +6,52 @@
|
|
|
6
6
|
import { fillWith } from '../utils';
|
|
7
7
|
import * as pluginModule from '@kitschpatrol/tweakpane-plugin-image';
|
|
8
8
|
import { BROWSER } from 'esm-env';
|
|
9
|
-
|
|
9
|
+
import { shallowEqual } from 'fast-equals';
|
|
10
|
+
export let value = void 0;
|
|
10
11
|
export let fit = void 0;
|
|
11
12
|
export let extensions = void 0;
|
|
13
|
+
let internalValue = 'placeholder';
|
|
14
|
+
function updateInternalValueFromValue() {
|
|
15
|
+
const newInternalValue = value ?? 'placeholder';
|
|
16
|
+
if (!shallowEqual(internalValue, newInternalValue)) {
|
|
17
|
+
internalValue = newInternalValue;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function updateValueFromInternalValue() {
|
|
21
|
+
if (internalValue === 'placeholder') {
|
|
22
|
+
if (value !== void 0) {
|
|
23
|
+
value = void 0;
|
|
24
|
+
}
|
|
25
|
+
} else if (internalValue instanceof HTMLImageElement) {
|
|
26
|
+
if (value !== internalValue.src) {
|
|
27
|
+
value = internalValue.src;
|
|
28
|
+
}
|
|
29
|
+
} else if (internalValue instanceof File) {
|
|
30
|
+
console.warn('Image control does not support File objects.');
|
|
31
|
+
if (value !== void 0) {
|
|
32
|
+
value = void 0;
|
|
33
|
+
}
|
|
34
|
+
} else if (value !== internalValue) {
|
|
35
|
+
value = internalValue;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
12
38
|
let options;
|
|
13
39
|
$: options = {
|
|
14
40
|
extensions,
|
|
15
41
|
imageFit: fit,
|
|
16
42
|
view: 'input-image'
|
|
17
43
|
};
|
|
44
|
+
$: value, updateInternalValueFromValue();
|
|
45
|
+
$: internalValue, updateValueFromInternalValue();
|
|
18
46
|
</script>
|
|
19
47
|
|
|
20
|
-
<GenericInput
|
|
48
|
+
<GenericInput
|
|
49
|
+
bind:value={internalValue}
|
|
50
|
+
on:change
|
|
51
|
+
{options}
|
|
52
|
+
plugin={pluginModule}
|
|
53
|
+
{...$$restProps}
|
|
54
|
+
/>
|
|
21
55
|
{#if !BROWSER}
|
|
22
56
|
<ClsPad keysAdd={fillWith('containerVerticalPadding', 2)} theme={$$props.theme} />
|
|
23
57
|
{/if}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { SvelteComponent } from 'svelte';
|
|
2
2
|
import type { ValueChangeEvent } from '../utils.js';
|
|
3
|
-
export type ImageValue =
|
|
3
|
+
export type ImageValue = string | undefined;
|
|
4
4
|
export type ImageChangeEvent = ValueChangeEvent<ImageValue>;
|
|
5
5
|
declare const __propDef: {
|
|
6
6
|
props: {
|
|
7
7
|
/**
|
|
8
|
-
* Image data
|
|
9
|
-
* @default `'
|
|
8
|
+
* Image data as Base64-encoded string, or `undefined` to clear.
|
|
9
|
+
* @default `'undefined'`
|
|
10
10
|
* @bindable
|
|
11
11
|
*/
|
|
12
12
|
value?: ImageValue;
|
|
@@ -25,18 +25,19 @@ declare const __propDef: {
|
|
|
25
25
|
} & Omit<
|
|
26
26
|
{
|
|
27
27
|
/**
|
|
28
|
-
* Image data
|
|
29
|
-
* @default `'
|
|
28
|
+
* Image data as Base64-encoded string, or `undefined` to clear.
|
|
29
|
+
* @default `'undefined'`
|
|
30
30
|
* @bindable
|
|
31
31
|
*/
|
|
32
|
-
value:
|
|
32
|
+
value: string | HTMLImageElement | File | undefined;
|
|
33
33
|
} & Omit<
|
|
34
34
|
{
|
|
35
35
|
/**
|
|
36
36
|
* The binding's target object with values to manipulate.
|
|
37
37
|
* @bindable
|
|
38
38
|
*/
|
|
39
|
-
object: import('@tweakpane/core').Bindable &
|
|
39
|
+
object: import('@tweakpane/core').Bindable &
|
|
40
|
+
Record<string, string | HTMLImageElement | File | undefined>;
|
|
40
41
|
/** The key for the value in the target `object` that the control should manipulate. */
|
|
41
42
|
key: string;
|
|
42
43
|
/**
|
|
@@ -130,6 +131,8 @@ export type ImageSlots = typeof __propDef.slots;
|
|
|
130
131
|
* Dias](https://www.linkedin.com/in/matheusdbs/), [Palash Bansal](https://github.com/repalash), and
|
|
131
132
|
* others.
|
|
132
133
|
*
|
|
134
|
+
* Use the `<File>` control instead if you're working with other file types, or don't wish to display a thumbnail preview of an uploaded image.
|
|
135
|
+
*
|
|
133
136
|
* There is currently a known bug where change events' `origin` values are sometimes incorrect. (This issue is limited to this component.)
|
|
134
137
|
*
|
|
135
138
|
* Usage outside of a `<Pane>` component will implicitly wrap the image control in `<Pane
|
|
@@ -142,9 +145,9 @@ export type ImageSlots = typeof __propDef.slots;
|
|
|
142
145
|
* @example
|
|
143
146
|
* ```svelte
|
|
144
147
|
* <script lang="ts">
|
|
145
|
-
* import { Button, Image } from '
|
|
148
|
+
* import { Button, Image, type ImageValue } from '..';
|
|
146
149
|
*
|
|
147
|
-
* let source
|
|
150
|
+
* let source: ImageValue;
|
|
148
151
|
*
|
|
149
152
|
* async function getRandomKittenUrl() {
|
|
150
153
|
* const { url } = await fetch('https://loremflickr.com/800/800/kitten', {
|
|
@@ -165,9 +168,9 @@ export type ImageSlots = typeof __propDef.slots;
|
|
|
165
168
|
* />
|
|
166
169
|
*
|
|
167
170
|
* <div class="demo">
|
|
168
|
-
* {#if source ===
|
|
171
|
+
* {#if source === undefined}
|
|
169
172
|
* <p>Tap “No Image” above to load an image from disk.</p>
|
|
170
|
-
* {:else}
|
|
173
|
+
* {:else if typeof source === 'string'}
|
|
171
174
|
* <img alt="" src={source} />
|
|
172
175
|
* {/if}
|
|
173
176
|
* </div>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<script>
|
|
4
4
|
import GenericSlider from '../internal/GenericSlider.svelte';
|
|
5
|
+
import {} from 'svelte';
|
|
5
6
|
export let value;
|
|
6
7
|
export let wide = void 0;
|
|
7
8
|
let ref;
|
|
@@ -16,4 +17,4 @@
|
|
|
16
17
|
$: ref && wide !== void 0 && updateWide(wide);
|
|
17
18
|
</script>
|
|
18
19
|
|
|
19
|
-
<GenericSlider bind:value bind:ref
|
|
20
|
+
<GenericSlider bind:value bind:ref on:change {...$$restProps} />
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script context="module"></script>
|
|
2
|
+
|
|
3
|
+
<script>
|
|
4
|
+
import GenericSlider from '../internal/GenericSlider.svelte';
|
|
5
|
+
import * as pluginModule from '@kitschpatrol/tweakpane-plugin-inputs';
|
|
6
|
+
export let value;
|
|
7
|
+
export let wide = void 0;
|
|
8
|
+
let options;
|
|
9
|
+
$: options = {
|
|
10
|
+
view: 'stepper'
|
|
11
|
+
};
|
|
12
|
+
let ref;
|
|
13
|
+
function updateWide(wide2) {
|
|
14
|
+
const inputField = ref?.element.querySelector('div.tp-stepv_t');
|
|
15
|
+
const buttonContainer = ref?.element.querySelector('div.tp-stepv_s');
|
|
16
|
+
const buttons = buttonContainer?.querySelectorAll('button');
|
|
17
|
+
if (wide2) {
|
|
18
|
+
inputField?.style.setProperty('display', 'none');
|
|
19
|
+
buttonContainer?.style.setProperty('flex', '1');
|
|
20
|
+
for (const button of buttons ?? []) {
|
|
21
|
+
button.style.setProperty('flex', '1');
|
|
22
|
+
}
|
|
23
|
+
} else {
|
|
24
|
+
inputField?.style.removeProperty('display');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
$: ref && wide !== void 0 && updateWide(wide);
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<GenericSlider bind:value bind:ref on:change {options} plugin={pluginModule} {...$$restProps} />
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { SvelteComponent } from 'svelte';
|
|
2
|
+
import type { ValueChangeEvent } from '../utils.js';
|
|
3
|
+
import type { SliderInputBindingApi as GenericSliderRef } from 'tweakpane';
|
|
4
|
+
export type StepperChangeEvent = ValueChangeEvent<number>;
|
|
5
|
+
declare const __propDef: {
|
|
6
|
+
props: {
|
|
7
|
+
/**
|
|
8
|
+
* A `number` value to control.
|
|
9
|
+
* @bindable
|
|
10
|
+
* */
|
|
11
|
+
value: number;
|
|
12
|
+
} & Omit<
|
|
13
|
+
{
|
|
14
|
+
/**
|
|
15
|
+
* Minimum value.
|
|
16
|
+
*
|
|
17
|
+
* Specifying both a `min` and a `max` prop turns the control into a slider.
|
|
18
|
+
* @default `undefined`
|
|
19
|
+
*/
|
|
20
|
+
min?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Maximum value.
|
|
23
|
+
*
|
|
24
|
+
* Specifying both a `min` and a `max` prop turns the control into a slider.
|
|
25
|
+
* @default `undefined`
|
|
26
|
+
*/
|
|
27
|
+
max?: number;
|
|
28
|
+
/**
|
|
29
|
+
* A function to customize the point value's string representation (e.g. rounding, etc.).
|
|
30
|
+
* @default `undefined` \
|
|
31
|
+
* Normal `.toString()` formatting.
|
|
32
|
+
*/
|
|
33
|
+
format?: ((value: number) => string) | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* The unit scale for key-based input for all dimensions (e.g. the up and down arrow keys).
|
|
36
|
+
* @default `1` \
|
|
37
|
+
* Or `stepValue` if defined.
|
|
38
|
+
*/
|
|
39
|
+
keyScale?: number;
|
|
40
|
+
/**
|
|
41
|
+
* The unit scale for pointer-based input for all dimensions.
|
|
42
|
+
* @default `undefined` \
|
|
43
|
+
* [Dynamic based on magnitude of
|
|
44
|
+
* `value`](https://github.com/cocopon/tweakpane/blob/66dfbea04bfe9b7f031673c955ceda1f92356e75/packages/core/src/common/number/util.ts#L54).
|
|
45
|
+
*/
|
|
46
|
+
pointerScale?: number;
|
|
47
|
+
/**
|
|
48
|
+
* The minimum step interval.
|
|
49
|
+
* @default `undefined` \
|
|
50
|
+
* No step constraint.
|
|
51
|
+
*/
|
|
52
|
+
step?: number;
|
|
53
|
+
/**
|
|
54
|
+
* When `true`, expand the width of the control at the expense of the numeric input
|
|
55
|
+
* field.
|
|
56
|
+
* @default `false`
|
|
57
|
+
*/
|
|
58
|
+
wide?: boolean;
|
|
59
|
+
} & {
|
|
60
|
+
/**
|
|
61
|
+
* A `number` value to control.
|
|
62
|
+
* @bindable
|
|
63
|
+
*/
|
|
64
|
+
value: number;
|
|
65
|
+
} & Omit<
|
|
66
|
+
{
|
|
67
|
+
/**
|
|
68
|
+
* The binding's target object with values to manipulate.
|
|
69
|
+
* @bindable
|
|
70
|
+
*/
|
|
71
|
+
object: import('@tweakpane/core').Bindable & Record<string, number>;
|
|
72
|
+
/** The key for the value in the target `object` that the control should manipulate. */
|
|
73
|
+
key: string;
|
|
74
|
+
/**
|
|
75
|
+
* Prevent interactivity and gray out the control.
|
|
76
|
+
* @default `false`
|
|
77
|
+
*/
|
|
78
|
+
disabled?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Text displayed next to control.
|
|
81
|
+
* @default `undefined`
|
|
82
|
+
*/
|
|
83
|
+
label?: string | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* Tweakpane's internal options object.
|
|
86
|
+
*
|
|
87
|
+
* See [`BindingParams`](https://tweakpane.github.io/docs/api/types/BindingParams.html).
|
|
88
|
+
*
|
|
89
|
+
* Valid types are contingent on the type of the value `key` points to in `object`.
|
|
90
|
+
*
|
|
91
|
+
* This is intended internal use, when implementing convenience components wrapping Binding's
|
|
92
|
+
* functionality. Options of interest are instead exposed as top-level props in _Svelte
|
|
93
|
+
* Tweakpane UI_.
|
|
94
|
+
* @default `undefined`
|
|
95
|
+
*/
|
|
96
|
+
options?: import('tweakpane').NumberInputParams | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Custom color scheme.
|
|
99
|
+
*
|
|
100
|
+
* @default `undefined` \
|
|
101
|
+
* Inherits default Tweakpane theme equivalent to `ThemeUtils.presets.standard`, or the theme
|
|
102
|
+
* set with `setGlobalDefaultTheme()`.
|
|
103
|
+
*/
|
|
104
|
+
theme?: import('..').Theme | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Reference to internal Tweakpane
|
|
107
|
+
* [`BindingApi`](https://tweakpane.github.io/docs/api/classes/_internal_.BindingApi.html) for
|
|
108
|
+
* this control.
|
|
109
|
+
*
|
|
110
|
+
* This property is exposed for advanced use cases only, such as when implementing convenience
|
|
111
|
+
* components wrapping `<Binding>`'s functionality.
|
|
112
|
+
*
|
|
113
|
+
* Direct manipulation of Tweakpane's internals can break _Svelte Tweakpane UI_ abstractions.
|
|
114
|
+
*
|
|
115
|
+
* @bindable
|
|
116
|
+
* @readonly
|
|
117
|
+
*/
|
|
118
|
+
ref?: GenericSliderRef | undefined;
|
|
119
|
+
/**
|
|
120
|
+
* Imported Tweakpane `TpPluginBundle` (aliased as `Plugin`) module to automatically register in
|
|
121
|
+
* the `<Binding>`'s containing `<Pane>`.
|
|
122
|
+
*
|
|
123
|
+
* This property is exposed for advanced use cases only, such as when implementing convenience
|
|
124
|
+
* components wrapping `<Binding>`'s functionality in combination with a Tweakpane plugin.
|
|
125
|
+
*
|
|
126
|
+
* Direct manipulation of Tweakpane's internals can break _Svelte Tweakpane UI_ abstractions.
|
|
127
|
+
*
|
|
128
|
+
* @default `undefined`
|
|
129
|
+
*/
|
|
130
|
+
plugin?: import('../utils.js').Plugin | undefined;
|
|
131
|
+
},
|
|
132
|
+
'object' | 'key'
|
|
133
|
+
>,
|
|
134
|
+
'ref' | 'options' | 'plugin' | 'amount'
|
|
135
|
+
>;
|
|
136
|
+
slots: {};
|
|
137
|
+
events: {
|
|
138
|
+
/**
|
|
139
|
+
* Fires when `value` changes.
|
|
140
|
+
*
|
|
141
|
+
* _This event is provided for advanced use cases. It's usually preferred to bind to the `value` prop instead._
|
|
142
|
+
*
|
|
143
|
+
* The `event.details` payload includes a copy of the value and an `origin` field to distinguish between user-interactive changes (`internal`)
|
|
144
|
+
* and changes resulting from programmatic manipulation of the `value` (`external`).
|
|
145
|
+
*
|
|
146
|
+
* @extends ValueChangeEvent
|
|
147
|
+
* @event
|
|
148
|
+
* */
|
|
149
|
+
change: StepperChangeEvent;
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
export type StepperProps = typeof __propDef.props;
|
|
153
|
+
export type StepperEvents = typeof __propDef.events;
|
|
154
|
+
export type StepperSlots = typeof __propDef.slots;
|
|
155
|
+
/**
|
|
156
|
+
* A control for simple incremental value changes.
|
|
157
|
+
*
|
|
158
|
+
* Similar in functionality to a `<Slider>`, but with nice big buttons to increment and decrement the value.
|
|
159
|
+
*
|
|
160
|
+
* Integrates the [Stepper](https://github.com/tallneil/tweakpane-plugin-inputs/blob/main/src/stepper/plugin.ts)
|
|
161
|
+
* control from [Neil Shankar's](https://tallneil.io/) ["Inputs for Tweakpane
|
|
162
|
+
* " plugin](https://github.com/tallneil/tweakpane-plugin-inputs).
|
|
163
|
+
*
|
|
164
|
+
* Usage outside of a `<Pane>` component will implicitly wrap the stepper in `<Pane position="inline">`.
|
|
165
|
+
*
|
|
166
|
+
* Note that _Svelte Tweakpane UI_ embeds a functionally identical [fork](https://github.com/kitschpatrol/tweakpane-plugin-inputs) of the plugin with build optimizations.
|
|
167
|
+
*
|
|
168
|
+
* @emits {StepperChangeEvent} change - When `value` changes. (This event is provided for advanced use cases. Prefer binding to `value`.)
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```svelte
|
|
172
|
+
* <script lang="ts">
|
|
173
|
+
* import { Stepper } from 'svelte-tweakpane-ui';
|
|
174
|
+
* let angle = 45;
|
|
175
|
+
* </script>
|
|
176
|
+
*
|
|
177
|
+
* <Stepper bind:value={angle} label="Angle" step={45} />
|
|
178
|
+
*
|
|
179
|
+
* <div class="demo" style:--a="{angle}deg"></div>
|
|
180
|
+
*
|
|
181
|
+
* <style>
|
|
182
|
+
* div.demo {
|
|
183
|
+
* aspect-ratio: 1;
|
|
184
|
+
* width: 100%;
|
|
185
|
+
* background: linear-gradient(var(--a), magenta, orange);
|
|
186
|
+
* }
|
|
187
|
+
* </style>
|
|
188
|
+
* ```
|
|
189
|
+
*
|
|
190
|
+
* @sourceLink
|
|
191
|
+
* [Stepper.svelte](https://github.com/kitschpatrol/svelte-tweakpane-ui/blob/main/src/lib/control/Stepper.svelte)
|
|
192
|
+
*/
|
|
193
|
+
export default class Stepper extends SvelteComponent<StepperProps, StepperEvents, StepperSlots> {}
|
|
194
|
+
export {};
|
package/dist/core/Binding.svelte
CHANGED
|
@@ -44,17 +44,31 @@
|
|
|
44
44
|
_ref?.dispose();
|
|
45
45
|
});
|
|
46
46
|
const dispatch = createEventDispatcher();
|
|
47
|
+
function safeCopy(value) {
|
|
48
|
+
if (value instanceof File) {
|
|
49
|
+
return new File([value], value.name, {
|
|
50
|
+
lastModified: value.lastModified,
|
|
51
|
+
type: value.type
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (BROWSER && value instanceof HTMLImageElement) {
|
|
55
|
+
const copy2 = new Image();
|
|
56
|
+
copy2.src = value.src;
|
|
57
|
+
return copy2;
|
|
58
|
+
}
|
|
59
|
+
return copy(value);
|
|
60
|
+
}
|
|
47
61
|
let lastObject = object;
|
|
48
|
-
let lastValue =
|
|
62
|
+
let lastValue = safeCopy(object[key]);
|
|
49
63
|
let internalChange = false;
|
|
50
64
|
function onBoundValueChange(object2) {
|
|
51
65
|
if (lastObject !== object2) {
|
|
52
66
|
internalChange = false;
|
|
53
67
|
}
|
|
54
68
|
if (!shallowEqual(object2[key], lastValue)) {
|
|
55
|
-
lastValue =
|
|
69
|
+
lastValue = safeCopy(object2[key]);
|
|
56
70
|
dispatch('change', {
|
|
57
|
-
value:
|
|
71
|
+
value: safeCopy(object2[key]),
|
|
58
72
|
origin: internalChange ? 'internal' : 'external'
|
|
59
73
|
});
|
|
60
74
|
if (!internalChange && _ref) {
|
|
@@ -71,7 +85,7 @@
|
|
|
71
85
|
}
|
|
72
86
|
function onTweakpaneChange() {
|
|
73
87
|
internalChange = true;
|
|
74
|
-
object[key] =
|
|
88
|
+
object[key] = safeCopy(object[key]);
|
|
75
89
|
}
|
|
76
90
|
$: DEV && enforceReadonly(_ref, ref, 'Binding', 'ref', true);
|
|
77
91
|
$: options, $parentStore !== void 0 && index !== void 0 && create();
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export {
|
|
|
18
18
|
type CubicBezierValueTuple,
|
|
19
19
|
default as CubicBezier
|
|
20
20
|
} from './control/CubicBezier.svelte';
|
|
21
|
+
export { default as File, type FileChangeEvent, type FileValue } from './control/File.svelte';
|
|
21
22
|
export { default as Image, type ImageChangeEvent, type ImageValue } from './control/Image.svelte';
|
|
22
23
|
export {
|
|
23
24
|
default as IntervalSlider,
|
|
@@ -74,6 +75,7 @@ export {
|
|
|
74
75
|
type RotationQuaternionValueTuple
|
|
75
76
|
} from './control/RotationQuaternion.svelte';
|
|
76
77
|
export { default as Slider, type SliderChangeEvent } from './control/Slider.svelte';
|
|
78
|
+
export { default as Stepper, type StepperChangeEvent } from './control/Stepper.svelte';
|
|
77
79
|
export { default as Text, type TextChangeEvent } from './control/Text.svelte';
|
|
78
80
|
export { default as Textarea, type TextareaChangeEvent } from './control/Textarea.svelte';
|
|
79
81
|
export { default as Wheel, type WheelChangeEvent } from './control/Wheel.svelte';
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
// Components
|
|
2
1
|
export { default as Button } from './control/Button.svelte';
|
|
3
|
-
// Essentials (1st party plugins)
|
|
4
2
|
export { default as ButtonGrid } from './control/ButtonGrid.svelte';
|
|
5
3
|
export { default as Checkbox } from './control/Checkbox.svelte';
|
|
6
4
|
export { default as Color } from './control/Color.svelte';
|
|
7
5
|
export { default as CubicBezier } from './control/CubicBezier.svelte';
|
|
8
|
-
|
|
6
|
+
export { default as File } from './control/File.svelte';
|
|
9
7
|
export { default as Image } from './control/Image.svelte';
|
|
10
8
|
export { default as IntervalSlider } from './control/IntervalSlider.svelte';
|
|
11
9
|
export { default as List } from './control/List.svelte';
|
|
@@ -16,10 +14,10 @@ export { default as Ring } from './control/Ring.svelte';
|
|
|
16
14
|
export { default as RotationEuler } from './control/RotationEuler.svelte';
|
|
17
15
|
export { default as RotationQuaternion } from './control/RotationQuaternion.svelte';
|
|
18
16
|
export { default as Slider } from './control/Slider.svelte';
|
|
17
|
+
export { default as Stepper } from './control/Stepper.svelte';
|
|
19
18
|
export { default as Text } from './control/Text.svelte';
|
|
20
19
|
export { default as Textarea } from './control/Textarea.svelte';
|
|
21
20
|
export { default as Wheel } from './control/Wheel.svelte';
|
|
22
|
-
// Core (tweakpane building blocks)
|
|
23
21
|
export { default as Binding } from './core/Binding.svelte';
|
|
24
22
|
export { default as Blade } from './core/Blade.svelte';
|
|
25
23
|
export { default as Folder } from './core/Folder.svelte';
|
|
@@ -27,7 +25,6 @@ export { default as Pane } from './core/Pane.svelte';
|
|
|
27
25
|
export { default as Separator } from './core/Separator.svelte';
|
|
28
26
|
export { default as TabGroup } from './core/TabGroup.svelte';
|
|
29
27
|
export { default as TabPage } from './core/TabPage.svelte';
|
|
30
|
-
// Extra (svelte convenience components)
|
|
31
28
|
export { default as AutoObject } from './extra/AutoObject.svelte';
|
|
32
29
|
export { default as AutoValue } from './extra/AutoValue.svelte';
|
|
33
30
|
export { default as Element } from './extra/Element.svelte';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-tweakpane-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A Svelte component library wrapping UI elements from Tweakpane, plus some additional functionality for convenience and flexibility.",
|
|
6
6
|
"repository": {
|
|
@@ -47,6 +47,10 @@
|
|
|
47
47
|
"types": "./dist/control/CubicBezier.svelte.d.ts",
|
|
48
48
|
"svelte": "./dist/control/CubicBezier.svelte"
|
|
49
49
|
},
|
|
50
|
+
"./File.svelte": {
|
|
51
|
+
"types": "./dist/control/File.svelte.d.ts",
|
|
52
|
+
"svelte": "./dist/control/File.svelte"
|
|
53
|
+
},
|
|
50
54
|
"./Image.svelte": {
|
|
51
55
|
"types": "./dist/control/Image.svelte.d.ts",
|
|
52
56
|
"svelte": "./dist/control/Image.svelte"
|
|
@@ -83,6 +87,10 @@
|
|
|
83
87
|
"types": "./dist/control/Slider.svelte.d.ts",
|
|
84
88
|
"svelte": "./dist/control/Slider.svelte"
|
|
85
89
|
},
|
|
90
|
+
"./Stepper.svelte": {
|
|
91
|
+
"types": "./dist/control/Stepper.svelte.d.ts",
|
|
92
|
+
"svelte": "./dist/control/Stepper.svelte"
|
|
93
|
+
},
|
|
86
94
|
"./Text.svelte": {
|
|
87
95
|
"types": "./dist/control/Text.svelte.d.ts",
|
|
88
96
|
"svelte": "./dist/control/Text.svelte"
|
|
@@ -187,49 +195,51 @@
|
|
|
187
195
|
"dependencies": {
|
|
188
196
|
"@kitschpatrol/tweakpane-plugin-camerakit": "0.3.1-beta.2",
|
|
189
197
|
"@kitschpatrol/tweakpane-plugin-essentials": "0.2.2-beta.2",
|
|
198
|
+
"@kitschpatrol/tweakpane-plugin-file-import": "1.1.2-beta.1",
|
|
190
199
|
"@kitschpatrol/tweakpane-plugin-image": "2.0.1-beta.4",
|
|
200
|
+
"@kitschpatrol/tweakpane-plugin-inputs": "1.0.4-beta.3",
|
|
191
201
|
"@kitschpatrol/tweakpane-plugin-profiler": "0.4.2-beta.2",
|
|
192
202
|
"@kitschpatrol/tweakpane-plugin-rotation": "0.2.1-beta.1",
|
|
193
203
|
"@kitschpatrol/tweakpane-plugin-textarea": "2.0.1-beta.1",
|
|
194
204
|
"@kitschpatrol/tweakpane-plugin-waveform": "1.0.4-beta.2",
|
|
195
|
-
"@tweakpane/core": "2.0.
|
|
196
|
-
"esm-env": "1.
|
|
197
|
-
"fast-copy": "3.0.2",
|
|
198
|
-
"fast-equals": "5.0.1",
|
|
199
|
-
"nanoid": "5.0.
|
|
200
|
-
"svelte-persisted-store": "0.
|
|
201
|
-
"tweakpane": "4.0.
|
|
205
|
+
"@tweakpane/core": "2.0.5",
|
|
206
|
+
"esm-env": "^1.2.1",
|
|
207
|
+
"fast-copy": "^3.0.2",
|
|
208
|
+
"fast-equals": "^5.0.1",
|
|
209
|
+
"nanoid": "^5.0.9",
|
|
210
|
+
"svelte-persisted-store": "0.12.0",
|
|
211
|
+
"tweakpane": "4.0.5"
|
|
202
212
|
},
|
|
203
213
|
"devDependencies": {
|
|
204
|
-
"@kitschpatrol/shared-config": "4.7.
|
|
205
|
-
"@phenomnomnominal/tsquery": "6.1.3",
|
|
206
|
-
"@playwright/test": "1.
|
|
207
|
-
"@stkb/rewrap": "0.1.0",
|
|
208
|
-
"@sveltejs/adapter-static": "3.0.
|
|
209
|
-
"@sveltejs/kit": "2.
|
|
210
|
-
"@sveltejs/package": "2.3.
|
|
211
|
-
"@sveltejs/vite-plugin-svelte": "3.1.2",
|
|
212
|
-
"@types/eslint": "8.56.12",
|
|
213
|
-
"@types/fs-extra": "11.0.4",
|
|
214
|
-
"@types/node": "18.19.
|
|
215
|
-
"bumpp": "9.
|
|
216
|
-
"eslint": "8.57.1",
|
|
217
|
-
"fs-extra": "11.2.0",
|
|
218
|
-
"glob": "11.0.0",
|
|
219
|
-
"postcss-html": "1.7.0",
|
|
220
|
-
"publint": "0.2.
|
|
221
|
-
"read-package-up": "11.0.0",
|
|
222
|
-
"remark-mdat": "0.7.
|
|
223
|
-
"svelte": "4.2.19",
|
|
224
|
-
"svelte-check": "4.
|
|
214
|
+
"@kitschpatrol/shared-config": "^4.7.12",
|
|
215
|
+
"@phenomnomnominal/tsquery": "^6.1.3",
|
|
216
|
+
"@playwright/test": "^1.49.1",
|
|
217
|
+
"@stkb/rewrap": "^0.1.0",
|
|
218
|
+
"@sveltejs/adapter-static": "^3.0.6",
|
|
219
|
+
"@sveltejs/kit": "^2.10.1",
|
|
220
|
+
"@sveltejs/package": "^2.3.7",
|
|
221
|
+
"@sveltejs/vite-plugin-svelte": "^3.1.2",
|
|
222
|
+
"@types/eslint": "^8.56.12",
|
|
223
|
+
"@types/fs-extra": "^11.0.4",
|
|
224
|
+
"@types/node": "^18.19.68",
|
|
225
|
+
"bumpp": "^9.9.0",
|
|
226
|
+
"eslint": "^8.57.1",
|
|
227
|
+
"fs-extra": "^11.2.0",
|
|
228
|
+
"glob": "^11.0.0",
|
|
229
|
+
"postcss-html": "^1.7.0",
|
|
230
|
+
"publint": "^0.2.12",
|
|
231
|
+
"read-package-up": "^11.0.0",
|
|
232
|
+
"remark-mdat": "^0.7.4",
|
|
233
|
+
"svelte": "^4.2.19",
|
|
234
|
+
"svelte-check": "^4.1.1",
|
|
225
235
|
"svelte-language-server": "0.17.0",
|
|
226
|
-
"svelte2tsx": "0.7.
|
|
227
|
-
"ts-morph": "24.0.0",
|
|
228
|
-
"tslib": "2.8.
|
|
229
|
-
"tsx": "4.19.
|
|
230
|
-
"typescript": "5.6.3",
|
|
231
|
-
"vite": "5.4.
|
|
232
|
-
"yaml": "2.6.
|
|
236
|
+
"svelte2tsx": "^0.7.30",
|
|
237
|
+
"ts-morph": "^24.0.0",
|
|
238
|
+
"tslib": "^2.8.1",
|
|
239
|
+
"tsx": "^4.19.2",
|
|
240
|
+
"typescript": "~5.6.3",
|
|
241
|
+
"vite": "^5.4.11",
|
|
242
|
+
"yaml": "^2.6.1"
|
|
233
243
|
},
|
|
234
244
|
"publishConfig": {
|
|
235
245
|
"access": "public"
|
package/readme.md
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
|
|
35
35
|
## Overview
|
|
36
36
|
|
|
37
|
-
🎛️ **_Svelte Tweakpane UI_** wraps user-interface elements from the excellent [Tweakpane](https://tweakpane.github.io/docs/) library in a collection of <!-- component-count -->
|
|
37
|
+
🎛️ **_Svelte Tweakpane UI_** wraps user-interface elements from the excellent [Tweakpane](https://tweakpane.github.io/docs/) library in a collection of <!-- component-count -->33<!-- /component-count --> idiomatic, reactive, type-safe, carefully-crafted, and obsessively-documented [Svelte](https://svelte.dev) components.
|
|
38
38
|
|
|
39
39
|
The library makes it easy to quickly and declaratively add knobs and dials to your projects using components that feel like they were made for Svelte. It also augments Tweakpane with a few [extra features](https://kitschpatrol.com/svelte-tweakpane-ui/docs/features) for your convenience and enjoyment.
|
|
40
40
|
|
|
@@ -102,6 +102,8 @@ npm install svelte-tweakpane-ui
|
|
|
102
102
|
A color picker.
|
|
103
103
|
- **[CubicBezier](https://kitschpatrol.com/svelte-tweakpane-ui/docs/components/cubicbezier)**\
|
|
104
104
|
A control for editing a bezier curve. Ideal for tweaking animation easing values.
|
|
105
|
+
- **[File](https://kitschpatrol.com/svelte-tweakpane-ui/docs/components/file)**\
|
|
106
|
+
A file input control.
|
|
105
107
|
- **[Image](https://kitschpatrol.com/svelte-tweakpane-ui/docs/components/image)**\
|
|
106
108
|
An image input control.
|
|
107
109
|
- **[IntervalSlider](https://kitschpatrol.com/svelte-tweakpane-ui/docs/components/intervalslider)**\
|
|
@@ -120,6 +122,8 @@ npm install svelte-tweakpane-ui
|
|
|
120
122
|
Integrates the [quaternion rotation](https://github.com/0b5vr/tweakpane-plugin-rotation/blob/dev/src/RotationInputPluginQuaternion.ts) control from [0b5vr](https://0b5vr.com)'s [tweakpane-plugin-rotation](https://github.com/0b5vr/tweakpane-plugin-rotation).
|
|
121
123
|
- **[Slider](https://kitschpatrol.com/svelte-tweakpane-ui/docs/components/slider)**\
|
|
122
124
|
A slider component providing fine-grained control over numeric values.
|
|
125
|
+
- **[Stepper](https://kitschpatrol.com/svelte-tweakpane-ui/docs/components/stepper)**\
|
|
126
|
+
A control for simple incremental value changes.
|
|
123
127
|
- **[Text](https://kitschpatrol.com/svelte-tweakpane-ui/docs/components/text)**\
|
|
124
128
|
A text field, in the spirit of the HTML `<input type="text">` element.
|
|
125
129
|
- **[Textarea](https://kitschpatrol.com/svelte-tweakpane-ui/docs/components/textarea)**\
|