diff --git a/.eslintrc.js b/.eslintrc.js
index fd9ba02..2a6f399 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -21,6 +21,7 @@ module.exports = {
"error",
{
allowList: {
+ prop: true,
props: true,
Props: true,
ref: true,
diff --git a/__tests__/styled/__snapshots__/props.tsx.snap b/__tests__/styled/__snapshots__/props.tsx.snap
new file mode 100644
index 0000000..c0c3066
--- /dev/null
+++ b/__tests__/styled/__snapshots__/props.tsx.snap
@@ -0,0 +1,30 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Styled - Custom Props can style custom props 1`] = `
+Array [
+
= PropsWithChildren< P & { @@ -25,68 +22,66 @@ type StyledProps
= PropsWithChildren< type Component
= string | FunctionComponent
| ComponentClass
; +export interface StyledOptions
{
+ props?: boolean | Array (
- Component: Component
-): FunctionComponent ,
+ options?: { props: false }
+): FunctionComponent (
+ Component: Component ,
+ options: { props: Array (
+ Component: Component ,
+ options: { props: true }
+): FunctionComponent (
+ Component: Component ,
+ { props: propsToTransform }: StyledOptions = {}
+) {
function Styled({
className,
tw,
- style: styleProperty,
+ style: componentStyles,
children: componentChildren,
- ...props
+ ...componentProps
}: StyledProps ) {
- const { hover, focus, active, ...handlers } = useInteraction(props);
+ const { hover, focus, active, ...handlers } =
+ useInteraction(componentProps);
const classes = tw ?? className ?? "";
- const tailwindStyles = useTailwind({
+ const twCallback = useTailwind({
hover,
focus,
active,
flatten: false,
- })(classes);
+ });
- const style = styleProperty
- ? [tailwindStyles, styleProperty]
- : tailwindStyles;
+ const { childStyles, ...styledProps } = useStyledProps({
+ tw: twCallback,
+ classes,
+ componentStyles,
+ propsToTransform,
+ componentProps,
+ });
- let children = isFragment(componentChildren)
- ? // This probably needs to be recursive
- componentChildren.props.children
- : componentChildren;
-
- if (tailwindStyles[ChildClassNameSymbol]) {
- children = Children.map(children, (child, index) => {
- const childStyles: P[] = [];
- for (const { atRules, ...styles } of tailwindStyles[
- ChildClassNameSymbol
- ] ?? []) {
- const matches = atRules.every(([rule, params]) => {
- return matchChildAtRule({
- nthChild: index + 1,
- rule,
- params,
- });
- });
- if (matches) {
- childStyles.push(styles as P);
- }
- }
-
- return cloneElement(child, {
- style: child.props.style
- ? [child.props.style, childStyles]
- : childStyles.length > 0
- ? childStyles
- : undefined,
- });
- });
- }
+ const children = useStyledChildren({
+ componentChildren,
+ childStyles,
+ });
const element = createElement(Component, {
- ...props,
+ ...componentProps,
...handlers,
- style,
+ ...styledProps,
children,
} as unknown as P);
diff --git a/src/use-styled-children.ts b/src/use-styled-children.ts
new file mode 100644
index 0000000..d8883c7
--- /dev/null
+++ b/src/use-styled-children.ts
@@ -0,0 +1,47 @@
+import { ReactNode, Children, cloneElement } from "react";
+import { isFragment } from "react-is";
+import { matchChildAtRule } from "./match-at-rule";
+import { AtRuleRecord } from "./types/common";
+
+export interface UseStyledChildrenOptions {
+ componentChildren: ReactNode;
+ childStyles?: AtRuleRecord[];
+}
+
+export function useStyledChildren({
+ componentChildren,
+ childStyles,
+}: UseStyledChildrenOptions): ReactNode {
+ let children = isFragment(componentChildren)
+ ? // This probably needs to be recursive
+ componentChildren.props.children
+ : componentChildren;
+
+ if (childStyles) {
+ children = Children.map(children, (child, index) => {
+ const matchingStyles = [];
+ for (const { atRules, ...styles } of childStyles) {
+ const matches = atRules.every(([rule, params]) => {
+ return matchChildAtRule({
+ nthChild: index + 1,
+ rule,
+ params,
+ });
+ });
+ if (matches) {
+ matchingStyles.push(styles);
+ }
+ }
+
+ return cloneElement(child, {
+ style: child.props.style
+ ? [child.props.style, matchingStyles]
+ : matchingStyles.length > 0
+ ? matchingStyles
+ : undefined,
+ });
+ });
+ }
+
+ return children;
+}
diff --git a/src/use-styled-props.ts b/src/use-styled-props.ts
new file mode 100644
index 0000000..3ba5c71
--- /dev/null
+++ b/src/use-styled-props.ts
@@ -0,0 +1,47 @@
+import { StyleProp } from "react-native";
+import { UseTailwindCallback } from "./use-tailwind";
+import { ChildClassNameSymbol } from "./utils/child-styles";
+
+export interface UseStyledPropsOptions {
+ tw: UseTailwindCallback