Skip to content

Commit 9a03f5f

Browse files
committed
chore: different approach
1 parent a4110dc commit 9a03f5f

File tree

5 files changed

+113
-61
lines changed

5 files changed

+113
-61
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.tabs-example [role='tab'] {
2+
width: 250px;
3+
background: lightgreen;
4+
}
5+
6+
.tabs-example [role='tab'].selected {
7+
background: magenta;
8+
}
9+
10+
.tabs-example [role='tablist'] {
11+
border: 1px solid;
12+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { component$, useStyles$ } from '@builder.io/qwik';
2+
import {
3+
Tab,
4+
TabList,
5+
TabPanel,
6+
Tabs,
7+
} from '../../../../../packages/kit-headless/src';
8+
9+
import styles from './index.css?inline';
10+
11+
export default component$(() => {
12+
useStyles$(styles);
13+
return (
14+
<div class="tabs-example">
15+
<Tabs behavior="automatic">
16+
<h3 id="tablist-1">Danish Composers</h3>
17+
<TabList>
18+
<Tab for="maria">Maria Ahlefeldt</Tab>
19+
<Tab for="carl">Carl Andersen</Tab>
20+
<Tab for="ida">Ida Henriette da Fonseca</Tab>
21+
</TabList>
22+
<TabPanel id="maria">
23+
<p>
24+
Maria Theresia Ahlefeldt (16 January 1755 - 20 December 1810) was a
25+
...
26+
</p>
27+
</TabPanel>
28+
<TabPanel id="carl">
29+
<p>Carl Joachim Andersen (29 April 1847 - 7 May 1909) was a ...</p>
30+
</TabPanel>
31+
<TabPanel id="ida">
32+
<p>
33+
Ida Henriette da Fonseca (July 27, 1802 - July 6, 1858) was a ...
34+
</p>
35+
</TabPanel>
36+
</Tabs>
37+
</div>
38+
);
39+
});

packages/kit-headless/src/components/tabs/tab.tsx

Lines changed: 57 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -13,77 +13,77 @@ import {
1313
import { tabsContextId } from './tabs-context-id';
1414

1515
export interface TabProps {
16+
for: string;
1617
onClick?: PropFunction<() => void>;
1718
class?: string;
1819
selectedClassName?: string;
1920
}
2021

2122
// Tab button inside of a tab list
22-
export const Tab = component$(
23-
({ selectedClassName, onClick, class: classString }: TabProps) => {
24-
const contextService = useContext(tabsContextId);
23+
export const Tab = component$((props: TabProps) => {
24+
const contextService = useContext(tabsContextId);
2525

26-
const uniqueId = useId();
26+
const uniqueId = useId();
2727

28-
const currentTabIndex = useSignal(0);
28+
const currentTabIndex = useSignal(0);
2929

30-
const isSelectedSignal = useSignal(false);
30+
const isSelectedSignal = useSignal(false);
3131

32-
useTask$(({ cleanup }) => {
33-
contextService.tabsChanged$();
32+
useTask$(({ cleanup }) => {
33+
contextService.tabsChanged$();
3434

35-
cleanup(() => {
36-
contextService.tabsChanged$();
37-
});
35+
cleanup(() => {
36+
contextService.tabsChanged$();
3837
});
38+
});
3939

40-
useTask$(({ track }) => {
41-
track(contextService.indexByTabId);
42-
console.log('contextService.indexByTabId', contextService.indexByTabId);
43-
currentTabIndex.value = contextService.indexByTabId[uniqueId];
44-
});
40+
useTask$(({ track }) => {
41+
track(contextService.indexByTabId);
42+
console.log('contextService.indexByTabId', contextService.indexByTabId);
43+
currentTabIndex.value = contextService.indexByTabId[uniqueId];
44+
});
4545

46-
useVisibleTask$(() => {
47-
console.log(
48-
'contextService.selectedIndex.value',
49-
contextService.selectedIndex.value
50-
);
51-
console.log('currentTabIndex.value', currentTabIndex.value);
52-
isSelectedSignal.value =
53-
contextService.selectedIndex.value === currentTabIndex.value;
54-
});
46+
useVisibleTask$(() => {
47+
console.log(
48+
'contextService.selectedIndex.value',
49+
contextService.selectedIndex.value
50+
);
51+
console.log('currentTabIndex.value', currentTabIndex.value);
52+
isSelectedSignal.value =
53+
contextService.selectedIndex.value === currentTabIndex.value;
54+
});
5555

56-
const selectTab$ = $(() => {
57-
contextService.selectedIndex.value = currentTabIndex.value;
58-
});
56+
const selectTab$ = $(() => {
57+
contextService.selectedIndex.value = currentTabIndex.value;
58+
});
5959

60-
const selectIfAutomatic$ = $(() => {
61-
if (contextService.behavior === 'automatic') {
62-
selectTab$();
63-
}
64-
});
60+
const selectIfAutomatic$ = $(() => {
61+
if (contextService.behavior === 'automatic') {
62+
selectTab$();
63+
}
64+
});
6565

66-
return (
67-
<button
68-
data-tab-id={uniqueId}
69-
type="button"
70-
role="tab"
71-
onFocus$={selectIfAutomatic$}
72-
onMouseEnter$={selectIfAutomatic$}
73-
aria-selected={isSelectedSignal.value}
74-
aria-controls={'tabpanel-' + currentTabIndex.value}
75-
class={`${isSelectedSignal ? `selected ${selectedClassName}` : ''}${
76-
classString ? ` ${classString}` : ''
77-
}`}
78-
onClick$={async () => {
79-
await selectTab$();
80-
if (onClick) {
81-
onClick();
82-
}
83-
}}
84-
>
85-
<Slot />
86-
</button>
87-
);
88-
}
89-
);
66+
return (
67+
<button
68+
data-for={props.for}
69+
data-tab-id={uniqueId}
70+
type="button"
71+
role="tab"
72+
onFocus$={selectIfAutomatic$}
73+
onMouseEnter$={selectIfAutomatic$}
74+
aria-selected={isSelectedSignal.value}
75+
aria-controls={'tabpanel-' + props.for}
76+
class={`${isSelectedSignal ? `selected ${props.selectedClassName}` : ''}${
77+
props.class ? ` ${props.class}` : ''
78+
}`}
79+
onClick$={async () => {
80+
await selectTab$();
81+
if (props.onClick) {
82+
props.onClick();
83+
}
84+
}}
85+
>
86+
<Slot />
87+
</button>
88+
);
89+
});

packages/kit-headless/src/components/tabs/tabs-panel.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import {
1111
import { tabsContextId } from './tabs-context-id';
1212

1313
export interface TabPanelProps {
14+
id: string;
1415
class?: string;
1516
}
1617

1718
// Tab Panel implementation
1819
export const TabPanel = component$(({ ...props }: TabPanelProps) => {
19-
const { class: classNames, ...rest } = props;
2020
const contextService = useContext(tabsContextId);
2121
const uniqueId = useId();
2222

@@ -42,15 +42,14 @@ export const TabPanel = component$(({ ...props }: TabPanelProps) => {
4242
return (
4343
<div
4444
data-tabpanel-id={uniqueId}
45-
id={'tabpanel-' + currentPanelIndex.value}
45+
id={'tabpanel-' + props.id}
4646
role="tabpanel"
4747
tabIndex={0}
4848
aria-labelledby={`tab-${currentPanelIndex}`}
4949
class={`${isSelectedSignal.value ? 'is-hidden' : ''}${
50-
classNames ? ` ${classNames}` : ''
50+
props.class ? ` ${props.class}` : ''
5151
}`}
5252
style={isSelectedSignal.value ? 'display: block' : 'display: none'}
53-
{...rest}
5453
>
5554
<p>thisPanelIndex.value: {currentPanelIndex.value} </p>
5655
<p>contextService.selectedIndex: {contextService.selectedIndex} </p>

packages/kit-headless/src/components/tabs/tabs.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ export const Tabs = component$((props: TabsProps) => {
140140

141141
tabElements.forEach((tab, index) => {
142142
const tabId = tab.getAttribute('data-tab-id');
143+
const tabForId = tab.getAttribute('data-for');
144+
143145
if (!tabId) {
144146
throw new Error('Missing tab id for tab: ' + index);
145147
}

0 commit comments

Comments
 (0)