Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Changesets

Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets)

We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
11 changes: 11 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "restricted",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
70 changes: 55 additions & 15 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,77 @@ jobs:

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

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

- name: Use cached node_modules
uses: actions/cache@v1
- name: Use Node 20
uses: actions/setup-node@v4
with:
path: node_modules
key: nodeModules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
nodeModules-
node-version: 20.x
cache: pnpm

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Install dependencies
run: yarn install --frozen-lockfile
run: pnpm install --frozen-lockfile
env:
CI: true

- name: Lint
run: yarn lint
run: pnpm lint
env:
CI: true

- name: Test
run: yarn test --ci --coverage --maxWorkers=2
run: pnpm test
env:
CI: true

- name: Build
run: yarn build
run: pnpm build
env:
CI: true

react-compatibility:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
react-version: [16.14.0, 17.0.2, 18.3.1, 19.0.0]

steps:
- name: Begin compatibility checks...
uses: actions/checkout@v4

- name: Setup pnpm
uses: pnpm/action-setup@v4

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

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Install dependencies
run: pnpm install --frozen-lockfile
env:
CI: true

- name: Test React ${{ matrix.react-version }} compatibility
run: pnpm add -Dw react@${{ matrix.react-version }} react-dom@${{ matrix.react-version }} --ignore-scripts

- name: Run tests
run: pnpm test
env:
CI: true

- name: Build with matrix React version
run: pnpm build
env:
CI: true
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
*.log
.DS_Store
node_modules
.pnpm-store
.cache
dist
.parcel-cache
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pnpm lint
43 changes: 29 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<a href="https://www.npmjs.com/package/react-toggle-dark-mode" target="_blank">
<img alt="Version" src="https://img.shields.io/npm/v/react-toggle-dark-mode.svg">
</a>
<img src="https://img.shields.io/badge/node-%3E%3D10-blue.svg" />
<img src="https://img.shields.io/badge/node-%3E%3D20-blue.svg" />
<a href="#" target="_blank">
<img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg" />
</a>
Expand All @@ -17,29 +17,31 @@

> 🌃 Animated dark mode toggle as seen in blogs!

Supports React 16.14+ through 19.

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

## Prerequisites

- node >=10
- node >=20

## Installation

```shell
npm i react-toggle-dark-mode
```

or with Yarn:
or with pnpm:

```shell
yarn add react-toggle-dark-mode
pnpm add react-toggle-dark-mode
```

## Usage

```jsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client';
import { DarkModeSwitch } from 'react-toggle-dark-mode';

const App = () => {
Expand All @@ -58,6 +60,14 @@ const App = () => {
/>
);
};

const rootElement = document.getElementById('root');

if (!rootElement) {
throw new Error('Unable to find root element');
}

createRoot(rootElement).render(<App />);
```

## API
Expand All @@ -66,15 +76,20 @@ const App = () => {

#### 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 | \(checked: boolean\) => void | | Event that triggers when icon is clicked. |
| checked | boolean | false | Current icon state. |
| style | React.CSSProperties | | CSS properties object applied to the button wrapper. |
| size | number \| string | 24 | SVG size. |
| animationProperties | Partial animation properties object | defaultProperties \(see below\) | Override only the fields you want; missing fields are merged with defaults. |
| moonColor | string | white | Color of the moon. |
| sunColor | string | black | Color of the sun. |
| aria-label | string | Toggle dark mode | Accessible label for the control. Ignored when `aria-labelledby` is provided. |
| aria-labelledby | string | | Links the control to an external label element. |
| onClick | \(event: React.MouseEvent<HTMLButtonElement>\)=>void | | Optional button click handler. Call `event.preventDefault()` to prevent toggling on click. |

All valid button attributes (except `children`) are forwarded to the underlying button element.

### Default Animation Properties

Expand Down
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>
20 changes: 13 additions & 7 deletions example/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'react-app-polyfill/ie11';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DarkModeSwitch } from '../.';
import { createRoot } from 'react-dom/client';
import { DarkModeSwitch } from '../src';

function arrayN(size: number) {
return new Array(size).fill(undefined);
Expand All @@ -16,7 +15,7 @@ const App = () => {
};

const addToggle = () => {
setToggleAmount(prevValue => prevValue + 1);
setToggleAmount((prevValue) => prevValue + 1);
};

return (
Expand Down Expand Up @@ -50,17 +49,24 @@ const App = () => {
moonColor="red"
size={30}
/>
{arrayN(toggleAmount).map(() => (
{arrayN(toggleAmount).map((_, index) => (
<DarkModeSwitch
key={index}
style={{ marginBottom: '2rem' }}
checked={isDarkMode}
onChange={toggleDarkMode}
size={Math.floor(Math.random() * 60) + 1}
size={Math.floor(Math.random() * 20) + 20}
/>
))}
<button onClick={addToggle}>Add toggle</button>
</div>
);
};

ReactDOM.render(<App />, document.getElementById('root'));
const rootElement = document.getElementById('root');

if (!rootElement) {
throw new Error('Unable to find root element');
}

createRoot(rootElement).render(<App />);
15 changes: 5 additions & 10 deletions example/package.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
{
"name": "example",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "parcel index.html",
"build": "parcel build index.html"
},
"dependencies": {
"react-app-polyfill": "^1.0.0"
},
"alias": {
"react": "../node_modules/react",
"react-dom": "../node_modules/react-dom/profiling",
"scheduler/tracing": "../node_modules/scheduler/tracing-profiling"
"react": "19.0.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@types/react": "^16.9.11",
"@types/react-dom": "^16.8.4",
"parcel": "^1.12.3",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"parcel": "^2.16.4",
"typescript": "^3.4.5"
}
}
Loading
Loading