aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIndrajith K L2024-02-05 04:15:02 +0530
committerIndrajith K L2024-02-05 04:15:02 +0530
commitf05a472585b2506da21aed71f0252b2d4c04a221 (patch)
tree4f65a3801f29250a049f3cc5cd2ac9c0a41d78f9 /src
downloadreact-hooks-training-f05a472585b2506da21aed71f0252b2d4c04a221.tar.gz
react-hooks-training-f05a472585b2506da21aed71f0252b2d4c04a221.tar.bz2
react-hooks-training-f05a472585b2506da21aed71f0252b2d4c04a221.zip
React Slides
* Adds useState * State * useEffect * Side Effects
Diffstat (limited to 'src')
-rw-r--r--src/<!DOCTYPE html>.html11
-rw-r--r--src/config.ts52
-rw-r--r--src/global.d.ts6
-rw-r--r--src/lib/components/code.svelte22
-rw-r--r--src/lib/components/fit.svelte13
-rw-r--r--src/lib/components/index.ts25
-rw-r--r--src/lib/components/markdown.svelte13
-rw-r--r--src/lib/components/media.svelte22
-rw-r--r--src/lib/components/notes.svelte3
-rw-r--r--src/lib/components/presentation.svelte77
-rw-r--r--src/lib/components/slide.svelte48
-rw-r--r--src/lib/components/stack.svelte3
-rw-r--r--src/lib/components/step.svelte53
-rw-r--r--src/lib/components/stretch.svelte13
-rw-r--r--src/lib/components/vertical.svelte3
-rw-r--r--src/lib/languages/index.ts6
-rw-r--r--src/lib/languages/svelte.ts50
-rw-r--r--src/lib/languages/types.ts3
-rw-r--r--src/lib/motion/index.ts4
-rw-r--r--src/lib/motion/signal.ts61
-rw-r--r--src/lib/motion/types.ts2
-rw-r--r--src/lib/motion/utils.ts10
-rw-r--r--src/lib/styles/code.css56
-rw-r--r--src/lib/styles/tailwind.css3
-rw-r--r--src/lib/styles/theme.css127
-rw-r--r--src/lib/types/highlight.js/index.d.ts323
-rw-r--r--src/main.ts8
-rw-r--r--src/slides.svelte276
-rw-r--r--src/vite-env.d.ts2
29 files changed, 1295 insertions, 0 deletions
diff --git a/src/<!DOCTYPE html>.html b/src/<!DOCTYPE html>.html
new file mode 100644
index 0000000..5a60528
--- /dev/null
+++ b/src/<!DOCTYPE html>.html
@@ -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> \ No newline at end of file
diff --git a/src/config.ts b/src/config.ts
new file mode 100644
index 0000000..0461e3d
--- /dev/null
+++ b/src/config.ts
@@ -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
diff --git a/src/global.d.ts b/src/global.d.ts
new file mode 100644
index 0000000..0988c71
--- /dev/null
+++ b/src/global.d.ts
@@ -0,0 +1,6 @@
+declare namespace svelteHTML {
+ interface HTMLAttributes<T> {
+ 'on:in'?: (event: CustomEvent) => void
+ 'on:out'?: (event: CustomEvent) => void
+ }
+}
diff --git a/src/lib/components/code.svelte b/src/lib/components/code.svelte
new file mode 100644
index 0000000..255bf7e
--- /dev/null
+++ b/src/lib/components/code.svelte
@@ -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>
diff --git a/src/lib/components/fit.svelte b/src/lib/components/fit.svelte
new file mode 100644
index 0000000..8772061
--- /dev/null
+++ b/src/lib/components/fit.svelte
@@ -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>
diff --git a/src/lib/components/index.ts b/src/lib/components/index.ts
new file mode 100644
index 0000000..392800d
--- /dev/null
+++ b/src/lib/components/index.ts
@@ -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,
+}
diff --git a/src/lib/components/markdown.svelte b/src/lib/components/markdown.svelte
new file mode 100644
index 0000000..204815b
--- /dev/null
+++ b/src/lib/components/markdown.svelte
@@ -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}
diff --git a/src/lib/components/media.svelte b/src/lib/components/media.svelte
new file mode 100644
index 0000000..ffa2633
--- /dev/null
+++ b/src/lib/components/media.svelte
@@ -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>
diff --git a/src/lib/components/notes.svelte b/src/lib/components/notes.svelte
new file mode 100644
index 0000000..198e18d
--- /dev/null
+++ b/src/lib/components/notes.svelte
@@ -0,0 +1,3 @@
+<aside class="notes">
+ <slot />
+</aside>
diff --git a/src/lib/components/presentation.svelte b/src/lib/components/presentation.svelte
new file mode 100644
index 0000000..c11010a
--- /dev/null
+++ b/src/lib/components/presentation.svelte
@@ -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>
diff --git a/src/lib/components/slide.svelte b/src/lib/components/slide.svelte
new file mode 100644
index 0000000..439d312
--- /dev/null
+++ b/src/lib/components/slide.svelte
@@ -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>
diff --git a/src/lib/components/stack.svelte b/src/lib/components/stack.svelte
new file mode 100644
index 0000000..a03d205
--- /dev/null
+++ b/src/lib/components/stack.svelte
@@ -0,0 +1,3 @@
+<div class="r-stack">
+ <slot />
+</div>
diff --git a/src/lib/components/step.svelte b/src/lib/components/step.svelte
new file mode 100644
index 0000000..13c2f7c
--- /dev/null
+++ b/src/lib/components/step.svelte
@@ -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>
diff --git a/src/lib/components/stretch.svelte b/src/lib/components/stretch.svelte
new file mode 100644
index 0000000..be808d5
--- /dev/null
+++ b/src/lib/components/stretch.svelte
@@ -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>
diff --git a/src/lib/components/vertical.svelte b/src/lib/components/vertical.svelte
new file mode 100644
index 0000000..fb20c0a
--- /dev/null
+++ b/src/lib/components/vertical.svelte
@@ -0,0 +1,3 @@
+<section>
+ <slot />
+</section>
diff --git a/src/lib/languages/index.ts b/src/lib/languages/index.ts
new file mode 100644
index 0000000..296c1fa
--- /dev/null
+++ b/src/lib/languages/index.ts
@@ -0,0 +1,6 @@
+import { svelte } from './svelte'
+import type { Hljs } from './types'
+
+export function registerLanguages(hljs: Hljs) {
+ hljs.registerLanguage('svelte', svelte)
+}
diff --git a/src/lib/languages/svelte.ts b/src/lib/languages/svelte.ts
new file mode 100644
index 0000000..237c7c7
--- /dev/null
+++ b/src/lib/languages/svelte.ts
@@ -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,
+ },
+ ],
+ },
+ ],
+ }
+}
diff --git a/src/lib/languages/types.ts b/src/lib/languages/types.ts
new file mode 100644
index 0000000..a030e24
--- /dev/null
+++ b/src/lib/languages/types.ts
@@ -0,0 +1,3 @@
+import hljs from 'highlight.js'
+
+export type Hljs = typeof hljs
diff --git a/src/lib/motion/index.ts b/src/lib/motion/index.ts
new file mode 100644
index 0000000..79e3d36
--- /dev/null
+++ b/src/lib/motion/index.ts
@@ -0,0 +1,4 @@
+import { signal } from './signal'
+import { animate, all } from './utils'
+
+export { signal, animate, all }
diff --git a/src/lib/motion/signal.ts b/src/lib/motion/signal.ts
new file mode 100644
index 0000000..99697ce
--- /dev/null
+++ b/src/lib/motion/signal.ts
@@ -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 }
+}
diff --git a/src/lib/motion/types.ts b/src/lib/motion/types.ts
new file mode 100644
index 0000000..e97a109
--- /dev/null
+++ b/src/lib/motion/types.ts
@@ -0,0 +1,2 @@
+export type AnimationFn = () => Promise<void>
+export type Resolve = (value?: any) => Promise<void>
diff --git a/src/lib/motion/utils.ts b/src/lib/motion/utils.ts
new file mode 100644
index 0000000..a81c02e
--- /dev/null
+++ b/src/lib/motion/utils.ts
@@ -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)
+}
diff --git a/src/lib/styles/code.css b/src/lib/styles/code.css
new file mode 100644
index 0000000..36adfe4
--- /dev/null
+++ b/src/lib/styles/code.css
@@ -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;
+}
diff --git a/src/lib/styles/tailwind.css b/src/lib/styles/tailwind.css
new file mode 100644
index 0000000..b5c61c9
--- /dev/null
+++ b/src/lib/styles/tailwind.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/src/lib/styles/theme.css b/src/lib/styles/theme.css
new file mode 100644
index 0000000..5215feb
--- /dev/null
+++ b/src/lib/styles/theme.css
@@ -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);
+}
diff --git a/src/lib/types/highlight.js/index.d.ts b/src/lib/types/highlight.js/index.d.ts
new file mode 100644
index 0000000..98dfac2
--- /dev/null
+++ b/src/lib/types/highlight.js/index.d.ts
@@ -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
+}
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..d64a5b3
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,8 @@
+import Slides from './slides.svelte'
+import '@styles/tailwind.css'
+
+const app = new Slides({
+ target: document.getElementById('app'),
+})
+
+export default app
diff --git a/src/slides.svelte b/src/slides.svelte
new file mode 100644
index 0000000..64166a8
--- /dev/null
+++ b/src/slides.svelte
@@ -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>
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
new file mode 100644
index 0000000..4078e74
--- /dev/null
+++ b/src/vite-env.d.ts
@@ -0,0 +1,2 @@
+/// <reference types="svelte" />
+/// <reference types="vite/client" />