Skip to content

Commit fa8dd7a

Browse files
Merge pull request #789 from thejackshelton/intro
Headless intro
2 parents cd0bf9e + ff5f3e5 commit fa8dd7a

File tree

6 files changed

+143
-131
lines changed

6 files changed

+143
-131
lines changed

.changeset/fast-actors-report.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ import { Collapsible, Combobox } from '@qwik-ui/headless';
5555

5656
The searchability of available components has also been improved. You can now use the autocomplete feature to find a specific sub-component.
5757

58-
![component autocomplete](image-1.png)
58+
![component autocomplete](../apps/website/public/images/autocomplete.png)
5959

6060
### Improved legibility
6161

File renamed without changes.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { component$ } from '@builder.io/qwik';
2+
import { Accordion } from '@qwik-ui/styled';
3+
4+
export const FAQ = component$(() => {
5+
return (
6+
<Accordion.Root>
7+
<Accordion.Item>
8+
<Accordion.Trigger>
9+
What kind of support or resources are available if I encounter issues with Qwik
10+
UI?
11+
</Accordion.Trigger>
12+
<Accordion.Content>
13+
If you stumble into any problems, please{' '}
14+
<a
15+
class="font-semibold underline underline-offset-4 hover:opacity-90"
16+
href="https://github.com/qwikifiers/qwik-ui/issues"
17+
>
18+
create an issue
19+
</a>{' '}
20+
on the Qwik UI repository. We also have a{' '}
21+
<a
22+
class="font-semibold underline underline-offset-4 hover:opacity-90"
23+
href="https://discord.gg/PVWUUejrez"
24+
>
25+
Discord community
26+
</a>{' '}
27+
where you can raise any concerns, propose ideas, or chat all things Qwik UI 😊
28+
</Accordion.Content>
29+
</Accordion.Item>
30+
<Accordion.Item>
31+
<Accordion.Trigger>How can I contribute to the project?</Accordion.Trigger>
32+
<Accordion.Content>
33+
We provide a{' '}
34+
<a
35+
class="font-semibold underline underline-offset-4 hover:opacity-90"
36+
href="../../../contributing"
37+
>
38+
contributing guide
39+
</a>{' '}
40+
guide to help get familiar with the repository. Additionally, we offer a quick
41+
start{' '}
42+
<a
43+
class="font-semibold underline underline-offset-4 hover:opacity-90"
44+
href="https://github.com/qwikifiers/qwik-ui/blob/main/CONTRIBUTING.md"
45+
>
46+
setup guide
47+
</a>{' '}
48+
and a section dedicated to advanced resources below the Components navigation.
49+
</Accordion.Content>
50+
</Accordion.Item>
51+
<Accordion.Item>
52+
<Accordion.Trigger>
53+
How can I migrate my existing application to use Qwik UI from another framework?
54+
</Accordion.Trigger>
55+
<Accordion.Content>
56+
We recommend gradually adding Qwik UI components to your app. Qwik's
57+
microfrontend architecture allows for seamless integration, reducing migration
58+
risks and complexity.
59+
</Accordion.Content>
60+
</Accordion.Item>
61+
</Accordion.Root>
62+
);
63+
});

