@ttoss/ui 5.0.7 → 5.0.9

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.
Files changed (36) hide show
  1. package/LICENSE +21 -674
  2. package/package.json +8 -8
  3. package/src/components/ActionButton.tsx +0 -41
  4. package/src/components/Badge.tsx +0 -54
  5. package/src/components/Box.tsx +0 -1
  6. package/src/components/Button.tsx +0 -43
  7. package/src/components/Card.tsx +0 -1
  8. package/src/components/Checkbox.tsx +0 -36
  9. package/src/components/CloseButton.tsx +0 -49
  10. package/src/components/Container.tsx +0 -12
  11. package/src/components/Divider.tsx +0 -1
  12. package/src/components/Flex.tsx +0 -1
  13. package/src/components/Grid.tsx +0 -1
  14. package/src/components/Heading.tsx +0 -1
  15. package/src/components/HelpText.tsx +0 -31
  16. package/src/components/IconButton.tsx +0 -12
  17. package/src/components/Image.tsx +0 -1
  18. package/src/components/InfiniteLinearProgress.tsx +0 -38
  19. package/src/components/Input.tsx +0 -83
  20. package/src/components/InputNumber.tsx +0 -150
  21. package/src/components/InputPassword/InputPassword.tsx +0 -32
  22. package/src/components/InputPassword/useHidePassInput.ts +0 -26
  23. package/src/components/Label.tsx +0 -46
  24. package/src/components/LinearProgress.tsx +0 -4
  25. package/src/components/Link.tsx +0 -20
  26. package/src/components/Paragraph.tsx +0 -1
  27. package/src/components/Radio.tsx +0 -1
  28. package/src/components/Select.tsx +0 -284
  29. package/src/components/Slider.tsx +0 -1
  30. package/src/components/Spinner.tsx +0 -1
  31. package/src/components/Stack.tsx +0 -24
  32. package/src/components/Text.tsx +0 -1
  33. package/src/components/Textarea.tsx +0 -55
  34. package/src/index.ts +0 -58
  35. package/src/theme/ThemeProvider.tsx +0 -36
  36. package/src/theme/useTheme.ts +0 -3
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@ttoss/ui",
3
- "version": "5.0.7",
3
+ "version": "5.0.9",
4
4
  "description": "Primitive layout, typographic, and other components for styling applications.",
5
+ "license": "MIT",
5
6
  "author": "ttoss",
6
7
  "contributors": [
7
8
  "Pedro Arantes <pedro@arantespp.com> (https://arantespp.com/contact)"
@@ -19,20 +20,19 @@
19
20
  }
20
21
  },
21
22
  "files": [
22
- "dist",
23
- "src"
23
+ "dist"
24
24
  ],
25
25
  "sideEffects": false,
26
26
  "dependencies": {
27
27
  "@theme-ui/match-media": "^0.16.2",
28
28
  "react-select": "^5.8.0",
29
29
  "theme-ui": "^0.16.2",
30
- "@ttoss/theme": "^1.7.22"
30
+ "@ttoss/theme": "^1.8.0"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "@emotion/react": "^11",
34
34
  "react": ">=16.8.0",
35
- "@ttoss/react-icons": "^0.4.3"
35
+ "@ttoss/react-icons": "^0.4.4"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@emotion/react": "^11.11.4",
@@ -42,9 +42,9 @@
42
42
  "jest": "^29.7.0",
43
43
  "react": "^18.3.1",
44
44
  "tsup": "^8.3.0",
45
- "@ttoss/config": "^1.34.0",
46
- "@ttoss/react-icons": "^0.4.3",
47
- "@ttoss/test-utils": "^2.1.16"
45
+ "@ttoss/config": "^1.34.1",
46
+ "@ttoss/test-utils": "^2.1.17",
47
+ "@ttoss/react-icons": "^0.4.4"
48
48
  },
