diff --git a/src/Tools/temp/index.jsx b/src/Tools/temp/index.jsx index 13ac0f3c13..7d1b2c86ca 100644 --- a/src/Tools/temp/index.jsx +++ b/src/Tools/temp/index.jsx @@ -1,5 +1,13 @@ import React from "react"; import { createRoot } from "react-dom/client"; +import Button from "../../_reactComponents/ChakraComponents/Button"; +import ButtonGroup from "../../_reactComponents/ChakraComponents/ButtonGroup"; +import { ChakraProvider } from "@chakra-ui/react"; +import theme from "/home/node/workspace/src/theme.jsx"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faCode } from "@fortawesome/free-solid-svg-icons"; const root = createRoot(document.getElementById("root")); -root.render(<>test here); +root.render( + Test code goes here!, +); diff --git a/src/Tools/uiDocs/uiDocs.jsx b/src/Tools/uiDocs/uiDocs.jsx index d583e8d16b..e7f8b60e33 100644 --- a/src/Tools/uiDocs/uiDocs.jsx +++ b/src/Tools/uiDocs/uiDocs.jsx @@ -15,8 +15,8 @@ import ActionButtonGroup from "../../_reactComponents/PanelHeaderComponents/Acti import SearchBar from "../../_reactComponents/PanelHeaderComponents/SearchBar.jsx"; import ToggleButton from "../../_reactComponents/PanelHeaderComponents/ToggleButton.jsx"; import ToggleButtonGroup from "../../_reactComponents/PanelHeaderComponents/ToggleButtonGroup.jsx"; -import Button from "../../_reactComponents/PanelHeaderComponents/Button.jsx"; -import ButtonGroup from "../../_reactComponents/PanelHeaderComponents/ButtonGroup.jsx"; +import Button from "../../_reactComponents/ChakraComponents/Button.jsx"; +import ButtonGroup from "../../_reactComponents/ChakraComponents/ButtonGroup.jsx"; import Form from "../../_reactComponents/PanelHeaderComponents/Form.jsx"; import Textfield from "../../_reactComponents/PanelHeaderComponents/Textfield.jsx"; import TextArea from "../../_reactComponents/PanelHeaderComponents/TextArea.jsx"; @@ -36,6 +36,16 @@ import Checkbox from "../../_reactComponents/PanelHeaderComponents/Checkbox.jsx" import Tooltip from "../../_reactComponents/PanelHeaderComponents/Tooltip.jsx"; import DueDateBar from "../../_reactComponents/PanelHeaderComponents/DueDateBar.jsx"; import { useState } from "react"; +import { + Box, + ChakraProvider, + Container, + Divider, + Heading, + Link as ChakraLink, + Text, +} from "@chakra-ui/react"; +import theme from "/home/node/workspace/src/theme.jsx"; // === HOW TO ADD TO UI DOCS === // 1. Import the component in the COMPONENT IMPORTS SECTION above @@ -56,17 +66,32 @@ import { useState } from "react"; // ] // }, -const NavBar = styled.div` - width: 240px; - height: 100vh; - position: fixed; - background-color: var(--solidLightBlue); - color: var(--canvastext); - top: 0; - left: 0; - overflow-x: hidden; - z-index: 1; -`; +// const NavBar = styled.div` +// width: 240px; +// height: 100vh; +// position: fixed; +// background-color: var(--solidLightBlue); +// color: var(--canvastext); +// top: 0; +// left: 0; +// overflow-x: hidden; +// z-index: 1; +// `; + +function NavBar({ content }) { + const navBarStyle = { + width: "240px", + height: "100vh", + position: "fixed", + backgroundColor: "var(--solidLightBlue)", + color: "var(--canvastext)", + top: "0", + left: "0", + overflowX: "hidden", + zIndex: "1", + }; + return {content}; +} const Content = styled.div` margin-left: 240px; `; @@ -81,6 +106,9 @@ export default function Attempt() { const font = () => {}; const vertical = () => {}; const verticalLabel = () => {}; + const isDisabled = () => {}; + const isLoading = () => {}; + const isAttached = () => {}; const disabled = () => {}; const absolute = () => {}; const left = () => {}; @@ -211,67 +239,92 @@ export default function Attempt() { name: "Button", id: "button", code: Button, - codePreview: "", req_props: null, - req_children: null, + req_children: ["Button"], use: "This style is more eye-catching. It is meant to be used when you want the user to do this thing! Click this button here!!", props: [ { - name: "Width - Menu Panel", - propPreview: ' ', + description: "Sets the size of the button (default size is 'md')", + propCode: { size: "xs" }, }, + { propCode: { size: "sm" } }, + { propCode: { size: "md" } }, + { propCode: { size: "lg" } }, + // { + // name: "Value", + // propPreview: ' ", + description: + "See Style Guide for more info on how to use FontAwesomeIcons. Adds icon to button, along with text", + propCode: { + leftIcon: , + }, }, + { propCode: { rightIcon: } }, { - name: "Alert", - propPreview: "", + propCode: { isLoading }, + description: "If true, the button will show a spinner", }, + // { + // name: "Label", + // propPreview: '', propCode: { onClick: () => console.log("clicked") }, description: "Function called when button is clicked", }, { name: "Disabled", - propPreview: "", + propCode: { isDisabled }, + description: "Makes button not able to be used", }, ], }, @@ -279,21 +332,54 @@ export default function Attempt() { name: "ButtonGroup", id: "buttongroup", code: ButtonGroup, - codePreview: " ", req_props: null, - req_children: [ - React.createElement(Button), - React.createElement(Button), - React.createElement(Button), - ], + req_children: [, ], use: "This groups related buttons together.", props: [ { - name: "Vertical", - propPreview: "", - propCode: { vertical }, - description: "Makes buttons align vertically", + name: "Variant", + propPreview: + " ", + propCode: { variant: "outline" }, + description: "Sets the variant of all buttons in the ButtonGroup", + }, + { + name: "Size", + propPreview: + " ", + propCode: { size: "sm" }, + description: "Sets the size of all buttons in the ButtonGroup", + }, + { + name: "Spacing", + propPreview: + " ", + propCode: { spacing: 10 }, + description: "Adds space between the buttons in the ButtonGroup", }, + { + name: "Attached", + propPreview: + " ", + propCode: { isAttached }, + description: + "Flush the buttons together by removing the border radius of their children as needed", + }, + { + name: "Disabled", + propPreview: + " ", + propCode: { isDisabled }, + description: "Disables all the buttons in the ButtonGroup", + }, + // { + // name: "Vertical", + // propPreview: "", + // propCode: { vertical }, + // description: "Makes buttons align vertically", + // }, // {name: 'Width - Menu Panel', // propPreview: '', // propCode: {width: 'menu'}, @@ -1579,153 +1665,162 @@ export default function Attempt() { //NEW COMPONENT PAGE function New() { return ( -
-

