Skip to content

Commit 5d12a82

Browse files
authored
fix: dropdown in breadcrumb and table (#409)
1 parent 02b6412 commit 5d12a82

File tree

2 files changed

+94
-71
lines changed

2 files changed

+94
-71
lines changed
Lines changed: 68 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { ChevronDownIcon,DotsHorizontalIcon } from "@radix-ui/react-icons";
2-
import { cva, type VariantProps } from "class-variance-authority";
3-
import React, { forwardRef, PropsWithChildren } from "react";
1+
import { ChevronDownIcon, DotsHorizontalIcon } from '@radix-ui/react-icons';
2+
import { type VariantProps, cva } from 'class-variance-authority';
3+
import React, { forwardRef, PropsWithChildren } from 'react';
44

5-
import { DropdownMenu } from "../dropdown-menu";
6-
import styles from "./breadcrumb.module.css";
5+
import { DropdownMenu } from '../dropdown-menu';
6+
import styles from './breadcrumb.module.css';
77

88
interface BreadcrumbItem {
99
label: string;
@@ -15,16 +15,18 @@ interface BreadcrumbItem {
1515
const breadcrumb = cva(styles['breadcrumb'], {
1616
variants: {
1717
size: {
18-
small: styles["breadcrumb-small"],
19-
medium: styles["breadcrumb-medium"],
20-
},
18+
small: styles['breadcrumb-small'],
19+
medium: styles['breadcrumb-medium']
20+
}
2121
},
2222
defaultVariants: {
23-
size: "medium",
24-
},
23+
size: 'medium'
24+
}
2525
});
2626

27-
type BreadcrumbProps = PropsWithChildren<Omit<VariantProps<typeof breadcrumb>, 'size'>> & {
27+
type BreadcrumbProps = PropsWithChildren<
28+
Omit<VariantProps<typeof breadcrumb>, 'size'>
29+
> & {
2830
items: BreadcrumbItem[];
2931
maxVisibleItems?: number;
3032
separator?: React.ReactNode;
@@ -34,82 +36,105 @@ type BreadcrumbProps = PropsWithChildren<Omit<VariantProps<typeof breadcrumb>, '
3436
};
3537

3638
export const Breadcrumb = forwardRef<HTMLDivElement, BreadcrumbProps>(
37-
({
38-
className,
39-
size = 'medium',
40-
items,
41-
maxVisibleItems,
42-
separator = '/',
43-
onItemClick,
44-
...props
45-
}, ref) => {
46-
const visibleItems = maxVisibleItems && items.length > maxVisibleItems
47-
? [
48-
...items.slice(0, 1),
49-
{ label: 'ellipsis', href: '#' },
50-
...items.slice(-Math.min(maxVisibleItems - 1, items.length - 1))
51-
]
52-
: items;
39+
(
40+
{
41+
className,
42+
size = 'medium',
43+
items,
44+
maxVisibleItems,
45+
separator = '/',
46+
onItemClick,
47+
...props
48+
},
49+
ref
50+
) => {
51+
const visibleItems =
52+
maxVisibleItems && items.length > maxVisibleItems
53+
? [
54+
...items.slice(0, 1),
55+
{ label: 'ellipsis', href: '#' },
56+
...items.slice(-Math.min(maxVisibleItems - 1, items.length - 1))
57+
]
58+
: items;
5359

54-
const renderItem = (item: BreadcrumbItem, index: number, isLast: boolean) => (
60+
const renderItem = (
61+
item: BreadcrumbItem,
62+
index: number,
63+
isLast: boolean
64+
) => (
5565
<li key={index} className={styles['breadcrumb-item']}>
5666
{item.label === 'ellipsis' ? (
5767
<span className={styles['breadcrumb-ellipsis']}>
5868
<DotsHorizontalIcon />
5969
</span>
6070
) : item?.dropdownItems ? (
6171
<DropdownMenu>
62-
<DropdownMenu.Trigger className={styles['breadcrumb-dropdown-trigger']}>
63-
{item.icon && <span className={styles['breadcrumb-icon']}>{item.icon}</span>}
72+
<DropdownMenu.Trigger
73+
className={styles['breadcrumb-dropdown-trigger']}
74+
>
75+
{item.icon && (
76+
<span className={styles['breadcrumb-icon']}>{item.icon}</span>
77+
)}
6478
<span>{item.label}</span>
6579
<ChevronDownIcon className={styles['breadcrumb-dropdown-icon']} />
6680
</DropdownMenu.Trigger>
67-
<DropdownMenu.Content className={styles['breadcrumb-dropdown-content']}>
81+
<DropdownMenu.Content
82+
className={styles['breadcrumb-dropdown-content']}
83+
>
6884
{item.dropdownItems.map((dropdownItem, dropdownIndex) => (
69-
<DropdownMenu.Item
85+
<DropdownMenu.Item
7086
key={dropdownIndex}
7187
className={styles['breadcrumb-dropdown-item']}
72-
onSelect={() => onItemClick && onItemClick({
73-
label: dropdownItem.label,
74-
href: dropdownItem.href
75-
})}
88+
onClick={() =>
89+
onItemClick &&
90+
onItemClick({
91+
label: dropdownItem.label,
92+
href: dropdownItem.href
93+
})
94+
}
7695
>
7796
{dropdownItem.label}
7897
</DropdownMenu.Item>
7998
))}
8099
</DropdownMenu.Content>
81100
</DropdownMenu>
82101
) : (
83-
<a
102+
<a
84103
href={item.href}
85104
className={`${styles['breadcrumb-link']} ${isLast ? styles['breadcrumb-link-active'] : ''}`}
86-
onClick={(e) => {
105+
onClick={e => {
87106
if (onItemClick && item.href !== '#') {
88107
e.preventDefault();
89108
onItemClick(item);
90109
}
91110
}}
92111
>
93-
{item.icon && <span className={styles['breadcrumb-icon']}>{item.icon}</span>}
112+
{item.icon && (
113+
<span className={styles['breadcrumb-icon']}>{item.icon}</span>
114+
)}
94115
<span>{item.label}</span>
95116
</a>
96117
)}
97-
{!isLast && <span className={styles['breadcrumb-separator']}>{separator}</span>}
118+
{!isLast && (
119+
<span className={styles['breadcrumb-separator']}>{separator}</span>
120+
)}
98121
</li>
99122
);
100123

101124
return (
102-
<nav
125+
<nav
103126
className={breadcrumb({ size: size as 'small' | 'medium', className })}
104127
ref={ref}
105128
{...props}
106129
>
107130
<ol className={styles['breadcrumb-list']}>
108-
{visibleItems.map((item, index) => renderItem(item, index, index === visibleItems.length - 1))}
131+
{visibleItems.map((item, index) =>
132+
renderItem(item, index, index === visibleItems.length - 1)
133+
)}
109134
</ol>
110135
</nav>
111136
);
112137
}
113138
);
114139

115-
Breadcrumb.displayName = "Breadcrumb";
140+
Breadcrumb.displayName = 'Breadcrumb';

packages/raystack/v1/components/data-table/components/filters.tsx

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { Button } from "../../button";
2-
import { DropdownMenu } from "../../dropdown-menu";
3-
import { FilterChip } from "../../filter-chip";
4-
import { Flex } from "../../flex";
5-
import { IconButton } from "../../icon-button";
6-
import { FilterIcon } from "~/icons";
7-
import { DataTableColumn } from "../data-table.types";
8-
import { useDataTable } from "../hooks/useDataTable";
9-
import { FilterOperatorTypes, FilterType } from "~/v1/types/filters";
10-
import { useFilters } from "../hooks/useFilters";
1+
import { FilterIcon } from '~/icons';
2+
import { FilterOperatorTypes, FilterType } from '~/v1/types/filters';
3+
import { Button } from '../../button';
4+
import { DropdownMenu } from '../../dropdown-menu';
5+
import { FilterChip } from '../../filter-chip';
6+
import { Flex } from '../../flex';
7+
import { IconButton } from '../../icon-button';
8+
import { DataTableColumn } from '../data-table.types';
9+
import { useDataTable } from '../hooks/useDataTable';
10+
import { useFilters } from '../hooks/useFilters';
1111

1212
interface AddFilterProps<TData, TValue> {
1313
columnList: DataTableColumn<TData, TValue>[];
@@ -18,10 +18,10 @@ interface AddFilterProps<TData, TValue> {
1818
function AddFilter<TData, TValue>({
1919
columnList = [],
2020
appliedFiltersSet,
21-
onAddFilter,
21+
onAddFilter
2222
}: AddFilterProps<TData, TValue>) {
2323
const availableFilters = columnList?.filter(
24-
(col) => !appliedFiltersSet.has(col.id)
24+
col => !appliedFiltersSet.has(col.id)
2525
);
2626

2727
return availableFilters.length > 0 ? (
@@ -32,17 +32,17 @@ function AddFilter<TData, TValue>({
3232
<FilterIcon />
3333
</IconButton>
3434
) : (
35-
<Button variant={"text"} size={"small"} leadingIcon={<FilterIcon />}>
35+
<Button variant={'text'} size={'small'} leadingIcon={<FilterIcon />}>
3636
Filter
3737
</Button>
3838
)}
3939
</DropdownMenu.Trigger>
40-
<DropdownMenu.Content align="start">
41-
{availableFilters?.map((column) => {
40+
<DropdownMenu.Content>
41+
{availableFilters?.map(column => {
4242
const columnDef = column.columnDef;
4343
const id = columnDef.accessorKey || column.id;
4444
return (
45-
<DropdownMenu.Item key={id} onSelect={() => onAddFilter(column)}>
45+
<DropdownMenu.Item key={id} onClick={() => onAddFilter(column)}>
4646
{columnDef.header || id}
4747
</DropdownMenu.Item>
4848
);
@@ -60,45 +60,43 @@ export function Filters<TData, TValue>() {
6060
onAddFilter,
6161
handleRemoveFilter,
6262
handleFilterValueChange,
63-
handleFilterOperationChange,
63+
handleFilterOperationChange
6464
} = useFilters<TData, TValue>();
6565

6666
const columnList = columns?.filter(
67-
(column) => column.columnDef.enableColumnFilter
67+
column => column.columnDef.enableColumnFilter
6868
);
6969

7070
const appliedFiltersSet = new Set(
71-
tableQuery?.filters?.map((filter) => filter.name)
71+
tableQuery?.filters?.map(filter => filter.name)
7272
);
7373

7474
const appliedFilters =
75-
tableQuery?.filters?.map((filter) => {
76-
const columnDef = columns?.find((col) => {
75+
tableQuery?.filters?.map(filter => {
76+
const columnDef = columns?.find(col => {
7777
const columnDef = col.columnDef;
7878
const id = columnDef.accessorKey || col.id;
7979
return id === filter.name;
8080
})?.columnDef;
8181
return {
8282
filterType: columnDef?.filterType || FilterType.string,
83-
label: (columnDef?.header as string) || "",
83+
label: (columnDef?.header as string) || '',
8484
options: columnDef?.filterOptions || [],
85-
...filter,
85+
...filter
8686
};
8787
}) || [];
8888

8989
return (
9090
<Flex gap={3}>
9191
<Flex gap={3}>
92-
{appliedFilters.map((filter) => (
92+
{appliedFilters.map(filter => (
9393
<FilterChip
9494
key={filter.name}
9595
label={filter.label}
9696
value={filter.value}
9797
onRemove={() => handleRemoveFilter(filter.name)}
98-
onValueChange={(value) =>
99-
handleFilterValueChange(filter.name, value)
100-
}
101-
onOperationChange={(operator) =>
98+
onValueChange={value => handleFilterValueChange(filter.name, value)}
99+
onOperationChange={operator =>
102100
handleFilterOperationChange(
103101
filter.name,
104102
operator as FilterOperatorTypes

0 commit comments

Comments
 (0)