dialogs sorta work now
This commit is contained in:
+3
-2
@@ -19,7 +19,7 @@
|
||||
"node-sass": "4.14.1",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-modal": "^3.13.1",
|
||||
"react-modal": "^3.14.2",
|
||||
"react-scripts": "4.0.3",
|
||||
"react-semantic-ui-range": "^0.7.1",
|
||||
"typescript": "^4.1.2",
|
||||
@@ -50,6 +50,7 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/hookrouter": "^2.2.5"
|
||||
"@types/hookrouter": "^2.2.5",
|
||||
"@types/react-modal": "^3.12.0"
|
||||
}
|
||||
}
|
||||
|
||||
+36
-13
@@ -1,16 +1,24 @@
|
||||
import React from 'react';
|
||||
import React, {useContext, useLayoutEffect} from 'react';
|
||||
import {HookRouter, navigate, usePath, useRoutes} from "hookrouter";
|
||||
import {Tabs} from "./primitives/Layout";
|
||||
import {HSColorPicker} from "./primitives/Forms";
|
||||
import {Dialog, Page, Tabs} from "./primitives/Layout";
|
||||
import {IconElement} from "./primitives/Elements";
|
||||
import SettingsPage from "./pages/SettingsPage";
|
||||
import {LuciferIcon} from "./models/Icons";
|
||||
import ReactModal from "react-modal";
|
||||
import DialogContext, {DialogContextProvider, makeDialog} from "./contexts/DialogContext";
|
||||
|
||||
const routeObj: HookRouter.RouteObject = {
|
||||
"/": () => (
|
||||
<div>
|
||||
<HSColorPicker h={30} s={1} onChange={() => void (0)}/>
|
||||
</div>
|
||||
<Page>
|
||||
<Dialog title="Testdialog" buttons={[
|
||||
{icon: LuciferIcon.Check, text: "Lagre"},
|
||||
{icon: LuciferIcon.Cross, text: "Avbryt"},
|
||||
]}>
|
||||
Test
|
||||
</Dialog>
|
||||
<h1> </h1>
|
||||
<h1>Enheter</h1>
|
||||
</Page>
|
||||
),
|
||||
"/devices": () => (
|
||||
<div>
|
||||
@@ -19,12 +27,13 @@ const routeObj: HookRouter.RouteObject = {
|
||||
<IconElement icon={LuciferIcon.Bulb} caption="Kelvin 2k" color={{kelvin: 2000}}/>
|
||||
<IconElement icon={LuciferIcon.BulbGroup} caption="Kelvin 3k" color={{kelvin: 3000}}/>
|
||||
<IconElement icon={LuciferIcon.Bridge} caption="Kelvin 4k" color={{kelvin: 4000}}/>
|
||||
<IconElement caption="Kelvin 5k" color={{kelvin: 5000}}/>
|
||||
<IconElement caption="Kelvin 6k" color={{kelvin: 6000}}/>
|
||||
<IconElement caption="Kelvin 7k" color={{kelvin: 7000}}/>
|
||||
<IconElement caption="Kelvin 8k" color={{kelvin: 8000}}/>
|
||||
<IconElement caption="Kelvin 9k" color={{kelvin: 9000}}/>
|
||||
<IconElement caption="Kelvin 10k" color={{kelvin: 10000}}/>
|
||||
<IconElement icon={LuciferIcon.Cog} caption="Kelvin 5k" color={{kelvin: 5000}}/>
|
||||
<IconElement icon={LuciferIcon.Switch} caption="Kelvin 6k" color={{kelvin: 6000}}/>
|
||||
<IconElement icon={LuciferIcon.Triangle} caption="Kelvin 7k" color={{kelvin: 7000}}/>
|
||||
<IconElement icon={LuciferIcon.HexagonGroup} caption="Kelvin 8k" color={{kelvin: 8000}}/>
|
||||
<IconElement icon={LuciferIcon.Router} caption="Kelvin 9k" color={{kelvin: 9000}}/>
|
||||
<IconElement icon={LuciferIcon.Check} caption="Kelvin 10k" color={{kelvin: 10000}}/>
|
||||
<IconElement icon={LuciferIcon.Cross} caption="Kelvin 10k" color={{kelvin: 10000}}/>
|
||||
<IconElement caption="Mer" color="hs-gradient"/>
|
||||
<IconElement caption="Mer" color="k-gradient"/>
|
||||
</div>
|
||||
@@ -37,8 +46,21 @@ const routeList = ["/", "/devices", "/settings"];
|
||||
const tabNames = ["Lucifer", "Enheter", "Oppsett"];
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<DialogContextProvider>
|
||||
<AppInContext/>
|
||||
</DialogContextProvider>
|
||||
);
|
||||
}
|
||||
|
||||
function AppInContext() {
|
||||
const route = useRoutes(routeObj);
|
||||
const path = usePath();
|
||||
const {dialog} = useContext(DialogContext);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
ReactModal.setAppElement("#root");
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
@@ -47,7 +69,8 @@ function App() {
|
||||
onChange={i => navigate(routeList[i])}
|
||||
large boldIndex={0}
|
||||
/>
|
||||
{route || <div>B</div>}
|
||||
{route || <Page>404</Page>}
|
||||
{makeDialog(dialog)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import React, {createContext, useState} from "react";
|
||||
import {DialogConfig, DialogType} from "../models/Dialog";
|
||||
import {unimplemented} from "../helpers/misc";
|
||||
|
||||
interface DialogContextValue {
|
||||
dialog: DialogConfig,
|
||||
setDialog: (dialog: DialogConfig) => void,
|
||||
}
|
||||
|
||||
const DialogContext = createContext<DialogContextValue>({
|
||||
dialog: {type: DialogType.None},
|
||||
setDialog: unimplemented,
|
||||
});
|
||||
|
||||
export const DialogContextProvider: React.FC = ({children}) => {
|
||||
const [dialog, setDialog] = useState<DialogConfig>({type: DialogType.None});
|
||||
|
||||
return (
|
||||
<DialogContext.Provider value={{dialog, setDialog}}>
|
||||
{children}
|
||||
</DialogContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export function makeDialog(dialog: DialogConfig) {
|
||||
switch (dialog.type) {
|
||||
case DialogType.None:
|
||||
return undefined;
|
||||
case DialogType.AddColor:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export default DialogContext;
|
||||
@@ -0,0 +1,9 @@
|
||||
export enum DialogType {
|
||||
None,
|
||||
AddColor,
|
||||
}
|
||||
|
||||
export type DialogConfig =
|
||||
| { type: DialogType.None }
|
||||
| { type: DialogType.AddColor }
|
||||
;
|
||||
@@ -1,26 +1,49 @@
|
||||
import bridgeIcon from "@iconify-icons/mdi/bridge";
|
||||
import checkIcon from "@iconify-icons/mdi/check";
|
||||
import crossIcon from "@iconify-icons/mdi/window-close";
|
||||
import cogIcon from "@iconify-icons/mdi/cog";
|
||||
import hexagonIcon from "@iconify-icons/mdi/hexagon";
|
||||
import hexagonGroupIcon from "@iconify-icons/mdi/hexagon-multiple";
|
||||
import lightBulbIcon from "@iconify-icons/mdi/lightbulb";
|
||||
import lightBulbGroupIcon from "@iconify-icons/mdi/lightbulb-group";
|
||||
import lightSwitchIcon from '@iconify-icons/mdi/light-switch';
|
||||
import routerIcon from "@iconify-icons/mdi/router-wireless";
|
||||
import squareIcon from "@iconify-icons/mdi/square-rounded";
|
||||
import triangleIcon from "@iconify-icons/mdi/triangle";
|
||||
|
||||
|
||||
|
||||
// To add a new icon, follow the instructions on this page:
|
||||
// https://iconify.design/icon-sets/mdi/
|
||||
|
||||
export enum LuciferIcon {
|
||||
Bridge = "Bridge",
|
||||
Check = "Check",
|
||||
Cog = "Cog",
|
||||
Cross = "Cross",
|
||||
Bulb = "Bulb",
|
||||
BulbGroup = "BulbGroup",
|
||||
Hexagon = "Hexagon",
|
||||
HexagonGroup = "HexagonGroup",
|
||||
Router = "Router",
|
||||
Square = "Square",
|
||||
Switch = "Switch",
|
||||
Triangle = "Triangle",
|
||||
}
|
||||
|
||||
const iconMap = {
|
||||
[LuciferIcon.Bridge]: bridgeIcon,
|
||||
[LuciferIcon.Check]: checkIcon,
|
||||
[LuciferIcon.Cog]: cogIcon,
|
||||
[LuciferIcon.Cross]: crossIcon,
|
||||
[LuciferIcon.Bulb]: lightBulbIcon,
|
||||
[LuciferIcon.BulbGroup]: lightBulbGroupIcon,
|
||||
[LuciferIcon.Hexagon]: hexagonIcon,
|
||||
[LuciferIcon.HexagonGroup]: hexagonGroupIcon,
|
||||
[LuciferIcon.Router]: routerIcon,
|
||||
[LuciferIcon.Square]: squareIcon,
|
||||
[LuciferIcon.Switch]: lightSwitchIcon,
|
||||
[LuciferIcon.Triangle]: triangleIcon,
|
||||
}
|
||||
|
||||
export function toIconify(icon: LuciferIcon): object {
|
||||
|
||||
@@ -2,10 +2,9 @@ import React, {useContext, useEffect} from "react";
|
||||
import {Page} from "../primitives/Layout";
|
||||
import DataContext from "../contexts/DataContext";
|
||||
import {IconElement} from "../primitives/Elements";
|
||||
import {addColorPreset} from "../actions/ColorPresets";
|
||||
|
||||
const SettingsPage: React.FC = () => {
|
||||
const {colorPresets, refresh} = useContext(DataContext);
|
||||
const {colorPresets} = useContext(DataContext);
|
||||
|
||||
useEffect(() => {
|
||||
}, []);
|
||||
|
||||
@@ -12,13 +12,12 @@ function Element({children}: React.PropsWithChildren<{}>) {
|
||||
)
|
||||
}
|
||||
|
||||
interface ColorElementProps {
|
||||
caption: string
|
||||
interface IconProps {
|
||||
icon?: LuciferIcon
|
||||
color?: ColorValue | "hs-gradient" | "k-gradient"
|
||||
}
|
||||
|
||||
export function IconElement({caption, color, icon}: ColorElementProps) {
|
||||
export function IconBlock({icon, color}: IconProps) {
|
||||
const style: CSSProperties = useMemo(() => {
|
||||
const s: CSSProperties = {
|
||||
backgroundClip: "text",
|
||||
@@ -44,9 +43,22 @@ export function IconElement({caption, color, icon}: ColorElementProps) {
|
||||
return s;
|
||||
}, [color]);
|
||||
|
||||
return (
|
||||
<Icon icon={toIconify(icon || LuciferIcon.Square)}
|
||||
className="ColorElement-block"
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
interface IconElementProps extends IconProps {
|
||||
caption: string
|
||||
}
|
||||
|
||||
export function IconElement({caption, color, icon}: IconElementProps) {
|
||||
return (
|
||||
<Element>
|
||||
<Icon icon={toIconify(icon || LuciferIcon.Square)} className="ColorElement-block" style={style}/>
|
||||
<IconBlock icon={icon} color={color}/>
|
||||
{caption}
|
||||
</Element>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@import "../res/colors"
|
||||
|
||||
.Tabs-container
|
||||
background-color: $color-foreground-dark
|
||||
background-color: $color-background-elevated
|
||||
|
||||
&.Tabs-large
|
||||
text-align: center
|
||||
@@ -23,3 +23,68 @@
|
||||
.Page
|
||||
max-width: 800px
|
||||
margin: 0.25em auto
|
||||
|
||||
|
||||
.Dialog-overlay
|
||||
background-color: rgba(0, 0, 0, 0.5)
|
||||
position: fixed
|
||||
left: 0
|
||||
top: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
overflow-y: scroll
|
||||
|
||||
.Dialog-main
|
||||
max-width: 640px
|
||||
margin: 4em auto
|
||||
// background-color: #202020
|
||||
color: #ddd
|
||||
outline: none
|
||||
box-shadow: 5px 10px 20px rgba(0, 0, 0, 0.5)
|
||||
|
||||
.Card
|
||||
margin: 0
|
||||
|
||||
.Dialog-title
|
||||
font-weight: 800
|
||||
font-size: 200%
|
||||
text-align: center
|
||||
padding: 0.25em 0.5ch
|
||||
|
||||
.Dialog-body
|
||||
margin-bottom: 0
|
||||
|
||||
.Dialog-footer
|
||||
border-top: solid 1px #000
|
||||
|
||||
.Dialog-container
|
||||
background-color: $color-background
|
||||
|
||||
.Dialog-header
|
||||
font-size: 140%
|
||||
font-weight: bold
|
||||
text-align: center
|
||||
padding: 0.1em 0
|
||||
background-color: $color-background-elevated
|
||||
|
||||
.Dialog-footer
|
||||
display: flex
|
||||
flex-direction: row
|
||||
|
||||
button
|
||||
flex-grow: 4
|
||||
text-align: center
|
||||
font: inherit
|
||||
padding: 0.5em 1.5ch
|
||||
background-color: $color-background-elevated
|
||||
color: $color-foreground
|
||||
border: none
|
||||
cursor: pointer
|
||||
|
||||
&:hover, &:active
|
||||
background-color: $color-background-elevated2
|
||||
color: $color-foreground-elevated
|
||||
|
||||
|
||||
&:not(:last-of-type)
|
||||
border-right: solid 1px #000
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import React, {PropsWithChildren, useCallback, useEffect} from "react";
|
||||
import ReactModal from "react-modal";
|
||||
import "./Layout.sass";
|
||||
import {LuciferIcon} from "../models/Icons";
|
||||
import {IconBlock} from "./Elements";
|
||||
|
||||
interface TabsProps {
|
||||
tabNames: string[]
|
||||
@@ -54,7 +57,7 @@ interface PageProps {
|
||||
export function Page({title, children}: PropsWithChildren<PageProps>) {
|
||||
useEffect(() => {
|
||||
window.document.title = title ? `${title} - Lucifer` : "Lucifer";
|
||||
}, []);
|
||||
}, [title]);
|
||||
|
||||
return (
|
||||
<div className="Page">
|
||||
@@ -67,13 +70,35 @@ interface DialogProps {
|
||||
title: string
|
||||
buttons?: {
|
||||
text: string
|
||||
icon: LuciferIcon
|
||||
onClick?: (() => void)
|
||||
}[]
|
||||
loading?: boolean
|
||||
}
|
||||
|
||||
export function Dialog({}: PropsWithChildren<DialogProps>) {
|
||||
export function Dialog({title, buttons, children}: PropsWithChildren<DialogProps>) {
|
||||
|
||||
|
||||
return undefined;
|
||||
return (
|
||||
<ReactModal isOpen={true}
|
||||
className="Dialog-main"
|
||||
overlayClassName="Dialog-overlay"
|
||||
>
|
||||
<div className="Dialog-container">
|
||||
<div className="Dialog-header">
|
||||
{title}
|
||||
</div>
|
||||
{children}
|
||||
<div className="Dialog-footer">
|
||||
{buttons?.map(b => (
|
||||
<button key={b.text}>
|
||||
<IconBlock icon={b.icon}/>
|
||||
{" "}
|
||||
{b.text}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</ReactModal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
$color-background: #111
|
||||
$color-background-elevated: #222
|
||||
$color-background-elevated2: #333
|
||||
$color-foreground: rgb(204, 204, 204)
|
||||
$color-foreground-elevated: #FFF
|
||||
$color-foreground-dark: rgba(238, 238, 238, 0.05)
|
||||
|
||||
|
||||
body, html
|
||||
background-color: $color-background
|
||||
color: $color-foreground
|
||||
|
||||
+13
-6
@@ -1829,6 +1829,13 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-modal@^3.12.0":
|
||||
version "3.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-modal/-/react-modal-3.12.0.tgz#91fa86a76fd7fc57e36d2cf9b76efe5735a855a1"
|
||||
integrity sha512-UnHu/YO73NZLwqFpju/c0tqiswR0UHIfeO16rkfLVJUIMfQsl7X0CBm99H5XXgBMe/PgtQ/Rkud72iuRBr1TeA==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^17.0.0":
|
||||
version "17.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.6.tgz#0ec564566302c562bf497d73219797a5e0297013"
|
||||
@@ -9193,7 +9200,7 @@ prompts@2.4.0, prompts@^2.0.1:
|
||||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.5"
|
||||
|
||||
prop-types@^15.5.10, prop-types@^15.7.2:
|
||||
prop-types@^15.7.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
@@ -9433,13 +9440,13 @@ react-lifecycles-compat@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
|
||||
react-modal@^3.13.1:
|
||||
version "3.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.13.1.tgz#a02dce63bbfee7582936f1e9835d518ef8f56453"
|
||||
integrity sha512-m6yXK7I4YKssQnsjHK7xITSXy2O81BSOHOsg0/uWAsdKtuT9HF2tdoYhRuxNNQg2V+LgepsoHUPJKS8m6no+eg==
|
||||
react-modal@^3.14.2:
|
||||
version "3.14.2"
|
||||
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.14.2.tgz#e04e1119d64c9fbb3db80736eb80ea9372f28778"
|
||||
integrity sha512-CYasEJanwneDsmvtx/fisXhgDxtt3I8jWTVX/tP9dM/J1NgDKU9lgjR9zuCCl33ub2jrTWhXyijCxCzYGN8sJg==
|
||||
dependencies:
|
||||
exenv "^1.2.0"
|
||||
prop-types "^15.5.10"
|
||||
prop-types "^15.7.2"
|
||||
react-lifecycles-compat "^3.0.0"
|
||||
warning "^4.0.3"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user