Skip to content

Commit d258189

Browse files
tleperougederergioboa
authored
feat(component): add carousel component (#258)
* feat(component): add carousel component Adds a carousel component using a hook for maximum headlessness. 124 * feat: export Carousel to headless index * docs: add Carousel to docs * fix: add unique keys * docs: update docs of Carousel * feat: make Carousel a11y frierndly * fix: relocate use-methods into ts files * feat: integrate Carousel with child components * docs: update Carousel with child components pattern * feat(Carousel): clean up css * feat: improve aria keyboard navigation * feat: pass axe tests * feat: improve styling & keyboard supports * docs: add parts of Carousel * feat: add aria-current to Carousel Item * feat: remove control prop --------- Co-authored-by: Greg Ederer <[email protected]> Co-authored-by: Giorgio Boa <[email protected]>
1 parent a52d865 commit d258189

File tree

11 files changed

+1034
-0
lines changed

11 files changed

+1034
-0
lines changed

apps/website/src/components/menu/menu.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ export const Menu = component$<Props>(({ onClose$ }) => {
3737
path: `/docs/${appState.theme.toLowerCase()}/button-group`,
3838
},
3939
{ label: 'Card', path: `/docs/${appState.theme.toLowerCase()}/card` },
40+
{
41+
label: 'Carousel',
42+
path: `/docs/${appState.theme.toLowerCase()}/carousel`,
43+
},
4044
{
4145
label: 'Collapse',
4246
path: `/docs/${appState.theme.toLowerCase()}/collapse`,
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import {
2+
component$,
3+
useId,
4+
useSignal,
5+
useStylesScoped$,
6+
} from '@builder.io/qwik';
7+
import { Carousel } from '@qwik-ui/headless';
8+
9+
const {
10+
Controls,
11+
Control,
12+
Item,
13+
Items,
14+
Root,
15+
ButtonNext,
16+
ButtonPrevious,
17+
IconNext,
18+
IconPrevious,
19+
} = Carousel;
20+
21+
export const ITEMS: { src: string; title: string }[] = Array.from({
22+
length: 4,
23+
}).map(() => ({
24+
src: 'https://picsum.photos/1200/550',
25+
title: 'My great image',
26+
}));
27+
28+
export default component$(() => {
29+
const { scopeId } = useStylesScoped$(`
30+
h1 { margin: 2rem 0; padding-top: 1rem; font-weight: bold; border-top: 1px dotted #222}
31+
h2 { margin-block: 1.15em 0.5em; font-size: xx-large; }
32+
h3 { margin-block: 0.85em 0.35em; font-size: x-large; }
33+
hr { margin-block: 2em; }
34+
35+
.form-item, hr { width: 35em; }
36+
37+
.outter {
38+
display: grid;
39+
}
40+
41+
.inner {
42+
display: flex;
43+
align-items: center;
44+
}
45+
46+
.controls {
47+
padding: 2em;
48+
margin-inline: auto;
49+
display: flex;
50+
justify-content: center;
51+
gap: 0.5em;
52+
}
53+
54+
.control {
55+
width: 2em;
56+
aspect-ratio: 1/1;
57+
border-radius: 50%;
58+
display: flex;
59+
align-items: center;
60+
justify-content: center;
61+
transition: all .3s .1s ease-out;
62+
cursor: pointer;
63+
}
64+
65+
.control[aria-current="true"] {
66+
font-weight: 900;
67+
}
68+
69+
.item {
70+
height: 500px;
71+
width: 100%;
72+
object-fit: cover;
73+
}
74+
`);
75+
76+
const items = useSignal(ITEMS);
77+
78+
return (
79+
<>
80+
<p>This is the documentation for the Carousel</p>
81+
82+
<h2>Carousel Example</h2>
83+
84+
<Root class="outter" startAt={1} loop={false}>
85+
<div class="inner">
86+
<ButtonPrevious>
87+
<IconPrevious />
88+
</ButtonPrevious>
89+
<Items>
90+
{items.value.map(({ src, title }, i) => (
91+
<Item key={useId()} index={i} label={title}>
92+
<img src={src} class="item" />
93+
</Item>
94+
))}
95+
</Items>
96+
<ButtonNext>
97+
<IconNext />
98+
</ButtonNext>
99+
</div>
100+
<Controls class={[scopeId, 'controls']}>
101+
{items.value.map((_, i) => (
102+
<Control key={useId()} index={i} class={[scopeId, 'control']}>
103+
{i + 1}
104+
</Control>
105+
))}
106+
</Controls>
107+
</Root>
108+
109+
<hr />
110+
111+
<h3>Inputs</h3>
112+
113+
<ul>
114+
<li>startAt: number, default 0</li>
115+
<li>loop: boolean, default true</li>
116+
</ul>
117+
118+
<h3>Parts</h3>
119+
120+
<ul>
121+
<li>Root</li>
122+
<li>Items & Item</li>
123+
<li>ButtonPrevious</li>
124+
<li>ButtonNext</li>
125+
<li>Controls & Control</li>
126+
</ul>
127+
128+
<hr />
129+
130+
<h3>Outputs</h3>
131+
132+
<ul>
133+
<li></li>
134+
</ul>
135+
</>
136+
);
137+
});

0 commit comments

Comments
 (0)