diff --git a/frontend/src/lib/components/ArgInput.svelte b/frontend/src/lib/components/ArgInput.svelte index c37daf932f..009ec4da95 100644 --- a/frontend/src/lib/components/ArgInput.svelte +++ b/frontend/src/lib/components/ArgInput.svelte @@ -8,7 +8,7 @@ } from '@fortawesome/free-solid-svg-icons' import { setInputCat as computeInputCat, type InputCat } from '$lib/utils' - import { Button } from './common' + import { Badge, Button } from './common' import { createEventDispatcher } from 'svelte' import Icon from 'svelte-awesome' import FieldHeader from './FieldHeader.svelte' @@ -24,6 +24,8 @@ import Password from './Password.svelte' import type VariableEditor from './VariableEditor.svelte' import type ItemPicker from './ItemPicker.svelte' + import NumberTypeNarrowing from './NumberTypeNarrowing.svelte' + import Range from './Range.svelte' export let label: string = '' export let value: any @@ -53,6 +55,7 @@ export let variableEditor: VariableEditor | undefined = undefined export let itemPicker: ItemPicker | undefined = undefined export let noMargin = false + export let extra: Record = {} let seeEditable: boolean = enum_ != undefined || pattern != undefined const dispatch = createEventDispatcher() @@ -185,6 +188,8 @@ /> {#if type == 'string' && format != 'date-time'} + {:else if type == 'number'} + {:else if type == 'object'} {:else if type == 'array'} @@ -212,18 +217,31 @@
{#if inputCat == 'number'} - dispatch('input', { value, isRaw: true })} - /> + {#if extra['min'] != undefined && extra['max'] != undefined} +
+ {extra['min']} +
+ +
+ {extra['max']} + {value} +
+ {:else} + dispatch('input', { value, isRaw: true })} + /> + {/if} {:else if inputCat == 'boolean'} + import Toggle from './Toggle.svelte' + + export let min: number | undefined + export let max: number | undefined + + let minChecked: boolean = min != undefined + let maxChecked: boolean = max != undefined + + +
+ +
+
+ + +
+
+ + +
+
diff --git a/frontend/src/lib/components/Range.svelte b/frontend/src/lib/components/Range.svelte new file mode 100644 index 0000000000..e1095331a9 --- /dev/null +++ b/frontend/src/lib/components/Range.svelte @@ -0,0 +1,303 @@ + + + +
+
+
+
+
(thumbHover = true)} + on:mouseout={() => (thumbHover = false)} + > + {#if holding || thumbHover} +
+ {value} +
+ {/if} +
+
+
+
+ + + + + + diff --git a/frontend/src/lib/components/SchemaForm.svelte b/frontend/src/lib/components/SchemaForm.svelte index fb28bb8f22..67882d05e0 100644 --- a/frontend/src/lib/components/SchemaForm.svelte +++ b/frontend/src/lib/components/SchemaForm.svelte @@ -97,6 +97,7 @@ {variableEditor} {itemPicker} bind:pickForField + bind:extra={schema.properties[argName]} /> {:else} Expected argument to be an object, got {JSON.stringify(args)} instead diff --git a/frontend/src/lib/components/Tooltip.svelte b/frontend/src/lib/components/Tooltip.svelte index bb248e04d1..2fab326d76 100644 --- a/frontend/src/lib/components/Tooltip.svelte +++ b/frontend/src/lib/components/Tooltip.svelte @@ -4,7 +4,7 @@ import Popover from './Popover.svelte' - + + import { Badge } from '$lib/components/common' + import Range from '$lib/components/Range.svelte' + import { getContext } from 'svelte' + import type { AppInput } from '../../inputType' + import type { Output } from '../../rx' + import type { AppEditorContext } from '../../types' + import AlignWrapper from '../helpers/AlignWrapper.svelte' + import InputValue from '../helpers/InputValue.svelte' + + export let id: string + export let configuration: Record + export let verticalAlignment: 'top' | 'center' | 'bottom' | undefined = undefined + export const staticOutputs: string[] = ['result'] + + const { worldStore } = getContext('AppEditorContext') + let value: number + let min = 0 + let max = 42 + + $: outputs = $worldStore?.outputsById[id] as { + result: Output + } + $: if (value || !value) { + // Disallow 'e' character in numbers + // if(value && value.toString().includes('e')) { + // value = +value.toString().replaceAll('e', '') + // } + const num = isNaN(+value) ? null : +value + outputs?.result.set(num) + } + + + + + + +
+ {min} +
+ +
+ {max} + {value} +
+
diff --git a/frontend/src/lib/components/apps/editor/ComponentEditor.svelte b/frontend/src/lib/components/apps/editor/ComponentEditor.svelte index d6a3cadd30..745a23a7d4 100644 --- a/frontend/src/lib/components/apps/editor/ComponentEditor.svelte +++ b/frontend/src/lib/components/apps/editor/ComponentEditor.svelte @@ -18,6 +18,7 @@ import AppScatterChart from '../components/dataDisplay/AppScatterChart.svelte' import AppTimeseries from '../components/dataDisplay/AppTimeseries.svelte' import AppHtml from '../components/dataDisplay/AppHtml.svelte' + import AppSliderInputs from '../components/numberInputs/AppSliderInputs.svelte' export let component: AppComponent export let selected: boolean @@ -134,6 +135,8 @@ /> {:else if component.type === 'numberinputcomponent'} + {:else if component.type === 'slidercomponent'} + {/if}
diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/data.ts b/frontend/src/lib/components/apps/editor/componentsPanel/data.ts index a272c0e10c..a262c68bf8 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/data.ts +++ b/frontend/src/lib/components/apps/editor/componentsPanel/data.ts @@ -52,6 +52,28 @@ const inputs: ComponentSet = { }, card: false }, + { + softWrap: true, + verticalAlignment: 'center', + id: 'slidercomponent', + type: 'slidercomponent', + componentInput: undefined, + configuration: { + min: { + type: 'static', + value: 0, + fieldType: 'number', + onlyStatic: true, + }, + max: { + type: 'static', + value: 42, + fieldType: 'number', + onlyStatic: true, + }, + }, + card: false + }, { softWrap: true, verticalAlignment: 'center', diff --git a/frontend/src/lib/components/apps/types.ts b/frontend/src/lib/components/apps/types.ts index 73814cc58e..0e17e8f553 100644 --- a/frontend/src/lib/components/apps/types.ts +++ b/frontend/src/lib/components/apps/types.ts @@ -20,6 +20,7 @@ export type TextInputComponent = BaseComponent<'textinputcomponent'> export type PasswordInputComponent = BaseComponent<'passwordinputcomponent'> export type DateInputComponent = BaseComponent<'dateinputcomponent'> export type NumberInputComponent = BaseComponent<'numberinputcomponent'> +export type SliderComponent = BaseComponent<'slidercomponent'> export type HtmlComponent = BaseComponent<'htmlcomponent'> export type TimeseriesComponent = BaseComponent<'timeseriescomponent'> export type ButtonComponent = BaseComponent<'buttoncomponent'> & { @@ -74,6 +75,7 @@ export type AppComponent = BaseAppComponent & | PasswordInputComponent | DateInputComponent | NumberInputComponent + | SliderComponent | BarChartComponent | TimeseriesComponent | HtmlComponent diff --git a/frontend/src/lib/components/apps/utils.ts b/frontend/src/lib/components/apps/utils.ts index a65578f923..a368b48f02 100644 --- a/frontend/src/lib/components/apps/utils.ts +++ b/frontend/src/lib/components/apps/utils.ts @@ -19,7 +19,8 @@ import { Calendar, ToggleLeft, GripHorizontal, - Code2 + Code2, + SlidersHorizontal } from 'lucide-svelte' import type { AppInput, InputType, ResultAppInput, StaticAppInput } from './inputType' import type { AppComponent } from './types' @@ -146,6 +147,10 @@ export const displayData: RecordCode Dependencies lock file Arguments JSON Schema - - The jsonschema defines the constraints that the payload must respect to be compatible - with the input parameters of this script. The UI form is generated automatically from - the script jsonschema. See - - jsonschema documentation - - + > + Arguments JSON Schema + + The jsonschema defines the constraints that the payload must respect to be + compatible with the input parameters of this script. The UI form is generated + automatically from the script jsonschema. See + + jsonschema documentation + + + +