apps/website/src/components/feature-list/feature-list.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ export const FeatureList = component$((props: FeatureListProps) => {
1414
<ul class="mb-12 mt-6 !px-0">
1515
{props.features && (
1616
<>
17-
{props.features.map((descriptor) => {
17+
{props.features.map((descriptor, index) => {
1818
return (
1919
<li
2020
key={descriptor}
21-
class="flex w-full list-none items-center gap-x-2 gap-y-4 border-b-[1px] border-slate-200 py-2 dark:border-slate-800"
21+
class={`flex w-full list-none items-center gap-x-2 gap-y-4 ${index === props.features.length - 1 ? '' : 'border-b-[1px]'} border-slate-200 py-2 dark:border-slate-800`}
2222
>
2323
<CheckIcon class="min-w-[21px]" />
2424
{descriptor}
Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,55 @@
11
import { component$, useSignal } from '@builder.io/qwik';
2-
// @ts-ignore
2+
// @ts-expect-error no types
33
import confetti from 'canvas-confetti';
44

5-
export const ConfettiButton = component$(() => {
5+
export const ConfettiButton = component$(({ intro }: { intro?: boolean }) => {
66
const buttonRef = useSignal<HTMLButtonElement>();
7+
const didClickSig = useSignal(false);
8+
79
return (
8-
<div class="relative my-6 flex justify-center">
9-
<div class="relative">
10-
<div class="absolute top-[3px] z-0 block h-full w-full rounded-base bg-slate-800 transition-transform duration-300 dark:bg-slate-500"></div>
11-
<button
12-
ref={buttonRef}
13-
onClick$={async () => {
14-
if (!buttonRef.value) return;
15-
const rect = buttonRef.value.getBoundingClientRect();
10+
<div class="flex flex-wrap items-baseline gap-4">
11+
<div class={`relative ${intro ? 'my-0' : 'mb-6'} flex`}>
12+
<div class="relative">
13+
<div class="absolute top-[3px] z-0 block h-full w-full rounded-sm bg-primary/30 transition-transform duration-300 dark:bg-primary/60"></div>
14+
<button
15+
ref={buttonRef}
16+
onClick$={async () => {
17+
didClickSig.value = true;
18+
if (!buttonRef.value) return;
19+
const rect = buttonRef.value.getBoundingClientRect();
20+
21+
if (!rect) return;
1622

17-
if (!rect) return;
23+
// so it's always on top of the button
24+
const x = (rect.left + rect.width / 2) / window.innerWidth;
25+
const y = rect.top / window.innerHeight;
1826

19-
// so it's always on top of the button
20-
const x = (rect.left + rect.width / 2) / window.innerWidth;
21-
const y = rect.top / window.innerHeight;
27+
const jsLogo = confetti.shapeFromPath({
28+
path: [
29+
'M0 0h1052v1052H0z',
30+
'M965.9 801.1c-7.7-48-39-88.3-131.7-125.9-32.2-14.8-68.1-25.399-78.8-49.8-3.8-14.2-4.3-22.2-1.9-30.8 6.9-27.9 40.2-36.6 66.6-28.6 17 5.7 33.1 18.801 42.8 39.7 45.4-29.399 45.3-29.2 77-49.399-11.6-18-17.8-26.301-25.4-34-27.3-30.5-64.5-46.2-124-45-10.3 1.3-20.699 2.699-31 4-29.699 7.5-58 23.1-74.6 44-49.8 56.5-35.6 155.399 25 196.1 59.7 44.8 147.4 55 158.6 96.9 10.9 51.3-37.699 67.899-86 62-35.6-7.4-55.399-25.5-76.8-58.4-39.399 22.8-39.399 22.8-79.899 46.1 9.6 21 19.699 30.5 35.8 48.7 76.2 77.3 266.899 73.5 301.1-43.5 1.399-4.001 10.6-30.801 3.199-72.101zm-394-317.6h-98.4c0 85-.399 169.4-.399 254.4 0 54.1 2.8 103.7-6 118.9-14.4 29.899-51.7 26.2-68.7 20.399-17.3-8.5-26.1-20.6-36.3-37.699-2.8-4.9-4.9-8.7-5.601-9-26.699 16.3-53.3 32.699-80 49 13.301 27.3 32.9 51 58 66.399 37.5 22.5 87.9 29.4 140.601 17.3 34.3-10 63.899-30.699 79.399-62.199 22.4-41.3 17.6-91.3 17.4-146.6.5-90.2 0-180.4 0-270.9z',
31+
],
32+
});
2233

23-
await confetti({
24-
colors: ['#02B9FC', '#B57DFC'],
25-
origin: {
26-
x,
27-
y,
28-
},
29-
});
30-
}}
31-
class="z-1 relative h-[44px] rounded-base bg-slate-700 px-3 font-bold text-white shadow-md dark:bg-slate-600"
32-
id="add-confetti-button"
33-
>
34-
Woohoo! 🎉
35-
</button>
34+
await confetti({
35+
colors: intro ? ['#f0db4f'] : ['#02B9FC', '#B57DFC'],
36+
shapes: intro ? [jsLogo] : undefined,
37+
origin: {
38+
x,
39+
y,
40+
},
41+
});
42+
}}
43+
class="z-1 relative h-[44px] rounded-base bg-primary px-3 font-bold text-white shadow-md"
44+
id="add-confetti-button"
45+
>
46+
{intro ? 'Click me!' : 'Woohoo! 🎉'}
47+
</button>
48+
</div>
3649
</div>
50+
{didClickSig.value && intro ? (
51+
<p>My click event just executed! (not the button component)</p>
52+
) : null}
3753
</div>
3854
);
3955
});

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

Lines changed: 34 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -2,134 +2,67 @@
22
title: Qwik UI | Introduction
33
---
44

5-
import headlessHero from '/public/images/qwik-ui-headless-hero.webp';
6-
import { Accordion } from '@qwik-ui/styled';
5+
import { FAQ } from '~/components/faq/faq';
6+
import { ConfettiButton } from '../install/confetti-button';
7+
import autocompleteImg from '../../../../../public/images/autocomplete.png';
78

89
# Headless kit
910

10-
Taking inspiration from popular headless libraries such as [Headless UI](https://headlessui.com/), [Radix UI](https://www.radix-ui.com/primitives/docs/components/accordion), [React Aria](https://react-spectrum.adobe.com/react-aria/components.html), [Kobalte](https://kobalte.dev/docs/core/overview/introduction), and [Melt UI](https://melt-ui.com/docs/builders/accordion), the headless kit is a library of completely unstyled, accessible, and resumable components with built-in structure, behavior, and state.
11-
You can use it to build your design system from scratch with any of the tools you want, or simply use the docs as a reference to the components API if you're using the styled kit.
11+
Qwik UI is a tool to help you build better design systems. It includes components with **no default styles** and a [styled kit](../../styled/introduction/) with configurable presets. Both are fully customizable and accessible.
12+
13+
You are currently exploring the headless kit, which manages the essential structure, behavior, and state of advanced UI components. It also happens to be the world's fastest UI library, squeezing out every bit of performance. _(Like lemonade from lemons that had a run-in with a steamroller.)_ 🥤
1214

1315
<Note status="warning">
14-
Qwik UI is in its **beta** phase - it's like a roller coaster, thrilling and full of
15-
surprises! Expect new features and some breaking changes until we reach version 1.0. So,
16-
buckle up and enjoy the ride. 🏍️
16+
Qwik UI is currently in its **beta** phase. We appreciate your support and patience as
17+
we continue to add new features and make improvements. Expect some breaking changes
18+
until we reach version 1.0.
1719
</Note>
1820

19-
## Vision
20-
21-
In 2024, developers should not have to recreate the same [WAI-Aria Patterns](https://www.w3.org/WAI/ARIA/apg/patterns/) from scratch. Building custom components is challenging, and developers shouldn't need to reinvent common UI patterns.
22-
23-
Our aim is to ensure Qwik UI is not just an effective, but also a simple, reliable, and flexible choice for developing applications.
24-
25-
Qwik UI Headless is optimized to squeeze every possible ounce of performance out of Qwik _(Like lemonade from lemons that had a run-in with a steamroller.)_ 🥤
26-
27-
## Why Qwik UI Headless?
28-
29-
### The client and the server
30-
31-
Like Qwik itself, Qwik UI is super performant because it renders everything it can on the server
32-
33-
Unlike many other solutions that focus solely on client-side components, Qwik UI takes advantage of the server, the client, and the concept of resumability.
34-
35-
This means that Qwik UI can operate with any meta-framework that supports Qwik, including the full framework benefits. At the time of writing, that includes [Qwik City](https://qwik.builder.io/docs/qwikcity/) and [Astro](https://astro.build/).
36-
37-
### Embracing native first
38-
39-
Qwik values HTML as the source of truth, and this principle extends to Qwik UI components. We appreciate and adopt the excellent work done by the [Open UI Group](https://open-ui.org/) when appropriate.
40-
41-
This approach also encompasses future native APIs. Users of Qwik UI might find themselves using components that can be gradually adopted into the native specification. This implies that, eventually, these custom patterns might not need any JavaScript.
42-
43-
> For instance, [Qwik UI's popover component](https://github.com/qwikifiers/qwik-ui/pull/445) uses the native Popover API on supported browsers. The Anchor API is also incrementally adoptable.
21+
## It's fast, like really fast
4422

45-
Thanks to resumability, we do less work because there are less components to execute. With Qwik UI we build on top of that, providing the same functionality with less code needed to prefetch in the first place.
23+
The claim of being the world's fastest UI library is genuine, not just marketing hype. In Qwik UI, every component starts as **lightweight HTML** and activates smaller pieces upon **user interaction**. Each event is handled independently, without affecting the entire component.
4624

47-
## Features
25+
## Accessibility
4826

49-
### Unstyled
27+
Components in Qwik UI follow the [WAI-ARIA Design Patterns](https://www.w3.org/WAI/ARIA/apg/patterns/) when possible. The project manages ARIA attributes, focus management, and keyboard handling.
5028

51-
Qwik UI is a headless library, and comes with zero or very minimal styling. This means the design of your components are completely customizable.
29+
However, following these guidelines alone does not guarantee full accessibility. The headless kit tests with assistive technologies to ensure that people with disabilities can fully use your applications.
5230

53-
<CodeSnippet name="headless-jsx" />
31+
## Bring your own styles
5432

55-
This is in contrast to styled libraries such as Bootstrap or Material UI, where [styles often need to be stripped](https://www.smashingmagazine.com/2022/05/you-dont-need-ui-framework/) in order to be custom.
33+
Out of the box, components ship with zero or necessary behavioral styles, giving you complete control over your design. You can style them using any solution.
5634

57-
<CodeSnippet name="headless-css.css" />
58-
59-
### Accessible at its core
60-
61-
Everyone should have equal access to information and functionality on the web. Every Qwik UI component is designed to follow the [WCAG Guidelines](https://www.w3.org/WAI/standards-guidelines/wcag/).
62-
63-
However, it's a common misconception that meeting WCAG success criteria guarantees full accessibility of your components. Unfortunately, this is not the case.
64-
65-
The ultimate measure of your components' accessibility is user testing. This aspect, often overlooked in other projects, is a high priority for us.
35+
<FeatureList
36+
features={['Vanilla CSS', 'SASS and PostCSS', 'CSS-in-JS', 'Whatever you want!']}
37+
/>
6638

67-
### Developer Experience that matches UX
39+
<ConfettiButton intro />
6840

69-
Many libraries tout their excellent Developer Experience (DX), but this doesn't necessarily translate into a superior User Experience (UX).
41+
## Environment agnostic
7042

71-
Conversely, some packages offer great UX, but fall short when it comes to DX.
43+
Whether you're building an _SSG_ marketing page, _SSR_ e-commerce site, or _CSR_ dashboard, Qwik UI knows when each function should run on the server or the client for you.
7244

73-
One of the benefits of Qwik is its ability to create performant applications without compromising on DX. Our goal is to extend this same balance of performance and ease-of-use to those utilizing Qwik UI components.
45+
## Developer experience
7446

75-
#### Some examples being:
47+
Our goal is to provide the **best developer experience**. Qwik UI offers fully-typed, discoverable, and composable components.
7648

77-
<FeatureList
78-
features={[
79-
'TypeScript support',
80-
'Custom Signal Binds',
81-
'Automatic entry and exit animations across browsers',
82-
'Works across environments / microfrontends',
83-
'Automatic performance optimization',
84-
]}
49+
<img
50+
src={autocompleteImg}
51+
class="h-60 rounded-sm object-cover object-left px-2 md:h-[revert]"
52+
width="1920"
53+
height="600"
8554
/>
8655

8756
## FAQ
8857

89-
<Accordion.Root>
90-
<Accordion.Item>
91-
<Accordion.Trigger>
92-
What kind of support or resources are available if I encounter issues with Qwik UI?
93-
</Accordion.Trigger>
94-
<Accordion.Content>
95-
If you stumble into any problems, [create an
96-
issue](https://github.com/qwikifiers/qwik-ui/issues) on the Qwik UI repository. We
97-
also have a [discord community](https://discord.gg/PVWUUejrez) with a Qwik UI
98-
channel where you can raise any concerns, propose ideas, or chat all things Qwik UI
99-
😊
100-
</Accordion.Content>
101-
</Accordion.Item>
102-
<Accordion.Item>
103-
<Accordion.Trigger>How can I contribute to the project?</Accordion.Trigger>
104-
<Accordion.Content>
105-
We provide a [contributing](/docs/headless/contributing) guide to help get familiar
106-
with the repository. Additionally, we offer a quick start [setup
107-
guide](https://github.com/qwikifiers/qwik-ui/blob/main/CONTRIBUTING.md) and a
108-
section dedicated to advanced resources below the Components navigation.
109-
</Accordion.Content>
110-
</Accordion.Item>
111-
<Accordion.Item>
112-
<Accordion.Trigger>
113-
How can I migrate my existing application to use Qwik UI?
114-
</Accordion.Trigger>
115-
<Accordion.Content>
116-
If you're using `Qwik-React`, `Qwik-Angular`, `@qwikdev/astro`, we suggest
117-
incrementally adding Qwik UI components to your application. Qwik, built as a
118-
microfrontend, allows you to incrementally integrate Qwik UI components into your
119-
existing application. This approach reduces migration risk and complexity, letting
120-
you leverage Qwik UI's benefits at your own pace.
121-
</Accordion.Content>
122-
</Accordion.Item>
123-
</Accordion.Root>
58+
<FAQ />
12459

12560
## Credits
12661

127-
We strongly believe in having a [learner's mindset](https://www.jakeyou.com/blog/learners-mindset-how-to-be-a-learner), and as such, we've drawn inspiration from a multitude of projects, learning from their successes and challenges.
128-
129-
Qwik UI's development has been shaped by the following remarkable projects:
62+
We believe in a _learner's mindset_ and have drawn inspiration from many projects, learning from their successes and challenges.
13063

131-
- [Radix UI](https://www.radix-ui.com/)
13264
- [Kobalte](https://kobalte.dev/docs/core/overview/introduction)
133-
- [Melt UI](https://www.melt-ui.com/docs/introduction)
13465
- [React Aria](https://react-spectrum.adobe.com/react-aria/)
135-
- [Reach UI](https://reach.tech/)
66+
- [Melt UI](https://www.melt-ui.com/docs/introduction)
67+
- [Radix UI](https://www.radix-ui.com/)
68+
- [Ariakit](https://ariakit.org/)

0 commit comments

Comments
 (0)