@@ -7,31 +7,55 @@ import {
77 useComputed$ ,
88 useTask$ ,
99 $ ,
10+ useSignal ,
1011} from '@builder.io/qwik' ;
1112import { tabsContextId } from './tabs-context-id' ;
13+ import { KeyCode } from '../../utils/key-code.type' ;
14+ import { isBrowser , isServer } from '@builder.io/qwik/build' ;
1215
1316export interface TabProps {
1417 onClick ?: PropFunction < ( ) => void > ;
1518 class ?: string ;
1619 selectedClassName ?: string ;
20+ disabled ?: boolean ;
1721}
1822
1923export const Tab = component$ ( ( props : TabProps ) => {
2024 const contextService = useContext ( tabsContextId ) ;
2125
26+ const serverAssignedIndexSig = useSignal < number | undefined > ( undefined ) ;
2227 const uniqueId = useId ( ) ;
2328
2429 useTask$ ( ( { cleanup } ) => {
25- contextService . tabsChanged$ ( ) ;
26-
30+ if ( isServer ) {
31+ serverAssignedIndexSig . value =
32+ contextService . lastAssignedTabIndexSig . value ;
33+ contextService . lastAssignedTabIndexSig . value ++ ;
34+ }
35+ if ( isBrowser ) {
36+ contextService . onTabsChanged$ ( ) ;
37+ }
2738 cleanup ( ( ) => {
28- contextService . tabsChanged $( ) ;
39+ contextService . onTabsChanged $( ) ;
2940 } ) ;
3041 } ) ;
3142
43+ useTask$ ( ( { track } ) => {
44+ track ( ( ) => props . disabled ) ;
45+
46+ if ( props . disabled && contextService . tabsMap [ uniqueId ] ) {
47+ contextService . tabsMap [ uniqueId ] . disabled = true ;
48+ }
49+ } ) ;
50+
3251 const isSelectedSignal = useComputed$ ( ( ) => {
52+ if ( isServer ) {
53+ return (
54+ serverAssignedIndexSig . value === contextService . selectedIndexSig . value
55+ ) ;
56+ }
3357 return (
34- contextService . selectedIndex . value ===
58+ contextService . selectedIndexSig . value ===
3559 contextService . tabsMap [ uniqueId ] ?. index
3660 ) ;
3761 } ) ;
@@ -40,17 +64,13 @@ export const Tab = component$((props: TabProps) => {
4064 ( ) => contextService . tabsMap [ uniqueId ] ?. tabPanelId
4165 ) ;
4266
43- // TODO: Figure out a way to fix this shitty hack :)
44- useTask$ ( ( { track } ) => {
45- track ( ( ) => isSelectedSignal . value ) ;
67+ const selectTab$ = $ ( ( ) => {
68+ // TODO: try to move this to the Tabs component
4669
47- if ( isSelectedSignal . value ) {
48- contextService . showTabs$ ( ) ;
70+ if ( props . disabled ) {
71+ return ;
4972 }
50- } ) ;
51-
52- const selectTab$ = $ ( ( ) => {
53- contextService . selectedIndex . value =
73+ contextService . selectedIndexSig . value =
5474 contextService . tabsMap [ uniqueId ] ?. index || 0 ;
5575
5676 contextService . selectTab$ ( uniqueId ) ;
@@ -68,6 +88,8 @@ export const Tab = component$((props: TabProps) => {
6888 data-tab-id = { uniqueId }
6989 type = "button"
7090 role = "tab"
91+ disabled = { props . disabled }
92+ aria-disabled = { props . disabled }
7193 onFocus$ = { selectIfAutomatic$ }
7294 onMouseEnter$ = { selectIfAutomatic$ }
7395 aria-selected = { isSelectedSignal . value }
@@ -84,6 +106,12 @@ export const Tab = component$((props: TabProps) => {
84106 props . onClick ( ) ;
85107 }
86108 } }
109+ onKeyDown$ = { ( e ) => {
110+ contextService . onTabKeyDown$ (
111+ e . key as KeyCode ,
112+ ( e . target as any ) . getAttribute ( 'data-tab-id' )
113+ ) ;
114+ } }
87115 >
88116 < Slot />
89117 </ button >
0 commit comments