49
49
  "keywords": [
50
50
  "React",
@@ -1,41 +0,0 @@
1
- import { Button, type ButtonProps } from './Button';
2
-
3
- export type ActionButtonProps = Omit<
4
- ButtonProps,
5
- 'rightIcon' | 'leftIcon' | 'variant'
6
- > & {
7
- icon: ButtonProps['leftIcon'];
8
- variant?: 'default' | 'accent' | 'quiet';
9
- };
10
-
11
- export const ActionButton = ({
12
- icon,
13
- variant = 'default',
14
- sx,
15
- ...props
16
- }: ActionButtonProps) => {
17
- return (
18
- <Button
19
- variant={`buttons.actionButton.${variant}`}
20
- leftIcon={icon}
21
- sx={{
22
- padding: 'sm',
23
- gap: 'xs',
24
- fontFamily: 'caption',
25
- borderRadius: 'action',
26
- outlineColor: 'transparent',
27
- ':disabled': props.disabled
28
- ? {
29
- backgroundColor: 'muted',
30
- color: 'onMuted',
31
- cursor: 'not-allowed',
32
- border: 'muted',
33
- borderColor: 'onMuted',
34
- }
35
- : undefined,
36
- ...sx,
37
- }}
38
- {...props}
39
- />
40
- );
41
- };
@@ -1,54 +0,0 @@
1
- import { type BadgeProps as BadgePropsUi, Badge as BadgeUi } from 'theme-ui';
2
- import { Icon, IconType } from '@ttoss/react-icons';
3
- import { Text } from '../components/Text';
4
-
5
- export type BadgeProps = BadgePropsUi & {
6
- icon?: IconType;
7
- chip?: boolean;
8
- onDelete?: () => void;
9
- };
10
-
11
- export const Badge = ({
12
- icon,
13
- children,
14
- sx,
15
- chip,
16
- onDelete,
17
- ...props
18
- }: BadgeProps) => {
19
- return (
20
- <BadgeUi
21
- sx={{
22
- display: 'flex',
23
- alignItems: 'center',
24
- fontFamily: 'caption',
25
- fontWeight: 'normal',
26
- lineHeight: 'base',
27
- fontSize: 'sm',
28
- paddingX: 'xs',
29
- borderRadius: 'informative',
30
- paddingY: '2xs',
31
- gap: 'xs',
32
- ...sx,
33
- }}
34
- {...props}
35
- >
36
- {icon && <Icon inline icon={icon} />}
37
-
38
- {children}
39
-
40
- {chip && (
41
- <Text
42
- sx={{
43
- cursor: 'pointer',
44
- lineHeight: 0,
45
- color: 'currentcolor',
46
- alignSelf: 'center',
47
- }}
48
- >
49
- <Icon onClick={onDelete} inline icon="close" />
50
- </Text>
51
- )}
52
- </BadgeUi>
53
- );
54
- };
@@ -1 +0,0 @@
1
- export { Box, type BoxProps } from 'theme-ui';
@@ -1,43 +0,0 @@
1
- import * as React from 'react';
2
- import {
3
- type ButtonProps as ButtonPropsUi,
4
- Button as ButtonUi,
5
- } from 'theme-ui';
6
- import { Icon, IconType } from '@ttoss/react-icons';
7
-
8
- export type ButtonProps = ButtonPropsUi & {
9
- leftIcon?: IconType;
10
- rightIcon?: IconType;
11
- loading?: boolean;
12
- };
13
-
14
- export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
15
- (props, ref) => {
16
- const { children, leftIcon, rightIcon, loading, ...restProps } = props;
17
-
18
- return (
19
- <ButtonUi
20
- type="button"
21
- {...restProps}
22
- ref={ref}
23
- sx={{
24
- cursor: 'pointer',
25
- paddingX: 'xl',
26
- paddingY: 'lg',
27
- fontFamily: 'body',
28
- display: 'inline-flex',
29
- alignItems: 'center',
30
- gap: 'lg',
31
- ...restProps.sx,
32
- }}
33
- >
34
- {loading && <Icon inline icon="three-dots-loading" />}
35
- {!loading && leftIcon && <Icon inline icon={leftIcon} />}
36
- {children}
37
- {rightIcon && <Icon inline icon={rightIcon} />}
38
- </ButtonUi>
39
- );
40
- }
41
- );
42
-
43
- Button.displayName = 'Button';
@@ -1 +0,0 @@
1
- export { Card, type CardProps } from 'theme-ui';
@@ -1,36 +0,0 @@
1
- import * as React from 'react';
2
- import {
3
- Checkbox as CheckBoxUi,
4
- CheckboxProps as CheckboxPropsUi,
5
- } from 'theme-ui';
6
-
7
- export interface CheckboxProps extends CheckboxPropsUi {
8
- indeterminate?: boolean;
9
- }
10
-
11
- export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
12
- ({ indeterminate = false, ...rest }, ref) => {
13
- const innerRef = React.useRef<HTMLInputElement>(null);
14
-
15
- /**
16
- * https://stackoverflow.com/a/68163315/8786986
17
- */
18
- React.useImperativeHandle(ref, () => {
19
- return innerRef.current as HTMLInputElement;
20
- });
21
-
22
- React.useEffect(() => {
23
- if (innerRef.current) {
24
- innerRef.current.indeterminate = indeterminate;
25
- }
26
- }, [indeterminate]);
27
-
28
- if (indeterminate) {
29
- return <input type="checkbox" ref={innerRef} {...rest} />;
30
- }
31
-
32
- return <CheckBoxUi ref={innerRef} {...rest} />;
33
- }
34
- );
35
-
36
- Checkbox.displayName = 'Checkbox';
@@ -1,49 +0,0 @@
1
- import * as React from 'react';
2
- import { Button, type ButtonProps } from './Button';
3
- import { Icon } from '@ttoss/react-icons';
4
-
5
- export type CloseButtonProps = ButtonProps & {
6
- label?: string;
7
- onlyText?: boolean;
8
- };
9
-
10
- export const CloseButton = React.forwardRef<
11
- HTMLButtonElement,
12
- CloseButtonProps
13
- >(({ label, sx, onlyText, ...props }, ref) => {
14
- if (onlyText && !label) {
15
- return null;
16
- }
17
-
18
- return (
19
- <Button
20
- variant="buttons.closeButton"
21
- type="button"
22
- aria-label={label}
23
- sx={{
24
- fontFamily: 'caption',
25
- fontSize: 'xs',
26
- display: 'inline-flex',
27
- alignItems: 'center',
28
- cursor: 'pointer',
29
- lineHeight: 'normal',
30
- gap: 'sm',
31
- padding: 'sm',
32
- width: 'fit-content',
33
- transition: 'all 0.2s',
34
- '& > iconify-icon': {
35
- fontSize: 'base',
36
- },
37
- ...sx,
38
- }}
39
- {...props}
40
- ref={ref}
41
- >
42
- {label}
43
-
44
- {!onlyText && <Icon icon="close" />}
45
- </Button>
46
- );
47
- });
48
-
49
- CloseButton.displayName = 'CloseButton';
@@ -1,12 +0,0 @@
1
- import * as React from 'react';
2
- import { type ContainerProps, Container as ContainerUi } from 'theme-ui';
3
-
4
- export type { ContainerProps };
5
-
6
- export const Container = React.forwardRef<HTMLDivElement, ContainerProps>(
7
- (props, ref) => {
8
- return <ContainerUi ref={ref} {...props} />;
9
- }
10
- );
11
-
12
- Container.displayName = 'Container';
@@ -1 +0,0 @@
1
- export { Divider, type DividerProps } from 'theme-ui';
@@ -1 +0,0 @@
1
- export { Flex, type FlexProps } from 'theme-ui';
@@ -1 +0,0 @@
1
- export { Grid, type GridProps } from 'theme-ui';
@@ -1 +0,0 @@
1
- export { Heading, type HeadingProps } from 'theme-ui';
@@ -1,31 +0,0 @@
1
- import { Text, TextProps } from './Text';
2
-
3
- export type HelpTextProps = Omit<TextProps, 'variant'> & {
4
- disabled?: boolean;
5
- negative?: boolean;
6
- };
7
-
8
- export const HelpText = ({
9
- sx,
10
- disabled,
11
- negative,
12
- ...props
13
- }: HelpTextProps) => {
14
- const variant = ['text.help', negative ? 'negative' : undefined]
15
- .filter(Boolean)
16
- .join('.');
17
-
18
- return (
19
- <Text
20
- variant={variant}
21
- sx={{
22
- fontSize: 'sm',
23
- fontFamily: 'caption',
24
- lineHeight: 'base',
25
- ...sx,
26
- }}
27
- aria-disabled={disabled ? 'true' : undefined}
28
- {...props}
29
- />
30
- );
31
- };
@@ -1,12 +0,0 @@
1
- import * as React from 'react';
2
- import { type IconButtonProps, IconButton as IconButtonUi } from 'theme-ui';
3
-
4
- export type { IconButtonProps };
5
-
6
- export const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(
7
- (props, ref) => {
8
- return <IconButtonUi type="button" {...props} ref={ref} />;
9
- }
10
- );
11
-
12
- IconButton.displayName = 'IconButton';
@@ -1 +0,0 @@
1
- export { Image, type ImageProps } from 'theme-ui';
@@ -1,38 +0,0 @@
1
- import * as React from 'react';
2
- import { LinearProgress } from './LinearProgress';
3
-
4
- const MAX_PROGRESS = 100;
5
-
6
- export const InfiniteLinearProgress = () => {
7
- const [progress, setProgress] = React.useState(0);
8
-
9
- React.useEffect(() => {
10
- const timer = setInterval(() => {
11
- setProgress((oldProgress) => {
12
- if (oldProgress === MAX_PROGRESS) {
13
- return 0;
14
- }
15
-
16
- let diff = 0;
17
-
18
- if (oldProgress > 0.97 * MAX_PROGRESS) {
19
- diff -= 0.75 * MAX_PROGRESS;
20
- } else if (oldProgress > 0.6 * MAX_PROGRESS) {
21
- diff = Math.random() * (MAX_PROGRESS - oldProgress) * 0.1;
22
- } else {
23
- diff = Math.random() * (MAX_PROGRESS * 0.02);
24
- }
25
-
26
- return Math.min(oldProgress + diff, MAX_PROGRESS);
27
- });
28
- }, 100);
29
-
30
- return () => {
31
- clearInterval(timer);
32
- };
33
- }, []);
34
-
35
- return (
36
- <LinearProgress max={MAX_PROGRESS} value={progress} role="progressbar" />
37
- );
38
- };
@@ -1,83 +0,0 @@
1
- import * as React from 'react';
2
- import { Flex, Text } from '..';
3
- import { Icon, type IconType } from '@ttoss/react-icons';
4
- import { InputProps as InputPropsUI, Input as InputUI } from 'theme-ui';
5
-
6
- export interface InputProps extends InputPropsUI {
7
- leadingIcon?: IconType;
8
- onLeadingIconClick?: () => void;
9
- trailingIcon?: IconType;
10
- onTrailingIconClick?: () => void;
11
- }
12
-
13
- export const Input = React.forwardRef<HTMLInputElement, InputProps>(
14
- (
15
- {
16
- leadingIcon,
17
- trailingIcon: trailingIconProp,
18
- onLeadingIconClick,
19
- onTrailingIconClick,
20
- className,
21
- sx,
22
- ...inputProps
23
- },
24
- ref
25
- ) => {
26
- const trailingIcon = inputProps['aria-invalid']
27
- ? 'warning-alt'
28
- : trailingIconProp;
29
-
30
- return (
31
- <Flex
32
- className={className}
33
- sx={{ ...sx, position: 'relative', padding: 0, border: 'none' }}
34
- >
35
- {leadingIcon && (
36
- <Text
37
- sx={{
38
- position: 'absolute',
39
- alignSelf: 'center',
40
- left: '1rem',
41
- cursor: onLeadingIconClick ? 'pointer' : 'default',
42
- }}
43
- onClick={onLeadingIconClick}
44
- variant="leading-icon"
45
- >
46
- <Icon inline icon={leadingIcon} />
47
- </Text>
48
- )}
49
- <InputUI
50
- ref={ref}
51
- sx={{
52
- fontFamily: 'body',
53
- paddingY: 'lg',
54
- paddingX: 'xl',
55
- ...sx,
56
- paddingLeft: leadingIcon ? '3xl' : undefined,
57
- paddingRight: trailingIcon ? '3xl' : undefined,
58
- margin: 0,
59
- }}
60
- className={className}
61
- {...inputProps}
62
- />
63
-
64
- {trailingIcon && (
65
- <Text
66
- sx={{
67
- position: 'absolute',
68
- right: '1rem',
69
- alignSelf: 'center',
70
- cursor: onTrailingIconClick ? 'pointer' : 'default',
71
- }}
72
- variant="trailing-icon"
73
- onClick={onTrailingIconClick}
74
- >
75
- <Icon inline icon={trailingIcon} />
76
- </Text>
77
- )}
78
- </Flex>
79
- );
80
- }
81
- );
82
-
83
- Input.displayName = 'Input';
@@ -1,150 +0,0 @@
1
- import * as React from 'react';
2
- import { Flex, Text } from '..';
3
- import { Icon } from '@ttoss/react-icons';
4
- import { Input, type InputProps as InputPropsUI } from 'theme-ui';
5
-
6
- export type InputNumberProps = Omit<
7
- InputPropsUI,
8
- 'type' | 'variant' | 'onChange'
9
- > & {
10
- onChange: (value: number) => void;
11
- value?: number;
12
- infoIcon?: boolean;
13
- onClickInfoIcon?: () => void;
14
- };
15
-
16
- export const InputNumber = React.forwardRef<HTMLInputElement, InputNumberProps>(
17
- ({ sx, value, infoIcon, onChange, onClickInfoIcon, ...inputProps }, ref) => {
18
- const sxProps: InputPropsUI['sx'] = React.useMemo(() => {
19
- const size = String(typeof value === 'undefined' ? 0 : value).length;
20
-
21
- if (inputProps['aria-invalid'] === 'true') {
22
- return {
23
- width: `calc(139px + ${size > 1 ? size * 10 : 0}px)`,
24
- textAlign: 'left',
25
- '&[type=number]::-webkit-inner-spin-button, &[type=number]::-webkit-outer-spin-button':
26
- {
27
- WebkitAppearance: 'none',
28
- margin: 0,
29
- },
30
- ...sx,
31
- paddingLeft: '3xl',
32
- paddingRight: '2xl',
33
- margin: 0,
34
- };
35
- }
36
-
37
- return {
38
- width: `calc(108px + ${size > 1 ? size * 10 : 0}px)`,
39
- textAlign: 'center',
40
- '&[type=number]::-webkit-inner-spin-button, &[type=number]::-webkit-outer-spin-button':
41
- {
42
- WebkitAppearance: 'none',
43
- margin: 0,
44
- },
45
- fontFamily: 'body',
46
- paddingY: 'lg',
47
- paddingX: 'xl',
48
- ...sx,
49
- paddingLeft: '2xl',
50
- paddingRight: '2xl',
51
- margin: 0,
52
- };
53
- }, [inputProps, value, sx]);
54
-
55
- const handleChangeUp = () => {
56
- if (inputProps.disabled) {
57
- return;
58
- }
59
-
60
- if (typeof value !== 'number') {
61
- onChange(-1);
62
- return;
63
- }
64
-
65
- onChange(value - 1);
66
- };
67
-
68
- const handleChangeDown = () => {
69
- if (inputProps.disabled) {
70
- return;
71
- }
72
-
73
- if (typeof value !== 'number') {
74
- onChange(1);
75
- return;
76
- }
77
-
78
- onChange(value + 1);
79
- };
80
-
81
- return (
82
- <Flex
83
- sx={{
84
- width: 'fit-content',
85
- ...sx,
86
- position: 'relative',
87
- padding: 0,
88
- border: 'none',
89
- }}
90
- ref={ref}
91
- aria-invalid={inputProps['aria-invalid']}
92
- >
93
- <Input
94
- ref={ref}
95
- variant="forms.inputNumber"
96
- sx={sxProps}
97
- type="number"
98
- onChange={(e) => {
99
- onChange(Number(e.target.value));
100
- }}
101
- value={value}
102
- {...inputProps}
103
- />
104
-
105
- <Text
106
- sx={{
107
- position: 'absolute',
108
- alignSelf: 'center',
109
- left: '1rem',
110
- zIndex: 1,
111
- cursor: 'pointer',
112
- }}
113
- onClick={handleChangeUp}
114
- >
115
- <Icon icon="picker-down" />
116
- </Text>
117
-
118
- {infoIcon && (
119
- <Text
120
- sx={{
121
- position: 'absolute',
122
- alignSelf: 'center',
123
- right: '2.5rem',
124
- zIndex: 1,
125
- cursor: onClickInfoIcon ? 'pointer' : 'default',
126
- }}
127
- onClick={onClickInfoIcon}
128
- >
129
- <Icon icon="info" />
130
- </Text>
131
- )}
132
-
133
- <Text
134
- sx={{
135
- position: 'absolute',
136
- alignSelf: 'center',
137
- right: '1rem',
138
- zIndex: 1,
139
- cursor: 'pointer',
140
- }}
141
- onClick={handleChangeDown}
142
- >
143
- <Icon icon="picker-up" />
144
- </Text>
145
- </Flex>
146
- );
147
- }
148
- );
149
-
150
- InputNumber.displayName = 'InputNumber';
@@ -1,32 +0,0 @@
1
- import * as React from 'react';
2
- import { Input } from '../Input';
3
- import { type InputProps } from '../Input';
4
- import { useHidePassInput } from './useHidePassInput';
5
-
6
- export type InputPasswordProps = Omit<
7
- InputProps,
8
- 'trailingIcon' | 'onTrailingIconClick' | 'type'
9
- > & {
10
- showPasswordByDefault?: boolean;
11
- };
12
-
13
- export const InputPassword = React.forwardRef<
14
- HTMLInputElement,
15
- InputPasswordProps
16
- >(({ showPasswordByDefault, ...inputPasswordProps }, ref) => {
17
- const { handleClick, icon, inputType } = useHidePassInput(
18
- !showPasswordByDefault
19
- );
20
-
21
- return (
22
- <Input
23
- ref={ref}
24
- {...inputPasswordProps}
25
- trailingIcon={icon}
26
- onTrailingIconClick={handleClick}
27
- type={inputType}
28
- />
29
- );
30
- });
31
-
32
- InputPassword.displayName = 'InputPassword';
@@ -1,26 +0,0 @@
1
- import * as React from 'react';
2
-
3
- export const useHidePassInput = (defaultValue = true) => {
4
- const [hidePass, setHidePass] = React.useState<boolean>(
5
- Boolean(defaultValue)
6
- );
7
-
8
- const { icon, inputType } = React.useMemo(() => {
9
- return {
10
- icon: hidePass ? 'view-off' : 'view-on',
11
- inputType: hidePass ? 'password' : 'text',
12
- };
13
- }, [hidePass]);
14
-
15
- const handleClick = () => {
16
- setHidePass((prev) => {
17
- return !prev;
18
- });
19
- };
20
-
21
- return {
22
- handleClick,
23
- icon,
24
- inputType,
25
- };
26
- };