@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.
Files changed (115) hide show
  1. package/.turbo/turbo-build.log +61 -57
  2. package/CHANGELOG.md +11 -0
  3. package/dist/components/avatar.d.ts +11 -0
  4. package/dist/components/avatar.js +58 -0
  5. package/dist/components/{ui/button.d.ts → button.d.ts} +2 -2
  6. package/dist/components/{ui/button.js → button.js} +9 -6
  7. package/dist/components/calendar.d.ts +11 -0
  8. package/dist/components/calendar.js +751 -0
  9. package/dist/components/checkbox.d.ts +8 -0
  10. package/dist/components/{ui/input/root.js → checkbox.js} +69 -79
  11. package/dist/components/chip.d.ts +24 -0
  12. package/dist/components/chip.js +255 -0
  13. package/dist/components/collapsible.d.ts +8 -0
  14. package/dist/components/collapsible.js +41 -0
  15. package/dist/components/date-picker.d.ts +20 -0
  16. package/dist/components/date-picker.js +230 -0
  17. package/dist/components/divider.d.ts +7 -0
  18. package/dist/components/divider.js +28 -0
  19. package/dist/components/dropdown-menu.d.ts +22 -0
  20. package/dist/components/dropdown-menu.js +294 -0
  21. package/dist/components/{resources/icons.d.ts → icon.d.ts} +11 -2
  22. package/dist/components/{ui/icon.js → icon.js} +18 -5
  23. package/dist/components/input.d.ts +32 -0
  24. package/dist/components/input.js +299 -0
  25. package/dist/components/list.d.ts +25 -0
  26. package/dist/components/{ui/input/content.js → list.js} +83 -87
  27. package/dist/components/{ui/logo.d.ts → logo.d.ts} +2 -2
  28. package/dist/components/{ui/logo.js → logo.js} +5 -5
  29. package/dist/components/{ui/otp-input.js → otp-input.js} +1 -1
  30. package/dist/components/radio.d.ts +10 -0
  31. package/dist/components/{ui/input/label.js → radio.js} +68 -77
  32. package/dist/components/search-input.d.ts +17 -0
  33. package/dist/components/search-input.js +274 -0
  34. package/dist/components/select.d.ts +33 -0
  35. package/dist/components/select.js +548 -0
  36. package/dist/components/sheet.d.ts +19 -0
  37. package/dist/components/sheet.js +251 -0
  38. package/dist/components/switch.d.ts +7 -0
  39. package/dist/components/switch.js +36 -0
  40. package/dist/components/tabs.d.ts +11 -0
  41. package/dist/components/tabs.js +54 -0
  42. package/dist/components/tag.d.ts +18 -0
  43. package/dist/components/tag.js +189 -0
  44. package/dist/components/{ui/typography.d.ts → typography.d.ts} +3 -3
  45. package/dist/components/{ui/typography.js → typography.js} +1 -1
  46. package/dist/index.css +1156 -62
  47. package/dist/index.d.ts +2 -17
  48. package/dist/index.js +0 -788
  49. package/eslint.config.js +8 -1
  50. package/package.json +40 -10
  51. package/src/components/avatar.tsx +53 -0
  52. package/src/components/{ui/button.tsx → button.tsx} +7 -5
  53. package/src/components/calendar.tsx +123 -0
  54. package/src/components/checkbox.tsx +57 -0
  55. package/src/components/chip.tsx +109 -0
  56. package/src/components/collapsible.tsx +35 -0
  57. package/src/components/date-picker.tsx +154 -0
  58. package/src/components/divider.tsx +23 -0
  59. package/src/components/dropdown-menu.tsx +101 -0
  60. package/src/components/{ui/icon.tsx → icon.tsx} +1 -1
  61. package/src/components/input.tsx +241 -0
  62. package/src/components/list.tsx +111 -0
  63. package/src/components/radio.tsx +74 -0
  64. package/src/components/search-input.tsx +112 -0
  65. package/src/components/select.tsx +234 -0
  66. package/src/components/sheet.tsx +141 -0
  67. package/src/components/switch.tsx +31 -0
  68. package/src/components/tabs.tsx +53 -0
  69. package/src/components/tag.tsx +91 -0
  70. package/src/index.css +4 -1
  71. package/src/index.ts +0 -1
  72. package/src/{components/resources → resources}/icons.ts +14 -1
  73. package/src/resources/input-mask.ts +91 -0
  74. package/dist/components/resources/icons.js +0 -133
  75. package/dist/components/resources/logo/horizontal.d.ts +0 -12
  76. package/dist/components/resources/logo/horizontal.js +0 -107
  77. package/dist/components/resources/logo/icon.d.ts +0 -12
  78. package/dist/components/resources/logo/icon.js +0 -79
  79. package/dist/components/resources/logo/index.d.ts +0 -4
  80. package/dist/components/resources/logo/index.js +0 -291
  81. package/dist/components/resources/logo/vertical.d.ts +0 -12
  82. package/dist/components/resources/logo/vertical.js +0 -107
  83. package/dist/components/ui/accordion.d.ts +0 -5
  84. package/dist/components/ui/accordion.js +0 -8
  85. package/dist/components/ui/icon.d.ts +0 -12
  86. package/dist/components/ui/index.d.ts +0 -17
  87. package/dist/components/ui/index.js +0 -788
  88. package/dist/components/ui/input/content.d.ts +0 -9
  89. package/dist/components/ui/input/index.d.ts +0 -12
  90. package/dist/components/ui/input/index.js +0 -335
  91. package/dist/components/ui/input/label.d.ts +0 -12
  92. package/dist/components/ui/input/message.d.ts +0 -10
  93. package/dist/components/ui/input/message.js +0 -128
  94. package/dist/components/ui/input/root.d.ts +0 -18
  95. package/dist/components/ui/input/slot.d.ts +0 -10
  96. package/dist/components/ui/input/slot.js +0 -20
  97. package/dist/components/ui/input/text.d.ts +0 -10
  98. package/dist/components/ui/input/text.js +0 -195
  99. package/src/components/ui/accordion.tsx +0 -3
  100. package/src/components/ui/index.ts +0 -13
  101. package/src/components/ui/input/content.tsx +0 -59
  102. package/src/components/ui/input/index.ts +0 -6
  103. package/src/components/ui/input/label.tsx +0 -41
  104. package/src/components/ui/input/message.tsx +0 -37
  105. package/src/components/ui/input/root.tsx +0 -57
  106. package/src/components/ui/input/slot.tsx +0 -21
  107. package/src/components/ui/input/text.tsx +0 -69
  108. /package/dist/components/{ui/otp-input.d.ts → otp-input.d.ts} +0 -0
  109. /package/src/components/{ui/logo.tsx → logo.tsx} +0 -0
  110. /package/src/components/{ui/otp-input.tsx → otp-input.tsx} +0 -0
  111. /package/src/components/{ui/typography.tsx → typography.tsx} +0 -0
  112. /package/src/{components/resources → resources}/logo/horizontal.tsx +0 -0
  113. /package/src/{components/resources → resources}/logo/icon.tsx +0 -0
  114. /package/src/{components/resources → resources}/logo/index.ts +0 -0
  115. /package/src/{components/resources → resources}/logo/vertical.tsx +0 -0
