From 11669b7612e1814a03bbd939ddb42bb6c056601c Mon Sep 17 00:00:00 2001 From: Arnei Date: Thu, 23 May 2024 11:31:33 +0200 Subject: [PATCH 01/19] Add modal from tobira Adds the "Modal" component from Tobira. The component is ported with the minimum amount of required changes. Translations string will have to be provided in their translated form. --- package.json | 4 +- src/index.tsx | 1 + src/modal.tsx | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 src/modal.tsx diff --git a/package.json b/package.json index 69e593e..d6e1597 100644 --- a/package.json +++ b/package.json @@ -18,13 +18,15 @@ "prepare": "npm run build" }, "devDependencies": { - "@opencast/eslint-config-ts-react": "^0.1.0", + "@opencast/eslint-config-ts-react": "^0.2.0", "@types/react": "^18.2.13", + "@types/react-dom": "^18.2.19", "typescript": "^5.1.3" }, "peerDependencies": { "@emotion/react": "^11.11.1", "@floating-ui/react": "^0.24.3", + "focus-trap-react": "^10.2.3", "react": "^18.2.0", "react-icons": "^4.9.0", "react-merge-refs": "^2.0.2" diff --git a/src/index.tsx b/src/index.tsx index 33a43a6..e9b7111 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -8,6 +8,7 @@ export * from "./floating"; export * from "./header"; export * from "./spinner"; export * from "./util"; +export * from "./modal"; /** diff --git a/src/modal.tsx b/src/modal.tsx new file mode 100644 index 0000000..317f974 --- /dev/null +++ b/src/modal.tsx @@ -0,0 +1,120 @@ +import { + PropsWithChildren, + forwardRef, + useState, + useImperativeHandle, + useEffect, +} from "react"; +import ReactDOM from "react-dom"; +import { LuX } from "react-icons/lu"; +import FocusTrap from "focus-trap-react"; +import { + useAppkitConfig, ProtoButton, focusStyle, useColorScheme, +} from "."; + +export type ModalProps = { + title: string; + closable?: boolean; + className?: string; + closeOnOutsideClick?: boolean; + open?: boolean; + initialFocus?: false; + text: { + generalActionClose: string, + }, +}; + +export type ModalHandle = { + open: () => void; + close?: () => void; + isOpen?: () => boolean; +}; + +export const Modal = forwardRef>(({ + title, + closable = true, + children, + className, + closeOnOutsideClick = false, + open = false, + initialFocus, + text, +}, ref) => { + const config = useAppkitConfig(); + // const { t } = useTranslation(); + const [isOpen, setOpen] = useState(open); + const isDark = useColorScheme().scheme === "dark"; + + useImperativeHandle(ref, () => ({ + isOpen: () => isOpen, + open: () => setOpen(true), + close: () => setOpen(false), + }), [isOpen]); + + useEffect(() => { + const handleEscape = (event: KeyboardEvent) => { + if (closable && event.key === "Escape") { + setOpen(false); + } + }; + window.addEventListener("keydown", handleEscape); + return () => window.removeEventListener("keydown", handleEscape); + }, [closable]); + + return ReactDOM.createPortal( + isOpen && +
{ + if (e.target === e.currentTarget) { + setOpen(false); + } + } })} + css={{ + position: "fixed", + top: 0, + bottom: 0, + left: 0, + right: 0, + backgroundColor: "rgba(0, 0, 0, 0.8)", + display: "flex", + justifyContent: "center", + alignItems: "center", + zIndex: 10001, + }} + > +
+
+

{title}

+ {closable && setOpen(false)} + css={{ + fontSize: 32, + cursor: "pointer", + display: "inline-flex", + borderRadius: 4, + ...focusStyle(config, { inset: true }), + }} + >} +
+
{children}
+
+
+
, + document.body, + ); +}); From 868f280946200e07cfb0d7b5b1b78a50193de17b Mon Sep 17 00:00:00 2001 From: Arnei Date: Thu, 23 May 2024 14:25:54 +0200 Subject: [PATCH 02/19] Add basic styled button from Tobira Adds another button component from Tobira, with the goal of using it in the confirmation modal from Tobira. The button can be normal, happy or danger. --- package.json | 2 +- src/config.tsx | 18 ++++++++++ src/index.tsx | 2 ++ src/styledButton.tsx | 82 ++++++++++++++++++++++++++++++++++++++++++++ src/utilFunc.ts | 12 +++++++ 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 src/styledButton.tsx create mode 100644 src/utilFunc.ts diff --git a/package.json b/package.json index d6e1597..0ad6dc3 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "typescript": "^5.1.3" }, "peerDependencies": { - "@emotion/react": "^11.11.1", + "@emotion/react": "^11.11.4", "@floating-ui/react": "^0.24.3", "focus-trap-react": "^10.2.3", "react": "^18.2.0", diff --git a/src/config.tsx b/src/config.tsx index 9ff6e0d..752c05a 100644 --- a/src/config.tsx +++ b/src/config.tsx @@ -28,11 +28,20 @@ export type ColorConfig = { neutral90: string, danger0: string, + danger0BwInverted: string; danger1: string, + danger1BwInverted: string; danger2: string, danger4: string, danger5: string, + happy0: string; + happy0BwInverted: string; + happy1: string; + happy1BwInverted: string; + happy2: string; + happy2BwInverted: string; + accent8: string; accent7: string; accent6: string; @@ -59,11 +68,20 @@ export const DEFAULT_CONFIG: AppkitConfig = { neutral90: "var(--color-neutral90)", danger0: "var(--color-danger0)", + danger0BwInverted: "var(--color-danger0-bw-inverted)", danger1: "var(--color-danger1)", + danger1BwInverted: "var(--color-danger1-bw-inverted)", danger2: "var(--color-danger2)", danger4: "var(--color-danger4)", danger5: "var(--color-danger5)", + happy0: "var(--color-happy0)", + happy0BwInverted: "var(--color-happy0-bw-inverted)", + happy1: "var(--color-happy1)", + happy1BwInverted: "var(--color-happy1-bw-inverted)", + happy2: "var(--color-happy2)", + happy2BwInverted: "var(--color-happy2-bw-inverted)", + accent8: "var(--color-accent8)", accent7: "var(--color-accent7)", accent6: "var(--color-accent6)", diff --git a/src/index.tsx b/src/index.tsx index e9b7111..8de3344 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -8,7 +8,9 @@ export * from "./floating"; export * from "./header"; export * from "./spinner"; export * from "./util"; +export * from "./utilFunc"; export * from "./modal"; +export * from "./styledButton"; /** diff --git a/src/styledButton.tsx b/src/styledButton.tsx new file mode 100644 index 0000000..a6844e5 --- /dev/null +++ b/src/styledButton.tsx @@ -0,0 +1,82 @@ +import { Interpolation, Theme } from "@emotion/react"; +import React from "react"; +import { focusStyle, match, useAppkitConfig } from "."; + +export type Kind = "normal" | "danger" | "happy"; + +type ButtonProps = JSX.IntrinsicElements["button"] & { + kind?: Kind; + extraCss?: Interpolation; +}; + +/** A styled button */ +export const Button = React.forwardRef( + ({ kind = "normal", extraCss, children, ...rest }, ref) => ( + + ), +); + +const css = (kind: Kind, extraCss: Interpolation = {}): Interpolation => { + const config = useAppkitConfig(); + + const notDisabledStyle = match(kind, { + "normal": () => ({ + border: `1px solid ${config.colors.neutral40}`, + color: config.colors.neutral90, + "&:hover, &:focus-visible": { + border: `1px solid ${config.colors.neutral60}`, + backgroundColor: config.colors.neutral15, + }, + ...focusStyle(config, { offset: -1 }), + }), + + "danger": () => ({ + border: `1px solid ${config.colors.danger0}`, + color: config.colors.danger0, + "&:hover, &:focus-visible": { + border: `1px solid ${config.colors.danger1}`, + backgroundColor: config.colors.danger0, + color: config.colors.danger0BwInverted, + }, + ...focusStyle(config, { offset: 1 }), + }), + + "happy": () => ({ + border: `1px solid ${config.colors.happy1}`, + color: config.colors.happy0BwInverted, + backgroundColor: config.colors.happy0, + "&:hover, &:focus-visible": { + border: `1px solid ${config.colors.happy2}`, + backgroundColor: config.colors.happy1, + color: config.colors.happy1BwInverted, + }, + ...focusStyle(config, { offset: 1 }), + }), + }); + + return { + borderRadius: 8, + display: "inline-flex", + alignItems: "center", + padding: "7px 14px", + gap: 12, + whiteSpace: "nowrap", + backgroundColor: config.colors.neutral10, + transition: "background-color 0.15s, border-color 0.15s", + textDecoration: "none", + "& > svg": { + fontSize: 20, + }, + "&:disabled": { + border: `1px solid ${config.colors.neutral25}`, + color: config.colors.neutral40, + }, + "&:not([disabled])": { + cursor: "pointer", + ...notDisabledStyle, + }, + ...extraCss as Record, + }; +}; + +export const buttonStyle = css; diff --git a/src/utilFunc.ts b/src/utilFunc.ts new file mode 100644 index 0000000..caba4a5 --- /dev/null +++ b/src/utilFunc.ts @@ -0,0 +1,12 @@ +import React from "react"; +import { bug } from "."; + +/** + * Accesses the current value of a ref, signaling an error when it is unbound. + * Note: **Don't** use this if you expect the ref to be unbound temporarily. + * This is mainly for accessing refs in event handlers for elements + * that are guaranteed to be alive as long as the ref itself. + */ +export const currentRef = (ref: React.RefObject): T => ( + ref.current ?? bug("ref unexpectedly unbound") +); From a7da5611efece3c13537b0858976d56867ac9ddb Mon Sep 17 00:00:00 2001 From: Arnei Date: Thu, 23 May 2024 14:35:17 +0200 Subject: [PATCH 03/19] Use color config for Spinner As how it is in Tobira. --- src/spinner.tsx | 53 +++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/src/spinner.tsx b/src/spinner.tsx index aaa3867..1a76f6c 100644 --- a/src/spinner.tsx +++ b/src/spinner.tsx @@ -1,33 +1,38 @@ import { keyframes } from "@emotion/react"; import React from "react"; +import { useAppkitConfig } from "."; type Props = JSX.IntrinsicElements["svg"] & { size?: number | string; }; -export const Spinner = React.forwardRef(({ size = "1em", ...rest }, ref) => ( - circle": { - fill: "none", - stroke: "currentcolor", - strokeWidth: 4, - strokeDasharray: 83, // 2/3 of circumference - strokeLinecap: "round", - }, +export const Spinner = React.forwardRef(({ size = "1em", ...rest }, ref) => { + const config = useAppkitConfig(); - }} - {...rest} - > - - -)); + return ( + circle": { + fill: "none", + stroke: config.colors.neutral90, + strokeWidth: 4, + strokeDasharray: 83, // 2/3 of circumference + strokeLinecap: "round", + }, + + }} + {...rest} + > + + + ); +}); From 2339768b4da0629086f91b0a80dbb63a7c2b4688 Mon Sep 17 00:00:00 2001 From: Arnei Date: Thu, 23 May 2024 15:16:03 +0200 Subject: [PATCH 04/19] Add error box from Tobira Adds a nice little error box from Tobira to render errors in. Also adds the card component which is required for that. Used by confirmation modal. --- src/card.tsx | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/errorBox.tsx | 17 +++++++++++++++++ src/index.tsx | 2 ++ 3 files changed, 66 insertions(+) create mode 100644 src/card.tsx create mode 100644 src/errorBox.tsx diff --git a/src/card.tsx b/src/card.tsx new file mode 100644 index 0000000..bc29d5f --- /dev/null +++ b/src/card.tsx @@ -0,0 +1,47 @@ +import { LuAlertTriangle, LuInfo } from "react-icons/lu"; +import { match, useAppkitConfig } from "."; + + +type Props = JSX.IntrinsicElements["div"] & { + kind: "error" | "info"; + iconPos?: "left" | "top"; +}; + +/** A styled container for different purposes */ +export const Card: React.FC = ({ kind, iconPos = "left", children, ...rest }) => { + const config = useAppkitConfig(); + + return ( +
svg": { + fontSize: 24, + minWidth: 24, + }, + ...match(kind, { + "error": () => ({ + backgroundColor: config.colors.danger0, + border: `1.5px solid ${config.colors.danger0}`, + color: config.colors.danger0BwInverted, + }) as Record, + "info": () => ({ + backgroundColor: config.colors.neutral10, + }), + }), + }} + {...rest} + > + {match(kind, { + "error": () => , + "info": () => , + })} +
{children}
+
+ ); +}; diff --git a/src/errorBox.tsx b/src/errorBox.tsx new file mode 100644 index 0000000..57d8568 --- /dev/null +++ b/src/errorBox.tsx @@ -0,0 +1,17 @@ +import { ReactNode } from "react"; + +import { Card } from "."; + +export const ErrorBox: React.FC<{ children: ReactNode }> = ({ children }) => ( +
+ {children} +
+); + +/** +* If the given error is not `null` nor `undefined`, returns an `` +* with it as content. Returns `null` otherwise. +*/ +export const boxError = (err: ReactNode): JSX.Element | null => ( + err == null ? null : {err} +); diff --git a/src/index.tsx b/src/index.tsx index 8de3344..d820cfb 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,9 +1,11 @@ import { AppkitConfig } from "./config"; export * from "./button"; +export * from "./card"; export * from "./colorScheme"; export * from "./config"; export * from "./err"; +export * from "./errorBox"; export * from "./floating"; export * from "./header"; export * from "./spinner"; From 21e3b30593080662772052eb943e981dbb80de3f Mon Sep 17 00:00:00 2001 From: Arnei Date: Thu, 23 May 2024 15:37:08 +0200 Subject: [PATCH 05/19] Add ConfirmationModal from Tobira Adds the confirmation modal from tobira --- src/confirmationModal.tsx | 101 ++++++++++++++++++++++++++++++++++++++ src/index.tsx | 1 + 2 files changed, 102 insertions(+) create mode 100644 src/confirmationModal.tsx diff --git a/src/confirmationModal.tsx b/src/confirmationModal.tsx new file mode 100644 index 0000000..8dd53c1 --- /dev/null +++ b/src/confirmationModal.tsx @@ -0,0 +1,101 @@ +import { + ReactNode, + FormEvent, + PropsWithChildren, + forwardRef, + useState, + useRef, + useImperativeHandle, +} from "react"; +import { bug, ModalProps, ModalHandle, Modal, Spinner, Button, boxError } from "."; +import { currentRef } from "./utilFunc"; + + +type ConfirmationModalProps = Omit & { + title?: string; + buttonContent: ReactNode; + onSubmit?: () => void; + text: { + generalActionCancel: string, + generalActionClose: string, + manageAreYouSure: string, + }, +}; + +export type ConfirmationModalHandle = ModalHandle & { + done: () => void; + reportError: (error: JSX.Element) => void; +}; + +export const ConfirmationModal + = forwardRef>( + ({ + title: titleOverride, + buttonContent, + onSubmit, + text, + children, + }, ref) => { + const title = titleOverride ?? text.manageAreYouSure ?? bug("missing translation"); + + const [inFlight, setInFlight] = useState(false); + const [error, setError] = useState(); + + const modalRef = useRef(null); + + useImperativeHandle(ref, () => ({ + open: () => { + setInFlight(false); + setError(undefined); + currentRef(modalRef).open(); + }, + done: () => { + currentRef(modalRef).close?.(); + }, + reportError: (error: JSX.Element) => { + setInFlight(false); + setError(error); + }, + })); + + const onSubmitWrapper = (event: FormEvent) => { + event.preventDefault(); + // Don't let the event escape the portal, + // which might be sitting inside of other `form` elements. + event.stopPropagation(); + setInFlight(true); + setError(undefined); + onSubmit?.(); + }; + + return + {children} +
+
+ + +
+ {inFlight &&
} +
+ {boxError(error)} +
; + }, + ); diff --git a/src/index.tsx b/src/index.tsx index d820cfb..857dc94 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,6 +4,7 @@ export * from "./button"; export * from "./card"; export * from "./colorScheme"; export * from "./config"; +export * from "./confirmationModal"; export * from "./err"; export * from "./errorBox"; export * from "./floating"; From 647595bb34e3361d6a258cbe23cdbac1f53ef737 Mon Sep 17 00:00:00 2001 From: Arnei Date: Fri, 24 May 2024 13:54:16 +0200 Subject: [PATCH 06/19] Fix colors for styled button Added missing colors, changed unused colors. --- src/colors.css | 24 ++++++++++++++++++++++++ src/config.tsx | 18 ++++++------------ src/styledButton.tsx | 22 +++++++++++----------- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/colors.css b/src/colors.css index f57ecad..bea000a 100644 --- a/src/colors.css +++ b/src/colors.css @@ -19,6 +19,12 @@ html[data-color-scheme="light"], html:not([data-color-scheme]) { --color-danger4: #c22a2c; --color-danger5: #880e11; + --color-happy0: #fff; + --color-happy1: #d0e3e7; + --color-happy3: #01758f; + --color-happy4: #015669; + --color-happy5: #013846; + --color-accent9: #044a81; --color-accent8: #215D99; --color-accent7: #3073B8; @@ -51,6 +57,12 @@ html[data-color-scheme="dark"] { --color-danger4: #e0584d; --color-danger5: #fb7c67; + --color-happy0: #013846; + --color-happy1: #015669; + --color-happy3: #759ca4; + --color-happy4: #9bbdc4; + --color-happy5: #d0e3e7; + --color-accent9: #85ace3; --color-accent8: #7da4db; --color-accent7: #588ccd; @@ -83,6 +95,12 @@ html[data-color-scheme="light-high-contrast"] { --color-danger4: #a50613; --color-danger5: #a50613; + --color-happy0: #fff; + --color-happy1: #fff; + --color-happy3: #013846; + --color-happy4: #013846; + --color-happy5: #013846; + --color-accent8: #000099; --color-accent7: #000099; --color-accent6: #000099; @@ -114,6 +132,12 @@ html[data-color-scheme="dark-high-contrast"] { --color-danger4: #eb1722; --color-danger5: #eb1722; + --color-happy0: #000; + --color-happy1: #000; + --color-happy3: #d0e3e7; + --color-happy4: #d0e3e7; + --color-happy5: #d0e3e7; + --color-accent8: #a6ffea; --color-accent7: #a6ffea; --color-accent6: #a6ffea; diff --git a/src/config.tsx b/src/config.tsx index 752c05a..d23593f 100644 --- a/src/config.tsx +++ b/src/config.tsx @@ -28,19 +28,16 @@ export type ColorConfig = { neutral90: string, danger0: string, - danger0BwInverted: string; danger1: string, - danger1BwInverted: string; danger2: string, danger4: string, danger5: string, happy0: string; - happy0BwInverted: string; happy1: string; - happy1BwInverted: string; - happy2: string; - happy2BwInverted: string; + happy3: string; + happy4: string; + happy5: string; accent8: string; accent7: string; @@ -68,19 +65,16 @@ export const DEFAULT_CONFIG: AppkitConfig = { neutral90: "var(--color-neutral90)", danger0: "var(--color-danger0)", - danger0BwInverted: "var(--color-danger0-bw-inverted)", danger1: "var(--color-danger1)", - danger1BwInverted: "var(--color-danger1-bw-inverted)", danger2: "var(--color-danger2)", danger4: "var(--color-danger4)", danger5: "var(--color-danger5)", happy0: "var(--color-happy0)", - happy0BwInverted: "var(--color-happy0-bw-inverted)", happy1: "var(--color-happy1)", - happy1BwInverted: "var(--color-happy1-bw-inverted)", - happy2: "var(--color-happy2)", - happy2BwInverted: "var(--color-happy2-bw-inverted)", + happy3: "var(--color-happy3)", + happy4: "var(--color-happy4)", + happy5: "var(--color-happy5)", accent8: "var(--color-accent8)", accent7: "var(--color-accent7)", diff --git a/src/styledButton.tsx b/src/styledButton.tsx index a6844e5..92c0167 100644 --- a/src/styledButton.tsx +++ b/src/styledButton.tsx @@ -31,24 +31,24 @@ const css = (kind: Kind, extraCss: Interpolation = {}): Interpolation ({ - border: `1px solid ${config.colors.danger0}`, - color: config.colors.danger0, + border: `1px solid ${config.colors.danger4}`, + color: config.colors.danger4, "&:hover, &:focus-visible": { - border: `1px solid ${config.colors.danger1}`, - backgroundColor: config.colors.danger0, - color: config.colors.danger0BwInverted, + border: `1px solid ${config.colors.danger5}`, + backgroundColor: config.colors.danger4, + color: config.colors.danger0, // danger0BwInverted }, ...focusStyle(config, { offset: 1 }), }), "happy": () => ({ - border: `1px solid ${config.colors.happy1}`, - color: config.colors.happy0BwInverted, - backgroundColor: config.colors.happy0, + border: `1px solid ${config.colors.happy4}`, + color: config.colors.happy1, // happy0BwInverted + backgroundColor: config.colors.happy3, "&:hover, &:focus-visible": { - border: `1px solid ${config.colors.happy2}`, - backgroundColor: config.colors.happy1, - color: config.colors.happy1BwInverted, + border: `1px solid ${config.colors.happy5}`, + backgroundColor: config.colors.happy4, + color: config.colors.happy0, // happy1BwInverted }, ...focusStyle(config, { offset: 1 }), }), From 0dca519b153feef1c8d0b28f682a7938280ac453 Mon Sep 17 00:00:00 2001 From: Arnei Date: Tue, 28 May 2024 12:51:38 +0200 Subject: [PATCH 07/19] Various small improvements As suggested by @LukasKalbertodt. Thanks. --- src/confirmationModal.tsx | 14 +++++++------- src/modal.tsx | 7 +++---- src/styledButton.tsx | 5 ++--- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/confirmationModal.tsx b/src/confirmationModal.tsx index 8dd53c1..eb1f2c0 100644 --- a/src/confirmationModal.tsx +++ b/src/confirmationModal.tsx @@ -7,7 +7,7 @@ import { useRef, useImperativeHandle, } from "react"; -import { bug, ModalProps, ModalHandle, Modal, Spinner, Button, boxError } from "."; +import { ModalProps, ModalHandle, Modal, Spinner, Button, boxError } from "."; import { currentRef } from "./utilFunc"; @@ -16,9 +16,9 @@ type ConfirmationModalProps = Omit & { buttonContent: ReactNode; onSubmit?: () => void; text: { - generalActionCancel: string, - generalActionClose: string, - manageAreYouSure: string, + cancel: string, + close: string, + areYouSure: string, }, }; @@ -36,7 +36,7 @@ export const ConfirmationModal text, children, }, ref) => { - const title = titleOverride ?? text.manageAreYouSure ?? bug("missing translation"); + const title = titleOverride ?? text.areYouSure; const [inFlight, setInFlight] = useState(false); const [error, setError] = useState(); @@ -72,7 +72,7 @@ export const ConfirmationModal title={title} closable={!inFlight} ref={modalRef} - text={{ generalActionClose: text.generalActionClose }} + text={text} > {children}
@@ -85,7 +85,7 @@ export const ConfirmationModal , ); + +/** The kind of buttons a "Button" can be. Used for styling */ +export type Kind = "normal" | "danger" | "happy"; + +type ButtonProps = JSX.IntrinsicElements["button"] & { + kind?: Kind; + extraCss?: Interpolation; +}; + +/** A styled button */ +export const Button = React.forwardRef( + ({ kind = "normal", extraCss, children, ...rest }, ref) => ( + + ), +); + +/** + * Returns css for different types of buttons. + * Comes in the kinds "normal", "danger" and "happy". + */ +const css = (kind: Kind, extraCss: Interpolation = {}): Interpolation => { + const config = useAppkitConfig(); + + const notDisabledStyle = match(kind, { + "normal": () => ({ + border: `1px solid ${config.colors.neutral40}`, + color: config.colors.neutral90, + "&:hover, &:focus-visible": { + border: `1px solid ${config.colors.neutral60}`, + backgroundColor: config.colors.neutral15, + }, + }), + + "danger": () => ({ + border: `1px solid ${config.colors.danger4}`, + color: config.colors.danger4, + "&:hover, &:focus-visible": { + border: `1px solid ${config.colors.danger5}`, + backgroundColor: config.colors.danger4, + color: config.colors.danger0, // danger0BwInverted + }, + }), + + "happy": () => ({ + border: `1px solid ${config.colors.happy4}`, + color: config.colors.happy1, // happy0BwInverted + backgroundColor: config.colors.happy3, + "&:hover, &:focus-visible": { + border: `1px solid ${config.colors.happy5}`, + backgroundColor: config.colors.happy4, + color: config.colors.happy0, // happy1BwInverted + }, + }), + + ...focusStyle(config, { offset: -1 }), + }); + + return { + borderRadius: 8, + display: "inline-flex", + alignItems: "center", + padding: "7px 14px", + gap: 12, + whiteSpace: "nowrap", + backgroundColor: config.colors.neutral10, + transition: "background-color 0.15s, border-color 0.15s", + textDecoration: "none", + "& > svg": { + fontSize: 20, + }, + "&:disabled": { + border: `1px solid ${config.colors.neutral25}`, + color: config.colors.neutral40, + }, + "&:not([disabled])": { + cursor: "pointer", + ...notDisabledStyle, + }, + ...extraCss as Record, + }; +}; + +export const buttonStyle = css; diff --git a/src/index.tsx b/src/index.tsx index 8a10afc..d025739 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -12,7 +12,6 @@ export * from "./header"; export * from "./spinner"; export * from "./util"; export * from "./modal"; -export * from "./styledButton"; /** diff --git a/src/styledButton.tsx b/src/styledButton.tsx deleted file mode 100644 index 345b1fe..0000000 --- a/src/styledButton.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { Interpolation, Theme } from "@emotion/react"; -import React from "react"; -import { focusStyle, match, useAppkitConfig } from "."; - -export type Kind = "normal" | "danger" | "happy"; - -type ButtonProps = JSX.IntrinsicElements["button"] & { - kind?: Kind; - extraCss?: Interpolation; -}; - -/** A styled button */ -export const Button = React.forwardRef( - ({ kind = "normal", extraCss, children, ...rest }, ref) => ( - - ), -); - -/** - * Returns css for different types of buttons. - * Comes in the kinds "normal", "danger" and "happy". - */ -const css = (kind: Kind, extraCss: Interpolation = {}): Interpolation => { - const config = useAppkitConfig(); - - const notDisabledStyle = match(kind, { - "normal": () => ({ - border: `1px solid ${config.colors.neutral40}`, - color: config.colors.neutral90, - "&:hover, &:focus-visible": { - border: `1px solid ${config.colors.neutral60}`, - backgroundColor: config.colors.neutral15, - }, - }), - - "danger": () => ({ - border: `1px solid ${config.colors.danger4}`, - color: config.colors.danger4, - "&:hover, &:focus-visible": { - border: `1px solid ${config.colors.danger5}`, - backgroundColor: config.colors.danger4, - color: config.colors.danger0, // danger0BwInverted - }, - }), - - "happy": () => ({ - border: `1px solid ${config.colors.happy4}`, - color: config.colors.happy1, // happy0BwInverted - backgroundColor: config.colors.happy3, - "&:hover, &:focus-visible": { - border: `1px solid ${config.colors.happy5}`, - backgroundColor: config.colors.happy4, - color: config.colors.happy0, // happy1BwInverted - }, - }), - - ...focusStyle(config, { offset: -1 }), - }); - - return { - borderRadius: 8, - display: "inline-flex", - alignItems: "center", - padding: "7px 14px", - gap: 12, - whiteSpace: "nowrap", - backgroundColor: config.colors.neutral10, - transition: "background-color 0.15s, border-color 0.15s", - textDecoration: "none", - "& > svg": { - fontSize: 20, - }, - "&:disabled": { - border: `1px solid ${config.colors.neutral25}`, - color: config.colors.neutral40, - }, - "&:not([disabled])": { - cursor: "pointer", - ...notDisabledStyle, - }, - ...extraCss as Record, - }; -}; - -export const buttonStyle = css; From e876eb837019d63fbfe4c197c732392ce39f5cc8 Mon Sep 17 00:00:00 2001 From: Arnei Date: Tue, 28 May 2024 16:14:35 +0200 Subject: [PATCH 11/19] Fix copy & paste errors --- src/button.tsx | 3 +-- src/confirmationModal.tsx | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/button.tsx b/src/button.tsx index 2682927..e1a424e 100644 --- a/src/button.tsx +++ b/src/button.tsx @@ -75,8 +75,6 @@ const css = (kind: Kind, extraCss: Interpolation = {}): Interpolation = {}): Interpolation, }; diff --git a/src/confirmationModal.tsx b/src/confirmationModal.tsx index 4a7083e..a855980 100644 --- a/src/confirmationModal.tsx +++ b/src/confirmationModal.tsx @@ -18,7 +18,7 @@ type ConfirmationModalProps = Omit & { onSubmit?: () => void; /** Strings that will be displayed in the UI */ text: { - /** Text on the button to close the modal */ + /** Text on the button to cancel the modal */ cancel: string, /** Text on the button to close the modal */ close: string, From 0f22128a53d1463b16adcc79206183275820c638 Mon Sep 17 00:00:00 2001 From: Arnei Date: Tue, 28 May 2024 16:20:36 +0200 Subject: [PATCH 12/19] Make stroke color configurable for spinner Optional, defaults to "currentcolor". --- src/spinner.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/spinner.tsx b/src/spinner.tsx index 1a76f6c..fcd4fc0 100644 --- a/src/spinner.tsx +++ b/src/spinner.tsx @@ -1,15 +1,16 @@ import { keyframes } from "@emotion/react"; import React from "react"; -import { useAppkitConfig } from "."; - type Props = JSX.IntrinsicElements["svg"] & { size?: number | string; + strokeColor?: string, }; -export const Spinner = React.forwardRef(({ size = "1em", ...rest }, ref) => { - const config = useAppkitConfig(); - +export const Spinner = React.forwardRef(({ + size = "1em", + strokeColor = "currentcolor", + ...rest +}, ref) => { return ( (({ size = "1em", . })}`, "& > circle": { fill: "none", - stroke: config.colors.neutral90, + stroke: strokeColor, strokeWidth: 4, strokeDasharray: 83, // 2/3 of circumference strokeLinecap: "round", From d316d89e5a6a045183671c67e350a86f175be9e4 Mon Sep 17 00:00:00 2001 From: Arnei Date: Wed, 29 May 2024 10:54:30 +0200 Subject: [PATCH 13/19] Update happy and inverted colors Based on the advice by @LukasKalbertodt --- src/button.tsx | 18 +++++++++--------- src/colors.css | 44 ++++++++++++++++++++------------------------ src/config.tsx | 32 ++++++++++++++++++++++++-------- 3 files changed, 53 insertions(+), 41 deletions(-) diff --git a/src/button.tsx b/src/button.tsx index e1a424e..7ab4d1d 100644 --- a/src/button.tsx +++ b/src/button.tsx @@ -24,7 +24,7 @@ export const ProtoButton = React.forwardRef = {}): Interpolation ({ - border: `1px solid ${config.colors.happy4}`, - color: config.colors.happy1, // happy0BwInverted - backgroundColor: config.colors.happy3, + "call-to-action": () => ({ + border: `1px solid ${config.colors.happy5}`, + color: config.colors.happy4BwInverted, // happy0BwInverted + backgroundColor: config.colors.happy4, "&:hover, &:focus-visible": { - border: `1px solid ${config.colors.happy5}`, - backgroundColor: config.colors.happy4, - color: config.colors.happy0, // happy1BwInverted + border: `1px solid ${config.colors.happy6}`, + backgroundColor: config.colors.happy5, + color: config.colors.happy5BwInverted, // happy1BwInverted }, }), }); diff --git a/src/colors.css b/src/colors.css index bea000a..c799182 100644 --- a/src/colors.css +++ b/src/colors.css @@ -14,23 +14,22 @@ html[data-color-scheme="light"], html:not([data-color-scheme]) { --color-neutral90: #181818; --color-danger0: #feedeb; + --color-danger0-bw-inverted: #fff; --color-danger1: #ffd2cd; + --color-danger1-bw-inverted: #fff; --color-danger2: #feaba1; --color-danger4: #c22a2c; --color-danger5: #880e11; - --color-happy0: #fff; - --color-happy1: #d0e3e7; - --color-happy3: #01758f; - --color-happy4: #015669; - --color-happy5: #013846; - --color-accent9: #044a81; --color-accent8: #215D99; --color-accent7: #3073B8; --color-accent6: #3E8AD8; + --color-accent6-bw-inverted: #000; --color-accent5: #4DA1F7; + --color-accent5-bw-inverted: #000; --color-accent4: #71B4F9; + --color-accent4-bw-inverted: #000; --color-focus: #215D99; color-scheme: light; @@ -52,23 +51,22 @@ html[data-color-scheme="dark"] { --color-neutral90: #c4c4c4; --color-danger0: #361314; + --color-danger0-bw-inverted: #fff; --color-danger1: #462522; + --color-danger1-bw-inverted: #fff; --color-danger2: #712f2a; --color-danger4: #e0584d; --color-danger5: #fb7c67; - --color-happy0: #013846; - --color-happy1: #015669; - --color-happy3: #759ca4; - --color-happy4: #9bbdc4; - --color-happy5: #d0e3e7; - --color-accent9: #85ace3; --color-accent8: #7da4db; --color-accent7: #588ccd; --color-accent6: #1f72ba; + --color-accent6-bw-inverted: #fff; --color-accent5: #1c619e; + --color-accent5-bw-inverted: #fff; --color-accent4: #195483; + --color-accent4-bw-inverted: #fff; --color-focus: #B8D9FC; color-scheme: dark; @@ -90,22 +88,21 @@ html[data-color-scheme="light-high-contrast"] { --color-neutral90: #000; --color-danger0: #fff; + --color-danger0-bw-inverted: #fff; --color-danger1: #fff; + --color-danger1-bw-inverted: #fff; --color-danger2: #a50613; --color-danger4: #a50613; --color-danger5: #a50613; - --color-happy0: #fff; - --color-happy1: #fff; - --color-happy3: #013846; - --color-happy4: #013846; - --color-happy5: #013846; - --color-accent8: #000099; --color-accent7: #000099; --color-accent6: #000099; + --color-accent6-bw-inverted: #fff; --color-accent5: #000099; + --color-accent5-bw-inverted: #fff; --color-accent4: #000099; + --color-accent4-bw-inverted: #fff; --color-focus: #000099; color-scheme: light; @@ -127,22 +124,21 @@ html[data-color-scheme="dark-high-contrast"] { --color-neutral90: #fff; --color-danger0: #000; + --color-danger0-bw-iInverted: #fff; --color-danger1: #000; + --color-danger1-bw-inverted: #fff; --color-danger2: #eb1722; --color-danger4: #eb1722; --color-danger5: #eb1722; - --color-happy0: #000; - --color-happy1: #000; - --color-happy3: #d0e3e7; - --color-happy4: #d0e3e7; - --color-happy5: #d0e3e7; - --color-accent8: #a6ffea; --color-accent7: #a6ffea; --color-accent6: #a6ffea; + --color-accent6-bw-inverted: #000; --color-accent5: #a6ffea; + --color-accent5-bw-inverted: #000; --color-accent4: #a6ffea; + --color-accent4-bw-inverted: #000; --color-focus: #a6ffea; color-scheme: dark; diff --git a/src/config.tsx b/src/config.tsx index d23593f..f202a10 100644 --- a/src/config.tsx +++ b/src/config.tsx @@ -28,22 +28,30 @@ export type ColorConfig = { neutral90: string, danger0: string, + danger0BwInverted: string, danger1: string, + danger1BwInverted: string, danger2: string, danger4: string, danger5: string, - happy0: string; - happy1: string; - happy3: string; happy4: string; + happy4BwInverted: string; happy5: string; + happy5BwInverted: string; + happy6: string; + happy6BwInverted: string; + happy7: string; + happy8: string; accent8: string; accent7: string; accent6: string; + accent6BwInverted: string; accent5: string; + accent5BwInverted: string; accent4: string; + accent4BwInverted: string; focus: string; }; @@ -65,22 +73,30 @@ export const DEFAULT_CONFIG: AppkitConfig = { neutral90: "var(--color-neutral90)", danger0: "var(--color-danger0)", + danger0BwInverted: "var(--color-danger0-bw-inverted)", danger1: "var(--color-danger1)", + danger1BwInverted: "var(--color-danger1-bw-inverted)", danger2: "var(--color-danger2)", danger4: "var(--color-danger4)", danger5: "var(--color-danger5)", - happy0: "var(--color-happy0)", - happy1: "var(--color-happy1)", - happy3: "var(--color-happy3)", - happy4: "var(--color-happy4)", - happy5: "var(--color-happy5)", + happy4: "var(--color-accent4)", + happy4BwInverted: "var(--color-accent4-bw-inverted)", + happy5: "var(--color-accent5)", + happy5BwInverted: "var(--color-accent5-bw-inverted)", + happy6: "var(--color-accent6)", + happy6BwInverted: "var(--color-accent6-bw-inverted)", + happy7: "var(--color-accent7)", + happy8: "var(--color-accent8)", accent8: "var(--color-accent8)", accent7: "var(--color-accent7)", accent6: "var(--color-accent6)", + accent6BwInverted: "var(--color-accent6-bw-inverted)", accent5: "var(--color-accent5)", + accent5BwInverted: "var(--color-accent5-bw-inverted)", accent4: "var(--color-accent4)", + accent4BwInverted: "var(--color-accent4-bw-inverted)", focus: "var(--color-accent8)", }, From 9ccf24054d20b4392c2391b5bff08ab71b1679f2 Mon Sep 17 00:00:00 2001 From: Arnei Date: Wed, 29 May 2024 11:15:57 +0200 Subject: [PATCH 14/19] Pass appkit config to css function We should not rely on a hook in a function working, so better let the calling component pass it. --- src/button.tsx | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/button.tsx b/src/button.tsx index 7ab4d1d..651fcb1 100644 --- a/src/button.tsx +++ b/src/button.tsx @@ -1,6 +1,6 @@ import React from "react"; import { Interpolation, Theme } from "@emotion/react"; -import { focusStyle, match, useAppkitConfig } from "."; +import { AppkitConfig, focusStyle, match, useAppkitConfig } from "."; /** * A mostly unstyled button used to build buttons. Always use this instead of @@ -33,18 +33,24 @@ type ButtonProps = JSX.IntrinsicElements["button"] & { /** A styled button */ export const Button = React.forwardRef( - ({ kind = "normal", extraCss, children, ...rest }, ref) => ( - - ), + ({ kind = "normal", extraCss, children, ...rest }, ref) => { + const config = useAppkitConfig(); + + return ( + + ); + }, ); /** * Returns css for different types of buttons. * Comes in the kinds "normal", "danger" and "happy". */ -const css = (kind: Kind, extraCss: Interpolation = {}): Interpolation => { - const config = useAppkitConfig(); - +const css = ( + config: AppkitConfig, + kind: Kind, + extraCss: Interpolation = {} +): Interpolation => { const notDisabledStyle = match(kind, { "normal": () => ({ border: `1px solid ${config.colors.neutral40}`, From 07f038541954c95b9fc67c7a5a8e54b8d5c157ac Mon Sep 17 00:00:00 2001 From: Arnei Date: Wed, 29 May 2024 11:57:04 +0200 Subject: [PATCH 15/19] More color fixes --- src/button.tsx | 15 +++++++-------- src/colors.css | 32 +++++++++++++++++++++++++++----- src/config.tsx | 14 ++++++++++++++ 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/button.tsx b/src/button.tsx index 651fcb1..cfdb1f6 100644 --- a/src/button.tsx +++ b/src/button.tsx @@ -44,7 +44,6 @@ export const Button = React.forwardRef( /** * Returns css for different types of buttons. - * Comes in the kinds "normal", "danger" and "happy". */ const css = ( config: AppkitConfig, @@ -67,18 +66,18 @@ const css = ( "&:hover, &:focus-visible": { border: `1px solid ${config.colors.danger5}`, backgroundColor: config.colors.danger4, - color: config.colors.danger0BwInverted, // danger0BwInverted + color: config.colors.danger4BwInverted, }, }), "call-to-action": () => ({ - border: `1px solid ${config.colors.happy5}`, - color: config.colors.happy4BwInverted, // happy0BwInverted - backgroundColor: config.colors.happy4, + border: `1px solid ${config.colors.happy7}`, + color: config.colors.happy6BwInverted, + backgroundColor: config.colors.happy6, "&:hover, &:focus-visible": { - border: `1px solid ${config.colors.happy6}`, - backgroundColor: config.colors.happy5, - color: config.colors.happy5BwInverted, // happy1BwInverted + border: `1px solid ${config.colors.happy8}`, + backgroundColor: config.colors.happy7, + color: config.colors.happy7BwInverted, }, }), }); diff --git a/src/colors.css b/src/colors.css index c799182..330903a 100644 --- a/src/colors.css +++ b/src/colors.css @@ -14,16 +14,22 @@ html[data-color-scheme="light"], html:not([data-color-scheme]) { --color-neutral90: #181818; --color-danger0: #feedeb; - --color-danger0-bw-inverted: #fff; + --color-danger0-bw-inverted: #000; --color-danger1: #ffd2cd; - --color-danger1-bw-inverted: #fff; + --color-danger1-bw-inverted: #000; --color-danger2: #feaba1; + --color-danger2-bw-inverted: #000; --color-danger4: #c22a2c; + --color-danger4-bw-inverted: #fff; --color-danger5: #880e11; + --color-danger5-bw-inverted: #fff; --color-accent9: #044a81; + --color-accent9-bw-inverted: #fff; --color-accent8: #215D99; + --color-accent8-bw-inverted: #fff; --color-accent7: #3073B8; + --color-accent7-bw-inverted: #fff; --color-accent6: #3E8AD8; --color-accent6-bw-inverted: #000; --color-accent5: #4DA1F7; @@ -55,12 +61,18 @@ html[data-color-scheme="dark"] { --color-danger1: #462522; --color-danger1-bw-inverted: #fff; --color-danger2: #712f2a; + --color-danger2-bw-inverted: #fff; --color-danger4: #e0584d; + --color-danger4-bw-inverted: #fff; --color-danger5: #fb7c67; + --color-danger5-bw-inverted: #000; --color-accent9: #85ace3; + --color-accent9-bw-inverted: #000; --color-accent8: #7da4db; + --color-accent8-bw-inverted: #000; --color-accent7: #588ccd; + --color-accent7-bw-inverted: #000; --color-accent6: #1f72ba; --color-accent6-bw-inverted: #fff; --color-accent5: #1c619e; @@ -88,15 +100,20 @@ html[data-color-scheme="light-high-contrast"] { --color-neutral90: #000; --color-danger0: #fff; - --color-danger0-bw-inverted: #fff; + --color-danger0-bw-inverted: #000; --color-danger1: #fff; - --color-danger1-bw-inverted: #fff; + --color-danger1-bw-inverted: #000; --color-danger2: #a50613; + --color-danger2-bw-inverted: #fff; --color-danger4: #a50613; + --color-danger4-bw-inverted: #fff; --color-danger5: #a50613; + --color-danger5-bw-inverted: #fff; --color-accent8: #000099; + --color-accent8-bw-inverted: #fff; --color-accent7: #000099; + --color-accent7-bw-inverted: #fff; --color-accent6: #000099; --color-accent6-bw-inverted: #fff; --color-accent5: #000099; @@ -124,15 +141,20 @@ html[data-color-scheme="dark-high-contrast"] { --color-neutral90: #fff; --color-danger0: #000; - --color-danger0-bw-iInverted: #fff; + --color-danger0-bw-inverted: #fff; --color-danger1: #000; --color-danger1-bw-inverted: #fff; --color-danger2: #eb1722; + --color-danger2-bw-inverted: #fff; --color-danger4: #eb1722; + --color-danger4-bw-inverted: #fff; --color-danger5: #eb1722; + --color-danger5-bw-inverted: #fff; --color-accent8: #a6ffea; + --color-accent8-bw-inverted: #000; --color-accent7: #a6ffea; + --color-accent7-bw-inverted: #000; --color-accent6: #a6ffea; --color-accent6-bw-inverted: #000; --color-accent5: #a6ffea; diff --git a/src/config.tsx b/src/config.tsx index f202a10..4d74102 100644 --- a/src/config.tsx +++ b/src/config.tsx @@ -32,8 +32,11 @@ export type ColorConfig = { danger1: string, danger1BwInverted: string, danger2: string, + danger2BwInverted: string, danger4: string, + danger4BwInverted: string, danger5: string, + danger5BwInverted: string, happy4: string; happy4BwInverted: string; @@ -42,10 +45,14 @@ export type ColorConfig = { happy6: string; happy6BwInverted: string; happy7: string; + happy7BwInverted: string; happy8: string; + happy8BwInverted: string; accent8: string; + accent8BwInverted: string; accent7: string; + accent7BwInverted: string; accent6: string; accent6BwInverted: string; accent5: string; @@ -77,8 +84,11 @@ export const DEFAULT_CONFIG: AppkitConfig = { danger1: "var(--color-danger1)", danger1BwInverted: "var(--color-danger1-bw-inverted)", danger2: "var(--color-danger2)", + danger2BwInverted: "var(--color-danger1-bw-inverted)", danger4: "var(--color-danger4)", + danger4BwInverted: "var(--color-danger1-bw-inverted)", danger5: "var(--color-danger5)", + danger5BwInverted: "var(--color-danger1-bw-inverted)", happy4: "var(--color-accent4)", happy4BwInverted: "var(--color-accent4-bw-inverted)", @@ -87,10 +97,14 @@ export const DEFAULT_CONFIG: AppkitConfig = { happy6: "var(--color-accent6)", happy6BwInverted: "var(--color-accent6-bw-inverted)", happy7: "var(--color-accent7)", + happy7BwInverted: "var(--color-accent6-bw-inverted)", happy8: "var(--color-accent8)", + happy8BwInverted: "var(--color-accent6-bw-inverted)", accent8: "var(--color-accent8)", + accent8BwInverted: "var(--color-accent6-bw-inverted)", accent7: "var(--color-accent7)", + accent7BwInverted: "var(--color-accent6-bw-inverted)", accent6: "var(--color-accent6)", accent6BwInverted: "var(--color-accent6-bw-inverted)", accent5: "var(--color-accent5)", From 2cadf8db118c97c05a92a43ac9e0b3fa259069c4 Mon Sep 17 00:00:00 2001 From: Arnei Date: Wed, 29 May 2024 12:23:24 +0200 Subject: [PATCH 16/19] More color fixes --- src/config.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/config.tsx b/src/config.tsx index 4d74102..79ead11 100644 --- a/src/config.tsx +++ b/src/config.tsx @@ -84,11 +84,11 @@ export const DEFAULT_CONFIG: AppkitConfig = { danger1: "var(--color-danger1)", danger1BwInverted: "var(--color-danger1-bw-inverted)", danger2: "var(--color-danger2)", - danger2BwInverted: "var(--color-danger1-bw-inverted)", + danger2BwInverted: "var(--color-danger2-bw-inverted)", danger4: "var(--color-danger4)", - danger4BwInverted: "var(--color-danger1-bw-inverted)", + danger4BwInverted: "var(--color-danger4-bw-inverted)", danger5: "var(--color-danger5)", - danger5BwInverted: "var(--color-danger1-bw-inverted)", + danger5BwInverted: "var(--color-danger5-bw-inverted)", happy4: "var(--color-accent4)", happy4BwInverted: "var(--color-accent4-bw-inverted)", @@ -97,14 +97,14 @@ export const DEFAULT_CONFIG: AppkitConfig = { happy6: "var(--color-accent6)", happy6BwInverted: "var(--color-accent6-bw-inverted)", happy7: "var(--color-accent7)", - happy7BwInverted: "var(--color-accent6-bw-inverted)", + happy7BwInverted: "var(--color-accent7-bw-inverted)", happy8: "var(--color-accent8)", - happy8BwInverted: "var(--color-accent6-bw-inverted)", + happy8BwInverted: "var(--color-accent8-bw-inverted)", accent8: "var(--color-accent8)", - accent8BwInverted: "var(--color-accent6-bw-inverted)", + accent8BwInverted: "var(--color-accent8-bw-inverted)", accent7: "var(--color-accent7)", - accent7BwInverted: "var(--color-accent6-bw-inverted)", + accent7BwInverted: "var(--color-accent7-bw-inverted)", accent6: "var(--color-accent6)", accent6BwInverted: "var(--color-accent6-bw-inverted)", accent5: "var(--color-accent5)", From 7430e75429f5e184b62c358018ef6ff3e883a30f Mon Sep 17 00:00:00 2001 From: Arnei Date: Wed, 29 May 2024 12:56:39 +0200 Subject: [PATCH 17/19] Add accent9 color --- src/button.tsx | 12 ++++++------ src/colors.css | 4 ++++ src/config.tsx | 8 ++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/button.tsx b/src/button.tsx index cfdb1f6..70b770b 100644 --- a/src/button.tsx +++ b/src/button.tsx @@ -71,13 +71,13 @@ const css = ( }), "call-to-action": () => ({ - border: `1px solid ${config.colors.happy7}`, - color: config.colors.happy6BwInverted, - backgroundColor: config.colors.happy6, + border: `1px solid ${config.colors.happy8}`, + color: config.colors.happy7BwInverted, + backgroundColor: config.colors.happy7, "&:hover, &:focus-visible": { - border: `1px solid ${config.colors.happy8}`, - backgroundColor: config.colors.happy7, - color: config.colors.happy7BwInverted, + border: `1px solid ${config.colors.happy9}`, + backgroundColor: config.colors.happy8, + color: config.colors.happy8BwInverted, }, }), }); diff --git a/src/colors.css b/src/colors.css index 330903a..3e18829 100644 --- a/src/colors.css +++ b/src/colors.css @@ -110,6 +110,8 @@ html[data-color-scheme="light-high-contrast"] { --color-danger5: #a50613; --color-danger5-bw-inverted: #fff; + --color-accent9: #000099; + --color-accent9-bw-inverted: #fff; --color-accent8: #000099; --color-accent8-bw-inverted: #fff; --color-accent7: #000099; @@ -151,6 +153,8 @@ html[data-color-scheme="dark-high-contrast"] { --color-danger5: #eb1722; --color-danger5-bw-inverted: #fff; + --color-accent9: #a6ffea; + --color-accent9-bw-inverted: #000; --color-accent8: #a6ffea; --color-accent8-bw-inverted: #000; --color-accent7: #a6ffea; diff --git a/src/config.tsx b/src/config.tsx index 79ead11..b6684b5 100644 --- a/src/config.tsx +++ b/src/config.tsx @@ -48,7 +48,11 @@ export type ColorConfig = { happy7BwInverted: string; happy8: string; happy8BwInverted: string; + happy9: string; + happy9BwInverted: string; + accent9: string; + accent9BwInverted: string; accent8: string; accent8BwInverted: string; accent7: string; @@ -100,7 +104,11 @@ export const DEFAULT_CONFIG: AppkitConfig = { happy7BwInverted: "var(--color-accent7-bw-inverted)", happy8: "var(--color-accent8)", happy8BwInverted: "var(--color-accent8-bw-inverted)", + happy9: "var(--color-accent9)", + happy9BwInverted: "var(--color-accent9-bw-inverted)", + accent9: "var(--color-accent9)", + accent9BwInverted: "var(--color-accent9-bw-inverted)", accent8: "var(--color-accent8)", accent8BwInverted: "var(--color-accent8-bw-inverted)", accent7: "var(--color-accent7)", From 35f67ad7d49a7d74c0ba6b664115fcb1857d0896 Mon Sep 17 00:00:00 2001 From: Arnei Date: Wed, 29 May 2024 14:24:46 +0200 Subject: [PATCH 18/19] Optimize danger colors for high contrast --- src/colors.css | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/colors.css b/src/colors.css index 3e18829..69c18f5 100644 --- a/src/colors.css +++ b/src/colors.css @@ -62,9 +62,9 @@ html[data-color-scheme="dark"] { --color-danger1-bw-inverted: #fff; --color-danger2: #712f2a; --color-danger2-bw-inverted: #fff; - --color-danger4: #e0584d; - --color-danger4-bw-inverted: #fff; - --color-danger5: #fb7c67; + --color-danger4: #f2685b; + --color-danger4-bw-inverted: #000; + --color-danger5: #ff9581; --color-danger5-bw-inverted: #000; --color-accent9: #85ace3; @@ -146,12 +146,12 @@ html[data-color-scheme="dark-high-contrast"] { --color-danger0-bw-inverted: #fff; --color-danger1: #000; --color-danger1-bw-inverted: #fff; - --color-danger2: #eb1722; - --color-danger2-bw-inverted: #fff; - --color-danger4: #eb1722; - --color-danger4-bw-inverted: #fff; - --color-danger5: #eb1722; - --color-danger5-bw-inverted: #fff; + --color-danger2: #ff9581; + --color-danger2-bw-inverted: #000; + --color-danger4: #ff9581; + --color-danger4-bw-inverted: #000; + --color-danger5: #ff9581; + --color-danger5-bw-inverted: #000; --color-accent9: #a6ffea; --color-accent9-bw-inverted: #000; From b81d3c928448307ceb6e29766d3ea80546748b21 Mon Sep 17 00:00:00 2001 From: Arnei Date: Wed, 29 May 2024 14:40:53 +0200 Subject: [PATCH 19/19] Danger button font bold --- src/button.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/button.tsx b/src/button.tsx index 70b770b..faad70d 100644 --- a/src/button.tsx +++ b/src/button.tsx @@ -1,6 +1,6 @@ import React from "react"; import { Interpolation, Theme } from "@emotion/react"; -import { AppkitConfig, focusStyle, match, useAppkitConfig } from "."; +import { AppkitConfig, focusStyle, match, useAppkitConfig, useColorScheme } from "."; /** * A mostly unstyled button used to build buttons. Always use this instead of @@ -35,9 +35,10 @@ type ButtonProps = JSX.IntrinsicElements["button"] & { export const Button = React.forwardRef( ({ kind = "normal", extraCss, children, ...rest }, ref) => { const config = useAppkitConfig(); + const { isHighContrast } = useColorScheme(); return ( - + ); }, ); @@ -48,6 +49,7 @@ export const Button = React.forwardRef( const css = ( config: AppkitConfig, kind: Kind, + isHighContrast: boolean, extraCss: Interpolation = {} ): Interpolation => { const notDisabledStyle = match(kind, { @@ -63,6 +65,7 @@ const css = ( "danger": () => ({ border: `1px solid ${config.colors.danger4}`, color: config.colors.danger4, + fontWeight: isHighContrast ? "bold" : "inherit", "&:hover, &:focus-visible": { border: `1px solid ${config.colors.danger5}`, backgroundColor: config.colors.danger4,