diff --git a/.vscode/settings.json b/.vscode/settings.json index 39b1264..4ce1c05 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,7 @@ "daisyui", "degit", "gitzy", + "iconify", "noreferrer", "Parens", "pnpm", @@ -13,9 +14,10 @@ "vitest", "zustand" ], - "editor.formatOnSave": true, "css.lint.unknownAtRules": "ignore", "tailwindCSS.experimental.classRegex": [ ["clsx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"] - ] + ], + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode" } diff --git a/README.md b/README.md index c4e973c..0cc4e3c 100644 --- a/README.md +++ b/README.md @@ -16,15 +16,15 @@ [![pnpm](https://img.shields.io/badge/pnpm-%234a4a4a.svg?style=for-the-badge&logo=pnpm&logoColor=f69220)][pnpm] [![GitHub Actions](https://img.shields.io/badge/GitHub_Actions-2088FF?style=for-the-badge&logo=github-actions&logoColor=white)][GitHub Actions] -- ⚡️ [vite][vite] for fast server start and HMR -- 🏷️ [TypeScript][TypeScript] for a less frustrating & consistent experience -- 💄 [tailwindcss][tailwindcss] for utility-first CSS -- 🧪 [vitest][vitest] for fast testing -- 🧪 [Playwright][Playwright] for fast and reliable e2e testing -- 🩺 [eslint][eslint] for static analysis -- 🎨 [prettier][prettier] for formatting -- ⚡️ [pnpm][pnpm] for fast and consistent installs -- 👷 [GitHub Actions][GitHub Actions] for easy workflow automation +- ⚡️ [vite][vite] for instant server start and lighting fast HMR. +- 🏷️ [TypeScript][TypeScript] for a less frustrating & consistent experience. +- 💄 [tailwindcss][tailwindcss] for utility-first CSS. +- 🧪 [vitest][vitest] for fast testing. +- 🧪 [Playwright][Playwright] for fast and reliable e2e testing. +- 🩺 [eslint][eslint] for static analysis. +- 🎨 [prettier][prettier] for formatting. +- ⚡️ [pnpm][pnpm] for fast and consistent installs. +- 👷 [GitHub Actions][GitHub Actions] for easy workflow automation. ## Usage diff --git a/e2e/app.spec.ts b/e2e/app.spec.ts index 50f8495..bdc6514 100644 --- a/e2e/app.spec.ts +++ b/e2e/app.spec.ts @@ -14,7 +14,7 @@ test.describe('external links', () => { test('opened vite docs', async ({ page, context }) => { const pagePromise = context.waitForEvent('page') - await page.getByRole('link', { name: /vite logo/i }).click() + await page.getByRole('link', { name: /vite/i }).click() const newPage = await pagePromise @@ -26,7 +26,7 @@ test.describe('external links', () => { test('opened React docs', async ({ page, context }) => { const pagePromise = context.waitForEvent('page') - await page.getByRole('link', { name: /react logo/i }).click() + await page.getByRole('link', { name: /react/i }).click() const newPage = await pagePromise @@ -38,7 +38,7 @@ test.describe('external links', () => { test('opened TypeScript docs', async ({ page, context }) => { const pagePromise = context.waitForEvent('page') - await page.getByRole('link', { name: /TypeScript logo/i }).click() + await page.getByRole('link', { name: /TypeScript/i }).click() const newPage = await pagePromise @@ -50,7 +50,7 @@ test.describe('external links', () => { test('opened tailwindcss docs', async ({ page, context }) => { const pagePromise = context.waitForEvent('page') - await page.getByRole('link', { name: /tailwindcss logo/i }).click() + await page.getByRole('link', { name: /tailwindcss/i }).click() const newPage = await pagePromise @@ -62,7 +62,7 @@ test.describe('external links', () => { test('opened repo', async ({ page, context }) => { const pagePromise = context.waitForEvent('page') - await page.getByRole('link', { name: /repo/i }).click() + await page.getByRole('link', { name: /get started/i }).click() const newPage = await pagePromise diff --git a/index.html b/index.html index c7875c1..fe32e82 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,10 @@ + React Starter diff --git a/package.json b/package.json index bfcb9ff..9ac25ef 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,8 @@ "react-dom": "18.2.0" }, "devDependencies": { + "@iconify-json/logos": "1.1.38", + "@iconify/tailwind": "0.1.3", "@playwright/test": "1.40.0", "@tailwindcss/typography": "0.5.10", "@testing-library/dom": "9.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2b54b6e..fdf7503 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,6 +16,12 @@ dependencies: version: 18.2.0(react@18.2.0) devDependencies: + '@iconify-json/logos': + specifier: 1.1.38 + version: 1.1.38 + '@iconify/tailwind': + specifier: 0.1.3 + version: 0.1.3 '@playwright/test': specifier: 1.40.0 version: 1.40.0 @@ -437,6 +443,22 @@ packages: resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} dev: true + /@iconify-json/logos@1.1.38: + resolution: {integrity: sha512-26sPSWn/Y3nY4Kx3kbHOPU8zzEFaDMeuStFhDbW2SpLy6grusqTAgf0o4r4irNAPkdI1gPF8kuSyGDKeSPFzZw==} + dependencies: + '@iconify/types': 2.0.0 + dev: true + + /@iconify/tailwind@0.1.3: + resolution: {integrity: sha512-uVV49QtR9cZ9VLxrMSeW1E6iXWeBlpQ0z4aWx7B5WvGEE5OvCjloNYYqwZbZ/W+EsTcApzSm6szqcCVeb9pxDw==} + dependencies: + '@iconify/types': 2.0.0 + dev: true + + /@iconify/types@2.0.0: + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + dev: true + /@istanbuljs/schema@0.1.3: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} diff --git a/src/App.spec.tsx b/src/App.spec.tsx index fea6920..03e1dc0 100644 --- a/src/App.spec.tsx +++ b/src/App.spec.tsx @@ -7,8 +7,8 @@ describe('app', () => { await user.click(screen.getByRole('button', { name: /count is 0/i })) - await expect( - screen.findByRole('button', { name: /count is 1/i }) - ).resolves.toBeInTheDocument() + expect( + screen.getByRole('button', { name: /count is 1/i }) + ).toBeInTheDocument() }) }) diff --git a/src/App.tsx b/src/App.tsx index e31ed50..d07c986 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,53 +1,54 @@ import { useState } from 'react' -import reactLogo from './assets/react.svg' -import tailwindcssLogo from './assets/tailwindcss.svg' -import typeScriptLogo from './assets/typescript.svg' -import viteLogo from './assets/vite.svg' -import { Logo } from './components/Logo' +import { XLink } from './components/XLink' export default function App() { const [count, setCount] = useState(0) return ( -
-
- - - - -
-

Vite + React + TypeScript + tailwindcss

-
- -

- Edit src/App.tsx and save to test HMR -

-

- Click on logos to learn more or visit the{' '} - - repo - -

+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+

+ React Starter +

+

+ 🍱 Another opinionated React Starter + using Vite,{' '} + TypeScript and{' '} + tailwindcss. +

+
+ + + Get Started{' '} + + +
+
+
) diff --git a/src/assets/react.svg b/src/assets/react.svg deleted file mode 100644 index fbf3ae0..0000000 --- a/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ -React diff --git a/src/assets/tailwindcss.svg b/src/assets/tailwindcss.svg deleted file mode 100644 index 10a5ef6..0000000 --- a/src/assets/tailwindcss.svg +++ /dev/null @@ -1 +0,0 @@ -Tailwind CSS diff --git a/src/assets/typescript.svg b/src/assets/typescript.svg deleted file mode 100644 index 1829f4b..0000000 --- a/src/assets/typescript.svg +++ /dev/null @@ -1 +0,0 @@ -TypeScript diff --git a/src/assets/vite.svg b/src/assets/vite.svg deleted file mode 100644 index ee9fada..0000000 --- a/src/assets/vite.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/components/Logo.spec.tsx b/src/components/Logo.spec.tsx deleted file mode 100644 index 8eca574..0000000 --- a/src/components/Logo.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import viteLogo from '@/assets/vite.svg' -import { render, screen } from '@/test/utils' - -import { Logo } from './Logo' - -describe('logo', () => { - it('should render link and image', () => { - render() - - expect(screen.getByRole('link', { name: /vite logo/i })).toBeInTheDocument() - expect(screen.getByRole('img', { name: /vite logo/i })).toBeInTheDocument() - expect(screen.getByRole('img', { name: /vite logo/i })).toHaveClass( - 'h-24 transition duration-300 hover:drop-shadow-[0_0_2em_#646CFF]' - ) - }) -}) diff --git a/src/components/Logo.tsx b/src/components/Logo.tsx deleted file mode 100644 index d34925f..0000000 --- a/src/components/Logo.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { clsx } from 'clsx' - -interface LogoProps { - imgSrc: string - link: string - name: 'React' | 'tailwindcss' | 'TypeScript' | 'Vite' -} - -const classNames = { - Vite: 'hover:drop-shadow-[0_0_2em_#646CFF]', - React: - 'hover:drop-shadow-[0_0_2em_#61DAFB] animate-[spin_20s_linear_infinite]', - TypeScript: 'hover:drop-shadow-[0_0_2em_#3178C6]', - tailwindcss: 'hover:drop-shadow-[0_0_2em_#06B6D4]', -} - -export const Logo = ({ link, imgSrc, name }: LogoProps) => { - return ( - - {`${name} - - ) -} diff --git a/src/components/XLink.spec.tsx b/src/components/XLink.spec.tsx new file mode 100644 index 0000000..6683e63 --- /dev/null +++ b/src/components/XLink.spec.tsx @@ -0,0 +1,11 @@ +import { render, screen } from '@/test/utils' + +import { XLink } from './XLink' + +describe('logo', () => { + it('should render link and image', () => { + render(Vite) + + expect(screen.getByRole('link', { name: /vite/i })).toBeInTheDocument() + }) +}) diff --git a/src/components/XLink.tsx b/src/components/XLink.tsx new file mode 100644 index 0000000..e9bc4cb --- /dev/null +++ b/src/components/XLink.tsx @@ -0,0 +1,34 @@ +import { clsx } from 'clsx' +import { type ReactNode } from 'react' + +const links = { + Vite: 'https://vitejs.dev', + React: 'https://react.dev', + TypeScript: 'https://www.typescriptlang.org', + tailwindcss: 'https://tailwindcss.com', + repo: 'https://github.com/jimmy-guzman/react-starter#readme', +} + +interface LogoProps { + children: ReactNode + className?: string + to: keyof typeof links +} + +/** + * Pre-configured Type Safe External Link + * @example + * tailwindcss // https://tailwindcss.com + */ +export const XLink = ({ to, className = 'dsy-link', children }: LogoProps) => { + return ( + + {children} + + ) +} diff --git a/tailwind.config.js b/tailwind.config.js index 605206b..d8b7bc0 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,3 +1,4 @@ +import { addDynamicIconSelectors } from '@iconify/tailwind' import typography from '@tailwindcss/typography' import daisyui from 'daisyui' @@ -13,5 +14,5 @@ export default { prefix: 'dsy-', logs: false, }, - plugins: [typography, daisyui], + plugins: [typography, daisyui, addDynamicIconSelectors()], }