Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,341 changes: 2,193 additions & 148 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"js-yaml": "^4.1.0",
"oidc-client-ts": "^3.1.0",
"react": "19.0.0",
"react-aria-components": "^1.7.1",
"react-dom": "19.0.0",
"react-error-boundary": "^5.0.0",
"react-hook-form": "^7.54.2",
Expand Down
9 changes: 9 additions & 0 deletions src/@ui-components/Avatar/Avatar.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.avatar {
width: 2rem;
height: 2rem;

padding: 0;
border-radius: 50%;

font-weight: 700;
}
20 changes: 20 additions & 0 deletions src/@ui-components/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Button, ButtonProps } from '../Button/Button.tsx';
import clsx from 'clsx';

import classes from './Avatar.module.css';

export interface AvatarProps extends Omit<ButtonProps, 'children'> {
initials?: string;
}

export function Avatar({ initials, className, ...rest }: AvatarProps) {
return (
<Button
design="primary"
className={clsx(classes.avatar, className)}
{...rest}
>
{initials}
</Button>
);
}
46 changes: 46 additions & 0 deletions src/@ui-components/Button/Button.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.button {
height: 2.25rem;

border: 1px solid;
border-radius: 0.375em;
margin: 0;
padding: 0.5em 0.75em;

font-size: var(--mcp-font-size);

outline: none;


&[data-pressed] {
outline: 2px solid var(--mcp-color-outline-focus);
outline-offset: -1px;
}

&[data-focus-visible] {
outline: 2px solid var(--mcp-color-outline-focus);
outline-offset: -1px;
}


/** Design: Default */
&[data-mcp-button-design="default"] {
background-color: var(--mcp-color-default);
border-color: var(--mcp-color-default-border);
color: var(--mcp-color-text-dark);

&[data-hovered] {
background-color: var(--mcp-color-default-hover);
}
}

/** Design: Primary */
&[data-mcp-button-design="primary"] {
background-color: var(--mcp-color-primary);
border-color: var(--mcp-color-primary-border);
color: var(--mcp-color-white);

&[data-hovered] {
background-color: var(--mcp-color-primary-hover);
}
}
}
29 changes: 29 additions & 0 deletions src/@ui-components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
Button as ButtonBase,
ButtonProps as ButtonBaseProps,
} from 'react-aria-components';

import clsx from 'clsx';

import classes from './Button.module.css';

export interface ButtonProps extends ButtonBaseProps {
design?: 'default' | 'primary';
}

export function Button({
design = 'default',
className,
children,
...rest
}: ButtonProps) {
return (
<ButtonBase
className={clsx(classes.button, className)}
data-mcp-button-design={design}
{...rest}
>
{children}
</ButtonBase>
);
}
18 changes: 18 additions & 0 deletions src/@ui-components/Icon/Icon.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.svg {
width: 1rem;
height: 1rem;

fill: var(--mcp-color-text-dark);

&[data-mcp-icon-design="warning"] {
fill: var(--mcp-color-text-warning);
}

&[data-mcp-icon-design="negative"] {
fill: var(--mcp-color-text-negative);
}

&[data-mcp-icon-design="positive"] {
fill: var(--mcp-color-text-positive);
}
}
31 changes: 31 additions & 0 deletions src/@ui-components/Icon/Icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import IconPaths from './IconPaths.ts';

import classes from './Icon.module.css';
import clsx from 'clsx';

export interface IconProps {
src: keyof typeof IconPaths;
design?: 'neutral' | 'positive' | 'negative' | 'warning';
alt?: string;
className?: string;
}

export function Icon({ design = 'neutral', src, alt, className }: IconProps) {
return (
<svg
className={clsx(classes.svg, className)}
viewBox="0 0 512 512"
role="presentation"
focusable="false"
preserveAspectRatio="xMidYMid meet"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
data-mcp-icon-design={design}
aria-label={alt}
>
<g role="presentation">
<path d={IconPaths[src]?.path} />
</g>
</svg>
);
}
2,486 changes: 2,486 additions & 0 deletions src/@ui-components/Icon/IconPaths.ts

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions src/@ui-components/Menu/Menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { MenuTrigger } from 'react-aria-components';

import { ReactNode } from 'react';

export interface MenuProps {
/** Any button (e.g. `MenuButton` or `Button`) and `MenuList` */
children: ReactNode;
}

export function Menu({ children }: MenuProps) {
return <MenuTrigger>{children}</MenuTrigger>;
}
13 changes: 13 additions & 0 deletions src/@ui-components/Menu/MenuButton.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.menuButton {
display: flex;
}

.inner {
display: flex;
align-items: center;
}

