Skip to content
Merged
8 changes: 8 additions & 0 deletions .changeset/tailwind-existing-app-recipe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@astryxdesign/cli': patch
'@astryxdesign/core': patch
---

[docs] The Tailwind guide (`astryx docs styling-libraries/tailwind`) adds a recipe for an app that already uses Tailwind: keep the app's own `@import "tailwindcss"`, put the `@layer` line above it, and add the Astryx stylesheets after it. It explains why the `@layer` line must come before the Tailwind import: below it, the Astryx reset outranks every utility class, and nothing reports it. The Core README's Next.js + Tailwind section points to it.

@cixzhang
6 changes: 3 additions & 3 deletions packages/cli/assets/docs/styling-overview.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const docs = {
{
type: 'code',
lang: 'bash',
label: 'Install (add to an existing Tailwind v4 app)',
label: 'Install',
code: '{@pm install @astryxdesign/core @stylexjs/stylex @astryxdesign/theme-neutral}',
},
{
Expand All @@ -113,7 +113,7 @@ export const docs = {
},
{
type: 'prose',
text: 'For Tailwind v3, see the layer workaround in {@link generic:migration-setup}.',
text: 'A project with Tailwind already set up needs a smaller change, which {@link generic:tailwind} shows. For Tailwind v3, see the layer workaround in {@link generic:migration-setup}.',
},
],
},
Expand Down Expand Up @@ -162,7 +162,7 @@ export const docs = {
},
{
type: 'prose',
text: '`{@command swizzle <Component>}` writes an `astryx-swizzle.json` marker into an output folder it owns (one the copy creates, an empty one, or one it marked before); every module under that folder then compiles as Astryx source, so keep copies in a folder of their own, such as the default `components/astryx`. For a folder that already holds other files it writes no marker and says how to add one by hand. With `@astryxdesign/build`\'s Babel, PostCSS and Vite integrations, or `withAstryx()` under webpack, a copy under that folder compiles into `astryx-base`, below `astryx-theme`, so theme component overrides reach it as they reach the package component. Under Turbopack, and with the stock StyleX plugins above, a copy\'s rules land in your own styles, above `astryx-theme`, and theme component overrides do not reach it.',
text: "`{@command swizzle <Component>}` writes an `astryx-swizzle.json` marker into an output folder it owns (one the copy creates, an empty one, or one it marked before); every module under that folder then compiles as Astryx source, so keep copies in a folder of their own, such as the default `components/astryx`. For a folder that already holds other files it writes no marker and says how to add one by hand. With `@astryxdesign/build`'s Babel, PostCSS and Vite integrations, or `withAstryx()` under webpack, a copy under that folder compiles into `astryx-base`, below `astryx-theme`, so theme component overrides reach it as they reach the package component. Under Turbopack, and with the stock StyleX plugins above, a copy's rules land in your own styles, above `astryx-theme`, and theme component overrides do not reach it.",
},
],
},
Expand Down
42 changes: 41 additions & 1 deletion packages/cli/assets/docs/tree/tailwind.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export const docs = {
'tailwind-theme.css',
'utility classes',
'preflight',
'existing Tailwind app',
'cascade layer order',
],

