Support data object

This commit is contained in:
Alex 2024-06-29 12:28:04 -04:00
parent d0f032edc1
commit 69cc90730c
5 changed files with 61 additions and 15 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@aet/tailwind",
"version": "0.0.1-beta.14",
"version": "0.0.1-beta.15",
"main": "dist/index.js",
"license": "MIT",
"scripts": {

View File

@ -86,6 +86,14 @@ export function babelTailwind(
if (isPlainObject(value)) {
return Object.entries(value).flatMap(([modifier, classes]) => {
if (modifier === "data" && isPlainObject(classes)) {
return Object.entries(classes as object).flatMap(([key, cls]) =>
trim(cls)
.split(" ")
.map(value => `${modifier}-[${key}]:${value}`)
);
}
if (typeof classes !== "string") {
throw new Error(`Value for "${modifier}" should be a string`);
}

View File

@ -5,27 +5,54 @@ interface WithClassName<P = object> extends FunctionComponent<P> {
className: string;
}
type InputProps = React.DetailedHTMLProps<
React.InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
>;
export const classed: {
(
type: "input",
className: string | string[]
): WithClassName<
React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
>;
className: string | string[],
defaultProps?: Partial<InputProps>
): InputProps;
<K extends keyof JSX.IntrinsicElements>(
type: K,
className: string | string[]
): WithClassName<JSX.IntrinsicElements[K]>;
className: string | string[],
defaultProps?: Partial<JSX.IntrinsicElements[K]>
): JSX.IntrinsicElements[K];
(
type: string,
className: string | string[]
className: string | string[],
defaultProps?: Record<string, unknown>
): WithClassName<React.ClassAttributes<any> & React.DOMAttributes<any>>;
<P>(type: FunctionComponent<P>, className: string | string[]): WithClassName<P>;
<P>(type: React.ComponentClass<P>, className: string | string[]): WithClassName<P>;
} = (Component: any, classNameInput: string | (string | false)[]) => {
<P>(
type: FunctionComponent<P>,
className: string | string[],
defaultProps?: Partial<P>
): WithClassName<P>;
<P>(
type: React.ComponentClass<P>,
className: string | string[],
defaultProps?: Partial<P>
): WithClassName<P>;
} = (
Component: any,
classNameInput: string | string[],
defaultProps?: Record<string, unknown>
) => {
const className = cx(classNameInput);
const component: any = forwardRef<any, any>(({ className: cls, ...props }, ref) => (
<Component {...props} ref={ref} className={cx(className, cls)} />
<Component
{...defaultProps}
{...props}
ref={ref}
className={
typeof cls === "function"
? (...args: unknown[]) => cx(className, cls(...args))
: cx(className, cls)
}
/>
));
component.className = className;
return component;

View File

@ -167,12 +167,15 @@ describe("babel-tailwind", () => {
export default tw("text-sm", \`flex\`, {
"group-hover": "text-center",
"[&>div]": \`font-semibold\`,
data: {
"name='hello'": "text-right",
},
})
`,
});
const clsName = getClassName(
"text-sm flex group-hover:text-center [&>div]:font-semibold"
"text-sm flex group-hover:text-center [&>div]:font-semibold data-[name='hello']:text-right"
);
expect(files.js.text).toContain(`= "${clsName}"`);
expect(files.css.text).toMatch(
@ -185,6 +188,9 @@ describe("babel-tailwind", () => {
`.group:hover .${clsName} {`,
" text-align: center;",
"}",
`.${clsName}[data-name=hello] {`,
" text-align: right;",
"}",
`.${clsName} > div {`,
" font-weight: 600;",
"}",
@ -192,7 +198,7 @@ describe("babel-tailwind", () => {
);
});
it("supports grouped array css jsx attribute like tw function", async () => {
it("supports grouped array css attribute", async () => {
const { files } = await compileESBuild({
clsx: "emotion",
expectFiles: 2,

View File

@ -19,7 +19,12 @@ type GetClassName = (className: string) => string;
*/
export interface TailwindFunction {
(strings: TemplateStringsArray): string;
(...args: (string | { [modifier: string]: string })[]): string;
(
...args: (
| string
| ({ data?: { [key: string]: string } } & { [modifier: string]: string })
)[]
): string;
}
export interface TailwindPluginOptions {