refactor(theme): dates should be formatted on the client-side instead of in nodejs code (#9868)

Co-authored-by: OzakIOne <OzakIOne@users.noreply.github.com>
Co-authored-by: sebastien <lorber.sebastien@gmail.com>
This commit is contained in:
ozaki 2024-02-23 18:30:05 +01:00 committed by GitHub
parent 6bf21d215c
commit 0279c329ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 83 additions and 162 deletions

View file

@ -41,6 +41,7 @@ const markdown: MarkdownConfig = {
}
return result;
},
remarkRehypeOptions: undefined,
};
function findByTitle(
@ -175,7 +176,6 @@ describe('blog plugin', () => {
description: `date inside front matter`,
authors: [],
date: new Date('2019-01-01'),
formattedDate: 'January 1, 2019',
frontMatter: {
date: new Date('2019-01-01'),
tags: ['date'],
@ -220,7 +220,6 @@ describe('blog plugin', () => {
},
],
date: new Date('2018-12-14'),
formattedDate: 'December 14, 2018',
frontMatter: {
authors: [
{
@ -256,7 +255,6 @@ describe('blog plugin', () => {
title: 'Simple Slug',
},
date: new Date('2020-08-16'),
formattedDate: 'August 16, 2020',
frontMatter: {
date: '2020/08/16',
slug: '/hey/my super path/héllô',
@ -302,7 +300,6 @@ describe('blog plugin', () => {
title: 'draft',
},
date: new Date('2020-08-15'),
formattedDate: 'August 15, 2020',
frontMatter: {
author: 'Sébastien Lorber',
author_title: 'Docusaurus maintainer',
@ -328,7 +325,6 @@ describe('blog plugin', () => {
description: '',
authors: [],
date: new Date('2019-01-02'),
formattedDate: 'January 2, 2019',
frontMatter: {
date: new Date('2019-01-02'),
},
@ -343,39 +339,6 @@ describe('blog plugin', () => {
});
});
it('builds simple website blog with localized dates', async () => {
const siteDir = path.join(__dirname, '__fixtures__', 'website');
const blogPostsFrench = await getBlogPosts(siteDir, {}, getI18n('fr'));
expect(blogPostsFrench).toHaveLength(10);
expect(blogPostsFrench[0]!.metadata.formattedDate).toMatchInlineSnapshot(
`"23 juillet 2023"`,
);
expect(blogPostsFrench[1]!.metadata.formattedDate).toMatchInlineSnapshot(
`"6 mars 2021"`,
);
expect(blogPostsFrench[2]!.metadata.formattedDate).toMatchInlineSnapshot(
`"5 mars 2021"`,
);
expect(blogPostsFrench[3]!.metadata.formattedDate).toMatchInlineSnapshot(
`"16 août 2020"`,
);
expect(blogPostsFrench[4]!.metadata.formattedDate).toMatchInlineSnapshot(
`"15 août 2020"`,
);
expect(blogPostsFrench[5]!.metadata.formattedDate).toMatchInlineSnapshot(
`"27 février 2020"`,
);
expect(blogPostsFrench[6]!.metadata.formattedDate).toMatchInlineSnapshot(
`"27 février 2020"`,
);
expect(blogPostsFrench[7]!.metadata.formattedDate).toMatchInlineSnapshot(
`"2 janvier 2019"`,
);
expect(blogPostsFrench[8]!.metadata.formattedDate).toMatchInlineSnapshot(
`"1 janvier 2019"`,
);
});
it('handles edit URL with editLocalizedBlogs: true', async () => {
const siteDir = path.join(__dirname, '__fixtures__', 'website');
const blogPosts = await getBlogPosts(siteDir, {editLocalizedFiles: true});
@ -476,11 +439,6 @@ describe('blog plugin', () => {
// We know the file exists and we know we have git
const result = getFileCommitDate(noDateSourceFile, {age: 'oldest'});
const noDateSourceTime = result.date;
const formattedDate = Intl.DateTimeFormat('en', {
day: 'numeric',
month: 'long',
year: 'numeric',
}).format(noDateSourceTime);
expect({
...getByTitle(blogPosts, 'no date').metadata,
@ -494,7 +452,6 @@ describe('blog plugin', () => {
description: `no date`,
authors: [],
date: noDateSourceTime,
formattedDate,
frontMatter: {},
tags: [],
prevItem: undefined,

View file

@ -164,25 +164,6 @@ export function parseBlogFileName(
return {date: undefined, text, slug};
}
function formatBlogPostDate(
locale: string,
date: Date,
calendar: string,
): string {
try {
return new Intl.DateTimeFormat(locale, {
day: 'numeric',
month: 'long',
year: 'numeric',
timeZone: 'UTC',
calendar,
}).format(date);
} catch (err) {
logger.error`Can't format blog post date "${String(date)}"`;
throw err;
}
}
async function parseBlogPostMarkdownFile({
filePath,
parseFrontMatter,
@ -289,11 +270,6 @@ async function processBlogSourceFile(
}
const date = await getDate();
const formattedDate = formatBlogPostDate(
i18n.currentLocale,
date,
i18n.localeConfigs[i18n.currentLocale]!.calendar,
);
const title = frontMatter.title ?? contentTitle ?? parsedBlogFileName.text;
const description = frontMatter.description ?? excerpt ?? '';
@ -348,7 +324,6 @@ async function processBlogSourceFile(
title,
description,
date,
formattedDate,
tags: normalizeFrontMatterTags(tagsBasePath, frontMatter.tags),
readingTime: showReadingTime
? options.readingTime({

View file

@ -192,11 +192,6 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
* into a string.
*/
readonly date: Date;
/**
* Publish date formatted according to the locale, so that the client can
* render the date regardless of the existence of `Intl.DateTimeFormat`.
*/
readonly formattedDate: string;
/** Full link including base URL. */
readonly permalink: string;
/**

View file

@ -52,7 +52,6 @@ exports[`simple website content 1`] = `
"description": "Images",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"id": "baz",
"pagination_label": "baz pagination_label",
@ -105,7 +104,6 @@ exports[`simple website content 2`] = `
"description": "Hi, Endilie here :)",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"id": "hello",
"sidebar_label": "Hello sidebar_label",
@ -151,7 +149,6 @@ exports[`simple website content 3`] = `
"description": "This is custom description",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"description": "This is custom description",
"id": "bar",
@ -1971,7 +1968,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "Getting started text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "getting-started",
"lastUpdatedAt": undefined,
@ -1999,7 +1995,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "Installation text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "installation",
"lastUpdatedAt": undefined,
@ -2030,7 +2025,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "Guide 1 text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"id": "guide1",
"sidebar_position": 1,
@ -2064,7 +2058,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "Guide 2 text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"id": "guide2",
},
@ -2097,7 +2090,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "Guide 2.5 text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"id": "guide2.5",
"sidebar_position": 2.5,
@ -2131,7 +2123,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "Guide 3 text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"id": "guide3",
"sidebar_position": 3,
@ -2165,7 +2156,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "Guide 4 text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"id": "guide4",
},
@ -2198,7 +2188,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "Guide 5 text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"id": "guide5",
},
@ -2231,7 +2220,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "API Overview text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "API/api-overview",
"lastUpdatedAt": undefined,
@ -2262,7 +2250,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "Client API text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "API/Core APIs/Client API",
"lastUpdatedAt": undefined,
@ -2293,7 +2280,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "Server API text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "API/Core APIs/Server API",
"lastUpdatedAt": undefined,
@ -2324,7 +2310,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "Plugin API text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "API/Extension APIs/Plugin API",
"lastUpdatedAt": undefined,
@ -2355,7 +2340,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "Theme API text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "API/Extension APIs/Theme API",
"lastUpdatedAt": undefined,
@ -2386,7 +2370,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
"description": "API End text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "API/api-end",
"lastUpdatedAt": undefined,
@ -2566,7 +2549,6 @@ exports[`site with partial autogenerated sidebars docs in partially generated si
"description": "API End text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "API/api-end",
"lastUpdatedAt": undefined,
@ -2594,7 +2576,6 @@ exports[`site with partial autogenerated sidebars docs in partially generated si
"description": "API Overview text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "API/api-overview",
"lastUpdatedAt": undefined,
@ -2625,7 +2606,6 @@ exports[`site with partial autogenerated sidebars docs in partially generated si
"description": "Plugin API text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "API/Extension APIs/Plugin API",
"lastUpdatedAt": undefined,
@ -2656,7 +2636,6 @@ exports[`site with partial autogenerated sidebars docs in partially generated si
"description": "Theme API text",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "API/Extension APIs/Theme API",
"lastUpdatedAt": undefined,
@ -2716,7 +2695,6 @@ exports[`versioned website (community) content 1`] = `
"description": "Team current version (translated)",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"title": "Team title translated",
},
@ -2743,7 +2721,6 @@ exports[`versioned website (community) content 2`] = `
"description": "Team 1.0.0",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "team",
"lastUpdatedAt": undefined,
@ -3023,7 +3000,6 @@ exports[`versioned website content 1`] = `
"description": "This is next version of bar.",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"slug": "barSlug",
"tags": [
@ -3074,7 +3050,6 @@ exports[`versioned website content 2`] = `
"description": "Bar 1.0.1 !",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "foo/bar",
"lastUpdatedAt": undefined,
@ -3102,7 +3077,6 @@ exports[`versioned website content 3`] = `
"description": "Hello next !",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"slug": "/",
},
@ -3132,7 +3106,6 @@ exports[`versioned website content 4`] = `
"description": "Hello 1.0.1 !",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {
"slug": "/",
},
@ -3162,7 +3135,6 @@ exports[`versioned website content 5`] = `
"description": "Baz 1.0.0 ! This will be deleted in next subsequent versions.",
"draft": false,
"editUrl": undefined,
"formattedLastUpdatedAt": undefined,
"frontMatter": {},
"id": "foo/baz",
"lastUpdatedAt": undefined,

View file

@ -475,7 +475,6 @@ describe('simple site', () => {
unrelated_front_matter: "won't be part of metadata",
},
lastUpdatedAt: 1539502055,
formattedLastUpdatedAt: 'Oct 14, 2018',
lastUpdatedBy: 'Author',
tags: [],
unlisted: false,
@ -573,7 +572,6 @@ describe('simple site', () => {
title: 'Custom Last Update',
},
lastUpdatedAt: new Date('1/1/2000').getTime() / 1000,
formattedLastUpdatedAt: 'Jan 1, 2000',
lastUpdatedBy: 'Custom Author (processed by parseFrontMatter)',
sidebarPosition: undefined,
tags: [],
@ -612,7 +610,6 @@ describe('simple site', () => {
title: 'Last Update Author Only',
},
lastUpdatedAt: 1539502055,
formattedLastUpdatedAt: 'Oct 14, 2018',
lastUpdatedBy: 'Custom Author (processed by parseFrontMatter)',
sidebarPosition: undefined,
tags: [],
@ -651,7 +648,6 @@ describe('simple site', () => {
title: 'Last Update Date Only',
},
lastUpdatedAt: new Date('1/1/2000').getTime() / 1000,
formattedLastUpdatedAt: 'Jan 1, 2000',
lastUpdatedBy: 'Author',
sidebarPosition: undefined,
tags: [],
@ -691,7 +687,6 @@ describe('simple site', () => {
title: 'Custom Last Update',
},
lastUpdatedAt: undefined,
formattedLastUpdatedAt: undefined,
lastUpdatedBy: undefined,
sidebarPosition: undefined,
tags: [],

View file

@ -8,7 +8,6 @@
import path from 'path';
import fs from 'fs-extra';
import _ from 'lodash';
import logger from '@docusaurus/logger';
import {
aliasedSitePath,
getEditUrl,
@ -142,7 +141,6 @@ async function doProcessDocMetadata({
const {source, content, contentPath, filePath} = docFile;
const {
siteDir,
i18n,
siteConfig: {
markdown: {parseFrontMatter},
},
@ -257,21 +255,6 @@ async function doProcessDocMetadata({
const draft = isDraft({env, frontMatter});
const unlisted = isUnlisted({env, frontMatter});
const formatDate = (locale: string, date: Date, calendar: string): string => {
try {
return new Intl.DateTimeFormat(locale, {
day: 'numeric',
month: 'short',
year: 'numeric',
timeZone: 'UTC',
calendar,
}).format(date);
} catch (err) {
logger.error`Can't format docs lastUpdatedAt date "${String(date)}"`;
throw err;
}
};
// Assign all of object properties during instantiation (if possible) for
// NodeJS optimization.
// Adding properties to object after instantiation will cause hidden
@ -291,13 +274,6 @@ async function doProcessDocMetadata({
version: versionMetadata.versionName,
lastUpdatedBy: lastUpdate.lastUpdatedBy,
lastUpdatedAt: lastUpdate.lastUpdatedAt,
formattedLastUpdatedAt: lastUpdate.lastUpdatedAt
? formatDate(
i18n.currentLocale,
new Date(lastUpdate.lastUpdatedAt * 1000),
i18n.localeConfigs[i18n.currentLocale]!.calendar,
)
: undefined,
sidebarPosition,
frontMatter,
};

View file

@ -407,8 +407,6 @@ declare module '@docusaurus/plugin-content-docs' {
export type LastUpdateData = {
/** A timestamp in **seconds**, directly acquired from `git log`. */
lastUpdatedAt?: number;
/** `lastUpdatedAt` formatted as a date according to the current locale. */
formattedLastUpdatedAt?: string;
/** The author's name directly acquired from `git log`. */
lastUpdatedBy?: string;
};

View file

@ -824,7 +824,6 @@ declare module '@theme/SearchMetadata' {
declare module '@theme/LastUpdated' {
export interface Props {
readonly lastUpdatedAt?: number;
readonly formattedLastUpdatedAt?: string;
readonly lastUpdatedBy?: string;
}

View file

@ -9,6 +9,7 @@ import React from 'react';
import Link from '@docusaurus/Link';
import {translate} from '@docusaurus/Translate';
import {PageMetadata} from '@docusaurus/theme-common';
import {useDateTimeFormat} from '@docusaurus/theme-common/internal';
import Layout from '@theme/Layout';
import type {ArchiveBlogPost, Props} from '@theme/BlogArchivePage';
import Heading from '@theme/Heading';
@ -19,6 +20,15 @@ type YearProp = {
};
function Year({year, posts}: YearProp) {
const dateTimeFormat = useDateTimeFormat({
day: 'numeric',
month: 'long',
timeZone: 'UTC',
});
const formatDate = (lastUpdated: string) =>
dateTimeFormat.format(new Date(lastUpdated));
return (
<>
<Heading as="h3" id={year}>
@ -28,7 +38,7 @@ function Year({year, posts}: YearProp) {
{posts.map((post) => (
<li key={post.metadata.date}>
<Link to={post.metadata.permalink}>
{post.metadata.formattedDate} - {post.metadata.title}
{formatDate(post.metadata.date)} - {post.metadata.title}
</Link>
</li>
))}

View file

@ -9,7 +9,10 @@ import React from 'react';
import clsx from 'clsx';
import {translate} from '@docusaurus/Translate';
import {usePluralForm} from '@docusaurus/theme-common';
import {useBlogPost} from '@docusaurus/theme-common/internal';
import {
useBlogPost,
useDateTimeFormat,
} from '@docusaurus/theme-common/internal';
import type {Props} from '@theme/BlogPostItem/Header/Info';
import styles from './styles.module.css';
@ -39,7 +42,13 @@ function ReadingTime({readingTime}: {readingTime: number}) {
return <>{readingTimePlural(readingTime)}</>;
}
function Date({date, formattedDate}: {date: string; formattedDate: string}) {
function DateTime({
date,
formattedDate,
}: {
date: string;
formattedDate: string;
}) {
return <time dateTime={date}>{formattedDate}</time>;
}
@ -51,11 +60,21 @@ export default function BlogPostItemHeaderInfo({
className,
}: Props): JSX.Element {
const {metadata} = useBlogPost();
const {date, formattedDate, readingTime} = metadata;
const {date, readingTime} = metadata;
const dateTimeFormat = useDateTimeFormat({
day: 'numeric',
month: 'long',
year: 'numeric',
timeZone: 'UTC',
});
const formatDate = (blogDate: string) =>
dateTimeFormat.format(new Date(blogDate));
return (
<div className={clsx(styles.container, 'margin-vert--md', className)}>
<Date date={date} formattedDate={formattedDate} />
<DateTime date={date} formattedDate={formatDate(date)} />
{typeof readingTime !== 'undefined' && (
<>
<Spacer />

View file

@ -33,13 +33,12 @@ function TagsRow(props: TagsListInlineProps) {
type EditMetaRowProps = Pick<
DocContextValue['metadata'],
'editUrl' | 'lastUpdatedAt' | 'lastUpdatedBy' | 'formattedLastUpdatedAt'
'editUrl' | 'lastUpdatedAt' | 'lastUpdatedBy'
>;
function EditMetaRow({
editUrl,
lastUpdatedAt,
lastUpdatedBy,
formattedLastUpdatedAt,
}: EditMetaRowProps) {
return (
<div className={clsx(ThemeClassNames.docs.docFooterEditMetaRow, 'row')}>
@ -49,7 +48,6 @@ function EditMetaRow({
{(lastUpdatedAt || lastUpdatedBy) && (
<LastUpdated
lastUpdatedAt={lastUpdatedAt}
formattedLastUpdatedAt={formattedLastUpdatedAt}
lastUpdatedBy={lastUpdatedBy}
/>
)}
@ -60,8 +58,7 @@ function EditMetaRow({
export default function DocItemFooter(): JSX.Element | null {
const {metadata} = useDoc();
const {editUrl, lastUpdatedAt, formattedLastUpdatedAt, lastUpdatedBy, tags} =
metadata;
const {editUrl, lastUpdatedAt, lastUpdatedBy, tags} = metadata;
const canDisplayTagsRow = tags.length > 0;
const canDisplayEditMetaRow = !!(editUrl || lastUpdatedAt || lastUpdatedBy);
@ -81,7 +78,6 @@ export default function DocItemFooter(): JSX.Element | null {
editUrl={editUrl}
lastUpdatedAt={lastUpdatedAt}
lastUpdatedBy={lastUpdatedBy}
formattedLastUpdatedAt={formattedLastUpdatedAt}
/>
)}
</footer>

View file

@ -8,15 +8,25 @@
import React from 'react';
import Translate from '@docusaurus/Translate';
import {ThemeClassNames} from '@docusaurus/theme-common';
import {useDateTimeFormat} from '@docusaurus/theme-common/internal';
import type {Props} from '@theme/LastUpdated';
function LastUpdatedAtDate({
lastUpdatedAt,
formattedLastUpdatedAt,
}: {
lastUpdatedAt: number;
formattedLastUpdatedAt: string;
}): JSX.Element {
const atDate = new Date(lastUpdatedAt * 1000);
const dateTimeFormat = useDateTimeFormat({
day: 'numeric',
month: 'short',
year: 'numeric',
timeZone: 'UTC',
});
const formattedLastUpdatedAt = dateTimeFormat.format(atDate);
return (
<Translate
id="theme.lastUpdated.atDate"
@ -24,7 +34,7 @@ function LastUpdatedAtDate({
values={{
date: (
<b>
<time dateTime={new Date(lastUpdatedAt * 1000).toISOString()}>
<time dateTime={atDate.toISOString()}>
{formattedLastUpdatedAt}
</time>
</b>
@ -54,7 +64,6 @@ function LastUpdatedByUser({
export default function LastUpdated({
lastUpdatedAt,
formattedLastUpdatedAt,
lastUpdatedBy,
}: Props): JSX.Element {
return (
@ -63,12 +72,8 @@ export default function LastUpdated({
id="theme.lastUpdated.lastUpdatedAtBy"
description="The sentence used to display when a page has been last updated, and by who"
values={{
atDate:
lastUpdatedAt && formattedLastUpdatedAt ? (
<LastUpdatedAtDate
lastUpdatedAt={lastUpdatedAt}
formattedLastUpdatedAt={formattedLastUpdatedAt}
/>
atDate: lastUpdatedAt ? (
<LastUpdatedAtDate lastUpdatedAt={lastUpdatedAt} />
) : (
''
),

View file

@ -114,6 +114,7 @@ export {
} from './hooks/useTOCHighlight';
export {useVisibleBlogSidebarItems} from './utils/blogUtils';
export {useDateTimeFormat} from './utils/IntlUtils';
export {useHideableNavbar} from './hooks/useHideableNavbar';
export {

View file

@ -0,0 +1,27 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
export function useCalendar(): string {
const {
i18n: {currentLocale, localeConfigs},
} = useDocusaurusContext();
return localeConfigs[currentLocale]!.calendar;
}
export function useDateTimeFormat(
options: Intl.DateTimeFormatOptions = {},
): Intl.DateTimeFormat {
const {
i18n: {currentLocale},
} = useDocusaurusContext();
const calendar = useCalendar();
return new Intl.DateTimeFormat(currentLocale, {
calendar,
...options,
});
}

View file

@ -8,7 +8,6 @@ algoliasearch
Allez
Anshul
anshul
août
APFS
apfs
appinstalled
@ -105,7 +104,6 @@ Formik
FOUC
froms
funboxteam
février
gabrielcsapo
Gifs
Goss
@ -139,14 +137,12 @@ interactiveness
Interpolatable
interpolatable
Investec
janvier
javadoc
jiti
jmarcey
jodyheavener
joshcena
jssdk
juillet
Kaszubowski
Katex
katex