Update na twin.macro
This commit is contained in:
parent
9c0c6fd818
commit
f591e46b67
|
|
@ -1,5 +1,16 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import tw, {styled} from "twin.macro"
|
||||||
|
import 'styled-components/macro'
|
||||||
|
import { colors, colorsDisabled, colorsHover } from './Colors'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const BtnBase = styled.button(({ type }) => [
|
||||||
|
tw`bg-secondary hover:bg-trinary disabled:bg-trinary m-2 outline-none focus:outline-none text-primary font-bold ease-linear transition-all duration-150`,
|
||||||
|
colors[type], colorsHover[type], colorsDisabled[type]
|
||||||
|
])
|
||||||
|
|
||||||
|
/*
|
||||||
function ButtonBase(props) {
|
function ButtonBase(props) {
|
||||||
let color = "bg-secondary hover:bg-trinary"
|
let color = "bg-secondary hover:bg-trinary"
|
||||||
switch (props.type) {
|
switch (props.type) {
|
||||||
|
|
@ -33,7 +44,20 @@ function ButtonBase(props) {
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
const ButtonBig = tw(BtnBase)`px-6 py-4 rounded-2xl`
|
||||||
|
const ButtonBigAnim = tw(ButtonBig)`transition duration-500 ease-in-out transform hover:scale-110`
|
||||||
|
|
||||||
|
const Button = tw(BtnBase)`px-4 py-2 rounded-xl`
|
||||||
|
const ButtonSmall = tw(BtnBase)`px-3 py-1 rounded`
|
||||||
|
const ButtonRound = tw(BtnBase)`p-2 rounded-full`
|
||||||
|
const IconButton = tw(BtnBase)`p-2 rounded-full`
|
||||||
|
|
||||||
|
export { ButtonBig, ButtonBigAnim, ButtonSmall, ButtonRound, IconButton }
|
||||||
|
export default Button;
|
||||||
|
|
||||||
|
/*
|
||||||
export function ButtonBig(props) {
|
export function ButtonBig(props) {
|
||||||
return (
|
return (
|
||||||
<ButtonBase {...props} className={"px-6 py-4 rounded-2xl " + (props.className ?? "")}>
|
<ButtonBase {...props} className={"px-6 py-4 rounded-2xl " + (props.className ?? "")}>
|
||||||
|
|
@ -41,6 +65,13 @@ export function ButtonBig(props) {
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
export function ButtonBigAnim(props) {
|
||||||
|
return (
|
||||||
|
<ButtonBase {...props} className={"px-6 py-4 rounded-2xl transition duration-500 ease-in-out transform hover:scale-110 " + (props.className ?? "")}>
|
||||||
|
{props.children}
|
||||||
|
</ButtonBase>
|
||||||
|
)
|
||||||
|
}
|
||||||
export default function Button(props) {
|
export default function Button(props) {
|
||||||
return (
|
return (
|
||||||
<ButtonBase {...props} className={"px-4 py-2 rounded-xl " + (props.className ?? "")}>
|
<ButtonBase {...props} className={"px-4 py-2 rounded-xl " + (props.className ?? "")}>
|
||||||
|
|
@ -69,3 +100,4 @@ export function IconButton({icon,...props}){
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
@ -1,15 +1,17 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import tw, {styled} from "twin.macro"
|
||||||
|
import 'styled-components/macro'
|
||||||
|
|
||||||
export default function Card(props) {
|
export default function Card(props) {
|
||||||
return <div {...props} className={"relative flex flex-col min-w-0 break-words bg-primary w-full shadow-xl rounded-2xl " + (props.className ?? "")}>
|
return <div {...props} css={[tw`relative flex flex-col min-w-0 break-words bg-primary w-full shadow-xl rounded-2xl`, props.css]}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
export function CardHeader(props) {
|
export function CardHeader(props) {
|
||||||
return <div className="rounded-t px-6 py-4 pb-2 bg-transparent">
|
return <div tw="rounded-t px-6 py-4 pb-2 bg-transparent">
|
||||||
<div className="flex flex-wrap items-center">
|
<div tw="flex flex-wrap items-center">
|
||||||
<div className="relative w-full max-w-full flex-grow flex-1">
|
<div tw="relative w-full max-w-full flex-grow flex-1">
|
||||||
{ props.desc != null ? <h2 className="text-primary text-xl font-semibold">{props.desc}</h2> : ""}
|
{ props.desc != null ? <h2 tw="text-primary text-xl font-semibold">{props.desc}</h2> : ""}
|
||||||
</div>
|
</div>
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useRef, useState } from "react";
|
import React, { useRef, useState } from "react";
|
||||||
import Chart from "chart.js";
|
import Chart from 'chart.js/auto';
|
||||||
|
|
||||||
import Card, { CardHeader } from "./Card";
|
import Card, { CardHeader } from "./Card";
|
||||||
import { createPopper } from "@popperjs/core";
|
import { createPopper } from "@popperjs/core";
|
||||||
|
|
@ -71,15 +71,15 @@ export default function NejChart(props) {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
defaultColor: [accentCol, accent2Col, accent3Col, accent4Col, accent5Col, accent6Col],
|
defaultColor: [accentCol, accent2Col, accent3Col, accent4Col, accent5Col, accent6Col],
|
||||||
legend: {
|
legend: {
|
||||||
...Chart.defaults.global.legend,
|
...Chart.defaults.global?.legend,
|
||||||
labels: {
|
labels: {
|
||||||
...Chart.defaults.global.legend.labels,
|
...Chart.defaults.global?.legend?.labels,
|
||||||
fontColor: secondary,
|
fontColor: secondary,
|
||||||
usePointStyle: true
|
usePointStyle: true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
tooltips: {
|
tooltips: {
|
||||||
...Chart.defaults.global.tooltips,
|
...Chart.defaults.global?.tooltips,
|
||||||
backgroundColor: bgTrianry,
|
backgroundColor: bgTrianry,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
custom: (tooltipModel) => {
|
custom: (tooltipModel) => {
|
||||||
|
|
|
||||||
47
Parts/Colors.js
Normal file
47
Parts/Colors.js
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
import tw, {styled} from "twin.macro"
|
||||||
|
import 'styled-components/macro'
|
||||||
|
|
||||||
|
|
||||||
|
export let colors = {
|
||||||
|
error: tw`bg-red-600`,
|
||||||
|
accent: tw`bg-accent`,
|
||||||
|
accent2: tw`bg-accent2`,
|
||||||
|
accent3: tw`bg-accent3`,
|
||||||
|
accent4: tw`bg-accent4`,
|
||||||
|
accent5: tw`bg-accent5`,
|
||||||
|
}
|
||||||
|
|
||||||
|
export let colorsHover = {
|
||||||
|
error: tw`hover:bg-red-700`,
|
||||||
|
accent: tw`hover:bg-accent-dark`,
|
||||||
|
accent2: tw`hover:bg-accent2-dark`,
|
||||||
|
accent3: tw`hover:bg-accent3-dark`,
|
||||||
|
accent4: tw`hover:bg-accent4-dark`,
|
||||||
|
accent5: tw`hover:bg-accent5-dark`,
|
||||||
|
}
|
||||||
|
export let colorsDisabled = {
|
||||||
|
error: tw`disabled:bg-red-700`,
|
||||||
|
accent: tw`disabled:bg-accent-dark`,
|
||||||
|
accent2: tw`disabled:bg-accent2-dark`,
|
||||||
|
accent3: tw`disabled:bg-accent3-dark`,
|
||||||
|
accent4: tw`disabled:bg-accent4-dark`,
|
||||||
|
accent5: tw`disabled:bg-accent5-dark`,
|
||||||
|
}
|
||||||
|
|
||||||
|
export let textColors = {
|
||||||
|
error: tw`text-red-600`,
|
||||||
|
accent: tw`text-accent`,
|
||||||
|
accent2: tw`text-accent2`,
|
||||||
|
accent3: tw`text-accent3`,
|
||||||
|
accent4: tw`text-accent4`,
|
||||||
|
accent5: tw`text-accent5`,
|
||||||
|
}
|
||||||
|
export let textColorsHover = {
|
||||||
|
error: tw`hover:text-red-700`,
|
||||||
|
accent: tw`hover:text-accent-dark`,
|
||||||
|
accent2: tw`hover:text-accent2-dark`,
|
||||||
|
accent3: tw`hover:text-accent3-dark`,
|
||||||
|
accent4: tw`hover:text-accent4-dark`,
|
||||||
|
accent5: tw`hover:text-accent5-dark`,
|
||||||
|
}
|
||||||
|
|
@ -1,27 +1,41 @@
|
||||||
import React, { useEffect } from "react";
|
import React, { cloneElement, isValidElement, useEffect, useImperativeHandle, useRef, useState } from "react";
|
||||||
import { createPopper } from "@popperjs/core";
|
import { createPopper } from "@popperjs/core";
|
||||||
|
|
||||||
export function DropDownItem(props) {
|
import tw, { styled } from "twin.macro"
|
||||||
return <button
|
import 'styled-components/macro'
|
||||||
className={"text-sm text-left py-2 px-4 focus:outline-none block w-full whitespace-no-wrap bg-transparent hover:bg-secondary text-primary"}
|
import { colors, colorsDisabled, colorsHover, textColors, textColorsHover } from "./Colors";
|
||||||
onClick={(e) => e.preventDefault()}
|
|
||||||
>
|
const DropDownItem = styled.button(({ type }) => [
|
||||||
{props.children}
|
// The common button styles added with the tw import
|
||||||
</button>;
|
tw`text-sm text-left py-2 px-4 focus:outline-none block w-full whitespace-nowrap bg-transparent hover:bg-secondary disabled:bg-secondary text-primary hover:text-primary`,
|
||||||
}
|
|
||||||
export default function Dropdown(props) {
|
// Use props to conditionally style your components
|
||||||
|
textColors[type], colorsHover[type]
|
||||||
|
])
|
||||||
|
export { DropDownItem }
|
||||||
|
|
||||||
|
let Dropdown = React.forwardRef(({ children, dropdownCss, onValueChanged, button, popper, placement, hover, ...props }, ref) => {
|
||||||
// dropdown props
|
// dropdown props
|
||||||
|
const [overButton, setOverButton] = React.useState(false);
|
||||||
|
const [overDropDown, setOverDropDown] = React.useState(false);
|
||||||
|
|
||||||
const [dropdownPopoverShow, setDropdownPopoverShow] = React.useState(false);
|
const [dropdownPopoverShow, setDropdownPopoverShow] = React.useState(false);
|
||||||
|
|
||||||
const btnDropdownRef = React.createRef();
|
const btnDropdownRef = React.createRef();
|
||||||
const popoverDropdownRef = React.createRef();
|
const popoverDropdownRef = React.createRef();
|
||||||
|
|
||||||
const openDropdownPopover = () => {
|
const openDropdownPopover = () => {
|
||||||
createPopper(btnDropdownRef.current, popoverDropdownRef.current, {
|
createPopper(btnDropdownRef.current, popoverDropdownRef.current, {
|
||||||
placement: props.placement ?? "left-start",
|
placement: placement ?? "bottom",
|
||||||
|
...popper
|
||||||
});
|
});
|
||||||
setDropdownPopoverShow(true);
|
setDropdownPopoverShow(true);
|
||||||
|
|
||||||
|
onValueChanged && onValueChanged(true);
|
||||||
};
|
};
|
||||||
const closeDropdownPopover = () => {
|
const closeDropdownPopover = () => {
|
||||||
setDropdownPopoverShow(false);
|
setDropdownPopoverShow(false);
|
||||||
|
onValueChanged && onValueChanged(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleOutsideClick(event) {
|
function handleOutsideClick(event) {
|
||||||
|
|
@ -31,6 +45,7 @@ export default function Dropdown(props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if ('ontouchend' in window) {
|
if ('ontouchend' in window) {
|
||||||
document.addEventListener('touchend', handleOutsideClick)
|
document.addEventListener('touchend', handleOutsideClick)
|
||||||
|
|
@ -44,28 +59,71 @@ export default function Dropdown(props) {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
openDropdownPopover,
|
||||||
|
closeDropdownPopover
|
||||||
|
}))
|
||||||
|
|
||||||
|
let childrenWithProps = React.Children.map(children, (item) => {
|
||||||
|
if (!item)
|
||||||
|
return;
|
||||||
|
let click = item.props?.onClick;
|
||||||
|
let close = item.props?.closeOnClick ?? true;
|
||||||
|
return cloneElement(item, { key: children.indexOf ? children.indexOf(item) : 0, onClick: () => { close && closeDropdownPopover(); click && click() } });
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<a
|
<button
|
||||||
className="text-secondary py-1 px-3"
|
|
||||||
href="#pablo"
|
|
||||||
ref={btnDropdownRef}
|
ref={btnDropdownRef}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
dropdownPopoverShow ? closeDropdownPopover() : openDropdownPopover();
|
dropdownPopoverShow ? closeDropdownPopover() : openDropdownPopover();
|
||||||
}}
|
}}
|
||||||
|
onMouseEnter={() => { setOverButton(true); hover && openDropdownPopover() }}
|
||||||
|
onMouseLeave={() => { setOverButton(false); (!overDropDown && hover) && closeDropdownPopover() }}
|
||||||
>
|
>
|
||||||
{props.button}
|
{button}
|
||||||
</a>
|
</button>
|
||||||
<div
|
<div
|
||||||
|
{...props}
|
||||||
ref={popoverDropdownRef}
|
ref={popoverDropdownRef}
|
||||||
className={
|
onMouseEnter={() => { setOverDropDown(true); hover && openDropdownPopover() }}
|
||||||
(dropdownPopoverShow ? "block " : "hidden ") +
|
onMouseLeave={() => { setOverDropDown(false); (!overButton && hover) && closeDropdownPopover() }}
|
||||||
"bg-trinary text-base z-50 float-left overflow-hidden text-left rounded-xl shadow-lg min-w-48"
|
css={[
|
||||||
}
|
(dropdownPopoverShow ? tw`block` : tw`hidden`),
|
||||||
|
tw`bg-trinary text-base z-50 float-left rounded-xl overflow-hidden text-left shadow-lg`,
|
||||||
|
dropdownCss,
|
||||||
|
props.css
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
{props.children}
|
{dropdownPopoverShow && childrenWithProps}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
export default Dropdown;
|
||||||
|
|
||||||
|
export function DropdownMenu({ children, fallback, notSelectedOne = true, ...props }) {
|
||||||
|
let [selectedItem, setSelectedItem] = useState(0);
|
||||||
|
let ref = useRef()
|
||||||
|
|
||||||
|
let btn = fallback ?? "";
|
||||||
|
if (children && children.length > 0)
|
||||||
|
btn = children[selectedItem > children.length ? 0 : selectedItem]
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<Dropdown ref={ref} button={btn} {...props}>
|
||||||
|
{
|
||||||
|
children && children.map((i) => {
|
||||||
|
if (children.indexOf(i) == selectedItem)
|
||||||
|
return;
|
||||||
|
return <DropDownItem key={children.indexOf(i)} onClick={() => setSelectedItem(children.indexOf(i))}>{i}</DropDownItem>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
{
|
||||||
|
(children == null || children.length <= (notSelectedOne ? 1 : 0)) && <p tw="p-4 text-secondary">Nothing to show</p>
|
||||||
|
}
|
||||||
|
</Dropdown>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
@ -1,25 +1,29 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import tw from 'twin.macro'
|
||||||
|
import 'styled-components/macro'
|
||||||
|
|
||||||
export default function Input(props) {
|
export default function Input({ label, title, name, id, children, ...props }) {
|
||||||
return (
|
return (
|
||||||
<div className={props.title != null ? "my-1": ""}>
|
<div css={title != null && tw`my-1`}>
|
||||||
{props.title != null ? (
|
{title && (
|
||||||
<label {...props.label} className={"block text-secondary text-sm font-bold mb-1 "+props.label?.className} htmlFor={props.id || props.name || props.title}>
|
<label {...label} css={[tw`block text-secondary text-sm font-bold mb-2`, label?.css]} htmlFor={id ?? name ?? title}>
|
||||||
{props.title}
|
{title}
|
||||||
</label>
|
</label>
|
||||||
) : null}
|
)}
|
||||||
<input {...props} name={props.name || props.title} id={props.id || props.name || props.title} className={"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.className}/>
|
<input {...props} name={name || title} id={id || name || title} 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}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export function TextArea({ label, title, name, id, children, ...props }) {
|
export function TextArea({ label, title, name, id, children, ...props }) {
|
||||||
return (
|
return (
|
||||||
<div className="my-1">
|
<div tw="my-1">
|
||||||
<label {...label} className={"block text-secondary text-sm font-bold mb-2 "+ label?.className} htmlFor={id ?? name ?? title}>
|
{title && (
|
||||||
|
<label {...label} css={[tw`block text-secondary text-sm font-bold mb-2`, label?.css]} htmlFor={id ?? name ?? title}>
|
||||||
{title}
|
{title}
|
||||||
</label>
|
</label>
|
||||||
<textarea {...props} name={name ?? title} id={id ?? name ?? props.title} className={"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.className}/>
|
)}
|
||||||
|
<textarea {...props} name={name ?? title} id={id ?? name ?? title} 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}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
@ -27,14 +31,16 @@ export function TextArea({label, title, name, id, children, ...props}) {
|
||||||
|
|
||||||
export function CheckBox({ label, title, name, id, children, ...props }) {
|
export function CheckBox({ label, title, name, id, children, ...props }) {
|
||||||
return (
|
return (
|
||||||
<div class="my-1 flex text-secondary">
|
<div tw="my-1 flex text-secondary">
|
||||||
<input {...props} type="checkbox" name={name ?? title} id={id ?? name ?? title} className={"checked:bg-accent w-6 h-6 rounded-full bg-secondary border-secondary border-4 appearance-none cursor-pointer "+props.className}/>
|
<input {...props} type="checkbox" name={name ?? title} id={id ?? name ?? title} tw="checked:bg-accent w-6 h-6 rounded-full bg-secondary border-secondary border-4 appearance-none cursor-pointer " />
|
||||||
{title != null ? (
|
{title != null ? (
|
||||||
<label {...props.label} htmlFor={id ?? name ?? title} class="block font-bold px-2">
|
<label {...label} htmlFor={id ?? name ?? title} css={[tw`block font-bold px-2`, label?.css]}>
|
||||||
{title}
|
{title}
|
||||||
</label>
|
</label>
|
||||||
) : null}
|
) : null
|
||||||
|
}
|
||||||
{children}
|
{children}
|
||||||
</div >
|
</div >
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,18 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import tw, {styled} from "twin.macro"
|
||||||
|
import 'styled-components/macro'
|
||||||
|
|
||||||
export function Full(props) {
|
const Full = styled.div(tw`w-full lg:px-2 py-2`)
|
||||||
return <div {...props} className={"w-full lg:px-2 py-2 " + (props.className??"")}>
|
export {Full}
|
||||||
{props.children}
|
|
||||||
</div>
|
const Half = styled.div(tw`w-full lg:w-6/12 lg:px-2 py-2`)
|
||||||
}
|
export {Half}
|
||||||
export function Half(props) {
|
|
||||||
return <div {...props} className={"w-full lg:w-6/12 lg:px-2 py-2 " + (props.className??"")}>
|
const Quarter = styled.div(tw`w-full lg:w-6/12 xl:w-3/12 lg:px-2 py-2 `)
|
||||||
{props.children}
|
export {Quarter}
|
||||||
</div>
|
|
||||||
}
|
const Third = styled.div(tw`w-full lg:w-4/12 lg:px-2 py-2 `)
|
||||||
export function Quarter(props) {
|
export {Third}
|
||||||
return <div {...props} className={"w-full lg:w-6/12 xl:w-3/12 lg:px-2 py-2 " + (props.className??"")}>
|
|
||||||
{props.children}
|
const TwoThird = styled.div(tw`w-full lg:w-8/12 lg:px-2 py-2 `)
|
||||||
</div>
|
export {TwoThird}
|
||||||
}
|
|
||||||
export function Third(props) {
|
|
||||||
return <div {...props} className={"w-full lg:w-4/12 lg:px-2 py-2 " + (props.className??"")}>
|
|
||||||
{props.children}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
export function TwoThird(props) {
|
|
||||||
return <div {...props} className={"w-full lg:w-8/12 lg:px-2 py-2 " + (props.className??"")}>
|
|
||||||
{props.children}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Third } from './Layout'
|
import { Third } from './Layout'
|
||||||
|
|
||||||
|
import tw, { styled } from "twin.macro"
|
||||||
|
import 'styled-components/macro'
|
||||||
|
|
||||||
function Modal({ isOpen, onBackdropClick, ...props }) {
|
function Modal({ isOpen, onBackdropClick, ...props }) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
return <div onClick={onBackdropClick} className="fixed flex flex-col justify-center items-center inset-0 bg-gray-800 bg-opacity-75">
|
return <div onClick={onBackdropClick} tw="fixed flex flex-col justify-center items-center inset-0 bg-gray-800 bg-opacity-75">
|
||||||
<Third {...props} onClick={e=>e.stopPropagation()}>
|
<Third {...props} onClick={e=>e.stopPropagation()}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</Third>
|
</Third>
|
||||||
|
|
|
||||||
62
Parts/Pagination.js
Normal file
62
Parts/Pagination.js
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import Button from "./Button";
|
||||||
|
import tw, { styled } from "twin.macro"
|
||||||
|
import 'styled-components/macro'
|
||||||
|
|
||||||
|
function CustomBtn({children, setPage, currentPage, page, css, ...props}){
|
||||||
|
console.log(css)
|
||||||
|
return <Button onClick={()=>{setPage(page??children); console.log(page??children)}} css={[tw`rounded-none mx-0`, currentPage==children && tw`bg-accent`, css]} {...props}>{children}</Button>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Pagination({ currentPage, maxPages, setPage, ...props }) {
|
||||||
|
|
||||||
|
function RenderButtons() {
|
||||||
|
switch (maxPages) {
|
||||||
|
case 1:
|
||||||
|
return <CustomBtn tw="rounded-xl" setPage={setPage} currentPage={currentPage}>1</CustomBtn>;
|
||||||
|
case 2:
|
||||||
|
return <>
|
||||||
|
<CustomBtn tw="rounded-l-xl" setPage={setPage} currentPage={currentPage}>1</CustomBtn>
|
||||||
|
<CustomBtn tw="rounded-r-xl" setPage={setPage} currentPage={currentPage}>2</CustomBtn>
|
||||||
|
</>
|
||||||
|
case 3:
|
||||||
|
return <>
|
||||||
|
<CustomBtn tw="rounded-l-xl" setPage={setPage} currentPage={currentPage}>1</CustomBtn>
|
||||||
|
<CustomBtn setPage={setPage} currentPage={currentPage}>2</CustomBtn>
|
||||||
|
<CustomBtn tw="rounded-r-xl" setPage={setPage} currentPage={currentPage}>3</CustomBtn>
|
||||||
|
</>
|
||||||
|
case 4:
|
||||||
|
return <>
|
||||||
|
<CustomBtn tw="rounded-l-xl" setPage={setPage} currentPage={currentPage}>1</CustomBtn>
|
||||||
|
<CustomBtn setPage={setPage} currentPage={currentPage}>2</CustomBtn>
|
||||||
|
<CustomBtn setPage={setPage} currentPage={currentPage}>3</CustomBtn>
|
||||||
|
<CustomBtn tw="rounded-r-xl" setPage={setPage} currentPage={currentPage}>4</CustomBtn>
|
||||||
|
</>
|
||||||
|
case 5:
|
||||||
|
return <>
|
||||||
|
<CustomBtn tw="rounded-l-xl" setPage={setPage} currentPage={currentPage}>1</CustomBtn>
|
||||||
|
<CustomBtn setPage={setPage} currentPage={currentPage}>2</CustomBtn>
|
||||||
|
<CustomBtn setPage={setPage} currentPage={currentPage}>3</CustomBtn>
|
||||||
|
<CustomBtn setPage={setPage} currentPage={currentPage}>4</CustomBtn>
|
||||||
|
<CustomBtn tw="rounded-r-xl" setPage={setPage} currentPage={currentPage}>5</CustomBtn>
|
||||||
|
</>
|
||||||
|
default: {
|
||||||
|
return <>
|
||||||
|
{currentPage > 3 && <CustomBtn css={[tw`rounded-l-xl`]} page={1} setPage={setPage} currentPage={currentPage}><</CustomBtn>}
|
||||||
|
<CustomBtn css={[currentPage <= 3 &&tw`rounded-l-xl`]} setPage={setPage} currentPage={currentPage}>{Math.max(currentPage-2,1)}</CustomBtn>
|
||||||
|
<CustomBtn setPage={setPage} currentPage={currentPage}>{Math.max(currentPage-2,1)+1}</CustomBtn>
|
||||||
|
<CustomBtn setPage={setPage} currentPage={currentPage}>{Math.max(currentPage-2,1)+2}</CustomBtn>
|
||||||
|
{(maxPages - currentPage) >= 1 && <CustomBtn css={[(Math.max(currentPage-2,1)+3)==maxPages && tw`rounded-r-xl`]} setPage={setPage} currentPage={currentPage}>{Math.max(currentPage-2,1)+3}</CustomBtn>}
|
||||||
|
{(maxPages - currentPage) >= 2 && <CustomBtn css={[(Math.max(currentPage-2,1)+4)==maxPages && tw`rounded-r-xl`]} tw="rounded-r-xl" setPage={setPage} currentPage={currentPage}>{Math.max(currentPage-2,1)+4}</CustomBtn>}
|
||||||
|
{(maxPages - currentPage) >= 3 && <CustomBtn css={[tw`rounded-r-xl`]} page={maxPages} setPage={setPage} currentPage={currentPage}>></CustomBtn>}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div {...props}>
|
||||||
|
<RenderButtons />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
26
Parts/RangeSlider.js
Normal file
26
Parts/RangeSlider.js
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
|
|
||||||
|
import styles from "./RangeSlider.scss"
|
||||||
|
|
||||||
|
import tw from 'twin.macro'
|
||||||
|
import 'styled-components/macro'
|
||||||
|
|
||||||
|
|
||||||
|
export function RangeSlider({ value=0, rangeType="", onChange, min=0, max=10, right = true, ...props }) {
|
||||||
|
let ref = useRef(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (ref.current) {
|
||||||
|
ref.current.style.left = (((Math.max(Math.min(value-min, max-min), 0)) * 100) / ((max-min)+2)) + `%`;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div tw="flex flex-col py-2" {...props}>
|
||||||
|
<div className="rs-label w-full" ref={ref}>
|
||||||
|
{!right ? (rangeType + "" + value) : (value + "" + rangeType)}
|
||||||
|
</div>
|
||||||
|
<input type="range" className="rs-range relative range" min={min} max={max} value={value} onChange={({target: {value: radius}})=>onChange(radius)} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
87
Parts/RangeSlider.scss
Normal file
87
Parts/RangeSlider.scss
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
|
||||||
|
.rs-range {
|
||||||
|
|
||||||
|
-webkit-appearance: none;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
&::-webkit-slider-runnable-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: none;
|
||||||
|
background: --accent;
|
||||||
|
}
|
||||||
|
&::-moz-range-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: --accent;
|
||||||
|
}
|
||||||
|
&::-webkit-slider-runnable-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-slider-thumb {
|
||||||
|
box-shadow: none;
|
||||||
|
border: 0px solid --accent;
|
||||||
|
box-shadow: 0px 10px 10px rgba(0,0,0,0.25);
|
||||||
|
height: 32px;
|
||||||
|
width: 22px;
|
||||||
|
border-radius: 22px;
|
||||||
|
background: var(--accent);
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin-top: -12px;
|
||||||
|
}
|
||||||
|
&::-moz-range-thumb{
|
||||||
|
box-shadow: none;
|
||||||
|
border: 0px solid;
|
||||||
|
box-shadow: 0px 10px 10px rgba(0,0,0,0.25);
|
||||||
|
height: 31px;
|
||||||
|
width: 12px;
|
||||||
|
border-radius: 22px;
|
||||||
|
background: var(--accent);
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin-top: -20px;
|
||||||
|
}
|
||||||
|
&::-moz-focus-outer {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.rs-label {
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
margin-left: -1rem;
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 50%;
|
||||||
|
line-height: 30px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
padding-top: 0.4rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 2px solid var(--accent);
|
||||||
|
margin-top: 20px;
|
||||||
|
left: attr(value);
|
||||||
|
color: var(--accent);
|
||||||
|
font-size: 20px;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "Price";
|
||||||
|
display: block;
|
||||||
|
font-size: 8px;
|
||||||
|
letter-spacing: 0.07em;
|
||||||
|
margin-top: -1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,19 +1,18 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import tw, {styled} from "twin.macro"
|
||||||
|
import 'styled-components/macro'
|
||||||
|
|
||||||
export function Table(props) {
|
export function Table(props) {
|
||||||
return <div className="block w-full overflow-x-auto text-secondary">
|
return <div tw="block w-full overflow-x-auto text-secondary">
|
||||||
<table className="items-center w-full bg-transparent border-collapse">
|
<table tw="items-center w-full bg-transparent border-collapse">
|
||||||
{props.children}
|
{props.children}
|
||||||
</table>
|
</table>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
export function TablePart(props) {
|
|
||||||
return <td className={"border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-no-wrap p-4 " + props.className}>
|
|
||||||
{props.children}
|
const TablePart = styled.td(tw`border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap p-4`)
|
||||||
</td>;
|
export {TablePart}
|
||||||
}
|
|
||||||
export function TableHeader(props) {
|
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`)
|
||||||
return <th className={"px-6 py-3 align-middle text-xs uppercase whitespace-no-wrap font-bold text-left text-secondary border-b-2 border-secondary " + props.className}>
|
export {TableHeader}
|
||||||
{props.children}
|
|
||||||
</th>;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import tw, {styled} from "twin.macro"
|
||||||
|
import 'styled-components/macro'
|
||||||
|
import { textColors, textColorsHover } from './Colors'
|
||||||
|
|
||||||
|
|
||||||
function Text() {
|
function Text() {
|
||||||
return (
|
return (
|
||||||
|
|
@ -7,34 +11,22 @@ function Text() {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export function Divider() {
|
|
||||||
return <hr className="my-2 md:min-w-full border-secondary" />;
|
const Divider = styled.hr(tw`my-2 md:min-w-full border-secondary`)
|
||||||
}
|
export {Divider}
|
||||||
export function ClickableText({className, ...props}){
|
|
||||||
let color = "text-secondary hover:text-primary"
|
const DividerGreen = styled.hr(tw`h-2 border-0 from-accent bg-gradient-to-r rounded-2xl`)
|
||||||
switch (props.type) {
|
export {DividerGreen}
|
||||||
case "warning":
|
|
||||||
color = "text-accent4 hover:text-accent4-dark"
|
|
||||||
break;
|
|
||||||
case "danger":
|
const ClickableText = styled.button(({ type }) => [
|
||||||
color = "text-red-700 hover:text-red-800"
|
// The common button styles added with the tw import
|
||||||
break;
|
tw`text-secondary hover:text-primary font-semibold cursor-pointer`,
|
||||||
case "accent":
|
|
||||||
color = "text-accent hover:text-accent-dark"
|
// Use props to conditionally style your components
|
||||||
break;
|
textColors[type], textColorsHover[type]
|
||||||
case "accent2":
|
])
|
||||||
color = "text-accent2 hover:text-accent2-dark"
|
export {ClickableText}
|
||||||
break;
|
|
||||||
case "accent3":
|
|
||||||
color = "text-accent3 hover:text-accent3-dark"
|
|
||||||
break;
|
|
||||||
case "accent5":
|
|
||||||
color = "text-accent5 hover:btextg-accent5-dark"
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return <a {...props} className={color + " text-secondary hover:text-primary font-semibold cursor-pointer " + (className ?? "")}>{props.children}</a>
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Text
|
export default Text
|
||||||
|
|
|
||||||
76
globalStyle.js
Normal file
76
globalStyle.js
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
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
|
||||||
Loading…
Reference in New Issue
Block a user