diff --git a/.vscode/settings.json b/.vscode/settings.json index fbaef8e1..a8ef4c90 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,7 +12,7 @@ "editor.wordWrap": "on" }, "[svelte]": { - "editor.defaultFormatter": "svelte.svelte-vscode" - }, + "editor.defaultFormatter": "svelte.svelte-vscode" + }, "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/package.json b/package.json index ac599ebb..90b58bcd 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,8 @@ "dayjs": "^1.11.13", "journalize": "^2.6.0", "lodash-es": "^4.17.21", - "marked": "^4.3.0", + "marked": "^15.0.7", + "marked-smartypants": "^1.1.9", "proper-url-join": "^2.1.2", "pym.js": "^1.3.2", "slugify": "^1.6.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4472d286..1b56a901 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,8 +33,11 @@ importers: specifier: ^4.17.21 version: 4.17.21 marked: - specifier: ^4.3.0 - version: 4.3.0 + specifier: ^15.0.7 + version: 15.0.7 + marked-smartypants: + specifier: ^1.1.9 + version: 1.1.9(marked@15.0.7) proper-url-join: specifier: ^2.1.2 version: 2.1.2 @@ -2968,9 +2971,14 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - marked@4.3.0: - resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} - engines: {node: '>= 12'} + marked-smartypants@1.1.9: + resolution: {integrity: sha512-VPeuaUr5IWptI7nJdgQ9ugrLWYGv13NdzEXTtKY3cmB4aRWOI2RzhLlf+xQp6Wnob9SAPO2sNVlfSJr+nflk/A==} + peerDependencies: + marked: '>=4 <16' + + marked@15.0.7: + resolution: {integrity: sha512-dgLIeKGLx5FwziAnsk4ONoGwHwGPJzselimvlVskE9XLN4Orv9u2VA3GWw/lYUqjfA0rUT/6fqKwfZJapP9BEg==} + engines: {node: '>= 18'} hasBin: true math-intrinsics@1.1.0: @@ -3909,6 +3917,10 @@ packages: resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==} engines: {node: '>=8.0.0'} + smartypants@0.2.2: + resolution: {integrity: sha512-TzobUYoEft/xBtb2voRPryAUIvYguG0V7Tt3de79I1WfXgCwelqVsGuZSnu3GFGRZhXR90AeEYIM+icuB/S06Q==} + hasBin: true + smol-toml@1.3.1: resolution: {integrity: sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ==} engines: {node: '>= 18'} @@ -7598,7 +7610,12 @@ snapshots: markdown-table@3.0.4: {} - marked@4.3.0: {} + marked-smartypants@1.1.9(marked@15.0.7): + dependencies: + marked: 15.0.7 + smartypants: 0.2.2 + + marked@15.0.7: {} math-intrinsics@1.1.0: {} @@ -8979,6 +8996,8 @@ snapshots: slugify@1.6.6: {} + smartypants@0.2.2: {} + smol-toml@1.3.1: {} snake-case@3.0.4: diff --git a/src/app.html b/src/app.html index 7bf73d49..61516813 100644 --- a/src/app.html +++ b/src/app.html @@ -1,11 +1,11 @@ - + - - - - %sveltekit.head% - - - %sveltekit.body% - - \ No newline at end of file + + + + %sveltekit.head% + + + %sveltekit.body% + + diff --git a/src/components/AdSlot/AdSlot.svelte b/src/components/AdSlot/AdSlot.svelte index 4fed36b9..c80e6925 100644 --- a/src/components/AdSlot/AdSlot.svelte +++ b/src/components/AdSlot/AdSlot.svelte @@ -55,7 +55,7 @@ }); -
+
+``` + + diff --git a/src/components/BeforeAfter/BeforeAfter.stories.svelte b/src/components/BeforeAfter/BeforeAfter.stories.svelte index d2f79821..74ef3be3 100644 --- a/src/components/BeforeAfter/BeforeAfter.stories.svelte +++ b/src/components/BeforeAfter/BeforeAfter.stories.svelte @@ -1,19 +1,10 @@ - - - - - + -
-

July 7, 2020

-

Initially, this site was far smaller.

-
-
-

Oct. 20, 2020

-

But then forces built up.

-
-

Photos by MAXAR Technologies, 2021.

+ {#snippet beforeOverlay()} +
+

July 7, 2020

+

Initially, this site was far smaller.

+
+ {/snippet} + {#snippet afterOverlay()} +
+

Oct. 20, 2020

+

But then forces built up.

+
+ {/snippet} + {#snippet caption()} +

Photos by MAXAR Technologies, 2021.

+ {/snippet}
-
- - - -
-

- On July 7, 2020, the base contained only a few transport vehicles. -

-
-
- -
-

- But by October, tanks and artillery could be seen. -

-

- In total, over 50 pieces of heavy machinery and 200 personnel are now - based here. -

-
-
-

Photos by MAXAR Technologies, 2021.

-
- diff --git a/src/components/BeforeAfter/stories/myrne-after.jpg b/src/components/BeforeAfter/images/myrne-after.jpg similarity index 100% rename from src/components/BeforeAfter/stories/myrne-after.jpg rename to src/components/BeforeAfter/images/myrne-after.jpg diff --git a/src/components/BeforeAfter/stories/myrne-before.jpg b/src/components/BeforeAfter/images/myrne-before.jpg similarity index 100% rename from src/components/BeforeAfter/stories/myrne-before.jpg rename to src/components/BeforeAfter/images/myrne-before.jpg diff --git a/src/components/BeforeAfter/stories/docs/ariaDescriptions.md b/src/components/BeforeAfter/stories/docs/ariaDescriptions.md deleted file mode 100644 index 7e87edd3..00000000 --- a/src/components/BeforeAfter/stories/docs/ariaDescriptions.md +++ /dev/null @@ -1,35 +0,0 @@ -Use text elements in your overlays as [ARIA descriptions](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby) for your images by setting an ID on text elements within each overlay with the `description` [slot prop](https://svelte.dev/tutorial/slot-props). - -> **💡 TIP:** You must always use the `beforeAlt` / `afterAlt` props to label your image for visually impaired readers, but you can use these descriptions to provide more information or context that the reader might also need. - -```svelte - -
-

