diff --git a/README.md b/README.md index 3842474..6bac63b 100644 --- a/README.md +++ b/README.md @@ -1 +1,64 @@ # @rkrupinski/react + +An experimental, lightweight [React](https://react.dev/) alternative. + +- [Getting started](#getting-started) + +## Getting started + +Install: + +``` +yarn add @rkrupinski/react +``` + +Make sure to set: + +```json +{ + "jsx": "react" +} +``` + +in your `tsconfig.json` -> `"compilerOptions"`. + +Now you're all set: + +```tsx +/* @jsx createElement */ +/* @jsxFrag Fragment */ + +import { + render, + useState, + useEffect, + createElement, + Fragment, + type FC, +} from "@rkrupinski/react"; + +const App: FC = () => { + const [clicked, setClicked] = useState(0); + + useEffect(() => { + console.log(`Clicked ${clicked} times`); + }, [clicked]); + + return ( + <> +

Hello!

+ + + ); +}; + +const root = document.querySelector("#root") as HTMLElement; + +render(, root); +``` diff --git a/package.json b/package.json index 13ae10e..9d56f15 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,12 @@ "packages/*" ], "scripts": { - "clean": "wsrun -mc clean", - "typecheck": "wsrun -mc typecheck", - "lint": "wsrun -mc lint", - "test": "wsrun -mc test", - "build": "wsrun -tc build" + "clean": "wsrun -mc clean", + "typecheck": "wsrun -mc typecheck", + "lint": "wsrun -mc lint", + "test": "wsrun -mc test", + "start": "wsrun -mc start", + "build": "wsrun -tc build" }, "devDependencies": { "wsrun": "5.2.4" diff --git a/packages/example/.prettierrc.json b/packages/example/.prettierrc.json new file mode 100644 index 0000000..0764141 --- /dev/null +++ b/packages/example/.prettierrc.json @@ -0,0 +1 @@ +"@rkrupinski/prettierconfig" \ No newline at end of file diff --git a/packages/example/README.md b/packages/example/README.md new file mode 100644 index 0000000..383b694 --- /dev/null +++ b/packages/example/README.md @@ -0,0 +1,3 @@ +# @rkrupinski/react + +- [Docs](https://github.com/rkrupinski/react#readme) diff --git a/packages/example/package.json b/packages/example/package.json new file mode 100644 index 0000000..e633077 --- /dev/null +++ b/packages/example/package.json @@ -0,0 +1,18 @@ +{ + "name": "example", + "private": true, + "version": "0.0.0", + "scripts": { + "clean": "rm -rf dist", + "start": "parcel src/index.html --open", + "build": "parcel build src/index.html" + }, + "dependencies": { + "@rkrupinski/react": "*", + "todomvc-app-css": "2.4.2" + }, + "devDependencies": { + "@rkrupinski/prettierconfig": "1.0.1", + "parcel": "2.9.3" + } +} diff --git a/packages/example/src/components/TodoInput/TodoInput.tsx b/packages/example/src/components/TodoInput/TodoInput.tsx new file mode 100644 index 0000000..ecf7267 --- /dev/null +++ b/packages/example/src/components/TodoInput/TodoInput.tsx @@ -0,0 +1,43 @@ +/* @jsx createElement */ + +import { + createElement, + useState, + useCallback, + type FC, +} from '@rkrupinski/react'; + +export type TodoInputProps = { + onNewTodo: (text: string) => void; +}; + +export const TodoInput: FC = ({ onNewTodo }) => { + const [text, setText] = useState(''); + + const handleInput = useCallback( + (e: any) => { + setText(e.target.value); + }, + [setText], + ); + + const handleKeyDown = useCallback( + (e: any) => { + if (e.keyCode !== 13) return; + + onNewTodo(e.target.value); + setText(''); + }, + [onNewTodo, setText], + ); + + return ( + + ); +}; diff --git a/packages/example/src/components/TodoInput/index.ts b/packages/example/src/components/TodoInput/index.ts new file mode 100644 index 0000000..a825475 --- /dev/null +++ b/packages/example/src/components/TodoInput/index.ts @@ -0,0 +1 @@ +export * from './TodoInput'; diff --git a/packages/example/src/components/TodoItem/TodoItem.tsx b/packages/example/src/components/TodoItem/TodoItem.tsx new file mode 100644 index 0000000..ceac768 --- /dev/null +++ b/packages/example/src/components/TodoItem/TodoItem.tsx @@ -0,0 +1,26 @@ +/* @jsx createElement */ + +import { createElement, type FC } from '@rkrupinski/react'; + +import type { Todo } from '../../types'; + +export type TodoItemProps = { + data: Todo; + onToggle: (todo: Todo) => void; + onDestroy: (todo: Todo) => void; +}; + +export const TodoItem: FC = ({ data, onToggle, onDestroy }) => ( +
  • +
    + onToggle(data)} + /> + +
    +
  • +); diff --git a/packages/example/src/components/TodoItem/index.ts b/packages/example/src/components/TodoItem/index.ts new file mode 100644 index 0000000..21f4aba --- /dev/null +++ b/packages/example/src/components/TodoItem/index.ts @@ -0,0 +1 @@ +export * from './TodoItem'; diff --git a/packages/example/src/components/TodoList/TodoList.tsx b/packages/example/src/components/TodoList/TodoList.tsx new file mode 100644 index 0000000..087c8e8 --- /dev/null +++ b/packages/example/src/components/TodoList/TodoList.tsx @@ -0,0 +1,25 @@ +/* @jsx createElement */ + +import { createElement, type FC } from '@rkrupinski/react'; + +import type { Todo } from '../../types'; +import { TodoItem } from '../TodoItem'; + +export type TodoListProps = { + todos: Todo[]; + onToggle: (todo: Todo) => void; + onDestroy: (todo: Todo) => void; +}; + +export const TodoList: FC = ({ todos, onToggle, onDestroy }) => ( +
      + {todos.map(todo => ( + + ))} +
    +); diff --git a/packages/example/src/components/TodoList/index.ts b/packages/example/src/components/TodoList/index.ts new file mode 100644 index 0000000..f239f43 --- /dev/null +++ b/packages/example/src/components/TodoList/index.ts @@ -0,0 +1 @@ +export * from './TodoList'; diff --git a/packages/example/src/components/TodoNav/TodoNav.tsx b/packages/example/src/components/TodoNav/TodoNav.tsx new file mode 100644 index 0000000..488cc65 --- /dev/null +++ b/packages/example/src/components/TodoNav/TodoNav.tsx @@ -0,0 +1,26 @@ +/* @jsx createElement */ + +import { createElement, type FC } from '@rkrupinski/react'; + +import { view, type View } from '../../types'; + +export type TodoNavProps = { + current: View; + onChange: (newView: View) => void; +}; + +export const TodoNav: FC = ({ current, onChange }) => ( + +); diff --git a/packages/example/src/components/TodoNav/index.ts b/packages/example/src/components/TodoNav/index.ts new file mode 100644 index 0000000..b547747 --- /dev/null +++ b/packages/example/src/components/TodoNav/index.ts @@ -0,0 +1 @@ +export * from './TodoNav'; diff --git a/packages/example/src/components/ToggleAll/ToggleAll.tsx b/packages/example/src/components/ToggleAll/ToggleAll.tsx new file mode 100644 index 0000000..5439560 --- /dev/null +++ b/packages/example/src/components/ToggleAll/ToggleAll.tsx @@ -0,0 +1,36 @@ +/* @jsx createElement */ +/* @jsxFrag Fragment */ + +import { + createElement, + Fragment, + useCallback, + type FC, +} from '@rkrupinski/react'; + +export type ToggleAllProps = { + all: boolean; + onToggle: (all: boolean) => void; +}; + +export const ToggleAll: FC = ({ all, onToggle }) => { + const handleToggle = useCallback( + (e: any) => { + onToggle(e.target.checked); + }, + [onToggle], + ); + + return ( + <> + +