@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
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type {Meta, StoryObj} from '@storybook/react';
|
|
2
|
+
import {ButtonLink} from './button-link';
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Components/Button/ButtonLink',
|
|
6
|
+
component: ButtonLink,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
argTypes: {
|
|
9
|
+
variant: {
|
|
10
|
+
control: 'select',
|
|
11
|
+
options: ['base', 'interactive', 'muted', 'subtle'],
|
|
12
|
+
},
|
|
13
|
+
size: {
|
|
14
|
+
control: 'select',
|
|
15
|
+
options: ['xs', 'sm', 'md', 'xl'],
|
|
16
|
+
},
|
|
17
|
+
underline: {control: 'boolean'},
|
|
18
|
+
asChild: {control: 'boolean'},
|
|
19
|
+
},
|
|
20
|
+
args: {
|
|
21
|
+
children: 'Label',
|
|
22
|
+
variant: 'base',
|
|
23
|
+
size: 'sm',
|
|
24
|
+
underline: false,
|
|
25
|
+
href: '#',
|
|
26
|
+
},
|
|
27
|
+
} satisfies Meta<typeof ButtonLink>;
|
|
28
|
+
|
|
29
|
+
export default meta;
|
|
30
|
+
type Story = StoryObj<typeof meta>;
|
|
31
|
+
|
|
32
|
+
export const Default: Story = {};
|
|
33
|
+
|
|
34
|
+
export const Variants: Story = {
|
|
35
|
+
render: (args) => (
|
|
36
|
+
<div className="flex gap-16 items-center">
|
|
37
|
+
<ButtonLink {...args} variant="base">
|
|
38
|
+
Base
|
|
39
|
+
</ButtonLink>
|
|
40
|
+
<ButtonLink {...args} variant="interactive">
|
|
41
|
+
Interactive
|
|
42
|
+
</ButtonLink>
|
|
43
|
+
<ButtonLink {...args} variant="muted">
|
|
44
|
+
Muted
|
|
45
|
+
</ButtonLink>
|
|
46
|
+
<ButtonLink {...args} variant="subtle">
|
|
47
|
+
Subtle
|
|
48
|
+
</ButtonLink>
|
|
49
|
+
</div>
|
|
50
|
+
),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const WithUnderline: Story = {
|
|
54
|
+
render: (args) => (
|
|
55
|
+
<div className="flex gap-16 items-center">
|
|
56
|
+
<ButtonLink {...args} variant="base" underline>
|
|
57
|
+
Base
|
|
58
|
+
</ButtonLink>
|
|
59
|
+
<ButtonLink {...args} variant="interactive" underline>
|
|
60
|
+
Interactive
|
|
61
|
+
</ButtonLink>
|
|
62
|
+
<ButtonLink {...args} variant="muted" underline>
|
|
63
|
+
Muted
|
|
64
|
+
</ButtonLink>
|
|
65
|
+
<ButtonLink {...args} variant="subtle" underline>
|
|
66
|
+
Subtle
|
|
67
|
+
</ButtonLink>
|
|
68
|
+
</div>
|
|
69
|
+
),
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const WithIcons: Story = {
|
|
73
|
+
render: (args) => (
|
|
74
|
+
<div className="flex gap-16 items-center">
|
|
75
|
+
<ButtonLink {...args} iconLeft="addLine">
|
|
76
|
+
Icon Left
|
|
77
|
+
</ButtonLink>
|
|
78
|
+
<ButtonLink {...args} iconRight="chevronRight">
|
|
79
|
+
Icon Right
|
|
80
|
+
</ButtonLink>
|
|
81
|
+
<ButtonLink {...args} iconLeft="addLine" iconRight="chevronRight">
|
|
82
|
+
Both Icons
|
|
83
|
+
</ButtonLink>
|
|
84
|
+
</div>
|
|
85
|
+
),
|
|
86
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {Slot} from '@radix-ui/react-slot';
|
|
2
|
+
import {cva, type VariantProps} from 'class-variance-authority';
|
|
3
|
+
import {Icon, type IconName} from 'components/icon';
|
|
4
|
+
import type {ComponentProps} from 'react';
|
|
5
|
+
import {cn} from 'utils/cn';
|
|
6
|
+
|
|
7
|
+
export const buttonLinkVariants = cva(
|
|
8
|
+
'inline-flex items-center justify-center gap-4 whitespace-nowrap transition-colors disabled:pointer-events-none outline-none font-medium',
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
base: 'text-foreground-neutral-base hover:text-foreground-neutral-base focus-visible:text-foreground-neutral-base disabled:text-foreground-neutral-disabled',
|
|
13
|
+
interactive:
|
|
14
|
+
'text-foreground-highlight-interactive hover:text-foreground-highlight-interactive-hover focus-visible:text-foreground-highlight-interactive disabled:text-foreground-neutral-disabled',
|
|
15
|
+
muted:
|
|
16
|
+
'text-foreground-neutral-muted hover:text-foreground-neutral-base focus-visible:text-foreground-neutral-base disabled:text-foreground-neutral-disabled',
|
|
17
|
+
subtle:
|
|
18
|
+
'text-foreground-neutral-subtle hover:text-foreground-neutral-base focus-visible:text-foreground-neutral-base disabled:text-foreground-neutral-disabled',
|
|
19
|
+
},
|
|
20
|
+
size: {
|
|
21
|
+
xs: 'text-xs',
|
|
22
|
+
sm: 'text-sm',
|
|
23
|
+
md: 'text-md',
|
|
24
|
+
xl: 'text-xl',
|
|
25
|
+
},
|
|
26
|
+
underline: {
|
|
27
|
+
true: 'underline decoration-solid [text-underline-position:from-font]',
|
|
28
|
+
false: '',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
defaultVariants: {
|
|
32
|
+
variant: 'base',
|
|
33
|
+
size: 'sm',
|
|
34
|
+
underline: false,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const iconSizeMap = {
|
|
40
|
+
xs: 14,
|
|
41
|
+
sm: 14,
|
|
42
|
+
md: 16,
|
|
43
|
+
xl: 20,
|
|
44
|
+
} as const;
|
|
45
|
+
|
|
46
|
+
export function ButtonLink({
|
|
47
|
+
className,
|
|
48
|
+
variant,
|
|
49
|
+
size = 'sm',
|
|
50
|
+
underline,
|
|
51
|
+
asChild = false,
|
|
52
|
+
children,
|
|
53
|
+
iconLeft,
|
|
54
|
+
iconRight,
|
|
55
|
+
...props
|
|
56
|
+
}: ComponentProps<'a'> &
|
|
57
|
+
VariantProps<typeof buttonLinkVariants> & {
|
|
58
|
+
asChild?: boolean;
|
|
59
|
+
iconLeft?: IconName;
|
|
60
|
+
iconRight?: IconName;
|
|
61
|
+
}) {
|
|
62
|
+
const Comp = asChild ? Slot : 'a';
|
|
63
|
+
const iconSize = iconSizeMap[size as keyof typeof iconSizeMap];
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<Comp
|
|
67
|
+
data-slot="button-link"
|
|
68
|
+
className={cn(buttonLinkVariants({variant, size, underline, className}))}
|
|
69
|
+
{...props}
|
|
70
|
+
>
|
|
71
|
+
{iconLeft && <Icon name={iconLeft} size={iconSize} />}
|
|
72
|
+
{children}
|
|
73
|
+
{iconRight && <Icon name={iconRight} size={iconSize} />}
|
|
74
|
+
</Comp>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
@@ -6,6 +6,7 @@ const variantOptions = [
|
|
|
6
6
|
'primary',
|
|
7
7
|
'secondary',
|
|
8
8
|
'danger',
|
|
9
|
+
'success',
|
|
9
10
|
'transparent',
|
|
10
11
|
'transparentMuted',
|
|
11
12
|
] as const;
|
|
@@ -48,7 +49,6 @@ export const Variants: Story = {
|
|
|
48
49
|
<th>{size}</th>
|
|
49
50
|
<th>Default</th>
|
|
50
51
|
<th>Hover</th>
|
|
51
|
-
<th>Active</th>
|
|
52
52
|
<th>Focus</th>
|
|
53
53
|
<th>Disabled</th>
|
|
54
54
|
</tr>
|
|
@@ -71,11 +71,6 @@ export const Variants: Story = {
|
|
|
71
71
|
Click me
|
|
72
72
|
</Button>
|
|
73
73
|
</td>
|
|
74
|
-
<td>
|
|
75
|
-
<Button {...args} variant={variant} className="active" size={size}>
|
|
76
|
-
Click me
|
|
77
|
-
</Button>
|
|
78
|
-
</td>
|
|
79
74
|
<td>
|
|
80
75
|
<Button {...args} variant={variant} className="focus" size={size}>
|
|
81
76
|
Click me
|
|
@@ -98,7 +93,6 @@ export const Variants: Story = {
|
|
|
98
93
|
Variants.parameters = {
|
|
99
94
|
pseudo: {
|
|
100
95
|
hover: '.hover',
|
|
101
|
-
active: '.active',
|
|
102
96
|
focusVisible: '.focus',
|
|
103
97
|
},
|
|
104
98
|
};
|
|
@@ -15,18 +15,20 @@ export const buttonVariants = cva(
|
|
|
15
15
|
'bg-background-button-neutral-default text-foreground-neutral-base shadow-button-neutral hover:bg-background-button-neutral-hover active:bg-background-button-neutral-pressed disabled:bg-background-neutral-disabled focus-visible:shadow-button-neutral-focus disabled:text-foreground-neutral-disabled disabled:shadow-none',
|
|
16
16
|
danger:
|
|
17
17
|
'bg-background-button-danger-default text-foreground-neutral-on-color shadow-button-danger hover:bg-background-button-danger-hover active:bg-background-button-danger-pressed focus-visible:shadow-button-danger-focus disabled:bg-background-neutral-disabled disabled:text-foreground-neutral-disabled disabled:shadow-none',
|
|
18
|
+
success:
|
|
19
|
+
'bg-background-button-success-default text-foreground-neutral-on-color shadow-button-success hover:bg-background-button-success-hover active:bg-background-button-success-pressed focus-visible:shadow-button-success-focus disabled:bg-background-neutral-disabled disabled:text-foreground-neutral-disabled disabled:shadow-none',
|
|
18
20
|
transparent:
|
|
19
21
|
'bg-background-button-transparent-default text-foreground-neutral-base hover:bg-background-button-transparent-hover active:bg-background-button-transparent-pressed focus-visible:shadow-button-neutral-focus disabled:text-foreground-neutral-disabled',
|
|
20
22
|
transparentMuted:
|
|
21
23
|
'bg-background-button-transparent-default text-foreground-neutral-muted hover:bg-background-button-transparent-hover active:bg-background-button-transparent-pressed focus-visible:shadow-button-neutral-focus disabled:text-foreground-neutral-disabled',
|
|
22
24
|
},
|
|
23
25
|
size: {
|
|
24
|
-
'2xs': 'px-6 text-xs gap-4',
|
|
25
|
-
xs: 'px-6
|
|
26
|
-
sm: 'px-8
|
|
27
|
-
md: 'px-10
|
|
28
|
-
lg: 'px-12
|
|
29
|
-
xl: 'px-12
|
|
26
|
+
'2xs': 'h-20 px-6 text-xs gap-4',
|
|
27
|
+
xs: 'h-24 px-6 text-xs gap-4',
|
|
28
|
+
sm: 'h-28 px-8 text-sm gap-6',
|
|
29
|
+
md: 'h-32 px-10 text-md gap-8',
|
|
30
|
+
lg: 'h-36 px-12 text-lg gap-8',
|
|
31
|
+
xl: 'h-40 px-12 text-xl gap-10',
|
|
30
32
|
},
|
|
31
33
|
},
|
|
32
34
|
defaultVariants: {
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type {Meta, StoryObj} from '@storybook/react';
|
|
2
|
+
import {Code} from 'components/typography';
|
|
3
|
+
import {IconButton} from './icon-button';
|
|
4
|
+
|
|
5
|
+
const variantOptions = ['primary', 'transparent'] as const;
|
|
6
|
+
const sizeOptions = ['2xs', 'xs', 'sm', 'md', 'lg', 'xl'] as const;
|
|
7
|
+
const radiusOptions = ['rounded', 'full'] as const;
|
|
8
|
+
|
|
9
|
+
const meta = {
|
|
10
|
+
title: 'Components/Button/IconButton',
|
|
11
|
+
component: IconButton,
|
|
12
|
+
tags: ['autodocs'],
|
|
13
|
+
argTypes: {
|
|
14
|
+
variant: {
|
|
15
|
+
control: 'select',
|
|
16
|
+
options: variantOptions,
|
|
17
|
+
},
|
|
18
|
+
size: {
|
|
19
|
+
control: 'select',
|
|
20
|
+
options: sizeOptions,
|
|
21
|
+
},
|
|
22
|
+
radius: {
|
|
23
|
+
control: 'select',
|
|
24
|
+
options: radiusOptions,
|
|
25
|
+
},
|
|
26
|
+
muted: {control: 'boolean'},
|
|
27
|
+
asChild: {control: 'boolean'},
|
|
28
|
+
},
|
|
29
|
+
args: {
|
|
30
|
+
icon: 'addLine',
|
|
31
|
+
variant: 'primary',
|
|
32
|
+
size: 'md',
|
|
33
|
+
radius: 'rounded',
|
|
34
|
+
muted: false,
|
|
35
|
+
},
|
|
36
|
+
} satisfies Meta<typeof IconButton>;
|
|
37
|
+
|
|
38
|
+
export default meta;
|
|
39
|
+
type Story = StoryObj<typeof meta>;
|
|
40
|
+
|
|
41
|
+
export const Default: Story = {};
|
|
42
|
+
|
|
43
|
+
export const Variants: Story = {
|
|
44
|
+
render: (args) => (
|
|
45
|
+
<div className="flex flex-col gap-32">
|
|
46
|
+
{sizeOptions.map((size) => (
|
|
47
|
+
<div key={size} className="flex flex-col gap-16">
|
|
48
|
+
<Code variant="label" className="text-foreground-neutral-subtle">
|
|
49
|
+
Size: {size}
|
|
50
|
+
</Code>
|
|
51
|
+
{radiusOptions.map((radius) => (
|
|
52
|
+
<table
|
|
53
|
+
key={radius}
|
|
54
|
+
className="w-fit border-separate border-spacing-x-32 border-spacing-y-16"
|
|
55
|
+
>
|
|
56
|
+
<thead>
|
|
57
|
+
<tr>
|
|
58
|
+
<th>{radius}</th>
|
|
59
|
+
<th>Default</th>
|
|
60
|
+
<th>Hover</th>
|
|
61
|
+
<th>Focus</th>
|
|
62
|
+
<th>Disabled</th>
|
|
63
|
+
</tr>
|
|
64
|
+
</thead>
|
|
65
|
+
<tbody>
|
|
66
|
+
{variantOptions.map((variant) => (
|
|
67
|
+
<tr key={variant}>
|
|
68
|
+
<td>
|
|
69
|
+
<Code variant="label" className="text-foreground-neutral-subtle">
|
|
70
|
+
{variant}
|
|
71
|
+
</Code>
|
|
72
|
+
</td>
|
|
73
|
+
<td>
|
|
74
|
+
<IconButton
|
|
75
|
+
{...args}
|
|
76
|
+
icon="addLine"
|
|
77
|
+
aria-label="Add"
|
|
78
|
+
variant={variant}
|
|
79
|
+
size={size}
|
|
80
|
+
radius={radius}
|
|
81
|
+
/>
|
|
82
|
+
</td>
|
|
83
|
+
<td>
|
|
84
|
+
<IconButton
|
|
85
|
+
{...args}
|
|
86
|
+
icon="addLine"
|
|
87
|
+
aria-label="Add"
|
|
88
|
+
variant={variant}
|
|
89
|
+
className="hover"
|
|
90
|
+
size={size}
|
|
91
|
+
radius={radius}
|
|
92
|
+
/>
|
|
93
|
+
</td>
|
|
94
|
+
<td>
|
|
95
|
+
<IconButton
|
|
96
|
+
{...args}
|
|
97
|
+
icon="addLine"
|
|
98
|
+
aria-label="Add"
|
|
99
|
+
variant={variant}
|
|
100
|
+
className="focus"
|
|
101
|
+
size={size}
|
|
102
|
+
radius={radius}
|
|
103
|
+
/>
|
|
104
|
+
</td>
|
|
105
|
+
<td>
|
|
106
|
+
<IconButton
|
|
107
|
+
{...args}
|
|
108
|
+
icon="addLine"
|
|
109
|
+
aria-label="Add"
|
|
110
|
+
variant={variant}
|
|
111
|
+
disabled
|
|
112
|
+
size={size}
|
|
113
|
+
radius={radius}
|
|
114
|
+
/>
|
|
115
|
+
</td>
|
|
116
|
+
</tr>
|
|
117
|
+
))}
|
|
118
|
+
</tbody>
|
|
119
|
+
</table>
|
|
120
|
+
))}
|
|
121
|
+
</div>
|
|
122
|
+
))}
|
|
123
|
+
</div>
|
|
124
|
+
),
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
Variants.parameters = {
|
|
128
|
+
pseudo: {
|
|
129
|
+
hover: '.hover',
|
|
130
|
+
focusVisible: '.focus',
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const Muted: Story = {
|
|
135
|
+
render: (args) => (
|
|
136
|
+
<div className="flex flex-col gap-16">
|
|
137
|
+
<div className="flex gap-16 items-center">
|
|
138
|
+
<Code variant="label">Normal:</Code>
|
|
139
|
+
<IconButton {...args} icon="addLine" aria-label="Add" />
|
|
140
|
+
<IconButton {...args} icon="addLine" aria-label="Add" variant="transparent" />
|
|
141
|
+
</div>
|
|
142
|
+
<div className="flex gap-16 items-center">
|
|
143
|
+
<Code variant="label">Muted:</Code>
|
|
144
|
+
<IconButton {...args} icon="addLine" aria-label="Add" muted />
|
|
145
|
+
<IconButton {...args} icon="addLine" aria-label="Add" variant="transparent" muted />
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
),
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const Sizes: Story = {
|
|
152
|
+
render: ({children: _children, ...args}) => (
|
|
153
|
+
<div className="flex flex-col gap-16">
|
|
154
|
+
<div className="flex gap-16 items-center">
|
|
155
|
+
<Code variant="label">Rounded:</Code>
|
|
156
|
+
{sizeOptions.map((size) => (
|
|
157
|
+
<IconButton
|
|
158
|
+
{...args}
|
|
159
|
+
key={size}
|
|
160
|
+
icon="addLine"
|
|
161
|
+
aria-label="Add"
|
|
162
|
+
size={size}
|
|
163
|
+
radius="rounded"
|
|
164
|
+
/>
|
|
165
|
+
))}
|
|
166
|
+
</div>
|
|
167
|
+
<div className="flex gap-16 items-center">
|
|
168
|
+
<Code variant="label">Full:</Code>
|
|
169
|
+
{sizeOptions.map((size) => (
|
|
170
|
+
<IconButton
|
|
171
|
+
{...args}
|
|
172
|
+
key={size}
|
|
173
|
+
icon="addLine"
|
|
174
|
+
aria-label="Add"
|
|
175
|
+
size={size}
|
|
176
|
+
radius="full"
|
|
177
|
+
/>
|
|
178
|
+
))}
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
),
|
|
182
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import {Slot} from '@radix-ui/react-slot';
|
|
2
|
+
import {cva, type VariantProps} from 'class-variance-authority';
|
|
3
|
+
import {Icon, type IconName} from 'components/icon';
|
|
4
|
+
import type {ComponentProps} from 'react';
|
|
5
|
+
import {cn} from 'utils/cn';
|
|
6
|
+
|
|
7
|
+
export const iconButtonVariants = cva(
|
|
8
|
+
'inline-flex items-center justify-center whitespace-nowrap transition-colors disabled:pointer-events-none shrink-0 outline-none',
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
primary:
|
|
13
|
+
'bg-background-button-inverted-default text-tag-neutral-icon shadow-button-inverted hover:bg-background-button-inverted-hover active:bg-background-button-inverted-pressed focus-visible:shadow-button-inverted-focus disabled:bg-background-neutral-disabled disabled:text-foreground-neutral-disabled disabled:shadow-none',
|
|
14
|
+
transparent:
|
|
15
|
+
'bg-background-button-transparent-default text-tag-neutral-icon hover:bg-background-button-transparent-hover active:bg-background-button-transparent-pressed focus-visible:shadow-button-neutral-focus disabled:text-foreground-neutral-disabled',
|
|
16
|
+
},
|
|
17
|
+
size: {
|
|
18
|
+
'2xs': 'w-20 h-20 text-xs',
|
|
19
|
+
xs: 'w-24 h-24 text-xs',
|
|
20
|
+
sm: 'w-28 h-28 text-sm',
|
|
21
|
+
md: 'w-32 h-32 text-md',
|
|
22
|
+
lg: 'w-36 h-36 text-lg',
|
|
23
|
+
xl: 'w-40 h-40 text-xl',
|
|
24
|
+
},
|
|
25
|
+
radius: {
|
|
26
|
+
rounded: 'rounded-6',
|
|
27
|
+
full: 'rounded-full',
|
|
28
|
+
},
|
|
29
|
+
muted: {
|
|
30
|
+
true: 'opacity-60',
|
|
31
|
+
false: '',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
defaultVariants: {
|
|
35
|
+
variant: 'primary',
|
|
36
|
+
size: 'md',
|
|
37
|
+
radius: 'rounded',
|
|
38
|
+
muted: false,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
export function IconButton({
|
|
44
|
+
className,
|
|
45
|
+
variant,
|
|
46
|
+
size,
|
|
47
|
+
radius,
|
|
48
|
+
muted,
|
|
49
|
+
asChild = false,
|
|
50
|
+
children,
|
|
51
|
+
icon,
|
|
52
|
+
...props
|
|
53
|
+
}: ComponentProps<'button'> &
|
|
54
|
+
VariantProps<typeof iconButtonVariants> & {
|
|
55
|
+
asChild?: boolean;
|
|
56
|
+
icon?: IconName;
|
|
57
|
+
}) {
|
|
58
|
+
const Comp = asChild ? Slot : 'button';
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<Comp
|
|
62
|
+
data-slot="icon-button"
|
|
63
|
+
className={cn(iconButtonVariants({variant, size, radius, muted}), className)}
|
|
64
|
+
{...props}
|
|
65
|
+
>
|
|
66
|
+
{icon ? <Icon name={icon} /> : children}
|
|
67
|
+
</Comp>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {Slot} from '@radix-ui/react-slot';
|
|
2
2
|
import {Icon} from 'components/icon/icon';
|
|
3
|
+
import {Text} from 'components/typography';
|
|
3
4
|
import type {ComponentProps, HTMLAttributes, ReactNode} from 'react';
|
|
4
5
|
import {cn} from 'utils/cn';
|
|
5
6
|
|
|
@@ -53,22 +54,12 @@ export function CodeBlockFooter({
|
|
|
53
54
|
className={cn('flex w-full items-center justify-start gap-12 px-16 py-12', className)}
|
|
54
55
|
{...props}
|
|
55
56
|
>
|
|
56
|
-
<
|
|
57
|
-
{defaultIcon}
|
|
58
|
-
</div>
|
|
57
|
+
<CodeBlockFooterIcon className="text-tag-success-icon">{defaultIcon}</CodeBlockFooterIcon>
|
|
59
58
|
{(message || description) && (
|
|
60
|
-
<
|
|
61
|
-
{message &&
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
</div>
|
|
65
|
-
)}
|
|
66
|
-
{description && (
|
|
67
|
-
<div className="overflow-hidden text-ellipsis whitespace-nowrap text-xs leading-20 text-foreground-neutral-subtle">
|
|
68
|
-
{description}
|
|
69
|
-
</div>
|
|
70
|
-
)}
|
|
71
|
-
</div>
|
|
59
|
+
<CodeBlockFooterContent>
|
|
60
|
+
{message && <CodeBlockFooterMessage>{message}</CodeBlockFooterMessage>}
|
|
61
|
+
{description && <CodeBlockFooterDescription>{description}</CodeBlockFooterDescription>}
|
|
62
|
+
</CodeBlockFooterContent>
|
|
72
63
|
)}
|
|
73
64
|
</Comp>
|
|
74
65
|
);
|
|
@@ -112,7 +103,7 @@ export function CodeBlockFooterContent({
|
|
|
112
103
|
return (
|
|
113
104
|
<Comp
|
|
114
105
|
data-slot="code-block-footer-content"
|
|
115
|
-
className={cn('flex flex-col items-start justify-center gap-0', className)}
|
|
106
|
+
className={cn('flex flex-col items-start justify-center gap-0 min-w-0 flex-1', className)}
|
|
116
107
|
{...props}
|
|
117
108
|
>
|
|
118
109
|
{children}
|
|
@@ -130,19 +121,27 @@ export function CodeBlockFooterMessage({
|
|
|
130
121
|
children,
|
|
131
122
|
...props
|
|
132
123
|
}: CodeBlockFooterMessageProps) {
|
|
133
|
-
|
|
124
|
+
if (asChild) {
|
|
125
|
+
return (
|
|
126
|
+
<Slot
|
|
127
|
+
data-slot="code-block-footer-message"
|
|
128
|
+
className={cn('overflow-hidden text-ellipsis whitespace-nowrap text-xs', className)}
|
|
129
|
+
{...props}
|
|
130
|
+
>
|
|
131
|
+
{children}
|
|
132
|
+
</Slot>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
134
135
|
|
|
135
136
|
return (
|
|
136
|
-
<
|
|
137
|
+
<Text
|
|
137
138
|
data-slot="code-block-footer-message"
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
className,
|
|
141
|
-
)}
|
|
139
|
+
size="xs"
|
|
140
|
+
className={cn('overflow-hidden text-ellipsis whitespace-nowrap', className)}
|
|
142
141
|
{...props}
|
|
143
142
|
>
|
|
144
143
|
{children}
|
|
145
|
-
</
|
|
144
|
+
</Text>
|
|
146
145
|
);
|
|
147
146
|
}
|
|
148
147
|
|
|
@@ -156,18 +155,26 @@ export function CodeBlockFooterDescription({
|
|
|
156
155
|
children,
|
|
157
156
|
...props
|
|
158
157
|
}: CodeBlockFooterDescriptionProps) {
|
|
159
|
-
|
|
158
|
+
if (asChild) {
|
|
159
|
+
return (
|
|
160
|
+
<Slot
|
|
161
|
+
data-slot="code-block-footer-description"
|
|
162
|
+
className={cn('text-xs text-foreground-neutral-subtle', className)}
|
|
163
|
+
{...props}
|
|
164
|
+
>
|
|
165
|
+
{children}
|
|
166
|
+
</Slot>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
160
169
|
|
|
161
170
|
return (
|
|
162
|
-
<
|
|
171
|
+
<Text
|
|
163
172
|
data-slot="code-block-footer-description"
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
className,
|
|
167
|
-
)}
|
|
173
|
+
size="xs"
|
|
174
|
+
className={cn('text-foreground-neutral-subtle', className)}
|
|
168
175
|
{...props}
|
|
169
176
|
>
|
|
170
177
|
{children}
|
|
171
|
-
</
|
|
178
|
+
</Text>
|
|
172
179
|
);
|
|
173
180
|
}
|
|
@@ -49,8 +49,11 @@ export function CodeContent({
|
|
|
49
49
|
'[counter-reset:line] [counter-increment:line_0] [&_.line]:before:content-[counter(line)] [&_.line]:before:inline-block [&_.line]:before:[counter-increment:line] [&_.line]:before:w-16 [&_.line]:before:mr-16 [&_.line]:before:text-xs [&_.line]:before:text-right [&_.line]:before:text-foreground-neutral-subtle [&_.line]:before:font-code [&_.line]:before:select-none',
|
|
50
50
|
)}
|
|
51
51
|
>
|
|
52
|
-
{lines.map((line) => (
|
|
53
|
-
<span
|
|
52
|
+
{lines.map((line, index) => (
|
|
53
|
+
<span
|
|
54
|
+
className="line px-12 w-full relative font-code text-xs leading-20"
|
|
55
|
+
key={`${index}-${line}`}
|
|
56
|
+
>
|
|
54
57
|
{line}
|
|
55
58
|
</span>
|
|
56
59
|
))}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {Meta, StoryObj} from '@storybook/react';
|
|
2
2
|
import {Button} from 'components/button/button';
|
|
3
3
|
import {ItemTitle} from 'components/item';
|
|
4
|
+
import {MovingBorder} from 'components/moving-border';
|
|
4
5
|
import {cn} from 'utils/cn';
|
|
5
6
|
import illustration1 from '../../assets/illustration-1.svg';
|
|
6
7
|
import illustration2 from '../../assets/illustration-2.svg';
|
|
@@ -8,7 +9,6 @@ import illustrationBg from '../../assets/illustration-gradient.svg';
|
|
|
8
9
|
import {Avatar} from '../avatar/avatar';
|
|
9
10
|
import {AvatarGroup, AvatarGroupTooltip} from '../avatar/avatar-group';
|
|
10
11
|
import {Icon} from '../icon/icon';
|
|
11
|
-
import {MovingBorder} from '../moving-border/moving-border';
|
|
12
12
|
import {DynamicItem} from './dynamic-item';
|
|
13
13
|
|
|
14
14
|
const meta = {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type RemixiconComponentType,
|
|
3
|
+
RiAddLine,
|
|
4
|
+
RiArrowRightSLine,
|
|
5
|
+
RiBookOpenFill,
|
|
3
6
|
RiCheckLine,
|
|
4
7
|
RiCloseLine,
|
|
5
8
|
RiFileCopyLine,
|
|
@@ -56,6 +59,9 @@ const iconsMap = {
|
|
|
56
59
|
money: RiMoneyDollarCircleLine,
|
|
57
60
|
homeSmile: RiHomeSmileFill,
|
|
58
61
|
copy: RiFileCopyLine,
|
|
62
|
+
addLine: RiAddLine,
|
|
63
|
+
chevronRight: RiArrowRightSLine,
|
|
64
|
+
bookOpen: RiBookOpenFill,
|
|
59
65
|
} as const satisfies Record<string, RemixiconComponentType>;
|
|
60
66
|
|
|
61
67
|
export type IconName = keyof typeof iconsMap;
|
package/src/components/index.ts
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
ModalContentProps,
|
|
3
|
+
ModalDescriptionProps,
|
|
4
|
+
ModalHeaderProps,
|
|
5
|
+
ModalOverlayProps,
|
|
6
|
+
ModalTitleProps,
|
|
7
|
+
} from './modal';
|
|
8
|
+
export {
|
|
9
|
+
Modal,
|
|
10
|
+
ModalBody,
|
|
11
|
+
ModalClose,
|
|
12
|
+
ModalContent,
|
|
13
|
+
ModalDescription,
|
|
14
|
+
ModalFooter,
|
|
15
|
+
ModalHeader,
|
|
16
|
+
ModalOverlay,
|
|
17
|
+
ModalPortal,
|
|
18
|
+
ModalTitle,
|
|
19
|
+
ModalTrigger,
|
|
20
|
+
modalContentVariants,
|
|
21
|
+
modalDefaultTransition,
|
|
22
|
+
modalOverlayVariants,
|
|
23
|
+
} from './modal';
|