@shipfox/react-ui 0.4.0 → 0.6.0
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/.storybook/main.ts +20 -10
- package/.storybook/preview.tsx +11 -0
- package/.storybook/vitest.setup.ts +4 -0
- package/.turbo/turbo-build.log +16 -3
- package/.turbo/turbo-check.log +2 -2
- package/.turbo/turbo-type.log +1 -1
- package/CHANGELOG.md +15 -0
- package/README.md +56 -1
- package/argos.config.ts +33 -0
- package/dist/build-css-entry.js +5 -0
- package/dist/build-css-entry.js.map +1 -0
- package/dist/components/button/button-link.d.ts +14 -0
- package/dist/components/button/button-link.d.ts.map +1 -0
- package/dist/components/button/button-link.js +63 -0
- package/dist/components/button/button-link.js.map +1 -0
- package/dist/components/button/button-link.stories.js +127 -0
- package/dist/components/button/button-link.stories.js.map +1 -0
- package/dist/components/button/button.d.ts +1 -1
- package/dist/components/button/button.d.ts.map +1 -1
- package/dist/components/button/button.js +7 -6
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/button/button.stories.js +1 -13
- package/dist/components/button/button.stories.js.map +1 -1
- package/dist/components/button/icon-button.d.ts +14 -0
- package/dist/components/button/icon-button.d.ts.map +1 -0
- package/dist/components/button/icon-button.js +53 -0
- package/dist/components/button/icon-button.js.map +1 -0
- package/dist/components/button/icon-button.stories.js +254 -0
- package/dist/components/button/icon-button.stories.js.map +1 -0
- package/dist/components/button/index.d.ts +2 -0
- package/dist/components/button/index.d.ts.map +1 -1
- package/dist/components/button/index.js +2 -0
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/code-block/code-block-footer.d.ts.map +1 -1
- package/dist/components/code-block/code-block-footer.js +29 -15
- package/dist/components/code-block/code-block-footer.js.map +1 -1
- package/dist/components/code-block/code-content.d.ts.map +1 -1
- package/dist/components/code-block/code-content.js +2 -2
- package/dist/components/code-block/code-content.js.map +1 -1
- package/dist/components/dynamic-item/dynamic-item.stories.js +1 -1
- package/dist/components/dynamic-item/dynamic-item.stories.js.map +1 -1
- package/dist/components/icon/icon.d.ts +3 -0
- package/dist/components/icon/icon.d.ts.map +1 -1
- package/dist/components/icon/icon.js +5 -2
- package/dist/components/icon/icon.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/modal/index.d.ts +3 -0
- package/dist/components/modal/index.d.ts.map +1 -0
- package/dist/components/modal/index.js +3 -0
- package/dist/components/modal/index.js.map +1 -0
- package/dist/components/modal/modal.d.ts +37 -0
- package/dist/components/modal/modal.d.ts.map +1 -0
- package/dist/components/modal/modal.js +262 -0
- package/dist/components/modal/modal.js.map +1 -0
- package/dist/components/modal/modal.stories.js +497 -0
- package/dist/components/modal/modal.stories.js.map +1 -0
- package/dist/components/moving-border/index.d.ts +2 -0
- package/dist/components/moving-border/index.d.ts.map +1 -0
- package/dist/components/moving-border/index.js +3 -0
- package/dist/components/moving-border/index.js.map +1 -0
- package/dist/components/typography/text.d.ts.map +1 -1
- package/dist/components/typography/text.js +1 -1
- package/dist/components/typography/text.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useMediaQuery.d.ts +2 -0
- package/dist/hooks/useMediaQuery.d.ts.map +1 -0
- package/dist/hooks/useMediaQuery.js +74 -0
- package/dist/hooks/useMediaQuery.js.map +1 -0
- package/dist/onboarding/sign-in.stories.js +93 -0
- package/dist/onboarding/sign-in.stories.js.map +1 -0
- package/dist/styles.css +1 -0
- package/index.css +30 -4
- package/package.json +19 -7
- package/src/build-css-entry.ts +3 -0
- package/src/components/button/button-link.stories.tsx +86 -0
- package/src/components/button/button-link.tsx +76 -0
- package/src/components/button/button.stories.tsx +1 -7
- package/src/components/button/button.tsx +8 -6
- package/src/components/button/icon-button.stories.tsx +182 -0
- package/src/components/button/icon-button.tsx +69 -0
- package/src/components/button/index.ts +2 -0
- package/src/components/code-block/code-block-footer.tsx +37 -30
- package/src/components/code-block/code-content.tsx +5 -2
- package/src/components/dynamic-item/dynamic-item.stories.tsx +1 -1
- package/src/components/icon/icon.tsx +6 -0
- package/src/components/index.ts +1 -0
- package/src/components/modal/index.ts +23 -0
- package/src/components/modal/modal.stories.tsx +384 -0
- package/src/components/modal/modal.tsx +309 -0
- package/src/components/moving-border/index.ts +1 -0
- package/src/components/typography/text.tsx +9 -1
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useMediaQuery.ts +87 -0
- package/src/onboarding/sign-in.stories.tsx +73 -0
- package/tsconfig.build.json +7 -1
- package/vite.css.config.ts +30 -0
- package/vitest.config.ts +30 -3
|
@@ -24,7 +24,15 @@ export type TextProps = PropsWithChildren<HTMLAttributes<HTMLParagraphElement>>
|
|
|
24
24
|
bold?: boolean;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
export function Text({
|
|
27
|
+
export function Text({
|
|
28
|
+
children,
|
|
29
|
+
className,
|
|
30
|
+
size,
|
|
31
|
+
as,
|
|
32
|
+
compact = true,
|
|
33
|
+
bold = false,
|
|
34
|
+
...props
|
|
35
|
+
}: TextProps) {
|
|
28
36
|
const Component = as ?? 'p';
|
|
29
37
|
return (
|
|
30
38
|
<Component
|
package/src/hooks/index.ts
CHANGED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {useEffect, useState} from 'react';
|
|
2
|
+
|
|
3
|
+
class MediaQueryManager {
|
|
4
|
+
private queries = new Map<string, MediaQueryList>();
|
|
5
|
+
private listeners = new Map<string, Set<() => void>>();
|
|
6
|
+
private changeHandlers = new Map<string, () => void>();
|
|
7
|
+
|
|
8
|
+
getMatches(query: string): boolean {
|
|
9
|
+
if (typeof window === 'undefined') return false;
|
|
10
|
+
|
|
11
|
+
if (!this.queries.has(query)) {
|
|
12
|
+
this.queries.set(query, window.matchMedia(query));
|
|
13
|
+
this.listeners.set(query, new Set());
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const mediaQuery = this.queries.get(query);
|
|
17
|
+
return mediaQuery ? mediaQuery.matches : false;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
subscribe(query: string, callback: () => void): () => void {
|
|
21
|
+
if (typeof window === 'undefined') {
|
|
22
|
+
return () => {
|
|
23
|
+
// Cleanup function for SSR - no-op
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!this.queries.has(query)) {
|
|
28
|
+
this.queries.set(query, window.matchMedia(query));
|
|
29
|
+
this.listeners.set(query, new Set());
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const mediaQuery = this.queries.get(query);
|
|
33
|
+
const listeners = this.listeners.get(query);
|
|
34
|
+
|
|
35
|
+
if (!mediaQuery || !listeners) {
|
|
36
|
+
return () => {
|
|
37
|
+
// Cleanup function - no-op if query wasn't found
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
listeners.add(callback);
|
|
42
|
+
|
|
43
|
+
if (listeners.size === 1) {
|
|
44
|
+
const changeHandler = () => {
|
|
45
|
+
for (const cb of listeners) {
|
|
46
|
+
cb();
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
this.changeHandlers.set(query, changeHandler);
|
|
50
|
+
mediaQuery.addEventListener('change', changeHandler);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return () => {
|
|
54
|
+
listeners.delete(callback);
|
|
55
|
+
|
|
56
|
+
if (listeners.size === 0) {
|
|
57
|
+
const changeHandler = this.changeHandlers.get(query);
|
|
58
|
+
if (changeHandler) {
|
|
59
|
+
mediaQuery.removeEventListener('change', changeHandler);
|
|
60
|
+
this.changeHandlers.delete(query);
|
|
61
|
+
}
|
|
62
|
+
this.queries.delete(query);
|
|
63
|
+
this.listeners.delete(query);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const mediaQueryManager = new MediaQueryManager();
|
|
70
|
+
|
|
71
|
+
export function useMediaQuery(query: string): boolean {
|
|
72
|
+
const [matches, setMatches] = useState(() => mediaQueryManager.getMatches(query));
|
|
73
|
+
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
const updateMatches = () => {
|
|
76
|
+
setMatches(mediaQueryManager.getMatches(query));
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const unsubscribe = mediaQueryManager.subscribe(query, updateMatches);
|
|
80
|
+
|
|
81
|
+
updateMatches();
|
|
82
|
+
|
|
83
|
+
return unsubscribe;
|
|
84
|
+
}, [query]);
|
|
85
|
+
|
|
86
|
+
return matches;
|
|
87
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {argosScreenshot} from '@argos-ci/storybook/vitest';
|
|
2
|
+
import type {Meta, StoryObj} from '@storybook/react';
|
|
3
|
+
import {Avatar} from 'components/avatar';
|
|
4
|
+
import {Button} from 'components/button';
|
|
5
|
+
import {Header, Text} from 'components/typography';
|
|
6
|
+
|
|
7
|
+
const meta = {
|
|
8
|
+
title: 'Onboarding/Signin',
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: 'fullscreen',
|
|
11
|
+
},
|
|
12
|
+
} satisfies Meta;
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
type Story = StoryObj<typeof meta>;
|
|
16
|
+
|
|
17
|
+
export const Default: Story = {
|
|
18
|
+
play: async (ctx) => {
|
|
19
|
+
await argosScreenshot(ctx, 'example-screenshot');
|
|
20
|
+
},
|
|
21
|
+
render: () => {
|
|
22
|
+
return (
|
|
23
|
+
<div className="flex min-h-screen items-center justify-center bg-background-subtle-base">
|
|
24
|
+
{/* Background illustration - simplified decorative element */}
|
|
25
|
+
<div className="pointer-events-none absolute left-1/2 top-0 -translate-x-1/2 -translate-y-[120px]">
|
|
26
|
+
<div
|
|
27
|
+
className="h-[332px] w-[800px] opacity-20"
|
|
28
|
+
style={{
|
|
29
|
+
backgroundImage: `radial-gradient(circle, rgba(255, 75, 0, 0.3) 1px, transparent 1px)`,
|
|
30
|
+
backgroundSize: '24px 24px',
|
|
31
|
+
backgroundPosition: '-80px 31px',
|
|
32
|
+
}}
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
{/* Main content */}
|
|
37
|
+
<div className="relative flex w-full max-w-[384px] flex-col items-center gap-32 px-24 pb-80 pt-24">
|
|
38
|
+
{/* Logo and title section */}
|
|
39
|
+
<div className="flex flex-col items-center gap-16">
|
|
40
|
+
<Avatar content="logo" size="xl" radius="rounded" logoName="shipfox" />
|
|
41
|
+
<div className="flex min-w-[128px] flex-col items-center gap-4 text-center">
|
|
42
|
+
<Header
|
|
43
|
+
variant="h1"
|
|
44
|
+
className="text-[28px] font-medium leading-[44px] text-foreground-neutral-base"
|
|
45
|
+
>
|
|
46
|
+
Connect to Shipfox
|
|
47
|
+
</Header>
|
|
48
|
+
<Text
|
|
49
|
+
size="sm"
|
|
50
|
+
className="text-sm font-normal leading-[24px] text-foreground-neutral-subtle"
|
|
51
|
+
>
|
|
52
|
+
Log in to access Shipfox.
|
|
53
|
+
</Text>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
{/* Action buttons */}
|
|
58
|
+
<div className="flex w-full flex-col gap-20">
|
|
59
|
+
<Button variant="primary" size="md" iconLeft="google" className="w-full">
|
|
60
|
+
Continue with Google
|
|
61
|
+
</Button>
|
|
62
|
+
<Button variant="primary" size="md" iconLeft="microsoft" className="w-full">
|
|
63
|
+
Continue with Microsoft
|
|
64
|
+
</Button>
|
|
65
|
+
<Button variant="transparent" size="md" className="w-full">
|
|
66
|
+
Connect with Enterprise SSO
|
|
67
|
+
</Button>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
},
|
|
73
|
+
};
|
package/tsconfig.build.json
CHANGED
|
@@ -9,5 +9,11 @@
|
|
|
9
9
|
"types": ["@shipfox/vite/client"]
|
|
10
10
|
},
|
|
11
11
|
"include": ["src"],
|
|
12
|
-
"exclude": [
|
|
12
|
+
"exclude": [
|
|
13
|
+
"**/*.test.tsx",
|
|
14
|
+
"**/*.test.ts",
|
|
15
|
+
"**/*.stories.tsx",
|
|
16
|
+
"**/*.stories.ts",
|
|
17
|
+
"**/build-css-entry.ts"
|
|
18
|
+
]
|
|
13
19
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {dirname, resolve} from 'node:path';
|
|
2
|
+
import {fileURLToPath} from 'node:url';
|
|
3
|
+
import {defineConfig} from '@shipfox/vite';
|
|
4
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
5
|
+
import react from '@vitejs/plugin-react';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
|
|
10
|
+
export default defineConfig(
|
|
11
|
+
{
|
|
12
|
+
plugins: [react(), tailwindcss()],
|
|
13
|
+
build: {
|
|
14
|
+
outDir: 'dist',
|
|
15
|
+
emptyOutDir: false,
|
|
16
|
+
cssCodeSplit: false,
|
|
17
|
+
rollupOptions: {
|
|
18
|
+
input: resolve(__dirname, 'src/build-css-entry.ts'),
|
|
19
|
+
output: {
|
|
20
|
+
entryFileNames: 'css-entry.js',
|
|
21
|
+
assetFileNames: 'styles.css',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
css: {
|
|
26
|
+
minify: true,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
import.meta.url,
|
|
30
|
+
);
|
package/vitest.config.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import {fileURLToPath} from 'node:url';
|
|
3
|
+
import {argosVitestPlugin} from '@argos-ci/storybook/vitest-plugin';
|
|
1
4
|
import {defineConfig} from '@shipfox/vitest';
|
|
5
|
+
import {storybookTest} from '@storybook/addon-vitest/vitest-plugin';
|
|
2
6
|
import tailwindcss from '@tailwindcss/vite';
|
|
3
7
|
import react from '@vitejs/plugin-react';
|
|
8
|
+
import {playwright} from '@vitest/browser-playwright';
|
|
9
|
+
|
|
10
|
+
const dirname =
|
|
11
|
+
typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url));
|
|
4
12
|
|
|
5
13
|
// https://vitejs.dev/config/
|
|
6
14
|
export default defineConfig(
|
|
@@ -8,9 +16,28 @@ export default defineConfig(
|
|
|
8
16
|
plugins: [react(), tailwindcss()],
|
|
9
17
|
css: {},
|
|
10
18
|
test: {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
19
|
+
projects: [
|
|
20
|
+
{
|
|
21
|
+
extends: true,
|
|
22
|
+
plugins: [
|
|
23
|
+
storybookTest({configDir: path.join(dirname, '.storybook')}),
|
|
24
|
+
argosVitestPlugin({
|
|
25
|
+
uploadToArgos: !!process.env.CI,
|
|
26
|
+
token: process.env.ARGOS_TOKEN,
|
|
27
|
+
}),
|
|
28
|
+
],
|
|
29
|
+
test: {
|
|
30
|
+
name: 'storybook',
|
|
31
|
+
browser: {
|
|
32
|
+
enabled: true,
|
|
33
|
+
headless: true,
|
|
34
|
+
provider: playwright(),
|
|
35
|
+
instances: [{browser: 'chromium'}],
|
|
36
|
+
},
|
|
37
|
+
setupFiles: ['.storybook/vitest.setup.ts'],
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
],
|
|
14
41
|
},
|
|
15
42
|
},
|
|
16
43
|
import.meta.url,
|