@reuters-graphics/graphics-components 3.10.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/components/Analytics/GTM.svelte.d.ts +3 -3
  2. package/dist/components/BlogPost/BlogPost.svelte +6 -5
  3. package/dist/components/BlogPost/BlogPost.svelte.d.ts +3 -2
  4. package/dist/components/BlogPost/CopyLink.svelte +7 -4
  5. package/dist/components/BlogPost/CopyLink.svelte.d.ts +5 -2
  6. package/dist/components/BlogPost/PostHeadline.svelte +7 -4
  7. package/dist/components/BlogPost/PostHeadline.svelte.d.ts +5 -2
  8. package/dist/components/BlogPost/utils.d.ts +2 -1
  9. package/dist/components/BlogPost/utils.js +8 -2
  10. package/dist/components/BlogTOC/BlogTOC.svelte +7 -4
  11. package/dist/components/BlogTOC/BlogTOC.svelte.d.ts +8 -5
  12. package/dist/components/BlogTOC/TOCList.svelte.d.ts +3 -3
  13. package/dist/components/Headpile/Headpile.svelte +2 -2
  14. package/dist/components/Headpile/Headpile.svelte.d.ts +2 -2
  15. package/dist/components/LanguageButton/LanguageButton.svelte +10 -7
  16. package/dist/components/LanguageButton/LanguageButton.svelte.d.ts +5 -2
  17. package/dist/components/SEO/SEO.svelte.d.ts +3 -3
  18. package/dist/components/Video/Video.svelte +2 -2
  19. package/dist/llm-docs/components/AdSlot.md +11 -0
  20. package/dist/llm-docs/components/Analytics.md +89 -0
  21. package/dist/llm-docs/components/Article.md +183 -0
  22. package/dist/llm-docs/components/BeforeAfter.md +170 -0
  23. package/dist/llm-docs/components/BioBox.md +74 -0
  24. package/dist/llm-docs/components/Block.md +211 -0
  25. package/dist/llm-docs/components/BlogPost.md +66 -0
  26. package/dist/llm-docs/components/BlogTOC.md +89 -0
  27. package/dist/llm-docs/components/BodyText.md +143 -0
  28. package/dist/llm-docs/components/Byline.md +242 -0
  29. package/dist/llm-docs/components/ClockWall.md +48 -0
  30. package/dist/llm-docs/components/DatawrapperChart.md +87 -0
  31. package/dist/llm-docs/components/DocumentCloud.md +47 -0
  32. package/dist/llm-docs/components/EmbedPreviewerLink.md +35 -0
  33. package/dist/llm-docs/components/EndNotes.md +79 -0
  34. package/dist/llm-docs/components/FeaturePhoto.md +102 -0
  35. package/dist/llm-docs/components/Framer.md +44 -0
  36. package/dist/llm-docs/components/Geocoder.md +49 -0
  37. package/dist/llm-docs/components/GraphicBlock.md +319 -0
  38. package/dist/llm-docs/components/Headline.md +248 -0
  39. package/dist/llm-docs/components/Headpile.md +55 -0
  40. package/dist/llm-docs/components/HeroHeadline.md +515 -0
  41. package/dist/llm-docs/components/HorizontalScroller.md +523 -0
  42. package/dist/llm-docs/components/InfoBox.md +196 -0
  43. package/dist/llm-docs/components/KinesisLogo.md +34 -0
  44. package/dist/llm-docs/components/LanguageButton.md +170 -0
  45. package/dist/llm-docs/components/Legend.md +251 -0
  46. package/dist/llm-docs/components/Lottie.md +464 -0
  47. package/dist/llm-docs/components/PaddingReset.md +78 -0
  48. package/dist/llm-docs/components/PhotoPack.md +238 -0
  49. package/dist/llm-docs/components/PymChild.md +49 -0
  50. package/dist/llm-docs/components/ReferralBlock.md +119 -0
  51. package/dist/llm-docs/components/ReutersGraphicsLogo.md +37 -0
  52. package/dist/llm-docs/components/ReutersLogo.md +35 -0
  53. package/dist/llm-docs/components/SEO.md +113 -0
  54. package/dist/llm-docs/components/Scroller.md +350 -0
  55. package/dist/llm-docs/components/ScrollerBase.md +104 -0
  56. package/dist/llm-docs/components/ScrollerVideo.md +576 -0
  57. package/dist/llm-docs/components/SearchInput.md +44 -0
  58. package/dist/llm-docs/components/ShareBar.md +78 -0
  59. package/dist/llm-docs/components/SimpleTimeline.md +141 -0
  60. package/dist/llm-docs/components/SiteFooter.md +77 -0
  61. package/dist/llm-docs/components/SiteHeader.md +55 -0
  62. package/dist/llm-docs/components/SiteHeadline.md +111 -0
  63. package/dist/llm-docs/components/Spinner.md +43 -0
  64. package/dist/llm-docs/components/Table.md +298 -0
  65. package/dist/llm-docs/components/Theme.md +266 -0
  66. package/dist/llm-docs/components/TileMap.md +477 -0
  67. package/dist/llm-docs/components/ToolsHeader.md +46 -0
  68. package/dist/llm-docs/components/Video.md +254 -0
  69. package/dist/llm-docs/components/Visible.md +54 -0
  70. package/dist/llm-docs/components/cssVariables.md +40 -0
  71. package/dist/llm-docs/components/index.md +59 -0
  72. package/dist/llm-docs/components/resizeObserver.md +21 -0
  73. package/dist/llm-docs/guides/archieml.md +406 -0
  74. package/dist/llm-docs/guides/colours.md +443 -0
  75. package/dist/llm-docs/guides/customising-with-scss.md +61 -0
  76. package/dist/llm-docs/guides/graphics-kit.md +25 -0
  77. package/dist/llm-docs/guides/index.md +16 -0
  78. package/dist/llm-docs/guides/intro.md +21 -0
  79. package/dist/llm-docs/guides/layout.md +13 -0
  80. package/dist/llm-docs/guides/llm-docs.md +71 -0
  81. package/dist/llm-docs/guides/styles.md +16 -0
  82. package/dist/llm-docs/guides/theming.md +100 -0
  83. package/dist/llm-docs/guides/tokens.md +150 -0
  84. package/dist/llm-docs/index.md +36 -0
  85. package/package.json +18 -24
