├── docs
├── .nojekyll
├── favicon.ico
├── _app
│ ├── env.js
│ ├── version.json
│ └── immutable
│ │ ├── nodes
│ │ ├── 6.DUcV82Gi.js
│ │ ├── 1.Qh7DPxM0.js
│ │ ├── 2.lXA7VpVS.js
│ │ └── 5.Bozl_rDw.js
│ │ ├── entry
│ │ └── start.3zWGZb7n.js
│ │ ├── chunks
│ │ ├── CWj6FrbW.js
│ │ ├── Cdd2vc2j.js
│ │ ├── DpoC0QzE.js
│ │ ├── D6iY2F4E.js
│ │ ├── CZjA61F2.js
│ │ ├── B7mm1rr4.js
│ │ ├── CY5piJI4.js
│ │ ├── CWT9bnGQ.js
│ │ ├── DnXbvXxH.js
│ │ ├── CkxHW-tX.js
│ │ └── DfLy1BuI.js
│ │ └── assets
│ │ ├── 4.BosP74pi.css
│ │ ├── _page.BosP74pi.css
│ │ ├── _page.BbtFu9-w.css
│ │ ├── 3.CO4jlTh2.css
│ │ ├── 5.B-mGqUsL.css
│ │ └── _page.B-mGqUsL.css
├── assets
│ ├── demo
│ │ ├── test.csv
│ │ ├── test.jpg
│ │ └── fonts
│ │ │ ├── cozette.css
│ │ │ ├── jamboree.css
│ │ │ ├── jersey.css
│ │ │ ├── recoleta.css
│ │ │ ├── lyon.css
│ │ │ ├── atlas-typewriter.css
│ │ │ ├── canela.css
│ │ │ ├── spacemono.css
│ │ │ ├── publico.css
│ │ │ ├── baloo-bhai.css
│ │ │ ├── atkinson.css
│ │ │ ├── computer-modern.css
│ │ │ ├── tiempos.css
│ │ │ ├── inter.css
│ │ │ ├── rubik.css
│ │ │ ├── metropolis.css
│ │ │ ├── atlas.css
│ │ │ ├── inconsolata.css
│ │ │ └── national.css
│ └── branding
│ │ ├── cloud.jpg
│ │ ├── donate.jpg
│ │ └── subscribe.png
└── __data.json
├── static
├── favicon.ico
└── assets
│ ├── demo
│ ├── test.csv
│ ├── test.jpg
│ └── fonts
│ │ ├── jamboree.css
│ │ ├── jersey.css
│ │ ├── recoleta.css
│ │ ├── cozette.css
│ │ ├── lyon.css
│ │ ├── atlas-typewriter.css
│ │ ├── canela.css
│ │ ├── spacemono.css
│ │ ├── publico.css
│ │ ├── atkinson.css
│ │ ├── baloo-bhai.css
│ │ ├── computer-modern.css
│ │ ├── tiempos.css
│ │ ├── inter.css
│ │ ├── rubik.css
│ │ ├── metropolis.css
│ │ ├── atlas.css
│ │ ├── inconsolata.css
│ │ └── national.css
│ └── branding
│ ├── cloud.jpg
│ ├── donate.jpg
│ └── subscribe.png
├── src
├── runes
│ ├── misc.svelte.js
│ ├── useWindowFocus.svelte.js
│ ├── useWindowDimensions.svelte.js
│ ├── useFetcher.svelte.js
│ └── useClipboard.svelte.js
├── data
│ ├── test.csv
│ ├── copy.json
│ └── variables.json
├── routes
│ ├── +page.server.js
│ ├── +layout.js
│ ├── demo
│ │ ├── +page.svelte
│ │ ├── fonts
│ │ │ └── +page.svelte
│ │ ├── elements
│ │ │ └── +page.svelte
│ │ └── ig-story
│ │ │ └── +page.svelte
│ ├── +error.svelte
│ ├── +layout.svelte
│ └── +page.svelte
├── utils
│ ├── translate.js
│ ├── mapToArray.js
│ ├── loadJson.js
│ ├── csvDownload.js
│ ├── loadCsv.js
│ ├── version.js
│ ├── loadImage.js
│ ├── generateId.js
│ ├── checkScrollDir.js
│ ├── transformSvg.js
│ ├── localStorage.js
│ ├── locate.js
│ ├── loadPixels.js
│ └── urlParams.js
├── components
│ ├── demo
│ │ ├── Demo.SvelteComponent.B.svelte
│ │ ├── Demo.SvelteComponent.A.svelte
│ │ ├── Demo.MicroCMSTest.svelte
│ │ ├── migrate
│ │ │ ├── Demo.Tip.svelte
│ │ │ ├── Demo.Range.svelte
│ │ │ ├── Demo.Figure.svelte
│ │ │ ├── Demo.Select.svelte
│ │ │ ├── Demo.ButtonSet.svelte
│ │ │ ├── Demo.Toggle.svelte
│ │ │ ├── Demo.SortTable.svelte
│ │ │ ├── Demo.Slider.svelte
│ │ │ ├── Demo.LayerCake.svelte
│ │ │ ├── Demo.IgStory.Figure.svelte
│ │ │ ├── Demo.IgStory.Chapters.svelte
│ │ │ └── Demo.IgStory.svelte
│ │ ├── Demo.Link.svelte
│ │ ├── Demo.SvelteElement.svelte
│ │ ├── Demo.Img.svelte
│ │ ├── Demo.MicroCMS.svelte
│ │ ├── Demo.SvelteComponent.svelte
│ │ ├── Demo.LoadData.svelte
│ │ ├── Demo.Scrolly.svelte
│ │ ├── Demo.svelte
│ │ ├── Demo.Fonts.svelte
│ │ ├── demo-fonts.json
│ │ ├── Demo.Fonts.Sample.svelte
│ │ └── Demo.Svelte5.svelte
│ ├── figure
│ │ └── migrate
│ │ │ ├── Figure.Template.svelte
│ │ │ ├── Figure.Tooltip.svelte
│ │ │ ├── Figure.MapPoints.svelte
│ │ │ ├── Figure.MapSvg.svelte
│ │ │ ├── Figure.MapPath.svelte
│ │ │ ├── Figure.MapCanvas.svelte
│ │ │ ├── Figure.MapLabels.svelte
│ │ │ └── Figure.svelte
│ ├── Index.svelte
│ ├── layercake
│ │ ├── migrate
│ │ │ ├── Area.svelte
│ │ │ ├── Bar.svelte
│ │ │ ├── Scatter.svg.svelte
│ │ │ ├── ColumnStacked.svelte
│ │ │ ├── Line.svelte
│ │ │ ├── Tooltip.html.svelte
│ │ │ ├── Scatter.canvas.svelte
│ │ │ ├── Scatter.html.svelte
│ │ │ ├── Column.svelte
│ │ │ ├── Voronoi.svelte
│ │ │ ├── AxisY.svg.svelte
│ │ │ ├── AxisY.html.svelte
│ │ │ ├── AxisX.html.svelte
│ │ │ └── AxisX.svg.svelte
│ │ └── future
│ │ │ ├── MultiLine.svelte
│ │ │ ├── ClevelandDotPlot.svelte
│ │ │ ├── MapPoints.svelte
│ │ │ ├── MapPoints.canvas.svelte
│ │ │ ├── MapPoints.html.svelte
│ │ │ ├── Map.canvas.svelte
│ │ │ ├── MapLabels.svg.svelte
│ │ │ ├── BeeswarmForce.svelte
│ │ │ ├── MapLabels.html.svelte
│ │ │ ├── Beeswarm.svg.svelte
│ │ │ ├── BeeswarmForce.html.svelte
│ │ │ ├── Map.svg.svelte
│ │ │ └── Beeswarm.html.svelte
│ ├── Header.svelte
│ ├── helpers
│ │ ├── migrate
│ │ │ ├── Slider.Slide.svelte
│ │ │ ├── ShareLink.svelte
│ │ │ ├── Tip.svelte
│ │ │ ├── Toggle.svelte
│ │ │ └── Slider.svelte
│ │ ├── CMS.svelte
│ │ └── Scrolly.svelte
│ ├── Meta.svelte
│ └── Footer.Story.svelte
├── svg
│ ├── arrow-footer.svg
│ ├── arrow-up-right.svg
│ ├── play.svg
│ ├── logo-white.svg
│ └── logo-black.svg
├── app.html
├── actions
│ ├── canTab.js
│ ├── keepWithinBox.js
│ ├── checkOverlap.js
│ ├── resize.js
│ ├── inView.js
│ └── focusTrap.js
└── styles
│ ├── font.css
│ ├── variables.css
│ └── app.css
├── .npmrc
├── .gitignore
├── tsconfig.json
├── .prettierignore
├── google.config.js
├── .prettierrc
├── properties
├── category.json
├── font-size.json
└── color.json
├── svelte.config.js
├── jsconfig.json
├── tasks
├── style-dictionary.js
└── fetch-google.js
├── Makefile
├── vite.config.js
├── LICENSE
└── package.json
/docs/.nojekyll:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/static/favicon.ico:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/runes/misc.svelte.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | engine-strict=true
2 |
--------------------------------------------------------------------------------
/docs/_app/env.js:
--------------------------------------------------------------------------------
1 | export const env={}
--------------------------------------------------------------------------------
/docs/_app/version.json:
--------------------------------------------------------------------------------
1 | {"version":"1751985803593"}
--------------------------------------------------------------------------------
/src/data/test.csv:
--------------------------------------------------------------------------------
1 | name,value
2 | test,2
3 | more,3
--------------------------------------------------------------------------------
/docs/assets/demo/test.csv:
--------------------------------------------------------------------------------
1 | name,value
2 | russell,2
3 | samora,3
--------------------------------------------------------------------------------
/static/assets/demo/test.csv:
--------------------------------------------------------------------------------
1 | name,value
2 | russell,2
3 | samora,3
--------------------------------------------------------------------------------
/src/routes/+page.server.js:
--------------------------------------------------------------------------------
1 | export async function load() {
2 | return {};
3 | }
4 |
--------------------------------------------------------------------------------
/docs/__data.json:
--------------------------------------------------------------------------------
1 | {"type":"data","nodes":[null,{"type":"data","data":[{}],"uses":{}}]}
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | .svelte
4 | .svelte-kit
5 | build
6 | functions
7 | .env
--------------------------------------------------------------------------------
/src/routes/+layout.js:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 | export const trailingSlash = "always";
--------------------------------------------------------------------------------
/docs/_app/immutable/nodes/6.DUcV82Gi.js:
--------------------------------------------------------------------------------
1 | import"../chunks/CWj6FrbW.js";function p(o){}export{p as component};
2 |
--------------------------------------------------------------------------------
/docs/assets/demo/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/svelte-starter/HEAD/docs/assets/demo/test.jpg
--------------------------------------------------------------------------------
/src/utils/translate.js:
--------------------------------------------------------------------------------
1 | export default function (x, y) {
2 | return `transform: translate(${x}px, ${y}px);`;
3 | }
4 |
--------------------------------------------------------------------------------
/static/assets/demo/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/svelte-starter/HEAD/static/assets/demo/test.jpg
--------------------------------------------------------------------------------
/docs/assets/branding/cloud.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/svelte-starter/HEAD/docs/assets/branding/cloud.jpg
--------------------------------------------------------------------------------
/docs/assets/branding/donate.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/svelte-starter/HEAD/docs/assets/branding/donate.jpg
--------------------------------------------------------------------------------
/static/assets/branding/cloud.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/svelte-starter/HEAD/static/assets/branding/cloud.jpg
--------------------------------------------------------------------------------
/static/assets/branding/donate.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/svelte-starter/HEAD/static/assets/branding/donate.jpg
--------------------------------------------------------------------------------
/docs/_app/immutable/entry/start.3zWGZb7n.js:
--------------------------------------------------------------------------------
1 | import{l as o,a as r}from"../chunks/BASgGI1b.js";export{o as load_css,r as start};
2 |
--------------------------------------------------------------------------------
/docs/assets/branding/subscribe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/svelte-starter/HEAD/docs/assets/branding/subscribe.png
--------------------------------------------------------------------------------
/src/routes/demo/+page.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
I am component B and my name is {name}.
6 | -------------------------------------------------------------------------------- /src/routes/demo/elements/+page.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |I am component A and my favorite number is {number}.
6 | -------------------------------------------------------------------------------- /src/utils/loadJson.js: -------------------------------------------------------------------------------- 1 | export default async function loadJson(url) { 2 | const response = await fetch(url); 3 | const data = await response.json(); 4 | return data; 5 | } 6 | -------------------------------------------------------------------------------- /src/components/demo/Demo.MicroCMSTest.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |{label}
6 | 7 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "verbatimModuleSyntax": true, 4 | "moduleResolution": "bundler", 5 | "module": "ESNext", 6 | "target": "ESNext" 7 | }, 8 | "include": ["src/**/*"] 9 | } -------------------------------------------------------------------------------- /src/components/demo/migrate/Demo.Tip.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |img tag
4 |
5 | background image
6 | 7 |
14 | {raw.replace(/\t/g, " ")}
15 |
16 | loading data...
20 | {:else if response.error} 21 |error: {response.error}
22 | {:else} 23 |data loaded
24 |{JSON.stringify(response.data, null, 2)}
25 | {/if}
26 | {text}
14 |{@html value}
22 | {:else if isString} 23 |15 | Do not use fonts hosted by The Pudding without written permission. 16 |
17 | 23 |console.log("enter")} 9 | * > 10 | * 11 | * optional params { debounce, exclude } 12 | * // debounce: ms to debounce resize event 13 | * // exclude: "width" or "height" to exclude from triggering resize event 14 | * use:resize={{ debounce: 250, exclude: "height" }} 15 | * 16 | */ 17 | 18 | export default function resize(node, params = {}) { 19 | let observer; 20 | let w; 21 | let h; 22 | 23 | const handleResize = (entries) => { 24 | const firstTime = w === undefined; 25 | 26 | for (const entry of entries) { 27 | const { width, height } = entry.contentRect; 28 | const widthTrigger = params.exclude !== "width" && width !== w; 29 | const heightTrigger = params.exclude !== "height" && height !== h; 30 | if (widthTrigger || heightTrigger) { 31 | w = width; 32 | h = height; 33 | if (!firstTime) node.dispatchEvent(new CustomEvent("resize")); 34 | } 35 | } 36 | }; 37 | 38 | const setObserver = () => { 39 | if (observer) observer.disconnect(); 40 | const cb = params.debounce 41 | ? debounce(handleResize, params.debounce) 42 | : handleResize; 43 | observer = new ResizeObserver(cb); 44 | observer.observe(node); 45 | }; 46 | 47 | setObserver(params); 48 | 49 | return { 50 | update(params) { 51 | setObserver(params); 52 | }, 53 | 54 | destroy() { 55 | if (observer) observer.disconnect(); 56 | } 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /src/utils/urlParams.js: -------------------------------------------------------------------------------- 1 | function get(key) { 2 | const name = key.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); 3 | const regex = new RegExp(`[\\?&]${name}=([^]*)`); 4 | const results = regex.exec(window.location.search); 5 | return results === null 6 | ? "" 7 | : decodeURIComponent(results[1].replace(/\+/g, " ")); 8 | } 9 | 10 | function set(key, value) { 11 | const baseUrl = [ 12 | window.location.protocol, 13 | "//", 14 | window.location.host, 15 | window.location.pathname 16 | ].join(""); 17 | const urlQueryString = document.location.search; 18 | const newParam = `${key}=${value}`; 19 | let params = `?${newParam}`; 20 | 21 | // If the "search" string exists, then build params from it 22 | if (urlQueryString) { 23 | const updateRegex = new RegExp(`([\?&])${key}[^&]*`); 24 | const removeRegex = new RegExp(`([\?&])${key}=[^&;]+[&;]?`); 25 | 26 | // Remove param if value is empty 27 | if (typeof value === "undefined" || value === null || value === "") { 28 | params = urlQueryString.replace(removeRegex, "$1"); 29 | params = params.replace(/[&;]$/, ""); 30 | } else if (urlQueryString.match(updateRegex) !== null) { 31 | // If param exists already, update it 32 | params = urlQueryString.replace(updateRegex, `$1${newParam}`); 33 | } else { 34 | // Otherwise, add it to end of query string 35 | params = `${urlQueryString}&${newParam}`; 36 | } 37 | } 38 | 39 | // no parameter was set so we don't need the question mark 40 | params = params === "?" ? "" : params; 41 | 42 | window.history.replaceState({}, "", `${baseUrl}${params}`); 43 | } 44 | 45 | export default { get, set }; 46 | -------------------------------------------------------------------------------- /src/actions/inView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This action triggers a custom event on node entering/exiting the viewport. 3 | * example: 4 | *
console.log("enter")}
7 | * on:exit={() => console.log("exit")}
8 | * >
9 | *
10 | * optional params { root, top, bottom, progress }
11 | * top and bottom are numbers
12 | * use:inView={{ bottom: 100 }} // 100 pixels from bottom of viewport
13 | *
14 | * progress is a boolean for incremental updates
15 | * use:inView={{ progres: true }}
16 | */
17 |
18 | export default function inView(node, params = {}) {
19 | let observer;
20 |
21 | const handleIntersect = (e) => {
22 | const intersecting = e[0].isIntersecting;
23 | const v = intersecting ? "enter" : "exit";
24 | node.dispatchEvent(new CustomEvent(v));
25 | if (params.progress && intersecting) {
26 | const ratio = e[0].intersectionRatio;
27 | const detail = { ratio };
28 | node.dispatchEvent(new CustomEvent("progress", { detail }));
29 | }
30 | };
31 |
32 | const setObserver = ({ root, top, bottom }) => {
33 | const marginTop = top ? top * -1 : 0;
34 | const marginBottom = bottom ? bottom * -1 : 0;
35 | const rootMargin = `${marginTop}px 0px ${marginBottom}px 0px`;
36 | const options = { root, rootMargin };
37 | if (observer) observer.disconnect();
38 | observer = new IntersectionObserver(handleIntersect, options);
39 | observer.observe(node);
40 | };
41 |
42 | setObserver(params);
43 |
44 | return {
45 | update(params) {
46 | setObserver(params);
47 | },
48 |
49 | destroy() {
50 | if (observer) observer.disconnect();
51 | }
52 | };
53 | }
54 |
--------------------------------------------------------------------------------
/src/components/Meta.svelte:
--------------------------------------------------------------------------------
1 |
10 |
11 |
{text}
35 |
38 | {source}
39 |
40 | {count} doubled is {result1} (derived)
45 |{count} doubled is {result2} (derived by)
46 |{count} doubled is {result3} ($effect)
47 | 48 | 49 |{p.name}
61 |{p.age}
62 |#{id}
19 |{month}
20 |
29 | {#if youtube}
30 | {@html playSvg}
31 | {/if}
32 | 38 | {@html tease} 39 |
40 |
Do not use fonts hosted by The Pudding without written permission.