@wazobiatech/wazui 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.dockerignore +9 -0
  4. package/.env.sample +22 -0
  5. package/.husky/pre-commit +7 -0
  6. package/.prettierignore +5 -0
  7. package/.prettierrc +9 -0
  8. package/.storybook/main.ts +41 -0
  9. package/.storybook/preview-head.html +3 -0
  10. package/.storybook/preview.ts +53 -0
  11. package/Dockerfile +58 -0
  12. package/Dockerfile.dev +11 -0
  13. package/README.md +130 -0
  14. package/__mocks__/fileMock.ts +1 -0
  15. package/__mocks__/svgMock.ts +1 -0
  16. package/babel.config.js +46 -0
  17. package/bitbucket-pipelines.yml +70 -0
  18. package/components.json +21 -0
  19. package/e2e/example.spec.ts +18 -0
  20. package/eslint.config.mjs +37 -0
  21. package/index.html +13 -0
  22. package/jest.config.ts +79 -0
  23. package/jest.setup.tsx +276 -0
  24. package/lint-staged.config.js +45 -0
  25. package/package.json +167 -0
  26. package/playwright.config.ts +79 -0
  27. package/plop-templates/Component.tsx.hbs +13 -0
  28. package/plop-templates/ComponentStories.tsx.hbs +24 -0
  29. package/plop-templates/ComponentTests.tsx.hbs +15 -0
  30. package/plop-templates/ComponentTypes.ts.hbs +1 -0
  31. package/plopfile.js +35 -0
  32. package/setupTests.ts +1 -0
  33. package/src/assets/dashboard/book.svg +6 -0
  34. package/src/assets/dashboard/edit.svg +5 -0
  35. package/src/assets/dashboard/emerald.svg +9 -0
  36. package/src/assets/dashboard/eye.svg +4 -0
  37. package/src/assets/dashboard/gold.svg +9 -0
  38. package/src/assets/dashboard/percentage-square.svg +6 -0
  39. package/src/assets/dashboard/sapphire.svg +9 -0
  40. package/src/assets/dashboard/send-2.svg +4 -0
  41. package/src/assets/desktop.svg +7 -0
  42. package/src/assets/fonts/UniversalFeature/FeatureJungle-Light.otf +0 -0
  43. package/src/assets/fonts/UniversalFeature/FeatureJungle-Light.woff +0 -0
  44. package/src/assets/fonts/UniversalFeature/FeatureJungle-Light.woff2 +0 -0
  45. package/src/assets/fonts/UniversalFeature/FeatureJungle-Regular.otf +0 -0
  46. package/src/assets/fonts/UniversalFeature/FeatureJungle-Regular.woff +0 -0
  47. package/src/assets/fonts/UniversalFeature/FeatureJungle-Regular.woff2 +0 -0
  48. package/src/assets/fonts/UniversalJungle/UniversalJungle-420.otf +0 -0
  49. package/src/assets/fonts/UniversalJungle/UniversalJungle-420.woff +0 -0
  50. package/src/assets/fonts/UniversalJungle/UniversalJungle-420.woff2 +0 -0
  51. package/src/assets/fonts/UniversalJungle/UniversalJungle-515.otf +0 -0
  52. package/src/assets/fonts/UniversalJungle/UniversalJungle-515.woff +0 -0
  53. package/src/assets/fonts/UniversalJungle/UniversalJungle-515.woff2 +0 -0
  54. package/src/assets/instagram.svg +9 -0
  55. package/src/assets/mobile.svg +4 -0
  56. package/src/assets/no-data-image.svg +41 -0
  57. package/src/assets/no-image-icon.svg +84 -0
  58. package/src/assets/pexels.svg +9 -0
  59. package/src/assets/react.svg +1 -0
  60. package/src/assets/sounds/draft.mp3 +0 -0
  61. package/src/assets/sounds/error.mp3 +0 -0
  62. package/src/assets/sounds/publish.mp3 +0 -0
  63. package/src/assets/tablet.svg +4 -0
  64. package/src/assets/unsplash.svg +3 -0
  65. package/src/assets/upload-image.svg +43 -0
  66. package/src/assets/user.svg +4 -0
  67. package/src/components/shadcn/index.ts +31 -0
  68. package/src/config/env.ts +15 -0
  69. package/src/contexts/ThemeContext.tsx +11 -0
  70. package/src/data/users.json +6014 -0
  71. package/src/decorators/ActionModalDecorator.tsx +10 -0
  72. package/src/decorators/ApolloDecorator.tsx +19 -0
  73. package/src/decorators/DolosApolloDecorator.tsx +31 -0
  74. package/src/decorators/JestDecorators.tsx +34 -0
  75. package/src/decorators/ReactQueryDecorator.tsx +13 -0
  76. package/src/decorators/RouterDecorator.tsx +5 -0
  77. package/src/decorators/UnsafePropsDecorator.tsx +0 -0
  78. package/src/env.ts +99 -0
  79. package/src/hooks/use-autogrow.ts +28 -0
  80. package/src/hooks/use-mobile.ts +19 -0
  81. package/src/hooks/useAuthors.ts +78 -0
  82. package/src/hooks/useDebounce.ts +18 -0
  83. package/src/hooks/useMercuryProjectToken.ts +112 -0
  84. package/src/hooks/useProjectToken.ts +21 -0
  85. package/src/hooks/useTheme.ts +12 -0
  86. package/src/index.css +397 -0
  87. package/src/index.ts +59 -0
  88. package/src/mocks/env.ts +12 -0
  89. package/src/providers/QueryProvider/index.tsx +10 -0
  90. package/src/providers/ThemeProvider/index.tsx +52 -0
  91. package/src/types/category.types.ts +13 -0
  92. package/src/types/image.types.ts +44 -0
  93. package/src/types/post.types.ts +121 -0
  94. package/src/types/theme.types.ts +10 -0
  95. package/src/types/users.types.ts +5 -0
  96. package/src/utils/apolloClient.ts +160 -0
  97. package/src/utils/articleMetadata.ts +92 -0
  98. package/src/utils/audio.ts +10 -0
  99. package/src/utils/imageProcessing.ts +399 -0
  100. package/src/utils/images.ts +279 -0
  101. package/src/utils/mercury.ts +0 -0
  102. package/src/utils/utils.ts +638 -0
  103. package/src/utils/videos.ts +29 -0
  104. package/src/vite-env.d.ts +1 -0
  105. package/tsconfig.app.json +30 -0
  106. package/tsconfig.json +32 -0
  107. package/tsconfig.node.json +24 -0
  108. package/tsconfig.tsbuildinfo +1 -0
  109. package/vite.config.ts +50 -0
