@xjur-ui/react 1.0.0 → 1.0.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.
Files changed (117) hide show
  1. package/.turbo/turbo-build.log +63 -57
  2. package/CHANGELOG.md +18 -0
  3. package/dist/components/avatar.d.ts +11 -0
  4. package/dist/components/avatar.js +58 -0
  5. package/dist/components/badge.d.ts +13 -0
  6. package/dist/components/{ui/input/message.js → badge.js} +30 -47
  7. package/dist/components/{ui/button.d.ts → button.d.ts} +2 -2
  8. package/dist/components/{ui/button.js → button.js} +9 -6
  9. package/dist/components/calendar.d.ts +11 -0
  10. package/dist/components/calendar.js +751 -0
  11. package/dist/components/checkbox.d.ts +8 -0
  12. package/dist/components/{ui/input/root.js → checkbox.js} +69 -79
  13. package/dist/components/chip.d.ts +24 -0
  14. package/dist/components/chip.js +255 -0
  15. package/dist/components/collapsible.d.ts +8 -0
  16. package/dist/components/collapsible.js +41 -0
  17. package/dist/components/date-picker.d.ts +20 -0
  18. package/dist/components/date-picker.js +232 -0
  19. package/dist/components/divider.d.ts +7 -0
  20. package/dist/components/divider.js +28 -0
  21. package/dist/components/dropdown-menu.d.ts +22 -0
  22. package/dist/components/dropdown-menu.js +294 -0
  23. package/dist/components/{resources/icons.d.ts → icon.d.ts} +11 -2
  24. package/dist/components/{ui/icon.js → icon.js} +20 -5
  25. package/dist/components/input.d.ts +32 -0
  26. package/dist/components/input.js +315 -0
  27. package/dist/components/list.d.ts +25 -0
  28. package/dist/components/{ui/input/content.js → list.js} +83 -87
  29. package/dist/components/{ui/logo.d.ts → logo.d.ts} +2 -2
  30. package/dist/components/{ui/logo.js → logo.js} +5 -5
  31. package/dist/components/{ui/otp-input.js → otp-input.js} +1 -1
  32. package/dist/components/radio.d.ts +10 -0
  33. package/dist/components/{ui/input/label.js → radio.js} +68 -77
  34. package/dist/components/search-input.d.ts +17 -0
  35. package/dist/components/search-input.js +274 -0
  36. package/dist/components/select.d.ts +33 -0
  37. package/dist/components/select.js +550 -0
  38. package/dist/components/sheet.d.ts +19 -0
  39. package/dist/components/sheet.js +251 -0
  40. package/dist/components/switch.d.ts +7 -0
  41. package/dist/components/switch.js +36 -0
  42. package/dist/components/tabs.d.ts +11 -0
  43. package/dist/components/tabs.js +54 -0
  44. package/dist/components/tag.d.ts +18 -0
  45. package/dist/components/tag.js +189 -0
  46. package/dist/components/{ui/typography.d.ts → typography.d.ts} +4 -4
  47. package/dist/components/{ui/typography.js → typography.js} +1 -1
  48. package/dist/index.css +1233 -62
  49. package/dist/index.d.ts +2 -17
  50. package/dist/index.js +0 -788
  51. package/eslint.config.js +8 -1
  52. package/package.json +41 -10
  53. package/src/components/avatar.tsx +53 -0
  54. package/src/components/badge.tsx +40 -0
  55. package/src/components/{ui/button.tsx → button.tsx} +7 -5
  56. package/src/components/calendar.tsx +123 -0
  57. package/src/components/checkbox.tsx +57 -0
  58. package/src/components/chip.tsx +109 -0
  59. package/src/components/collapsible.tsx +35 -0
  60. package/src/components/date-picker.tsx +160 -0
  61. package/src/components/divider.tsx +23 -0
  62. package/src/components/dropdown-menu.tsx +101 -0
  63. package/src/components/{ui/icon.tsx → icon.tsx} +1 -1
  64. package/src/components/input.tsx +256 -0
  65. package/src/components/list.tsx +111 -0
  66. package/src/components/radio.tsx +74 -0
  67. package/src/components/search-input.tsx +112 -0
  68. package/src/components/select.tsx +240 -0
  69. package/src/components/sheet.tsx +141 -0
  70. package/src/components/switch.tsx +31 -0
  71. package/src/components/tabs.tsx +53 -0
  72. package/src/components/tag.tsx +91 -0
  73. package/src/index.css +4 -1
  74. package/src/index.ts +0 -1
  75. package/src/{components/resources → resources}/icons.ts +16 -1
  76. package/src/resources/input-mask.ts +91 -0
  77. package/dist/components/resources/icons.js +0 -133
  78. package/dist/components/resources/logo/horizontal.d.ts +0 -12
  79. package/dist/components/resources/logo/horizontal.js +0 -107
  80. package/dist/components/resources/logo/icon.d.ts +0 -12
  81. package/dist/components/resources/logo/icon.js +0 -79
  82. package/dist/components/resources/logo/index.d.ts +0 -4
  83. package/dist/components/resources/logo/index.js +0 -291
  84. package/dist/components/resources/logo/vertical.d.ts +0 -12
  85. package/dist/components/resources/logo/vertical.js +0 -107
  86. package/dist/components/ui/accordion.d.ts +0 -5
  87. package/dist/components/ui/accordion.js +0 -8
  88. package/dist/components/ui/icon.d.ts +0 -12
  89. package/dist/components/ui/index.d.ts +0 -17
  90. package/dist/components/ui/index.js +0 -788
  91. package/dist/components/ui/input/content.d.ts +0 -9
  92. package/dist/components/ui/input/index.d.ts +0 -12
  93. package/dist/components/ui/input/index.js +0 -335
  94. package/dist/components/ui/input/label.d.ts +0 -12
  95. package/dist/components/ui/input/message.d.ts +0 -10
  96. package/dist/components/ui/input/root.d.ts +0 -18
  97. package/dist/components/ui/input/slot.d.ts +0 -10
  98. package/dist/components/ui/input/slot.js +0 -20
  99. package/dist/components/ui/input/text.d.ts +0 -10
  100. package/dist/components/ui/input/text.js +0 -195
  101. package/src/components/ui/accordion.tsx +0 -3
  102. package/src/components/ui/index.ts +0 -13
  103. package/src/components/ui/input/content.tsx +0 -59
  104. package/src/components/ui/input/index.ts +0 -6
  105. package/src/components/ui/input/label.tsx +0 -41
  106. package/src/components/ui/input/message.tsx +0 -37
  107. package/src/components/ui/input/root.tsx +0 -57
  108. package/src/components/ui/input/slot.tsx +0 -21
  109. package/src/components/ui/input/text.tsx +0 -69
  110. /package/dist/components/{ui/otp-input.d.ts → otp-input.d.ts} +0 -0
  111. /package/src/components/{ui/logo.tsx → logo.tsx} +0 -0
  112. /package/src/components/{ui/otp-input.tsx → otp-input.tsx} +0 -0
  113. /package/src/components/{ui/typography.tsx → typography.tsx} +0 -0
  114. /package/src/{components/resources → resources}/logo/horizontal.tsx +0 -0
  115. /package/src/{components/resources → resources}/logo/icon.tsx +0 -0
  116. /package/src/{components/resources → resources}/logo/index.ts +0 -0
  117. /package/src/{components/resources → resources}/logo/vertical.tsx +0 -0
