@adea-ai/ui 0.89.2 → 0.93.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.
- package/README.md +22 -5
- package/dist/NOTICE +19 -0
- package/dist/components/composites/list-row/index.d.ts +1 -0
- package/dist/components/composites/list-row/index.d.ts.map +1 -1
- package/dist/components/composites/list-row/index.js +2 -1
- package/dist/components/composites/list-row/list-row-control.d.ts +20 -0
- package/dist/components/composites/list-row/list-row-control.d.ts.map +1 -0
- package/dist/components/composites/list-row/list-row-control.js +96 -0
- package/dist/components/composites/list-row/list-row-control.js.map +1 -0
- package/dist/components/composites/list-row/list-row.d.ts +15 -35
- package/dist/components/composites/list-row/list-row.d.ts.map +1 -1
- package/dist/components/composites/list-row/list-row.js +88 -135
- package/dist/components/composites/list-row/list-row.js.map +1 -1
- package/dist/components/composites/tree/index.d.ts +4 -0
- package/dist/components/composites/tree/index.d.ts.map +1 -0
- package/dist/components/composites/tree/index.js +2 -0
- package/dist/components/composites/tree/tree-navigation.d.ts +46 -0
- package/dist/components/composites/tree/tree-navigation.d.ts.map +1 -0
- package/dist/components/composites/tree/tree-navigation.js +95 -0
- package/dist/components/composites/tree/tree-navigation.js.map +1 -0
- package/dist/components/composites/tree/tree.d.ts +64 -0
- package/dist/components/composites/tree/tree.d.ts.map +1 -0
- package/dist/components/composites/tree/tree.js +311 -0
- package/dist/components/composites/tree/tree.js.map +1 -0
- package/dist/components/conversation/message-composer.d.ts +18 -3
- package/dist/components/conversation/message-composer.d.ts.map +1 -1
- package/dist/components/conversation/message-composer.js +93 -27
- package/dist/components/conversation/message-composer.js.map +1 -1
- package/dist/components/layout/sidebar-nav/index.d.ts +1 -1
- package/dist/components/layout/sidebar-nav/index.d.ts.map +1 -1
- package/dist/components/layout/sidebar-nav/index.js +2 -2
- package/dist/components/layout/sidebar-nav/sidebar-nav.d.ts +19 -1
- package/dist/components/layout/sidebar-nav/sidebar-nav.d.ts.map +1 -1
- package/dist/components/layout/sidebar-nav/sidebar-nav.js +83 -17
- package/dist/components/layout/sidebar-nav/sidebar-nav.js.map +1 -1
- package/dist/components/layout/top-bar/top-bar.d.ts +6 -5
- package/dist/components/layout/top-bar/top-bar.d.ts.map +1 -1
- package/dist/components/layout/top-bar/top-bar.js +30 -7
- package/dist/components/layout/top-bar/top-bar.js.map +1 -1
- package/dist/components/ui/dialog/dialog.d.ts +2 -0
- package/dist/components/ui/dialog/dialog.d.ts.map +1 -1
- package/dist/components/ui/dialog/dialog.js +4 -3
- package/dist/components/ui/dialog/dialog.js.map +1 -1
- package/dist/components/ui/modal-dialog/modal-dialog.d.ts +5 -2
- package/dist/components/ui/modal-dialog/modal-dialog.d.ts.map +1 -1
- package/dist/components/ui/modal-dialog/modal-dialog.js +33 -24
- package/dist/components/ui/modal-dialog/modal-dialog.js.map +1 -1
- package/dist/components/ui/textarea/index.d.ts +1 -1
- package/dist/components/ui/textarea/index.d.ts.map +1 -1
- package/dist/components/ui/textarea/index.js +2 -2
- package/dist/components/ui/textarea/textarea.d.ts +15 -2
- package/dist/components/ui/textarea/textarea.d.ts.map +1 -1
- package/dist/components/ui/textarea/textarea.js +47 -3
- package/dist/components/ui/textarea/textarea.js.map +1 -1
- package/dist/components/ui/tooltip/tooltip.d.ts.map +1 -1
- package/dist/components/ui/tooltip/tooltip.js +239 -17
- package/dist/components/ui/tooltip/tooltip.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/lib/variants.js +2 -2
- package/dist/r/conversation.json +1 -0
- package/dist/r/list-row.json +5 -0
- package/dist/r/registry.json +41 -2
- package/dist/r/src/components/composites/list-row/index.ts +1 -0
- package/dist/r/src/components/composites/list-row/list-row-control.tsx +108 -0
- package/dist/r/src/components/composites/list-row/list-row.tsx +60 -127
- package/dist/r/src/components/composites/tree/index.ts +3 -0
- package/dist/r/src/components/composites/tree/tree-navigation.ts +114 -0
- package/dist/r/src/components/composites/tree/tree.tsx +405 -0
- package/dist/r/src/components/conversation/message-composer.tsx +103 -22
- package/dist/r/src/components/layout/sidebar-nav/index.ts +3 -0
- package/dist/r/src/components/layout/sidebar-nav/sidebar-nav.tsx +75 -6
- package/dist/r/src/components/layout/top-bar/top-bar.tsx +34 -11
- package/dist/r/src/components/ui/dialog/dialog.tsx +4 -2
- package/dist/r/src/components/ui/modal-dialog/modal-dialog.tsx +20 -4
- package/dist/r/src/components/ui/textarea/index.ts +1 -1
- package/dist/r/src/components/ui/textarea/textarea.tsx +52 -10
- package/dist/r/src/components/ui/tooltip/tooltip.tsx +305 -10
- package/dist/r/src/styles/base.css +39 -0
- package/dist/r/textarea.json +3 -1
- package/dist/r/top-bar.json +3 -1
- package/dist/r/tree.json +29 -0
- package/package.json +4 -1
- package/registry.json +41 -2
- package/src/components/composites/list-row/index.ts +1 -0
- package/src/components/composites/list-row/list-row-control.tsx +108 -0
- package/src/components/composites/list-row/list-row.tsx +60 -127
- package/src/components/composites/tree/index.ts +3 -0
- package/src/components/composites/tree/tree-navigation.ts +114 -0
- package/src/components/composites/tree/tree.tsx +405 -0
- package/src/components/conversation/message-composer.tsx +103 -22
- package/src/components/layout/sidebar-nav/index.ts +3 -0
- package/src/components/layout/sidebar-nav/sidebar-nav.tsx +75 -6
- package/src/components/layout/top-bar/top-bar.tsx +34 -11
- package/src/components/ui/dialog/dialog.tsx +4 -2
- package/src/components/ui/modal-dialog/modal-dialog.tsx +20 -4
- package/src/components/ui/textarea/index.ts +1 -1
- package/src/components/ui/textarea/textarea.tsx +52 -10
- package/src/components/ui/tooltip/tooltip.tsx +305 -10
- package/src/index.ts +1 -0
- package/src/styles/base.css +39 -0
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
import { Tooltip as KobalteTooltip } from '@kobalte/core/tooltip'
|
|
1
|
+
import { Tooltip as KobalteTooltip, useTooltipContext } from '@kobalte/core/tooltip'
|
|
2
2
|
import type { ComponentProps } from 'solid-js'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
createContext,
|
|
5
|
+
createEffect,
|
|
6
|
+
createSignal,
|
|
7
|
+
createUniqueId,
|
|
8
|
+
onCleanup,
|
|
9
|
+
splitProps,
|
|
10
|
+
useContext,
|
|
11
|
+
} from 'solid-js'
|
|
12
|
+
import { isServer } from 'solid-js/web'
|
|
4
13
|
import { cn } from '#lib/utils'
|
|
5
14
|
|
|
6
15
|
/**
|
|
@@ -33,6 +42,99 @@ const tooltipDefaults: TooltipTiming = {
|
|
|
33
42
|
|
|
34
43
|
const TooltipTimingContext = createContext<TooltipTiming>(tooltipDefaults)
|
|
35
44
|
|
|
45
|
+
type TooltipInteraction = {
|
|
46
|
+
id: string
|
|
47
|
+
trigger: () => HTMLElement | undefined
|
|
48
|
+
setTrigger: (element: HTMLElement) => void
|
|
49
|
+
isOpen: () => boolean
|
|
50
|
+
isDisabled: () => boolean
|
|
51
|
+
isTriggerFocused: () => boolean
|
|
52
|
+
markOpenIntent: () => void
|
|
53
|
+
clearOpenIntent: () => void
|
|
54
|
+
requestCloseFromAnotherTooltip: () => void
|
|
55
|
+
markPointerCloseIntent: () => void
|
|
56
|
+
clearPointerCloseIntent: () => void
|
|
57
|
+
markCloseIntent: () => void
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const TooltipInteractionContext = createContext<TooltipInteraction>()
|
|
61
|
+
const openTooltipInteractions = new Set<TooltipInteraction>()
|
|
62
|
+
let pendingTooltipOpenId: string | undefined
|
|
63
|
+
let tooltipScrollListenerAttached = false
|
|
64
|
+
|
|
65
|
+
function clearPendingTooltipOpen(id: string) {
|
|
66
|
+
if (pendingTooltipOpenId === id) pendingTooltipOpenId = undefined
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function tooltipScrollContainsTrigger(event: Event, trigger: HTMLElement) {
|
|
70
|
+
const target = event.target
|
|
71
|
+
return target === window || (target instanceof Node && target.contains(trigger))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function handleTooltipScroll(event: Event) {
|
|
75
|
+
for (const interaction of openTooltipInteractions) {
|
|
76
|
+
const trigger = interaction.trigger()
|
|
77
|
+
if (interaction.isOpen() && trigger && tooltipScrollContainsTrigger(event, trigger)) {
|
|
78
|
+
interaction.markCloseIntent()
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function handleTooltipPointerMove(event: PointerEvent) {
|
|
84
|
+
for (const interaction of openTooltipInteractions) {
|
|
85
|
+
const trigger = interaction.trigger()
|
|
86
|
+
const target = event.target
|
|
87
|
+
if (
|
|
88
|
+
interaction.isOpen() &&
|
|
89
|
+
interaction.isTriggerFocused() &&
|
|
90
|
+
trigger &&
|
|
91
|
+
!(target instanceof Node && trigger.contains(target))
|
|
92
|
+
) {
|
|
93
|
+
interaction.markPointerCloseIntent()
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function setTooltipInteractionOpen(interaction: TooltipInteraction, open: boolean) {
|
|
99
|
+
if (isServer) return
|
|
100
|
+
|
|
101
|
+
if (open) {
|
|
102
|
+
if (openTooltipInteractions.has(interaction)) return
|
|
103
|
+
openTooltipInteractions.add(interaction)
|
|
104
|
+
if (!tooltipScrollListenerAttached) {
|
|
105
|
+
tooltipScrollListenerAttached = true
|
|
106
|
+
// Register before Kobalte's global listeners so intentional scroll
|
|
107
|
+
// dismissal can be distinguished from its delayed pointer dismissal.
|
|
108
|
+
window.addEventListener('scroll', handleTooltipScroll, true)
|
|
109
|
+
document.addEventListener('pointermove', handleTooltipPointerMove, true)
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
openTooltipInteractions.delete(interaction)
|
|
113
|
+
if (openTooltipInteractions.size === 0 && tooltipScrollListenerAttached) {
|
|
114
|
+
tooltipScrollListenerAttached = false
|
|
115
|
+
window.removeEventListener('scroll', handleTooltipScroll, true)
|
|
116
|
+
document.removeEventListener('pointermove', handleTooltipPointerMove, true)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function registerTooltipInteraction(interaction: TooltipInteraction) {
|
|
122
|
+
onCleanup(() => {
|
|
123
|
+
setTooltipInteractionOpen(interaction, false)
|
|
124
|
+
clearPendingTooltipOpen(interaction.id)
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function invokeEventHandler(handler: unknown, event: Event) {
|
|
129
|
+
if (Array.isArray(handler)) {
|
|
130
|
+
const [callback, data] = handler as [(data: unknown, event: Event) => void, unknown]
|
|
131
|
+
callback(data, event)
|
|
132
|
+
} else if (typeof handler === 'function') {
|
|
133
|
+
const callback = handler as (event: Event) => void
|
|
134
|
+
callback(event)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
36
138
|
export type TooltipProviderProps = {
|
|
37
139
|
children?: ComponentProps<'div'>['children']
|
|
38
140
|
openDelay?: number
|
|
@@ -58,19 +160,192 @@ export type TooltipRootProps = ComponentProps<typeof KobalteTooltip>
|
|
|
58
160
|
|
|
59
161
|
export function Tooltip(props: TooltipRootProps) {
|
|
60
162
|
const timing = useContext(TooltipTimingContext)
|
|
163
|
+
const [local, rest] = splitProps(props, ['open', 'defaultOpen', 'onOpenChange', 'disabled'])
|
|
164
|
+
const id = createUniqueId()
|
|
165
|
+
const controlled = () => local.open !== undefined
|
|
166
|
+
const [uncontrolledOpen, setUncontrolledOpen] = createSignal(local.defaultOpen ?? false)
|
|
167
|
+
const isOpen = () => (controlled() ? (local.open ?? false) : uncontrolledOpen())
|
|
168
|
+
const [trigger, setTrigger] = createSignal<HTMLElement>()
|
|
169
|
+
let closeIntent = false
|
|
170
|
+
let ignoreDuplicateClose = false
|
|
171
|
+
let onOpenChange: (next: boolean, source?: 'handoff') => void
|
|
172
|
+
let pointerCloseIntentUntil = 0
|
|
173
|
+
let pointerCloseIntentTimeout: ReturnType<typeof setTimeout> | undefined
|
|
174
|
+
const clearPointerCloseIntent = () => {
|
|
175
|
+
pointerCloseIntentUntil = 0
|
|
176
|
+
if (pointerCloseIntentTimeout) clearTimeout(pointerCloseIntentTimeout)
|
|
177
|
+
pointerCloseIntentTimeout = undefined
|
|
178
|
+
}
|
|
179
|
+
const markPointerCloseIntent = () => {
|
|
180
|
+
if (!isOpen()) return
|
|
181
|
+
clearPointerCloseIntent()
|
|
182
|
+
const closeDelay = props.closeDelay ?? timing.closeDelay
|
|
183
|
+
pointerCloseIntentUntil = Date.now() + closeDelay + 50
|
|
184
|
+
pointerCloseIntentTimeout = setTimeout(clearPointerCloseIntent, closeDelay + 50)
|
|
185
|
+
}
|
|
186
|
+
const markCloseIntent = () => {
|
|
187
|
+
closeIntent = true
|
|
188
|
+
clearPointerCloseIntent()
|
|
189
|
+
queueMicrotask(() => {
|
|
190
|
+
closeIntent = false
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
const requestCloseFromAnotherTooltip = () => {
|
|
194
|
+
if (!isOpen()) return
|
|
195
|
+
|
|
196
|
+
// Another trigger is an explicit handoff, even when a focused tooltip has
|
|
197
|
+
// a pending pointer-close intent that would otherwise suppress Kobalte's
|
|
198
|
+
// close callback. Route the request through the same controlled/uncontrolled
|
|
199
|
+
// state contract as Kobalte and ignore its duplicate callback for this turn.
|
|
200
|
+
ignoreDuplicateClose = true
|
|
201
|
+
queueMicrotask(() => {
|
|
202
|
+
ignoreDuplicateClose = false
|
|
203
|
+
})
|
|
204
|
+
onOpenChange(false, 'handoff')
|
|
205
|
+
}
|
|
206
|
+
const interaction: TooltipInteraction = {
|
|
207
|
+
id,
|
|
208
|
+
trigger,
|
|
209
|
+
setTrigger,
|
|
210
|
+
isOpen,
|
|
211
|
+
isDisabled: () => local.disabled ?? false,
|
|
212
|
+
isTriggerFocused: () =>
|
|
213
|
+
Boolean(trigger() && typeof document !== 'undefined' && trigger() === document.activeElement),
|
|
214
|
+
markOpenIntent: () => {
|
|
215
|
+
clearPointerCloseIntent()
|
|
216
|
+
pendingTooltipOpenId = id
|
|
217
|
+
// A focused tooltip ignores ordinary pointer movement, but entering or
|
|
218
|
+
// focusing another tooltip is an explicit transfer.
|
|
219
|
+
for (const openInteraction of openTooltipInteractions) {
|
|
220
|
+
if (openInteraction.id !== id) openInteraction.requestCloseFromAnotherTooltip()
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
clearOpenIntent: () => clearPendingTooltipOpen(id),
|
|
224
|
+
requestCloseFromAnotherTooltip,
|
|
225
|
+
markPointerCloseIntent,
|
|
226
|
+
clearPointerCloseIntent,
|
|
227
|
+
markCloseIntent,
|
|
228
|
+
}
|
|
229
|
+
registerTooltipInteraction(interaction)
|
|
230
|
+
onCleanup(() => {
|
|
231
|
+
clearPointerCloseIntent()
|
|
232
|
+
ignoreDuplicateClose = false
|
|
233
|
+
})
|
|
234
|
+
if (isOpen()) setTooltipInteractionOpen(interaction, true)
|
|
235
|
+
createEffect(() => setTooltipInteractionOpen(interaction, isOpen()))
|
|
236
|
+
onOpenChange = (next: boolean, source) => {
|
|
237
|
+
if (!next && source !== 'handoff' && ignoreDuplicateClose) return
|
|
238
|
+
|
|
239
|
+
if (next) {
|
|
240
|
+
clearPendingTooltipOpen(id)
|
|
241
|
+
clearPointerCloseIntent()
|
|
242
|
+
// Install this capture listener before Kobalte's open-state effect adds
|
|
243
|
+
// its scroll listener later in the same update.
|
|
244
|
+
setTooltipInteractionOpen(interaction, true)
|
|
245
|
+
} else {
|
|
246
|
+
const focusedTrigger = interaction.isTriggerFocused()
|
|
247
|
+
const anotherTooltipOpening =
|
|
248
|
+
pendingTooltipOpenId !== undefined && pendingTooltipOpenId !== id
|
|
249
|
+
const pointerClosePending = Date.now() <= pointerCloseIntentUntil
|
|
250
|
+
if (
|
|
251
|
+
source !== 'handoff' &&
|
|
252
|
+
focusedTrigger &&
|
|
253
|
+
pointerClosePending &&
|
|
254
|
+
!closeIntent &&
|
|
255
|
+
!anotherTooltipOpening
|
|
256
|
+
) {
|
|
257
|
+
clearPointerCloseIntent()
|
|
258
|
+
return
|
|
259
|
+
}
|
|
260
|
+
closeIntent = false
|
|
261
|
+
clearPointerCloseIntent()
|
|
262
|
+
clearPendingTooltipOpen(id)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (!controlled()) setUncontrolledOpen(next)
|
|
266
|
+
local.onOpenChange?.(next)
|
|
267
|
+
if (next) {
|
|
268
|
+
// A controlled parent can reject the open request without changing its
|
|
269
|
+
// signal, so the effect above would not rerun to release this listener.
|
|
270
|
+
queueMicrotask(() => {
|
|
271
|
+
if (!isOpen()) setTooltipInteractionOpen(interaction, false)
|
|
272
|
+
})
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Kobalte dismisses on Escape only when its content owns the top-most
|
|
277
|
+
// layer, and a handoff keeps the previous tooltip's content mounted while
|
|
278
|
+
// it exits — swallowing the key for the tooltip that just took over.
|
|
279
|
+
// Listening on document (capture) closes this tooltip first; the layer's
|
|
280
|
+
// own handler still runs for anything stacked above it.
|
|
281
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
282
|
+
if (event.key !== 'Escape') return
|
|
283
|
+
markCloseIntent()
|
|
284
|
+
onOpenChange(false)
|
|
285
|
+
}
|
|
286
|
+
createEffect(() => {
|
|
287
|
+
if (isServer || !isOpen()) return
|
|
288
|
+
document.addEventListener('keydown', handleKeyDown, true)
|
|
289
|
+
onCleanup(() => document.removeEventListener('keydown', handleKeyDown, true))
|
|
290
|
+
})
|
|
61
291
|
|
|
62
292
|
return (
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
293
|
+
<TooltipInteractionContext.Provider value={interaction}>
|
|
294
|
+
<KobalteTooltip
|
|
295
|
+
open={isOpen()}
|
|
296
|
+
onOpenChange={onOpenChange}
|
|
297
|
+
disabled={local.disabled}
|
|
298
|
+
openDelay={props.openDelay ?? timing.openDelay}
|
|
299
|
+
closeDelay={props.closeDelay ?? timing.closeDelay}
|
|
300
|
+
skipDelayDuration={props.skipDelayDuration ?? timing.skipDelayDuration}
|
|
301
|
+
{...rest}
|
|
302
|
+
/>
|
|
303
|
+
</TooltipInteractionContext.Provider>
|
|
69
304
|
)
|
|
70
305
|
}
|
|
71
306
|
|
|
72
307
|
export function TooltipTrigger(props: ComponentProps<typeof KobalteTooltip.Trigger>) {
|
|
73
|
-
|
|
308
|
+
const interaction = useContext(TooltipInteractionContext)
|
|
309
|
+
const [local, rest] = splitProps(props, [
|
|
310
|
+
'ref',
|
|
311
|
+
'onFocus',
|
|
312
|
+
'onBlur',
|
|
313
|
+
'onPointerEnter',
|
|
314
|
+
'onPointerLeave',
|
|
315
|
+
'onClick',
|
|
316
|
+
])
|
|
317
|
+
|
|
318
|
+
return (
|
|
319
|
+
<KobalteTooltip.Trigger
|
|
320
|
+
{...rest}
|
|
321
|
+
ref={(element) => {
|
|
322
|
+
interaction?.setTrigger(element)
|
|
323
|
+
if (typeof local.ref === 'function') local.ref(element)
|
|
324
|
+
}}
|
|
325
|
+
onFocus={(event) => {
|
|
326
|
+
invokeEventHandler(local.onFocus, event)
|
|
327
|
+
if (!event.defaultPrevented && !interaction?.isDisabled()) interaction?.markOpenIntent()
|
|
328
|
+
}}
|
|
329
|
+
onBlur={(event) => {
|
|
330
|
+
invokeEventHandler(local.onBlur, event)
|
|
331
|
+
interaction?.clearOpenIntent()
|
|
332
|
+
interaction?.markCloseIntent()
|
|
333
|
+
}}
|
|
334
|
+
onPointerEnter={(event) => {
|
|
335
|
+
invokeEventHandler(local.onPointerEnter, event)
|
|
336
|
+
if (!event.defaultPrevented && !interaction?.isDisabled()) interaction?.markOpenIntent()
|
|
337
|
+
}}
|
|
338
|
+
onPointerLeave={(event) => {
|
|
339
|
+
invokeEventHandler(local.onPointerLeave, event)
|
|
340
|
+
interaction?.clearOpenIntent()
|
|
341
|
+
interaction?.markPointerCloseIntent()
|
|
342
|
+
}}
|
|
343
|
+
onClick={(event) => {
|
|
344
|
+
invokeEventHandler(local.onClick, event)
|
|
345
|
+
interaction?.markCloseIntent()
|
|
346
|
+
}}
|
|
347
|
+
/>
|
|
348
|
+
)
|
|
74
349
|
}
|
|
75
350
|
|
|
76
351
|
export type TooltipContentProps = ComponentProps<typeof KobalteTooltip.Content> & {
|
|
@@ -79,8 +354,19 @@ export type TooltipContentProps = ComponentProps<typeof KobalteTooltip.Content>
|
|
|
79
354
|
}
|
|
80
355
|
|
|
81
356
|
export function TooltipContent(props: TooltipContentProps) {
|
|
82
|
-
const
|
|
357
|
+
const interaction = useContext(TooltipInteractionContext)
|
|
358
|
+
const [local, rest] = splitProps(props, [
|
|
359
|
+
'class',
|
|
360
|
+
'hideArrow',
|
|
361
|
+
'children',
|
|
362
|
+
'aria-hidden',
|
|
363
|
+
'onEscapeKeyDown',
|
|
364
|
+
'onPointerDownOutside',
|
|
365
|
+
])
|
|
366
|
+
const context = useTooltipContext()
|
|
83
367
|
|
|
368
|
+
// Kobalte keeps force-mounted and exiting content present after close. Hide
|
|
369
|
+
// that retained tooltip from assistive technology until it opens again.
|
|
84
370
|
return (
|
|
85
371
|
<KobalteTooltip.Portal>
|
|
86
372
|
<KobalteTooltip.Content
|
|
@@ -92,6 +378,15 @@ export function TooltipContent(props: TooltipContentProps) {
|
|
|
92
378
|
'data-expanded:duration-150 data-closed:duration-100',
|
|
93
379
|
local.class
|
|
94
380
|
)}
|
|
381
|
+
aria-hidden={context.isOpen() ? local['aria-hidden'] : true}
|
|
382
|
+
onEscapeKeyDown={(event) => {
|
|
383
|
+
invokeEventHandler(local.onEscapeKeyDown, event)
|
|
384
|
+
if (!event.defaultPrevented) interaction?.markCloseIntent()
|
|
385
|
+
}}
|
|
386
|
+
onPointerDownOutside={(event) => {
|
|
387
|
+
invokeEventHandler(local.onPointerDownOutside, event)
|
|
388
|
+
if (!event.defaultPrevented) interaction?.markCloseIntent()
|
|
389
|
+
}}
|
|
95
390
|
{...rest}
|
|
96
391
|
>
|
|
97
392
|
{local.children}
|
package/src/index.ts
CHANGED
|
@@ -102,6 +102,7 @@ export * from './components/composites/account-menu'
|
|
|
102
102
|
export * from './components/composites/action-button'
|
|
103
103
|
export * from './components/composites/catalog-browser'
|
|
104
104
|
export * from './components/composites/list-row'
|
|
105
|
+
export * from './components/composites/tree'
|
|
105
106
|
export * from './components/composites/settings'
|
|
106
107
|
export * from './components/composites/stat'
|
|
107
108
|
export * from './components/composites/appearance-editor'
|
package/src/styles/base.css
CHANGED
|
@@ -92,6 +92,45 @@
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
/* Emitted only when ListRowControl is used. A described row changes its own
|
|
96
|
+
height and stacks trailing actions when its available width gets tight. */
|
|
97
|
+
@utility list-row-description {
|
|
98
|
+
&[data-description] {
|
|
99
|
+
align-items: flex-start;
|
|
100
|
+
container: list-row / inline-size;
|
|
101
|
+
flex-wrap: wrap;
|
|
102
|
+
min-height: var(--row-height-lg);
|
|
103
|
+
padding-block: calc(var(--spacing) * 1.5);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
&[data-description] [data-slot='list-row-content'] {
|
|
107
|
+
flex: 1 1 14rem;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@container list-row (width < 28rem) {
|
|
111
|
+
&[data-description] [data-slot='list-row-content'] {
|
|
112
|
+
align-items: stretch;
|
|
113
|
+
flex-direction: column;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
&[data-description] [data-slot='list-row-label'],
|
|
117
|
+
&[data-description] [data-slot='list-row-trailing'] {
|
|
118
|
+
flex: none;
|
|
119
|
+
width: 100%;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
&[data-description] [data-slot='list-row-trailing'] {
|
|
123
|
+
flex-wrap: wrap;
|
|
124
|
+
justify-content: flex-end;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
&[data-description] [data-slot='list-row-trailing'] button {
|
|
128
|
+
max-width: 100%;
|
|
129
|
+
white-space: normal;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
95
134
|
@custom-variant data-horizontal {
|
|
96
135
|
&:where([data-orientation='horizontal']) {
|
|
97
136
|
@slot;
|