|
1 | 1 | <script lang="ts"> |
2 | 2 | import { randomHex } from '@dvcol/common-utils/common/crypto'; |
3 | 3 |
|
| 4 | + import { fade } from 'svelte/transition'; |
| 5 | +
|
4 | 6 | import SphereBackdrop from '../utils/SphereBackdrop.svelte'; |
5 | 7 |
|
6 | 8 | import type { TabId } from '~/nav/neo-tab.model.js'; |
7 | | - import type { TabsProps } from '~/nav/neo-tabs.model.js'; |
| 9 | + import type { NeoTabsProps } from '~/nav/neo-tabs.model.js'; |
8 | 10 |
|
9 | 11 | import NeoButton from '~/buttons/NeoButton.svelte'; |
10 | 12 | import NeoButtonGroup from '~/buttons/NeoButtonGroup.svelte'; |
11 | 13 | import NeoCard from '~/cards/NeoCard.svelte'; |
| 14 | + import TransitionContainer from '~/container/TransitionContainer.svelte'; |
12 | 15 | import IconAccount from '~/icons/IconAccount.svelte'; |
13 | 16 | import NeoTab from '~/nav/NeoTab.svelte'; |
14 | 17 | import NeoTabPane from '~/nav/NeoTabPane.svelte'; |
15 | 18 | import NeoTabs from '~/nav/NeoTabs.svelte'; |
16 | 19 |
|
17 | 20 | const added = $state([ |
18 | | - { text: `Added ${randomHex(2)}-0`, tabId: crypto.randomUUID() }, |
19 | | - { text: `Added ${randomHex(2)}-1`, tabId: crypto.randomUUID() }, |
| 21 | + { text: `Added ${randomHex(1)}-0`, tabId: crypto.randomUUID() }, |
| 22 | + { text: `Added ${randomHex(1)}-1`, tabId: crypto.randomUUID() }, |
20 | 23 | ]); |
21 | 24 | const onclose = (id: TabId) => { |
22 | 25 | const index = added.findIndex(tab => tab.tabId === id); |
23 | 26 | if (index === -1) return; |
24 | 27 | added.splice(index, 1); |
25 | 28 | }; |
26 | 29 | const onadd = () => { |
27 | | - added.push({ text: `Added ${randomHex(2)}-${added.length + 1}`, tabId: crypto.randomUUID() }); |
| 30 | + added.push({ text: `Added ${randomHex(1)}-${added.length + 1}`, tabId: crypto.randomUUID() }); |
28 | 31 | }; |
29 | 32 |
|
30 | 33 | let active: unknown | undefined = $state(); |
31 | 34 | const onClear = () => { |
32 | 35 | active = undefined; |
33 | 36 | }; |
34 | 37 |
|
35 | | - let loading = $state(false); |
36 | | - const options = $state<TabsProps>({ |
| 38 | + const options = $state<NeoTabsProps>({ |
37 | 39 | disabled: false, |
38 | 40 | close: true, |
39 | 41 | add: true, |
|
43 | 45 | before: false, |
44 | 46 | skeleton: false, |
45 | 47 | vertical: false, |
| 48 | + nowrap: false, |
46 | 49 | }); |
47 | 50 |
|
48 | | - const columns: { label: string; props?: TabsProps }[] = [{ label: 'Default' }]; |
| 51 | + const columns: { label: string; props?: NeoTabsProps }[] = [{ label: 'Default' }]; |
49 | 52 | </script> |
50 | 53 |
|
51 | 54 | <div class="row"> |
|
55 | 58 | <NeoButton toggle bind:checked={options.shallow}>Shallow</NeoButton> |
56 | 59 | <NeoButton toggle bind:checked={options.before}>Before</NeoButton> |
57 | 60 | <NeoButton toggle bind:checked={options.vertical}>Vertical</NeoButton> |
| 61 | + <NeoButton toggle bind:checked={options.nowrap}>No Wrap</NeoButton> |
58 | 62 | <NeoButton toggle bind:checked={options.skeleton}>Skeleton</NeoButton> |
59 | | - <NeoButton toggle bind:checked={loading}>Loading</NeoButton> |
60 | 63 | <NeoButton onclick={onClear}>Clear</NeoButton> |
61 | 64 | </NeoButtonGroup> |
62 | 65 | </div> |
|
68 | 71 |
|
69 | 72 | {#snippet tabs()} |
70 | 73 | <NeoTab tabId="button" value="button" close={false}>Button</NeoTab> |
71 | | - <NeoTab tabId="icon" value="icon" {loading} close={false} {icon} /> |
| 74 | + <NeoTab tabId="icon" value="icon" close={false} {icon}>Icon</NeoTab> |
72 | 75 | <NeoTab tabId="reversed" value="reversed" reverse close={false} {icon}>Reversed</NeoTab> |
73 | 76 | {#each added as { text, ...tab } (tab.tabId)} |
74 | 77 | <NeoTab {...tab}>{text}</NeoTab> |
75 | 78 | {/each} |
76 | 79 | {/snippet} |
77 | 80 |
|
78 | 81 | {#snippet content(word)} |
79 | | - <div>{Array.from({ length: 10 }, () => word).join(' ')}</div> |
80 | | - <div>{Array.from({ length: 10 }, () => word).join(' ')}</div> |
81 | | - <div>{Array.from({ length: 10 }, () => word).join(' ')}</div> |
82 | | - <div>{Array.from({ length: 10 }, () => word).join(' ')}</div> |
83 | | - <div>{Array.from({ length: 10 }, () => word).join(' ')}</div> |
| 82 | + <div class="panel" in:fade={{ delay: 400 }} out:fade> |
| 83 | + <div>{Array.from({ length: 10 }, () => word).join(' ')}</div> |
| 84 | + <div>{Array.from({ length: 10 }, () => word).join(' ')}</div> |
| 85 | + <div>{Array.from({ length: 10 }, () => word).join(' ')}</div> |
| 86 | + <div>{Array.from({ length: 10 }, () => word).join(' ')}</div> |
| 87 | + <div>{Array.from({ length: 10 }, () => word).join(' ')}</div> |
| 88 | + </div> |
84 | 89 | {/snippet} |
85 | 90 |
|
86 | 91 | {#snippet panes()} |
87 | 92 | <NeoCard> |
88 | | - <NeoTabPane empty> |
89 | | - {@render content('Empty')} |
90 | | - </NeoTabPane> |
91 | | - <NeoTabPane tabId="button"> |
92 | | - {@render content('Button')} |
93 | | - </NeoTabPane> |
94 | | - <NeoTabPane tabId="icon"> |
95 | | - {@render content('Icon')} |
96 | | - </NeoTabPane> |
97 | | - <NeoTabPane tabId="reversed"> |
98 | | - {@render content('Reversed')} |
99 | | - </NeoTabPane> |
100 | | - |
101 | | - {#each added as { text, tabId } (tabId)} |
102 | | - <NeoTabPane {tabId}> |
103 | | - {@render content(text)} |
| 93 | + <TransitionContainer> |
| 94 | + <NeoTabPane empty> |
| 95 | + {@render content('Empty')} |
| 96 | + </NeoTabPane> |
| 97 | + <NeoTabPane tabId="button"> |
| 98 | + {@render content('Button')} |
| 99 | + </NeoTabPane> |
| 100 | + <NeoTabPane tabId="icon"> |
| 101 | + {@render content('Icon')} |
104 | 102 | </NeoTabPane> |
105 | | - {/each} |
| 103 | + <NeoTabPane tabId="reversed"> |
| 104 | + {@render content('Reversed')} |
| 105 | + </NeoTabPane> |
| 106 | + |
| 107 | + {#each added as { text, tabId } (tabId)} |
| 108 | + <NeoTabPane {tabId}> |
| 109 | + {@render content(text)} |
| 110 | + </NeoTabPane> |
| 111 | + {/each} |
| 112 | + </TransitionContainer> |
106 | 113 | </NeoCard> |
107 | 114 | {/snippet} |
108 | 115 |
|
109 | | -{#snippet group(props: TabsProps = {})} |
| 116 | +{#snippet group(props: NeoTabsProps = {})} |
110 | 117 | <div class="column"> |
111 | 118 | <NeoTabs {panes} {active} {onclose} {onadd} {...options} {...props}> |
112 | 119 | {@render tabs()} |
|
131 | 138 | <style lang="scss"> |
132 | 139 | @use 'src/lib/styles/common/flex' as flex; |
133 | 140 |
|
134 | | - .content { |
135 | | - width: min-content; |
136 | | - } |
137 | | -
|
138 | 141 | .column { |
139 | 142 | @include flex.column($center: true, $gap: var(--neo-gap-lg)); |
140 | 143 | } |
141 | 144 |
|
142 | 145 | .row { |
143 | | - @include flex.row($gap: var(--neo-gap-xl)); |
| 146 | + @include flex.row($gap: var(--neo-gap-xl), $flex: 0 1 auto); |
144 | 147 |
|
145 | 148 | align-items: center; |
146 | 149 | justify-content: center; |
147 | 150 | margin: 2rem 0; |
148 | 151 | } |
| 152 | +
|
| 153 | + .content { |
| 154 | + flex: 0 1 37.5rem; |
| 155 | + max-width: 37.5rem; |
| 156 | + } |
| 157 | +
|
| 158 | + .panel { |
| 159 | + min-width: 37.5rem; |
| 160 | + min-height: 15rem; |
| 161 | + } |
149 | 162 | </style> |
0 commit comments