Features of A Standard Doenet Component

-

+ + Features of A Standard Doenet Component + These are the guidelines for creating components for user input on Doenet. They are guidelines -- you can break them (and should if something looks ridiculous), but make sure you have a reason why you need to and that you can convince someone else of that reason. Once you’ve created or fixed a component, add the documentation for it to - this file ../src/Tools/uiDocs.js and update the component spreadsheet - - {" "} here - + .{" "} -

-
+ + -

Comments on Accessibility

-

+ Comments on Accessibility + All clickable elements need to have a focus indicator. Our standard is a 2px border that matches the element's current border with a 2px - offset. See styling - - {" "} - here{" "} - {" "} -

-

+ here + + {"."} + + All clickable elements also need an aria-label. Some elements, like buttons, do this for you, so adding an additional aria-label is considered bad practice. The naming techniques and accessible name - guidance sections will be the most helpful. Read more - - {" "} - here{" "} - -

-

+ here + + {"."} + + All components must follow standard keyboard and aria practices for that specific element. Find the element you are working on here and add the required keyboard interactions and aria information that it - lists. Here is the - - {" "} - link{" "} - -

+ link + + {"."} +
-

States to Consider (* denotes required)

-

- *disabled - remove ability for user to interact with component, - see styling - States to Consider (* denotes required) + + *disabled - remove ability for user to interact + with component, see styling{" "} + - {" "} here - -

