Skip to content

Commit fd03700

Browse files
committed
Feat: styled - Support styled.div like shorthand API
1 parent 4a185b4 commit fd03700

File tree

5 files changed

+217
-22
lines changed

5 files changed

+217
-22
lines changed

.changeset/mighty-nights-see.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@mincho-js/react": minor
3+
---
4+
5+
**styled**
6+
- Add `style.div` like shorthand API

.changeset/stupid-hairs-behave.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@mincho-js/react": minor
3+
---
4+
5+
**styled**
6+
- Add `style.div` like shorthand API

examples/react-babel/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { styled } from "@mincho-js/react";
22

3-
const BaseComponent = styled("div", {
3+
const BaseComponent = styled.div({
44
base: {
55
fontWeight: "bold",
66
},

packages/react/src/index.ts

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ import {
1919
RefAttributes
2020
} from "react";
2121

22-
export { $$styled } from "./runtime.js";
22+
import { tags, SupportedElements } from "./tags.js";
2323

24-
type KeyofIntrinsicElements = keyof JSX.IntrinsicElements;
24+
export { $$styled } from "./runtime.js";
2525

2626
// == Main =====================================================================
27-
export function styled<
27+
function styledImpl<
2828
Props,
2929
Component extends ForwardRefExoticComponent<Props>,
3030
RulesVariants extends VariantGroups | undefined = undefined,
@@ -41,7 +41,7 @@ export function styled<
4141
RulesProps
4242
>;
4343

44-
export function styled<
44+
function styledImpl<
4545
Props,
4646
Component extends ComponentType<Props>,
4747
RulesVariants extends VariantGroups | undefined = undefined,
@@ -58,7 +58,7 @@ export function styled<
5858
RulesProps
5959
>;
6060

61-
export function styled<
61+
function styledImpl<
6262
Props extends object,
6363
Component extends ElementType,
6464
RulesVariants extends VariantGroups | undefined = undefined,
@@ -75,8 +75,8 @@ export function styled<
7575
RulesProps
7676
>;
7777

78-
export function styled<
79-
Component extends KeyofIntrinsicElements,
78+
function styledImpl<
79+
Component extends SupportedElements,
8080
RulesVariants extends VariantGroups | undefined = undefined,
8181
RulesToggleVariants extends VariantDefinitions | undefined = undefined,
8282
RulesProps extends ComplexPropDefinitions<PropTarget> | undefined = undefined
@@ -91,11 +91,11 @@ export function styled<
9191
RulesProps
9292
>;
9393

94-
export function styled<
94+
function styledImpl<
9595
Component extends
9696
| ForwardRefExoticComponent<unknown>
9797
| ComponentType<unknown>
98-
| KeyofIntrinsicElements
98+
| SupportedElements
9999
| ComponentWithAs<object, ElementType>,
100100
RulesVariants extends VariantGroups | undefined = undefined,
101101
RulesToggleVariants extends VariantDefinitions | undefined = undefined,
@@ -115,23 +115,58 @@ export function styled<
115115
);
116116
}
117117

118-
type IntrinsicProps<TComponent> = TComponent extends KeyofIntrinsicElements
118+
type TaggedStyled = {
119+
[Tag in SupportedElements]: <
120+
RulesVariants extends VariantGroups | undefined = undefined,
121+
RulesToggleVariants extends VariantDefinitions | undefined = undefined,
122+
RulesProps extends
123+
| ComplexPropDefinitions<PropTarget>
124+
| undefined = undefined
125+
>(
126+
options: PatternOptions<RulesVariants, RulesToggleVariants, RulesProps>
127+
) => StyledComponent<
128+
IntrinsicProps<Tag>,
129+
Tag,
130+
RulesVariants,
131+
RulesToggleVariants,
132+
RulesProps
133+
>;
134+
};
135+
136+
const taggedStyled: TaggedStyled = {} as TaggedStyled;
137+
138+
function createStyledComponent(
139+
tag: SupportedElements
140+
): TaggedStyled[SupportedElements] {
141+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
142+
// @ts-ignore Prevent TS too complex type inference error
143+
return (options: unknown) => styledImpl(tag, options);
144+
}
145+
146+
tags.forEach((tag) => {
147+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
148+
// @ts-ignore Prevent TS too complex type inference error
149+
taggedStyled[tag] = createStyledComponent(tag);
150+
});
151+
152+
export const styled = Object.assign(styledImpl, taggedStyled as TaggedStyled);
153+
154+
type IntrinsicProps<TComponent> = TComponent extends SupportedElements
119155
? JSX.IntrinsicElements[TComponent]
120156
: never;
121157

122-
type InferStyledComponentProps<Component> =
123-
Component extends KeyofIntrinsicElements
124-
? IntrinsicProps<Component>
125-
: Component extends ComponentType<infer ComponentTypeProps>
126-
? ComponentTypeProps
127-
: Component extends ForwardRefExoticComponent<infer ForwardRefProps>
128-
? ForwardRefProps
129-
: Component extends ComponentWithAs<infer WithAsProps, ElementType>
130-
? WithAsProps
131-
: never;
158+
type InferStyledComponentProps<Component> = Component extends SupportedElements
159+
? IntrinsicProps<Component>
160+
: Component extends ComponentType<infer ComponentTypeProps>
161+
? ComponentTypeProps
162+
: Component extends ForwardRefExoticComponent<infer ForwardRefProps>
163+
? ForwardRefProps
164+
: Component extends ComponentWithAs<infer WithAsProps, ElementType>
165+
? WithAsProps
166+
: never;
132167

133168
type InferStyledComponentElement<Component> =
134-
Component extends KeyofIntrinsicElements
169+
Component extends SupportedElements
135170
? Component
136171
: Component extends ElementType
137172
? Component

packages/react/src/tags.ts

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import type { JSX } from "react";
2+
3+
export type KeyofIntrinsicElements = keyof JSX.IntrinsicElements;
4+
export type SupportedElements = (typeof tags)[number];
5+
6+
/**
7+
* Based on
8+
* - Emotion: https://github.com/emotion-js/emotion/blob/main/packages/styled/src/tags.ts
9+
* - Styled Components: https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/utils/domElements.ts
10+
*/
11+
export const tags = [
12+
"a",
13+
"abbr",
14+
"address",
15+
"area",
16+
"article",
17+
"aside",
18+
"audio",
19+
"b",
20+
"base",
21+
"bdi",
22+
"bdo",
23+
"big",
24+
"blockquote",
25+
"body",
26+
"br",
27+
"button",
28+
"canvas",
29+
"caption",
30+
"cite",
31+
"code",
32+
"col",
33+
"colgroup",
34+
"data",
35+
"datalist",
36+
"dd",
37+
"del",
38+
"details",
39+
"dfn",
40+
"dialog",
41+
"div",
42+
"dl",
43+
"dt",
44+
"em",
45+
"embed",
46+
"fieldset",
47+
"figcaption",
48+
"figure",
49+
"footer",
50+
"form",
51+
"h1",
52+
"h2",
53+
"h3",
54+
"h4",
55+
"h5",
56+
"h6",
57+
"head",
58+
"header",
59+
"hgroup",
60+
"hr",
61+
"html",
62+
"i",
63+
"iframe",
64+
"img",
65+
"input",
66+
"ins",
67+
"kbd",
68+
"keygen",
69+
"label",
70+
"legend",
71+
"li",
72+
"link",
73+
"main",
74+
"map",
75+
"mark",
76+
"menu",
77+
"menuitem",
78+
"meta",
79+
"meter",
80+
"nav",
81+
"noscript",
82+
"object",
83+
"ol",
84+
"optgroup",
85+
"option",
86+
"output",
87+
"p",
88+
"param",
89+
"picture",
90+
"pre",
91+
"progress",
92+
"q",
93+
"rp",
94+
"rt",
95+
"ruby",
96+
"s",
97+
"samp",
98+
"script",
99+
"section",
100+
"select",
101+
"small",
102+
"source",
103+
"span",
104+
"strong",
105+
"style",
106+
"sub",
107+
"summary",
108+
"sup",
109+
"table",
110+
"tbody",
111+
"td",
112+
"textarea",
113+
"tfoot",
114+
"th",
115+
"thead",
116+
"time",
117+
"title",
118+
"tr",
119+
"track",
120+
"u",
121+
"ul",
122+
"use",
123+
"var",
124+
"video",
125+
"wbr",
126+
127+
// SVG
128+
"circle",
129+
"clipPath",
130+
"defs",
131+
"ellipse",
132+
"foreignObject",
133+
"g",
134+
"image",
135+
"line",
136+
"linearGradient",
137+
"mask",
138+
"path",
139+
"pattern",
140+
"polygon",
141+
"polyline",
142+
"radialGradient",
143+
"rect",
144+
"stop",
145+
"svg",
146+
"text",
147+
"tspan"
148+
] as const satisfies Array<KeyofIntrinsicElements>;

0 commit comments

Comments
 (0)