@crystallize/design-system 1.3.0 → 1.3.2
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/CHANGELOG.md +106 -0
- package/dist/index.css +1813 -0
- package/dist/index.d.ts +345 -2
- package/dist/index.js +2631 -5
- package/dist/index.mjs +2574 -0
- package/package.json +90 -78
- package/readme.md +9 -0
- package/src/Tokens.stories.tsx +18 -0
- package/src/action-menu/ActionMenu.stories.tsx +25 -0
- package/src/action-menu/action-item.tsx +16 -0
- package/src/action-menu/action-menu.css +38 -0
- package/src/action-menu/action-menu.tsx +25 -0
- package/src/action-menu/index.tsx +3 -0
- package/src/avatar/Avatar.stories.tsx +20 -0
- package/src/avatar/avatar.css +23 -0
- package/src/avatar/avatar.tsx +34 -0
- package/src/avatar/get-initials.ts +5 -0
- package/src/avatar/index.ts +1 -0
- package/src/button/Button.stories.tsx +105 -0
- package/src/button/button.css +116 -0
- package/src/button/button.tsx +136 -0
- package/src/button/index.ts +3 -0
- package/src/card/card.css +7 -0
- package/src/card/card.stories.tsx +24 -0
- package/src/card/card.tsx +27 -0
- package/src/card/index.ts +3 -0
- package/src/checkbox/checkbox.css +30 -0
- package/src/checkbox/checkbox.stories.tsx +62 -0
- package/src/checkbox/checkbox.test.tsx +16 -0
- package/src/checkbox/checkbox.tsx +28 -0
- package/src/checkbox/index.ts +1 -0
- package/src/colors/Colors.stories.tsx +127 -0
- package/src/colors/color-defaults.json +15 -0
- package/src/colors/color-pairing.json +12 -0
- package/src/colors/colors.json +158 -0
- package/src/colors/index.ts +1 -0
- package/src/colors/old-to-new.txt +19 -0
- package/src/colors/types.ts +29 -0
- package/src/dialog/Dialog.stories.tsx +168 -0
- package/src/dialog/Dialog.test.tsx +25 -0
- package/src/dialog/config.tsx +139 -0
- package/src/dialog/confirm-dialog.tsx +70 -0
- package/src/dialog/destroyFns.ts +1 -0
- package/src/dialog/dialog.css +27 -0
- package/src/dialog/dialog.tsx +94 -0
- package/src/dialog/index.tsx +40 -0
- package/src/dialog/types.ts +70 -0
- package/src/dropdown-menu/DropdownMenu.stories.tsx +38 -0
- package/src/dropdown-menu/dropdown-menu-item.tsx +15 -0
- package/src/dropdown-menu/dropdown-menu-label.tsx +10 -0
- package/src/dropdown-menu/dropdown-menu-root.tsx +33 -0
- package/src/dropdown-menu/dropdown-menu.css +20 -0
- package/src/dropdown-menu/index.ts +11 -0
- package/src/icon-button/IconButton.stories.tsx +45 -0
- package/src/icon-button/icon-button.css +48 -0
- package/src/icon-button/icon-button.tsx +39 -0
- package/src/icon-button/index.ts +3 -0
- package/src/iconography/Icon.stories.tsx +47 -0
- package/src/iconography/add.tsx +30 -0
- package/src/iconography/arrow.tsx +15 -0
- package/src/iconography/atom.tsx +59 -0
- package/src/iconography/cancel.tsx +26 -0
- package/src/iconography/catalogue.tsx +26 -0
- package/src/iconography/copy.tsx +24 -0
- package/src/iconography/crystal.tsx +93 -0
- package/src/iconography/customers.tsx +38 -0
- package/src/iconography/edit.tsx +30 -0
- package/src/iconography/error.tsx +40 -0
- package/src/iconography/fulfilment.tsx +58 -0
- package/src/iconography/glasses.tsx +62 -0
- package/src/iconography/graphQL.tsx +90 -0
- package/src/iconography/grid.tsx +84 -0
- package/src/iconography/hooks.tsx +26 -0
- package/src/iconography/image.tsx +47 -0
- package/src/iconography/index.ts +63 -0
- package/src/iconography/info.tsx +41 -0
- package/src/iconography/key.tsx +19 -0
- package/src/iconography/language.tsx +38 -0
- package/src/iconography/nail-polish.tsx +84 -0
- package/src/iconography/order.tsx +38 -0
- package/src/iconography/particle.tsx +88 -0
- package/src/iconography/percentage.tsx +44 -0
- package/src/iconography/price-tag.tsx +40 -0
- package/src/iconography/shapes.tsx +48 -0
- package/src/iconography/subscription.tsx +34 -0
- package/src/iconography/topics.tsx +58 -0
- package/src/iconography/triangle.tsx +27 -0
- package/src/iconography/usage.tsx +34 -0
- package/src/iconography/users.tsx +44 -0
- package/src/iconography/warning.tsx +51 -0
- package/src/index.css +14 -0
- package/src/index.ts +33 -0
- package/src/inline-radio/index.ts +1 -0
- package/src/inline-radio/inline-radio.css +36 -0
- package/src/inline-radio/inline-radio.stories.tsx +81 -0
- package/src/inline-radio/inline-radio.tsx +41 -0
- package/src/input/Input.stories.tsx +26 -0
- package/src/input/index.ts +1 -0
- package/src/input/input.css +7 -0
- package/src/input/input.tsx +20 -0
- package/src/input-with-label/InputWithLabel.stories.tsx +98 -0
- package/src/input-with-label/index.ts +3 -0
- package/src/input-with-label/input-with-label.css +35 -0
- package/src/input-with-label/input-with-label.tsx +59 -0
- package/src/label/index.ts +1 -0
- package/src/label/label.css +3 -0
- package/src/label/label.stories.tsx +19 -0
- package/src/label/label.tsx +13 -0
- package/src/progress/Progress.stories.tsx +26 -0
- package/src/progress/index.ts +1 -0
- package/src/progress/progress.css +7 -0
- package/src/progress/progress.tsx +17 -0
- package/src/radio/index.ts +1 -0
- package/src/radio/radio.css +20 -0
- package/src/radio/radio.stories.tsx +142 -0
- package/src/radio/radio.tsx +19 -0
- package/src/select/index.ts +1 -0
- package/src/select/select-item.tsx +18 -0
- package/src/select/select-root.tsx +50 -0
- package/src/select/select.css +44 -0
- package/src/select/select.stories.tsx +74 -0
- package/src/select/select.ts +9 -0
- package/src/slider/Slider.stories.tsx +54 -0
- package/src/slider/index.ts +1 -0
- package/src/slider/slider.css +27 -0
- package/src/slider/slider.tsx +20 -0
- package/src/spinner/Spinner.stories.tsx +19 -0
- package/src/spinner/index.tsx +48 -0
- package/src/spinner/spinner.css +11 -0
- package/src/tag/Tag.stories.tsx +32 -0
- package/src/tag/index.ts +1 -0
- package/src/tag/tag.css +7 -0
- package/src/tag/tag.tsx +27 -0
- package/src/vite-env.d.ts +1 -0
- package/tailwind.config.cjs +51 -0
- package/LICENSE +0 -21
- package/README.md +0 -35
- package/dist/components/Button.d.ts +0 -11
- package/dist/components/Typography.d.ts +0 -14
- package/dist/design-system.cjs.development.js +0 -164
- package/dist/design-system.cjs.development.js.map +0 -1
- package/dist/design-system.cjs.production.min.js +0 -2
- package/dist/design-system.cjs.production.min.js.map +0 -1
- package/dist/design-system.esm.js +0 -156
- package/dist/design-system.esm.js.map +0 -1
- package/dist/styles/theme.d.ts +0 -2
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { forwardRef, SVGProps } from 'react';
|
|
2
|
+
|
|
3
|
+
type WarningProps = SVGProps<SVGSVGElement>;
|
|
4
|
+
type WarningRef = SVGSVGElement;
|
|
5
|
+
|
|
6
|
+
export const Warning = forwardRef<WarningRef, WarningProps>((delegated, ref) => {
|
|
7
|
+
return (
|
|
8
|
+
<svg
|
|
9
|
+
ref={ref}
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
width="22"
|
|
12
|
+
height="22"
|
|
13
|
+
fill="none"
|
|
14
|
+
viewBox="0 0 22 22"
|
|
15
|
+
{...delegated}
|
|
16
|
+
>
|
|
17
|
+
<path
|
|
18
|
+
d="M9.67541 3.72993C10.2804 2.68198 11.793 2.68198 12.398 3.72993L19.8853 16.6982C20.4903 17.7462 19.734 19.0561 18.524 19.0561H3.54948C2.33942 19.0561 1.58313 17.7462 2.18816 16.6982L9.67541 3.72993Z"
|
|
19
|
+
fill="#FFDE99"
|
|
20
|
+
/>
|
|
21
|
+
<path
|
|
22
|
+
fillRule="evenodd"
|
|
23
|
+
clipRule="evenodd"
|
|
24
|
+
d="M19.3657 16.9982L11.8784 4.02993C11.5043 3.38198 10.5691 3.38198 10.195 4.02993L2.70778 16.9982C2.33369 17.6462 2.8013 18.4561 3.54948 18.4561H18.524C19.2722 18.4561 19.7398 17.6462 19.3657 16.9982ZM12.398 3.72993C11.793 2.68198 10.2804 2.68198 9.67541 3.72993L2.18816 16.6982C1.58313 17.7462 2.33942 19.0561 3.54948 19.0561H18.524C19.734 19.0561 20.4903 17.7462 19.8853 16.6982L12.398 3.72993Z"
|
|
25
|
+
fill="#528693"
|
|
26
|
+
/>
|
|
27
|
+
<path
|
|
28
|
+
d="M10.4293 8.73822C10.4293 8.33098 10.7595 8.00085 11.1667 8.00085V8.00085C11.5739 8.00085 11.9041 8.33098 11.9041 8.73822V12.3883C11.9041 12.7956 11.5739 13.1257 11.1667 13.1257V13.1257C10.7595 13.1257 10.4293 12.7956 10.4293 12.3883V8.73822Z"
|
|
29
|
+
fill="white"
|
|
30
|
+
/>
|
|
31
|
+
<path
|
|
32
|
+
fillRule="evenodd"
|
|
33
|
+
clipRule="evenodd"
|
|
34
|
+
d="M12.504 8.73824V12.3883C12.504 13.127 11.9053 13.7257 11.1667 13.7257C10.4281 13.7257 9.82932 13.127 9.82932 12.3883V8.73825C9.82932 7.99964 10.4281 7.40088 11.1667 7.40088C11.9053 7.40088 12.504 7.99964 12.504 8.73824ZM11.1667 8.00088C10.7594 8.00088 10.4293 8.33101 10.4293 8.73825V12.3883C10.4293 12.7956 10.7594 13.1257 11.1667 13.1257C11.5739 13.1257 11.904 12.7956 11.904 12.3883V8.73824C11.904 8.33101 11.5739 8.00088 11.1667 8.00088Z"
|
|
35
|
+
fill="#528693"
|
|
36
|
+
/>
|
|
37
|
+
<path
|
|
38
|
+
d="M11.9041 15.7807C11.9041 16.1879 11.5739 16.5181 11.1667 16.5181C10.7595 16.5181 10.4293 16.1879 10.4293 15.7807C10.4293 15.3735 10.7595 15.0433 11.1667 15.0433C11.5739 15.0433 11.9041 15.3735 11.9041 15.7807Z"
|
|
39
|
+
fill="white"
|
|
40
|
+
/>
|
|
41
|
+
<path
|
|
42
|
+
fillRule="evenodd"
|
|
43
|
+
clipRule="evenodd"
|
|
44
|
+
d="M12.504 15.7807C12.504 16.5193 11.9053 17.1181 11.1667 17.1181C10.4281 17.1181 9.82932 16.5193 9.82932 15.7807C9.82932 15.0421 10.4281 14.4434 11.1667 14.4434C11.9053 14.4434 12.504 15.0421 12.504 15.7807ZM11.1667 16.5181C11.5739 16.5181 11.904 16.188 11.904 15.7807C11.904 15.3735 11.5739 15.0434 11.1667 15.0434C10.7594 15.0434 10.4293 15.3735 10.4293 15.7807C10.4293 16.188 10.7594 16.5181 11.1667 16.5181Z"
|
|
45
|
+
fill="#528693"
|
|
46
|
+
/>
|
|
47
|
+
</svg>
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
Warning.displayName = 'WarningIcon';
|
package/src/index.css
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
|
|
3
|
+
// Components ---
|
|
4
|
+
export * from './action-menu';
|
|
5
|
+
export * from './avatar';
|
|
6
|
+
export * from './button';
|
|
7
|
+
export * from './card';
|
|
8
|
+
export * from './checkbox';
|
|
9
|
+
export * from './dialog';
|
|
10
|
+
export * from './dropdown-menu';
|
|
11
|
+
export * from './icon-button';
|
|
12
|
+
export * from './inline-radio';
|
|
13
|
+
export * from './input-with-label';
|
|
14
|
+
export * from './input';
|
|
15
|
+
export * from './label';
|
|
16
|
+
export * from './progress';
|
|
17
|
+
export * from './radio';
|
|
18
|
+
export * from './select';
|
|
19
|
+
export * from './slider';
|
|
20
|
+
export * from './spinner';
|
|
21
|
+
export * from './tag';
|
|
22
|
+
|
|
23
|
+
// Icons ---
|
|
24
|
+
export * from './iconography';
|
|
25
|
+
|
|
26
|
+
// Tokens ---
|
|
27
|
+
import { buttonTokens } from './button';
|
|
28
|
+
import { cardToken } from './card';
|
|
29
|
+
|
|
30
|
+
export const tokens = {
|
|
31
|
+
button: buttonTokens,
|
|
32
|
+
card: cardToken,
|
|
33
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './inline-radio';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
.c-inline-radio-group {
|
|
2
|
+
@apply inline-flex space-x-1 rounded bg-gray-100-800 p-[3px];
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.c-inline-radio-group-xs {
|
|
6
|
+
@apply h-6;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.c-inline-radio-group-sm {
|
|
10
|
+
@apply h-9 text-sm;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.c-inline-radio-group-md {
|
|
14
|
+
@apply h-11 text-base;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.c-inline-radio-group-lg {
|
|
18
|
+
@apply h-14 text-lg;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.c-inline-radio {
|
|
22
|
+
@apply m-0 flex cursor-pointer items-center justify-center rounded-[3px] border-none bg-transparent text-sm font-medium !leading-none text-gray;
|
|
23
|
+
|
|
24
|
+
&[aria-checked='true'] {
|
|
25
|
+
@apply bg-elevate shadow-sm;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&:focus-visible {
|
|
29
|
+
@apply outline outline-1 outline-inherit;
|
|
30
|
+
outline-color: currentColor;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&:disabled {
|
|
34
|
+
@apply cursor-not-allowed;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { InlineRadio } from './inline-radio';
|
|
3
|
+
import { Icon } from '../iconography';
|
|
4
|
+
|
|
5
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof InlineRadio.Group> = {
|
|
8
|
+
title: 'Components/InlineRadio',
|
|
9
|
+
component: InlineRadio.Group,
|
|
10
|
+
argTypes: {
|
|
11
|
+
size: {
|
|
12
|
+
defaultValue: 'sm',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default meta;
|
|
18
|
+
|
|
19
|
+
type Story = StoryObj<typeof InlineRadio.Group>;
|
|
20
|
+
|
|
21
|
+
export const Example: Story = {
|
|
22
|
+
render: () => {
|
|
23
|
+
return (
|
|
24
|
+
<InlineRadio.Group defaultValue="plus" size="xs">
|
|
25
|
+
<InlineRadio.Item value="plus" id="example-r1">
|
|
26
|
+
+
|
|
27
|
+
</InlineRadio.Item>
|
|
28
|
+
<InlineRadio.Item value="minus" id="example-r2">
|
|
29
|
+
-
|
|
30
|
+
</InlineRadio.Item>
|
|
31
|
+
</InlineRadio.Group>
|
|
32
|
+
);
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const ProductView: Story = {
|
|
37
|
+
render: () => {
|
|
38
|
+
return (
|
|
39
|
+
<InlineRadio.Group defaultValue="pretty" size="xs">
|
|
40
|
+
<InlineRadio.Item value="pretty" id="productview-r1">
|
|
41
|
+
<Icon.NailPolish />
|
|
42
|
+
</InlineRadio.Item>
|
|
43
|
+
<InlineRadio.Item value="nerdy" id="productview-r2">
|
|
44
|
+
<Icon.Glasses />
|
|
45
|
+
</InlineRadio.Item>
|
|
46
|
+
</InlineRadio.Group>
|
|
47
|
+
);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const Controlled: Story = {
|
|
52
|
+
render: () => {
|
|
53
|
+
const [view, setView] = useState('pretty');
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<InlineRadio.Group value={view} onValueChange={v => setView(v)} size="xs">
|
|
57
|
+
<InlineRadio.Item value="pretty" id="controlled-r1">
|
|
58
|
+
<Icon.NailPolish />
|
|
59
|
+
</InlineRadio.Item>
|
|
60
|
+
<InlineRadio.Item value="nerdy" id="controlled-r2">
|
|
61
|
+
<Icon.Glasses />
|
|
62
|
+
</InlineRadio.Item>
|
|
63
|
+
</InlineRadio.Group>
|
|
64
|
+
);
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const WithSize: Story = {
|
|
69
|
+
render: ({ size }) => {
|
|
70
|
+
return (
|
|
71
|
+
<InlineRadio.Group defaultValue="preview" size={size}>
|
|
72
|
+
<InlineRadio.Item value="preview" id="controlled-r1">
|
|
73
|
+
Preview
|
|
74
|
+
</InlineRadio.Item>
|
|
75
|
+
<InlineRadio.Item value="edit" id="controlled-r2">
|
|
76
|
+
Edit
|
|
77
|
+
</InlineRadio.Item>
|
|
78
|
+
</InlineRadio.Group>
|
|
79
|
+
);
|
|
80
|
+
},
|
|
81
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
2
|
+
import { cx, cva, VariantProps } from 'class-variance-authority';
|
|
3
|
+
import type { ComponentProps } from 'react';
|
|
4
|
+
|
|
5
|
+
import './inline-radio.css';
|
|
6
|
+
|
|
7
|
+
const inlineRadioGroupStyles = cva('c-inline-radio-group', {
|
|
8
|
+
variants: {
|
|
9
|
+
size: {
|
|
10
|
+
xs: 'c-inline-radio-group-xs',
|
|
11
|
+
sm: 'c-inline-radio-group-sm',
|
|
12
|
+
md: 'c-inline-radio-group-md',
|
|
13
|
+
lg: 'c-inline-radio-group-lg',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
defaultVariants: {
|
|
17
|
+
size: 'sm',
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
type InlineRadioGroupProps = ComponentProps<typeof RadioGroupPrimitive.Root> &
|
|
22
|
+
VariantProps<typeof inlineRadioGroupStyles>;
|
|
23
|
+
|
|
24
|
+
function InlineRadioGroup({ size, className, ...delegated }: InlineRadioGroupProps) {
|
|
25
|
+
return <RadioGroupPrimitive.Root {...delegated} className={inlineRadioGroupStyles({ size, className })} />;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type InlineRadioItemProps = ComponentProps<typeof RadioGroupPrimitive.Item>;
|
|
29
|
+
|
|
30
|
+
function InlineRadioItem({ children, className, ...delegated }: InlineRadioItemProps) {
|
|
31
|
+
return (
|
|
32
|
+
<RadioGroupPrimitive.Item {...delegated} className={cx('c-inline-radio', className)}>
|
|
33
|
+
<RadioGroupPrimitive.Indicator forceMount>{children}</RadioGroupPrimitive.Indicator>
|
|
34
|
+
</RadioGroupPrimitive.Item>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const InlineRadio = {
|
|
39
|
+
Group: InlineRadioGroup,
|
|
40
|
+
Item: InlineRadioItem,
|
|
41
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { Input } from '.';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Input> = {
|
|
6
|
+
title: 'Components/Input',
|
|
7
|
+
component: Input,
|
|
8
|
+
argTypes: {},
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
|
|
13
|
+
type Story = StoryObj<typeof Input>;
|
|
14
|
+
|
|
15
|
+
export const Default: Story = {
|
|
16
|
+
args: {
|
|
17
|
+
placeholder: "c'mon type something",
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const Disabled: Story = {
|
|
22
|
+
args: {
|
|
23
|
+
value: "I'm disabled",
|
|
24
|
+
disabled: true,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Input } from './input';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { cva, VariantProps } from 'class-variance-authority';
|
|
2
|
+
import { ComponentPropsWithRef, forwardRef } from 'react';
|
|
3
|
+
|
|
4
|
+
import './input.css';
|
|
5
|
+
|
|
6
|
+
type InputStylesProps = VariantProps<typeof inputStyles>;
|
|
7
|
+
const inputStyles = cva(['c-input'], {
|
|
8
|
+
variants: {},
|
|
9
|
+
defaultVariants: {},
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
type InputProps = InputStylesProps & ComponentPropsWithRef<'input'>;
|
|
13
|
+
|
|
14
|
+
export type InputRef = HTMLInputElement;
|
|
15
|
+
|
|
16
|
+
export const Input = forwardRef<InputRef, InputProps>(({ className, ...delegated }, ref) => {
|
|
17
|
+
return <input ref={ref} className={inputStyles({ className })} type="text" {...delegated} />;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
Input.displayName = 'Input';
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { InputWithLabel } from '.';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof InputWithLabel> = {
|
|
6
|
+
title: 'Components/InputWithLabel',
|
|
7
|
+
component: InputWithLabel,
|
|
8
|
+
argTypes: {
|
|
9
|
+
variant: {
|
|
10
|
+
defaultValue: '',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
16
|
+
|
|
17
|
+
type Story = StoryObj<typeof InputWithLabel>;
|
|
18
|
+
|
|
19
|
+
export const Default: Story = {
|
|
20
|
+
args: {
|
|
21
|
+
placeholder: 'Luke Skywalker',
|
|
22
|
+
label: 'Name',
|
|
23
|
+
value: 'Luke Skywalker',
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const Error: Story = {
|
|
28
|
+
args: {
|
|
29
|
+
placeholder: 'Luke Skywalker',
|
|
30
|
+
label: 'Name',
|
|
31
|
+
status: 'error',
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const ErrorWithMessage: Story = {
|
|
36
|
+
args: {
|
|
37
|
+
placeholder: 'Luke Skywalker',
|
|
38
|
+
label: 'Name',
|
|
39
|
+
status: 'error',
|
|
40
|
+
errorMessage: 'You are not my father',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const Elevated: Story = {
|
|
45
|
+
args: {
|
|
46
|
+
placeholder: 'Luke Skywalker',
|
|
47
|
+
label: 'Name',
|
|
48
|
+
variant: 'elevated',
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const ElevatedError: Story = {
|
|
53
|
+
args: {
|
|
54
|
+
placeholder: 'Luke Skywalker',
|
|
55
|
+
label: 'Name',
|
|
56
|
+
variant: 'elevated',
|
|
57
|
+
status: 'error',
|
|
58
|
+
errorMessage: 'Something went no no',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const WithAppend: Story = {
|
|
63
|
+
args: {
|
|
64
|
+
placeholder: 'Luke Skywalker',
|
|
65
|
+
label: 'Name',
|
|
66
|
+
variant: 'elevated',
|
|
67
|
+
append: <div className="self-end">🍩</div>,
|
|
68
|
+
id: 'my-id',
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const Disabled: Story = {
|
|
73
|
+
args: {
|
|
74
|
+
placeholder: 'Luke Skywalker',
|
|
75
|
+
label: 'Name',
|
|
76
|
+
disabled: true,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const Readonly: Story = {
|
|
81
|
+
args: {
|
|
82
|
+
placeholder: 'Luke Skywalker',
|
|
83
|
+
label: 'Name',
|
|
84
|
+
readOnly: true,
|
|
85
|
+
value: 'Darth Vader',
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const PassingPropsToLabel: Story = {
|
|
90
|
+
args: {
|
|
91
|
+
placeholder: 'Luke Skywalker',
|
|
92
|
+
label: 'Name',
|
|
93
|
+
value: 'Darth Vader',
|
|
94
|
+
labelProps: {
|
|
95
|
+
className: 'bg-elevated',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
.c-input-with-label {
|
|
2
|
+
@apply relative block rounded border border-solid border-transparent p-3;
|
|
3
|
+
|
|
4
|
+
&-input-wrap {
|
|
5
|
+
@apply mt-3 flex;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
&-input {
|
|
9
|
+
@apply flex-1 overflow-hidden text-ellipsis text-base;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
&-append {
|
|
13
|
+
@apply -mr-3 flex flex-shrink-0 items-center px-3;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
&-elevated {
|
|
17
|
+
@apply bg-elevate shadow;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&.c-input-with-label--error {
|
|
21
|
+
@apply text-error;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&-error {
|
|
25
|
+
@apply !mt-1 text-xs text-error;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&-sm {
|
|
29
|
+
@apply text-sm;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&-lg {
|
|
33
|
+
@apply text-lg;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef, ComponentPropsWithRef, forwardRef, ReactNode } from 'react';
|
|
2
|
+
import { cva, cx, VariantProps } from 'class-variance-authority';
|
|
3
|
+
|
|
4
|
+
import { Input } from '../input';
|
|
5
|
+
import { Label } from '../label';
|
|
6
|
+
import { Triangle } from '../iconography/triangle';
|
|
7
|
+
|
|
8
|
+
const inputWithLabelStyles = cva(['c-input-with-label'], {
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
default: '',
|
|
12
|
+
elevated: 'c-input-with-label-elevated',
|
|
13
|
+
outlined: 'c-input-with-label-outlined',
|
|
14
|
+
},
|
|
15
|
+
status: {
|
|
16
|
+
error: 'c-input-with-label--error',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
defaultVariants: {},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
type InputWithLabelStylesProps = VariantProps<typeof inputWithLabelStyles>;
|
|
23
|
+
|
|
24
|
+
export type InputWithLabelProps = InputWithLabelStylesProps & {
|
|
25
|
+
label: string;
|
|
26
|
+
append?: ReactNode;
|
|
27
|
+
errorMessage?: string;
|
|
28
|
+
labelProps?: ComponentPropsWithoutRef<'label'>;
|
|
29
|
+
} & ComponentPropsWithRef<'input'>;
|
|
30
|
+
|
|
31
|
+
export type InputWithLabelRef = HTMLInputElement;
|
|
32
|
+
|
|
33
|
+
export const InputWithLabel = forwardRef<InputWithLabelRef, InputWithLabelProps>(
|
|
34
|
+
({ className, label, append, errorMessage, status, variant, id, labelProps, ...delegated }, ref) => {
|
|
35
|
+
const { className: labelClassName, ...labelPropsRest } = labelProps ?? {};
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<>
|
|
39
|
+
<Label
|
|
40
|
+
className={inputWithLabelStyles({ status, variant, className: labelClassName })}
|
|
41
|
+
htmlFor={id}
|
|
42
|
+
{...labelPropsRest}
|
|
43
|
+
>
|
|
44
|
+
{label}
|
|
45
|
+
<span className="c-input-with-label-input-wrap">
|
|
46
|
+
<Input className={cx('c-input-with-label-input', className)} ref={ref} id={id} {...delegated} />
|
|
47
|
+
{!append && !errorMessage ? null : (
|
|
48
|
+
<div className="c-input-with-label-append" title={errorMessage}>
|
|
49
|
+
{errorMessage ? <Triangle /> : append}
|
|
50
|
+
</div>
|
|
51
|
+
)}
|
|
52
|
+
</span>
|
|
53
|
+
</Label>
|
|
54
|
+
</>
|
|
55
|
+
);
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
InputWithLabel.displayName = 'InputWithLabel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './label';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { Label } from './label';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Label> = {
|
|
5
|
+
title: 'Components/Label',
|
|
6
|
+
component: Label,
|
|
7
|
+
argTypes: {},
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default meta;
|
|
11
|
+
|
|
12
|
+
type Story = StoryObj<typeof Label>;
|
|
13
|
+
|
|
14
|
+
export const Default: Story = {
|
|
15
|
+
args: {
|
|
16
|
+
htmlFor: 'id',
|
|
17
|
+
children: 'Hello, World!',
|
|
18
|
+
},
|
|
19
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { forwardRef, LabelHTMLAttributes } from 'react';
|
|
2
|
+
import { cx } from 'class-variance-authority';
|
|
3
|
+
|
|
4
|
+
import './label.css';
|
|
5
|
+
|
|
6
|
+
type LabelRef = HTMLLabelElement;
|
|
7
|
+
type LabelProps = LabelHTMLAttributes<LabelRef>;
|
|
8
|
+
|
|
9
|
+
export const Label = forwardRef<LabelRef, LabelProps>(({ className, ...delegated }, ref) => {
|
|
10
|
+
return <label ref={ref} className={cx('c-label', className)} {...delegated} />;
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
Label.displayName = 'Label';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Progress } from '.';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Progress> = {
|
|
6
|
+
title: 'Components/Progress',
|
|
7
|
+
component: Progress,
|
|
8
|
+
argTypes: {},
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
type Story = StoryObj<typeof Progress>;
|
|
13
|
+
|
|
14
|
+
export const Default: Story = {
|
|
15
|
+
name: 'Default',
|
|
16
|
+
render: () => {
|
|
17
|
+
const [progress, setProgress] = useState(13);
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const timer = setTimeout(() => setProgress(100), 1500);
|
|
21
|
+
return () => clearTimeout(timer);
|
|
22
|
+
}, []);
|
|
23
|
+
|
|
24
|
+
return <Progress value={progress} />;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Progress } from './progress';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as ProgressPrimitives from '@radix-ui/react-progress';
|
|
2
|
+
import { cx } from 'class-variance-authority';
|
|
3
|
+
|
|
4
|
+
import './progress.css';
|
|
5
|
+
|
|
6
|
+
type ProgressProps = ProgressPrimitives.ProgressProps;
|
|
7
|
+
|
|
8
|
+
export function Progress({ className, value }: ProgressProps) {
|
|
9
|
+
return (
|
|
10
|
+
<ProgressPrimitives.Root className={cx(className, 'c-progress-root')} value={value}>
|
|
11
|
+
<ProgressPrimitives.Indicator
|
|
12
|
+
className="c-progress-indicator"
|
|
13
|
+
style={{ transform: `translateX(-${100 - (value ?? 0)}%)` }}
|
|
14
|
+
/>
|
|
15
|
+
</ProgressPrimitives.Root>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './radio';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.c-radio-item {
|
|
2
|
+
@apply flex h-3 w-3 flex-shrink-0 items-center justify-center rounded-full border border-solid border-gray-200-700 bg-gray-50-900 p-0;
|
|
3
|
+
|
|
4
|
+
&:focus,
|
|
5
|
+
&:focus-visible {
|
|
6
|
+
@apply outline-none;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
&:disabled {
|
|
10
|
+
@apply bg-gray-100-800 opacity-40;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
&[aria-checked='true'] {
|
|
14
|
+
@apply border-cyan-700-200 bg-cyan-200-700;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.c-radio-indicator {
|
|
19
|
+
@apply block h-[6px] w-[6px] rounded-full bg-cyan-700-200;
|
|
20
|
+
}
|