-

- *alert - if component requires user's attention, give red - #C1292E border, see styling - + {"."} + + + *alert - if component requires user's attention, + give red #C1292E border, see styling{" "} + - {" "} here - -

-
+ + {"."} + + -

Standard Props (* denotes required)

-

- width = menu (235px) is the only option, otherwise the size - should be a default based on input (text, icons, ...) -

-

- value = information expected to be shown on component (text on - Button) -

-

- icon = small image that can be displayed, if it can show text - - it can have an icon. More info - Standard Props (* denotes required) + + width = menu (235px) is the only option, otherwise + the size should be a default based on input (text, icons, ...) + + + value = information expected to be shown on + component (text on Button) + + + icon = small image that can be displayed, if it + can show text - it can have an icon. More info{" "} + - {" "} here - -

-

- value + icon = ability to have icon and value together -

-

- label = text before componenet telling user what it is for, - 14px font size -

-

- vertical label = ability to have label stack on top of - component, label must be there for vertical label to work -

-

- placeholder = default shown before user input -

-

- *margin = default is 0px, make 4px left and right margin with - 2px bottom margin on label if prop margin -

-

- *aria-label = built in HTML accessibility requirement -

-

- onClick = you know what this is, don’t use callback function -

-

- onChange = okay you probably know this as well, no callback - function! -

-

- onBlur = same idea -

-

- onKeyDown = same thing here -

+ + {"."} + + + value + icon = ability to have icon and value + together + + + label = text before componenet telling user what + it is for, 14px font size + + + vertical label = ability to have label stack on + top of component, label must be there for vertical label to work + + + placeholder = default shown before user input + + + *margin = default is 0px, make 4px left and right + margin with 2px bottom margin on label if prop margin + + + *aria-label = built in HTML accessibility + requirement + + + onClick = you know what this is, don’t use + callback function + + + onChange = okay you probably know this as well, no + callback function! + + + onBlur = same idea + + + onKeyDown = same thing here + {/*

onHover = you can guess this, see

*/} -
+ -

Comments on Styling

-

