Compare commits
5 Commits
wmill-scri
...
tl/app-bui
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67578250b3 | ||
|
|
74cc8905f8 | ||
|
|
eda978f7b0 | ||
|
|
e039f57f85 | ||
|
|
a74c680cf1 |
@@ -138,10 +138,16 @@
|
||||
{#if everRender}
|
||||
<div class="h-full w-full">
|
||||
<AlignWrapper {noWFull} {horizontalAlignment} {verticalAlignment}>
|
||||
<div
|
||||
class="inline-flex"
|
||||
title={resolvedConfig.tooltip && String(resolvedConfig.tooltip).length > 0
|
||||
? String(resolvedConfig.tooltip)
|
||||
: undefined}
|
||||
>
|
||||
<Button
|
||||
btnClasses={twMerge(css?.button?.class, 'wm-button', 'wm-modal-button')}
|
||||
wrapperClasses={twMerge(
|
||||
resolvedConfig?.buttonFillContainer ? 'w-full h-full' : '',
|
||||
resolvedConfig?.fillContainer ? 'w-full h-full' : '',
|
||||
css?.buttonContainer?.class,
|
||||
'wm-button-container',
|
||||
'wm-modal-button-container',
|
||||
@@ -151,7 +157,7 @@
|
||||
)}
|
||||
style={css?.button?.style}
|
||||
wrapperStyle={css?.buttonContainer?.style}
|
||||
disabled={resolvedConfig.buttonDisabled}
|
||||
disabled={resolvedConfig.disabled}
|
||||
on:pointerdown={(e) => {
|
||||
e?.stopPropagation()
|
||||
}}
|
||||
@@ -162,12 +168,13 @@
|
||||
}
|
||||
disposable?.openDrawer()
|
||||
}}
|
||||
extendedSize={resolvedConfig.buttonSize}
|
||||
color={resolvedConfig.buttonColor}
|
||||
extendedSize={resolvedConfig.size}
|
||||
color={resolvedConfig.color}
|
||||
variant="contained"
|
||||
>
|
||||
<div>{resolvedConfig.buttonLabel}</div>
|
||||
</Button>
|
||||
<div>{resolvedConfig.label}</div>
|
||||
</Button>
|
||||
</div>
|
||||
</AlignWrapper>
|
||||
</div>
|
||||
<Portal target="#app-editor-top-level-drawer" name="app-modal">
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
render: boolean
|
||||
disabledTabs: RichConfiguration[]
|
||||
hiddenTabs: RichConfiguration[]
|
||||
tooltipTabs: RichConfiguration[] | undefined
|
||||
onTabChange?: string[] | undefined
|
||||
}
|
||||
|
||||
@@ -41,6 +42,7 @@
|
||||
render,
|
||||
disabledTabs,
|
||||
hiddenTabs,
|
||||
tooltipTabs = undefined,
|
||||
onTabChange = undefined
|
||||
}: Props = $props()
|
||||
|
||||
@@ -157,7 +159,7 @@
|
||||
|
||||
let resolvedDisabledTabs: boolean[] = $state([])
|
||||
let resolvedHiddenTabs: boolean[] = $state([])
|
||||
|
||||
let resolvedTooltipTabs: string[] = $state([])
|
||||
// Filter visible tabs based on hiddenTabs configuration
|
||||
let visibleTabsIndices = $derived(
|
||||
(tabs ?? []).map((_, index) => index).filter((index) => !resolvedHiddenTabs[index])
|
||||
@@ -210,6 +212,10 @@
|
||||
<InputValue key="tabHidden {index}" {id} input={hideTab} bind:value={resolvedHiddenTabs[index]} />
|
||||
{/each}
|
||||
|
||||
{#each tooltipTabs ?? [] as tooltipTab, index}
|
||||
<InputValue key="tabTooltip {index}" {id} input={tooltipTab} bind:value={resolvedTooltipTabs[index]} />
|
||||
{/each}
|
||||
|
||||
{#if everRender}
|
||||
<div class={resolvedConfig.tabsKind == 'sidebar' ? 'flex gap-4 w-full h-full' : 'w-full'}>
|
||||
{#if !resolvedConfig.tabsKind || resolvedConfig.tabsKind == 'tabs' || (resolvedConfig.tabsKind == 'invisibleOnView' && $mode == 'dnd')}
|
||||
@@ -229,6 +235,9 @@
|
||||
selectedStyle={css?.selectedTab?.style}
|
||||
disabled={resolvedDisabledTabs[index]}
|
||||
label={res}
|
||||
tooltip={resolvedTooltipTabs[index] && String(resolvedTooltipTabs[index]).length > 0
|
||||
? String(resolvedTooltipTabs[index])
|
||||
: undefined}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
@@ -245,6 +254,11 @@
|
||||
>
|
||||
{#each tabs ?? [] as res, index}
|
||||
{#if !resolvedHiddenTabs[index]}
|
||||
<div
|
||||
title={resolvedTooltipTabs[index] && String(resolvedTooltipTabs[index]).length > 0
|
||||
? String(resolvedTooltipTabs[index])
|
||||
: undefined}
|
||||
>
|
||||
<button
|
||||
onpointerdown={stopPropagation(bubble('pointerdown'))}
|
||||
onclick={() => !resolvedDisabledTabs[index] && (selected = res)}
|
||||
@@ -269,7 +283,8 @@
|
||||
: css?.allTabs?.style}
|
||||
>
|
||||
{res}
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
@@ -279,29 +294,35 @@
|
||||
{#each tabs ?? [] as res, index}
|
||||
{#if !resolvedHiddenTabs[index]}
|
||||
<div class="border-b">
|
||||
<button
|
||||
onpointerdown={stopPropagation(bubble('pointerdown'))}
|
||||
onclick={() => !resolvedDisabledTabs[index] && (selected = res)}
|
||||
disabled={resolvedDisabledTabs[index]}
|
||||
class={twMerge(
|
||||
'w-full text-left bg-surface !truncate text-sm hover:text-primary px-1 py-2',
|
||||
css?.allTabs?.class,
|
||||
'wm-tabs-alltabs',
|
||||
selected == res
|
||||
? twMerge(
|
||||
'bg-surface text-primary ',
|
||||
css?.selectedTab?.class,
|
||||
'wm-tabs-selectedTab'
|
||||
)
|
||||
: 'text-secondary',
|
||||
resolvedDisabledTabs[index]
|
||||
? 'opacity-50 cursor-not-allowed hover:text-secondary'
|
||||
: ''
|
||||
)}
|
||||
<div
|
||||
title={resolvedTooltipTabs[index] && String(resolvedTooltipTabs[index]).length > 0
|
||||
? String(resolvedTooltipTabs[index])
|
||||
: undefined}
|
||||
>
|
||||
<span class="mr-2 w-8 font-mono">{selected == res ? '-' : '+'}</span>
|
||||
{res}
|
||||
</button>
|
||||
<button
|
||||
onpointerdown={stopPropagation(bubble('pointerdown'))}
|
||||
onclick={() => !resolvedDisabledTabs[index] && (selected = res)}
|
||||
disabled={resolvedDisabledTabs[index]}
|
||||
class={twMerge(
|
||||
'w-full text-left bg-surface !truncate text-sm hover:text-primary px-1 py-2',
|
||||
css?.allTabs?.class,
|
||||
'wm-tabs-alltabs',
|
||||
selected == res
|
||||
? twMerge(
|
||||
'bg-surface text-primary ',
|
||||
css?.selectedTab?.class,
|
||||
'wm-tabs-selectedTab'
|
||||
)
|
||||
: 'text-secondary',
|
||||
resolvedDisabledTabs[index]
|
||||
? 'opacity-50 cursor-not-allowed hover:text-secondary'
|
||||
: ''
|
||||
)}
|
||||
>
|
||||
<span class="mr-2 w-8 font-mono">{selected == res ? '-' : '+'}</span>
|
||||
{res}
|
||||
</button>
|
||||
</div>
|
||||
<div class={selected == res ? 'border-t' : ''}>
|
||||
<SubGridEditor
|
||||
{id}
|
||||
|
||||
@@ -858,6 +858,7 @@
|
||||
tabs={component.tabs}
|
||||
disabledTabs={component.disabledTabs}
|
||||
hiddenTabs={component.hiddenTabs}
|
||||
tooltipTabs={component.tooltipTabs}
|
||||
onTabChange={component.onTabChange}
|
||||
customCss={component.customCss}
|
||||
{componentContainerHeight}
|
||||
|
||||
@@ -244,6 +244,7 @@ export type TabsComponent = BaseComponent<'tabscomponent'> & {
|
||||
tabs: string[]
|
||||
disabledTabs: RichConfiguration[]
|
||||
hiddenTabs: RichConfiguration[]
|
||||
tooltipTabs: RichConfiguration[]
|
||||
onTabChange?: string[]
|
||||
}
|
||||
|
||||
@@ -3124,6 +3125,10 @@ See date-fns format for more information. By default, it is 'dd.MM.yyyy HH:mm'
|
||||
hiddenTabs: [
|
||||
{ type: 'static', value: false, fieldType: 'boolean' },
|
||||
{ type: 'static', value: false, fieldType: 'boolean' }
|
||||
] as RichConfiguration[],
|
||||
tooltipTabs: [
|
||||
{ type: 'static', value: '', fieldType: 'text' },
|
||||
{ type: 'static', value: '', fieldType: 'text' },
|
||||
] as RichConfiguration[]
|
||||
}
|
||||
},
|
||||
@@ -3609,12 +3614,12 @@ See date-fns format for more information. By default, it is 'dd.MM.yyyy HH:mm'
|
||||
value: false,
|
||||
tooltip: 'Make button invisible when app is used outside of the edit mode'
|
||||
},
|
||||
buttonLabel: {
|
||||
label: {
|
||||
type: 'static',
|
||||
fieldType: 'text',
|
||||
value: 'Press me'
|
||||
},
|
||||
buttonColor: {
|
||||
color: {
|
||||
fieldType: 'select',
|
||||
type: 'static',
|
||||
|
||||
@@ -3622,14 +3627,14 @@ See date-fns format for more information. By default, it is 'dd.MM.yyyy HH:mm'
|
||||
value: 'blue',
|
||||
tooltip: 'These presets can be overwritten with custom styles.'
|
||||
},
|
||||
buttonSize: {
|
||||
size: {
|
||||
fieldType: 'select',
|
||||
type: 'static',
|
||||
|
||||
selectOptions: selectOptions.buttonSizeOptions,
|
||||
value: 'xs'
|
||||
},
|
||||
buttonFillContainer: {
|
||||
fillContainer: {
|
||||
fieldType: 'boolean',
|
||||
type: 'static',
|
||||
|
||||
@@ -3637,10 +3642,16 @@ See date-fns format for more information. By default, it is 'dd.MM.yyyy HH:mm'
|
||||
tooltip:
|
||||
'This will make the button fill the container width and height. Height and width can be overwritten with custom styles.'
|
||||
},
|
||||
buttonDisabled: {
|
||||
disabled: {
|
||||
fieldType: 'boolean',
|
||||
type: 'static',
|
||||
value: false
|
||||
},
|
||||
tooltip: {
|
||||
type: 'static',
|
||||
fieldType: 'text',
|
||||
value: '',
|
||||
tooltip: 'Tooltip text to show on hover'
|
||||
}
|
||||
},
|
||||
componentInput: undefined,
|
||||
|
||||
@@ -393,9 +393,11 @@
|
||||
bind:tabs={item.data.tabs}
|
||||
bind:disabledTabs={item.data.disabledTabs}
|
||||
bind:hiddenTabs={item.data.hiddenTabs}
|
||||
bind:tooltipTabs={item.data.tooltipTabs}
|
||||
bind:component={item.data}
|
||||
canDisableTabs
|
||||
canHideTabs
|
||||
canTooltipTabs
|
||||
/>
|
||||
{:else if item.data.type === 'aggridcomponentee'}
|
||||
<GridAgGridLicenseKey bind:license={item.data.license} />
|
||||
|
||||
@@ -14,13 +14,16 @@
|
||||
import { GripVertical, Plus } from 'lucide-svelte'
|
||||
import GridTabDisabled from './GridTabDisabled.svelte'
|
||||
import GridTabHidden from './GridTabHidden.svelte'
|
||||
import GridTabTooltip from './GridTabTooltip.svelte'
|
||||
|
||||
interface Props {
|
||||
tabs?: string[]
|
||||
disabledTabs?: RichConfiguration[]
|
||||
hiddenTabs?: RichConfiguration[]
|
||||
tooltipTabs?: RichConfiguration[]
|
||||
canDisableTabs?: boolean
|
||||
canHideTabs?: boolean
|
||||
canTooltipTabs?: boolean
|
||||
word?: string
|
||||
component: AppComponent
|
||||
}
|
||||
@@ -29,8 +32,10 @@
|
||||
tabs = $bindable(undefined),
|
||||
disabledTabs = $bindable(undefined),
|
||||
hiddenTabs = $bindable(undefined),
|
||||
tooltipTabs = $bindable(undefined),
|
||||
canDisableTabs = false,
|
||||
canHideTabs = false,
|
||||
canTooltipTabs = false,
|
||||
word = 'Tab',
|
||||
component = $bindable()
|
||||
}: Props = $props()
|
||||
@@ -51,6 +56,12 @@
|
||||
{ type: 'static', value: false, fieldType: 'boolean' }
|
||||
]
|
||||
}
|
||||
if (tooltipTabs == undefined) {
|
||||
tooltipTabs = [
|
||||
{ type: 'static', value: '', fieldType: 'text' },
|
||||
{ type: 'static', value: '', fieldType: 'text' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
let items = $state.raw(
|
||||
@@ -89,6 +100,7 @@
|
||||
|
||||
disabledTabs = [...(disabledTabs ?? []), { type: 'static', value: false, fieldType: 'boolean' }]
|
||||
hiddenTabs = [...(hiddenTabs ?? []), { type: 'static', value: false, fieldType: 'boolean' }]
|
||||
tooltipTabs = [...(tooltipTabs ?? []), { type: 'static', value: '', fieldType: 'text' }]
|
||||
}
|
||||
|
||||
function deleteSubgrid(index: number) {
|
||||
@@ -114,6 +126,8 @@
|
||||
// Delete the item in the hiddenTabs array
|
||||
hiddenTabs = (hiddenTabs ?? []).filter((_, i) => i !== index)
|
||||
|
||||
// Delete the item in the tooltipTabs array
|
||||
tooltipTabs = (tooltipTabs ?? []).filter((_, i) => i !== index)
|
||||
component.numberOfSubgrids = items.length
|
||||
// Update the originalIndex of the remaining items
|
||||
items.forEach((item, i) => {
|
||||
@@ -152,13 +166,15 @@
|
||||
|
||||
const newDisabledTabs: RichConfiguration[] = []
|
||||
const newHiddenTabs: RichConfiguration[] = []
|
||||
const newTooltipTabs: RichConfiguration[] = []
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
disabledTabs && newDisabledTabs.push(disabledTabs[items[i].originalIndex])
|
||||
hiddenTabs && newHiddenTabs.push(hiddenTabs[items[i].originalIndex])
|
||||
tooltipTabs && newTooltipTabs.push(tooltipTabs[items[i].originalIndex])
|
||||
}
|
||||
disabledTabs = newDisabledTabs
|
||||
hiddenTabs = newHiddenTabs
|
||||
|
||||
tooltipTabs = newTooltipTabs
|
||||
// update originalIndex
|
||||
items.forEach((item, i) => {
|
||||
item.originalIndex = i
|
||||
@@ -226,6 +242,11 @@
|
||||
<GridTabHidden {index} bind:field={hiddenTabs[index]} id={component.id} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if canTooltipTabs && tooltipTabs}
|
||||
<div class="mt-2">
|
||||
<GridTabTooltip {index} bind:field={tooltipTabs[index]} id={component.id} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</section>
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<script lang="ts">
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import type { RichConfiguration } from '../../types'
|
||||
import InputsSpecEditor from './InputsSpecEditor.svelte'
|
||||
import { slide } from 'svelte/transition'
|
||||
|
||||
interface Props {
|
||||
id: string
|
||||
field: RichConfiguration
|
||||
index: number
|
||||
}
|
||||
|
||||
let { id, field = $bindable(), index }: Props = $props()
|
||||
|
||||
// Tooltip is active if it's not empty static value
|
||||
let hasTooltip = $state(
|
||||
field && !(field?.type === 'static' && (field?.value === '' || field?.value == null))
|
||||
)
|
||||
</script>
|
||||
|
||||
<Toggle
|
||||
bind:checked={hasTooltip}
|
||||
size="xs"
|
||||
options={{
|
||||
right: 'Tooltip'
|
||||
}}
|
||||
on:change={() => {
|
||||
if (hasTooltip) {
|
||||
field = {
|
||||
type: 'evalv2',
|
||||
expr: "''",
|
||||
fieldType: 'text',
|
||||
connections: []
|
||||
}
|
||||
} else {
|
||||
field = {
|
||||
type: 'static',
|
||||
value: '',
|
||||
fieldType: 'text'
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
{#if hasTooltip}
|
||||
<div transition:slide|local>
|
||||
<InputsSpecEditor
|
||||
key="tabTooltip {index}"
|
||||
bind:componentInput={field}
|
||||
{id}
|
||||
userInputEnabled={false}
|
||||
shouldCapitalize={true}
|
||||
resourceOnly={false}
|
||||
fieldType={field?.['fieldType']}
|
||||
subFieldType={field?.['subFieldType']}
|
||||
format={field?.['format']}
|
||||
selectOptions={field?.['selectOptions']}
|
||||
tooltip={field?.['tooltip']}
|
||||
fileUpload={field?.['fileUpload']}
|
||||
placeholder={field?.['placeholder']}
|
||||
customTitle="Tooltip"
|
||||
displayType={false}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -21,6 +21,7 @@
|
||||
exact?: boolean
|
||||
otherValues?: string[]
|
||||
disabled?: boolean
|
||||
tooltip?: string
|
||||
extra?: import('svelte').Snippet
|
||||
}
|
||||
|
||||
@@ -39,6 +40,7 @@
|
||||
exact = false,
|
||||
otherValues = [],
|
||||
disabled = false,
|
||||
tooltip = undefined,
|
||||
extra = undefined
|
||||
}: Props = $props()
|
||||
const { selected, update, hashNavigation } = getContext<TabsContext>('Tabs')
|
||||
@@ -58,7 +60,11 @@
|
||||
let isSelected = $derived(isSelectedFn($selected))
|
||||
</script>
|
||||
|
||||
<button
|
||||
<div
|
||||
title={tooltip}
|
||||
class="inline-block"
|
||||
>
|
||||
<button
|
||||
use:triggerableByAI={{
|
||||
id: aiId,
|
||||
description: aiDescription,
|
||||
@@ -109,4 +115,5 @@
|
||||
{/if}
|
||||
{@render extra?.()}
|
||||
</div>
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user