Skip to content

Commit f75773c

Browse files
authored
docs: remove import.meta.glob for faster docs and less bugs (#1076)
* chore: small fixes * chore: remove non-planned components * refactor: showcase-components without import meta glob * refactor: code-snippets without import meta glob * chore: remove compoent-imports.ts * fix: typo * chore: remove showcase references in contributing.mdx
1 parent 62988f1 commit f75773c

File tree

114 files changed

+3423
-777
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+3423
-777
lines changed

apps/component-tests/src/components/showcase-test/showcase-test.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Component, component$, useSignal, useTask$ } from '@builder.io/qwik';
22
import { useLocation } from '@builder.io/qwik-city';
3-
import { isDev } from '@builder.io/qwik/build';
43
import { metaGlobComponents } from './component-imports';
54

65
export const ShowcaseTest = component$(() => {
@@ -12,12 +11,9 @@ export const ShowcaseTest = component$(() => {
1211
const MetaGlobComponentSig = useSignal<Component<any>>();
1312

1413
useTask$(async () => {
15-
// eslint-disable-next-line qwik/valid-lexical-scope
16-
MetaGlobComponentSig.value = isDev
17-
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
18-
// @ts-expect-error
19-
await metaGlobComponents[componentPath]() // We need to call `await metaGlobComponents[componentPath]()` in development as it is `eager:false`
20-
: metaGlobComponents[componentPath]; // We need to directly access the `metaGlobComponents[componentPath]` expression in preview/production as it is `eager:true`
14+
MetaGlobComponentSig.value =
15+
await // eslint-disable-next-line @typescript-eslint/no-explicit-any
16+
(metaGlobComponents[componentPath] as () => Promise<Component<any>>)();
2117
});
2218

2319
return (
Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,14 @@
1-
import { PropsOf, component$, useSignal, useTask$ } from '@builder.io/qwik';
2-
import { useLocation } from '@builder.io/qwik-city';
1+
import { PropsOf, component$ } from '@builder.io/qwik';
32
import { Highlight } from '../highlight/highlight';
43

5-
// The below `/src/routes/docs/**/**/snippets/*.tsx` pattern is here so that import.meta.glob works both for styled and headless routes.
6-
// For example:
7-
// /src/routes/docs/components/styled/modal/snippets/building-blocks.tsx
8-
// /src/routes/docs/components/headless/modal/snippets/building-blocks.tsx
9-
10-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
11-
const codeSnippets: any = import.meta.glob('/src/routes/docs/**/**/snippets/*', {
12-
query: '?raw',
13-
import: 'default',
14-
});
15-
164
type CodeSnippetProps = PropsOf<'div'> & {
17-
name: string;
5+
code: string;
186
};
197

20-
export const CodeSnippet = component$<CodeSnippetProps>(({ name }) => {
21-
const location = useLocation();
22-
23-
// Determine the file extension if not specified
24-
const fileExtension =
25-
name.endsWith('.tsx') || name.endsWith('.ts') || name.endsWith('.css') ? '' : '.tsx';
26-
const snippetPath = `/src/routes${location.url.pathname}snippets/${name}${fileExtension}`;
27-
28-
const codeSnippetSig = useSignal<string>();
29-
30-
useTask$(async () => {
31-
codeSnippetSig.value = await codeSnippets[snippetPath](); // We need to call `await codeSnippets[snippetPath]()` in development as it is `eager:false`
32-
});
33-
8+
export const CodeSnippet = component$<CodeSnippetProps>(({ code }) => {
349
return (
3510
<div class="shadow-3xl mb-6 rounded-md border shadow-lg">
36-
<Highlight code={codeSnippetSig.value || ''} />
11+
<Highlight code={code} />
3712
</div>
3813
);
3914
});

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { FeatureList } from '../feature-list/feature-list';
99
import { InstallSnippet } from '../install-snippet/install-snippet';
1010
import { KeyboardInteractionTable } from '../keyboard-interaction-table/keyboard-interaction-table';
1111
import { Note } from '../note/note';
12-
import { Showcase } from '../showcase/showcase';
1312
import { StatusBanner } from '../status-banner/status-banner';
1413
import { TopLayerAnimationsCaveats } from '../animations/caveats';
1514
import { BrowserAnimationsCompatability } from '../animations/compatability';
@@ -137,7 +136,6 @@ export const components: Record<string, Component> = {
137136
KeyboardInteractionTable,
138137
Note,
139138
StatusBanner,
140-
Showcase,
141139
AutoAPI,
142140
TopLayerAnimationsCaveats,
143141
BrowserAnimationsCompatability,

apps/website/src/components/search/search.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,17 @@ export const Search = component$(({ isOpen }: { isOpen: Signal<boolean> }) => {
128128
class="w-full"
129129
mode="inline"
130130
filter={false}
131-
onChange$={(value: string) => {
132-
window.location.href = value;
133-
isOpen.value = false;
134-
}}
131+
onChange$={$(
132+
(value: string | string[]) => {
133+
if (typeof value === 'string') {
134+
window.location.href = value;
135+
isOpen.value = false;
136+
} else {
137+
window.location.href = value[0];
138+
isOpen.value = false;
139+
}
140+
},
141+
)}
135142
>
136143
<Combobox.Input
137144
onInput$={handleInput}

apps/website/src/components/showcase/component-imports.ts

Lines changed: 0 additions & 21 deletions
This file was deleted.

apps/website/src/components/showcase/showcase.tsx

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,13 @@
1-
import { Component, component$, useSignal, useTask$ } from '@builder.io/qwik';
2-
import { useLocation } from '@builder.io/qwik-city';
1+
import { component$, Slot } from '@builder.io/qwik';
32
import { Tabs } from '@qwik-ui/headless';
43
import { Highlight } from '../highlight/highlight';
5-
import { metaGlobComponents, rawComponents } from './component-imports';
64

75
type ShowcaseProps = {
8-
name?: string;
96
vertical?: boolean;
7+
rawCode: string;
108
};
119

12-
export const Showcase = component$<ShowcaseProps>(({ name, ...props }) => {
13-
const location = useLocation();
14-
const componentPath = `/src/routes${location.url.pathname}examples/${name}.tsx`;
15-
16-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
17-
const MetaGlobComponentSig = useSignal<Component<any>>();
18-
const componentCodeSig = useSignal<string>();
19-
20-
useTask$(async () => {
21-
try {
22-
// eslint-disable-next-line qwik/valid-lexical-scope
23-
MetaGlobComponentSig.value = await metaGlobComponents[componentPath](); // We need to call `await metaGlobComponents[componentPath]()` in development as it is `eager:false`
24-
componentCodeSig.value = await rawComponents[componentPath]();
25-
} catch (e) {
26-
throw new Error(`Unable to load path ${componentPath}`);
27-
}
28-
});
29-
10+
export const Showcase = component$<ShowcaseProps>(({ rawCode, ...props }) => {
3011
return (
3112
<div class="mb-12 rounded-xl shadow-lg">
3213
{!props.vertical ? (
@@ -44,22 +25,19 @@ export const Showcase = component$<ShowcaseProps>(({ name, ...props }) => {
4425
</Tabs.List>
4526
<Tabs.Panel class="rounded-b-md border px-8 py-32 md:px-32">
4627
<section class="flex flex-col items-center">
47-
{MetaGlobComponentSig.value && <MetaGlobComponentSig.value />}
28+
<Slot />
4829
</section>
4930
</Tabs.Panel>
5031
<Tabs.Panel class="relative rounded-b-md border">
51-
<Highlight class="rounded-t-none" code={componentCodeSig.value || ''} />
32+
<Highlight class="rounded-t-none" code={rawCode || ''} />
5233
</Tabs.Panel>
5334
</Tabs.Root>
5435
) : (
5536
<div data-pagefind-ignore="all">
5637
<section class="flex justify-center space-x-6 rounded-t-md border p-8">
57-
{MetaGlobComponentSig.value && <MetaGlobComponentSig.value />}
38+
<Slot />
5839
</section>
59-
<Highlight
60-
class="rounded-none rounded-b-md border p-8"
61-
code={componentCodeSig.value || ''}
62-
/>
40+
<Highlight class="rounded-none rounded-b-md border p-8" code={rawCode || ''} />
6341
</div>
6442
)}
6543
</div>

apps/website/src/routes/docs/contributing/index.mdx

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { InfoPopup } from '~/components/info-popup/info-popup';
88

99
import { statusByComponent } from '~/_state/component-statuses';
1010

11+
import { ShowcaseTheProblem, ShowcaseInline, ShowcaseServer } from './showcase-components';
12+
1113
# Contributing
1214

1315
Thinking about contributing to the project, but don't know where to start? You're in the right place!
@@ -83,12 +85,6 @@ Qwik UI uses [MDX](https://mdxjs.com/docs/what-is-mdx/) for interactive markdown
8385

8486
Here is a quick link to the [headless docs in github](https://github.com/qwikifiers/qwik-ui/tree/main/apps/website/src/routes/docs/headless).
8587

86-
One of the most import components in the docs is the `showcase` component, which gives typescript support, a component preview of your example, and **automatically** updates the code example as you edit it! 🤯
87-
88-
> Here's [an example](https://github.com/qwikifiers/qwik-ui/blob/main/apps/website/src/routes/docs/headless/modal/examples/hero.tsx) of someone consuming a headless component! In `index.mdx` we can use `<Showcase name="hero" />`, because `hero.tsx` is the file path.
89-
90-
The same thing goes for the `snippet` component, which is for showing code blocks only.
91-
9288
### Docs Components
9389

9490
There are more [docs components](https://github.com/qwikifiers/qwik-ui/tree/main/apps/website/src/components) to make your life easier! Some examples being:
@@ -152,7 +148,9 @@ We strongly recommend TDD development for the headless library.
152148

153149
### Getting started w/ testing
154150

155-
Using what we've learned with the showcase component, let's create a new example to test:
151+
152+
153+
We use the components showcased in the docs to test the headless library. Let's create a new example to test:
156154

157155
```tsx
158156
import { component$ } from '@builder.io/qwik';
@@ -168,14 +166,6 @@ export default component$(() => {
168166
});
169167
```
170168

171-
Above is a new file called `hero.tsx` in our `examples` folder. In the collapsible pages `index.mdx` file add the following:
172-
173-
```shell
174-
<Showcase name="hero" />
175-
```
176-
177-
Adding the showcase component to the website MDX will automatically create a new isolated environment in playwright as well.
178-
179169
Each headless component also needs a "driver file", or the reusable component pieces we will need throughout the test.
180170

181171
In the headless folder, create a new file with the convention of `<component-name>.driver.tsx`.
@@ -319,13 +309,13 @@ A more detailed explanation:
319309
320310
In client-side rendered environments, such as dashboards, Qwik components can render asynchronously and even out of order.
321311
322-
<Showcase name="the-problem" />
312+
<ShowcaseTheProblem />
323313
324314
The above demonstrates the problem. The conditional JSX added is rendered on the client when the button is clicked, and the items are not rendered in the correct order.
325315
326316
By contrast, when it is rendered on the server, we get the expected order.
327317
328-
<Showcase name="server" />
318+
<ShowcaseServer />
329319
330320
This has to do with the entrypoints of the application. The current and previous generation of frameworks execute from the root entrypoint down in a tree-like structure, which is O(n) complexity.
331321
@@ -356,7 +346,7 @@ In our case, the tradeoff is negligible, but it's something to keep in mind.
356346
357347
To use an inline component, create a standard function that returns JSX. In the below example, the inline component is called ExampleRoot.
358348
359-
<Showcase name="inline" />
349+
<ShowcaseInline />
360350
361351
The root component uses two utilities from Qwik UI.
362352
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { component$ } from '@builder.io/qwik';
2+
import { Showcase } from '~/components/showcase/showcase';
3+
4+
import TheProblem from './examples/the-problem';
5+
import TheProblemRawCode from './examples/the-problem.tsx?raw';
6+
export const ShowcaseTheProblem = component$(() => {
7+
return (
8+
<Showcase rawCode={TheProblemRawCode}>
9+
<TheProblem />
10+
</Showcase>
11+
);
12+
});
13+
14+
import Inline from './examples/inline';
15+
import InlineRawCode from './examples/inline.tsx?raw';
16+
export const ShowcaseInline = component$(() => {
17+
return (
18+
<Showcase rawCode={InlineRawCode}>
19+
<Inline />
20+
</Showcase>
21+
);
22+
});
23+
24+
import Server from './examples/server';
25+
import ServerRawCode from './examples/server.tsx?raw';
26+
export const ShowcaseServer = component$(() => {
27+
return (
28+
<Showcase rawCode={ServerRawCode}>
29+
<Server />
30+
</Showcase>
31+
);
32+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { component$ } from '@builder.io/qwik';
2+
import { CodeSnippet } from '~/components/code-snippet/code-snippet';
3+
4+
import BuildingBlocksSnippet from './snippets/building-blocks.tsx?raw';
5+
export const CodeSnippetBuildingBlocks = component$(() => {
6+
return <CodeSnippet code={BuildingBlocksSnippet} />;
7+
});
8+
9+
import AnimationCssSnippet from './snippets/animation.css?raw';
10+
export const CodeSnippetAnimationCss = component$(() => {
11+
return <CodeSnippet code={AnimationCssSnippet} />;
12+
});
13+
14+
import AccordionCssSnippet from './snippets/accordion.css?raw';
15+
export const CodeSnippetAccordionCss = component$(() => {
16+
return <CodeSnippet code={AccordionCssSnippet} />;
17+
});

apps/website/src/routes/docs/headless/accordion/examples/dynamic.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Accordion } from '@qwik-ui/headless';
44
interface DynamicAccordionProps {
55
itemIndexToDelete?: number;
66
itemIndexToAdd?: number;
7-
itemsLength: number;
7+
itemsLength?: number;
88
}
99

1010
export default component$(({ itemsLength = 3 }: DynamicAccordionProps) => {

0 commit comments

Comments
 (0)