Skip to content

Commit

Permalink
Replacing Primary+ SeconaryButton with AcitonButton. (#313)
Browse files Browse the repository at this point in the history
Co-authored-by: Sigrid <[email protected]>
Co-authored-by: Mathilde Haukø Haugum <[email protected]>
Co-authored-by: Mathilde Haukø Haugum <[email protected]>
  • Loading branch information
4 people authored Nov 23, 2023
1 parent f602093 commit 169eff9
Show file tree
Hide file tree
Showing 19 changed files with 369 additions and 82 deletions.
4 changes: 2 additions & 2 deletions frontend/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import SecondaryButton from "@/components/SecondaryButton";
import ActionButton from "@/components/Buttons/ActionButton";
import { fetchWithToken } from "@/data/apiCallsWithToken";
import { Organisation } from "@/types";
import Link from "next/link";
Expand All @@ -10,7 +10,7 @@ export default async function Root() {
{orgs.map((o) => (
<li key={o.urlKey}>
<Link href={`/${o.urlKey}/bemanning`}>
<SecondaryButton label={o.name} />
<ActionButton variant="secondary">{o.name}</ActionButton>
</Link>
</li>
))}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/ActiveFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function ActiveFilters() {
return (
<div className="h-4">
{filterSummaryText != "" && (
<div className="flex flex-row gap-[5px] text-primary_default items-center">
<div className="flex flex-row gap-3 text-primary items-center">
<Filter size="12" />{" "}
<p className="small-medium"> {filterSummaryText} </p>
</div>
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/BaseModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { RefObject } from "react";
export interface BaseModalProps {
children: React.ReactNode;
modalRef: RefObject<HTMLDialogElement>;
classNames?: string;
}

function BaseModal(props: BaseModalProps) {
const { children, modalRef } = props;
const { children, modalRef, classNames } = props;

return (
<dialog ref={modalRef} className="rounded-lg p-4">
<dialog ref={modalRef} className={`rounded-lg p-4 ${classNames}`}>
{children}
</dialog>
);
Expand Down
56 changes: 56 additions & 0 deletions frontend/src/components/Buttons/ActionButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from "react";
import BaseButton from "./BaseButton";
import { IconBox } from "./IconBox";

export type ActionButtonProps = {
variant: "primary" | "secondary" | "terniary";
iconLeft?: React.ReactNode;
iconRight?: React.ReactNode;
small?: boolean;
fullWidth?: true;
onClick?: () => void;
disabled?: true;
children?: React.ReactNode;
className?: string;
isIconBtn?: true;
};

export default function ActionButton({
variant,
iconLeft,
iconRight,
small,
fullWidth,
disabled,
onClick,
children,
className = "",
isIconBtn,
}: ActionButtonProps) {
const variantClass =
{
primary:
"bg-primary text-white hover:bg-primary_darker hover:border-primary_darker",
secondary:
"bg-white text-primary border border-primary/50 hover:bg-primary/10 hover:border-primary",
terniary:
"bg-white text-primary hover:bg-primary/10 hover:border-primary",
}[variant] ?? "Default";

const disabledClass = disabled ? "bg-opacity-50" : "";
const fullWidthClass = fullWidth ? "w-full" : "";

const paddingClass = isIconBtn ? "p-2" : "px-3 py-2";
const roundedBorders = small ? "rounded h-8" : "rounded-lg h-10";

return (
<BaseButton
className={`${variantClass} ${disabledClass} ${fullWidthClass} ${paddingClass} ${roundedBorders} ${className} `}
onClick={onClick}
>
<IconBox small={small}>{iconLeft}</IconBox>
{children}
<IconBox small={small}>{iconRight}</IconBox>
</BaseButton>
);
}
23 changes: 23 additions & 0 deletions frontend/src/components/Buttons/BaseButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react";

export default function BaseButton({
onClick,
disabled,
className,
children,
}: {
onClick?: () => void;
disabled?: true;
className: string;
children: React.ReactNode;
}) {
return (
<button
disabled={disabled}
className={`normal-semibold inline-flex items-center justify-center gap-2 ${className}`}
onClick={onClick}
>
{children}
</button>
);
}
16 changes: 16 additions & 0 deletions frontend/src/components/Buttons/IconActionButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react";
import ActionButton, { ActionButtonProps } from "./ActionButton";
import { IconBox } from "./IconBox";

type IconActionButtonProps = ActionButtonProps & {
icon: React.ReactNode;
small?: true;
};

export default function IconActionButton(props: IconActionButtonProps) {
return (
<ActionButton {...props} isIconBtn>
<IconBox small={props.small}>{props.icon}</IconBox>
</ActionButton>
);
}
19 changes: 19 additions & 0 deletions frontend/src/components/Buttons/IconBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from "react";

export function IconBox({
children,
small,
}: {
children: React.ReactNode;
small?: boolean;
}) {
const size = small ? "h-4 w-4" : "h-6 w-6";

if (!children) {
return null;
}

return (
<div className={`flex items-center justify-center ${size}`}>{children}</div>
);
}
2 changes: 1 addition & 1 deletion frontend/src/components/ConsultantRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { FilteredContext } from "@/hooks/ConsultantFilterProvider";
import { usePathname, useRouter } from "next/navigation";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { useModal } from "@/hooks/useModal";
import EasyModal from "./EasyModal";
import EasyModal from "./EasyModal/EasyModal";

export default function ConsultantRows({
consultant,
Expand Down
11 changes: 9 additions & 2 deletions frontend/src/components/DropDown.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"use client";
import { Check, ChevronDown } from "react-feather";
import { ChevronUp } from "react-feather";
import { useState } from "react";
import { useRef, useState } from "react";
import { useOutsideClick } from "@/hooks/useOutsideClick";

export default function DropDown({
startingOption,
Expand All @@ -15,8 +16,14 @@ export default function DropDown({
const [isDropDownOpen, setIsDropDownOpen] = useState(false);
const [chosenOption, setChosenOption] = useState(startingOption);

const dropDownRef = useRef(null);

useOutsideClick(dropDownRef, () => {
if (isDropDownOpen) setIsDropDownOpen(false);
});

return (
<div className="relative">
<div className="relative" ref={dropDownRef}>
<button
className={`w-[120px] py-2 px-3 flex flex-row justify-between items-center rounded-lg hover:bg-primary hover:bg-opacity-10 border hover:border-primary ${
isDropDownOpen ? "border-primary" : "border-primary/50"
Expand Down
147 changes: 147 additions & 0 deletions frontend/src/components/EasyModal/ButtonExampleModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
"use client";

import BaseModal from "../BaseModal";
import { Check, Plus } from "react-feather";
import { EasyModalHeader } from "./EasyModalHeader";
import ActionButton from "../Buttons/ActionButton";
import IconActionButton from "../Buttons/IconActionButton";
import { useModal } from "@/hooks/useModal";

function ButtonExampleModal() {
const { modalRef, openModal, closeModal } = useModal();

const dialogElement = modalRef?.current;

function handleClose() {
dialogElement?.close();
}

function handleSave() {
dialogElement?.close();
}

return (
<>
<BaseModal modalRef={modalRef}>
<div className="w-[332px]">
<EasyModalHeader
title="Button Examples"
handleClose={handleClose}
showCloseButton={true}
/>

<div className="space-y-2 space-x-2">
<ActionButton variant="primary" onClick={handleSave}>
Button
</ActionButton>
<ActionButton variant="secondary" onClick={handleSave}>
Button
</ActionButton>
<ActionButton variant="terniary" onClick={handleSave}>
Button
</ActionButton>
<IconActionButton
variant="secondary"
onClick={handleSave}
small
icon={<Plus />}
/>
<IconActionButton
variant="primary"
onClick={handleSave}
icon={<Check />}
/>
<ActionButton
variant="primary"
onClick={handleSave}
iconLeft={<Plus />}
>
Button
</ActionButton>
<ActionButton variant="primary" onClick={handleSave}>
Button
</ActionButton>
<ActionButton variant="secondary" onClick={handleSave}>
Button
</ActionButton>
<ActionButton
variant="primary"
onClick={handleSave}
iconLeft={<Plus />}
iconRight={<Plus />}
>
Button
</ActionButton>
<ActionButton
variant="secondary"
onClick={handleSave}
iconLeft={<Plus />}
iconRight={<Plus />}
>
Button
</ActionButton>
<ActionButton
variant="secondary"
onClick={handleSave}
iconLeft={<Plus />}
iconRight={<Plus />}
small
>
Button
</ActionButton>
<ActionButton
variant="terniary"
onClick={handleSave}
small
iconRight={<Plus />}
iconLeft={<Plus />}
>
Button
</ActionButton>
<ActionButton
variant="primary"
onClick={handleSave}
small
iconRight={<Plus />}
iconLeft={<Plus />}
>
Button
</ActionButton>
<ActionButton
variant="secondary"
onClick={handleSave}
iconLeft={<Plus />}
fullWidth
small
>
Button
</ActionButton>
<ActionButton
variant="terniary"
onClick={handleSave}
small
fullWidth
iconLeft={<Plus />}
>
Button
</ActionButton>
<ActionButton
variant="primary"
onClick={handleSave}
small
fullWidth
iconLeft={<Plus />}
>
Button
</ActionButton>
</div>
</div>
</BaseModal>
<ActionButton variant="primary" onClick={openModal}>
Button Examples
</ActionButton>
</>
);
}

export default ButtonExampleModal;
Loading

0 comments on commit 169eff9

Please sign in to comment.