feat(analytics-docs): Add highlight to cards

This commit is contained in:
Jan Václavík
2026-02-18 14:37:32 +01:00
parent 0f5e50e775
commit d0c87d08a9
3 changed files with 38 additions and 15 deletions

View File

@@ -96,6 +96,18 @@ const ContentArea = styled.div`
} }
`; `;
const HIGHLIGHT_DURATION_MS = 1000;
const EventCardWrapper = styled.div`
border-radius: 18px;
border: 2px solid transparent;
transition: border-color 0.4s ease-out;
&.highlighted {
border-color: ${({ theme }) => theme.backgroundAlertYellowBold};
}
`;
type AnalyticsContentProps = { type AnalyticsContentProps = {
isAnalyticsDataLoading: boolean; isAnalyticsDataLoading: boolean;
isAnalyticsDataGenerated: boolean; isAnalyticsDataGenerated: boolean;
@@ -111,8 +123,8 @@ const AnalyticsContent = ({
if (!isAnalyticsDataGenerated) { if (!isAnalyticsDataGenerated) {
return ( return (
<Paragraph typographyStyle="callout" intent="warning"> <Paragraph typographyStyle="callout" intent="warning">
analytics.json has not been generated. Run{' '} analytics.json has not been generated. Run <code>yarn build-data</code> (or{' '}
<code>yarn build-data</code> (or <code>yarn dev</code>) to generate it. <code>yarn dev</code>) to generate it.
</Paragraph> </Paragraph>
); );
} }
@@ -148,12 +160,19 @@ export const App = ({ theme }: AppProps) => {
[filteredEvents], [filteredEvents],
); );
const handleSidebarEventClick = (eventName: string) => {
const el = document.getElementById(getEventId(eventName));
if (!el) return;
el.classList.add('highlighted');
setTimeout(() => el.classList.remove('highlighted'), HIGHLIGHT_DURATION_MS);
};
const eventCards = useMemo( const eventCards = useMemo(
() => () =>
filteredEvents.map(event => ( filteredEvents.map(event => (
<div key={event.name} id={getEventId(event.name)}> <EventCardWrapper key={event.name} id={getEventId(event.name)}>
<EventCard event={event} /> <EventCard event={event} />
</div> </EventCardWrapper>
)), )),
[filteredEvents], [filteredEvents],
); );
@@ -257,16 +276,19 @@ export const App = ({ theme }: AppProps) => {
/> />
</ContentContainer> </ContentContainer>
</ContentArea> </ContentArea>
<VersionsSidebar versionsWithEvents={versionsWithEvents} /> <VersionsSidebar
versionsWithEvents={versionsWithEvents}
onEventClick={handleSidebarEventClick}
/>
</MainWithSidebar> </MainWithSidebar>
) : ( ) : (
<Content> <Content>
<ContentContainer> <ContentContainer>
<AnalyticsContent <AnalyticsContent
isAnalyticsDataLoading={isAnalyticsDataLoading} isAnalyticsDataLoading={isAnalyticsDataLoading}
isAnalyticsDataGenerated={isAnalyticsDataGenerated} isAnalyticsDataGenerated={isAnalyticsDataGenerated}
eventCards={eventCards} eventCards={eventCards}
/> />
</ContentContainer> </ContentContainer>
</Content> </Content>
)} )}

View File

@@ -62,9 +62,10 @@ const SidebarWrapper = styled.aside<{ theme: SuiteThemeColors }>`
type VersionsSidebarProps = { type VersionsSidebarProps = {
versionsWithEvents: VersionWithEvents[]; versionsWithEvents: VersionWithEvents[];
onEventClick?: (eventName: string) => void;
}; };
export const VersionsSidebar = ({ versionsWithEvents }: VersionsSidebarProps) => ( export const VersionsSidebar = ({ versionsWithEvents, onEventClick }: VersionsSidebarProps) => (
<SidebarWrapper> <SidebarWrapper>
<Column gap={0}> <Column gap={0}>
<H3 margin={{ left: 20, top: 8, bottom: 16 }}>Changelog</H3> <H3 margin={{ left: 20, top: 8, bottom: 16 }}>Changelog</H3>
@@ -82,7 +83,10 @@ export const VersionsSidebar = ({ versionsWithEvents }: VersionsSidebarProps) =>
.map(event => ( .map(event => (
<CardList.Item <CardList.Item
paddingType="small" paddingType="small"
onClick={() => scrollToEvent(event.name)} onClick={() => {
scrollToEvent(event.name);
onEventClick?.(event.name);
}}
key={event.name} key={event.name}
> >
<Text typographyStyle="label">{event.name}</Text> <Text typographyStyle="label">{event.name}</Text>

View File

@@ -34,10 +34,7 @@ export const useFilteredEvents = () => {
.catch(() => setAnalyticsData({})); .catch(() => setAnalyticsData({}));
}, []); }, []);
const allEvents = useMemo( const allEvents = useMemo(() => getEventsFromJson(analyticsData ?? {}), [analyticsData]);
() => getEventsFromJson(analyticsData ?? {}),
[analyticsData],
);
const isAnalyticsDataGenerated = const isAnalyticsDataGenerated =
analyticsData !== null && analyticsData !== null &&
typeof analyticsData === 'object' && typeof analyticsData === 'object' &&