|
| 1 | +<script lang="ts"> |
| 2 | + import { randomHex } from '@dvcol/common-utils/common/crypto'; |
| 3 | +
|
| 4 | + import SphereBackdrop from '../utils/SphereBackdrop.svelte'; |
| 5 | +
|
| 6 | + import type { TabId } from '~/nav/neo-tab.model.js'; |
| 7 | + import type { TabsProps } from '~/nav/neo-tabs.model.js'; |
| 8 | +
|
| 9 | + import NeoButton from '~/buttons/NeoButton.svelte'; |
| 10 | + import NeoButtonGroup from '~/buttons/NeoButtonGroup.svelte'; |
| 11 | + import IconAccount from '~/icons/IconAccount.svelte'; |
| 12 | + import NeoTab from '~/nav/NeoTab.svelte'; |
| 13 | + import NeoTabPane from '~/nav/NeoTabPane.svelte'; |
| 14 | + import NeoTabs from '~/nav/NeoTabs.svelte'; |
| 15 | +
|
| 16 | + const added = $state([ |
| 17 | + { text: `Added ${randomHex(2)}-0`, tabId: crypto.randomUUID() }, |
| 18 | + { text: `Added ${randomHex(2)}-1`, tabId: crypto.randomUUID() }, |
| 19 | + ]); |
| 20 | + const onclose = (id: TabId) => { |
| 21 | + const index = added.findIndex(tab => tab.tabId === id); |
| 22 | + if (index === -1) return; |
| 23 | + added.splice(index, 1); |
| 24 | + }; |
| 25 | + const onadd = () => { |
| 26 | + added.push({ text: `Added ${randomHex(2)}-${added.length + 1}`, tabId: crypto.randomUUID() }); |
| 27 | + }; |
| 28 | +
|
| 29 | + let active: unknown | undefined = $state(); |
| 30 | + const onClear = () => { |
| 31 | + active = undefined; |
| 32 | + }; |
| 33 | +
|
| 34 | + let loading = $state(false); |
| 35 | + let skeleton = $state(false); |
| 36 | + let vertical = $state(false); |
| 37 | + const options = $state({ disabled: false, close: true, add: true, slide: true, shallow: false, toggle: true, position: 'after' }); |
| 38 | +
|
| 39 | + const togglePosition = () => { |
| 40 | + options.position = options.position === 'after' ? 'before' : 'after'; |
| 41 | + }; |
| 42 | +
|
| 43 | + const columns: { label: string; props?: TabsProps }[] = [{ label: 'Default' }]; |
| 44 | +</script> |
| 45 | + |
| 46 | +<div class="row"> |
| 47 | + <div class="column"> |
| 48 | + <NeoButtonGroup> |
| 49 | + <NeoButton toggle bind:checked={options.disabled}>Disabled</NeoButton> |
| 50 | + <NeoButton toggle bind:checked={options.shallow}>Shallow</NeoButton> |
| 51 | + <NeoButton onclick={togglePosition}>Position</NeoButton> |
| 52 | + <NeoButton toggle bind:checked={vertical}>Vertical</NeoButton> |
| 53 | + <NeoButton toggle bind:checked={skeleton}>Skeleton</NeoButton> |
| 54 | + <NeoButton toggle bind:checked={loading}>Loading</NeoButton> |
| 55 | + <NeoButton onclick={onClear}>Clear</NeoButton> |
| 56 | + </NeoButtonGroup> |
| 57 | + </div> |
| 58 | +</div> |
| 59 | + |
| 60 | +{#snippet icon()} |
| 61 | + <IconAccount /> |
| 62 | +{/snippet} |
| 63 | + |
| 64 | +{#snippet tabs()} |
| 65 | + <NeoTab tabId="button" value="button" close={false}>Button</NeoTab> |
| 66 | + <NeoTab tabId="icon" value="icon" {loading} close={false} {icon} /> |
| 67 | + <NeoTab tabId="reversed" value="reversed" reverse close={false} {icon}>Reversed</NeoTab> |
| 68 | + {#each added as { text, ...tab } (tab.tabId)} |
| 69 | + <NeoTab {...tab}>{text}</NeoTab> |
| 70 | + {/each} |
| 71 | +{/snippet} |
| 72 | + |
| 73 | +{#snippet panes()} |
| 74 | + <NeoTabPane empty> |
| 75 | + <div>Empty</div> |
| 76 | + </NeoTabPane> |
| 77 | + <NeoTabPane tabId="button"> |
| 78 | + <div>Button</div> |
| 79 | + </NeoTabPane> |
| 80 | + <NeoTabPane tabId="icon" {loading} {icon}> |
| 81 | + <div>Icon</div> |
| 82 | + </NeoTabPane> |
| 83 | + <NeoTabPane tabId="reversed" {icon}> |
| 84 | + <div>Reversed</div> |
| 85 | + </NeoTabPane> |
| 86 | + |
| 87 | + {#each added as { text, tabId } (tabId)} |
| 88 | + <NeoTabPane {tabId}>{text}</NeoTabPane> |
| 89 | + {/each} |
| 90 | +{/snippet} |
| 91 | + |
| 92 | +{#snippet group(props: TabsProps = {})} |
| 93 | + <div class="column"> |
| 94 | + <NeoTabs {panes} {active} {vertical} {skeleton} {onclose} {onadd} {...options} {...props}> |
| 95 | + {@render tabs()} |
| 96 | + </NeoTabs> |
| 97 | + </div> |
| 98 | +{/snippet} |
| 99 | + |
| 100 | +<div class="row"> |
| 101 | + {#each columns as { label, props }} |
| 102 | + <div class="column"> |
| 103 | + <span class="label">{label}</span> |
| 104 | + |
| 105 | + {#if props?.glass} |
| 106 | + <SphereBackdrop>{@render group(props)}</SphereBackdrop> |
| 107 | + {:else} |
| 108 | + {@render group(props)} |
| 109 | + {/if} |
| 110 | + </div> |
| 111 | + {/each} |
| 112 | +</div> |
| 113 | + |
| 114 | +<style lang="scss"> |
| 115 | + @use 'src/lib/styles/common/flex' as flex; |
| 116 | +
|
| 117 | + .column { |
| 118 | + @include flex.column($center: true, $gap: var(--gap-lg)); |
| 119 | + } |
| 120 | +
|
| 121 | + .row { |
| 122 | + @include flex.row($gap: var(--gap-xl)); |
| 123 | +
|
| 124 | + align-items: center; |
| 125 | + justify-content: center; |
| 126 | + margin: 2rem 0; |
| 127 | + } |
| 128 | +</style> |
0 commit comments