Skip to content

Ws 2480 implement save button on article page#13932

Open
SantaZena wants to merge 27 commits intolatestfrom
WS-2480-implement-save-button-on-article-page
Open

Ws 2480 implement save button on article page#13932
SantaZena wants to merge 27 commits intolatestfrom
WS-2480-implement-save-button-on-article-page

Conversation

@SantaZena
Copy link
Copy Markdown
Contributor

@SantaZena SantaZena commented Apr 21, 2026

Resolves JIRA: https://bbc.atlassian.net/browse/WS-2480

Summary

Introducing ActionButton and refactoring existing SaveArticleButton into a HOC/container

Default:
Screenshot 2026-04-24 at 16 49 46

On hover:
Screenshot 2026-04-24 at 16 49 59

On focus:
Screenshot 2026-04-24 at 16 50 12

Saving:
Screenshot 2026-04-24 at 16 52 14

Saved:
Screenshot 2026-04-24 at 16 51 12

Saved on hover:
Screenshot 2026-04-24 at 16 51 24

Code changes

  • Created new AtionButton (UI component)
  • Refactored SaveArticleButton (business logic)
  • Created storybook stories for unsaved, loading and saved states
  • Added styles for the button's each state

Testing

  1. List the steps required to test this PR.

Useful Links

Figma design: https://www.figma.com/design/O5es2iJ7Ocjm85He1wc38q/WS-Save-for-later-Component?node-id=256-10697&t=7NGD3io8UIDF6DRG-0

@SantaZena SantaZena self-assigned this Apr 21, 2026
@SantaZena SantaZena marked this pull request as ready for review April 21, 2026 12:58
Copilot AI review requested due to automatic review settings April 21, 2026 12:58

This comment was marked as outdated.

{isLoading && (
<Spinner css={(theme: Theme) => styles.buttonAnimation(theme)} />
)}
{!isLoading && !isSaved && <BookmarkIcon />}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Icon is not aligned with text:
Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, it doesn't look like this for me.. The icon isn't correct right now, but it is aligned with text for me.
Screenshot 2026-04-23 at 12 07 27

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for me as for @elvinasv , alignment and font remain to be adjusted:
image

Comment thread src/app/components/ActionButton/index.styles.ts
Comment thread src/app/components/ActionButton/index.tsx Outdated
Comment thread src/app/components/ActionButton/index.tsx Outdated
Comment thread src/app/components/SaveArticleButton/index.tsx Outdated
@SantaZena SantaZena requested a review from elvinasv April 23, 2026 11:14
Comment thread src/app/components/ActionButton/metadata.json
Comment thread src/app/components/icons/index.tsx Outdated
Comment on lines +278 to +279
width="13"
height="18"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the Figma board, the icon should have been width = 12.5 and height = 17.5. Has this been rounded up? What was decided?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the icon should render at 20x20 to match the Figma design. The 12.5x17.5 is drawn inside the SVG coordinate system.
Image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please double check spinner and remove icons? Thanks
Screenshot 2026-04-24 at 12 56 25
Screenshot 2026-04-24 at 12 57 27

@SantaZena SantaZena requested a review from Nabeel1276 April 24, 2026 07:33
Copy link
Copy Markdown
Member

@elvinasv elvinasv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the previous comments. We're getting there 🙌

Comment on lines +25 to +26
backgroundColor: isSaved ? palette.WHITE : palette.WHITE,
color: isSaved ? palette.GREY_8 : palette.GREY_8,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can remove isSaved if the colors are consistent between states

alignItems: 'center',
justifyContent: 'center',
height: '2.75rem',
fontFamily: 'ReithSans, Arial, Helvetica, sans-serif',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The font depends on the service used. Let's use this approach:

height: '1rem',
width: '1rem',
animation: `${spinAnimation} 1s linear 0s infinite normal none running`,
animationName: spinAnimation,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think animationName is redundant because it's already included in the animation shorthand.

@@ -0,0 +1,74 @@
import { css, Theme, keyframes } from '@emotion/react';

const spinAnimation = keyframes`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: we could use object syntax, which would work better with linting. I.e.

const spinAnimation = keyframes({
  '0%': { transform: 'rotate(0deg)' },
  '100%': { transform: 'rotate(360deg)' },
});

Comment on lines +38 to +39
outline: `3px solid ${palette.GREY_8}`,
boxShadow: `0 0 0 ${palette.WHITE}, 0 0 0 9px ${palette.GREY_8}`,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use pixelsToRem instead of px values here?

onClick={onClick}
disabled={disabled || isLoading}
aria-label={label}
title={label}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity: do we expect the button title? Was this suggested by the UX?

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, this wasn't in the UX spec. Removing it.

// return null;
}

const buttonLabel = isSaved
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't have default values here. If translations are not defined, we could do an early return. That should help with TS errors.

disabled={isLoading}
label={buttonLabel}
buttonText={buttonText}
removeText={saveArticleButton?.removeButton ?? 'Remove'}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above - there shouldn't be hardcoded translations

closeLabel: 'Close',
buttonSeparatorText: 'या',
},
saveArticleButton: {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: button suffix is redundant.

saveArticleButton: {
  save: 'Save for later',
  saving: 'Saving', 
  saved: 'Saved to My News',
  remove: 'Remove',
}

Comment thread src/app/components/icons/index.tsx Outdated
Comment on lines +278 to +279
width="13"
height="18"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please double check spinner and remove icons? Thanks
Screenshot 2026-04-24 at 12 56 25
Screenshot 2026-04-24 at 12 57 27

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants