Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Tailwind utility and component classes #675

Merged
merged 19 commits into from
Oct 22, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions packages/components/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,33 @@ declare var x: AbstractComponent<Props, HTMLElement>;
```

- Preserve exact-typed objects when possible. If you must make them inexact, add an explicit `...` at the end of the object.

## Tailwind Utility Classes
Tailwind utility classes can be used with either `@apply` in CSS files such as
```css
div {
@apply rounded border-2;
/* border-radius: 0.25 rem;
border-width: 2px; */
}
```
or used directly as class names such as
```jsx
<div className="rounded border-2">
```
Use the [docs](https://tailwindcss.com/docs) to search for appropriate classes.

**Conflicts may arise rarely with Bootstrap classes, some that we know of:**
jinlee93 marked this conversation as resolved.
Show resolved Hide resolved
- Most annoying, `.hidden`
- Both Tailwind and Bootstrap have the same styling for `.hidden` but Bootstrap applies the `!important ` property, which can be annoying when trying to utilize Tailwind breakpoints, e.g.:
```html
<div class="hidden md:block lg:inline">
```
- Where the expectation is `display: none ` for breakpoints smaller than 768px, `display: block `for 768px - 1023px, and `display: inline ` for >= 1024px. However since Bootstrap applies the `!important` property, all screen sizes show `display: none`.
- This can be circumvented with the `@apply` directive with `!important`, such as `@apply hidden md:block lg:inline !important` or using custom CSS with regular media queries.
- `.invisible` and `.text-` alignment
- These classes have the same styling in both Tailwind and Bootstrap, and therefore can be used without issues. Tailwind responsive states (such as breakpoints, hover, etc.) will have higher specificity so no issues will be caused there.
- Other unfound conflicts
- Without Bootstrap using `!important`, should styling will likely be the same, so can likely be used without issues. If issues do arise even without `!important`, the options are similar as above, use `@apply` to scope styling into higher specificity, or use custom styling
- If the conflict is due to Bootstrap using `!important`, follow similar strategy above as `.hidden`
- Bootstrap [styling](https://github.com/twbs/bootstrap-sass/tree/master/assets/stylesheets/bootstrap) and mentioned conflicts in [_utilities.scss](https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/bootstrap/_utilities.scss#L46) and [_type.scss](https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/bootstrap/_type.scss#L90) for reference
16 changes: 16 additions & 0 deletions packages/components/src/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,20 @@
--tw-ring-shadow: 0 0 #0000;
}

/**
* This injects Tailwind's base styles and any base styles registered by
* plugins.
*/
@tailwind base;

/**
* This injects Tailwind's component classes and any component classes
* registered by plugins.
*/
@tailwind components;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My read of https://tailwindcss.com/docs/extracting-components#extracting-component-classes-with-apply is that this is where the @apply-ed stuff goes.

But I thought we were already getting those in the compiled css? 🤔

Is it possible we're now duplicating anything from @apply?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Jin noted that the components.css class contains really few things: https://unpkg.com/[email protected]/dist/components.css. My read of that section was that you can use @layer to control specificity, but it doesn't overlap with the content of @tailwind components

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And if the component classes are not being used, they should be purged out

Copy link
Contributor

@ahuth ahuth Oct 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah you're right. Looks like @apply stuff gets inlined right into the .module.css file, not put in components.


/**
* This injects Tailwind's utility classes and any utility classes registered
* by plugins.
*/
@tailwind utilities;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hadn't thought of this until now, but another option is to allow utility classes in stories, but only use @apply in component styles. (And definitely allow utility classes in apps)

Then there's no chance for conflicts and no unfortunate increase in size.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or put another way:

I think the value in utility classes is in storybook stories and in an app. So we don't necessarily need to actually use them in the design system components if we don't want to.

(If we do want to then that's fine too)

Copy link
Contributor

@anniehu4 anniehu4 Oct 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense to me! It's essentially what we're doing already (since global.css is only used in the storybook file), but we could be more explicit by only purge-ing story files. I'm less worried about the size since according to Tailwind,

When removing unused styles with Tailwind, it’s very hard to end up with more than 10kb of compressed CSS

there is an argument that it's easier to just follow the standard convention though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separated components and utilities as suggested into tailwindUtilities.css which is imported into .storybook/preview.tsx for storybook use in eds
Let me know if that's not proper naming conventions

Copy link
Contributor

@ahuth ahuth Oct 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to put the @tailwind stuff in another file. Something like src/styles/tailwind.css.

That way an App already using Tailwind (like Traject is/will?) can use it's own Tailwind stuff instead of importing 2 of them (one from here and one from the app), by only importing src/styles/tailwind.css if it's not already doing so.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can certainly rename this file. It currently only contains tailwind stuff, and it's actually not even imported in traject because there were issues with including all of the base styles (traject defines its own tailwind.base.css instead)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, okay. I assumed there was other stuff going on in it, but it makes sense that there's not.

Naming it tailwind.css sometime might make it more clear when to (and not to) include it in an app.