React Slides
* Adds useState * State * useEffect * Side Effects
This commit is contained in:
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
15
.prettierrc
Normal file
15
.prettierrc
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"semi": false,
|
||||||
|
"useTabs": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"printWidth": 80,
|
||||||
|
"plugins": ["prettier-plugin-svelte"],
|
||||||
|
"pluginSearchDirs": ["."],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": "*.svelte",
|
||||||
|
"options": { "parser": "svelte" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["svelte.svelte-vscode"]
|
||||||
|
}
|
||||||
23
README.md
Normal file
23
README.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Animotion
|
||||||
|
|
||||||
|
This is an Animotion presentation.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
Install dependencies.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm i
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the development server at http://localhost:5173/.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Build and preview deploy.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm run build && pnpm run preview
|
||||||
|
```
|
||||||
13
index.html
Normal file
13
index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="icon" href="https://fav.farm/🪄" />
|
||||||
|
<title>Animotion</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
37
package.json
Normal file
37
package.json
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"name": "animotion",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"check": "svelte-check --tsconfig ./tsconfig.json"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@sveltejs/vite-plugin-svelte": "^2.5.2",
|
||||||
|
"@tsconfig/svelte": "^5.0.2",
|
||||||
|
"@types/d3-interpolate": "^3.0.4",
|
||||||
|
"@types/node": "^20.9.0",
|
||||||
|
"@types/reveal.js": "^4.4.6",
|
||||||
|
"autoprefixer": "^10.4.16",
|
||||||
|
"postcss": "^8.4.31",
|
||||||
|
"postcss-load-config": "^4.0.1",
|
||||||
|
"prettier": "^3.1.0",
|
||||||
|
"prettier-plugin-svelte": "^3.1.0",
|
||||||
|
"prettier-plugin-tailwindcss": "^0.5.7",
|
||||||
|
"svelte": "^4.2.3",
|
||||||
|
"svelte-check": "^3.6.0",
|
||||||
|
"tailwindcss": "^3.3.5",
|
||||||
|
"tslib": "^2.6.2",
|
||||||
|
"typescript": "^5.2.2",
|
||||||
|
"vite": "^4.5.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@fontsource-variable/jetbrains-mono": "^5.0.18",
|
||||||
|
"@fontsource-variable/manrope": "^5.0.17",
|
||||||
|
"d3-interpolate": "^3.0.1",
|
||||||
|
"reveal.js": "^5.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
1487
pnpm-lock.yaml
generated
Normal file
1487
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
postcss.config.js
Normal file
13
postcss.config.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import tailwindcss from 'tailwindcss'
|
||||||
|
import autoprefixer from 'autoprefixer'
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
plugins: [
|
||||||
|
//Some plugins, like tailwindcss/nesting, need to run before Tailwind,
|
||||||
|
tailwindcss(),
|
||||||
|
//But others, like autoprefixer, need to run after,
|
||||||
|
autoprefixer,
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config
|
||||||
11
src/<!DOCTYPE html>.html
Normal file
11
src/<!DOCTYPE html>.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Indrajith Makes Games</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h4>Site Under Maintenance</h4>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
52
src/config.ts
Normal file
52
src/config.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import Markdown from 'reveal.js/plugin/markdown/markdown'
|
||||||
|
import Highlight from 'reveal.js/plugin/highlight/highlight'
|
||||||
|
import Math from 'reveal.js/plugin/math/math'
|
||||||
|
import Notes from 'reveal.js/plugin/notes/notes'
|
||||||
|
|
||||||
|
import { registerLanguages } from '@languages'
|
||||||
|
|
||||||
|
const options: Reveal.Options = {
|
||||||
|
// presentation size respecting aspect ratio
|
||||||
|
width: 960,
|
||||||
|
height: 700,
|
||||||
|
// content padding
|
||||||
|
margin: 0.04,
|
||||||
|
// smallest and largest possible scale
|
||||||
|
minScale: 0.2,
|
||||||
|
maxScale: 2.0,
|
||||||
|
// plugins
|
||||||
|
plugins: [Markdown, Highlight, Math.KaTeX, Notes],
|
||||||
|
// syntax highlight options
|
||||||
|
highlight: {
|
||||||
|
// add new languages
|
||||||
|
beforeHighlight: registerLanguages,
|
||||||
|
// disable automatic syntax highlighting
|
||||||
|
highlightOnLoad: false,
|
||||||
|
},
|
||||||
|
// slide controls
|
||||||
|
controls: true,
|
||||||
|
// slide progress bar
|
||||||
|
progress: true,
|
||||||
|
// slide transition
|
||||||
|
transition: 'slide',
|
||||||
|
// bring your own layout
|
||||||
|
disableLayout: false,
|
||||||
|
// display mode used to show slides
|
||||||
|
display: 'block',
|
||||||
|
// center slides on the screen
|
||||||
|
center: true,
|
||||||
|
// auto-animate duration
|
||||||
|
autoAnimateDuration: 1,
|
||||||
|
// auto-animate easing
|
||||||
|
autoAnimateEasing: 'ease',
|
||||||
|
// animate unmatched elements
|
||||||
|
autoAnimateUnmatched: true,
|
||||||
|
// hide cursor
|
||||||
|
hideInactiveCursor: true,
|
||||||
|
// time before cursor is hidden (ms)
|
||||||
|
hideCursorTime: 5000,
|
||||||
|
// show current slide
|
||||||
|
hash: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default options
|
||||||
6
src/global.d.ts
vendored
Normal file
6
src/global.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
declare namespace svelteHTML {
|
||||||
|
interface HTMLAttributes<T> {
|
||||||
|
'on:in'?: (event: CustomEvent) => void
|
||||||
|
'on:out'?: (event: CustomEvent) => void
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/lib/components/code.svelte
Normal file
22
src/lib/components/code.svelte
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
type Lines = string | boolean | null
|
||||||
|
type Offset = string | null
|
||||||
|
type Language = string | null
|
||||||
|
|
||||||
|
export let id = 'code-animation'
|
||||||
|
export let lines: Lines = true
|
||||||
|
export let offset: Offset = null
|
||||||
|
export let lang: Language = null
|
||||||
|
|
||||||
|
delete $$restProps.class
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<pre data-id={id} class={$$props.class || ''} {...$$restProps}>
|
||||||
|
<code
|
||||||
|
data-trim
|
||||||
|
data-line-numbers={lines || null}
|
||||||
|
data-ln-start-from={offset}
|
||||||
|
class="language-{lang}">
|
||||||
|
<slot />
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
13
src/lib/components/fit.svelte
Normal file
13
src/lib/components/fit.svelte
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let type = 'h2'
|
||||||
|
|
||||||
|
delete $$restProps.class
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:element
|
||||||
|
this={type}
|
||||||
|
class="r-fit-text {$$props.class || ''}"
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</svelte:element>
|
||||||
25
src/lib/components/index.ts
Normal file
25
src/lib/components/index.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import Code from './code.svelte'
|
||||||
|
import FitText from './fit.svelte'
|
||||||
|
import Markdown from './markdown.svelte'
|
||||||
|
import Media from './media.svelte'
|
||||||
|
import Notes from './notes.svelte'
|
||||||
|
import Presentation from './presentation.svelte'
|
||||||
|
import Slide from './slide.svelte'
|
||||||
|
import Stack from './stack.svelte'
|
||||||
|
import Step from './step.svelte'
|
||||||
|
import Stretch from './stretch.svelte'
|
||||||
|
import Vertical from './vertical.svelte'
|
||||||
|
|
||||||
|
export {
|
||||||
|
Code,
|
||||||
|
FitText,
|
||||||
|
Markdown,
|
||||||
|
Media,
|
||||||
|
Notes,
|
||||||
|
Presentation,
|
||||||
|
Slide,
|
||||||
|
Stack,
|
||||||
|
Step,
|
||||||
|
Stretch,
|
||||||
|
Vertical,
|
||||||
|
}
|
||||||
13
src/lib/components/markdown.svelte
Normal file
13
src/lib/components/markdown.svelte
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let file: string | null = null
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if file}
|
||||||
|
<section data-markdown={file} />
|
||||||
|
{:else}
|
||||||
|
<section data-markdown>
|
||||||
|
<div data-template>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/if}
|
||||||
22
src/lib/components/media.svelte
Normal file
22
src/lib/components/media.svelte
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
type Bool = boolean | null
|
||||||
|
type Element = 'video' | 'img' | 'iframe'
|
||||||
|
|
||||||
|
export let type: Element
|
||||||
|
export let src: string
|
||||||
|
export let autoplay: Bool = null
|
||||||
|
export let preload: Bool = null
|
||||||
|
|
||||||
|
delete $$restProps.class
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:element
|
||||||
|
this={type}
|
||||||
|
data-src={src}
|
||||||
|
data-autoplay={autoplay}
|
||||||
|
data-prelod={preload}
|
||||||
|
class={$$props.class || ''}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</svelte:element>
|
||||||
3
src/lib/components/notes.svelte
Normal file
3
src/lib/components/notes.svelte
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<aside class="notes">
|
||||||
|
<slot />
|
||||||
|
</aside>
|
||||||
77
src/lib/components/presentation.svelte
Normal file
77
src/lib/components/presentation.svelte
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onMount } from 'svelte'
|
||||||
|
import Reveal from 'reveal.js'
|
||||||
|
import options from '@config'
|
||||||
|
|
||||||
|
import 'reveal.js/dist/reveal.css'
|
||||||
|
import '@styles/theme.css'
|
||||||
|
import '@styles/code.css'
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
// create deck instance
|
||||||
|
const deck = new Reveal(options)
|
||||||
|
|
||||||
|
// custom event listeners
|
||||||
|
const inEvent = new CustomEvent('in')
|
||||||
|
const outEvent = new CustomEvent('out')
|
||||||
|
|
||||||
|
// keep track of current slide
|
||||||
|
deck.on('slidechanged', (event) => {
|
||||||
|
if ('currentSlide' in event) {
|
||||||
|
const currentSlideEl = event.currentSlide as HTMLElement
|
||||||
|
currentSlideEl.dispatchEvent(inEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('previousSlide' in event) {
|
||||||
|
const currentPreviousEl = event.previousSlide as HTMLElement
|
||||||
|
currentPreviousEl.dispatchEvent(outEvent)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
deck.on('fragmentshown', (event) => {
|
||||||
|
if ('fragment' in event) {
|
||||||
|
const fragmentEl = event.fragment as HTMLElement
|
||||||
|
fragmentEl.dispatchEvent(inEvent)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
deck.on('fragmenthidden', (event) => {
|
||||||
|
if ('fragment' in event) {
|
||||||
|
const fragmentEl = event.fragment as HTMLElement
|
||||||
|
fragmentEl.dispatchEvent(outEvent)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
deck.initialize().then(() => {
|
||||||
|
// we pass the language to the `<Code>` block
|
||||||
|
// and higlight code blocks after initialization
|
||||||
|
highlightCodeBlocks(deck)
|
||||||
|
})
|
||||||
|
|
||||||
|
// reload page after update to avoid HMR issues
|
||||||
|
// reloadPageAfterUpdate()
|
||||||
|
})
|
||||||
|
|
||||||
|
function highlightCodeBlocks(deck: Reveal.Api) {
|
||||||
|
const highlight = deck.getPlugin('highlight')
|
||||||
|
const codeBlocks = [...document.querySelectorAll('code')]
|
||||||
|
codeBlocks.forEach((block) => {
|
||||||
|
// @ts-ignore
|
||||||
|
highlight.highlightBlock(block)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function reloadPageAfterUpdate() {
|
||||||
|
if (import.meta.hot) {
|
||||||
|
import.meta.hot.on('vite:afterUpdate', () => {
|
||||||
|
location.reload()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="reveal">
|
||||||
|
<div class="slides">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
48
src/lib/components/slide.svelte
Normal file
48
src/lib/components/slide.svelte
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
type Bool = boolean | null
|
||||||
|
type String = string | null
|
||||||
|
type Transition =
|
||||||
|
| 'none'
|
||||||
|
| 'fade'
|
||||||
|
| 'slide'
|
||||||
|
| 'convex'
|
||||||
|
| 'concave'
|
||||||
|
| 'zoom'
|
||||||
|
| null
|
||||||
|
|
||||||
|
export let animate: Bool = null
|
||||||
|
export let animateEasing: String = null
|
||||||
|
export let animateUnmatched: Bool = null
|
||||||
|
export let animateId: String = null
|
||||||
|
export let animateRestart: Bool = null
|
||||||
|
export let background: String = null
|
||||||
|
export let gradient: String = null
|
||||||
|
export let image: String = null
|
||||||
|
export let video: String = null
|
||||||
|
export let iframe: String = null
|
||||||
|
export let interactive: Bool = null
|
||||||
|
export let transition: Transition = null
|
||||||
|
|
||||||
|
delete $$restProps.class
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section
|
||||||
|
on:in
|
||||||
|
on:out
|
||||||
|
data-auto-animate={animate}
|
||||||
|
data-auto-animate-easing={animateEasing}
|
||||||
|
data-auto-animate-unmatched={animateUnmatched}
|
||||||
|
data-auto-animate-id={animateId}
|
||||||
|
data-auto-animate-restart={animateRestart}
|
||||||
|
data-background-color={background}
|
||||||
|
data-background-gradient={gradient}
|
||||||
|
data-background-image={image}
|
||||||
|
data-background-video={video}
|
||||||
|
data-background-iframe={iframe}
|
||||||
|
data-background-interactive={interactive}
|
||||||
|
data-transition={transition}
|
||||||
|
class={$$props.class || ''}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</section>
|
||||||
3
src/lib/components/stack.svelte
Normal file
3
src/lib/components/stack.svelte
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<div class="r-stack">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
53
src/lib/components/step.svelte
Normal file
53
src/lib/components/step.svelte
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let order: string | null = null
|
||||||
|
export let fadeIn = false
|
||||||
|
export let fadeOut = false
|
||||||
|
export let fadeUp = false
|
||||||
|
export let fadeDown = false
|
||||||
|
export let fadeLeft = false
|
||||||
|
export let fadeRight = false
|
||||||
|
export let fadeInThenOut = false
|
||||||
|
export let currentVisible = false
|
||||||
|
export let fadeInThenSemiOut = false
|
||||||
|
export let semiFadeOut = false
|
||||||
|
export let highlightRed = false
|
||||||
|
export let highlightGreen = false
|
||||||
|
export let highlightBlue = false
|
||||||
|
export let highlightCurrentRed = false
|
||||||
|
export let highlightCurrentGreen = false
|
||||||
|
export let highlightCurrentBlue = false
|
||||||
|
export let grow = false
|
||||||
|
export let shrink = false
|
||||||
|
export let strike = false
|
||||||
|
|
||||||
|
delete $$restProps.class
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p
|
||||||
|
on:in
|
||||||
|
on:out
|
||||||
|
class:fade-in={fadeIn}
|
||||||
|
class:fade-out={fadeOut}
|
||||||
|
class:fade-up={fadeUp}
|
||||||
|
class:fade-down={fadeDown}
|
||||||
|
class:fade-left={fadeLeft}
|
||||||
|
class:fade-right={fadeRight}
|
||||||
|
class:fade-in-then-out={fadeInThenOut}
|
||||||
|
class:current-visible={currentVisible}
|
||||||
|
class:fade-in-then-semi-out={fadeInThenSemiOut}
|
||||||
|
class:semi-fade-out={semiFadeOut}
|
||||||
|
class:highlight-red={highlightRed}
|
||||||
|
class:highlight-green={highlightGreen}
|
||||||
|
class:highlight-blue={highlightBlue}
|
||||||
|
class:highlight-current-red={highlightCurrentRed}
|
||||||
|
class:highlight-current-green={highlightCurrentGreen}
|
||||||
|
class:highlight-current-blue={highlightCurrentBlue}
|
||||||
|
class:grow
|
||||||
|
class:shrink
|
||||||
|
class:strike
|
||||||
|
class="fragment {$$props.class || ''}"
|
||||||
|
data-fragment-index={order}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</p>
|
||||||
13
src/lib/components/stretch.svelte
Normal file
13
src/lib/components/stretch.svelte
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let type = 'p'
|
||||||
|
|
||||||
|
delete $$restProps.class
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:element
|
||||||
|
this={type}
|
||||||
|
class="r-stretch {$$props.class || ''}"
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</svelte:element>
|
||||||
3
src/lib/components/vertical.svelte
Normal file
3
src/lib/components/vertical.svelte
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<section>
|
||||||
|
<slot />
|
||||||
|
</section>
|
||||||
6
src/lib/languages/index.ts
Normal file
6
src/lib/languages/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { svelte } from './svelte'
|
||||||
|
import type { Hljs } from './types'
|
||||||
|
|
||||||
|
export function registerLanguages(hljs: Hljs) {
|
||||||
|
hljs.registerLanguage('svelte', svelte)
|
||||||
|
}
|
||||||
50
src/lib/languages/svelte.ts
Normal file
50
src/lib/languages/svelte.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import type { Hljs } from './types'
|
||||||
|
|
||||||
|
export function svelte(hljs: Hljs) {
|
||||||
|
return {
|
||||||
|
subLanguage: 'xml',
|
||||||
|
contains: [
|
||||||
|
hljs.COMMENT('<!--', '-->', {
|
||||||
|
relevance: 10,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
begin: /^(\s*)(<script(\s*context="module")?>)/gm,
|
||||||
|
end: /^(\s*)(<\/script>)/gm,
|
||||||
|
subLanguage: 'javascript',
|
||||||
|
excludeBegin: true,
|
||||||
|
excludeEnd: true,
|
||||||
|
contains: [
|
||||||
|
{
|
||||||
|
begin: /^(\s*)(\$:)/gm,
|
||||||
|
end: /(\s*)/gm,
|
||||||
|
className: 'keyword',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
begin: /^(\s*)(<style.*>)/gm,
|
||||||
|
end: /^(\s*)(<\/style>)/gm,
|
||||||
|
subLanguage: 'css',
|
||||||
|
excludeBegin: true,
|
||||||
|
excludeEnd: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
begin: /\{/gm,
|
||||||
|
end: /\}/gm,
|
||||||
|
subLanguage: 'javascript',
|
||||||
|
contains: [
|
||||||
|
{
|
||||||
|
begin: /[\{]/,
|
||||||
|
end: /[\}]/,
|
||||||
|
skip: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
begin: /([#:\/@])(if|else|each|await|then|catch|debug|html)/gm,
|
||||||
|
className: 'keyword',
|
||||||
|
relevance: 10,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/lib/languages/types.ts
Normal file
3
src/lib/languages/types.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import hljs from 'highlight.js'
|
||||||
|
|
||||||
|
export type Hljs = typeof hljs
|
||||||
4
src/lib/motion/index.ts
Normal file
4
src/lib/motion/index.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { signal } from './signal'
|
||||||
|
import { animate, all } from './utils'
|
||||||
|
|
||||||
|
export { signal, animate, all }
|
||||||
61
src/lib/motion/signal.ts
Normal file
61
src/lib/motion/signal.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { tweened, type TweenedOptions } from 'svelte/motion'
|
||||||
|
import { cubicInOut } from 'svelte/easing'
|
||||||
|
import { interpolate } from 'd3-interpolate'
|
||||||
|
import type { AnimationFn, Resolve } from './types'
|
||||||
|
|
||||||
|
export function signal<TweenValues>(
|
||||||
|
values: TweenValues,
|
||||||
|
options: TweenedOptions<TweenValues> = {}
|
||||||
|
) {
|
||||||
|
const { subscribe, update, set } = tweened<TweenValues>(values, {
|
||||||
|
duration: 1000,
|
||||||
|
easing: cubicInOut,
|
||||||
|
interpolate,
|
||||||
|
...options,
|
||||||
|
})
|
||||||
|
|
||||||
|
let tasks: AnimationFn[] = []
|
||||||
|
|
||||||
|
function to(
|
||||||
|
this: any,
|
||||||
|
values: Partial<TweenValues>,
|
||||||
|
toOptions: TweenedOptions<TweenValues> = {}
|
||||||
|
) {
|
||||||
|
if (typeof values === 'object') {
|
||||||
|
tasks.push(() => update((prev) => ({ ...prev, ...values }), toOptions))
|
||||||
|
} else {
|
||||||
|
tasks.push(() => set(values, toOptions))
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
set(values, { duration: 0 })
|
||||||
|
tasks = []
|
||||||
|
}
|
||||||
|
|
||||||
|
function sfx(this: any, sound: string, { volume = 0.5 } = {}) {
|
||||||
|
const audio = new Audio(sound)
|
||||||
|
audio.volume = volume
|
||||||
|
|
||||||
|
tasks.push(async () => {
|
||||||
|
audio
|
||||||
|
.play()
|
||||||
|
.catch(() =>
|
||||||
|
console.error('To play sounds interact with the page first.')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
async function then(resolve: Resolve) {
|
||||||
|
for (const task of tasks) {
|
||||||
|
await task()
|
||||||
|
}
|
||||||
|
resolve()
|
||||||
|
tasks = []
|
||||||
|
}
|
||||||
|
|
||||||
|
return { subscribe, to, reset, sfx, then }
|
||||||
|
}
|
||||||
2
src/lib/motion/types.ts
Normal file
2
src/lib/motion/types.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export type AnimationFn = () => Promise<void>
|
||||||
|
export type Resolve = (value?: any) => Promise<void>
|
||||||
10
src/lib/motion/utils.ts
Normal file
10
src/lib/motion/utils.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { onMount } from 'svelte'
|
||||||
|
import type { AnimationFn } from './types'
|
||||||
|
|
||||||
|
export function animate(fn: AnimationFn) {
|
||||||
|
onMount(fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function all(...animations: AnimationFn[]) {
|
||||||
|
return Promise.all(animations)
|
||||||
|
}
|
||||||
56
src/lib/styles/code.css
Normal file
56
src/lib/styles/code.css
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
.hljs {
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
padding: 0.5em;
|
||||||
|
color: #e4f0fb;
|
||||||
|
background-color: var(--r-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-selector-class,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-strong,
|
||||||
|
.hljs-name,
|
||||||
|
.hljs-string {
|
||||||
|
color: #5de4c7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-code {
|
||||||
|
color: #66d9ef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-class .hljs-title {
|
||||||
|
color: #add7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-symbol,
|
||||||
|
.hljs-regexp,
|
||||||
|
.hljs-link {
|
||||||
|
color: #e4f0fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-bullet,
|
||||||
|
.hljs-subst,
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-section,
|
||||||
|
.hljs-emphasis,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-builtin-name,
|
||||||
|
.hljs-selector-attr,
|
||||||
|
.hljs-selector-pseudo,
|
||||||
|
.hljs-addition,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-template-variable,
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-attr {
|
||||||
|
color: #add7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-quote,
|
||||||
|
.hljs-deletion,
|
||||||
|
.hljs-meta {
|
||||||
|
color: #a6accd;
|
||||||
|
}
|
||||||
3
src/lib/styles/tailwind.css
Normal file
3
src/lib/styles/tailwind.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
127
src/lib/styles/theme.css
Normal file
127
src/lib/styles/theme.css
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
@import '@fontsource-variable/manrope';
|
||||||
|
@import '@fontsource-variable/jetbrains-mono';
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--r-background-color: hsl(226 19% 13%);
|
||||||
|
--r-main-font: 'Manrope Variable';
|
||||||
|
--r-main-font-size: 42px;
|
||||||
|
--r-main-color: hsl(226 19% 98%);
|
||||||
|
--r-heading-font: 'Manrope';
|
||||||
|
--r-code-font: 'JetBrains Mono Variable';
|
||||||
|
--r-link-color: hsl(180 100% 50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* required for Reveal.js to work */
|
||||||
|
#app {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal-viewport {
|
||||||
|
background-color: var(--r-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal {
|
||||||
|
color: var(--r-main-color);
|
||||||
|
font-family: var(--r-main-font);
|
||||||
|
font-size: var(--r-main-font-size);
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
margin-inline: auto;
|
||||||
|
font-family: var(--r-code-font);
|
||||||
|
font-size: 0.55em;
|
||||||
|
line-height: 1.6em;
|
||||||
|
text-align: left;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal code {
|
||||||
|
font-family: var(--r-code-font);
|
||||||
|
text-transform: none;
|
||||||
|
tab-size: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal code::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre code {
|
||||||
|
max-height: 600px;
|
||||||
|
display: block;
|
||||||
|
padding: 5px;
|
||||||
|
overflow: auto;
|
||||||
|
word-wrap: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .code-wrapper {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .code-wrapper code {
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table {
|
||||||
|
margin: auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th,
|
||||||
|
.reveal table td {
|
||||||
|
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th[align='center'],
|
||||||
|
.reveal table td[align='center'] {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th[align='right'],
|
||||||
|
.reveal table td[align='right'] {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table tbody tr:last-child th,
|
||||||
|
.reveal table tbody tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal sup {
|
||||||
|
vertical-align: super;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal sub {
|
||||||
|
vertical-align: sub;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.6em;
|
||||||
|
line-height: 1.2em;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small * {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .controls {
|
||||||
|
color: var(--r-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .progress {
|
||||||
|
color: var(--r-link-color);
|
||||||
|
}
|
||||||
323
src/lib/types/highlight.js/index.d.ts
vendored
Normal file
323
src/lib/types/highlight.js/index.d.ts
vendored
Normal file
@@ -0,0 +1,323 @@
|
|||||||
|
/*
|
||||||
|
Yoinked from https://github.com/highlightjs/highlight.js/blob/main/types/index.d.ts
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
/* eslint-disable no-use-before-define */
|
||||||
|
// For TS consumers who use Node and don't have dom in their tsconfig lib, import the necessary types here.
|
||||||
|
/// <reference lib="dom" />
|
||||||
|
|
||||||
|
declare module 'highlight.js/private' {
|
||||||
|
import { CompiledMode, Mode, Language } from 'highlight.js'
|
||||||
|
|
||||||
|
type MatchType = 'begin' | 'end' | 'illegal'
|
||||||
|
type EnhancedMatch = RegExpMatchArray & {
|
||||||
|
rule: CompiledMode
|
||||||
|
type: MatchType
|
||||||
|
}
|
||||||
|
type AnnotatedError = Error & {
|
||||||
|
mode?: Mode | Language
|
||||||
|
languageName?: string
|
||||||
|
badRule?: Mode
|
||||||
|
}
|
||||||
|
|
||||||
|
type KeywordData = [string, number]
|
||||||
|
type KeywordDict = Record<string, KeywordData>
|
||||||
|
}
|
||||||
|
declare module 'highlight.js' {
|
||||||
|
import { KeywordDict } from 'highlight.js/private'
|
||||||
|
|
||||||
|
export type HLJSApi = PublicApi & ModesAPI
|
||||||
|
|
||||||
|
export interface VuePlugin {
|
||||||
|
install: (vue: any) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
// perhaps make this an interface?
|
||||||
|
type RegexEitherOptions = {
|
||||||
|
capture?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PublicApi {
|
||||||
|
highlight: (
|
||||||
|
codeOrLanguageName: string,
|
||||||
|
optionsOrCode: string | HighlightOptions,
|
||||||
|
ignoreIllegals?: boolean
|
||||||
|
) => HighlightResult
|
||||||
|
highlightAuto: (
|
||||||
|
code: string,
|
||||||
|
languageSubset?: string[]
|
||||||
|
) => AutoHighlightResult
|
||||||
|
highlightBlock: (element: HTMLElement) => void
|
||||||
|
highlightElement: (element: HTMLElement) => void
|
||||||
|
configure: (options: Partial<HLJSOptions>) => void
|
||||||
|
initHighlighting: () => void
|
||||||
|
initHighlightingOnLoad: () => void
|
||||||
|
highlightAll: () => void
|
||||||
|
registerLanguage: (languageName: string, language: LanguageFn) => void
|
||||||
|
unregisterLanguage: (languageName: string) => void
|
||||||
|
listLanguages: () => string[]
|
||||||
|
registerAliases: (
|
||||||
|
aliasList: string | string[],
|
||||||
|
{ languageName }: { languageName: string }
|
||||||
|
) => void
|
||||||
|
getLanguage: (languageName: string) => Language | undefined
|
||||||
|
autoDetection: (languageName: string) => boolean
|
||||||
|
inherit: <T>(original: T, ...args: Record<string, any>[]) => T
|
||||||
|
addPlugin: (plugin: HLJSPlugin) => void
|
||||||
|
removePlugin: (plugin: HLJSPlugin) => void
|
||||||
|
debugMode: () => void
|
||||||
|
safeMode: () => void
|
||||||
|
versionString: string
|
||||||
|
vuePlugin: () => VuePlugin
|
||||||
|
regex: {
|
||||||
|
concat: (...args: (RegExp | string)[]) => string
|
||||||
|
lookahead: (re: RegExp | string) => string
|
||||||
|
either: (
|
||||||
|
...args:
|
||||||
|
| (RegExp | string)[]
|
||||||
|
| [...(RegExp | string)[], RegexEitherOptions]
|
||||||
|
) => string
|
||||||
|
optional: (re: RegExp | string) => string
|
||||||
|
anyNumberOfTimes: (re: RegExp | string) => string
|
||||||
|
}
|
||||||
|
newInstance: () => HLJSApi
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ModesAPI {
|
||||||
|
SHEBANG: (mode?: Partial<Mode> & { binary?: string | RegExp }) => Mode
|
||||||
|
BACKSLASH_ESCAPE: Mode
|
||||||
|
QUOTE_STRING_MODE: Mode
|
||||||
|
APOS_STRING_MODE: Mode
|
||||||
|
PHRASAL_WORDS_MODE: Mode
|
||||||
|
COMMENT: (
|
||||||
|
begin: string | RegExp,
|
||||||
|
end: string | RegExp,
|
||||||
|
modeOpts?: Mode | {}
|
||||||
|
) => Mode
|
||||||
|
C_LINE_COMMENT_MODE: Mode
|
||||||
|
C_BLOCK_COMMENT_MODE: Mode
|
||||||
|
HASH_COMMENT_MODE: Mode
|
||||||
|
NUMBER_MODE: Mode
|
||||||
|
C_NUMBER_MODE: Mode
|
||||||
|
BINARY_NUMBER_MODE: Mode
|
||||||
|
REGEXP_MODE: Mode
|
||||||
|
TITLE_MODE: Mode
|
||||||
|
UNDERSCORE_TITLE_MODE: Mode
|
||||||
|
METHOD_GUARD: Mode
|
||||||
|
END_SAME_AS_BEGIN: (mode: Mode) => Mode
|
||||||
|
// built in regex
|
||||||
|
IDENT_RE: string
|
||||||
|
UNDERSCORE_IDENT_RE: string
|
||||||
|
MATCH_NOTHING_RE: string
|
||||||
|
NUMBER_RE: string
|
||||||
|
C_NUMBER_RE: string
|
||||||
|
BINARY_NUMBER_RE: string
|
||||||
|
RE_STARTERS_RE: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LanguageFn = (hljs: HLJSApi) => Language
|
||||||
|
export type CompilerExt = (mode: Mode, parent: Mode | Language | null) => void
|
||||||
|
|
||||||
|
export interface HighlightResult {
|
||||||
|
code?: string
|
||||||
|
relevance: number
|
||||||
|
value: string
|
||||||
|
language?: string
|
||||||
|
illegal: boolean
|
||||||
|
errorRaised?: Error
|
||||||
|
// * for auto-highlight
|
||||||
|
secondBest?: Omit<HighlightResult, 'second_best'>
|
||||||
|
// private
|
||||||
|
_illegalBy?: illegalData
|
||||||
|
_emitter: Emitter
|
||||||
|
_top?: Language | CompiledMode
|
||||||
|
}
|
||||||
|
export interface AutoHighlightResult extends HighlightResult {}
|
||||||
|
|
||||||
|
export interface illegalData {
|
||||||
|
message: string
|
||||||
|
context: string
|
||||||
|
index: number
|
||||||
|
resultSoFar: string
|
||||||
|
mode: CompiledMode
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BeforeHighlightContext = {
|
||||||
|
code: string
|
||||||
|
language: string
|
||||||
|
result?: HighlightResult
|
||||||
|
}
|
||||||
|
export type PluginEvent = keyof HLJSPlugin
|
||||||
|
export type HLJSPlugin = {
|
||||||
|
'after:highlight'?: (result: HighlightResult) => void
|
||||||
|
'before:highlight'?: (context: BeforeHighlightContext) => void
|
||||||
|
'after:highlightElement'?: (data: {
|
||||||
|
el: Element
|
||||||
|
result: HighlightResult
|
||||||
|
text: string
|
||||||
|
}) => void
|
||||||
|
'before:highlightElement'?: (data: {
|
||||||
|
el: Element
|
||||||
|
language: string
|
||||||
|
}) => void
|
||||||
|
// TODO: Old API, remove with v12
|
||||||
|
'after:highlightBlock'?: (data: {
|
||||||
|
block: Element
|
||||||
|
result: HighlightResult
|
||||||
|
text: string
|
||||||
|
}) => void
|
||||||
|
'before:highlightBlock'?: (data: {
|
||||||
|
block: Element
|
||||||
|
language: string
|
||||||
|
}) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
interface EmitterConstructor {
|
||||||
|
new (opts: any): Emitter
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HighlightOptions {
|
||||||
|
language: string
|
||||||
|
ignoreIllegals?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HLJSOptions {
|
||||||
|
noHighlightRe: RegExp
|
||||||
|
languageDetectRe: RegExp
|
||||||
|
classPrefix: string
|
||||||
|
cssSelector: string
|
||||||
|
languages?: string[]
|
||||||
|
__emitter: EmitterConstructor
|
||||||
|
ignoreUnescapedHTML?: boolean
|
||||||
|
throwUnescapedHTML?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CallbackResponse {
|
||||||
|
data: Record<string, any>
|
||||||
|
ignoreMatch: () => void
|
||||||
|
isMatchIgnored: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ModeCallback = (
|
||||||
|
match: RegExpMatchArray,
|
||||||
|
response: CallbackResponse
|
||||||
|
) => void
|
||||||
|
export type Language = LanguageDetail & Partial<Mode>
|
||||||
|
export interface Mode extends ModeCallbacks, ModeDetails {}
|
||||||
|
|
||||||
|
export interface LanguageDetail {
|
||||||
|
name?: string
|
||||||
|
unicodeRegex?: boolean
|
||||||
|
rawDefinition?: () => Language
|
||||||
|
aliases?: string[]
|
||||||
|
disableAutodetect?: boolean
|
||||||
|
contains: Mode[]
|
||||||
|
case_insensitive?: boolean
|
||||||
|
keywords?: string | string[] | Record<string, string | string[]>
|
||||||
|
isCompiled?: boolean
|
||||||
|
exports?: any
|
||||||
|
classNameAliases?: Record<string, string>
|
||||||
|
compilerExtensions?: CompilerExt[]
|
||||||
|
supersetOf?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// technically private, but exported for convenience as this has
|
||||||
|
// been a pretty stable API and is quite useful
|
||||||
|
export interface Emitter {
|
||||||
|
startScope(name: string): void
|
||||||
|
endScope(): void
|
||||||
|
addText(text: string): void
|
||||||
|
toHTML(): string
|
||||||
|
finalize(): void
|
||||||
|
__addSublanguage(emitter: Emitter, subLanguageName: string): void
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HighlightedHTMLElement = HTMLElement & {
|
||||||
|
result?: object
|
||||||
|
secondBest?: object
|
||||||
|
parentNode: HTMLElement
|
||||||
|
}
|
||||||
|
|
||||||
|
/* modes */
|
||||||
|
|
||||||
|
interface ModeCallbacks {
|
||||||
|
'on:end'?: Function
|
||||||
|
'on:begin'?: ModeCallback
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompiledLanguage extends LanguageDetail, CompiledMode {
|
||||||
|
isCompiled: true
|
||||||
|
contains: CompiledMode[]
|
||||||
|
keywords: Record<string, any>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompiledScope = Record<number, string> & {
|
||||||
|
_emit?: Record<number, boolean>
|
||||||
|
_multi?: boolean
|
||||||
|
_wrap?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompiledMode = Omit<Mode, 'contains'> & {
|
||||||
|
begin?: RegExp | string
|
||||||
|
end?: RegExp | string
|
||||||
|
scope?: string
|
||||||
|
contains: CompiledMode[]
|
||||||
|
keywords: KeywordDict
|
||||||
|
data: Record<string, any>
|
||||||
|
terminatorEnd: string
|
||||||
|
keywordPatternRe: RegExp
|
||||||
|
beginRe: RegExp
|
||||||
|
endRe: RegExp
|
||||||
|
illegalRe: RegExp
|
||||||
|
matcher: any
|
||||||
|
isCompiled: true
|
||||||
|
starts?: CompiledMode
|
||||||
|
parent?: CompiledMode
|
||||||
|
beginScope?: CompiledScope
|
||||||
|
endScope?: CompiledScope
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ModeDetails {
|
||||||
|
begin?: RegExp | string | (RegExp | string)[]
|
||||||
|
match?: RegExp | string | (RegExp | string)[]
|
||||||
|
end?: RegExp | string | (RegExp | string)[]
|
||||||
|
// deprecated in favor of `scope`
|
||||||
|
className?: string
|
||||||
|
scope?: string | Record<number, string>
|
||||||
|
beginScope?: string | Record<number, string>
|
||||||
|
endScope?: string | Record<number, string>
|
||||||
|
contains?: ('self' | Mode)[]
|
||||||
|
endsParent?: boolean
|
||||||
|
endsWithParent?: boolean
|
||||||
|
endSameAsBegin?: boolean
|
||||||
|
skip?: boolean
|
||||||
|
excludeBegin?: boolean
|
||||||
|
excludeEnd?: boolean
|
||||||
|
returnBegin?: boolean
|
||||||
|
returnEnd?: boolean
|
||||||
|
__beforeBegin?: Function
|
||||||
|
parent?: Mode
|
||||||
|
starts?: Mode
|
||||||
|
lexemes?: string | RegExp
|
||||||
|
keywords?: string | string[] | Record<string, string | string[]>
|
||||||
|
beginKeywords?: string
|
||||||
|
relevance?: number
|
||||||
|
illegal?: string | RegExp | Array<string | RegExp>
|
||||||
|
variants?: Mode[]
|
||||||
|
cachedVariants?: Mode[]
|
||||||
|
// parsed
|
||||||
|
subLanguage?: string | string[]
|
||||||
|
isCompiled?: boolean
|
||||||
|
label?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const hljs: HLJSApi
|
||||||
|
export default hljs
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'highlight.js/lib/languages/*' {
|
||||||
|
import { LanguageFn } from 'highlight.js'
|
||||||
|
const defineLanguage: LanguageFn
|
||||||
|
export default defineLanguage
|
||||||
|
}
|
||||||
8
src/main.ts
Normal file
8
src/main.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import Slides from './slides.svelte'
|
||||||
|
import '@styles/tailwind.css'
|
||||||
|
|
||||||
|
const app = new Slides({
|
||||||
|
target: document.getElementById('app'),
|
||||||
|
})
|
||||||
|
|
||||||
|
export default app
|
||||||
276
src/slides.svelte
Normal file
276
src/slides.svelte
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {
|
||||||
|
Presentation,
|
||||||
|
Slide,
|
||||||
|
FitText,
|
||||||
|
Step,
|
||||||
|
Notes,
|
||||||
|
Media,
|
||||||
|
Code
|
||||||
|
} from '@components'
|
||||||
|
import { signal } from '@motion'
|
||||||
|
|
||||||
|
const circle = signal(
|
||||||
|
{ x: 0, y: 200, r: 80, fill: '#00ffff' },
|
||||||
|
{ duration: 2000 }
|
||||||
|
)
|
||||||
|
|
||||||
|
async function animate() {
|
||||||
|
await circle.to({ x: 400, fill: '#ffff00' }, { delay: 600 })
|
||||||
|
await circle.to({ x: 0, fill: '#00ffff' }, { delay: 300 })
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetAnimation() {
|
||||||
|
circle.reset()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Presentation>
|
||||||
|
<Slide animate>
|
||||||
|
<p class="font-bold text-8xl text-pink-700">React Builtin Hooks</p>
|
||||||
|
</Slide>
|
||||||
|
|
||||||
|
<!-- <Slide on:in={animate} on:out={resetAnimation} animate>
|
||||||
|
<p class="font-bold text-6xl">React Builtin Hooks</p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<li>useState()</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</Slide> -->
|
||||||
|
<Slide on:in={animate} animate>
|
||||||
|
<p class="font-bold text-6xl mb-4 text-pink-700">React Builtin Hooks</p>
|
||||||
|
<ul class="mx-auto w-[200px] list-disc">
|
||||||
|
<Step>
|
||||||
|
<li>useState()</li>
|
||||||
|
</Step>
|
||||||
|
<Step>
|
||||||
|
<li>useEffect()</li>
|
||||||
|
</Step>
|
||||||
|
<Step>
|
||||||
|
<li>useContext()</li>
|
||||||
|
</Step>
|
||||||
|
<Step>
|
||||||
|
<li>useReducer()</li>
|
||||||
|
</Step>
|
||||||
|
<Step>
|
||||||
|
<li>useRef()</li>
|
||||||
|
</Step>
|
||||||
|
<Step>
|
||||||
|
<li>useMemo()</li>
|
||||||
|
</Step>
|
||||||
|
<Step>
|
||||||
|
<li>useCallback()</li>
|
||||||
|
</Step>
|
||||||
|
</ul>
|
||||||
|
</Slide>
|
||||||
|
<Slide on:in={animate} animate>
|
||||||
|
<p class="font-bold text-6xl mb-4 text-pink-700">What is a State?</p>
|
||||||
|
<Notes>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
State is something which holds the info or details about a Component's State at a TIME
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
It can change over time.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Whenever the state changes the COMPONENT attached to it re-renders
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</Notes>
|
||||||
|
</Slide>
|
||||||
|
<Slide on:in={animate} animate>
|
||||||
|
<p class="font-bold text-6xl mb-4 text-pink-700">useState()</p>
|
||||||
|
<Notes>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
useState hooks allows to have state variable inside a FUNCTIONAL COMPONENT
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
useState ENCAPSULATES only a single value
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
For mulatiple values you may need to call multiple useState's
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
useState arguments
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Initialization of a state variable
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Passing function as initial value - to calculate an initial value
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Managing multiple states
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Multi-variable's
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Object as value
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</Notes>
|
||||||
|
</Slide>
|
||||||
|
<Slide on:in={animate} animate>
|
||||||
|
<p class="font-bold text-6xl mb-4 text-yellow-500">Side Effects</p>
|
||||||
|
<Media
|
||||||
|
class="h-[600px] w-full"
|
||||||
|
src="https://giphy.com/embed/39sYm1hvWRPN3NxHdI"
|
||||||
|
type="iframe"
|
||||||
|
>
|
||||||
|
</Media>
|
||||||
|
<Notes>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Something which is outside the scope of REACT
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Calling AJAX requests
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Calling Web API stuffs (document.get...)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
localStorage etc...
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
setTimeout, setInterval
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Everything which is not part of React Library
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Fun Fact - What happens if you call setTimeout without any arguments
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Executes outside the execution queue
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</Notes>
|
||||||
|
</Slide>
|
||||||
|
<Slide on:in={animate} animate>
|
||||||
|
<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
|
||||||
|
<div class="mx-auto w-[800px]">
|
||||||
|
<Code lang="js" lines="1-3|3">
|
||||||
|
{`
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = "Hey There, I'm from useEffect"
|
||||||
|
})
|
||||||
|
`}
|
||||||
|
</Code>
|
||||||
|
</div>
|
||||||
|
</Slide>
|
||||||
|
<Slide on:in={animate} animate>
|
||||||
|
<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
|
||||||
|
<div class="mx-auto w-[800px]">
|
||||||
|
<Code lang="js" lines="3-4">
|
||||||
|
{`
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = "Hey There, I'm from useEffect"
|
||||||
|
}) ← No Arguments means this will be called each time
|
||||||
|
this component re-renders
|
||||||
|
`}
|
||||||
|
</Code>
|
||||||
|
</div>
|
||||||
|
</Slide>
|
||||||
|
<Slide on:in={animate} animate>
|
||||||
|
<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
|
||||||
|
<div class="mx-auto w-[800px]">
|
||||||
|
<Code lang="js" lines="3-4">
|
||||||
|
{`
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = "Hey There, I'm from useEffect"
|
||||||
|
}, []) ← An empty array as an argument will run the
|
||||||
|
effect once the component is mounted
|
||||||
|
`}
|
||||||
|
</Code>
|
||||||
|
</div>
|
||||||
|
</Slide>
|
||||||
|
<Slide on:in={animate} animate>
|
||||||
|
<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
|
||||||
|
<div class="mx-auto w-[800px]">
|
||||||
|
<Code lang="js" lines="3-4">
|
||||||
|
{`
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = "Hey There, I'm from useEffect"
|
||||||
|
}, [prop1]) ← We can pass value
|
||||||
|
`}
|
||||||
|
</Code>
|
||||||
|
</div>
|
||||||
|
</Slide>
|
||||||
|
<Slide on:in={animate} animate>
|
||||||
|
<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
|
||||||
|
<div class="mx-auto">
|
||||||
|
<Code lang="js" lines="3-4">
|
||||||
|
{`
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = "Hey There, I'm from useEffect"
|
||||||
|
}, [prop1, state1]) ← Actually we can pass multiple-values
|
||||||
|
`}
|
||||||
|
</Code>
|
||||||
|
</div>
|
||||||
|
</Slide>
|
||||||
|
<Slide on:in={animate} animate>
|
||||||
|
<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
|
||||||
|
<div class="mx-auto w-[800px]">
|
||||||
|
<Code lang="js" lines="3-4">
|
||||||
|
{`
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = "Hey There, I'm from useEffect"
|
||||||
|
}, [prop1, state1]) ← This is called dependency list
|
||||||
|
`}
|
||||||
|
</Code>
|
||||||
|
</div>
|
||||||
|
</Slide>
|
||||||
|
<Slide on:in={animate} animate>
|
||||||
|
<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
|
||||||
|
<div class="mx-auto w-[800px]">
|
||||||
|
<Code lang="js" lines="3-4">
|
||||||
|
{`
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = "Hey There, I'm from useEffect"
|
||||||
|
}, [prop1, state1]) ← Effect will run whenever any
|
||||||
|
of the values on dependency list changes
|
||||||
|
`}
|
||||||
|
</Code>
|
||||||
|
</div>
|
||||||
|
</Slide>
|
||||||
|
<Slide on:in={animate} animate>
|
||||||
|
<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
|
||||||
|
<div class="mx-auto w-[800px]">
|
||||||
|
<Code lang="js" lines="4-6">
|
||||||
|
{`
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = "Hey There, I'm from useEffect";
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
// Clean Up function 🧹
|
||||||
|
}
|
||||||
|
}, [prop1, state1]);
|
||||||
|
`}
|
||||||
|
</Code>
|
||||||
|
</div>
|
||||||
|
<Notes>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
You can do removeListeners, unsubscribes, reset layouts etc
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
This will be called by default when component unmouts.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</Notes>
|
||||||
|
</Slide>
|
||||||
|
</Presentation>
|
||||||
2
src/vite-env.d.ts
vendored
Normal file
2
src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/// <reference types="svelte" />
|
||||||
|
/// <reference types="vite/client" />
|
||||||
7
svelte.config.js
Normal file
7
svelte.config.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// Consult https://svelte.dev/docs#compile-time-svelte-preprocess
|
||||||
|
// for more information about preprocessors
|
||||||
|
preprocess: [vitePreprocess()],
|
||||||
|
}
|
||||||
10
tailwind.config.js
Normal file
10
tailwind.config.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/** @type {import('tailwindcss').Config}*/
|
||||||
|
const config = {
|
||||||
|
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config
|
||||||
24
tsconfig.json
Normal file
24
tsconfig.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@config": ["./src/config.ts"],
|
||||||
|
"@components": ["./src/lib/components/index.ts"],
|
||||||
|
"@motion": ["./src/lib/motion/index.ts"],
|
||||||
|
"@languages": ["./src/lib/languages/index.ts"],
|
||||||
|
"@lib/*": ["./src/lib/*"],
|
||||||
|
"@stores/*": ["./src/lib/stores/*"],
|
||||||
|
"@styles/*": ["./src/lib/styles/*"]
|
||||||
|
},
|
||||||
|
"target": "ESNext",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true,
|
||||||
|
"isolatedModules": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
|
||||||
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
|
}
|
||||||
9
tsconfig.node.json
Normal file
9
tsconfig.node.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler"
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
||||||
19
vite.config.ts
Normal file
19
vite.config.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import { svelte } from '@sveltejs/vite-plugin-svelte'
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [svelte()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@config': path.resolve(__dirname, './src/config.ts'),
|
||||||
|
'@components': path.resolve(__dirname, './src/lib/components/index.ts'),
|
||||||
|
'@motion': path.resolve(__dirname, './src/lib/motion/index.ts'),
|
||||||
|
'@languages': path.resolve(__dirname, './src/lib/languages/index.ts'),
|
||||||
|
'@lib': path.resolve(__dirname, './src/lib'),
|
||||||
|
'@stores': path.resolve(__dirname, './src/lib/stores'),
|
||||||
|
'@styles': path.resolve(__dirname, './src/lib/styles'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user