mirror of
https://github.com/zhigang1992/nativewind.git
synced 2026-06-13 01:18:18 +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",
|
||||
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 { isFragment } from "react-is";
|
||||
import { useInteraction } from "./use-interaction";
|
||||
import { ComponentContext } from "./context";
|
||||
|
||||
type StyledProps<P> = PropsWithChildren<
|
||||
P & {
|
||||
@@ -38,13 +39,15 @@ export function styled<P>(
|
||||
}: StyledProps<P>) {
|
||||
const { hover, focus, active, ...handlers } = useInteraction(props);
|
||||
|
||||
const classes = tw ?? className ?? "";
|
||||
|
||||
const tailwindStyles = useTailwind({
|
||||
nthChild,
|
||||
hover,
|
||||
focus,
|
||||
active,
|
||||
[ChildClassNameSymbol]: inheritedClassName,
|
||||
})(tw ?? className);
|
||||
})(classes);
|
||||
|
||||
const style = styleProperty
|
||||
? [tailwindStyles, styleProperty]
|
||||
@@ -64,12 +67,22 @@ export function styled<P>(
|
||||
});
|
||||
}
|
||||
|
||||
return createElement(Component, {
|
||||
const element = createElement(Component, {
|
||||
...props,
|
||||
...handlers,
|
||||
style,
|
||||
children,
|
||||
} 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") {
|
||||
|
||||
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";
|
||||
import { StyleError } from "../../types/common";
|
||||
import { boxShadow } from "./box-shadow";
|
||||
import { component } from "./component";
|
||||
import { divide } from "./divide";
|
||||
import { elevation } from "./elevation";
|
||||
import { fontSize } from "./font-size";
|
||||
@@ -48,6 +49,7 @@ export const nativePlugin = plugin.withOptions<NativePluginOptions | undefined>(
|
||||
skew(helpers, notSupported);
|
||||
boxShadow(helpers, notSupported);
|
||||
pseudoClasses(helpers, notSupported);
|
||||
component(helpers, notSupported);
|
||||
};
|
||||
},
|
||||
function ({ rem = 16 } = {}) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { match } from "css-mediaquery";
|
||||
import { normaliseSelector } from "./shared/selector";
|
||||
import { TailwindContext } from "./context";
|
||||
import { ComponentContext, TailwindContext } from "./context";
|
||||
import {
|
||||
RWNCssStyle,
|
||||
UseTailwindCallback,
|
||||
@@ -48,6 +48,8 @@ export function useTailwind<P>({
|
||||
const { platform, styles, media, width, height, orientation, colorScheme } =
|
||||
useContext(TailwindContext);
|
||||
|
||||
const componentInteraction = useContext(ComponentContext);
|
||||
|
||||
// useState ensure this 'resets' every render
|
||||
let [nthChild] = useState(initialNthChild);
|
||||
|
||||
@@ -99,6 +101,12 @@ export function useTailwind<P>({
|
||||
return focus;
|
||||
} else if (rule === "pseudo-class" && params === "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") {
|
||||
return match(params, {
|
||||
"aspect-ratio": width / height,
|
||||
|
||||
Reference in New Issue
Block a user