Skip to content

Commit

Permalink
✨ feat(ui): improve grid styles (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
thrownullexception authored Jun 20, 2024
1 parent ee13ae9 commit a3d07c9
Show file tree
Hide file tree
Showing 39 changed files with 1,040 additions and 1,331 deletions.
632 changes: 609 additions & 23 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.1.0",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
Expand Down Expand Up @@ -97,7 +98,6 @@
"react-quill": "^2.0.0",
"react-select": "^5.3.2",
"react-simple-code-editor": "^0.11.0",
"react-tooltip": "^5.7.4",
"react-use": "^17.4.0",
"redis": "^4.4.0",
"styled-components": "^6.1.8",
Expand Down
11 changes: 11 additions & 0 deletions src/__tests__/_/setupGlobals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,14 @@ Object.defineProperty(window, "matchMedia", {
});

export {};

window.ResizeObserver =
window.ResizeObserver ||
jest.fn().mockImplementation(() => ({
disconnect: jest.fn(),
observe: jest.fn(),
unobserve: jest.fn(),
}));

const scrollIntoViewMock = jest.fn();
window.HTMLElement.prototype.scrollIntoView = scrollIntoViewMock;
2 changes: 1 addition & 1 deletion src/__tests__/account/logout.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe("pages/account/logout", () => {
);

await userEvent.click(
await screen.findByRole("button", { name: "Log Out" })
await screen.findByRole("option", { name: "Log Out" })
);

await waitFor(() => {
Expand Down
4 changes: 3 additions & 1 deletion src/components/app/button/soft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ export function SoftButton({
) : (
<div className="flex gap-2 w-auto items-center">
<SystemIcon icon={systemIcon} className="w-[14px] h-[14px]" />
<span className="whitespace-nowrap">{labelString}</span>
<span className="whitespace-nowrap hidden md:inline-block">
{labelString}
</span>
</div>
);

Expand Down
2 changes: 2 additions & 0 deletions src/components/app/button/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ export interface IGroupActionButton extends IActionButton {
export interface IMenuActionItem extends IGroupActionButton {
subtle?: boolean;
destructive?: boolean;
active?: boolean;
secondaryAction?: () => void;
}
21 changes: 7 additions & 14 deletions src/components/app/content-layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
import { ReactElement, ReactNode } from "react";
import styled from "styled-components";
import { BREAKPOINTS } from "@/frontend/design-system/constants";

interface IProps {
children: ReactNode;
}

export const GridRoot = styled.div`
display: grid;
grid-gap: 16px;
grid-template-columns: 2fr 8fr;
@media (max-width: ${BREAKPOINTS.md}) {
grid-template-columns: 1fr;
}
`;

type TContentLayout = ((params: IProps) => ReactElement) & {
Left: (params: IProps) => ReactElement;
Right: (params: IProps) => ReactElement;
Expand All @@ -23,16 +12,20 @@ type TContentLayout = ((params: IProps) => ReactElement) & {

// eslint-disable-next-line react/function-component-definition
export const ContentLayout: TContentLayout = ({ children }: IProps) => {
return <GridRoot>{children}</GridRoot>;
return (
<div className="grid gap-4 grid-cols-1 md:grid-cols-[2fr,8fr]">
{children}
</div>
);
};

ContentLayout.Left = function SectionLeft({ children }: IProps) {
return <div className="mb-3 flex flex-col gap-3">{children}</div>;
return <div className="flex flex-col gap-3">{children}</div>;
};

ContentLayout.Right = function SectionRight({ children }: IProps) {
return (
<div className="overflow-x-hidden min-h-[calc(100vh-100px)] mb-3 flex flex-col gap-3">
<div className="overflow-x-hidden min-h-[calc(100vh-100px)] mb-2 flex flex-col gap-3">
{children}
</div>
);
Expand Down
40 changes: 24 additions & 16 deletions src/components/app/drop-drop-menu/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useState, useEffect, useMemo } from "react";
import { ChevronDown, MoreVertical } from "react-feather";

import { Button } from "@/components/ui/button";
import {
DropdownMenu,
Expand All @@ -11,31 +10,43 @@ import { useToggle } from "@/frontend/hooks/state/useToggleState";
import { MenuSection } from "@/components/app/menu-section";
import { IMenuActionItem } from "../button/types";
import { SoftButton } from "../button/soft";
import { cn } from "@/lib/utils";

export interface IProps {
menuItems: IMenuActionItem[];
ariaLabel: string;
disabled?: boolean;
ellipsis?: true;
contentClassName?: string;
className?: string;
}

export function DropDownMenu({
menuItems: menuItems$1,
ellipsis,
ariaLabel,
contentClassName,
className,
}: IProps) {
const menuItems = useMemo(() => {
return [...menuItems$1].sort((a, b) => {
return (a.order || 0) - (b.order || 0);
});
}, [menuItems$1]);

const [currentMenuItem, setCurrentMenuItem] = useState<IMenuActionItem>(
menuItems?.[0]
menuItems$1[0]
);

const menuItems: IMenuActionItem[] = useMemo(() => {
return [...menuItems$1]
.sort((a, b) => {
return (a.order || 0) - (b.order || 0);
})
.map((menuItem) => {
return {
...menuItem,
secondaryAction: () => {
setCurrentMenuItem(menuItem);
},
};
});
}, [menuItems$1]);

useEffect(() => {
setCurrentMenuItem(menuItems[0]);
}, [JSON.stringify(menuItems)]);
Expand All @@ -48,12 +59,6 @@ export function DropDownMenu({
return <SoftButton {...currentMenuItem} />;
}

// TODO
// const onMenuItemClick = (menuIndex: number) => {
// const menuItem = menuItems[menuIndex];
// setCurrentMenuItem(menuItem);
// };

const { isOn: isOpen, toggle } = useToggle(false);

return (
Expand Down Expand Up @@ -81,8 +86,11 @@ export function DropDownMenu({
</Button>
)}
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0 border-0" onClick={toggle}>
<MenuSection menuItems={menuItems$1} size="sm" />
<DropdownMenuContent
className={cn("p-0 border-0", contentClassName)}
onClick={toggle}
>
<MenuSection menuItems={menuItems} size="sm" />
</DropdownMenuContent>
</DropdownMenu>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/app/form/input/Stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { TestProviders } from "__tests__/_/Provider";
import { FormInput } from "./text";
import { FormNumberInput } from "./number";
import { FormRichTextArea } from "../../../../frontend/design-system/components/Form/RichText";
import { FormDateInput } from "../../../../frontend/design-system/components/Form/Date";
import { FormTextArea } from "./textarea";
import {
FormMultiSelect,
Expand All @@ -24,6 +23,7 @@ import { DELETE_BUTTON_PROPS } from "../../button/constants";
import { FormPasswordInput } from "./password";
import { FormButton } from "../../button/form";
import { ActionButtons } from "../../button/action";
import { FormDateInput } from "./date";

function DemoForm() {
return (
Expand Down
138 changes: 138 additions & 0 deletions src/components/app/form/input/date.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { FieldMetaState } from "react-final-form";
import * as React from "react";
import { format } from "date-fns";
import { Calendar as CalendarIcon } from "react-feather";
import { Trans, msg } from "@lingui/macro";
import {
LabelAndError,
generateClassNames,
generateFormArias,
} from "@/components/app/form/input/label-and-error";
import { ISharedFormInput } from "@/components/app/form/input/types";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { SoftButton } from "@/components/app/button/soft";
import { useToggle } from "@/frontend/hooks/state/useToggleState";

interface IFormDateInput extends ISharedFormInput {
minDate?: Date;
maxDate?: Date;
}

interface IProps {
minDate?: Date;
maxDate?: Date;
onChange: (value: Date | null) => void;
value: Date;
id?: string;
disabled?: boolean;
className?: string;
meta?: FieldMetaState<any>;
}

export const dateWithoutTimezone = (date: Date) => {
const tzoffset = date.getTimezoneOffset() * 60000; // offset in milliseconds
const withoutTimezone = new Date(date.valueOf() - tzoffset)
.toISOString()
.slice(0, -1);
return new Date(withoutTimezone);
};

export function ControlledFormDateInput({
minDate,
maxDate,
onChange,
value,
id,
disabled,
className,
meta,
}: IProps) {
const isOpen = useToggle();

const onChangeRemoveTimeZone = (inputValue: Date | null) => {
onChange(dateWithoutTimezone(inputValue));
};

return (
<Popover onOpenChange={isOpen.set}>
<PopoverTrigger asChild>
<Button
variant="ghost"
className={cn(
"input-base h-9 justify-start text-sm",
{
"ring-1 ring-primary": isOpen.isOn,
},
generateClassNames(meta),
className
)}
id={id}
disabled={disabled}
{...generateFormArias(meta)}
>
<CalendarIcon
className={cn("mr-2 h-4 w-4", {
"text-muted": !value,
})}
/>
{value ? (
format(new Date(value), "PPP")
) : (
<span className="text-muted">
<Trans>Pick a date </Trans>
</span>
)}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Calendar
mode="single"
selected={value}
onSelect={onChangeRemoveTimeZone}
initialFocus
fromDate={minDate}
toDate={maxDate}
footer={
<SoftButton
systemIcon="Close"
action={() => onChange(null)}
label={msg`Clear`}
className="w-full mt-3"
size="sm"
disabled={!value}
/>
}
/>
</PopoverContent>
</Popover>
);
}
// TODO fix date
export function FormDateInput(formInput: IFormDateInput) {
const { input, disabled, meta, minDate, maxDate } = formInput;
let { value } = input;
if (value && typeof value === "string") {
value = new Date(value);
input.onChange(value);
}
return (
<LabelAndError formInput={formInput}>
<ControlledFormDateInput
onChange={input.onChange}
value={value}
id={input.name}
minDate={minDate}
maxDate={maxDate}
meta={meta}
disabled={disabled}
/>
</LabelAndError>
);
}
2 changes: 1 addition & 1 deletion src/components/app/form/schema/_RenderFormInput.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { FormSelect } from "frontend/design-system/components/Form/Select";
import { FormDateInput } from "frontend/design-system/components/Form/Date";
import { AsyncFormSelect } from "frontend/design-system/components/Form/Select/Async";
import { FormCodeEditor } from "frontend/design-system/components/Form/CodeEditor";
import { FormFileInput } from "frontend/design-system/components/Form/File";
Expand All @@ -13,6 +12,7 @@ import { FormSelectButton } from "../input/select-button";
import { FormPasswordInput } from "../input/password";
import { FormTextArea } from "../input/textarea";
import { FormSwitch } from "../input/switch";
import { FormDateInput } from "../input/date";

export function RenderFormInput(props: IRenderFormInputProps) {
const {
Expand Down
10 changes: 2 additions & 8 deletions src/components/app/form/schema/form-grid.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { gridItem, gridRoot } from "frontend/design-system/constants/grid";
import { gridItem } from "frontend/design-system/constants/grid";
import { ReactNode } from "react";
import { GridSpanSizes } from "shared/types/ui";
import styled from "styled-components";

const Root = styled.div`
${gridRoot}
grid-auto-rows: auto;
align-items: center;
`;

// TOOD fix
const Container = styled.div`
// container-type: inline-size;
Expand All @@ -17,7 +11,7 @@ const Container = styled.div`
export const FormGrid = {
Root: ({ children }: { children: ReactNode }) => (
<Container>
<Root>{children}</Root>
<div className="grid-root auto-rows-auto items-center">{children}</div>
</Container>
),
Item: styled.div<{
Expand Down
Loading

0 comments on commit a3d07c9

Please sign in to comment.