Skip to content

Commit 9775deb

Browse files
committed
chore(components): fix themed()
1 parent b994c5e commit 9775deb

File tree

3 files changed

+37
-34
lines changed

3 files changed

+37
-34
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"typecheck:tests": "tsc --noEmit -P ./tsconfig.test.json",
1414
"logo": "yarn workspace docs logo",
1515
"postinstall": "preconstruct dev",
16+
"dev": "preconstruct dev",
1617
"version:bump": "lerna version",
1718
"version:bump-next": "lerna version prerelease --preid alpha --exact",
1819
"release": "yarn clean && yarn build && yarn shipit",

packages/mdx/src/index.tsx

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
ReactNode,
88
DetailedHTMLProps,
99
HTMLAttributes,
10-
ElementType,
1110
ComponentProps,
1211
useMemo,
1312
} from 'react'
@@ -86,21 +85,8 @@ const alias = (n: ThemedComponentName): keyof JSX.IntrinsicElements =>
8685
isAlias(n) ? aliases[n] : n
8786

8887
export const themed =
89-
(key: ThemedComponentName | (string & {})) =>
90-
({ theme, ...rest }: ThemedProps) => {
91-
const extraStyles: CSSObject = {}
92-
93-
if (key === 'th' || key === 'td') {
94-
const { align } = rest as DetailedHTMLProps<
95-
React.ThHTMLAttributes<HTMLTableHeaderCellElement>,
96-
HTMLTableHeaderCellElement
97-
>
98-
99-
if (align !== 'char') extraStyles.textAlign = align
100-
}
101-
102-
return css({ ...get(theme, `styles.${key}`), ...extraStyles })(theme)
103-
}
88+
(key: ThemedComponentName | (string & {})) => (theme: Theme) =>
89+
css(get(theme, `styles.${key}`))(theme)
10490

10591
// opt out of typechecking whenever `as` prop is used
10692
interface AnyComponentProps extends JSX.IntrinsicAttributes {
@@ -109,8 +95,11 @@ interface AnyComponentProps extends JSX.IntrinsicAttributes {
10995

11096
export interface ThemedComponent<Name extends string> {
11197
(
112-
props: Name extends keyof JSX.IntrinsicElements ? ComponentProps<Name> : {}
98+
props: (Name extends keyof JSX.IntrinsicElements
99+
? ComponentProps<Name>
100+
: {}) & { css?: CSSObject }
113101
): JSX.Element
102+
displayName: string
114103
}
115104

116105
export type ThemedComponentsDict = {
@@ -127,14 +116,30 @@ const createThemedComponent = <Name extends string>(
127116
): ThemedComponent<Name> => {
128117
const variantStyles = themed(variant)
129118

130-
return (props) => {
119+
const component: ThemedComponent<Name> = (props) => {
120+
const extraStyles: { textAlign?: 'left' | 'right' | 'center' | 'justify' } =
121+
{}
122+
123+
if (name === 'th' || name === 'td') {
124+
const { align } = props as DetailedHTMLProps<
125+
React.ThHTMLAttributes<HTMLTableHeaderCellElement>,
126+
HTMLTableHeaderCellElement
127+
>
128+
129+
if (align !== 'char') extraStyles.textAlign = align
130+
}
131+
131132
const css = (props as any)['css']
132133

133134
return jsx(name, {
134135
...props,
135-
css: css ? [css, variantStyles] : variantStyles,
136+
css: [props.css, variantStyles, extraStyles].filter(Boolean),
136137
})
137138
}
139+
140+
component.displayName = `Themed(${name})`
141+
142+
return component
138143
}
139144

140145
interface ThemedDivProps
@@ -167,10 +172,18 @@ const createComponents = (comps: MDXProviderComponents) => {
167172
// todo: test this behaviour
168173
componentKeys.forEach((key) => {
169174
const componentAtKey = comps[key]
175+
170176
if (componentAtKey) {
171-
next[key] = (props) => jsx(componentAtKey, { ...props, css: themed(key) })
177+
const component: ThemedComponent<string> = (props) => {
178+
return jsx(componentAtKey, { ...props, css: themed(key) })
179+
}
180+
181+
component.displayName = "MdxComponents('" + key + "')"
182+
183+
next[key] = component
172184
}
173185
})
186+
174187
return next
175188
}
176189

packages/mdx/test/index.tsx

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ expect.extend(matchers)
1717

1818
test('styles React components', () => {
1919
const Beep = (props: React.ComponentPropsWithoutRef<'h2'>) => (
20+
// eslint-disable-next-line jsx-a11y/heading-has-content
2021
<h2 {...props} />
2122
)
23+
2224
const Inner = (props: React.ComponentPropsWithoutRef<typeof Beep>) =>
2325
mdx('Beep', props)
2426

@@ -45,22 +47,9 @@ test('styles React components', () => {
4547
expect(json).toHaveStyleRule('color', 'tomato')
4648
})
4749

48-
test('cleans up style props', () => {
49-
const json = renderJSON(
50-
// @ts-expect-error
51-
<Themed.h1 mx={2} id="test">
52-
Hello
53-
</Themed.h1>
54-
)!
55-
expect(json.props.id).toBe('test')
56-
expect(json.props.mx).not.toBeDefined()
57-
})
58-
5950
test('themed extracts styles from the theme', () => {
6051
expect(
61-
themed('footer')({
62-
theme: { styles: { footer: { background: 'skyblue' } } },
63-
})
52+
themed('footer')({ styles: { footer: { background: 'skyblue' } } })
6453
).toStrictEqual({ background: 'skyblue' })
6554
})
6655

0 commit comments

Comments
 (0)