mirror of
https://github.com/Steffo99/bluelib.git
synced 2024-12-22 19:44:21 +00:00
do things very useful im sleepy
This commit is contained in:
parent
9fe371df81
commit
41c0a458ce
6 changed files with 157 additions and 91 deletions
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@steffo/bluelib-react",
|
"name": "@steffo/bluelib-react",
|
||||||
"version": "4.3.0",
|
"version": "4.4.0",
|
||||||
"description": "React bindings for Bluelib",
|
"description": "React bindings for Bluelib",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
|
|
|
@ -17,7 +17,7 @@ export interface BaseElementProps extends React.HTMLProps<any> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function BaseElement({kind = "div", bluelibClassNames, disabled = false, builtinColor, customColor, ...props}: BaseElementProps): JSX.Element {
|
export const BaseElement = React.forwardRef(({kind = "div", bluelibClassNames, disabled = false, builtinColor, customColor, ...props}: BaseElementProps, ref): JSX.Element => {
|
||||||
// Set the Bluelib color
|
// Set the Bluelib color
|
||||||
if(customColor) {
|
if(customColor) {
|
||||||
props.style = {...props.style, ...Colors.colorToBluelibStyle("color", customColor)}
|
props.style = {...props.style, ...Colors.colorToBluelibStyle("color", customColor)}
|
||||||
|
@ -36,5 +36,8 @@ export function BaseElement({kind = "div", bluelibClassNames, disabled = false,
|
||||||
bluelibClassNames = BluelibMapper.rootToModule(bluelibClassNames)
|
bluelibClassNames = BluelibMapper.rootToModule(bluelibClassNames)
|
||||||
props.className = mergeClassNames(props.className, bluelibClassNames)
|
props.className = mergeClassNames(props.className, bluelibClassNames)
|
||||||
|
|
||||||
|
// Set the ref on the child element
|
||||||
|
props.ref = ref
|
||||||
|
|
||||||
return React.createElement(kind, props)
|
return React.createElement(kind, props)
|
||||||
}
|
})
|
||||||
|
|
|
@ -1,101 +1,52 @@
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import * as ReactDOM from "react-dom"
|
|
||||||
import {BluelibTheme} from "../types"
|
|
||||||
import * as Types from "../types"
|
import * as Types from "../types"
|
||||||
import * as Colors from "../utils/Colors"
|
import * as Splitter from "../utils/Splitter"
|
||||||
import Color from "color"
|
|
||||||
import mergeClassNames from "classnames"
|
|
||||||
import {BaseElement} from "./BaseElement"
|
import {BaseElement} from "./BaseElement"
|
||||||
import PaperTheme from "../bluelib/src/targets/paper.module.css"
|
import {useBluelib, UseBluelibOptions} from "../hooks/useBluelib"
|
||||||
import RoyalBlueTheme from "../bluelib/src/targets/royalblue.module.css"
|
|
||||||
import HackerTheme from "../bluelib/src/targets/hacker.module.css"
|
|
||||||
import SophonTheme from "../bluelib/src/targets/sophon.module.css"
|
|
||||||
import GestioneAmberTheme from "../bluelib/src/targets/amber.module.css"
|
|
||||||
|
|
||||||
|
|
||||||
const BuiltinThemes = {
|
export interface BluelibProps extends Types.BluelibHTMLProps<HTMLDivElement>, UseBluelibOptions {}
|
||||||
"paper": PaperTheme,
|
|
||||||
"royalblue": RoyalBlueTheme,
|
|
||||||
"hacker": HackerTheme,
|
|
||||||
"sophon": SophonTheme,
|
|
||||||
"amber": GestioneAmberTheme,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export interface BluelibProps extends Types.BluelibHTMLProps<HTMLDivElement> {
|
export const Bluelib = (props: BluelibProps): JSX.Element => {
|
||||||
theme: BluelibTheme,
|
|
||||||
|
|
||||||
backgroundColor?: typeof Color,
|
const [useBluelibOptions, baseElementProps] = Splitter.splitInTwo(props, [
|
||||||
foregroundColor?: typeof Color,
|
"theme",
|
||||||
accentColor?: typeof Color,
|
"backgroundColor",
|
||||||
linkColor?: typeof Color,
|
"foregroundColor",
|
||||||
brokenColor?: typeof Color,
|
"accentColor",
|
||||||
visitedColor?: typeof Color,
|
"linkColor",
|
||||||
downloadColor?: typeof Color,
|
"brokenColor",
|
||||||
redColor?: typeof Color,
|
"visitedColor",
|
||||||
orangeColor?: typeof Color,
|
"downloadColor",
|
||||||
yellowColor?: typeof Color,
|
"redColor",
|
||||||
limeColor?: typeof Color,
|
"orangeColor",
|
||||||
cyanColor?: typeof Color,
|
"yellowColor",
|
||||||
blueColor?: typeof Color,
|
"limeColor",
|
||||||
magentaColor?: typeof Color,
|
"cyanColor",
|
||||||
grayColor?: typeof Color,
|
"blueColor",
|
||||||
polarity?: number,
|
"magentaColor",
|
||||||
}
|
"grayColor",
|
||||||
|
"polarity",
|
||||||
|
])
|
||||||
|
|
||||||
|
const ref = React.useRef<HTMLDivElement>(null)
|
||||||
export function Bluelib({
|
const element = React.useMemo(
|
||||||
theme,
|
() => (
|
||||||
backgroundColor,
|
|
||||||
foregroundColor,
|
|
||||||
accentColor,
|
|
||||||
linkColor,
|
|
||||||
brokenColor,
|
|
||||||
visitedColor,
|
|
||||||
downloadColor,
|
|
||||||
redColor,
|
|
||||||
orangeColor,
|
|
||||||
yellowColor,
|
|
||||||
limeColor,
|
|
||||||
cyanColor,
|
|
||||||
blueColor,
|
|
||||||
magentaColor,
|
|
||||||
grayColor,
|
|
||||||
polarity,
|
|
||||||
...props
|
|
||||||
}: BluelibProps): JSX.Element {
|
|
||||||
|
|
||||||
props.className = mergeClassNames(props.className, BuiltinThemes[theme]["bluelib"])
|
|
||||||
|
|
||||||
if(backgroundColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("background", backgroundColor)}
|
|
||||||
if(foregroundColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("foreground", foregroundColor)}
|
|
||||||
if(accentColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("accent", accentColor)}
|
|
||||||
if(linkColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("link", linkColor)}
|
|
||||||
if(brokenColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("broken", brokenColor)}
|
|
||||||
if(visitedColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("visited", visitedColor)}
|
|
||||||
if(downloadColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("download", downloadColor)}
|
|
||||||
if(redColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("red", redColor)}
|
|
||||||
if(orangeColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("orange", orangeColor)}
|
|
||||||
if(yellowColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("yellow", yellowColor)}
|
|
||||||
if(limeColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("lime", limeColor)}
|
|
||||||
if(cyanColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("cyan", cyanColor)}
|
|
||||||
if(blueColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("blue", blueColor)}
|
|
||||||
if(magentaColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("magenta", magentaColor)}
|
|
||||||
if(grayColor) props.style = {...props.style, ...Colors.colorToBluelibStyle("gray", grayColor)}
|
|
||||||
if(polarity) {
|
|
||||||
// @ts-ignore
|
|
||||||
props.style["--bluelib-polarity"] = polarity
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<BaseElement
|
<BaseElement
|
||||||
|
ref={ref}
|
||||||
kind={"div"}
|
kind={"div"}
|
||||||
bluelibClassNames={"bluelib"}
|
bluelibClassNames={"bluelib"}
|
||||||
{...props}
|
{...baseElementProps}
|
||||||
/>
|
/>
|
||||||
|
),
|
||||||
|
[ref, baseElementProps]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
useBluelib(ref, useBluelibOptions)
|
||||||
|
|
||||||
|
return element
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Bluelib.Element = BaseElement
|
Bluelib.Element = BaseElement
|
||||||
|
|
||||||
|
|
83
src/hooks/useBluelib.tsx
Normal file
83
src/hooks/useBluelib.tsx
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
import * as React from "react"
|
||||||
|
import { BluelibTheme } from "../types"
|
||||||
|
import mergeClassNames from "classnames"
|
||||||
|
import Color from "color";
|
||||||
|
import * as Colors from "../utils/Colors"
|
||||||
|
|
||||||
|
import PaperTheme from "../bluelib/src/targets/paper.module.css"
|
||||||
|
import RoyalBlueTheme from "../bluelib/src/targets/royalblue.module.css"
|
||||||
|
import HackerTheme from "../bluelib/src/targets/hacker.module.css"
|
||||||
|
import SophonTheme from "../bluelib/src/targets/sophon.module.css"
|
||||||
|
import GestioneAmberTheme from "../bluelib/src/targets/amber.module.css"
|
||||||
|
|
||||||
|
|
||||||
|
const BuiltinThemes = {
|
||||||
|
"paper": PaperTheme,
|
||||||
|
"royalblue": RoyalBlueTheme,
|
||||||
|
"hacker": HackerTheme,
|
||||||
|
"sophon": SophonTheme,
|
||||||
|
"amber": GestioneAmberTheme,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface UseBluelibOptions {
|
||||||
|
theme?: BluelibTheme,
|
||||||
|
backgroundColor?: typeof Color,
|
||||||
|
foregroundColor?: typeof Color,
|
||||||
|
accentColor?: typeof Color,
|
||||||
|
linkColor?: typeof Color,
|
||||||
|
brokenColor?: typeof Color,
|
||||||
|
visitedColor?: typeof Color,
|
||||||
|
downloadColor?: typeof Color,
|
||||||
|
redColor?: typeof Color,
|
||||||
|
orangeColor?: typeof Color,
|
||||||
|
yellowColor?: typeof Color,
|
||||||
|
limeColor?: typeof Color,
|
||||||
|
cyanColor?: typeof Color,
|
||||||
|
blueColor?: typeof Color,
|
||||||
|
magentaColor?: typeof Color,
|
||||||
|
grayColor?: typeof Color,
|
||||||
|
polarity?: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function useBluelib(ref: React.RefObject<HTMLElement>, options: UseBluelibOptions) {
|
||||||
|
React.useEffect(
|
||||||
|
() => {
|
||||||
|
const target = ref.current
|
||||||
|
if(!target) return
|
||||||
|
|
||||||
|
let extraClassName: string = ""
|
||||||
|
if(options.theme) extraClassName = BuiltinThemes[options.theme]["bluelib"]
|
||||||
|
|
||||||
|
let extraStyle: {[_: string]: number} = {}
|
||||||
|
if(options.backgroundColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("background", options.backgroundColor)}
|
||||||
|
if(options.foregroundColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("foreground", options.foregroundColor)}
|
||||||
|
if(options.accentColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("accent", options.accentColor)}
|
||||||
|
if(options.linkColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("link", options.linkColor)}
|
||||||
|
if(options.brokenColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("broken", options.brokenColor)}
|
||||||
|
if(options.visitedColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("visited", options.visitedColor)}
|
||||||
|
if(options.downloadColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("download", options.downloadColor)}
|
||||||
|
if(options.redColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("red", options.redColor)}
|
||||||
|
if(options.orangeColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("orange", options.orangeColor)}
|
||||||
|
if(options.yellowColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("yellow", options.yellowColor)}
|
||||||
|
if(options.limeColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("lime", options.limeColor)}
|
||||||
|
if(options.cyanColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("cyan", options.cyanColor)}
|
||||||
|
if(options.blueColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("blue", options.blueColor)}
|
||||||
|
if(options.magentaColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("magenta", options.magentaColor)}
|
||||||
|
if(options.grayColor) extraStyle = {...extraStyle, ...Colors.colorToBluelibStyle("gray", options.grayColor)}
|
||||||
|
|
||||||
|
target.classList.forEach((className) => {
|
||||||
|
if(Object.values(BuiltinThemes).map(a => a["bluelib"]).includes(className)) {
|
||||||
|
target.classList.remove(className)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
target.classList.add(extraClassName)
|
||||||
|
|
||||||
|
Object.entries(extraStyle).forEach(([k, v]) => {
|
||||||
|
target.style.setProperty(k, v.toString(), "")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
[ref, options]
|
||||||
|
)
|
||||||
|
}
|
|
@ -59,3 +59,4 @@ export {Bluelib as default} from "./components/Bluelib"
|
||||||
|
|
||||||
export {usePromise} from "./hooks/usePromise"
|
export {usePromise} from "./hooks/usePromise"
|
||||||
export {useFormState} from "./hooks/useFormState"
|
export {useFormState} from "./hooks/useFormState"
|
||||||
|
export {useBluelib} from "./hooks/useBluelib"
|
||||||
|
|
28
src/utils/Splitter.js
Normal file
28
src/utils/Splitter.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// FIXME: Converting this to TypeScript breaks the transpiler. Why? I have absolutely no idea. JS is a mess.
|
||||||
|
|
||||||
|
export function split(obj, ...keyGroups) {
|
||||||
|
const results = keyGroups.map((_) => {return {}})
|
||||||
|
const other = {}
|
||||||
|
|
||||||
|
Object.entries(obj).forEach(([k, v]) => {
|
||||||
|
let matched = false
|
||||||
|
keyGroups.forEach((keyGroup, index) => {
|
||||||
|
if(keyGroup.includes(k)) {
|
||||||
|
results[index][k] = v
|
||||||
|
matched = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if(!matched) {
|
||||||
|
other[k] = v
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
results.push(other)
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function splitInTwo (obj, keyGroup) {
|
||||||
|
return split(obj, keyGroup)
|
||||||
|
}
|
Loading…
Reference in a new issue