@@ -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
+ }
@@ -0,0 +1,240 @@
1
+ import type { ComponentProps } from 'react'
2
+ import * as RadixPopover from '@radix-ui/react-popover'
3
+ import { cx } from '@xjur-ui/util'
4
+ import {
5
+ ListContent,
6
+ ListItem,
7
+ ListRoot,
8
+ ListHeader,
9
+ ListHeaderTitle
10
+ } from './list'
11
+ import {
12
+ SearchInputContent,
13
+ SearchInputText,
14
+ SearchInputRoot,
15
+ SearchInputSlot
16
+ } from './search-input'
17
+ import { Icon } from './icon'
18
+ import { Typography, type TypographyProps } from './typography'
19
+
20
+ export function SelectRoot(props: ComponentProps<typeof RadixPopover.Root>) {
21
+ return <RadixPopover.Root {...props} />
22
+ }
23
+
24
+ export function SelectTrigger({
25
+ className,
26
+ ...props
27
+ }: ComponentProps<typeof RadixPopover.Trigger>) {
28
+ return (
29
+ <RadixPopover.Trigger
30
+ className={cx(
31
+ className,
32
+ 'group h-large-4x rounded-small-1x gap-small py-small_1x-alt px-small relative flex w-full cursor-pointer items-center',
33
+ 'bg-layer-2-idle border-border-layer-2 hover:border-border-layer-3 border',
34
+ 'data-[state=open]:border-primary-idle data-[state=open]:shadow-focus-primary',
35
+ 'has-[input:not(:placeholder-shown)]:text-primary-idle',
36
+ 'has-[input:not(:placeholder-shown)]:border-primary-idle'
37
+ )}
38
+ {...props}
39
+ />
40
+ )
41
+ }
42
+
43
+ export function SelectContent({
44
+ className,
45
+ children,
46
+ sideOffset = 4,
47
+ side = 'bottom',
48
+ align = 'start',
49
+ ...props
50
+ }: ComponentProps<typeof RadixPopover.Content>) {
51
+ return (
52
+ <RadixPopover.Portal>
53
+ <RadixPopover.Content
54
+ align={align}
55
+ className={cx(
56
+ className,
57
+ 'group z-10 max-h-[var(--radix-popover-content-available-height)] max-w-[var(--radix-popover-content-available-width)] min-w-[var(--radix-popover-trigger-width)]'
58
+ )}
59
+ side={side}
60
+ sideOffset={sideOffset}
61
+ {...props}
62
+ >
63
+ <ListRoot>{children}</ListRoot>
64
+ </RadixPopover.Content>
65
+ </RadixPopover.Portal>
66
+ )
67
+ }
68
+
69
+ export function SelectValue({
70
+ className,
71
+ displayValue = '',
72
+ ...props
73
+ }: ComponentProps<'input'> & { displayValue?: string }) {
74
+ return (
75
+ <>
76
+ {!!displayValue && (
77
+ <Typography className="text-neutral-dark group-has-[div[data-slot=select-left-slot]]:pl-large-1x">
78
+ {displayValue}
79
+ </Typography>
80
+ )}
81
+
82
+ <input
83
+ {...props}
84
+ aria-readonly={true}
85
+ className={cx(className, 'pointer-events-none')}
86
+ hidden={true}
87
+ placeholder={props.placeholder ?? ' '}
88
+ readOnly={true}
89
+ />
90
+ </>
91
+ )
92
+ }
93
+
94
+ export function SelectMultiValue({
95
+ className,
96
+ values,
97
+ children,
98
+ ...props
99
+ }: ComponentProps<'div'> & { values: string[] }) {
100
+ return (
101
+ <div
102
+ className={cx(
103
+ className,
104
+ 'gap-small-1x scrollbar-hide group-has-[div[data-slot=select-left-slot]]:pl-large-1x overflow-x-small flex'
105
+ )}
106
+ {...props}
107
+ >
108
+ {children}
109
+
110
+ <input
111
+ aria-readonly={true}
112
+ className={cx(className, 'pointer-events-none')}
113
+ hidden={true}
114
+ placeholder={' '}
115
+ readOnly={true}
116
+ value={values.join(',')}
117
+ />
118
+ </div>
119
+ )
120
+ }
121
+
122
+ export function SelectLabel({
123
+ className,
124
+ htmlFor,
125
+ children,
126
+ ...props
127
+ }: TypographyProps & { htmlFor?: string }) {
128
+ return (
129
+ <Typography
130
+ asChild={true}
131
+ className={cx(
132
+ 'inline-block max-w-full truncate text-left font-normal',
133
+ 'left-small right-small pointer-events-none absolute top-1/2 -translate-y-1/2',
134
+ 'ease transition-all duration-250',
135
+ // Content Open
136
+ 'group-data-[state=open]:text-primary-idle',
137
+ 'group-data-[state=open]:-top-[3px]',
138
+ 'group-data-[state=open]:text-size-label-sm-1x',
139
+ 'group-data-[state=open]:font-medium',
140
+ // Filled
141
+ 'group-has-[input:not(:placeholder-shown)]:text-primary-idle',
142
+ 'group-has-[input:not(:placeholder-shown)]:-top-[3px]',
143
+ 'group-has-[input:not(:placeholder-shown)]:text-size-label-sm-1x',
144
+ 'group-has-[input:not(:placeholder-shown)]:font-medium',
145
+ // If has left slot
146
+ 'group-has-[div[data-slot=select-left-slot]]:left-large-4x',
147
+ 'group-has-[div[data-slot=select-left-slot]]:group-data-[state=open]:left-small',
148
+ 'group-has-[div[data-slot=select-left-slot]]:group-has-[input:not(:placeholder-shown)]:left-small',
149
+ // If has right slot
150
+ 'group-has-[div[data-slot=select-right-slot]]:right-large-4x',
151
+ 'group-has-[div[data-slot=select-right-slot]]:group-data-[state=open]:right-small',
152
+ 'group-has-[div[data-slot=select-right-slot]]:group-has-[input:not(:placeholder-shown)]:right-small',
153
+ // Animate
154
+ 'group-data-[state=open]:animate-in',
155
+ 'group-data-[state=closed]:animate-out',
156
+ 'group-has-[input:not(:placeholder-shown)]:animate-out',
157
+ className
158
+ )}
159
+ weight="medium"
160
+ {...props}
161
+ >
162
+ <label htmlFor={htmlFor}>
163
+ <span className="bg-layer-2-idle rounded-small-1x max-w-full">
164
+ {children}
165
+ </span>
166
+ </label>
167
+ </Typography>
168
+ )
169
+ }
170
+
171
+ export function SelectOptions(props: ComponentProps<typeof ListContent>) {
172
+ return <ListContent {...props} />
173
+ }
174
+
175
+ export function SelectOption({
176
+ className,
177
+ ...props
178
+ }: ComponentProps<typeof ListItem>) {
179
+ return <ListItem className={cx(className, 'cursor-pointer')} {...props} />
180
+ }
181
+
182
+ export function SelectOptionText(props: ComponentProps<typeof Typography>) {
183
+ return <Typography {...props} />
184
+ }
185
+
186
+ export function SelectHeader(props: ComponentProps<typeof ListHeader>) {
187
+ return <ListHeader {...props} />
188
+ }
189
+
190
+ export function SelectHeaderTitle(
191
+ props: ComponentProps<typeof ListHeaderTitle>
192
+ ) {
193
+ return <ListHeaderTitle {...props} />
194
+ }
195
+
196
+ export function SelectDropdown(props: ComponentProps<'div'>) {
197
+ return <div {...props} />
198
+ }
199
+
200
+ export function SelectLeftSlot({ className, ...props }: ComponentProps<'div'>) {
201
+ return (
202
+ <div
203
+ {...props}
204
+ className={cx(
205
+ className,
206
+ 'left-small absolute top-1/2 flex -translate-y-1/2 items-center justify-center'
207
+ )}
208
+ data-slot="select-left-slot"
209
+ />
210
+ )
211
+ }
212
+
213
+ export function SelectRightSlot({
214
+ className,
215
+ ...props
216
+ }: ComponentProps<'div'>) {
217
+ return (
218
+ <div
219
+ {...props}
220
+ className={cx(
221
+ className,
222
+ 'right-small absolute top-1/2 flex -translate-y-1/2 items-center justify-center'
223
+ )}
224
+ data-slot="select-right-slot"
225
+ />
226
+ )
227
+ }
228
+
229
+ export function SelectSearch(props: ComponentProps<typeof SearchInputText>) {
230
+ return (
231
+ <SearchInputRoot variant="line">
232
+ <SearchInputContent>
233
+ <SearchInputSlot>
234
+ <Icon className="text-icon-neutral-3" name="search" />
235
+ </SearchInputSlot>
236
+ <SearchInputText {...props} />
237
+ </SearchInputContent>
238
+ </SearchInputRoot>
239
+ )
240
+ }
@@ -0,0 +1,141 @@
1
+ import * as React from 'react'
2
+ import * as SheetPrimitive from '@radix-ui/react-dialog'
3
+ import { cx } from '@xjur-ui/util'
4
+ import { Button } from './button'
5
+ import { Icon } from './icon'
6
+
7
+ export function SheetRoot({
8
+ ...props
9
+ }: React.ComponentProps<typeof SheetPrimitive.Root>) {
10
+ return <SheetPrimitive.Root data-slot="sheet" {...props} />
11
+ }
12
+
13
+ export function SheetTrigger({
14
+ ...props
15
+ }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
16
+ return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
17
+ }
18
+
19
+ export function SheetClose({
20
+ children = (
21
+ <Button appearance="ghost" size="icon_md" variant="tertiary">
22
+ <Icon className="text-icon-neutral-3" name="close" />
23
+ </Button>
24
+ ),
25
+ ...props
26
+ }: React.ComponentProps<typeof SheetPrimitive.Close>) {
27
+ return (
28
+ <SheetPrimitive.Close data-slot="sheet-close" {...props}>
29
+ {children}
30
+ </SheetPrimitive.Close>
31
+ )
32
+ }
33
+
34
+ export function SheetPortal({
35
+ ...props
36
+ }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
37
+ return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
38
+ }
39
+
40
+ export function SheetOverlay({
41
+ className,
42
+ ...props
43
+ }: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
44
+ return (
45
+ <SheetPrimitive.Overlay
46
+ className={cx(
47
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
48
+ className
49
+ )}
50
+ data-slot="sheet-overlay"
51
+ {...props}
52
+ />
53
+ )
54
+ }
55
+
56
+ export function SheetContent({
57
+ className,
58
+ children,
59
+ side = 'right',
60
+ overlay = false,
61
+ ...props
62
+ }: React.ComponentProps<typeof SheetPrimitive.Content> & {
63
+ side?: 'top' | 'right' | 'bottom' | 'left'
64
+ overlay?: boolean
65
+ }) {
66
+ return (
67
+ <SheetPortal>
68
+ {overlay && <SheetOverlay />}
69
+ <SheetPrimitive.Content
70
+ className={cx(
71
+ 'border-border-layer-2 bg-layer-2-idle data-[state=open]:animate-in data-[state=closed]:animate-out shadow-elevation-2 fixed z-50 flex flex-col gap-4 transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
72
+ side === 'right' &&
73
+ 'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
74
+ side === 'left' &&
75
+ 'data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',
76
+ side === 'top' &&
77
+ 'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b',
78
+ side === 'bottom' &&
79
+ 'data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t',
80
+ className
81
+ )}
82
+ data-slot="sheet-content"
83
+ {...props}
84
+ >
85
+ {children}
86
+ </SheetPrimitive.Content>
87
+ </SheetPortal>
88
+ )
89
+ }
90
+
91
+ export function SheetBody({
92
+ className,
93
+ ...props
94
+ }: React.ComponentProps<'div'>) {
95
+ return <div className={cx('px-large-2x', className)} {...props} />
96
+ }
97
+
98
+ export function SheetHeader({
99
+ className,
100
+ ...props
101
+ }: React.ComponentProps<'div'>) {
102
+ return (
103
+ <div
104
+ className={cx(
105
+ 'py-large px-large-2x border-b-border-layer-2 border-b',
106
+ className
107
+ )}
108
+ data-slot="sheet-header"
109
+ {...props}
110
+ />
111
+ )
112
+ }
113
+
114
+ export function SheetFooter({
115
+ className,
116
+ ...props
117
+ }: React.ComponentProps<'div'>) {
118
+ return (
119
+ <div
120
+ className={cx(
121
+ 'py-large px-large-2x border-t-border-layer-2 mt-auto border-t',
122
+ className
123
+ )}
124
+ data-slot="sheet-footer"
125
+ {...props}
126
+ />
127
+ )
128
+ }
129
+
130
+ export function SheetTitle({
131
+ className,
132
+ ...props
133
+ }: React.ComponentProps<typeof SheetPrimitive.Title>) {
134
+ return (
135
+ <SheetPrimitive.Title
136
+ className={cx('text-size-title-lg font-medium', className)}
137
+ data-slot="sheet-title"
138
+ {...props}
139
+ />
140
+ )
141
+ }
@@ -0,0 +1,31 @@
1
+ import * as React from 'react'
2
+ import * as SwitchPrimitive from '@radix-ui/react-switch'
3
+ import { cx } from '@xjur-ui/util'
4
+
5
+ function Switch({
6
+ className,
7
+ ...props
8
+ }: React.ComponentProps<typeof SwitchPrimitive.Root>) {
9
+ return (
10
+ <SwitchPrimitive.Root
11
+ className={cx(
12
+ 'w-large-3x h-large rounded-circle inline-flex shrink-0 items-center border border-transparent',
13
+ 'peer data-[state=checked]:bg-primary-idle data-[state=unchecked]:bg-alt-4',
14
+ 'focus-visible:border-ring focus-visible:ring-ring/50 transition-all outline-none disabled:cursor-not-allowed disabled:opacity-50',
15
+ 'hover:shadow-focus-primary p-[2px]',
16
+ className
17
+ )}
18
+ data-slot="switch"
19
+ {...props}
20
+ >
21
+ <SwitchPrimitive.Thumb
22
+ className={cx(
23
+ 'bg-layer-2-idle size-medium pointer-events-none rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0'
24
+ )}
25
+ data-slot="switch-thumb"
26
+ />
27
+ </SwitchPrimitive.Root>
28
+ )
29
+ }
30
+
31
+ export { Switch }
@@ -0,0 +1,53 @@
1
+ import * as TabsPrimitive from '@radix-ui/react-tabs'
2
+ import { cva, cx } from '@xjur-ui/util'
3
+
4
+ export function TabsRoot({
5
+ ...props
6
+ }: React.ComponentProps<typeof TabsPrimitive.Tabs>) {
7
+ return <TabsPrimitive.Tabs {...props} />
8
+ }
9
+
10
+ export function TabsList({
11
+ ...props
12
+ }: React.ComponentProps<typeof TabsPrimitive.TabsList>) {
13
+ return <TabsPrimitive.TabsList {...props} />
14
+ }
15
+
16
+ export function TabsTrigger({
17
+ variant,
18
+ className,
19
+ ...props
20
+ }: React.ComponentProps<typeof TabsPrimitive.TabsTrigger> & {
21
+ variant?: 'line' | 'button'
22
+ }) {
23
+ const variants = cva(
24
+ [
25
+ 'rounded-small-1x h-large-4x cursor-pointer text-size-label-md text-neutral-dark'
26
+ ],
27
+ {
28
+ variants: {
29
+ variant: {
30
+ line: 'py-small_1x-alt px-small data-[state=active]:border-b-[3px] data-[state=active]:border-b-primary-active data-[state=active]:rounded-none hover:bg-layer-2-hover',
31
+ button:
32
+ 'rounded-br-none rounded-bl-none py-small_1x-alt px-large bg-primary-idle text-neutral-label hover:bg-primary-hover data-[state=active]:bg-layer-2-idle data-[state=active]:text-primary-label-active'
33
+ }
34
+ },
35
+ defaultVariants: {
36
+ variant: 'button'
37
+ }
38
+ }
39
+ )
40
+
41
+ return (
42
+ <TabsPrimitive.TabsTrigger
43
+ className={cx(className, variants({ variant }))}
44
+ {...props}
45
+ />
46
+ )
47
+ }
48
+
49
+ export function TabsContent({
50
+ ...props
51
+ }: React.ComponentProps<typeof TabsPrimitive.TabsContent>) {
52
+ return <TabsPrimitive.TabsContent {...props} />
53
+ }