diff --git a/docs/generated/packages/next/generators/component.json b/docs/generated/packages/next/generators/component.json
index f21be28991641..c708ed95b612b 100644
--- a/docs/generated/packages/next/generators/component.json
+++ b/docs/generated/packages/next/generators/component.json
@@ -38,6 +38,10 @@
"value": "less",
"label": "LESS [ https://lesscss.org ]"
},
+ {
+ "value": "tailwind",
+ "label": "tailwind [ https://tailwindcss.com/ ]"
+ },
{
"value": "styled-components",
"label": "styled-components [ https://styled-components.com ]"
diff --git a/docs/generated/packages/next/generators/library.json b/docs/generated/packages/next/generators/library.json
index d101fa4219834..5b3cc7a3aa220 100644
--- a/docs/generated/packages/next/generators/library.json
+++ b/docs/generated/packages/next/generators/library.json
@@ -40,6 +40,10 @@
"value": "less",
"label": "LESS [ https://lesscss.org ]"
},
+ {
+ "value": "tailwind",
+ "label": "tailwind [ https://tailwindcss.com/ ]"
+ },
{
"value": "styled-components",
"label": "styled-components [ https://styled-components.com ]"
diff --git a/docs/generated/packages/react/generators/component.json b/docs/generated/packages/react/generators/component.json
index e1fb4b811172e..09f3e95db015f 100644
--- a/docs/generated/packages/react/generators/component.json
+++ b/docs/generated/packages/react/generators/component.json
@@ -38,6 +38,10 @@
"value": "less",
"label": "LESS [ https://lesscss.org ]"
},
+ {
+ "value": "tailwind",
+ "label": "tailwind [ https://tailwindcss.com/ ]"
+ },
{
"value": "styled-components",
"label": "styled-components [ https://styled-components.com ]"
diff --git a/docs/generated/packages/react/generators/library.json b/docs/generated/packages/react/generators/library.json
index fa5b8dc3b5ad8..6133297c0d286 100644
--- a/docs/generated/packages/react/generators/library.json
+++ b/docs/generated/packages/react/generators/library.json
@@ -49,6 +49,10 @@
"value": "less",
"label": "LESS [ https://lesscss.org ]"
},
+ {
+ "value": "tailwind",
+ "label": "tailwind [ https://tailwindcss.com/ ]"
+ },
{
"value": "styled-components",
"label": "styled-components [ https://styled-components.com ]"
diff --git a/packages/next/src/generators/application/__snapshots__/application.spec.ts.snap b/packages/next/src/generators/application/__snapshots__/application.spec.ts.snap
index 9019c2808c9bc..ddfa88dfae1a6 100644
--- a/packages/next/src/generators/application/__snapshots__/application.spec.ts.snap
+++ b/packages/next/src/generators/application/__snapshots__/application.spec.ts.snap
@@ -477,3 +477,474 @@ export default function Index() {
}
"
`;
+
+exports[`app --style tailwind should generate tailwind styles 1`] = `
+"export default function Index() {
+ /*
+ * Replace the elements below with your own.
+ *
+ * Note: The corresponding styles are in the ./index.tailwind file.
+ */
+ return (
+
+
+
+
+
+ Hello there,
+ Welcome myapp 👋
+
+
+
+
+
+
+
+
+
Next steps
+
Here are some things you can do with Nx:
+
+
+
+
+
+ Add UI library
+
+
+ # Generate UI lib
+ nx g @nx/next:library ui
+ # Add a component
+ nx g @nx/next:component ui/src/lib/button
+
+
+
+
+
+
+
+ View project details
+
+ nx show project myapp --web
+
+
+
+
+
+
+ View interactive project graph
+
+ nx graph
+
+
+
+
+
+
+ Run affected commands
+
+
+ # see what's been affected by changes
+ nx affected:graph
+ # run tests for current changes
+ nx affected:test
+ # run e2e tests for current changes
+ nx affected:e2e
+
+
+
+
+
+ Carefully crafted with
+
+
+
+
+
+
+
+ );
+}
+"
+`;
diff --git a/packages/next/src/generators/application/application.spec.ts b/packages/next/src/generators/application/application.spec.ts
index e2c5173944b45..a1977fc601f22 100644
--- a/packages/next/src/generators/application/application.spec.ts
+++ b/packages/next/src/generators/application/application.spec.ts
@@ -433,6 +433,48 @@ describe('app', () => {
});
});
+ describe('--style tailwind', () => {
+ it('should generate tailwind styles', async () => {
+ await applicationGenerator(tree, {
+ directory: 'myapp',
+ style: 'tailwind',
+ });
+
+ expect(tree.exists(`myapp/src/app/page.module.scss`)).toBeFalsy();
+ expect(tree.exists(`myapp/src/app/global.css`)).toBeTruthy();
+
+ const indexContent = tree.read(`myapp/src/app/page.tsx`, 'utf-8');
+ expect(indexContent).not.toContain(`import styles from './page.module`);
+ expect(indexContent).not.toContain(
+ `import styled from 'styled-components'`
+ );
+ expect(indexContent).toMatchSnapshot();
+
+ expect(tree.read(`myapp/src/app/layout.tsx`, 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "import './global.css';
+
+ export const metadata = {
+ title: 'Welcome to myapp',
+ description: 'Generated by create-nx-workspace',
+ };
+
+ export default function RootLayout({
+ children,
+ }: {
+ children: React.ReactNode;
+ }) {
+ return (
+
+ {children}
+
+ );
+ }
+ "
+ `);
+ });
+ });
+
it('should setup jest with tsx support', async () => {
const name = uniq();
diff --git a/packages/next/src/generators/component/schema.json b/packages/next/src/generators/component/schema.json
index c35a59782b446..f4123eea0b4dd 100644
--- a/packages/next/src/generators/component/schema.json
+++ b/packages/next/src/generators/component/schema.json
@@ -41,6 +41,10 @@
"value": "less",
"label": "LESS [ https://lesscss.org ]"
},
+ {
+ "value": "tailwind",
+ "label": "tailwind [ https://tailwindcss.com/ ]"
+ },
{
"value": "styled-components",
"label": "styled-components [ https://styled-components.com ]"
diff --git a/packages/next/src/generators/library/schema.json b/packages/next/src/generators/library/schema.json
index 4ac42721138fa..357ba21e606c3 100644
--- a/packages/next/src/generators/library/schema.json
+++ b/packages/next/src/generators/library/schema.json
@@ -43,6 +43,10 @@
"value": "less",
"label": "LESS [ https://lesscss.org ]"
},
+ {
+ "value": "tailwind",
+ "label": "tailwind [ https://tailwindcss.com/ ]"
+ },
{
"value": "styled-components",
"label": "styled-components [ https://styled-components.com ]"
diff --git a/packages/react/src/generators/application/__snapshots__/application.spec.ts.snap b/packages/react/src/generators/application/__snapshots__/application.spec.ts.snap
index 0a05b6eb0842d..9029419e4bad2 100644
--- a/packages/react/src/generators/application/__snapshots__/application.spec.ts.snap
+++ b/packages/react/src/generators/application/__snapshots__/application.spec.ts.snap
@@ -192,6 +192,40 @@ export default defineConfig({
"
`;
+exports[`app --style scss should generate scss styles 1`] = `
+"// Uncomment this line to use CSS modules
+// import styles from './app.module.scss';
+import NxWelcome from "./nx-welcome";
+
+export function App() {
+ return (
+
+
+
+ );
+}
+
+export default App;
+
+
+"
+`;
+
+exports[`app --style tailwind should not generate any styles files 1`] = `
+"import NxWelcome from './nx-welcome';
+
+export function App() {
+ return (
+
+
+
+ );
+}
+
+export default App;
+"
+`;
+
exports[`app not nested should add vite types to tsconfigs 1`] = `
"///
import { defineConfig } from 'vite';
@@ -358,6 +392,66 @@ export function App() {
export default App;
+"
+`;
+
+exports[`app should generate valid .babelrc JSON config for CSS-in-JS solutions 1`] = `
+"import styled from 'styled-components';
+import NxWelcome from "./nx-welcome";
+
+const StyledApp = styled.div\`
+ // Your style here
+\`;
+
+export function App() {
+ return (
+
+
+
+ );
+}
+
+export default App;
+
+"
+`;
+
+exports[`app should generate valid .babelrc JSON config for CSS-in-JS solutions 2`] = `
+"import NxWelcome from "./nx-welcome";
+
+export function App() {
+ return (
+
+
+
+
+ );
+}
+
+export default App;
+
+
+"
+`;
+
+exports[`app should generate valid .babelrc JSON config for CSS-in-JS solutions 3`] = `
+"import styled from '@emotion/styled';
+import NxWelcome from "./nx-welcome";
+
+const StyledApp = styled.div\`
+ // Your style here
+\`;
+
+export function App() {
+ return (
+
+
+
+ );
+}
+
+export default App;
+
"
`;
diff --git a/packages/react/src/generators/application/application.spec.ts b/packages/react/src/generators/application/application.spec.ts
index 1cd5c63075145..44826502ba28d 100644
--- a/packages/react/src/generators/application/application.spec.ts
+++ b/packages/react/src/generators/application/application.spec.ts
@@ -486,6 +486,8 @@ describe('app', () => {
expect(() => {
readJson(appTree, `my-app/.babelrc`);
}).not.toThrow();
+ const content = appTree.read('my-app/src/app/app.tsx').toString();
+ expect(content).toMatchSnapshot();
}
);
@@ -493,6 +495,8 @@ describe('app', () => {
it('should generate scss styles', async () => {
await applicationGenerator(appTree, { ...schema, style: 'scss' });
expect(appTree.exists('my-app/src/app/app.module.scss')).toEqual(true);
+ const content = appTree.read('my-app/src/app/app.tsx').toString();
+ expect(content).toMatchSnapshot();
});
});
@@ -509,6 +513,20 @@ describe('app', () => {
"
`);
});
+
+ it('should not generate any styles files', async () => {
+ await applicationGenerator(appTree, { ...schema, style: 'tailwind' });
+
+ expect(appTree.exists('my-app/src/app/app.tsx')).toBeTruthy();
+ expect(appTree.exists('my-app/src/app/app.spec.tsx')).toBeTruthy();
+ expect(appTree.exists('my-app/src/app/app.css')).toBeFalsy();
+ expect(appTree.exists('my-app/src/app/app.scss')).toBeFalsy();
+ expect(appTree.exists('my-app/src/app/app.module.css')).toBeFalsy();
+ expect(appTree.exists('my-app/src/app/app.module.scss')).toBeFalsy();
+
+ const content = appTree.read('my-app/src/app/app.tsx').toString();
+ expect(content).toMatchSnapshot();
+ });
});
it('should setup jest with tsx support', async () => {
diff --git a/packages/react/src/generators/component/__snapshots__/component.spec.ts.snap b/packages/react/src/generators/component/__snapshots__/component.spec.ts.snap
new file mode 100644
index 0000000000000..e22f1d160f449
--- /dev/null
+++ b/packages/react/src/generators/component/__snapshots__/component.spec.ts.snap
@@ -0,0 +1,81 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`component --style @emotion/styled should use @emotion/styled as the styled API library 1`] = `
+"import styled from '@emotion/styled';
+
+const StyledHello = styled.div\`
+ color: pink;
+\`;
+export function Hello() {
+ return (
+
+ Welcome to Hello!
+
+ );
+}
+
+export default Hello;
+"
+`;
+
+exports[`component --style none should generate component files without styles 1`] = `
+"export function Hello() {
+ return (
+
+
Welcome to Hello!
+
+ );
+}
+
+export default Hello;
+"
+`;
+
+exports[`component --style styled-components should use styled-components as the styled API library 1`] = `
+"import styled from 'styled-components';
+
+const StyledHello = styled.div\`
+ color: pink;
+\`;
+export function Hello() {
+ return (
+
+ Welcome to Hello!
+
+ );
+}
+
+export default Hello;
+"
+`;
+
+exports[`component --style styled-jsx should use styled-jsx as the styled API library 1`] = `
+"export function Hello() {
+ return (
+
+ {' '}
+
Welcome to Hello!
+
+ );
+}
+
+export default Hello;
+"
+`;
+
+exports[`component --style tailwind should not generate any style in component 1`] = `
+"export function Hello() {
+ return (
+
+
Welcome to Hello!
+
+ );
+}
+
+export default Hello;
+"
+`;
diff --git a/packages/react/src/generators/component/component.spec.ts b/packages/react/src/generators/component/component.spec.ts
index acb66237ed83c..89ca1c4ad43cb 100644
--- a/packages/react/src/generators/component/component.spec.ts
+++ b/packages/react/src/generators/component/component.spec.ts
@@ -217,6 +217,7 @@ describe('component', () => {
expect(content).not.toContain('hello.scss');
expect(content).not.toContain('hello.module.css');
expect(content).not.toContain('hello.module.scss');
+ expect(content).toMatchSnapshot();
});
});
@@ -236,6 +237,7 @@ describe('component', () => {
const content = appTree.read('my-lib/src/lib/hello/hello.tsx').toString();
expect(content).toContain('styled-components');
expect(content).toContain('');
+ expect(content).toMatchSnapshot();
});
it('should add dependencies to package.json', async () => {
@@ -266,6 +268,7 @@ describe('component', () => {
const content = appTree.read('my-lib/src/lib/hello/hello.tsx').toString();
expect(content).toContain('@emotion/styled');
expect(content).toContain('');
+ expect(content).toMatchSnapshot();
});
it('should add dependencies to package.json', async () => {
@@ -297,6 +300,7 @@ describe('component', () => {
const content = appTree.read('my-lib/src/lib/hello/hello.tsx').toString();
expect(content).toContain('