@luxfi/ui 7.0.0 → 7.2.0

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 (70) hide show
  1. package/dist/alert.cjs +184 -335
  2. package/dist/alert.js +184 -335
  3. package/dist/badge.cjs +162 -321
  4. package/dist/badge.d.cts +3 -7
  5. package/dist/badge.d.ts +3 -7
  6. package/dist/badge.js +162 -320
  7. package/dist/bank.d.cts +1 -1
  8. package/dist/bank.d.ts +1 -1
  9. package/dist/button.cjs +373 -484
  10. package/dist/button.d.cts +10 -7
  11. package/dist/button.d.ts +10 -7
  12. package/dist/button.js +373 -484
  13. package/dist/close-button.cjs +37 -18
  14. package/dist/close-button.d.cts +1 -1
  15. package/dist/close-button.d.ts +1 -1
  16. package/dist/close-button.js +37 -18
  17. package/dist/collapsible.cjs +125 -272
  18. package/dist/collapsible.js +125 -272
  19. package/dist/dialog.cjs +60 -44
  20. package/dist/dialog.d.cts +7 -8
  21. package/dist/dialog.d.ts +7 -8
  22. package/dist/dialog.js +60 -43
  23. package/dist/drawer.cjs +37 -13
  24. package/dist/drawer.js +37 -13
  25. package/dist/heading.cjs +3 -8
  26. package/dist/heading.js +3 -8
  27. package/dist/icon-button.cjs +213 -337
  28. package/dist/icon-button.d.cts +4 -4
  29. package/dist/icon-button.d.ts +4 -4
  30. package/dist/icon-button.js +213 -338
  31. package/dist/image.cjs +125 -272
  32. package/dist/image.js +125 -272
  33. package/dist/index.cjs +695 -858
  34. package/dist/index.d.cts +0 -3
  35. package/dist/index.d.ts +0 -3
  36. package/dist/index.js +695 -856
  37. package/dist/input.cjs +25 -36
  38. package/dist/input.js +25 -36
  39. package/dist/link.cjs +125 -272
  40. package/dist/link.js +125 -272
  41. package/dist/popover.cjs +55 -40
  42. package/dist/popover.js +55 -39
  43. package/dist/select.cjs +125 -272
  44. package/dist/select.js +125 -272
  45. package/dist/skeleton.cjs +125 -272
  46. package/dist/skeleton.js +125 -272
  47. package/dist/table.cjs +127 -274
  48. package/dist/table.js +127 -274
  49. package/dist/tag.cjs +199 -341
  50. package/dist/tag.js +199 -340
  51. package/dist/textarea.cjs +25 -36
  52. package/dist/textarea.js +25 -36
  53. package/dist/tooltip.cjs +22 -21
  54. package/dist/tooltip.d.cts +2 -3
  55. package/dist/tooltip.d.ts +2 -3
  56. package/dist/tooltip.js +22 -20
  57. package/package.json +9 -8
  58. package/src/alert.tsx +23 -51
  59. package/src/badge.tsx +20 -31
  60. package/src/button.tsx +304 -238
  61. package/src/close-button.tsx +48 -22
  62. package/src/dialog.tsx +37 -47
  63. package/src/heading.tsx +8 -19
  64. package/src/icon-button.tsx +129 -104
  65. package/src/input.tsx +27 -36
  66. package/src/popover.tsx +30 -44
  67. package/src/skeleton.tsx +96 -144
  68. package/src/tag.tsx +17 -35
  69. package/src/textarea.tsx +27 -36
  70. package/src/tooltip.tsx +54 -47
package/src/textarea.tsx CHANGED
@@ -1,41 +1,32 @@
1
- import { cva } from 'class-variance-authority';
2
1
  import React from 'react';
3
2
 
4
3
  import { cn } from './utils';
5
4
 
