-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 86f1d10
Showing
54 changed files
with
11,190 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Allow personal config overrides | ||
root = false | ||
|
||
[*] | ||
indent_style = tab | ||
insert_final_newline = true | ||
trim_trailing_whitespace = true | ||
end_of_line = lf | ||
charset = utf-8 | ||
|
||
[*.yml] | ||
indent_style = space | ||
indent_size = 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* text=auto eol=lf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# https://vitejs.dev/guide/static-deploy.html#github-pages | ||
name: Deploy to GitHub Pages | ||
on: | ||
push: | ||
branches: ["main"] | ||
workflow_dispatch: | ||
permissions: | ||
contents: read | ||
pages: write | ||
id-token: write | ||
concurrency: | ||
group: "pages" | ||
cancel-in-progress: true | ||
jobs: | ||
deploy: | ||
environment: | ||
name: github-pages | ||
url: ${{ steps.deployment.outputs.page_url }} | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
- name: Install pnpm | ||
uses: pnpm/action-setup@v4 | ||
with: | ||
version: 9 | ||
- name: Set up Node | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version-file: ".nvmrc" | ||
cache: "pnpm" | ||
- name: Install dependencies | ||
run: pnpm install | ||
- name: Build | ||
run: pnpm build:demo | ||
- name: Setup Pages | ||
uses: actions/configure-pages@v5 | ||
- name: Upload artifact | ||
uses: actions/upload-pages-artifact@v3 | ||
with: | ||
path: "./demo/dist" | ||
- name: Deploy to GitHub Pages | ||
id: deployment | ||
uses: actions/deploy-pages@v4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
name: CI Lint | ||
on: | ||
push: | ||
branches: ["main"] | ||
pull_request: | ||
jobs: | ||
lint: | ||
name: Lint | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: pnpm/action-setup@v4 | ||
with: | ||
version: 9 | ||
- uses: actions/setup-node@v4 | ||
- run: pnpm install | ||
- run: pnpm lint |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
name: CI Test | ||
on: | ||
push: | ||
branches: ["main"] | ||
pull_request: | ||
jobs: | ||
test: | ||
name: Node.js ${{ matrix.node-version }} | ||
runs-on: ubuntu-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
node-version: [18.19, 20.8, 21, 22] | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: pnpm/action-setup@v4 | ||
with: | ||
version: 9 | ||
- uses: actions/setup-node@v4 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
- run: pnpm install | ||
- run: pnpm exec tsimp --start # Preload the transpiler | ||
- run: pnpm test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
node_modules | ||
coverage | ||
.tsimp | ||
dist | ||
package-lock.json | ||
yarn.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
v20.15.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { fileURLToPath } from "url"; | ||
|
||
export default { | ||
extends: [ | ||
"@tommy-mitchell/xo", | ||
"@tommy-mitchell/xo/react", | ||
"@tommy-mitchell/xo/tailwind", | ||
"@tommy-mitchell/xo/dprint", | ||
], | ||
settings: { | ||
tailwindcss: { | ||
config: fileURLToPath(new URL("demo/tailwind.config.ts", import.meta.url)), | ||
}, | ||
}, | ||
rules: { | ||
"@typescript-eslint/naming-convention": "off", | ||
"simple-import-sort/imports": ["error", { | ||
groups: [["^\\u0000", "^node:", "^react", "^react-dom", "^@?\\w", "^", "^\\.", "^.+\\.s?css$"]], | ||
}], | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>use-boop-simple</title> | ||
<script> | ||
if (localStorage.theme === "dark" || (!("theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches)) { | ||
document.documentElement.classList.add("dark") | ||
} | ||
</script> | ||
</head> | ||
<body class="bg-background text-primary"> | ||
<div id="root"></div> | ||
<script type="module" src="src/index.tsx"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"private": true, | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite", | ||
"host": "vite --host", | ||
"build": "vite build", | ||
"preview": "vite preview" | ||
}, | ||
"dependencies": { | ||
"@icons-pack/react-simple-icons": "10.0.0", | ||
"@radix-ui/react-slider": "1.2.0", | ||
"lucide-react": "0.428.0", | ||
"react": "18.3.1", | ||
"react-dom": "18.3.1", | ||
"tailwind-merge": "2.5.2", | ||
"use-boop-simple": "workspace:*" | ||
}, | ||
"devDependencies": { | ||
"@mdx-js/rollup": "3.0.1", | ||
"@tailwindcss/typography": "0.5.14", | ||
"@types/mdx": "2.0.13", | ||
"@types/react": "18.3.3", | ||
"@types/react-dom": "18.3.0", | ||
"@vitejs/plugin-react-swc": "3.7.0", | ||
"autoprefixer": "10.4.20", | ||
"tailwind-mode-aware-colors": "2.0.2", | ||
"tailwindcss": "3.4.10", | ||
"vite": "5.4.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { SiGithub } from "@icons-pack/react-simple-icons"; | ||
import About from "../content/about.md"; | ||
import { BoopInput } from "./BoopInput.tsx"; | ||
import { IconButton } from "./IconButton.tsx"; | ||
import { Prose } from "./Prose.tsx"; | ||
import { ThemeToggle } from "./ThemeToggle.tsx"; | ||
|
||
export function App() { | ||
return ( | ||
<div className="flex h-full flex-col gap-6 p-4 sm:mx-8 xl:py-8"> | ||
<header className="container flex flex-wrap items-center justify-between gap-4"> | ||
<Prose className="max-xs:prose-sm"> | ||
<h1> | ||
<code>use-boop-simple</code> | ||
</h1> | ||
</Prose> | ||
<nav className="flex flex-wrap gap-3"> | ||
<ThemeToggle /> | ||
<IconButton href="https://github.com/tommy-mitchell/use-boop-simple"> | ||
<SiGithub className="size-7" /> | ||
</IconButton> | ||
</nav> | ||
</header> | ||
<main className="container flex grow flex-col"> | ||
<Prose className="prose-p:first-of-type:mt-0"> | ||
<About /> | ||
</Prose> | ||
<BoopInput /> | ||
</main> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { useEffect } from "react"; | ||
import { twMerge } from "tailwind-merge"; | ||
import { useBoop, type UseBoopOptions } from "use-boop-simple"; | ||
|
||
export type BoopProps = | ||
& Omit<React.ComponentProps<"button">, "onClick" | "type"> | ||
& Readonly<{ | ||
trigger?: boolean; | ||
onClick?: () => void; | ||
}> | ||
& UseBoopOptions; | ||
|
||
export function Boop({ | ||
className, | ||
friction, | ||
onClick, | ||
rotate, | ||
scale, | ||
tension, | ||
timing, | ||
trigger, | ||
x, | ||
y, | ||
...props | ||
}: BoopProps) { | ||
const boopOptions = { friction, rotate, scale, tension, timing, x, y }; | ||
const [style, boopTrigger] = useBoop(boopOptions); | ||
|
||
useEffect(() => { | ||
if (trigger) { | ||
boopTrigger(); | ||
} | ||
}, [boopTrigger, trigger]); | ||
|
||
const triggers = props.disabled ? {} : { | ||
onFocus: boopTrigger, | ||
onPointerEnter: boopTrigger, | ||
}; | ||
|
||
return ( | ||
<button | ||
type="button" | ||
className={twMerge("group z-50 block w-fit outline-offset-2 will-change-transform", className)} | ||
style={style} | ||
onClick={() => { | ||
boopTrigger(); | ||
onClick?.(); | ||
}} | ||
{...triggers} | ||
{...props} | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { useState } from "react"; | ||
import type { UseBoopOptions } from "use-boop-simple"; | ||
import { Boop } from "./Boop.tsx"; | ||
import { NumberSlider } from "./NumberSlider.tsx"; | ||
import { ResetButton } from "./ResetButton.tsx"; | ||
|
||
/* eslint-disable perfectionist/sort-objects */ | ||
const INITIAL_BOOP_OPTIONS: Required<UseBoopOptions> = { | ||
x: 15, | ||
y: 0, | ||
rotate: 30, | ||
scale: 1, | ||
tension: 500, | ||
friction: 10, | ||
timing: 150, | ||
}; | ||
/* eslint-enable perfectionist/sort-objects */ | ||
|
||
const isInitial = (boopOptions: UseBoopOptions) => ( | ||
Object.entries(boopOptions).every(([key, value]) => INITIAL_BOOP_OPTIONS[key as keyof UseBoopOptions] === value) | ||
); | ||
|
||
export function BoopInput() { | ||
const [boopOptions, setBoopOptions] = useState(INITIAL_BOOP_OPTIONS); | ||
const [trigger, setTrigger] = useState(false); | ||
|
||
const handleChange = (key: keyof UseBoopOptions) => (value: number) => { | ||
setBoopOptions({ ...boopOptions, [key]: value }); | ||
}; | ||
|
||
const getProps = (key: keyof UseBoopOptions) => ({ | ||
label: key, | ||
onChange: handleChange(key), | ||
value: boopOptions[key], | ||
}); | ||
|
||
return ( | ||
<div className="flex grow flex-col items-center gap-4 md:grid md:grid-cols-2 md:place-items-center md:gap-6"> | ||
<div | ||
className={` | ||
relative flex size-full flex-col gap-4 rounded-xl border-2 border-dashed p-4 border-accent-400 | ||
max-md:pt-2 | ||
md:justify-center | ||
`} | ||
> | ||
<p className="left-4 top-2 text-tertiary md:absolute"> | ||
Interact to <em>boop!</em> Or click the button in the controls. | ||
</p> | ||
<Boop className="self-center" trigger={trigger} {...boopOptions}> | ||
<span className="text-[48px]">👋</span> | ||
</Boop> | ||
</div> | ||
<div className="grid size-full place-items-center rounded-xl border border-accent-400 p-4 md:px-8"> | ||
<form className="grid w-full grid-cols-2 gap-x-6 gap-y-4 text-secondary 2xl:grid-cols-1 lg:gap-6 max-xs:grid-cols-1"> | ||
<NumberSlider {...getProps("x")} min={-50} max={50} /> | ||
<NumberSlider {...getProps("y")} min={-50} max={50} /> | ||
<NumberSlider {...getProps("rotate")} max={360} /> | ||
<NumberSlider {...getProps("scale")} min={-5} max={5} step={.1} /> | ||
<NumberSlider {...getProps("tension")} step={10} min={1} max={1000} /> | ||
<NumberSlider {...getProps("friction")} min={1} max={100} /> | ||
<NumberSlider {...getProps("timing")} min={0} max={1000} step={50} /> | ||
<div className="flex items-center gap-2 self-end max-xs:-order-1"> | ||
<button | ||
type="button" | ||
className={` | ||
grow rounded border border-accent-600 bg-primary px-2 transition-colors text-primary | ||
active:!border-accent-700 active:!bg-primary-active | ||
hocus:border-accent-500 hocus:bg-primary-hocus | ||
`} | ||
onClick={() => { | ||
setTrigger(true); | ||
setTimeout(() => setTrigger(false), 0); | ||
}} | ||
> | ||
boop! | ||
</button> | ||
<ResetButton disabled={isInitial(boopOptions)} onReset={() => setBoopOptions(INITIAL_BOOP_OPTIONS)} /> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { twMerge } from "tailwind-merge"; | ||
import type { UseBoopOptions } from "use-boop-simple"; | ||
import { Boop, type BoopProps } from "./Boop.tsx"; | ||
import { VisuallyHidden } from "./VisuallyHidden.tsx"; | ||
|
||
type IconProps = | ||
& Omit<BoopProps, keyof UseBoopOptions> | ||
& Readonly<{ | ||
as: React.ComponentType<React.ComponentProps<"svg">>; | ||
boop: UseBoopOptions; | ||
className?: string; | ||
label: string; | ||
}>; | ||
|
||
export function Icon({ as: IconComponent, boop, className, label, ...props }: IconProps) { | ||
return ( | ||
<Boop {...boop} {...props}> | ||
<IconComponent | ||
aria-hidden="true" | ||
className={twMerge( | ||
` | ||
h-auto w-16 transition-colors duration-100 text-accent-300 | ||
dark:text-accent-500 dark:group-disabled:!text-accent-700 dark:group-hocus:text-accent-400 | ||
group-disabled:!text-accent-200 group-disabled:cursor-not-allowed | ||
group-hocus:text-accent-500 | ||
`, | ||
className, | ||
)} | ||
focusable="false" | ||
/> | ||
<VisuallyHidden>{label}</VisuallyHidden> | ||
</Boop> | ||
); | ||
} |
Oops, something went wrong.