tabs styling

This commit is contained in:
BFlat committed 2024-03-24 11:23:17 +07:00
1 parent 911648f1f0
commit 69f62b8f00
6 files changed
+177 -189

No files matched your search

+42 -55
View File
@@ -1,67 +1,54 @@
import {
Fragment,
useState
} from 'react'
import { Dialog, Transition } from '@headlessui/react'
import {
faGears,
} from '@fortawesome/pro-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Fragment, useState } from "react";
import { Dialog, Transition } from "@headlessui/react";
import { faGears } from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Button } from '~/components/Button';
import { Button } from "~/components/Button";
import { SidePanelInner } from './SidePanelInner';
import { SidePanelInner } from "./SidePanelInner";
interface SidePanelPropsI{
interface SidePanelPropsI {
title?: string;
children: React.ReactNode;
}
export const SidePanel =({
title,
children,
}:SidePanelPropsI)=>{
export const SidePanel = ({ title, children }: SidePanelPropsI) => {
const [open, setOpen] = useState<boolean>(false);
const handleOpen = ()=> setOpen(true);
const handleClose = ()=>setOpen(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
return (<>
<Button
className='fixed right-0 top-20 mt-2 mr-4'
onClick={handleOpen}
>
<FontAwesomeIcon className="fa-2xl -mx-2" icon={faGears} />
</Button>
<Transition.Root show={open} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={setOpen}>
<div className="fixed inset-0" />
return (
<>
<Button className="fixed right-0 top-20 mr-4 mt-2" onClick={handleOpen}>
<FontAwesomeIcon className="fa-2xl -mx-2" icon={faGears} />
</Button>
<Transition.Root show={open} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={setOpen}>
<div className="fixed inset-0" />
<div className="fixed inset-0 overflow-hidden">
<div className="absolute inset-0 overflow-hidden">
<div className="pointer-events-none inset-y-0 fixed top-16 mt-2 right-0 flex max-w-full pl-10 sm:pl-16">
<Transition.Child
as={Fragment}
enter="transform transition ease-in-out duration-500 sm:duration-700"
enterFrom="translate-x-full"
enterTo="translate-x-0"
leave="transform transition ease-in-out duration-500 sm:duration-700"
leaveFrom="translate-x-0"
leaveTo="translate-x-full"
>
<Dialog.Panel className="pointer-events-auto w-screen lg:max-w-md">
<SidePanelInner
title={title}
closeCallback={handleClose}
>
{children}
</SidePanelInner>
</Dialog.Panel>
</Transition.Child>
<div className="fixed inset-0 overflow-hidden">
<div className="absolute inset-0 overflow-hidden">
<div className="pointer-events-none fixed inset-y-0 right-0 top-16 mt-2 flex max-w-full pl-10 sm:pl-16">
<Transition.Child
as={Fragment}
enter="transform transition ease-in-out duration-500 sm:duration-700"
enterFrom="translate-x-full"
enterTo="translate-x-0"
leave="transform transition ease-in-out duration-500 sm:duration-700"
leaveFrom="translate-x-0"
leaveTo="translate-x-full"
>
<Dialog.Panel className="pointer-events-auto lg:max-w-full">
<SidePanelInner title={title} closeCallback={handleClose}>
{children}
</SidePanelInner>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</div>
</div>
</Dialog>
</Transition.Root>
</>);
}
</Dialog>
</Transition.Root>
</>
);
};
+23 -31
View File
@@ -1,35 +1,29 @@
import {
useCallback,
useLayoutEffect,
useState
} from 'react';
import { Dialog } from '@headlessui/react'
import { useCallback, useLayoutEffect, useState } from "react";
import { Dialog } from "@headlessui/react";
import {
faXmark,
} from '@fortawesome/pro-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faXmark } from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { TOP_BAR_HEIGHT } from '~/constants';
import { TOP_BAR_HEIGHT } from "~/constants";
export const SidePanelInner = ({
title,
children,
closeCallback
}:{
closeCallback,
}: {
title?: string;
children: React.ReactNode;
closeCallback: ()=>void;
})=>{
closeCallback: () => void;
}) => {
const [height, setHeight] = useState(0);
const handleWindowResize = useCallback(()=>{
if(window){
setHeight (Math.ceil(window.innerHeight * 3 / 4) - TOP_BAR_HEIGHT);
const handleWindowResize = useCallback(() => {
if (window) {
setHeight(Math.ceil((window.innerHeight * 3) / 4) - TOP_BAR_HEIGHT);
}
return 0;
},[])
}, []);
useLayoutEffect(()=>{
useLayoutEffect(() => {
handleWindowResize();
window.addEventListener("resize", handleWindowResize);
return () => {
@@ -37,19 +31,19 @@ export const SidePanelInner = ({
};
}, [handleWindowResize]);
return(
return (
<div
className="flex flex-col overflow-y-scroll bg-ui-panel py-6 shadow-xl border-y border-l border-ui-panel-border"
style={{height:height+'px'}}
className="flex flex-col overflow-y-scroll border-y border-l border-ui-panel-border bg-ui-panel py-6 shadow-xl"
style={{ height: height + "px" }}
>
<div className="px-4 sm:px-6">
<div className="flex items-start justify-between">
{!title && <span/>}
{title &&
{!title && <span />}
{title && (
<Dialog.Title className="text-base font-semibold leading-6 text-white">
{title}
</Dialog.Title>
}
)}
<div className="ml-3 flex h-7 items-center">
<button
type="button"
@@ -59,7 +53,7 @@ export const SidePanelInner = ({
{/* <span className="absolute -inset-2.5" /> */}
<span className="sr-only">Close panel</span>
<FontAwesomeIcon
className="h-6 w-6 mt-1 mx-1"
className="mx-1 mt-1 h-6 w-6"
aria-hidden="true"
icon={faXmark}
/>
@@ -67,9 +61,7 @@ export const SidePanelInner = ({
</div>
</div>
</div>
<div className="relative mt-6 flex-1 px-4 sm:px-6">
{children}
</div>
<div className="relative mt-6 flex-1">{children}</div>
</div>
);
}
};
+22 -33
View File
@@ -1,55 +1,44 @@
import { useState } from 'react'
import { Tab } from '@headlessui/react'
import { useState } from "react";
import { Tab } from "@headlessui/react";
import { twMerge } from "tailwind-merge";
import { joinClassNames } from '~/helpers';
export type Tab = {
export type TabType = {
header: string;
children: JSX.Element;
}
};
export const Tabs = ({
tabs: tabProps
}:{
tabs:Tab[]
}) =>{
const [tabs, setTabs] = useState(tabProps);
export const Tabs = ({ tabs: tabProps }: { tabs: TabType[] }) => {
const [tabs] = useState(tabProps);
const tabHeaderClassName = (selected: boolean) =>
twMerge(
"px-4 py-4 text-md font-medium leading-5 focus:outline-none transition duration-150 ease-in-out border-b-[3px] border-white/[.1]",
selected
? "bg-ui-panel text-white border-brand-primary"
: "text-gray-400 hover:bg-ui-panel hover:text-white hover:border-white/[.2]",
);
return (
<div className="w-full max-w-md px-2 py-16 sm:px-0">
<div className="w-full max-w-md px-2 sm:px-0">
<Tab.Group>
<Tab.List className="flex space-x-1 rounded-xl bg-blue-900/20 p-1">
<Tab.List className="flex">
{tabs.map((tab, idx) => (
<Tab
key={idx}
className={({ selected }) =>
joinClassNames(
'w-full rounded-lg py-2.5 text-sm font-medium leading-5',
'ring-white/60 ring-offset-2 ring-offset-blue-400 focus:outline-none focus:ring-2',
selected
? 'bg-white text-blue-700 shadow'
: 'text-blue-100 hover:bg-white/[0.12] hover:text-white'
)
}
className={({ selected }) => tabHeaderClassName(selected)}
>
{tab.header}
</Tab>
))}
</Tab.List>
<Tab.Panels className="mt-2">
<Tab.Panels>
{tabs.map((tab, idx) => (
<Tab.Panel
key={idx}
className={joinClassNames(
'rounded-xl bg-white p-3',
'ring-white/60 ring-offset-2 ring-offset-blue-400 focus:outline-none focus:ring-2'
)}
>
<Tab.Panel key={idx} className="p-4 text-white focus:outline-none">
{tab.children}
</Tab.Panel>
))}
</Tab.Panels>
</Tab.Group>
</div>
)
}
);
};
+17 -6
View File
@@ -27,6 +27,7 @@
"isbot": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwind-merge": "^2.2.2",
"three": "^0.162.0",
"uuid": "^9.0.1",
"webm-writer": "^1.0.0"
@@ -722,10 +723,9 @@
}
},
"node_modules/@babel/runtime": {
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz",
"integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==",
"dev": true,
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz",
"integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -10600,8 +10600,7 @@
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
"dev": true
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
},
"node_modules/regexp.prototype.flags": {
"version": "1.5.2",
@@ -11720,6 +11719,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/tailwind-merge": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.2.2.tgz",
"integrity": "sha512-tWANXsnmJzgw6mQ07nE3aCDkCK4QdT3ThPMCzawoYA2Pws7vSTCvz3Vrjg61jVUGfFZPJzxEP+NimbcW+EdaDw==",
"dependencies": {
"@babel/runtime": "^7.24.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/dcastil"
}
},
"node_modules/tailwindcss": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz",
+1
View File
@@ -33,6 +33,7 @@
"isbot": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwind-merge": "^2.2.2",
"three": "^0.162.0",
"uuid": "^9.0.1",
"webm-writer": "^1.0.0"
+72 -64
View File
@@ -1,5 +1,5 @@
import type { Config } from 'tailwindcss';
import colors from 'tailwindcss/colors';
import type { Config } from "tailwindcss";
import colors from "tailwindcss/colors";
export default {
content: [
@@ -8,76 +8,84 @@ export default {
"./app/*.{js,jsx,ts,tsx}",
],
theme: {
// extend: {},
colors:{
transparent: 'transparent',
current: 'currentColor',
extend: {
fontFamily: {
"custom-font": ["Fira Sans", "sans-serif"],
},
},
colors: {
transparent: "transparent",
current: "currentColor",
'brand-primary': { //sunglo
DEFAULT: '#e66462', //=500
'50': '#fdf3f3',
'100': '#fce4e4',
'200': '#facfce',
'300': '#f6acab',
'400': '#ef7c7a',
'500': '#e66462',
'600': '#cf3533',
'700': '#ae2927',
'800': '#902624',
'900': '#782524',
'950': '#410f0e',
"brand-primary": {
//sunglo
DEFAULT: "#e66462", //=500
"50": "#fdf3f3",
"100": "#fce4e4",
"200": "#facfce",
"300": "#f6acab",
"400": "#ef7c7a",
"500": "#e66462",
"600": "#cf3533",
"700": "#ae2927",
"800": "#902624",
"900": "#782524",
"950": "#410f0e",
},
'brand-secondary': { //gunpowder
DEFAULT: '#39394c', //=950
'50': '#f5f6f9',
'100': '#e8eaf1',
'200': '#d7dbe6',
'300': '#bbc1d5',
'400': '#9aa2c0',
'500': '#8188b0',
'600': '#6f74a1',
'700': '#636492',
'800': '#545579',
'900': '#464762',
'950': '#39394c',
"brand-secondary": {
//gunpowder
DEFAULT: "#39394c", //=950
"50": "#f5f6f9",
"100": "#e8eaf1",
"200": "#d7dbe6",
"300": "#bbc1d5",
"400": "#9aa2c0",
"500": "#8188b0",
"600": "#6f74a1",
"700": "#636492",
"800": "#545579",
"900": "#464762",
"950": "#39394c",
},
danger: { //copper rust
DEFAULT: '#8f4951', //=700
'50': '#fbf5f5',
'100': '#f7ecec',
'200': '#efdcdc',
'300': '#e2c0bf',
'400': '#d19b9c',
'500': '#bd7679',
'600': '#a5595f',
'700': '#8f4951',
'800': '#743d45',
'900': '#64373f',
'950': '#361b1e',
danger: {
//copper rust
DEFAULT: "#8f4951", //=700
"50": "#fbf5f5",
"100": "#f7ecec",
"200": "#efdcdc",
"300": "#e2c0bf",
"400": "#d19b9c",
"500": "#bd7679",
"600": "#a5595f",
"700": "#8f4951",
"800": "#743d45",
"900": "#64373f",
"950": "#361b1e",
},
success:{ //apple
DEFAULT: '#40ad48', //=500
'50': '#f2fbf2',
'100': '#e2f6e3',
'200': '#c5edc7',
'300': '#98dd9d',
'400': '#64c46b',
'500': '#40ad48',
'600': '#2f8a35',
'700': '#286d2e',
'800': '#245728',
'900': '#1f4823',
'950': '#0c270f',
success: {
//apple
DEFAULT: "#40ad48", //=500
"50": "#f2fbf2",
"100": "#e2f6e3",
"200": "#c5edc7",
"300": "#98dd9d",
"400": "#64c46b",
"500": "#40ad48",
"600": "#2f8a35",
"700": "#286d2e",
"800": "#245728",
"900": "#1f4823",
"950": "#0c270f",
},
'ui-background': '#1a1a27',
'ui-panel': '#242433',
'ui-panel-border': '#5e6097',
"ui-background": "#1a1a27",
"ui-panel": "#242433",
"ui-panel-border": "#5e6097",
gray: colors.gray,
white: colors.white
}
white: colors.white,
},
},
plugins: [],
} satisfies Config
} satisfies Config;