⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 12 additions & 20 deletions apps/www/src/components/playground/tooltip-examples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,21 @@ export function TooltipExamples() {
return (
<PlaygroundLayout title='Tooltip'>
<Flex gap='medium' align='center' wrap='wrap'>
<Tooltip message='Top tooltip' side='top'>
<Button>Top</Button>
<Tooltip>
<Tooltip.Trigger render={<Button />}>Top</Tooltip.Trigger>
<Tooltip.Content side='top'>Top tooltip</Tooltip.Content>
</Tooltip>
<Tooltip message='Right tooltip' side='right'>
<Button>Right</Button>
<Tooltip>
<Tooltip.Trigger render={<Button />}>Right</Tooltip.Trigger>
<Tooltip.Content side='right'>Right tooltip</Tooltip.Content>
</Tooltip>
<Tooltip message='Bottom tooltip' side='bottom'>
<Button>Bottom</Button>
<Tooltip>
<Tooltip.Trigger render={<Button />}>Bottom</Tooltip.Trigger>
<Tooltip.Content side='bottom'>Bottom tooltip</Tooltip.Content>
</Tooltip>
<Tooltip message='Left tooltip' side='left'>
<Button>Left</Button>
</Tooltip>
<Tooltip message='Top Left tooltip' side='top-left'>
<Button>Top Left</Button>
</Tooltip>
<Tooltip message='Top Right tooltip' side='top-right'>
<Button>Top Right</Button>
</Tooltip>
<Tooltip message='Bottom Left tooltip' side='bottom-left'>
<Button>Bottom Left</Button>
</Tooltip>
<Tooltip message='Bottom Right tooltip' side='bottom-right'>
<Button>Bottom Right</Button>
<Tooltip>
<Tooltip.Trigger render={<Button />}>Left</Tooltip.Trigger>
<Tooltip.Content side='left'>Left tooltip</Tooltip.Content>
</Tooltip>
</Flex>
</PlaygroundLayout>
Expand Down
190 changes: 104 additions & 86 deletions apps/www/src/content/docs/components/tooltip/demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,52 @@
import { getPropsString } from '@/lib/utils';

export const getCode = (props: any) => {
const { children = 'Tooltip message', trackCursorAxis, ...rest } = props;
return `
<Tooltip${getPropsString(props)}>
<Button>Hover me</Button>
<Tooltip ${trackCursorAxis ? `trackCursorAxis="${trackCursorAxis}"` : ''}>
<Tooltip.Trigger render={<Button />}>
Hover me
</Tooltip.Trigger>
<Tooltip.Content ${getPropsString(rest)}>
${children}
</Tooltip.Content>
</Tooltip>`;
};

export const playground = {
type: 'playground',
controls: {
message: {
children: {
type: 'text',
initialValue: 'Tooltip message'
},
side: {
type: 'select',
options: [
'top',
'right',
'bottom',
'left',
'top-left',
'top-right',
'bottom-left',
'bottom-right'
],
options: ['top', 'right', 'bottom', 'left'],
defaultValue: 'top'
},
disabled: {
type: 'checkbox',
defaultValue: false
align: {
type: 'select',
options: ['start', 'center', 'end'],
defaultValue: 'center'
},
delayDuration: {
sideOffset: {
type: 'number',
defaultValue: 200,
min: 0
defaultValue: 4
},
skipDelayDuration: {
alignOffset: {
type: 'number',
defaultValue: 200,
min: 0
defaultValue: 0
},
followCursor: {
showArrow: {
type: 'checkbox',
initialValue: false,
defaultValue: false
},
trackCursorAxis: {
type: 'select',
options: ['none', 'x', 'y', 'both'],
defaultValue: 'none'
}
},
getCode
Expand All @@ -56,92 +58,108 @@ export const sideDemo = {
type: 'code',
code: `
<Flex gap="medium" align="center">
<Tooltip message="Top tooltip" side="top">
<Button>Top</Button>
</Tooltip>
<Tooltip message="Right tooltip" side="right">
<Button>Right</Button>
<Tooltip>
<Tooltip.Trigger render={<Button />}>Top</Tooltip.Trigger>
<Tooltip.Content side="top">Top tooltip</Tooltip.Content>
</Tooltip>
<Tooltip message="Bottom tooltip" side="bottom">
<Button>Bottom</Button>
<Tooltip>
<Tooltip.Trigger render={<Button />}>Right</Tooltip.Trigger>
<Tooltip.Content side="right">Right tooltip</Tooltip.Content>
</Tooltip>
<Tooltip message="Left tooltip" side="left">
<Button>Left</Button>
<Tooltip>
<Tooltip.Trigger render={<Button />}>Bottom</Tooltip.Trigger>
<Tooltip.Content side="bottom">Bottom tooltip</Tooltip.Content>
</Tooltip>
<Tooltip message="Top Left tooltip" side="top-left">
<Button>Top Left</Button>
<Tooltip>
<Tooltip.Trigger render={<Button />}>Left</Tooltip.Trigger>
<Tooltip.Content side="left">Left tooltip</Tooltip.Content>
</Tooltip>
<Tooltip message="Top Right tooltip" side="top-right">
<Button>Top Right</Button>
</Flex>`
};
export const alignDemo = {
type: 'code',
code: `
<Flex gap="large" align="center">
<Tooltip>
<Tooltip.Trigger render={<Button />}>Start</Tooltip.Trigger>
<Tooltip.Content align="start">Start tooltip</Tooltip.Content>
</Tooltip>
<Tooltip message="Bottom Left tooltip" side="bottom-left">
<Button>Bottom Left</Button>
<Tooltip>
<Tooltip.Trigger render={<Button />}>Center</Tooltip.Trigger>
<Tooltip.Content align="center">Center tooltip</Tooltip.Content>
</Tooltip>
<Tooltip message="Bottom Right tooltip" side="bottom-right">
<Button>Bottom Right</Button>
<Tooltip>
<Tooltip.Trigger render={<Button />}>End</Tooltip.Trigger>
<Tooltip.Content align="end">End tooltip</Tooltip.Content>
</Tooltip>
</Flex>`
};
export const followCursorDemo = {

export const customDemo = {
type: 'code',
code: `
<Tooltip message="Tooltip message" followCursor>
<Button>Hover me</Button>
</Tooltip>
`
<Tooltip>
<Tooltip.Trigger render={<Button />}>Hover me</Tooltip.Trigger>
<Tooltip.Content>
<div>
<span style={{ fontWeight: "medium" }}>Custom Tooltip</span>
</div>
Comment on lines +104 to +106
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Invalid CSS fontWeight value.

"medium" is not a valid CSS font-weight value. Valid values are numeric (100-900) or keywords like "normal" (400), "bold" (700). This will be ignored by the browser.

🐛 Proposed fix
-        <span style={{ fontWeight: "medium" }}>Custom Tooltip</span>
+        <span style={{ fontWeight: 500 }}>Custom Tooltip</span>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div>
<span style={{ fontWeight: "medium" }}>Custom Tooltip</span>
</div>
<div>
<span style={{ fontWeight: 500 }}>Custom Tooltip</span>
</div>
🤖 Prompt for AI Agents
In `@apps/www/src/content/docs/components/tooltip/demo.ts` around lines 104 - 106,
The inline style on the span in the Tooltip demo uses an invalid fontWeight
value ("medium"); locate the <span style={{ fontWeight: "medium" }}>Custom
Tooltip</span> in apps/www/src/content/docs/components/tooltip/demo.ts and
replace "medium" with a valid CSS font-weight such as "500" or the keyword
"normal"/"bold" (e.g., fontWeight: 500 or fontWeight: "normal") so the browser
applies the weight correctly.

</Tooltip.Content>
</Tooltip>`
};
export const customDemo = {

export const providerDemo = {
type: 'code',
code: `
<Tooltip message={
<div>
<span style={{ fontWeight: "medium" }}>Custom Tooltip</span>
</div>
}>
<Button>Hover me</Button>
</Tooltip>`
<Tooltip.Provider>
<Flex gap="medium" align="center">
<Tooltip>
<Tooltip.Trigger render={<Button />}>Tooltip 1</Tooltip.Trigger>
<Tooltip.Content>Top Left tooltip</Tooltip.Content>
</Tooltip>
<Tooltip>
<Tooltip.Trigger render={<Button />}>Tooltip 2</Tooltip.Trigger>
<Tooltip.Content>Top Right tooltip</Tooltip.Content>
</Tooltip>
</Flex>
</Tooltip.Provider>`
};

export const providerDemo = {
export const trackCursorDemo = {
type: 'code',
tabs: [
{
name: 'With Provider',
name: 'Both',
code: `
<Flex gap="medium" align="center">
<Tooltip.Provider>
<Tooltip message='Top Left tooltip' side='top-left'>
<Button>Top Left</Button>
</Tooltip>
<Tooltip message='Top Right tooltip' side='top-right'>
<Button>Top Right</Button>
</Tooltip>
<Tooltip message='Bottom Left tooltip' side='bottom-left'>
<Button>Bottom Left</Button>
</Tooltip>
<Tooltip message='Bottom Right tooltip' side='bottom-left'>
<Button>Bottom Right</Button>
</Tooltip>
</Tooltip.Provider>
</Flex>`
<Tooltip trackCursorAxis="both">
<Tooltip.Trigger render={<Button />}>Hover me</Tooltip.Trigger>
<Tooltip.Content>Tooltip follows cursor</Tooltip.Content>
</Tooltip>`
},
{
name: 'Without Provider',
name: 'X',
code: `
<Flex gap="medium" align="center">
<Tooltip message='Top Left tooltip' side='top-left'>
<Button>Top Left</Button>
</Tooltip>
<Tooltip message='Top Right tooltip' side='top-right'>
<Button>Top Right</Button>
</Tooltip>
<Tooltip message='Bottom Left tooltip' side='bottom-left'>
<Button>Bottom Left</Button>
</Tooltip>
<Tooltip message='Bottom Right tooltip' side='bottom-left'>
<Button>Bottom Right</Button>
</Tooltip>
</Flex>`
<Tooltip trackCursorAxis="x">
<Tooltip.Trigger render={<Button />}>Hover me</Tooltip.Trigger>
<Tooltip.Content>Tooltip follows cursor</Tooltip.Content>
</Tooltip>`
},
{
name: 'Y',
code: `
<Tooltip trackCursorAxis="y">
<Tooltip.Trigger render={<Button />}>Hover me</Tooltip.Trigger>
<Tooltip.Content>Tooltip follows cursor</Tooltip.Content>
</Tooltip>`
}
]
};

export const arrowDemo = {
type: 'code',
code: `
<Tooltip>
<Tooltip.Trigger render={<Button />}>Hover me</Tooltip.Trigger>
<Tooltip.Content showArrow>Tooltip with arrow</Tooltip.Content>
</Tooltip>`
};
40 changes: 27 additions & 13 deletions apps/www/src/content/docs/components/tooltip/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: A popup that displays information related to an element when it rec
source: packages/raystack/components/tooltip
---

import { playground, sideDemo, customDemo,followCursorDemo, providerDemo } from "./demo.ts";
import { playground, sideDemo, alignDemo, customDemo, providerDemo, trackCursorDemo, noArrowDemo, arrowDemo } from "./demo.ts";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for noArrowDemo usage in the tooltip directory
rg -n 'noArrowDemo' apps/www/src/content/docs/components/tooltip/

Repository: raystack/apsara

Length of output: 243


🏁 Script executed:

#!/bin/bash
# Read the entire file to see what demos are actually used in the content
cat -n apps/www/src/content/docs/components/tooltip/index.mdx | head -100

Repository: raystack/apsara

Length of output: 2673


🏁 Script executed:

#!/bin/bash
# Check if there's more content in the file after line 100
wc -l apps/www/src/content/docs/components/tooltip/index.mdx
tail -20 apps/www/src/content/docs/components/tooltip/index.mdx

Repository: raystack/apsara

Length of output: 563


Remove unused import noArrowDemo.

The noArrowDemo is imported but not used anywhere in the documentation. Either remove the import or add a section demonstrating the no-arrow variant (e.g., contrasting with the "With Arrow" section).

🤖 Prompt for AI Agents
In `@apps/www/src/content/docs/components/tooltip/index.mdx` at line 7, Remove the
unused import noArrowDemo from the import list in
apps/www/src/content/docs/components/tooltip/index.mdx (the current line that
imports playground, sideDemo, alignDemo, customDemo, providerDemo,
trackCursorDemo, noArrowDemo, arrowDemo) or alternatively add a new
documentation section that references noArrowDemo (e.g., a "Without Arrow" demo
contrasting with the "With Arrow" section) and render it in the MDX content so
the import is used.


<Demo data={playground} />

Expand All @@ -20,20 +20,38 @@ The Tooltip component accepts various props to customize its behavior and appear

<auto-type-table path="./props.ts" name="TooltipProps" />

## Tooltip.Trigger Props

The Trigger component wraps the element that activates the tooltip.

<auto-type-table path="./props.ts" name="TooltipTriggerProps" />

## Tooltip.Content Props

The Content component displays the tooltip content and controls positioning.

<auto-type-table path="./props.ts" name="TooltipContentProps" />

## Tooltip.Provider Props

The TooltipProvider component serves as a context wrapper that provides global configuration and functionality to all tooltip instances within your application.
The Provider component serves as a context wrapper that provides global configuration and functionality to all tooltip instances within your application.

<auto-type-table path="./props.ts" name="TooltipProviderProps" />

## Examples

### Side

The Tooltip component can be positioned in different directions using the `side` prop:
The Tooltip Content component can be positioned in different directions using the `side` prop:

<Demo data={sideDemo} />

### Align

The Tooltip Content component can be aligned in different directions using the `align` prop:

<Demo data={alignDemo} />

### Custom Content

Tooltips can contain custom content using ReactNode:
Expand All @@ -46,18 +64,14 @@ The TooltipProvider component can be used to provide a global configuration for

<Demo data={providerDemo} />

### Follow Cursor
### Track Cursor

When `followCursor` is true, the tooltip will follow the cursor and will be positioned relative to the cursor.
Use `trackCursorAxis` prop on the Root component to make the tooltip follow the cursor:

<Demo data={followCursorDemo} />
<Demo data={trackCursorDemo} />

## Accessibility
### With Arrow

The Tooltip component follows WAI-ARIA guidelines for tooltips:
Show the arrow by setting `showArrow={true}` on the Content component:

- Uses `role="tooltip"` for proper semantic meaning
- Automatically manages focus and hover interactions
- Supports keyboard navigation
- Provides appropriate ARIA attributes for accessibility
- Manages enter/exit animations for smooth user experience
<Demo data={arrowDemo} />
Loading