-
Notifications
You must be signed in to change notification settings - Fork 0
feat(Tooltip): Engineering guideline #429
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7c3e0db
d2901df
2195689
46e896e
27715fe
2a0362b
b057dc1
f8c725d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
--- | ||
id: Components-tooltip-dev | ||
title: Tooltip Engineering Guidelines | ||
description: Engineering guideline for using the Nimbus Tooltip component | ||
documentState: InitialDraft | ||
order: 999 | ||
menu: | ||
- Components | ||
- Feedback | ||
- TooltipDev | ||
tags: | ||
- component | ||
- engineering | ||
- migration | ||
--- | ||
|
||
# Tooltip Component | ||
|
||
Tooltips is a compound component that displays informative text when users hover over or focus on an element. | ||
|
||
## Component Anatomy [Optional for simple components] | ||
|
||
Component Anatomy here - image with parts and description as can be seen on [combobox](https://www.figma.com/design/AvtPX6g7OGGCRvNlatGOIY/NIMBUS-design-system?node-id=5311-13804&p=f&m=dev) for example | ||
|
||
 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is likely not relevant to this component but since this is almost like a Poc, I added it. The idea is the component anatomy image might not be necessary for simple components so it is optional. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is very valuable conceptually, especially for consumers who prefer to learn visually. I think it'd be worth including in every guideline |
||
|
||
## Component Usage | ||
|
||
### How to Import | ||
|
||
```tsx | ||
import { Tooltip } from '@commercetools/nimbus'; | ||
``` | ||
|
||
### Basic Example | ||
|
||
A minimal, copy-and-paste example of the tooltip in its simplest form: edit the placement in code code interface to different positions of choice (top, left, right, etc) | ||
|
||
```jsx-live-dev | ||
// Example: A basic tooltip | ||
const App = () => ( | ||
<Tooltip.Root placement="top"> | ||
<Button>Hover me</Button> | ||
<Tooltip.Content | ||
placement="top" | ||
maxWidth="300px" | ||
backgroundColor="blue" | ||
color="white" | ||
> | ||
This is a helpful tooltip | ||
</Tooltip.Content> | ||
</Tooltip.Root> | ||
) | ||
``` | ||
|
||
### Common props and Variations | ||
|
||
#### Placement Options | ||
Control where the tooltip appears relative to its trigger: change the placement to any of these options to reposition the tooltip: | ||
```"top" | "top left" | "top right" | "top start" | "top end" | "bottom" | "bottom left" | "bottom right" | "bottom start" | "bottom end" | "left" | "left top" | "left bottom" | "right" | "right top" | "right bottom" | "start" | "start top" | "start bottom" | "end" | "end top" | "end bottom"``` | ||
|
||
```jsx-live-dev | ||
const App = () => ( | ||
<Tooltip.Root> | ||
<Button>Tooltip placement</Button> | ||
<Tooltip.Content placement="top">Tooltip on top</Tooltip.Content> | ||
</Tooltip.Root> | ||
) | ||
``` | ||
|
||
#### Offset Options | ||
|
||
Control the tooltip offset: | ||
```offset``` | ||
|
||
```jsx-live-dev | ||
const App = () => ( | ||
<Tooltip.Root> | ||
<Button>Tooltip placement</Button> | ||
<Tooltip.Content offset={50}>Tooltip on top</Tooltip.Content> | ||
</Tooltip.Root> | ||
) | ||
``` | ||
|
||
```...Add example snippets for each relevant component prop``` | ||
|
||
## Testing Strategies and Best Practices | ||
|
||
#### 1. Unit Testing with React Testing Library | ||
> [!CAUTION]\ | ||
> **Note** | ||
> | ||
> - if you are using app-kit as your initial setup and for your entry point, then the provider is already available. You won't be needing the setup below.. | ||
|
||
**Recommended Testing Library Setup:** | ||
```tsx | ||
import { render, screen, userEvent } from '@testing-library/react'; | ||
import { NimbusProvider } from '@commercetools/nimbus'; | ||
import { IntlProvider } from 'react-intl'; | ||
import { Tooltip, Button } from '@commercetools/nimbus'; | ||
|
||
// Test wrapper with required providers | ||
const TestWrapper = ({ children }: { children: React.ReactNode }) => ( | ||
<IntlProvider locale="en" messages={{}} defaultLocale="en"> | ||
<NimbusProvider> | ||
{children} | ||
</NimbusProvider> | ||
</IntlProvider> | ||
); | ||
Comment on lines
+102
to
+109
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aren't we going to put There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we are doing that, then that would be great! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, I think we can point to the guidelines here |
||
|
||
// Custom render function | ||
const renderWithProviders = (ui: React.ReactElement) => | ||
render(ui, { wrapper: TestWrapper }); | ||
``` | ||
|
||
#### 2. Storybook Integration for Testing | ||
|
||
Use the [Nimbus storybook Tooltip component story](https://nimbus-storybook-6l4m4g78g-commercetools.vercel.app/?path=/docs/components-tooltip-tooltip--docs) as a playground for visual testing of the component. | ||
|
||
#### 3. Regression tests | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Anything in here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Its kind of a placeholder for now since we have not fully come up with a regression test strategy yet. |
||
|
||
### 4. Accessibility requirements | ||
|
||
Nimbus Tooltip automatically handles most accessibility requirements, but developers should be aware of these basic requirements: | ||
- Add `aria-label` to enable proper definition of the alert component. | ||
- Ensure `aria-describedby` is present for error messages. | ||
- Include `role="alert"` for critical notifications. | ||
|
||
## Quick Reference Summary | ||
|
||
### Design Guidelines | ||
For essential patterns and guidelines, see the [Tooltip design guideline]((https://Nimbus-docs/components/feedback/tooltip)) | ||
|
||
### Code Patterns | ||
|
||
#### Hooks | ||
```tsx | ||
// Custom Hook Pattern | ||
const useTooltip = (content: string, options = {}) => { ...}; | ||
|
||
// Using the Custom Hook | ||
const MyComponent = () => { | ||
const { tooltipProps, contentProps } = useTooltip( | ||
"This action will save your changes", | ||
{ placement: "bottom", delay: 300 } | ||
); | ||
|
||
return ( | ||
<Tooltip.Root {...tooltipProps}> | ||
<Button>Save</Button> | ||
<Tooltip.Content {...contentProps} /> | ||
</Tooltip.Root> | ||
); | ||
}; | ||
``` | ||
|
||
|
||
### API Reference | ||
|
||
<PropsTable id="Tooltip" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We still need a different topic to discuss how we would manually add props. The exposed props listing on the props table does not capture a lot of the important props. |
||
|
||
<br/> | ||
|
||
### Need Help? | ||
Join `#nimbus-migration` on Slack or check the [Nimbus Storybook](https://nimbus.commercetools.com/?path=/story/components-tooltip) for live examples. | ||
|
||
**Additional Resources:** | ||
- [Tooltip design guideline](https://Nimbus-docs/components/feedback/tooltip) | ||
- [React-Aria Tooltip Docs](https://react-spectrum.adobe.com/react-aria/Tooltip.html#tooltip) | ||
- [ARIA Tooltip Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/) | ||
- [Figma Design Library](https://www.figma.com/design/gHbAJGfcrCv7f2bgzUQgHq/NIMBUS-Guidelines?node-id=1695-45519&m) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
--- | ||
id: Components-tooltip-migration | ||
title: Tooltip Migration Guideline | ||
description: Engineering guideline for migrating from UI Kit to Nimbus Tooltip component | ||
documentState: InitialDraft | ||
order: 999 | ||
menu: | ||
- Components | ||
- Feedback | ||
- TooltipMigration | ||
tags: | ||
- component | ||
- engineering | ||
- migration | ||
--- | ||
|
||
# Tooltip Migration Guideline (Uikit to Nimbus) | ||
|
||
## Basic requirement | ||
|
||
Migration requirements like ensuring the right codemod exists, where to find it or put it etc. | ||
|
||
|
||
### Code Mod Instructions | ||
|
||
If a code mod exists for Tooltip migration, run: | ||
|
||
```bash | ||
npx nimbus-codemods migrate-tooltip | ||
``` | ||
|
||
### Manual Migration Steps | ||
|
||
For manual migration, follow these steps: | ||
|
||
#### Step 1: Replace Component Structure | ||
**Before (UI Kit):** | ||
```tsx | ||
<Tooltip title="Helpful information" isOpen={isOpen} onClose={handleClose}> | ||
<Button>Hover me</Button> | ||
</Tooltip> | ||
``` | ||
|
||
**After (Nimbus):** | ||
```tsx | ||
<Tooltip.Root isOpen={isOpen} onOpenChange={setIsOpen}> | ||
<Button>Hover me</Button> | ||
<Tooltip.Content>Helpful information</Tooltip.Content> | ||
</Tooltip.Root> | ||
``` | ||
|
||
#### Step 2: Update Event Handlers | ||
**Before:** | ||
```tsx | ||
const handleClose = () => { | ||
setIsOpen(false); | ||
}; | ||
``` | ||
|
||
**After:** | ||
```tsx | ||
const handleOpenChange = (isOpen: boolean) => { | ||
setIsOpen(isOpen); | ||
}; | ||
``` | ||
|
||
#### Step 3: Handle Removed Props | ||
For `horizontalConstraint`, wrap with a container or use CSS: | ||
|
||
**Before:** | ||
```tsx | ||
<Tooltip title="Long text content..." horizontalConstraint="m"> | ||
<Button>Button</Button> | ||
</Tooltip> | ||
``` | ||
|
||
**After:** | ||
```tsx | ||
<Tooltip.Root> | ||
<Button>Button</Button> | ||
<Tooltip.Content maxWidth: '200px'> | ||
Long text content... | ||
</Tooltip.Content> | ||
</Tooltip.Root> | ||
``` | ||
|
||
### API Changes and Component Mapping | ||
|
||
These are the possible changes for this component after a successful migration to Nimbus | ||
|
||
| UI Kit Component | Nimbus Component | Notes | | ||
|------------------|------------------|-------| | ||
| `<Tooltip>` | `<Tooltip.Root>` + `<Tooltip.Content>` | Now uses compound component pattern | | ||
| `title` prop | `<Tooltip.Content>` children | Text content now goes as children | | ||
| `isOpen` prop | `isOpen` prop | ✅ Same API | | ||
| `onClose` | `onOpenChange` | ⚠️ Renamed, now receives boolean parameter | | ||
| `horizontalConstraint` | Not supported | ❌ Removed - use CSS or container sizing | | ||
Comment on lines
+91
to
+97
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Beautiful. I cried. 10/10 |
||
|
||
#### Props Renamed or Changed | ||
- `onClose` → `onOpenChange`: Now receives `(isOpen: boolean) => void` instead of `() => void` | ||
- `title` prop → Content as children: Text now goes inside `<Tooltip.Content>` | ||
- `delay` and `closeDelay`: More granular control over timing | ||
|
||
#### Props Removed | ||
- `horizontalConstraint`: Use CSS width constraints on content instead | ||
- `tone`: Styling is now handled through design tokens | ||
|
||
#### New Props Introduced | ||
- `placement`: More placement options with modifiers | ||
- `defaultOpen`: Set initial state without controlled component | ||
|
||
|
||
## Testing Strategies and Best Practices After Migration | ||
|
||
#### 1. Unit Testing with React Testing Library | ||
|
||
List all possible test adjustments to be made to unit tests, regression tests etc | ||
|
||
**Recommended Testing Library Setup:** | ||
```tsx | ||
import { render, screen, userEvent } from '@testing-library/react'; | ||
import { NimbusProvider } from '@commercetools/nimbus'; | ||
import { IntlProvider } from 'react-intl'; | ||
import { Tooltip, Button } from '@commercetools/nimbus'; | ||
|
||
// Test wrapper with required providers | ||
const TestWrapper = ({ children }: { children: React.ReactNode }) => ( | ||
<IntlProvider locale="en" messages={{}} defaultLocale="en"> | ||
<NimbusProvider> | ||
{children} | ||
</NimbusProvider> | ||
</IntlProvider> | ||
); | ||
|
||
// Custom render function | ||
const renderWithProviders = (ui: React.ReactElement) => | ||
render(ui, { wrapper: TestWrapper }); | ||
``` | ||
|
||
## ⚠️ Caveats and Best Practices For Migration | ||
|
||
### Testing Requirements | ||
- **Run Tests After Migration**: Always run your test suites after migrating to ensure components function as expected | ||
- **Update Test Patterns**: Switch from UI Kit testing patterns to Nimbus patterns shown in this guide | ||
- **Provider Requirements**: Ensure tests include both `NimbusProvider` and `IntlProvider` | ||
|
||
### Common Pitfalls | ||
- **Event Handler Updates**: Remember `onClose` is now `onOpenChange` with different signature | ||
- **Compound Component Pattern**: Both `Tooltip.Root` and `Tooltip.Content` are required | ||
|
||
|
||
**Additional Resources:** | ||
- [React-Aria Tooltip Docs](https://react-spectrum.adobe.com/react-aria/Tooltip.html#tooltip) | ||
- [ARIA Tooltip Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/) | ||
- [Figma Design Library](https://www.figma.com/design/gHbAJGfcrCv7f2bgzUQgHq/NIMBUS-Guidelines?node-id=1695-45519&m) | ||
|
||
### API Reference | ||
|
||
<PropsTable id="Tooltip" /> | ||
|
||
## Quick Reference Summary | ||
|
||
### Essential Patterns | ||
- **Compound Components**: Always use `<Tooltip.Root>` + `<Tooltip.Content>` | ||
- **Testing**: Include both providers in test wrapper | ||
- **Accessibility**: Built-in ARIA support, keyboard navigation included | ||
|
||
### Migration Checklist | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should calm some nerves - it may not ever be totally complete for every instance but that's a lovely idea. |
||
- [ ] Replace UI Kit `<Tooltip title="...">` with `<Tooltip.Root>` + `<Tooltip.Content>` | ||
- [ ] Update `onClose` handlers to `onOpenChange` | ||
- [ ] Remove `horizontalConstraint`. | ||
- [ ] Test hover, focus, and keyboard interactions | ||
- [ ] Verify accessibility features | ||
|
||
### Need Help? | ||
Join `#nimbus-migration` on Slack or check the [Nimbus Storybook](https://nimbus.commercetools.com/?path=/story/components-tooltip) for live examples. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to introduce this change since we agreed that for the engineering guideline, the code editor should be the default view.