diff --git a/apps/web-twig-demo/assets/scripts/tooltip-advanced-usage.ts b/apps/web-twig-demo/assets/scripts/tooltip-advanced-usage.ts new file mode 100644 index 0000000000..731c037ab0 --- /dev/null +++ b/apps/web-twig-demo/assets/scripts/tooltip-advanced-usage.ts @@ -0,0 +1,40 @@ +import { Tooltip } from '@lmc-eu/spirit-web/src/js/index.esm'; + +const checkboxFlip = document.getElementById('my-advanced-flip') as HTMLInputElement; +const checkboxFlipCrossAxis = document.getElementById('my-advanced-flip-cross-axis') as HTMLInputElement; +const checkboxShift = document.getElementById('my-advanced-shift') as HTMLInputElement; +const checkboxSize = document.getElementById('my-advanced-size') as HTMLInputElement; +const select = document.getElementById('my-advanced-select') as HTMLSelectElement; +const selectFallback = document.getElementById('my-advanced-select-fallback') as HTMLSelectElement; + +const tooltip = Tooltip.getOrCreateInstance(document.getElementById('my-advanced-tooltip')); + +tooltip.show(); + +checkboxFlip.addEventListener('change', () => tooltip.updateConfig({ enableFlipping: checkboxFlip.checked })); + +checkboxFlipCrossAxis.addEventListener('change', () => { + tooltip.updateConfig({ enableFlippingCrossAxis: checkboxFlipCrossAxis.checked }); +}); + +checkboxShift.addEventListener('change', () => { + tooltip.updateConfig({ enableShifting: checkboxShift.checked }); +}); + +checkboxSize.addEventListener('change', () => { + tooltip.updateConfig({ enableSizing: checkboxSize.checked }); +}); + +select.addEventListener('change', () => { + tooltip.updateConfig({ placement: select.value }); +}); + +selectFallback.addEventListener('change', () => { + tooltip.updateConfig({ flipFallbackPlacements: selectFallback.value }); +}); + +const viewport = document.getElementById('my-advanced-viewport'); +const content = document.getElementById('my-advanced-content'); + +viewport.scrollLeft = (content.offsetWidth - viewport.offsetWidth) / 2; +viewport.scrollTop = (content.offsetHeight - viewport.offsetHeight) / 2; 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 c2f8014bc5..879d13cb58 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,4 +1,4 @@ -import Tooltip from '@lmc-eu/spirit-web/src/js/Tooltip'; +import { Tooltip } from '@lmc-eu/spirit-web/src/js/index.esm'; const myTooltipEl = document.getElementById('my-dismissible-tooltip2'); const myTooltip = new Tooltip(myTooltipEl); diff --git a/apps/web-twig-demo/package.json b/apps/web-twig-demo/package.json index ab2a094284..7cb15da035 100644 --- a/apps/web-twig-demo/package.json +++ b/apps/web-twig-demo/package.json @@ -8,10 +8,11 @@ "@babel/core": "7.23.7", "@babel/preset-env": "7.23.7", "@csstools/normalize.css": "12.1.1", + "@floating-ui/dom": "^1.5.4", "@hotwired/stimulus": "3.2.2", - "@lmc-eu/spirit-web": "1.6.0", - "@lmc-eu/spirit-form-validations": "1.0.9", "@lmc-eu/spirit-demo": "0.1.0", + "@lmc-eu/spirit-form-validations": "1.0.9", + "@lmc-eu/spirit-web": "1.6.0", "@symfony/stimulus-bridge": "3.2.2", "@symfony/webpack-encore": "4.5.0", "core-js": "3.35.0", diff --git a/apps/web-twig-demo/webpack.config.js b/apps/web-twig-demo/webpack.config.js index 3d74ef8377..7cc9dc1197 100644 --- a/apps/web-twig-demo/webpack.config.js +++ b/apps/web-twig-demo/webpack.config.js @@ -1,3 +1,4 @@ +const path = require('path'); // eslint-disable-next-line import/no-unresolved const Encore = require('@symfony/webpack-encore'); // eslint-disable-next-line import/no-extraneous-dependencies @@ -28,6 +29,7 @@ Encore .addEntry('fileUploaderMetaData', './assets/scripts/file-uploader-meta-data.ts') .addEntry('formValidations', './assets/scripts/form-validations.ts') .addEntry('tooltipDismissibleViaJS', './assets/scripts/tooltip-dismissible-via-js.ts') + .addEntry('tooltipAdvancedUsage', './assets/scripts/tooltip-advanced-usage.ts') // enables the Symfony UX Stimulus bridge (used in assets/bootstrap.js) // .enableStimulusBridge('./assets/controllers.json') @@ -93,4 +95,10 @@ Encore // .enableIntegrityHashes(Encore.isProduction()) ; -module.exports = Encore.getWebpackConfig(); +const config = Encore.getWebpackConfig(); + +config.resolve.alias = { + '@floating-ui/dom': path.resolve(__dirname, 'node_modules/@floating-ui/dom'), +}; + +module.exports = config; diff --git a/apps/web-twig-demo/yarn.lock b/apps/web-twig-demo/yarn.lock index dc67122ea1..ebb33a0c8e 100644 --- a/apps/web-twig-demo/yarn.lock +++ b/apps/web-twig-demo/yarn.lock @@ -1150,6 +1150,26 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== +"@floating-ui/core@^1.5.3": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.3.tgz#b6aa0827708d70971c8679a16cf680a515b8a52a" + integrity sha512-O0WKDOo0yhJuugCx6trZQj5jVJ9yR0ystG2JaNAemYUWce+pmM6WUEFIibnWyEJKdrDxhm75NoSRME35FNaM/Q== + dependencies: + "@floating-ui/utils" "^0.2.0" + +"@floating-ui/dom@^1.5.4": + version "1.5.4" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.4.tgz#28df1e1cb373884224a463235c218dcbd81a16bb" + integrity sha512-jByEsHIY+eEdCjnTVu+E3ephzTOzkQ8hgUfGwos+bg7NlH33Zc5uO+QHz1mrQUOgIKKDD1RtS201P9NvAfq3XQ== + dependencies: + "@floating-ui/core" "^1.5.3" + "@floating-ui/utils" "^0.2.0" + +"@floating-ui/utils@^0.2.0": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" + integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== + "@hotwired/stimulus-webpack-helpers@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@hotwired/stimulus-webpack-helpers/-/stimulus-webpack-helpers-1.0.1.tgz#4cd74487adeca576c9865ac2b9fe5cb20cef16dd" @@ -1966,25 +1986,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001449: - version "1.0.30001481" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz#f58a717afe92f9e69d0e35ff64df596bfad93912" - integrity sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ== - -caniuse-lite@^1.0.30001503: - version "1.0.30001517" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz#90fabae294215c3495807eb24fc809e11dc2f0a8" - integrity sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA== - -caniuse-lite@^1.0.30001541: - version "1.0.30001553" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001553.tgz#e64e7dc8fd4885cd246bb476471420beb5e474b5" - integrity sha512-N0ttd6TrFfuqKNi+pMgWJTb9qrdJu4JSpgPFLe/lrD19ugC6fZgF0pUewRowDwzdDnb9V41mFcdlYgl/PyKf4A== - -caniuse-lite@^1.0.30001565: - version "1.0.30001570" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz#b4e5c1fa786f733ab78fc70f592df6b3f23244ca" - integrity sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001503, caniuse-lite@^1.0.30001541, caniuse-lite@^1.0.30001565: + version "1.0.30001579" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz" + integrity sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA== chalk@^2.0.0, chalk@^2.3.2, chalk@^2.4.2: version "2.4.2" diff --git a/packages/web-twig/src/Resources/components/Tooltip/README.md b/packages/web-twig/src/Resources/components/Tooltip/README.md index 421ad6795b..789cbf6b69 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/README.md +++ b/packages/web-twig/src/Resources/components/Tooltip/README.md @@ -72,10 +72,89 @@ These attributes will be passed to the topmost HTML element of the component. ### TooltipWrapper +⚠️ `TooltipWrapper` component is [deprecated] and will be renamed to the `Tooltip` in the next major version. + You can add `id`, `data-*` or `aria-*` attributes to further extend the component's descriptiveness and accessibility. Also, UNSAFE styling props are available, see the [Escape hatches][escape-hatches] section in README to learn how and when to use them. +### TooltipPopover + +#### Usage with the Advanced Floating Functionality + +To enable the advanced floating functionality, you need to have activated feature flag `spirit-feature-tooltip-enable-data-placement` on any parent element. +This requirement will be removed in future major version. + +For more info about feature flags, see main [README][readme-feature-flags]. + +Advanced floating functionality is provided by JavaScript plugin and by [Floating UI][floating-ui] library. + +#### Basic + +```html +
+ + + Hello there! + +
+; +``` + +#### Dismissible + +Add `isDismissible` prop to `TooltipPopover` component. +there will be automatically displayed close button in `TooltipPopover`` component + +```html +
+ + + Close me + +
+``` + +#### Full Advanced Usage + +```html +
+ + + + Close me + + +
+``` + +#### 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`. | +| `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 | + ## JavaScript Plugin For full functionality, you need to provide Spirit JavaScript: @@ -90,8 +169,16 @@ Or, feel free to write the controlling script yourself. πŸ‘‰ Check the [component's docs in the web package][web-js-api] to see the full documentation and API of the plugin. +[dictionary-placement]: https://github.com/lmc-eu/spirit-design-system/blob/main/docs/DICTIONARIES.md#placement +[escape-hatches]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-twig/README.md#escape-hatches +[floating-ui-flip-cross-axis]: https://floating-ui.com/docs/flip#crossaxis +[floating-ui-flip-fallback-axis-side-direction]: https://floating-ui.com/docs/flip#fallbackaxissidedirection +[floating-ui-flip-fallback-placements]: https://floating-ui.com/docs/flip#fallbackplacements +[floating-ui-flip]: https://floating-ui.com/docs/flip +[floating-ui-shift]: https://floating-ui.com/docs/shift +[floating-ui-size]: https://floating-ui.com/docs/size +[floating-ui]: https://floating-ui.com +[readme-feature-flags]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/README.md#feature-flags +[tooltip]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web/src/scss/components/Tooltip [web-js-api]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/src/scss/components/Tooltip/README.md#javascript-api [web-readme]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/README.md -[tooltip]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web/src/scss/components/Tooltip -[dictionary-placement]: https://github.com/lmc-eu/spirit-design-system/tree/main/docs/DICTIONARIES.md#placement -[escape-hatches]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web-twig/README.md#escape-hatches 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 4cb6f43ea2..b703a709ea 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/Tooltip.stories.twig +++ b/packages/web-twig/src/Resources/components/Tooltip/Tooltip.stories.twig @@ -14,6 +14,10 @@ {% include '@components/Tooltip/stories/TooltipOnHover.twig' %} + + {% include '@components/Tooltip/stories/TooltipWithJsPlugin.twig' %} + + {% include '@components/Tooltip/stories/TooltipClickable.twig' %} @@ -22,11 +26,11 @@ {% include '@components/Tooltip/stories/TooltipDismissible.twig' %} - + {% include '@components/Tooltip/stories/TooltipDismissibleViaJS.twig' %} - + {% include '@components/Tooltip/stories/TooltipFloatingUI.twig' %} diff --git a/packages/web-twig/src/Resources/components/Tooltip/Tooltip.twig b/packages/web-twig/src/Resources/components/Tooltip/Tooltip.twig index ba7122d1e7..ef0c5a5d70 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/Tooltip.twig +++ b/packages/web-twig/src/Resources/components/Tooltip/Tooltip.twig @@ -79,6 +79,8 @@ {% deprecated 'Tooltip: Non-flow-relative values (eg. "' ~ _placement ~ '") in "placement" property are deprecated and will be removed in the next major version. Use flow-relative (eg. "' ~ deprecatedPlacements[_placement] ~ '") instead.' %} {% endif %} +{% deprecated 'Tooltip: Implmentation of this component is deprecated and will be replaced with the implementation of the TooltipPopover in the next major version. Please, use it instead.' %} +
prop is not same as('id')) -%} + +
+ {% block content %}{% endblock %} + {% if _isDismissible == 'true' %} + + {% endif %} + +
diff --git a/packages/web-twig/src/Resources/components/Tooltip/TooltipWrapper.twig b/packages/web-twig/src/Resources/components/Tooltip/TooltipWrapper.twig index 4a3f8e2419..6001509d55 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/TooltipWrapper.twig +++ b/packages/web-twig/src/Resources/components/Tooltip/TooltipWrapper.twig @@ -8,10 +8,14 @@ {%- set _styleProps = useStyleProps(props) -%} {%- set _classNames = [ _rootClassName, _styleProps.className ] -%} +{# Deprecations #} +{% deprecated 'TooltipWrapper: This component will be renamed to Tooltip in the next major version.' %} +
{% block content %}{% endblock %}
diff --git a/packages/web-twig/src/Resources/components/Tooltip/__tests__/__fixtures__/tooltipPopover.twig b/packages/web-twig/src/Resources/components/Tooltip/__tests__/__fixtures__/tooltipPopover.twig new file mode 100644 index 0000000000..81c0db6a46 --- /dev/null +++ b/packages/web-twig/src/Resources/components/Tooltip/__tests__/__fixtures__/tooltipPopover.twig @@ -0,0 +1,18 @@ +Hello there! + + + + Hello there! + diff --git a/packages/web-twig/src/Resources/components/Tooltip/__tests__/__snapshots__/tooltipPopover.twig.snap.html b/packages/web-twig/src/Resources/components/Tooltip/__tests__/__snapshots__/tooltipPopover.twig.snap.html new file mode 100644 index 0000000000..aa840ef489 --- /dev/null +++ b/packages/web-twig/src/Resources/components/Tooltip/__tests__/__snapshots__/tooltipPopover.twig.snap.html @@ -0,0 +1,19 @@ + + + + + + + +
+ Hello there! +
+ + +
+ Hello there! +
+ + diff --git a/packages/web-twig/src/Resources/components/Tooltip/__tests__/__snapshots__/tooltipWrapper.twig.snap.html b/packages/web-twig/src/Resources/components/Tooltip/__tests__/__snapshots__/tooltipWrapper.twig.snap.html index b0d42cbde1..3aa1d879ee 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/__tests__/__snapshots__/tooltipWrapper.twig.snap.html +++ b/packages/web-twig/src/Resources/components/Tooltip/__tests__/__snapshots__/tooltipWrapper.twig.snap.html @@ -5,7 +5,7 @@ -
+
content
diff --git a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipClickable.twig b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipClickable.twig index 6eb5672680..c84abb0d00 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipClickable.twig +++ b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipClickable.twig @@ -1,3 +1,5 @@ +

Without Floating UI

+ + + +
+ I have an externally-triggered tooltip +
+ + Hello there! + +
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 9920a883e1..c766aa987c 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipDismissibleViaJS.twig +++ b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipDismissibleViaJS.twig @@ -1,12 +1,19 @@

- Saves data to local storage. + Saves data to local storage.

- - - - Close me - + + + + Close me + {{ encore_entry_script_tags('tooltipDismissibleViaJS') }} diff --git a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipFloatingUI.twig b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipFloatingUI.twig index bd0e280436..d67bbdfc4e 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipFloatingUI.twig +++ b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipFloatingUI.twig @@ -1,30 +1,39 @@

- The following example is using external library Floating UI. - Try scrolling the frame or resizing the window to see how the Tooltip behaves. The Floating UI - library is trying to keep the Tooltip in the viewport and it is also flipping, shifting and - resizing the Tooltip when it is not possible to keep it in the viewport. + Try scrolling the frame or resizing the window to see how the Tooltip behaves. + The Floating UI library is trying to keep the Tooltip in the viewport and it is also flipping, + shifting and resizing the Tooltip when it is not possible to keep it in the viewport.

- - Please note that the Floating UI library is trying to point the arrow to the center - of the trigger element. This is not possible to achieve in CSS only so our behavior - is slightly different for tooltips not using Floating UI. - - - + + + + + + + + + +
- - - This long tooltip is flipping, resizing and shifting to stay in the viewport. - Also its arrow is always trying to point to the center of the trigger. - + + + + This long tooltip is flipping, resizing and shifting to stay in the viewport. + Also its arrow is always trying to point to the center of the trigger. + +
- +{{ encore_entry_script_tags('tooltipAdvancedUsage') }} diff --git a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipPlacements.twig b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipPlacements.twig index 646d55296a..73e1545a80 100644 --- a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipPlacements.twig +++ b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipPlacements.twig @@ -1,5 +1,5 @@
- + @@ -28,13 +28,13 @@ - + Click
the dots!
- + bottom - +
diff --git a/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipWithJsPlugin.twig b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipWithJsPlugin.twig new file mode 100644 index 0000000000..9e9768a105 --- /dev/null +++ b/packages/web-twig/src/Resources/components/Tooltip/stories/TooltipWithJsPlugin.twig @@ -0,0 +1,39 @@ +

Without Floating UI

+ + + + + This long tooltip is not flipping to stay in the viewport. + + + +

With Floating UI and placement fallbacks

+ + + + + This long tooltip is flipping to stay in the viewport. + + diff --git a/packages/web-twig/src/Resources/twig-components/tooltipPopover.twig b/packages/web-twig/src/Resources/twig-components/tooltipPopover.twig new file mode 100644 index 0000000000..5a514f5edf --- /dev/null +++ b/packages/web-twig/src/Resources/twig-components/tooltipPopover.twig @@ -0,0 +1 @@ +{% extends '@spirit/Tooltip/TooltipPopover.twig' %} diff --git a/packages/web/src/js/Tooltip.ts b/packages/web/src/js/Tooltip.ts index b64042b938..4eb5b17c6f 100644 --- a/packages/web/src/js/Tooltip.ts +++ b/packages/web/src/js/Tooltip.ts @@ -82,9 +82,11 @@ class Tooltip extends BaseComponent { } isPlacementControlled() { - const { placementControlled } = this.config as Config; + const config = this.config as Config; + const placementControlledKey = 'placementControlled'; - return placementControlled !== false; + // key can exist in the dataset but can have undefined value + return placementControlledKey in config && config[placementControlledKey] !== false; } updateConfig(newConfig: Partial) {