Skip to content

Commit 0707baf

Browse files
committed
refactor(mdxprovider): add MDXProvider pattern
1 parent 6c5a72e commit 0707baf

File tree

66 files changed

+927
-778
lines changed

Some content is hidden

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

66 files changed

+927
-778
lines changed

.prettierignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@
66
dist
77
node_modules
88
coverage
9-
**/*.mdx
109
discussion
1110
pnpm-lock.yaml
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import type { Plugin } from 'unified';
2+
import type {
3+
Program,
4+
Node,
5+
FunctionDeclaration,
6+
VariableDeclarator,
7+
VariableDeclaration,
8+
CallExpression,
9+
Literal,
10+
} from 'estree-jsx';
11+
12+
function isNamedFunction(node: FunctionDeclaration, name: string) {
13+
return Boolean(node.id?.name === name);
14+
}
15+
16+
export const recmaProvideComponents: Plugin<any, Program> = () => {
17+
let id = 0;
18+
return (tree) => {
19+
const replacement = [];
20+
for (const _node of tree.body) {
21+
const node = _node as Node;
22+
if (node.type === 'FunctionDeclaration' && node.id) {
23+
if (
24+
isNamedFunction(node, 'MDXContent') ||
25+
isNamedFunction(node, '_createMdxContent')
26+
) {
27+
/**
28+
* Transforms function MDXContent (props = {}) {...}
29+
* to const MDXContent = _componentQrl(_inlinedQrl(function (props = {}) {...}, 'symbolName', []))
30+
* allows using Qwik hooks inside
31+
* */
32+
const symbolName = `${node.id?.name || 'mdx'}_${id++}`;
33+
const declarations: VariableDeclarator[] = [
34+
{
35+
id: node.id,
36+
type: 'VariableDeclarator',
37+
init: {
38+
type: 'CallExpression',
39+
callee: {
40+
type: 'Identifier',
41+
name: '_componentQrl',
42+
},
43+
arguments: [
44+
{
45+
type: 'CallExpression',
46+
callee: {
47+
type: 'Identifier',
48+
name: '_inlinedQrl',
49+
},
50+
arguments: [
51+
{
52+
type: 'ArrowFunctionExpression',
53+
id: null,
54+
params: node.params,
55+
body: node.body,
56+
async: node.async,
57+
generator: node.generator,
58+
},
59+
{
60+
type: 'Literal',
61+
value: symbolName,
62+
raw: String.raw`"${symbolName}"`,
63+
} as Literal,
64+
{
65+
type: 'ArrayExpression',
66+
elements: [],
67+
},
68+
],
69+
} as CallExpression,
70+
],
71+
} as CallExpression,
72+
},
73+
];
74+
const newNode: VariableDeclaration = {
75+
type: 'VariableDeclaration',
76+
kind: 'const',
77+
declarations,
78+
};
79+
replacement.push(newNode);
80+
continue;
81+
}
82+
}
83+
replacement.push(_node);
84+
}
85+
tree.body = replacement;
86+
87+
tree.body.unshift({
88+
type: 'ImportDeclaration',
89+
specifiers: [
90+
{
91+
type: 'ImportSpecifier',
92+
imported: { type: 'Identifier', name: 'componentQrl' },
93+
local: { type: 'Identifier', name: '_componentQrl' },
94+
},
95+
{
96+
type: 'ImportSpecifier',
97+
imported: { type: 'Identifier', name: 'inlinedQrl' },
98+
local: { type: 'Identifier', name: '_inlinedQrl' },
99+
},
100+
],
101+
source: { type: 'Literal', value: '@builder.io/qwik' },
102+
});
103+
};
104+
};
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {
2+
Component,
3+
component$,
4+
createContextId,
5+
useContext,
6+
Slot,
7+
useContextProvider,
8+
} from '@builder.io/qwik';
9+
10+
export const MDXContext = createContextId<Components>('MDXContext');
11+
12+
export interface Components {
13+
[tag: string]: Component<any>;
14+
}
15+
16+
/**
17+
* Get current components from the MDX Context.
18+
*/
19+
export function useMDXComponents() {
20+
return useContext(MDXContext, {});
21+
}
22+
23+
export const DefaultWrapper = component$(() => {
24+
return <Slot />;
25+
});
26+
27+
/**
28+
* Provider for MDX context
29+
*/
30+
export const MDXProvider = component$(
31+
({
32+
components,
33+
disableParentContext,
34+
}: {
35+
components: Components;
36+
disableParentContext?: boolean;
37+
}) => {
38+
let allComponents = useMDXComponents();
39+
if (disableParentContext) {
40+
allComponents = components;
41+
} else {
42+
allComponents = { ...allComponents, ...components };
43+
}
44+
useContextProvider(MDXContext, {
45+
wrapper: DefaultWrapper,
46+
...allComponents,
47+
});
48+
return <Slot />;
49+
},
50+
);

