Negative spacing values
tamlyn opened this issue · comments
Is there a way to specify negative spacing values?
Assuming I have my theme spacing set up with t-shirt sizes, I'd love to be able to do something like
<Box marginVertical="m" marginHorizontal="-m"> ... </Box>
If it's not currently possible, is it something you would be open to PRs for?
You could add negative spacing values manually like so
const spacing = {
"-m": -8,
"-sm": -4,
sm: 4,
m: 8
}
but it's not ideal for a few reasons (you will probably enable padding to be negative, unwanted mirroring/duplication of tokens, semantics, etc).
As for me, I added style prop bleed
that flips the sign of my space token and applies it to margin.
import {
createBox,
createRestyleComponent,
createRestyleFunction,
boxRestyleFunctions,
ResponsiveValue,
} from "@shopify/restyle";
import { Theme } from "../../theme.config";
type BleedTransform = { value: keyof Theme["spacing"]; theme: Theme };
const SHORTHANDS = ["", "Horizontal", "Vertical"] as const;
const bleedRestyleFunctions = SHORTHANDS.map((shorthand) =>
createRestyleFunction({
property: ("bleed" + shorthand) as `bleed${typeof shorthand}`,
styleProperty: ("margin" + shorthand) as `margin${typeof shorthand}`,
transform: ({ value, theme }: BleedTransform) => -theme.spacing[value],
})
);
type BleedProps = {
[key in typeof bleedRestyleFunctions[number]["property"]]?: ResponsiveValue<
BleedTransform["value"],
Theme
>;
};
const BaseBox = createBox<Theme>();
const restyleFns = [
// Default
...boxRestyleFunctions,
// Extensions
...bleedRestyleFunctions,
];
export interface BoxProps
extends React.ComponentProps<typeof BaseBox>,
BleedProps {}
export const Box = createRestyleComponent<BoxProps, Theme>(restyleFns, BaseBox);
Edit: While it's probably the correct way of dealing with negative margin, I realise it doesn't provide an answer to your exact question.
If you want the syntax marginHorizontal="-m"
you can probably achieve it by overriding like so
type MarginTransform = {
value: keyof Theme["spacing"] | `-${keyof Theme["spacing"]}`;
theme: Theme;
};
const marginRestyleFn = createRestyleFunction({
property: "margin",
transform: ({ value, theme }: MarginTransform) => {
if (value[0] === "-") {
return -theme.spacing[value as keyof Theme["spacing"]];
}
return theme.spacing[value as keyof Theme["spacing"]];
},
});