chore(ui): small design adjustments@@ -17,12 +17,13 @@ export const Chip = styled.div<WithThemeSchemeProp & { color?: string }>`
font-weight: bold;
text-transform: uppercase;
+ text-decoration: none !important;
color: ${color
- ? Color(color).alpha(1).toString()
+ ? Color(color).alpha(1).lightness(0.3).toString()
: NamedColors.TEXT_DEFAULT[themeScheme]};
background-color: ${color
- ? Color(color).alpha(0.3).toString()
+ ? Color(color).alpha(0.2).toString()
: "rgba(0, 0, 0, 0.3)"};
border-radius: 8px;
`};
@@ -10,6 +10,7 @@ import {
type CommonViewProps,
type WithThemeSchemeProp,
} from "../types";
+import { useMediaQuery } from "../utils/hooks/useMediaQuery";
import { buildRouteLink } from "../utils/shared";
import { AppRoute } from "../routes.defs";
// app components
@@ -73,12 +74,17 @@ export const DrawerPrimary = ({
repoSlug: repoSlug,
});
+ // const isMobile = useMediaQuery("sm");
+ // if (isMobile === false) {
+ // visible = true;
+ // }
+
if (visible === false) {
return null;
}
return (
- <StyledDrawerPrimary themeScheme={themeScheme}>
+ <StyledDrawerPrimary id="drawer" themeScheme={themeScheme}>
<StyledDrawerHeader>
<StyledLogoArea themeScheme={themeScheme}>
<a href={"/"}>
@@ -122,6 +128,7 @@ export const DrawerPrimary = ({
padding: "2px 6px",
backgroundColor: "rgba(0,0,0,0.1)",
fontSize: 11,
+ color: NamedColors.TEXT_MUTED[themeScheme],
}}
>
{counters.watchers || "0"}
@@ -137,6 +144,7 @@ export const DrawerPrimary = ({
padding: "2px 6px",
backgroundColor: "rgba(0,0,0,0.1)",
fontSize: 11,
+ color: NamedColors.TEXT_MUTED[themeScheme],
}}
>
{counters.likes || "0"}
@@ -152,6 +160,7 @@ export const DrawerPrimary = ({
padding: "2px 6px",
backgroundColor: "rgba(0,0,0,0.1)",
fontSize: 11,
+ color: NamedColors.TEXT_MUTED[themeScheme],
}}
>
{counters.forks || "0"}
@@ -173,6 +182,7 @@ export const DrawerPrimary = ({
? "active"
: undefined
}
+ style={{ paddingRight: 16 }}
>
<span>Files</span>
<FolderIcon
@@ -276,8 +286,22 @@ const StyledDrawerPrimary = styled.aside<
background: ${NamedColors.HEADER[themeScheme]};
border-right: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]};
- @media only screen and (max-width: 768px) {
+ @media only screen and (max-width: 386px) {
display: none;
+
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ z-index: 1000;
+ width: 85vw;
+ max-width: 320px;
+ transform: translateX(-100%);
+
+ &:target {
+ transform: translateX(0);
+ transition: transform 0.3s ease-in-out;
+ }
}
`};
`;
@@ -11,6 +11,7 @@ import {
type WithThemeSchemeProp,
} from "../types";
import { buildRouteLink } from "../utils/shared";
+import { useMediaQuery } from "../utils/hooks/useMediaQuery";
import { AppRoute } from "../routes.defs";
import { KeyIcon } from "./icons/KeyIcon";
import { SupportIcon } from "./icons/SupportIcon";
@@ -48,6 +49,11 @@ export const DrawerSettings = ({
{ encodeURIComponent: false },
);
+ // const isMobile = useMediaQuery("sm");
+ // if (isMobile === false) {
+ // visible = true;
+ // }
+
if (visible === false) {
return null;
}
@@ -55,7 +61,7 @@ export const DrawerSettings = ({
console.log("counters:", counters);
return (
- <StyledDrawerSettings themeScheme={themeScheme}>
+ <StyledDrawerSettings id="drawer" themeScheme={themeScheme}>
<StyledDrawerHeader>
<StyledLogoArea themeScheme={themeScheme}>
<a href={"/"}>
@@ -173,8 +179,22 @@ const StyledDrawerSettings = styled.aside<
background: ${NamedColors.HEADER[themeScheme]};
border-right: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]};
- @media only screen and (max-width: 768px) {
+ @media only screen and (max-width: 386px) {
display: none;
+
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ z-index: 1000;
+ width: 85vw;
+ max-width: 320px;
+ transform: translateX(-100%);
+
+ &.target {
+ transform: translateX(0);
+ transition: transform 0.3s ease-in-out;
+ }
}
`};
`;
@@ -17,7 +17,7 @@ const BRANDLINE_HEIGHT = 4;
const HEADER_HEIGHT = 64;
// Default Layout implementation.
-// (dataloading happens through HOC at export level lower in file)
+// (dataloading happens in request context and pass through common props)
const LayoutComponent: FC<LayoutProps & WithThemeSchemeProp> = (props) => {
const {
appVersion,
@@ -93,26 +93,30 @@ const LayoutComponent: FC<LayoutProps & WithThemeSchemeProp> = (props) => {
<InstantRouterIndicator />
</div>
<StyledPageWrapper>
- <DrawerPrimary
- commonProps={props as any}
- themeScheme={themeScheme}
- visible={drawerPrimaryOpen}
- counters={layoutCounters}
- orgSlug={orgSlug}
- repoSlug={repoSlug}
- currentRef={currentRef}
- path={path}
- />
- <DrawerSettings
- commonProps={props as any}
- themeScheme={themeScheme}
- visible={drawerSettingsOpen}
- counters={layoutCounters}
- username={username!}
- />
+ {showDrawerPrimary && (
+ <DrawerPrimary
+ commonProps={props as any}
+ themeScheme={themeScheme}
+ visible={drawerPrimaryOpen}
+ counters={layoutCounters}
+ orgSlug={orgSlug}
+ repoSlug={repoSlug}
+ currentRef={currentRef}
+ path={path}
+ />
+ )}
+ {showDrawerSettings && (
+ <DrawerSettings
+ commonProps={props as any}
+ themeScheme={themeScheme}
+ visible={drawerSettingsOpen}
+ counters={layoutCounters}
+ username={username!}
+ />
+ )}
<StyledChildrenWrapper
{...sharedProps}
- showDrawerPrimary={drawerPrimaryOpen}
+ showDrawerPrimary={drawerPrimaryOpen || drawerSettingsOpen}
>
<StyledPageHeaderWrapper {...sharedProps}>
<PageHeader
@@ -24,19 +24,19 @@ export const PageHeader: VFC<PageHeaderProps & WithThemeSchemeProp> = ({
commonProps,
themeScheme,
forceShowLogo = true,
- setDrawerPrimaryOpen = undefined,
- setDrawerSettingsOpen = undefined,
+ // setDrawerPrimaryOpen = undefined,
+ // setDrawerSettingsOpen = undefined,
}) => {
const invertThemeScheme = themeScheme === "light" ? "dark" : "light";
- const toggleDrawerPrimary = () => {
- if (setDrawerPrimaryOpen) {
- setDrawerPrimaryOpen((prev) => !prev);
- }
- if (setDrawerSettingsOpen) {
- setDrawerSettingsOpen((prev) => !prev);
- }
- };
+ // const toggleDrawerPrimary = () => {
+ // if (setDrawerPrimaryOpen) {
+ // setDrawerPrimaryOpen((prev) => !prev);
+ // }
+ // if (setDrawerSettingsOpen) {
+ // setDrawerSettingsOpen((prev) => !prev);
+ // }
+ // };
const pageHeaderActions = useMemo(() => {
if (commonProps.authenticated) {
@@ -86,7 +86,8 @@ export const PageHeader: VFC<PageHeaderProps & WithThemeSchemeProp> = ({
<PageWrapper style={{ gap: 12 }}>
<StyledBurgerMenu
themeScheme={themeScheme}
- onClick={toggleDrawerPrimary}
+ // onClick={toggleDrawerPrimary}
+ href="#drawer"
>
<BurgerMenuIcon
color={NamedColors.TEXT_DEFAULT[themeScheme]}
@@ -102,6 +103,7 @@ export const PageHeader: VFC<PageHeaderProps & WithThemeSchemeProp> = ({
<a
aria-label={"Explore Repositories"}
href={buildRouteLink(AppRoute.REPOSITORY_EXPLORE, null)}
+ style={{ minWidth: 88 }}
className={
commonProps.path ===
buildRouteLink(AppRoute.REPOSITORY_EXPLORE, null)
@@ -174,12 +176,14 @@ export const PageHeader: VFC<PageHeaderProps & WithThemeSchemeProp> = ({
);
};
-const StyledBurgerMenu = styled.button<WithThemeSchemeProp>`
+const StyledBurgerMenu = styled.a<WithThemeSchemeProp>`
${({ themeScheme }) => css`
display: flex;
justify-content: center;
align-items: center;
+ text-decoration: none;
+
/* above mobile size */
@media only screen and (min-width: 768px) {
& {
@@ -193,8 +193,8 @@ const RepositoryTreeView: ReactIsland<
</Grid.Row>
<Grid.Row nowrap alignItems={"center"}>
<GitCommmitIcon
- color={NamedColors.TEXT_DEFAULT[themeScheme]}
- size={24}
+ color={NamedColors.TEXT_MUTED[themeScheme]}
+ size={20}
/>
<a
style={{ minWidth: "max-content" }}
@@ -29,6 +29,7 @@ const Colors = {
PURPLE_01: "#23014D",
CYAN_01: "#1B8F97",
RED_01: "red",
+ GREEN_01: "green",
};
export default Colors;
@@ -0,0 +1,134 @@
+type ColorParam =
+ | Color
+ | string
+ | ArrayLike<number>
+ | number
+ | { [key: string]: any };
+
+interface Color<T extends ColorParam = ColorParam> {
+ toString(): string;
+ toJSON(): Color<T>;
+ string(places?: number): string;
+ percentString(places?: number): string;
+ array(): number[];
+ object(): { alpha?: number | undefined } & { [key: string]: number };
+ unitArray(): number[];
+ unitObject(): { r: number; g: number; b: number; alpha?: number | undefined };
+ round(places?: number): Color;
+ alpha(): number;
+ alpha(val: number): Color;
+ red(): number;
+ red(val: number): Color;
+ green(): number;
+ green(val: number): Color;
+ blue(): number;
+ blue(val: number): Color;
+ hue(): number;
+ hue(val: number): Color;
+ saturationl(): number;
+ saturationl(val: number): Color;
+ lightness(): number;
+ lightness(val: number): Color;
+ saturationv(): number;
+ saturationv(val: number): Color;
+ value(): number;
+ value(val: number): Color;
+ chroma(): number;
+ chroma(val: number): Color;
+ gray(): number;
+ gray(val: number): Color;
+ white(): number;
+ white(val: number): Color;
+ wblack(): number;
+ wblack(val: number): Color;
+ cyan(): number;
+ cyan(val: number): Color;
+ magenta(): number;
+ magenta(val: number): Color;
+ yellow(): number;
+ yellow(val: number): Color;
+ black(): number;
+ black(val: number): Color;
+ x(): number;
+ x(val: number): Color;
+ y(): number;
+ y(val: number): Color;
+ z(): number;
+ z(val: number): Color;
+ l(): number;
+ l(val: number): Color;
+ a(): number;
+ a(val: number): Color;
+ b(): number;
+ b(val: number): Color;
+ keyword(): string;
+ keyword<V extends string>(val: V): Color<V>;
+ hex(): string;
+ hex<V extends string>(val: V): Color<V>;
+ hexa(): string;
+ hexa<V extends string>(val: V): Color<V>;
+ rgbNumber(): number;
+ luminosity(): number;
+ contrast(color2: Color): number;
+ level(color2: Color): "AAA" | "AA" | "";
+ isDark(): boolean;
+ isLight(): boolean;
+ negate(): Color;
+ lighten(ratio: number): Color;
+ darken(ratio: number): Color;
+ saturate(ratio: number): Color;
+ desaturate(ratio: number): Color;
+ whiten(ratio: number): Color;
+ blacken(ratio: number): Color;
+ grayscale(): Color;
+ fade(ratio: number): Color;
+ opaquer(ratio: number): Color;
+ rotate(degrees: number): Color;
+ mix(mixinColor: Color, weight?: number): Color;
+
+ rgb(...args: number[]): Color;
+ hsl(...args: number[]): Color;
+ hsv(...args: number[]): Color;
+ hwb(...args: number[]): Color;
+ cmyk(...args: number[]): Color;
+ xyz(...args: number[]): Color;
+ lab(...args: number[]): Color;
+ lch(...args: number[]): Color;
+ ansi16(...args: number[]): Color;
+ ansi256(...args: number[]): Color;
+ hcg(...args: number[]): Color;
+ apple(...args: number[]): Color;
+}
+
+interface ColorConstructor {
+ <T extends ColorParam>(obj?: T, model?: string): Color<T>;
+ new <T extends ColorParam>(obj?: T, model?: string): Color<T>;
+ rgb(...val: number[]): Color;
+ rgb(color: ColorParam): Color;
+ hsl(...val: number[]): Color;
+ hsl(color: ColorParam): Color;
+ hsv(...val: number[]): Color;
+ hsv(color: ColorParam): Color;
+ hwb(...val: number[]): Color;
+ hwb(color: ColorParam): Color;
+ cmyk(...val: number[]): Color;
+ cmyk(color: ColorParam): Color;
+ xyz(...val: number[]): Color;
+ xyz(color: ColorParam): Color;
+ lab(...val: number[]): Color;
+ lab(color: ColorParam): Color;
+ lch(...val: number[]): Color;
+ lch(color: ColorParam): Color;
+ ansi16(...val: number[]): Color;
+ ansi16(color: ColorParam): Color;
+ ansi256(...val: number[]): Color;
+ ansi256(color: ColorParam): Color;
+ hcg(...val: number[]): Color;
+ hcg(color: ColorParam): Color;
+ apple(...val: number[]): Color;
+ apple(color: ColorParam): Color;
+}
+
+declare const Color: ColorConstructor;
+
+export = Color;
@@ -13,7 +13,7 @@ import { Grid } from "../../components/Grid";
import { Layout } from "../../components/Layout";
import { PageWrapper } from "../../components/PageWrapper";
import { buildRouteLink } from "../../utils/shared";
-import { NamedColors } from "../../utils/style";
+import { Colors, NamedColors } from "../../utils/style";
// app islands
import { IslandWrapper } from "../../components/IslandWrapper.styled";
import RepositoryHero from "../../islands/RepositoryHero";
@@ -158,18 +158,15 @@ const RepositoryPullRequestsView: ReactView<
</Grid.Col>
<Grid.Col fluid gap={4} style={{ marginTop: 12 }}>
{pullRequests != null && pullRequests.length >= 1 ? (
- pullRequests.map((pr, idx) => (
+ pullRequests.map((pr) => (
<Card
key={pr.id}
themeScheme={commonProps.themeScheme}
- style={{ width: "100%" }}
+ style={{ width: "100%", padding: 8 }}
>
- <Grid.Col
- key={pr.id}
- fluid
- style={{ marginTop: idx === 0 ? 0 : 16 }}
- >
+ <Grid.Col fluid>
<a
+ style={{ width: "100%" }}
href={buildRouteLink(
AppRoute.REPOSITORY_PULL_REQUEST_DETAILS,
{
@@ -179,21 +176,61 @@ const RepositoryPullRequestsView: ReactView<
},
)}
>
- #{pr.uid} - {pr.summary} [{pr.state}]
+ <Grid.Row fluid alignItems={"center"} gap={4}>
+ <span>#{pr.uid}</span>
+ <span>•</span>
+ <span style={{ flex: 1 }}>{pr.summary}</span>
+ <Chip
+ themeScheme={commonProps.themeScheme}
+ color={
+ {
+ OPEN: Colors.PRIMARY_01,
+ CLOSE_MERGED: Colors.GREEN_01,
+ CLOSE_DENIED: Colors.RED_01,
+ }[pr.state]
+ }
+ >
+ {
+ {
+ OPEN: "Open",
+ CLOSE_MERGED: "Merged",
+ CLOSE_DENIED: "Closed",
+ }[pr.state]
+ }
+ </Chip>
+ </Grid.Row>
</a>
- <span style={{ opacity: 0.67 }}>
- wants to merge <code>{pr.sourceBranch}</code> into{" "}
- <code>{pr.targetBranch}</code>
- </span>
<Grid.Row
fluid
+ nowrap
+ gap={8}
alignItems={"center"}
+ style={{ opacity: 0.67 }}
+ >
+ wants to merge{" "}
+ <Chip
+ themeScheme={commonProps.themeScheme}
+ style={{ textTransform: "none" }}
+ >
+ <code>{pr.sourceBranch}</code>
+ </Chip>
+ into{" "}
+ <Chip
+ themeScheme={commonProps.themeScheme}
+ style={{ textTransform: "none" }}
+ >
+ <code>{pr.targetBranch}</code>
+ </Chip>
+ </Grid.Row>
+ <Grid.Col
+ fluid
+ gap={4}
style={{ opacity: 0.67, marginTop: 4 }}
>
{new Date(pr.createdAt).getTime() <=
new Date(pr.updatedAt).getTime() && (
<span>
- opened on {new Date(pr.createdAt).toLocaleString()}
+ {`opened on ${new Date(pr.createdAt).toLocaleString()}`}
</span>
)}
{((pr.closedAt == null &&
@@ -203,16 +240,15 @@ const RepositoryPullRequestsView: ReactView<
new Date(pr.updatedAt).getTime() <
new Date(pr.closedAt).getTime())) && (
<span>
- updated on {new Date(pr.updatedAt).toLocaleString()}
+ {`updated on ${new Date(pr.updatedAt).toLocaleString()}`}
</span>
)}
{pr.closedAt != null && (
<span>
- closed on
- {new Date(pr.closedAt).toLocaleString()}
+ {`closed on ${new Date(pr.closedAt).toLocaleString()}`}
</span>
)}
- </Grid.Row>
+ </Grid.Col>
</Grid.Col>
</Card>
))
@@ -45,7 +45,7 @@ const SettingsView: ReactView<SettingsViewProps> = ({
/>
</IslandWrapper>
<Grid.Col fluid nowrap gap={24} style={{ marginTop: 16 }}>
- <Grid.Col fluid nowrap gap={12}>
+ <Grid.Col fluid nowrap gap={4}>
{sshKeys.map((key, idx) => (
<IslandWrapper
key={key.id}