-
Notifications
You must be signed in to change notification settings - Fork 2
/
jsx-runtime.ts
95 lines (84 loc) · 3.02 KB
/
jsx-runtime.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import {
createComponent,
createContext,
mergeProps,
useContext,
type JSX,
type JSXElement,
type ParentProps,
} from 'solid-js';
import { Dynamic } from 'solid-js/web';
import { isFirstLetterCapital, isSVGElement, normalizeKeySvg } from 'utilities';
export const MDXContext = createContext<Record<string, (properties_: never) => JSX.Element>>(
Object.create(null) as Record<string, never>,
);
export const MDXProvider = (
properties: ParentProps<{
components: Record<string, (properties_: never) => JSX.Element>;
}>,
): JSXElement => {
const context = useContext(MDXContext);
return createComponent(MDXContext.Provider, {
get value() {
return {
...context,
...properties.components,
};
},
get children() {
return properties.children;
},
});
};
export const useMDXComponents = (
components: Record<string, (properties_: never) => JSX.Element>,
): Record<string, (properties_: never) => JSX.Element> => {
const contextComponents = useContext(MDXContext);
return { ...contextComponents, ...components };
};
const REPLACED_COMPAT_SET = new Set(['mjx']);
const compatRegExp = new RegExp(`(?:${[...REPLACED_COMPAT_SET].join('|')})-.+`, 'g');
const expressionCache = Object.create(null) as Record<string, string>;
const replaceDashWithUnderscore = <T>(expression: T): string | T =>
typeof expression === 'string'
? expressionCache[expression] ??
(expressionCache[expression] = expression.replaceAll(compatRegExp, (match: string) =>
match.replaceAll('-', '_'),
))
: expression;
const getProperties = (
properties: Record<string, unknown> & { children?: JSX.Element },
type?: string,
): ParentProps => {
const properties_: Record<string, unknown> = {};
for (const key of Object.keys(properties))
properties_[jsxKeyToSolid(key, type)] =
typeof properties[key] === 'object' && !Array.isArray(properties[key])
? getProperties(properties[key] as Record<string, unknown>, type)
: replaceDashWithUnderscore(properties[key]);
return properties_;
};
export const Fragment = (properties: ParentProps): JSX.Element => properties.children;
export const jsx = (
type: string | ((properties_: ParentProps) => JSX.Element),
properties: ParentProps,
): JSX.Element =>
typeof type === 'function'
? type.name === 'Fragment'
? Fragment(properties)
: type(getProperties(properties))
: createComponent(
Dynamic,
mergeProps(isFirstLetterCapital(type) ? properties : getProperties(properties, type), {
component: replaceDashWithUnderscore(type),
}),
);
const jsxKeyToSolid = (key: string, type = ''): string =>
isSVGElement(type)
? (key = key === 'xlinkHref' || key === 'xlink:href' ? 'href' : normalizeKeySvg(key))
: key;
// For the moment we do not distinguish static children from dynamic ones
export const jsxs = jsx;
// For the moment there is not special development handling
// function jsxDEV(type, props , maybeKey, isStaticChildren, source, self)
export const jsxDEV = jsx;