Skip to content

feat(tooltip): implement tooltip to beta phase #882

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

Closed
wants to merge 6 commits into from
Closed
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
5 changes: 5 additions & 0 deletions .changeset/tasty-pugs-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@qwik-ui/headless': patch
---

feat: implement a beta version of the Tooltip component
2 changes: 1 addition & 1 deletion apps/website/src/_state/component-statuses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@ export const statusByComponent: ComponentKitsStatuses = {
Select: ComponentStatus.Beta,
Separator: ComponentStatus.Beta,
Tabs: ComponentStatus.Beta,
Tooltip: ComponentStatus.Draft,
Tooltip: ComponentStatus.Beta,
},
};
19 changes: 12 additions & 7 deletions apps/website/src/components/showcase/showcase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@ export const Showcase = component$<ShowcaseProps>(({ name, ...props }) => {
const componentCodeSig = useSignal<string>();

useTask$(async () => {
// eslint-disable-next-line qwik/valid-lexical-scope
MetaGlobComponentSig.value = isDev
? await metaGlobComponents[componentPath]() // We need to call `await metaGlobComponents[componentPath]()` in development as it is `eager:false`
: metaGlobComponents[componentPath]; // We need to directly access the `metaGlobComponents[componentPath]` expression in preview/production as it is `eager:true`
componentCodeSig.value = isDev
? await rawComponents[componentPath]()
: rawComponents[componentPath];
try {
// eslint-disable-next-line qwik/valid-lexical-scope
MetaGlobComponentSig.value = isDev
? await metaGlobComponents[componentPath]() // We need to call `await metaGlobComponents[componentPath]()` in development as it is `eager:false`
: metaGlobComponents[componentPath]; // We need to directly access the `metaGlobComponents[componentPath]` expression in preview/production as it is `eager:true`
componentCodeSig.value = isDev
? await rawComponents[componentPath]()
: rawComponents[componentPath];
} catch (e) {
console.error('Unable to load path %s', componentPath, e);
throw e;
}
});

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { component$ } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';

import '../snippets/animation.css';

export default component$(() => {
return (
<Tooltip.Root gutter={4} flip>
<Tooltip.Trigger>Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel class="tooltip-animation">
Animated tooltip content here
</Tooltip.Panel>
</Tooltip.Root>
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { component$ } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';

import '../snippets/arrow-styling.css';

export default component$(() => {
return (
<Tooltip.Root gutter={4} flip>
<Tooltip.Trigger>Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel aria-label="Tooltip content" class="tooltip-arrow-styled-panel">
<Tooltip.Arrow class="tooltip-arrow-styled-arrow" width={20} height={10} />
<div>
<h3 style="margin: 0 0 10px;">Tooltip Title</h3>
<p style="margin: 0;">This tooltip has a snazzy styled arrow!</p>
</div>
</Tooltip.Panel>
</Tooltip.Root>
);
});
11 changes: 11 additions & 0 deletions apps/website/src/routes/docs/headless/tooltip/examples/auto.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { component$ } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';

export default component$(() => {
return (
<Tooltip.Root gutter={4} flip>
<Tooltip.Trigger>Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel class="tooltip-panel">Tooltip content here</Tooltip.Panel>
</Tooltip.Root>
);
});
14 changes: 14 additions & 0 deletions apps/website/src/routes/docs/headless/tooltip/examples/basic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { component$ } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';

export default component$(() => {
return (
<Tooltip.Root gutter={4} flip>
<Tooltip.Trigger>Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel aria-label="Tooltip content">
<Tooltip.Arrow width={10} height={5} />
Tooltip content here
</Tooltip.Panel>
</Tooltip.Root>
);
});
22 changes: 22 additions & 0 deletions apps/website/src/routes/docs/headless/tooltip/examples/complex.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { component$ } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';

export default component$(() => {
return (
<Tooltip.Root gutter={4} flip placement="bottom">
<Tooltip.Trigger>Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel aria-label="Complex Tooltip content">
<Tooltip.Arrow width={10} height={5} />
<div>
<h3>Tooltip Title</h3>
<p>This is a tooltip with complex HTML content, including:</p>
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
</div>
</Tooltip.Panel>
</Tooltip.Root>
);
});
13 changes: 13 additions & 0 deletions apps/website/src/routes/docs/headless/tooltip/examples/flip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { component$ } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';

export default component$(() => {
return (
<Tooltip.Root gutter={4} flip>
<Tooltip.Trigger>Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel class="tooltip-panel">
Tooltip content with flip enabled
</Tooltip.Panel>
</Tooltip.Root>
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { component$ } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';

export default component$(() => {
return (
<Tooltip.Root gutter={4} flip>
<Tooltip.Trigger>Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel class="tooltip-panel">Floating Tooltip content here</Tooltip.Panel>
</Tooltip.Root>
);
});
11 changes: 11 additions & 0 deletions apps/website/src/routes/docs/headless/tooltip/examples/gutter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { component$ } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';

export default component$(() => {
return (
<Tooltip.Root gutter={20} flip>
<Tooltip.Trigger>Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel class="tooltip-panel">Tooltip content with gutter</Tooltip.Panel>
</Tooltip.Root>
);
});
13 changes: 4 additions & 9 deletions apps/website/src/routes/docs/headless/tooltip/examples/hero.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import { component$, useStyles$ } from '@builder.io/qwik';
import { component$ } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';

export default component$(() => {
useStyles$(styles);

return (
<Tooltip.Root>
<Tooltip.Trigger class="tooltip-trigger">Hover over me</Tooltip.Trigger>
<Tooltip.Content class="tooltip-content">I'm a tooltip!</Tooltip.Content>
<Tooltip.Root gutter={4} flip>
<Tooltip.Trigger>Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel class="tooltip-panel">Tooltip content here</Tooltip.Panel>
</Tooltip.Root>
);
});

// internal
import styles from '../snippets/tooltip.css?inline';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { component$, useSignal } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';

export default component$(() => {
const tooltipState = useSignal<'open' | 'closed'>('closed');

return (
<>
<Tooltip.Root gutter={4} onOpenChange$={(e) => (tooltipState.value = e)} flip>
<Tooltip.Trigger>Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel aria-label="Tooltip content">
<Tooltip.Arrow width={10} height={5} />
Tooltip content here
</Tooltip.Panel>
</Tooltip.Root>
The tooltip is {tooltipState.value}
</>
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { component$, useSignal } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';

export default component$(() => {
const placement = useSignal<'top' | 'right' | 'bottom' | 'left'>('top');

return (
<div>
<label for="placement">Select Tooltip Placement: </label>
<select
id="placement"
value={placement.value}
onChange$={(e) =>
(placement.value = (e.target as HTMLSelectElement).value as
| 'top'
| 'right'
| 'bottom'
| 'left')
}
>
<option value="top">Top</option>
<option value="right">Right</option>
<option value="bottom">Bottom</option>
<option value="left">Left</option>
</select>

<Tooltip.Root key={placement.value} gutter={4} flip placement={placement.value}>
<Tooltip.Trigger>Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel
aria-label={`Tooltip content on the ${placement.value}`}
class="tooltip-panel"
>
Tooltip content on the {placement.value}
</Tooltip.Panel>
</Tooltip.Root>
</div>
);
});
12 changes: 12 additions & 0 deletions apps/website/src/routes/docs/headless/tooltip/examples/styling.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { component$ } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';
import '../snippets/styling.css';

export default component$(() => {
return (
<Tooltip.Root delayDuration={800} gutter={4} flip>
<Tooltip.Trigger class="custom-trigger">Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel class="custom-tooltip-panel">Tooltip content here</Tooltip.Panel>
</Tooltip.Root>
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { component$ } from '@builder.io/qwik';
import { Tooltip } from '@qwik-ui/headless';

import '../snippets/transition.css';

export default component$(() => {
return (
<Tooltip.Root gutter={4} flip>
<Tooltip.Trigger>Hover or Focus me</Tooltip.Trigger>
<Tooltip.Panel class="tooltip-transition">
Tooltip content with transition
</Tooltip.Panel>
</Tooltip.Root>
);
});
Loading
Loading