6
- const textareaVariants = cva(
7
- [
8
- 'w-full appearance-none outline-none transition-colors resize-y',
9
- 'bg-[var(--color-input-bg)] text-[var(--color-input-fg)] border-[var(--color-input-border)]',
10
- 'placeholder:text-[var(--color-input-placeholder,theme(colors.gray.400))]',
11
- 'hover:border-[var(--color-input-border-hover,theme(colors.gray.400))]',
12
- 'focus:border-[var(--color-input-border-focus,theme(colors.blue.500))]',
13
- 'focus:placeholder:text-[var(--color-input-placeholder-focus,theme(colors.gray.300))]',
14
- 'disabled:opacity-40 disabled:cursor-not-allowed',
15
- 'read-only:opacity-70',
16
- 'data-[invalid]:border-[var(--color-input-border-invalid,theme(colors.red.500))]',
17
- ].join(' '),
18
- {
19
- variants: {
20
- size: {
21
- xs: 'px-2 py-1 text-xs rounded',
22
- sm: 'px-3 py-2 text-sm rounded-md',
23
- md: 'px-4 py-2 text-base rounded-md',
24
- lg: 'px-4 py-3 text-lg rounded-lg',
25
- '2xl': 'px-4 py-3 text-xl rounded-lg',
26
- },
27
- variant: {
28
- outline: 'border border-solid',
29
- filled: 'border-0 bg-[var(--color-input-filled-bg,theme(colors.gray.100))]',
30
- unstyled: 'border-0 bg-transparent p-0',
31
- },
32
- },
33
- defaultVariants: {
34
- size: 'md',
35
- variant: 'outline',
36
- },
37
- },
38
- );
5
+ const TEXTAREA_BASE = [
6
+ 'w-full appearance-none outline-none transition-colors resize-y',
7
+ 'bg-[var(--color-input-bg)] text-[var(--color-input-fg)] border-[var(--color-input-border)]',
8
+ 'placeholder:text-[var(--color-input-placeholder,theme(colors.gray.400))]',
9
+ 'hover:border-[var(--color-input-border-hover,theme(colors.gray.400))]',
10
+ 'focus:border-[var(--color-input-border-focus,theme(colors.blue.500))]',
11
+ 'focus:placeholder:text-[var(--color-input-placeholder-focus,theme(colors.gray.300))]',
12
+ 'disabled:opacity-40 disabled:cursor-not-allowed',
13
+ 'read-only:opacity-70',
14
+ 'data-[invalid]:border-[var(--color-input-border-invalid,theme(colors.red.500))]',
15
+ ].join(' ');
16
+
17
+ const TEXTAREA_SIZE_CLASSES: Record<string, string> = {
18
+ xs: 'px-2 py-1 text-xs rounded',
19
+ sm: 'px-3 py-2 text-sm rounded-md',
20
+ md: 'px-4 py-2 text-base rounded-md',
21
+ lg: 'px-4 py-3 text-lg rounded-lg',
22
+ '2xl': 'px-4 py-3 text-xl rounded-lg',
23
+ };
24
+
25
+ const TEXTAREA_VARIANT_CLASSES: Record<string, string> = {
26
+ outline: 'border border-solid',
27
+ filled: 'border-0 bg-[var(--color-input-filled-bg,theme(colors.gray.100))]',
28
+ unstyled: 'border-0 bg-transparent p-0',
29
+ };
39
30
 
40
31
  type TextareaSize = 'xs' | 'sm' | 'md' | 'lg' | '2xl';
41
32
  type TextareaVariant = 'outline' | 'filled' | 'unstyled';
@@ -46,11 +37,11 @@ export interface TextareaProps extends Omit<React.ComponentPropsWithRef<'textare
46
37
  }
47
38
 
48
39
  export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
