@usefui/components 1.5.3 → 1.7.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/CHANGELOG.md +12 -0
- package/dist/index.d.mts +615 -51
- package/dist/index.d.ts +615 -51
- package/dist/index.js +3154 -660
- package/dist/index.mjs +3131 -661
- package/package.json +12 -12
- package/src/__tests__/Avatar.test.tsx +55 -55
- package/src/__tests__/MessageBubble.test.tsx +179 -0
- package/src/__tests__/Shimmer.test.tsx +122 -0
- package/src/__tests__/Tree.test.tsx +275 -0
- package/src/accordion/Accordion.stories.tsx +6 -4
- package/src/accordion/hooks/index.tsx +3 -1
- package/src/accordion/index.tsx +1 -2
- package/src/avatar/Avatar.stories.tsx +37 -7
- package/src/avatar/index.tsx +90 -19
- package/src/avatar/styles/index.ts +58 -12
- package/src/badge/Badge.stories.tsx +27 -5
- package/src/badge/index.tsx +21 -14
- package/src/badge/styles/index.ts +69 -40
- package/src/button/Button.stories.tsx +40 -27
- package/src/button/index.tsx +13 -9
- package/src/button/styles/index.ts +308 -47
- package/src/card/index.tsx +2 -4
- package/src/checkbox/Checkbox.stories.tsx +72 -33
- package/src/checkbox/hooks/index.tsx +5 -1
- package/src/checkbox/index.tsx +8 -6
- package/src/checkbox/styles/index.ts +239 -19
- package/src/collapsible/Collapsible.stories.tsx +6 -4
- package/src/collapsible/hooks/index.tsx +3 -1
- package/src/dialog/Dialog.stories.tsx +173 -31
- package/src/dialog/hooks/index.tsx +5 -1
- package/src/dialog/styles/index.ts +15 -8
- package/src/dropdown/Dropdown.stories.tsx +61 -23
- package/src/dropdown/hooks/index.tsx +3 -1
- package/src/dropdown/index.tsx +51 -40
- package/src/dropdown/styles/index.ts +30 -19
- package/src/field/Field.stories.tsx +183 -24
- package/src/field/hooks/index.tsx +5 -1
- package/src/field/index.tsx +930 -13
- package/src/field/styles/index.ts +246 -14
- package/src/field/types/index.ts +31 -0
- package/src/field/utils/index.ts +201 -0
- package/src/index.ts +8 -1
- package/src/message-bubble/MessageBubble.stories.tsx +138 -0
- package/src/message-bubble/hooks/index.tsx +41 -0
- package/src/message-bubble/index.tsx +171 -0
- package/src/message-bubble/styles/index.ts +58 -0
- package/src/otp-field/OTPField.stories.tsx +22 -24
- package/src/otp-field/hooks/index.tsx +3 -1
- package/src/otp-field/index.tsx +14 -3
- package/src/otp-field/styles/index.ts +114 -16
- package/src/otp-field/types/index.ts +9 -1
- package/src/overlay/styles/index.ts +1 -0
- package/src/ruler/Ruler.stories.tsx +43 -0
- package/src/ruler/constants/index.ts +3 -0
- package/src/ruler/hooks/index.tsx +53 -0
- package/src/ruler/index.tsx +239 -0
- package/src/ruler/styles/index.tsx +154 -0
- package/src/ruler/types/index.ts +17 -0
- package/src/select/Select.stories.tsx +91 -0
- package/src/select/hooks/index.tsx +71 -0
- package/src/select/index.tsx +331 -0
- package/src/select/styles/index.tsx +156 -0
- package/src/sheet/hooks/index.tsx +5 -1
- package/src/shimmer/Shimmer.stories.tsx +97 -0
- package/src/shimmer/index.tsx +64 -0
- package/src/shimmer/styles/index.ts +33 -0
- package/src/skeleton/index.tsx +7 -6
- package/src/spinner/Spinner.stories.tsx +29 -4
- package/src/spinner/index.tsx +16 -6
- package/src/spinner/styles/index.ts +41 -22
- package/src/switch/Switch.stories.tsx +46 -17
- package/src/switch/hooks/index.tsx +5 -1
- package/src/switch/index.tsx +5 -8
- package/src/switch/styles/index.ts +45 -45
- package/src/tabs/Tabs.stories.tsx +43 -15
- package/src/tabs/hooks/index.tsx +5 -1
- package/src/text-area/Textarea.stories.tsx +45 -8
- package/src/text-area/index.tsx +9 -6
- package/src/text-area/styles/index.ts +1 -1
- package/src/toggle/Toggle.stories.tsx +6 -4
- package/src/toolbar/hooks/index.tsx +5 -1
- package/src/tree/Tree.stories.tsx +141 -0
- package/src/tree/hooks/tree-node-provider.tsx +50 -0
- package/src/tree/hooks/tree-provider.tsx +75 -0
- package/src/tree/index.tsx +231 -0
- package/src/tree/styles/index.ts +23 -0
- package/tsconfig.build.json +20 -0
- package/tsconfig.json +1 -3
- package/src/privacy-field/PrivacyField.stories.tsx +0 -29
- package/src/privacy-field/index.tsx +0 -56
- package/src/privacy-field/styles/index.ts +0 -17
package/src/skeleton/index.tsx
CHANGED
|
@@ -4,16 +4,17 @@ import React from "react";
|
|
|
4
4
|
import { SkeletonLoader } from "./styles";
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
+
ComponentShapeEnum,
|
|
7
8
|
ComponentSizeEnum,
|
|
9
|
+
type IComponentShape,
|
|
8
10
|
type IComponentSize,
|
|
9
|
-
type TComponentShape,
|
|
10
11
|
} from "../../../../types";
|
|
11
12
|
|
|
12
13
|
export interface SkeletonProperties
|
|
13
|
-
extends
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
14
|
+
extends
|
|
15
|
+
IComponentSize,
|
|
16
|
+
IComponentShape,
|
|
17
|
+
React.ComponentPropsWithRef<"span"> {}
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Skeletons are used to convoy a loading state information.
|
|
@@ -26,7 +27,7 @@ export interface SkeletonProperties
|
|
|
26
27
|
export const Skeleton = (props: SkeletonProperties): React.ReactElement => {
|
|
27
28
|
const {
|
|
28
29
|
sizing = ComponentSizeEnum.Medium,
|
|
29
|
-
shape =
|
|
30
|
+
shape = ComponentShapeEnum.Smooth,
|
|
30
31
|
...restProps
|
|
31
32
|
} = props;
|
|
32
33
|
|
|
@@ -8,6 +8,17 @@ import { Page, Spinner } from "..";
|
|
|
8
8
|
const meta = {
|
|
9
9
|
title: "Components/Spinner",
|
|
10
10
|
component: Spinner,
|
|
11
|
+
decorators: [
|
|
12
|
+
(Story) => (
|
|
13
|
+
<Page>
|
|
14
|
+
<Page.Content className="p-medium-30">
|
|
15
|
+
<div className="flex flex-column align-center justify-center h-100 g-medium-30">
|
|
16
|
+
<Story />
|
|
17
|
+
</div>
|
|
18
|
+
</Page.Content>
|
|
19
|
+
</Page>
|
|
20
|
+
),
|
|
21
|
+
],
|
|
11
22
|
tags: ["autodocs"],
|
|
12
23
|
} satisfies Meta<typeof Spinner>;
|
|
13
24
|
export default meta;
|
|
@@ -16,12 +27,26 @@ type Story = StoryObj<typeof meta>;
|
|
|
16
27
|
export const Default: Story = {
|
|
17
28
|
args: {},
|
|
18
29
|
render: ({ ...args }) => (
|
|
19
|
-
<
|
|
20
|
-
<
|
|
30
|
+
<React.Fragment>
|
|
31
|
+
<div className="flex align-center g-medium-30">
|
|
21
32
|
<Spinner sizing="small" {...args} />
|
|
22
33
|
<Spinner sizing="medium" {...args} />
|
|
23
34
|
<Spinner sizing="large" {...args} />
|
|
24
|
-
</
|
|
25
|
-
</
|
|
35
|
+
</div>
|
|
36
|
+
</React.Fragment>
|
|
37
|
+
),
|
|
38
|
+
};
|
|
39
|
+
export const Variants: Story = {
|
|
40
|
+
args: {},
|
|
41
|
+
render: ({ ...args }) => (
|
|
42
|
+
<React.Fragment>
|
|
43
|
+
{["circle", "circle-filled"].map((variant) => (
|
|
44
|
+
<div className="flex align-center g-medium-30" key={variant}>
|
|
45
|
+
<Spinner sizing="small" variant={variant} />
|
|
46
|
+
<Spinner sizing="medium" variant={variant} />
|
|
47
|
+
<Spinner sizing="large" variant={variant} />
|
|
48
|
+
</div>
|
|
49
|
+
))}
|
|
50
|
+
</React.Fragment>
|
|
26
51
|
),
|
|
27
52
|
};
|
package/src/spinner/index.tsx
CHANGED
|
@@ -2,18 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
import React from "react";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { AnimatedSpinner } from "./styles";
|
|
6
6
|
import type { IComponentSize } from "../../../../types";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
type SpinnerVariant = "circle" | "circle-filled";
|
|
9
|
+
|
|
10
|
+
interface SpinnerProperties extends IComponentSize {
|
|
11
|
+
variant?: SpinnerVariant;
|
|
12
|
+
}
|
|
9
13
|
|
|
10
14
|
/**
|
|
11
|
-
* Spinners are used to
|
|
15
|
+
* Spinners are used to convey a loading state information.
|
|
12
16
|
*
|
|
13
|
-
* @param {
|
|
14
|
-
* @param {
|
|
17
|
+
* @param {SpinnerProperties} props - The props for the Spinner component.
|
|
18
|
+
* @param {string} props.sizing - The size of the component. Defaults to `medium`.
|
|
19
|
+
* @param {SpinnerVariant} props.variant - The spinner animation variant. Defaults to `circle`.
|
|
15
20
|
* @returns {ReactElement} The Spinner component.
|
|
16
21
|
*/
|
|
17
22
|
export const Spinner = (props: SpinnerProperties) => {
|
|
18
|
-
return
|
|
23
|
+
return (
|
|
24
|
+
<AnimatedSpinner
|
|
25
|
+
data-variant={props?.variant ?? "circle"}
|
|
26
|
+
data-size={props?.sizing ?? "medium"}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
19
29
|
};
|
|
@@ -3,41 +3,60 @@
|
|
|
3
3
|
import styled, { css, keyframes } from "styled-components";
|
|
4
4
|
|
|
5
5
|
const Rotate = keyframes`
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
100% {
|
|
10
|
-
transform: rotate(360deg);
|
|
11
|
-
}
|
|
6
|
+
0% { transform: rotate(0deg); }
|
|
7
|
+
100% { transform: rotate(360deg); }
|
|
12
8
|
`;
|
|
13
9
|
|
|
14
|
-
const
|
|
10
|
+
const SpinnerSizeStyles = css`
|
|
15
11
|
&[data-size="small"] {
|
|
16
|
-
width:
|
|
17
|
-
height:
|
|
12
|
+
width: 12px;
|
|
13
|
+
height: 12px;
|
|
18
14
|
}
|
|
19
15
|
&[data-size="medium"] {
|
|
20
|
-
width:
|
|
21
|
-
height:
|
|
16
|
+
width: 18px;
|
|
17
|
+
height: 18px;
|
|
22
18
|
}
|
|
23
19
|
&[data-size="large"] {
|
|
24
|
-
width:
|
|
25
|
-
height:
|
|
20
|
+
width: 24px;
|
|
21
|
+
height: 24px;
|
|
26
22
|
}
|
|
27
23
|
`;
|
|
24
|
+
const CircleStyles = css`
|
|
25
|
+
border: var(--measurement-small-80) solid var(--font-color-alpha-10);
|
|
26
|
+
border-bottom-color: transparent;
|
|
27
|
+
border-radius: var(--measurement-large-90);
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
display: inline-block;
|
|
34
|
-
box-sizing: border-box;
|
|
35
|
-
|
|
29
|
+
animation: ${Rotate} 0.8s linear infinite;
|
|
30
|
+
`;
|
|
31
|
+
const CircleFilledStyles = css`
|
|
36
32
|
border: var(--measurement-small-60) solid var(--font-color-alpha-30);
|
|
33
|
+
|
|
34
|
+
border-top-color: transparent;
|
|
35
|
+
border-right-color: transparent;
|
|
37
36
|
border-bottom-color: transparent;
|
|
37
|
+
|
|
38
38
|
border-radius: var(--measurement-large-90);
|
|
39
|
+
background-color: var(--font-color-alpha-10);
|
|
40
|
+
|
|
41
|
+
&::before {
|
|
42
|
+
position: absolute;
|
|
43
|
+
content: "";
|
|
44
|
+
width: 100%;
|
|
45
|
+
height: 100%;
|
|
46
|
+
background-color: var(--body-color);
|
|
47
|
+
border-radius: var(--measurement-large-90);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
animation: ${Rotate} 0.8s linear infinite;
|
|
51
|
+
`;
|
|
39
52
|
|
|
40
|
-
|
|
53
|
+
export const AnimatedSpinner = styled.div`
|
|
54
|
+
${SpinnerSizeStyles}
|
|
41
55
|
|
|
42
|
-
|
|
56
|
+
&[data-variant="circle"] {
|
|
57
|
+
${CircleStyles}
|
|
58
|
+
}
|
|
59
|
+
&[data-variant="circle-filled"] {
|
|
60
|
+
${CircleFilledStyles}
|
|
61
|
+
}
|
|
43
62
|
`;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
3
|
|
|
4
|
-
import { Switch } from "..";
|
|
4
|
+
import { Field, Page, Switch } from "..";
|
|
5
5
|
import { ComponentSizeEnum, ComponentVariantEnum } from "../../../../types";
|
|
6
6
|
|
|
7
7
|
// Duplicated doc: The JSDoc content isn't rendering on Storybook.
|
|
@@ -20,9 +20,13 @@ const meta = {
|
|
|
20
20
|
tags: ["autodocs"],
|
|
21
21
|
decorators: [
|
|
22
22
|
(Story) => (
|
|
23
|
-
<
|
|
24
|
-
<
|
|
25
|
-
|
|
23
|
+
<Page>
|
|
24
|
+
<Page.Content className="p-medium-30">
|
|
25
|
+
<div className="flex flex-column align-center justify-center h-100 g-medium-30">
|
|
26
|
+
<Story />
|
|
27
|
+
</div>
|
|
28
|
+
</Page.Content>
|
|
29
|
+
</Page>
|
|
26
30
|
),
|
|
27
31
|
],
|
|
28
32
|
} satisfies Meta<typeof Switch>;
|
|
@@ -67,12 +71,26 @@ export const DefaultChecked: Story = {
|
|
|
67
71
|
};
|
|
68
72
|
export const Sizes: Story = {
|
|
69
73
|
render: ({ ...args }) => (
|
|
70
|
-
<div className="flex g-medium-30">
|
|
71
|
-
{["
|
|
74
|
+
<div className="flex flex-column g-medium-30">
|
|
75
|
+
{["small", "medium", "large"].map((item) => (
|
|
72
76
|
<Switch.Root key={item}>
|
|
73
|
-
<
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
<Field.Label
|
|
78
|
+
id={`${item}-label`}
|
|
79
|
+
htmlFor={item}
|
|
80
|
+
className="flex align-center g-medium-30"
|
|
81
|
+
optional
|
|
82
|
+
>
|
|
83
|
+
<Switch name={item} sizing={item}>
|
|
84
|
+
<Switch.Thumb />
|
|
85
|
+
</Switch>
|
|
86
|
+
|
|
87
|
+
<div className="flex flex-column">
|
|
88
|
+
<Field.Meta variant="emphasis">{item}</Field.Meta>
|
|
89
|
+
<Field.Meta variant="hint" className="fs-small-60">
|
|
90
|
+
The {item} Checkbox sizing
|
|
91
|
+
</Field.Meta>
|
|
92
|
+
</div>
|
|
93
|
+
</Field.Label>
|
|
76
94
|
</Switch.Root>
|
|
77
95
|
))}
|
|
78
96
|
</div>
|
|
@@ -80,15 +98,26 @@ export const Sizes: Story = {
|
|
|
80
98
|
};
|
|
81
99
|
export const Variants: Story = {
|
|
82
100
|
render: ({ ...args }) => (
|
|
83
|
-
<div className="flex g-medium-30">
|
|
84
|
-
{["
|
|
101
|
+
<div className="flex flex-column g-medium-30">
|
|
102
|
+
{["accent", "primary"].map((item) => (
|
|
85
103
|
<Switch.Root key={item}>
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
104
|
+
<Field.Label
|
|
105
|
+
id={`${item}-label`}
|
|
106
|
+
htmlFor={item}
|
|
107
|
+
className="flex align-center g-medium-30"
|
|
108
|
+
optional
|
|
109
|
+
>
|
|
110
|
+
<Switch name={item} variant={item}>
|
|
111
|
+
<Switch.Thumb />
|
|
112
|
+
</Switch>
|
|
113
|
+
|
|
114
|
+
<div className="flex flex-column">
|
|
115
|
+
<Field.Meta variant="emphasis">{item}</Field.Meta>
|
|
116
|
+
<Field.Meta variant="hint" className="fs-small-60">
|
|
117
|
+
The {item} Checkbox variant
|
|
118
|
+
</Field.Meta>
|
|
119
|
+
</div>
|
|
120
|
+
</Field.Label>
|
|
92
121
|
</Switch.Root>
|
|
93
122
|
))}
|
|
94
123
|
</div>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import React, { useState, createContext, useContext } from "react";
|
|
2
4
|
import { IReactChildren, IComponentAPI } from "../../../../../types";
|
|
3
5
|
|
|
@@ -9,7 +11,9 @@ const defaultComponentAPI = {
|
|
|
9
11
|
const SwitchContext = createContext<IComponentAPI>(defaultComponentAPI);
|
|
10
12
|
export const useSwitch = () => useContext(SwitchContext);
|
|
11
13
|
|
|
12
|
-
export const SwitchProvider = ({
|
|
14
|
+
export const SwitchProvider = ({
|
|
15
|
+
children,
|
|
16
|
+
}: IReactChildren): React.JSX.Element => {
|
|
13
17
|
const context = useSwitchProvider();
|
|
14
18
|
|
|
15
19
|
return (
|
package/src/switch/index.tsx
CHANGED
|
@@ -17,17 +17,14 @@ export interface ISwitchComposition {
|
|
|
17
17
|
Thumb: typeof SwitchThumb;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
type SwitchVariants = "primary" | "accent";
|
|
20
21
|
export interface ISwitchProperties
|
|
21
|
-
extends React.ComponentProps<"button">,
|
|
22
|
-
IComponentSize,
|
|
23
|
-
IComponentVariant,
|
|
24
|
-
IComponentStyling {
|
|
22
|
+
extends React.ComponentProps<"button">, IComponentSize, IComponentStyling {
|
|
25
23
|
defaultChecked?: boolean;
|
|
24
|
+
variant?: SwitchVariants;
|
|
26
25
|
}
|
|
27
26
|
export interface ISwitchThumbProperties
|
|
28
|
-
extends React.ComponentProps<"span">,
|
|
29
|
-
IComponentSize,
|
|
30
|
-
IComponentStyling {}
|
|
27
|
+
extends React.ComponentProps<"span">, IComponentSize, IComponentStyling {}
|
|
31
28
|
|
|
32
29
|
/**
|
|
33
30
|
* Switch are toggle components that allows the user to turn a setting on or off.
|
|
@@ -40,7 +37,7 @@ export interface ISwitchThumbProperties
|
|
|
40
37
|
* @param {ISwitchProperties} props - The props for the Switch component.
|
|
41
38
|
* @param {boolean} props.raw - Whether the switch should be rendered without any styles.
|
|
42
39
|
* @param {ComponentSizeEnum} props.sizing - The size of the switch.
|
|
43
|
-
* @param {
|
|
40
|
+
* @param {SwitchVariants} props.variant - The variant of the switch.
|
|
44
41
|
* @param {boolean} props.defaultChecked - The initial state of the switch.
|
|
45
42
|
* @param {ReactNode} props.children - The content to be rendered inside the switch.
|
|
46
43
|
* @returns {ReactElement} The Switch component.
|
|
@@ -15,81 +15,79 @@ const SwitchDefaultStyles = css`
|
|
|
15
15
|
}
|
|
16
16
|
`;
|
|
17
17
|
const SwitchVariantsStyles = css`
|
|
18
|
-
&[data-variant="
|
|
18
|
+
&[data-variant="accent"] {
|
|
19
19
|
&[aria-checked="true"] {
|
|
20
|
-
background-color: var(--color-
|
|
21
|
-
border-color: var(--
|
|
20
|
+
background-color: var(--color-accent);
|
|
21
|
+
border-color: var(--alpha-accent-10);
|
|
22
22
|
}
|
|
23
23
|
&[aria-checked="false"] {
|
|
24
24
|
background-color: var(--font-color-alpha-10);
|
|
25
25
|
border-color: var(--font-color-alpha-10);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
&[data-variant="
|
|
29
|
-
&[aria-checked="true"] {
|
|
30
|
-
background-color: var(--font-color-alpha-10);
|
|
31
|
-
border-color: var(--font-color-alpha-10);
|
|
32
|
-
}
|
|
33
|
-
&[aria-checked="false"] {
|
|
34
|
-
background-color: var(--body-color-alpha-10);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
&[data-variant="ghost"] {
|
|
28
|
+
&[data-variant="primary"] {
|
|
39
29
|
&[aria-checked="true"] {
|
|
30
|
+
background-color: var(--color-green);
|
|
40
31
|
border-color: var(--font-color-alpha-10);
|
|
41
|
-
background-color: var(--body-color-alpha-10);
|
|
42
32
|
}
|
|
43
33
|
&[aria-checked="false"] {
|
|
34
|
+
background-color: var(--font-color-alpha-10);
|
|
44
35
|
border-color: var(--font-color-alpha-10);
|
|
45
36
|
}
|
|
46
37
|
}
|
|
47
38
|
`;
|
|
48
39
|
const SwitchSizeStyles = css`
|
|
49
40
|
&[data-size="small"] {
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
--thumb-size: calc(
|
|
42
|
+
var(--measurement-medium-40) - var(--measurement-small-10)
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
padding: 0 var(--measurement-small-10);
|
|
46
|
+
width: calc(var(--thumb-size) * 2);
|
|
47
|
+
height: var(--measurement-medium-40);
|
|
52
48
|
|
|
53
49
|
span {
|
|
54
|
-
width: var(--
|
|
55
|
-
height: var(--
|
|
50
|
+
width: var(--thumb-size);
|
|
51
|
+
height: var(--thumb-size);
|
|
52
|
+
|
|
56
53
|
&[data-checked="true"] {
|
|
57
|
-
transform: translateX(var(--
|
|
58
|
-
}
|
|
59
|
-
&[data-checked="false"] {
|
|
60
|
-
transform: translateX(var(--measurement-small-60));
|
|
54
|
+
transform: translateX(var(--thumb-size));
|
|
61
55
|
}
|
|
62
56
|
}
|
|
63
57
|
}
|
|
64
|
-
|
|
65
58
|
&[data-size="medium"] {
|
|
66
|
-
|
|
59
|
+
--thumb-size: calc(
|
|
60
|
+
var(--measurement-medium-60) - var(--measurement-small-10)
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
padding: 0 var(--measurement-small-10);
|
|
64
|
+
width: calc(var(--thumb-size) * 2);
|
|
67
65
|
height: var(--measurement-medium-60);
|
|
68
66
|
|
|
69
67
|
span {
|
|
70
|
-
width: var(--
|
|
71
|
-
height: var(--
|
|
68
|
+
width: var(--thumb-size);
|
|
69
|
+
height: var(--thumb-size);
|
|
70
|
+
|
|
72
71
|
&[data-checked="true"] {
|
|
73
|
-
transform: translateX(var(--
|
|
74
|
-
}
|
|
75
|
-
&[data-checked="false"] {
|
|
76
|
-
transform: translateX(var(--measurement-small-60));
|
|
72
|
+
transform: translateX(var(--thumb-size));
|
|
77
73
|
}
|
|
78
74
|
}
|
|
79
75
|
}
|
|
80
|
-
|
|
81
76
|
&[data-size="large"] {
|
|
82
|
-
|
|
77
|
+
--thumb-size: calc(
|
|
78
|
+
var(--measurement-medium-70) - var(--measurement-small-30)
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
padding: 0 var(--measurement-small-30);
|
|
82
|
+
width: calc(var(--thumb-size) * 2);
|
|
83
83
|
height: var(--measurement-medium-70);
|
|
84
84
|
|
|
85
85
|
span {
|
|
86
|
-
width: var(--
|
|
87
|
-
height: var(--
|
|
86
|
+
width: var(--thumb-size);
|
|
87
|
+
height: var(--thumb-size);
|
|
88
|
+
|
|
88
89
|
&[data-checked="true"] {
|
|
89
|
-
transform: translateX(
|
|
90
|
-
}
|
|
91
|
-
&[data-checked="false"] {
|
|
92
|
-
transform: translateX(var(--measurement-small-80));
|
|
90
|
+
transform: translateX(var(--thumb-size));
|
|
93
91
|
}
|
|
94
92
|
}
|
|
95
93
|
}
|
|
@@ -107,12 +105,14 @@ export const Thumb = styled.span<any>`
|
|
|
107
105
|
all: unset;
|
|
108
106
|
display: block;
|
|
109
107
|
|
|
110
|
-
background:
|
|
111
|
-
border-radius:
|
|
112
|
-
|
|
108
|
+
background: white;
|
|
109
|
+
border-radius: var(--measurement-large-90);
|
|
110
|
+
box-shadow:
|
|
111
|
+
0 var(--measurement-small-30) var(--measurement-small-80)
|
|
112
|
+
var(--alpha-mono-darkest-10),
|
|
113
|
+
0 var(--measurement-small-30) var(--measurement-small-60)
|
|
114
|
+
calc(var(--measurement-small-30) * -1) var(--alpha-mono-darkest-10);
|
|
113
115
|
|
|
114
|
-
|
|
115
|
-
background: var(--font-color);
|
|
116
|
-
}
|
|
116
|
+
transition: all 0.1s ease-in-out 0.2s;
|
|
117
117
|
}
|
|
118
118
|
`;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
3
|
|
|
4
|
-
import { Tabs } from "..";
|
|
4
|
+
import { Page, Tabs } from "..";
|
|
5
5
|
import { ComponentVariantEnum, ComponentSizeEnum } from "../../../../types";
|
|
6
6
|
|
|
7
7
|
// Duplicated doc: The JSDoc content isn't rendering on Storybook.
|
|
@@ -22,9 +22,13 @@ const meta = {
|
|
|
22
22
|
tags: ["autodocs"],
|
|
23
23
|
decorators: [
|
|
24
24
|
(Story) => (
|
|
25
|
-
<
|
|
26
|
-
<
|
|
27
|
-
|
|
25
|
+
<Page>
|
|
26
|
+
<Page.Content className="p-medium-30">
|
|
27
|
+
<div className="flex flex-column g-medium-30">
|
|
28
|
+
<Story />
|
|
29
|
+
</div>
|
|
30
|
+
</Page.Content>
|
|
31
|
+
</Page>
|
|
28
32
|
),
|
|
29
33
|
],
|
|
30
34
|
} satisfies Meta<typeof Tabs>;
|
|
@@ -61,27 +65,51 @@ export const Default: Story = {
|
|
|
61
65
|
render: ({ ...args }) => (
|
|
62
66
|
<Tabs.Root>
|
|
63
67
|
<Tabs>
|
|
64
|
-
<div className="flex g-medium-30">
|
|
65
|
-
<Tabs.Trigger value="
|
|
66
|
-
|
|
68
|
+
<div className="flex g-medium-30 p-b-medium-30">
|
|
69
|
+
<Tabs.Trigger value="eng" variant="link">
|
|
70
|
+
Engineering
|
|
71
|
+
</Tabs.Trigger>
|
|
72
|
+
<Tabs.Trigger value="design" variant="link">
|
|
73
|
+
Design
|
|
74
|
+
</Tabs.Trigger>
|
|
67
75
|
</div>
|
|
76
|
+
<Tabs.Content value="eng">
|
|
77
|
+
Iste nam quasi quam. Ullam numquam reiciendis ratione rem consequatur
|
|
78
|
+
vero suscipit ut dicta, ducimus magni doloribus est, accusantium
|
|
79
|
+
explicabo quae fuga.
|
|
80
|
+
</Tabs.Content>
|
|
81
|
+
<Tabs.Content value="design">
|
|
82
|
+
Fuga aut reiciendis porro! Aspernatur autem voluptatibus, quis
|
|
83
|
+
assumenda consectetur, qui ipsam placeat cum harum animi
|
|
84
|
+
necessitatibus! Error nisi dolore numquam neque.
|
|
85
|
+
</Tabs.Content>
|
|
68
86
|
</Tabs>
|
|
69
|
-
<Tabs.Content value="🐻❄️">🐻❄️</Tabs.Content>
|
|
70
|
-
<Tabs.Content value="🐻">🐻</Tabs.Content>
|
|
71
87
|
</Tabs.Root>
|
|
72
88
|
),
|
|
73
89
|
};
|
|
74
90
|
export const DefaultOpen: Story = {
|
|
75
91
|
render: ({ ...args }) => (
|
|
76
92
|
<Tabs.Root>
|
|
77
|
-
<Tabs defaultOpen="
|
|
78
|
-
<div className="flex g-medium-30">
|
|
79
|
-
<Tabs.Trigger value="
|
|
80
|
-
|
|
93
|
+
<Tabs defaultOpen="eng">
|
|
94
|
+
<div className="flex g-medium-30 p-b-medium-30">
|
|
95
|
+
<Tabs.Trigger value="eng" variant="link">
|
|
96
|
+
Engineering
|
|
97
|
+
</Tabs.Trigger>
|
|
98
|
+
<Tabs.Trigger value="design" variant="link">
|
|
99
|
+
Design
|
|
100
|
+
</Tabs.Trigger>
|
|
81
101
|
</div>
|
|
102
|
+
<Tabs.Content value="eng">
|
|
103
|
+
Iste nam quasi quam. Ullam numquam reiciendis ratione rem consequatur
|
|
104
|
+
vero suscipit ut dicta, ducimus magni doloribus est, accusantium
|
|
105
|
+
explicabo quae fuga.
|
|
106
|
+
</Tabs.Content>
|
|
107
|
+
<Tabs.Content value="design">
|
|
108
|
+
Fuga aut reiciendis porro! Aspernatur autem voluptatibus, quis
|
|
109
|
+
assumenda consectetur, qui ipsam placeat cum harum animi
|
|
110
|
+
necessitatibus! Error nisi dolore numquam neque.
|
|
111
|
+
</Tabs.Content>
|
|
82
112
|
</Tabs>
|
|
83
|
-
<Tabs.Content value="🐻❄️">🐻❄️</Tabs.Content>
|
|
84
|
-
<Tabs.Content value="🐻">🐻</Tabs.Content>
|
|
85
113
|
</Tabs.Root>
|
|
86
114
|
),
|
|
87
115
|
};
|
package/src/tabs/hooks/index.tsx
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import React, { createContext, useContext, useState } from "react";
|
|
2
4
|
import { IReactChildren, IComponentAPI } from "../../../../../types";
|
|
3
5
|
|
|
@@ -9,7 +11,9 @@ const defaultComponentAPI = {
|
|
|
9
11
|
const TabsContext = createContext<IComponentAPI>(defaultComponentAPI);
|
|
10
12
|
export const useTabs = () => useContext(TabsContext);
|
|
11
13
|
|
|
12
|
-
export const TabsProvider = ({
|
|
14
|
+
export const TabsProvider = ({
|
|
15
|
+
children,
|
|
16
|
+
}: IReactChildren): React.JSX.Element => {
|
|
13
17
|
const context = useTabsProvider();
|
|
14
18
|
|
|
15
19
|
return (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
3
|
|
|
4
|
-
import { Page, Textarea } from "..";
|
|
4
|
+
import { Field, Page, Textarea } from "..";
|
|
5
5
|
import { TComponentSize } from "../../../../types";
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -11,6 +11,15 @@ const meta = {
|
|
|
11
11
|
title: "Components/Textarea",
|
|
12
12
|
component: Textarea,
|
|
13
13
|
tags: ["autodocs"],
|
|
14
|
+
decorators: [
|
|
15
|
+
(Story) => (
|
|
16
|
+
<Page>
|
|
17
|
+
<Page.Content className="p-medium-30">
|
|
18
|
+
<Story />
|
|
19
|
+
</Page.Content>
|
|
20
|
+
</Page>
|
|
21
|
+
),
|
|
22
|
+
],
|
|
14
23
|
} satisfies Meta<typeof Textarea>;
|
|
15
24
|
export default meta;
|
|
16
25
|
|
|
@@ -21,12 +30,40 @@ export const Default: Story = {
|
|
|
21
30
|
resizable: false,
|
|
22
31
|
},
|
|
23
32
|
render: ({ ...args }) => (
|
|
24
|
-
<
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
<div className="flex flex-column align-center justify-center h-100 g-medium-30">
|
|
34
|
+
<Field.Wrapper style={{ width: 325 }}>
|
|
35
|
+
<Textarea />
|
|
36
|
+
</Field.Wrapper>
|
|
37
|
+
</div>
|
|
38
|
+
),
|
|
39
|
+
};
|
|
40
|
+
export const Sizes: Story = {
|
|
41
|
+
args: {
|
|
42
|
+
variant: "secondary",
|
|
43
|
+
resizable: false,
|
|
44
|
+
},
|
|
45
|
+
render: ({ ...args }) => (
|
|
46
|
+
<div className="flex flex-column align-center justify-center h-100 g-medium-30">
|
|
47
|
+
{["small", "medium", "large"].map((item) => (
|
|
48
|
+
<Field.Wrapper key={item} style={{ width: 325 }}>
|
|
49
|
+
<Textarea sizing={item} />
|
|
50
|
+
</Field.Wrapper>
|
|
51
|
+
))}
|
|
52
|
+
</div>
|
|
53
|
+
),
|
|
54
|
+
};
|
|
55
|
+
export const Variants: Story = {
|
|
56
|
+
args: {
|
|
57
|
+
variant: "secondary",
|
|
58
|
+
resizable: false,
|
|
59
|
+
},
|
|
60
|
+
render: ({ ...args }) => (
|
|
61
|
+
<div className="flex flex-column align-center justify-center h-100 g-medium-30">
|
|
62
|
+
{["primary", "secondary", "ghost"].map((item) => (
|
|
63
|
+
<Field.Wrapper key={item} style={{ width: 325 }}>
|
|
64
|
+
<Textarea variant={item} />
|
|
65
|
+
</Field.Wrapper>
|
|
66
|
+
))}
|
|
67
|
+
</div>
|
|
31
68
|
),
|
|
32
69
|
};
|