@xjur-ui/react 1.0.0 → 1.0.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.
- package/.turbo/turbo-build.log +61 -57
- package/CHANGELOG.md +11 -0
- package/dist/components/avatar.d.ts +11 -0
- package/dist/components/avatar.js +58 -0
- package/dist/components/{ui/button.d.ts → button.d.ts} +2 -2
- package/dist/components/{ui/button.js → button.js} +9 -6
- package/dist/components/calendar.d.ts +11 -0
- package/dist/components/calendar.js +751 -0
- package/dist/components/checkbox.d.ts +8 -0
- package/dist/components/{ui/input/root.js → checkbox.js} +69 -79
- package/dist/components/chip.d.ts +24 -0
- package/dist/components/chip.js +255 -0
- package/dist/components/collapsible.d.ts +8 -0
- package/dist/components/collapsible.js +41 -0
- package/dist/components/date-picker.d.ts +20 -0
- package/dist/components/date-picker.js +230 -0
- package/dist/components/divider.d.ts +7 -0
- package/dist/components/divider.js +28 -0
- package/dist/components/dropdown-menu.d.ts +22 -0
- package/dist/components/dropdown-menu.js +294 -0
- package/dist/components/{resources/icons.d.ts → icon.d.ts} +11 -2
- package/dist/components/{ui/icon.js → icon.js} +18 -5
- package/dist/components/input.d.ts +32 -0
- package/dist/components/input.js +299 -0
- package/dist/components/list.d.ts +25 -0
- package/dist/components/{ui/input/content.js → list.js} +83 -87
- package/dist/components/{ui/logo.d.ts → logo.d.ts} +2 -2
- package/dist/components/{ui/logo.js → logo.js} +5 -5
- package/dist/components/{ui/otp-input.js → otp-input.js} +1 -1
- package/dist/components/radio.d.ts +10 -0
- package/dist/components/{ui/input/label.js → radio.js} +68 -77
- package/dist/components/search-input.d.ts +17 -0
- package/dist/components/search-input.js +274 -0
- package/dist/components/select.d.ts +33 -0
- package/dist/components/select.js +548 -0
- package/dist/components/sheet.d.ts +19 -0
- package/dist/components/sheet.js +251 -0
- package/dist/components/switch.d.ts +7 -0
- package/dist/components/switch.js +36 -0
- package/dist/components/tabs.d.ts +11 -0
- package/dist/components/tabs.js +54 -0
- package/dist/components/tag.d.ts +18 -0
- package/dist/components/tag.js +189 -0
- package/dist/components/{ui/typography.d.ts → typography.d.ts} +3 -3
- package/dist/components/{ui/typography.js → typography.js} +1 -1
- package/dist/index.css +1156 -62
- package/dist/index.d.ts +2 -17
- package/dist/index.js +0 -788
- package/eslint.config.js +8 -1
- package/package.json +40 -10
- package/src/components/avatar.tsx +53 -0
- package/src/components/{ui/button.tsx → button.tsx} +7 -5
- package/src/components/calendar.tsx +123 -0
- package/src/components/checkbox.tsx +57 -0
- package/src/components/chip.tsx +109 -0
- package/src/components/collapsible.tsx +35 -0
- package/src/components/date-picker.tsx +154 -0
- package/src/components/divider.tsx +23 -0
- package/src/components/dropdown-menu.tsx +101 -0
- package/src/components/{ui/icon.tsx → icon.tsx} +1 -1
- package/src/components/input.tsx +241 -0
- package/src/components/list.tsx +111 -0
- package/src/components/radio.tsx +74 -0
- package/src/components/search-input.tsx +112 -0
- package/src/components/select.tsx +234 -0
- package/src/components/sheet.tsx +141 -0
- package/src/components/switch.tsx +31 -0
- package/src/components/tabs.tsx +53 -0
- package/src/components/tag.tsx +91 -0
- package/src/index.css +4 -1
- package/src/index.ts +0 -1
- package/src/{components/resources → resources}/icons.ts +14 -1
- package/src/resources/input-mask.ts +91 -0
- package/dist/components/resources/icons.js +0 -133
- package/dist/components/resources/logo/horizontal.d.ts +0 -12
- package/dist/components/resources/logo/horizontal.js +0 -107
- package/dist/components/resources/logo/icon.d.ts +0 -12
- package/dist/components/resources/logo/icon.js +0 -79
- package/dist/components/resources/logo/index.d.ts +0 -4
- package/dist/components/resources/logo/index.js +0 -291
- package/dist/components/resources/logo/vertical.d.ts +0 -12
- package/dist/components/resources/logo/vertical.js +0 -107
- package/dist/components/ui/accordion.d.ts +0 -5
- package/dist/components/ui/accordion.js +0 -8
- package/dist/components/ui/icon.d.ts +0 -12
- package/dist/components/ui/index.d.ts +0 -17
- package/dist/components/ui/index.js +0 -788
- package/dist/components/ui/input/content.d.ts +0 -9
- package/dist/components/ui/input/index.d.ts +0 -12
- package/dist/components/ui/input/index.js +0 -335
- package/dist/components/ui/input/label.d.ts +0 -12
- package/dist/components/ui/input/message.d.ts +0 -10
- package/dist/components/ui/input/message.js +0 -128
- package/dist/components/ui/input/root.d.ts +0 -18
- package/dist/components/ui/input/slot.d.ts +0 -10
- package/dist/components/ui/input/slot.js +0 -20
- package/dist/components/ui/input/text.d.ts +0 -10
- package/dist/components/ui/input/text.js +0 -195
- package/src/components/ui/accordion.tsx +0 -3
- package/src/components/ui/index.ts +0 -13
- package/src/components/ui/input/content.tsx +0 -59
- package/src/components/ui/input/index.ts +0 -6
- package/src/components/ui/input/label.tsx +0 -41
- package/src/components/ui/input/message.tsx +0 -37
- package/src/components/ui/input/root.tsx +0 -57
- package/src/components/ui/input/slot.tsx +0 -21
- package/src/components/ui/input/text.tsx +0 -69
- /package/dist/components/{ui/otp-input.d.ts → otp-input.d.ts} +0 -0
- /package/src/components/{ui/logo.tsx → logo.tsx} +0 -0
- /package/src/components/{ui/otp-input.tsx → otp-input.tsx} +0 -0
- /package/src/components/{ui/typography.tsx → typography.tsx} +0 -0
- /package/src/{components/resources → resources}/logo/horizontal.tsx +0 -0
- /package/src/{components/resources → resources}/logo/icon.tsx +0 -0
- /package/src/{components/resources → resources}/logo/index.ts +0 -0
- /package/src/{components/resources → resources}/logo/vertical.tsx +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'
|
|
3
|
+
import { cx } from '@xjur-ui/util'
|
|
4
|
+
import {
|
|
5
|
+
ListContent,
|
|
6
|
+
ListHeader,
|
|
7
|
+
ListHeaderTitle,
|
|
8
|
+
ListItem,
|
|
9
|
+
ListRoot
|
|
10
|
+
} from './list'
|
|
11
|
+
import { Typography } from './typography'
|
|
12
|
+
import { Divider } from './divider'
|
|
13
|
+
|
|
14
|
+
export function DropdownMenuRoot({
|
|
15
|
+
...props
|
|
16
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
|
|
17
|
+
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function DropdownMenuPortal({
|
|
21
|
+
...props
|
|
22
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
|
|
23
|
+
return (
|
|
24
|
+
<DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function DropdownMenuTrigger({
|
|
29
|
+
...props
|
|
30
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
|
|
31
|
+
return (
|
|
32
|
+
<DropdownMenuPrimitive.Trigger
|
|
33
|
+
data-slot="dropdown-menu-trigger"
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function DropdownMenuContent({
|
|
40
|
+
className,
|
|
41
|
+
sideOffset = 4,
|
|
42
|
+
align = 'start',
|
|
43
|
+
side = 'bottom',
|
|
44
|
+
children,
|
|
45
|
+
...props
|
|
46
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
|
|
47
|
+
return (
|
|
48
|
+
<DropdownMenuPrimitive.Portal>
|
|
49
|
+
<DropdownMenuPrimitive.Content
|
|
50
|
+
align={align}
|
|
51
|
+
className={cx(
|
|
52
|
+
'group z-10 max-h-[var(--radix-popover-content-available-height)] max-w-[var(--radix-popover-trigger-width)] min-w-[240px]',
|
|
53
|
+
className
|
|
54
|
+
)}
|
|
55
|
+
data-slot="dropdown-menu-content"
|
|
56
|
+
side={side}
|
|
57
|
+
sideOffset={sideOffset}
|
|
58
|
+
{...props}
|
|
59
|
+
>
|
|
60
|
+
<ListRoot>{children}</ListRoot>
|
|
61
|
+
</DropdownMenuPrimitive.Content>
|
|
62
|
+
</DropdownMenuPrimitive.Portal>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function DropdownMenuList({
|
|
67
|
+
...props
|
|
68
|
+
}: React.ComponentProps<typeof ListContent>) {
|
|
69
|
+
return <ListContent {...props} />
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function DropdownMenuHeader({
|
|
73
|
+
...props
|
|
74
|
+
}: React.ComponentProps<typeof ListHeader>) {
|
|
75
|
+
return <ListHeader {...props} />
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function DropdownMenuHeaderTitle({
|
|
79
|
+
...props
|
|
80
|
+
}: React.ComponentProps<typeof ListHeaderTitle>) {
|
|
81
|
+
return <ListHeaderTitle {...props} />
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function DropdownMenuItem({
|
|
85
|
+
className,
|
|
86
|
+
...props
|
|
87
|
+
}: React.ComponentProps<typeof ListItem>) {
|
|
88
|
+
return <ListItem className={cx(className, 'cursor-pointer')} {...props} />
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function DropdownMenuItemText({
|
|
92
|
+
...props
|
|
93
|
+
}: React.ComponentProps<typeof Typography>) {
|
|
94
|
+
return <Typography {...props} />
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function DropdownMenuItemDivider({
|
|
98
|
+
...props
|
|
99
|
+
}: React.ComponentProps<typeof Divider>) {
|
|
100
|
+
return <Divider {...props} />
|
|
101
|
+
}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { cva, cx } from '@xjur-ui/util'
|
|
2
|
+
import type { ComponentProps } from 'react'
|
|
3
|
+
import { createContext } from 'react'
|
|
4
|
+
import { InputMask, type MaskOptions } from '@react-input/mask'
|
|
5
|
+
import {
|
|
6
|
+
InputNumberFormat,
|
|
7
|
+
type InputNumberFormatProps
|
|
8
|
+
} from '@react-input/number-format'
|
|
9
|
+
import { inputMask, type InputMaskType } from '../resources/input-mask'
|
|
10
|
+
|
|
11
|
+
export { inputMask, type InputMaskType, type MaskOptions }
|
|
12
|
+
|
|
13
|
+
export type InputProps = {
|
|
14
|
+
variant?: 'outlined' | 'filled'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const FieldContext = createContext<InputProps>({
|
|
18
|
+
variant: 'filled'
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
export function InputRoot({
|
|
22
|
+
className,
|
|
23
|
+
children,
|
|
24
|
+
variant = 'filled',
|
|
25
|
+
...props
|
|
26
|
+
}: ComponentProps<'div'> & InputProps) {
|
|
27
|
+
return (
|
|
28
|
+
<FieldContext.Provider value={{ variant }}>
|
|
29
|
+
<div
|
|
30
|
+
className={cx(
|
|
31
|
+
'group gap-small relative flex w-full flex-col',
|
|
32
|
+
className
|
|
33
|
+
)}
|
|
34
|
+
{...props}
|
|
35
|
+
>
|
|
36
|
+
{children}
|
|
37
|
+
</div>
|
|
38
|
+
</FieldContext.Provider>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function InputContent({ className, ...props }: ComponentProps<'div'>) {
|
|
43
|
+
const variants = cva(
|
|
44
|
+
[
|
|
45
|
+
'relative h-large-4x rounded-small-1x gap-small py-small_1x-alt px-small flex items-center w-full',
|
|
46
|
+
'focus-within:border-primary-idle focus-within:shadow-focus-primary focus-within:border',
|
|
47
|
+
'group-has-[div[data-slot=input-right-action-slot]]:rounded-r-none',
|
|
48
|
+
'group-has-[div[data-slot=input-left-action-slot]]:rounded-l-none'
|
|
49
|
+
],
|
|
50
|
+
{
|
|
51
|
+
variants: {
|
|
52
|
+
variant: {
|
|
53
|
+
default: '',
|
|
54
|
+
outlined:
|
|
55
|
+
'bg-layer-2-idle border-border-layer-2 border hover:border-border-layer-3 has-[input:not(:placeholder-shown)]:border-primary-idle',
|
|
56
|
+
filled:
|
|
57
|
+
'bg-layer-2-hover group-hover:border-border-layer-1 group-hover:border-1'
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<FieldContext.Consumer>
|
|
65
|
+
{({ variant }) => {
|
|
66
|
+
return (
|
|
67
|
+
<div className={cx(className, variants({ variant }))} {...props} />
|
|
68
|
+
)
|
|
69
|
+
}}
|
|
70
|
+
</FieldContext.Consumer>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function InputLabel({
|
|
75
|
+
htmlFor,
|
|
76
|
+
className,
|
|
77
|
+
...props
|
|
78
|
+
}: ComponentProps<'label'> & { htmlFor: string }) {
|
|
79
|
+
return (
|
|
80
|
+
<FieldContext.Consumer>
|
|
81
|
+
{({ variant }) => {
|
|
82
|
+
return (
|
|
83
|
+
<label
|
|
84
|
+
className={cx(
|
|
85
|
+
'rounded-small-1x text-size-body-md text-neutral-dark data-[variant=outlined]:bg-layer-2-idle bg-layer-2-hover w-fit font-normal',
|
|
86
|
+
'ease animate-in pointer-events-none absolute top-1/2 left-auto -translate-y-1/2 transition-all duration-250',
|
|
87
|
+
// Filled
|
|
88
|
+
'group-focus-within:text-primary-idle group-focus-within:bg-layer-2-hover data-[variant=outlined]:group-focus-within:bg-layer-2-idle group-focus-within:-top-[3px]',
|
|
89
|
+
'group-focus-within:text-size-label-sm-1x group-focus-within:font-medium',
|
|
90
|
+
'group-has-[input:not(:placeholder-shown)]:-top-[3px]',
|
|
91
|
+
'group-has-[input:not(:placeholder-shown)]:text-size-label-sm-1x',
|
|
92
|
+
'group-has-[input:not(:placeholder-shown)]:font-medium',
|
|
93
|
+
'data-[variant=outlined]:group-has-[input:not(:placeholder-shown)]:text-primary-idle',
|
|
94
|
+
// If has left slot
|
|
95
|
+
'group-has-[div[data-slot=input-left-slot]]:left-large-4x',
|
|
96
|
+
'group-has-[div[data-slot=input-left-slot]]:group-focus-within:left-auto',
|
|
97
|
+
'group-has-[div[data-slot=input-left-slot]]:group-has-[input:not(:placeholder-shown)]:left-auto',
|
|
98
|
+
// Animate
|
|
99
|
+
'group-focus-within:animate-in',
|
|
100
|
+
'group-has-[input:not(:placeholder-shown)]:animate-out',
|
|
101
|
+
className
|
|
102
|
+
)}
|
|
103
|
+
data-variant={variant}
|
|
104
|
+
htmlFor={htmlFor}
|
|
105
|
+
{...props}
|
|
106
|
+
/>
|
|
107
|
+
)
|
|
108
|
+
}}
|
|
109
|
+
</FieldContext.Consumer>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function InputText({
|
|
114
|
+
className,
|
|
115
|
+
maskOptions,
|
|
116
|
+
maskType,
|
|
117
|
+
...props
|
|
118
|
+
}: ComponentProps<'input'> & {
|
|
119
|
+
maskOptions?: MaskOptions
|
|
120
|
+
maskType?: InputMaskType
|
|
121
|
+
}) {
|
|
122
|
+
const Component = maskOptions || maskType ? InputMask : 'input'
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<Component
|
|
126
|
+
{...props}
|
|
127
|
+
{...(maskType
|
|
128
|
+
? { ...inputMask(maskType) }
|
|
129
|
+
: maskOptions && { ...maskOptions })}
|
|
130
|
+
className={cx(
|
|
131
|
+
className,
|
|
132
|
+
'peer text-size-body-md text-neutral-dark flex-1 font-medium outline-none',
|
|
133
|
+
'group-has-[div[data-slot=input-left-slot]]:pl-large-1x ml-small-1x'
|
|
134
|
+
)}
|
|
135
|
+
placeholder={props.placeholder || ' '}
|
|
136
|
+
{...(maskOptions && { ...maskOptions })}
|
|
137
|
+
/>
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function InputNumber({
|
|
142
|
+
className,
|
|
143
|
+
locales = 'pt-BR',
|
|
144
|
+
...props
|
|
145
|
+
}: InputNumberFormatProps) {
|
|
146
|
+
return (
|
|
147
|
+
<InputNumberFormat
|
|
148
|
+
{...props}
|
|
149
|
+
className={cx(
|
|
150
|
+
className,
|
|
151
|
+
'peer text-size-body-md text-neutral-dark flex-1 font-medium outline-none',
|
|
152
|
+
'group-has-[div[data-slot=input-left-slot]]:pl-large-1x ml-small-1x'
|
|
153
|
+
)}
|
|
154
|
+
locales={locales}
|
|
155
|
+
placeholder={props.placeholder || ' '}
|
|
156
|
+
/>
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function InputLeftSlot({ className, ...props }: ComponentProps<'div'>) {
|
|
161
|
+
return (
|
|
162
|
+
<div
|
|
163
|
+
{...props}
|
|
164
|
+
className={cx(
|
|
165
|
+
className,
|
|
166
|
+
'left-small absolute top-1/2 flex -translate-y-1/2 items-center justify-center'
|
|
167
|
+
)}
|
|
168
|
+
data-slot="input-left-slot"
|
|
169
|
+
/>
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function InputRightSlot({ className, ...props }: ComponentProps<'div'>) {
|
|
174
|
+
return (
|
|
175
|
+
<div
|
|
176
|
+
{...props}
|
|
177
|
+
className={cx(
|
|
178
|
+
className,
|
|
179
|
+
'right-small absolute top-1/2 flex -translate-y-1/2 items-center justify-center'
|
|
180
|
+
)}
|
|
181
|
+
data-slot="input-right-slot"
|
|
182
|
+
/>
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function InputMessage({ className, ...props }: ComponentProps<'p'>) {
|
|
187
|
+
return (
|
|
188
|
+
<p
|
|
189
|
+
{...props}
|
|
190
|
+
className={cx(
|
|
191
|
+
'text-size-body-sm text-neutral-dark font-normal',
|
|
192
|
+
className
|
|
193
|
+
)}
|
|
194
|
+
/>
|
|
195
|
+
)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function InputContainer({ className, ...props }: ComponentProps<'div'>) {
|
|
199
|
+
return (
|
|
200
|
+
<div
|
|
201
|
+
{...props}
|
|
202
|
+
className={cx(className, 'flex items-center')}
|
|
203
|
+
data-slot="input-content"
|
|
204
|
+
/>
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function InputAction({
|
|
209
|
+
className,
|
|
210
|
+
side,
|
|
211
|
+
...props
|
|
212
|
+
}: ComponentProps<'div'> & {
|
|
213
|
+
side: 'left' | 'right'
|
|
214
|
+
}) {
|
|
215
|
+
return (
|
|
216
|
+
<div
|
|
217
|
+
{...props}
|
|
218
|
+
className={cx(
|
|
219
|
+
className,
|
|
220
|
+
'group h-large-4x flex items-center justify-center'
|
|
221
|
+
)}
|
|
222
|
+
data-side={side}
|
|
223
|
+
data-slot={`input-${side}-action-slot`}
|
|
224
|
+
/>
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export function InputActionButton({
|
|
229
|
+
className,
|
|
230
|
+
...props
|
|
231
|
+
}: ComponentProps<'div'>) {
|
|
232
|
+
return (
|
|
233
|
+
<div
|
|
234
|
+
{...props}
|
|
235
|
+
className={cx(
|
|
236
|
+
className,
|
|
237
|
+
'h-large-4x w-large-4x bg-layer-2-hover flex cursor-pointer items-center justify-center'
|
|
238
|
+
)}
|
|
239
|
+
/>
|
|
240
|
+
)
|
|
241
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Slot } from '@radix-ui/react-slot'
|
|
2
|
+
import { cx, cva, type ClassVariantProps } from '@xjur-ui/util'
|
|
3
|
+
import type { ComponentProps } from 'react'
|
|
4
|
+
import { type TypographyProps, Typography } from './typography'
|
|
5
|
+
|
|
6
|
+
export function ListRoot({
|
|
7
|
+
className,
|
|
8
|
+
asChild,
|
|
9
|
+
...props
|
|
10
|
+
}: ComponentProps<'div'> & {
|
|
11
|
+
asChild?: boolean
|
|
12
|
+
}) {
|
|
13
|
+
const Comp = asChild ? Slot : 'div'
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<Comp
|
|
17
|
+
{...props}
|
|
18
|
+
className={cx(
|
|
19
|
+
className,
|
|
20
|
+
'rounded-small scrollbar-hide bg-layer-2-idle border-border-layer-2 shadow-elevation-3 z-10 max-h-[400px] list-none overflow-y-auto border'
|
|
21
|
+
)}
|
|
22
|
+
/>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function ListHeader({
|
|
27
|
+
className,
|
|
28
|
+
asChild,
|
|
29
|
+
...props
|
|
30
|
+
}: ComponentProps<'div'> & {
|
|
31
|
+
asChild?: boolean
|
|
32
|
+
}) {
|
|
33
|
+
const Comp = asChild ? Slot : 'div'
|
|
34
|
+
return <Comp {...props} className={cx(className, 'px-small pt-small-1x')} />
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function ListHeaderTitle({
|
|
38
|
+
variant = 'label',
|
|
39
|
+
size = 'sm',
|
|
40
|
+
weight = 'medium',
|
|
41
|
+
className,
|
|
42
|
+
...props
|
|
43
|
+
}: TypographyProps) {
|
|
44
|
+
return (
|
|
45
|
+
<Typography
|
|
46
|
+
className={cx(className, 'text-neutral-placeholder')}
|
|
47
|
+
size={size}
|
|
48
|
+
variant={variant}
|
|
49
|
+
weight={weight}
|
|
50
|
+
{...props}
|
|
51
|
+
/>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function ListContent({
|
|
56
|
+
className,
|
|
57
|
+
asChild,
|
|
58
|
+
...props
|
|
59
|
+
}: ComponentProps<'ul'> & {
|
|
60
|
+
asChild?: boolean
|
|
61
|
+
}) {
|
|
62
|
+
const Comp = asChild ? Slot : 'ul'
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<Comp
|
|
66
|
+
{...props}
|
|
67
|
+
className={cx('gap-small-1x p-small flex flex-col', className)}
|
|
68
|
+
/>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const variants = cva(
|
|
73
|
+
[
|
|
74
|
+
'py-medium px-small flex items-center gap-small rounded-small-1x',
|
|
75
|
+
'bg-layer-2-idle text-neutral-dark',
|
|
76
|
+
'hover:bg-layer-2-hover transition-colors duration-100 ease-out',
|
|
77
|
+
'active:bg-layer-2-pressed'
|
|
78
|
+
],
|
|
79
|
+
{
|
|
80
|
+
variants: {
|
|
81
|
+
size: {
|
|
82
|
+
md: 'h-large-4x',
|
|
83
|
+
lg: 'h-large-7x'
|
|
84
|
+
},
|
|
85
|
+
isActive: {
|
|
86
|
+
true: 'bg-primary-alt-active text-primary-label-active hover:bg-primary-alt-hover active:bg-primary-alt-pressed'
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
defaultVariants: {
|
|
90
|
+
size: 'md',
|
|
91
|
+
isActive: false
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
export function ListItem({
|
|
97
|
+
className,
|
|
98
|
+
size,
|
|
99
|
+
isActive,
|
|
100
|
+
asChild,
|
|
101
|
+
...props
|
|
102
|
+
}: ComponentProps<'li'> &
|
|
103
|
+
ClassVariantProps<typeof variants> & {
|
|
104
|
+
asChild?: boolean
|
|
105
|
+
}) {
|
|
106
|
+
const Comp = asChild ? Slot : 'li'
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<Comp {...props} className={cx(variants({ size, isActive }), className)} />
|
|
110
|
+
)
|
|
111
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group'
|
|
3
|
+
import { cx } from '@xjur-ui/util'
|
|
4
|
+
import { Typography } from './typography'
|
|
5
|
+
|
|
6
|
+
export function RadioGroup({
|
|
7
|
+
className,
|
|
8
|
+
orientation = 'vertical',
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {
|
|
11
|
+
return (
|
|
12
|
+
<RadioGroupPrimitive.Root
|
|
13
|
+
className={cx(
|
|
14
|
+
'gap-small flex data-[orientation=horizontal]:flex-row data-[orientation=vertical]:flex-col',
|
|
15
|
+
className
|
|
16
|
+
)}
|
|
17
|
+
data-orientation={orientation}
|
|
18
|
+
data-slot="radio-group"
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function RadioItem({
|
|
25
|
+
className,
|
|
26
|
+
id,
|
|
27
|
+
label,
|
|
28
|
+
disabled = false,
|
|
29
|
+
...props
|
|
30
|
+
}: React.ComponentProps<typeof RadioGroupPrimitive.Item> & {
|
|
31
|
+
label?: string
|
|
32
|
+
}) {
|
|
33
|
+
return (
|
|
34
|
+
<div className="gap-small flex items-center">
|
|
35
|
+
<RadioGroupPrimitive.Item
|
|
36
|
+
className={cx(
|
|
37
|
+
// layout
|
|
38
|
+
'size-large-alt rounded-circle inline-flex items-center justify-center transition-[border-color,box-shadow,background-color] duration-200 outline-none',
|
|
39
|
+
// base
|
|
40
|
+
'border-border-layer-2 bg-layer-2-idle cursor-pointer border-2',
|
|
41
|
+
// hover/focus (desmarcado)
|
|
42
|
+
'hover:border-primary-idle focus:border-primary-idle focus:shadow-focus-primary',
|
|
43
|
+
// estado checked
|
|
44
|
+
'data-[state=checked]:bg-primary-active data-[state=checked]:border-primary-active',
|
|
45
|
+
// hover quando estiver checked (opcional)
|
|
46
|
+
'data-[state=checked]:hover:border-primary-idle',
|
|
47
|
+
// disabled
|
|
48
|
+
'disabled:hover:border-border-layer-2 disabled:cursor-not-allowed disabled:opacity-[38%]',
|
|
49
|
+
className
|
|
50
|
+
)}
|
|
51
|
+
data-slot="radio-group-item"
|
|
52
|
+
disabled={disabled}
|
|
53
|
+
id={id}
|
|
54
|
+
{...props}
|
|
55
|
+
>
|
|
56
|
+
<RadioGroupPrimitive.Indicator
|
|
57
|
+
className="relative flex items-center justify-center"
|
|
58
|
+
data-slot="radio-group-indicator"
|
|
59
|
+
/>
|
|
60
|
+
</RadioGroupPrimitive.Item>
|
|
61
|
+
|
|
62
|
+
{!!label && (
|
|
63
|
+
<Typography
|
|
64
|
+
asChild={true}
|
|
65
|
+
className="text-size-body-sm data-[disabled=true]:opacity-38"
|
|
66
|
+
data-disabled={disabled}
|
|
67
|
+
weight="medium"
|
|
68
|
+
>
|
|
69
|
+
<label htmlFor={id}>{label}</label>
|
|
70
|
+
</Typography>
|
|
71
|
+
)}
|
|
72
|
+
</div>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { cva, cx } from '@xjur-ui/util'
|
|
2
|
+
import { createContext, type ComponentProps } from 'react'
|
|
3
|
+
import { Typography } from './typography'
|
|
4
|
+
import { Button, type ButtonProps } from './button'
|
|
5
|
+
|
|
6
|
+
export type SearchInputProps = {
|
|
7
|
+
variant?: 'outlined' | 'line' | 'action'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const SearchInputRootContext = createContext<SearchInputProps>({
|
|
11
|
+
variant: 'outlined'
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export function SearchInputRoot({
|
|
15
|
+
className,
|
|
16
|
+
variant = 'outlined',
|
|
17
|
+
...props
|
|
18
|
+
}: ComponentProps<'div'> & SearchInputProps) {
|
|
19
|
+
return (
|
|
20
|
+
<SearchInputRootContext.Provider value={{ variant }}>
|
|
21
|
+
<div className={cx(className, 'relative flex w-full')} {...props} />
|
|
22
|
+
</SearchInputRootContext.Provider>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function SearchInputContent({
|
|
27
|
+
className,
|
|
28
|
+
...props
|
|
29
|
+
}: ComponentProps<'div'>) {
|
|
30
|
+
const contentVarians = cva(
|
|
31
|
+
[
|
|
32
|
+
'gap-small py-small_1x-alt px-small flex items-center w-full',
|
|
33
|
+
'h-large-4x rounded-circle',
|
|
34
|
+
'border-border-layer-2 placeholder:placeholder-neutral-placeholder text-size-body-md text-neutral-dark border font-normal',
|
|
35
|
+
'group-hover:border-border-layer-3 transition-colors duration-200',
|
|
36
|
+
'disabled:opacity-60',
|
|
37
|
+
'focus-within:border-primary-idle'
|
|
38
|
+
],
|
|
39
|
+
{
|
|
40
|
+
variants: {
|
|
41
|
+
variant: {
|
|
42
|
+
outlined:
|
|
43
|
+
'rounded-circle focus-within:border-primary-idle focus-within:shadow-focus-primary',
|
|
44
|
+
line: 'rounded-none border-t-0 border-b-1 border-x-0',
|
|
45
|
+
action: 'rounded-tr-none rounded-br-none border-r-0'
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<SearchInputRootContext.Consumer>
|
|
53
|
+
{({ variant }) => (
|
|
54
|
+
<div
|
|
55
|
+
className={cx(className, contentVarians({ variant }))}
|
|
56
|
+
data-variant={variant}
|
|
57
|
+
{...props}
|
|
58
|
+
/>
|
|
59
|
+
)}
|
|
60
|
+
</SearchInputRootContext.Consumer>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function SearchInputLabel({
|
|
65
|
+
htmlFor,
|
|
66
|
+
...props
|
|
67
|
+
}: ComponentProps<'label'>) {
|
|
68
|
+
return (
|
|
69
|
+
<Typography
|
|
70
|
+
asChild={true}
|
|
71
|
+
className={cx('absolute -top-[22px] left-0')}
|
|
72
|
+
size="sm"
|
|
73
|
+
variant="label"
|
|
74
|
+
weight="medium"
|
|
75
|
+
>
|
|
76
|
+
<label htmlFor={htmlFor} {...props} />
|
|
77
|
+
</Typography>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function SearchInputText({
|
|
82
|
+
className,
|
|
83
|
+
...props
|
|
84
|
+
}: ComponentProps<'input'>) {
|
|
85
|
+
return <input className={cx(className, 'flex-1 outline-none')} {...props} />
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function SearchInputSlot(props: ComponentProps<'div'>) {
|
|
89
|
+
return <div {...props} data-slot="search-input-slot" />
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function SearchInputAction({
|
|
93
|
+
className,
|
|
94
|
+
appearance = 'ghost',
|
|
95
|
+
variant = 'outlined',
|
|
96
|
+
...props
|
|
97
|
+
}: ButtonProps) {
|
|
98
|
+
return (
|
|
99
|
+
<Button
|
|
100
|
+
{...props}
|
|
101
|
+
appearance={appearance}
|
|
102
|
+
className={cx(
|
|
103
|
+
className,
|
|
104
|
+
'cursor-pointer',
|
|
105
|
+
'h-large-4x rounded-tr-circle rounded-br-circle px-small py-small_1x-alt flex items-center justify-center rounded-none',
|
|
106
|
+
'text-size-body-md text-neutral-dark gap-small-1x'
|
|
107
|
+
)}
|
|
108
|
+
data-slot="search-input-action"
|
|
109
|
+
variant={variant}
|
|
110
|
+
/>
|
|
111
|
+
)
|
|
112
|
+
}
|