Skip to content

Commit

Permalink
feat: Responsive implemented on the Table component
Browse files Browse the repository at this point in the history
  • Loading branch information
ipapandinas committed Jan 4, 2024
1 parent a29d30d commit d7597e3
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 15 deletions.
20 changes: 15 additions & 5 deletions components/contributions-table/row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ interface IProjectProps {
}
export const Project = ({ avatarSrc, name, repository }: IProjectProps) => {
return (
<div className="flex gap-4">
<div className="flex md:gap-4">
<Project.Avatar alt={`${name} logo`} src={avatarSrc} />
<div className="flex flex-col w-36">
<div className="hidden md:flex flex-col w-36">
<h2 className="font-semibold truncate">{name}</h2>
<p className="text-small text-default-500 truncate">{repository}</p>
</div>
Expand Down Expand Up @@ -47,12 +47,22 @@ Project.Avatar = Avatar;

interface IContentProps {
title: string;
project: string;
repository: string;
language: string; //TODO: make it an enum type with available languages from filters
}
export const Content = ({ title, language }: IContentProps) => {
export const Content = ({
title,
project,
repository,
language,
}: IContentProps) => {
return (
<div>
<h3 className="font-semibold max-w-96 truncate">{title}</h3>
<div className="flex flex-col space-y-unit-1 md:space-y-0">
<h3 className="font-semibold max-w-64 sm:truncate sm:max-w-80 lg:max-w-64 xl:max-w-96">
{title}
</h3>
<span className="text-small text-default-500 truncate md:hidden">{`${project} / ${repository}`}</span>
<Chip className="mt-[1px]" variant="bordered" size="sm">
{language}
</Chip>
Expand Down
39 changes: 29 additions & 10 deletions components/contributions-table/table.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";
import React from "react";
import { useMediaQuery } from "react-responsive";
import {
Table as NuiTable,
TableHeader,
Expand All @@ -14,6 +15,7 @@ import { Contribution, PaginatedContributions } from "@/types/contribution";
import { ExternalLink, Content, Labels, Time, Project } from "./row";
import { useContributions } from "@/hooks/useContributions";
import { KudosQueryParameters } from "@/lib/notion/types";
import { isNotNull } from "@/utils/type-guard";

interface ITableProps {
items: PaginatedContributions;
Expand All @@ -34,6 +36,16 @@ export const Table = ({ items, queries = {} }: ITableProps) => {
return results?.pages.flatMap((page) => page.data) || [];
}, [results]);

const isMobile = useMediaQuery({ maxWidth: 639 }); // tailwind lg default: 640px
const isLaptop = useMediaQuery({ minWidth: 1024 }); // tailwind lg default: 1024px
const COLUMNS = [
{ name: "PROJECT", uid: "project" },
{ name: "CONTENT", uid: "content" },
isLaptop ? { name: "LABELS", uid: "labels" } : null,
{ name: "DATE", uid: "date" },
isMobile ? null : { name: "ACTIONS", uid: "actions" },
].filter(isNotNull);

const renderCell = React.useCallback(
(item: Contribution, columnKey: React.Key) => {
const cellValue = item[columnKey as keyof Contribution];
Expand All @@ -48,11 +60,25 @@ export const Table = ({ items, queries = {} }: ITableProps) => {
/>
);
case "content":
return <Content title={item.title} language={item.language} />;
return (
<Content
title={item.title}
project={item.project}
repository={item.repository}
language={item.language}
/>
);
case "labels":
return <Labels labels={item.labels} />;
case "date":
return <Time timestamp={item.timestamp} />;
return (
<div className="flex flex-col items-center gap-2">
<div className="block sm:hidden">
<ExternalLink href={item.url} />
</div>
<Time timestamp={item.timestamp} />
</div>
);
case "actions":
return <ExternalLink href={item.url} />;
default:
Expand Down Expand Up @@ -83,6 +109,7 @@ export const Table = ({ items, queries = {} }: ITableProps) => {
wrapper:
"bg-background overflow-visible p-0 rounded-none border-small border-y-0",
tr: "relative bg-gradient-to-r from-background to-background-200 to-80% border-y-small border-y-overlay before:content-[''] before:absolute before:bg-hover-overlay before:opacity-0 before:w-full before:h-full before:transition-opacity before:duration-300 before:ease-in-out hover:before:opacity-100",
td: "px-2 sm:px-inherit",
}}
>
<TableHeader columns={COLUMNS}>
Expand Down Expand Up @@ -113,11 +140,3 @@ export const Table = ({ items, queries = {} }: ITableProps) => {
};

export default Table;

const COLUMNS = [
{ name: "PROJECT", uid: "project" },
{ name: "CONTENT", uid: "content" },
{ name: "LABELS", uid: "labels" },
{ name: "DATE", uid: "date" },
{ name: "ACTIONS", uid: "actions" },
];
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-intersection-observer": "^9.5.3",
"react-responsive": "^9.0.2",
"tailwind-variants": "^0.1.19",
"tailwindcss": "3.4.0",
"typescript": "5.3.3"
Expand Down
34 changes: 34 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions utils/type-guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function isNotNull<T>(value: T | null): value is T {
return value !== null;
}

0 comments on commit d7597e3

Please sign in to comment.