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