Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Major changes: Add System Theme Mode, Color Preferences, Accessibility and more! #48

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
3637a1e
Move types to its own file
mobeigi Aug 23, 2024
ce733b1
Restructure app further
mobeigi Aug 23, 2024
a28ba26
Commit WIP: Supporting half sun style without white line artefact
mobeigi Aug 23, 2024
cae7e2e
Run prettier
mobeigi Aug 23, 2024
24b771e
Bump main package and example package to latest React, Spring and oth…
mobeigi Aug 23, 2024
c0b8a4c
Test all the different theme modes in test
mobeigi Aug 23, 2024
d5e9112
Update note & action versions in workflow
mobeigi Aug 23, 2024
5f2809a
Use more modern tsconfig
mobeigi Aug 23, 2024
b66e4e9
Use clamp to avoid overshooting, makes animation look much smoother
mobeigi Aug 23, 2024
e7103f0
Add parcel clean commands to examples
mobeigi Aug 23, 2024
69033ad
Add example showcasing customimsed system option
mobeigi Aug 23, 2024
7fc1726
Cleanup util file
mobeigi Aug 23, 2024
60a9b2e
Fix heading colors on example page
mobeigi Aug 23, 2024
efdab54
Remove leftover props
mobeigi Aug 23, 2024
499955f
Remove more comments ; restore style prop functionality
mobeigi Aug 23, 2024
6fc3dd0
Move SunAndMoonAnimatedSvg into its own component and tidy up
mobeigi Aug 23, 2024
9047e8f
Avoid using any type
mobeigi Aug 23, 2024
7022df3
Tweak animation transitions further
mobeigi Aug 23, 2024
5bf4543
Tweak example colors further
mobeigi Aug 24, 2024
e0f09ed
Remove rest prop. Undocumented and unneeded?
mobeigi Aug 24, 2024
c087142
Add option to control if system mode is enabled
mobeigi Aug 24, 2024
f185e6c
Wrap with button to make component accessible
mobeigi Aug 24, 2024
44d5211
Rename prop
mobeigi Aug 24, 2024
7bb68b9
Tweak default colors further
mobeigi Aug 24, 2024
92da0f7
Make sun on left side (common convention) and rename prop for right h…
mobeigi Aug 24, 2024
e464847
Switch ordering of styles
mobeigi Aug 27, 2024
229c2f9
Support partial color overrides
mobeigi Aug 27, 2024
65a2879
Update readme
mobeigi Aug 27, 2024
0467a0a
Update demo gif
mobeigi Aug 27, 2024
8026a55
Center demo in readme
mobeigi Aug 27, 2024
84de27b
Bump package to 2.0.0
mobeigi Aug 27, 2024
79c382f
Move spring logic into animated component
mobeigi Aug 27, 2024
881523c
Add color blending into animations
mobeigi Aug 27, 2024
883102f
Run prettier
mobeigi Aug 27, 2024
d29264b
Ensure button wraps svg perfectly
mobeigi Aug 28, 2024
42d70ac
Add ability to programatically trigger clicks via ref
mobeigi Aug 31, 2024
b32f5a8
Prettify example code
mobeigi Aug 31, 2024
bf62991
Prefer reacts useId to generate unique ids
mobeigi Aug 31, 2024
2087df6
Add aria label to button for a11y
mobeigi Oct 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ jobs:

steps:
- name: Begin CI...
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Use Node 12
uses: actions/setup-node@v1
- name: Use Node 20
uses: actions/setup-node@v4
with:
node-version: 12.x
node-version: 20

- name: Use cached node_modules
uses: actions/cache@v1
uses: actions/cache@v4
with:
path: node_modules
key: nodeModules-${{ hashFiles('**/yarn.lock') }}
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
*.log
.DS_Store
node_modules
.cache
.parcel-cache
dist
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20
159 changes: 129 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@

> 🌃 Animated dark mode toggle as seen in blogs!

<div align="center">

![Interactive sun and moon transition](./docs/demo.gif)

</div>

## Prerequisites

- node >=10
- node >=20

## Installation

Expand All @@ -37,80 +41,175 @@ yarn add react-toggle-dark-mode

## Usage

### 3-state (System, Light, Dark)

```jsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DarkModeSwitch, ThemeMode } from 'react-toggle-dark-mode';

const App = () => {
const [themeMode, setThemeMode] = React.useState(ThemeMode.System);

const cycleThemeMode = (themeMode: ThemeMode) => {
setThemeMode(themeMode);
};

return (
<DarkModeSwitch
onChange={cycleThemeMode}
isSystemThemeModeEnabled={true}
themeMode={themeMode}
size={120}
/>
);
};
```

### 2-state (Light, Dark)

```jsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DarkModeSwitch } from 'react-toggle-dark-mode';
import { DarkModeSwitch, ThemeMode } from 'react-toggle-dark-mode';

const App = () => {
const [isDarkMode, setDarkMode] = React.useState(false);
const [themeMode, setThemeMode] = React.useState(ThemeMode.Light);

const toggleDarkMode = (checked: boolean) => {
setDarkMode(checked);
const toggleThemeMode = (themeMode: ThemeMode) => {
toggleThemeMode(themeMode);
};

return (
<DarkModeSwitch
style={{ marginBottom: '2rem' }}
checked={isDarkMode}
onChange={toggleDarkMode}
onChange={toggleThemeMode}
isSystemThemeModeEnabled={false}
themeMode={themeMode}
size={120}
/>
);
};
```

### Trigger click programmatically

```jsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DarkModeSwitch, DarkModeSwitchHandle, ThemeMode } from 'react-toggle-dark-mode';

const App = () => {
const [themeMode, setThemeMode] = React.useState(ThemeMode.Light);
const darkModeSwitchRef = React.useRef<DarkModeSwitchHandle>(null);

const toggleThemeMode = (themeMode: ThemeMode) => {
toggleThemeMode(themeMode);
};

const triggerClick = () => {
if (darkModeSwitchRef.current) {
darkModeSwitchRef.current.click();
}
};

return (
<div>
<DarkModeSwitch
ref={darkModeSwitchRef}
onChange={toggleThemeMode}
isSystemThemeModeEnabled={false}
themeMode={themeMode}
size={120}
/>
<button onClick={triggerClick}>Trigger Click</button>
<div>
);
};
```

## API

### DarkModeSwitch

#### Props

| Name | Type | Default Value | Description |
| ------------------- | ---------------------------- | ------------------------------- | ----------------------------------------- |
| onChange | \(checked: boolean\) => void | | Event that triggers when icon is clicked. |
| checked | boolean | false | Current icon state. |
| style | Object | | CSS properties object. |
| size | number | 24 | SVG size. |
| animationProperties | Object | defaultProperties \(see below\) | Override default animation properties. |
| moonColor | string | white | Color of the moon. |
| sunColor | string | black | Color of the sun. |
| Name | Type | Default Value | Description |
| ------------------------- | -------------------------------- | -------------------------------------------------------- | --------------------------------------------- |
| onChange | \(themeMode: ThemeMode\) => void | | Event that triggers when icon is clicked. |
| isSystemThemeModeEnabled | boolean | true | If the system theme mode is enabled. |
| themeMode | ThemeMode | ThemeMode.System (or ThemeMode.Light if System disabled) | Current theme mode. |
| style | Object | | Custom SVG styling \(CSS properties object\). |
| size | number | 24 | SVG size. |
| colors | Partial<ColorOptions> | defaultColors \(see below\) | Override default colors. |
| animationProperties | AnimationProperties | defaultProperties \(see below\) | Override default animation properties. |

### Default Colors
```javascript
const defaultColors: ColorOptions = {
halfSunLeftFill: '#ffca00',
halfSunLeftStroke: '#ffca00',
halfSunLeftBeamStroke: '#ffe873',
halfMoonRightFill: '#44415d',
halfMoonRightStroke: '#44415d',
halfMoonRightBeamStroke: '#c0b9c7',
sunFill: '#ffd700',
sunStroke: '#444444',
sunBeamStroke: '#444444',
moonFill: '#f5f5f5',
moonStroke: '#bbbbbb',
};
```

### Default Animation Properties

```javascript
const defaultProperties = {
dark: {
const defaultProperties: AnimationProperties = {
[ThemeMode.System]: {
svg: {
transform: 'rotate(0deg)',
},
circle: {
r: 9,
r: 5,
},
mask: {
cx: '50%',
cy: '23%',
},
svg: {
transform: 'rotate(40deg)',
cx: '100%',
cy: '0%',
},
lines: {
opacity: 0,
opacity: 1,
},
},
light: {
[ThemeMode.Light]: {
svg: {
transform: 'rotate(90deg)',
},
circle: {
r: 5,
},
mask: {
cx: '100%',
cy: '0%',
},
lines: {
opacity: 1,
},
},
[ThemeMode.Dark]: {
svg: {
transform: 'rotate(90deg)',
transform: 'rotate(40deg)',
},
circle: {
r: 9,
},
mask: {
cx: '50%',
cy: '23%',
},
lines: {
opacity: 1,
opacity: 0,
},
},
springConfig: { mass: 4, tension: 250, friction: 35 },
springConfig: { mass: 4, tension: 250, friction: 35, clamp: true },
};
```

Expand Down
Binary file modified docs/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

<body style="margin: 0 ;">
<div id="root"></div>
<script src="./index.tsx"></script>
<script type="module" src="./index.tsx"></script>
</body>
</html>
Loading