diff --git a/web/global.d.ts b/web/global.d.ts
index b98930e..64647a5 100644
--- a/web/global.d.ts
+++ b/web/global.d.ts
@@ -1,6 +1,3 @@
-import {} from "styled-components";
-import { lightTheme } from "./src/styles/themes";
-
declare global {
module "*.svg" {
const content: React.FC>;
@@ -12,8 +9,4 @@ declare global {
}
}
-declare module "styled-components" {
- type Theme = typeof lightTheme;
- //eslint-disable-next-line @typescript-eslint/no-empty-interface
- export interface DefaultTheme extends Theme {}
-}
+export {};
diff --git a/web/package.json b/web/package.json
index 672c636..ea366cd 100644
--- a/web/package.json
+++ b/web/package.json
@@ -48,10 +48,9 @@
"@graphql-codegen/client-preset": "^4.2.0",
"@kleros/curate-v2-tsconfig": "workspace:^",
"@kleros/kleros-v2-contracts": "^0.10.0",
+ "@tailwindcss/vite": "^4.1.16",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
- "@types/react-modal": "^3.16.3",
- "@types/styled-components": "^5.1.34",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"@typescript-eslint/utils": "^5.62.0",
@@ -61,6 +60,7 @@
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"lru-cache": "^7.18.3",
+ "tailwindcss": "^4.1.16",
"typescript": "^5.3.3",
"vite": "^5.4.2",
"vite-plugin-node-polyfills": "^0.22.0",
@@ -71,7 +71,7 @@
"@cyntler/react-doc-viewer": "^1.17.0",
"@kleros/curate-v2-templates": "workspace:^",
"@kleros/kleros-app": "^2.0.2",
- "@kleros/ui-components-library": "^2.20.0",
+ "@kleros/ui-components-library": "^3.6.0",
"@reown/appkit": "^1.6.6",
"@reown/appkit-adapter-wagmi": "^1.6.6",
"@sentry/react": "^7.93.0",
@@ -82,6 +82,7 @@
"@yornaath/batshit": "^0.9.0",
"chart.js": "^3.9.1",
"chartjs-adapter-moment": "^1.0.1",
+ "clsx": "^2.1.1",
"core-js": "^3.35.0",
"graphql": "^16.9.0",
"graphql-request": "^7.1.2",
@@ -98,13 +99,12 @@
"react-is": "^18.2.0",
"react-loading-skeleton": "^3.3.1",
"react-markdown": "^8.0.7",
- "react-modal": "^3.16.1",
"react-router-dom": "^6.21.2",
"react-scripts": "^5.0.1",
"react-toastify": "^9.1.3",
"react-use": "^17.4.3",
- "styled-components": "^5.3.11",
"subgraph-status": "^1.2.4",
+ "tailwind-merge": "^3.3.1",
"viem": "^2.27.2",
"wagmi": "^2.14.10",
"zod": "^3.24.2"
diff --git a/web/src/app.tsx b/web/src/app.tsx
index 082eb22..a0f2764 100644
--- a/web/src/app.tsx
+++ b/web/src/app.tsx
@@ -3,10 +3,12 @@ import { Route } from "react-router-dom";
import { SentryRoutes } from "./utils/sentry";
import "react-loading-skeleton/dist/skeleton.css";
import "react-toastify/dist/ReactToastify.css";
+import "overlayscrollbars/styles/overlayscrollbars.css";
+import "./global.css";
+import ThemeProvider from "context/ThemeProvider";
import Web3Provider from "context/Web3Provider";
import IsListViewProvider from "context/IsListViewProvider";
import QueryClientProvider from "context/QueryClientProvider";
-import StyledComponentsProvider from "context/StyledComponentsProvider";
import Layout from "layout/index";
import Home from "./pages/Home";
import AllLists from "./pages/AllLists";
@@ -22,7 +24,7 @@ import Settings from "./pages/Settings";
const App: React.FC = () => {
return (
-
+
@@ -55,7 +57,7 @@ const App: React.FC = () => {
-
+
);
};
diff --git a/web/src/components/ActionButton/ExecuteButton.tsx b/web/src/components/ActionButton/ExecuteButton.tsx
index 3110621..551353e 100644
--- a/web/src/components/ActionButton/ExecuteButton.tsx
+++ b/web/src/components/ActionButton/ExecuteButton.tsx
@@ -26,7 +26,7 @@ const ExecuteButton: React.FC = ({ registryAddress, itemId, refe
);
};
diff --git a/web/src/components/ItemCard/ItemField/ChainField.tsx b/web/src/components/ItemCard/ItemField/ChainField.tsx
index 4ef62f1..2609573 100644
--- a/web/src/components/ItemCard/ItemField/ChainField.tsx
+++ b/web/src/components/ItemCard/ItemField/ChainField.tsx
@@ -1,18 +1,7 @@
import React from "react";
-import styled from "styled-components";
import { getChainById } from "utils/getChainById";
import ChainIcon, { getChainName } from "components/ChainIcon";
-const Container = styled.div`
- display: flex;
- align-items: center;
- gap: 8px;
-`;
-
-const StyledP = styled.p`
- margin: 0px;
-`;
-
export interface IChainField {
value: string;
}
@@ -23,10 +12,10 @@ const ChainField: React.FC = ({ value }) => {
const chainName = getChainName(chain.id);
return (
-
+
-
{chainName}
-
+
{chainName}
+
);
};
diff --git a/web/src/components/ItemCard/ItemField/FileField.tsx b/web/src/components/ItemCard/ItemField/FileField.tsx
index 8f7e870..caa73f0 100644
--- a/web/src/components/ItemCard/ItemField/FileField.tsx
+++ b/web/src/components/ItemCard/ItemField/FileField.tsx
@@ -1,14 +1,8 @@
import React from "react";
import { Link } from "react-router-dom";
-import styled from "styled-components";
import PDFIcon from "svgs/icons/pdf.svg";
import { getIpfsUrl } from "utils/getIpfsUrl";
-const Container = styled(Link)`
- display: flex;
- gap: 8px;
-`;
-
export interface IFileField {
value: string;
label: string;
@@ -18,10 +12,10 @@ export interface IFileField {
const FileField: React.FC = ({ value, label }) => {
const fileUrl = getIpfsUrl(value);
return (
- event.stopPropagation()}>
+ event.stopPropagation()}>
{label}
-
+
);
};
diff --git a/web/src/components/ItemCard/ItemField/ImageField.tsx b/web/src/components/ItemCard/ItemField/ImageField.tsx
index e149826..b19c593 100644
--- a/web/src/components/ItemCard/ItemField/ImageField.tsx
+++ b/web/src/components/ItemCard/ItemField/ImageField.tsx
@@ -1,14 +1,7 @@
import React from "react";
import { Link } from "react-router-dom";
-import styled from "styled-components";
import { getIpfsUrl } from "utils/getIpfsUrl";
-const StyledImg = styled.img<{ detailed?: boolean }>`
- width: ${({ detailed }) => (detailed ? "125px" : "40px")};
- height: ${({ detailed }) => (detailed ? "125px" : "40px")};
- object-fit: contain;
-`;
-
export interface IImageField {
value: string;
detailed?: boolean;
@@ -18,7 +11,13 @@ const ImageField: React.FC = ({ value, detailed }) => {
const imgUrl = getIpfsUrl(value);
return (
-
+
);
};
diff --git a/web/src/components/ItemCard/ItemField/LinkField.tsx b/web/src/components/ItemCard/ItemField/LinkField.tsx
index 46da8d5..a66b5ff 100644
--- a/web/src/components/ItemCard/ItemField/LinkField.tsx
+++ b/web/src/components/ItemCard/ItemField/LinkField.tsx
@@ -1,12 +1,6 @@
import React from "react";
-import styled from "styled-components";
import Globe from "svgs/icons/globe.svg";
-const Container = styled.a`
- display: flex;
- gap: 8px;
-`;
-
export interface ILinkField {
value: string;
detailed?: boolean;
@@ -14,10 +8,16 @@ export interface ILinkField {
const LinkField: React.FC = ({ value }) => {
return (
- event.stopPropagation()} target="blank" rel="noreferrer">
+ event.stopPropagation()}
+ target="_blank"
+ rel="noopener noreferrer"
+ >
{value}
-
+
);
};
diff --git a/web/src/components/ItemCard/ItemField/LongTextField.tsx b/web/src/components/ItemCard/ItemField/LongTextField.tsx
index a4ff6e7..f832c9c 100644
--- a/web/src/components/ItemCard/ItemField/LongTextField.tsx
+++ b/web/src/components/ItemCard/ItemField/LongTextField.tsx
@@ -1,35 +1,16 @@
import React from "react";
-import styled from "styled-components";
import WithHelpTooltip from "components/WithHelpTooltip";
import TruncatedText from "components/TruncatedText";
import { Overlay } from "components/Overlay";
-import { Textarea } from "@kleros/ui-components-library";
+import { TextArea } from "@kleros/ui-components-library";
import { useToggle } from "react-use";
import Modal from "components/Modal";
-const Container = styled.p`
- margin: 0px;
-`;
-
-const StyledModal = styled(Modal)`
- padding: 0;
-`;
-
-const TextDisplay = styled(Textarea)`
- width: 100%;
- height: 80vh;
-`;
-
-const StyledLabel = styled.label`
- color: ${({ theme }) => theme.primaryBlue};
- cursor: pointer;
-`;
-
const LongTextFullDisplay: React.FC<{ text: string; toggleModal: () => void }> = ({ text, toggleModal }) => (
-
-
-
+
+
+
);
@@ -43,16 +24,19 @@ const LongTextField: React.FC = ({ value, detailed, label }) =>
const [isModalOpen, toggleModal] = useToggle(false);
return (
<>
-
+
{detailed ? (
- [Read More]
+ {" "}
+
) : (
)}
-
+
{isModalOpen && }
>
);
diff --git a/web/src/components/ItemCard/ItemField/NumberField.tsx b/web/src/components/ItemCard/ItemField/NumberField.tsx
index db960e5..93826e0 100644
--- a/web/src/components/ItemCard/ItemField/NumberField.tsx
+++ b/web/src/components/ItemCard/ItemField/NumberField.tsx
@@ -1,14 +1,6 @@
import React from "react";
-import styled from "styled-components";
import WithHelpTooltip from "components/WithHelpTooltip";
-const Container = styled.p`
- margin: 0px;
- display: flex;
- gap: 8px;
- align-items: center;
-`;
-
export interface INumberField {
value: string;
detailed?: boolean;
@@ -17,7 +9,7 @@ export interface INumberField {
}
const NumberField: React.FC = ({ value, detailed, label, description }) => {
return (
-
+
{detailed ? (
<>
{label}: {value}
@@ -25,7 +17,7 @@ const NumberField: React.FC = ({ value, detailed, label, descripti
) : (
{value}
)}
-
+
);
};
diff --git a/web/src/components/ItemCard/ItemField/TextField.tsx b/web/src/components/ItemCard/ItemField/TextField.tsx
index 56f00ea..c978973 100644
--- a/web/src/components/ItemCard/ItemField/TextField.tsx
+++ b/web/src/components/ItemCard/ItemField/TextField.tsx
@@ -1,12 +1,7 @@
import React from "react";
-import styled from "styled-components";
import WithHelpTooltip from "components/WithHelpTooltip";
import TruncatedText from "components/TruncatedText";
-const Container = styled.p`
- margin: 0px;
-`;
-
export interface ITextField {
value: string;
detailed?: boolean;
@@ -14,13 +9,13 @@ export interface ITextField {
}
const TextField: React.FC = ({ value, detailed, label }) => {
return (
-
+
{detailed ? (
{value}
) : (
)}
-
+
);
};
diff --git a/web/src/components/ItemCard/ItemField/index.tsx b/web/src/components/ItemCard/ItemField/index.tsx
index cbe5bc2..e9804b2 100644
--- a/web/src/components/ItemCard/ItemField/index.tsx
+++ b/web/src/components/ItemCard/ItemField/index.tsx
@@ -1,5 +1,4 @@
import React from "react";
-import styled from "styled-components";
import { ItemDetailsFragment } from "src/graphql/graphql";
import TextField, { ITextField } from "./TextField";
import AddressField, { IAddressField } from "./AddressField";
@@ -15,24 +14,6 @@ import { arbitrum, arbitrumSepolia } from "@reown/appkit/networks";
import { Tooltip } from "@kleros/ui-components-library";
import WarningIcon from "src/assets/svgs/icons/warning-outline.svg";
-const Container = styled.div`
- display: flex;
- gap: 8px;
- align-items: center;
-`;
-
-const StyledTooltip = styled(Tooltip)`
- height: 14px;
- display: flex;
- align-items: center;
- cursor: pointer;
-`;
-
-const StyledWarningIcon = styled(WarningIcon)`
- width: 14px;
- height: 14px;
-`;
-
type ItemDetails = ItemDetailsFragment["props"][number];
export interface IItemField extends ItemDetails {
@@ -100,14 +81,18 @@ const ItemField: React.FC = ({ detailed, type, isUnrecognized = fals
}
}
return (
-
+
{FieldComponent}
{isUnrecognized ? (
-
-
-
+
+
+
) : null}
-
+
);
};
diff --git a/web/src/components/ItemCard/index.tsx b/web/src/components/ItemCard/index.tsx
index 9a24984..704cba9 100644
--- a/web/src/components/ItemCard/index.tsx
+++ b/web/src/components/ItemCard/index.tsx
@@ -1,80 +1,18 @@
import React from "react";
-import styled, { css } from "styled-components";
import { Button, Card } from "@kleros/ui-components-library";
-import { landscapeStyle } from "styles/landscapeStyle";
import { useNavigateAndScrollTop } from "hooks/useNavigateAndScrollTop";
import { responsiveSize } from "styles/responsiveSize";
import StatusBanner, { mapFromSubgraphStatus } from "../RegistryCard/StatusBanner";
import ArrowIcon from "svgs/icons/arrow.svg";
import { ItemDetailsFragment } from "src/graphql/graphql";
import ItemField from "./ItemField";
+import { cn } from "~src/utils";
+import clsx from "clsx";
-const StyledListItem = styled(Card)`
- display: flex;
- flex-grow: 1;
- width: 100%;
- height: max-content;
- ${landscapeStyle(
- () => css`
- height: 64px;
- `
- )}
-`;
+const landscapeGridColsCalc =
+ "lg:grid-cols-[1fr_calc(150px+(180-150)*(min(max(100vw,900px),1250px)-900px)/(1250-900))_max-content]";
+const landscapeGapCalc = "lg:gap-[calc(16px+(36-16)*(min(max(100vw,900px),1250px)-900px)/(1250-900))]";
-const Container = styled.div`
- width: 100%;
- height: max-content;
- align-items: center;
- display: grid;
- grid-template-rows: repeat(3, min-content);
- grid-template-columns: 1fr min-content;
- column-gap: ${responsiveSize(12, 32, 900)};
- row-gap: 8px;
- padding: 16px;
- ${landscapeStyle(
- () => css`
- height: 64px;
- justify-content: space-between;
- grid-template-rows: 1fr;
- grid-template-columns: 1fr ${responsiveSize(150, 180, 900)} max-content;
- padding: 0 32px;
- `
- )}
-`;
-
-const StyledButton = styled(Button)`
- background-color: transparent;
- padding: 0;
- flex-direction: row-reverse;
- gap: 8px;
- .button-text {
- color: ${({ theme }) => theme.primaryBlue};
- font-weight: 400;
- }
-
- :focus,
- :hover {
- background-color: transparent;
- }
-`;
-
-const FieldsContainer = styled.div`
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- align-items: start;
- width: fit-content;
- gap: 16px;
- grid-column: span 2;
- ${landscapeStyle(
- () => css`
- flex-direction: row;
- align-items: center;
- grid-column: span 1;
- gap: ${responsiveSize(16, 36, 900)};
- `
- )}
-`;
interface IItemCard extends ItemDetailsFragment {}
const ItemCard: React.FC = ({ id, status, disputed, props }) => {
@@ -84,13 +22,41 @@ const ItemCard: React.FC = ({ id, status, disputed, props }) => {
const sortedProps = sortItemProps(props);
return (
- navigateAndScrollTop(`/lists/item/${id?.toString()}`)}>
-
- {sortedProps.map((prop) => prop.isIdentifier && )}
+ navigateAndScrollTop(`/lists/item/${id?.toString()}`)}
+ >
+
+
+ {sortedProps.map((prop) => prop.isIdentifier && )}
+
-
-
-
+
+
+
);
};
diff --git a/web/src/components/LabeledInput.tsx b/web/src/components/LabeledInput.tsx
index 7ad4e31..ce9e701 100644
--- a/web/src/components/LabeledInput.tsx
+++ b/web/src/components/LabeledInput.tsx
@@ -1,39 +1,11 @@
-import { Field, FieldProps } from "@kleros/ui-components-library";
-import React from "react";
-import styled from "styled-components";
-import { isUndefined } from "utils/index";
+import React, { ReactNode } from "react";
+import { cn, isUndefined } from "utils/index";
import WithHelpTooltip from "./WithHelpTooltip";
+import { TextField } from "@kleros/ui-components-library";
-const Container = styled.div`
- width: 100%;
- height: min-content;
- display: grid;
- grid-template-columns: auto auto;
- .field {
- grid-column: span 2;
- }
-`;
-
-const StyledField = styled(Field)`
- width: 100%;
-`;
-
-const StyledLabel = styled.label<{ alignRight?: boolean; top?: boolean }>`
- text-align: ${({ alignRight }) => (alignRight ? "end" : "start")};
- float: ${({ alignRight }) => (alignRight ? "right" : "left")};
- color: ${({ theme, top }) => (top ? theme.primaryText : theme.secondaryText)};
-`;
-
-const Wrapper = styled.div<{ top?: boolean }>`
- ${({ top }) => (top ? "margin-bottom: 12px;" : "margin-top: 12px")}
-`;
-
-const ElementWrapper = styled.div<{ alignRight?: boolean }>`
- width: 100%;
- display: flex;
- justify-content: ${({ alignRight }) => (alignRight ? "end" : "start")};
- align-items: top;
-`;
+const ElementWrapper: React.FC<{ children: ReactNode; alignRight?: boolean }> = ({ children, alignRight = false }) => {
+ return {children}
;
+};
const Label: React.FC<{
label: string;
@@ -42,19 +14,29 @@ const Label: React.FC<{
top?: boolean;
}> = ({ label, tooltipMsg, alignRight, top }) => {
return (
-
+
{tooltipMsg ? (
-
+
+
) : (
-
+
+
)}
-
+
);
};
@@ -63,7 +45,7 @@ interface LabelOptions {
tooltipMsg?: string;
tooltipPlace?: "top" | "bottom" | "left" | "right";
}
-interface ILabeledInput extends FieldProps {
+interface ILabeledInput {
topLeftLabel?: LabelOptions;
topRightLabel?: LabelOptions;
bottomLeftLabel?: LabelOptions;
@@ -74,7 +56,7 @@ const LabeledInput: React.FC = (props) => {
const { topLeftLabel, topRightLabel, bottomLeftLabel, bottomRightLabel } = props;
return (
-
+
{/* top left label */}
{!isUndefined(topLeftLabel) && typeof topLeftLabel.text === `string` ? (
@@ -93,7 +75,7 @@ const LabeledInput: React.FC = (props) => {
{topRightLabel.text}
) : null}
-
+
{/* bottom left label */}
{!isUndefined(bottomLeftLabel) && typeof bottomLeftLabel.text === `string` ? (
@@ -112,7 +94,7 @@ const LabeledInput: React.FC = (props) => {
{!isUndefined(bottomRightLabel) && isReactElement(bottomRightLabel.text) ? (
{bottomRightLabel.text}
) : null}
-
+
);
};
diff --git a/web/src/components/LightButton.tsx b/web/src/components/LightButton.tsx
index 86307d5..4bbd06a 100644
--- a/web/src/components/LightButton.tsx
+++ b/web/src/components/LightButton.tsx
@@ -1,39 +1,6 @@
import React from "react";
-import styled, { css } from "styled-components";
-import { landscapeStyle } from "styles/landscapeStyle";
-import { hoverShortTransitionTiming } from "styles/commonStyles";
-
import { Button } from "@kleros/ui-components-library";
-
-const StyledButton = styled(Button)<{ isMobileNavbar?: boolean }>`
- ${hoverShortTransitionTiming}
- background-color: transparent;
- padding: 8px !important;
- border-radius: 7px;
- .button-text {
- color: ${({ theme }) => theme.primaryText};
- font-weight: 400;
- }
- .button-svg {
- fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.secondaryText : `${theme.white}BF`)} !important;
- }
-
- &:hover {
- .button-svg {
- fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.primaryText : `${theme.white}`)} !important;
- }
- background-color: ${({ theme }) => theme.whiteLowOpacityStrong};
- }
-
- ${landscapeStyle(
- () => css`
- padding: 8px !important;
- .button-svg {
- margin-right: 0;
- }
- `
- )}
-`;
+import { cn } from "~src/utils";
interface ILightButton {
text: string;
@@ -45,7 +12,21 @@ interface ILightButton {
}
const LightButton: React.FC = ({ text, Icon, onClick, disabled, className, isMobileNavbar }) => (
-
+
);
export default LightButton;
diff --git a/web/src/components/Modal.tsx b/web/src/components/Modal.tsx
index 7fde443..14867e2 100644
--- a/web/src/components/Modal.tsx
+++ b/web/src/components/Modal.tsx
@@ -1,28 +1,7 @@
import React, { useRef } from "react";
-import styled from "styled-components";
import { Overlay } from "./Overlay";
import { useClickAway } from "react-use";
-
-const StyledModal = styled.div`
- display: flex;
- position: fixed;
- top: 10vh;
- left: 50%;
- transform: translateX(-50%);
- max-height: 80vh;
- overflow-y: auto;
-
- z-index: 10;
- flex-direction: column;
- align-items: center;
- width: 86vw;
- max-width: 600px;
- border-radius: 3px;
- border: 1px solid ${({ theme }) => theme.stroke};
- background-color: ${({ theme }) => theme.whiteBackground};
- box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.06);
- padding: 32px 32px 32px 36px;
-`;
+import { cn } from "~src/utils";
const Modal: React.FC<{ children: React.ReactNode; toggleModal: () => void; className?: string }> = ({
children,
@@ -33,9 +12,20 @@ const Modal: React.FC<{ children: React.ReactNode; toggleModal: () => void; clas
useClickAway(containerRef, () => toggleModal());
return (
-
+
{children}
-
+
);
};
diff --git a/web/src/components/Overlay.tsx b/web/src/components/Overlay.tsx
index b9b2978..37d29c1 100644
--- a/web/src/components/Overlay.tsx
+++ b/web/src/components/Overlay.tsx
@@ -1,11 +1,5 @@
-import styled from "styled-components";
+import React from "react";
-export const Overlay = styled.div`
- position: fixed;
- top: 0;
- left: 0;
- width: 100vw;
- height: 100vh;
- background-color: ${({ theme }) => theme.blackLowOpacity};
- z-index: 30;
-`;
+export const Overlay: React.FC<{ children?: React.ReactNode }> = ({ children }) => (
+ {children}
+);
diff --git a/web/src/components/OverlayPortal.tsx b/web/src/components/OverlayPortal.tsx
index b2f3c94..9d3e4ca 100644
--- a/web/src/components/OverlayPortal.tsx
+++ b/web/src/components/OverlayPortal.tsx
@@ -1,18 +1,11 @@
import React from "react";
import ReactDOM from "react-dom";
-import styled from "styled-components";
-
-const PortalContainer = styled.div`
- position: fixed;
- top: 0;
- left: 0;
- z-index: 9999;
- width: 100%;
- height: 100%;
-`;
const OverlayPortal: React.FC<{ children: React.ReactNode }> = ({ children }) => {
- return ReactDOM.createPortal({children}, document.body);
+ return ReactDOM.createPortal(
+ {children}
,
+ document.body
+ );
};
export default OverlayPortal;
diff --git a/web/src/components/RegistriesDisplay/RegistriesGrid.tsx b/web/src/components/RegistriesDisplay/RegistriesGrid.tsx
index 6de6a0f..e5c7542 100644
--- a/web/src/components/RegistriesDisplay/RegistriesGrid.tsx
+++ b/web/src/components/RegistriesDisplay/RegistriesGrid.tsx
@@ -1,37 +1,15 @@
import React, { useMemo } from "react";
-import styled from "styled-components";
import { useWindowSize } from "react-use";
import { useParams } from "react-router-dom";
import { SkeletonRegistryCard, SkeletonRegistryListItem } from "../StyledSkeleton";
import { StandardPagination } from "@kleros/ui-components-library";
-import { BREAKPOINT_LANDSCAPE } from "styles/landscapeStyle";
import { useIsListView } from "context/IsListViewProvider";
import { isUndefined } from "utils/index";
import { decodeListURIFilter } from "utils/uri";
// import { RegistryDetailsFragment } from "queries/useCasesQuery";
import RegistryCard from "components/RegistryCard";
import { mapFromSubgraphStatus } from "../RegistryCard/StatusBanner";
-
-const GridContainer = styled.div`
- --gap: 16px;
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(min(100%, max(274px, (100% - var(--gap) * 2)/3)), 1fr));
- align-items: center;
- gap: var(--gap);
-`;
-
-const ListContainer = styled.div`
- display: flex;
- flex-direction: column;
- justify-content: center;
- gap: 8px;
-`;
-
-const StyledPagination = styled(StandardPagination)`
- margin-top: 24px;
- margin-left: auto;
- margin-right: auto;
-`;
+import { LG_BREAKPOINT } from "~src/styles/breakpoints";
export interface IRegistriesGrid {
registries?: [];
@@ -57,12 +35,12 @@ const RegistriesGrid: React.FC = ({
const { id: searchValue } = decodedFilter;
const { isListView } = useIsListView();
const { width } = useWindowSize();
- const screenIsBig = useMemo(() => width > BREAKPOINT_LANDSCAPE, [width]);
+ const screenIsBig = useMemo(() => width > LG_BREAKPOINT, [width]);
return (
<>
{isListView && screenIsBig ? (
-
+
{isUndefined(registries) || registriesLoading
? [...Array(registriesPerPage)].map((_, i) => )
: registries.map((registry) => {
@@ -74,9 +52,9 @@ const RegistriesGrid: React.FC = ({
/>
);
})}
-
+
) : (
-
+
{isUndefined(registries) || registriesLoading
? [...Array(registriesPerPage)].map((_, i) => )
: registries.map((registry) => {
@@ -89,11 +67,12 @@ const RegistriesGrid: React.FC = ({
/>
);
})}
-
+
)}
{isUndefined(searchValue) && showPagination ? (
- setCurrentPage(page)}
diff --git a/web/src/components/RegistryCard/RegistryInfo.tsx b/web/src/components/RegistryCard/RegistryInfo.tsx
index 8f8adda..ca5be27 100644
--- a/web/src/components/RegistryCard/RegistryInfo.tsx
+++ b/web/src/components/RegistryCard/RegistryInfo.tsx
@@ -1,7 +1,5 @@
import React, { useEffect, useState } from "react";
-import styled, { css } from "styled-components";
import { responsiveSize } from "styles/responsiveSize";
-import { landscapeStyle } from "styles/landscapeStyle";
import Skeleton from "react-loading-skeleton";
import { Button } from "@kleros/ui-components-library";
import ArrowIcon from "svgs/icons/arrow.svg";
@@ -10,85 +8,7 @@ import { getIpfsUrl } from "utils/getIpfsUrl";
import StatusBanner from "./StatusBanner";
import { DEFAULT_LIST_LOGO } from "consts/index";
import TruncatedText from "../TruncatedText";
-
-const Container = styled.div<{ isListView: boolean }>`
- height: calc(100% - 45px);
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- gap: 8px;
-
- // css for isList view
- ${({ isListView }) =>
- isListView &&
- css`
- width: 100%;
- height: max-content;
- display: grid;
- grid-template-rows: repeat(3, min-content);
- grid-template-columns: 21px max-content 1fr max-content;
- column-gap: ${responsiveSize(8, 24, 900)};
- row-gap: 16px;
- padding: 16px;
- h3,
- img {
- grid-column: span 4;
- }
- ${landscapeStyle(
- () => css`
- height: 64px;
- justify-content: space-between;
- grid-template-rows: 1fr;
- grid-template-columns: auto 1fr ${responsiveSize(80, 100, 900)} ${responsiveSize(100, 150, 900)} max-content;
- padding: 0 32px;
- img {
- grid-column: 1;
- }
- h3 {
- grid-column: 2;
- }
- `
- )}
- `}
-`;
-
-const StyledLogo = styled.img<{ isListView: boolean }>`
- width: ${({ isListView }) => (isListView ? "40px" : "125px")};
- height: ${({ isListView }) => (isListView ? "40px" : "125px")};
- object-fit: contain;
- margin-bottom: ${({ isListView }) => (isListView ? "0px" : "8px")};
-`;
-
-const StyledLabel = styled.label`
- color: ${({ theme }) => theme.secondaryText};
-`;
-
-const StyledButton = styled(Button)`
- background-color: transparent;
- padding: 0;
- flex-direction: row-reverse;
- gap: 8px;
- .button-text {
- color: ${({ theme }) => theme.primaryBlue};
- font-weight: 400;
- }
- .button-svg {
- fill: ${({ theme }) => theme.secondaryPurple};
- }
-
- :focus,
- :hover {
- background-color: transparent;
- }
-`;
-
-const SkeletonLogo = styled(Skeleton)<{ isListView: boolean }>`
- width: ${({ isListView }) => (isListView ? "40px" : "125px")};
- height: ${({ isListView }) => (isListView ? "40px" : "125px")};
- border-radius: ${({ isListView }) => (isListView ? "24px" : "62.5px")};
- margin-bottom: ${({ isListView }) => (isListView ? "0px" : "8px")};
-`;
+import { cn } from "~src/utils";
interface IListInfo {
title?: string;
@@ -98,6 +18,9 @@ interface IListInfo {
isListView?: boolean;
}
+const landscapeGridColsCalc =
+ "lg:grid-cols-[auto_1fr_calc(80px+(100-80)*(min(max(100vw,900px),1250px)-900px)/(1250-900))_calc(100px+(150-100)*(min(max(100vw,900px),1250px)-900px)/(1250-900))_max-content]";
+
const ListInfo: React.FC = ({ title, totalItems, logoURI, status, isListView = false }) => {
const [imageLoaded, setImageLoaded] = useState(false);
const [imageSrc, setImageSrc] = useState(getIpfsUrl(logoURI ?? DEFAULT_LIST_LOGO));
@@ -108,21 +31,51 @@ const ListInfo: React.FC = ({ title, totalItems, logoURI, status, isL
}, [logoURI]);
return (
-
- {!imageLoaded ? : null}
-
+ {!imageLoaded ? (
+
+ ) : null}
+
setImageLoaded(true)}
onError={() => setImageSrc(getIpfsUrl(DEFAULT_LIST_LOGO))}
style={{ display: imageLoaded ? "block" : "none" }}
/>
- {totalItems} items
+
{isListView && }
- {isListView && }
-
+ {isListView && (
+
+ )}
+
);
};
diff --git a/web/src/components/RegistryCard/StatusBanner.tsx b/web/src/components/RegistryCard/StatusBanner.tsx
index 7d5ccda..1e2c94b 100644
--- a/web/src/components/RegistryCard/StatusBanner.tsx
+++ b/web/src/components/RegistryCard/StatusBanner.tsx
@@ -1,65 +1,13 @@
import React from "react";
-import styled, { Theme } from "styled-components";
import { Status } from "consts/status";
import { Status as SubgraphStatus } from "src/graphql/graphql";
-
-const Container = styled.div<{ status: Status; isListView: boolean }>`
- height: ${({ isListView }) => (isListView ? "min-content" : "45px")};
- border-top-right-radius: 3px;
- border-top-left-radius: 3px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 24px;
- .dot {
- ::before {
- content: "";
- display: inline-block;
- height: 8px;
- width: 8px;
- border-radius: 50%;
- margin-right: 8px;
- }
- }
- ${({ theme, status, isListView }) => {
- const [frontColor, backgroundColor] = getStatusColor(status, theme);
- return `
- ${!isListView && `border-top: 5px solid ${frontColor}`};
- ${!isListView && `background-color: ${backgroundColor}`};
- ${isListView && `padding: 0px`};
- .front-color {
- color: ${frontColor};
- }
- .dot {
- ::before {
- background-color: ${frontColor};
- }
- }
- `;
- }};
-`;
+import { cn } from "~src/utils";
interface IStatusBanner {
status: Status;
isListView?: boolean;
}
-export const getStatusColor = (status: Status, theme: Theme): [string, string] => {
- switch (status) {
- case Status.RegistrationPending:
- case Status.ClearingPending:
- return [theme.primaryBlue, theme.mediumBlue];
- case Status.Disputed:
- return [theme.secondaryPurple, theme.mediumPurple];
- case Status.Included:
- return [theme.success, theme.successLight];
- case Status.Removed:
- return [theme.error, theme.errorLight];
- default:
- return [theme.lightGrey, theme.lightGrey];
- }
-};
-
export const getStatusLabel = (status: Status): string => {
switch (status) {
case Status.RegistrationPending:
@@ -90,10 +38,39 @@ export const mapFromSubgraphStatus = (status: string, isDisputed: boolean) => {
return Status.ClearingPending;
}
};
+
+const borderAndBgStyles: Record = {
+ [Status.RegistrationPending]: "border-t-klerosUIComponentsPrimaryBlue bg-klerosUIComponentsMediumBlue",
+ [Status.ClearingPending]: "border-t-klerosUIComponentsPrimaryBlue bg-klerosUIComponentsMediumBlue",
+ [Status.Disputed]: "border-t-klerosUIComponentsSecondaryPurple bg-klerosUIComponentsMediumPurple",
+ [Status.Included]: "border-t-klerosUIComponentsSuccess bg-klerosUIComponentsSuccessLight",
+ [Status.Removed]: "border-t-klerosUIComponentsError bg-klerosUIComponentsErrorLight",
+};
+
+const dotAndFrontColorStyles: Record = {
+ [Status.RegistrationPending]:
+ "[&_.front-color]:text-klerosUIComponentsPrimaryBlue [&_.dot::before]:bg-klerosUIComponentsPrimaryBlue",
+ [Status.ClearingPending]:
+ "[&_.front-color]:text-klerosUIComponentsPrimaryBlue [&_.dot::before]:bg-klerosUIComponentsPrimaryBlue",
+ [Status.Disputed]:
+ "[&_.front-color]:text-klerosUIComponentsSecondaryPurple [&_.dot::before]:bg-klerosUIComponentsSecondaryPurple",
+ [Status.Included]: "[&_.front-color]:text-klerosUIComponentsSuccess [&_.dot::before]:bg-klerosUIComponentsSuccess",
+ [Status.Removed]: "[&_.front-color]:text-klerosUIComponentsError [&_.dot::before]:bg-klerosUIComponentsError",
+};
+
const StatusBanner: React.FC = ({ status, isListView = false }) => (
-
+
-
+
);
export default StatusBanner;
diff --git a/web/src/components/RegistryCard/index.tsx b/web/src/components/RegistryCard/index.tsx
index 9f83ca2..b0780d4 100644
--- a/web/src/components/RegistryCard/index.tsx
+++ b/web/src/components/RegistryCard/index.tsx
@@ -1,31 +1,12 @@
import React from "react";
-import styled, { css } from "styled-components";
import { Card } from "@kleros/ui-components-library";
import { useIsListView } from "context/IsListViewProvider";
-import { landscapeStyle } from "styles/landscapeStyle";
import StatusBanner from "./StatusBanner";
import RegistryInfo from "./RegistryInfo";
import { useNavigateAndScrollTop } from "hooks/useNavigateAndScrollTop";
import { GetRegistriesByIdsQuery } from "src/graphql/graphql";
import { Status } from "src/consts/status";
-const StyledCard = styled(Card)`
- width: 100%;
- height: 274px;
-`;
-
-const StyledListItem = styled(Card)`
- display: flex;
- flex-grow: 1;
- width: 100%;
- height: max-content;
- ${landscapeStyle(
- () => css`
- height: 64px;
- `
- )}
-`;
-
type List = GetRegistriesByIdsQuery["registries"][number];
interface IListCard extends List {
overrideIsListView?: boolean;
@@ -43,17 +24,22 @@ const RegistryCard: React.FC = ({ id, itemId, title, logoURI, totalIt
return (
<>
{!isListView || overrideIsListView ? (
- navigateAndScrollTop(`/lists/${registryAddressAndItemId}/display/1/desc/all`)}>
+ navigateAndScrollTop(`/lists/${registryAddressAndItemId}/display/1/desc/all`)}
+ >
-
+
) : (
- navigateAndScrollTop(`/lists/${registryAddressAndItemId}/display/desc/all`)}
>
-
+
)}
>
);
diff --git a/web/src/components/RegistryInfo/AliasDisplay.tsx b/web/src/components/RegistryInfo/AliasDisplay.tsx
index bef153b..e3df87d 100644
--- a/web/src/components/RegistryInfo/AliasDisplay.tsx
+++ b/web/src/components/RegistryInfo/AliasDisplay.tsx
@@ -1,24 +1,9 @@
import React from "react";
-import styled from "styled-components";
import { AddressOrName, IdenticonOrAvatar } from "../ConnectWallet/AccountDisplay";
import { useEnsAddress } from "wagmi";
import { isAddress } from "viem";
import Skeleton from "react-loading-skeleton";
-
-const AliasContainer = styled.div`
- min-height: 32px;
- display: flex;
- gap: 8px;
- align-items: center;
-`;
-
-const TextContainer = styled.div`
- display: flex;
- > label {
- color: ${({ theme }) => theme.primaryText};
- font-size: 14px;
- }
-`;
+import { cn } from "~src/utils";
interface IAlias {
address: string;
@@ -35,12 +20,12 @@ const AliasDisplay: React.FC = ({ address, className }) => {
const finalAddress = addressFromENS ?? address;
return (
-
+
);
};
diff --git a/web/src/components/Search.tsx b/web/src/components/Search.tsx
index 48c2fac..37a6722 100644
--- a/web/src/components/Search.tsx
+++ b/web/src/components/Search.tsx
@@ -1,6 +1,4 @@
import React, { useState } from "react";
-import styled, { css } from "styled-components";
-import { landscapeStyle } from "styles/landscapeStyle";
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
import { useDebounce } from "react-use";
import { Searchbar, DropdownSelect, Button } from "@kleros/ui-components-library";
@@ -9,60 +7,6 @@ import PaperIcon from "svgs/icons/paper.svg";
import PlusIcon from "svgs/icons/plus.svg";
import { List_filters } from "consts/filters";
-const Container = styled.div`
- display: flex;
- flex-direction: column;
- gap: 16px;
- margin-bottom: 16px;
- flex-wrap: wrap;
-
- ${landscapeStyle(
- () =>
- css`
- flex-direction: row;
- `
- )}
-`;
-
-const SearchBarContainer = styled.div`
- display: flex;
- flex: 1;
- flex-wrap: wrap;
- gap: 8px;
- z-index: 0;
-`;
-
-const StyledSearchbar = styled(Searchbar)`
- flex: 1;
- flex-basis: 310px;
- input {
- font-size: 16px;
- height: 45px;
- padding-top: 0px;
- padding-bottom: 0px;
- }
-`;
-
-const StyledPaperIcon = styled(PaperIcon)`
- path {
- fill: ${({ theme }) => theme.whiteBackground};
- }
-`;
-
-const StyledPlusIcon = styled(PlusIcon)`
- path {
- fill: ${({ theme }) => theme.whiteBackground};
- }
-`;
-
-const StyledDropdownSelect = styled(DropdownSelect)`
- [class*="button__Container"] {
- [class*="base-item__Item"] {
- border-left: 1px solid transparent;
- }
- }
-`;
-
const Search: React.FC<{ isList?: Boolean }> = ({ isList }) => {
const { page, order, filter, id } = useParams();
const location = useListRootPath();
@@ -70,7 +14,7 @@ const Search: React.FC<{ isList?: Boolean }> = ({ isList }) => {
const keywords = searchParams.get("keywords");
const decodedFilter = decodeListURIFilter(filter ?? "all");
- const [search, setSearch] = useState(keywords);
+ const [search, setSearch] = useState(keywords ?? undefined);
const navigate = useNavigate();
useDebounce(
@@ -91,37 +35,59 @@ const Search: React.FC<{ isList?: Boolean }> = ({ isList }) => {
};
return (
-
-
-
+
+ setSearch(e.target.value)}
+ onChange={(value) => setSearch(value)}
/>
-
-
+ handleStatusChange(item.itemValue)}
/>
{isList ? (
- navigate("/submit-list")} />
+ navigate("/submit-list")} />
) : (
- navigate(`/submit-item/${id}`)} />
+ navigate(`/submit-item/${id}`)} />
)}
-
+
);
};
diff --git a/web/src/components/StatDisplay.tsx b/web/src/components/StatDisplay.tsx
index 728b1e9..989d77d 100644
--- a/web/src/components/StatDisplay.tsx
+++ b/web/src/components/StatDisplay.tsx
@@ -1,56 +1,8 @@
-import React, { useMemo } from "react";
-import { landscapeStyle } from "styles/landscapeStyle";
-import styled, { useTheme, css } from "styled-components";
-import { responsiveSize } from "styles/responsiveSize";
-import { Theme } from "styled-components";
-
-const Container = styled.div`
- display: flex;
- max-width: 196px;
- align-items: center;
- gap: 8px;
-
- ${landscapeStyle(
- () => css`
- margin-bottom: ${responsiveSize(16, 30)};
- `
- )}
-`;
-
-const SVGContainer = styled.div<{ iconColor: string; backgroundColor: string }>`
- height: 48px;
- width: 48px;
- border-radius: 50%;
- background-color: ${({ backgroundColor }) => backgroundColor};
- display: flex;
- align-items: center;
- justify-content: center;
- svg {
- fill: ${({ iconColor }) => iconColor};
- height: 21px;
- width: 21px;
- }
-`;
-
-const TextContainer = styled.div`
- h1 {
- margin: 0;
- }
-`;
-
-const SubtextLabel = styled.label`
- font-size: 12px;
-`;
-
-const COLORS: Record> = {
- green: ["success", "successLight"],
- blue: ["primaryBlue", "mediumBlue"],
- purple: ["secondaryPurple", "mediumPurple"],
- orange: ["warning", "warningLight"],
-};
-
-export type IColors = keyof typeof COLORS;
+import React from "react";
+import clsx from "clsx";
+import { cn } from "~src/utils";
+export type IColors = "green" | "blue" | "purple" | "orange";
interface IStatDisplay {
title: string;
text: string | React.ReactNode;
@@ -59,22 +11,29 @@ interface IStatDisplay {
color: IColors;
}
-const StatDisplay: React.FC = ({ title, text, subtext, icon: Icon, color, ...props }) => {
- const theme = useTheme();
-
- const [iconColor, backgroundColor] = useMemo(() => {
- return COLORS[color].map((color) => theme[color]);
- }, [theme, color]);
+const landscapeMarginBottomCalc = "lg:mb-[calc(16px+(30-16)*(min(max(100vw,375px),1250px)-375px)/(1250-375))]";
+const StatDisplay: React.FC = ({ title, text, subtext, icon: Icon, color, ...props }) => {
return (
-
- {}
-
+
+
+ {}
+
+
-
{text}
- {subtext}
-
-
+ {text}
+
+
+
);
};
diff --git a/web/src/components/StatsAndFilters/Filters.tsx b/web/src/components/StatsAndFilters/Filters.tsx
index e9c11c2..c7acda2 100644
--- a/web/src/components/StatsAndFilters/Filters.tsx
+++ b/web/src/components/StatsAndFilters/Filters.tsx
@@ -1,9 +1,6 @@
import React from "react";
-import styled, { css } from "styled-components";
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
-import { hoverShortTransitionTiming } from "styles/commonStyles";
-
import { DropdownSelect } from "@kleros/ui-components-library";
import { useIsListView } from "context/IsListViewProvider";
@@ -12,41 +9,6 @@ import GridIcon from "svgs/icons/grid.svg";
import { useItemRootPath, useListRootPath } from "utils/uri";
import useIsDesktop from "hooks/useIsDesktop";
-const Container = styled.div`
- display: flex;
- justify-content: end;
- gap: 12px;
- width: fit-content;
-`;
-
-const IconsContainer = styled.div`
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 4px;
-`;
-
-const BaseIconStyles = css`
- ${hoverShortTransitionTiming}
- cursor: pointer;
- fill: ${({ theme }) => theme.primaryBlue};
- width: 16px;
- height: 16px;
- overflow: hidden;
-
- :hover {
- fill: ${({ theme }) => theme.secondaryBlue};
- }
-`;
-
-const StyledGridIcon = styled(GridIcon)`
- ${BaseIconStyles}
-`;
-
-const StyledListIcon = styled(ListIcon)`
- ${BaseIconStyles}
-`;
-
export interface IFilters {
isListFilter?: boolean;
}
@@ -69,23 +31,28 @@ const Filters: React.FC = ({ isListFilter = false }) => {
const isDesktop = useIsDesktop();
return (
-
+
handleOrderChange(item.itemValue)}
/>
{isDesktop && isListFilter ? (
-
+
{isListView ? (
- setIsListView(false)} />
+ setIsListView(false)}
+ />
) : (
- {
if (isDesktop) {
setIsListView(true);
@@ -93,9 +60,9 @@ const Filters: React.FC = ({ isListFilter = false }) => {
}}
/>
)}
-
+
) : null}
-
+
);
};
diff --git a/web/src/components/StatsAndFilters/Stats.tsx b/web/src/components/StatsAndFilters/Stats.tsx
index 7f741ae..aecb59a 100644
--- a/web/src/components/StatsAndFilters/Stats.tsx
+++ b/web/src/components/StatsAndFilters/Stats.tsx
@@ -1,28 +1,13 @@
import React from "react";
-import styled from "styled-components";
-
-const FieldWrapper = styled.div`
- display: inline-flex;
- gap: 4px;
-`;
-
-const SeparatorLabel = styled.label`
- margin: 0 8px;
- color: ${({ theme }) => theme.primaryText};
-`;
-
-const StyledLabel = styled.label`
- color: ${({ theme }) => theme.primaryText};
-`;
const Field: React.FC<{ label: string; value: string }> = ({ label, value }) => (
-
+
{value}
- {label}
-
+
+
);
-const Separator: React.FC = () => |;
+const Separator: React.FC = () => ;
type Field = {
label: string;
diff --git a/web/src/components/StatsAndFilters/index.tsx b/web/src/components/StatsAndFilters/index.tsx
index 52fe1a1..83ec637 100644
--- a/web/src/components/StatsAndFilters/index.tsx
+++ b/web/src/components/StatsAndFilters/index.tsx
@@ -1,22 +1,12 @@
import React from "react";
-import styled from "styled-components";
import Stats, { IStats } from "./Stats";
import Filters, { IFilters } from "./Filters";
-const Container = styled.div`
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
- margin-top: 11px;
- margin-bottom: 48px;
- justify-content: space-between;
-`;
-
const StatsAndFilters: React.FC = ({ fields, isListFilter }) => (
-
+
-
+
);
export default StatsAndFilters;
diff --git a/web/src/components/StyledIcons/ClosedCircleIcon.tsx b/web/src/components/StyledIcons/ClosedCircleIcon.tsx
index 29b7e47..e3ddc94 100644
--- a/web/src/components/StyledIcons/ClosedCircleIcon.tsx
+++ b/web/src/components/StyledIcons/ClosedCircleIcon.tsx
@@ -1,14 +1,7 @@
import React from "react";
-import styled from "styled-components";
import ClosedCircle from "svgs/icons/close-circle.svg";
-const StyledClosedCircle = styled(ClosedCircle)`
- path {
- fill: ${({ theme }) => theme.error};
- }
-`;
-
const ClosedCircleIcon: React.FC = () => {
- return ;
+ return ;
};
export default ClosedCircleIcon;
diff --git a/web/src/components/StyledSkeleton.tsx b/web/src/components/StyledSkeleton.tsx
index 02e4def..75e58ca 100644
--- a/web/src/components/StyledSkeleton.tsx
+++ b/web/src/components/StyledSkeleton.tsx
@@ -1,88 +1,30 @@
import React from "react";
-import styled from "styled-components";
import Skeleton from "react-loading-skeleton";
import { responsiveSize } from "styles/responsiveSize";
-export const StyledSkeleton = styled(Skeleton)`
- z-index: 0;
-`;
-
-const SkeletonRegistryCardContainer = styled.div`
- width: 100%;
-`;
-
-const StyledSkeletonRegistryCard = styled(Skeleton)`
- height: ${responsiveSize(270, 296)};
-`;
-
-const StyledSkeletonRegistryListItem = styled(Skeleton)`
- height: 62px;
-`;
-
-const StyledSkeletonEvidenceCard = styled(Skeleton)`
- height: 146px;
- width: 76vw;
-`;
-
-const HistorySkeletonContainer = styled.div`
- display: flex;
- flex-direction: column;
- gap: 8px;
-`;
-const HistoryStatusSkeleton = styled(Skeleton)`
- height: 24px;
- width: 160px;
-`;
-const HistoryDateSkeleton = styled(Skeleton)`
- height: 18px;
- width: 100px;
-`;
-
-const SkeletonJustificationContainer = styled.div`
- width: 100%;
- display: flex;
- gap: 16px;
- flex-direction: column;
-`;
-
-const SkeletonJustificationTitle = styled(Skeleton)`
- width: ${responsiveSize(100, 160)};
- height: 24px;
- margin-left: auto;
-`;
-
-const SkeletonJustificationDescription = styled(Skeleton)`
- height: 60px;
-`;
-
-const SkeletonJustificationAttachment = styled(Skeleton)`
- width: ${responsiveSize(60, 80)};
- height: 24px;
-`;
-
export const HistorySkeletonCard = () => (
-
-
-
-
-
-
+
+
+
+
+
+
);
export const SkeletonRegistryCard = () => (
-
-
-
+
+
+
);
export const SkeletonJustificationCard = () => (
-
-
-
-
-
+
+
+
+
+
);
-export const SkeletonRegistryListItem = () => ;
+export const SkeletonRegistryListItem = () => ;
-export const SkeletonEvidenceCard = () => ;
+export const SkeletonEvidenceCard = () => ;
diff --git a/web/src/components/TruncatedText.tsx b/web/src/components/TruncatedText.tsx
index 5056fb5..894cebf 100644
--- a/web/src/components/TruncatedText.tsx
+++ b/web/src/components/TruncatedText.tsx
@@ -1,10 +1,5 @@
import React from "react";
-import styled from "styled-components";
-
-const StyledText = styled.h3`
- font-weight: 400;
- margin: 0px;
-`;
+import { cn } from "~src/utils";
interface ITruncatedText {
text: string;
@@ -19,7 +14,7 @@ interface ITruncatedText {
*/
const TruncatedText: React.FC = ({ text, maxLength, className }) => {
const truncatedText = text?.length <= maxLength ? text : text?.slice(0, maxLength) + "…";
- return {truncatedText};
+ return {truncatedText}
;
};
export default TruncatedText;
diff --git a/web/src/components/WithHelpTooltip.tsx b/web/src/components/WithHelpTooltip.tsx
index 395b0ea..4fa564f 100644
--- a/web/src/components/WithHelpTooltip.tsx
+++ b/web/src/components/WithHelpTooltip.tsx
@@ -1,29 +1,6 @@
import React from "react";
-import styled, { css } from "styled-components";
-import { landscapeStyle } from "styles/landscapeStyle";
import { Tooltip } from "@kleros/ui-components-library";
-import _HelpIcon from "svgs/menu-icons/help.svg";
-
-const Container = styled.div`
- display: flex;
- align-items: center;
-`;
-
-const HelpIcon = styled(_HelpIcon)`
- display: flex;
- align-items: center;
- height: 12px;
- width: 12px;
- fill: ${({ theme }) => theme.secondaryText};
- margin: 0 0 0 8px;
-
- ${landscapeStyle(
- () => css`
- height: 14px;
- width: 14px;
- `
- )}
-`;
+import HelpIcon from "svgs/menu-icons/help.svg";
interface IWithHelpTooltip {
tooltipMsg: string;
@@ -32,12 +9,12 @@ interface IWithHelpTooltip {
}
const WithHelpTooltip: React.FC = ({ tooltipMsg, children, place }) => (
-
+
{children}
-
+
-
+
);
export default WithHelpTooltip;
diff --git a/web/src/context/StyledComponentsProvider.tsx b/web/src/context/StyledComponentsProvider.tsx
deleted file mode 100644
index 7d11c34..0000000
--- a/web/src/context/StyledComponentsProvider.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import React from "react";
-import { ThemeProvider } from "styled-components";
-import { useLocalStorage } from "hooks/useLocalStorage";
-import { ToggleThemeProvider } from "hooks/useToggleThemeContext";
-import { GlobalStyle } from "styles/global-style";
-import { lightTheme, darkTheme } from "styles/themes";
-
-const StyledComponentsProvider: React.FC<{
- children: React.ReactNode;
-}> = ({ children }) => {
- const [theme, setTheme] = useLocalStorage("theme", "dark");
- const toggleTheme = () => {
- if (theme === "light") setTheme("dark");
- else setTheme("light");
- };
- return (
-
-
-
- {children}
-
-
- );
-};
-
-export default StyledComponentsProvider;
diff --git a/web/src/context/ThemeProvider.tsx b/web/src/context/ThemeProvider.tsx
new file mode 100644
index 0000000..9530cce
--- /dev/null
+++ b/web/src/context/ThemeProvider.tsx
@@ -0,0 +1,29 @@
+import React, { useEffect } from "react";
+import { useLocalStorage } from "hooks/useLocalStorage";
+import { ToggleThemeProvider } from "hooks/useToggleThemeContext";
+
+type Theme = "light" | "dark";
+
+const ThemeProvider: React.FC<{
+ children: React.ReactNode;
+}> = ({ children }) => {
+ const [theme, setTheme] = useLocalStorage("theme", "dark");
+
+ const toggleTheme = () => {
+ if (theme === "light") setTheme("dark");
+ else setTheme("light");
+ };
+
+ useEffect(() => {
+ const root = document.documentElement;
+ if (theme === "dark") {
+ root.classList.add("dark");
+ } else {
+ root.classList.remove("dark");
+ }
+ }, [theme]);
+
+ return {children};
+};
+
+export default ThemeProvider;
diff --git a/web/src/context/Web3Provider.tsx b/web/src/context/Web3Provider.tsx
index fff5fe5..daf99b9 100644
--- a/web/src/context/Web3Provider.tsx
+++ b/web/src/context/Web3Provider.tsx
@@ -7,8 +7,6 @@ import { WagmiAdapter } from "@reown/appkit-adapter-wagmi";
import { ALL_CHAINS, DEFAULT_CHAIN } from "consts/chains";
import { isProductionDeployment } from "consts/index";
-import { lightTheme } from "styles/themes";
-
const alchemyApiKey = import.meta.env.ALCHEMY_API_KEY ?? "";
const isProduction = isProductionDeployment();
@@ -61,7 +59,7 @@ createAppKit({
defaultNetwork: isProduction ? arbitrum : arbitrumSepolia,
projectId,
themeVariables: {
- "--w3m-color-mix": lightTheme.primaryPurple,
+ "--w3m-color-mix": "#4D00B4",
"--w3m-color-mix-strength": 20,
// overlay portal is at 9999
"--w3m-z-index": 10000,
diff --git a/web/src/global.css b/web/src/global.css
new file mode 100644
index 0000000..45f5410
--- /dev/null
+++ b/web/src/global.css
@@ -0,0 +1,187 @@
+@import "../../node_modules/@kleros/ui-components-library/dist/assets/theme.css";
+@tailwind utilities;
+@source "../../node_modules/@kleros/ui-components-library";
+@import "tailwindcss";
+@custom-variant dark (&:where(.dark, .dark *));
+
+@theme {
+ --color-white: #ffffff;
+ --color-white-73: #ffffffba;
+ --color-black: #000000;
+ --color-light-blue-65: #2a1260a6;
+ --color-light-grey: #f0f0f0;
+ --color-dark-purple: #220050;
+ --color-violet-purple: #6a1dcd;
+ --color-lavender-purple: #bb72ff;
+ --color-pale-cyan: #acffff;
+ --color-lime-green: #f3ffd9;
+ --color-white-low-opacity-subtle: #ffffff0d;
+ --color-white-low-opacity-strong: #ffffff26;
+ --color-black-low-opacity: #00000080;
+ --color-primary-text-73: color-mix(in srgb, var(--klerosUIComponentsPrimaryText) 73%, transparent);
+ --color-skeleton-bg: #ebebeb;
+ --color-skeleton-highlight: #f5f5f5;
+ --max-width-landscape: 87.5rem;
+ --shadow-custom: 0px 2px 3px rgba(0, 0, 0, 0.06);
+ --leading-18px: 18px;
+}
+
+.dark {
+ --color-skeleton-bg: #3a2270;
+ --color-skeleton-highlight: #3e307c;
+}
+
+:root {
+ --toastify-color-info: var(--klerosUIComponentsPrimaryBlue);
+ --toastify-color-success: var(--klerosUIComponentsSuccess);
+ --toastify-color-warning: var(--klerosUIComponentsWarning);
+ --toastify-color-error: var(--klerosUIComponentsError);
+}
+
+.react-loading-skeleton {
+ z-index: 0;
+ --base-color: var(--color-skeleton-bg);
+ --highlight-color: var(--color-skeleton-highlight);
+}
+
+body {
+ font-family: "Open Sans", sans-serif;
+ margin: 0;
+ background-color: var(--klerosUIComponentsLightBlue);
+}
+
+html {
+ box-sizing: border-box;
+}
+
+*,
+*:before,
+*:after {
+ box-sizing: inherit;
+}
+
+:focus:not(:focus-visible) {
+ outline: none;
+}
+
+:focus-visible {
+ outline: 2px solid var(--klerosUIComponentsPrimaryBlue);
+ outline-offset: 2px;
+}
+
+h1 {
+ margin: 0 0 16px 0;
+ font-weight: 600;
+ font-size: 24px;
+ line-height: 32px;
+ color: var(--klerosUIComponentsPrimaryText);
+}
+
+h2 {
+ margin: 0 0 16px 0;
+ font-weight: 400;
+ font-size: 24px;
+ line-height: 32px;
+ color: var(--klerosUIComponentsPrimaryText);
+}
+
+h3 {
+ margin: 0 0 16px 0;
+ font-weight: 600;
+ font-size: 16px;
+ line-height: 24px;
+ color: var(--klerosUIComponentsPrimaryText);
+}
+
+p {
+ font-weight: 400;
+ font-size: 16px;
+ line-height: 24px;
+ color: var(--klerosUIComponentsPrimaryText);
+}
+
+textarea {
+ font-family: "Open Sans";
+ font-size: 14px;
+}
+
+small {
+ font-weight: 600;
+ font-size: 14px;
+ line-height: 18px;
+ color: var(--klerosUIComponentsPrimaryText);
+}
+
+label {
+ font-weight: 400;
+ font-size: 14px;
+ line-height: 18px;
+ color: var(--klerosUIComponentsSecondaryText);
+}
+
+a {
+ font-weight: 400;
+ font-size: 14px;
+ text-decoration: none;
+ color: var(--klerosUIComponentsPrimaryBlue);
+}
+
+hr {
+ opacity: 1;
+ border: 1px solid var(--klerosUIComponentsStroke);
+}
+
+svg,
+img {
+ display: inline-block;
+ vertical-align: middle;
+ visibility: visible;
+}
+
+ul li {
+ color: var(--klerosUIComponentsPrimaryText);
+}
+
+.os-theme-dark {
+ --os-handle-bg: var(--color-violet-purple);
+ --os-handle-bg-hover: var(--klerosUIComponentsSecondaryPurple);
+ --os-handle-bg-active: var(--color-lavender-purple);
+}
+
+.Toastify__toast-container.Toastify__toast-container {
+ top: unset;
+ padding-top: 20px;
+}
+
+/* Custom Scrollbar */
+.custom-scrollbar::-webkit-scrollbar {
+ width: 6px;
+ height: 6px;
+}
+
+.custom-scrollbar::-webkit-scrollbar-track {
+ background: transparent;
+}
+
+.custom-scrollbar::-webkit-scrollbar-thumb {
+ background-color: var(--color-violet-purple);
+ border-radius: 10px;
+ transition:
+ opacity 0.15s,
+ background-color 0.15s,
+ border-color 0.15s,
+ width 0.15s;
+}
+
+.custom-scrollbar::-webkit-scrollbar-thumb:hover {
+ background-color: var(--klerosUIComponentsSecondaryPurple);
+}
+
+.custom-scrollbar::-webkit-scrollbar-thumb:active {
+ background-color: var(--color-lavender-purple);
+}
+
+.custom-scrollbar {
+ scrollbar-width: thin;
+ scrollbar-color: var(--color-violet-purple) transparent;
+}
diff --git a/web/src/hooks/useIsDesktop.tsx b/web/src/hooks/useIsDesktop.tsx
index 1b0928f..89e9477 100644
--- a/web/src/hooks/useIsDesktop.tsx
+++ b/web/src/hooks/useIsDesktop.tsx
@@ -1,10 +1,10 @@
import { useMemo } from "react";
import { useWindowSize } from "react-use";
-import { BREAKPOINT_LANDSCAPE } from "styles/landscapeStyle";
+import { LG_BREAKPOINT } from "~src/styles/breakpoints";
const useIsDesktop = () => {
const { width } = useWindowSize();
- return useMemo(() => width > BREAKPOINT_LANDSCAPE, [width]);
+ return useMemo(() => width > LG_BREAKPOINT, [width]);
};
export default useIsDesktop;
diff --git a/web/src/hooks/useToggleThemeContext.tsx b/web/src/hooks/useToggleThemeContext.tsx
index 9c2017d..610bb46 100644
--- a/web/src/hooks/useToggleThemeContext.tsx
+++ b/web/src/hooks/useToggleThemeContext.tsx
@@ -12,11 +12,9 @@ export const ToggleThemeProvider: React.FC<{
theme: string;
toggleTheme: () => void;
}> = ({ theme, toggleTheme, children }) => {
- return (
- {children}
- );
+ return {children};
};
-export const useToggleTheme: () => [string, () => void] = () => {
+export const useTheme: () => [string, () => void] = () => {
return useContext(Context);
};
diff --git a/web/src/index.tsx b/web/src/index.tsx
index 08bcb91..cc2ad2d 100644
--- a/web/src/index.tsx
+++ b/web/src/index.tsx
@@ -1,11 +1,9 @@
import React from "react";
import { createRoot } from "react-dom/client";
import App from "./app";
-import Modal from "react-modal";
import { HashRouter } from "react-router-dom";
const container = document.getElementById("app");
-Modal.setAppElement(container!);
const root = createRoot(container!);
root.render(
@@ -13,4 +11,4 @@ root.render(
-);
\ No newline at end of file
+);
diff --git a/web/src/layout/Footer/index.tsx b/web/src/layout/Footer/index.tsx
index bebb00c..892bb69 100644
--- a/web/src/layout/Footer/index.tsx
+++ b/web/src/layout/Footer/index.tsx
@@ -1,79 +1,39 @@
import React from "react";
-import styled, { css } from "styled-components";
-
-import { landscapeStyle } from "styles/landscapeStyle";
-import { hoverShortTransitionTiming } from "styles/commonStyles";
+import clsx from "clsx";
import SecuredByKlerosLogo from "svgs/footer/secured-by-kleros.svg";
import { socialmedia } from "consts/socialmedia";
import LightButton from "components/LightButton";
-import { ExternalLink } from "components/ExternalLink";
-
-const Container = styled.div`
- height: 114px;
- width: 100%;
- background-color: ${({ theme }) => (theme.name === "dark" ? theme.lightBlue : theme.primaryPurple)};
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- padding: 8px;
- gap: 16px;
-
- ${landscapeStyle(
- () => css`
- height: 64px;
- flex-direction: row;
- justify-content: space-between;
- padding: 0 32px;
- `
- )}
-`;
-
-const StyledSecuredByKlerosLogo = styled(SecuredByKlerosLogo)`
- ${hoverShortTransitionTiming}
- min-height: 24px;
-
- path {
- fill: ${({ theme }) => theme.white}BF;
- }
-
- :hover path {
- fill: ${({ theme }) => theme.white};
- }
-`;
-
-const StyledSocialMedia = styled.div`
- display: flex;
-
- .button-svg {
- margin-right: 0;
- }
-`;
const SecuredByKleros: React.FC = () => (
-
-
-
+
+
+
);
const SocialMedia = () => (
-
+
{Object.values(socialmedia).map((site, i) => (
-
+
-
+
))}
-
+
);
const Footer: React.FC = () => (
-
+
-
+
);
export default Footer;
diff --git a/web/src/layout/Header/DesktopHeader.tsx b/web/src/layout/Header/DesktopHeader.tsx
index cf30e78..d1877bb 100644
--- a/web/src/layout/Header/DesktopHeader.tsx
+++ b/web/src/layout/Header/DesktopHeader.tsx
@@ -1,5 +1,4 @@
import React from "react";
-import styled, { css } from "styled-components";
import { useToggle } from "react-use";
import { useAccount } from "wagmi";
@@ -9,7 +8,6 @@ import KlerosSolutionsIcon from "svgs/menu-icons/kleros-solutions.svg";
import { DEFAULT_CHAIN } from "consts/chains";
import { useLockOverlayScroll } from "hooks/useLockOverlayScroll";
-import { landscapeStyle } from "styles/landscapeStyle";
import { responsiveSize } from "styles/responsiveSize";
import ConnectWallet from "components/ConnectWallet";
@@ -24,61 +22,6 @@ import Menu from "./navbar/Menu";
import Help from "./navbar/Menu/Help";
import Settings from "./navbar/Menu/Settings";
-const Container = styled.div`
- display: none;
- position: absolute;
- height: 64px;
-
- ${landscapeStyle(
- () => css`
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- position: relative;
- `
- )};
-`;
-
-const LeftSide = styled.div`
- display: flex;
- gap: 8px;
-`;
-
-const MiddleSide = styled.div`
- display: flex;
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
-`;
-
-const RightSide = styled.div`
- display: flex;
- gap: ${responsiveSize(4, 8)};
-
- margin-left: 8px;
- canvas {
- width: 20px;
- }
-`;
-
-const LightButtonContainer = styled.div`
- display: flex;
- align-items: center;
-`;
-
-const StyledKlerosSolutionsIcon = styled(KlerosSolutionsIcon)`
- fill: ${({ theme }) => theme.white} !important;
-`;
-
-const ConnectWalletContainer = styled.div<{ isConnected: boolean; isDefaultChain: boolean }>`
- label {
- color: ${({ theme }) => theme.white};
- cursor: pointer;
- }
-`;
-
const DesktopHeader: React.FC = () => {
const [isDappListOpen, toggleIsDappListOpen] = useToggle(false);
const [isHelpOpen, toggleIsHelpOpen] = useToggle(false);
@@ -89,34 +32,34 @@ const DesktopHeader: React.FC = () => {
return (
<>
-
-
-
+
+
+
{
toggleIsDappListOpen();
}}
- Icon={StyledKlerosSolutionsIcon}
+ Icon={KlerosSolutionsIcon}
/>
-
+
-
+
-
+
-
+
-
-
+
-
+
-
-
+
+
{(isDappListOpen || isHelpOpen || isSettingsOpen) && (
diff --git a/web/src/layout/Header/Logo.tsx b/web/src/layout/Header/Logo.tsx
index 243ffa2..04a08b2 100644
--- a/web/src/layout/Header/Logo.tsx
+++ b/web/src/layout/Header/Logo.tsx
@@ -1,38 +1,16 @@
import React from "react";
-import styled from "styled-components";
-
-import { hoverShortTransitionTiming } from "styles/commonStyles";
import { Link } from "react-router-dom";
import CurateLogo from "svgs/header/curate.svg";
-const Container = styled.div`
- display: flex;
- flex-direction: row;
- align-items: center;
- gap: 16px;
-`;
-
-const StyledCurateLogo = styled(CurateLogo)`
- ${hoverShortTransitionTiming}
- max-height: 48px;
- width: auto;
-
- &:hover {
- path {
- fill: ${({ theme }) => theme.white}BF;
- }
- }
-`;
-
const Logo: React.FC = () => (
-
+
{" "}
-
+
-
+
);
export default Logo;
diff --git a/web/src/layout/Header/MobileHeader.tsx b/web/src/layout/Header/MobileHeader.tsx
index 280881c..5296bce 100644
--- a/web/src/layout/Header/MobileHeader.tsx
+++ b/web/src/layout/Header/MobileHeader.tsx
@@ -1,39 +1,14 @@
import React, { useContext, useMemo, useRef } from "react";
-import styled, { css } from "styled-components";
import { useClickAway, useToggle } from "react-use";
import HamburgerIcon from "svgs/header/hamburger.svg";
-import { landscapeStyle } from "styles/landscapeStyle";
-
import LightButton from "components/LightButton";
import Logo from "./Logo";
import NavBar from "./navbar";
-const Container = styled.div`
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- height: 64px;
-
- ${landscapeStyle(
- () => css`
- display: none;
- `
- )}
-`;
-
-const StyledLightButton = styled(LightButton)`
- padding: 0 !important;
-
- .button-svg {
- margin-right: 0px;
- }
-`;
-
const OpenContext = React.createContext({
isOpen: false,
toggleIsOpen: () => {
@@ -51,13 +26,13 @@ const MobileHeader = () => {
useClickAway(containerRef, () => toggleIsOpen(false));
const memoizedContext = useMemo(() => ({ isOpen, toggleIsOpen }), [isOpen, toggleIsOpen]);
return (
-
+
-
+
-
+
);
};
export default MobileHeader;
diff --git a/web/src/layout/Header/index.tsx b/web/src/layout/Header/index.tsx
index 2f926ab..e70ffd6 100644
--- a/web/src/layout/Header/index.tsx
+++ b/web/src/layout/Header/index.tsx
@@ -1,5 +1,4 @@
import React from "react";
-import styled, { useTheme } from "styled-components";
import { StatusBanner } from "subgraph-status";
@@ -8,46 +7,18 @@ import { getGraphqlUrl } from "utils/getGraphqlUrl";
import DesktopHeader from "./DesktopHeader";
import MobileHeader from "./MobileHeader";
-const Container = styled.div`
- display: flex;
- flex-wrap: wrap;
- position: sticky;
- z-index: 10;
- top: 0;
- width: 100%;
- background-color: ${({ theme }) => (theme.name === "dark" ? `${theme.lightBlue}A6` : theme.primaryPurple)};
- backdrop-filter: ${({ theme }) => (theme.name === "dark" ? "blur(12px)" : "none")};
- -webkit-backdrop-filter: ${({ theme }) => (theme.name === "dark" ? "blur(12px)" : "none")}; // Safari support
-`;
-
-const HeaderContainer = styled.div`
- width: 100%;
- padding: 0px 24px;
-`;
-
-const StyledBanner = styled(StatusBanner)`
- position: sticky !important;
- .status-text {
- h2 {
- margin: 0;
- line-height: 24px;
- }
- }
-`;
-
const Header: React.FC = () => {
- const theme = useTheme();
-
return (
-
-
+ {
{ name: "Kleros Core", url: getGraphqlUrl(true) },
]}
/>
-
+
-
-
+
+
);
};
diff --git a/web/src/layout/Header/navbar/DappList.tsx b/web/src/layout/Header/navbar/DappList.tsx
index 5c00e38..4b8fdf0 100644
--- a/web/src/layout/Header/navbar/DappList.tsx
+++ b/web/src/layout/Header/navbar/DappList.tsx
@@ -1,5 +1,4 @@
import React, { useRef } from "react";
-import styled, { css } from "styled-components";
import { useClickAway } from "react-use";
@@ -11,65 +10,10 @@ import Court from "svgs/icons/kleros.svg";
import POH from "svgs/icons/poh-image.png";
import Vea from "svgs/icons/vea.svg";
-import { landscapeStyle } from "styles/landscapeStyle";
import { responsiveSize } from "styles/responsiveSize";
import Product from "./Product";
-
-const Container = styled.div`
- display: flex;
- position: absolute;
- max-height: 340px;
- top: 5%;
- left: 50%;
- transform: translate(-50%);
- z-index: 1;
- flex-direction: column;
- align-items: center;
-
- width: 86vw;
- max-width: 480px;
- border-radius: 3px;
- border: 1px solid ${({ theme }) => theme.stroke};
- background-color: ${({ theme }) => theme.whiteBackground};
- box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.06);
-
- svg {
- visibility: visible;
- }
-
- ${landscapeStyle(
- () => css`
- margin-top: 64px;
- top: 0;
- left: 0;
- right: auto;
- transform: none;
- width: ${responsiveSize(300, 480)};
- max-height: 80vh;
- `
- )}
-`;
-
-const Header = styled.h1`
- padding-top: 24px;
- font-size: 24px;
- font-weight: 600;
- line-height: 32.68px;
-`;
-
-const ItemsDiv = styled.div`
- display: grid;
- overflow-y: auto;
- padding: 4px ${responsiveSize(8, 24)} 16px;
- row-gap: 8px;
- column-gap: 2px;
- justify-items: center;
- max-width: 480px;
- min-width: 300px;
- width: ${responsiveSize(300, 480)};
- grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
-`;
+import clsx from "clsx";
const ITEMS = [
{
@@ -138,19 +82,34 @@ interface IDappList {
toggleIsDappListOpen: () => void;
}
+const landscapeWidthCalc = "lg:w-[calc(300px+(480-300)*(min(max(100vw,375px),1250px)-375px)/(1250-375))]";
+
const DappList: React.FC = ({ toggleIsDappListOpen }) => {
const containerRef = useRef(null);
useClickAway(containerRef, () => toggleIsDappListOpen());
return (
-
-
-
+
+
Kleros Solutions
+
{ITEMS.map((item) => {
return
;
})}
-
-
+
+
);
};
export default DappList;
diff --git a/web/src/layout/Header/navbar/Debug.tsx b/web/src/layout/Header/navbar/Debug.tsx
index 1be2281..f2d4db2 100644
--- a/web/src/layout/Header/navbar/Debug.tsx
+++ b/web/src/layout/Header/navbar/Debug.tsx
@@ -1,22 +1,16 @@
import React from "react";
-import styled from "styled-components";
// import { useSortitionModulePhase } from "hooks/contracts/generated";
import { GIT_BRANCH, GIT_DIRTY, GIT_HASH, GIT_TAGS, GIT_URL, RELEASE_VERSION } from "consts/index";
-const Container = styled.div`
- label,
- a {
- font-family: "Roboto Mono", monospace;
- line-height: 10px;
- font-size: 10px;
- color: ${({ theme }) => theme.stroke};
- }
-`;
-
const Version = () => (
-