add: dark theme to a few components

This commit is contained in:
Mahyar Khanbolooki
2025-08-12 19:01:54 +03:30
parent e92c33963d
commit 5936f66665
7 changed files with 92 additions and 53 deletions
+3 -3
View File
@@ -310,16 +310,16 @@ const MenuIndex = () => {
selectedId={selectedDeliveryId}
onSelectionChange={changeSelectedDelivery} />
<div
className="flex w-full mt-[23px] h-11 items-center justify-between gap-2 px-3 py-4 relative bg-white/29 rounded-xl border border-solid border-neutral-200 cursor-pointer focus:outline-none focus:ring-2 focus:ring-black"
className="flex w-full mt-[23px] h-11 items-center justify-between gap-2 px-3 py-4 relative bg-container/29 rounded-xl border border-solid border-border cursor-pointer focus:outline-none focus:ring-2 focus:ring-black"
>
<span className="inline-flex items-center gap-2.5 text-sm2">
<MedalStar size="16" color="#333333" />
<MedalStar size="16" className="stroke-foreground" />
{tMenu('MenuFilterDrawer.PlusPoint')}
</span>
<Switch className="w-12 h-6" />
</div>
<div
className="flex w-full mt-[23px] h-11 items-center justify-between gap-2 px-3 py-4 relative bg-white/29 rounded-xl border border-solid border-neutral-200 cursor-pointer focus:outline-none focus:ring-2 focus:ring-black"
className="flex w-full mt-[23px] h-11 items-center justify-between gap-2 px-3 py-4 relative bg-container/29 rounded-xl border border-solid border-border cursor-pointer focus:outline-none focus:ring-2 focus:ring-black"
>
<span className="inline-flex items-center gap-2.5 text-sm2">
<TicketPercentIcon size={16} />
+74 -35
View File
@@ -147,7 +147,14 @@ input:autofill {
}
@theme inline {
@theme {
--font-irancell: var(--font-irancell);
--radius-normal: var(--radius-normal);
--text-sm2: var(--text-sm2);
--text-xs2: var(--text-xs2);
--radius-container: var(--radius-container);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
@@ -179,12 +186,37 @@ input:autofill {
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
--color-background: var(--background); /* oklch(0.963 0.008 289.2) */
--color-container: var(--container); /* oklch(1 0 0) */
--color-primary: var(--primary); /* oklch(0.14 0 0) */
--color-border: var(--border); /* oklch(0.885 0.007 248.3) */
--color-invalid: var(--invalid); /* oklch(0.515 0.118 27.5) */
--color-valid: var(--valid); /* oklch(0.46 0.107 132.7) */
--color-foreground: var(--foreground); /* oklch(0.202 0 0) */
--color-disabled: var(--disabled); /* oklch(0.91 0.004 295.2) */
--color-disabled2: var(--disabled2); /* oklch(0.5 0 0) */
--color-disabled3: var(--disabled3); /* oklch(0.949 0.002 277.1) */
--color-disabled-text: var(--disabled-text); /* oklch(0.34 0.006 257.4) */
--color-menu-header: var(--menu-header); /* oklch(0.79 0.03 237.3) */
--color-icon-deactive: var(--icon-deactive); /* oklch(0.65 0.027 234.8) */
--color-icon-active: var(--icon-active); /* oklch(0.12 0.002 304.5) */
}
:root {
--radius: 0.625rem;
/* unified theme */
:root {
--font-irancell: "Irancell";
--radius-normal: 10px;
--text-sm2: 13px;
--text-xs2: 10px;
--radius-container: 24px;
}
html[data-theme="light"] {
/* --radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--foreground: oklch(21% 0.006 285.885);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
@@ -193,12 +225,12 @@ input:autofill {
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted: oklch(0.928 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--border: oklch(0.9219 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.646 0.222 41.116);
@@ -213,11 +245,26 @@ input:autofill {
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
--sidebar-ring: oklch(0.708 0 0); */
--background: oklch(0.963 0.008 289.2); /* #F4F5F9 */
--container: oklch(1 0 0); /* #FFFFFF */
--primary: oklch(0.14 0 0); /* #000000 */
--border: oklch(0.885 0.007 248.3); /* #E5E5E5 */
--invalid: oklch(0.515 0.118 27.5); /* red (#FF0000 approx) */
--valid: oklch(0.46 0.107 132.7); /* #439C46 */
--foreground: oklch(0.202 0 0); /* #333333 */
--disabled: oklch(0.91 0.004 295.2); /* #E7E7E7 */
--disabled2: oklch(0.5 0 0); /* #7F7F7F */
--disabled3: oklch(0.949 0.002 277.1); /* #F2F2F2 */
--disabled-text: oklch(0.34 0.006 257.4); /* #8C90A3 */
--menu-header: oklch(0.79 0.03 237.3); /* #C3C7DD */
--icon-deactive: oklch(0.65 0.027 234.8); /* #A8ABBF */
--icon-active: oklch(0.12 0.002 304.5); /* #292D32 */
}
.dark {
--background: oklch(0.145 0 0);
html[data-theme="dark"] {
/* --background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
@@ -247,10 +294,25 @@ input:autofill {
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
--sidebar-ring: oklch(0.556 0 0); */
--background: oklch(23.26% 0.014 253.1); /* #F4F5F9 */
--container: oklch(25.33% 0.016 252.42); /* #FFFFFF */
--primary: oklch(14% 0.005 285.823); /* #000000 */
--border: oklch(21.15% 0.012 254.09); /* #E5E5E5 */
--invalid: oklch(0.515 0.118 27.5); /* red (#FF0000 approx) */
--valid: oklch(0.46 0.107 132.7); /* #439C46 */
--foreground: oklch(97.807% 0.029 256.847); /* #333333 */
--disabled: oklch(42.866% 0.00494 286.051); /* #E7E7E7 */
--disabled2: oklch(0.5 0 0); /* #7F7F7F */
--disabled3: oklch(0.949 0.002 277.1); /* #F2F2F2 */
--disabled-text: oklch(75.73% 0.01398 251.72); /* #8C90A3 */
--menu-header: oklch(0.79 0.03 237.3); /* #C3C7DD */
--icon-deactive: oklch(0.65 0.027 234.8); /* #A8ABBF */
--icon-active: oklch(0.12 0.002 304.5); /* #292D32 */
}
@layer base {
/* @layer base {
* {
@apply border-border outline-ring/50;
}
@@ -258,27 +320,4 @@ input:autofill {
body {
@apply bg-background text-foreground;
}
}
@theme {
--font-irancell: "Irancell";
--color-background: #F4F5F9;
--color-container: #FFFFFF;
--color-primary: #000000;
--color-border: #E5E5E5;
--color-invalid: red;
--color-valid: #439C46;
--color-foreground: #333333;
--color-disabled: #E7E7E7;
--color-disabled2: #7F7F7F;
--color-disabled3: #F2F2F2;
--color-disabled-text: #8C90A3;
--color-menu-header: #C3C7DD;
--color-icon-deactive: #A8ABBF;
--color-icon-active: #292D32;
--radius-normal: 10px;
--text-sm2: 13px;
--text-xs2: 10px;
--radius-container: 24px;
}
} */
@@ -53,7 +53,7 @@ const AnimatedBottomSheet = ({ blurOpacity = 64, overrideClassName = '', showTit
overrideClassName ?? '',
'absolute left-0 w-full rounded-t-4xl pt-[39px] pb-6',
'bottom-0',
'bg-container/64'
'bg-container/64 dark:bg-container/80'
)}
initial="hidden"
animate={props.visible ? 'visible' : 'hidden'}
@@ -61,12 +61,12 @@ const AnimatedBottomSheet = ({ blurOpacity = 64, overrideClassName = '', showTit
>
<div className="ps-[31px] pe-[33px] flex justify-between">
{showTitle &&
<div className='text-lg font-medium text-black leading-8 mt-2.5'>
<div className='text-lg font-medium text-foreground leading-8 mt-2.5'>
{props.title}
</div>
}
{showCloseButton &&
<div ref={closeRef} onClick={props.onClick} className="bg-white/38 w-8 h-8 rounded-full p-1.5">
<div ref={closeRef} onClick={props.onClick} className="bg-container/38 w-8 h-8 rounded-full p-1.5">
<CloseIcon size={20} />
</div>
}
+3 -3
View File
@@ -16,14 +16,14 @@ function Button({ children, className, disabled, pending, ...rest }: Props) {
disabled={disabled}
className={clsx(
className,
disabled ? 'bg-disabled text-disabled-text' : 'bg-primary text-white hover:bg-[#222222] active:brightness-110',
disabled ? 'bg-disabled text-disabled-text' : 'bg-primary text-background dark:text-foreground hover:bg-primary/60 active:brightness-110',
pending && 'bg-transparent! text-transparent! cursor-auto!',
'relative transition-all duration-200 cursor-pointer w-full rounded-normal p-3 font-normal text-sm overflow-clip'
)}
{...rest}
>
<motion.div
className='absolute left-0 top-0 h-full w-full bg-neutral-200'
className='absolute left-0 top-0 h-full w-full bg-border'
initial={{ y: '100%' }}
animate={!pending ? { y: '100%' } : { y: 0 }}
>
@@ -33,7 +33,7 @@ function Button({ children, className, disabled, pending, ...rest }: Props) {
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
className='-translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2 absolute'>
<Refresh stroke='#333333' size={24} />
<Refresh className='stroke-foreground' size={24} />
</motion.div>
</motion.div>
{children}
+5 -5
View File
@@ -97,7 +97,7 @@ function Combobox({ title, options, placeholder, icon: Icon, expanded, selectedI
{...props}
>
<div
className="flex w-full h-11 items-center justify-end gap-2 px-3 py-4 relative bg-white/29 rounded-xl border border-solid border-neutral-200 cursor-pointer"
className="flex w-full h-11 items-center justify-end gap-2 px-3 py-4 relative bg-container/29 rounded-xl border border-solid border-border cursor-pointer"
tabIndex={0}
onClick={toggleExpand}
role="combobox"
@@ -110,7 +110,7 @@ function Combobox({ title, options, placeholder, icon: Icon, expanded, selectedI
htmlFor="content-select"
className="pointer-events-none inline-flex flex-col items-end justify-center px-1 py-0 absolute -top-6 right-0 z-[2]"
>
<span className="relative w-fit mt-[-1px] text-xs tracking-[0] leading-4 whitespace-nowrap">
<span className="relative text-foreground w-fit mt-[-1px] text-xs tracking-[0] leading-4 whitespace-nowrap">
{title}
</span>
</label>
@@ -137,7 +137,7 @@ function Combobox({ title, options, placeholder, icon: Icon, expanded, selectedI
<motion.div
data-expand={expand}
aria-hidden={!expand}
className="absolute top-full left-0 w-full mt-1 text-foreground bg-white rounded-xl outline outline-solid outline-neutral-200 shadow-lg z-10"
className="absolute top-full left-0 w-full mt-1 text-foreground bg-container rounded-xl outline outline-solid outline-border shadow-lg z-10"
role="listbox"
aria-label={`${title} options`}
onClick={(e) => e.stopPropagation()}
@@ -147,7 +147,7 @@ function Combobox({ title, options, placeholder, icon: Icon, expanded, selectedI
>
{searchable &&
<div className="w-full flex gap-2 border-b px-3 items-center">
<div className="w-full flex gap-2 border-b border-border px-3 items-center">
<SearchNormal size={16} className='stroke-gray-400' />
<input
placeholder="جستجو ..."
@@ -165,7 +165,7 @@ function Combobox({ title, options, placeholder, icon: Icon, expanded, selectedI
onClick={(e) => setSelection(e, i)}
key={v.id}
data-selected={v.id === selectedId}
className="flex gap-3 items-center justify-end px-2 py-1 cursor-pointer hover:bg-gray-50 rounded-md last:rounded-b-xl"
className="flex gap-3 items-center justify-end px-2 py-1 cursor-pointer hover:bg-current/10 rounded-md last:rounded-b-xl"
tabIndex={0}
role="option"
aria-selected
+2 -2
View File
@@ -14,7 +14,7 @@ function Switch({
dir="ltr"
data-slot="switch"
className={cn(
"cursor-pointer peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-6 w-12 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
"cursor-pointer peer dark:data-[state=unchecked]:bg-neutral-600 dark:data-[state=checked]:bg-primary/80 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 inline-flex h-6 w-12 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
@@ -22,7 +22,7 @@ function Switch({
<SwitchPrimitive.Thumb
data-slot="switch-thumb"
className={cn(
"bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-5 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(140%-3px)] data-[state=unchecked]:translate-x-[1px]"
"bg-background dark:data-[state=checked]:bg-foreground dark:data-[state=unchecked]:bg-border pointer-events-none block size-5 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(140%-3px)] data-[state=unchecked]:translate-x-[1px]"
)}
/>
</SwitchPrimitive.Root>
@@ -42,14 +42,14 @@ function ClientMenuRouteWrapper({ children }: Props) {
}, [location])
useEffect(() => {
const theme = nightMode || window.matchMedia("(prefers-color-scheme: dark)").matches;
const theme = nightMode// || window.matchMedia("(prefers-color-scheme: dark)").matches;
document.documentElement.setAttribute("data-theme", theme ? "dark" : "light");
}, [nightMode]);
return (
<div className="h-svh overflow-hidden pt-10 flex flex-col pb-4 xl:pt-12">
<div className="z-50 fixed right-4 left-4 xl:right-[285px] top-4 xl:h-16 h-12 flex items-center px-4 bg-white justify-between rounded-[32px] xl:w-[calc(100%-305px)]">
<div className="z-50 fixed right-4 left-4 xl:right-[285px] top-4 xl:h-16 h-12 flex items-center px-4 bg-container justify-between rounded-[32px] xl:w-[calc(100%-305px)]">
<TopBar
profileDropState={profileDrop}
toggleProfileDropState={toggleProfileDrop}