Skip to content

Commit f7a63e2

Browse files
authored
[LG-5713] feat(tooltip): add variant prop with compact option (#3320)
* feat(tooltip): add compact variant * refactor(tooltip): styles * chore(tooltip): changeset * fix(tooltip): avoid breaking change with Tooltip API * refactor(tooltip): feedback
1 parent 78f8481 commit f7a63e2

File tree

10 files changed

+284
-163
lines changed

10 files changed

+284
-163
lines changed

.changeset/all-boxes-read.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@leafygreen-ui/tooltip': minor
3+
---
4+
5+
[LG-5713](https://jira.mongodb.org/browse/LG-5713): Add `variant` prop with options for `'default'` and `'compact'`

packages/tooltip/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,14 @@ import Tooltip from '@leafygreen-ui/tooltip';
5757
| `className` | `string` | Applies a className to Tooltip container | |
5858
| `children` | `node` | Content that will be rendered inside of `<Tooltip />` | |
5959
| `enabled` | `boolean` | Enables Tooltip to trigger based on the event specified by `triggerEvent`. | `true` |
60-
| `onClose` | `function` | Callback that is called when the tooltip is closed internally. E.g. on ESC press, on backdrop click, on blur.. | `() => {}` |
60+
| `onClose` | `function` | Callback that is called when the tooltip is closed internally. E.g. on ESC press, on backdrop click, on blur.. | |
6161
| `renderMode` | `'inline'` \| `'portal'` \| `'top-layer'` | Options to render the popover element <br> \* [deprecated] `'inline'` will render the popover element inline in the DOM where it's written <br> \* [deprecated] `'portal'` will render the popover element in a new div appended to the body. Alternatively, can be portaled into a provided `portalContainer` <br> \* `'top-layer'` will render the popover element in the top layer | `'top-layer'` |
6262
| `portalContainer` | `HTMLElement` \| `null` | Sets the container used for the popover's portal. NOTE: If using a `scrollContainer` make sure that the `portalContainer` is contained within the `scrollContainer`. E.g, passing the same refrence to `scrollContainer` and `portalContainer`. | |
6363
| `scrollContainer` | `HTMLElement` \| `null` | If the popover portal has a scrollable ancestor other than the window, this prop allows passing a reference to that lement to allow the portal to position properly. | |
6464
| `portalClassName` | `string` | Passes the given className to the popover's portal container if the default portal container is being used. | |
6565
| `popoverZIndex` | `number` | Sets the z-index CSS property for the popover. | |
66-
| `baseFontSize` | `13` \| `16` | font-size applied to typography element | default to value set by LeafyGreen Provider |
66+
| `baseFontSize` | `13` \| `16` | Allows consuming applications to override font-size as set by the LeafyGreen Provider. This prop is only considered when `variant` is `'default'`. | default to value set by LeafyGreen Provider |
67+
| `variant` | `'default'` \| `'compact'` | Variant of the tooltip to be rendered. | `'default'` |
6768
| ... | native `div` attributes | Any other props will be spread on the root `div` element | |
6869

6970
### External tooltip triggers

packages/tooltip/src/Tooltip.stories.tsx

Lines changed: 110 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
storybookExcludedControlParams,
66
StoryMetaType,
77
} from '@lg-tools/storybook-utils';
8-
import { type StoryObj } from '@storybook/react';
8+
import { StoryFn, type StoryObj } from '@storybook/react';
99
import {
1010
expect,
1111
within,
@@ -17,13 +17,19 @@ import {
1717
import { Button, Size } from '@leafygreen-ui/button';
1818
import { css } from '@leafygreen-ui/emotion';
1919
import { Icon } from '@leafygreen-ui/icon';
20-
import { RenderMode, TestUtils } from '@leafygreen-ui/popover';
20+
import LeafyGreenProvider from '@leafygreen-ui/leafygreen-provider';
21+
import { RenderMode } from '@leafygreen-ui/popover';
2122
import { BaseFontSize, transitionDuration } from '@leafygreen-ui/tokens';
2223
import { Body, InlineCode, Subtitle } from '@leafygreen-ui/typography';
2324

24-
import { Align, Justify, Tooltip, TooltipProps, TriggerEvent } from '.';
25-
26-
const { getAlign, getJustify } = TestUtils;
25+
import {
26+
Align,
27+
Justify,
28+
Tooltip,
29+
TooltipProps,
30+
TooltipVariant,
31+
TriggerEvent,
32+
} from '.';
2733

2834
const meta: StoryMetaType<typeof Tooltip> = {
2935
title: 'Composition/Overlays/Tooltip',
@@ -33,6 +39,7 @@ const meta: StoryMetaType<typeof Tooltip> = {
3339
renderMode: RenderMode.TopLayer,
3440
triggerEvent: TriggerEvent.Hover,
3541
children: 'I am a tooltip!',
42+
variant: TooltipVariant.Default,
3643
},
3744
argTypes: {
3845
open: { control: 'boolean' },
@@ -46,6 +53,10 @@ const meta: StoryMetaType<typeof Tooltip> = {
4653
control: 'select',
4754
options: Object.values(TriggerEvent),
4855
},
56+
variant: {
57+
control: 'radio',
58+
options: Object.values(TooltipVariant),
59+
},
4960
},
5061
parameters: {
5162
default: 'LiveExample',
@@ -61,75 +72,86 @@ const meta: StoryMetaType<typeof Tooltip> = {
6172
delay: transitionDuration.slowest,
6273
},
6374
generate: {
64-
storyNames: ['ShortString', 'LongString', 'JSXChildren'],
75+
storyNames: ['LightMode', 'DarkMode'],
6576
combineArgs: {
66-
darkMode: [false, true],
67-
align: Object.values(Align),
68-
justify: Object.values(Justify),
6977
baseFontSize: Object.values(BaseFontSize),
78+
variant: Object.values(TooltipVariant),
7079
},
80+
excludeCombinations: [
81+
{
82+
baseFontSize: BaseFontSize.Body2,
83+
variant: TooltipVariant.Compact,
84+
},
85+
],
7186
args: {
7287
open: true,
7388
},
7489
decorator: (Instance, ctx) => (
75-
<div
76-
className={css`
77-
width: 256px;
78-
height: 100px;
79-
display: flex;
80-
align-items: ${getAlign(ctx?.args.align, ctx?.args.justify)};
81-
justify-content: ${getJustify(ctx?.args.align, ctx?.args.justify)};
82-
`}
83-
>
84-
<Instance
85-
trigger={
86-
<Button darkMode={ctx?.args.darkMode} size="xsmall">
87-
Trigger
88-
</Button>
89-
}
90-
/>
91-
</div>
90+
<LeafyGreenProvider darkMode={ctx?.args.darkMode}>
91+
<div
92+
className={css`
93+
width: 240px;
94+
height: 120px;
95+
display: flex;
96+
align-items: center;
97+
justify-content: center;
98+
`}
99+
>
100+
<Instance trigger={<Button size="xsmall">Trigger</Button>} />
101+
</div>
102+
</LeafyGreenProvider>
92103
),
93104
},
94105
},
95106
};
96107
export default meta;
97108

109+
const TemplateComponent: StoryFn<TooltipProps> = (args: TooltipProps) => (
110+
<div
111+
className={css`
112+
padding: 100px;
113+
`}
114+
>
115+
<Tooltip
116+
trigger={<Button size={Size.XSmall}>{args.triggerEvent} me!</Button>}
117+
{...args}
118+
/>
119+
</div>
120+
);
121+
98122
export const LiveExample: StoryObj<TooltipProps> = {
123+
render: TemplateComponent,
99124
parameters: {
100125
chromatic: {
101126
disableSnapshot: true,
102127
},
103128
},
104-
render: ({ darkMode, ...args }: TooltipProps) => (
105-
<div
106-
className={css`
107-
padding: 100px;
108-
`}
109-
>
110-
<Tooltip
111-
trigger={<Button size={Size.XSmall}>{args.triggerEvent} me!</Button>}
112-
darkMode={darkMode}
113-
{...args}
114-
/>
115-
</div>
116-
),
117129
};
118130

119131
export const Controlled: StoryObj<TooltipProps> = {
120-
...LiveExample,
132+
render: TemplateComponent,
121133
args: {
122-
...LiveExample.args,
123134
open: true,
124135
},
136+
parameters: {
137+
chromatic: {
138+
disableSnapshot: true,
139+
},
140+
},
125141
};
126142

127143
export const HoverTrigger: StoryObj<TooltipProps> = {
144+
render: TemplateComponent,
128145
args: {
129146
triggerEvent: TriggerEvent.Hover,
130147
},
131-
render: LiveExample.render,
132-
play: async ({ canvasElement, args }) => {
148+
play: async ({
149+
canvasElement,
150+
args,
151+
}: {
152+
canvasElement: HTMLElement;
153+
args: TooltipProps;
154+
}) => {
133155
const trigger = within(canvasElement).getByRole('button');
134156

135157
userEvent.hover(trigger);
@@ -144,11 +166,17 @@ export const HoverTrigger: StoryObj<TooltipProps> = {
144166
};
145167

146168
export const HoverTriggerUnhover: StoryObj<TooltipProps> = {
169+
render: TemplateComponent,
147170
args: {
148171
triggerEvent: TriggerEvent.Hover,
149172
},
150-
render: LiveExample.render,
151-
play: async ({ canvasElement, args }) => {
173+
play: async ({
174+
canvasElement,
175+
args,
176+
}: {
177+
canvasElement: HTMLElement;
178+
args: TooltipProps;
179+
}) => {
152180
const trigger = within(canvasElement).getByRole('button');
153181
let tooltip: HTMLElement;
154182

@@ -168,11 +196,17 @@ export const HoverTriggerUnhover: StoryObj<TooltipProps> = {
168196
};
169197

170198
export const ClickTrigger: StoryObj<TooltipProps> = {
199+
render: TemplateComponent,
171200
args: {
172201
triggerEvent: TriggerEvent.Click,
173202
},
174-
render: LiveExample.render,
175-
play: async ({ canvasElement, args }) => {
203+
play: async ({
204+
canvasElement,
205+
args,
206+
}: {
207+
canvasElement: HTMLElement;
208+
args: TooltipProps;
209+
}) => {
176210
const trigger = within(canvasElement).getByRole('button');
177211

178212
userEvent.click(trigger);
@@ -209,7 +243,13 @@ export const InitialOpen: StoryObj<TooltipProps> = {
209243
</div>
210244
);
211245
},
212-
play: async ({ canvasElement, args }) => {
246+
play: async ({
247+
canvasElement,
248+
args,
249+
}: {
250+
canvasElement: HTMLElement;
251+
args: TooltipProps;
252+
}) => {
213253
await waitFor(async () => {
214254
const tooltip = await within(canvasElement).findByText(
215255
args.children as string,
@@ -220,7 +260,7 @@ export const InitialOpen: StoryObj<TooltipProps> = {
220260
};
221261

222262
export const WithLeafyGreenChildren: StoryObj<TooltipProps> = {
223-
...LiveExample,
263+
render: TemplateComponent,
224264
args: {
225265
initialOpen: true,
226266
children: (
@@ -380,7 +420,13 @@ export const ScrollableContainer: StoryObj<TooltipScrollableProps> = {
380420
</div>
381421
);
382422
},
383-
play: async ({ canvasElement, args }) => {
423+
play: async ({
424+
canvasElement,
425+
args,
426+
}: {
427+
canvasElement: HTMLElement;
428+
args: TooltipProps;
429+
}) => {
384430
const container = within(canvasElement).getByTestId('scrollable-container');
385431
const trigger = within(canvasElement).getByRole('button');
386432
userEvent.click(trigger);
@@ -396,3 +442,17 @@ export const ScrollableContainer: StoryObj<TooltipScrollableProps> = {
396442
});
397443
},
398444
};
445+
446+
export const LightMode: StoryObj<TooltipProps> = {
447+
render: TemplateComponent,
448+
args: {
449+
darkMode: false,
450+
},
451+
};
452+
453+
export const DarkMode: StoryObj<TooltipProps> = {
454+
render: TemplateComponent,
455+
args: {
456+
darkMode: true,
457+
},
458+
};

0 commit comments

Comments
 (0)