mirror of
https://github.com/zhigang1992/nativewind.git
synced 2026-06-15 10:17:54 +08:00
feat: add component
This commit is contained in:
12
__tests__/custom-tailwindcss/component.ts
Normal file
12
__tests__/custom-tailwindcss/component.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { tailwindRunner } from "../tailwindcss/runner";
|
||||||
|
|
||||||
|
tailwindRunner("Custom Tailwind CSS - component", [
|
||||||
|
[
|
||||||
|
"component-hover:text-green-500",
|
||||||
|
{
|
||||||
|
"component-hover_text-green-500": [
|
||||||
|
{ atRules: [["component", "hover"]], color: "#22c55e" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]);
|
||||||
@@ -37,3 +37,15 @@ export const TailwindContext = createContext<TailwindContext>({
|
|||||||
orientation: "portrait",
|
orientation: "portrait",
|
||||||
preview: false,
|
preview: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export interface ComponentContext {
|
||||||
|
hover: boolean;
|
||||||
|
focus: boolean;
|
||||||
|
active: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ComponentContext = createContext<ComponentContext>({
|
||||||
|
hover: false,
|
||||||
|
focus: false,
|
||||||
|
active: false,
|
||||||
|
});
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { useTailwind } from "./use-tailwind";
|
|||||||
import { ChildClassNameSymbol } from "./utils/child-styles";
|
import { ChildClassNameSymbol } from "./utils/child-styles";
|
||||||
import { isFragment } from "react-is";
|
import { isFragment } from "react-is";
|
||||||
import { useInteraction } from "./use-interaction";
|
import { useInteraction } from "./use-interaction";
|
||||||
|
import { ComponentContext } from "./context";
|
||||||
|
|
||||||
type StyledProps<P> = PropsWithChildren<
|
type StyledProps<P> = PropsWithChildren<
|
||||||
P & {
|
P & {
|
||||||
@@ -38,13 +39,15 @@ export function styled<P>(
|
|||||||
}: StyledProps<P>) {
|
}: StyledProps<P>) {
|
||||||
const { hover, focus, active, ...handlers } = useInteraction(props);
|
const { hover, focus, active, ...handlers } = useInteraction(props);
|
||||||
|
|
||||||
|
const classes = tw ?? className ?? "";
|
||||||
|
|
||||||
const tailwindStyles = useTailwind({
|
const tailwindStyles = useTailwind({
|
||||||
nthChild,
|
nthChild,
|
||||||
hover,
|
hover,
|
||||||
focus,
|
focus,
|
||||||
active,
|
active,
|
||||||
[ChildClassNameSymbol]: inheritedClassName,
|
[ChildClassNameSymbol]: inheritedClassName,
|
||||||
})(tw ?? className);
|
})(classes);
|
||||||
|
|
||||||
const style = styleProperty
|
const style = styleProperty
|
||||||
? [tailwindStyles, styleProperty]
|
? [tailwindStyles, styleProperty]
|
||||||
@@ -64,12 +67,22 @@ export function styled<P>(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return createElement(Component, {
|
const element = createElement(Component, {
|
||||||
...props,
|
...props,
|
||||||
...handlers,
|
...handlers,
|
||||||
style,
|
style,
|
||||||
children,
|
children,
|
||||||
} as unknown as P);
|
} as unknown as P);
|
||||||
|
|
||||||
|
return !classes.includes("container")
|
||||||
|
? element
|
||||||
|
: createElement<PropsWithChildren<{ value: ComponentContext }>>(
|
||||||
|
ComponentContext.Provider,
|
||||||
|
{
|
||||||
|
children: element,
|
||||||
|
value: { hover, focus, active },
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof Component !== "string") {
|
if (typeof Component !== "string") {
|
||||||
|
|||||||
7
src/tailwind/native/component.ts
Normal file
7
src/tailwind/native/component.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { CustomPluginFunction } from "./types";
|
||||||
|
|
||||||
|
export const component: CustomPluginFunction = ({ addVariant }) => {
|
||||||
|
addVariant("component-hover", "@component hover");
|
||||||
|
addVariant("component-focus", "@component focus");
|
||||||
|
addVariant("component-active", "@component active");
|
||||||
|
};
|
||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
} from "tailwindcss/tailwind-config";
|
} from "tailwindcss/tailwind-config";
|
||||||
import { StyleError } from "../../types/common";
|
import { StyleError } from "../../types/common";
|
||||||
import { boxShadow } from "./box-shadow";
|
import { boxShadow } from "./box-shadow";
|
||||||
|
import { component } from "./component";
|
||||||
import { divide } from "./divide";
|
import { divide } from "./divide";
|
||||||
import { elevation } from "./elevation";
|
import { elevation } from "./elevation";
|
||||||
import { fontSize } from "./font-size";
|
import { fontSize } from "./font-size";
|
||||||
@@ -48,6 +49,7 @@ export const nativePlugin = plugin.withOptions<NativePluginOptions | undefined>(
|
|||||||
skew(helpers, notSupported);
|
skew(helpers, notSupported);
|
||||||
boxShadow(helpers, notSupported);
|
boxShadow(helpers, notSupported);
|
||||||
pseudoClasses(helpers, notSupported);
|
pseudoClasses(helpers, notSupported);
|
||||||
|
component(helpers, notSupported);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
function ({ rem = 16 } = {}) {
|
function ({ rem = 16 } = {}) {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { match } from "css-mediaquery";
|
import { match } from "css-mediaquery";
|
||||||
import { normaliseSelector } from "./shared/selector";
|
import { normaliseSelector } from "./shared/selector";
|
||||||
import { TailwindContext } from "./context";
|
import { ComponentContext, TailwindContext } from "./context";
|
||||||
import {
|
import {
|
||||||
RWNCssStyle,
|
RWNCssStyle,
|
||||||
UseTailwindCallback,
|
UseTailwindCallback,
|
||||||
@@ -48,6 +48,8 @@ export function useTailwind<P>({
|
|||||||
const { platform, styles, media, width, height, orientation, colorScheme } =
|
const { platform, styles, media, width, height, orientation, colorScheme } =
|
||||||
useContext(TailwindContext);
|
useContext(TailwindContext);
|
||||||
|
|
||||||
|
const componentInteraction = useContext(ComponentContext);
|
||||||
|
|
||||||
// useState ensure this 'resets' every render
|
// useState ensure this 'resets' every render
|
||||||
let [nthChild] = useState(initialNthChild);
|
let [nthChild] = useState(initialNthChild);
|
||||||
|
|
||||||
@@ -99,6 +101,12 @@ export function useTailwind<P>({
|
|||||||
return focus;
|
return focus;
|
||||||
} else if (rule === "pseudo-class" && params === "active") {
|
} else if (rule === "pseudo-class" && params === "active") {
|
||||||
return active;
|
return active;
|
||||||
|
} else if (rule === "component" && params === "hover") {
|
||||||
|
return componentInteraction.hover;
|
||||||
|
} else if (rule === "component" && params === "focus") {
|
||||||
|
return componentInteraction.focus;
|
||||||
|
} else if (rule === "component" && params === "active") {
|
||||||
|
return componentInteraction.active;
|
||||||
} else if (rule === "media") {
|
} else if (rule === "media") {
|
||||||
return match(params, {
|
return match(params, {
|
||||||
"aspect-ratio": width / height,
|
"aspect-ratio": width / height,
|
||||||
|
|||||||
Reference in New Issue
Block a user