@@ -0,0 +1,196 @@
1
+ # InfoBox
2
+
3
+ **Category:** Components/Text elements/InfoBox
4
+
5
+ **Import:** `import { InfoBox } from '@reuters-graphics/graphics-components'`
6
+
7
+ ## Props
8
+
9
+ | Prop | Type | Default | Required | Description |
10
+ |------|------|---------|:--------:|-------------|
11
+ | `title` | `string \| null` | `null` | | Title of the box |
12
+ | `text` | `string` | — | | Contents of the note as a markdown string |
13
+ | `notes` | `string \| null` | `null` | | Additional footnotes |
14
+ | `width` | `ContainerWidth` | `'normal'` | | Width of the component within the text well. Options: `normal`, `wide`, `wider`, `widest`, `fluid` |
15
+ | `class` | `string` | `''` | | Add extra classes to the block tag to target it with custom CSS. |
16
+ | `id` | `string` | `''` | | Add an id to the block tag to target it with custom CSS. |
17
+ | `theme` | `Theme` | `'light'` | | Page theme Options: `light`, `dark` |
18
+ | `header` | `Snippet` | — | | Optional custom header snippet |
19
+ | `body` | `Snippet` | — | | Optional custom body snippet |
20
+ | `footer` | `Snippet` | — | | Optional custom footer snippet |
21
+
22
+ ## Examples
23
+
24
+ ### Demo
25
+
26
+ ```svelte
27
+ <BodyText
28
+ text="Bacon ipsum dolor amet turducken buffalo beef ribs bresaola pancetta ribeye pork belly doner hamburger biltong cupim porchetta chuck ham tenderloin. Turducken bresaola jerky chicken."
29
+ />
30
+ <InfoBox
31
+ title="About this data"
32
+ text={'Reuters is collecting daily COVID-19 infections and deaths data for 240 countries and territories around the world, updated regularly throughout each day. \n\n Every country reports those figures a little differently and, inevitably, misses undiagnosed infections and deaths. With this project we are focusing on the trends within countries as they try to contain the virus’ spread, whether they are approaching or past peak infection rates, or if they are seeing a resurgence of infections or deaths.'}
33
+ notes={'[Read more about our methodology](https://www.reuters.com/world-coronavirus-tracker-and-maps/en/methodology/)'}
34
+ />
35
+ <BodyText
36
+ text="Ham drumstick tail ribeye pancetta, leberkas hamburger chicken spare ribs buffalo jerky sausage ground round meatball. Leberkas kevin short loin, tri-tip shank spare ribs buffalo beef pork belly corned beef chislic tongue."
37
+ />
38
+ ```
39
+
40
+ ### Lists
41
+
42
+ ```svelte
43
+ <InfoBox
44
+ title="What you need to know about the war"
45
+ text={/* value — see Props/Types for full type */}
46
+ />
47
+ ```
48
+
49
+ ### Customised
50
+
51
+ ```svelte
52
+ <InfoBox>
53
+ {#snippet header()}
54
+ <h3>Global video game market</h3>
55
+ {/snippet}
56
+ {#snippet body()}
57
+ <table>
58
+ <thead>
59
+ <tr>
60
+ <th>Year</th>
61
+ <th>Market size ($bln)</th>
62
+ </tr>
63
+ </thead>
64
+ <tbody>
65
+ <tr>
66
+ <td>2024</td>
67
+ <td>274.63</td>
68
+ </tr>
69
+ <tr>
70
+ <td>2023</td>
71
+ <td>281.77</td>
72
+ </tr>
73
+ <tr>
74
+ <td>2022</td>
75
+ <td>249.55</td>
76
+ </tr>
77
+ </tbody>
78
+ </table>
79
+ {/snippet}
80
+ {#snippet footer()}
81
+ <div class="text-xs font-note">Source: Precedence Research</div>
82
+ {/snippet}
83
+ </InfoBox>
84
+ ```
85
+
86
+ ## Documentation
87
+
88
+ # InfoBox
89
+
90
+ The `InfoBox` component creates a stylised text box that provides additional information that needs to be visually separate from the main content flow, such as methodology, detailed notes about data and extra context.
91
+
92
+ ```svelte
93
+ <script>
94
+ import { InfoBox } from '@reuters-graphics/graphics-components';
95
+ </script>
96
+
97
+ <InfoBox
98
+ title="About this data"
99
+ text={'Reuters is collecting daily COVID-19 infections and deaths data for 240 countries and territories around the world, updated regularly throughout each day. \n\n Every country reports those figures a little differently and, inevitably, misses undiagnosed infections and deaths. With this project we are focusing on the trends within countries as they try to contain the virus’ spread, whether they are approaching or past peak infection rates, or if they are seeing a resurgence of infections or deaths.'}
100
+ notes={'[Read more about our methodology](https://www.reuters.com/world-coronavirus-tracker-and-maps/en/methodology/)'}
101
+ />
102
+ ```
103
+
104
+ ## Using with ArchieML docs
105
+
106
+ With the graphics kit, you'll likely get your text value from an ArchieML doc...
107
+
108
+ ```yaml
109
+ # Archie ML doc
110
+ [blocks]
111
+
112
+ type: info-box
113
+ title: What you need to know about the war
114
+ text: Reuters is collecting daily COVID-19 infections and deaths data for 240 countries and territories around the world, updated regularly throughout each day.
115
+
116
+ Every country reports those figures a little differently and, inevitably, misses undiagnosed infections and deaths. With this project we are focusing on the trends within countries as they try to contain the virus’ spread, whether they are approaching or past peak infection rates, or if they are seeing a resurgence of infections or deaths.
117
+ :end
118
+ notes: [Read more about our methodology](https://www.reuters.com/world-coronavirus-tracker-and-maps/en/methodology/)
119
+ []
120
+ ```
121
+
122
+ ... which you'll parse out of a ArchieML block object before passing to the `InfoBox` component.
123
+
124
+ ```svelte
125
+ <!-- graphics kit -->
126
+ <script>
127
+ import { InfoBox } from '@reuters-graphics/graphics-components';
128
+ import content from '$locales/en/content.json';
129
+ </script>
130
+
131
+ # Graphics kit
132
+ {#each content.blocks as block}
133
+ {#if block.type === 'info-box'}
134
+ <InfoBox title={block.title} text={block.text} notes={block.notes} />
135
+ <!-- ... -->
136
+ {/if}
137
+ {/each}
138
+ ```
139
+
140
+ ## Lists
141
+
142
+ Use markdown to add lists to `InfoBox`.
143
+
144
+ ```svelte
145
+ <script>
146
+ import { InfoBox } from '@reuters-graphics/graphics-components';
147
+ </script>
148
+
149
+ <InfoBox
150
+ title="What you need to know about the war"
151
+ text={"- **Food crisis**: [Russia's invasion of Ukraine](#) in late February dramatically worsened the outlook for already inflated global food prices.\n- **Under fire**: Civillian homes destroyed in the conflict and Russia accused of war crimes.\n- **Nordstream sabotage**: A series of clandestine bombings and subsequent underwater gas leaks occurred on the Nord Stream 1 and Nord Stream 2 natural gas pipelines."}
152
+ notes={'[Read more about our methodology](https://www.reuters.com/world-coronavirus-tracker-and-maps/en/methodology/)'}
153
+ />
154
+ ```
155
+
156
+ ## Customisation
157
+
158
+ Use [snippets](https://svelte.dev/docs/svelte/snippet) to customise the `InfoBox`, such as adding tables, icons and thumbnail images.
159
+
160
+ ```svelte
161
+ <InfoBox title="About this data">
162
+ <!-- Optional custom header -->
163
+ {#snippet header()}
164
+ <h3>Global video game market</h3>
165
+ {/snippet}
166
+ <!-- Optional custom body -->
167
+ {#snippet body()}
168
+ <table>
169
+ <thead>
170
+ <tr>
171
+ <th>Year</th>
172
+ <th>Market size ($bln)</th>
173
+ </tr>
174
+ </thead>
175
+ <tbody>
176
+ <tr>
177
+ <td>2024</td>
178
+ <td>274.63</td>
179
+ </tr>
180
+ <tr>
181
+ <td>2023</td>
182
+ <td>281.77</td>
183
+ </tr>
184
+ <tr>
185
+ <td>2022</td>
186
+ <td>249.55</td>
187
+ </tr>
188
+ </tbody>
189
+ </table>
190
+ {/snippet}
191
+ <!-- Optional custom footer -->
192
+ {#snippet updated()}
193
+ <div class="text-xs font-note">Source: Precedence Research</div>
194
+ {/snippet}
195
+ </InfoBox>
196
+ ```
@@ -0,0 +1,34 @@
1
+ # KinesisLogo
2
+
3
+ **Category:** Components/Logos/KinesisLogo
4
+
5
+ **Import:** `import { KinesisLogo } from '@reuters-graphics/graphics-components'`
6
+
7
+ ## Props
8
+
9
+ | Prop | Type | Default | Required | Description |
10
+ |------|------|---------|:--------:|-------------|
11
+ | `colour` | `string` | `'#D64000'` | | "Kinesis" colour |
12
+ | `width` | `string` | `'100%'` | | CSS width value |
13
+
14
+ ## Examples
15
+
16
+ ### Demo
17
+
18
+ ```svelte
19
+ <KinesisLogo />
20
+ ```
21
+
22
+ ## Documentation
23
+
24
+ # KinesisLogo
25
+
26
+ The `KinesisLogo` component contains the official Kinesis logo.
27
+
28
+ ```svelte
29
+ <script>
30
+ import { KinesisLogo } from '@reuters-graphics/graphics-components';
31
+ </script>
32
+
33
+ <KinesisLogo />
34
+ ```
@@ -0,0 +1,170 @@
1
+ # LanguageButton
2
+
3
+ **Category:** Components/Text elements/LanguageButton
4
+
5
+ **Import:** `import { LanguageButton } from '@reuters-graphics/graphics-components'`
6
+
7
+ ## Props
8
+
9
+ | Prop | Type | Default | Required | Description |
10
+ |------|------|---------|:--------:|-------------|
11
+ | `locale` | `string \| undefined` | `'en'` | | The current locale of the article |
12
+ | `embedded` | `boolean` | `false` | | Whether the article is embedded |
13
+ | `buttonOptions` | `{ locale: string; label: string; }` | `{
14
+ locale: 'es',
15
+ label: 'Leer en español',
16
+ }` | | Options for the language toggle button |
17
+ | `setUrl` | `() => string` | — | | Custom function for handling URL changes for locales and embed versions. |
18
+
19
+ ## Examples
20
+
21
+ ### Demo
22
+
23
+ ```svelte
24
+ <div style="display: flex; flex-direction: column; gap: 2rem;">
25
+ {@render demoToggle(
26
+ spanishLocale,
27
+ 'es',
28
+ 'ES',
29
+ 'Toggle between English and Spanish',
30
+ () => {
31
+ spanishLocale = spanishLocale === 'en' ? 'es' : 'en';
32
+ }
33
+ )}
34
+ <LanguageButton locale={spanishLocale}></LanguageButton>
35
+ </div>
36
+ ```
37
+
38
+ ### CustomiseLanguage
39
+
40
+ ```svelte
41
+ <div style="display: flex; flex-direction: column; gap: 2rem;">
42
+ {@render demoToggle(
43
+ frenchLocale,
44
+ 'fr',
45
+ 'FR',
46
+ 'Toggle between English and French',
47
+ () => {
48
+ frenchLocale = frenchLocale === 'en' ? 'fr' : 'en';
49
+ }
50
+ )}
51
+ <LanguageButton
52
+ locale={frenchLocale}
53
+ buttonOptions={{
54
+ locale: 'fr',
55
+ label: 'Lire en français',
56
+ }}
57
+ ></LanguageButton>
58
+ </div>
59
+ ```
60
+
61
+ ## Documentation
62
+
63
+ # LanguageButton
64
+
65
+ The `LanguageButton` component creates a button that switches between an article written in English and another language.
66
+
67
+ > 💡**NOTE:** If a translated embed page does not exist, add `LanguageButton` conditionally so it only renders when `embedded` is `false`. This prevents a toggle button from appearing on the English embed page.
68
+
69
+ ```svelte
70
+ <script>
71
+ import { LanguageButton } from '@reuters-graphics/graphics-components';
72
+
73
+ // If using in the graphics kit, use `resolve` from `$app/paths` to ensure the toggle links to the correct URL
74
+ import { resolve } from '$app/paths';
75
+
76
+ // If using in the graphics kit, `embedded` prop will already be available in App.svelte.
77
+ // Additionally, pass `locale = 'en'` as a prop
78
+ let { embedded = false, locale = 'en' }: Props = $props();
79
+ </script>
80
+
81
+ <!-- Pass `embedded` to `LanguageButton` if the embed page is translated -->
82
+ <LanguageButton {locale} {embedded} {resolve} />
83
+ ```
84
+
85
+ ## Customise language and button label
86
+
87
+ By default, the toggle button will switch between English and Spanish, and the `buttonOptions` prop does not need to be passed. To customise the language and button label, pass the `locale` and the button `label` for the translation language as an object to the `buttonOptions` prop.
88
+
89
+ ```svelte
90
+ <script>
91
+ import { LanguageButton } from '@reuters-graphics/graphics-components';
92
+
93
+ // If using in the graphics kit, use `resolve` from `$app/paths` to ensure the toggle links to the correct URL
94
+ import { resolve } from '$app/paths';
95
+
96
+ // If using in the graphics kit, `embedded` prop will already be available in App.svelte.
97
+ // Additionally, pass `locale = 'en'` as a prop
98
+ let { embedded = false, locale = 'en' }: Props = $props();
99
+ </script>
100
+
101
+ <!-- Pass `buttonOptions` to customise the language and button label -->
102
+ <LanguageButton
103
+ {locale}
104
+ {embedded}
105
+ {resolve}
106
+ buttonOptions={{
107
+ locale: 'fr',
108
+ label: 'Lire en français',
109
+ }}
110
+ />
111
+ ```
112
+
113
+ ## Styling
114
+
115
+ Use global CSS to style the toggle button. The container div has the class `language-button` and the nested button has an id of `translate-button`.
116
+
117
+ ```scss
118
+ :global(div.language-button) {
119
+ /* Custom styles for the container div */
120
+
121
+ button#translate-button {
122
+ /* Custom styles for the toggle button */
123
+ }
124
+ }
125
+
126
+ <Canvas of={LanguageButtonStories.CustomStyle} />
127
+
128
+ ```
129
+
130
+ ## Customising URLs
131
+
132
+ By default, the `LanguageButton` component will switch from English to the translated version of the main article by appending `/{locale}/` to the base URL. For example, if the English version of the article is at `www.example.com/article/`, the translated version will be at `www.example.com/article/{locale}/`.
133
+
134
+ If `embedded` is passed, it will switch between English and translated versions of the embed page by appending `/embeds/{locale}/page/` to the base URL. For example, if the English version of the embed page is at `www.example.com/article/embeds/en/page/`, the translated version will be at `www.example.com/article/embeds/{locale}/page/`.
135
+
136
+ To customise this, pass a function to the `setUrl` prop that returns the URLs you want to link to.
137
+
138
+ ```svelte
139
+ <script>
140
+ import { LanguageButton } from '@reuters-graphics/graphics-components';
141
+
142
+ // If using in the graphics kit, use `resolve` from `$app/paths` to ensure the toggle links to the correct URL
143
+ import { resolve } from '$app/paths';
144
+
145
+ // If using in the graphics kit, `embedded` prop will already be available in App.svelte.
146
+ // Additionally, pass `locale = 'en'` as a prop
147
+ let { embedded = false, locale = 'en' }: Props = $props();
148
+
149
+ // Custom function to return the URLs for the toggle button
150
+ const setUrl = () => {
151
+ if (embedded) {
152
+ if (locale === 'es') {
153
+ // If we're in the non-English article, link to the English article
154
+ return resolve('/embeds/en/custom-embed-url/');
155
+ } else {
156
+ return resolve('/embeds/es/custom-embed-url/');
157
+ }
158
+ } else {
159
+ if (locale === 'es') {
160
+ // If we're in the non-English article, link to the English article
161
+ return resolve('/');
162
+ } else {
163
+ return resolve('/es/');
164
+ }
165
+ }
166
+ };
167
+ </script>
168
+
169
+ <LanguageButton {locale} {embedded} {setUrl} />
170
+ ```
@@ -0,0 +1,251 @@
1
+ # Legend
2
+
3
+ Quantitative and categorical legend for maps and data displays.
4
+
5
+ Renders one of five legend types:
6
+ - threshold: discrete bins with color swatches
7
+ - continuous: a continuous gradient with ticks
8
+ - diverging: threshold bins with a highlighted midpoint
9
+ - categorical: square swatches with labels in a horizontal row
10
+ - proportional-symbols: nested circles with leader lines and labels
11
+
12
+ The component is presentational and can be placed anywhere in page layout. The
13
+ optional noData prop renders a separate fallback swatch for missing, unknown,
14
+ or unavailable values across all legend modes.
15
+
16
+ **Category:** Components/Graphics/Legend
17
+
18
+ **Import:** `import { Legend } from '@reuters-graphics/graphics-components'`
19
+
20
+ ## Props
21
+
22
+ | Prop | Type | Default | Required | Description |
23
+ |------|------|---------|:--------:|-------------|
24
+ | `title` | `string` | `''` | | Optional legend heading displayed above the scale. |
25
+ | `subtitle` | `string` | `''` | | Optional subtitle displayed beneath the title. |
26
+ | `mode` | `LegendMode` | `'threshold'` | | Legend rendering mode. Options: `threshold`, `continuous`, `diverging`, `categorical`, `proportional-symbols` |
27
+ | `items` | `LegendItem[] \| LegendSymbolItem[]` | `[]` | | Legend entries. Threshold/diverging modes use numeric bounds and colors; categorical mode uses label and color pairs; proportional-symbols mode uses numeric values and optional labels. |
28
+ | `stops` | `LegendStop[]` | `[]` | | Ordered continuous color stops with numeric values. |
29
+ | `ticks` | `LegendTick[]` | `[]` | | Optional tick values and labels for continuous mode. |
30
+ | `midpoint` | `LegendMidpoint \| null` | `null` | | Diverging midpoint with a numeric value and optional label. |
31
+ | `formatter` | `LegendFormatter \| null` | `null` | | Optional formatter applied to numeric values. |
32
+ | `noData` | `LegendNoData \| null` | `null` | | Optional fallback swatch for missing values. |
33
+ | `width` | `ContainerWidth` | `'normal'` | | Width of the legend within the text well. Options: `narrower`, `narrow`, `normal`, `wide`, `wider`, `widest`, `fluid` |
34
+
35
+ ## Types
36
+
37
+ ```typescript
38
+ export type LegendMode =
39
+ | 'threshold'
40
+ | 'continuous'
41
+ | 'diverging'
42
+ | 'categorical'
43
+ | 'proportional-symbols';
44
+
45
+ export type LegendFormatter = (value: number) => string;
46
+
47
+ export interface LegendItem {
48
+ /** CSS color for the bin or category swatch. */
49
+ color: string;
50
+ /** Lower bound of the bin (inclusive). Omit for an open-ended first bin. */
51
+ from?: number | null;
52
+ /** Upper bound of the bin (exclusive). Omit for an open-ended last bin. */
53
+ to?: number | null;
54
+ /** Optional explicit label. Generated from the bounds when omitted. */
55
+ label?: string;
56
+ }
57
+
58
+ export interface LegendStop {
59
+ /** Numeric position of the stop along the domain. */
60
+ value: number;
61
+ /** CSS color at this stop. */
62
+ color: string;
63
+ /** Optional explicit label. */
64
+ label?: string;
65
+ }
66
+
67
+ export interface LegendTick {
68
+ /** Numeric position of the tick along the domain. */
69
+ value: number;
70
+ /** Optional explicit label. Formatted from `value` when omitted. */
71
+ label?: string;
72
+ }
73
+
74
+ export interface LegendMidpoint {
75
+ /** Numeric value of the midpoint within the legend domain. */
76
+ value: number;
77
+ /** Optional explicit label. Formatted from `value` when omitted. */
78
+ label?: string;
79
+ }
80
+
81
+ export interface LegendSymbolItem {
82
+ /** Non-negative numeric value mapped to circle area. */
83
+ value: number;
84
+ /** Optional explicit label. Formatted from `value` when omitted. */
85
+ label?: string;
86
+ }
87
+
88
+ export interface LegendNoData {
89
+ /** Label shown next to the fallback swatch. */
90
+ label: string;
91
+ /** Optional CSS color for the fallback swatch. */
92
+ color?: string;
93
+ }
94
+ ```
95
+
96
+ ## Examples
97
+
98
+ ### Threshold
99
+
100
+ ```svelte
101
+ <Legend
102
+ title="Annual average PM2.5"
103
+ subtitle="Micrograms per cubic meter"
104
+ mode="threshold"
105
+ items={[
106
+ { to: 12, color: 'var(--tr-light-orange)' },
107
+ { from: 12, to: 35, color: 'var(--tr-orange)' },
108
+ { from: 35, to: 55, color: 'var(--tr-dark-orange)' },
109
+ { from: 55, color: 'var(--tr-dark-red)' },
110
+ ]}
111
+ noData={{ label: 'Data not available' }}
112
+ />
113
+ ```
114
+
115
+ ### Continuous Gradient
116
+
117
+ ```svelte
118
+ <Legend
119
+ title="Graduation rate"
120
+ mode="continuous"
121
+ stops={[
122
+ { value: 0, color: 'var(--tr-superlight-blue)' },
123
+ { value: 50, color: 'var(--tr-light-blue)' },
124
+ { value: 100, color: 'var(--tr-dark-blue)' },
125
+ ]}
126
+ ticks={[
127
+ { value: 0, label: '0%' },
128
+ { value: 25, label: '25%' },
129
+ { value: 50, label: '50%' },
130
+ { value: 75, label: '75%' },
131
+ { value: 100, label: '100%' },
132
+ ]}
133
+ />
134
+ ```
135
+
136
+ ### Diverging Midpoint
137
+
138
+ ```svelte
139
+ <Legend
140
+ title="Today's difference from the normal high of 1961-1990"
141
+ mode="diverging"
142
+ items={/* array — see Props/Types for full type */}
143
+ midpoint={{ value: 0, label: '±0°' }}
144
+ formatter={(value: number) => {
145
+ if (value === 0) {
146
+ return '0°';
147
+ }
148
+
149
+ return `${value > 0 ? '+' : '−'}${Math.abs(value)}°`;
150
+ }}
151
+ />
152
+ ```
153
+
154
+ ### Categorical
155
+
156
+ ```svelte
157
+ <Legend
158
+ title="Hurricanes since 1980"
159
+ subtitle="By Saffir-Simpson category"
160
+ mode="categorical"
161
+ items={/* array — see Props/Types for full type */}
162
+ />
163
+ ```
164
+
165
+ ### Proportional Symbols
166
+
167
+ ```svelte
168
+ <Legend
169
+ title="Population"
170
+ subtitle="in millions"
171
+ mode="proportional-symbols"
172
+ items={[
173
+ { value: 1400, label: '1,400' },
174
+ { value: 600, label: '600' },
175
+ { value: 150, label: '150' },
176
+ { value: 0, label: '0' },
177
+ ]}
178
+ />
179
+ ```
180
+
181
+ ### Map Layout
182
+
183
+ ```svelte
184
+ <TileMap
185
+ id="legend-demo-map"
186
+ center={[0, 20]}
187
+ zoom={0}
188
+ height="460px"
189
+ onMapReady={addCycloneLayer}
190
+ >
191
+ {#snippet legend()}
192
+ <Legend
193
+ title="Hurricanes since 1980"
194
+ subtitle="By Saffir-Simpson category"
195
+ mode="categorical"
196
+ items={cycloneCategories}
197
+ />
198
+ {/snippet}
199
+ </TileMap>
200
+ ```
201
+
202
+ ## Documentation
203
+
204
+ # Legend
205
+
206
+ A legend or key for maps and data displays. Renders one of five
207
+ modes.
208
+
209
+ They are:
210
+
211
+ - **`threshold`** — discrete bins with color swatches and break ticks
212
+ - **`continuous`** — a continuous gradient with axis ticks
213
+ - **`diverging`** — threshold bins with a highlighted midpoint
214
+ - **`categorical`** — square swatches with labels in a horizontal row
215
+ - **`proportional-symbols`** — nested circles with leader lines and labels
216
+
217
+ The optional `noData` prop renders a separate fallback swatch for missing,
218
+ unknown, or unavailable values across every mode.
219
+
220
+ The legend sizes itself to the text well with the `width` prop, matching the
221
+ other graphics components.
222
+
223
+ ## Threshold
224
+
225
+ Discrete bins, each with its own color. Labels are generated from the numeric
226
+ bounds unless you pass an explicit `label`.
227
+
228
+ ## Continuous gradient
229
+
230
+ A smooth gradient built from ordered `stops`. Pass `ticks` to control the axis
231
+ labels.
232
+
233
+ ## Diverging midpoint
234
+
235
+ Threshold bins centered on a highlighted `midpoint`. Use `formatter` to control
236
+ how numeric boundaries are displayed.
237
+
238
+ ## Categorical
239
+
240
+ Square swatches with labels laid out in a wrapping row.
241
+
242
+ ## Proportional symbols
243
+
244
+ Nested circles sized by area, with leader lines and labels.
245
+
246
+ ## With a map
247
+
248
+ `Legend` is standalone and can be placed anywhere in the layout, including above
249
+ or below a `TileMap`.
250
+
251
+ ## Props