Skip to content

Commit

Permalink
[sparkle] - enh: Tooltip (#7853)
Browse files Browse the repository at this point in the history
* [sparkle] - feature: add tooltip and slot functionality to UI components

 - New dependencies on `@radix-ui/react-slot` and `@radix-ui/react-tooltip` have been introduced for enhanced UI component behavior
 - Removed the `dev: true` flag from `@floating-ui/*` dependencies indicating a move from dev-only to production usage
 - The `@floating-ui/utils` dependency integrity hash remains unchanged; indicating no version change, but a probable classification change in usage

* [sparkle] - refactor: replace custom tooltip implementation with @radix-ui/react-tooltip

 - Removed the entire custom tooltip logic to leverage the functionality from @radix-ui/react-tooltip package
 - Simplified tooltip related components by using primitives from the external library, ensuring a more standard and maintainable approach
 - Updated the `Tooltip.stories.tsx` to reflect changes in the tooltip implementation and usage with the new library components

* [sparkle] - refactor: update Breadcrumb component Tooltip usage

 - Replace old Tooltip component with new TooltipContent, TooltipProvider, TooltipRoot, and TooltipTrigger components
 - Improve the modularity and flexibility of tooltip implementation in Breadcrumbs component

* [sparkle] - refactor: update tooltip implementation for Buttons

 - Replaced custom Tooltip component with TooltipProvider, TooltipRoot, and TooltipTrigger from Radix UI
 - Updated Button component to use new tooltipPosition values from SIDE_OPTIONS
 - Modified stories to reflect changes in tooltipPosition's accepted values

* [sparkle/src/components] - refactor: update Tooltip implementation for Citation component

- Changed the Tooltip usage to the newer component structure with TooltipProvider, TooltipRoot, TooltipTrigger, and TooltipContent.
- Ensured the title is displayed on the 'top' side within the TooltipContent when hovering over the Citation component's card button.

* [sparkle] - refactor: update DataTable tooltip implementation

 - Replaced the single-component Tooltip import with multi-part Tooltip components for enhanced flexibility and control
 - Wrapped the Avatar within CellContent with the new TooltipProvider, TooltipRoot, TooltipTrigger, and TooltipContent components for better tooltip management and positioning

* [sparkle] - refactor: update Tooltip implementation in DropdownMenu

 - Replaced the old Tooltip with the new TooltipProvider, TooltipRoot, TooltipTrigger, and TooltipContent components
 - Updated tooltip positioning to use new SIDE_OPTIONS from @radix-ui/react-popper
 - Changed default tooltip positions to follow the new 'top' and 'bottom' convention instead of 'above' and 'below'

* [sparkle/components] - fix: standardize tooltip position property value

- Change `tooltipPosition` prop from "below" to "bottom" for consistency across components
- Update imports and whitespace formatting for improved code readability and style conformity

[sparkle/components] - refactor: enhance tooltip related components structure

- Group tooltip imports together for cleanliness and easier management
- Implement consistent tooltip content wrapping across different components

[sparkle] - style: consistent end-of-file newlines and minor formatting

- Ensure all modified files have a newline at the end of the file for POSIX compliance
- Adjust multiline JSX properties formatting for better readability

[sparkle/stories] - style: update storybook examples to match codebase practices

- Format multiline props and function parameters in Storybook files for clarity
- Correct minor issues like missing semicolons to follow project's coding standards

* [sparkle] - fix: standardize tooltip position for IconButton stories

 - Changed tooltipPosition value from "below" to "bottom" to unify the positioning across various IconButton story variants

* [sparkle] - refactor: remove unused Tooltip import from Tab component

 - Clean up code by removing the Tooltip import which is no longer used after refactoring the Tooltip component

* [sparkle] - fix: remove redundant tooltip from Tab component

 - Eliminate duplicate tooltip to prevent overlapping UI elements in tabs

* [sparkle] - refactor: reorganize Tooltip imports in DataTable component

 - Move Tooltip related imports to be grouped together at the top of the import list

[types] - fix: add missing semicolon in prettifyGroupName function

 - Ensure coding style consistency by adding a semicolon at the end of the return statement

* [sparkle] - fix: ensure tooltip background is consistently white

 - Added `s-bg-white` class to enforce a white background on the tooltip component for better visibility

* [sparkle] - feature: allow sending children elements to ElementDialog

 - Added `children` prop to `ElementDialog` to enable passing child components into the dialog

[sparkle] - refactor: update Dialog stories with new `validateVariant` props

 - Changed `validateVariant` prop from `primaryWarning` to `warning` in one of the Dialog stories
 - Added `validateVariant` props with values `primary`, `outline`, `ghost`, and `highlight` to other Dialog stories to represent different button styles

* [sparkle] - refactor: improve Button component variant typing

 - Change the variant prop type in Button component to a union type for better scalability and type safety
 - Create a constant array of button variants and derive the ButtonVariantType from it

[sparkle] - fix: correct content in Citation component tooltip

 - Replace title with description in the tooltip content of the Citation component for accurate data display

[sparkle] - refactor: update Dialog component's validateVariant prop type

 - Align the type of validateVariant prop in Dialog component with the new ButtonVariantType

[sparkle] - feature: add TooltipPortal export to Tooltip components

 - Expose TooltipPortal from TooltipPrimitive to enable portal functionality in Tooltip component

[sparkle] - docs: extend description in Citation component examples

 - Update the description in Citation.stories.tsx to include a more extended example text

[sparkle] - style: enhance DataTable content readability

 - Wrap DataTable cell content with CellContentWithCopy component for better readability and consistency

[sparkle] - fix: correct validateVariant prop in Dialog stories

 - Fix validateVariant prop in Dialog stories to use correct values from BUTTON_VARIANT array

[sparkle] - refactor: remove outdated validateVariant props in Dialog stories

 - Remove unused or outdated validateVariant props from Dialog stories examples to match current component API

* [sparkle] - feature: add TooltipPortal export to component library

 - Tooltip functionality extended to support portal usage in the component library.

* fix: lint/format

* [sparkle] - fix: standardize tooltip positioning and content

 - Remove fixed side for tooltip content to allow default positioning
 - Replace description with title in tooltip display for citation component

* [sparkle] - refactor: Remove default tooltipPosition from Button components

 - The `tooltipPosition` prop is no longer passed with a default value of "bottom" to Button components in BarHeader.tsx
 - `tooltipPosition` default assignment removed from Button.tsx, making it an explicitly required prop
 - `TooltipPortal` component removed as it is no longer used in the Tooltip system

* [sparkle] - feature: implement a new Tooltip component

 - Extended TooltipPrimitive with a custom TooltipContentProps interface
 - Created a Tooltip component that uses the new TooltipContentProps interface
 - Exposed the new Tooltip component for external access
 - Updated stories to include examples of the new Tooltip component
 - Cleaned up Tooltip-related exports in the component index file

* [sparkle/components] - refactor: streamline tooltip usage across components

 - Centralize tooltip implementation by replacing previous granular tooltip components with a unified `Tooltip` component
 - Simplify the codebase and improve maintainability by removing redundant tooltip wrapper elements across multiple files

* [sparkle] - fix: remove asChild prop from TooltipTrigger component

- Ensure that TooltipTrigger does not receive the asChild prop for consistency and possible bug avoidance

[sparkle] - feature: add ButtonWithTooltip component story examples

- Provide a story example showing how to manually instantiate a tooltip with a button trigger
- Add a story demonstrating the usage of the Tooltip component with a Button as its trigger

* fix: lint/format

* [sparkle] - refactor: standardize tooltip position prop and improve ellipsis presentation

 - Replace hardcoded ellipsis string with a constant for consistency in `Breadcrumbs`
 - Utilize `Tooltip` component prop type for tooltip position across several components
 - Remove unused import `SIDE_OPTIONS` from multiple files to clean up the codebase
 - Enhance Button stories with proper TooltipProvider wrapping and formatting

* [sparkle] - feature: bump package version to 0.2.255

 - Update the package version in both package-lock.json and package.json for release

---------

Co-authored-by: Jules <[email protected]>
Co-authored-by: Jules <[email protected]>
  • Loading branch information
3 people authored Oct 7, 2024
1 parent 889a7c1 commit 992be8c
Show file tree
Hide file tree
Showing 26 changed files with 745 additions and 248 deletions.
490 changes: 476 additions & 14 deletions sparkle/package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion sparkle/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dust-tt/sparkle",
"version": "0.2.254",
"version": "0.2.255",
"scripts": {
"build": "rm -rf dist && npm run tailwind && npm run build:esm && npm run build:cjs",
"tailwind": "tailwindcss -i ./src/styles/tailwind.css -o dist/sparkle.css",
Expand Down Expand Up @@ -87,6 +87,8 @@
"@emoji-mart/data": "^1.1.2",
"@emoji-mart/react": "^1.1.1",
"@headlessui/react": "^1.7.19",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.3",
"@tanstack/react-table": "^8.13.0",
"emoji-mart": "^5.5.2",
"esbuild": "^0.20.0",
Expand Down
3 changes: 0 additions & 3 deletions sparkle/src/components/BarHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ BarHeader.ButtonBar = function (props: BarHeaderButtonBarProps) {
icon={ChevronLeftIcon}
variant="tertiary"
label="Back"
tooltipPosition="below"
labelVisible={false}
onClick={props.onBack}
/>
Expand All @@ -97,7 +96,6 @@ BarHeader.ButtonBar = function (props: BarHeaderButtonBarProps) {
icon={XMarkIcon}
variant="tertiary"
label="Close"
tooltipPosition="below"
labelVisible={false}
onClick={props.onClose}
/>
Expand Down Expand Up @@ -134,7 +132,6 @@ BarHeader.ButtonBar = function (props: BarHeaderButtonBarProps) {
icon={TrashIcon}
variant="tertiary"
labelVisible={false}
tooltipPosition="below"
onClick={props.onDelete}
/>
<Button
Expand Down
4 changes: 2 additions & 2 deletions sparkle/src/components/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ export function Breadcrumbs({ items }: BreadcrumbProps) {
function truncateWithTooltip(text: string, length: number) {
return text.length > length ? (
<Tooltip
trigger={`${text.substring(0, length - 1)}${ELLIPSIS_STRING}`}
label={text}
position="below"
>{`${text.substring(0, length - 1)}…`}</Tooltip>
/>
) : (
text
);
Expand Down
30 changes: 16 additions & 14 deletions sparkle/src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,26 @@ import React, {
ReactNode,
} from "react";

import { Tooltip } from "@sparkle/components/Tooltip";
import { ChevronDownIcon, ChevronUpDownIcon } from "@sparkle/icons/solid";
import { classNames } from "@sparkle/lib/utils";

import { Avatar } from "./Avatar";
import { Icon, IconProps } from "./Icon";
import { Tooltip, TooltipProps } from "./Tooltip";

export type ButtonProps = {
variant?:
| "primary"
| "primaryWarning"
| "secondary"
| "secondaryWarning"
| "tertiary"
| "avatar";
const BUTTON_VARIANTS = [
"primary",
"primaryWarning",
"secondary",
"secondaryWarning",
"tertiary",
"avatar",
] as const;

export type ButtonVariantType = (typeof BUTTON_VARIANTS)[number];

export type ButtonProps = {
variant?: ButtonVariantType;
type?: "button" | "menu" | "select";
size?: "xs" | "sm" | "md" | "lg";
onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
Expand All @@ -32,7 +36,7 @@ export type ButtonProps = {
icon?: ComponentType;
avatar?: string;
className?: string;
tooltipPosition?: TooltipProps["position"];
tooltipPosition?: React.ComponentProps<typeof Tooltip>["side"];
disabledTooltip?: boolean;
};

Expand Down Expand Up @@ -173,7 +177,7 @@ export function Button({
label,
icon,
className = "",
tooltipPosition = "above",
tooltipPosition,
hasMagnifying = true,
disabledTooltip = false,
avatar,
Expand Down Expand Up @@ -242,9 +246,7 @@ export function Button({
return labelVisible || disabledTooltip ? (
buttonBase
) : (
<Tooltip label={label} position={tooltipPosition}>
{buttonBase}
</Tooltip>
<Tooltip trigger={buttonBase} label={label} side={tooltipPosition} />
);
}

Expand Down
8 changes: 1 addition & 7 deletions sparkle/src/components/Citation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,5 @@ export function Citation({
<div className={isLoading ? "s-opacity-50" : ""}>{cardContent}</div>
</CardButton>
);
return href ? (
<Tooltip label={title} position="above">
{cardButton}
</Tooltip>
) : (
cardButton
);
return href ? <Tooltip trigger={cardButton} label={title} /> : cardButton;
}
19 changes: 11 additions & 8 deletions sparkle/src/components/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -441,14 +441,17 @@ DataTable.CellContent = function CellContent({
{...props}
>
{avatarUrl && avatarTooltipLabel && (
<Tooltip label={avatarTooltipLabel} position="above">
<Avatar
visual={avatarUrl}
size="xs"
className="s-mr-2"
isRounded={roundedAvatar ?? false}
/>
</Tooltip>
<Tooltip
trigger={
<Avatar
visual={avatarUrl}
size="xs"
className="s-mr-2"
isRounded={roundedAvatar ?? false}
/>
}
label={avatarTooltipLabel}
/>
)}
{avatarUrl && !avatarTooltipLabel && (
<Avatar
Expand Down
8 changes: 4 additions & 4 deletions sparkle/src/components/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ConfettiBackground from "@sparkle/components/ConfettiBackground";
import Spinner from "@sparkle/components/Spinner";
import { classNames } from "@sparkle/lib/utils";

import { Button } from "./Button";
import { Button, ButtonVariantType } from "./Button";

export type BaseDialogProps = {
backgroundType?: "confetti" | "snow" | "none";
Expand All @@ -16,19 +16,19 @@ export type BaseDialogProps = {
onValidate: () => void;
title: string;
validateLabel?: string;
validateVariant?: "primary" | "primaryWarning";
validateVariant?: ButtonVariantType;
cancelLabel?: string;
};

export type DialogProps = BaseDialogProps & {
alertDialog?: false;
onCancel: () => void;
}
};

export type AlertDialogProps = BaseDialogProps & {
alertDialog: true;
onCancel?: () => void;
}
};

export function Dialog({
backgroundType = "none",
Expand Down
72 changes: 41 additions & 31 deletions sparkle/src/components/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { classNames } from "@sparkle/lib/utils";

import { Icon } from "./Icon";
import { Item as StandardItem, LinkProps } from "./Item";
import { Tooltip, TooltipProps } from "./Tooltip";
import { Tooltip } from "./Tooltip";

const ButtonRefContext =
React.createContext<MutableRefObject<HTMLButtonElement | null> | null>(null);
Expand Down Expand Up @@ -98,7 +98,7 @@ export interface DropdownButtonProps {
type?: "menu" | "submenu" | "select";
size?: "sm" | "md";
tooltip?: string;
tooltipPosition?: TooltipProps["position"];
tooltipPosition?: React.ComponentProps<typeof Tooltip>["side"];
icon?: ComponentType;
className?: string;
disabled?: boolean;
Expand All @@ -116,7 +116,7 @@ DropdownMenu.Button = forwardRef<HTMLButtonElement, DropdownButtonProps>(
tooltip,
icon,
children,
tooltipPosition = "above",
tooltipPosition = "top",
className = "",
disabled = false,
onClick,
Expand Down Expand Up @@ -178,9 +178,11 @@ DropdownMenu.Button = forwardRef<HTMLButtonElement, DropdownButtonProps>(
onClick={(e) => e.stopPropagation()}
>
{tooltip ? (
<Tooltip position={tooltipPosition} label={tooltip}>
{children}
</Tooltip>
<Tooltip
trigger={children}
label={tooltip}
side={tooltipPosition}
/>
) : (
children
)}
Expand All @@ -198,31 +200,39 @@ DropdownMenu.Button = forwardRef<HTMLButtonElement, DropdownButtonProps>(
return (
<>
{tooltip ? (
<Tooltip label={tooltip} position={tooltipPosition}>
<Menu.Button
disabled={disabled}
ref={aggregatedRef}
className={classNames(
disabled ? "s-cursor-default" : "s-cursor-pointer",
className,
"s-group/dm s-flex s-justify-items-center s-text-sm s-font-medium focus:s-outline-none focus:s-ring-0",
label ? (size === "md" ? "s-gap-2" : "s-gap-1.5") : "s-gap-0.5"
)}
onClick={(e) => {
e.stopPropagation();
if (onClick) {
onClick();
}
}}
>
<Icon visual={icon} size={size} className={finalIconClasses} />
<Icon
visual={chevronIcon}
size={size === "sm" ? "xs" : "sm"}
className={finalChevronClasses}
/>
</Menu.Button>
</Tooltip>
<Tooltip
trigger={
<Menu.Button
disabled={disabled}
ref={aggregatedRef}
className={classNames(
disabled ? "s-cursor-default" : "s-cursor-pointer",
className,
"s-group/dm s-flex s-justify-items-center s-text-sm s-font-medium focus:s-outline-none focus:s-ring-0",
label
? size === "md"
? "s-gap-2"
: "s-gap-1.5"
: "s-gap-0.5"
)}
onClick={(e) => {
e.stopPropagation();
if (onClick) {
onClick();
}
}}
>
<Icon visual={icon} size={size} className={finalIconClasses} />
<Icon
visual={chevronIcon}
size={size === "sm" ? "xs" : "sm"}
className={finalChevronClasses}
/>
</Menu.Button>
}
label={tooltip}
side={tooltipPosition}
/>
) : (
<Menu.Button
disabled={disabled}
Expand Down
5 changes: 4 additions & 1 deletion sparkle/src/components/ElementDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function ElementDialog<T>({
closeDialogFn,
onValidate,
onCancel,
children,
...props
}: ElementDialogProps<T>) {
const [isClosingTransition, setIsClosingTransition] = useState(false);
Expand All @@ -33,6 +34,8 @@ export function ElementDialog<T>({
onCancel={() => onCancel(transitionOnClose)}
onValidate={() => onValidate(transitionOnClose)}
{...props}
/>
>
{children}
</Dialog>
);
}
14 changes: 8 additions & 6 deletions sparkle/src/components/IconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import React, { ComponentType, MouseEventHandler } from "react";
import { classNames } from "@sparkle/lib/utils";

import { Icon, IconProps } from "./Icon";
import { Tooltip, TooltipProps } from "./Tooltip";
import { Tooltip } from "./Tooltip";

type IconButtonProps = {
variant?: "primary" | "warning" | "secondary" | "tertiary" | "white";
onClick?: MouseEventHandler<HTMLButtonElement>;
size?: "xs" | "sm" | "md";
tooltip?: string;
tooltipPosition?: TooltipProps["position"];
tooltipPosition?: React.ComponentProps<typeof Tooltip>["side"];
icon?: ComponentType;
className?: string;
disabled?: boolean;
Expand Down Expand Up @@ -87,7 +87,7 @@ export function IconButton({
onClick,
disabled = false,
tooltip,
tooltipPosition = "above",
tooltipPosition = "top",
icon,
className = "",
size = "sm",
Expand Down Expand Up @@ -117,9 +117,11 @@ export function IconButton({
);

return tooltip ? (
<Tooltip label={tooltip} position={tooltipPosition}>
{IconButtonContent}
</Tooltip>
<Tooltip
trigger={IconButtonContent}
label={tooltip}
side={tooltipPosition}
/>
) : (
IconButtonContent
);
Expand Down
14 changes: 8 additions & 6 deletions sparkle/src/components/IconToggleButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import React, { ComponentType, MouseEventHandler } from "react";
import { classNames } from "@sparkle/lib/utils";

import { Icon, IconProps } from "./Icon";
import { Tooltip, TooltipProps } from "./Tooltip";
import { Tooltip } from "./Tooltip";

type IconToggleButtonProps = {
variant?: "secondary" | "tertiary";
onClick?: MouseEventHandler<HTMLButtonElement>;
size?: "xs" | "sm" | "md";
tooltip?: string;
tooltipPosition?: TooltipProps["position"];
tooltipPosition?: React.ComponentProps<typeof Tooltip>["side"];
icon: ComponentType;
iconSelected?: ComponentType;
className?: string;
Expand Down Expand Up @@ -57,7 +57,7 @@ export function IconToggleButton({
onClick,
disabled = false,
tooltip,
tooltipPosition = "above",
tooltipPosition = "top",
icon,
iconSelected,
className = "",
Expand Down Expand Up @@ -105,9 +105,11 @@ export function IconToggleButton({
);

return tooltip ? (
<Tooltip label={tooltip} position={tooltipPosition}>
{IconButtonToggleContent}
</Tooltip>
<Tooltip
trigger={IconButtonToggleContent}
label={tooltip}
side={tooltipPosition}
/>
) : (
IconButtonToggleContent
);
Expand Down
Loading

0 comments on commit 992be8c

Please sign in to comment.