.icon {
width: 1rem;
margin-right: 0.375rem;
}
25 changes: 25 additions & 0 deletions src/@ui-components/Menu/MenuButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Button, ButtonProps } from '../Button/Button.tsx';
import { Icon } from '../Icon/Icon.tsx';
import { ReactNode } from 'react';
import clsx from 'clsx';

import classes from './MenuButton.module.css';

export interface MenuButtonProps extends Omit<ButtonProps, 'children'> {
children?: ReactNode;
}

export function MenuButton({ className, children, ...rest }: MenuButtonProps) {
return (
<Button
className={clsx(classes.menuButton, className)}
aria-label="Menu"
{...rest}
>
<div className={classes.inner}>
<Icon src="navigation-down-arrow" className={classes.icon} />
{children}
</div>
</Button>
);
}
20 changes: 20 additions & 0 deletions src/@ui-components/Menu/MenuItem.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.menuItem {
margin: 0.25rem;
padding: 0.5rem 1rem 0.5rem 0.5rem;
border-radius: 0.25rem;

cursor: default;
align-items: center;

background-color: var(--mcp-color-background);
color: var(--mcp-color-text-dark);

&[data-hovered] {
background-color: var(--mcp-color-background-hover);
}

&[data-focus-visible] {
outline: 2px solid var(--mcp-color-outline-focus);
outline-offset: -1px;
}
}
22 changes: 22 additions & 0 deletions src/@ui-components/Menu/MenuItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {
MenuItem as MenuItemBase,
MenuItemProps as MenuItemPropsBase,
} from 'react-aria-components';

import classes from './MenuItem.module.css';

export interface MenuItemProps extends MenuItemPropsBase {}

export function MenuItem({
textValue: passedTextValue,
children,
...rest
}: MenuItemProps) {
const textValue =
passedTextValue || (typeof children === 'string' ? children : undefined);
return (
<MenuItemBase className={classes.menuItem} {...rest} textValue={textValue}>
{children}
</MenuItemBase>
);
}
5 changes: 5 additions & 0 deletions src/@ui-components/Menu/MenuList.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.menuList {
padding: 0.125rem;
min-width: 10rem;
outline: none;
}
24 changes: 24 additions & 0 deletions src/@ui-components/Menu/MenuList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
Menu as BaseMenu,
MenuProps as BaseMenuProps,
} from 'react-aria-components';

import { Popover } from '../Popover/Popover.tsx';

import classes from './MenuList.module.css';

export interface MenuListProps<T> extends BaseMenuProps<T> {}

export function MenuList<T extends object>({
className,
children,
...rest
}: MenuListProps<T>) {
return (
<Popover offset={2}>
<BaseMenu className={classes.menuList} {...rest}>
{children}
</BaseMenu>
</Popover>
);
}
32 changes: 32 additions & 0 deletions src/@ui-components/Popover/Popover.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.popover {
border: 1px solid var(--mcp-color-default-border);
box-shadow: 0 8px 20px rgba(0 0 0 / 0.1);
border-radius: 6px;
background-color: var(--mcp-color-background);
color: var(--mcp-color-text-dark);
outline: none;
max-width: 250px;
transition: transform 200ms, opacity 200ms;

&[data-entering],
&[data-exiting] {
transform: var(--origin);
opacity: 0;
}

&[data-placement=top] {
--origin: translateY(8px);
}

&[data-placement=bottom] {
--origin: translateY(-8px);
}

&[data-placement=right] {
--origin: translateX(-8px);
}

&[data-placement=left] {
--origin: translateX(8px);
}
}
18 changes: 18 additions & 0 deletions src/@ui-components/Popover/Popover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {
Popover as PopoverBase,
PopoverProps as PopoverBaseProps,
} from 'react-aria-components';

import clsx from 'clsx';

import classes from './Popover.module.css';

export interface PopoverProps extends PopoverBaseProps {}

export function Popover({ className, children, ...rest }: PopoverProps) {
return (
<PopoverBase className={clsx(classes.popover, className)} {...rest}>
{children}
</PopoverBase>
);
}
38 changes: 38 additions & 0 deletions src/@ui-components/Shellbar/Shellbar.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.header {
height: 4rem;

display: flex;
padding: 0 var(--mcp-spacing-content);

background-color: var(--mcp-color-background);
color: var(--mcp-color-text-dark);
}

.inner {
display: flex;
width: 100%;
}

.start {
display: flex;
align-items: center;
}

.center {
flex: 1 1 0;
}

.end {
display: flex;
align-items: center;
}

.logo {
width: auto;
height: 2rem;
margin-right: 0.5rem;
}

.title {
font-weight: 700;
}
Loading