sections: [
Expand Down Expand Up @@ -69,7 +71,45 @@ import {themes, defaultThemeSlug} from './astryx-themes';`,
},
{
type: 'prose',
text: 'The Tailwind bridge is the concrete example of the general interop pattern: expose another library\'s semantic API, but point the values at system token variables.',
text: "The Tailwind bridge is the concrete example of the general interop pattern: expose another library's semantic API, but point the values at system token variables.",
},
],
},
{
title: 'Add Astryx to an app that already uses Tailwind',
content: [
{
type: 'prose',
text: 'The recipe in the Tailwind section is a whole `globals.css` for a new app. An app that already uses Tailwind keeps its own file: its `@import "tailwindcss"`, its `@theme` mapping, and its `:root` variables stay as they are. Add one `@layer` line above the Tailwind import and the Astryx stylesheets below it.',
},
{
type: 'code',
lang: 'css',
label: 'globals.css (existing Tailwind app)',
code: `@layer reset, theme, base, astryx-base, astryx-theme, components, utilities;

@import "tailwindcss"; /* the app's own entry, unchanged */
@import "@astryxdesign/core/reset.css";
@import "@astryxdesign/core/astryx.css";
Comment thread
astracat-bot[bot] marked this conversation as resolved.
Resolved
@import "@astryxdesign/theme-neutral/theme.css";

/* The app's own @theme and :root rules stay below, unchanged. */`,
},
{
type: 'prose',
text: "This recipe leaves out `tailwind-theme.css`. The bridge maps Tailwind theme names to system tokens, including Tailwind's own defaults such as `rounded-lg` and `shadow-md`, so in an existing app it changes what the app's own classes paint. Add it only when the app does not use the names it maps.",
},
{
type: 'prose',
text: "Astryx's theme defines its own CSS custom properties (color, spacing, radius, shadow, font, motion and more). If your app defines tokens with the same names, Astryx's values win: `astryx.css` sets them on `:root` above Tailwind's `theme` layer, and the root Theme component sets them again inside it. {@link namespace:tokens} has the full list. Rename any app `@theme` key or `:root` variable that shares a name. For example, an app `:root` that sets `--font-size-base: 1rem` renders its text at Astryx's size inside the root Theme.",
Comment thread
astracat-bot[bot] marked this conversation as resolved.
Resolved
},
{
type: 'prose',
text: "Put the `@layer` line above the app's `@import \"tailwindcss\"`, never below it. A `@layer` statement orders only the layer names the page has not seen yet, and the Tailwind import names `theme`, `base`, `components`, and `utilities` as it loads. Below that import, the statement can only add `reset`, `astryx-base`, and `astryx-theme` after Tailwind's `utilities`. That inverts the cascade: the Astryx reset then outranks every utility class in the app, and, for example, removes the borders and padding the app's utilities give its controls. Nothing reports it: the build and the browser console stay clean, and the `@layer` line still looks right in the source, so only the rendered page shows the problem.",
},
{
type: 'prose',
text: 'The load-order rule from the Tailwind section still applies: `globals.css` must be the first stylesheet the page loads, so its `@layer` line names the layers first.',
},
],
},
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/test/__golden__/no-icon-set/docs-tree.json
Original file line number Diff line number Diff line change
Expand Up @@ -1197,7 +1197,8 @@
"styling-libraries/tailwind": {
"type": "docs.detail",
"sections": [
"tailwind"
"tailwind",
"add-astryx-to-an-app-that-already-uses-tailwind"
],
"mentions": []
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"type": "search",
"data": {
"query": "icon set",
"matchCount": 387,
"matchCount": 389,
"results": [
{
"domain": "doc",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Results for "icon set" (20 of 387)
Results for "icon set" (20 of 389)
name: authoring/building-blocks/templates/build-the-template/template-assets/template-icons
section: use-astryx-icon
domain: doc
Expand Down
6 changes: 4 additions & 2 deletions packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ astryx gap-report # report a missing capability

## Related Packages

| Package | Description |
| ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| Package | Description |
| ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| [`@astryxdesign/cli`](https://github.com/meta/astryx/tree/main/packages/cli) | CLI tooling: component docs, templates, scaffolding, codemods |
| [`@astryxdesign/theme-neutral`](https://github.com/meta/astryx/tree/main/packages/themes/neutral) | Muted, minimal theme (Lucide icons) |

Expand Down Expand Up @@ -139,6 +139,8 @@ export default function RootLayout({children}: {children: React.ReactNode}) {

No build plugins needed; Astryx ships pre-built CSS that works alongside Tailwind.

This `globals.css` is the whole file for a new app. For an app that already uses Tailwind, keep its own `@import "tailwindcss"` and put the `@layer` line above it, as `astryx docs styling-libraries/tailwind` shows under "Add Astryx to an app that already uses Tailwind". A `@layer` line below the Tailwind import silently inverts the cascade.

**`src/app/globals.css`**

```css
Expand Down
Loading