Skip to content

Commit

Permalink
Use Primer component for RepositorySelector
Browse files Browse the repository at this point in the history
There seemed to be a bug with the Tremor selector where clearing the search
filter by closing the popover didn't restore the filtered list of items.

This commit switches to using the Primer `SelectPanel` instead. I added a
`RepositorySelector` component to manage the state for this. There may have
been a simpler fix - I'll probably take a look into the Tremor component to
see if I'm missing something.

We should decide what Component library we want to use for this - it might
more sense to roll with Tremor if we're going to use that for the charting.

I can also look into opening a PR upstream if there is in fact a bug in the
Select component.

Finally, I added some logic to make the Primer theme match the Tremor theme.
This is a downside of using two different component libraries.
  • Loading branch information
ipc103 authored Nov 9, 2023
1 parent 69df0a9 commit 6d2c575
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 17 deletions.
13 changes: 12 additions & 1 deletion who-metrics-ui/src/components/DashboardExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import {
DeltaType,
} from "@tremor/react";

import { Box } from "@primer/react";
import { Box, useTheme as primerUseTheme } from "@primer/react";
import Image from "next/image";
import logo from "@/images/who-logo-wide.svg";
import { ChartView } from "./";

import KpiCard from "./KpiCard";
import RepositoriesTable from "./RepositoriesTable";
import Data from "../data/data.json";
import { useTheme } from "next-themes";

type Kpi = {
title: string;
Expand Down Expand Up @@ -93,6 +94,16 @@ export const performance: DailyPerformance[] = [
];

export const DashboardExample = () => {
const { theme, systemTheme } = useTheme();
const { setColorMode } = primerUseTheme();
if (theme === "light" || theme === "dark" || theme === "auto") {
setColorMode(theme);
}

if (theme === "system" && systemTheme) {
setColorMode(systemTheme);
}

return (
<main className="px-18 py-18">
<Box
Expand Down
22 changes: 6 additions & 16 deletions who-metrics-ui/src/components/RepositoriesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import {
Card,
Select,
Flex,
MultiSelect,
MultiSelectItem,
SelectItem,
Table,
TableBody,
Expand All @@ -17,6 +15,7 @@ import {
} from "@tremor/react";
import { useState } from "react";
import Data from "../data/data.json";
import { RepositorySelector } from "./RepositorySelector";

const repos = Object.values(Data["repositories"]);
const licenses = repos
Expand Down Expand Up @@ -56,20 +55,11 @@ const RepositoriesTable = () => {
</Flex>
</div>
<div className="flex space-x-2">
<MultiSelect
className="max-w-full sm:max-w-xs"
onValueChange={setSelectedNames}
placeholder="Select repositories..."
>
{repos.map((item) => (
<MultiSelectItem
key={item.repositoryName}
value={item.repositoryName}
>
{item.repositoryName}
</MultiSelectItem>
))}
</MultiSelect>
<RepositorySelector
selectedNames={selectedNames}
setSelectedNames={setSelectedNames}
repositoryNames={repos.map((repo) => repo.repositoryName)}
/>
<Select
className="max-w-full sm:max-w-xs"
defaultValue="all"
Expand Down
58 changes: 58 additions & 0 deletions who-metrics-ui/src/components/RepositorySelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { TriangleDownIcon } from "@primer/octicons-react";
import { Button, SelectPanel } from "@primer/react";
import { ItemInput } from "@primer/react/lib/deprecated/ActionList/List";
import { useState } from "react";

export const RepositorySelector = ({
selectedNames,
setSelectedNames,
repositoryNames,
}: {
selectedNames: string[];
setSelectedNames: (nextSelection: string[]) => void;
repositoryNames: string[];
}) => {
const [open, setOpen] = useState(false);
const [filter, setFilter] = useState("");

const items: ItemInput[] = repositoryNames.map((repositoryName, index) => {
return {
text: repositoryName,
id: index,
};
});

const filteredItems = items.filter((item) => item.text?.includes(filter));

const selected = items.filter((item) => {
return item.text && selectedNames.includes(item.text);
});

const updateSelection = (selectedItems: ItemInput[]) => {
const updatedNames: string[] = selectedItems.map((item) => item.text || "");
setSelectedNames(updatedNames.filter((updatedName) => updatedName !== ""));
};
return (
<SelectPanel
renderAnchor={({ "aria-labelledby": ariaLabelledBy, ...anchorProps }) => (
<Button
trailingAction={TriangleDownIcon}
aria-labelledby={` ${ariaLabelledBy}`}
{...anchorProps}
>
Select repositories
</Button>
)}
title="Select repositories"
placeholderText="Filter repositories"
open={open}
onOpenChange={setOpen}
items={filteredItems}
selected={selected}
onSelectedChange={updateSelection}
onFilterChange={setFilter}
showItemDividers={true}
overlayProps={{ width: "xlarge", height: "xlarge" }}
/>
);
};

0 comments on commit 6d2c575

Please sign in to comment.