|
| 1 | +# Svelte Starter |
| 2 | + |
| 3 | +This [starter template](https://github.com/the-pudding/svelte-starter) aims to quickly scaffold a [SvelteKit](https://kit.svelte.dev/) project, designed around data-driven, visual stories at [The Pudding](https://pudding.cool). |
| 4 | + |
| 5 | +### Notes |
| 6 | +* _Do not use or reproduce The Pudding logos or fonts without written permission._ |
| 7 | +* _Prettier Formatting: Disable any text editor Prettier extensions to take advantage of the built-in rules._ |
| 8 | + |
| 9 | +### Features |
| 10 | + |
| 11 | +- [Lucide Icons](https://lucide.dev/) for simple/easy svg icons |
| 12 | +- [ArchieML](http://archieml.org/) for micro-CMS powered by Google Docs and Sheets |
| 13 | +- [Style Dictionary](https://amzn.github.io/style-dictionary/) for CSS/JS style parity |
| 14 | +- CSV, JSON, and SVG imports |
| 15 | +- SSR static-hosted builds by default |
| 16 | + |
| 17 | +## Quickstart |
| 18 | +#### From Scratch |
| 19 | +* Click the green `Use this template` button above. |
| 20 | +* Alternatively: `npx degit the-pudding/svelte-starter my-project` |
| 21 | + |
| 22 | +#### Pre-existing Project |
| 23 | +* clone the repo |
| 24 | + |
| 25 | +#### Installation |
| 26 | +* In your local repo run `pnpm install` or `npm install` |
| 27 | + |
| 28 | +## Development |
| 29 | + |
| 30 | +```bash |
| 31 | +npm run dev |
| 32 | +``` |
| 33 | + |
| 34 | +Change the script in `package.json` to `"dev": "svelte-kit dev --host"` to test on your local network on a different device. |
| 35 | + |
| 36 | +## Deploy |
| 37 | +```bash |
| 38 | +npm run build |
| 39 | +``` |
| 40 | + |
| 41 | +This generates a directory called `build` with the statically rendered app. |
| 42 | + |
| 43 | +A shortcut for github pages: |
| 44 | +```bash |
| 45 | +make github |
| 46 | +``` |
| 47 | + |
| 48 | +Deploying to Pudding AWS: |
| 49 | +```bash |
| 50 | +make pudding |
| 51 | +``` |
| 52 | + |
| 53 | +### Subdirectories |
| 54 | +If you are hosting the project on a subdirectory, set it in `package.json`. |
| 55 | + |
| 56 | +For example, if you are deploying to `https://domain.com/2021/01/test`: |
| 57 | + |
| 58 | +```json |
| 59 | +"subdirectory": "/2021/01/test" |
| 60 | +``` |
| 61 | + |
| 62 | +## Style |
| 63 | + |
| 64 | +There are a few stylesheets included by default in `src/styles`. Refer to them in `app.css`, the place for applying global styles. |
| 65 | + |
| 66 | +For variable parity in both CSS and JS, modify files in the `properties` folder using the [Style Dictionary](https://amzn.github.io/style-dictionary/) API. |
| 67 | + |
| 68 | +Run `npm run style` to regenerate the style dictionary. |
| 69 | + |
| 70 | +#### Some css utility classes in reset.css |
| 71 | +* `.sr-only`: makes content invisible available for screen reader |
| 72 | +* `.text-outline`: adds a psuedo stroke to text element |
| 73 | + |
| 74 | +### Custom Fonts |
| 75 | +For locally hosted fonts, simply add the font to the `static/assets` folder and include a reference in `src/styles/font.css`, making sure the url starts with `"assets/..."`. |
| 76 | + |
| 77 | +## Google Docs and Sheets |
| 78 | + |
| 79 | +* Create a Google Doc or Sheet |
| 80 | +* Click `Share` -> `Advanced` -> `Change...` -> `Anyone with this link` |
| 81 | +* In the address bar, grab the ID - eg. "...com/document/d/**1IiA5a5iCjbjOYvZVgPcjGzMy5PyfCzpPF-LnQdCdFI0**/edit" |
| 82 | +* paste in the ID above into `google.config.js`, and set the filepath to where you want the file saved |
| 83 | +* If you want to do a Google Sheet, be sure to include the `gid` value in the url as well |
| 84 | + |
| 85 | +Running `npm run gdoc` at any point (even in new tab while server is running) will fetch the latest from all Docs and Sheets. |
| 86 | + |
| 87 | +## Structural Overview |
| 88 | + |
| 89 | +### Pages |
| 90 | +The `src/routes` directory contains pages for your app. For a single-page app (most cases) you don't have to modify anything in here. `+page.svelte` represents the root page, think of it as the `index.html` file. It is prepopulated with a few things like metadata and font preloading. It also includes a reference to a blank slate component `src/components/Index.svelte`. This is the file you want to really start in for your app. |
| 91 | + |
| 92 | +### Embedding Data |
| 93 | +For smaller datasets, it is often great to embed the data into the HTML file. If you want to use data as-is, you can use normal import syntax (e.g., `import data from "$data/file.csv"`). If you are working with data but you want to preserve the original or clean/parse just what you need to use in the browser to optimize the front-end payload, you can load it via `+page.server.js`, do some work on it, and return just what you need. This is passed automatically to `+page.svelte` and accessible in any component with `getContext("data")`. |
| 94 | + |
| 95 | + |
| 96 | +## Pre-loaded helpers |
| 97 | + |
| 98 | +### Components |
| 99 | + |
| 100 | +Located in `src/components`. |
| 101 | + |
| 102 | +```js |
| 103 | +// Usage |
| 104 | +import Example from "$components/Example.svelte"; |
| 105 | +``` |
| 106 | + |
| 107 | +* `Footer.svelte`: Pudding recirculation and social links. |
| 108 | +* `Header.svelte`: Pudding masthead. |
| 109 | + |
| 110 | +### Helper Components |
| 111 | + |
| 112 | +Located in `src/components/helpers`. |
| 113 | + |
| 114 | +```js |
| 115 | +// Usage |
| 116 | +import Example from "$components/helpers/Example.svelte"; |
| 117 | +``` |
| 118 | + |
| 119 | +* `ButtonSet.svelte`: Accessible button group inputs. |
| 120 | +* `Chunk.svelte`: Split text into smaller dom element chunks. |
| 121 | +* `Countdown.svelte`: Countdown timer text. |
| 122 | +* `Figure.svelte`: A barebones chart figure component to handle slots. |
| 123 | +* `MotionToggle.svelte`: A toggle button to enable/disable front-end user motion preference. |
| 124 | +* `Range.svelte`: Customizable range slider. |
| 125 | +* `Scrolly.svelte`: Scrollytelling. |
| 126 | +* `SortTable.svelte`: Sortable semantic table with customizable props. |
| 127 | +* `Slider.svelte (and Slider.Slide.svelte)`: A slider widget, especially useful for swipe/slide stories. |
| 128 | +* `Tap.svelte`: Edge-of-screen tapping library, designed to integrate with slider. |
| 129 | +* `Tip.svelte`: Button that links to Strip payment link. |
| 130 | +* `Toggle.svelte`: Accessible toggle inputs. |
| 131 | +* `WIP.svelte`: A sticky banner saying this project is a WIP. |
| 132 | + |
| 133 | +### Layercake Chart Components |
| 134 | + |
| 135 | +Starter templates for various chart types to be used with [LayerCake](https://layercake.graphics/). Located in `src/components/layercake`. |
| 136 | + |
| 137 | +```js |
| 138 | +// Usage |
| 139 | +import Example from "$components/layercake/Example.svelte"; |
| 140 | +``` |
| 141 | + |
| 142 | +### Actions |
| 143 | + |
| 144 | +Located in `src/actions`. |
| 145 | + |
| 146 | +```js |
| 147 | +// Usage |
| 148 | +import example from "$actions/action.js"; |
| 149 | +``` |
| 150 | + |
| 151 | +* `canTab.js`: enable/disable tabbing on child elements. |
| 152 | +* `checkOverlap.js`: Label overlapping detection. Loops through selection of nodes and adds a class to the ones that are overlapping. Once one is hidden it ignores it. |
| 153 | +* `focusTrap.js`: Enable a keyboard focus trap for modals and menus. |
| 154 | +* `keepWithinBox.js`: Offsets and element left/right to stay within parent. |
| 155 | +* `inView.js`: detect when an element enters or exits the viewport. |
| 156 | +* `resize.js`: detect when an element is resized. |
| 157 | + |
| 158 | +### Stores |
| 159 | + |
| 160 | +These are located in `src/stores`. You can put custom ones in `src/stores/misc.js` or create unique files for more complex ones. |
| 161 | + |
| 162 | +```js |
| 163 | +// Usage |
| 164 | +import example from "$stores/example.js"; |
| 165 | +import { example } from "$stores/misc.js"; |
| 166 | +``` |
| 167 | + |
| 168 | +* `mq`: returns an object of media queries booleans if they are enabled or not. You can modify them in the js file. |
| 169 | +* `previous`: returns the previous value of another store. |
| 170 | +* `reducedMotion`: returns a boolean of front-end user event to enable/disable motion preference. |
| 171 | +* `scrollY`: returns a number of window vertical scroll position. It is throttled using rAF for performance. |
| 172 | +* `timer`: returns an object `{ timer, elapsed }`. `timer` has 5 methods (start, stop, toggle, set, reset) and `elapsed` is a store that is the number of ms. |
| 173 | +* `viewport`: returns an object `{ width, height }` of the viewport dimensions. It is debounced for performance. |
| 174 | + |
| 175 | +### Utils |
| 176 | + |
| 177 | +Located in `src/utils/`. |
| 178 | + |
| 179 | +```js |
| 180 | +// Usage |
| 181 | +import example from "$utils/example.js"; |
| 182 | +``` |
| 183 | +* `csvDownload.js`: Converts a flat array of data to CSV content ready to be used as an `href` value for download. |
| 184 | +* `generateId.js`: Generate an alphanumeric id. |
| 185 | +* `loadCsv.js`: Loads and parses a CSV file. |
| 186 | +* `loadImage.js`: Loads an image. |
| 187 | +* `loadJson.js`: Loads and parses a JSON file. |
| 188 | +* `loadPixels.js`: Loads the pixel data of an image via an offscreen canvas. |
| 189 | +* `localStorage.js`: Read and write to local storage. |
| 190 | +* `mapToArray.js`: Convenience function to convert a map to an array. |
| 191 | +* `move.js`: transform translate function shorthand. |
| 192 | +* `previous.js`: keep track of the previous value of a store. |
| 193 | +* `transformSvg.js`: Custom transition lets you apply an svg transform property with the in/out svelte transition. Parameters (with defaults): |
| 194 | +* `translate.js`: Convenience function for transform translate css. |
| 195 | +* `urlParams.js`: Get and set url parameters. |
| 196 | + |
| 197 | +## Gotchas |
| 198 | + |
| 199 | +* Any @html tags, e.g., `{@html user}` must be the child of a dom element so they can be properly hydrated. |
| 200 | +* Putting asset paths in CSS doesn't work without some hacks for subdirectory hosted projects |
0 commit comments