[copilot] Front end build for new topic discovery component#13927
Open
Nabeel1276 wants to merge 23 commits intolatestfrom
Open
[copilot] Front end build for new topic discovery component#13927Nabeel1276 wants to merge 23 commits intolatestfrom
Nabeel1276 wants to merge 23 commits intolatestfrom
Conversation
… and CurationGrid
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new TopicDiscovery UI component to render topic-based related content using a tabbed interface, reusing existing curation promo/grid building blocks in Simorgh.
Changes:
- Introduces
TopicDiscoverycomponent, styles, and data/types to render a tabbed related-content section. - Adds a
ScrollableTabssubcomponent for horizontally scrollable, keyboard-navigable tabs with scroll controls. - Adds Storybook stories and fixtures for local development/visual testing.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/app/components/TopicDiscovery/types.ts | Adds TypeScript types for topic discovery payloads. |
| src/app/components/TopicDiscovery/index.tsx | Implements the main TopicDiscovery section, tab state, and mapping items to curation summaries. |
| src/app/components/TopicDiscovery/index.styles.ts | Emotion styles for the TopicDiscovery section layout. |
| src/app/components/TopicDiscovery/index.stories.tsx | Storybook stories for default, single-topic, and empty states. |
| src/app/components/TopicDiscovery/fixtures.ts | Fixture data for Storybook/dev testing. |
| src/app/components/TopicDiscovery/ScrollableTabs/index.tsx | Implements scrollable tab UI with overflow detection and keyboard interaction. |
| src/app/components/TopicDiscovery/ScrollableTabs/index.styles.ts | Emotion styles for ScrollableTabs and scroll buttons. |
Comment on lines
+23
to
+26
| title: item.title, | ||
| link: item.link, | ||
| imageUrl: item.imageUrl.replace('{width}', String(DEFAULT_IMAGE_WIDTH)), | ||
| imageAlt: item.imageAlt, |
Comment on lines
+28
to
+34
| mediaType: item.type === 'article' ? undefined : item.type, | ||
| description: item.description, | ||
| firstPublished: item.firstPublished, | ||
| lastPublished: item.lastPublished, | ||
| isLive: item.isLive, | ||
| duration: item.duration, | ||
| isPortraitImage: item.isPortraitImage, |
| }); | ||
| }; | ||
|
|
||
| const handleKeyDown = (event: React.KeyboardEvent) => { |
Comment on lines
+142
to
+152
| <button | ||
| type="button" | ||
| css={styles.scrollButton} | ||
| onClick={() => scroll('end')} | ||
| disabled={!canScrollEnd} | ||
| aria-hidden="true" | ||
| tabIndex={-1} | ||
| data-testid="scroll-end" | ||
| > | ||
| <Chevron orientation={ChevronOrientation.FORWARD} dir={dir} /> | ||
| </button> |
Comment on lines
+41
to
+51
| const validTopics = topicDiscovery.topics.filter( | ||
| topic => topic.items && topic.items.length > 0, | ||
| ); | ||
|
|
||
| const [activeTabId, setActiveTabId] = useState(validTopics[0]?.topicId ?? ''); | ||
|
|
||
| if (validTopics.length === 0) return null; | ||
|
|
||
| const activeTopic = validTopics.find(topic => topic.topicId === activeTabId); | ||
|
|
||
| if (!activeTopic) return null; |
Comment on lines
+37
to
+84
| const TopicDiscovery = ({ | ||
| topicDiscovery, | ||
| headingText, | ||
| }: TopicDiscoveryProps) => { | ||
| const validTopics = topicDiscovery.topics.filter( | ||
| topic => topic.items && topic.items.length > 0, | ||
| ); | ||
|
|
||
| const [activeTabId, setActiveTabId] = useState(validTopics[0]?.topicId ?? ''); | ||
|
|
||
| if (validTopics.length === 0) return null; | ||
|
|
||
| const activeTopic = validTopics.find(topic => topic.topicId === activeTabId); | ||
|
|
||
| if (!activeTopic) return null; | ||
|
|
||
| const tabs = validTopics.map(topic => ({ | ||
| id: topic.topicId, | ||
| label: topic.topicName, | ||
| })); | ||
|
|
||
| const summaries = activeTopic.items.map(mapItemToSummary); | ||
|
|
||
| return ( | ||
| <section css={styles.section} data-testid="topic-discovery"> | ||
| <h2 id={HEADING_ID} css={styles.heading}> | ||
| {headingText} | ||
| </h2> | ||
| <ScrollableTabs | ||
| tabs={tabs} | ||
| activeTabId={activeTabId} | ||
| onTabChange={setActiveTabId} | ||
| labelledBy={HEADING_ID} | ||
| /> | ||
| <div | ||
| role="tabpanel" | ||
| id={`tabpanel-${activeTabId}`} | ||
| aria-labelledby={`tab-${activeTabId}`} | ||
| css={styles.tabPanel} | ||
| > | ||
| <CurationGrid | ||
| summaries={summaries} | ||
| eventTrackingData={eventTrackingData} | ||
| /> | ||
| </div> | ||
| </section> | ||
| ); | ||
| }; |
Comment on lines
+101
to
+110
| <button | ||
| type="button" | ||
| css={styles.scrollButton} | ||
| onClick={() => scroll('start')} | ||
| disabled={!canScrollStart} | ||
| aria-hidden="true" | ||
| tabIndex={-1} | ||
| data-testid="scroll-start" | ||
| > | ||
| <Chevron orientation={ChevronOrientation.BACKWARD} dir={dir} /> |
| aria-labelledby={labelledBy} | ||
| css={styles.tabList} | ||
| onKeyDown={handleKeyDown} | ||
| tabIndex={0} |
Comment on lines
+128
to
+133
| id={`tab-${tab.id}`} | ||
| data-tab-id={tab.id} | ||
| aria-selected={isActive} | ||
| aria-controls={`tabpanel-${tab.id}`} | ||
| tabIndex={isActive ? 0 : -1} | ||
| css={[styles.tab, isActive && styles.tabActive]} |
…overy-component
…overy-component
…overy-component
…overy-component
…overy-component
…overy-component
…overy-component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves JIRA: https://bbc.atlassian.net/browse/WS-2397
Summary
A very high-level summary of easily-reproducible changes that can be understood by non-devs, and why these changes where made.
Code changes
Testing
Useful Links