apps/website/src/components/highlight/highlight.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ export const Highlight = component$(
4545
const str = await highlighter.codeToHtml(modifiedCode, {
4646
lang: language,
4747
themes: {
48-
light: 'github-dark',
49-
dark: 'github-dark',
48+
light: 'poimandres',
49+
dark: 'poimandres',
5050
},
5151
});
5252
codeSig.value = str.toString();
@@ -66,7 +66,7 @@ export const Highlight = component$(
6666
<div
6767
{...props}
6868
class={[
69-
'tab-size code-example-gradient max-h-[31.25rem] max-w-full overflow-auto rounded-xl bg-slate-800 p-6 text-sm dark:bg-slate-800',
69+
'tab-size max-h-[31.25rem] max-w-full overflow-auto rounded-xl bg-[#1B1E28] p-6 text-sm dark:bg-[#1B1E28]',
7070
props.class,
7171
]}
7272
>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { QwikIntrinsicElements, Slot, component$ } from '@builder.io/qwik';
2+
import { OmitSignalClass } from '@qwik-ui/utils';
3+
import { StatusBanner } from '../status-banner/status-banner';
4+
import { AnatomyTable } from '../anatomy-table/anatomy-table';
5+
import { APITable } from '../api-table/api-table';
6+
import { KeyboardInteractionTable } from '../keyboard-interaction-table/keyboard-interaction-table';
7+
import { CodeCopy } from '../code-copy/code-copy';
8+
import { statusByComponent } from '~/_state/component-statuses';
9+
10+
export const components: Record<string, any> = {
11+
pre: component$<
12+
OmitSignalClass<
13+
QwikIntrinsicElements['pre'] & {
14+
__rawString__?: string;
15+
}
16+
>
17+
>(({ __rawString__, ...props }) => {
18+
return (
19+
<div class="code-example relative max-h-[31.25rem] rounded-b-xl">
20+
<CodeCopy
21+
class={[
22+
'copy-btn-bg-dark absolute right-4 top-4 bg-slate-200 text-white hover:bg-slate-600 hover:text-white',
23+
]}
24+
code={__rawString__}
25+
/>
26+
<div
27+
{...props}
28+
class={[
29+
'tab-size code-example-gradient max-h-[31.25rem] max-w-full overflow-auto rounded-xl bg-slate-800 p-6 text-sm dark:bg-slate-800',
30+
props.class,
31+
]}
32+
>
33+
<pre>
34+
<Slot />
35+
</pre>
36+
</div>
37+
</div>
38+
);
39+
}),
40+
AnatomyTable,
41+
APITable,
42+
KeyboardInteractionTable,
43+
StatusBanner,
44+
statusByComponent: statusByComponent,
45+
};

apps/website/src/components/preview-code-example/preview-code-example-tabs-deprecated.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { component$, Slot, useStyles$ } from '@builder.io/qwik';
22
import { Tab, TabList, TabPanel, Tabs } from '@qwik-ui/headless';
3-
import { CodeCopy } from '../code-copy/code-copy';
43

54
export const PreviewCodeExampleTabsDeprecated = component$((props: { code?: string }) => {
65
useStyles$(`
@@ -33,9 +32,8 @@ export const PreviewCodeExampleTabsDeprecated = component$((props: { code?: stri
3332
<Slot name="actualComponent" />
3433
</section>
3534
</TabPanel>
36-
<TabPanel class="border-qwikui-blue-300 dark:border-qwikui-purple-200 relative rounded-b-xl border-[1.5px] bg-slate-800 p-4 dark:bg-slate-900 md:p-12">
37-
<CodeCopy class="code-copy absolute right-0 top-0" code={props.code} />
38-
<section class="overflow-auto">
35+
<TabPanel class="border-qwikui-blue-300 dark:border-qwikui-purple-200 relative rounded-b-xl border-[1.5px] bg-slate-800 dark:bg-slate-900">
36+
<section>
3937
<Slot name="codeExample" />
4038
</section>
4139
</TabPanel>

apps/website/src/global.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@
155155
);
156156
}
157157

158-
/* no horizontal overflow on code examples */
158+
/* no horizontal overflow on code snippets */
159159
.tab-size pre {
160160
white-space: pre-wrap;
161161
background: transparent !important;

apps/website/src/routes/docs.css

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
}
2727

2828
h4 {
29-
@apply mb-4 mt-6 text-lg font-[600] font-medium;
29+
@apply mb-4 mt-6 text-lg font-medium;
3030
}
3131

3232
h5 {
@@ -47,7 +47,11 @@
4747
}
4848

4949
a {
50-
@apply border-qwikui-blue-500 dark:border-qwikui-purple-400 ease-step hover:border-qwikui-blue-600 border-b-[1.5px] font-semibold transition transition-colors duration-300;
50+
@apply border-qwikui-blue-500 dark:border-qwikui-purple-400 ease-step hover:border-qwikui-blue-600 border-b-[1.5px] font-semibold transition-colors duration-300;
51+
}
52+
53+
code {
54+
@apply bg-transparent;
5155
}
5256

5357
p code {

apps/website/src/routes/docs/fluffy/(components)/accordion/index.mdx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
title: Qwik UI | Fluffy Accordion Component
33
---
44

5-
import {StatusBanner, statusByComponent} from '../exports';
5+
import { statusByComponent } from '~/_state/component-statuses';
66

77
# Accordion
88

99
A vertically stacked set of beautifully interactive headings which like to play "hard to get" by revealing or hiding their associated content.
10-
<br/>
11-
<StatusBanner status={statusByComponent.fluffy.Accordion}/>
12-
10+
11+
<StatusBanner status={statusByComponent.fluffy.Accordion} />

apps/website/src/routes/docs/fluffy/(components)/alert/index.mdx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
title: Qwik UI | Fluffy Alert Component
33
---
44

5-
import {StatusBanner, statusByComponent} from '../exports';
5+
import { statusByComponent } from '~/_state/component-statuses';
66

77
# Alert
88

99
In a digital landscape of gentle nudges, the Fluffy alert pops with a playful flair, ensuring every crucial whisper finds its audience effortlessly.
10-
<br/>
11-
<StatusBanner status={statusByComponent.fluffy.Alert}/>
12-
10+
11+
<StatusBanner status={statusByComponent.fluffy.Alert} />

0 commit comments

Comments
 (0)