diff --git a/apps/cyberstorm-remix/app/Error.module.css b/apps/cyberstorm-remix/app/Error.module.css index 82747fc0c..0006e9bed 100644 --- a/apps/cyberstorm-remix/app/Error.module.css +++ b/apps/cyberstorm-remix/app/Error.module.css @@ -5,8 +5,8 @@ align-items: center; justify-content: center; - --glitch-color-1: var(--color-cyber-green--50); - --glitch-color-2: var(--color-pink--50); + --glitch-color-1: var(--old--color-cyber-green--50); + --glitch-color-2: var(--old--color-pink--50); } .description { diff --git a/apps/cyberstorm-remix/app/Markdown.module.css b/apps/cyberstorm-remix/app/Markdown.module.css index 8249431df..5ef7478c9 100644 --- a/apps/cyberstorm-remix/app/Markdown.module.css +++ b/apps/cyberstorm-remix/app/Markdown.module.css @@ -96,7 +96,7 @@ color: #f5f5f6; } -.root a { color: var(--color-cyber-green--50); } +.root a { color: var(--old--color-cyber-green--50); } .root blockquote { display: flex; diff --git a/apps/cyberstorm-remix/app/RootLayout.module.css b/apps/cyberstorm-remix/app/RootLayout.module.css index 6a0eb89e5..696c215c6 100644 --- a/apps/cyberstorm-remix/app/RootLayout.module.css +++ b/apps/cyberstorm-remix/app/RootLayout.module.css @@ -18,7 +18,10 @@ .middleContainer { position: relative; + display: flex; flex: 1 1 auto; + flex-direction: column; + gap: 1rem; width: 100%; max-width: 83.5rem; } @@ -36,7 +39,7 @@ } .pageHeader { - padding: 2.5rem 0; + padding: 0; } .pageBody { @@ -72,6 +75,14 @@ .fullWidth { flex: 0 0 100%; } + + .pageHeader { + padding: 2.5rem 0; + } + + .middleContainer { + gap: 0; + } } @media (max-width: 92.125rem) { diff --git a/apps/cyberstorm-remix/app/commonComponents/PackageSearch/CategoryTagCloud/CategoryTagCloud.module.css b/apps/cyberstorm-remix/app/commonComponents/PackageSearch/CategoryTagCloud/CategoryTagCloud.module.css index ff13160cd..c7065d428 100644 --- a/apps/cyberstorm-remix/app/commonComponents/PackageSearch/CategoryTagCloud/CategoryTagCloud.module.css +++ b/apps/cyberstorm-remix/app/commonComponents/PackageSearch/CategoryTagCloud/CategoryTagCloud.module.css @@ -16,8 +16,8 @@ } .tag.exclude { - --text-color: var(--color-red--3); - --bg-color: var(--color-red--10); + --text-color: var(--old--color-red--3); + --bg-color: var(--old--color-red--10); } .icon { @@ -26,5 +26,5 @@ } .tag.exclude .icon { - --text-color: var(--color-red--3); + --text-color: var(--old--color-red--3); } diff --git a/apps/cyberstorm-remix/app/commonComponents/PackageSearch/FilterMenus/CollapsibleMenu.module.css b/apps/cyberstorm-remix/app/commonComponents/PackageSearch/FilterMenus/CollapsibleMenu.module.css index 3004478a4..1b9d47f99 100644 --- a/apps/cyberstorm-remix/app/commonComponents/PackageSearch/FilterMenus/CollapsibleMenu.module.css +++ b/apps/cyberstorm-remix/app/commonComponents/PackageSearch/FilterMenus/CollapsibleMenu.module.css @@ -32,13 +32,13 @@ transition: var(--animation-length-xs); user-select: none; - --mark-color: var(--color-purple--6); + --mark-color: var(--old--color-purple--6); } .label:hover { background-color: var(--color-surface--4); - --mark-color: var(--color-purple--2); + --mark-color: var(--old--color-purple--2); } .checkbox { diff --git a/apps/cyberstorm-remix/app/commonComponents/PackageSearch/FilterMenus/FilterMenu.module.css b/apps/cyberstorm-remix/app/commonComponents/PackageSearch/FilterMenus/FilterMenu.module.css index 6888683a6..2e15a516a 100644 --- a/apps/cyberstorm-remix/app/commonComponents/PackageSearch/FilterMenus/FilterMenu.module.css +++ b/apps/cyberstorm-remix/app/commonComponents/PackageSearch/FilterMenus/FilterMenu.module.css @@ -26,13 +26,13 @@ transition: var(--animation-length-xs); user-select: none; - --mark-color: var(--color-purple--6); + --mark-color: var(--old--color-purple--6); } .label:hover { background-color: var(--color-surface--4); - --mark-color: var(--color-purple--2); + --mark-color: var(--old--color-purple--2); } .checkbox { diff --git a/apps/cyberstorm-remix/app/communities/Communities.module.css b/apps/cyberstorm-remix/app/communities/Communities.module.css new file mode 100644 index 000000000..02b3df9cf --- /dev/null +++ b/apps/cyberstorm-remix/app/communities/Communities.module.css @@ -0,0 +1,5 @@ +@media (max-width: 40rem) { + .breadcrumbs { + display: none; + } +} diff --git a/apps/cyberstorm-remix/app/communities/SearchAndOrder.module.css b/apps/cyberstorm-remix/app/communities/SearchAndOrder.module.css index edb61d3d8..7a4f589e3 100644 --- a/apps/cyberstorm-remix/app/communities/SearchAndOrder.module.css +++ b/apps/cyberstorm-remix/app/communities/SearchAndOrder.module.css @@ -6,46 +6,45 @@ } .searchTextInput { + display: flex; + flex-direction: column; + gap: var(--space--8); width: 50%; } -.searchFilters { - display: flex; - flex: 0 1 auto; - gap: var(--gap--16); - align-items: center; - justify-content: flex-end; +.searchInput { + max-width: 26.25rem; } -.searchFiltersSortLabel { - color: var(--color-text--tertiary); - font-weight: var(--font-weight-bold); +.searchFilters { + display: flex; + flex-direction: column; + gap: var(--space--8); white-space: nowrap; } -.skeletonSearch { - height: 2.75rem; -} - -.skeletonSort { - width: 13rem; - height: 2.75rem; -} - @media (max-width: 40rem) { - .searchTextInput { - width: 100%; - } - .root { flex-direction: column; } - .searchFiltersSortLabel { + .searchTextInput { + width: 100%; + } + + .searchTextInput > span { display: none; } .searchFilters { width: 100%; } + + .searchFilters > span { + display: none; + } + + .searchInput { + max-width: 100%; + } } diff --git a/apps/cyberstorm-remix/app/communities/communities.tsx b/apps/cyberstorm-remix/app/communities/communities.tsx index e0ede8140..e8749de82 100644 --- a/apps/cyberstorm-remix/app/communities/communities.tsx +++ b/apps/cyberstorm-remix/app/communities/communities.tsx @@ -1,14 +1,17 @@ import type { LoaderFunctionArgs, MetaFunction } from "@remix-run/node"; import { - BreadCrumbs, - CommunityCard, + Container, + CardCommunity, CommunityCardSkeleton, EmptyState, - Select, - TextInput, + Heading, + NewBreadCrumbs, range, + NewTextInput, + NewSelect, } from "@thunderstore/cyberstorm"; import rootStyles from "../RootLayout.module.css"; +import styles from "./Communities.module.css"; import searchAndOrderStyles from "./SearchAndOrder.module.css"; import communitiesListStyles from "./CommunityList.module.css"; import { useState, useEffect } from "react"; @@ -25,9 +28,8 @@ import { useNavigation, useSearchParams, } from "@remix-run/react"; -import { Communities } from "@thunderstore/dapper/types"; +import { Communities, Community } from "@thunderstore/dapper/types"; import { getDapper } from "cyberstorm/dapper/sessionUtils"; -import { PageHeader } from "~/commonComponents/PageHeader/PageHeader"; export const meta: MetaFunction = () => { return [ @@ -115,32 +117,42 @@ export default function CommunitiesPage() { return ( <> - Communities + + Communities +
- + + Communities +
-
+
- Search + setSearchValue(e.target.value)} value={searchValue} placeholder="Search communities..." clearValue={() => setSearchValue("")} leftIcon={} + csColor="cyber-green" + rootClasses={searchAndOrderStyles.searchInput} />
-
- Sort by -
- + {children} + + {clearValue && fProps.value !== "" ? ( + clearValue()} + rootClasses={styles.clearValueButton} + tooltipText="Clear" + tooltipSide="left" + csColor={csColor} + csVariant={"default"} + aria-label="Clear search input" + > + + + + + ) : null} + + ); + } +); + +TextInput.displayName = "TextInput"; diff --git a/packages/cyberstorm/src/primitiveComponents/Actionable/Actionable.tsx b/packages/cyberstorm/src/primitiveComponents/Actionable/Actionable.tsx new file mode 100644 index 000000000..86717d9ae --- /dev/null +++ b/packages/cyberstorm/src/primitiveComponents/Actionable/Actionable.tsx @@ -0,0 +1,125 @@ +import { + CyberstormLink, + CyberstormLinkIds, +} from "../../components/Links/Links"; +import React from "react"; +import { ThunderstoreLinkProps } from "../../components/Links/LinkingProvider"; +import { PrimitiveComponentDefaultProps, TooltipWrapper } from "../utils/utils"; +import { classnames } from "../../utils/utils"; + +export interface ActionableButtonProps + extends React.ButtonHTMLAttributes, + PrimitiveComponentDefaultProps { + primitiveType: "button"; +} + +export interface ActionableLinkProps + extends React.AnchorHTMLAttributes, + PrimitiveComponentDefaultProps { + primitiveType: "link"; + href: string; +} + +export interface ActionableCyberstormLinkProps + extends React.AnchorHTMLAttributes, + PrimitiveComponentDefaultProps, + ThunderstoreLinkProps { + primitiveType: "cyberstormLink"; + linkId: CyberstormLinkIds; +} + +export const Actionable = React.forwardRef< + HTMLButtonElement | HTMLAnchorElement, + ActionableButtonProps | ActionableLinkProps | ActionableCyberstormLinkProps +>( + ( + props: + | ActionableButtonProps + | ActionableLinkProps + | ActionableCyberstormLinkProps, + forwardedRef + ) => { + const { + children, + primitiveType, + rootClasses, + csColor, + csVariant, + csSize, + csTextStyles, + tooltipText, + tooltipSide, + ...forwardedProps + } = props; + + if (primitiveType === "button") { + const fRef = forwardedRef as React.ForwardedRef; + const fProps = forwardedProps as ActionableButtonProps; + + return ( + + + + ); + } + if (primitiveType === "link") { + const fRef = forwardedRef as React.ForwardedRef; + const fProps = forwardedProps as ActionableLinkProps; + return ( + + + {children} + + + ); + } + if (primitiveType === "cyberstormLink") { + const fRef = forwardedRef as React.ForwardedRef; + const { linkId, ...strippedForwardedProps } = + forwardedProps as ActionableCyberstormLinkProps; + return ( + + + {children} + + + ); + } + return

Errored actionable

; + } +); + +Actionable.displayName = "Actionable"; diff --git a/packages/cyberstorm/src/primitiveComponents/Frame/Display.module.css b/packages/cyberstorm/src/primitiveComponents/Frame/Display.module.css new file mode 100644 index 000000000..6c001498a --- /dev/null +++ b/packages/cyberstorm/src/primitiveComponents/Frame/Display.module.css @@ -0,0 +1,37 @@ +.display { + font-weight: 700; + font-family: inter, sans-serif; + font-style: normal; + line-height: normal; +} + +.display[data-stylelevel="1"] { + font-weight: var(--font-weight-heavy); + font-size: calc(var(--space--54) * var(--scaling, 1)); + font-family: Hubot-Sans, sans-serif; + line-height: 115%; /* 62.1px */ +} + +.display[data-stylelevel="2"] { + font-weight: var(--font-weight-heavy); + font-size: calc(var(--space--51) * var(--scaling, 1)); + font-family: Hubot-Sans, sans-serif; +} + +.display[data-stylelevel="3"] { + font-weight: 700; + font-size: calc(var(--space--38) * var(--scaling, 1)); + font-family: Hubot-Sans, sans-serif; +} + +.display[data-stylelevel="4"] { + font-size: calc(var(--space--16) * var(--scaling, 1)); +} + +.display[data-stylelevel="5"] { + font-size: calc(var(--space--14) * var(--scaling, 1)); +} + +.display[data-stylelevel="6"] { + font-size: calc(var(--space--12) * var(--scaling, 1)); +} diff --git a/packages/cyberstorm/src/primitiveComponents/Frame/Frame.tsx b/packages/cyberstorm/src/primitiveComponents/Frame/Frame.tsx new file mode 100644 index 000000000..79d0a8d29 --- /dev/null +++ b/packages/cyberstorm/src/primitiveComponents/Frame/Frame.tsx @@ -0,0 +1,490 @@ +import popooverStyles from "./Popover.module.css"; +import modalStyles from "./Modal.module.css"; +import headingStyles from "./Heading.module.css"; +import displayStyles from "./Display.module.css"; +import iconStyles from "./Icon.module.css"; +import { classnames } from "./../../utils/utils"; +import React from "react"; +import { PrimitiveComponentDefaultProps, TooltipWrapper } from "../utils/utils"; +import { Children, cloneElement } from "react"; + +export interface FrameWindowProps + extends React.HTMLAttributes, + PrimitiveComponentDefaultProps { + primitiveType: "window"; +} + +export interface FrameListProps + extends React.HTMLAttributes, + PrimitiveComponentDefaultProps { + primitiveType: "list"; +} + +export interface FrameListItemProps + extends React.HTMLAttributes, + PrimitiveComponentDefaultProps { + primitiveType: "listItem"; +} + +// TODO: Turn this into the new "attachable window", used for dropdowns etc +export interface FrameFloaterProps extends PrimitiveComponentDefaultProps { + primitiveType: "floater"; +} + +export interface FrameHeadingProps + extends React.HTMLAttributes, + PrimitiveComponentDefaultProps { + primitiveType: "heading"; + csStyleLevel: "1" | "2" | "3" | "4" | "5" | "6"; + csLevel: "1" | "2" | "3" | "4" | "5" | "6"; +} + +export interface FrameDisplayProps + extends React.HTMLAttributes, + PrimitiveComponentDefaultProps { + primitiveType: "display"; + csStyleLevel: "1" | "2" | "3" | "4" | "5" | "6"; + csLevel: "1" | "2" | "3" | "4" | "5" | "6"; +} + +export interface FrameTextProps + extends React.HTMLAttributes, + PrimitiveComponentDefaultProps { + primitiveType: "text"; +} + +export interface FramePopoverProps + extends React.HTMLAttributes, + PrimitiveComponentDefaultProps { + primitiveType: "popover"; + popoverId: string; + wrapperClasses?: string; + noWrapper?: boolean; +} + +export interface FrameModalProps + extends React.HTMLAttributes, + PrimitiveComponentDefaultProps { + primitiveType: "modal"; + popoverId: string; + wrapperClasses?: string; + noWrapper?: boolean; +} + +export interface FrameIconProps + extends React.HTMLAttributes, + Omit { + children?: JSX.Element | JSX.Element[]; + primitiveType: "icon"; + wrapperClasses?: string; + noWrapper?: boolean; + csMode?: "default" | "inline"; +} + +export const Frame = React.forwardRef< + | HTMLDivElement + | HTMLUListElement + | HTMLLIElement + | HTMLHeadingElement + | HTMLParagraphElement + | HTMLSpanElement + | SVGElement, + | FrameWindowProps + | FrameListProps + | FrameListItemProps + | FrameFloaterProps + | FrameHeadingProps + | FrameDisplayProps + | FrameTextProps + | FramePopoverProps + | FrameModalProps + | FrameIconProps +>( + ( + props: + | FrameWindowProps + | FrameListProps + | FrameListItemProps + | FrameFloaterProps + | FrameHeadingProps + | FrameDisplayProps + | FrameTextProps + | FramePopoverProps + | FrameModalProps + | FrameIconProps, + forwardedRef + ) => { + const { + children, + primitiveType, + csTextStyles, + csColor, + csVariant, + csSize, + rootClasses, + tooltipText, + tooltipSide, + ...forwardedProps + } = props; + if (primitiveType === "window") { + const fRef = forwardedRef as React.ForwardedRef; + const fProps = forwardedProps as FrameWindowProps; + return ( + +
+ {children} +
+
+ ); + } + if (primitiveType === "list") { + const fRef = forwardedRef as React.ForwardedRef; + const fProps = forwardedProps as FrameListProps; + return ( + +
    + {children} +
+
+ ); + } + if (primitiveType === "listItem") { + const fRef = forwardedRef as React.ForwardedRef; + const fProps = forwardedProps as FrameListItemProps; + return ( + +
  • + {children} +
  • +
    + ); + } + if (primitiveType === "heading" || primitiveType == "display") { + const fRef = forwardedRef as React.ForwardedRef; + const { csLevel, csStyleLevel, ...strippedForwardedProps } = + forwardedProps as FrameHeadingProps | FrameDisplayProps; + const primitiveStyles = + primitiveType === "heading" + ? headingStyles.heading + : displayStyles.display; + let element; + if (csLevel === "1") { + element = ( +

    + {children} +

    + ); + } else if (csLevel === "2") { + element = ( +

    + {children} +

    + ); + } else if (csLevel === "3") { + element = ( +

    + {children} +

    + ); + } else if (csLevel === "4") { + element = ( +

    + {children} +

    + ); + } else if (csLevel === "5") { + element = ( +
    + {children} +
    + ); + } else if (csLevel === "6") { + element = ( +
    + {children} +
    + ); + } + return ( + + {element} + + ); + } + if (primitiveType === "text") { + const fRef = forwardedRef as React.ForwardedRef; + const textProps = forwardedProps as FrameTextProps; + return ( + +

    + {children} +

    +
    + ); + } + if (primitiveType === "popover") { + const fRef = forwardedRef as React.ForwardedRef; + const { + wrapperClasses, + popoverId, + noWrapper, + ...strippedForwardedProps + } = forwardedProps as FramePopoverProps; + return ( + +
    + {noWrapper ? ( + children + ) : ( +
    {children}
    + )} +
    +
    + ); + } + if (primitiveType === "modal") { + const fRef = forwardedRef as React.ForwardedRef; + const { + wrapperClasses, + popoverId, + noWrapper, + ...strippedForwardedProps + } = forwardedProps as FrameModalProps; + return ( + +
    + {noWrapper ? ( + children + ) : ( +
    +
    {children}
    +
    + )} +
    +
    + ); + } + if (primitiveType === "icon") { + if (!children) { + return null; + } + + const { wrapperClasses, noWrapper, csMode, ...strippedForwardedProps } = + forwardedProps as FrameIconProps; + + let svgFProps: (Partial & React.Attributes) | null | undefined = + null; + if (noWrapper) { + svgFProps = { ...strippedForwardedProps }; + } + + const svgIconRef = forwardedRef as React.ForwardedRef; + + const clones = Children.map(children, (child) => + cloneElement(child, { + className: classnames( + child.props.className, + iconStyles.icon, + noWrapper && csMode === "inline" ? iconStyles.inline : null, + ...(csTextStyles ? csTextStyles : []), + rootClasses + ), + ref: noWrapper ? svgIconRef : null, + "data-color": csColor ? csColor : null, + "data-variant": csVariant ? csVariant : null, + "data-size": csSize ? csSize : null, + ...svgFProps, + }) + ); + + let content = null; + + if (noWrapper) { + content = <>{clones}; + } else if (csMode === "inline") { + const spanIconRef = forwardedRef as React.ForwardedRef; + content = ( + + {clones} + + ); + } else { + const divIconRef = forwardedRef as React.ForwardedRef; + content = ( +
    + {clones} +
    + ); + } + + return ( + + {content} + + ); + } + return

    Errored frame

    ; + } +); + +Frame.displayName = "Frame"; diff --git a/packages/cyberstorm/src/primitiveComponents/Frame/Heading.module.css b/packages/cyberstorm/src/primitiveComponents/Frame/Heading.module.css new file mode 100644 index 000000000..c2879194d --- /dev/null +++ b/packages/cyberstorm/src/primitiveComponents/Frame/Heading.module.css @@ -0,0 +1,34 @@ +.heading { + font-weight: 700; + font-family: inter, sans-serif; + font-style: normal; + line-height: normal; +} + +.heading[data-stylelevel="1"] { + font-weight: var(--font-weight-heavy); + font-size: var(--space--54); + font-family: Hubot-Sans, sans-serif; + line-height: 115%; /* 62.1px */ +} + +.heading[data-stylelevel="2"] { + font-size: var(--space--32); + line-height: 140%; /* 44.8px */ +} + +.heading[data-stylelevel="3"] { + font-size: var(--space--20); +} + +.heading[data-stylelevel="4"] { + font-size: var(--space--16); +} + +.heading[data-stylelevel="5"] { + font-size: var(--space--14); +} + +.heading[data-stylelevel="6"] { + font-size: var(--space--12); +} diff --git a/packages/cyberstorm/src/primitiveComponents/Frame/Icon.module.css b/packages/cyberstorm/src/primitiveComponents/Frame/Icon.module.css new file mode 100644 index 000000000..a1c870b71 --- /dev/null +++ b/packages/cyberstorm/src/primitiveComponents/Frame/Icon.module.css @@ -0,0 +1,26 @@ +/* Wrapper, not necessary */ +.iconWrapper { + display: flex; + align-items: center; + justify-content: center; +} + +.iconWrapper svg, +.icon { + display: flex; + + flex-shrink: 0; + fill: currentcolor; + stroke: currentcolor; + block-size: 100%; + inline-size: auto; + min-inline-size: 100%; + + stroke-width: 0; +} + +.inline { + display: inline-flex; + height: 1em; + min-inline-size: 1em; +} diff --git a/packages/cyberstorm/src/primitiveComponents/Frame/Modal.module.css b/packages/cyberstorm/src/primitiveComponents/Frame/Modal.module.css new file mode 100644 index 000000000..153dadbb9 --- /dev/null +++ b/packages/cyberstorm/src/primitiveComponents/Frame/Modal.module.css @@ -0,0 +1,18 @@ +.modal { + width: 100%; + height: 100%; + background: rgba(0 0 0 / 0.6); + backdrop-filter: blur(10px); +} + +.modal[data-size="s"] { + --frame-modal-gap: 1rem; + --frame-modal-padding: 1.5rem 2.25rem; + --frame-modal-border-radius: 0.25rem; +} + +.modal[data-size="m"] { + --frame-modal-gap: 2rem; + --frame-modal-padding: 3rem 5.5rem; + --frame-modal-border-radius: 0.5rem; +} diff --git a/packages/cyberstorm/src/primitiveComponents/Frame/Popover.module.css b/packages/cyberstorm/src/primitiveComponents/Frame/Popover.module.css new file mode 100644 index 000000000..f53e14f40 --- /dev/null +++ b/packages/cyberstorm/src/primitiveComponents/Frame/Popover.module.css @@ -0,0 +1,11 @@ +.popover[data-size="s"] { + --frame-popover-gap: 1rem; + --frame-popover-padding: 1.5rem 2.25rem; + --frame-popover-border-radius: 0.25rem; +} + +.popover[data-size="m"] { + --frame-popover-gap: 2rem; + --frame-popover-padding: 3rem 5.5rem; + --frame-popover-border-radius: 0.5rem; +} diff --git a/packages/cyberstorm/src/primitiveComponents/Input/Input.tsx b/packages/cyberstorm/src/primitiveComponents/Input/Input.tsx new file mode 100644 index 000000000..9228ff19f --- /dev/null +++ b/packages/cyberstorm/src/primitiveComponents/Input/Input.tsx @@ -0,0 +1,52 @@ +import React from "react"; +import { PrimitiveComponentDefaultProps, TooltipWrapper } from "../utils/utils"; +import { classnames } from "../../utils/utils"; + +export interface InputTextInputProps + extends React.InputHTMLAttributes, + PrimitiveComponentDefaultProps { + primitiveType: "textInput"; +} + +export const Input = React.forwardRef( + (props: InputTextInputProps, forwardedRef) => { + const { + children, + primitiveType, + rootClasses, + csTextStyles, + csColor, + csVariant, + csSize, + tooltipText, + tooltipSide, + ...forwardedProps + } = props; + + if (primitiveType === "textInput") { + const fRef = forwardedRef as React.ForwardedRef; + const fProps = forwardedProps as InputTextInputProps; + + return ( + + + {children} + + + ); + } + return

    Errored Input

    ; + } +); + +Input.displayName = "Input"; diff --git a/packages/cyberstorm/src/primitiveComponents/utils/utils.tsx b/packages/cyberstorm/src/primitiveComponents/utils/utils.tsx new file mode 100644 index 000000000..4233eb6df --- /dev/null +++ b/packages/cyberstorm/src/primitiveComponents/utils/utils.tsx @@ -0,0 +1,65 @@ +import { PropsWithChildren } from "react"; +import { Tooltip } from "../.."; + +export type variants = + | "default" + | "primary" + | "secondary" + | "tertiary" + | "accent" + | "special"; +export type colors = + | "surface" + | "surface-alpha" + | "blue" + | "pink" + | "red" + | "orange" + | "green" + | "yellow" + | "purple" + | "cyber-green"; +export type sizes = "xxs" | "xs" | "s" | "m" | "l"; + +const textStyleOptions = [ + "lineHeightAuto", + "lineHeightBody", + "fontSizeXXS", + "fontSizeXS", + "fontSizeS", + "fontSizeM", + "fontSizeL", + "fontWeightRegular", + "fontWeightMedium", + "fontWeightSemiBold", + "fontWeightBold", + "fontFamilyInter", + "fontFamilyHubot", +] as const; + +// eslint-disable-next-line prettier/prettier +export type TextStyles = typeof textStyleOptions[number]; + +interface TooltipWrapperProps extends PropsWithChildren { + tooltipText?: string; + tooltipSide?: "bottom" | "left" | "right" | "top"; +} + +export interface PrimitiveComponentDefaultProps + extends PropsWithChildren, + TooltipWrapperProps { + csColor?: colors; + csVariant?: variants; + csSize?: sizes; + csTextStyles?: TextStyles[]; + rootClasses?: string; +} + +export const TooltipWrapper = (props: TooltipWrapperProps) => + props.tooltipText ? ( + + {props.children} + + ) : ( + <>{props.children} + ); diff --git a/packages/cyberstorm/src/sharedComponentStyles/ButtonStyles/Button.module.css b/packages/cyberstorm/src/sharedComponentStyles/ButtonStyles/Button.module.css new file mode 100644 index 000000000..482be211c --- /dev/null +++ b/packages/cyberstorm/src/sharedComponentStyles/ButtonStyles/Button.module.css @@ -0,0 +1,187 @@ +/* Common Button styles */ +.button { + display: flex; + flex: none; + flex-direction: row; + + gap: var(--button-gap); + align-items: center; + + height: var(--button-height); + + padding: var(--button-padding); + border: var(--button-border); + + border-radius: var(--button-border-radius); + color: var(--button-color); + + text-align: center; + background-color: var(--button-bg-color); + user-select: none; +} + +.button:where(:not(:focus)) { + transition: var(--button-animation-length); + + --button-animation-length: ease-in-out var(--animation-length-s); +} + +/* Button variants */ + +/* default */ + +.button[data-variant="default"] { + --button-color: var(--color-11); + --button-bg-color: var(--color-4); +} + +.button[data-variant="default"]:hover { + --button-bg-color: var(--color-3); +} + +.button[data-variant="default"]:active { + --button-bg-color: var(--color-2); +} + +/* primary */ + +.button[data-variant="primary"] { + --button-color: var(--color-text--default); + --button-bg-color: var(--color-surface--10); +} + +.button[data-variant="primary"]:hover { + --button-bg-color: var(--color-surface--10--hover); +} + +.button[data-variant="primary"]:active { + background-color: var(--button-bg-color-active); +} + +/* secondary */ + +.button[data-variant="secondary"] { + --button-color: var(--color-text--default); + --button-bg-color: var(--color-6); +} + +.button[data-variant="secondary"]:hover { + --button-bg-color: var(--color-7); +} + +.button[data-variant="secondary"]:active { + --button-bg-color: var(--color-5); +} + +/* tertiary */ + +.button[data-variant="tertiary"] { + --button-color: var(--color-text--default); + --button-bg-color: transparent; +} + +.button[data-variant="tertiary"]:hover { + --button-bg-color: var(--color-6); +} + +.button[data-variant="tertiary"]:active { + --button-bg-color: var(--color-5); +} + +/* accent */ + +.button[data-variant="accent"] { + --button-color: var(--color-2); + --button-bg-color: var(--color-7); +} + +.button[data-variant="accent"]:hover { + --button-bg-color: var(--color-9); +} + +.button[data-variant="accent"]:active { + --button-bg-color: var(--color-6); +} + +/* special */ + +.button[data-variant="special"] { + border: 2px solid transparent; + background: + linear-gradient( + 284deg, + hsl(275deg 64% 11% / 1) 0%, + hsl(156deg 46% 12% / 1) 100% + ) padding-box, + linear-gradient( + 284deg, + hsl(276deg 77% 54% / 1) 0%, + hsl(158deg 100% 57% / 1) 100% + ) border-box; +} + +.button[data-variant="special"]:hover { + background: + linear-gradient( + 284deg, + hsl(203deg 80% 21% / 1) 0%, + hsl(155deg 46% 23% / 1) 100% + ) padding-box, + linear-gradient( + 284deg, + hsl(154deg 65% 67% / 1) 0%, + hsl(203deg 92% 63% / 1) 100% + ) border-box; +} + +.button[data-variant="special"]:active { + background: + linear-gradient( + 284deg, + hsl(203deg 80% 21% / 1) 0%, + hsl(155deg 46% 23% / 1) 100% + ) padding-box, + linear-gradient( + 284deg, + hsl(154deg 65% 67% / 1) 0%, + hsl(203deg 92% 63% / 1) 100% + ) border-box; +} + +/* Button sizes */ + +/* xs */ + +.button[data-size="xs"] { + --button-height: var(--space--30); + --button-padding: var(--space--12); + --button-gap: var(--gap--16); + --button-border-radius: var(--border-radius--8); +} + +/* s */ + +.button[data-size="s"] { + --button-height: var(--space--36); + --button-padding: var(--space--12); + --button-gap: var(--gap--16); + --button-border-radius: var(--border-radius--8); +} + +/* m */ + +.button[data-size="m"] { + --button-height: var(--space--44); + --button-padding: var(--space--12) var(--space--16); + --button-gap: var(--gap--16); + --button-border-radius: var(--border-radius--8); +} + +/* l */ + +.button[data-size="l"] { + --button-height: var(--space--44); + --button-padding: var(--space--12) var(--space--16); + --button-gap: var(--gap--16); + --button-border-radius: var(--border-radius--8); +} diff --git a/packages/cyberstorm/src/sharedComponentStyles/TagStyles/Tag.module.css b/packages/cyberstorm/src/sharedComponentStyles/TagStyles/Tag.module.css new file mode 100644 index 000000000..47f196a42 --- /dev/null +++ b/packages/cyberstorm/src/sharedComponentStyles/TagStyles/Tag.module.css @@ -0,0 +1,60 @@ +.tag { + display: inline-flex; + align-items: center; + justify-content: center; + color: var(--tag-color); + background: var(--tag-background-color); + + --tag-color: var(--color-primary); + --tag-background-color: var(--color-primary); +} + +.tag[data-variant="default"] { + --tag-color: var(--color-1); + --tag-background-color: var(--color-7); +} + +.tag[data-variant="default"].hoverable:hover { + --tag-background-color: var(--color-8); +} + +.tag[data-variant="default"].dark { + --tag-color: var(--color-9); + --tag-background-color: var(--color-2); +} + +.tag[data-variant="default"].dark.hoverable:hover { + --tag-background-color: var(--color-3); +} + +/* As surface color has different text color, override here */ + +.tag[data-variant="default"][data-color="surface"] { + --tag-color: var(--color-primary); + --tag-background-color: var(--color-9); +} + +.tag[data-variant="default"][data-color="surface"].hoverable:hover { + --tag-background-color: hsl(240deg 44% 55% / 1); +} + +.tag[data-variant="default"][data-color="surface"].dark { + --tag-color: var(--color-primary); + --tag-background-color: var(--color-surface-alpha--8); +} + +.tag[data-variant="default"][data-color="surface"].dark.hoverable:hover { + --tag-background-color: var(--color-surface-alpha--9); +} + +.tag[data-size="m"] { + gap: var(--space--8); + padding: var(--space--6) var(--border-radius--8); + border-radius: var(--border-radius--8); +} + +.tag[data-size="s"] { + gap: var(--gap--4); + padding: var(--space--4) var(--space--6); + border-radius: var(--border-radius--6); +} diff --git a/packages/cyberstorm/src/utils/utils.ts b/packages/cyberstorm/src/utils/utils.ts index dd0130244..5d832ab40 100644 --- a/packages/cyberstorm/src/utils/utils.ts +++ b/packages/cyberstorm/src/utils/utils.ts @@ -3,8 +3,11 @@ export const range = (start: number, end: number) => { return Array.from({ length }, (_, idx) => idx + start); }; -export const formatInteger = (inputNumber: number) => { - return Intl.NumberFormat("en", { notation: "compact" }).format(inputNumber); +export const formatInteger = ( + inputNumber: number, + notation: "standard" | "scientific" | "engineering" | "compact" = "compact" +) => { + return Intl.NumberFormat("en", { notation: notation }).format(inputNumber); }; export const numberWithSpaces = (x: number) => {