mirror of https://github.com/Budibase/budibase.git
25 changed files with 191 additions and 230 deletions
@ -1,35 +1,43 @@ |
|||||
<script> |
<script> |
||||
import { getContext, onMount } from 'svelte' |
import { getContext, onMount } from "svelte" |
||||
import Portal from "svelte-portal" |
import Portal from "svelte-portal" |
||||
export let title |
export let title |
||||
export let icon = ''; |
export let icon = "" |
||||
|
|
||||
const selected = getContext('tab') |
|
||||
let tab; |
|
||||
let tabInfo |
|
||||
const setTabInfo = () => { |
|
||||
tabInfo = tab.getBoundingClientRect() |
|
||||
if ($selected.title === title) { |
|
||||
$selected.info = tabInfo |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
onMount(() => { |
const selected = getContext("tab") |
||||
setTabInfo() |
let tab |
||||
}) |
let tabInfo |
||||
|
const setTabInfo = () => { |
||||
|
tabInfo = tab.getBoundingClientRect() |
||||
|
if ($selected.title === title) { |
||||
|
$selected.info = tabInfo |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
onMount(() => { |
||||
|
setTabInfo() |
||||
|
}) |
||||
</script> |
</script> |
||||
|
|
||||
<div bind:this={tab} on:click={() => $selected = {...$selected, title, info: tab.getBoundingClientRect()} } class:is-selected={$selected.title === title} class="spectrum-Tabs-item" tabindex="0"> |
<div |
||||
{#if icon} |
bind:this={tab} |
||||
<svg class="spectrum-Icon spectrum-Icon--sizeM" focusable="false" aria-hidden="true" aria-label="Folder"> |
on:click={() => ($selected = { ...$selected, title, info: tab.getBoundingClientRect() })} |
||||
<use xlink:href="#spectrum-icon-18-{icon}" /> |
class:is-selected={$selected.title === title} |
||||
</svg> |
class="spectrum-Tabs-item" |
||||
{/if} |
tabindex="0"> |
||||
<span class="spectrum-Tabs-itemLabel">{title}</span> |
{#if icon} |
||||
|
<svg |
||||
|
class="spectrum-Icon spectrum-Icon--sizeM" |
||||
|
focusable="false" |
||||
|
aria-hidden="true" |
||||
|
aria-label="Folder"> |
||||
|
<use xlink:href="#spectrum-icon-18-{icon}" /> |
||||
|
</svg> |
||||
|
{/if} |
||||
|
<span class="spectrum-Tabs-itemLabel">{title}</span> |
||||
</div> |
</div> |
||||
{#if $selected.title === title} |
{#if $selected.title === title} |
||||
<Portal target=".spectrum-Tabs-content-{$selected.id}"> |
<Portal target=".spectrum-Tabs-content-{$selected.id}"> |
||||
<slot /> |
<slot /> |
||||
</Portal> |
</Portal> |
||||
{/if} |
{/if} |
||||
|
|||||
@ -1,71 +1,82 @@ |
|||||
<script> |
<script> |
||||
import "@spectrum-css/tabs/dist/index-vars.css" |
import "@spectrum-css/tabs/dist/index-vars.css" |
||||
import { writable } from 'svelte/store' |
import { writable } from "svelte/store" |
||||
import { onMount, setContext, createEventDispatcher } from 'svelte' |
import { onMount, setContext, createEventDispatcher } from "svelte" |
||||
|
|
||||
export let selected; |
|
||||
export let vertical = false |
|
||||
let _id = id() |
|
||||
const tab = writable({title: selected, id: _id}) |
|
||||
setContext('tab', tab) |
|
||||
|
|
||||
let container; |
|
||||
|
|
||||
const dispatch = createEventDispatcher() |
export let selected |
||||
|
export let vertical = false |
||||
|
let _id = id() |
||||
|
const tab = writable({ title: selected, id: _id }) |
||||
|
setContext("tab", tab) |
||||
|
|
||||
$: selected = $tab.title |
let container |
||||
$: selected = dispatch('select', selected) |
|
||||
|
|
||||
let top, left, width, height; |
const dispatch = createEventDispatcher() |
||||
$: calculateIndicatorLength($tab) |
|
||||
$: calculateIndicatorOffset($tab) |
|
||||
|
|
||||
function calculateIndicatorLength() { |
$: selected = $tab.title |
||||
if (!vertical) { |
$: selected = dispatch("select", selected) |
||||
width = $tab.info?.width + 24 + 'px' |
|
||||
height = $tab.info?.height |
let top, left, width, height |
||||
} else { |
$: calculateIndicatorLength($tab) |
||||
height = $tab.info?.height + 4 + 'px' |
$: calculateIndicatorOffset($tab) |
||||
width = $tab.info?.width |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
function calculateIndicatorOffset() { |
function calculateIndicatorLength() { |
||||
if (!vertical) { |
if (!vertical) { |
||||
left = $tab.info?.left - container?.getBoundingClientRect().left - 12 + 'px' |
width = $tab.info?.width + "px" |
||||
top = $tab.info?.top |
height = $tab.info?.height |
||||
} else { |
} else { |
||||
top = $tab.info?.top - container?.getBoundingClientRect().top + 'px' |
height = $tab.info?.height + 4 + "px" |
||||
left = $tab.info?.left |
width = $tab.info?.width |
||||
} |
|
||||
} |
} |
||||
|
} |
||||
onMount(() => { |
|
||||
calculateIndicatorLength() |
|
||||
calculateIndicatorOffset() |
|
||||
}) |
|
||||
|
|
||||
function id() { |
function calculateIndicatorOffset() { |
||||
return ( |
if (!vertical) { |
||||
"_" + |
left = $tab.info?.left - container?.getBoundingClientRect().left + "px" |
||||
Math.random() |
top = $tab.info?.top |
||||
.toString(36) |
} else { |
||||
.substr(2, 9) |
top = $tab.info?.top - container?.getBoundingClientRect().top + "px" |
||||
) |
left = $tab.info?.left |
||||
} |
} |
||||
|
} |
||||
|
|
||||
|
onMount(() => { |
||||
|
calculateIndicatorLength() |
||||
|
calculateIndicatorOffset() |
||||
|
}) |
||||
|
|
||||
|
function id() { |
||||
|
return ( |
||||
|
"_" + |
||||
|
Math.random() |
||||
|
.toString(36) |
||||
|
.substr(2, 9) |
||||
|
) |
||||
|
} |
||||
</script> |
</script> |
||||
<div bind:this={container} class="selected-border spectrum-Tabs spectrum-Tabs--{vertical ? 'vertical' : 'horizontal'}"> |
|
||||
<slot /> |
<div |
||||
<div class="spectrum-Tabs-selectionIndicator indicator-transition" style="width: {width}; height: {height}; left: {left}; top: {top};"></div> |
bind:this={container} |
||||
|
class="selected-border spectrum-Tabs spectrum-Tabs--{vertical ? 'vertical' : 'horizontal'}"> |
||||
|
<slot /> |
||||
|
{#if $tab.info} |
||||
|
<div |
||||
|
class="spectrum-Tabs-selectionIndicator indicator-transition" |
||||
|
style="width: {width}; height: {height}; left: {left}; top: {top};" /> |
||||
|
{/if} |
||||
</div> |
</div> |
||||
|
|
||||
<div class="spectrum-Tabs-content spectrum-Tabs-content-{_id}" /> |
<div class="spectrum-Tabs-content spectrum-Tabs-content-{_id}" /> |
||||
|
|
||||
<style> |
<style> |
||||
.spectrum-Tabs-content { |
.spectrum-Tabs { |
||||
margin-top: var(--spectrum-global-dimension-static-size-150); |
padding-left: var(--spacing-xl); |
||||
} |
padding-right: var(--spacing-xl); |
||||
.indicator-transition { |
} |
||||
transition: all 200ms |
.spectrum-Tabs-content { |
||||
} |
margin-top: var(--spectrum-global-dimension-static-size-150); |
||||
</style> |
} |
||||
|
.indicator-transition { |
||||
|
transition: all 200ms; |
||||
|
} |
||||
|
</style> |
||||
|
|||||
Loading…
Reference in new issue