49
- ({ size, variant, className, ...rest }, ref) => {
40
+ ({ size = 'md', variant = 'outline', className, ...rest }, ref) => {
50
41
  return (
51
42
  <textarea
52
43
  ref={ ref }
53
- className={ cn(textareaVariants({ size, variant }), className) }
44
+ className={ cn(TEXTAREA_BASE, TEXTAREA_SIZE_CLASSES[size], TEXTAREA_VARIANT_CLASSES[variant], className) }
54
45
  { ...rest }
55
46
  />
56
47
  );
package/src/tooltip.tsx CHANGED
@@ -1,4 +1,7 @@
1
- import * as RadixTooltip from '@radix-ui/react-tooltip';
1
+ import {
2
+ Tooltip as GuiTooltip,
3
+ TooltipGroup as GuiTooltipGroup,
4
+ } from '@hanzogui/tooltip';
2
5
  import { useClickAway } from '@uidotdev/usehooks';
3
6
  import * as React from 'react';
4
7
 
@@ -24,14 +27,21 @@ function useIsMobile(): boolean {
24
27
  return isMobile;
25
28
  }
26
29
 
30
+ /** Map placement string to @hanzogui Popper placement prop. */
31
+ function mapPlacement(p: string | undefined): string | undefined {
32
+ if (!p) return undefined;
33
+ // @hanzogui/popper uses same placement strings as floating-ui
34
+ return p;
35
+ }
36
+
27
37
  export interface TooltipProps {
28
38
  selected?: boolean;
29
39
  showArrow?: boolean;
30
40
  portalled?: boolean;
31
41
  portalRef?: React.RefObject<HTMLElement>;
32
42
  content: React.ReactNode;
33
- contentProps?: React.ComponentPropsWithoutRef<typeof RadixTooltip.Content>;
34
- triggerProps?: React.ComponentPropsWithoutRef<typeof RadixTooltip.Trigger>;
43
+ contentProps?: React.HTMLAttributes<HTMLDivElement>;
44
+ triggerProps?: React.HTMLAttributes<HTMLButtonElement>;
35
45
  disabled?: boolean;
36
46
  disableOnMobile?: boolean;
37
47
  children?: React.ReactNode;
@@ -63,10 +73,8 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
63
73
  children,
64
74
  disabled,
65
75
  disableOnMobile,
66
- portalled = true,
67
76
  content,
68
77
  contentProps,
69
- portalRef,
70
78
  defaultOpen = false,
71
79
  triggerProps,
72
80
  closeDelay = 100,
@@ -127,58 +135,57 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
127
135
  const defaultShowArrow = variant === 'popover' ? false : true;
128
136
  const showArrow = showArrowProp !== undefined ? showArrowProp : defaultShowArrow;
129
137
 
130
- const placement = positioning?.placement ?? 'top';
131
- const side = placement.split('-')[0] as 'top' | 'bottom' | 'left' | 'right';
132
- const align = placement.includes('-') ? (placement.split('-')[1] as 'start' | 'end') : undefined;
133
- const sideOffset = positioning?.offset?.mainAxis ?? 4;
134
-
135
138
  const isPopover = variant === 'popover';
136
139
 
140
+ const placement = mapPlacement(positioning?.placement) ?? 'top';
141
+ const offset = positioning?.offset?.mainAxis ?? 4;
142
+
137
143
  return (
138
- <RadixTooltip.Provider delayDuration={ openDelay } skipDelayDuration={ 0 }>
139
- <RadixTooltip.Root
144
+ <GuiTooltipGroup delay={ openDelay }>
145
+ <GuiTooltip
140
146
  open={ open }
141
147
  onOpenChange={ handleOpenChange }
142
- delayDuration={ openDelay }
148
+ delay={{ open: openDelay, close: closeDelay }}
149
+ placement={ placement as any }
150
+ offset={ offset }
151
+ unstyled
143
152
  >
144
- <RadixTooltip.Trigger
153
+ <GuiTooltip.Trigger
145
154
  ref={ open ? triggerRef : undefined }
146
155
  asChild
147
- onClick={ isMobile ? handleTriggerClick : undefined }
148
- { ...triggerProps }
156
+ {...(isMobile ? { onPress: handleTriggerClick } : {})}
157
+ { ...triggerProps as any }
149
158
  >
150
159
  { children }
151
- </RadixTooltip.Trigger>
152
- <RadixTooltip.Portal container={ portalled ? (portalRef?.current ?? undefined) : undefined }>
153
- <RadixTooltip.Content
154
- ref={ ref }
155
- side={ side }
156
- align={ align }
157
- sideOffset={ sideOffset }
158
- onClick={ interactive ? handleContentClick : undefined }
159
- className={ cn(
160
- 'z-[9999] overflow-hidden rounded-lg px-3 py-2 text-sm',
161
- 'animate-in fade-in-0 zoom-in-95',
162
- isPopover && 'bg-[var(--color-popover-bg)] text-[var(--color-text-primary)]',
163
- isPopover && 'shadow-[var(--shadow-popover)] border border-[var(--color-border-divider)] max-w-sm',
164
- !isPopover && 'bg-[var(--color-tooltip-bg)] text-[var(--color-tooltip-fg)] max-w-xs',
165
- contentProps?.className,
166
- ) }
167
- { ...(selected ? { 'data-selected': true } : {}) }
168
- { ...contentProps }
169
- >
170
- { showArrow && (
171
- <RadixTooltip.Arrow
172
- className={ cn(
173
- isPopover ? 'fill-[var(--color-popover-bg)]' : 'fill-[var(--color-tooltip-bg)]',
174
- ) }
175
- />
176
- ) }
177
- { content }
178
- </RadixTooltip.Content>
179
- </RadixTooltip.Portal>
180
- </RadixTooltip.Root>
181
- </RadixTooltip.Provider>
160
+ </GuiTooltip.Trigger>
161
+
162
+ <GuiTooltip.Content
163
+ ref={ ref }
164
+ unstyled
165
+ className={ cn(
166
+ 'z-[9999] overflow-hidden rounded-lg px-3 py-2 text-sm',
167
+ 'animate-in fade-in-0 zoom-in-95',
168
+ isPopover && 'bg-[var(--color-popover-bg)] text-[var(--color-text-primary)]',
169
+ isPopover && 'shadow-[var(--shadow-popover)] border border-[var(--color-border-divider)] max-w-sm',
170
+ !isPopover && 'bg-[var(--color-tooltip-bg)] text-[var(--color-tooltip-fg)] max-w-xs',
171
+ contentProps?.className,
172
+ ) }
173
+ onClick={ interactive ? handleContentClick : undefined }
174
+ { ...(selected ? { 'data-selected': true } : {}) }
175
+ { ...contentProps as any }
176
+ >
177
+ { showArrow && (
178
+ <GuiTooltip.Arrow
179
+ unstyled
180
+ className={ cn(
181
+ isPopover ? 'fill-[var(--color-popover-bg)]' : 'fill-[var(--color-tooltip-bg)]',
182
+ ) }
183
+ />
184
+ ) }
185
+ { content }
186
+ </GuiTooltip.Content>
187
+ </GuiTooltip>
188
+ </GuiTooltipGroup>
182
189
  );
183
190
  },
184
191
  );