mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-14 13:52:11 +00:00
buttons, and topbar scafoldding
This commit is contained in:
1 parent
bd8bb31f9c
commit
6a50feea35
10 files changed
+139
-18
No files matched your search
+1
-1
@@ -1,5 +1,5 @@
|
||||
node_modules
|
||||
|
||||
/~/
|
||||
/.cache
|
||||
/public/build
|
||||
/build
|
||||
|
||||
@@ -3,20 +3,33 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
icon?: IconDefinition;
|
||||
variant?: "primary"|"secondary";
|
||||
}
|
||||
|
||||
export const Button = ({
|
||||
icon,
|
||||
children,
|
||||
className : propsClassName,
|
||||
variant = 'primary',
|
||||
...rest
|
||||
}:ButtonProps)=>{
|
||||
function getVariantClassNames(variant: string){
|
||||
switch(variant){
|
||||
case "secondary":{
|
||||
return "bg-brand-secondary hover:bg-brand-secondary-900 text-white focus-visible:outline-brand-secondary";
|
||||
}
|
||||
case "primary":
|
||||
default:{
|
||||
return "bg-brand-primary hover:bg-brand-primary-400 text-white focus-visible:outline-brand-primary-600";
|
||||
}
|
||||
}
|
||||
};
|
||||
const className = `
|
||||
bg-brand-primary hover:bg-brand-primary-400
|
||||
text-white text-sm font-semibold
|
||||
text-sm font-semibold
|
||||
rounded-md px-3.5 py-2.5 shadow-sm
|
||||
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-primary-600
|
||||
` + (propsClassName ? ` ${propsClassName}` : null);
|
||||
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
|
||||
` + getVariantClassNames(variant)
|
||||
+ (propsClassName ? ` ${propsClassName}` : null);
|
||||
|
||||
return(
|
||||
<button
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Link, LinkProps } from "@remix-run/react";
|
||||
import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
interface LinkButtonProps extends LinkProps {
|
||||
icon?: IconDefinition;
|
||||
variant?: "primary"|"secondary";
|
||||
}
|
||||
|
||||
export const ButtonLink = ({
|
||||
icon,
|
||||
children,
|
||||
className: propsClassName,
|
||||
variant = "primary",
|
||||
...rest
|
||||
}:LinkButtonProps)=>{
|
||||
//TODO: Duplicated from Button.tsx
|
||||
function getVariantClassNames(variant: string){
|
||||
switch(variant){
|
||||
case "secondary":{
|
||||
return "bg-brand-secondary hover:bg-brand-secondary-900 text-white focus-visible:outline-brand-secondary";
|
||||
}
|
||||
case "primary":
|
||||
default:{
|
||||
return "bg-brand-primary hover:bg-brand-primary-400 text-white focus-visible:outline-brand-primary-600";
|
||||
}
|
||||
}
|
||||
};
|
||||
const className = `
|
||||
text-sm font-semibold
|
||||
rounded-md px-3.5 py-2.5 shadow-sm
|
||||
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
|
||||
` + getVariantClassNames(variant)
|
||||
+ (propsClassName ? ` ${propsClassName}` : null);
|
||||
// END TODO
|
||||
|
||||
return(
|
||||
<Link {...rest}>
|
||||
<button className={className}>
|
||||
{icon && <FontAwesomeIcon className="mr-2" icon={icon}/>}
|
||||
{children}
|
||||
</button>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { ReactNode, createContext } from "react";
|
||||
|
||||
export const TopBarInnerContext = createContext<{
|
||||
TopBarInner: JSX.Element | null;
|
||||
setTopBarInner: (el: JSX.Element | null)=>void;
|
||||
} | null>(null);
|
||||
@@ -1,3 +0,0 @@
|
||||
import { ReactNode, createContext } from "react";
|
||||
|
||||
export const TopBarMidSection = createContext<ReactNode | null>(null);
|
||||
@@ -1,13 +1,26 @@
|
||||
import {
|
||||
useRef,
|
||||
useEffect,
|
||||
useState,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import {
|
||||
faChevronLeft
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
import { Button } from '~/components/Button';
|
||||
import { ButtonLink } from '~/components/ButtonLink';
|
||||
import { TopBarInnerContext } from "~/contexts/TopBarInner";
|
||||
|
||||
import { SceneWithCube } from './SceneWithCube';
|
||||
|
||||
export const PageCube = () => {
|
||||
|
||||
const { setTopBarInner } = useContext(TopBarInnerContext) || {};
|
||||
|
||||
const mountRef = useRef<HTMLDivElement | null>(null);
|
||||
const sceneRef = useRef<SceneWithCube | null>(null);
|
||||
const [{
|
||||
@@ -45,10 +58,25 @@ export const PageCube = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
useLayoutEffect(()=>{
|
||||
if(setTopBarInner){
|
||||
const BackButton = (
|
||||
<ButtonLink
|
||||
to={"/"}
|
||||
variant='secondary'
|
||||
icon={faChevronLeft}
|
||||
>
|
||||
Back to Dashboard
|
||||
</ButtonLink>
|
||||
);
|
||||
setTopBarInner(BackButton);
|
||||
}
|
||||
},[setTopBarInner]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="Cube" ref={mountRef} />
|
||||
<button onClick={toggleStopped}> STOP </button>
|
||||
<Button onClick={toggleStopped}> STOP </Button>
|
||||
<p>{rotationX ? rotationX : ""}</p>
|
||||
<p>{rotationY ? rotationY : ""}</p>
|
||||
</>
|
||||
|
||||
+12
-3
@@ -1,3 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { LinksFunction } from "@remix-run/deno";
|
||||
import {
|
||||
Links,
|
||||
@@ -11,7 +12,8 @@ import tailwindCss from "./styles/tailwind.css?url";
|
||||
import normalizeCss from "./styles/normalize.css?url";
|
||||
|
||||
import { TopBar } from "./template/TopBar";
|
||||
import { TopBarMidSection } from "./contexts/TopbarMidSection";
|
||||
import { TopBarInnerContext } from '~/contexts/TopBarInner';
|
||||
|
||||
|
||||
export const links : LinksFunction = () => [{
|
||||
rel: "stylesheet",
|
||||
@@ -22,6 +24,8 @@ export const links : LinksFunction = () => [{
|
||||
}];
|
||||
|
||||
export default function App() {
|
||||
const [topBarInnerComponent, setTopBarInnerComponent] = useState<JSX.Element | null>(null);
|
||||
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
@@ -31,8 +35,13 @@ export default function App() {
|
||||
<Links />
|
||||
</head>
|
||||
<body className="bg-ui-background">
|
||||
<Outlet />
|
||||
<TopBar />
|
||||
<TopBarInnerContext.Provider value={{
|
||||
TopBarInner: topBarInnerComponent,
|
||||
setTopBarInner: setTopBarInnerComponent
|
||||
}}>
|
||||
<Outlet />
|
||||
<TopBar />
|
||||
</TopBarInnerContext.Provider>
|
||||
<ScrollRestoration />
|
||||
<Scripts />
|
||||
</body>
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@ import { useState } from 'react';
|
||||
import { PageCube } from "../pages/PageCube";
|
||||
import { Button } from '~/components/Button';
|
||||
export default function Cube(){
|
||||
const pausedRiddle = true;
|
||||
const [riddle, setRiddle] = useState<string>("");
|
||||
const [submitted, setSubmitted] = useState<boolean>(false);
|
||||
|
||||
@@ -17,7 +18,7 @@ export default function Cube(){
|
||||
alert("What is the price for your blind eye?")
|
||||
}
|
||||
|
||||
if(submitted){
|
||||
if(submitted || pausedRiddle){
|
||||
return <PageCube />
|
||||
}else{
|
||||
return(
|
||||
|
||||
+12
-1
@@ -1,4 +1,10 @@
|
||||
import {
|
||||
useContext,
|
||||
useLayoutEffect,
|
||||
} from "react";
|
||||
import type { MetaFunction } from "@remix-run/deno";
|
||||
import { TopBarInnerContext } from "~/contexts/TopBarInner";
|
||||
|
||||
import sonic from "./_assets/sonic-the-hedgehog-classic-sonic.gif";
|
||||
|
||||
export const meta: MetaFunction = () => {
|
||||
@@ -8,8 +14,13 @@ export const meta: MetaFunction = () => {
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
export default function Index() {
|
||||
const { setTopBarInner } = useContext(TopBarInnerContext) || {};
|
||||
useLayoutEffect(()=>{
|
||||
if(setTopBarInner){
|
||||
setTopBarInner(null);
|
||||
}
|
||||
},[setTopBarInner]);
|
||||
return (
|
||||
<div className="size-full">
|
||||
<img
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { Button } from '~/components/Button'
|
||||
import { faRightToBracket } from '@fortawesome/free-solid-svg-icons'
|
||||
export const TopBar = () => {
|
||||
import { TopBarInnerContext } from '~/contexts/TopBarInner';
|
||||
|
||||
export const TopBar = () => {
|
||||
return (
|
||||
<header className="bg-ui-panel fixed top-0 left-0 w-full">
|
||||
<nav className="mx-auto flex max-w-full items-center justify-between p-4 lg:px-8" aria-label="Global">
|
||||
@@ -10,9 +13,17 @@ export const TopBar = () => {
|
||||
<span className="sr-only">FakeYou</span>
|
||||
<img className="h-10 w-auto" src="/resources/images/Storyteller-Logo-1.png" alt="Logo FakeYou StoryTeller.ai" />
|
||||
</a>
|
||||
<span className="w-4 lg:w-8"/>
|
||||
<TopBarInner />
|
||||
</div>
|
||||
<Button icon={faRightToBracket}>Login</Button>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
const TopBarInner = ()=>{
|
||||
const { TopBarInner } = useContext(TopBarInnerContext) || {}
|
||||
return(TopBarInner);
|
||||
}
|
||||
Reference in new issue
Block a user