@@ -0,0 +1,8 @@
1
+ # Changesets
2
+
3
+ Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4
+ with multi-package repos, or single-package repos to help you version and publish your code. You can
5
+ find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6
+
7
+ We have a quick list of common questions to get you started engaging with this project in
8
+ [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
@@ -0,0 +1,11 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
3
+ "changelog": "@changesets/cli/changelog",
4
+ "commit": false,
5
+ "fixed": [],
6
+ "linked": [],
7
+ "access": "restricted",
8
+ "baseBranch": "releases/npm",
9
+ "updateInternalDependencies": "patch",
10
+ "ignore": []
11
+ }
package/.dockerignore ADDED
@@ -0,0 +1,9 @@
1
+ .git
2
+ .gitignore
3
+ node_modules
4
+ npm-debug.log
5
+ Dockerfile*
6
+ docker-compose*
7
+ README.md
8
+ LICENSE
9
+ .vscode
package/.env.sample ADDED
@@ -0,0 +1,22 @@
1
+ VITE_PORTAL_GRAPHQL_ENDPOINT=
2
+ VITE_DOLOS_URL=
3
+ VITE_DOLOS_TRANSFORMATION_ENDPOINT=
4
+ VITE_RECIPES_ENDPOINT=
5
+ VITE_MUSE_ENDPOINT=
6
+ VITE_MUSE_TOKEN=
7
+ VITE_PHOENIX_ENDPOINT=
8
+ VITE_PROJECT_UUID=
9
+ VITE_REVALIDATION_TWISTEDFOOD_TOKEN=
10
+ VITE_REVALIDATION_VT_TOKEN=
11
+ VITE_MERCURY_TOKEN_ENDPOINT=
12
+ VITE_ATHENS_APP_ID=
13
+ VITE_ATHENS_APP_SECRET=
14
+ VITE_BLOG_UUID=
15
+ VITE_GRAPH_QL_URL=
16
+ VITE_MUSE_GRAPHQL_URL=
17
+ VITE_RECIPE_GRAPHQL_URL=
18
+
19
+ VITE_PROJECT_TOKEN=
20
+
21
+ # NPM Token for private registry authentication
22
+ NPM_TOKEN=
@@ -0,0 +1,7 @@
1
+ # !/usr/bin/env sh
2
+
3
+ # export NODE_OPTIONS="--max-old-space-size=4096"
4
+
5
+ yarn run lint:staged
6
+ yarn test
7
+ yarn run build
@@ -0,0 +1,5 @@
1
+ node_modules
2
+ build
3
+ dist
4
+ .vscode
5
+ storybook-static
package/.prettierrc ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "singleQuote": true,
3
+ "semi": true,
4
+ "tabWidth": 2,
5
+ "trailingComma": "es5",
6
+ "printWidth": 100,
7
+ "arrowParens": "avoid",
8
+ "jsxSingleQuote": true
9
+ }
@@ -0,0 +1,41 @@
1
+ import type { StorybookConfig } from '@storybook/react-vite';
2
+
3
+ const config: StorybookConfig = {
4
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
5
+ addons: [
6
+ '@storybook/addon-essentials',
7
+ '@storybook/addon-onboarding',
8
+ '@chromatic-com/storybook',
9
+ '@storybook/experimental-addon-test',
10
+ '@storybook/addon-themes',
11
+ ],
12
+ framework: {
13
+ name: '@storybook/react-vite',
14
+ options: {},
15
+ },
16
+ viteFinal(storybookConfig) {
17
+ if (!storybookConfig.build) storybookConfig.build = {};
18
+ if (!storybookConfig.build.rollupOptions) storybookConfig.build.rollupOptions = {};
19
+ if (!storybookConfig.build.rollupOptions.external)
20
+ storybookConfig.build.rollupOptions.external = [];
21
+
22
+ // Add external dependencies
23
+ const external = storybookConfig.build.rollupOptions.external as string[];
24
+ external.push('@storybook/types', '@storybook/internal/manager-api');
25
+
26
+ // ✅ Add proxy for /api/phoenix
27
+ // storybookConfig.server = storybookConfig.server || {};
28
+ // storybookConfig.server.proxy = {
29
+ // ...(storybookConfig.server.proxy || {}),
30
+ // '/api/phoenix': {
31
+ // target: 'https://phoenix.hogfort.com',
32
+ // changeOrigin: true,
33
+ // rewrite: (path: string) => path.replace(/^\/api\/phoenix/, '/graphql'),
34
+ // },
35
+ // };
36
+
37
+ return storybookConfig;
38
+ },
39
+ };
40
+
41
+ export default config;
@@ -0,0 +1,3 @@
1
+ <!-- Load your CSS file -->
2
+ <link rel="stylesheet" href="../src/index.css" />
3
+ <link rel="stylesheet" href="./styles.css" />
@@ -0,0 +1,53 @@
1
+ import '../src/index.css';
2
+ import type { Preview } from '@storybook/react';
3
+
4
+ import { withThemeByClassName } from '@storybook/addon-themes';
5
+
6
+ import TimeAgo from 'javascript-time-ago';
7
+
8
+ import en from 'javascript-time-ago/locale/en';
9
+ import ru from 'javascript-time-ago/locale/ru';
10
+ import { withApollo } from '../src/decorators/ApolloDecorator';
11
+ import { withReactQuery } from '../src/decorators/ReactQueryDecorator';
12
+ import { withRouter } from '../src/decorators/RouterDecorator';
13
+ import { withActionModalProvider } from '../src/decorators/ActionModalDecorator';
14
+
15
+ TimeAgo.addDefaultLocale(en);
16
+ TimeAgo.addLocale(ru);
17
+
18
+ export const decorators = [
19
+ withThemeByClassName({
20
+ themes: {
21
+ light: 'light',
22
+ dark: 'dark',
23
+ brand: 'brand',
24
+ },
25
+ defaultTheme: 'light',
26
+ parentSelector: 'html',
27
+ }),
28
+ withRouter,
29
+ withReactQuery,
30
+ withApollo,
31
+ withActionModalProvider,
32
+ ];
33
+
34
+ const preview: Preview = {
35
+ parameters: {
36
+ controls: {
37
+ matchers: {
38
+ color: /(background|color)$/i,
39
+ date: /Date$/i,
40
+ },
41
+ },
42
+ backgrounds: {
43
+ default: 'light',
44
+ values: [
45
+ { name: 'light', value: '#ffffff' },
46
+ { name: 'dark', value: '#000000' },
47
+ { name: 'brand', value: '#f0f0f0' },
48
+ ],
49
+ },
50
+ },
51
+ };
52
+
53
+ export default preview;
package/Dockerfile ADDED
@@ -0,0 +1,58 @@
1
+ # Build stage
2
+ FROM node:20-alpine AS build
3
+
4
+ # Set working directory
5
+ WORKDIR /app
6
+
7
+ # Copy package files
8
+ COPY package.json ./
9
+
10
+ # Install dependencies
11
+ RUN yarn install
12
+
13
+ # Copy project files
14
+ COPY . .
15
+
16
+ # Build the component library
17
+ RUN npm run build
18
+
19
+ # Build Storybook
20
+ RUN npm run build-storybook
21
+
22
+ # Production stage with Nginx
23
+ FROM nginx:alpine AS production
24
+
25
+ # Create directories for both builds
26
+ RUN mkdir -p /usr/share/nginx/html/storybook
27
+ RUN mkdir -p /usr/share/nginx/html/dist
28
+
29
+ # Copy Storybook static files
30
+ COPY --from=build /app/storybook-static /usr/share/nginx/html/storybook
31
+
32
+ # Copy dist files
33
+ COPY --from=build /app/dist /usr/share/nginx/html/dist
34
+
35
+ # Create a custom Nginx configuration
36
+ RUN echo 'server { \
37
+ listen 80; \
38
+ \
39
+ location /storybook/ { \
40
+ alias /usr/share/nginx/html/storybook/; \
41
+ try_files $uri $uri/ /storybook/index.html; \
42
+ } \
43
+ \
44
+ location /dist/ { \
45
+ alias /usr/share/nginx/html/dist/; \
46
+ try_files $uri $uri/ /dist/index.html; \
47
+ } \
48
+ \
49
+ location / { \
50
+ return 301 /storybook/; \
51
+ } \
52
+ }' > /etc/nginx/conf.d/default.conf
53
+
54
+ # Nginx already exposes port 80
55
+ EXPOSE 80
56
+
57
+ # Start Nginx
58
+ CMD ["nginx", "-g", "daemon off;"]
package/Dockerfile.dev ADDED
@@ -0,0 +1,11 @@
1
+ FROM node:20-alpine
2
+
3
+ WORKDIR /app
4
+
5
+ COPY ./package.json .
6
+
7
+ RUN yarn
8
+
9
+ COPY . .
10
+
11
+ CMD ["tail", "-f", "/dev/null"]
package/README.md ADDED
@@ -0,0 +1,130 @@
1
+ # Wazui Component Library
2
+
3
+ `@repo/wazui` is a React component library that provides a set of reusable UI components, hooks, and providers for building modern web applications. It is built with TypeScript, Tailwind CSS, and integrates Shadcn UI components.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Usage](#usage)
9
+ - [Available Components](#available-components)
10
+ - [Contributing](#contributing)
11
+
12
+ ## Installation
13
+
14
+ To use the Wazui component library, you need to have a React project set up.
15
+
16
+ 1. **Install the package**:
17
+
18
+ ```bash
19
+ npm install @repo/wazui
20
+ ```
21
+
22
+ 2. **Install peer dependencies**:
23
+
24
+ This package has peer dependencies that need to be installed in your project.
25
+
26
+ ```bash
27
+ npm install react react-dom @tanstack/react-query @tanstack/react-query-devtools
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ### 1. Import Styles
33
+
34
+ For the components to be styled correctly, import the CSS file into your main application file (e.g., `index.tsx` or `App.tsx`).
35
+
36
+ ```tsx
37
+ import '@repo/wazui/styles.css';
38
+ ```
39
+
40
+ ### 2. Set up Providers
41
+
42
+ The library includes providers for theme and data fetching. Wrap your application with them.
43
+
44
+ ```tsx
45
+ // In your main App component
46
+ import React from 'react';
47
+ import ReactDOM from 'react-dom/client';
48
+ import App from './App';
49
+ import { WazUIThemeProvider, WazUIQueryProvider } from '@repo/wazui';
50
+ import '@repo/wazui/styles.css';
51
+
52
+ ReactDOM.createRoot(document.getElementById('root')!).render(
53
+ <React.StrictMode>
54
+ <WazUIQueryProvider>
55
+ <WazUIThemeProvider defaultTheme='dark' storageKey='wazui-theme'>
56
+ <App />
57
+ </WazUIThemeProvider>
58
+ </WazUIQueryProvider>
59
+ </React.StrictMode>
60
+ );
61
+ ```
62
+
63
+ ### 3. Use Components
64
+
65
+ You can import and use components from the library in your application.
66
+
67
+ #### Wazui Components
68
+
69
+ These are the main components from the `@repo/wazui` package.
70
+
71
+ ```tsx
72
+ import { WazUIButton } from '@repo/wazui';
73
+
74
+ function MyComponent() {
75
+ return <WazUIButton>Click Me</WazUIButton>;
76
+ }
77
+ ```
78
+
79
+ #### Shadcn Components
80
+
81
+ The library also exports Shadcn UI components from a secondary entry point.
82
+
83
+ ```tsx
84
+ import { Button } from '@repo/wazui/shadcn';
85
+
86
+ function MyOtherComponent() {
87
+ return <Button variant='outline'>Shadcn Button</Button>;
88
+ }
89
+ ```
90
+
91
+ ## Available Components
92
+
93
+ This library exports a wide range of components, hooks, and utilities.
94
+
95
+ ### Main Exports (`@repo/wazui`)
96
+
97
+ - `WazUIButton`
98
+ - `WazUIBlogComponent`
99
+ - `WazUiPostCard`
100
+ - `WazUiGqlMediaLibrary`
101
+ - `WazUiCreateBlogContent`
102
+ - `WazUIBlogDashboard`
103
+ - `WazUIThemeProvider` and `useWazUITheme` hook
104
+ - `WazUIQueryProvider`
105
+ - And many more...
106
+
107
+ ### Shadcn Exports (`@repo/wazui/shadcn`)
108
+
109
+ A large set of UI primitives are available, including:
110
+
111
+ - `Alert`
112
+ - `Badge`
113
+ - `Button`
114
+ - `Card`
115
+ - `Dialog`
116
+ - `DropdownMenu`
117
+ - `Input`
118
+ - `Sheet`
119
+ - `Table`
120
+ - And many more...
121
+
122
+ Refer to your Storybook or source code for a complete list of available components and their props.
123
+
124
+ ## Contributing
125
+
126
+ 1. Create a new branch from `main`
127
+ 2. Make your changes
128
+ 3. Submit a pull request
129
+ 4. Ensure tests pass and linting is clean
130
+ 5. Get approval from at least two senior engineers
@@ -0,0 +1 @@
1
+ module.exports = 'test-file-stub';
@@ -0,0 +1 @@
1
+ module.exports = 'SvgMock';
@@ -0,0 +1,46 @@
1
+ // import babelConfig from "@repo/babel-config/babel.config.base.js";
2
+ // export default babelConfig;
3
+ const replaceImportMeta = () => ({
4
+ visitor: {
5
+ MetaProperty(path) {
6
+ if (path.node.meta.name === 'import' && path.node.property.name === 'meta') {
7
+ path.replaceWithSourceString('process');
8
+ }
9
+ },
10
+ },
11
+ });
12
+ const config = {
13
+ presets: [
14
+ [
15
+ '@babel/preset-env',
16
+ {
17
+ targets: {
18
+ node: 'current',
19
+ },
20
+ },
21
+ ],
22
+ [
23
+ '@babel/preset-react',
24
+ {
25
+ runtime: 'automatic',
26
+ },
27
+ ],
28
+ '@babel/preset-typescript',
29
+ ],
30
+ plugins: ['@babel/plugin-syntax-import-meta'],
31
+ env: {
32
+ test: {
33
+ presets: [
34
+ [
35
+ '@babel/preset-env',
36
+ {
37
+ targets: { node: 'current' },
38
+ modules: 'commonjs',
39
+ },
40
+ ],
41
+ ],
42
+ plugins: ['@babel/plugin-syntax-import-meta', replaceImportMeta],
43
+ },
44
+ },
45
+ };
46
+ export default config;
@@ -0,0 +1,70 @@
1
+ image: node:22.12.0-alpine
2
+
3
+ definitions:
4
+ caches:
5
+ yarn: ~/.cache/yarn
6
+
7
+ services:
8
+ docker:
9
+ memory: 3072
10
+
11
+ steps:
12
+ # -------------------------
13
+ # Base step: install, lint, test, build
14
+ # -------------------------
15
+ - step: &install-lint-test-build
16
+ name: Install, Lint, Test, Build
17
+ caches:
18
+ - yarn
19
+ script:
20
+ - corepack enable
21
+ - yarn install --frozen-lockfile
22
+ - yarn lint
23
+ - yarn test
24
+ - yarn build
25
+ artifacts:
26
+ - dist/**
27
+ - storybook-static/**
28
+ - coverage/**
29
+ after-script:
30
+ - rm -rf node_modules/.cache
31
+
32
+ # -------------------------
33
+ # Version + Publish (main only)
34
+ # -------------------------
35
+ - step: &version-and-publish
36
+ name: Version & Publish (npm private)
37
+ deployment: production
38
+ caches:
39
+ - yarn
40
+ script:
41
+ - corepack enable
42
+ - yarn install --frozen-lockfile
43
+
44
+ # Apply version bumps from .changeset files
45
+ - yarn changeset version
46
+
47
+ # Reinstall after package.json updates
48
+ - yarn install --frozen-lockfile
49
+
50
+ # Build before publish
51
+ - yarn build
52
+
53
+ # Publish private packages
54
+ - yarn changeset publish
55
+
56
+ pipelines:
57
+ # Default pipeline for all branches
58
+ default:
59
+ - step: *install-lint-test-build
60
+
61
+ # Pipeline for pull requests
62
+ pull-requests:
63
+ '**':
64
+ - step: *install-lint-test-build
65
+
66
+ # Pipeline for main branch (publishing enabled)
67
+ branches:
68
+ 'releases/npm':
69
+ - step: *install-lint-test-build
70
+ - step: *version-and-publish
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "new-york",
4
+ "rsc": false,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "",
8
+ "css": "src/index.css",
9
+ "baseColor": "neutral",
10
+ "cssVariables": true,
11
+ "prefix": ""
12
+ },
13
+ "aliases": {
14
+ "components": "@/components/shadcn",
15
+ "utils": "@/utils/utils",
16
+ "ui": "@/components/shadcn/ui",
17
+ "lib": "@/lib",
18
+ "hooks": "@/hooks"
19
+ },
20
+ "iconLibrary": "lucide"
21
+ }
@@ -0,0 +1,18 @@
1
+ import { test, expect } from '@playwright/test';
2
+
3
+ test('has title', async ({ page }) => {
4
+ await page.goto('https://playwright.dev/');
5
+
6
+ // Expect a title "to contain" a substring.
7
+ await expect(page).toHaveTitle(/Playwright/);
8
+ });
9
+
10
+ test('get started link', async ({ page }) => {
11
+ await page.goto('https://playwright.dev/');
12
+
13
+ // Click the get started link.
14
+ await page.getByRole('link', { name: 'Get started' }).click();
15
+
16
+ // Expects page to have a heading with the name of Installation.
17
+ await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible();
18
+ });
@@ -0,0 +1,37 @@
1
+ import js from '@eslint/js';
2
+ import globals from 'globals';
3
+ import reactHooks from 'eslint-plugin-react-hooks';
4
+ import reactRefresh from 'eslint-plugin-react-refresh';
5
+ import tseslint from 'typescript-eslint';
6
+
7
+ export default tseslint.config(
8
+ { ignores: ['dist', 'storybook-static', '.storybook'] },
9
+ {
10
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
11
+ files: ['**/*.{ts,tsx}'],
12
+ languageOptions: {
13
+ ecmaVersion: 2020,
14
+ globals: globals.browser,
15
+ },
16
+ plugins: {
17
+ 'react-hooks': reactHooks,
18
+ 'react-refresh': reactRefresh,
19
+ },
20
+ rules: {
21
+ ...reactHooks.configs.recommended.rules,
22
+ 'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
23
+ // Add single quotes rule for JavaScript
24
+ quotes: ['error', 'single'],
25
+ // Add JSX quotes rule if needed
26
+ 'jsx-quotes': ['error', 'prefer-single'],
27
+ },
28
+ },
29
+ // Add TypeScript-specific rules in a separate config object
30
+ {
31
+ files: ['**/*.{ts,tsx}'],
32
+ rules: {
33
+ // TypeScript-specific rules
34
+ quotes: ['error', 'single'],
35
+ },
36
+ }
37
+ );
package/index.html ADDED
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Vite + React + TS</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
package/jest.config.ts ADDED
@@ -0,0 +1,79 @@
1
+ import type { JestConfigWithTsJest } from 'ts-jest';
2
+
3
+ const config: JestConfigWithTsJest = {
4
+ preset: 'ts-jest/presets/default-esm',
5
+
6
+ testEnvironment: 'jsdom',
7
+
8
+ testPathIgnorePatterns: [
9
+ '/node_modules/',
10
+ '/e2e/',
11
+ 'node_modules/(?!(apollo-upload-client|@apollo/client)/)',
12
+ ],
13
+ setupFilesAfterEnv: ['./jest.setup.tsx'], // reference setup file here
14
+ // Module name mapping for path aliases
15
+ moduleNameMapper: {
16
+ // Handle ES module imports in source code only (not node_modules)
17
+ '^(\\.{1,2}/.*)\\.js$': '$1',
18
+ // Handle static assets
19
+ '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
20
+ '\\.svg$': '<rootDir>/__mocks__/svgMock.ts',
21
+ '\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
22
+ 'jest-transform-stub',
23
+ // Mock env file to avoid import.meta issues (must come before generic @/ mapping)
24
+ '^@/env$': '<rootDir>/src/mocks/env.ts',
25
+ // Path aliases (generic mapping must come last)
26
+ '^@/(.*)$': '<rootDir>/src/$1',
27
+ },
28
+
29
+ // Transform files
30
+ transform: {
31
+ '^.+\\.(js|jsx|ts|tsx)$': [
32
+ 'ts-jest',
33
+ {
34
+ useESM: true,
35
+ tsconfig: {
36
+ jsx: 'react-jsx',
37
+ },
38
+ },
39
+ ],
40
+ // Transform CSS files to empty objects
41
+ '\\.(css|less|scss|sass)$': 'jest-transform-stub',
42
+ '\\.(mp3|wav|ogg|m4a|aac|flac)$': 'jest-transform-stub',
43
+ },
44
+
45
+ // Transform ignore patterns - let Jest handle ES modules properly
46
+ transformIgnorePatterns: ['node_modules/(?!(@tanstack|@apollo|react-day-picker|date-fns)/)'],
47
+
48
+ // File extensions to consider
49
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
50
+
51
+ // Coverage configuration
52
+ collectCoverageFrom: [
53
+ 'src/**/*.{ts,tsx}',
54
+ '!src/**/*.d.ts',
55
+ '!src/**/*.stories.{ts,tsx}',
56
+ '!src/index.tsx',
57
+ '!src/reportWebVitals.ts',
58
+ ],
59
+
60
+ // Coverage thresholds
61
+ coverageThreshold: {
62
+ global: {
63
+ branches: 70,
64
+ functions: 70,
65
+ lines: 70,
66
+ statements: 70,
67
+ },
68
+ },
69
+
70
+ // Additional Jest options for modern React
71
+ testEnvironmentOptions: {
72
+ customExportConditions: ['node', 'node-addons'],
73
+ },
74
+
75
+ // Handle ES modules
76
+ extensionsToTreatAsEsm: ['.ts', '.tsx'],
77
+ };
78
+
79
+ export default config;