Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5b7915bf49 |
0
Form/index.js
Normal file
0
Form/index.js
Normal file
|
|
@ -1,18 +0,0 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import tw, { TwStyle } from "twin.macro";
|
||||
import "styled-components/macro";
|
||||
import { ComponentProps, forwardRef } from "react";
|
||||
|
||||
export const Badge = forwardRef<HTMLParagraphElement, { color: string | TwStyle, text: string | number }>(({ color, text, ...props }, ref) => {
|
||||
const colors = {
|
||||
yellow: tw`bg-yellow-500`,
|
||||
gray: tw`bg-gray-500`,
|
||||
red: tw`bg-red-700`,
|
||||
};
|
||||
|
||||
const realColor = (typeof (color) === "string" && color in colors) ? colors[color] : color;
|
||||
|
||||
return (
|
||||
<p ref={ref} css={[tw`px-2 py-1 inline text-primary text-xs font-semibold uppercase rounded-full `, realColor]} {...props}>{text}</p>
|
||||
);
|
||||
});
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
import React, { cloneElement, isValidElement, useEffect, useImperativeHandle, useRef, useState } from "react";
|
||||
import { createPopper, Placement } from "@popperjs/core";
|
||||
import { createPopper } from "@popperjs/core";
|
||||
import { usePopper } from 'react-popper';
|
||||
|
||||
import styled from "styled-components";
|
||||
import tw from "twin.macro"
|
||||
import tw, { styled } from "twin.macro"
|
||||
|
||||
|
||||
import { colors, colorsDisabled, colorsHover, textColors, textColorsHover } from "./Colors";
|
||||
|
|
@ -17,16 +16,7 @@ const DropDownItem = styled.button(({ type }) => [
|
|||
])
|
||||
export { DropDownItem }
|
||||
|
||||
let Dropdown = React.forwardRef(({ children, dropdownCss = null, onValueChanged = null, button, buttonProps = null, popper = null, placement = null, hover = null, ...props }: {
|
||||
children: React.ReactNode,
|
||||
dropdownCss?: any,
|
||||
onValueChanged?: (value: boolean) => void,
|
||||
button?: React.ReactNode,
|
||||
buttonProps?: any,
|
||||
popper?: any,
|
||||
placement?: Placement,
|
||||
hover?: boolean,
|
||||
}, ref) => {
|
||||
let Dropdown = React.forwardRef(({ children, dropdownCss, onValueChanged, button, buttonProps, popper, placement, hover, ...props }, ref) => {
|
||||
// dropdown props
|
||||
const [overButton, setOverButton] = React.useState(false);
|
||||
const [overDropDown, setOverDropDown] = React.useState(false);
|
||||
|
|
@ -95,14 +85,11 @@ let Dropdown = React.forwardRef(({ children, dropdownCss = null, onValueChanged
|
|||
let childrenWithProps = React.Children.map(children, (item) => {
|
||||
if (!item)
|
||||
return;
|
||||
//check that item is not only ReactNode
|
||||
if (!isValidElement(item))
|
||||
return;
|
||||
let click = item.props?.onClick;
|
||||
let close = item.props?.closeOnClick ?? true;
|
||||
|
||||
return cloneElement(item as any, { key: Array.isArray(children) ? children.indexOf(item) : 0, onClick: () => { close && closeDropdownPopover(); click && click() } });
|
||||
return cloneElement(item, { key: children.indexOf ? children.indexOf(item) : 0, onClick: () => { close && closeDropdownPopover(); click && click() } });
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
|
|
@ -129,7 +116,7 @@ let Dropdown = React.forwardRef(({ children, dropdownCss = null, onValueChanged
|
|||
dropdownPopoverShow ? tw`block` : tw`hidden`,
|
||||
tw`bg-trinary text-base z-50 float-left rounded-xl overflow-hidden text-left shadow-lg`,
|
||||
dropdownCss,
|
||||
(props as any).css
|
||||
props.css
|
||||
]}
|
||||
>
|
||||
{childrenWithProps}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import { Country } from "@services/accounting-api";
|
||||
import { lazy, Suspense } from 'react';
|
||||
|
||||
export default function Flag({ country, ...props }: { country: Country | "EU" }) {
|
||||
const FlagIcon = lazy(() => import(`country-flag-icons/react/3x2`).then(module => ({ default: module[country] })));
|
||||
|
||||
return (
|
||||
<Suspense fallback={<div {...props}>...</div>}>
|
||||
<FlagIcon {...props}/>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
111
Parts/Input.js
Normal file
111
Parts/Input.js
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
import React from "react";
|
||||
|
||||
import tw, { styled } from "twin.macro";
|
||||
;
|
||||
//import { useField as useFormikField, useFormikContext } from "formik";
|
||||
const useFormikField = null;
|
||||
const useFormikContext = ()=>{};
|
||||
|
||||
export function useField(props){
|
||||
let getField = useFormikField;
|
||||
const context = useFormikContext();
|
||||
if(!context){
|
||||
getField = (props)=>{
|
||||
return [props, null, null];
|
||||
}
|
||||
}
|
||||
return getField(props);
|
||||
}
|
||||
|
||||
export default function Input({ label, title, children, ...props }) {
|
||||
/*name, id*/
|
||||
|
||||
const [field, meta, helpers] = useField(props);
|
||||
|
||||
return (
|
||||
<div css={[title && tw`my-1`]} >
|
||||
{title && (
|
||||
<label
|
||||
{...label}
|
||||
css={[tw`block text-secondary text-sm font-bold mb-2`, label?.css]}
|
||||
>
|
||||
{/*htmlFor={id ?? name ?? title}*/}
|
||||
{title}
|
||||
</label>
|
||||
)}
|
||||
{/*name={name || title} id={id || name || title}*/}
|
||||
<input
|
||||
{...field}
|
||||
{...props}
|
||||
tw="bg-primary appearance-none border-2 border-secondary rounded w-full py-2 px-4 text-primary leading-tight focus:outline-none focus:bg-secondary focus:border-accent transition duration-150 "
|
||||
/>
|
||||
{children}
|
||||
{meta?.touched && meta.error ? (
|
||||
<div tw="text-[#c23c3c]">{meta.error}</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export function TextArea({
|
||||
label,
|
||||
title,
|
||||
children,
|
||||
...props
|
||||
}) {
|
||||
|
||||
const [field, meta, helpers] = useField(props);
|
||||
|
||||
return (
|
||||
<div css={[title && tw`my-1`]} >
|
||||
{title && (
|
||||
<label
|
||||
{...label}
|
||||
css={[tw`block text-secondary text-sm font-bold mb-2`, label?.css]}
|
||||
|
||||
>
|
||||
{title}
|
||||
</label>
|
||||
)}
|
||||
<textarea
|
||||
{...props}
|
||||
{...field}
|
||||
tw="bg-primary appearance-none border-2 border-secondary rounded w-full py-2 px-4 text-primary leading-tight focus:outline-none focus:bg-secondary focus:border-accent transition duration-150 "
|
||||
/>
|
||||
{children}
|
||||
{meta?.touched && meta.error ? (
|
||||
<div tw="text-[#c23c3c]">{meta.error}</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function CheckBox({
|
||||
label,
|
||||
title,
|
||||
|
||||
children,
|
||||
...props
|
||||
}) {
|
||||
|
||||
const [field, meta, helpers] = useField(props);
|
||||
|
||||
return (
|
||||
<div tw="my-1 flex text-secondary">
|
||||
<input
|
||||
{...props}
|
||||
{...field}
|
||||
type="checkbox"
|
||||
tw="checked:bg-accent w-6 h-6 rounded-full bg-secondary border-secondary border-4 appearance-none cursor-pointer "
|
||||
/>
|
||||
{title != null ? (
|
||||
<label
|
||||
{...label}
|
||||
css={[tw`block font-bold px-2`, label?.css]}
|
||||
>
|
||||
{title}
|
||||
</label>
|
||||
) : null}
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
187
Parts/Input.tsx
187
Parts/Input.tsx
|
|
@ -1,187 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
import tw from "twin.macro";
|
||||
import { useField as useFormikField, useFormikContext, FieldHookConfig } from "formik";
|
||||
import { IMaskInput, IMaskInputProps, IMaskMixinProps } from 'react-imask';
|
||||
//const useFormikField = null;
|
||||
//const useFormikContext = ()=>{};
|
||||
|
||||
export function useField<Val=any>(props) {
|
||||
let getField = useFormikField<Val>;
|
||||
const context = useFormikContext();
|
||||
if (!context) {
|
||||
getField = (propsOrFieldName: FieldHookConfig<any>) => {
|
||||
return [props, null, null];
|
||||
}
|
||||
}
|
||||
return getField(props);
|
||||
}
|
||||
|
||||
export default function Input(
|
||||
props: React.InputHTMLAttributes<HTMLInputElement> & FieldHookConfig<any> & {
|
||||
label?: React.ComponentPropsWithoutRef<"label">;
|
||||
title?: string;
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
) {
|
||||
/*name, id*/
|
||||
let { children, ...otherProps } = props;
|
||||
|
||||
const [field, meta, helpers] = useField(otherProps);
|
||||
|
||||
return (
|
||||
<div css={[props.title && tw`my-1`, tw`relative`]} className={props.className}>
|
||||
{props.title && (
|
||||
<label
|
||||
{...props.label}
|
||||
htmlFor={props.id ?? props.name ?? props.title}
|
||||
css={[tw`block text-secondary text-sm font-bold mb-2`, props.label?.css]}
|
||||
>
|
||||
{/*htmlFor={id ?? name ?? title}*/}
|
||||
{props.title}
|
||||
</label>
|
||||
)}
|
||||
{/*name={name || title} id={id || name || title}*/}
|
||||
<input
|
||||
id={props.id ?? props.name ?? props.title}
|
||||
{...field}
|
||||
{...otherProps as any}
|
||||
tw="bg-primary appearance-none border-2 border-secondary rounded w-full py-2 px-4 text-primary leading-tight focus:outline-none focus:bg-secondary focus:border-accent transition duration-150 "
|
||||
/>
|
||||
{props.children}
|
||||
{meta?.touched && meta.error ? (
|
||||
<div tw="text-[#c23c3c]">{meta.error}</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function MaskedInput(
|
||||
props: Omit<IMaskInputProps<HTMLInputElement>, "validate" | "label"> & FieldHookConfig<any> & {
|
||||
definitions: { [k: string]: RegExp };
|
||||
|
||||
label?: React.ComponentPropsWithoutRef<"label">;
|
||||
title?: string;
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
) {
|
||||
/*name, id*/
|
||||
let { children, validate, ...otherProps } = props;
|
||||
|
||||
const [field, meta, helpers] = useField({ ...otherProps, validate });
|
||||
|
||||
return (
|
||||
<div css={[props.title && tw`my-1`, tw`relative`]} className={props.className}>
|
||||
{props.title && (
|
||||
<label
|
||||
{...props.label}
|
||||
//htmlFor={props.id ?? props.name ?? props.title}
|
||||
css={[tw`block text-secondary text-sm font-bold mb-2`, props.label?.css]}
|
||||
>
|
||||
{/*htmlFor={id ?? name ?? title}*/}
|
||||
{props.title}
|
||||
</label>
|
||||
)}
|
||||
{/*name={name || title} id={id || name || title}*/}
|
||||
<IMaskInput
|
||||
//id={props.id ?? props.name ?? props.title}
|
||||
{...otherProps as any}
|
||||
value={field.value}
|
||||
unmask="typed"
|
||||
onAccept={
|
||||
(value, mask) => field.onChange({ target: { value, name: field.name } })
|
||||
}
|
||||
onBlur={field.onBlur}
|
||||
tw="bg-primary appearance-none border-2 border-secondary rounded w-full py-2 px-4 text-primary leading-tight focus:outline-none focus:bg-secondary focus:border-accent transition duration-150 "
|
||||
/>
|
||||
{props.children}
|
||||
{meta?.touched && meta.error ? (
|
||||
<div tw="text-[#c23c3c]">{meta.error}</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function TextArea({
|
||||
title,
|
||||
children = null,
|
||||
label = null,
|
||||
...props
|
||||
}) {
|
||||
|
||||
const [field, meta, helpers] = useField(props);
|
||||
|
||||
return (
|
||||
<div css={[title && tw`my-1`]} >
|
||||
{title && (
|
||||
<label
|
||||
{...label}
|
||||
css={[tw`block text-secondary text-sm font-bold mb-2`, label?.css]}
|
||||
|
||||
>
|
||||
{title}
|
||||
</label>
|
||||
)}
|
||||
<textarea
|
||||
{...props}
|
||||
{...field}
|
||||
tw="bg-primary appearance-none border-2 border-secondary rounded w-full py-2 px-4 text-primary leading-tight focus:outline-none focus:bg-secondary focus:border-accent transition duration-150 "
|
||||
/>
|
||||
{children}
|
||||
{meta?.touched && meta.error ? (
|
||||
<div tw="text-[#c23c3c]">{meta.error}</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Renders a checkbox input with optional label and error message.
|
||||
*
|
||||
* @param {Object} props - The properties for the CheckBox component.
|
||||
* @param {string} props.label - The label for the checkbox.
|
||||
* @param {string} props.title - The title for the checkbox.
|
||||
* @param {string} props.className - The class name for the container div.
|
||||
* @param {ReactNode} props.children - The children components.
|
||||
* @param {Object} props... - Additional properties for the checkbox input.
|
||||
* @return {ReactElement} The rendered CheckBox component.
|
||||
*/
|
||||
export function CheckBox(
|
||||
props: (Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "checked"> | Omit<FieldHookConfig<boolean>, "value">) & {
|
||||
label?: React.ComponentPropsWithoutRef<"label">;
|
||||
title?: string;
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
value?: boolean
|
||||
}
|
||||
) {
|
||||
/*name, id*/
|
||||
const { children, ...otherProps } = props;
|
||||
|
||||
const [field, meta, helpers] = useField<boolean>(otherProps);
|
||||
|
||||
return (
|
||||
<div tw="my-1 flex text-secondary">
|
||||
<input
|
||||
id={props.id ?? props.name ?? props.title}
|
||||
checked={otherProps?.value == undefined ? field.value : otherProps?.value}
|
||||
{...field}
|
||||
{...otherProps as any}
|
||||
type="checkbox"
|
||||
tw="checked:bg-accent w-6 h-6 rounded-full bg-secondary border-secondary border-4 appearance-none cursor-pointer "
|
||||
/>
|
||||
{props.title && (
|
||||
<label
|
||||
{...props.label}
|
||||
htmlFor={props.id ?? props.name ?? props.title}
|
||||
css={[tw`block text-secondary text-sm font-bold mb-2`, props.label?.css]}
|
||||
>
|
||||
{/*htmlFor={id ?? name ?? title}*/}
|
||||
{props.title}
|
||||
</label>
|
||||
)}
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import React from "react"
|
||||
import tw, {styled} from "twin.macro"
|
||||
|
||||
|
||||
const Full = styled.div(tw`w-full lg:px-2 py-2`)
|
||||
export {Full}
|
||||
|
||||
const Half = styled.div(tw`w-full lg:w-8/12 xl:w-6/12 lg:px-2 py-2`)
|
||||
export {Half}
|
||||
|
||||
const Quarter = styled.div(tw`w-full lg:w-6/12 xl:w-3/12 lg:px-2 py-2 `)
|
||||
export {Quarter}
|
||||
|
||||
const Sixth = styled.div(tw`w-full lg:w-1/5 xl:w-1/6 lg:px-2 py-2 `)
|
||||
export {Sixth}
|
||||
|
||||
const Third = styled.div(tw`w-full lg:w-8/12 xl:w-4/12 lg:px-2 py-2 `)
|
||||
export {Third}
|
||||
|
||||
const TwoThird = styled.div(tw`w-full lg:w-8/12 lg:px-2 py-2 `)
|
||||
export {TwoThird}
|
||||
11
Parts/Layout.jsx
Normal file
11
Parts/Layout.jsx
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
export function Full({ className, ...props }) { return <div className={"w-full lg:px-2 py-2" + className} {...props} /> }
|
||||
|
||||
export function Half({ className, ...props }) { return <div className={"w-full lg:w-8/12 xl:w-6/12 lg:px-2 py-2" + className} {...props} /> }
|
||||
|
||||
export function Quarter({ className, ...props }) { return <div className={"w-full lg:w-6/12 xl:w-3/12 lg:px-2 py-2" + className} {...props} />; }
|
||||
|
||||
export function Sixth({ className, ...props }) { return <div className={"w-full lg:w-1/5 xl:w-1/6 lg:px-2 py-2" + className} {...props} />; }
|
||||
|
||||
export function Third({ className, ...props }) { return <div className={"w-full lg:w-8/12 xl:w-4/12 lg:px-2 py-2" + className} {...props} />; }
|
||||
|
||||
export function classNameoThird({ className, ...props }) { return <div className={"w-full lg:w-8/12 lg:px-2 py-2" + className} {...props} />; }
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import Button from "./Button";
|
||||
import tw, { styled } from "twin.macro";
|
||||
;
|
||||
|
||||
const Btn = styled(Button)(({ active }) => [tw`rounded-none mx-0`, active && tw`bg-accent`]);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
import { MaskedInput } from "./Input";
|
||||
|
||||
export type PreMaskedProps = Omit<React.ComponentPropsWithoutRef<typeof MaskedInput>, "mask" | "definitions">
|
||||
|
||||
export function IbanInput(props: PreMaskedProps) {
|
||||
return <MaskedInput {...props}
|
||||
mask="XXXX XXXX XXXX XXXX [XXXX] [XXXX] [XXXX] [XX]"
|
||||
definitions={{ 'X': /[0-9A-Z]/ }}
|
||||
prepare={(str: string) => str.toUpperCase()}
|
||||
validate={(iban: string) => {
|
||||
console.log(iban);
|
||||
|
||||
if (iban.length < 15 || iban.length > 34)
|
||||
return "Invalid length";
|
||||
|
||||
// Rearranged IBAN
|
||||
const rearranged = iban.slice(4) + iban.slice(0, 4);
|
||||
|
||||
// Convert letters to numbers (A=10 ... Z=35)
|
||||
const converted = rearranged.replace(/[A-Z]/g, ch => (ch.charCodeAt(0) - 55).toString());
|
||||
|
||||
// Perform mod-97 check
|
||||
let remainder = converted;
|
||||
let block;
|
||||
|
||||
while (remainder.length > 2) {
|
||||
block = remainder.slice(0, 9);
|
||||
remainder = (parseInt(block, 10) % 97).toString() + remainder.slice(block.length);
|
||||
}
|
||||
|
||||
if (parseInt(remainder, 10) % 97 !== 1)
|
||||
return "Invalid checksum";
|
||||
|
||||
return null;
|
||||
}}
|
||||
/>
|
||||
}
|
||||
|
|
@ -11,18 +11,15 @@ export function Table(props) {
|
|||
}
|
||||
|
||||
|
||||
const TablePart = styled.td(tw`border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs p-4`)
|
||||
const TablePart = styled.td(tw`border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap p-4`)
|
||||
export {TablePart}
|
||||
|
||||
const TableRow = styled.tr(tw`odd:bg-black/10 hover:bg-black/15`)
|
||||
export {TableRow}
|
||||
|
||||
const TableHeader = styled.th(tw`px-6 py-3 align-middle text-xs uppercase font-bold text-left text-secondary border-b-2 border-secondary`)
|
||||
const TableHeader = styled.th(tw`px-6 py-3 align-middle text-xs uppercase whitespace-nowrap font-bold text-left text-secondary border-b-2 border-secondary`)
|
||||
export {TableHeader}
|
||||
|
||||
const TableNote = styled.p(tw`text-xs font-normal italic normal-case`)
|
||||
export {TableNote}
|
||||
|
||||
const TableSidePart = styled.td(tw`border-t-0 px-8 align-middle border-l-0 border-r-0 text-xs p-4 pl-6 py-3 align-middle text-xs uppercase whitespace-nowrap font-bold text-left w-1/3 text-secondary border-r-2 border-secondary`)
|
||||
const TableSidePart = styled.td(tw`border-t-0 px-8 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap p-4 pl-6 py-3 align-middle text-xs uppercase whitespace-nowrap font-bold text-left w-1/3 text-secondary border-r-2 border-secondary`)
|
||||
export {TableSidePart}
|
||||
|
||||
|
|
|
|||
75
globalStyle.js
Normal file
75
globalStyle.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { createGlobalStyle } from "styled-components"
|
||||
import tw, { theme, GlobalStyles as BaseStyles } from "twin.macro"
|
||||
|
||||
const CustomStyles = createGlobalStyle`
|
||||
body {
|
||||
-webkit-tap-highlight-color: ${theme`colors.accent`};
|
||||
}
|
||||
|
||||
:root{
|
||||
--primary: #3d3d3d;
|
||||
--secondary: #535353;
|
||||
--trinary: #2c2c2c;
|
||||
|
||||
--primary-text: #ffffff;
|
||||
--secondary-text: #a0a0a0;
|
||||
|
||||
--primary-invert: #f3f3f3;
|
||||
--secondary-invert: #dbdbdb;
|
||||
--trinary-invert: #ffffff;
|
||||
|
||||
--primary-invert-text: #3d3d3d;
|
||||
--secondary-invert-text: #535353;
|
||||
|
||||
--accent: #00C800;
|
||||
--accent-dark: #008f00;
|
||||
--accent-light: #00ed00;
|
||||
--accent2: #3080FF;
|
||||
--accent2-dark: #225ab4;
|
||||
--accent3: #804000;
|
||||
--accent3-dark: #472400;
|
||||
--accent4: #F8B02C;
|
||||
--accent4-dark: #bd8724;
|
||||
--accent5: #9E3086;
|
||||
--accent5-dark: #6b215b;
|
||||
}
|
||||
|
||||
.light\-theme{
|
||||
--primary: #f3f3f3;
|
||||
--secondary: #dbdbdb;
|
||||
--trinary: #ffffff;
|
||||
--primary-text: #3d3d3d;
|
||||
--secondary-text: #535353;
|
||||
|
||||
|
||||
--primary-invert: #3d3d3d;
|
||||
--secondary-invert: #535353;
|
||||
--trinary-invert: #2c2c2c;
|
||||
--primary-text-invert: #ffffff;
|
||||
--secondary-text-invert: #a0a0a0;
|
||||
}
|
||||
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 0.5rem;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--secondary);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--accent-dark);
|
||||
}
|
||||
`
|
||||
|
||||
const GlobalStyles = () => {
|
||||
return <>
|
||||
<BaseStyles />
|
||||
<CustomStyles />
|
||||
</>
|
||||
}
|
||||
|
||||
export default GlobalStyles
|
||||
25
styledRegistry.js
Normal file
25
styledRegistry.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
'use client'
|
||||
|
||||
import React, { useState } from 'react'
|
||||
import { useServerInsertedHTML } from 'next/navigation'
|
||||
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
|
||||
|
||||
export default function StyledComponentsRegistry({ children }) {
|
||||
// Only create stylesheet once with lazy initial state
|
||||
// x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
|
||||
const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())
|
||||
|
||||
useServerInsertedHTML(() => {
|
||||
const styles = styledComponentsStyleSheet.getStyleElement()
|
||||
styledComponentsStyleSheet.instance.clearTag()
|
||||
return <>{styles}</>
|
||||
})
|
||||
|
||||
if (typeof window !== 'undefined') return <>{children}</>
|
||||
|
||||
return (
|
||||
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
|
||||
{children}
|
||||
</StyleSheetManager>
|
||||
)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user