initial commit

This commit is contained in:
cupcakearmy 2020-01-06 23:17:34 +01:00
parent 4f7354c78e
commit c9c90ae5d2
11 changed files with 294 additions and 0 deletions

7
.gitignore vendored Executable file
View File

@ -0,0 +1,7 @@
# Node
node_modules
yarn.lock
# Generated
dist
.cache

2
.npmignore Executable file
View File

@ -0,0 +1,2 @@
*
!dist/*

5
.prettierrc Executable file
View File

@ -0,0 +1,5 @@
semi: false
singleQuote: true
trailingComma: es5
tabWidth: 4
printWidth: 200

21
LICENSE Executable file
View 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
View 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
View 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 })
}

View File

@ -18,8 +18,10 @@
},
"devDependencies": {
"@types/react": "^16.8",
"parcel-bundler": "^1.12.4",
"react": "^16.8",
"react-dom": "^16.8",
"stylus": "^0.54.7",
"typescript": "^3.7"
}
}

36
test/index.html Normal file
View 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
View 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
View 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
View 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"
]
}