@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.
- package/.changeset/README.md +8 -0
- package/.changeset/config.json +11 -0
- package/.dockerignore +9 -0
- package/.env.sample +22 -0
- package/.husky/pre-commit +7 -0
- package/.prettierignore +5 -0
- package/.prettierrc +9 -0
- package/.storybook/main.ts +41 -0
- package/.storybook/preview-head.html +3 -0
- package/.storybook/preview.ts +53 -0
- package/Dockerfile +58 -0
- package/Dockerfile.dev +11 -0
- package/README.md +130 -0
- package/__mocks__/fileMock.ts +1 -0
- package/__mocks__/svgMock.ts +1 -0
- package/babel.config.js +46 -0
- package/bitbucket-pipelines.yml +70 -0
- package/components.json +21 -0
- package/e2e/example.spec.ts +18 -0
- package/eslint.config.mjs +37 -0
- package/index.html +13 -0
- package/jest.config.ts +79 -0
- package/jest.setup.tsx +276 -0
- package/lint-staged.config.js +45 -0
- package/package.json +167 -0
- package/playwright.config.ts +79 -0
- package/plop-templates/Component.tsx.hbs +13 -0
- package/plop-templates/ComponentStories.tsx.hbs +24 -0
- package/plop-templates/ComponentTests.tsx.hbs +15 -0
- package/plop-templates/ComponentTypes.ts.hbs +1 -0
- package/plopfile.js +35 -0
- package/setupTests.ts +1 -0
- package/src/assets/dashboard/book.svg +6 -0
- package/src/assets/dashboard/edit.svg +5 -0
- package/src/assets/dashboard/emerald.svg +9 -0
- package/src/assets/dashboard/eye.svg +4 -0
- package/src/assets/dashboard/gold.svg +9 -0
- package/src/assets/dashboard/percentage-square.svg +6 -0
- package/src/assets/dashboard/sapphire.svg +9 -0
- package/src/assets/dashboard/send-2.svg +4 -0
- package/src/assets/desktop.svg +7 -0
- package/src/assets/fonts/UniversalFeature/FeatureJungle-Light.otf +0 -0
- package/src/assets/fonts/UniversalFeature/FeatureJungle-Light.woff +0 -0
- package/src/assets/fonts/UniversalFeature/FeatureJungle-Light.woff2 +0 -0
- package/src/assets/fonts/UniversalFeature/FeatureJungle-Regular.otf +0 -0
- package/src/assets/fonts/UniversalFeature/FeatureJungle-Regular.woff +0 -0
- package/src/assets/fonts/UniversalFeature/FeatureJungle-Regular.woff2 +0 -0
- package/src/assets/fonts/UniversalJungle/UniversalJungle-420.otf +0 -0
- package/src/assets/fonts/UniversalJungle/UniversalJungle-420.woff +0 -0
- package/src/assets/fonts/UniversalJungle/UniversalJungle-420.woff2 +0 -0
- package/src/assets/fonts/UniversalJungle/UniversalJungle-515.otf +0 -0
- package/src/assets/fonts/UniversalJungle/UniversalJungle-515.woff +0 -0
- package/src/assets/fonts/UniversalJungle/UniversalJungle-515.woff2 +0 -0
- package/src/assets/instagram.svg +9 -0
- package/src/assets/mobile.svg +4 -0
- package/src/assets/no-data-image.svg +41 -0
- package/src/assets/no-image-icon.svg +84 -0
- package/src/assets/pexels.svg +9 -0
- package/src/assets/react.svg +1 -0
- package/src/assets/sounds/draft.mp3 +0 -0
- package/src/assets/sounds/error.mp3 +0 -0
- package/src/assets/sounds/publish.mp3 +0 -0
- package/src/assets/tablet.svg +4 -0
- package/src/assets/unsplash.svg +3 -0
- package/src/assets/upload-image.svg +43 -0
- package/src/assets/user.svg +4 -0
- package/src/components/shadcn/index.ts +31 -0
- package/src/config/env.ts +15 -0
- package/src/contexts/ThemeContext.tsx +11 -0
- package/src/data/users.json +6014 -0
- package/src/decorators/ActionModalDecorator.tsx +10 -0
- package/src/decorators/ApolloDecorator.tsx +19 -0
- package/src/decorators/DolosApolloDecorator.tsx +31 -0
- package/src/decorators/JestDecorators.tsx +34 -0
- package/src/decorators/ReactQueryDecorator.tsx +13 -0
- package/src/decorators/RouterDecorator.tsx +5 -0
- package/src/decorators/UnsafePropsDecorator.tsx +0 -0
- package/src/env.ts +99 -0
- package/src/hooks/use-autogrow.ts +28 -0
- package/src/hooks/use-mobile.ts +19 -0
- package/src/hooks/useAuthors.ts +78 -0
- package/src/hooks/useDebounce.ts +18 -0
- package/src/hooks/useMercuryProjectToken.ts +112 -0
- package/src/hooks/useProjectToken.ts +21 -0
- package/src/hooks/useTheme.ts +12 -0
- package/src/index.css +397 -0
- package/src/index.ts +59 -0
- package/src/mocks/env.ts +12 -0
- package/src/providers/QueryProvider/index.tsx +10 -0
- package/src/providers/ThemeProvider/index.tsx +52 -0
- package/src/types/category.types.ts +13 -0
- package/src/types/image.types.ts +44 -0
- package/src/types/post.types.ts +121 -0
- package/src/types/theme.types.ts +10 -0
- package/src/types/users.types.ts +5 -0
- package/src/utils/apolloClient.ts +160 -0
- package/src/utils/articleMetadata.ts +92 -0
- package/src/utils/audio.ts +10 -0
- package/src/utils/imageProcessing.ts +399 -0
- package/src/utils/images.ts +279 -0
- package/src/utils/mercury.ts +0 -0
- package/src/utils/utils.ts +638 -0
- package/src/utils/videos.ts +29 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.app.json +30 -0
- package/tsconfig.json +32 -0
- package/tsconfig.node.json +24 -0
- package/tsconfig.tsbuildinfo +1 -0
- 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
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=
|
package/.prettierignore
ADDED
package/.prettierrc
ADDED
|
@@ -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,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
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';
|
package/babel.config.js
ADDED
|
@@ -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
|
package/components.json
ADDED
|
@@ -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;
|