π¦ΉββοΈ Twin blends the magic of Tailwind with the flexibility of css-in-js (emotion, styled-components, solid-styled-components, stitches and goober) at build time.
MIT License
Bot releases are hidden (Show)
Published by ben-rogerson over 3 years ago
This release adds a new globalStyles
import which contains the preflight/reset styles.
Here's how it can be used with styled-components, instead of the existing GlobalStyles
import:
import { createGlobalStyle } from 'styled-components'
import tw, { theme, globalStyles } from 'twin.macro'
const globals = {
body: {
WebkitTapHighlightColor: theme`colors.purple.500`,
...tw`antialiased`,
},
}
const GlobalStyles = createGlobalStyle(globalStyles, globals) // Use two arguments so a deep merge happens
export default GlobalStyles
GlobalStyles
import is only for use in jsx, so twin requires the new import for css-in-js solutions like with stitches
and @emotion/css
where the global import needs to be called outside of jsx.The stitches integration now has much better support for twin features!
Once you add the preset ({ preset: "stitches" }
), twin will add features like the tw prop, the css prop (without a styled definition required), and global + plugin styles now work like normal.
This integration took quite a lot of work to achieve, but twin is now in a better position for more integrations in the future π―
Check out the PR for more information β
twitches
π€£animation-timing-function
If youβre kicking ass with twin - especially if youβre in a team - then please consider becoming a sponsor.
It will really help out with the continued development of twin - cheers! π»
Published by ben-rogerson over 3 years ago
Twin now supports the same arbitrary values syntax popularized by Tailwindβs jit ("Just-in-Time") mode.
tw`top-[calc(100vh - 2rem)]`
// β β β β β β
;({ top: 'calc(100vh - 2rem)' })
This is a great way to add once-off values that donβt need to be in your tailwind config.
Read more about arbitrary values β
Also from Tailwind JIT, is the bang !
prefix to add important styles:
tw`!block`;
// β β β β β β
;({ "display": "block !important" })
Twin will continue to support a bang at the end of the class too - so you've got a couple of options.
The screen import creates media queries for custom css that sync with your tailwind config screen values (sm, md, lg, etc).
Usage with the css prop
import tw, { screen, css } from 'twin.macro'
const styles = [
screen`sm`({ display: 'block', ...tw`inline` }),
]
<div css={styles} />
Usage with styled components
import tw, { styled, screen, css } from 'twin.macro'
const Component = styled.div(() => [
screen`sm`({ display: 'block', ...tw`inline` }),
])
<Component />
Read more about the screen import β
[divide/space]-[x-/y-]reverse
(#359)Published by ben-rogerson over 3 years ago
@tailwindcss/forms
#440Published by ben-rogerson over 3 years ago
This release adds all the new classes from Tailwindcss v2.1.0 π
tw`backdrop-invert-0`;
tw`backdrop-invert`;
tw`backdrop-opacity-0`;
tw`backdrop-opacity-5`;
tw`backdrop-opacity-10`;
tw`backdrop-opacity-20`;
tw`backdrop-opacity-25`;
tw`backdrop-opacity-30`;
tw`backdrop-opacity-40`;
tw`backdrop-opacity-50`;
tw`backdrop-opacity-60`;
tw`backdrop-opacity-70`;
tw`backdrop-opacity-75`;
tw`backdrop-opacity-80`;
tw`backdrop-opacity-90`;
tw`backdrop-opacity-95`;
tw`backdrop-opacity-100`;
tw`backdrop-saturate-0`;
tw`backdrop-saturate-50`;
tw`backdrop-saturate-100`;
tw`backdrop-saturate-150`;
tw`backdrop-saturate-200`;
tw`backdrop-sepia-0`;
tw`backdrop-sepia`;
tw`backdrop-grayscale-0`;
tw`backdrop-grayscale`;
tw`-backdrop-hue-rotate-180`;
tw`-backdrop-hue-rotate-90`;
tw`-backdrop-hue-rotate-60`;
tw`-backdrop-hue-rotate-30`;
tw`-backdrop-hue-rotate-15`;
tw`backdrop-hue-rotate-0`;
tw`backdrop-hue-rotate-15`;
tw`backdrop-hue-rotate-30`;
tw`backdrop-hue-rotate-60`;
tw`backdrop-hue-rotate-90`;
tw`backdrop-hue-rotate-180`;
tw`backdrop-contrast-0`;
tw`backdrop-contrast-50`;
tw`backdrop-contrast-75`;
tw`backdrop-contrast-100`;
tw`backdrop-contrast-125`;
tw`backdrop-contrast-150`;
tw`backdrop-contrast-200`;
tw`backdrop-brightness-0`;
tw`backdrop-brightness-50`;
tw`backdrop-brightness-75`;
tw`backdrop-brightness-90`;
tw`backdrop-brightness-95`;
tw`backdrop-brightness-100`;
tw`backdrop-brightness-105`;
tw`backdrop-brightness-110`;
tw`backdrop-brightness-125`;
tw`backdrop-brightness-150`;
tw`backdrop-brightness-200`;
tw`backdrop-blur-0`;
tw`backdrop-blur-sm`;
tw`backdrop-blur`;
tw`backdrop-blur-md`;
tw`backdrop-blur-lg`;
tw`backdrop-blur-xl`;
tw`backdrop-blur-2xl`;
tw`backdrop-blur-3xl`;
tw`saturate-0`;
tw`saturate-50`;
tw`saturate-100`;
tw`saturate-150`;
tw`saturate-200`;
tw`invert-0`;
tw`invert`;
tw`-hue-rotate-180`;
tw`-hue-rotate-90`;
tw`-hue-rotate-60`;
tw`-hue-rotate-30`;
tw`-hue-rotate-15`;
tw`hue-rotate-0`;
tw`hue-rotate-15`;
tw`hue-rotate-30`;
tw`hue-rotate-60`;
tw`hue-rotate-90`;
tw`hue-rotate-180`;
tw`grayscale-0`;
tw`grayscale`;
tw`drop-shadow-sm`;
tw`drop-shadow`;
tw`drop-shadow-md`;
tw`drop-shadow-lg`;
tw`drop-shadow-xl`;
tw`drop-shadow-2xl`;
tw`drop-shadow-none`;
tw`contrast-0`;
tw`contrast-50`;
tw`contrast-75`;
tw`contrast-100`;
tw`contrast-125`;
tw`contrast-150`;
tw`contrast-200`;
tw`brightness-0`;
tw`brightness-50`;
tw`brightness-75`;
tw`brightness-90`;
tw`brightness-95`;
tw`brightness-100`;
tw`brightness-105`;
tw`brightness-110`;
tw`brightness-125`;
tw`brightness-150`;
tw`brightness-200`;
tw`blur-0`;
tw`blur-sm`;
tw`blur`;
tw`blur-md`;
tw`blur-lg`;
tw`blur-xl`;
tw`blur-2xl`;
tw`blur-3xl`;
tw`mix-blend-normal`;
tw`mix-blend-multiply`;
tw`mix-blend-screen`;
tw`mix-blend-overlay`;
tw`mix-blend-darken`;
tw`mix-blend-lighten`;
tw`mix-blend-color-dodge`;
tw`mix-blend-color-burn`;
tw`mix-blend-hard-light`;
tw`mix-blend-soft-light`;
tw`mix-blend-difference`;
tw`mix-blend-exclusion`;
tw`mix-blend-hue`;
tw`mix-blend-saturation`;
tw`mix-blend-color`;
tw`mix-blend-luminosity`;
tw`bg-blend-normal`;
tw`bg-blend-multiply`;
tw`bg-blend-screen`;
tw`bg-blend-overlay`;
tw`bg-blend-darken`;
tw`bg-blend-lighten`;
tw`bg-blend-color-dodge`;
tw`bg-blend-color-burn`;
tw`bg-blend-hard-light`;
tw`bg-blend-soft-light`;
tw`bg-blend-difference`;
tw`bg-blend-exclusion`;
tw`bg-blend-hue`;
tw`bg-blend-saturation`;
tw`bg-blend-color`;
tw`bg-blend-luminosity`;
tw`isolate`;
tw`isolation-auto`;
tw`decoration-slice`;
tw`decoration-clone`;
tw`inline-table`;
tw`list-item`;
ringOffsetWidth.DEFAULT
and ringOffsetColor.DEFAULT
are now added in the reset styles #405
These tailwindcss JIT features will be rolled out in coming releases:
There is no current support for custom tailwind class values - but it will be added to twin:
<button tw="bg-[#1da1f1]" /> // support coming soon
For now, use twin's short css feature that allows any css properties to be added:
<div tw="background-color[#1da1f1]" />
Twin already supports a!
added at the end of the class.
I'm going to add support for the same syntax tailwind uses (!
at the front):
<div tw="font-bold !font-medium" /> // support coming soon
"disableShortCss": true
#409opacityValue
to color functions to better support colors added with css variables #403That's all for now, cheers!
bg-clip-x
values #375ring-opacity-x
to end of class lists to avoid ordering issues #374Published by ben-rogerson over 3 years ago
col-span-x
to operate with other grid classes #364transform
to play nicer with other transformation classes aebf6da061ec49d55628c19c203fabd57d2d0d06transition
to play nicer with other transition classes aebf6da061ec49d55628c19c203fabd57d2d0d06grid-flow-col-dense
#365Published by ben-rogerson over 3 years ago
babel-plugin-twin gives you the tw
and css
prop without having to import 'twin.macro'
in your files!
Take a look at babel-plugin-twin β
You can now use comments to disable classes:
// Disable classes with a single-line comment
<div tw="block // flex relative" />; // flex + relative will be ignored
// For more control, use a multi-line comment
<div tw="/* block flex */ relative" />; // block + flex will be ignored
β‘ @lightyen has already added support for comments in the twin intellisense vscode plugin
// Style input/textarea placeholders
tw`placeholder:text-black`;
// Target screen + print
tw`screen:flex`;
tw`print:flex`;
// Target screen orientation
tw`landscape:flex`;
tw`portrait:flex`;
// Pointer and hover targeting selectors
// https://developer.mozilla.org/en-US/docs/Web/CSS/@media/any-pointer
tw`any-pointer-none:flex`;
tw`any-pointer-fine:flex`;
tw`any-pointer-coarse:flex`;
// https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer
tw`pointer-none:flex`;
tw`pointer-fine:flex`;
tw`pointer-coarse:flex`;
// https://developer.mozilla.org/en-US/docs/Web/CSS/@media/any-hover
tw`any-hover-none:flex`;
tw`any-hover:flex`;
// https://developer.mozilla.org/en-US/docs/Web/CSS/@media/hover
tw`can-hover:flex`;
tw`cant-hover:flex`;
In custom tailwind plugins you can now use everyones favourite parent selector - the "&".
This selector allows you to add styles if there is a class/attribute on a parent.
This example creates a gap-x-1
class that applies a callback when a class it added higher up the tree:
// tailwind.config.js
const plugin = require("tailwindcss/plugin");
const gapFallback = plugin(({ addUtilities }) =>
addUtilities({
'.gap-x-1': {
rowGap: '1em',
".no-flex-gap &": {
marginTop: '-0.5em',
marginBottom: '-0.5em',
},
".no-flex-gap & > *": {
marginTop: '0.5em',
marginBottom: '0.5em',
},
},
})
);
module.exports = { plugins: [gapFallback] };
// App.js
<body className="no-flex-gap">
<div tw="gap-x-1">
Element using modern rowGap with a fallback for older browsers
</div>
</body>
The above example is just a demonstration, ideally we should loop through the existing gap values instead - check out the pr for a production example.
Twin now supports the prefix feature from tailwindcss.
This feature lets you specify a prefix for all the tailwind classes to avoid clashing with other styling systems.
Add the prefix to your tailwind config like this:
// tailwind.config.js
module.exports = {
prefix: "twin-"
};
Then use anywhere you can write tailwind classes:
// App.js
<div tw="twin-block" />
<div css={tw`twin-block`} />
<div className="twin-block" /> // with `includeClassNames: true` in your twin config
styled.div(tw`twin-block`)
tw.div`twin-block`
Your longer short css values can be specified on multiple lines:
tw`
box-shadow[
5px 5px blue,
10px 10px red,
15px 15px green;
]
`
You can now tell twin to keep the data-tw
prop in production:
// twin config
"twin": {
"dataTwProp": "all"
}
ReferenceError: tw is not defined
error (#339 ffc06dc4f13980900a606ff032572699cbccea1c)Did you know twin is just over a year old and this is the 48th release? π±
It's been an utter ride this past year and I'm feeling incredibly grateful for all your positive feedback.
If youβre kicking ass with twin - especially if youβre in a team - then please consider becoming a sponsor. It would really help out - cheers! π»
Published by ben-rogerson over 3 years ago
flex-gap-y-1.5
π₯ You can now use gap classes with full browser support with the gap polyfill plugin β
Published by ben-rogerson over 3 years ago
This patch adds greater support and bugfixes for the css syntax:
There's no more need for camel-casing the property name, you can now use dash-case which is much nicer:
tw`max-width[100vw]`
CSS variables can now be set:
tw`--my-var[100px]`
And used:
tw`max-width[var(--my-var)]`
Values with square brackets can now be set:
tw`grid[[stack] 1fr / min-content [stack] 1fr]`
Browser vendor prefixes now work:
tw`-webkit-line-clamp[3]`
Published by ben-rogerson over 3 years ago
This PR brings a new feature which allows you to add custom css right next to your other classes.
It avoids the need to switch to the css prop (or styled.div``) in every occasion - which historically has been mildly annoying, especially when you only need to add a single css property.
The short css syntax is: theCssProperty[the css value]
(Camel-case the property for now but use dash-case in the next patch)
Usage:
<div tw="maxWidth[calc(100vw - 2em)]" />
const Component = tw.div`maxWidth[calc(100vw - 2em)]`
tw`maxWidth[calc(100vw - 2em)]`
You can also use this short css syntax with variants, both by themselves or within variant groups:
tw`md:maxWidth[calc(100vw - 2em)]`
tw`md:(h-10 mt-3 maxWidth[calc(100vw - 2em)])`
I've also added a new cs
prop if you would like to keep this new syntax separate from your tw classes:
<div cs="md:maxWidth[calc(100vw - 2em)]" />
Just like the data-tw prop, you'll see a data-cs
prop in development for traceability.
Examples:
// Setting a content property in a pseudo element
tw`before:(content['hey there'] block)`
// Using a css variable
tw`width[--my-width-variable]`
// Setting grid areas
tw`gridArea[1 / 1 / 4 / 2]`
// Setting grid template areas
tw`gridTemplateAreas['"z z z" "a b c" "d e f"']`
// Setting a vendor prefix like line clamping
tw`webkitLineClamp[3]`
This feature should help trim down some of your styling markup and I really hope you enjoy using it!
Published by ben-rogerson over 3 years ago
import { createGlobalStyles } from 'goober/global'
#302 - Thanks @gerhardslettenPublished by ben-rogerson over 3 years ago
Now rounded brackets can be used as a tool to add groups of common classes:
<div tw="(text-white bg-black) (mt-3 w-10)" />
Adding a bang ! afterwards will !important
all the items in the group:
<div tw="(text-white bg-black)!" />
You can also get crazy with nesting if you need to:
<div tw="md:(bg-red-500 hover:((bg-black text-white) (mt-3 w-10)))" />
Cheers to @lightyen for adding this feature π
Check PR#281 for more info β
Just like tailwind presets, twin can now use other tailwind.config(s) as a default. This is great for packaging up a base tailwind.config.js and installing it into various projects.
// tailwind.config.js
module.exports = {
presets: [
require("my-sweet-default-tailwind-config")
],
// ...
};
Check tailwind preset docs for more info β
After activating this feature, youβll be able to add tailwind classes within the className prop. It works very similarly to the tw prop but doesnβt show suggestions and instead skips over unmatched classes.
<div className="block mt-5 another-class" />
// β β β β β β
<div className="another-class" css={{
"display": "block",
"marginTop": "1.25rem"
}} />
Add includeClassNames: true
in your twin config to activate this feature.
Cheers to @mxstbr for the feature idea π
Published by ben-rogerson almost 4 years ago
sm:(block hover:(bg-black text-white))
^ Note for styled-components users: Check that the base styles aren't overriding your component styles after the upgrade. Read this issue for more information.
Published by ben-rogerson almost 4 years ago
Published by ben-rogerson almost 4 years ago
addBase
in plugins - this now gives twin @tailwindcss/forms support π--tw-shadow
base style implementation a35fc29
group
@types/react@17
to match react@17
#246Published by ben-rogerson almost 4 years ago
Published by ben-rogerson almost 4 years ago