- Only use the colors found on the - Comments on Styling + + Only use the colors found on the{" "} + - {" "} - Style Guide!!{" "} - {" "} + Style Guide!! + {" "} (Unless you've talked to Clara or Kevin about it...) -

-

- Give it a border or a color, as shown - + + Give it a border or a color, as shown{" "} + - {" "} - here{" "} - -

-

+ here + + {"."} + + Don’t apply the font to the component, fonts will be called in the - Tool that loads it -

-
+ Tool that loads it. + + ); } @@ -1792,14 +1888,16 @@ export default function Attempt() { if (component.props) { return component.props.map( ({ name, propPreview, propCode, description }) => ( -
-

{name}

-

+ + + {name} + + {propPreview} -

-

{description}

+ + {description} {React.createElement(display, propCode, children)} -
+ ), ); } else { @@ -1807,25 +1905,25 @@ export default function Attempt() { } } return ( -
-

{component.name}

-

{component.codePreview}

+ + {component.name} + {component.codePreview} {React.createElement( display, component.req_props, component.req_children, )} -
+ -

Why would I use this?

-

{component.use}

+ Why would I use this? + {component.use} -
+ -

Props

+ Props {Props(component)} -
+ ); } @@ -1833,37 +1931,45 @@ export default function Attempt() { function Layout() { return ( <> - -
-

Components

- {actionResult == "" ? null : ( - <> -

{actionResult}

- - - )} - {/* */} -
-

- - New Component Guidelines - -

- - {dataStructure.map(({ name, id }) => ( -
  • - - {name} - -
  • - ))} -
    -
    + + + Components + {actionResult == "" ? null : ( + <> +

    {actionResult}

    + + + )} + {/* */} +
    + + New Component Guidelines + + + {dataStructure.map(({ name, id }) => ( +
  • + + {name} + +
  • + ))} +
    + + } + >
    @@ -1873,14 +1979,16 @@ export default function Attempt() { //ROUTER SECTION return ( - - - }> - } /> - } /> - } /> - - - + + + + }> + } /> + } /> + } /> + + + + ); } diff --git a/src/_reactComponents/ChakraComponents/Button.jsx b/src/_reactComponents/ChakraComponents/Button.jsx new file mode 100644 index 0000000000..d682ed44d4 --- /dev/null +++ b/src/_reactComponents/ChakraComponents/Button.jsx @@ -0,0 +1,8 @@ +import React, { useState } from "react"; +import styled from "styled-components"; +import { MathJax } from "better-react-mathjax"; +import { Button as ChakraButton } from "@chakra-ui/react"; + +export default function Button(props) { + return ; +} diff --git a/src/_reactComponents/ChakraComponents/ButtonGroup.jsx b/src/_reactComponents/ChakraComponents/ButtonGroup.jsx new file mode 100644 index 0000000000..f4f05801a7 --- /dev/null +++ b/src/_reactComponents/ChakraComponents/ButtonGroup.jsx @@ -0,0 +1,9 @@ +import React from "react"; +import styled, { ThemeProvider } from "styled-components"; +import { ButtonGroup as ChakraButtonGroup } from "@chakra-ui/react"; + +export default function ButtonGroup(props) { + let elem = React.Children.toArray(props.children); + + return {elem}; +} diff --git a/src/index.jsx b/src/index.jsx index f03f15fcf1..3821c4ceba 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -38,14 +38,14 @@ import { action as portfolioActivityViewerAction, PortfolioActivityViewer, } from "./Tools/_framework/Paths/PortfolioActivityViewer"; -import { ChakraProvider, extendTheme } from "@chakra-ui/react"; +import { ChakraProvider } from "@chakra-ui/react"; +import theme from "/home/node/workspace/src/theme.jsx"; import { action as editorSupportPanelAction, loader as editorSupportPanelLoader, } from "./Tools/_framework/Panels/NewSupportPanel"; import ErrorPage from "./Tools/_framework/Paths/ErrorPage"; -import "@fontsource/jost"; import { PortfolioActivityEditor, loader as portfolioEditorLoader, @@ -58,87 +58,6 @@ import { } from "./Tools/_framework/Paths/PublicEditor"; // import { loader as portfolioEditorMenuCapLoader } from './Tools/_framework/MenuPanelCaps/PortfolioEditorInfoCap'; -const theme = extendTheme({ - fonts: { - body: "Jost", - }, - textStyles: { - primary: { - fontFamily: "Jost", - }, - }, - config: { - initialColorMode: "light", - useSystemColorMode: false, - // initialColorMode: "system", - // useSystemColorMode: true, - }, - colors: { - doenet: { - mainBlue: "#1a5a99", - lightBlue: "#b8d2ea", - solidLightBlue: "#8fb8de", - mainGray: "#e3e3e3", - mediumGray: "#949494", - lightGray: "#e7e7e7", - donutBody: "#eea177", - donutTopping: "#6d4445", - mainRed: "#c1292e", - lightRed: "#eab8b8", - mainGreen: "#459152", - canvas: "#ffffff", - canvastext: "#000000", - lightGreen: "#a6f19f", - lightYellow: "#f5ed85", - whiteBlankLink: "#6d4445", - mainYellow: "#94610a", - mainPurple: "#4a03d9", - }, - }, - components: { - Button: { - baseStyle: { - fontWeight: "normal", - letterSpacing: ".5px", - _focus: { - outline: "2px solid #2D5994", - outlineOffset: "2px", - }, - _disabled: { - bg: "#E2E2E2", - color: "black", - cursor: "none", - }, - }, - variants: { - // We can override existing variants - solid: { - bg: "doenet.mainBlue", - color: "white", - _hover: { - bg: "doenet.solidLightBlue", - color: "black", - }, - }, - outline: { - borderColor: "#2D5994", - _hover: { - bg: "solidLightBlue", - }, - }, - ghost: { - _hover: { - bg: "solidLightBlue", - }, - }, - link: { - color: "solidLightBlue", - }, - }, - }, - }, -}); - const router = createBrowserRouter([ { path: "/", @@ -304,28 +223,28 @@ const router = createBrowserRouter([ ), }, - { - path: "*", - // errorElement:
    Error!
    , - element: ( - (mathJax.Hub.processSectionDelay = 0)} - > - - - ), - // TODO - probably not a good idea long term, this is to populate the site header - // on the 404 page, but this results in extra network requests when loading - // ToolRoot content - loader: siteLoader, - errorElement: ( - - } /> - - ), - }, + // { + // path: "*", + // // errorElement:
    Error!
    , + // element: ( + // (mathJax.Hub.processSectionDelay = 0)} + // > + // + // + // ), + // // TODO - probably not a good idea long term, this is to populate the site header + // // on the 404 page, but this results in extra network requests when loading + // // ToolRoot content + // loader: siteLoader, + // errorElement: ( + // + // } /> + // + // ), + // }, ]); const root = createRoot(document.getElementById("root")); diff --git a/src/theme.jsx b/src/theme.jsx new file mode 100644 index 0000000000..2c34dc0fee --- /dev/null +++ b/src/theme.jsx @@ -0,0 +1,88 @@ +import { extendTheme } from "@chakra-ui/react"; +import "@fontsource/jost"; + +const theme = extendTheme({ + fonts: { + body: "Jost", + }, + textStyles: { + primary: { + fontFamily: "Jost", + }, + }, + config: { + initialColorMode: "light", + useSystemColorMode: false, + // initialColorMode: "system", + // useSystemColorMode: true, + }, + colors: { + doenet: { + mainBlue: "#1a5a99", + lightBlue: "#b8d2ea", + solidLightBlue: "#8fb8de", + mainGray: "#e3e3e3", + mediumGray: "#949494", + lightGray: "#e7e7e7", + donutBody: "#eea177", + donutTopping: "#6d4445", + mainRed: "#c1292e", + lightRed: "#eab8b8", + mainGreen: "#459152", + canvas: "#ffffff", + canvastext: "#000000", + lightGreen: "#a6f19f", + lightYellow: "#f5ed85", + whiteBlankLink: "#6d4445", + mainYellow: "#94610a", + mainPurple: "#4a03d9", + }, + }, + components: { + Button: { + baseStyle: { + fontWeight: "normal", + letterSpacing: ".5px", + // _focus: { + // outline: "2px solid #2D5994", + // outlineOffset: "2px", + // }, + // _disabled: { + // bg: "#E2E2E2", + // color: "black", + // }, + }, + variants: { + // We can override existing variants + solid: { + bg: "doenet.mainBlue", + color: "white", + _hover: { + bg: "doenet.solidLightBlue", + color: "black", + _disabled: { + bg: "doenet.mainBlue", + color: "white", + }, + }, + }, + outline: { + borderColor: "doenet.mainBlue", + _hover: { + bg: "doenet.solidLightBlue", + }, + }, + ghost: { + _hover: { + bg: "doenet.solidLightBlue", + }, + }, + link: { + color: "doenet.mainBlue", + }, + }, + }, + }, +}); + +export default theme;