fragment-tools 0.1.19 → 0.2.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/bin/index.js +1 -0
- package/package.json +5 -6
- package/src/cli/templates/three-fragment/index.js +6 -6
- package/src/cli/templates/three-orthographic/index.js +3 -3
- package/src/cli/templates/three-perspective/index.js +3 -3
- package/src/client/app/actions/resize.js +14 -0
- package/src/client/app/components/HintLoading.svelte +94 -0
- package/src/client/app/components/HintPaused.svelte +88 -0
- package/src/client/app/components/HintRecord.svelte +62 -0
- package/src/client/app/components/IconLocked.svelte +51 -0
- package/src/client/app/components/IconTriggers.svelte +48 -0
- package/src/client/app/components/Init.svelte +14 -27
- package/src/client/app/components/KeyBinding.svelte +3 -6
- package/src/client/app/helpers.js +4 -40
- package/src/client/app/hooks.js +41 -17
- package/src/client/app/inputs/MIDI.js +2 -1
- package/src/client/app/lib/canvas-recorder/CanvasRecorder.js +6 -1
- package/src/client/app/lib/gl/Renderer.js +1 -0
- package/src/client/app/lib/svelte-json-tree/ErrorNode.svelte +28 -0
- package/src/client/app/lib/svelte-json-tree/ErrorStack.svelte +31 -0
- package/src/client/app/lib/svelte-json-tree/Expandable.svelte +25 -0
- package/src/client/app/lib/svelte-json-tree/JSONArrayNode.svelte +38 -0
- package/src/client/app/lib/svelte-json-tree/JSONArrow.svelte +47 -0
- package/src/client/app/lib/svelte-json-tree/JSONFunctionNode.svelte +114 -0
- package/src/client/app/lib/svelte-json-tree/JSONIterableArrayNode.svelte +60 -0
- package/src/client/app/lib/svelte-json-tree/JSONIterableMapNode.svelte +87 -0
- package/src/client/app/lib/svelte-json-tree/JSONNested.svelte +94 -0
- package/src/client/app/lib/svelte-json-tree/JSONNode.svelte +91 -0
- package/src/client/app/lib/svelte-json-tree/JSONObjectNode.svelte +40 -0
- package/src/client/app/lib/svelte-json-tree/JSONStringNode.svelte +31 -0
- package/src/client/app/lib/svelte-json-tree/JSONValueNode.svelte +31 -0
- package/src/client/app/lib/svelte-json-tree/PreviewList.svelte +38 -0
- package/src/client/app/lib/svelte-json-tree/RegExpNode.svelte +42 -0
- package/src/client/app/lib/svelte-json-tree/Root.svelte +75 -0
- package/src/client/app/lib/svelte-json-tree/Summary.svelte +9 -0
- package/src/client/app/lib/svelte-json-tree/TypedArrayNode.svelte +56 -0
- package/src/client/app/lib/svelte-json-tree/index.js +1 -0
- package/src/client/app/lib/svelte-json-tree/utils.js +57 -0
- package/src/client/app/modules/Console/ConsoleLine.svelte +12 -11
- package/src/client/app/modules/Console.svelte +82 -17
- package/src/client/app/modules/Exports.svelte +48 -48
- package/src/client/app/modules/MidiPanel.svelte +12 -19
- package/src/client/app/modules/Monitor.svelte +147 -55
- package/src/client/app/modules/Params.svelte +127 -80
- package/src/client/app/renderers/2DRenderer.js +1 -0
- package/src/client/app/renderers/FragmentRenderer.js +1 -1
- package/src/client/app/renderers/P5GLRenderer.js +11 -5
- package/src/client/app/renderers/P5Renderer.js +7 -3
- package/src/client/app/renderers/THREERenderer.js +42 -79
- package/src/client/app/state/Sketch.svelte.js +538 -0
- package/src/client/app/state/errors.svelte.js +17 -0
- package/src/client/app/state/exports.svelte.js +152 -0
- package/src/client/app/state/layout.svelte.js +205 -0
- package/src/client/app/state/monitors.svelte.js +36 -0
- package/src/client/app/state/renderers.svelte.js +77 -0
- package/src/client/app/state/rendering.svelte.js +697 -0
- package/src/client/app/state/sketches.svelte.js +73 -0
- package/src/client/app/state/utils.svelte.js +65 -0
- package/src/client/app/ui/Build.svelte +53 -60
- package/src/client/app/ui/ErrorOverlay.svelte +2 -2
- package/src/client/app/ui/Field.svelte +63 -189
- package/src/client/app/ui/FieldGroup.svelte +4 -5
- package/src/client/app/ui/FieldSection.svelte +14 -9
- package/src/client/app/ui/FieldSpace.svelte +1 -1
- package/src/client/app/ui/FieldTrigger.svelte +86 -84
- package/src/client/app/ui/FieldTriggers.svelte +25 -24
- package/src/client/app/ui/FloatingParams.svelte +50 -12
- package/src/client/app/ui/Layout.svelte +24 -13
- package/src/client/app/ui/LayoutColumn.svelte +2 -2
- package/src/client/app/ui/LayoutComponent.svelte +86 -195
- package/src/client/app/ui/LayoutResizer.svelte +25 -37
- package/src/client/app/ui/LayoutRoot.svelte +3 -5
- package/src/client/app/ui/LayoutRow.svelte +2 -2
- package/src/client/app/ui/LayoutToolbar.svelte +17 -76
- package/src/client/app/ui/Module.svelte +31 -35
- package/src/client/app/ui/ModuleHeaderAction.svelte +23 -16
- package/src/client/app/ui/ModuleHeaderButton.svelte +3 -3
- package/src/client/app/ui/ModuleHeaderSelect.svelte +4 -12
- package/src/client/app/ui/ModuleRenderer.svelte +84 -22
- package/src/client/app/ui/ParamsOutput.svelte +61 -77
- package/src/client/app/ui/Preview.svelte +15 -4
- package/src/client/app/ui/SelectChevrons.svelte +1 -2
- package/src/client/app/ui/SketchRenderer.svelte +89 -701
- package/src/client/app/ui/SketchSelect.svelte +14 -49
- package/src/client/app/ui/fields/ButtonInput.svelte +14 -11
- package/src/client/app/ui/fields/CheckboxInput.svelte +5 -12
- package/src/client/app/ui/fields/ColorInput.svelte +46 -121
- package/src/client/app/ui/fields/FieldInputRow.svelte +5 -1
- package/src/client/app/ui/fields/ImageInput.svelte +14 -14
- package/src/client/app/ui/fields/Input.svelte +19 -25
- package/src/client/app/ui/fields/IntervalInput.svelte +22 -22
- package/src/client/app/ui/fields/NumberInput.svelte +32 -38
- package/src/client/app/ui/fields/ProgressInput.svelte +14 -13
- package/src/client/app/ui/fields/Select.svelte +34 -45
- package/src/client/app/ui/fields/TextInput.svelte +10 -6
- package/src/client/app/ui/fields/VectorInput.svelte +25 -30
- package/src/client/app/utils/canvas.utils.js +8 -8
- package/src/client/app/utils/color.utils.js +46 -13
- package/src/client/app/utils/fields.utils.js +1 -1
- package/src/client/app/utils/glsl.utils.js +1 -1
- package/src/client/app/utils/glslErrors.js +1 -1
- package/src/client/main.js +2 -2
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { displayError } from '../state/errors.svelte.js';
|
|
2
|
+
import { sketches as all } from '@fragment/sketches';
|
|
3
|
+
import Sketch from './Sketch.svelte.js';
|
|
4
|
+
import { rendering } from './rendering.svelte.js';
|
|
5
|
+
import { removeHotListeners } from '../triggers/index.js';
|
|
6
|
+
|
|
7
|
+
class SketchesManager {
|
|
8
|
+
sketches = $state({});
|
|
9
|
+
keys = $derived(Object.keys(this.sketches));
|
|
10
|
+
count = $derived(this.keys.length);
|
|
11
|
+
|
|
12
|
+
async loadSketch(collection, key) {
|
|
13
|
+
try {
|
|
14
|
+
let sketch = await collection[key]();
|
|
15
|
+
|
|
16
|
+
await rendering.preloadRenderer({
|
|
17
|
+
renderingMode: sketch.rendering,
|
|
18
|
+
renderer: sketch.renderer,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return sketch;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error(error);
|
|
24
|
+
displayError(error, key);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async loadAll(collection) {
|
|
29
|
+
const keys = [...Object.keys(collection)];
|
|
30
|
+
|
|
31
|
+
Object.keys(this.sketches).forEach((key) => {
|
|
32
|
+
removeHotListeners(key);
|
|
33
|
+
|
|
34
|
+
if (!keys.includes(key)) {
|
|
35
|
+
delete this.sketches[key];
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const loadedSketches = await Promise.all(
|
|
40
|
+
keys.map((key) => this.loadSketch(collection, key)),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const newSketches = keys.reduce((all, key, index) => {
|
|
44
|
+
if (loadedSketches[index]) {
|
|
45
|
+
all[key] = loadedSketches[index];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return all;
|
|
49
|
+
}, {});
|
|
50
|
+
|
|
51
|
+
const newInstancedSketches = Object.keys(newSketches).reduce(
|
|
52
|
+
(all, key, index) => {
|
|
53
|
+
const prevSketch = this.sketches[key];
|
|
54
|
+
|
|
55
|
+
const instanced = new Sketch({
|
|
56
|
+
key,
|
|
57
|
+
instance: newSketches[key],
|
|
58
|
+
previous: prevSketch,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
all[key] = instanced;
|
|
62
|
+
|
|
63
|
+
return all;
|
|
64
|
+
},
|
|
65
|
+
{},
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
this.sketches = newInstancedSketches;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export let sketchesManager = new SketchesManager();
|
|
73
|
+
sketchesManager.loadAll(all);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export function persist(key, data) {
|
|
2
|
+
try {
|
|
3
|
+
window.localStorage.setItem(`fragment.${key}`, JSON.stringify(data));
|
|
4
|
+
} catch (err) {
|
|
5
|
+
throw err;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function hydrate(key, target = {}, defaultValue = {}) {
|
|
10
|
+
try {
|
|
11
|
+
const storageKey = `fragment.${key}`;
|
|
12
|
+
const item = window.localStorage.getItem(storageKey);
|
|
13
|
+
|
|
14
|
+
if (item) {
|
|
15
|
+
const data = JSON.parse(item);
|
|
16
|
+
|
|
17
|
+
if (target && typeof data === 'object') {
|
|
18
|
+
Object.keys(data).forEach((key) => {
|
|
19
|
+
if (target[key] !== undefined) {
|
|
20
|
+
target[key] = data[key];
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return defaultValue;
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.error(err);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function isObject(item) {
|
|
35
|
+
return item && typeof item === 'object';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function isFunction(item) {
|
|
39
|
+
return item && typeof item === 'function';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function deepAssign(target, source) {
|
|
43
|
+
for (const key in source) {
|
|
44
|
+
if (isObject(source[key]) && isObject(target[key])) {
|
|
45
|
+
deepAssign(target[key], source[key]);
|
|
46
|
+
} else {
|
|
47
|
+
Object.assign(target, { [key]: source[key] });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function deepEqual(target, source) {
|
|
53
|
+
if (isObject(target) && isObject(target)) {
|
|
54
|
+
let isEqual = true;
|
|
55
|
+
for (const key in source) {
|
|
56
|
+
if (isEqual) {
|
|
57
|
+
isEqual = deepEqual(target[key], source[key]);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return isEqual;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return target === source;
|
|
65
|
+
}
|
|
@@ -3,60 +3,50 @@
|
|
|
3
3
|
|
|
4
4
|
import Monitor from '../modules/Monitor.svelte';
|
|
5
5
|
import Params from '../modules/Params.svelte';
|
|
6
|
-
import { layout } from '../stores/layout';
|
|
7
|
-
import { override, preview } from '../stores/rendering';
|
|
8
|
-
import { sketches, sketchesKeys } from '../stores/sketches';
|
|
9
6
|
import FloatingParams from './FloatingParams.svelte';
|
|
10
7
|
import Column from './LayoutColumn.svelte';
|
|
11
8
|
import Row from './LayoutRow.svelte';
|
|
9
|
+
import { sketchesManager } from '../state/sketches.svelte';
|
|
10
|
+
import { rendering } from '../state/rendering.svelte';
|
|
12
11
|
|
|
13
12
|
console.log(`Made with Fragment. https://fragment.tools`);
|
|
14
13
|
|
|
15
|
-
let
|
|
16
|
-
let defaultGUIConfig = {
|
|
17
|
-
position: 'float',
|
|
18
|
-
align: 'right',
|
|
19
|
-
size: 0.3,
|
|
20
|
-
output: false,
|
|
21
|
-
hidden: false,
|
|
22
|
-
};
|
|
14
|
+
let sketchKey = $derived(sketchesManager.keys[0]);
|
|
23
15
|
|
|
24
|
-
let
|
|
25
|
-
$: sketchKey = $layout.previewing && $preview ? $preview : $sketchesKeys[0];
|
|
26
|
-
$: sketch = $sketches[sketchKey];
|
|
16
|
+
let sketch = $derived(sketchesManager.sketches[sketchKey]);
|
|
27
17
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
18
|
+
let gui = $derived(sketch?.buildConfig?.gui);
|
|
19
|
+
let guiOutput = $derived(gui?.output);
|
|
20
|
+
let guiAlign = $derived(gui?.align ?? 'right');
|
|
21
|
+
let guiHidden = $derived(gui?.hidden);
|
|
22
|
+
let guiSize = $derived(gui?.size ?? 0.25);
|
|
23
|
+
let guiMinimize = $derived(gui?.minimize);
|
|
24
|
+
let guiPosition = $derived(gui?.position);
|
|
25
|
+
let styles = $derived(sketch?.buildConfig?.styles ?? '');
|
|
36
26
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
};
|
|
42
|
-
}
|
|
27
|
+
/** @type {HTMLHeadElement} */
|
|
28
|
+
let head;
|
|
29
|
+
/** @type {HTMLStyleElement} */
|
|
30
|
+
let style;
|
|
43
31
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
head = document.getElementsByTagName('head')[0];
|
|
32
|
+
$effect(() => {
|
|
33
|
+
rendering.override(sketch?.buildConfig);
|
|
34
|
+
});
|
|
48
35
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
36
|
+
$effect(() => {
|
|
37
|
+
if (styles !== '') {
|
|
38
|
+
head = document.getElementsByTagName('head')[0];
|
|
52
39
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
style.appendChild(document.createTextNode(styles));
|
|
56
|
-
head.appendChild(style);
|
|
40
|
+
if (style) {
|
|
41
|
+
head.removeChild(style);
|
|
57
42
|
}
|
|
43
|
+
|
|
44
|
+
style = document.createElement('style');
|
|
45
|
+
style.setAttribute('type', 'text/css');
|
|
46
|
+
style.appendChild(document.createTextNode(styles));
|
|
47
|
+
head.appendChild(style);
|
|
58
48
|
}
|
|
59
|
-
}
|
|
49
|
+
});
|
|
60
50
|
|
|
61
51
|
onDestroy(() => {
|
|
62
52
|
if (style && head) {
|
|
@@ -65,34 +55,37 @@
|
|
|
65
55
|
});
|
|
66
56
|
</script>
|
|
67
57
|
|
|
68
|
-
{#if
|
|
69
|
-
{#if
|
|
58
|
+
{#if sketch}
|
|
59
|
+
{#if guiPosition === 'fixed'}
|
|
70
60
|
<Row>
|
|
71
|
-
{#if
|
|
72
|
-
<Column size={
|
|
73
|
-
<
|
|
61
|
+
{#if guiAlign === 'left'}
|
|
62
|
+
<Column size={guiSize}>
|
|
63
|
+
<Params />
|
|
74
64
|
</Column>
|
|
75
|
-
<Column size={
|
|
76
|
-
<
|
|
65
|
+
<Column size={1 - guiSize}>
|
|
66
|
+
<Monitor params={{ selected: sketchKey }} />
|
|
77
67
|
</Column>
|
|
78
68
|
{:else}
|
|
79
|
-
<Column size={
|
|
80
|
-
<
|
|
69
|
+
<Column size={1 - guiSize}>
|
|
70
|
+
<Monitor params={{ selected: sketchKey }} />
|
|
81
71
|
</Column>
|
|
82
|
-
<Column size={
|
|
83
|
-
<
|
|
72
|
+
<Column size={guiSize}>
|
|
73
|
+
<Params />
|
|
84
74
|
</Column>
|
|
85
75
|
{/if}
|
|
86
76
|
</Row>
|
|
87
77
|
{:else}
|
|
88
|
-
<
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
78
|
+
<Row>
|
|
79
|
+
<Monitor headless {sketchKey} params={{ selected: sketchKey }} />
|
|
80
|
+
{#if gui}
|
|
81
|
+
<FloatingParams
|
|
82
|
+
output={guiOutput}
|
|
83
|
+
align={guiAlign}
|
|
84
|
+
size={guiSize}
|
|
85
|
+
hidden={guiHidden}
|
|
86
|
+
minimize={guiMinimize}
|
|
87
|
+
/>
|
|
88
|
+
{/if}
|
|
89
|
+
</Row>
|
|
95
90
|
{/if}
|
|
96
|
-
{:else}
|
|
97
|
-
<Monitor hasHeader={false} />
|
|
98
91
|
{/if}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { clearErrors } from '../
|
|
2
|
+
import { clearErrors } from '../state/errors.svelte';
|
|
3
3
|
|
|
4
4
|
export let error;
|
|
5
5
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
? error.stack
|
|
21
21
|
.split('\n')
|
|
22
22
|
.filter((line, i, s) => (s.length === 1 ? true : i !== 0))
|
|
23
|
-
.filter((line) => !line.includes('/app'))
|
|
23
|
+
.filter((line) => !line.includes('/app/'))
|
|
24
24
|
.map((line) => {
|
|
25
25
|
// remove path to file in URL
|
|
26
26
|
line = line.replace(
|
|
@@ -27,66 +27,42 @@
|
|
|
27
27
|
</script>
|
|
28
28
|
|
|
29
29
|
<script>
|
|
30
|
-
import { createEventDispatcher } from 'svelte';
|
|
31
|
-
|
|
32
30
|
import FieldSection from './FieldSection.svelte';
|
|
33
31
|
import FieldTriggers from './FieldTriggers.svelte';
|
|
34
32
|
import { download } from '../utils/file.utils.js';
|
|
35
33
|
import { map } from '../utils/math.utils';
|
|
36
34
|
import frameDebounce from '../lib/helpers/frameDebounce.js';
|
|
37
|
-
import { getStore } from '../stores/utils';
|
|
38
|
-
import { writable } from 'svelte/store';
|
|
39
35
|
import { inferFieldType } from '../utils/fields.utils.js';
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
if (!$store.props[key]) {
|
|
63
|
-
$store.props[key] = { triggers: [] };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
let triggers = writable(
|
|
67
|
-
$store.props[key].triggers.filter(
|
|
68
|
-
(trigger) => trigger.inputType !== undefined,
|
|
69
|
-
),
|
|
70
|
-
);
|
|
71
|
-
triggers.subscribe((all) => {
|
|
72
|
-
store.update((curr) => {
|
|
73
|
-
curr.props[key].triggers = all;
|
|
74
|
-
|
|
75
|
-
return curr;
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
const dispatch = createEventDispatcher();
|
|
36
|
+
import IconTriggers from '../components/IconTriggers.svelte';
|
|
37
|
+
import IconLocked from '../components/IconLocked.svelte';
|
|
38
|
+
|
|
39
|
+
let {
|
|
40
|
+
key,
|
|
41
|
+
value = null,
|
|
42
|
+
initialValue = value,
|
|
43
|
+
context = null,
|
|
44
|
+
params = $bindable({}),
|
|
45
|
+
type = null,
|
|
46
|
+
disabled = false,
|
|
47
|
+
displayName = undefined,
|
|
48
|
+
index = null,
|
|
49
|
+
onchange,
|
|
50
|
+
onclick = () => {},
|
|
51
|
+
children,
|
|
52
|
+
triggers = [],
|
|
53
|
+
} = $props();
|
|
54
|
+
|
|
55
|
+
let showTriggers = $state(false);
|
|
80
56
|
|
|
81
57
|
const onTriggers = {
|
|
82
58
|
checkbox: () => {
|
|
83
59
|
value = !value;
|
|
84
60
|
|
|
85
|
-
|
|
61
|
+
onchange(value);
|
|
86
62
|
},
|
|
87
63
|
button: (event) => {
|
|
88
64
|
value(event);
|
|
89
|
-
|
|
65
|
+
onclick(event);
|
|
90
66
|
},
|
|
91
67
|
download: (event) => {
|
|
92
68
|
let [data, filename] = value(event);
|
|
@@ -105,32 +81,23 @@
|
|
|
105
81
|
let step = params.step ? params.step : 1;
|
|
106
82
|
let value = Math.round(v * (1 / step)) / (1 / step);
|
|
107
83
|
|
|
108
|
-
|
|
84
|
+
onchange(value);
|
|
109
85
|
}
|
|
110
86
|
},
|
|
111
87
|
};
|
|
112
88
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
89
|
+
let fieldType = $derived(inferFieldType({ type, value, params, key }));
|
|
90
|
+
let fieldProps = $derived(composeFieldProps(params, disabled));
|
|
91
|
+
let onTrigger = $derived(frameDebounce(onTriggers[fieldType]));
|
|
92
|
+
let input = $derived(fields[fieldType]);
|
|
93
|
+
let triggerable = $derived(
|
|
118
94
|
params.triggerable !== false &&
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const isButton = fieldType === fieldTypes.BUTTON;
|
|
126
|
-
if ((isDownload || isButton) && params.label == undefined) {
|
|
127
|
-
fieldProps.label = isDownload ? 'download' : 'run';
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
$: xxsmall = offsetWidth < 200;
|
|
131
|
-
$: xsmall = !xxsmall && offsetWidth < 260;
|
|
132
|
-
$: small = !xxsmall && !xsmall && offsetWidth < 320;
|
|
133
|
-
$: triggersActive = $triggers.length > 0;
|
|
95
|
+
((fieldType === fieldTypes.NUMBER &&
|
|
96
|
+
isFinite(params.min) &&
|
|
97
|
+
isFinite(params.max)) ||
|
|
98
|
+
fieldType === fieldTypes.BUTTON),
|
|
99
|
+
);
|
|
100
|
+
let triggersActive = $derived(triggers.length > 0);
|
|
134
101
|
|
|
135
102
|
function toggleTriggers(event) {
|
|
136
103
|
event.preventDefault();
|
|
@@ -153,140 +120,45 @@
|
|
|
153
120
|
<div
|
|
154
121
|
class="field"
|
|
155
122
|
class:disabled
|
|
156
|
-
class:xxsmall
|
|
157
|
-
class:xsmall
|
|
158
|
-
class:small
|
|
159
123
|
class:changed={!disabled && hasChanged(initialValue, value)}
|
|
160
|
-
bind:offsetWidth
|
|
161
124
|
style="--index: {index};"
|
|
162
125
|
>
|
|
163
126
|
<FieldSection
|
|
164
127
|
{key}
|
|
165
128
|
{displayName}
|
|
166
129
|
interactive={triggerable}
|
|
167
|
-
|
|
130
|
+
onclick={toggleTriggers}
|
|
168
131
|
{disabled}
|
|
169
132
|
>
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
<
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
/>
|
|
192
|
-
<path
|
|
193
|
-
stroke="currentColor"
|
|
194
|
-
stroke-linecap="round"
|
|
195
|
-
stroke-linejoin="round"
|
|
196
|
-
stroke-width="1.5"
|
|
197
|
-
d="M4.75 16H12.25"
|
|
198
|
-
/>
|
|
199
|
-
<path
|
|
200
|
-
stroke="currentColor"
|
|
201
|
-
stroke-linecap="round"
|
|
202
|
-
stroke-linejoin="round"
|
|
203
|
-
stroke-width="1.5"
|
|
204
|
-
d="M17.75 16H19.25"
|
|
205
|
-
/>
|
|
206
|
-
<circle
|
|
207
|
-
cx="10"
|
|
208
|
-
cy="8"
|
|
209
|
-
r="2.25"
|
|
210
|
-
stroke="currentColor"
|
|
211
|
-
stroke-linecap="round"
|
|
212
|
-
stroke-linejoin="round"
|
|
213
|
-
stroke-width="1.5"
|
|
214
|
-
/>
|
|
215
|
-
<circle
|
|
216
|
-
cx="15"
|
|
217
|
-
cy="16"
|
|
218
|
-
r="2.25"
|
|
219
|
-
stroke="currentColor"
|
|
220
|
-
stroke-linecap="round"
|
|
221
|
-
stroke-linejoin="round"
|
|
222
|
-
stroke-width="1.5"
|
|
223
|
-
/>
|
|
224
|
-
</svg>
|
|
225
|
-
</button>
|
|
226
|
-
{/if}
|
|
227
|
-
{#if fieldType === 'vec' && !disabled}
|
|
228
|
-
<button
|
|
229
|
-
class="field__action field__action--lock"
|
|
230
|
-
on:click={() => (params.locked = !params.locked)}
|
|
231
|
-
>
|
|
232
|
-
{#if params.locked}
|
|
233
|
-
<svg
|
|
234
|
-
class="action__icon"
|
|
235
|
-
width="16"
|
|
236
|
-
height="16"
|
|
237
|
-
fill="none"
|
|
238
|
-
viewBox="0 0 24 24"
|
|
239
|
-
>
|
|
240
|
-
<path
|
|
241
|
-
stroke="currentColor"
|
|
242
|
-
stroke-linecap="round"
|
|
243
|
-
stroke-linejoin="round"
|
|
244
|
-
stroke-width="1.5"
|
|
245
|
-
d="M5.75 11.75C5.75 11.1977 6.19772 10.75 6.75 10.75H17.25C17.8023 10.75 18.25 11.1977 18.25 11.75V17.25C18.25 18.3546 17.3546 19.25 16.25 19.25H7.75C6.64543 19.25 5.75 18.3546 5.75 17.25V11.75Z"
|
|
246
|
-
/>
|
|
247
|
-
<path
|
|
248
|
-
stroke="currentColor"
|
|
249
|
-
stroke-linecap="round"
|
|
250
|
-
stroke-linejoin="round"
|
|
251
|
-
stroke-width="1.5"
|
|
252
|
-
d="M7.75 10.5V10.3427C7.75 8.78147 7.65607 7.04125 8.74646 5.9239C9.36829 5.2867 10.3745 4.75 12 4.75C13.6255 4.75 14.6317 5.2867 15.2535 5.9239C16.3439 7.04125 16.25 8.78147 16.25 10.3427V10.5"
|
|
253
|
-
/>
|
|
254
|
-
</svg>
|
|
255
|
-
{:else}
|
|
256
|
-
<svg
|
|
257
|
-
class="action__icon"
|
|
258
|
-
width="16"
|
|
259
|
-
height="16"
|
|
260
|
-
fill="none"
|
|
261
|
-
viewBox="0 0 24 24"
|
|
262
|
-
>
|
|
263
|
-
<path
|
|
264
|
-
stroke="currentColor"
|
|
265
|
-
stroke-linecap="round"
|
|
266
|
-
stroke-linejoin="round"
|
|
267
|
-
stroke-width="1.5"
|
|
268
|
-
d="M5.75 11.75C5.75 11.1977 6.19772 10.75 6.75 10.75H17.25C17.8023 10.75 18.25 11.1977 18.25 11.75V17.25C18.25 18.3546 17.3546 19.25 16.25 19.25H7.75C6.64543 19.25 5.75 18.3546 5.75 17.25V11.75Z"
|
|
269
|
-
/>
|
|
270
|
-
<path
|
|
271
|
-
stroke="currentColor"
|
|
272
|
-
stroke-linecap="round"
|
|
273
|
-
stroke-linejoin="round"
|
|
274
|
-
stroke-width="1.5"
|
|
275
|
-
d="M7.75 10.5V9.84343C7.75 8.61493 7.70093 7.29883 8.42416 6.30578C8.99862 5.51699 10.0568 4.75 12 4.75C14 4.75 15.25 6.25 15.25 6.25"
|
|
276
|
-
/>
|
|
277
|
-
</svg>
|
|
278
|
-
{/if}
|
|
279
|
-
</button>
|
|
280
|
-
{/if}
|
|
281
|
-
</div>
|
|
133
|
+
{#snippet infos()}
|
|
134
|
+
<div class="field__actions">
|
|
135
|
+
{#if triggerable && !disabled}
|
|
136
|
+
<button
|
|
137
|
+
onclick={toggleTriggers}
|
|
138
|
+
class="field__action field__action--triggers"
|
|
139
|
+
class:active={triggersActive}
|
|
140
|
+
>
|
|
141
|
+
<IconTriggers />
|
|
142
|
+
</button>
|
|
143
|
+
{/if}
|
|
144
|
+
{#if fieldType === fieldTypes.VEC && !disabled}
|
|
145
|
+
<button
|
|
146
|
+
class="field__action field__action--lock"
|
|
147
|
+
onclick={() => (params.locked = !params.locked)}
|
|
148
|
+
>
|
|
149
|
+
<IconLocked locked={params.locked} />
|
|
150
|
+
</button>
|
|
151
|
+
{/if}
|
|
152
|
+
</div>
|
|
153
|
+
{/snippet}
|
|
282
154
|
<svelte:component
|
|
283
155
|
this={input}
|
|
284
156
|
{value}
|
|
285
157
|
{...fieldProps}
|
|
286
|
-
|
|
287
|
-
|
|
158
|
+
{onchange}
|
|
159
|
+
onclick={onTrigger}
|
|
288
160
|
/>
|
|
289
|
-
|
|
161
|
+
{@render children?.()}
|
|
290
162
|
</FieldSection>
|
|
291
163
|
{#if triggerable}
|
|
292
164
|
<FieldSection {key} visible={showTriggers} secondary>
|
|
@@ -294,8 +166,8 @@
|
|
|
294
166
|
{triggers}
|
|
295
167
|
{onTrigger}
|
|
296
168
|
{context}
|
|
297
|
-
triggerable={fieldType ===
|
|
298
|
-
controllable={fieldType ===
|
|
169
|
+
triggerable={fieldType === fieldTypes.BUTTON}
|
|
170
|
+
controllable={fieldType === fieldTypes.NUMBER}
|
|
299
171
|
/>
|
|
300
172
|
</FieldSection>
|
|
301
173
|
{/if}
|
|
@@ -306,6 +178,8 @@
|
|
|
306
178
|
--column-gap: 3px;
|
|
307
179
|
--padding: 6px;
|
|
308
180
|
|
|
181
|
+
position: relative;
|
|
182
|
+
|
|
309
183
|
width: 100%;
|
|
310
184
|
|
|
311
185
|
padding: 3px 6px 3px 12px;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export let collapsed = false;
|
|
2
|
+
let { name, collapsed = false, children, onchange = () => {} } = $props();
|
|
5
3
|
|
|
6
4
|
function handleClick() {
|
|
7
5
|
collapsed = !collapsed;
|
|
6
|
+
onchange(collapsed);
|
|
8
7
|
}
|
|
9
8
|
</script>
|
|
10
9
|
|
|
11
10
|
<div class="field-group {collapsed ? 'collapsed' : ''}">
|
|
12
11
|
<header class="header">
|
|
13
|
-
<button class="header__action"
|
|
12
|
+
<button class="header__action" onclick={handleClick}>
|
|
14
13
|
<svg
|
|
15
14
|
class="header__icon"
|
|
16
15
|
width="24"
|
|
@@ -30,7 +29,7 @@
|
|
|
30
29
|
</button>
|
|
31
30
|
</header>
|
|
32
31
|
<div class="content">
|
|
33
|
-
|
|
32
|
+
{@render children?.()}
|
|
34
33
|
</div>
|
|
35
34
|
</div>
|
|
36
35
|
|