From 66758dc05eaf97a3c771819f8703f8d499134d2e Mon Sep 17 00:00:00 2001 From: Pavel Klibani Date: Mon, 12 Feb 2024 17:01:27 +0100 Subject: [PATCH] Feat(web-twig): Tooltip can be opened by hover --- .../assets/scripts/tooltip-advanced-usage.ts | 2 -- .../scripts/tooltip-dismissible-via-js.ts | 31 ++++++++++--------- .../Resources/components/Tooltip/README.md | 27 ++++++++-------- .../components/Tooltip/Tooltip.stories.twig | 4 +++ .../components/Tooltip/TooltipPopover.twig | 17 +++++----- .../stories/TooltipDismissibleViaJS.twig | 10 ++++-- .../Tooltip/stories/TooltipEnableHover.twig | 18 +++++++++++ .../Tooltip/stories/TooltipIcon.twig | 2 +- 8 files changed, 72 insertions(+), 39 deletions(-) create mode 100644 packages/web-twig/src/Resources/components/Tooltip/stories/TooltipEnableHover.twig diff --git a/apps/web-twig-demo/assets/scripts/tooltip-advanced-usage.ts b/apps/web-twig-demo/assets/scripts/tooltip-advanced-usage.ts index 731c037ab0..0ebbb41db5 100644 --- a/apps/web-twig-demo/assets/scripts/tooltip-advanced-usage.ts +++ b/apps/web-twig-demo/assets/scripts/tooltip-advanced-usage.ts @@ -9,8 +9,6 @@ const selectFallback = document.getElementById('my-advanced-select-fallback') as const tooltip = Tooltip.getOrCreateInstance(document.getElementById('my-advanced-tooltip')); -tooltip.show(); - checkboxFlip.addEventListener('change', () => tooltip.updateConfig({ enableFlipping: checkboxFlip.checked })); checkboxFlipCrossAxis.addEventListener('change', () => { diff --git a/apps/web-twig-demo/assets/scripts/tooltip-dismissible-via-js.ts b/apps/web-twig-demo/assets/scripts/tooltip-dismissible-via-js.ts index 879d13cb58..8fea8d1cbb 100644 --- a/apps/web-twig-demo/assets/scripts/tooltip-dismissible-via-js.ts +++ b/apps/web-twig-demo/assets/scripts/tooltip-dismissible-via-js.ts @@ -1,21 +1,24 @@ import { Tooltip } from '@lmc-eu/spirit-web/src/js/index.esm'; -const myTooltipEl = document.getElementById('my-dismissible-tooltip2'); +const buttonId = 'my-dismissible-button'; +const tooltipId = 'my-dismissible-tooltip-with-floating-ui'; +const storageName = 'show-tooltip'; +const myTooltipEl = document.getElementById(tooltipId); const myTooltip = new Tooltip(myTooltipEl); -if (!window.localStorage.getItem('my-tooltip-twig')) { - myTooltip.show(); +// show tooltip if it was toggled +if (window.localStorage.getItem(storageName)) { + myTooltip.toggle(); } -document.getElementById('my-dismissible-button').addEventListener('click', () => { - myTooltip.show(); - window.localStorage.removeItem('my-tooltip-twig'); -}); +// tooltip trigger button +document.getElementById(buttonId).addEventListener('click', () => { + const isToggled = window.localStorage.getItem(storageName); + const isShown = myTooltip.isShown(); -document - .getElementById('my-dismissible-tooltip2') - .querySelector('button') - .addEventListener('click', () => { - myTooltip.hide(); - window.localStorage.setItem('my-tooltip-twig', 'true'); - }); + if (isToggled && !isShown) { + window.localStorage.removeItem(storageName); + } else { + window.localStorage.setItem(storageName, 'true'); + } +}); diff --git a/packages/web-twig/src/Resources/components/Tooltip/README.md b/packages/web-twig/src/Resources/components/Tooltip/README.md index e498686158..6b261936a0 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/README.md +++ b/packages/web-twig/src/Resources/components/Tooltip/README.md @@ -139,19 +139,20 @@ Advanced floating functionality is provided by JavaScript plugin and by [Floatin #### API -| Attribute | Type | Default | Required | Description | -| ------------------------------- | -------------------------------------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `closeLabel` | `string` | `Close` | ✕ | Close label | -| `enableFlipping` | `bool` | true | ✕ | Enables [flipping][floating-ui-flip] of the element’s placement when it starts to overflow its boundary area. For example `top` can be flipped to `bottom`. | -| `enableFlippingCrossAxis` | `bool` | true | ✕ | Enables flipping on the [cross axis][floating-ui-flip-cross-axis], the axis perpendicular to main axis. For example `top-end` can be flipped to the `top-start`. | -| `enableHover` | `bool` | false | ✕ | Enables hover functionality when the cursor is positioned over the trigger. | -| `enableShifting` | `bool` | true | ✕ | Enables [shifting][floating-ui-shift] of the element to keep it inside the boundary area by adjusting its position. | -| `enableSizing` | `bool` | true | ✕ | Enables [sizing][floating-ui-size] of the element to keep it inside the boundary area by setting the max width. | -| `flipFallbackAxisSideDirection` | ["none" \| "start" \| "end"] | "none" | ✕ | Whether to allow [fallback to the opposite axis][floating-ui-flip-fallback-axis-side-direction] if no placements along the preferred placement axis fit, and if so, which side direction along that axis to choose. If necessary, it will fallback to the other direction. | -| `flipFallbackPlacements` | `string` | - | ✕ | This describes a list of [explicit placements][floating-ui-flip-fallback-placements] to try if the initial placement doesn’t fit on the axes in which overflow is checked. For example you can set `"top, right, bottom"` | -| `id` | `string` | - | ✔ | Tooltip id | -| `isDismissible` | `bool` | false | ✕ | Make tooltip dismissible | -| `placement` | [Placement Dictionary][dictionary-placement] | "bottom" | ✕ | Placement of tooltip | +| Attribute | Type | Default | Required | Description | +| ------------------------------- | -------------------------------------------- | -------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `closeLabel` | `string` | `Close` | ✕ | Close label | +| `enableFlipping` | `bool` | true | ✕ | Enables [flipping][floating-ui-flip] of the element’s placement when it starts to overflow its boundary area. For example `top` can be flipped to `bottom`. | +| `enableFlippingCrossAxis` | `bool` | true | ✕ | Enables flipping on the [cross axis][floating-ui-flip-cross-axis], the axis perpendicular to main axis. For example `top-end` can be flipped to the `top-start`. | +| `enableHover` | `bool` | false | ✕ | Enables hover functionality when the cursor is positioned over the trigger. | +| `enableShifting` | `bool` | true | ✕ | Enables [shifting][floating-ui-shift] of the element to keep it inside the boundary area by adjusting its position. | +| `enableSizing` | `bool` | true | ✕ | Enables [sizing][floating-ui-size] of the element to keep it inside the boundary area by setting the max width. | +| `flipFallbackAxisSideDirection` | ["none" \| "start" \| "end"] | "none" | ✕ | Whether to allow [fallback to the opposite axis][floating-ui-flip-fallback-axis-side-direction] if no placements along the preferred placement axis fit, and if so, which side direction along that axis to choose. If necessary, it will fallback to the other direction. | +| `flipFallbackPlacements` | `string` | - | ✕ | This describes a list of [explicit placements][floating-ui-flip-fallback-placements] to try if the initial placement doesn’t fit on the axes in which overflow is checked. For example you can set `"top, right, bottom"` | +| `id` | `string` | - | ✔ | Tooltip id | +| `isDismissible` | `bool` | false | ✕ | Make tooltip dismissible | +| `placement` | [Placement Dictionary][dictionary-placement] | "bottom" | ✕ | Placement of tooltip | +| `triggers` | string | "click, hover" | ✕ | How tooltip is triggered: click, hover. You may pass multiple triggers; separate them with a comma. | On top of the API options, the components accept [additional attributes][readme-additional-attributes]. If you need more control over the styling of a component, you can use [style props][readme-style-props] diff --git a/packages/web-twig/src/Resources/components/Tooltip/Tooltip.stories.twig b/packages/web-twig/src/Resources/components/Tooltip/Tooltip.stories.twig index 7962597faf..6a88f61e87 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/Tooltip.stories.twig +++ b/packages/web-twig/src/Resources/components/Tooltip/Tooltip.stories.twig @@ -30,6 +30,10 @@ {% include '@components/Tooltip/stories/TooltipDismissibleViaJS.twig' %} + + {% include '@components/Tooltip/stories/TooltipEnableHover.twig' %} + + {% include '@components/Tooltip/stories/TooltipIcon.twig' %} diff --git a/packages/web-twig/src/Resources/components/Tooltip/TooltipPopover.twig b/packages/web-twig/src/Resources/components/Tooltip/TooltipPopover.twig index dfc2ce0c66..ca42916770 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/TooltipPopover.twig +++ b/packages/web-twig/src/Resources/components/Tooltip/TooltipPopover.twig @@ -1,8 +1,6 @@ {# API #} {%- set props = props | default([]) -%} {%- set _closeLabel = props.closeLabel | default('Close') -%} -{%- set _id = props.id | default(null) -%} -{%- set _isDismissible = props.isDismissible | default(false) -%} {%- set _enableControlledPlacement = props.enableControlledPlacement | default(false) -%} {%- set _enableFlipping = props.enableFlipping | default(null) -%} {%- set _enableFlippingCrossAxis = props.enableFlippingCrossAxis | default(null) -%} @@ -10,7 +8,10 @@ {%- set _enableSizing = props.enableSizing | default(null) -%} {%- set _flipFallbackAxisSideDirection = props.flipFallbackAxisSideDirection | default(null) -%} {%- set _flipFallbackPlacements = props.flipFallbackPlacements | default(null) -%} +{%- set _id = props.id | default(null) -%} +{%- set _isDismissible = props.isDismissible | default(false) -%} {%- set _placement = props.placement | default('bottom') -%} +{%- set _trigger = props.trigger | default('click, hover') -%} {# Class names #} {%- set _arrowClassName = _spiritClassPrefix ~ 'Tooltip__arrow' -%} @@ -24,17 +25,18 @@ {%- set _enableShiftingValue = _enableShifting ? 'true' : 'false' -%} {%- set _enableSizingValue = _enableSizing ? 'true' : 'false' -%} -{%- set _idAttr = _id ? 'id="' ~ _id | escape('html_attr') ~ '"' : null -%} {%- set _ariaControlsAttr = _id ? 'aria-controls="' ~ _id | escape('html_attr') ~ '"' : null -%} -{%- set _dataPlacementAttr = _placement ? 'data-spirit-placement="' ~ _placement | escape('html_attr') ~ '"' : null -%} +{%- set _dataEnableControlledPlacement = _enableControlledPlacement ? 'data-spirit-placement-controlled' : null -%} {%- set _dataEnableFlippingAttr = _enableFlipping and _enableControlledPlacement ? 'data-spirit-enable-flipping="' ~ _enableFlippingValue ~ '"' : null -%} {%- set _dataEnableFlippingCrossAxisAttr = _enableFlippingCrossAxis and _enableControlledPlacement ? 'data-spirit-enable-flipping-cross-axis="' ~ _enableFlippingCrossAxisValue ~ '"' : null -%} -{%- set _dataFillFallbackAxisSideDirectionAttr = _flipFallbackAxisSideDirection and _enableControlledPlacement ? 'data-spirit-flip-fallback-axis-side-direction="' ~ _flipFallbackAxisSideDirection | escape('html_attr') ~ '"' : null -%} -{%- set _dataFlipFallbackPlacementsAttr = _flipFallbackPlacements and _enableControlledPlacement ? 'data-spirit-flip-fallback-placements="' ~ _flipFallbackPlacements | escape('html_attr') ~ '"' : null -%} {%- set _dataEnableShiftingAttr = _enableShifting and _enableControlledPlacement ? 'data-spirit-enable-shifting="' ~ _enableShiftingValue ~ '"' : null -%} {%- set _dataEnableSizingAttr = _enableSizing and _enableControlledPlacement ? 'data-spirit-enable-sizing="' ~ _enableSizingValue ~ '"' : null -%} -{%- set _dataEnableControlledPlacement = _enableControlledPlacement ? 'data-spirit-placement-controlled' : null -%} +{%- set _dataFillFallbackAxisSideDirectionAttr = _flipFallbackAxisSideDirection and _enableControlledPlacement ? 'data-spirit-flip-fallback-axis-side-direction="' ~ _flipFallbackAxisSideDirection | escape('html_attr') ~ '"' : null -%} +{%- set _dataFlipFallbackPlacementsAttr = _flipFallbackPlacements and _enableControlledPlacement ? 'data-spirit-flip-fallback-placements="' ~ _flipFallbackPlacements | escape('html_attr') ~ '"' : null -%} +{%- set _dataPlacementAttr = _placement ? 'data-spirit-placement="' ~ _placement | escape('html_attr') ~ '"' : null -%} {%- set _dataTargetAttr = _id ? 'data-spirit-target="#' ~ _id | escape('html_attr') ~ '"' : null -%} +{%- set _dataTriggerAttr = _enableControlledPlacement ? 'data-spirit-trigger="' ~ _trigger ~ '"' : null -%} +{%- set _idAttr = _id ? 'id="' ~ _id | escape('html_attr') ~ '"' : null -%} {# Miscellaneous #} {%- set _styleProps = useStyleProps(props) -%} @@ -54,6 +56,7 @@ {{ _dataFlipFallbackPlacementsAttr | raw }} {{ _dataEnableShiftingAttr | raw }} {{ _dataEnableSizingAttr | raw }} + {{ _dataTriggerAttr | raw }} > {% block content %}{% endblock %} {% if _isDismissible == 'true' %} diff --git a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipDismissibleViaJS.twig b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipDismissibleViaJS.twig index 7a968cc38b..03cf1d5045 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipDismissibleViaJS.twig +++ b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipDismissibleViaJS.twig @@ -3,14 +3,20 @@

- + Close me diff --git a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipEnableHover.twig b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipEnableHover.twig new file mode 100644 index 0000000000..ea36c4a11f --- /dev/null +++ b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipEnableHover.twig @@ -0,0 +1,18 @@ + + + + Hello there! + + diff --git a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipIcon.twig b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipIcon.twig index 88ba2c215e..beffab0ffb 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipIcon.twig +++ b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipIcon.twig @@ -21,4 +21,4 @@ Close me - \ No newline at end of file +