feat: Update apps button component with colors (#936)

* feat: Update app component types

* fix: Typos

* feat: Add select input type to components

* fix: Remove width property from component types

* fix: Make button full width in editor

* fix: Types

Co-authored-by: Faton Ramadani <faton.ramadani14@gmail.com>
This commit is contained in:
Ádám Kovács
2022-11-23 19:45:19 +01:00
committed by GitHub
parent ab481b3096
commit 4b2b3467d2
10 changed files with 135 additions and 73 deletions
@@ -1,5 +1,5 @@
<script lang="ts">
import Button from '$lib/components/common/button/Button.svelte'
import { Button, type ButtonType } from '$lib/components/common'
import type { ComponentInputsSpec, InputsSpec } from '../../types'
import InputValue from '../helpers/InputValue.svelte'
import RunnableComponent from '../helpers/RunnableComponent.svelte'
@@ -14,10 +14,12 @@
export const staticOutputs: string[] = ['loading', 'result']
let labelValue: string = 'Default label'
let color: ButtonType.Color
let runnableComponent: RunnableComponent
</script>
<InputValue input={componentInputs.label} bind:value={labelValue} />
<InputValue input={componentInputs.color} bind:value={color} />
<RunnableComponent
bind:this={runnableComponent}
@@ -32,7 +34,8 @@
on:click={() => {
runnableComponent?.runComponent()
}}
btnClasses="h-full w-full"
btnClasses="w-full h-full"
{color}
>
{labelValue}
</Button>
@@ -3,9 +3,10 @@
import type { StaticInput, DynamicInput, AppEditorContext, UserInput } from '../../types'
import { accessPropertyByPath } from '../../utils'
type T = $$Generic
type T = string | number | boolean | Record<string | number, any> | undefined
export let input: DynamicInput | StaticInput | UserInput
export let value: T | undefined = undefined
export let value: T
const { worldStore } = getContext<AppEditorContext>('AppEditorContext')
@@ -25,12 +26,12 @@
}
}
function onValueChange(newValue: T): void {
function onValueChange(newValue: any): void {
if (input.type === 'output') {
if (input.name?.includes('.')) {
const path = input.name.split('.').slice(1).join('.')
value = accessPropertyByPath(newValue, path)
value = accessPropertyByPath<T>(newValue, path)
} else {
value = newValue
}
@@ -1,11 +1,13 @@
import type { Aligned } from "../../types"
const defaultProps = {
inputs: {},
componentInputs: {}
}
const defaultAlignement = {
horizontalAlignement: 'center',
verticalAlignement: 'center'
const defaultAlignement: Aligned = {
horizontalAlignment: 'center',
verticalAlignment: 'center'
}
export { defaultProps, defaultAlignement }
@@ -0,0 +1,7 @@
import { BUTTON_COLORS } from "../../../common";
const buttonColorOptions = [...BUTTON_COLORS]
export const staticValues = {
buttonColorOptions,
} as const
@@ -1,4 +1,4 @@
import type { AppComponent } from '../../types'
import type { AppComponent, ComponentSet } from '../../types'
import { defaultAlignement, defaultProps } from './componentDefaultProps'
const windmillComponents = {
@@ -20,7 +20,7 @@ const windmillComponents = {
] as AppComponent[]
}
const plainComponents = {
const plainComponents: ComponentSet = {
title: 'Plain Components',
components: [
{
@@ -47,11 +47,18 @@ const plainComponents = {
visible: true,
value: 'Lorem ipsum',
fieldType: 'textarea'
},
color: {
fieldType: 'select',
type: 'static',
visible: true,
value: 'blue',
optionValuesKey: 'buttonColorOptions',
}
},
runnable: true
}
] as AppComponent[]
]
}
const chartComponents = {
@@ -118,11 +118,11 @@
</PanelSection>
{/if}
{#if component.verticalAlignement !== undefined}
<PanelSection title="Alignement">
<div class="w-full text-xs font-bold">Horizontal alignement</div>
{#if component.verticalAlignment !== undefined}
<PanelSection title="Alignment">
<div class="w-full text-xs font-bold">Horizontal alignment</div>
<ToggleButtonGroup bind:selected={component.horizontalAlignement}>
<ToggleButtonGroup bind:selected={component.horizontalAlignment}>
<ToggleButton position="left" value="left" size="xs">
<Icon data={faAlignLeft} />
</ToggleButton>
@@ -133,9 +133,9 @@
<Icon data={faAlignRight} />
</ToggleButton>
</ToggleButtonGroup>
<div class="w-full text-xs font-bold">Vertical alignement</div>
<div class="w-full text-xs font-bold">Vertical alignment</div>
<ToggleButtonGroup bind:selected={component.verticalAlignement}>
<ToggleButtonGroup bind:selected={component.verticalAlignment}>
<ToggleButton position="left" value="top" size="xs">
<Icon data={faAlignLeft} />
</ToggleButton>
@@ -1,6 +1,7 @@
<script lang="ts">
import type { StaticInput } from '../../types'
import Toggle from '$lib/components/Toggle.svelte'
import { staticValues } from '../componentsPanel/componentStaticValues'
export let input: StaticInput
export let canHide: boolean
@@ -16,6 +17,14 @@
<textarea bind:value={input.value} />
{:else if input.fieldType === 'boolean'}
<Toggle bind:checked={input.value} />
{:else if input.fieldType === 'select'}
<select bind:value={input.value}>
{#each staticValues[input.optionValuesKey] || [] as option}
<option value={option}>
{option}
</option>
{/each}
</select>
{:else}
<input bind:value={input.value} />
{/if}
+1 -1
View File
@@ -12,7 +12,7 @@ export interface Output<T> extends Observable<T> {
}
export interface Input<T> extends Subscriber<T> {
peak(): T | undefined
peak(): T | any | undefined
}
export type World = {
+83 -53
View File
@@ -2,6 +2,7 @@ import type { Schema, SchemaProperty } from '$lib/common'
import type { Preview } from '$lib/gen'
import type { FilledItem } from 'svelte-grid'
import type { Writable } from 'svelte/store'
import type { staticValues } from './editor/componentsPanel/componentStaticValues'
import type { World } from './rx'
export type UserInput = {
@@ -20,84 +21,113 @@ export type DynamicInput = {
defaultValue: any
}
export type StaticInput = {
export type StaticInputType =
('text'
| 'textarea'
| 'number'
| 'boolean'
| 'select'
| 'date'
| 'time'
| 'datetime'
| 'object')
type BaseStaticInput<T extends StaticInputType, V> = {
fieldType: T
value: V | undefined
type: 'static'
value: any
visible?: boolean
fieldType:
| 'text'
| 'textarea'
| 'number'
| 'boolean'
| 'select'
| 'date'
| 'time'
| 'datetime'
| 'object'
}
export type SelectStaticInput = BaseStaticInput<'select', string> & {
/**
* One of the keys of `staticValues` from `lib/components/apps/editor/componentsPanel/componentStaticValues`
*/
optionValuesKey: keyof typeof staticValues
}
export type StaticInput =
BaseStaticInput<'text', string>
| BaseStaticInput<'textarea', string>
| BaseStaticInput<'number', number>
| BaseStaticInput<'boolean', boolean>
| SelectStaticInput
| BaseStaticInput<'date', string>
| BaseStaticInput<'time', string>
| BaseStaticInput<'datetime', string>
| BaseStaticInput<'object', Record<string | number, any>>
export type AppInputTransform = DynamicInput | StaticInput | UserInput
// Inner inputs, (search, filter, page, inputs of a script or flow)
export type InputsSpec = Record<FieldID, AppInputTransform>
export type ComponentInputsSpec = Record<FieldID, DynamicInput | StaticInput>
export type TextComponent = {
type: 'textcomponent'
}
export type TextInputComponent = {
type: 'textinputcomponent'
}
export type ButtonComponent = {
type: 'buttoncomponent'
}
type Runnable = {
inlineScriptName?: string
path?: string
runType?: 'script' | 'flow'
}
export type BarChartComponent = Runnable & {
type: 'barchartcomponent'
type BaseComponent<T extends string> = {
type: T
}
export type PieChartComponent = Runnable & {
type: 'piechartcomponent'
export type TextComponent = BaseComponent<'textcomponent'>
export type TextInputComponent = BaseComponent<'textinputcomponent'>
export type ButtonComponent = BaseComponent<'buttoncomponent'>
export type RunFormComponent = Runnable & BaseComponent<'runformcomponent'>
export type BarChartComponent = BaseComponent<'barchartcomponent'>
export type PieChartComponent = Runnable & BaseComponent<'piechartcomponent'>
export type TableComponent = Runnable & BaseComponent<'tablecomponent'>
export type DisplayComponent = BaseComponent<'displaycomponent'>
export type ImageComponent = BaseComponent<'imagecomponent'>
export type InputComponent = BaseComponent<'inputcomponent'>
export type SelectComponent = BaseComponent<'selectcomponent'>
export type CheckboxComponent = BaseComponent<'checkboxcomponent'>
export type RadioComponent = BaseComponent<'radiocomponent'>
export type HorizontalAlignment = 'left' | 'center' | 'right'
export type VerticalAlignment = 'top' | 'center' | 'bottom'
export type Aligned = {
horizontalAlignment: HorizontalAlignment
verticalAlignment: VerticalAlignment
}
export type TableComponent = Runnable & {
type: 'tablecomponent'
}
export interface BaseAppComponent extends Partial<Aligned> {
id: ComponentID
inputs: InputsSpec
// Only dynamic inputs (Result of display)
componentInputs: ComponentInputsSpec
runnable?: boolean | undefined
card?: boolean | undefined
export type DisplayComponent = {
type: 'displaycomponent'
// TODO: add min/max width/height
}
export type AppComponent =
| (
| DisplayComponent
| TextInputComponent
| BarChartComponent
| TableComponent
| TextComponent
| TableComponent
| ButtonComponent
| PieChartComponent
) & {
id: ComponentID
horizontalAlignement?: 'left' | 'center' | 'right'
verticalAlignement?: 'top' | 'center' | 'bottom'
BaseAppComponent & (
RunFormComponent
| DisplayComponent
| TextInputComponent
| BarChartComponent
| TableComponent
| TextComponent
| TableComponent
| ButtonComponent
| PieChartComponent
| ImageComponent
| InputComponent
| SelectComponent
| CheckboxComponent
| RadioComponent
)
inputs: InputsSpec
componentInputs: ComponentInputsSpec
runnable?: boolean | undefined
card?: boolean | undefined
// TODO: add min/max width/height
}
export type ComponentSet = {
title: string,
components: AppComponent[]
}
type SectionID = string
@@ -1,6 +1,9 @@
export const BUTTON_COLORS = ['blue', 'red', 'dark', 'light', 'green'] as const
export namespace ButtonType {
export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
export type Color = 'blue' | 'red' | 'dark' | 'light' | 'green'
export type Color = typeof BUTTON_COLORS[number]
export type Variant = 'contained' | 'border'
export type Target = '_self' | '_blank'
export type Element = HTMLButtonElement | HTMLAnchorElement