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