feat: allow hairlineWidth as a theme value

This commit is contained in:
Mark Lawlor
2022-05-17 11:34:43 +10:00
parent 16be49da0f
commit 5cf20d00e2
9 changed files with 134 additions and 16 deletions

View File

@@ -1,5 +1,34 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Border - Divide Width divide-x 1`] = `
<View
onBlur={[Function]}
onFocus={[Function]}
onHoverIn={[Function]}
onHoverOut={[Function]}
onPress={[Function]}
onPressIn={[Function]}
onPressOut={[Function]}
style={Array []}
>
<Text>
A
</Text>
<Text
style={
Array [
Object {
"borderLeftWidth": 1,
"borderRightWidth": 0,
},
]
}
>
B
</Text>
</View>
`;
exports[`Border - Divide Width divide-x-0 1`] = `
<View
onBlur={[Function]}

View File

@@ -1,3 +1,4 @@
import { Style } from "css-to-react-native";
import { ViewStyle } from "react-native";
import { createTests, tailwindRunner } from "./runner";
@@ -16,20 +17,52 @@ tailwindRunner(
{
border: [
{
borderBottomWidth: 1,
borderTopWidth: 1,
borderLeftWidth: 1,
borderRightWidth: 1,
},
borderBottomWidth: "hairlineWidth",
borderTopWidth: "hairlineWidth",
borderLeftWidth: "hairlineWidth",
borderRightWidth: "hairlineWidth",
} as Style,
],
},
],
["border-x", { "border-x": [{ borderLeftWidth: 1, borderRightWidth: 1 }] }],
["border-y", { "border-y": [{ borderTopWidth: 1, borderBottomWidth: 1 }] }],
["border-t", { "border-t": [{ borderTopWidth: 1 }] }],
["border-b", { "border-b": [{ borderBottomWidth: 1 }] }],
["border-l", { "border-l": [{ borderLeftWidth: 1 }] }],
["border-r", { "border-r": [{ borderRightWidth: 1 }] }],
[
"border-x",
{
"border-x": [
{
borderLeftWidth: "hairlineWidth",
borderRightWidth: "hairlineWidth",
} as Style,
],
},
],
[
"border-y",
{
"border-y": [
{
borderTopWidth: "hairlineWidth",
borderBottomWidth: "hairlineWidth",
} as Style,
],
},
],
[
"border-t",
{ "border-t": [{ borderTopWidth: "hairlineWidth" } as Style] },
],
[
"border-b",
{ "border-b": [{ borderBottomWidth: "hairlineWidth" } as Style] },
],
[
"border-l",
{ "border-l": [{ borderLeftWidth: "hairlineWidth" } as Style] },
],
[
"border-r",
{ "border-r": [{ borderRightWidth: "hairlineWidth" } as Style] },
],
],
createTests("border", scenarios, (n) => ({
borderBottomWidth: n,
@@ -57,7 +90,4 @@ tailwindRunner(
createTests("border-r", scenarios, (n) => ({
borderRightWidth: n,
}))
// ...createTests("border-bl", scenarios, (n) => ({
// borderBottomWidth: n,
// })),
);

View File

@@ -6,6 +6,32 @@ import { StyledComponent } from "../../src";
const cases: Array<ViewStyle["borderWidth"][]> = [[0], [2], [4], [8]];
describe("Border - Divide Width", () => {
test("divide-x", () => {
const tree = render(
<TestProvider css={`divide-x`}>
<StyledComponent component={View} className="divide-x">
<Text>A</Text>
<Text>B</Text>
</StyledComponent>
</TestProvider>
).toJSON();
expect(tree).toMatchSnapshot();
});
test("divide-y", () => {
const tree = render(
<TestProvider css={`divide-y`}>
<StyledComponent component={View} className="divide-y">
<Text>A</Text>
<Text>B</Text>
</StyledComponent>
</TestProvider>
).toJSON();
expect(tree).toMatchSnapshot();
});
test.each(cases)("divide-x-%s", (unit) => {
const tree = render(
<TestProvider css={`divide-x-${unit}`}>

View File

@@ -53,6 +53,8 @@ export function TestProvider({
css,
...props
}: PropsWithChildren<TailwindProviderProps & { css: string }>) {
globalThis.hairlineWidthValue = 1;
const { styles } = extractStyles({
theme: {},
plugins: [plugin, nativePlugin()],

View File

@@ -60,6 +60,13 @@ function serialize(literal: unknown): Expression {
case "number":
return numericLiteral(literal);
case "string":
if (literal === "hairlineWidth") {
return memberExpression(
identifier("StyleSheet"),
identifier("hairlineWidth")
);
}
return stringLiteral(literal);
case "boolean":
return booleanLiteral(literal);

View File

@@ -89,9 +89,13 @@ export const plugin: PluginCreator<PostcssPluginOptions> = ({
writeFileSync(
output,
`// This file was generated by tailwindcss-react-native. Do not edit!
const { StyleSheet } = require("react-native")
module.exports = {
platform: '${platform}',
styles: ${JSON.stringify(serialised.styles)},
styles: ${JSON.stringify(serialised.styles).replace(
new RegExp('"hairlineWidth"', "g"),
"StyleSheet.hairlineWidth"
)},
media: ${JSON.stringify(serialised.media)},
}`
);

View File

@@ -1,6 +1,11 @@
import { getStylesForProperty, Style } from "css-to-react-native";
import { ImageStyle, TextStyle, ViewStyle } from "react-native";
declare global {
// eslint-disable-next-line no-var
var hairlineWidthValue: number | undefined;
}
export type PropertyGuard<T extends string> = (
value: string,
name: string
@@ -52,6 +57,15 @@ export function only<
const isNaN = Number.isNaN(Number.parseInt(value));
if (number) {
if (value === "hairlineWidth") {
return JSON.parse(
JSON.stringify(getStylesForProperty(name, "1px")).replace(
new RegExp("1", "g"),
globalThis.hairlineWidthValue?.toString() ?? '"hairlineWidth"'
)
);
}
if (isNaN) {
throw new Error(name);
}

View File

@@ -11,7 +11,6 @@ export const divide: CustomPluginFunction = ({
{
"divide-x": (value: string) => {
value = value === "0" ? "0px" : value;
return {
"&": {
"@selector (> *:not(:first-child))": {

View File

@@ -70,6 +70,13 @@ export const nativePlugin = plugin.withOptions<NativePluginOptions | undefined>(
wider: "0.5px",
widest: "1px",
},
borderWidth: {
DEFAULT: "hairlineWidth",
0: "0px",
2: "2px",
4: "4px",
8: "8px",
},
spacing: {
px: "1px",
0: "0px",