Skip to content

Commit 38e955c

Browse files
Merge branch 'main' into popover-combobox
2 parents 44ebc29 + fff68b4 commit 38e955c

File tree

7 files changed

+225
-71
lines changed

7 files changed

+225
-71
lines changed

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
66
],
77
"editor.codeActionsOnSave": {
8-
"source.removeUnusedImports": true
8+
"source.removeUnusedImports": "explicit"
99
}
1010
}

apps/website/src/components/mdx-components/index.tsx

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Showcase } from '../showcase/showcase';
88
import { CodeSnippet } from '../code-snippet/code-snippet';
99
import { InstallSnippet } from '../install-snippet/install-snippet';
1010
import { Note } from '../note/note';
11+
import { twMerge } from 'tailwind-merge';
1112

1213
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1314
export const components: Record<string, any> = {
@@ -16,8 +17,10 @@ export const components: Record<string, any> = {
1617
<p
1718
{...props}
1819
class={[
19-
'mb-6 last:mb-0',
20-
(props.class as Signal<string>)?.value ?? (props.class as string),
20+
twMerge(
21+
'mb-6 last:mb-0',
22+
(props.class as Signal<string>)?.value ?? (props.class as string),
23+
),
2124
]}
2225
>
2326
<Slot />
@@ -29,8 +32,10 @@ export const components: Record<string, any> = {
2932
<h1
3033
{...props}
3134
class={[
32-
'mb-6 pt-6 text-3xl font-extrabold md:text-5xl',
33-
(props.class as Signal<string>)?.value ?? (props.class as string),
35+
twMerge(
36+
'mb-6 pt-6 text-3xl font-extrabold md:text-5xl',
37+
(props.class as Signal<string>)?.value ?? (props.class as string),
38+
),
3439
]}
3540
>
3641
<Slot />
@@ -42,8 +47,10 @@ export const components: Record<string, any> = {
4247
<h2
4348
{...props}
4449
class={[
45-
'mb-8 mt-20 scroll-mt-32 border-b-[1px] pb-2 text-2xl font-extrabold',
46-
(props.class as Signal<string>)?.value ?? (props.class as string),
50+
twMerge(
51+
'mb-8 mt-20 scroll-mt-32 border-b-[1px] pb-2 text-2xl font-extrabold',
52+
(props.class as Signal<string>)?.value ?? (props.class as string),
53+
),
4754
]}
4855
>
4956
<Slot />
@@ -55,8 +62,10 @@ export const components: Record<string, any> = {
5562
<h3
5663
{...props}
5764
class={[
58-
'mb-6 mt-8 text-xl font-semibold',
59-
(props.class as Signal<string>)?.value ?? (props.class as string),
65+
twMerge(
66+
'mb-6 mt-8 text-xl font-semibold',
67+
(props.class as Signal<string>)?.value ?? (props.class as string),
68+
),
6069
]}
6170
>
6271
<Slot />
@@ -68,8 +77,10 @@ export const components: Record<string, any> = {
6877
<h4
6978
{...props}
7079
class={[
71-
'mb-4 mt-6 text-lg font-medium',
72-
(props.class as Signal<string>)?.value ?? (props.class as string),
80+
twMerge(
81+
'mb-4 mt-6 text-lg font-medium',
82+
(props.class as Signal<string>)?.value ?? (props.class as string),
83+
),
7384
]}
7485
>
7586
<Slot />
@@ -81,8 +92,10 @@ export const components: Record<string, any> = {
8192
<h5
8293
{...props}
8394
class={[
84-
'text-base font-[700]',
85-
(props.class as Signal<string>)?.value ?? (props.class as string),
95+
twMerge(
96+
'text-base font-[700]',
97+
(props.class as Signal<string>)?.value ?? (props.class as string),
98+
),
8699
]}
87100
>
88101
<Slot />
@@ -101,8 +114,10 @@ export const components: Record<string, any> = {
101114
<ul
102115
{...props}
103116
class={[
104-
'mb-4 list-disc px-6 font-medium',
105-
(props.class as Signal<string>)?.value ?? (props.class as string),
117+
twMerge(
118+
'mb-4 list-disc px-6 font-medium',
119+
(props.class as Signal<string>)?.value ?? (props.class as string),
120+
),
106121
]}
107122
>
108123
<Slot />
@@ -114,8 +129,10 @@ export const components: Record<string, any> = {
114129
<li
115130
{...props}
116131
class={[
117-
'py-2',
118-
(props.class as Signal<string>)?.value ?? (props.class as string),
132+
twMerge(
133+
'py-2',
134+
(props.class as Signal<string>)?.value ?? (props.class as string),
135+
),
119136
]}
120137
>
121138
<Slot />
@@ -128,20 +145,22 @@ export const components: Record<string, any> = {
128145
}
129146
>(({ __rawString__, ...props }) => {
130147
return (
131-
<div class="code-example relative -mx-6 mb-6 max-h-[31.25rem] rounded-xl bg-slate-900 lg:-mx-8 lg:mb-8">
148+
<div
149+
class={[
150+
twMerge(
151+
'code-example relative -mx-6 max-h-[31.25rem] rounded-xl bg-slate-900 lg:-mx-8',
152+
(props.class as Signal<string>)?.value ?? (props.class as string),
153+
),
154+
]}
155+
>
132156
<CodeCopy
133-
class={[
134-
'absolute right-4 top-4 border-2 text-slate-50 hover:bg-slate-800 hover:text-slate-50',
135-
]}
157+
class="absolute right-4 top-4 border-2 text-slate-50 hover:bg-slate-800 hover:text-slate-50"
136158
code={__rawString__}
137159
/>
138160
<div
139161
{...props}
140162
style={''} // required to override shiki's
141-
class={[
142-
'tab-size max-h-[31.25rem] max-w-full overflow-auto rounded-xl border bg-gradient-to-b from-slate-900 to-slate-800 p-6 text-sm',
143-
(props.class as Signal<string>)?.value ?? (props.class as string),
144-
]}
163+
class="tab-size max-h-[31.25rem] max-w-full overflow-auto rounded-xl border bg-gradient-to-b from-slate-900 to-slate-800 p-6 text-sm"
145164
>
146165
<pre>
147166
<Slot />
@@ -159,9 +178,10 @@ export const components: Record<string, any> = {
159178
}),
160179
AnatomyTable,
161180
APITable,
181+
CodeSnippet,
182+
InstallSnippet,
162183
KeyboardInteractionTable,
184+
Note,
163185
StatusBanner,
164186
Showcase,
165-
CodeSnippet,
166-
InstallSnippet,
167187
};

apps/website/src/components/note/note.tsx

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { component$, Slot, QwikIntrinsicElements } from '@builder.io/qwik';
33
export enum NoteStatus {
44
Info = 'info',
55
Warning = 'warning',
6-
Success = 'success',
76
Caution = 'caution',
87
}
98

@@ -14,30 +13,27 @@ export interface NoteProps {
1413
function getIconByStatus(status?: NoteStatus) {
1514
switch (status) {
1615
case NoteStatus.Info:
17-
return <InfoIcon class="text-qwikui-purple-500 dark:text-qwikui-blue-700" />;
16+
return <InfoIcon class="text-secondary" />;
1817
case NoteStatus.Warning:
1918
return <WarningIcon class="text-yellow-500" />;
20-
case NoteStatus.Success:
21-
return <SuccessIcon class="text-green-500 dark:text-green-600" />;
2219
case NoteStatus.Caution:
23-
return <CautionIcon class="text-red-600 dark:text-red-700" />;
20+
return <CautionIcon class="text-destructive" />;
21+
2422
default:
25-
return <InfoIcon class="text-qwikui-purple-500 dark:text-qwikui-blue-700" />;
23+
return <InfoIcon class="text-secondary" />;
2624
}
2725
}
2826

2927
function getBackgroundByStatus(status?: NoteStatus) {
3028
switch (status) {
3129
case NoteStatus.Info:
32-
return 'bg-[#ECDDFD] border-qwikui-purple-500 dark:bg-[#0C2944] border-l-2 dark:border-qwikui-blue-700 mb-4 rounded-lg block';
30+
return 'bg-secondary/20 border-secondary border-l-2 mb-4 rounded-lg block';
3331
case NoteStatus.Warning:
34-
return 'bg-[#FBF0CD] dark:bg-[#3B3623] border-yellow-500 border-l-2 dark:border-yellow-500 mb-4 rounded-lg block';
35-
case NoteStatus.Success:
36-
return 'dark:bg-[#103331] bg-[#D2F4DF] border-green-500 border-l-2 dark:border-green-600 mb-4 rounded-lg block';
32+
return 'bg-yellow-500/20 border-yellow-500 border-l-2 mb-4 rounded-lg block';
3733
case NoteStatus.Caution:
38-
return 'bg-[#F8D3D3] border-red-600 dark:bg-[#311727] border-l-2 dark:border-red-700 mb-4 rounded-lg block';
34+
return 'bg-destructive/20 border-destructive border-l-2 mb-4 rounded-lg block';
3935
default:
40-
return 'dark:bg-[#0C2944] border-l-2 dark:border-qwikui-blue-700 mb-4 rounded-lg block';
36+
return 'bg-secondary/20 border-secondary border-l-2 mb-4 rounded-lg block';
4137
}
4238
}
4339

@@ -96,24 +92,6 @@ export function WarningIcon(props: QwikIntrinsicElements['svg'], key: string) {
9692
);
9793
}
9894

99-
export function SuccessIcon(props: QwikIntrinsicElements['svg'], key: string) {
100-
return (
101-
<svg
102-
xmlns="http://www.w3.org/2000/svg"
103-
width="32"
104-
height="32"
105-
viewBox="0 0 256 256"
106-
{...props}
107-
key={key}
108-
>
109-
<g fill="currentColor">
110-
<path d="M224 128a96 96 0 1 1-96-96a96 96 0 0 1 96 96Z" opacity=".2"></path>
111-
<path d="M173.66 98.34a8 8 0 0 1 0 11.32l-56 56a8 8 0 0 1-11.32 0l-24-24a8 8 0 0 1 11.32-11.32L112 148.69l50.34-50.35a8 8 0 0 1 11.32 0ZM232 128A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104Zm-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88Z"></path>
112-
</g>
113-
</svg>
114-
);
115-
}
116-
11795
export function CautionIcon(props: QwikIntrinsicElements['svg'], key: string) {
11896
return (
11997
<svg
@@ -125,11 +103,8 @@ export function CautionIcon(props: QwikIntrinsicElements['svg'], key: string) {
125103
key={key}
126104
>
127105
<g fill="currentColor">
128-
<path
129-
d="M195.88 195.88a96 96 0 0 1-135.76 0L195.88 60.12a96 96 0 0 1 0 135.76Z"
130-
opacity=".2"
131-
></path>
132-
<path d="M201.54 54.46A104 104 0 0 0 54.46 201.54A104 104 0 0 0 201.54 54.46ZM65.78 65.77a88.08 88.08 0 0 1 118.52-5.38L60.38 184.31a88 88 0 0 1 5.4-118.54Zm124.44 124.46a88.1 88.1 0 0 1-118.52 5.38L195.62 71.69a88 88 0 0 1-5.4 118.54Z"></path>
106+
<path d="M224 128a96 96 0 1 1-96-96a96 96 0 0 1 96 96Z" opacity=".2"></path>
107+
<path d="M165.66 101.66L139.31 128l26.35 26.34a8 8 0 0 1-11.32 11.32L128 139.31l-26.34 26.35a8 8 0 0 1-11.32-11.32L116.69 128l-26.35-26.34a8 8 0 0 1 11.32-11.32L128 116.69l26.34-26.35a8 8 0 0 1 11.32 11.32ZM232 128A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104Zm-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88Z"></path>
133108
</g>
134109
</svg>
135110
);
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { Slot, component$ } from '@builder.io/qwik';
2+
import {
3+
Tab,
4+
TabList,
5+
TabListProps,
6+
TabPanel,
7+
TabPanelProps,
8+
TabProps,
9+
Tabs,
10+
TabsProps,
11+
} from '@qwik-ui/headless';
12+
13+
const CustomTabs = (props: TabsProps) => (
14+
<Tabs {...props} TabList={CustomTabList} Tab={CustomTab} TabPanel={CustomTabPanel} />
15+
);
16+
17+
const CustomTabList = component$<TabListProps>(() => {
18+
return (
19+
<TabList>
20+
<Slot />
21+
</TabList>
22+
);
23+
});
24+
25+
const CustomTab = component$<TabProps>(({ ...props }) => {
26+
return (
27+
<Tab {...props}>
28+
<span class="text-red-500">Custom</span>
29+
<Slot />
30+
</Tab>
31+
);
32+
});
33+
34+
const CustomTabPanel = component$<TabPanelProps>(({ ...props }) => {
35+
return (
36+
<TabPanel {...props}>
37+
<span class="text-red-500">Description:</span>
38+
<Slot />
39+
</TabPanel>
40+
);
41+
});
42+
43+
export default component$(() => {
44+
return (
45+
<div class="tabs-example mr-auto">
46+
<CustomTabs>
47+
<CustomTabList>
48+
<CustomTab>Tab 1</CustomTab>
49+
<CustomTab>Tab 2</CustomTab>
50+
<CustomTab>Tab 3</CustomTab>
51+
</CustomTabList>
52+
<CustomTabPanel>
53+
<p>Maria Theresia Ahlefeldt (16 January 1755 - 20 December 1810) ...</p>
54+
</CustomTabPanel>
55+
<CustomTabPanel>
56+
<p>Carl Joachim Andersen (29 April 1847 - 7 May 1909) ...</p>
57+
</CustomTabPanel>
58+
<CustomTabPanel>
59+
<p>Ida Henriette da Fonseca (July 27, 1802 - July 6, 1858) ...</p>
60+
</CustomTabPanel>
61+
</CustomTabs>
62+
</div>
63+
);
64+
});

apps/website/src/routes/docs/headless/tabs/index.mdx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,27 @@ You can pass a custom `onClick$` handler.
8585

8686
<Showcase name="on-click" />
8787

88+
## Creating reusable Tabs
89+
90+
In order to remove the need for a linking `value` prop for each Tab and TabPanel pair, we have chosen to create the Tabs component as an [inline component](https://qwik.builder.io/docs/components/overview/#inline-components).
91+
92+
By consequence, the Tabs component needs to be aware of its children. If you want to create your custom reusable TabList/Tab/TabPanel components, you will have to pass them to the Tabs component through its `TabList`, `Tab`, and `TabPanel` props:
93+
94+
```tsx
95+
const CustomTabs = (props: TabsProps) => (
96+
<Tabs {...props} TabList={CustomTabList} Tab={CustomTab} TabPanel={CustomTabPanel} />
97+
);
98+
```
99+
100+
<br />
101+
102+
<Note status="warning">
103+
If you don't do the above, the Tabs component cannot know if your CustomTab component is
104+
a Tab component.
105+
</Note>
106+
107+
<Showcase name="reusable" />
108+
88109
## Accessibility
89110

90111
### Keyboard interaction

0 commit comments

Comments
 (0)