Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions src/components/ui/category-horizontal-list.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { useState } from "react";
import type { Category, ContentType } from "oa-shared";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { CategoryHorizontalList } from "./category-horizontal-list";

const categories: Category[] = [
{
id: 1,
createdAt: new Date("2022-12-01T18:03:51.313Z"),
modifiedAt: null,
name: "Machines",
type: "questions" as ContentType,
imageUrl: null,
description: "Machine projects",
},
{
id: 2,
createdAt: new Date("2022-12-03T18:03:51.313Z"),
modifiedAt: null,
name: "Moulds",
type: "questions" as ContentType,
imageUrl: null,
description: null,
},
{
id: 3,
createdAt: new Date("2022-12-04T18:03:51.313Z"),
modifiedAt: null,
name: "Recycling",
type: "questions" as ContentType,
imageUrl: null,
description: null,
},
];

const meta: Meta<typeof CategoryHorizontalList> = {
title: "ui/CategoryHorizontalList",
component: CategoryHorizontalList,
};

export default meta;

type Story = StoryObj<typeof CategoryHorizontalList>;

export const Default: Story = {
render: () => {
const [activeCategory, setActiveCategory] = useState<Category | null>(null);

return (
<CategoryHorizontalList
activeCategory={activeCategory}
allCategories={categories}
setActiveCategory={setActiveCategory}
/>
);
},
};
54 changes: 54 additions & 0 deletions src/components/ui/category-horizontal-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import type { Category } from 'oa-shared';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';

interface CategoryHorizontalListProps {
activeCategory: Category | null;
allCategories: Category[];
setActiveCategory: (category: Category | null) => void;
}

export function CategoryHorizontalList({
activeCategory,
allCategories,
setActiveCategory,
}: CategoryHorizontalListProps) {
if (!allCategories?.length) {
return null;
}

const orderedCategories = allCategories
.slice()
.sort((a, b) => (a.createdAt > b.createdAt ? 1 : -1));

return (
<div data-cy="CategoryHorizonalList" className="flex overflow-x-auto">
{orderedCategories.map((category) => {
const isSelected = category.id === activeCategory?.id;

return (
<Button
key={category.id}
type="button"
variant="ghost"
aria-pressed={isSelected}
data-cy={`CategoryHorizonalList-Item${isSelected ? '-active' : ''}`}
data-testid="CategoryHorizonalList-Item"
title={category.name}
onClick={() => setActiveCategory(isSelected ? null : category)}
className={cn(
'mx-1 flex h-auto min-w-20 flex-col items-center justify-center rounded-lg border-2 py-2 text-center md:min-w-[100px] lg:min-w-[130px]',
isSelected ? 'border-foreground' : 'border-transparent',
)}
>
{category.imageUrl && (
<img src={category.imageUrl} alt="" className="size-10 object-contain" />
)}

<span className="text-sm">{category.name}</span>
</Button>
);
})}
</div>
);
}
12 changes: 3 additions & 9 deletions src/pages/Question/QuestionListHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import debounce from 'debounce';
import {
ButtonIcon,
CategoryHorizonalList,
Comment thread
mariojsnunes marked this conversation as resolved.
ReturnPathLink,
SearchField,
Select,
Tooltip,
} from 'oa-components';
import { ButtonIcon, ReturnPathLink, SearchField, Select, Tooltip } from 'oa-components';
import type { Category } from 'oa-shared';
import { useCallback, useEffect, useState } from 'react';
import { Link, useSearchParams } from 'react-router';
Expand All @@ -17,6 +10,7 @@ import type { FilterSection } from 'src/pages/common/Layout/MobileSortModal';
import { MobileSortModal } from 'src/pages/common/Layout/MobileSortModal';
import { categoryService } from 'src/services/categoryService';
import { Box, Button, Flex } from 'theme-ui';
import { CategoryHorizontalList } from '@/components/ui/category-horizontal-list';
import DraftButton from '../common/Drafts/DraftButton';
import { ListHeader } from '../common/Layout/ListHeader';
import { headings, listing } from './labels';
Expand Down Expand Up @@ -192,7 +186,7 @@ export const QuestionListHeader = (props: IProps) => {
);

const categoryComponent = (
<CategoryHorizonalList
<CategoryHorizontalList
allCategories={categories}
activeCategory={category}
setActiveCategory={(updatedCategory) =>
Expand Down
Loading