feat(frontend): App select tabs (#1557)
* feat(frontend): app select tabs * feat(frontend): app select tabs * feat(frontend): app select tabs * feat(frontend): fix build * feat(frontend): removeclasses * feat(frontend): add tabSize
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
|
||||
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
|
||||
import { concatCustomCss } from '../../utils'
|
||||
import AlignWrapper from '../helpers/AlignWrapper.svelte'
|
||||
import { initConfig, initOutput } from '../../editor/appUtils'
|
||||
import InitializeComponent from '../helpers/InitializeComponent.svelte'
|
||||
import { Tab, Tabs } from '$lib/components/common'
|
||||
import { components } from '../../editor/component'
|
||||
import ResolveConfig from '../helpers/ResolveConfig.svelte'
|
||||
|
||||
export let id: string
|
||||
export let configuration: RichConfigurations
|
||||
export let horizontalAlignment: 'left' | 'center' | 'right' | undefined = undefined
|
||||
export let verticalAlignment: 'top' | 'center' | 'bottom' | undefined = undefined
|
||||
export let customCss: ComponentCustomCSS<'selecttabcomponent'> | undefined = undefined
|
||||
export let render: boolean
|
||||
|
||||
const { app, worldStore } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
const resolvedConfig = initConfig(
|
||||
components['selecttabcomponent'].initialData.configuration,
|
||||
configuration
|
||||
)
|
||||
const outputs = initOutput($worldStore, id, {
|
||||
result: undefined as string | undefined
|
||||
})
|
||||
|
||||
let selected: string = ''
|
||||
$: selected === '' && resolvedConfig && setDefaultValue()
|
||||
|
||||
function setDefaultValue() {
|
||||
if (resolvedConfig.defaultValue === undefined) {
|
||||
selected = resolvedConfig.items[0].value
|
||||
} else if (resolvedConfig.defaultValue?.value) {
|
||||
selected = resolvedConfig.defaultValue?.value
|
||||
}
|
||||
}
|
||||
|
||||
function handleSelection(value: string) {
|
||||
outputs?.result.set(value)
|
||||
}
|
||||
|
||||
function onPointerDown(
|
||||
e: PointerEvent & {
|
||||
currentTarget: EventTarget & HTMLDivElement
|
||||
}
|
||||
) {
|
||||
if (!e.shiftKey) {
|
||||
e.stopPropagation()
|
||||
}
|
||||
}
|
||||
|
||||
$: selected && handleSelection(selected)
|
||||
$: css = concatCustomCss($app.css?.selecttabcomponent, customCss)
|
||||
</script>
|
||||
|
||||
{#each Object.keys(components['selecttabcomponent'].initialData.configuration) as key (key)}
|
||||
<ResolveConfig
|
||||
{id}
|
||||
{key}
|
||||
bind:resolvedConfig={resolvedConfig[key]}
|
||||
configuration={configuration[key]}
|
||||
/>
|
||||
{/each}
|
||||
|
||||
<InitializeComponent {id} />
|
||||
|
||||
<AlignWrapper {render} {horizontalAlignment} {verticalAlignment}>
|
||||
<div class="w-full" on:pointerdown={onPointerDown}>
|
||||
<Tabs bind:selected class={css?.tabRow?.class} style={css?.tabRow?.style}>
|
||||
{#each resolvedConfig?.items ?? [] as item}
|
||||
<Tab
|
||||
value={item.value}
|
||||
class={css?.allTabs?.class}
|
||||
style={css?.allTabs?.style}
|
||||
selectedClass={css?.selectedTab?.class}
|
||||
selectedStyle={css?.selectedTab?.style}
|
||||
size={resolvedConfig?.tabSize}
|
||||
>
|
||||
<span class="font-semibold text-md">{item.label}</span>
|
||||
</Tab>
|
||||
{/each}
|
||||
</Tabs>
|
||||
</div>
|
||||
</AlignWrapper>
|
||||
@@ -42,6 +42,7 @@
|
||||
import AppModal from '../../components/layout/AppModal.svelte'
|
||||
import AppSchemaForm from '../../components/buttons/AppSchemaForm.svelte'
|
||||
import AppStepper from '../../components/layout/AppStepper.svelte'
|
||||
import AppSelectTab from '../../components/inputs/AppSelectTab.svelte'
|
||||
import AppConditionalWrapper from '../../components/layout/AppConditionalWrapper.svelte'
|
||||
|
||||
export let component: AppComponent
|
||||
@@ -499,6 +500,15 @@
|
||||
{initializing}
|
||||
{render}
|
||||
/>
|
||||
{:else if component.type === 'selecttabcomponent'}
|
||||
<AppSelectTab
|
||||
id={component.id}
|
||||
verticalAlignment={component.verticalAlignment}
|
||||
horizontalAlignment={component.horizontalAlignment}
|
||||
configuration={component.configuration}
|
||||
customCss={component.customCss}
|
||||
{render}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -117,6 +117,7 @@ export type ConditionalWrapperComponent = BaseComponent<'conditionalwrapper'> &
|
||||
}
|
||||
|
||||
export type Schemaformcomponent = BaseComponent<'schemaformcomponent'>
|
||||
export type SelectTabComponent = BaseComponent<'selecttabcomponent'>
|
||||
|
||||
export type TypedComponent =
|
||||
| DisplayComponent
|
||||
@@ -161,6 +162,7 @@ export type TypedComponent =
|
||||
| ModalComponent
|
||||
| StepperComponent
|
||||
| Schemaformcomponent
|
||||
| SelectTabComponent
|
||||
| ConditionalWrapperComponent
|
||||
|
||||
export type AppComponent = BaseAppComponent & TypedComponent
|
||||
@@ -1792,6 +1794,44 @@ Hello \${ctx.username}
|
||||
}
|
||||
}
|
||||
},
|
||||
selecttabcomponent: {
|
||||
name: 'Select Tab',
|
||||
icon: List,
|
||||
dims: '2:1-3:1' as AppComponentDimensions,
|
||||
|
||||
customCss: {
|
||||
tabRow: { class: '', style: '' },
|
||||
allTabs: { class: '', style: '' },
|
||||
selectedTab: { class: '', style: '' }
|
||||
},
|
||||
initialData: {
|
||||
verticalAlignment: 'center',
|
||||
componentInput: undefined,
|
||||
configuration: {
|
||||
items: {
|
||||
type: 'static',
|
||||
fieldType: 'array',
|
||||
subFieldType: 'labeledselect',
|
||||
value: [
|
||||
{ value: 'foo', label: 'Foo' },
|
||||
{ value: 'bar', label: 'Bar' }
|
||||
]
|
||||
} as StaticAppInput,
|
||||
|
||||
defaultValue: {
|
||||
type: 'static',
|
||||
value: undefined as { value: string; label: string } | undefined,
|
||||
fieldType: 'object'
|
||||
},
|
||||
tabSize: {
|
||||
type: 'static',
|
||||
value: 'sm',
|
||||
fieldType: 'select',
|
||||
selectOptions: selectOptions.buttonSizeOptions
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
conditionalwrapper: {
|
||||
name: 'Conditional tabs',
|
||||
icon: Split,
|
||||
|
||||
@@ -41,7 +41,8 @@ const inputs: ComponentSet = {
|
||||
'checkboxcomponent',
|
||||
'selectcomponent',
|
||||
'resourceselectcomponent',
|
||||
'multiselectcomponent'
|
||||
'multiselectcomponent',
|
||||
'selecttabcomponent'
|
||||
]
|
||||
} as const
|
||||
|
||||
|
||||
@@ -702,5 +702,10 @@ export const quickStyleProperties: Record<
|
||||
schemaformcomponent: {
|
||||
container: containerDefaultProps,
|
||||
button: buttonDefaultProps
|
||||
},
|
||||
selecttabcomponent: {
|
||||
tabRow: containerDefaultProps,
|
||||
allTabs: [typographyGrouping, sizeGrouping],
|
||||
selectedTab: [typographyGrouping, sizeGrouping]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user