|
3 | 3 |
|
4 | 4 | import { untrack } from 'svelte'; |
5 | 5 |
|
6 | | - import type { OnChange, TabsProps } from '~/nav/neo-tabs.model.js'; |
| 6 | + import type { NeoTabsContext, OnChange, TabsProps } from '~/nav/neo-tabs.model.js'; |
7 | 7 |
|
8 | 8 | import NeoButton from '~/buttons/NeoButton.svelte'; |
9 | 9 | import NeoButtonGroup from '~/buttons/NeoButtonGroup.svelte'; |
10 | 10 | import IconAdd from '~/icons/IconAdd.svelte'; |
11 | 11 | import { type NeoTabContextPositions, setTabContext } from '~/nav/neo-tabs-context.svelte.js'; |
| 12 | + import { toAction, toActionProps } from '~/utils/action.utils.js'; |
12 | 13 |
|
13 | 14 | /* eslint-disable prefer-const -- necessary for binding checked */ |
14 | 15 | let { |
|
66 | 67 |
|
67 | 68 | const style = $derived([tabsProps?.style, position].filter(Boolean).join('; ')); |
68 | 69 |
|
69 | | - $inspect(position).with((...args) => console.info('position', ...args)); |
70 | | -
|
71 | 70 | // reflect component active to context |
72 | 71 | $effect(() => { |
73 | | - console.info('active', active, context.active); |
74 | 72 | if (active === context.active) return; |
75 | 73 | untrack(() => context.onChange(active)); |
76 | 74 | }); |
77 | 75 |
|
78 | 76 | $effect(() => { |
79 | | - context.onOption({ slide, line, closeable: close, disabled, vertical: rest.vertical }); |
| 77 | + context.onOption({ line, slide, closeable: close, disabled, vertical: rest.vertical }); |
80 | 78 | }); |
| 79 | +
|
| 80 | + const childContext: NeoTabsContext = $derived({ active, disabled, slide, close, add, vertical: rest.vertical }); |
| 81 | +
|
| 82 | + const useFn = $derived(toAction(tabsProps?.use)); |
| 83 | + const useProps = $derived(toActionProps(tabsProps?.use)); |
81 | 84 | </script> |
82 | 85 |
|
83 | 86 | {#snippet icon()} |
|
94 | 97 | class:text={rest.text} |
95 | 98 | class:vertical={rest.vertical} |
96 | 99 | class:rounded={rest.rounded} |
| 100 | + class:shallow={rest.shallow} |
97 | 101 | {...tabsProps} |
| 102 | + use:useFn={useProps} |
98 | 103 | {style} |
99 | 104 | > |
100 | 105 | <NeoButtonGroup {...rest}> |
101 | | - {@render children?.({ active, disabled, slide, close, add, vertical: rest.vertical })} |
| 106 | + {@render children?.(childContext)} |
102 | 107 | {#if add} |
103 | 108 | <div transition:transition={{ duration: 200, css: `overflow: hidden; white-space: nowrap` }}> |
104 | 109 | <NeoButton onclick={onadd} {icon} /> |
|
136 | 141 | padding-bottom: 0.5rem; |
137 | 142 | } |
138 | 143 |
|
139 | | - &.line :global(.neo-tab.active::before) { |
140 | | - --neo-tab-full-width: 2px; |
141 | | - --neo-tab-old-width: 2px; |
| 144 | + &.line { |
| 145 | + :global(.neo-tab::before) { |
| 146 | + --neo-tab-width: 2px; |
| 147 | + --neo-tab-old-width: 2px; |
| 148 | + --neo-tab-old-max-height: calc(var(--neo-tab-old-height, 100%) - 1rem); |
| 149 | + --neo-tab-max-height: calc(var(--neo-tab-height, 100%) - 1rem); |
| 150 | +
|
| 151 | + top: 0; |
| 152 | + width: 2px; |
| 153 | + height: 0; |
| 154 | + max-height: var(--neo-tab-max-height); |
| 155 | + margin-left: 0.3rem; |
| 156 | + transition: |
| 157 | + box-shadow 0.3s ease, |
| 158 | + height 0.3s var(--transition-bezier); |
| 159 | + margin-block: 0.5rem; |
| 160 | + } |
| 161 | +
|
| 162 | + :global(.neo-tab.active::before) { |
| 163 | + height: var(--neo-tab-height, 100%); |
| 164 | + } |
142 | 165 | } |
143 | 166 | } |
144 | 167 |
|
|
147 | 170 | } |
148 | 171 |
|
149 | 172 | &.slide { |
150 | | - --neo-tab-full-width: 100%; |
151 | | - --neo-tab-full-height: 100%; |
| 173 | + --neo-tab-width: 100%; |
| 174 | + --neo-tab-height: 100%; |
152 | 175 |
|
153 | 176 | :global(.neo-tab .neo-button) { |
154 | | - box-shadow: var(--box-shadow-flat); |
| 177 | + color: var(--neo-btn-text-color, inherit); |
| 178 | + box-shadow: var(--box-shadow-flat) !important; |
155 | 179 | transition: none; |
156 | 180 | } |
157 | 181 |
|
|
165 | 189 | top: calc(0 - var(--border-width, 1px)); |
166 | 190 | left: calc(0 - var(--border-width, 1px)); |
167 | 191 | z-index: var(--z-index-in-front, 1); |
168 | | - width: var(--neo-tab-full-width, 100%); |
169 | | - height: var(--neo-tab-full-height, 100%); |
| 192 | + width: var(--neo-tab-width, 100%); |
| 193 | + height: var(--neo-tab-height, 100%); |
170 | 194 | border: var(--border-width, 1px) var(--neo-tab-border-color, transparent) solid; |
171 | 195 | border-radius: var(--neo-tab-border-radius, var(--border-radius)); |
172 | 196 | box-shadow: var(--box-shadow-flat); |
|
178 | 202 |
|
179 | 203 | &.line :global(.neo-tab.active::before) { |
180 | 204 | bottom: 0; |
181 | | - height: 2px; |
182 | 205 | background-color: var(--color-primary, var(--text-color)); |
183 | 206 | box-shadow: var(--box-shadow-flat); |
184 | | - transition: |
185 | | - box-shadow 0.3s ease, |
186 | | - width 0.3s var(--transition-bezier); |
187 | 207 | } |
188 | 208 |
|
189 | | - &.line:not(.vertical) :global(.neo-tab.active::before) { |
190 | | - --neo-tab-full-height: 2px; |
191 | | - --neo-tab-old-height: 2px; |
| 209 | + &.line:not(.vertical) { |
| 210 | + :global(.neo-tab::before) { |
| 211 | + --neo-tab-height: 2px; |
| 212 | + --neo-tab-old-height: 2px; |
| 213 | + --neo-tab-old-max-width: calc(var(--neo-tab-old-width, 100%) - 1.5rem); |
| 214 | + --neo-tab-max-width: calc(var(--neo-tab-width, 100%) - 1.5rem); |
| 215 | +
|
| 216 | + width: 0; |
| 217 | + max-width: var(--neo-tab-max-width); |
| 218 | + height: 2px; |
| 219 | + margin-bottom: 0.125rem; |
| 220 | + transition: |
| 221 | + box-shadow 0.3s ease, |
| 222 | + width 0.3s var(--transition-bezier); |
| 223 | + margin-inline: 0.75rem; |
| 224 | + } |
| 225 | +
|
| 226 | + :global(.neo-tab.active::before) { |
| 227 | + width: var(--neo-tab-width, 100%); |
| 228 | + } |
192 | 229 | } |
193 | 230 |
|
194 | 231 | :global(.neo-tab.active::before) { |
|
201 | 238 |
|
202 | 239 | @keyframes slide { |
203 | 240 | 0% { |
204 | | - width: var(--neo-tab-old-width, var(--neo-tab-full-width, 100%)); |
205 | | - height: var(--neo-tab-old-height, var(--neo-tab-full-height, 100%)); |
| 241 | + width: var(--neo-tab-old-width, var(--neo-tab-width, 100%)); |
| 242 | + max-width: var(--neo-tab-old-max-width); |
| 243 | + height: var(--neo-tab-old-height, var(--neo-tab-height, 100%)); |
| 244 | + max-height: var(--neo-tab-old-max-height); |
206 | 245 | box-shadow: var(--box-shadow-inset-2); |
207 | 246 | transform: var(--transform); |
208 | 247 | } |
209 | 248 |
|
210 | 249 | 100% { |
211 | | - width: var(--neo-tab-full-width, 100%); |
212 | | - height: var(--neo-tab-full-height, 100%); |
| 250 | + width: var(--neo-tab-width, 100%); |
| 251 | + max-width: var(--neo-tab-max-width); |
| 252 | + height: var(--neo-tab-height, 100%); |
| 253 | + max-height: var(--neo-tab-max-height); |
213 | 254 | box-shadow: var(--box-shadow-inset-2); |
214 | 255 | transform: translate(0, 0); |
215 | 256 | } |
|
225 | 266 | } |
226 | 267 | } |
227 | 268 |
|
| 269 | + &.shallow { |
| 270 | + --box-shadow-inset-2: var(--box-shadow-inset-1); |
| 271 | + } |
| 272 | +
|
228 | 273 | &.rounded :global(.neo-button-group .neo-tab::before) { |
229 | 274 | border-radius: var(--neo-tab-border-radius, var(--border-radius-lg)); |
230 | 275 | } |
|
0 commit comments