1
0
Fork 0
mirror of synced 2024-06-02 02:25:17 +12:00
budibase/packages/bbui/src/Tabs/Tabs.svelte

131 lines
3.1 KiB
Svelte

<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
export let noPadding = false
// added as a separate option as noPadding is used for vertical padding
export let noHorizPadding = false
export let quiet = false
export let emphasized = false
export let onTop = false
export let size = "M"
let thisSelected = undefined
let _id = id()
const tab = writable({ title: selected, id: _id, emphasized })
setContext("tab", tab)
let container
const dispatch = createEventDispatcher()
$: {
if (thisSelected !== selected) {
thisSelected = selected
dispatch("select", thisSelected)
} else if ($tab.title !== thisSelected) {
thisSelected = $tab.title
selected = $tab.title
dispatch("select", thisSelected)
}
if ($tab.title !== thisSelected) {
tab.update(state => {
state.title = thisSelected
return state
})
}
}
let top, left, width, height
$: calculateIndicatorLength($tab)
$: calculateIndicatorOffset($tab)
function calculateIndicatorLength() {
if (!vertical) {
width = $tab.info?.width + "px"
height = $tab.info?.height
} else {
height = $tab.info?.height + 4 + "px"
width = $tab.info?.width
}
}
function calculateIndicatorOffset() {
if (!vertical) {
left = $tab.info?.left - container?.getBoundingClientRect().left + "px"
} else {
top = $tab.info?.top - container?.getBoundingClientRect().top + "px"
}
}
onMount(() => {
calculateIndicatorLength()
calculateIndicatorOffset()
})
function id() {
return "_" + Math.random().toString(36).slice(2, 9)
}
</script>
<div
bind:this={container}
class:spectrum-Tabs--quiet={quiet}
class:noHorizPadding
class:onTop
class:spectrum-Tabs--vertical={vertical}
class:spectrum-Tabs--horizontal={!vertical}
class="spectrum-Tabs spectrum-Tabs--size{size}"
>
<slot />
{#if $tab.info}
<div
class="spectrum-Tabs-selectionIndicator"
class:emphasized
style="width: {width}; height: {height}; left: {left}; top: {top};"
/>
{/if}
</div>
<div
class="spectrum-Tabs-content spectrum-Tabs-content-{_id}"
class:noPadding
/>
<style>
.spectrum-Tabs--quiet {
border-bottom: none !important;
}
.spectrum-Tabs {
padding-left: var(--spacing-xl);
padding-right: var(--spacing-xl);
position: relative;
border-bottom-color: var(--spectrum-global-color-gray-200);
}
.spectrum-Tabs-content {
margin-top: var(--spectrum-global-dimension-static-size-150);
}
.spectrum-Tabs-selectionIndicator {
transition: all 200ms;
background-color: var(--spectrum-global-color-gray-900);
}
.spectrum-Tabs-selectionIndicator.emphasized {
background-color: var(--spectrum-global-color-blue-400);
}
.spectrum-Tabs--horizontal .spectrum-Tabs-selectionIndicator {
}
.noHorizPadding {
padding: 0;
}
.noPadding {
margin: 0;
}
.onTop {
z-index: 100;
}
</style>