package/eslint.config.js CHANGED
@@ -1,3 +1,10 @@
1
1
  import eslintConfig from '@xjur-ui/eslint-config/react'
2
2
 
3
- export default [...eslintConfig]
3
+ export default [
4
+ ...eslintConfig,
5
+ {
6
+ rules: {
7
+ 'react/prop-types': 'off'
8
+ }
9
+ }
10
+ ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xjur-ui/react",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "description": "React components for XJur Design System",
6
6
  "main": "dist/index.js",
@@ -8,21 +8,51 @@
8
8
  "types": "dist/index.d.ts",
9
9
  "exports": {
10
10
  "./index.css": "./dist/index.css",
11
- ".": "./dist/index.js",
12
- "./button": "./dist/components/ui/button.js",
13
- "./icon": "./dist/components/ui/icon.js",
14
- "./typography": "./dist/components/ui/typography.js",
15
- "./logo": "./dist/components/ui/logo.js",
16
- "./input": "./dist/components/ui/input/index.js",
17
- "./otp-input": "./dist/components/ui/otp-input.js",
18
- "./accordion": "./dist/components/ui/accordion.js"
11
+ "./button": "./dist/components/button.js",
12
+ "./icon": "./dist/components/icon.js",
13
+ "./typography": "./dist/components/typography.js",
14
+ "./logo": "./dist/components/logo.js",
15
+ "./input": "./dist/components/input.js",
16
+ "./otp-input": "./dist/components/otp-input.js",
17
+ "./collapsible": "./dist/components/collapsible.js",
18
+ "./list": "./dist/components/list.js",
19
+ "./tabs": "./dist/components/tabs.js",
20
+ "./calendar": "./dist/components/calendar.js",
21
+ "./checkbox": "./dist/components/checkbox.js",
22
+ "./radio": "./dist/components/radio.js",
23
+ "./switch": "./dist/components/switch.js",
24
+ "./select": "./dist/components/select.js",
25
+ "./search-input": "./dist/components/search-input.js",
26
+ "./tag": "./dist/components/tag.js",
27
+ "./chip": "./dist/components/chip.js",
28
+ "./avatar": "./dist/components/avatar.js",
29
+ "./date-picker": "./dist/components/date-picker.js",
30
+ "./dropdown-menu": "./dist/components/dropdown-menu.js",
31
+ "./divider": "./dist/components/divider.js",
32
+ "./sheet": "./dist/components/sheet.js"
19
33
  },
20
34
  "dependencies": {
35
+ "@radix-ui/react-avatar": "^1.1.10",
36
+ "@radix-ui/react-checkbox": "^1.3.3",
37
+ "@radix-ui/react-collapsible": "^1.1.12",
38
+ "@radix-ui/react-dialog": "^1.1.15",
39
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
40
+ "@radix-ui/react-navigation-menu": "^1.2.14",
21
41
  "@radix-ui/react-one-time-password-field": "^0.1.8",
42
+ "@radix-ui/react-popover": "^1.1.15",
43
+ "@radix-ui/react-radio-group": "^1.3.8",
44
+ "@radix-ui/react-separator": "^1.1.7",
22
45
  "@radix-ui/react-slot": "^1.2.3",
46
+ "@radix-ui/react-switch": "^1.2.6",
47
+ "@radix-ui/react-tabs": "^1.1.13",
23
48
  "@react-input/mask": "^2.0.4",
49
+ "@react-input/number-format": "^2.0.3",
24
50
  "@xjur-ui/styles": "*",
25
- "@xjur-ui/util": "*"
51
+ "@xjur-ui/util": "*",
52
+ "react-day-picker": "^9.9.0",
53
+ "tailwind-scrollbar": "^4.0.2",
54
+ "tailwind-scrollbar-hide": "^4.0.0",
55
+ "tw-animate-css": "^1.3.7"
26
56
  },
27
57
  "devDependencies": {
28
58
  "@tailwindcss/postcss": "^4.1.11",
@@ -0,0 +1,53 @@
1
+ import * as React from 'react'
2
+ import * as AvatarPrimitive from '@radix-ui/react-avatar'
3
+ import { cx } from '@xjur-ui/util'
4
+
5
+ export function AvatarRoot({
6
+ className,
7
+ size = 'md',
8
+ ...props
9
+ }: React.ComponentProps<typeof AvatarPrimitive.Root> & {
10
+ size?: 'xs' | 'sm' | 'md' | 'lg'
11
+ }) {
12
+ return (
13
+ <AvatarPrimitive.Root
14
+ className={cx(
15
+ 'rounded-circle relative flex shrink-0 overflow-hidden',
16
+ 'data-[size=lg]:size-large-8x data-[size=md]:size-large-4x data-[size=sm]:size-large-2x data-[size=xs]:size-large-1x',
17
+ className
18
+ )}
19
+ data-size={size}
20
+ data-slot="avatar"
21
+ {...props}
22
+ />
23
+ )
24
+ }
25
+
26
+ export function AvatarImage({
27
+ className,
28
+ ...props
29
+ }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
30
+ return (
31
+ <AvatarPrimitive.Image
32
+ className={cx('aspect-square size-full', className)}
33
+ data-slot="avatar-image"
34
+ {...props}
35
+ />
36
+ )
37
+ }
38
+
39
+ export function AvatarFallback({
40
+ className,
41
+ ...props
42
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
43
+ return (
44
+ <AvatarPrimitive.Fallback
45
+ className={cx(
46
+ 'bg-alt-1 rounded-circle flex size-full items-center justify-center font-medium text-white',
47
+ className
48
+ )}
49
+ data-slot="avatar-fallback"
50
+ {...props}
51
+ />
52
+ )
53
+ }
@@ -1,16 +1,18 @@
1
1
  import { Slot } from '@radix-ui/react-slot'
2
2
  import type { ComponentProps } from 'react'
3
- import { cva, type ClassVariantProps } from '@xjur-ui/util'
3
+ import { cva, cx, type ClassVariantProps } from '@xjur-ui/util'
4
4
 
5
- const buttonVariants = cva(
5
+ export const buttonVariants = cva(
6
6
  [
7
- 'inline-flex items-center justify-center rounded-circle gap-small cursor-pointer disabled:opacity-38 disabled:pointer-events-none transition-colors'
7
+ 'outline-none inline-flex items-center justify-center rounded-circle gap-small cursor-pointer disabled:opacity-38 disabled:pointer-events-none transition-colors'
8
8
  ],
9
9
  {
10
10
  variants: {
11
11
  size: {
12
12
  md: 'py-small_1x-alt px-medium text-size-body-md',
13
- sm: 'py-small-1x px-small text-size-label-sm'
13
+ sm: 'py-small-1x px-small text-size-label-sm',
14
+ icon_md: 'p-small text-size-body-md h-large-4x w-large-4x',
15
+ icon_sm: 'p-small-1x text-size-label-sm h-large-2x w-large-2x'
14
16
  },
15
17
  variant: {
16
18
  primary: '',
@@ -98,7 +100,7 @@ export function Button({
98
100
  const Component = asChild ? Slot : 'button'
99
101
  return (
100
102
  <Component
101
- className={buttonVariants({ className, variant, appearance, size })}
103
+ className={cx(buttonVariants({ variant, appearance, size }), className)}
102
104
  {...props}
103
105
  />
104
106
  )
@@ -0,0 +1,123 @@
1
+ import 'react-day-picker/style.css'
2
+ import { ptBR } from 'date-fns/locale'
3
+ import { cx } from '@xjur-ui/util'
4
+ import {
5
+ type DayPickerProps,
6
+ type ClassNames,
7
+ DayPicker,
8
+ getDefaultClassNames
9
+ } from 'react-day-picker'
10
+ import { Icon, type IconType } from './icon'
11
+ import { Button } from './button'
12
+
13
+ function capitalize(str: string) {
14
+ return str.charAt(0).toUpperCase() + str.slice(1)
15
+ }
16
+
17
+ export { type DateRange } from 'react-day-picker'
18
+
19
+ export type CalendarProps = DayPickerProps & {
20
+ handleClear?: () => void
21
+ handleToday?: () => void
22
+ }
23
+
24
+ export function Calendar({
25
+ showOutsideDays = true,
26
+ locale = ptBR,
27
+ navLayout = 'around',
28
+ handleClear,
29
+ handleToday,
30
+ ...props
31
+ }: CalendarProps) {
32
+ const defaultClassNames = getDefaultClassNames()
33
+
34
+ const classNames: Partial<ClassNames> = {
35
+ root: cx(
36
+ 'bg-layer-2-idle shadow-elevation-2 rounded-[6px] p-small w-fit border border-border-layer-2 text-size-body-md text-neutral-dark font-inter',
37
+ defaultClassNames.root
38
+ ),
39
+ day: cx('rounded-circle hover:bg-layer-2-hover'),
40
+ caption_label: cx(
41
+ 'text-size-label-md text-neutral-dark font-medium',
42
+ defaultClassNames.caption_label
43
+ ),
44
+ outside: cx('text-neutral-placeholder', defaultClassNames.outside),
45
+ selected: cx(
46
+ 'text-size-body-md bg-primary-alt-active text-primary-label-active font-medium hover:bg-primary-alt-active'
47
+ ),
48
+ disabled: cx('opacity-60', defaultClassNames.disabled),
49
+ today: cx(
50
+ '!text-primary-label-active font-medium',
51
+ defaultClassNames.today
52
+ ),
53
+ range_start: cx(
54
+ 'text-size-body-md bg-primary-alt-active text-primary-label-active font-medium hover:bg-primary-alt-active'
55
+ ),
56
+ range_end: cx(
57
+ 'text-size-body-md bg-primary-alt-active text-primary-label-active font-medium hover:bg-primary-alt-active'
58
+ ),
59
+ range_middle: cx('!bg-layer-2-hover !text-primary-label-active')
60
+ }
61
+
62
+ return (
63
+ <DayPicker
64
+ classNames={{ ...classNames, ...props.classNames }}
65
+ components={{
66
+ Chevron: ({ orientation }) => {
67
+ const icon = orientation === 'left' ? 'chevron_left' : 'chevron_right'
68
+ return (
69
+ <Icon
70
+ className="size-large text-icon-neutral-3"
71
+ name={icon as IconType}
72
+ />
73
+ )
74
+ },
75
+ ...props.components
76
+ }}
77
+ footer={
78
+ (handleClear || handleToday) && (
79
+ <div className="py-small border-border-layer-2 mt-small flex h-full w-full items-center justify-between border-t">
80
+ {handleToday && (
81
+ <Button
82
+ appearance="ghost"
83
+ variant="secondary"
84
+ onClick={handleToday}
85
+ >
86
+ Hoje
87
+ </Button>
88
+ )}
89
+ {handleClear && (
90
+ <Button
91
+ appearance="ghost"
92
+ variant="secondary"
93
+ onClick={handleClear}
94
+ >
95
+ Limpar
96
+ </Button>
97
+ )}
98
+ </div>
99
+ )
100
+ }
101
+ formatters={{
102
+ formatWeekdayName: date => {
103
+ const weekday = date.toLocaleDateString('pt-BR', { weekday: 'short' })
104
+ return (
105
+ weekday.charAt(0).toUpperCase() + weekday.slice(1).replace('.', '')
106
+ )
107
+ },
108
+ formatCaption(month) {
109
+ const monthName = month.toLocaleDateString('pt-BR', {
110
+ month: 'long'
111
+ })
112
+ return `${capitalize(monthName)} ${month.getFullYear()}`
113
+ },
114
+ ...props.formatters
115
+ }}
116
+ locale={locale}
117
+ mode={props.mode ?? 'single'}
118
+ navLayout={navLayout}
119
+ showOutsideDays={showOutsideDays}
120
+ {...props}
121
+ />
122
+ )
123
+ }
@@ -0,0 +1,57 @@
1
+ import * as CheckoxPrimitive from '@radix-ui/react-checkbox'
2
+ import { cx } from '@xjur-ui/util'
3
+ import { Icon } from './icon'
4
+ import { Typography } from './typography'
5
+
6
+ export function Checkbox({
7
+ label,
8
+ name,
9
+ className,
10
+ disabled = false,
11
+ ...props
12
+ }: CheckoxPrimitive.CheckboxProps & {
13
+ label?: string
14
+ }) {
15
+ const fieldId = `field-checkbox-${name}`
16
+
17
+ return (
18
+ <div className="group gap-small flex items-center">
19
+ <CheckoxPrimitive.Root
20
+ disabled={disabled}
21
+ {...props}
22
+ className={cx(
23
+ // layout
24
+ 'size-large-alt rounded-small-1x inline-flex items-center justify-center transition-[border-color,box-shadow,background-color] duration-200 outline-none',
25
+ // base
26
+ 'border-border-layer-2 bg-layer-2-idle cursor-pointer border-2',
27
+ // hover/focus (desmarcado)
28
+ 'hover:border-primary-idle focus:border-primary-idle focus:shadow-focus-primary',
29
+ // estado checked
30
+ 'data-[state=checked]:bg-primary-active data-[state=checked]:border-primary-active',
31
+ // hover quando estiver checked (opcional)
32
+ 'data-[state=checked]:hover:border-primary-idle',
33
+ // disabled
34
+ 'disabled:hover:border-border-layer-2 disabled:cursor-not-allowed disabled:opacity-[38%]',
35
+ className
36
+ )}
37
+ id={fieldId}
38
+ name={name}
39
+ >
40
+ <CheckoxPrimitive.Indicator className="flex items-center justify-center">
41
+ <Icon className="text-neutral-label" name="check" />
42
+ </CheckoxPrimitive.Indicator>
43
+ </CheckoxPrimitive.Root>
44
+
45
+ {!!label && (
46
+ <Typography
47
+ asChild={true}
48
+ className="text-size-body-sm data-[disabled=true]:opacity-38"
49
+ data-disabled={disabled}
50
+ weight="medium"
51
+ >
52
+ <label htmlFor={fieldId}>{label}</label>
53
+ </Typography>
54
+ )}
55
+ </div>
56
+ )
57
+ }
@@ -0,0 +1,109 @@
1
+ import { cva, cx, type ClassVariantProps } from '@xjur-ui/util'
2
+ import { type ComponentProps } from 'react'
3
+ import { Typography } from './typography'
4
+ import { Icon, type IconType } from './icon'
5
+ import { AvatarFallback, AvatarImage, AvatarRoot } from './avatar'
6
+
7
+ const chipVariants = cva(
8
+ [
9
+ 'group/chip relative h-large-2x w-fit rounded-circle px-small py-none flex items-center gap-small_1x-alt',
10
+ 'transition-all duration-200'
11
+ ],
12
+ {
13
+ variants: {
14
+ variant: {
15
+ primary:
16
+ 'bg-primary-alt-idle text-primary-label-idle hover:bg-primary-alt-hover',
17
+ danger:
18
+ 'bg-danger-alt-idle text-danger-label-idle hover:bg-danger-alt-hover',
19
+ neutral: 'bg-layer-1-idle text-neutral-dark hover:bg-layer-1-hover'
20
+ }
21
+ },
22
+ defaultVariants: {
23
+ variant: 'primary'
24
+ }
25
+ }
26
+ )
27
+
28
+ export function ChipRoot({
29
+ className,
30
+ variant = 'primary',
31
+ ...props
32
+ }: ComponentProps<'div'> & ClassVariantProps<typeof chipVariants>) {
33
+ return <div className={cx(chipVariants({ variant }), className)} {...props} />
34
+ }
35
+
36
+ export function ChipText({
37
+ variant = 'label',
38
+ size = 'sm-1x',
39
+ weight = 'medium',
40
+ className,
41
+ ...props
42
+ }: ComponentProps<typeof Typography>) {
43
+ return (
44
+ <Typography
45
+ className={cx(className, 'truncate')}
46
+ size={size}
47
+ variant={variant}
48
+ weight={weight}
49
+ {...props}
50
+ />
51
+ )
52
+ }
53
+
54
+ export function ChipIcon({ className, ...props }: ComponentProps<typeof Icon>) {
55
+ return (
56
+ <Icon
57
+ className={
58
+ (cx(
59
+ 'text-size-body-md',
60
+ 'group-data-[variant=primary]:text-primary-label-idle',
61
+ 'group-data-[variant=danger]:text-danger-label-idle',
62
+ 'group-data-[variant=neutral]:text-icon-neutral-3'
63
+ ),
64
+ className)
65
+ }
66
+ {...props}
67
+ />
68
+ )
69
+ }
70
+
71
+ export function ChipClose({
72
+ className,
73
+ children = <ChipIcon name="close" />,
74
+ ...props
75
+ }: ComponentProps<'button'> & { name?: IconType }) {
76
+ return (
77
+ <button
78
+ className={cx(
79
+ className,
80
+ 'cursor-pointer bg-inherit',
81
+ 'invisible items-center justify-center group-hover/chip:visible',
82
+ 'absolute top-0 right-0',
83
+ 'h-large-2x w-large-2x rounded-circle',
84
+ 'transition-[visibility] duration-200'
85
+ )}
86
+ type="button"
87
+ {...props}
88
+ >
89
+ {children}
90
+ </button>
91
+ )
92
+ }
93
+
94
+ export function ChipAvatar({
95
+ size = 'xs',
96
+ avatarFallback = 'CN',
97
+ avatarUrl,
98
+ ...props
99
+ }: ComponentProps<typeof AvatarRoot> & {
100
+ avatarUrl?: string
101
+ avatarFallback: string
102
+ }) {
103
+ return (
104
+ <AvatarRoot size={size} style={{ marginLeft: '-4px' }} {...props}>
105
+ {avatarUrl && <AvatarImage src={avatarUrl} />}
106
+ <AvatarFallback>{avatarFallback}</AvatarFallback>
107
+ </AvatarRoot>
108
+ )
109
+ }
@@ -0,0 +1,35 @@
1
+ import * as CollapsiblePrimitive from '@radix-ui/react-collapsible'
2
+ import { cx } from '@xjur-ui/util'
3
+
4
+ export function CollapsibleRoot({
5
+ ...props
6
+ }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
7
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />
8
+ }
9
+
10
+ export function CollapsibleTrigger({
11
+ ...props
12
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
13
+ return (
14
+ <CollapsiblePrimitive.CollapsibleTrigger
15
+ data-slot="collapsible-trigger"
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ export function CollapsibleContent({
22
+ className,
23
+ ...props
24
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
25
+ return (
26
+ <CollapsiblePrimitive.CollapsibleContent
27
+ className={cx(
28
+ className,
29
+ 'data-[state=open]:animate-collapsible-down data-[state=closed]:animate-collapsible-up'
30
+ )}
31
+ data-slot="collapsible-content"
32
+ {...props}
33
+ />
34
+ )
35
+ }
@@ -0,0 +1,154 @@
1
+ import type { ComponentProps } from 'react'
2
+ import * as RadixPopover from '@radix-ui/react-popover'
3
+ import { cx } from '@xjur-ui/util'
4
+ import { Typography, type TypographyProps } from './typography'
5
+
6
+ export function DatePickerRoot(
7
+ props: ComponentProps<typeof RadixPopover.Root>
8
+ ) {
9
+ return <RadixPopover.Root {...props} />
10
+ }
11
+
12
+ export function DatePickerTrigger({
13
+ className,
14
+ ...props
15
+ }: ComponentProps<typeof RadixPopover.Trigger>) {
16
+ return (
17
+ <RadixPopover.Trigger
18
+ className={cx(
19
+ className,
20
+ 'group h-large-4x rounded-small-1x gap-small py-small_1x-alt px-small relative flex w-full cursor-pointer items-center',
21
+ 'bg-layer-2-idle border-border-layer-2 hover:border-border-layer-3 border',
22
+ 'data-[state=open]:border-primary-idle data-[state=open]:shadow-focus-primary',
23
+ 'has-[input:not(:placeholder-shown)]:text-primary-idle',
24
+ 'has-[input:not(:placeholder-shown)]:border-primary-idle'
25
+ )}
26
+ {...props}
27
+ />
28
+ )
29
+ }
30
+
31
+ export function DatePickerContent({
32
+ className,
33
+ sideOffset = 5,
34
+ side = 'bottom',
35
+ align = 'start',
36
+ ...props
37
+ }: ComponentProps<typeof RadixPopover.Content>) {
38
+ return (
39
+ <RadixPopover.Portal>
40
+ <RadixPopover.Content
41
+ align={align}
42
+ className={cx(
43
+ className,
44
+ 'group z-10 max-h-[var(--radix-popover-content-available-height)] max-w-[var(--radix-popover-trigger-width)]'
45
+ )}
46
+ side={side}
47
+ sideOffset={sideOffset}
48
+ {...props}
49
+ />
50
+ </RadixPopover.Portal>
51
+ )
52
+ }
53
+
54
+ export function DatePickerValue({
55
+ className,
56
+ displayValue = '',
57
+ value,
58
+ ...props
59
+ }: ComponentProps<'input'> & { displayValue?: string }) {
60
+ return (
61
+ <>
62
+ {!!displayValue && (
63
+ <Typography className="text-neutral-dark group-has-[div[data-slot=date-picker-left-slot]]:pl-large-1x">
64
+ {displayValue}
65
+ </Typography>
66
+ )}
67
+
68
+ <input
69
+ {...props}
70
+ aria-readonly={true}
71
+ className={cx('pointer-events-none', className)}
72
+ hidden={true}
73
+ placeholder={props.placeholder ?? ' '}
74
+ readOnly={true}
75
+ value={value ?? ''}
76
+ />
77
+ </>
78
+ )
79
+ }
80
+
81
+ export function DatePickerLabel({
82
+ className,
83
+ htmlFor,
84
+ children,
85
+ ...props
86
+ }: TypographyProps & { htmlFor?: string }) {
87
+ return (
88
+ <Typography
89
+ asChild={true}
90
+ className={cx(
91
+ 'bg-layer-2-idle w-fit font-normal',
92
+ 'pointer-events-none absolute top-[50%] left-auto -translate-y-1/2',
93
+ 'ease pointer-events-none transition-all duration-150',
94
+ // Content Open
95
+ 'group-data-[state=open]:text-primary-idle',
96
+ 'group-data-[state=open]:bg-layer-2-idle',
97
+ 'group-data-[state=open]:-top-[3px]',
98
+ 'group-data-[state=open]:text-size-label-sm-1x',
99
+ 'group-data-[state=open]:font-medium',
100
+ // Filled
101
+ 'group-has-[input:not(:placeholder-shown)]:text-primary-idle',
102
+ 'group-has-[input:not(:placeholder-shown)]:bg-layer-2-idle',
103
+ 'group-has-[input:not(:placeholder-shown)]:-top-[3px]',
104
+ 'group-has-[input:not(:placeholder-shown)]:text-size-label-sm-1x',
105
+ 'group-has-[input:not(:placeholder-shown)]:font-medium',
106
+ // If has left slot
107
+ 'group-has-[div[data-slot=date-picker-left-slot]]:left-large-4x',
108
+ 'group-has-[div[data-slot=date-picker-left-slot]]:group-data-[state=open]:left-auto',
109
+ 'group-has-[div[data-slot=date-picker-left-slot]]:group-has-[input:not(:placeholder-shown)]:left-auto',
110
+ // Animate
111
+ 'group-data-[state=open]:animate-in',
112
+ 'group-data-[state=closed]:animate-out',
113
+ 'group-has-[input:not(:placeholder-shown)]:animate-out',
114
+ className
115
+ )}
116
+ weight="medium"
117
+ {...props}
118
+ >
119
+ <label htmlFor={htmlFor}>{children}</label>
120
+ </Typography>
121
+ )
122
+ }
123
+
124
+ export function DatePickerLeftSlot({
125
+ className,
126
+ ...props
127
+ }: ComponentProps<'div'>) {
128
+ return (
129
+ <div
130
+ {...props}
131
+ className={cx(
132
+ className,
133
+ 'left-small absolute top-1/2 flex -translate-y-1/2 items-center justify-center'
134
+ )}
135
+ data-slot="date-picker-left-slot"
136
+ />
137
+ )
138
+ }
139
+
140
+ export function DatePickerRightSlot({
141
+ className,
142
+ ...props
143
+ }: ComponentProps<'div'>) {
144
+ return (
145
+ <div
146
+ {...props}
147
+ className={cx(
148
+ className,
149
+ 'right-small absolute top-1/2 flex -translate-y-1/2 items-center justify-center'
150
+ )}
151
+ data-slot="date-picker-right-slot"
152
+ />
153
+ )
154
+ }
@@ -0,0 +1,23 @@
1
+ import * as React from 'react'
2
+ import * as SeparatorPrimitive from '@radix-ui/react-separator'
3
+ import { cx } from '@xjur-ui/util'
4
+
5
+ export function Divider({
6
+ className,
7
+ orientation = 'horizontal',
8
+ decorative = true,
9
+ ...props
10
+ }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
11
+ return (
12
+ <SeparatorPrimitive.Root
13
+ className={cx(
14
+ 'bg-border-layer-2 shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px',
15
+ className
16
+ )}
17
+ data-slot="separator"
18
+ decorative={decorative}
19
+ orientation={orientation}
20
+ {...props}
21
+ />
22
+ )
23
+ }