This commit is contained in:
Gerard Burns 2024-04-03 09:08:31 +01:00
parent ad1b30431d
commit 96001dd409
6 changed files with 115 additions and 98 deletions

View File

@ -22,6 +22,8 @@
export let open = false export let open = false
export let loading export let loading
export let align export let align
export let onOptionMouseenter = () => {}
export let onOptionMouseleave = () => {}
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
@ -107,4 +109,6 @@
{customPopoverHeight} {customPopoverHeight}
{loading} {loading}
{align} {align}
{onOptionMouseenter}
{onOptionMouseleave}
/> />

View File

@ -19,8 +19,6 @@
import ContextTooltip from "../../Tooltip/Context.svelte" import ContextTooltip from "../../Tooltip/Context.svelte"
import { Heading } from "@budibase/bbui" import { Heading } from "@budibase/bbui"
export let id = null export let id = null
export let disabled = false export let disabled = false
export let fieldText = "" export let fieldText = ""
@ -52,18 +50,14 @@
export let footer = null export let footer = null
export let customAnchor = null export let customAnchor = null
export let loading export let loading
export let onOptionMouseenter = () => {}
export let onOptionMouseleave = () => {}
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let button let button
let component let component
let contextTooltipId = 0;
let contextTooltipAnchor = null
let contextTooltipOption = null
let previousContextTooltipOption = null
let contextTooltipVisible = false
$: sortedOptions = getSortedOptions(options, getOptionLabel, sort) $: sortedOptions = getSortedOptions(options, getOptionLabel, sort)
$: filteredOptions = getFilteredOptions( $: filteredOptions = getFilteredOptions(
sortedOptions, sortedOptions,
@ -119,28 +113,6 @@
onDestroy(() => { onDestroy(() => {
component?.removeEventListener("scroll", null) component?.removeEventListener("scroll", null)
}) })
const handleMouseenter = (e, option, idx) => {
contextTooltipId += 1;
const invokedContextTooltipId = contextTooltipId
setTimeout(() => {
if (contextTooltipId === invokedContextTooltipId) {
contextTooltipAnchor = e.target;
previousContextTooltipOption = contextTooltipOption;
contextTooltipOption = option;
contextTooltipVisible = true;
}
}, 200)
}
const handleMouseleave = (e, option) => {
setTimeout(() => {
if (option === contextTooltipOption) {
contextTooltipVisible = false;
}
}, 600)
}
</script> </script>
<button <button
@ -231,8 +203,8 @@
{#if filteredOptions.length} {#if filteredOptions.length}
{#each filteredOptions as option, idx} {#each filteredOptions as option, idx}
<li <li
on:mouseenter={(e) => handleMouseenter(e, option, idx)} on:mouseenter={(e) => onOptionMouseenter(e, option)}
on:mouseleave={(e) => handleMouseleave(e, option, idx)} on:mouseleave={(e) => onOptionMouseleave(e, option)}
class="spectrum-Menu-item" class="spectrum-Menu-item"
class:is-selected={isOptionSelected(getOptionValue(option, idx))} class:is-selected={isOptionSelected(getOptionValue(option, idx))}
role="option" role="option"
@ -300,64 +272,7 @@
{/if} {/if}
</div> </div>
</Popover> </Popover>
<ContextTooltip
visible={contextTooltipVisible}
anchor={contextTooltipAnchor}
offset={20}
>
<div
class="tooltipContents"
>
{#if contextTooltipOption}
<div class="contextTooltipHeader">
<Icon name={getOptionIcon(contextTooltipOption)} />
<Heading>{contextTooltipOption}</Heading>
</div>
<p>{getOptionTooltip(contextTooltipOption)}</p>
{/if}
</div>
<div slot="previous"
class="tooltipContents"
>
{#if previousContextTooltipOption}
<div class="contextTooltipHeader">
<Icon name={getOptionIcon(previousContextTooltipOption)} />
<Heading>{previousContextTooltipOption}</Heading>
</div>
<p>{getOptionTooltip(previousContextTooltipOption)}</p>
{/if}
</div>
</ContextTooltip>
<style> <style>
.tooltipContents {
max-width: 200px;
background-color: var(--spectrum-global-color-gray-200);
display: inline-block;
padding: 12px;
border-radius: 5px;
box-sizing: border-box;
}
.contextTooltipHeader {
display: flex;
align-items: center;
justify-content: center;
}
.contextTooltipHeader :global(svg) {
color: var(--background);
margin-right: 5px;
}
.contextTooltipHeader :global(h1) {
flex-grow: 1;
font-size: 15px;
text-wrap: wrap;
word-break: break-all;
}
.spectrum-Menu { .spectrum-Menu {
display: block; display: block;
} }

View File

@ -24,6 +24,8 @@
export let customPopoverHeight export let customPopoverHeight
export let helpText = null export let helpText = null
export let align export let align
export let onOptionMouseenter = () => {}
export let onOptionMouseleave = () => {}
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = e => {
@ -51,6 +53,8 @@
{autocomplete} {autocomplete}
{customPopoverHeight} {customPopoverHeight}
{align} {align}
{onOptionMouseenter}
{onOptionMouseleave}
bind:searchTerm bind:searchTerm
on:change={onChange} on:change={onChange}
on:click on:click

View File

@ -1,11 +1,14 @@
<script> <script>
import Portal from "svelte-portal" import Portal from "svelte-portal"
import { fade } from 'svelte/transition'; import { getContext } from "svelte"
import Context from "../context"
export let anchor export let anchor
export let visible = false export let visible = false
export let offset = 0; export let offset = 0;
$: target = getContext(Context.PopoverRoot) || ".spectrum"
let hovering = false let hovering = false
let wrapper let wrapper
let resetWrapper let resetWrapper
@ -95,7 +98,7 @@
} }
</script> </script>
<Portal target=".spectrum"> <Portal {target}>
<div <div
bind:this={wrapper} bind:this={wrapper}
on:mouseenter={handleMouseenter} on:mouseenter={handleMouseenter}

View File

@ -43,6 +43,7 @@ export {
TooltipType, TooltipType,
} from "./Tooltip/AbsTooltip.svelte" } from "./Tooltip/AbsTooltip.svelte"
export { default as TooltipWrapper } from "./Tooltip/TooltipWrapper.svelte" export { default as TooltipWrapper } from "./Tooltip/TooltipWrapper.svelte"
export { default as ContextTooltip } from "./Tooltip/Context.svelte"
export { default as Menu } from "./Menu/Menu.svelte" export { default as Menu } from "./Menu/Menu.svelte"
export { default as MenuSection } from "./Menu/Section.svelte" export { default as MenuSection } from "./Menu/Section.svelte"
export { default as MenuSeparator } from "./Menu/Separator.svelte" export { default as MenuSeparator } from "./Menu/Separator.svelte"

View File

@ -1,5 +1,5 @@
<script> <script>
import { Multiselect } from "@budibase/bbui" import { Icon, Heading, Multiselect, ContextTooltip } from "@budibase/bbui"
import { getDatasourceForProvider, getSchemaForDatasource } from "dataBinding" import { getDatasourceForProvider, getSchemaForDatasource } from "dataBinding"
import { selectedScreen } from "stores/builder" import { selectedScreen } from "stores/builder"
import { createEventDispatcher } from "svelte" import { createEventDispatcher } from "svelte"
@ -10,6 +10,12 @@
export let placeholder export let placeholder
export let fieldValidator export let fieldValidator
let contextTooltipId = 0;
let contextTooltipAnchor = null
let contextTooltipOption = null
let previousContextTooltipOption = null
let contextTooltipVisible = false
const TypeIconMap = { const TypeIconMap = {
text: "Text", text: "Text",
options: "Dropdown", options: "Dropdown",
@ -105,9 +111,7 @@
const support = fieldSupport[optionKey]?.support; const support = fieldSupport[optionKey]?.support;
const message = fieldSupport[optionKey]?.message; const message = fieldSupport[optionKey]?.message;
if (support === unsupported) return message return message
return null
} }
const isOptionEnabled = optionKey => { const isOptionEnabled = optionKey => {
@ -120,17 +124,103 @@
return true return true
} }
const onOptionMouseenter = (e, option, idx) => {
contextTooltipId += 1;
const invokedContextTooltipId = contextTooltipId
setTimeout(() => {
if (contextTooltipId === invokedContextTooltipId) {
contextTooltipAnchor = e.target;
previousContextTooltipOption = contextTooltipOption;
contextTooltipOption = option;
contextTooltipVisible = true;
}
}, 200)
}
const onOptionMouseleave = (e, option) => {
setTimeout(() => {
if (option === contextTooltipOption) {
contextTooltipVisible = false;
}
}, 600)
}
</script> </script>
<Multiselect <Multiselect
iconPosition="right" iconPosition="right"
{isOptionEnabled} {isOptionEnabled}
{getOptionIcon}
{getOptionIconTooltip}
{getOptionTooltip}
{placeholder} {placeholder}
value={boundValue} value={boundValue}
on:change={setValue} on:change={setValue}
{options} {options}
align="right" align="right"
{onOptionMouseenter}
{onOptionMouseleave}
/> />
<ContextTooltip
visible={contextTooltipVisible}
anchor={contextTooltipAnchor}
offset={20}
>
<div
class="tooltipContents"
>
{#if contextTooltipOption}
<div class="contextTooltipHeader">
<Icon name={getOptionIcon(contextTooltipOption)} />
<span>{contextTooltipOption}</span>
</div>
<p>{getOptionTooltip(contextTooltipOption)}</p>
{/if}
</div>
<div slot="previous"
class="tooltipContents"
>
{#if previousContextTooltipOption}
<div class="contextTooltipHeader">
<Icon name={getOptionIcon(previousContextTooltipOption)} />
<span>{previousContextTooltipOption}</span>
</div>
<p>{getOptionTooltip(previousContextTooltipOption)}</p>
{/if}
</div>
</ContextTooltip>
<style>
.tooltipContents {
max-width: 200px;
background-color: var(--spectrum-global-color-gray-200);
display: inline-block;
padding: 12px;
border-radius: 5px;
box-sizing: border-box;
}
.contextTooltipHeader {
display: flex;
align-items: center;
justify-content: center;
height: var(--spectrum-alias-item-height-m);
padding: 0px var(--spectrum-alias-item-padding-m);
border-width: var(--spectrum-actionbutton-border-size);
border-radius: var(--spectrum-alias-border-radius-regular);
border: 1px solid
var(
--spectrum-actionbutton-m-border-color,
var(--spectrum-alias-border-color)
);
}
.contextTooltipHeader :global(svg) {
color: var(--background);
margin-right: 5px;
}
.contextTooltipHeader :global(span) {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>