From 6e991e867b5f19593cbf24a7968ee201bc355bb0 Mon Sep 17 00:00:00 2001 From: RuthShryock Date: Tue, 28 Nov 2023 11:15:50 -0500 Subject: [PATCH 01/12] inital testing --- jsapp/js/components/common/tooltip.tsx | 24 +++++++++++++++++++ .../projectQuickActionsEmpty.tsx | 19 ++++++++------- 2 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 jsapp/js/components/common/tooltip.tsx diff --git a/jsapp/js/components/common/tooltip.tsx b/jsapp/js/components/common/tooltip.tsx new file mode 100644 index 0000000000..9db82b69b7 --- /dev/null +++ b/jsapp/js/components/common/tooltip.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +interface TooltipProps { + text?: string; + position?: string; + className?: string; +} + +const Tooltip: React.FC = ({ + text, + position, + className, + children, +}) => { + const tooltipClass = `tooltip ${position || ''} ${className || ''}`; + + return ( +
+ {children} +
+ ); +}; + +export default Tooltip; diff --git a/jsapp/js/projects/projectsTable/projectQuickActionsEmpty.tsx b/jsapp/js/projects/projectsTable/projectQuickActionsEmpty.tsx index 224f80bb6d..57ea4c8a5c 100644 --- a/jsapp/js/projects/projectsTable/projectQuickActionsEmpty.tsx +++ b/jsapp/js/projects/projectsTable/projectQuickActionsEmpty.tsx @@ -1,6 +1,7 @@ import React from 'react'; import Button from 'js/components/common/button'; import styles from './projectActions.module.scss'; +import Tooltip from 'jsapp/js/components/common/tooltip'; const NO_PROJECT_SELECTED = t('No project selected'); @@ -12,8 +13,8 @@ export default function ProjectQuickActionsEmpty() { return (
{/* Archive / Unarchive */} -
); } From 29cbba3c7d22cb0b55747c47a97e23265fade991 Mon Sep 17 00:00:00 2001 From: RuthShryock Date: Tue, 28 Nov 2023 14:41:08 -0500 Subject: [PATCH 02/12] adding storybook documetation, aria-element, and span --- .../js/components/common/tooltip.stories.tsx | 37 +++++++++++++++++++ jsapp/js/components/common/tooltip.tsx | 19 ++++------ .../projectQuickActionsEmpty.tsx | 3 ++ 3 files changed, 47 insertions(+), 12 deletions(-) create mode 100644 jsapp/js/components/common/tooltip.stories.tsx diff --git a/jsapp/js/components/common/tooltip.stories.tsx b/jsapp/js/components/common/tooltip.stories.tsx new file mode 100644 index 0000000000..67be313f89 --- /dev/null +++ b/jsapp/js/components/common/tooltip.stories.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import type {Story, Meta} from '@storybook/react'; + +import type {TooltipProps} from './tooltip'; +import Tooltip from './tooltip'; + +export default { + title: 'Components/Tooltip', + component: Tooltip, +} as Meta; + +const Template: Story = (args: typeof TooltipProps) => ( + + + +); + +export const Default = Template.bind({}); +Default.args = { + text: 'Default Tooltip Text', + className: '', + ariaLabel: 'Default Tooltip Text', +}; + +export const Right = Template.bind({}); +Right.args = { + text: 'Right Aligned Tooltip Text', + className: 'right-tooltip', + ariaLabel: 'Right Tooltip Text', +}; + +export const Left = Template.bind({}); +Left.args = { + text: 'Left Aligned Tooltip Text', + className: 'left-tooltip', + ariaLabel: 'Left Tooltip Text', +}; diff --git a/jsapp/js/components/common/tooltip.tsx b/jsapp/js/components/common/tooltip.tsx index 9db82b69b7..1df3500382 100644 --- a/jsapp/js/components/common/tooltip.tsx +++ b/jsapp/js/components/common/tooltip.tsx @@ -2,23 +2,18 @@ import React from 'react'; interface TooltipProps { text?: string; - position?: string; + ariaLabel?: string; className?: string; } const Tooltip: React.FC = ({ text, - position, + ariaLabel, className, children, -}) => { - const tooltipClass = `tooltip ${position || ''} ${className || ''}`; - - return ( -
- {children} -
- ); -}; - +}) => ( + + {children} + +); export default Tooltip; diff --git a/jsapp/js/projects/projectsTable/projectQuickActionsEmpty.tsx b/jsapp/js/projects/projectsTable/projectQuickActionsEmpty.tsx index 57ea4c8a5c..38f64751ee 100644 --- a/jsapp/js/projects/projectsTable/projectQuickActionsEmpty.tsx +++ b/jsapp/js/projects/projectsTable/projectQuickActionsEmpty.tsx @@ -15,6 +15,7 @@ export default function ProjectQuickActionsEmpty() { {/* Archive / Unarchive */} + + ); }; diff --git a/jsapp/js/projects/projectsTable/projectBulkActions.tsx b/jsapp/js/projects/projectsTable/projectBulkActions.tsx index 192b82d52f..3a7b9a28ff 100644 --- a/jsapp/js/projects/projectsTable/projectBulkActions.tsx +++ b/jsapp/js/projects/projectsTable/projectBulkActions.tsx @@ -33,38 +33,38 @@ export default function ProjectBulkActions(props: ProjectBulkActionsProps) { return (
{/* Archive / Unarchive - Bulk action not supported yet */} - -
); } diff --git a/jsapp/js/projects/projectsTable/projectQuickActionsEmpty.tsx b/jsapp/js/projects/projectsTable/projectQuickActionsEmpty.tsx index 38f64751ee..01a2910359 100644 --- a/jsapp/js/projects/projectsTable/projectQuickActionsEmpty.tsx +++ b/jsapp/js/projects/projectsTable/projectQuickActionsEmpty.tsx @@ -1,7 +1,6 @@ import React from 'react'; import Button from 'js/components/common/button'; import styles from './projectActions.module.scss'; -import Tooltip from 'jsapp/js/components/common/tooltip'; const NO_PROJECT_SELECTED = t('No project selected'); @@ -13,49 +12,37 @@ export default function ProjectQuickActionsEmpty() { return (
{/* Archive / Unarchive */} - -
); } From 9eb4e4e40ce6459d320519c36077dcdea66ccc98 Mon Sep 17 00:00:00 2001 From: RuthShryock Date: Tue, 28 Nov 2023 16:17:54 -0500 Subject: [PATCH 04/12] updating names and cleaning up code --- jsapp/js/components/common/button.tsx | 4 ++-- jsapp/js/components/common/tooltip.stories.tsx | 10 +++++----- jsapp/js/components/common/tooltip.tsx | 6 +++++- jsapp/js/projects/projectsTable/projectBulkActions.tsx | 6 +++--- .../js/projects/projectsTable/projectQuickActions.tsx | 10 +++++----- .../projectsTable/projectQuickActionsEmpty.tsx | 6 +++--- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/jsapp/js/components/common/button.tsx b/jsapp/js/components/common/button.tsx index 5bbb320b64..bbddd6bb3f 100644 --- a/jsapp/js/components/common/button.tsx +++ b/jsapp/js/components/common/button.tsx @@ -63,7 +63,7 @@ export interface ButtonProps { */ tooltip?: string; /** Sets the alignment of the tooltip */ - position?: string; + tooltipPosition?: string; isDisabled?: boolean; /** Changes the appearance to display spinner. */ isPending?: boolean; @@ -160,7 +160,7 @@ const Button = (props: ButtonProps) => { diff --git a/jsapp/js/components/common/tooltip.tsx b/jsapp/js/components/common/tooltip.tsx index a3b7b509a9..2e71e66493 100644 --- a/jsapp/js/components/common/tooltip.tsx +++ b/jsapp/js/components/common/tooltip.tsx @@ -21,3 +21,4 @@ const Tooltip: React.FC = ({ ); export default Tooltip; +export type {TooltipProps}; From a6915d71f9e2c4fb054bbe36f281deb6ced8959f Mon Sep 17 00:00:00 2001 From: RuthShryock Date: Tue, 28 Nov 2023 16:56:26 -0500 Subject: [PATCH 06/12] removing comment --- jsapp/js/components/common/tooltip.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/jsapp/js/components/common/tooltip.stories.tsx b/jsapp/js/components/common/tooltip.stories.tsx index 0111ec22d3..7d73224956 100644 --- a/jsapp/js/components/common/tooltip.stories.tsx +++ b/jsapp/js/components/common/tooltip.stories.tsx @@ -9,7 +9,6 @@ export default { component: Tooltip, } as Meta; -// Correctly importing TooltipProps as a type const Template: Story = (args) => ( From 0a1083fe132cfab2e847456012f2239fc83ce876 Mon Sep 17 00:00:00 2001 From: RuthShryock Date: Mon, 4 Dec 2023 15:09:47 -0500 Subject: [PATCH 07/12] requested changes for styling, adding comments, and moving scss file --- jsapp/js/components/common/button.tsx | 65 ++++++++++--------- .../components/common/tooltip.scss} | 2 +- .../js/components/common/tooltip.stories.tsx | 23 ++++++- jsapp/js/components/common/tooltip.tsx | 26 ++++++-- jsapp/scss/main.scss | 2 +- 5 files changed, 75 insertions(+), 43 deletions(-) rename jsapp/{scss/components/_kobo.tooltips.scss => js/components/common/tooltip.scss} (99%) diff --git a/jsapp/js/components/common/button.tsx b/jsapp/js/components/common/button.tsx index bbddd6bb3f..afac4d5fd9 100644 --- a/jsapp/js/components/common/button.tsx +++ b/jsapp/js/components/common/button.tsx @@ -63,7 +63,7 @@ export interface ButtonProps { */ tooltip?: string; /** Sets the alignment of the tooltip */ - tooltipPosition?: string; + tooltipPosition?: 'right' | 'left' | ''; isDisabled?: boolean; /** Changes the appearance to display spinner. */ isPending?: boolean; @@ -137,9 +137,6 @@ const Button = (props: ButtonProps) => { // For the attributes that don't have a falsy value. const additionalButtonAttributes: AdditionalButtonAttributes = {}; - if (props.tooltip) { - additionalButtonAttributes['data-tip'] = props.tooltip; - } if (props['data-cy']) { additionalButtonAttributes['data-cy'] = props['data-cy']; } @@ -157,33 +154,39 @@ const Button = (props: ButtonProps) => { }; return ( - - - + <> + {props.tooltip !== undefined && ( + + + + )} + ); }; diff --git a/jsapp/scss/components/_kobo.tooltips.scss b/jsapp/js/components/common/tooltip.scss similarity index 99% rename from jsapp/scss/components/_kobo.tooltips.scss rename to jsapp/js/components/common/tooltip.scss index 50d8c6cdbb..0218d0cc2b 100644 --- a/jsapp/scss/components/_kobo.tooltips.scss +++ b/jsapp/js/components/common/tooltip.scss @@ -43,7 +43,7 @@ Additional class names: } &::before { - content: ""; + content: ''; border-bottom: 5px solid colors.$kobo-gray-40; border-left: 5px solid transparent; border-right: 5px solid transparent; diff --git a/jsapp/js/components/common/tooltip.stories.tsx b/jsapp/js/components/common/tooltip.stories.tsx index 7d73224956..35b2e4d80e 100644 --- a/jsapp/js/components/common/tooltip.stories.tsx +++ b/jsapp/js/components/common/tooltip.stories.tsx @@ -7,6 +7,23 @@ import Tooltip from './tooltip'; export default { title: 'Common/Tooltip', component: Tooltip, + description: + 'This is a component that displays a tooltip on a button that is hovered over.', + argTypes: { + text: { + description: 'Content of the tooltip shown on hover over button', + }, + alignment: { + description: + 'Position of the tooltip (takes empty string to display the default centered alignment)', + options: ['right', 'left', ''], + control: 'select', + defaultValue: '', + }, + ariaLabel: { + description: 'Accessible label for screen readers', + }, + }, } as Meta; const Template: Story = (args) => ( @@ -18,20 +35,20 @@ const Template: Story = (args) => ( export const Default = Template.bind({}); Default.args = { text: 'Default Tooltip Text', - className: '', + alignment: '', ariaLabel: 'Default Tooltip Text', }; export const Right = Template.bind({}); Right.args = { text: 'Right Aligned Tooltip Text', - className: 'right', + alignment: 'right', ariaLabel: 'Right Aligned Tooltip Text', }; export const Left = Template.bind({}); Left.args = { text: 'Left Aligned Tooltip Text', - className: 'left', + alignment: 'left', ariaLabel: 'Left Aligned Tooltip Text', }; diff --git a/jsapp/js/components/common/tooltip.tsx b/jsapp/js/components/common/tooltip.tsx index 2e71e66493..fe0f58f910 100644 --- a/jsapp/js/components/common/tooltip.tsx +++ b/jsapp/js/components/common/tooltip.tsx @@ -1,24 +1,36 @@ import React from 'react'; -interface TooltipProps { - text?: string; - ariaLabel?: string; - className?: string; +export interface TooltipProps { + text: string; + ariaLabel: string; + alignment?: 'right' | 'left' | ''; } +/** + * Tooltip component that is necessary for managing dynamic content and + * accessibility features, such as readability. While we have the tooltip.scss + * component, that provides styling but not other functionaltiy such as + * allowing tooltips to work on disabled buttons. + * + * @param {string} text - Content of the tooltip. + * @param {string} ariaLabel - Accessible label for screen readers. + * @param {'right' | 'left' | ''} alignment - Position of the tooltip (centered + * if undefined or set to an empty string). + * @param {React.ReactNode} children - Button that triggers the tooltip when + * hovered. + */ const Tooltip: React.FC = ({ text, ariaLabel, - className, + alignment, children, }) => ( {children} ); export default Tooltip; -export type {TooltipProps}; diff --git a/jsapp/scss/main.scss b/jsapp/scss/main.scss index 332371671d..fa2f495941 100644 --- a/jsapp/scss/main.scss +++ b/jsapp/scss/main.scss @@ -29,7 +29,6 @@ @import "./components/kobo.button"; @import "./components/kobo.light-button"; @import "./components/kobo.text-button"; -@import "./components/kobo.tooltips"; @import "./components/kobo.tooltips-big"; @import "./components/kobo.navigation"; @import "./components/kobo.drawer"; @@ -46,6 +45,7 @@ @import "./components/kobo.simple-table"; @import "./components/kobo.background-audio-player"; @import "./components/kobo.dropzone"; +@import 'jsapp/js/components/common/tooltip.scss'; @import "./formbuild/kobomatrix"; From 508906769c89d83239a3f766483c75ad32010416 Mon Sep 17 00:00:00 2001 From: RuthShryock Date: Mon, 4 Dec 2023 15:12:21 -0500 Subject: [PATCH 08/12] removing auto formatting of quotations --- jsapp/js/components/common/tooltip.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsapp/js/components/common/tooltip.scss b/jsapp/js/components/common/tooltip.scss index 0218d0cc2b..50d8c6cdbb 100644 --- a/jsapp/js/components/common/tooltip.scss +++ b/jsapp/js/components/common/tooltip.scss @@ -43,7 +43,7 @@ Additional class names: } &::before { - content: ''; + content: ""; border-bottom: 5px solid colors.$kobo-gray-40; border-left: 5px solid transparent; border-right: 5px solid transparent; From 6c150362d66ab6847d42a8ef192266f3408bdab5 Mon Sep 17 00:00:00 2001 From: RuthShryock Date: Mon, 11 Dec 2023 10:52:00 -0500 Subject: [PATCH 09/12] adjusting alignment values and fixing comments for parameters in the tooltip --- jsapp/js/components/common/button.tsx | 4 ++-- jsapp/js/components/common/tooltip.stories.tsx | 8 ++++---- jsapp/js/components/common/tooltip.tsx | 16 +++++++--------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/jsapp/js/components/common/button.tsx b/jsapp/js/components/common/button.tsx index afac4d5fd9..378bde3d86 100644 --- a/jsapp/js/components/common/button.tsx +++ b/jsapp/js/components/common/button.tsx @@ -3,7 +3,7 @@ import type {IconName} from 'jsapp/fonts/k-icons'; import type {IconSize} from 'js/components/common/icon'; import Icon from 'js/components/common/icon'; import './button.scss'; -import Tooltip from './tooltip'; +import Tooltip, { TooltipAlignment } from './tooltip'; /** * Note: we use a simple TypeScript types here instead of enums, so we don't @@ -63,7 +63,7 @@ export interface ButtonProps { */ tooltip?: string; /** Sets the alignment of the tooltip */ - tooltipPosition?: 'right' | 'left' | ''; + tooltipPosition?: TooltipAlignment; isDisabled?: boolean; /** Changes the appearance to display spinner. */ isPending?: boolean; diff --git a/jsapp/js/components/common/tooltip.stories.tsx b/jsapp/js/components/common/tooltip.stories.tsx index 35b2e4d80e..5db7097104 100644 --- a/jsapp/js/components/common/tooltip.stories.tsx +++ b/jsapp/js/components/common/tooltip.stories.tsx @@ -15,10 +15,10 @@ export default { }, alignment: { description: - 'Position of the tooltip (takes empty string to display the default centered alignment)', - options: ['right', 'left', ''], + 'Position of the tooltip (centered as default)', + options: ['right', 'left', 'center'], control: 'select', - defaultValue: '', + defaultValue: 'center', }, ariaLabel: { description: 'Accessible label for screen readers', @@ -35,7 +35,7 @@ const Template: Story = (args) => ( export const Default = Template.bind({}); Default.args = { text: 'Default Tooltip Text', - alignment: '', + alignment: 'center', ariaLabel: 'Default Tooltip Text', }; diff --git a/jsapp/js/components/common/tooltip.tsx b/jsapp/js/components/common/tooltip.tsx index fe0f58f910..40eba80564 100644 --- a/jsapp/js/components/common/tooltip.tsx +++ b/jsapp/js/components/common/tooltip.tsx @@ -1,9 +1,14 @@ import React from 'react'; +export type TooltipAlignment = 'right' | 'left' | 'center'; + export interface TooltipProps { + /** Content of the tooltip */ text: string; + /** Accessible label for screen readers */ ariaLabel: string; - alignment?: 'right' | 'left' | ''; + /** Position of the tooltip (centered as default) */ + alignment?: TooltipAlignment; } /** @@ -11,13 +16,6 @@ export interface TooltipProps { * accessibility features, such as readability. While we have the tooltip.scss * component, that provides styling but not other functionaltiy such as * allowing tooltips to work on disabled buttons. - * - * @param {string} text - Content of the tooltip. - * @param {string} ariaLabel - Accessible label for screen readers. - * @param {'right' | 'left' | ''} alignment - Position of the tooltip (centered - * if undefined or set to an empty string). - * @param {React.ReactNode} children - Button that triggers the tooltip when - * hovered. */ const Tooltip: React.FC = ({ text, @@ -27,7 +25,7 @@ const Tooltip: React.FC = ({ }) => ( {children} From 0e077e8ca2c46586acec4d733d47d05511cb4dc6 Mon Sep 17 00:00:00 2001 From: Leszek Date: Wed, 13 Dec 2023 15:16:04 +0100 Subject: [PATCH 10/12] improve button storybook definition --- jsapp/js/components/common/button.stories.tsx | 65 ++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/jsapp/js/components/common/button.stories.tsx b/jsapp/js/components/common/button.stories.tsx index ee620f9c78..848ebf5ae4 100644 --- a/jsapp/js/components/common/button.stories.tsx +++ b/jsapp/js/components/common/button.stories.tsx @@ -1,11 +1,74 @@ import React from 'react'; import type {ComponentStory, ComponentMeta} from '@storybook/react'; import Button from './button'; +import type {ButtonType, ButtonColor, ButtonSize} from './button'; +import type {TooltipAlignment} from './tooltip'; +import {IconNames} from 'jsapp/fonts/k-icons'; + +const buttonTypes: ButtonType[] = ['bare', 'frame', 'full']; + +const buttonColors: ButtonColor[] = [ + 'blue', + 'light-blue', + 'red', + 'storm', + 'cloud', + 'dark-red', + 'dark-blue', +]; + +const buttonSizes: ButtonSize[] = ['s', 'm', 'l']; + +const tooltipPositions: TooltipAlignment[] = ['right', 'left', 'center']; export default { title: 'common/Button', component: Button, - argTypes: {}, + argTypes: { + type: { + description: 'Type of button', + options: buttonTypes, + control: 'select', + }, + color: { + description: 'Color of button', + options: buttonColors, + control: 'select', + }, + size: { + description: 'Size of button', + options: buttonSizes, + control: 'radio', + }, + startIcon: { + description: 'Icon on the beginning (please use only one of the icons)', + options: Object.keys(IconNames), + control: {type: 'select'}, + }, + endIcon: { + description: 'Icon on the end (please use only one of the icons)', + options: Object.keys(IconNames), + control: {type: 'select'}, + }, + label: { + control: 'text', + }, + tooltip: { + description: 'Tooltip text', + control: 'text', + }, + tooltipPosition: { + description: 'Position of the tooltip (optional)', + options: tooltipPositions, + control: 'radio', + }, + isDisabled: {control: 'boolean'}, + isPending: {control: 'boolean'}, + isFullWidth: { + description: 'Makes the button take 100% width of the container', + control: 'boolean', + }, + }, } as ComponentMeta; const Template: ComponentStory = (args) => + ); + return ( <> - {props.tooltip !== undefined && ( + {props.tooltip !== undefined ? ( - + {renderButton()} + ) : ( + renderButton() )} ); diff --git a/jsapp/js/components/common/tooltip.stories.tsx b/jsapp/js/components/common/tooltip.stories.tsx index 5db7097104..a639fcc149 100644 --- a/jsapp/js/components/common/tooltip.stories.tsx +++ b/jsapp/js/components/common/tooltip.stories.tsx @@ -1,9 +1,11 @@ import React from 'react'; import type {Meta, Story} from '@storybook/react'; -import type {TooltipProps} from './tooltip'; +import type {TooltipProps, TooltipAlignment} from './tooltip'; import Tooltip from './tooltip'; +const tooltipPositions: TooltipAlignment[] = ['right', 'left', 'center']; + export default { title: 'Common/Tooltip', component: Tooltip, @@ -12,13 +14,13 @@ export default { argTypes: { text: { description: 'Content of the tooltip shown on hover over button', + control: 'text', }, alignment: { description: 'Position of the tooltip (centered as default)', - options: ['right', 'left', 'center'], - control: 'select', - defaultValue: 'center', + options: tooltipPositions, + control: 'radio', }, ariaLabel: { description: 'Accessible label for screen readers', From fd2cbc157692a99166d971074883621474d44653 Mon Sep 17 00:00:00 2001 From: Leszek Date: Mon, 15 Jan 2024 14:52:28 +0100 Subject: [PATCH 12/12] change Button to be inline-flex so that tooltips work correctly --- jsapp/js/components/common/button.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsapp/js/components/common/button.scss b/jsapp/js/components/common/button.scss index c0dd730d57..5f7158b351 100644 --- a/jsapp/js/components/common/button.scss +++ b/jsapp/js/components/common/button.scss @@ -138,7 +138,7 @@ $button-border-radius: sizes.$x6; .k-button { cursor: pointer; color: inherit; - display: flex; + display: inline-flex; flex-direction: row; align-items: center; align-content: center;