mirror of
https://github.com/cupcakearmy/use-light-switch.git
synced 2024-12-21 23:46:26 +00:00
initial commit
This commit is contained in:
parent
4f7354c78e
commit
c9c90ae5d2
7
.gitignore
vendored
Executable file
7
.gitignore
vendored
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
# Node
|
||||||
|
node_modules
|
||||||
|
yarn.lock
|
||||||
|
|
||||||
|
# Generated
|
||||||
|
dist
|
||||||
|
.cache
|
2
.npmignore
Executable file
2
.npmignore
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!dist/*
|
5
.prettierrc
Executable file
5
.prettierrc
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
semi: false
|
||||||
|
singleQuote: true
|
||||||
|
trailingComma: es5
|
||||||
|
tabWidth: 4
|
||||||
|
printWidth: 200
|
21
LICENSE
Executable file
21
LICENSE
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Nicco
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
54
README.md
Executable file
54
README.md
Executable file
@ -0,0 +1,54 @@
|
|||||||
|
# use-light-switch
|
||||||
|
|
||||||
|
![Version](https://badgen.net/npm/v/use-light-switch)
|
||||||
|
![Dependencies](https://badgen.net/david/dep/cupcakearmy/use-light-switch)
|
||||||
|
![Size Badge](https://badgen.net/bundlephobia/minzip/use-light-switch)
|
||||||
|
|
||||||
|
**React hook for dark mode.**
|
||||||
|
|
||||||
|
## 🌈 Features
|
||||||
|
|
||||||
|
- Typescript compatible
|
||||||
|
- **0** Dependencies
|
||||||
|
- Tiny **~0.7kB**
|
||||||
|
- React Hooks
|
||||||
|
|
||||||
|
###### Installation
|
||||||
|
|
||||||
|
```
|
||||||
|
npm i use-light-switch
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🤔 Motivation
|
||||||
|
|
||||||
|
There was no library with typings 🤕
|
||||||
|
|
||||||
|
## 🚀 Quickstart
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import ReactDOM from 'react-dom'
|
||||||
|
import { useForm } from 'formhero'
|
||||||
|
|
||||||
|
const Form = () => {
|
||||||
|
const { field, form } = useForm({
|
||||||
|
username: '',
|
||||||
|
password: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const _submit = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault()
|
||||||
|
console.log(form)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<form onSubmit={_submit}>
|
||||||
|
<input {...field('username')} />
|
||||||
|
<input {...field('password')} />
|
||||||
|
|
||||||
|
<button type="submit">Go 🚀</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
52
lib/index.tsx
Executable file
52
lib/index.tsx
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
export enum Mode {
|
||||||
|
Light,
|
||||||
|
Dark,
|
||||||
|
Unset,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useLightSwitch = (): Mode => {
|
||||||
|
|
||||||
|
const darkMedia = window.matchMedia('(prefers-color-scheme: dark)')
|
||||||
|
const lightMedia = window.matchMedia('(prefers-color-scheme: light)')
|
||||||
|
|
||||||
|
const [dark, setDark] = useState(darkMedia.matches)
|
||||||
|
const [light, setLight] = useState(lightMedia.matches)
|
||||||
|
const unsed = !dark && !light
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const darkFn = (e: MediaQueryListEvent) => { setDark(e.matches) }
|
||||||
|
const lightFn = (e: MediaQueryListEvent) => { setLight(e.matches) }
|
||||||
|
darkMedia.addListener(darkFn)
|
||||||
|
lightMedia.addListener(lightFn)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
darkMedia.removeListener(darkFn)
|
||||||
|
lightMedia.removeListener(lightFn)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return unsed
|
||||||
|
? Mode.Unset
|
||||||
|
: dark
|
||||||
|
? Mode.Dark
|
||||||
|
: Mode.Light
|
||||||
|
}
|
||||||
|
|
||||||
|
export const modeSelector = <A, B, C>(mode: Mode, { light, dark, unset }: { light?: A, dark?: B, unset?: C }): A | B | C | undefined => {
|
||||||
|
switch (mode) {
|
||||||
|
case Mode.Light:
|
||||||
|
return light
|
||||||
|
case Mode.Dark:
|
||||||
|
return dark
|
||||||
|
case Mode.Unset:
|
||||||
|
return unset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useModeSelector = <A, B, C>({ light, dark, unset }: { light?: A, dark?: B, unset?: C }): A | B | C | undefined => {
|
||||||
|
const mode = useLightSwitch()
|
||||||
|
|
||||||
|
return modeSelector<A, B, C>(mode, { light, dark, unset })
|
||||||
|
}
|
@ -18,8 +18,10 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^16.8",
|
"@types/react": "^16.8",
|
||||||
|
"parcel-bundler": "^1.12.4",
|
||||||
"react": "^16.8",
|
"react": "^16.8",
|
||||||
"react-dom": "^16.8",
|
"react-dom": "^16.8",
|
||||||
|
"stylus": "^0.54.7",
|
||||||
"typescript": "^3.7"
|
"typescript": "^3.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
test/index.html
Normal file
36
test/index.html
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<link href="./index.styl" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h2>CSS</h2>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Light</th>
|
||||||
|
<th>Default</th>
|
||||||
|
<th>Dark</th>
|
||||||
|
</tr>
|
||||||
|
<tr class="up">
|
||||||
|
<td class="light">Up</td>
|
||||||
|
<td>Up</td>
|
||||||
|
<td class="dark">Up</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="down">
|
||||||
|
<td class="light">Down</td>
|
||||||
|
<td>Down</td>
|
||||||
|
<td class="dark">Down</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>React</h2>
|
||||||
|
<div id="root">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<script src="./index.tsx"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
38
test/index.styl
Normal file
38
test/index.styl
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
$white = #ffffff
|
||||||
|
$light = #dddddd
|
||||||
|
$dark = #444444
|
||||||
|
$black = #000000
|
||||||
|
|
||||||
|
table
|
||||||
|
text-align: center
|
||||||
|
|
||||||
|
.up
|
||||||
|
background: $light
|
||||||
|
color: $black
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark)
|
||||||
|
.dark
|
||||||
|
background: $dark
|
||||||
|
color: $white
|
||||||
|
@media (prefers-color-scheme: light)
|
||||||
|
.light
|
||||||
|
background: $white
|
||||||
|
color: $black
|
||||||
|
|
||||||
|
.down
|
||||||
|
background: $dark
|
||||||
|
color: $white
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark)
|
||||||
|
.dark
|
||||||
|
background: $black
|
||||||
|
color: $white
|
||||||
|
@media (prefers-color-scheme: light)
|
||||||
|
.light
|
||||||
|
background: $light
|
||||||
|
color: $black
|
||||||
|
|
||||||
|
td,th
|
||||||
|
padding: 1em 2em
|
||||||
|
border: 1px solid blue
|
||||||
|
|
52
test/index.tsx
Normal file
52
test/index.tsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import ReactDOM from 'react-dom'
|
||||||
|
import { Mode, useLightSwitch, modeSelector, useModeSelector } from '../'
|
||||||
|
|
||||||
|
|
||||||
|
const Simple: React.FC = () => {
|
||||||
|
const mode = useLightSwitch()
|
||||||
|
|
||||||
|
let color = 'green'
|
||||||
|
let name = 'Light'
|
||||||
|
if (mode === Mode.Dark) {
|
||||||
|
color = 'red'
|
||||||
|
name = 'Dark'
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div>
|
||||||
|
<h3>Simple</h3>
|
||||||
|
<div style={{
|
||||||
|
padding: '1em 2em',
|
||||||
|
backgroundColor: color
|
||||||
|
}}>
|
||||||
|
{name}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const WithSelector: React.FC = () => {
|
||||||
|
const selected = useModeSelector({
|
||||||
|
light: { color: 'green', name: 'Light' },
|
||||||
|
dark: { color: 'red', name: 'Dark' },
|
||||||
|
unset: { color: 'blue', name: 'Unset' },
|
||||||
|
})
|
||||||
|
|
||||||
|
return <div>
|
||||||
|
<h3>Selector</h3>
|
||||||
|
<div style={{
|
||||||
|
padding: '1em 2em',
|
||||||
|
backgroundColor: selected.color
|
||||||
|
}}>
|
||||||
|
{selected.name}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const App: React.FC = () => {
|
||||||
|
return <div>
|
||||||
|
<Simple />
|
||||||
|
<WithSelector />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
ReactDOM.render(<App />, window.document.getElementById('root'))
|
25
tsconfig.json
Executable file
25
tsconfig.json
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2017",
|
||||||
|
"module": "commonjs",
|
||||||
|
"jsx": "react",
|
||||||
|
"outDir": "./dist",
|
||||||
|
"declaration": true,
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"strictFunctionTypes": true,
|
||||||
|
"strictBindCallApply": true,
|
||||||
|
"strictPropertyInitialization": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"alwaysStrict": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"./lib"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user