@open-mercato/ui 0.5.1-develop.2953.6647bb2c43 → 0.5.1-develop.2964.d5ac4a6ebb
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 +1 -1
- package/AGENTS.md +8 -0
- package/dist/backend/CrudForm.js +57 -29
- package/dist/backend/CrudForm.js.map +2 -2
- package/dist/backend/DataTable.js +32 -14
- package/dist/backend/DataTable.js.map +2 -2
- package/dist/backend/FilterOverlay.js +23 -17
- package/dist/backend/FilterOverlay.js.map +2 -2
- package/dist/backend/JsonBuilder.js +32 -18
- package/dist/backend/JsonBuilder.js.map +2 -2
- package/dist/backend/columns/ColumnChooserPanel.js +12 -13
- package/dist/backend/columns/ColumnChooserPanel.js.map +2 -2
- package/dist/backend/custom-fields/FieldDefinitionsEditor.js +71 -62
- package/dist/backend/custom-fields/FieldDefinitionsEditor.js.map +2 -2
- package/dist/backend/date-range/DateRangeSelect.js +11 -10
- package/dist/backend/date-range/DateRangeSelect.js.map +2 -2
- package/dist/backend/date-range/InlineDateRangeSelect.js +10 -22
- package/dist/backend/date-range/InlineDateRangeSelect.js.map +2 -2
- package/dist/backend/detail/ActivitiesSection.js +20 -12
- package/dist/backend/detail/ActivitiesSection.js.map +2 -2
- package/dist/backend/detail/AddressEditor.js +24 -7
- package/dist/backend/detail/AddressEditor.js.map +2 -2
- package/dist/backend/detail/InlineEditors.js +12 -6
- package/dist/backend/detail/InlineEditors.js.map +2 -2
- package/dist/backend/detail/NotesSection.js +20 -14
- package/dist/backend/detail/NotesSection.js.map +2 -2
- package/dist/backend/filters/AdvancedFilterBuilder.js +52 -24
- package/dist/backend/filters/AdvancedFilterBuilder.js.map +2 -2
- package/dist/backend/injection/InjectedField.js +12 -7
- package/dist/backend/injection/InjectedField.js.map +2 -2
- package/dist/backend/inputs/ComboboxInput.js.map +2 -2
- package/dist/backend/inputs/EventSelect.js +22 -6
- package/dist/backend/inputs/EventSelect.js.map +2 -2
- package/dist/backend/inputs/PhoneNumberField.js +2 -2
- package/dist/backend/inputs/PhoneNumberField.js.map +2 -2
- package/dist/backend/inputs/TimeInput.js +9 -10
- package/dist/backend/inputs/TimeInput.js.map +2 -2
- package/dist/backend/messages/message-compose-form-groups.js +12 -7
- package/dist/backend/messages/message-compose-form-groups.js.map +2 -2
- package/dist/backend/messages/useMessageCompose.js +7 -1
- package/dist/backend/messages/useMessageCompose.js.map +2 -2
- package/dist/frontend/LanguageSwitcher.js +19 -14
- package/dist/frontend/LanguageSwitcher.js.map +2 -2
- package/dist/index.js +5 -0
- package/dist/index.js.map +2 -2
- package/dist/primitives/checkbox-field.js +17 -5
- package/dist/primitives/checkbox-field.js.map +2 -2
- package/dist/primitives/input.js +71 -14
- package/dist/primitives/input.js.map +2 -2
- package/dist/primitives/radio-field.js +74 -0
- package/dist/primitives/radio-field.js.map +7 -0
- package/dist/primitives/radio.js +37 -0
- package/dist/primitives/radio.js.map +7 -0
- package/dist/primitives/select.js +155 -0
- package/dist/primitives/select.js.map +7 -0
- package/dist/primitives/switch-field.js +76 -0
- package/dist/primitives/switch-field.js.map +7 -0
- package/dist/primitives/switch.js +17 -3
- package/dist/primitives/switch.js.map +2 -2
- package/dist/primitives/textarea.js +48 -12
- package/dist/primitives/textarea.js.map +2 -2
- package/dist/primitives/tooltip.js +44 -15
- package/dist/primitives/tooltip.js.map +2 -2
- package/package.json +5 -3
- package/src/backend/CrudForm.tsx +104 -37
- package/src/backend/DataTable.tsx +38 -20
- package/src/backend/FilterOverlay.tsx +35 -21
- package/src/backend/JsonBuilder.tsx +38 -20
- package/src/backend/__tests__/FieldDefinitionsEditor.test.tsx +23 -6
- package/src/backend/columns/ColumnChooserPanel.tsx +9 -10
- package/src/backend/custom-fields/FieldDefinitionsEditor.tsx +120 -87
- package/src/backend/date-range/DateRangeSelect.tsx +19 -12
- package/src/backend/date-range/InlineDateRangeSelect.tsx +16 -20
- package/src/backend/detail/ActivitiesSection.tsx +35 -23
- package/src/backend/detail/AddressEditor.tsx +30 -16
- package/src/backend/detail/InlineEditors.tsx +21 -11
- package/src/backend/detail/NotesSection.tsx +35 -25
- package/src/backend/filters/AdvancedFilterBuilder.tsx +60 -34
- package/src/backend/injection/InjectedField.tsx +21 -12
- package/src/backend/inputs/ComboboxInput.tsx +4 -0
- package/src/backend/inputs/EventSelect.tsx +30 -17
- package/src/backend/inputs/PhoneNumberField.tsx +2 -2
- package/src/backend/inputs/TimeInput.tsx +9 -10
- package/src/backend/messages/message-compose-form-groups.tsx +21 -12
- package/src/backend/messages/useMessageCompose.ts +20 -1
- package/src/frontend/LanguageSwitcher.tsx +20 -17
- package/src/index.ts +5 -0
- package/src/primitives/checkbox-field.tsx +10 -2
- package/src/primitives/input.tsx +73 -12
- package/src/primitives/radio-field.tsx +92 -0
- package/src/primitives/radio.tsx +42 -0
- package/src/primitives/select.tsx +200 -0
- package/src/primitives/switch-field.tsx +100 -0
- package/src/primitives/switch.tsx +17 -4
- package/src/primitives/textarea.tsx +67 -11
- package/src/primitives/tooltip.tsx +68 -24
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
5
|
+
import { Switch } from './switch'
|
|
6
|
+
|
|
7
|
+
export type SwitchFieldProps = Omit<React.ComponentProps<typeof Switch>, 'id'> & {
|
|
8
|
+
id?: string
|
|
9
|
+
label: React.ReactNode
|
|
10
|
+
sublabel?: React.ReactNode
|
|
11
|
+
description?: React.ReactNode
|
|
12
|
+
badge?: React.ReactNode
|
|
13
|
+
link?: React.ReactNode
|
|
14
|
+
/** When true, renders the switch on the left of the label content. */
|
|
15
|
+
flip?: boolean
|
|
16
|
+
containerClassName?: string
|
|
17
|
+
contentClassName?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const SwitchField = React.forwardRef<
|
|
21
|
+
React.ElementRef<typeof Switch>,
|
|
22
|
+
SwitchFieldProps
|
|
23
|
+
>(({
|
|
24
|
+
id: idProp,
|
|
25
|
+
label,
|
|
26
|
+
sublabel,
|
|
27
|
+
description,
|
|
28
|
+
badge,
|
|
29
|
+
link,
|
|
30
|
+
flip = false,
|
|
31
|
+
containerClassName,
|
|
32
|
+
contentClassName,
|
|
33
|
+
className,
|
|
34
|
+
disabled,
|
|
35
|
+
...switchProps
|
|
36
|
+
}, ref) => {
|
|
37
|
+
// useId is SSR/HMR-stable; counter-based fallbacks drift on hydration.
|
|
38
|
+
const fallbackId = React.useId()
|
|
39
|
+
const id = idProp ?? fallbackId
|
|
40
|
+
|
|
41
|
+
const hasMultiLine = Boolean(description || sublabel || link)
|
|
42
|
+
const switchEl = (
|
|
43
|
+
<Switch
|
|
44
|
+
ref={ref}
|
|
45
|
+
id={id}
|
|
46
|
+
disabled={disabled}
|
|
47
|
+
className={cn(hasMultiLine && 'mt-0.5', className)}
|
|
48
|
+
{...switchProps}
|
|
49
|
+
/>
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
const content = (
|
|
53
|
+
<div className={cn('flex flex-1 min-w-0 flex-col gap-2.5', contentClassName)}>
|
|
54
|
+
<div className="flex flex-col gap-1">
|
|
55
|
+
<div className="flex flex-wrap items-center gap-1">
|
|
56
|
+
<label
|
|
57
|
+
htmlFor={id}
|
|
58
|
+
className={cn(
|
|
59
|
+
'text-sm font-medium leading-5 text-foreground select-none',
|
|
60
|
+
disabled ? 'cursor-not-allowed opacity-60' : 'cursor-pointer'
|
|
61
|
+
)}
|
|
62
|
+
>
|
|
63
|
+
{label}
|
|
64
|
+
</label>
|
|
65
|
+
{sublabel ? (
|
|
66
|
+
<span className="text-xs leading-4 text-muted-foreground select-none">{sublabel}</span>
|
|
67
|
+
) : null}
|
|
68
|
+
{badge ? <span className="inline-flex shrink-0">{badge}</span> : null}
|
|
69
|
+
</div>
|
|
70
|
+
{description ? (
|
|
71
|
+
<p className="text-xs leading-4 text-muted-foreground">{description}</p>
|
|
72
|
+
) : null}
|
|
73
|
+
</div>
|
|
74
|
+
{link ? <div className="flex">{link}</div> : null}
|
|
75
|
+
</div>
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<div
|
|
80
|
+
className={cn(
|
|
81
|
+
'flex gap-3',
|
|
82
|
+
hasMultiLine ? 'items-start' : 'items-center',
|
|
83
|
+
containerClassName
|
|
84
|
+
)}
|
|
85
|
+
>
|
|
86
|
+
{flip ? (
|
|
87
|
+
<>
|
|
88
|
+
{switchEl}
|
|
89
|
+
{content}
|
|
90
|
+
</>
|
|
91
|
+
) : (
|
|
92
|
+
<>
|
|
93
|
+
{content}
|
|
94
|
+
{switchEl}
|
|
95
|
+
</>
|
|
96
|
+
)}
|
|
97
|
+
</div>
|
|
98
|
+
)
|
|
99
|
+
})
|
|
100
|
+
SwitchField.displayName = 'SwitchField'
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
1
3
|
import * as React from 'react'
|
|
2
4
|
|
|
3
5
|
import { cn } from '@open-mercato/shared/lib/utils'
|
|
@@ -66,7 +68,9 @@ export const Switch = React.forwardRef<HTMLButtonElement, SwitchProps>(
|
|
|
66
68
|
onKeyDown={handleKeyDown}
|
|
67
69
|
disabled={disabled}
|
|
68
70
|
className={cn(
|
|
69
|
-
'inline-flex h-
|
|
71
|
+
'group relative inline-flex h-5 w-8 shrink-0 cursor-pointer items-center justify-center rounded-full bg-transparent p-0',
|
|
72
|
+
'focus-visible:outline-none focus-visible:shadow-focus',
|
|
73
|
+
'disabled:cursor-not-allowed disabled:opacity-60',
|
|
70
74
|
className
|
|
71
75
|
)}
|
|
72
76
|
{...props}
|
|
@@ -74,10 +78,19 @@ export const Switch = React.forwardRef<HTMLButtonElement, SwitchProps>(
|
|
|
74
78
|
<span
|
|
75
79
|
aria-hidden
|
|
76
80
|
className={cn(
|
|
77
|
-
'
|
|
78
|
-
|
|
81
|
+
'pointer-events-none flex h-4 w-7 items-center rounded-full px-0.5 transition-colors duration-150',
|
|
82
|
+
'bg-border group-hover:bg-muted-foreground/30',
|
|
83
|
+
'group-data-[state=checked]:bg-accent-indigo group-data-[state=checked]:group-hover:bg-accent-indigo/85'
|
|
79
84
|
)}
|
|
80
|
-
|
|
85
|
+
>
|
|
86
|
+
<span
|
|
87
|
+
className={cn(
|
|
88
|
+
'block size-3 rounded-full bg-white transition-transform duration-200',
|
|
89
|
+
'shadow-[0_1px_2px_rgba(10,13,20,0.10),0_0_0_0.5px_rgba(10,13,20,0.04)]',
|
|
90
|
+
currentChecked ? 'translate-x-3' : 'translate-x-0'
|
|
91
|
+
)}
|
|
92
|
+
/>
|
|
93
|
+
</span>
|
|
81
94
|
</button>
|
|
82
95
|
)
|
|
83
96
|
}
|
|
@@ -1,20 +1,76 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
1
3
|
import * as React from 'react'
|
|
2
4
|
|
|
3
5
|
import { cn } from '@open-mercato/shared/lib/utils'
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
const baseTextareaClass =
|
|
8
|
+
'flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-colors placeholder:text-muted-foreground outline-none focus-visible:outline-none focus-visible:shadow-focus focus-visible:border-foreground hover:bg-muted/40 disabled:cursor-not-allowed disabled:bg-bg-disabled disabled:border-border-disabled disabled:shadow-none disabled:hover:bg-bg-disabled aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:border-destructive resize-y min-h-[80px]'
|
|
9
|
+
|
|
10
|
+
export type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement> & {
|
|
11
|
+
/** Show character counter (`current/max`) below the textarea. Requires `maxLength`. */
|
|
12
|
+
showCount?: boolean
|
|
13
|
+
/** Optional className applied to the outer wrapper (when counter is shown). */
|
|
14
|
+
wrapperClassName?: string
|
|
15
|
+
}
|
|
6
16
|
|
|
7
17
|
export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
8
|
-
({ className, ...props }, ref) =>
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
({ className, showCount, wrapperClassName, value, defaultValue, maxLength, onChange, ...props }, ref) => {
|
|
19
|
+
const [internalValue, setInternalValue] = React.useState<string>(
|
|
20
|
+
typeof defaultValue === 'string' ? defaultValue : typeof value === 'string' ? value : ''
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
const isControlled = value !== undefined
|
|
24
|
+
const currentValue = isControlled ? String(value ?? '') : internalValue
|
|
25
|
+
|
|
26
|
+
const handleChange = React.useCallback(
|
|
27
|
+
(event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
28
|
+
if (!isControlled) setInternalValue(event.target.value)
|
|
29
|
+
onChange?.(event)
|
|
30
|
+
},
|
|
31
|
+
[isControlled, onChange]
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
const textarea = (
|
|
35
|
+
<textarea
|
|
36
|
+
ref={ref}
|
|
37
|
+
value={value}
|
|
38
|
+
defaultValue={isControlled ? undefined : defaultValue}
|
|
39
|
+
maxLength={maxLength}
|
|
40
|
+
onChange={handleChange}
|
|
41
|
+
className={cn(baseTextareaClass, className)}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
if (!showCount) return textarea
|
|
47
|
+
|
|
48
|
+
const length = currentValue.length
|
|
49
|
+
const max = typeof maxLength === 'number' ? maxLength : undefined
|
|
50
|
+
const isError = max != null && length > max
|
|
51
|
+
const isDisabled = props.disabled
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<div className={cn('flex flex-col gap-1', wrapperClassName)}>
|
|
55
|
+
{textarea}
|
|
56
|
+
<div className="flex justify-end">
|
|
57
|
+
<span
|
|
58
|
+
className={cn(
|
|
59
|
+
'text-overline uppercase',
|
|
60
|
+
isDisabled
|
|
61
|
+
? 'text-text-disabled'
|
|
62
|
+
: isError
|
|
63
|
+
? 'text-destructive'
|
|
64
|
+
: 'text-muted-foreground'
|
|
65
|
+
)}
|
|
66
|
+
aria-live="polite"
|
|
67
|
+
>
|
|
68
|
+
{max != null ? `${length}/${max}` : `${length}`}
|
|
69
|
+
</span>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
18
74
|
)
|
|
19
75
|
|
|
20
76
|
Textarea.displayName = 'Textarea'
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip'
|
|
5
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
5
6
|
import { cn } from '@open-mercato/shared/lib/utils'
|
|
6
7
|
|
|
7
8
|
export const TooltipProvider = TooltipPrimitive.Provider
|
|
@@ -10,24 +11,53 @@ export const Tooltip = TooltipPrimitive.Root
|
|
|
10
11
|
|
|
11
12
|
export const TooltipTrigger = TooltipPrimitive.Trigger
|
|
12
13
|
|
|
14
|
+
const tooltipContentVariants = cva(
|
|
15
|
+
'z-tooltip overflow-hidden rounded-sm max-w-xs break-words shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
16
|
+
{
|
|
17
|
+
variants: {
|
|
18
|
+
variant: {
|
|
19
|
+
dark: 'bg-foreground text-background',
|
|
20
|
+
light: 'bg-popover text-popover-foreground border border-input',
|
|
21
|
+
},
|
|
22
|
+
size: {
|
|
23
|
+
sm: 'px-1.5 py-0.5 text-xs leading-4',
|
|
24
|
+
default: 'px-2 py-0.5 text-xs leading-4',
|
|
25
|
+
lg: 'px-3 py-2 text-sm leading-5',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
defaultVariants: {
|
|
29
|
+
variant: 'dark',
|
|
30
|
+
size: 'default',
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
export type TooltipContentProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> &
|
|
36
|
+
VariantProps<typeof tooltipContentVariants> & {
|
|
37
|
+
/** Show a small arrow pointing at the trigger. */
|
|
38
|
+
arrow?: boolean
|
|
39
|
+
}
|
|
40
|
+
|
|
13
41
|
export const TooltipContent = React.forwardRef<
|
|
14
42
|
React.ElementRef<typeof TooltipPrimitive.Content>,
|
|
15
|
-
|
|
16
|
-
>(({ className, sideOffset = 4, ...props }, ref) => (
|
|
43
|
+
TooltipContentProps
|
|
44
|
+
>(({ className, sideOffset = 4, variant, size, arrow = true, children, ...props }, ref) => (
|
|
17
45
|
<TooltipPrimitive.Portal>
|
|
18
46
|
<TooltipPrimitive.Content
|
|
19
47
|
ref={ref}
|
|
20
48
|
sideOffset={sideOffset}
|
|
21
|
-
className={cn(
|
|
22
|
-
'z-tooltip overflow-hidden rounded-md bg-slate-900 px-3 py-1.5 text-xs text-slate-50 animate-in fade-in-0 zoom-in-95',
|
|
23
|
-
'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95',
|
|
24
|
-
'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2',
|
|
25
|
-
'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
26
|
-
'max-w-xs break-words',
|
|
27
|
-
className
|
|
28
|
-
)}
|
|
49
|
+
className={cn(tooltipContentVariants({ variant, size }), className)}
|
|
29
50
|
{...props}
|
|
30
|
-
|
|
51
|
+
>
|
|
52
|
+
{children}
|
|
53
|
+
{arrow ? (
|
|
54
|
+
<TooltipPrimitive.Arrow
|
|
55
|
+
width={10}
|
|
56
|
+
height={5}
|
|
57
|
+
className={cn(variant === 'light' ? 'fill-popover stroke-input' : 'fill-foreground')}
|
|
58
|
+
/>
|
|
59
|
+
) : null}
|
|
60
|
+
</TooltipPrimitive.Content>
|
|
31
61
|
</TooltipPrimitive.Portal>
|
|
32
62
|
))
|
|
33
63
|
TooltipContent.displayName = TooltipPrimitive.Content.displayName
|
|
@@ -41,6 +71,9 @@ export type TooltipProps = {
|
|
|
41
71
|
open?: boolean
|
|
42
72
|
onOpenChange?: (open: boolean) => void
|
|
43
73
|
disabled?: boolean
|
|
74
|
+
variant?: 'dark' | 'light'
|
|
75
|
+
size?: 'sm' | 'default' | 'lg'
|
|
76
|
+
arrow?: boolean
|
|
44
77
|
}
|
|
45
78
|
|
|
46
79
|
/**
|
|
@@ -50,6 +83,11 @@ export type TooltipProps = {
|
|
|
50
83
|
* <SimpleTooltip content="Full text here">
|
|
51
84
|
* <span>Truncated...</span>
|
|
52
85
|
* </SimpleTooltip>
|
|
86
|
+
*
|
|
87
|
+
* @example with arrow + light variant
|
|
88
|
+
* <SimpleTooltip content="Help text" variant="light" arrow>
|
|
89
|
+
* <InfoIcon />
|
|
90
|
+
* </SimpleTooltip>
|
|
53
91
|
*/
|
|
54
92
|
export function SimpleTooltip({
|
|
55
93
|
content,
|
|
@@ -60,8 +98,10 @@ export function SimpleTooltip({
|
|
|
60
98
|
open,
|
|
61
99
|
onOpenChange,
|
|
62
100
|
disabled = false,
|
|
101
|
+
variant,
|
|
102
|
+
size,
|
|
103
|
+
arrow,
|
|
63
104
|
}: TooltipProps) {
|
|
64
|
-
// If disabled or no content, just render children without tooltip
|
|
65
105
|
const isDisabled = disabled || !content
|
|
66
106
|
|
|
67
107
|
if (isDisabled) {
|
|
@@ -69,17 +109,21 @@ export function SimpleTooltip({
|
|
|
69
109
|
}
|
|
70
110
|
|
|
71
111
|
return (
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
{
|
|
82
|
-
|
|
83
|
-
|
|
112
|
+
<TooltipProvider delayDuration={delayDuration}>
|
|
113
|
+
<Tooltip
|
|
114
|
+
open={open}
|
|
115
|
+
onOpenChange={onOpenChange}
|
|
116
|
+
delayDuration={delayDuration}
|
|
117
|
+
>
|
|
118
|
+
<TooltipTrigger asChild>
|
|
119
|
+
{children}
|
|
120
|
+
</TooltipTrigger>
|
|
121
|
+
<TooltipContent side={side} align={align} variant={variant} size={size} arrow={arrow}>
|
|
122
|
+
{content}
|
|
123
|
+
</TooltipContent>
|
|
124
|
+
</Tooltip>
|
|
125
|
+
</TooltipProvider>
|
|
84
126
|
)
|
|
85
127
|
}
|
|
128
|
+
|
|
129
|
+
export { tooltipContentVariants }
|