import React, { useMemo } from 'react'; import styled from 'styled-components'; import type { JSX } from 'react'; import { DEFAULT_LOCALE_PLACEHOLDER } from '@redocly/theme/core/constants'; import { useThemeHooks, useThemeConfig, useTimeAgo } from '@redocly/theme/core/hooks'; type Formats = 'timeago' | 'iso' | 'short' | 'long'; export type LastUpdatedProps = { lastModified: Date; format?: Formats; locale?: string; className?: string; }; export function LastUpdated(props: LastUpdatedProps): JSX.Element | null { const { markdown: { lastUpdatedBlock = {} } = {} } = useThemeConfig(); const { useTranslate, useL10nConfig } = useThemeHooks(); const { format: timeagoFormat } = useTimeAgo(); const { translate } = useTranslate(); const { currentLocale } = useL10nConfig(); const formats: Record string> = useMemo( () => ({ timeago: (date: Date) => timeagoFormat(date), iso: (date: Date) => date.toISOString().split('T')[0], short: (date: Date, locale: string) => date.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' }), long: (date: Date, locale: string) => date.toLocaleDateString(locale, { month: 'long', day: 'numeric', year: 'numeric' }), }), [timeagoFormat], ); if (lastUpdatedBlock?.hide) { return null; } const lastModified = props.lastModified; const format = props.format || lastUpdatedBlock.format || 'timeago'; const locale = props.locale || lastUpdatedBlock.locale || (currentLocale !== DEFAULT_LOCALE_PLACEHOLDER ? currentLocale || 'en-US' : 'en-US'); const isoDate = lastModified.toISOString().split('T')[0]; const lastUpdatedString = formats[format](lastModified, locale); const translationKey = format === 'timeago' ? 'page.lastUpdated.timeago' : 'page.lastUpdated.on'; const text = format === 'timeago' ? translate(translationKey, 'Last updated') + ' ' : translate(translationKey, 'Last updated on'); return ( {/* eslint-disable-next-line no-warning-comments */} {text} {/* TODO: fix issue with snapshot tests - they should not depend on current date */} ); } const LastUpdatedWrapper = styled.div<{ rawOnPrint?: boolean }>` color: var(--last-updated-text-color); font-size: var(--last-updated-font-size); font-family: var(--last-updated-font-family); line-height: var(--last-updated-line-height); padding-bottom: 30px; ${({ rawOnPrint }) => rawOnPrint && `@media print { time { display: none; } &::after { content: attr(data-print-datetime); } } `} `;