July 7, 2020

-

Initially, this site was far smaller.

-
-
-

Oct. 20, 2020

-

But then forces built up.

-
-

Photos by MAXAR Technologies, 2021.

-
- - -``` diff --git a/src/components/BeforeAfter/stories/docs/component.md b/src/components/BeforeAfter/stories/docs/component.md deleted file mode 100644 index 6998143a..00000000 --- a/src/components/BeforeAfter/stories/docs/component.md +++ /dev/null @@ -1,15 +0,0 @@ -A before and after image comparison component. - -```svelte - - - -``` diff --git a/src/components/BeforeAfter/stories/docs/withOverlays.md b/src/components/BeforeAfter/stories/docs/withOverlays.md deleted file mode 100644 index 4a6028d6..00000000 --- a/src/components/BeforeAfter/stories/docs/withOverlays.md +++ /dev/null @@ -1,33 +0,0 @@ -Add overlays with the `beforeOverlay` and `afterOverlay` slots and a caption to the `caption` slot, then style these elements to match your page design as below. - -```svelte - -
-

July 7, 2020

-

Initially, this site was far smaller.

-
-
-

Oct. 20, 2020

-

But then forces built up.

-
-

Photos by MAXAR Technologies, 2021.

-
- - -``` diff --git a/src/components/BodyText/BodyText.mdx b/src/components/BodyText/BodyText.mdx index 9cd25312..3055be1a 100644 --- a/src/components/BodyText/BodyText.mdx +++ b/src/components/BodyText/BodyText.mdx @@ -30,10 +30,10 @@ Venison shoulder *ham hock ham leberkas*. Flank beef ribs fatback, jerky meatbal ## Using with ArchieML docs -With the graphics kit, you'll likely get your text value from an ArchieML doc. +With the Graphics Kit, you'll likely get your text value from an ArchieML doc... ```yaml -# Archie ML doc +# ArchieML doc [blocks] type: text diff --git a/src/components/Byline/Byline.mdx b/src/components/Byline/Byline.mdx new file mode 100644 index 00000000..dbff6ad5 --- /dev/null +++ b/src/components/Byline/Byline.mdx @@ -0,0 +1,84 @@ +import { Meta, Canvas } from '@storybook/blocks'; + +import * as BylineStories from './Byline.stories.svelte'; + + + +# Byline + +The `Byline` component adds a byline, published and updated datelines to your page. + +```svelte + + + +``` + +## Using with ArchieML docs + +With the Graphics Kit, you'll likely get your text value from an ArchieML doc... + +```yaml +# ArchieML doc +[authors] +* Dea Bankova +* Prasanta Kumar Dutta +* Anurag Rao +* Mariano Zafra +[] +publishTime: 2021-09-12T00:00:00.000Z +updateTime: 2021-09-12T12:57:00.000Z +``` + +... which you'll pass to the `Byline` component. + +```svelte + + + +``` + + + +## Cutomisation + +Use [snippets](https://svelte.dev/docs/svelte/snippet) to customise the byline, published and updated datelines. + +```svelte + + + {#snippet byline()} + BY REUTERS GRAPHICS + {/snippet} + + + {#snippet published()} + PUBLISHED on some custom date and time + {/snippet} + + + {#snippet updated()} + Updated every 5 minutes + {/snippet} + +``` + + diff --git a/src/components/Byline/Byline.stories.svelte b/src/components/Byline/Byline.stories.svelte index 5855ceef..c0cf796a 100644 --- a/src/components/Byline/Byline.stories.svelte +++ b/src/components/Byline/Byline.stories.svelte @@ -1,17 +1,11 @@ -{#snippet template(args: ComponentProps)} - -{/snippet} - + + + + {#snippet byline()} + BY REUTERS GRAPHICS + {/snippet} + {#snippet published()} + PUBLISHED on some custom date and time + {/snippet} + {#snippet updated()} + Updated every 5 minutes + {/snippet} + + diff --git a/src/components/Byline/Byline.svelte b/src/components/Byline/Byline.svelte index 8f67a4e7..37050af2 100644 --- a/src/components/Byline/Byline.svelte +++ b/src/components/Byline/Byline.svelte @@ -4,63 +4,89 @@ import Block from '../Block/Block.svelte'; import slugify from 'slugify'; import { apdate } from 'journalize'; + import type { Snippet } from 'svelte'; + + interface Props { + /** + * Array of author names, which will be slugified to create links to Reuters author pages + */ + authors?: string[]; + /** + * Publish time as a datetime string. + */ + publishTime: string; + /** + * Update time as a datetime string. + */ + updateTime: string; + /** + * Alignment of the byline. + */ + align?: 'left' | 'center'; + /** + * Add an id to to target with custom CSS. + * @type {string} + */ + id?: string; + /** + * Add extra classes to target with custom CSS. + * @type {string} + */ + cls?: string; + /** + * Custom function that returns an author page URL. + */ + getAuthorPage?: (author: string) => string; + /** + * Optional snippet for a custom byline. + */ + byline?: Snippet; + /** + * Optional snippet for a custom published dateline. + */ + // Specify that this prop should have the type of a Svelte snippet, i.e. basic html + published?: Snippet; + /** + * Optional snippet for a custom updated dateline. + */ + updated?: Snippet; + } + + let { + authors = [], + publishTime, + updateTime, + align = 'left', + id = '', + cls = '', + getAuthorPage = (author: string): string => { + const authorSlug = slugify(author.trim(), { lower: true }); + return `https://www.reuters.com/authors/${authorSlug}/`; + }, + byline, + published, + updated, + }: Props = $props(); + + let alignmentClass = $derived(align === 'left' ? 'text-left' : 'text-center'); /** - * Array of author names, which will be slugified to create links to Reuters author pages + /* Date validation and formatter functions */ - export let authors: string[] = []; - /** - * Publish time as a datetime string. - * @type {string} - */ - export let publishTime: string = ''; - /** - * Update time as a datetime string. - * @type {string} - */ - export let updateTime: string = ''; - /** - * Alignment of the byline. - * @type {string} - */ - export let align: 'left' | 'center' = 'left'; - /** - * Add an id to to target with custom CSS. - * @type {string} - */ - export let id: string = ''; - /** - * Add extra classes to target with custom CSS. - * @type {string} - */ - let cls: string = ''; - export { cls as class }; - - /** - * Custom function that returns an author page URL. - * @param author - */ - export let getAuthorPage = (author: string): string => { - const authorSlug = slugify(author.trim(), { lower: true }); - return `https://www.reuters.com/authors/${authorSlug}/`; - }; - - $: alignmentClass = align === 'left' ? 'text-left' : 'text-center'; - - const isValidDate = (datetime) => { + const isValidDate = (datetime: string) => { if (!datetime) return false; if (!Date.parse(datetime)) return false; return true; }; - const formatTime = (datetime) => + const formatTime = (datetime: string) => new Date(datetime).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', timeZoneName: 'short', }); - const areSameDay = (first, second) => + const areSameDay = (first: Date, second: Date) => first.getFullYear() === second.getFullYear() && first.getMonth() === second.getMonth() && first.getDate() === second.getDate(); @@ -69,16 +95,16 @@