diff --git a/docs/grid-functionalities/custom-tooltip.md b/docs/grid-functionalities/custom-tooltip.md index dab0e61f9..d9563829d 100644 --- a/docs/grid-functionalities/custom-tooltip.md +++ b/docs/grid-functionalities/custom-tooltip.md @@ -13,6 +13,7 @@ - [How to delay the opening of a tooltip?](#how-to-delay-the-opening-of-a-tooltip) - [delay a tooltip with Formatter](#delay-a-tooltip-with-formatter) - [delay a Regular Tooltip](#delay-a-regular-tooltip) +- [Tooltips Outside the Grid](#tooltips-outside-the-grid) - `customTooltip` options - too many to list, consult the [CustomTooltipOption](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/column.interface.ts) interface for all possible options - [UI Sample](#ui-sample) @@ -260,6 +261,58 @@ this.columnDefinitions = [{ formatter: myFormatter }]; ``` + +### Tooltips Outside the Grid +You can use the custom tooltip plugin to display tooltips on elements outside the grid (e.g., menu items, buttons, dialogs, etc.) by enabling the `observeAllTooltips` option. This allows the plugin to observe elements anywhere in your page that have `title` or `data-slick-tooltip` attributes. + +#### Enable Global Tooltip Observation +```ts +this.gridOptions = { + externalResources: [new SlickCustomTooltip()], + customTooltip: { + observeAllTooltips: true, // enable tooltip observation outside the grid + formatter: this.tooltipFormatter, + }, +}; +``` + +#### Observe Specific Container(s) +If you want to limit tooltip observation to specific container(s), use the `observeTooltipContainer` option: + +```ts +this.gridOptions = { + externalResources: [new SlickCustomTooltip()], + customTooltip: { + observeAllTooltips: true, + observeTooltipContainer: '.my-tooltip-container', // observe only within this container + formatter: this.tooltipFormatter, + }, +}; +``` + +You can also observe multiple containers by providing a comma-separated string: +```ts +customTooltip: { + observeAllTooltips: true, + observeTooltipContainer: '.container1, .container2, #header-menu', // observe multiple containers + formatter: this.tooltipFormatter, +} +``` + +#### Using Tooltips on External Elements + +Once enabled, you can use regular `title` attributes or `data-slick-tooltip` on any element: + +```html + + + + +Info Icon +``` + +The styling and positioning will be consistent with your grid tooltips. + ### UI Sample The Export to Excel handles all characters quite well, from Latin, to Unicode and even Unicorn emoji, it all works on all browsers (`Chrome`, `Firefox`, even `IE11`, I don't have access to older versions). Here's a demo diff --git a/frameworks/angular-slickgrid/docs/grid-functionalities/custom-tooltip.md b/frameworks/angular-slickgrid/docs/grid-functionalities/custom-tooltip.md index d0c8b8712..1aa628446 100644 --- a/frameworks/angular-slickgrid/docs/grid-functionalities/custom-tooltip.md +++ b/frameworks/angular-slickgrid/docs/grid-functionalities/custom-tooltip.md @@ -13,6 +13,7 @@ - [How to delay the opening of a tooltip?](#how-to-delay-the-opening-of-a-tooltip) - [delay a tooltip with Formatter](#delay-a-tooltip-with-formatter) - [delay a Regular Tooltip](#delay-a-regular-tooltip) +- [Tooltips Outside the Grid](#tooltips-outside-the-grid) - `customTooltip` options - too many to list, consult the [CustomTooltipOption](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/column.interface.ts) interface for all possible options - [UI Sample](#ui-sample) @@ -260,6 +261,58 @@ this.columnDefinitions = [{ formatter: myFormatter }]; ``` + +### Tooltips Outside the Grid +You can use the custom tooltip plugin to display tooltips on elements outside the grid (e.g., menu items, buttons, dialogs, etc.) by enabling the `observeAllTooltips` option. This allows the plugin to observe elements anywhere in your page that have `title` or `data-slick-tooltip` attributes. + +#### Enable Global Tooltip Observation +```ts +this.gridOptions = { + externalResources: [new SlickCustomTooltip()], + customTooltip: { + observeAllTooltips: true, // enable tooltip observation outside the grid + formatter: this.tooltipFormatter, + }, +}; +``` + +#### Observe Specific Container(s) +If you want to limit tooltip observation to specific container(s), use the `observeTooltipContainer` option: + +```ts +this.gridOptions = { + externalResources: [new SlickCustomTooltip()], + customTooltip: { + observeAllTooltips: true, + observeTooltipContainer: '.my-tooltip-container', // observe only within this container + formatter: this.tooltipFormatter, + }, +}; +``` + +You can also observe multiple containers by providing a comma-separated string: +```ts +customTooltip: { + observeAllTooltips: true, + observeTooltipContainer: '.container1, .container2, #header-menu', // observe multiple containers + formatter: this.tooltipFormatter, +} +``` + +#### Using Tooltips on External Elements + +Once enabled, you can use regular `title` attributes or `data-slick-tooltip` on any element: + +```html + + + + +Info Icon +``` + +The styling and positioning will be consistent with your grid tooltips. + ### UI Sample The Export to Excel handles all characters quite well, from Latin, to Unicode and even Unicorn emoji, it all works on all browsers (`Chrome`, `Firefox`, even `IE11`, I don't have access to older versions). Here's a demo diff --git a/frameworks/aurelia-slickgrid/docs/grid-functionalities/custom-tooltip.md b/frameworks/aurelia-slickgrid/docs/grid-functionalities/custom-tooltip.md index c6e1d7fc0..1ff2298b0 100644 --- a/frameworks/aurelia-slickgrid/docs/grid-functionalities/custom-tooltip.md +++ b/frameworks/aurelia-slickgrid/docs/grid-functionalities/custom-tooltip.md @@ -13,6 +13,7 @@ - [How to delay the opening of a tooltip?](#how-to-delay-the-opening-of-a-tooltip) - [delay a tooltip with Formatter](#delay-a-tooltip-with-formatter) - [delay a Regular Tooltip](#delay-a-regular-tooltip) +- [Tooltips Outside the Grid](#tooltips-outside-the-grid) - `customTooltip` options - too many to list, consult the [CustomTooltipOption](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/column.interface.ts) interface for all possible options - [UI Sample](#ui-sample) @@ -260,6 +261,58 @@ this.columnDefinitions = [{ formatter: myFormatter }]; ``` + +### Tooltips Outside the Grid +You can use the custom tooltip plugin to display tooltips on elements outside the grid (e.g., menu items, buttons, dialogs, etc.) by enabling the `observeAllTooltips` option. This allows the plugin to observe elements anywhere in your page that have `title` or `data-slick-tooltip` attributes. + +#### Enable Global Tooltip Observation +```ts +this.gridOptions = { + externalResources: [new SlickCustomTooltip()], + customTooltip: { + observeAllTooltips: true, // enable tooltip observation outside the grid + formatter: this.tooltipFormatter, + }, +}; +``` + +#### Observe Specific Container(s) +If you want to limit tooltip observation to specific container(s), use the `observeTooltipContainer` option: + +```ts +this.gridOptions = { + externalResources: [new SlickCustomTooltip()], + customTooltip: { + observeAllTooltips: true, + observeTooltipContainer: '.my-tooltip-container', // observe only within this container + formatter: this.tooltipFormatter, + }, +}; +``` + +You can also observe multiple containers by providing a comma-separated string: +```ts +customTooltip: { + observeAllTooltips: true, + observeTooltipContainer: '.container1, .container2, #header-menu', // observe multiple containers + formatter: this.tooltipFormatter, +} +``` + +#### Using Tooltips on External Elements + +Once enabled, you can use regular `title` attributes or `data-slick-tooltip` on any element: + +```html + + + + +Info Icon +``` + +The styling and positioning will be consistent with your grid tooltips. + ### UI Sample The Export to Excel handles all characters quite well, from Latin, to Unicode and even Unicorn emoji, it all works on all browsers (`Chrome`, `Firefox`, even `IE11`, I don't have access to older versions). Here's a demo diff --git a/frameworks/slickgrid-react/docs/grid-functionalities/custom-tooltip.md b/frameworks/slickgrid-react/docs/grid-functionalities/custom-tooltip.md index ee1683c34..d08a7caac 100644 --- a/frameworks/slickgrid-react/docs/grid-functionalities/custom-tooltip.md +++ b/frameworks/slickgrid-react/docs/grid-functionalities/custom-tooltip.md @@ -13,6 +13,7 @@ - [How to delay the opening of a tooltip?](#how-to-delay-the-opening-of-a-tooltip) - [delay a tooltip with Formatter](#delay-a-tooltip-with-formatter) - [delay a Regular Tooltip](#delay-a-regular-tooltip) +- [Tooltips Outside the Grid](#tooltips-outside-the-grid) - `customTooltip` options - too many to list, consult the [CustomTooltipOption](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/column.interface.ts) interface for all possible options - [UI Sample](#ui-sample) @@ -41,18 +42,18 @@ const Example: React.FC = () => { useEffect(() => defineGrid(), []); function defineGrid() { - const columnDefinitions = [{ + setColumns([{ id: "title", name: "Title", field: "title", formatter: titleFormatter, customTooltip: { formatter: tooltipTaskFormatter, // ... } - }]; + }]); // make sure to register the plugin in your grid options - const gridOptions = { + setOptions({ externalResources: [new SlickCustomTooltip()], - }; + }); } } ``` @@ -72,7 +73,7 @@ const Example: React.FC = () => { useEffect(() => defineGrid(), []); function defineGrid() { - const gridOptions = { + setOptions({ externalResources: [new SlickCustomTooltip()], customTooltip: { formatter: tooltipTaskFormatter, @@ -80,7 +81,7 @@ const Example: React.FC = () => { // optionally skip tooltip on some of the column(s) (like 1st column when using row selection) usabilityOverride: (args) => (args.cell !== 0 && args?.column?.id !== 'action'), // disable on 1st and also "action" column }, - }; + }); } } ``` @@ -232,11 +233,11 @@ Both tooltips can be styled independently using the CSS `data-target-id` attribu By default the custom tooltip text will be limited, and potentially truncated, to 650 characters in order to keep the tooltip with a size that is not too large. You could change the grid option setting with this ```ts -const gridOptions = { +setOptions({ customTooltip: { tooltipTextMaxLength: 650, }, -} +}); ``` ### How to delay the opening of a tooltip? @@ -265,7 +266,7 @@ It is possible to also delay a regular tooltip (when using `useRegularTooltip`) ```ts // define your custom tooltip in a Column Definition OR Grid Options -const columnDefinitions = [{ +setColumns([{ id: 'firstName', field: 'firstName', name: 'First Name', customTooltip: { // 1- loading formatter @@ -276,7 +277,7 @@ const columnDefinitions = [{ asyncPostFormatter: `cell value`, // this will be read as tooltip }, formatter: `cell value`, // this won't be read as tooltip -}]; +}]); ``` the previous code could be refactored to have only 1 common formatter that is referenced in both cell `formatter` and tooltip `asyncPostFormatter` @@ -286,7 +287,7 @@ the previous code could be refactored to have only 1 common formatter that is re const myFormatter = () => `cell value`; // define your custom tooltip in a Column Definition OR Grid Options -const columnDefinitions = [{ +setColumns([{ id: 'firstName', field: 'firstName', name: 'First Name', customTooltip: { // 1- loading formatter @@ -297,9 +298,62 @@ const columnDefinitions = [{ asyncPostFormatter: myFormatter }, formatter: myFormatter -}]; +}]); +``` + +### Tooltips Outside the Grid +You can use the custom tooltip plugin to display tooltips on elements outside the grid (e.g., menu items, buttons, dialogs, etc.) by enabling the `observeAllTooltips` option. This allows the plugin to observe elements anywhere in your page that have `title` or `data-slick-tooltip` attributes. + +#### Enable Global Tooltip Observation +```ts +setOptions({ + externalResources: [new SlickCustomTooltip()], + customTooltip: { + observeAllTooltips: true, // enable tooltip observation outside the grid + formatter: tooltipFormatter, + }, +}); +``` + +#### Observe Specific Container(s) +If you want to limit tooltip observation to specific container(s), use the `observeTooltipContainer` option: + +```ts +setOptions({ + externalResources: [new SlickCustomTooltip()], + customTooltip: { + observeAllTooltips: true, + observeTooltipContainer: '.my-tooltip-container', // observe only within this container + formatter: tooltipFormatter, + }, +}); ``` +You can also observe multiple containers by providing a comma-separated string: +```ts +setOptions({ + customTooltip: { + observeAllTooltips: true, + observeTooltipContainer: '.container1, .container2, #header-menu', // observe multiple containers + formatter: tooltipFormatter, + }, +}); +``` + +#### Using Tooltips on External Elements + +Once enabled, you can use regular `title` attributes or `data-slick-tooltip` on any element: + +```html + + + + +Info Icon +``` + +The styling and positioning will be consistent with your grid tooltips. + ### UI Sample The Export to Excel handles all characters quite well, from Latin, to Unicode and even Unicorn emoji, it all works on all browsers (`Chrome`, `Firefox`, even `IE11`, I don't have access to older versions). Here's a demo diff --git a/frameworks/slickgrid-vue/docs/grid-functionalities/custom-tooltip.md b/frameworks/slickgrid-vue/docs/grid-functionalities/custom-tooltip.md index 3216ae217..8d3596a11 100644 --- a/frameworks/slickgrid-vue/docs/grid-functionalities/custom-tooltip.md +++ b/frameworks/slickgrid-vue/docs/grid-functionalities/custom-tooltip.md @@ -14,6 +14,7 @@ - [How to delay the opening of a tooltip?](#how-to-delay-the-opening-of-a-tooltip) - [delay a tooltip with Formatter](#delay-a-tooltip-with-formatter) - [delay a Regular Tooltip](#delay-a-regular-tooltip) +- [Tooltips Outside the Grid](#tooltips-outside-the-grid) - `customTooltip` options - too many to list, consult the [CustomTooltipOption](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/column.interface.ts) interface for all possible options - [UI Sample](#ui-sample) @@ -268,6 +269,57 @@ columnDefinitions.value = [{ }]; ``` +### Tooltips Outside the Grid +You can use the custom tooltip plugin to display tooltips on elements outside the grid (e.g., menu items, buttons, dialogs, etc.) by enabling the `observeAllTooltips` option. This allows the plugin to observe elements anywhere in your page that have `title` or `data-slick-tooltip` attributes. + +#### Enable Global Tooltip Observation +```ts +const gridOptions: GridOption = { + externalResources: [new SlickCustomTooltip()], + customTooltip: { + observeAllTooltips: true, // enable tooltip observation outside the grid + formatter: tooltipFormatter, + }, +}; +``` + +#### Observe Specific Container(s) +If you want to limit tooltip observation to specific container(s), use the `observeTooltipContainer` option: + +```ts +const gridOptions: GridOption = { + externalResources: [new SlickCustomTooltip()], + customTooltip: { + observeAllTooltips: true, + observeTooltipContainer: '.my-tooltip-container', // observe only within this container + formatter: tooltipFormatter, + }, +}; +``` + +You can also observe multiple containers by providing a comma-separated string: +```ts +customTooltip: { + observeAllTooltips: true, + observeTooltipContainer: '.container1, .container2, #header-menu', // observe multiple containers + formatter: tooltipFormatter, +} +``` + +#### Using Tooltips on External Elements + +Once enabled, you can use regular `title` attributes or `data-slick-tooltip` on any element: + +```html + + + + +Info Icon +``` + +The styling and positioning will be consistent with your grid tooltips. + ### UI Sample The Export to Excel handles all characters quite well, from Latin, to Unicode and even Unicorn emoji, it all works on all browsers (`Chrome`, `Firefox`, even `IE11`, I don't have access to older versions). Here's a demo diff --git a/packages/common/src/interfaces/customTooltipOption.interface.ts b/packages/common/src/interfaces/customTooltipOption.interface.ts index 213ff2986..271222ac5 100644 --- a/packages/common/src/interfaces/customTooltipOption.interface.ts +++ b/packages/common/src/interfaces/customTooltipOption.interface.ts @@ -114,7 +114,8 @@ export interface CustomTooltipOption { /** * defaults to 'body', CSS selector of the container element to observe when `observeAllTooltips` is enabled. * When defined, it will target only that specific container (e.g., use `'.tooltip-container'` to observe only elements within that container). - * NOTE: this option only works in combo with `observeAllTooltips` being enabled. + * You can also observe multiple containers by providing a comma separate string (e.g. `'.container1, container2'`) + * NOTE: this option only works in combo with `observeAllTooltips` which must be enabled. */ observeTooltipContainer?: string; diff --git a/packages/custom-tooltip-plugin/src/__tests__/slickCustomTooltip.spec.ts b/packages/custom-tooltip-plugin/src/__tests__/slickCustomTooltip.spec.ts index 94fbd89e7..252d49591 100644 --- a/packages/custom-tooltip-plugin/src/__tests__/slickCustomTooltip.spec.ts +++ b/packages/custom-tooltip-plugin/src/__tests__/slickCustomTooltip.spec.ts @@ -1178,11 +1178,15 @@ describe('SlickCustomTooltip plugin', () => { describe('observeAllTooltips feature', () => { let mockGridContainer: HTMLDivElement; + let mockGridContainer2: HTMLDivElement; beforeEach(() => { mockGridContainer = document.createElement('div'); + mockGridContainer2 = document.createElement('div'); mockGridContainer.className = 'grid-container'; + mockGridContainer2.className = 'grid-container2'; document.body.appendChild(mockGridContainer); + document.body.appendChild(mockGridContainer2); vi.spyOn(gridStub, 'getContainerNode').mockReturnValue(mockGridContainer); }); @@ -1242,6 +1246,36 @@ describe('SlickCustomTooltip plugin', () => { button.remove(); }); + it('should create global listeners on grid container when observeAllTooltips is true with 2 scopes "grid-container,grid-container2"', () => { + gridOptionsMock.customTooltip = { observeAllTooltips: true, observeTooltipContainer: '.grid-container, .grid-container2' }; + plugin.init(gridStub, container); + + const button = document.createElement('button'); + button.title = 'Button in container'; + mockGridContainer.appendChild(button); + + const mouseoverEvent = new MouseEvent('mouseover', { bubbles: true }); + button.dispatchEvent(mouseoverEvent); + + const tooltipElm = document.body.querySelector('.slick-custom-tooltip') as HTMLDivElement; + expect(tooltipElm).toBeTruthy(); + expect(tooltipElm.textContent).toBe('Button in container'); + button.remove(); + + const button2 = document.createElement('button'); + button2.title = 'Button in container 2'; + mockGridContainer2.appendChild(button2); + + const mouseoverEvent2 = new MouseEvent('mouseover', { bubbles: true }); + button2.dispatchEvent(mouseoverEvent2); + + const tooltipElm2 = document.body.querySelector('.slick-custom-tooltip') as HTMLDivElement; + expect(tooltipElm2).toBeTruthy(); + expect(tooltipElm2.textContent).toBe('Button in container 2'); + + button2.remove(); + }); + it('should show tooltip for element with data-slick-tooltip attribute', () => { gridOptionsMock.customTooltip = { observeAllTooltips: true, observeTooltipContainer: 'body' }; plugin.init(gridStub, container); diff --git a/packages/custom-tooltip-plugin/src/slickCustomTooltip.ts b/packages/custom-tooltip-plugin/src/slickCustomTooltip.ts index 31b38c168..e469aa051 100644 --- a/packages/custom-tooltip-plugin/src/slickCustomTooltip.ts +++ b/packages/custom-tooltip-plugin/src/slickCustomTooltip.ts @@ -167,7 +167,7 @@ export class SlickCustomTooltip { // optionally observe all title elements outside the grid if (this._addonOptions?.observeAllTooltips) { const containerSelector = this._addonOptions.observeTooltipContainer || 'body'; - const scope = containerSelector === 'body' ? document.body : document.querySelector(containerSelector) || grid.getContainerNode(); + const scope = containerSelector === 'body' ? document.body : document.querySelectorAll(containerSelector) || grid.getContainerNode(); this._bindEventService.bind(scope, 'mouseover', this.handleGlobalMouseOver.bind(this) as EventListener); this._bindEventService.bind(scope, 'mouseout', this.handleGlobalMouseOut.bind(this) as EventListener); }