Compare commits

..

2 Commits

Author SHA1 Message Date
hamid zarghami ecd43b0307 shadow fix in about
Build and Deploy Docker Images / build_and_deploy (push) Has been cancelled
2026-06-23 14:35:38 +03:30
hamid zarghami 62a255cb70 fix category active item 2026-06-23 14:32:32 +03:30
3 changed files with 103 additions and 145 deletions
@@ -4,9 +4,9 @@ import { Category } from "@/app/[name]/(Main)/types/Types";
import CategoryItemRenderer from "@/components/listview/CategoryItemRenderer";
import CategorySmallItemRenderer from "@/components/listview/CategorySmallItemRenderer";
import HorizontalScrollView from "@/components/listview/HorizontalScrollView";
import { GLASS_SURFACE_DISABLED, GLASS_SURFACE_SELECTED } from "@/lib/styles/glassSurface";
import clsx from "clsx";
import { usePathname } from "next/navigation";
import { GLASS_SURFACE_DISABLED, GLASS_SURFACE_SELECTED } from "@/lib/styles/glassSurface";
/** TODO: remove when backend sends avatarRenderMode */
const COLORED_SVG_RESTAURANT_SLUGS = new Set(["havasone"]);
@@ -114,11 +114,7 @@ const CategoryScroll = ({ categories, selectedCategory, onSelect, variant = "lar
return (
<Renderer
key={item.id}
className={clsx(
isDisabled && GLASS_SURFACE_DISABLED,
isDisabled && "cursor-not-allowed",
isSelected && !isDisabled && GLASS_SURFACE_SELECTED,
)}
className={clsx(!isSelected && GLASS_SURFACE_DISABLED, isDisabled && "cursor-not-allowed", isSelected && !isDisabled && GLASS_SURFACE_SELECTED)}
onClick={isDisabled ? undefined : handleSelect(item.id)}
aria-disabled={isDisabled}
>
+99 -127
View File
@@ -1,139 +1,111 @@
'use client';
"use client";
import React, { ReactElement, ReactNode, useCallback, useState } from 'react'
import HorizontalScrollView from '../listview/HorizontalScrollView'
import { TabHeader, TabItemProps } from './TabHeader';
import clsx from 'clsx';
import TabHeaderRenderer from './TabHeaderRenderer';
import Image from 'next/image';
import { glassSurfaceNav } from '@/lib/styles/glassSurface';
import { glassSurfaceNav } from "@/lib/styles/glassSurface";
import clsx from "clsx";
import Image from "next/image";
import React, { ReactElement, ReactNode, useCallback, useState } from "react";
import HorizontalScrollView from "../listview/HorizontalScrollView";
import { TabHeader, TabItemProps } from "./TabHeader";
import TabHeaderRenderer from "./TabHeaderRenderer";
type Props = {
itemRenderer?: (child: ReactNode, index: number) => ReactElement;
children: ReactNode;
className?: TabContainerClassName;
changeType?: TabContainerRenderType;
defaultIndex?: number;
selectedTab?: number;
onTabChange?: (index: number) => void;
} & Omit<React.OlHTMLAttributes<HTMLUListElement>, 'className'>;
itemRenderer?: (child: ReactNode, index: number) => ReactElement;
children: ReactNode;
className?: TabContainerClassName;
changeType?: TabContainerRenderType;
defaultIndex?: number;
selectedTab?: number;
onTabChange?: (index: number) => void;
} & Omit<React.OlHTMLAttributes<HTMLUListElement>, "className">;
export enum TabContainerRenderType {
RENDERER,
VISIBILITY,
RENDERER,
VISIBILITY,
}
export type TabContainerClassName = {
wrapper?: string;
scrollView?: string;
header?: string;
headerDeactive?: string;
headerActive?: string;
icon?: string;
iconDeactive?: string;
iconActive?: string;
title?: string;
titleDeactive?: string;
titleActive?: string
}
wrapper?: string;
scrollView?: string;
header?: string;
headerDeactive?: string;
headerActive?: string;
icon?: string;
iconDeactive?: string;
iconActive?: string;
title?: string;
titleDeactive?: string;
titleActive?: string;
};
export const TabContainerClassNames: TabContainerClassName = {
wrapper: 'h-full',
scrollView: glassSurfaceNav('h-[72px] gradient-border !pt-3 !pb-2 w-full overflow-y-hidden justify-center rounded-[32px] inline-flex items-center gap-10'),
header: '',
headerDeactive: '',
headerActive: '',
icon: 'text-xs transition-all duration-150',
iconDeactive: 'stroke-disabled-text',
iconActive: 'stroke-primary dark:stroke-foreground',
title: 'text-xs transition-all duration-150',
titleDeactive: 'text-disabled-text',
titleActive: 'text-primary dark:text-foreground'
wrapper: "h-full",
scrollView: glassSurfaceNav("h-[72px] gradient-border !pt-3 !pb-2 w-full overflow-y-hidden justify-center rounded-[32px] inline-flex items-center gap-10 !shadow-none"),
header: "",
headerDeactive: "",
headerActive: "",
icon: "text-xs transition-all duration-150",
iconDeactive: "stroke-disabled-text",
iconActive: "stroke-primary dark:stroke-foreground",
title: "text-xs transition-all duration-150",
titleDeactive: "text-disabled-text",
titleActive: "text-primary dark:text-foreground",
};
function TabContainer({
className = TabContainerClassNames,
changeType = TabContainerRenderType.RENDERER,
defaultIndex = 0,
selectedTab: controlledSelectedTab,
onTabChange,
itemRenderer,
children,
...restProps
}: Props) {
const [internalSelectedTab, setInternalSelectedTab] = useState(defaultIndex);
const selectedTab = controlledSelectedTab !== undefined ? controlledSelectedTab : internalSelectedTab;
const updateTab = useCallback(
(index: number) => {
if (onTabChange) {
onTabChange(index);
} else {
setInternalSelectedTab(index);
}
},
[onTabChange],
);
const items = React.Children.toArray(children).filter((child): child is ReactElement<TabItemProps> => React.isValidElement(child) && child.type === TabHeader);
return (
<div className={className.wrapper}>
<HorizontalScrollView className={className.scrollView} itemRenderer={itemRenderer} {...restProps}>
{items.map((item, index) => {
const { title, imageSrc, icon }: TabItemProps = item.props;
return (
<TabHeaderRenderer key={index} className={clsx(className.header, index === selectedTab ? className.headerActive : className.headerDeactive)} onClick={() => updateTab(index)}>
{imageSrc && <Image priority src={imageSrc} width={24} height={24} alt="category image" />}
{icon && <span className={clsx(className.icon, index === selectedTab ? className.iconActive : className.iconDeactive)}>{icon}</span>}
<h6 className={clsx(className.title, index === selectedTab ? className.titleActive : className.titleDeactive)}>{title}</h6>
</TabHeaderRenderer>
);
})}
</HorizontalScrollView>
{changeType === TabContainerRenderType.RENDERER && <div>{items[selectedTab]?.props?.viewRenderer ?? <div></div>}</div>}
{changeType === TabContainerRenderType.VISIBILITY && (
<>
{items.map((item, index) => {
return (
<div key={index} className={clsx(index === selectedTab ? "visible" : "hidden")}>
{item.props.viewRenderer}
</div>
);
})}
</>
)}
</div>
);
}
function TabContainer({ className = TabContainerClassNames, changeType = TabContainerRenderType.RENDERER, defaultIndex = 0, selectedTab: controlledSelectedTab, onTabChange, itemRenderer, children, ...restProps }: Props) {
const [internalSelectedTab, setInternalSelectedTab] = useState(defaultIndex);
const selectedTab = controlledSelectedTab !== undefined ? controlledSelectedTab : internalSelectedTab;
const updateTab = useCallback((index: number) => {
if (onTabChange) {
onTabChange(index);
} else {
setInternalSelectedTab(index);
}
}, [onTabChange]);
const items = React.Children.toArray(children).filter(
(child): child is ReactElement<TabItemProps> =>
React.isValidElement(child) && child.type === TabHeader
);
return (
<div className={className.wrapper}>
<HorizontalScrollView
className={className.scrollView}
itemRenderer={itemRenderer}
{...restProps}>
{items.map((item, index) => {
const { title, imageSrc, icon }: TabItemProps = item.props;
return (
<TabHeaderRenderer
key={index}
className={clsx(
className.header,
index === selectedTab ? className.headerActive : className.headerDeactive
)}
onClick={() => updateTab(index)}
>
{imageSrc &&
<Image
priority
src={imageSrc}
width={24}
height={24}
alt="category image"
/>
}
{icon &&
<span className={clsx(
className.icon,
index === selectedTab ? className.iconActive : className.iconDeactive
)}>
{icon}
</span>
}
<h6 className={clsx(
className.title,
index === selectedTab ? className.titleActive : className.titleDeactive
)}>
{title}
</h6>
</TabHeaderRenderer>
)
})}
</HorizontalScrollView>
{changeType === TabContainerRenderType.RENDERER &&
<div>
{items[selectedTab]?.props?.viewRenderer ?? <div></div>}
</div>
}
{changeType === TabContainerRenderType.VISIBILITY &&
<>
{items.map((item, index) => {
return (
<div key={index} className={clsx(
index === selectedTab ? 'visible' : 'hidden'
)}>
{item.props.viewRenderer}
</div>
)
})}
</>
}
</div>
)
}
export default TabContainer
export default TabContainer;
+2 -12
View File
@@ -48,12 +48,7 @@ html[data-theme="dark"] .glass-surface--selected {
inset: 0;
border-radius: inherit;
padding: 2px;
background: linear-gradient(
180deg,
rgba(255, 255, 255, 1) 0%,
rgba(255, 253, 253, 0) 50%,
rgba(255, 255, 255, 1) 100%
);
background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(255, 253, 253, 0) 50%, rgba(255, 255, 255, 1) 100%);
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
@@ -76,12 +71,7 @@ html[data-theme="dark"] .glass-surface--disabled {
}
html[data-theme="dark"] .glass-surface--disabled::before {
background: linear-gradient(
180deg,
rgba(255, 255, 255, 0.35) 0%,
rgba(255, 255, 255, 0) 50%,
rgba(255, 255, 255, 0.35) 100%
);
background: linear-gradient(180deg, rgba(255, 255, 255, 0.35) 0%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0.35) 100%);
}
.glass-surface-nav {