@koaris/bloom-ui 1.1.2 → 1.2.1

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.
@@ -1,154 +0,0 @@
1
- import {
2
- DetailedHTMLProps,
3
- InputHTMLAttributes,
4
- useEffect,
5
- useState,
6
- forwardRef,
7
- } from 'react'
8
- import { twMerge } from 'tailwind-merge'
9
- import { FiCheck, FiX } from 'react-icons/fi'
10
- import masks from '../Shared/masks'
11
-
12
- /**
13
- * Primary UI component for user interaction
14
- */
15
- export interface InputProps
16
- extends DetailedHTMLProps<
17
- InputHTMLAttributes<HTMLInputElement>,
18
- HTMLInputElement
19
- > {
20
- disabled?: boolean
21
- placeholder?: string
22
- value?: string
23
- validated?: boolean
24
- error: boolean
25
- required?: boolean
26
- type: 'text' | 'password' | 'date' | 'cpf' | 'phone' | 'cnpj' | 'cep'
27
- }
28
-
29
- const Input = forwardRef<HTMLInputElement, InputProps>(
30
- (
31
- {
32
- className,
33
- disabled,
34
- placeholder,
35
- value,
36
- validated,
37
- error,
38
- required,
39
- type,
40
- onClick,
41
- ...rest
42
- }: InputProps,
43
- ref,
44
- ) => {
45
- const [selected, setSelected] = useState(false)
46
- const [inputValue, setInputValue] = useState(value)
47
- const [hasNumber, setHasNumber] = useState(false)
48
- const [hasSpecialCharacteres, setHasSpecialCharacteres] = useState(false)
49
- const [hasEightCharacteres, setHasEightCharacteres] = useState(false)
50
-
51
- const handleFocus = () => {
52
- setSelected(!selected)
53
- }
54
-
55
- const handleBlur = () => {
56
- setSelected(false)
57
- }
58
-
59
- const handleInput = (event: React.FocusEvent<HTMLInputElement>) => {
60
- setInputValue(event.currentTarget.value)
61
- checkPassword(event.currentTarget.value as string)
62
- }
63
-
64
- useEffect(() => {
65
- setInputValue(value)
66
- }, [value])
67
-
68
- const checkPassword = (value: string) => {
69
- setHasSpecialCharacteres(value?.match(masks.password[0]) !== null)
70
- setHasNumber(value?.match(masks.password[1]) !== null)
71
- setHasEightCharacteres(value?.match(masks.password[2]) !== null)
72
- }
73
-
74
- return (
75
- <>
76
- {type === 'text' || type === 'password' || type === 'date' ? (
77
- <>
78
- <input
79
- type={type}
80
- required={required}
81
- ref={ref}
82
- className={twMerge(
83
- 'flex items-center justify-center border-2 border-neutral rounded-sm w-full px-3 py-2 text-md hover:shadow-md hover:shadow-neutral-500 focus:outline-none',
84
- className,
85
- disabled === true && 'opacity-50 cursor-not-allowed',
86
- selected === true && 'border-2 border-orange-500',
87
- validated === true && 'border-2 border-green-900',
88
- error === true && 'border-2 border-red-900',
89
- )}
90
- onClick={onClick}
91
- onFocus={handleFocus}
92
- onChange={handleInput}
93
- onBlur={handleBlur}
94
- placeholder={placeholder}
95
- value={inputValue}
96
- {...rest}
97
- />
98
- {type === 'password' &&
99
- (!hasEightCharacteres ||
100
- !hasSpecialCharacteres ||
101
- !hasNumber) && (
102
- <ul className="py-1">
103
- <li className="flex items-center px-2">
104
- {hasEightCharacteres ? <FiCheck /> : <FiX />}
105
- <span className="px-1">Pelo menos 8 caracteres</span>
106
- </li>
107
- <li className="flex items-center px-2">
108
- {hasSpecialCharacteres ? <FiCheck /> : <FiX />}
109
- <span className="px-1">
110
- Pelo menos 1 símbolo (@, !, $, etc)
111
- </span>
112
- </li>
113
- <li className="flex items-center px-2">
114
- {hasNumber ? <FiCheck /> : <FiX />}
115
- <span className="px-1">Deve conter 1 número</span>
116
- </li>
117
- </ul>
118
- )}
119
- </>
120
- ) : (
121
- <input
122
- type={type}
123
- required={required}
124
- ref={ref}
125
- className={twMerge(
126
- 'flex items-center justify-center border-2 border-neutral rounded-sm w-full px-3 py-2 text-md hover:shadow-md hover:shadow-neutral-500 focus:outline-none',
127
- className,
128
- disabled === true && 'opacity-50 cursor-not-allowed',
129
- selected === true && 'border-2 border-orange-500',
130
- error === true && 'border-2 border-red-900',
131
- )}
132
- onClick={onClick}
133
- onFocus={handleFocus}
134
- onChange={handleInput}
135
- onBlur={handleBlur}
136
- placeholder={placeholder}
137
- value={inputValue}
138
- {...rest}
139
- /* mask={masks[type as keyof typeof masks]} */
140
- />
141
- )}
142
- {error === true && (
143
- <label htmlFor={rest.id} className="text-red-900">
144
- Campo inválido.
145
- </label>
146
- )}
147
- </>
148
- )
149
- },
150
- )
151
-
152
- Input.displayName = 'Input'
153
-
154
- export { Input }
@@ -1,39 +0,0 @@
1
- import { DetailedHTMLProps, AnchorHTMLAttributes } from 'react'
2
- import { twMerge } from 'tailwind-merge'
3
-
4
- /**
5
- * Primary UI component for user interaction
6
- */
7
- export interface LinkProps
8
- extends DetailedHTMLProps<
9
- AnchorHTMLAttributes<HTMLAnchorElement>,
10
- HTMLAnchorElement
11
- > {
12
- url: string
13
- newPage: boolean
14
- disabled?: boolean
15
- children: string | JSX.Element
16
- }
17
-
18
- export const Link = ({
19
- className,
20
- disabled,
21
- url,
22
- newPage = true,
23
- onClick,
24
- ...rest
25
- }: LinkProps) => {
26
- return (
27
- <a
28
- className={twMerge(
29
- 'text-blue-800 font-bold',
30
- typeof rest.children !== 'string' && 'px-4',
31
- disabled === true && 'opacity-50 cursor-not-allowed',
32
- className,
33
- )}
34
- href={url}
35
- {...(newPage && { target: '_blank', rel: 'noopener noreferrer' })}
36
- {...rest}
37
- />
38
- )
39
- }
@@ -1,35 +0,0 @@
1
- import { DetailedHTMLProps, HTMLAttributes } from 'react'
2
- import { twMerge } from 'tailwind-merge'
3
- import { Text } from '../Text'
4
-
5
- export interface MultiStepProps
6
- extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
7
- size: number
8
- currentStep?: number
9
- }
10
-
11
- export const MultiStep = ({ className, size, currentStep }: MultiStepProps) => {
12
- return (
13
- <div className="w-full">
14
- <Text tag="label" color="neutral-100" size="xs">
15
- {`Passo ${currentStep} de ${size}`}
16
- </Text>
17
- <div className={`grid gap-2 grid-cols-${size} grid-flow-col mt-1`}>
18
- {Array.from(Array(size).keys()).map((_, index) => {
19
- return (
20
- <div
21
- key={index}
22
- className={twMerge(
23
- 'h-1 rounded-full',
24
- currentStep && index < currentStep
25
- ? 'bg-orange-500'
26
- : 'bg-neutral-500',
27
- className,
28
- )}
29
- />
30
- )
31
- })}
32
- </div>
33
- </div>
34
- )
35
- }
@@ -1,67 +0,0 @@
1
- import { DetailedHTMLProps, HTMLAttributes, useState } from 'react'
2
- import { twMerge } from 'tailwind-merge'
3
- import { FiCheck } from 'react-icons/fi'
4
-
5
- const options = [
6
- { id: 1, value: 'option1', label: 'Opção 1' },
7
- { id: 2, value: 'option2', label: 'Opção 2' },
8
- ]
9
-
10
- export interface RadioGroupProps
11
- extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
12
- disabled?: boolean
13
- options: typeof options
14
- required?: boolean
15
- }
16
-
17
- export const RadioGroup = ({
18
- disabled,
19
- options = [
20
- { id: 1, value: 'option1', label: 'Opção 1' },
21
- { id: 2, value: 'option2', label: 'Opção 2' },
22
- ],
23
- required = false,
24
- className,
25
- }: RadioGroupProps) => {
26
- const [selectedOption, setSelectedOption] = useState('')
27
-
28
- const handleOptionChange = (value: string) => {
29
- setSelectedOption(value)
30
- }
31
-
32
- return (
33
- <div className="flex flex-col ">
34
- {options.map((option) => (
35
- <div key={option.id} className="flex py-2 items-center">
36
- <label
37
- htmlFor={`radio${option.id}`}
38
- className={twMerge(
39
- 'relative rounded-full border-2 w-5 h-5 flex items-center justify-center hover:border-orange-500 hover:cursor-pointer',
40
- selectedOption === option.value
41
- ? 'bg-orange-500 border-orange-500'
42
- : 'border-neutral-500 hover:shadow-md hover:shadow-orange-500',
43
- disabled === true && 'opacity-50 cursor-not-allowed',
44
- className,
45
- )}
46
- >
47
- <input
48
- type="radio"
49
- id={`radio${option.id}`}
50
- name="radioGroup"
51
- value={option.value}
52
- required={required}
53
- className="hidden"
54
- checked={selectedOption === option.value}
55
- onChange={() => handleOptionChange(option.value)}
56
- disabled={disabled}
57
- />
58
- {selectedOption === option.value && (
59
- <FiCheck color="#FFFFFF" size={12} style={{ strokeWidth: 4 }} />
60
- )}
61
- </label>
62
- <span className="px-2">{option.label}</span>
63
- </div>
64
- ))}
65
- </div>
66
- )
67
- }
@@ -1,60 +0,0 @@
1
- const masks = {
2
- password: [/^(?=.*[!@#$%^&*])/, /(?=.*[0-9])/, /.{8,}$/],
3
- date: [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/],
4
- cpf: [
5
- /\d/,
6
- /\d/,
7
- /\d/,
8
- '.',
9
- /\d/,
10
- /\d/,
11
- /\d/,
12
- '.',
13
- /\d/,
14
- /\d/,
15
- /\d/,
16
- '-',
17
- /\d/,
18
- /\d/,
19
- ],
20
- cnpj: [
21
- /\d/,
22
- /\d/,
23
- '.',
24
- /\d/,
25
- /\d/,
26
- /\d/,
27
- '.',
28
- /\d/,
29
- /\d/,
30
- /\d/,
31
- '/',
32
- /\d/,
33
- /\d/,
34
- /\d/,
35
- /\d/,
36
- '-',
37
- /\d/,
38
- /\d/,
39
- ],
40
- cep: [/\d/, /\d/, /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/],
41
- phone: [
42
- '(',
43
- /[1-9]/,
44
- /[1-9]/,
45
- ')',
46
- ' ',
47
- /\d/,
48
- /\d/,
49
- /\d/,
50
- /\d/,
51
- /\d/,
52
- '-',
53
- /\d/,
54
- /\d/,
55
- /\d/,
56
- /\d/,
57
- ],
58
- }
59
-
60
- export default masks
@@ -1,62 +0,0 @@
1
- import { DetailedHTMLProps, HTMLAttributes, ReactNode } from 'react'
2
- import { twMerge } from 'tailwind-merge'
3
-
4
- export interface TextProps
5
- extends DetailedHTMLProps<
6
- HTMLAttributes<HTMLLabelElement>,
7
- HTMLLabelElement
8
- > {
9
- children: ReactNode
10
- color?: string
11
- size?:
12
- | 'xxs'
13
- | 'xs'
14
- | 'sm'
15
- | 'md'
16
- | 'lg'
17
- | 'xl'
18
- | '2xl'
19
- | '3xl'
20
- | '4xl'
21
- | '5xl'
22
- | '6xl'
23
- | '7xl'
24
- | '8xl'
25
- | '9xl'
26
- tag?: 'p' | 'strong' | 'span' | 'label'
27
- htmlFor?: string
28
- }
29
-
30
- export const Text = ({
31
- children,
32
- color = 'neutral-800',
33
- size = 'md',
34
- tag = 'p',
35
- className,
36
- ...rest
37
- }: TextProps) => {
38
- const fontSize = {
39
- xxs: 'text-xxs',
40
- xs: 'text-xs',
41
- sm: 'text-sm',
42
- md: 'text-md',
43
- lg: 'text-lg',
44
- xl: 'text-xl',
45
- '2xl': 'text-2xl',
46
- '3xl': 'text-3xl',
47
- '4xl': 'text-4xl',
48
- '5xl': 'text-5xl',
49
- '6xl': 'text-6xl',
50
- '7xl': 'text-7xl',
51
- '8xl': 'text-8xl',
52
- '9xl': 'text-9xl',
53
- }[size]
54
-
55
- const Tag = tag as React.ElementType
56
-
57
- return (
58
- <Tag {...rest} className={twMerge(`text-${color} ${fontSize}`, className)}>
59
- {children}
60
- </Tag>
61
- )
62
- }
@@ -1,79 +0,0 @@
1
- import {
2
- DetailedHTMLProps,
3
- TextareaHTMLAttributes,
4
- useEffect,
5
- useState,
6
- } from 'react'
7
- import { twMerge } from 'tailwind-merge'
8
-
9
- export interface TextAreaProps
10
- extends DetailedHTMLProps<
11
- TextareaHTMLAttributes<HTMLTextAreaElement>,
12
- HTMLTextAreaElement
13
- > {
14
- disabled?: boolean
15
- reference?: React.RefObject<HTMLTextAreaElement>
16
- placeholder?: string
17
- value?: string
18
- validated?: boolean
19
- error: boolean
20
- required?: boolean
21
- resize?: boolean
22
- type: 'text' | 'password' | 'date' | 'cpf' | 'phone' | 'cnpj' | 'cep'
23
- }
24
-
25
- export const TextArea = ({
26
- className,
27
- disabled,
28
- reference,
29
- value,
30
- error,
31
- required,
32
- placeholder,
33
- resize,
34
- onClick,
35
- ...rest
36
- }: TextAreaProps) => {
37
- const [selected, setSelected] = useState(false)
38
- const [inputValue, setInputValue] = useState(value)
39
-
40
- const handleFocus = () => {
41
- setSelected(!selected)
42
- }
43
-
44
- const handleBlur = () => {
45
- setSelected(false)
46
- }
47
-
48
- const handleInput = (event: React.FocusEvent<HTMLTextAreaElement>) => {
49
- setInputValue(event.currentTarget.value)
50
- }
51
-
52
- useEffect(() => {
53
- setInputValue(value)
54
- }, [value])
55
-
56
- return (
57
- <textarea
58
- required={required}
59
- ref={reference}
60
- disabled={disabled}
61
- className={twMerge(
62
- 'rounded-sm w-full px-3 py-2 border-2 border-neutral text-md hover:shadow-md hover:shadow-neutral-500 focus:outline-none',
63
- 'resize-y h-32',
64
- className,
65
- disabled === true && 'opacity-50 cursor-not-allowed',
66
- selected === true && 'border-2 border-orange-500',
67
- error === true && 'border-2 border-red-900',
68
- resize === false && 'resize-none overflow-hidden',
69
- )}
70
- onClick={onClick}
71
- onFocus={handleFocus}
72
- onChange={handleInput}
73
- onBlur={handleBlur}
74
- placeholder={placeholder}
75
- value={inputValue}
76
- {...rest}
77
- />
78
- )
79
- }
@@ -1,102 +0,0 @@
1
- import {
2
- DetailedHTMLProps,
3
- InputHTMLAttributes,
4
- useEffect,
5
- useState,
6
- forwardRef,
7
- } from 'react'
8
- import { twMerge } from 'tailwind-merge'
9
-
10
- export interface TextInputProps
11
- extends DetailedHTMLProps<
12
- InputHTMLAttributes<HTMLInputElement>,
13
- HTMLInputElement
14
- > {
15
- disabled?: boolean
16
- placeholder?: string
17
- prefix?: string
18
- value?: string
19
- variant?: 'primary' | 'secondary'
20
- validated?: boolean
21
- error: boolean
22
- required?: boolean
23
- type: 'text' | 'password' | 'date' | 'cpf' | 'phone' | 'cnpj' | 'cep'
24
- }
25
-
26
- const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
27
- (
28
- {
29
- className,
30
- disabled,
31
- value,
32
- prefix,
33
- placeholder,
34
- error,
35
- type = 'text',
36
- variant = 'primary',
37
- onClick,
38
- ...rest
39
- }: TextInputProps,
40
- ref,
41
- ) => {
42
- const [selected, setSelected] = useState(false)
43
- const [inputValue, setInputValue] = useState(value)
44
-
45
- const handleFocus = () => {
46
- setSelected(!selected)
47
- }
48
-
49
- const handleBlur = () => {
50
- setSelected(false)
51
- }
52
-
53
- const handleInput = (event: React.FocusEvent<HTMLInputElement>) => {
54
- setInputValue(event.currentTarget.value)
55
- }
56
-
57
- useEffect(() => {
58
- setInputValue(value)
59
- }, [value])
60
-
61
- return (
62
- <div
63
- className={twMerge(
64
- ' py-2 px-4 border-2 rounded-sm box-border flex items-baseline bg-neutral-200',
65
- 'hover:shadow-md hover:shadow-neutral-500 focus:outline-none',
66
- variant === 'secondary' && 'bg-neutral-800 border-neutral-800 ',
67
- selected === true && 'border-2 border-orange-500',
68
- disabled === true && 'opacity-50 cursor-not-allowed',
69
- error === true && 'border-2 border-red-900',
70
- )}
71
- >
72
- {!!prefix && (
73
- <span className="text-neutral-500 sm:text-sm">{prefix}</span>
74
- )}
75
- <input
76
- type={type}
77
- required={rest.required}
78
- onClick={onClick}
79
- onFocus={handleFocus}
80
- onChange={handleInput}
81
- onBlur={handleBlur}
82
- value={inputValue}
83
- placeholder={placeholder}
84
- disabled={disabled}
85
- ref={ref}
86
- className={twMerge(
87
- 'flex items-center justify-center bg-neutral-200 rounded-sm w-full px-1 py-2 text-md',
88
- 'focus:outline-none text-neutral-800',
89
- disabled === true && 'cursor-not-allowed',
90
- variant === 'secondary' && 'bg-neutral-800 text-neutral',
91
- className,
92
- )}
93
- {...rest}
94
- />
95
- </div>
96
- )
97
- },
98
- )
99
-
100
- TextInput.displayName = 'TextInput'
101
-
102
- export { TextInput }
package/src/index.tsx DELETED
@@ -1,14 +0,0 @@
1
- export * from './components/Card'
2
- export * from './components/Button'
3
- export * from './components/Link'
4
- export * from './components/RadioGroup'
5
- export * from './components/Checkbox'
6
- export * from './components/Input'
7
- export * from './components/TextInput'
8
- export * from './components/TextArea'
9
- export * from './components/Text'
10
- export * from './components/Heading'
11
- export * from './components/Box'
12
- export * from './components/Form'
13
- export * from './components/Avatar'
14
- export * from './components/MultiStep'
@@ -1,7 +0,0 @@
1
- @tailwind base;
2
- @tailwind components;
3
- @tailwind utilities;
4
-
5
- html {
6
- @apply font-default;
7
- }
@@ -1,19 +0,0 @@
1
- import { Config } from 'tailwindcss'
2
- import { colors, fontSizes, fontWeights, fonts, lineHeights, raddi, space } from '@koaris/tokens';
3
-
4
- /** @type {import('tailwindcss').Config} */
5
- export default {
6
- content: ['./src/**/*.{js,ts,jsx,tsx}'],
7
- theme: {
8
- extend: {
9
- colors: colors,
10
- fontSize: fontSizes,
11
- fontWeight: fontWeights,
12
- fontFamily: fonts,
13
- lineHeight: lineHeights,
14
- raddi,
15
- space
16
- },
17
- },
18
- plugins: [],
19
- } satisfies Config
package/tsconfig.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "extends": "@koaris/ts-config/react.json",
3
- "include": ["src"],
4
- "splitting": true,
5
- "external": ["react"],
6
- "entryPoints": ["src/index.tsx"],
7
- }
package/tsup.config.ts DELETED
@@ -1,14 +0,0 @@
1
- import { defineConfig } from "tsup";
2
-
3
- export default defineConfig({
4
- entry: ["src/index.tsx", "src/tailwind-preset.ts"],
5
- format: ["esm"],
6
- tsconfig: "./tsconfig.json",
7
- outExtension({ format }) {
8
- return { js: ".mjs" };
9
- },
10
- dts: true,
11
- external: ["react"],
12
-
13
- clean: true,
14
- });