Skip to content

Commit

Permalink
Merge pull request altalyst-solutions#13 from sleepinzombie/feat/add-…
Browse files Browse the repository at this point in the history
…use-persisted-state

Add usePersistedState hook
  • Loading branch information
sleepinzombie authored Dec 13, 2024
2 parents 21fee9b + 714667c commit 1dfd3b5
Show file tree
Hide file tree
Showing 21 changed files with 450 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { usePersistedState } from "@altalyst/hookify";

export const Counter = () => {
const [count, setCount] = usePersistedState<number>("counter", 0);

const increment = () => setCount((prev) => prev + 1);
const decrement = () => setCount((prev) => prev - 1);

return (
<div>
<h2>Counter</h2>
<p>Value: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { usePersistedState } from "@altalyst/hookify";

export const ThemeSwitcher = () => {
const [theme, setTheme] = usePersistedState<"light" | "dark">(
"theme",
"light"
);

const toggleTheme = () => {
setTheme((prev) => (prev === "light" ? "dark" : "light"));
};

return (
<div
style={{
background: theme === "dark" ? "#333" : "#fff",
color: theme === "dark" ? "#fff" : "#000",
padding: "1rem",
}}
>
<h2>Theme Switcher</h2>
<p>Current Theme: {theme}</p>
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { usePersistedState } from "@altalyst/hookify";
import { useState } from "react";

export const TodoList = () => {
const [todos, setTodos] = usePersistedState<string[]>("todos", []);
const [input, setInput] = useState("");

const addTodo = () => {
if (input.trim()) {
setTodos((prev) => [...prev, input]);
setInput("");
}
};

const removeTodo = (index: number) => {
setTodos((prev) => prev.filter((_, i) => i !== index));
};

return (
<div>
<h2>To-Do List</h2>
<input value={input} onChange={(e) => setInput(e.target.value)} />
<button onClick={addTodo}>Add</button>
<ul>
{todos.map((todo, index) => (
<li key={index}>
{todo} <button onClick={() => removeTodo(index)}>Remove</button>
</li>
))}
</ul>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { usePersistedState } from "@altalyst/hookify";

export const UserForm = () => {
const [formData, setFormData] = usePersistedState<{
name: string;
email: string;
}>("userForm", {
name: "",
email: "",
});

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setFormData((prev) => ({ ...prev, [name]: value }));
};

return (
<div>
<h2>User Form</h2>
<form>
<label>
Name:
<input name="name" value={formData.name} onChange={handleChange} />
</label>
<br />
<label>
Email:
<input name="email" value={formData.email} onChange={handleChange} />
</label>
</form>
</div>
);
};
15 changes: 15 additions & 0 deletions examples/basic/src/components/use-persisted-state/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Counter } from "./components/counter";
import { ThemeSwitcher } from "./components/theme-switcher";
import { TodoList } from "./components/todo-list";
import { UserForm } from "./components/user-form";

export const UsePersistedState = () => {
return (
<>
<Counter />
<ThemeSwitcher />
<TodoList />
<UserForm />
</>
);
};
76 changes: 0 additions & 76 deletions examples/basic/src/components/use-toggle-state.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useToggleState } from "@altalyst/hookify";

export const MultiToggle = () => {
const [isLightOn, toggleLight] = useToggleState(false);
const [isFanOn, toggleFan] = useToggleState(false);

return (
<div>
<h2>Multi Toggle</h2>
<button onClick={toggleLight}>
{isLightOn ? "Turn Off Light" : "Turn On Light"}
</button>
<button onClick={toggleFan}>
{isFanOn ? "Turn Off Fan" : "Turn On Fan"}
</button>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useToggleState } from "@altalyst/hookify";

export const PasswordField = () => {
const [isPasswordVisible, togglePasswordVisibility] = useToggleState(false);

return (
<div>
<h2>Password Field</h2>
<input
type={isPasswordVisible ? "text" : "password"}
placeholder="Enter your password"
/>
<button onClick={togglePasswordVisibility}>
{isPasswordVisible ? "Hide Password" : "Show Password"}
</button>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useToggleState } from "@altalyst/hookify";

export const ToggleButton = () => {
const [isActive, toggleActive] = useToggleState(false);

return (
<div>
<h2>Controlled Component: Toggle Button</h2>
<button
onClick={toggleActive}
style={{ background: isActive ? "green" : "red" }}
>
{isActive ? "Active" : "Inactive"}
</button>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useToggleState } from "@altalyst/hookify";

export const ToggleVisibility = () => {
const [isVisible, toggleVisibility] = useToggleState(false);

return (
<div>
<h2>Toggle Visibility</h2>
<button onClick={toggleVisibility}>
{isVisible ? "Hide" : "Show"} Content
</button>
{isVisible && <p>This is some toggleable content!</p>}
</div>
);
};
15 changes: 15 additions & 0 deletions examples/basic/src/components/use-toggle-state/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { MultiToggle } from "./components/multi-toggle";
import { PasswordField } from "./components/password-field";
import { ToggleButton } from "./components/toggle-button";
import { ToggleVisibility } from "./components/toggle-visibility";

export const UseToggleState = () => {
return (
<>
<MultiToggle />
<PasswordField />
<ToggleButton />
<ToggleVisibility />
</>
);
};
5 changes: 5 additions & 0 deletions examples/basic/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { HooksPage } from "./routes/hooks.tsx";
import { UseApiPage } from "./routes/hooks/use-api.tsx";
import { UseEffectAfterMountPage } from "./routes/hooks/use-effect-after-mount.tsx";
import { UseOutsideClickPage } from "./routes/hooks/use-outside-click.tsx";
import { UsePersistedStatePage } from "./routes/hooks/use-persisted-state.tsx";
import { UseToggleStatePage } from "./routes/hooks/use-toggle-state.tsx";
import { Root } from "./routes/root.tsx";

Expand Down Expand Up @@ -32,6 +33,10 @@ export const router = createBrowserRouter([
path: "/hooks/use-toggle-state",
element: <UseToggleStatePage />,
},
{
path: "/hooks/use-persisted-state",
element: <UsePersistedStatePage />,
},
],
},
]);
5 changes: 5 additions & 0 deletions examples/basic/src/routes/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ export const HooksPage = () => {
<li>
<Link to={"/hooks/use-toggle-state"}>useToggleState hook</Link>
</li>
<li>
<Link to={"/hooks/use-persisted-state"}>
usePersistedState hook
</Link>
</li>
</ul>
</nav>
<Outlet />
Expand Down
2 changes: 1 addition & 1 deletion examples/basic/src/routes/hooks/use-outside-click.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { UseOutsideClick } from "../../components/use-outside-click/use-outside-click";
import { UseOutsideClick } from "../../components/use-outside-click";

export const UseOutsideClickPage = () => {
return (
Expand Down
10 changes: 10 additions & 0 deletions examples/basic/src/routes/hooks/use-persisted-state.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { UsePersistedState } from "../../components/use-persisted-state";

export const UsePersistedStatePage = () => {
return (
<>
<h1>Demo for: usePersistedState hook</h1>
<UsePersistedState />
</>
);
};
1 change: 1 addition & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./use-api";
export * from "./use-effect-after-mount";
export * from "./use-outside-click";
export * from "./use-persisted-state";
export * from "./use-toggle-state";
2 changes: 1 addition & 1 deletion src/hooks/use-outside-click.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { useEffect } from "react";
* return <div ref={ref}>Click outside this element</div>;
* ```
*
* For a complete example, see [examples/useOutsideClick.ts](../../examples/basic/src/components/use-outside-click/use-outside-click.tsx).
* For a complete example, see [examples/useOutsideClick.ts](../../examples/basic/src/components/use-outside-click/index.tsx).
*/
export const useOutsideClick = (
ref: RefObject<HTMLElement>,
Expand Down
Loading

0 comments on commit 1dfd3b5

Please sign in to comment.