@luxfi/ui 7.4.11 → 7.4.13
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/dist/alert.cjs +68 -46
- package/dist/alert.js +69 -46
- package/dist/avatar.cjs +49 -47
- package/dist/avatar.js +52 -49
- package/dist/badge.cjs +82 -49
- package/dist/badge.js +83 -50
- package/dist/checkbox.cjs +42 -75
- package/dist/checkbox.js +43 -76
- package/dist/chrome.cjs +3 -7
- package/dist/chrome.js +3 -7
- package/dist/close-button.cjs +3 -7
- package/dist/close-button.js +3 -7
- package/dist/dialog.cjs +3 -7
- package/dist/dialog.js +3 -7
- package/dist/drawer.cjs +3 -7
- package/dist/drawer.js +3 -7
- package/dist/empty-state.cjs +13 -13
- package/dist/empty-state.js +13 -13
- package/dist/expiration-selector.cjs +58 -63
- package/dist/expiration-selector.js +58 -63
- package/dist/greeks-display.cjs +48 -39
- package/dist/greeks-display.js +48 -39
- package/dist/index.cjs +1053 -888
- package/dist/index.js +1054 -889
- package/dist/input-group.cjs +36 -19
- package/dist/input-group.js +37 -19
- package/dist/option-chain.cjs +89 -67
- package/dist/option-chain.js +89 -67
- package/dist/option-position.cjs +88 -85
- package/dist/option-position.js +88 -85
- package/dist/pin-input.cjs +30 -29
- package/dist/pin-input.js +30 -29
- package/dist/pnl-diagram.cjs +20 -20
- package/dist/pnl-diagram.js +20 -20
- package/dist/popover.cjs +3 -7
- package/dist/popover.js +3 -7
- package/dist/progress-circle.cjs +40 -22
- package/dist/progress-circle.d.cts +5 -5
- package/dist/progress-circle.d.ts +5 -5
- package/dist/progress-circle.js +41 -22
- package/dist/progress.cjs +15 -22
- package/dist/progress.d.cts +6 -6
- package/dist/progress.d.ts +6 -6
- package/dist/progress.js +15 -22
- package/dist/radio.cjs +35 -68
- package/dist/radio.d.cts +18 -18
- package/dist/radio.d.ts +18 -18
- package/dist/radio.js +36 -69
- package/dist/rating.cjs +15 -17
- package/dist/rating.js +15 -17
- package/dist/slider.cjs +33 -50
- package/dist/slider.js +34 -51
- package/dist/strategy-builder.cjs +194 -115
- package/dist/strategy-builder.js +194 -115
- package/dist/switch.cjs +48 -55
- package/dist/switch.js +49 -56
- package/dist/tag.cjs +115 -69
- package/dist/tag.js +116 -69
- package/dist/tooltip.cjs +28 -17
- package/dist/tooltip.js +30 -18
- package/package.json +1 -1
- package/src/alert.tsx +78 -45
- package/src/avatar.tsx +54 -38
- package/src/badge.tsx +65 -44
- package/src/checkbox.tsx +70 -89
- package/src/close-button.tsx +3 -8
- package/src/empty-state.tsx +21 -17
- package/src/expiration-selector.tsx +84 -66
- package/src/greeks-display.tsx +59 -51
- package/src/input-group.tsx +38 -24
- package/src/option-chain.tsx +154 -104
- package/src/option-position.tsx +143 -114
- package/src/pin-input.tsx +37 -29
- package/src/pnl-diagram.tsx +36 -28
- package/src/progress-circle.tsx +52 -28
- package/src/progress.tsx +17 -21
- package/src/radio.tsx +56 -76
- package/src/rating.tsx +22 -20
- package/src/slider.tsx +43 -45
- package/src/strategy-builder.tsx +260 -162
- package/src/switch.tsx +63 -64
- package/src/tag.tsx +89 -51
- package/src/tooltip.tsx +21 -13
- package/tokens.css +18 -0
package/src/switch.tsx
CHANGED
|
@@ -1,32 +1,23 @@
|
|
|
1
|
-
import { Switch as GuiSwitch } from '@hanzo/gui';
|
|
1
|
+
import { Label, Switch as GuiSwitch, Text, VisuallyHidden } from '@hanzo/gui';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
|
|
4
|
-
import { cn } from './utils';
|
|
5
|
-
|
|
6
4
|
const NOOP = () => { /* noop */ };
|
|
7
5
|
|
|
8
6
|
// ─── Size mappings ────────────────────────────────────────────────────
|
|
9
7
|
// Paint and box size only. Thumb travel is NOT a hardcoded translate any more:
|
|
10
8
|
// gui measures the track and the knob and moves the knob by the difference, so
|
|
11
9
|
// the switch stays correct at any size and on native.
|
|
12
|
-
const
|
|
13
|
-
sm: {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
label: 'text-xs',
|
|
17
|
-
},
|
|
18
|
-
md: {
|
|
19
|
-
root: 'h-5 w-9',
|
|
20
|
-
thumb: 'h-4 w-4',
|
|
21
|
-
label: 'text-sm',
|
|
22
|
-
},
|
|
23
|
-
lg: {
|
|
24
|
-
root: 'h-6 w-11',
|
|
25
|
-
thumb: 'h-5 w-5',
|
|
26
|
-
label: 'text-base',
|
|
27
|
-
},
|
|
10
|
+
const SIZE = {
|
|
11
|
+
sm: { width: 28, height: 16, thumb: 12, label: 12 },
|
|
12
|
+
md: { width: 36, height: 20, thumb: 16, label: 14 },
|
|
13
|
+
lg: { width: 44, height: 24, thumb: 20, label: 16 },
|
|
28
14
|
} as const;
|
|
29
15
|
|
|
16
|
+
const TRACK_ON = 'var(--color-text-primary)' as never;
|
|
17
|
+
const TRACK_OFF = 'var(--color-switch-bg)' as never;
|
|
18
|
+
const OUTLINE = 'var(--color-gray-500)' as never;
|
|
19
|
+
const WHITE = 'var(--color-white)' as never;
|
|
20
|
+
|
|
30
21
|
// ─── Props ────────────────────────────────────────────────────────────
|
|
31
22
|
export interface SwitchProps extends Omit<React.ComponentPropsWithoutRef<'label'>, 'onChange' | 'dir'> {
|
|
32
23
|
inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
|
|
@@ -59,7 +50,6 @@ const SwitchBase = React.forwardRef<HTMLInputElement, SwitchProps>(
|
|
|
59
50
|
disabled = false,
|
|
60
51
|
size = 'md',
|
|
61
52
|
direction,
|
|
62
|
-
className,
|
|
63
53
|
...rest
|
|
64
54
|
} = props;
|
|
65
55
|
|
|
@@ -80,78 +70,87 @@ const SwitchBase = React.forwardRef<HTMLInputElement, SwitchProps>(
|
|
|
80
70
|
[ isControlled, onCheckedChange ],
|
|
81
71
|
);
|
|
82
72
|
|
|
83
|
-
const
|
|
73
|
+
const s = SIZE[size];
|
|
84
74
|
const isRtl = direction === 'rtl';
|
|
85
75
|
|
|
86
76
|
return (
|
|
87
|
-
<
|
|
88
|
-
ref={ rootRef }
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
77
|
+
<Label
|
|
78
|
+
ref={ rootRef as never }
|
|
79
|
+
unstyled
|
|
80
|
+
flexDirection={ isRtl ? 'row-reverse' : 'row' }
|
|
81
|
+
alignItems="center"
|
|
82
|
+
gap={ 8 }
|
|
83
|
+
cursor={ disabled ? 'not-allowed' : 'pointer' }
|
|
84
|
+
userSelect="none"
|
|
85
|
+
opacity={ disabled ? 0.5 : 1 }
|
|
86
|
+
onChange={ onChange as never }
|
|
96
87
|
data-disabled={ disabled || undefined }
|
|
97
|
-
{ ...rest }
|
|
88
|
+
{ ...(rest as object) }
|
|
98
89
|
>
|
|
99
90
|
<GuiSwitch
|
|
100
91
|
unstyled
|
|
101
92
|
checked={ checkedState }
|
|
102
93
|
onCheckedChange={ handleCheckedChange }
|
|
103
94
|
disabled={ disabled }
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
95
|
+
position="relative"
|
|
96
|
+
flexShrink={ 0 }
|
|
97
|
+
alignItems="center"
|
|
98
|
+
width={ s.width }
|
|
99
|
+
height={ s.height }
|
|
100
|
+
borderRadius={ 9999 }
|
|
101
|
+
backgroundColor={ checkedState ? TRACK_ON : TRACK_OFF }
|
|
102
|
+
transition="quick"
|
|
103
|
+
focusStyle={{ outlineWidth: 2, outlineStyle: 'solid', outlineColor: OUTLINE, outlineOffset: 2 }}
|
|
112
104
|
>
|
|
113
105
|
{ trackLabel && (
|
|
114
|
-
<
|
|
106
|
+
<Text
|
|
107
|
+
position="absolute"
|
|
108
|
+
width="100%"
|
|
109
|
+
textAlign="center"
|
|
110
|
+
fontSize={ 8 }
|
|
111
|
+
fontWeight="700"
|
|
112
|
+
color={ WHITE }
|
|
113
|
+
pointerEvents="none"
|
|
114
|
+
>
|
|
115
115
|
{ checkedState ? trackLabel.on : trackLabel.off }
|
|
116
|
-
</
|
|
116
|
+
</Text>
|
|
117
117
|
) }
|
|
118
118
|
<GuiSwitch.Thumb
|
|
119
119
|
unstyled
|
|
120
120
|
data-thumb
|
|
121
121
|
transition="quicker"
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
122
|
+
width={ s.thumb }
|
|
123
|
+
height={ s.thumb }
|
|
124
|
+
borderRadius={ 9999 }
|
|
125
|
+
backgroundColor={ WHITE }
|
|
126
|
+
boxShadow="0 1px 2px 0 rgba(0,0,0,0.05)"
|
|
126
127
|
>
|
|
127
128
|
{ thumbLabel && (
|
|
128
|
-
<
|
|
129
|
+
<Text width="100%" height="100%" textAlign="center" fontSize={ 8 }>
|
|
129
130
|
{ checkedState ? thumbLabel.on : thumbLabel.off }
|
|
130
|
-
</
|
|
131
|
+
</Text>
|
|
131
132
|
) }
|
|
132
133
|
</GuiSwitch.Thumb>
|
|
133
134
|
</GuiSwitch>
|
|
134
135
|
{ /* Hidden native input for form compat and ref forwarding */ }
|
|
135
|
-
<
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
136
|
+
<VisuallyHidden>
|
|
137
|
+
<input
|
|
138
|
+
ref={ ref }
|
|
139
|
+
type="checkbox"
|
|
140
|
+
checked={ checkedState }
|
|
141
|
+
disabled={ disabled }
|
|
142
|
+
tabIndex={ -1 }
|
|
143
|
+
aria-hidden
|
|
144
|
+
onChange={ NOOP }
|
|
145
|
+
{ ...inputProps }
|
|
146
|
+
/>
|
|
147
|
+
</VisuallyHidden>
|
|
146
148
|
{ children != null && (
|
|
147
|
-
<
|
|
148
|
-
{ ...labelProps }
|
|
149
|
-
className={ cn(sizeClasses.label, labelProps?.className) }
|
|
150
|
-
>
|
|
149
|
+
<Text { ...(labelProps as object) } fontSize={ s.label }>
|
|
151
150
|
{ children }
|
|
152
|
-
</
|
|
151
|
+
</Text>
|
|
153
152
|
) }
|
|
154
|
-
</
|
|
153
|
+
</Label>
|
|
155
154
|
);
|
|
156
155
|
},
|
|
157
156
|
);
|
package/src/tag.tsx
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import { Text, XStack } from '@hanzo/gui';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
|
|
3
|
-
import { cn } from './utils';
|
|
4
|
-
|
|
5
4
|
import { CloseButton } from './close-button';
|
|
6
5
|
import { Skeleton } from './skeleton';
|
|
7
6
|
import { Tooltip } from './tooltip';
|
|
@@ -21,29 +20,29 @@ function TruncatedTextTooltip({ label, children }: { readonly label: React.React
|
|
|
21
20
|
type TagVariant = 'subtle' | 'clickable' | 'filter' | 'select';
|
|
22
21
|
type TagSize = 'sm' | 'md' | 'lg';
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
select: 'cursor-pointer bg-[var(--color-tag-select-bg)] text-[var(--color-tag-select-fg)] hover:text-[var(--color-hover)] hover:opacity-76',
|
|
23
|
+
/** The chip — background, cursor, and the hover opacity `clickable`/`select` get. */
|
|
24
|
+
const TAG_VARIANT: Record<TagVariant, { backgroundColor: string; cursor?: string; hoverStyle?: Record<string, unknown> }> = {
|
|
25
|
+
subtle: { backgroundColor: 'var(--color-tag-subtle-bg)' },
|
|
26
|
+
clickable: { backgroundColor: 'var(--color-tag-clickable-bg)', cursor: 'pointer', hoverStyle: { opacity: 0.76 } },
|
|
27
|
+
filter: { backgroundColor: 'var(--color-tag-filter-bg)' },
|
|
28
|
+
select: { backgroundColor: 'var(--color-tag-select-bg)', cursor: 'pointer', hoverStyle: { opacity: 0.76 } },
|
|
31
29
|
};
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
/** The label inside it — same four variants, the colour half (`filter` has none). */
|
|
32
|
+
const TAG_VARIANT_FG: Record<TagVariant, string | undefined> = {
|
|
33
|
+
subtle: 'var(--color-tag-subtle-fg)',
|
|
34
|
+
clickable: 'var(--color-tag-clickable-fg)',
|
|
35
|
+
filter: undefined,
|
|
36
|
+
select: 'var(--color-tag-select-fg)',
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
].join(' ');
|
|
39
|
+
const TAG_SIZE: Record<TagSize, Record<string, number>> = {
|
|
40
|
+
sm: { paddingHorizontal: 4, paddingVertical: 2, minHeight: 20, gap: 4 },
|
|
41
|
+
md: { paddingHorizontal: 4, paddingVertical: 2, minHeight: 24, gap: 4 },
|
|
42
|
+
lg: { paddingHorizontal: 6, paddingVertical: 6, minHeight: 32, minWidth: 32, gap: 4 },
|
|
43
|
+
};
|
|
45
44
|
|
|
46
|
-
const
|
|
45
|
+
const TAG_SIZE_FONT: Record<TagSize, number> = { sm: 12, md: 14, lg: 14 };
|
|
47
46
|
|
|
48
47
|
export interface TagProps extends Omit<React.ComponentPropsWithRef<'span'>, 'size'> {
|
|
49
48
|
readonly variant?: TagVariant;
|
|
@@ -80,14 +79,39 @@ export const Tag = React.forwardRef<HTMLSpanElement, TagProps>(
|
|
|
80
79
|
...rest
|
|
81
80
|
} = props;
|
|
82
81
|
|
|
82
|
+
const resolvedVariant = variant ?? 'subtle';
|
|
83
|
+
const resolvedSize = size ?? 'md';
|
|
84
|
+
const isSelected = Boolean(selected) && !loading;
|
|
85
|
+
|
|
86
|
+
// `selected` overrides the variant's own colours; `disabled` only dims —
|
|
87
|
+
// neither is known until render, so resolve the final tokens here rather
|
|
88
|
+
// than lean on a class-merge order that no longer exists.
|
|
89
|
+
const backgroundColor = isSelected ? 'var(--color-tag-select-selected-bg)' : TAG_VARIANT[resolvedVariant].backgroundColor;
|
|
90
|
+
const color = isSelected ? 'var(--color-tag-select-selected-fg)' : TAG_VARIANT_FG[resolvedVariant];
|
|
91
|
+
const hoverStyle = isSelected ? { opacity: 0.76 } : TAG_VARIANT[resolvedVariant].hoverStyle;
|
|
92
|
+
// Unselected `select` rows preview the selected look on hover; once
|
|
93
|
+
// selected the hover colour equals the resting colour, i.e. no change.
|
|
94
|
+
const textHoverColor = !isSelected && resolvedVariant === 'select' ? 'var(--color-hover)' : undefined;
|
|
95
|
+
|
|
83
96
|
const labelElement = label ? (
|
|
84
|
-
<
|
|
97
|
+
<Text fontSize={ TAG_SIZE_FONT[resolvedSize] } fontWeight="500" color={ 'var(--color-text-secondary)' as never }>
|
|
98
|
+
{ label }:{ nbsp }
|
|
99
|
+
</Text>
|
|
85
100
|
) : null;
|
|
86
101
|
|
|
87
102
|
const labelSpan = (
|
|
88
|
-
|
|
103
|
+
// `ellipsis` is Text's own built-in single-line-truncation variant —
|
|
104
|
+
// the same rule Tailwind's `line-clamp-1`/`text-ellipsis` drew, through
|
|
105
|
+
// the component's variants rather than three separate style props.
|
|
106
|
+
<Text
|
|
107
|
+
ellipsis
|
|
108
|
+
fontWeight="500"
|
|
109
|
+
fontSize={ TAG_SIZE_FONT[resolvedSize] }
|
|
110
|
+
color={ color as never }
|
|
111
|
+
hoverStyle={ textHoverColor ? { color: textHoverColor as never } : undefined }
|
|
112
|
+
>
|
|
89
113
|
{ labelElement }{ children }
|
|
90
|
-
</
|
|
114
|
+
</Text>
|
|
91
115
|
);
|
|
92
116
|
|
|
93
117
|
const contentElement = truncated ? (
|
|
@@ -98,43 +122,57 @@ export const Tag = React.forwardRef<HTMLSpanElement, TagProps>(
|
|
|
98
122
|
|
|
99
123
|
return (
|
|
100
124
|
<Skeleton loading={ loading } asChild>
|
|
101
|
-
<
|
|
102
|
-
ref={ ref }
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
{
|
|
125
|
+
<XStack
|
|
126
|
+
ref={ ref as never }
|
|
127
|
+
render={ <span/> }
|
|
128
|
+
display="inline-flex"
|
|
129
|
+
alignItems="center"
|
|
130
|
+
verticalAlign="top"
|
|
131
|
+
maxWidth="100%"
|
|
132
|
+
userSelect="text"
|
|
133
|
+
{ ...TAG_SIZE[resolvedSize] }
|
|
134
|
+
backgroundColor={ backgroundColor as never }
|
|
135
|
+
hoverStyle={ hoverStyle }
|
|
136
|
+
focusVisibleStyle={{
|
|
137
|
+
outlineWidth: 2,
|
|
138
|
+
outlineOffset: 2,
|
|
139
|
+
outlineColor: 'var(--color-gray-500)' as never,
|
|
140
|
+
outlineStyle: 'solid',
|
|
141
|
+
}}
|
|
142
|
+
// One cursor, decided once: disabled outranks the variant's.
|
|
143
|
+
cursor={ disabled ? 'not-allowed' : TAG_VARIANT[resolvedVariant].cursor }
|
|
144
|
+
{ ...(disabled ? { opacity: 0.4, pointerEvents: 'none' } : {}) }
|
|
145
|
+
{ ...(isSelected && { 'data-selected': true }) }
|
|
112
146
|
{ ...(disabled && { 'data-disabled': true }) }
|
|
113
|
-
{
|
|
147
|
+
className={ className }
|
|
148
|
+
{ ...(rest as object) }
|
|
114
149
|
>
|
|
115
150
|
{ startElement && (
|
|
116
|
-
<
|
|
151
|
+
<XStack flexShrink={ 0 } alignItems="center" justifyContent="center">
|
|
117
152
|
{ startElement }
|
|
118
|
-
</
|
|
153
|
+
</XStack>
|
|
119
154
|
) }
|
|
120
155
|
{ contentElement }
|
|
121
|
-
{ endElement && (
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
156
|
+
{ endElement && (() => {
|
|
157
|
+
const { className: endClassName, ...endElementRest } = endElementProps ?? {};
|
|
158
|
+
return (
|
|
159
|
+
<XStack
|
|
160
|
+
{ ...(endElementRest as object) }
|
|
161
|
+
flexShrink={ 0 }
|
|
162
|
+
alignItems="center"
|
|
163
|
+
justifyContent="center"
|
|
164
|
+
className={ endClassName }
|
|
165
|
+
>
|
|
166
|
+
{ endElement }
|
|
167
|
+
</XStack>
|
|
168
|
+
);
|
|
169
|
+
})() }
|
|
132
170
|
{ closable && (
|
|
133
|
-
<
|
|
171
|
+
<XStack flexShrink={ 0 } alignItems="center" justifyContent="center">
|
|
134
172
|
<CloseButton onClick={ onClose }/>
|
|
135
|
-
</
|
|
173
|
+
</XStack>
|
|
136
174
|
) }
|
|
137
|
-
</
|
|
175
|
+
</XStack>
|
|
138
176
|
</Skeleton>
|
|
139
177
|
);
|
|
140
178
|
},
|
package/src/tooltip.tsx
CHANGED
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
import { useClickAway } from '@uidotdev/usehooks';
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
|
|
8
|
+
import { ink } from './ink';
|
|
8
9
|
import { useIsTouch } from './use-narrow';
|
|
9
|
-
import { cn } from './utils';
|
|
10
10
|
|
|
11
11
|
/** Map placement string to @hanzogui Popper placement prop. */
|
|
12
12
|
function mapPlacement(p: string | undefined): string | undefined {
|
|
@@ -161,14 +161,21 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
|
|
|
161
161
|
<GuiTooltip.Content
|
|
162
162
|
ref={ ref }
|
|
163
163
|
unstyled
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
164
|
+
zIndex={ 9999 }
|
|
165
|
+
overflow="hidden"
|
|
166
|
+
borderRadius={ 8 }
|
|
167
|
+
paddingHorizontal={ 12 }
|
|
168
|
+
paddingVertical={ 8 }
|
|
169
|
+
maxWidth={ isPopover ? 384 : 320 }
|
|
170
|
+
backgroundColor={ (isPopover ? 'var(--color-popover-bg)' : 'var(--color-tooltip-bg)') as never }
|
|
171
|
+
transition="quick"
|
|
172
|
+
enterStyle={{ opacity: 0, scale: 0.95 }}
|
|
173
|
+
exitStyle={{ opacity: 0, scale: 0.95 }}
|
|
174
|
+
{ ...(isPopover ? {
|
|
175
|
+
borderWidth: 1,
|
|
176
|
+
borderColor: 'var(--color-border-divider)' as never,
|
|
177
|
+
shadowColor: 'var(--shadow-popover)' as never,
|
|
178
|
+
} : {}) }
|
|
172
179
|
onClick={ interactive ? handleContentClick : undefined }
|
|
173
180
|
{ ...(selected ? { 'data-selected': true } : {}) }
|
|
174
181
|
{ ...contentProps as any }
|
|
@@ -176,12 +183,13 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
|
|
|
176
183
|
{ showArrow && (
|
|
177
184
|
<GuiTooltip.Arrow
|
|
178
185
|
unstyled
|
|
179
|
-
|
|
180
|
-
isPopover ? 'fill-[var(--color-popover-bg)]' : 'fill-[var(--color-tooltip-bg)]',
|
|
181
|
-
) }
|
|
186
|
+
backgroundColor={ (isPopover ? 'var(--color-popover-bg)' : 'var(--color-tooltip-bg)') as never }
|
|
182
187
|
/>
|
|
183
188
|
) }
|
|
184
|
-
{ content
|
|
189
|
+
{ ink(content, undefined, {
|
|
190
|
+
fontSize: 14,
|
|
191
|
+
color: (isPopover ? 'var(--color-text-primary)' : 'var(--color-tooltip-fg)') as never,
|
|
192
|
+
}) }
|
|
185
193
|
</GuiTooltip.Content>
|
|
186
194
|
</GuiTooltip>
|
|
187
195
|
</GuiTooltipGroup>
|
package/tokens.css
CHANGED
|
@@ -890,6 +890,15 @@
|
|
|
890
890
|
they do not loop. The spinner rotates forever, so it is CSS. */
|
|
891
891
|
.lux-spin { animation: lux-spin 0.8s linear infinite }
|
|
892
892
|
|
|
893
|
+
/* A scrolling strip with no visible scrollbar. The scrollbar is a
|
|
894
|
+
pseudo-element on the box, so this is the only place it can be said. */
|
|
895
|
+
/* One-line truncation. `text-overflow` and `white-space` are not in gui's Text
|
|
896
|
+
style base, and the three declarations only mean anything together. */
|
|
897
|
+
.lux-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
898
|
+
|
|
899
|
+
.lux-no-scrollbar { scrollbar-width: none; -ms-overflow-style: none }
|
|
900
|
+
.lux-no-scrollbar::-webkit-scrollbar { display: none }
|
|
901
|
+
|
|
893
902
|
/* Size the ICON inside a control. A descendant selector has no prop form, so
|
|
894
903
|
the control publishes its icon size and this rule applies it. */
|
|
895
904
|
.lux-icon svg { width: var(--icon-size, 20px); height: var(--icon-size, 20px) }
|
|
@@ -943,6 +952,15 @@
|
|
|
943
952
|
user-select: none;
|
|
944
953
|
}
|
|
945
954
|
|
|
955
|
+
/* A skeleton wrapping real content (asChild, or loading with children already
|
|
956
|
+
mounted) must mask it — an <img> or an icon doesn't pick up `color:
|
|
957
|
+
transparent` above. `visibility` rather than `display:none` so the masked
|
|
958
|
+
subtree keeps its layout instead of collapsing it, which is the zero-CLS
|
|
959
|
+
promise this component makes. A descendant selector has no prop form. */
|
|
960
|
+
.lux-skeleton * {
|
|
961
|
+
visibility: hidden;
|
|
962
|
+
}
|
|
963
|
+
|
|
946
964
|
/* The one moving part. Fixed, 2px, above everything, out of flow — so it
|
|
947
965
|
cannot shift layout and cannot tint content. Mount it while any request
|
|
948
966
|
is in flight; unmount it when they land. One per page. */
|