Skip to content

Commit

Permalink
Add custom collapsible component to toggle some/all experience
Browse files Browse the repository at this point in the history
  • Loading branch information
josephdburdick committed Jun 27, 2024
1 parent 0f75e0c commit 43f482c
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 42 deletions.
19 changes: 0 additions & 19 deletions src/app/_content/Bio.tsx

This file was deleted.

43 changes: 41 additions & 2 deletions src/app/_content/Experience.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
"use client"

import {
Collapsible,
CollapsibleContent,
CollapsibleItem,
CollapsibleTrigger,
} from "@/components/global/Collapsible"
import DateSpan from "@/components/global/DateSpan"
import RuleHeader from "@/components/global/RuleHeader"
import { useApi } from "@/components/providers/DataProvider"
Expand All @@ -10,14 +16,17 @@ import {
AccordionTrigger,
} from "@/components/ui/accordion"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import convertNewLinesToHTML from "@/lib/convertNewLinesToHTML"
import toKebabCase from "@/lib/toKebabCase"
import { Experience as ExperienceType, Role } from "@/lib/types"
import { cn } from "@/lib/utils"
import { useState } from "react"

export default function Experience() {
const { data } = useApi()
const experience: ExperienceType[] = data.experience.attributes.experience
const [viewAllToggle, setViewAllToggle] = useState(false)
const renderSkill = (skill: string, key: number) =>
!!skill ? (
<li key={key}>
Expand Down Expand Up @@ -113,10 +122,36 @@ export default function Experience() {

const renderExperiences = (
<div className="container">
<ul className="grid-auto-rows grid gap-16">
<ul className="grid-auto-rows mx-auto grid gap-16">
{experience
.filter((item) => item?.disabled !== true)
.slice(0, 3)
.map(renderExperience)}
{experience.length > 3 && (
<Collapsible
type="single"
collapsible
onValueChange={(value: string) => setViewAllToggle(!!value)}
>
<CollapsibleItem value="expand">
<CollapsibleContent>
<ul className="grid-auto-rows grid gap-16">
{experience
.filter((item) => item?.disabled !== true)
.slice(3)
.map(renderExperience)}
</ul>
</CollapsibleContent>
<CollapsibleTrigger>
<RuleHeader side="both">
<span className="rounded-full border bg-primary px-4 py-2 text-xs text-primary-foreground">
{viewAllToggle ? "View Less" : "View All"} Experience
</span>
</RuleHeader>
</CollapsibleTrigger>
</CollapsibleItem>
</Collapsible>
)}
</ul>
</div>
)
Expand All @@ -137,7 +172,11 @@ export default function Experience() {
</h5>
</header>
</div>
<div className="flex w-full flex-1">{renderExperiences}</div>
<div className="flex w-full flex-1">
<ul className="grid-auto-rows mx-auto grid gap-16">
{renderExperiences}
</ul>
</div>
</section>
)
}
50 changes: 50 additions & 0 deletions src/components/global/Collapsible.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"use client"

import { cn } from "@/lib/utils"
import * as AccordionPrimitive from "@radix-ui/react-accordion"
import * as React from "react"

const Collapsible = AccordionPrimitive.Root

const CollapsibleItem = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
>(({ className, ...props }, ref) => (
<AccordionPrimitive.Item ref={ref} className={cn("", className)} {...props} />
))
CollapsibleItem.displayName = "CollapsibleItem"

const CollapsibleTrigger = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<AccordionPrimitive.Header className="flex">
<AccordionPrimitive.Trigger
ref={ref}
className={cn(
"flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all",
className,
)}
{...props}
>
{children}
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>
))
CollapsibleTrigger.displayName = AccordionPrimitive.Trigger.displayName

const CollapsibleContent = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<AccordionPrimitive.Content
ref={ref}
className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
{...props}
>
<div className={cn("pb-4 pt-0", className)}>{children}</div>
</AccordionPrimitive.Content>
))
CollapsibleContent.displayName = AccordionPrimitive.Content.displayName

export { Collapsible, CollapsibleItem, CollapsibleTrigger, CollapsibleContent }
14 changes: 0 additions & 14 deletions src/components/global/NameHeader.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions src/components/global/RuleHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ export default function RuleHeader(
return (
<div className="flex w-full items-center gap-4">
{["left", "both"].includes(side) && (
<div className="h-px w-full flex-1 bg-gradient-to-l from-current" />
<div className="h-px w-full flex-1 bg-gradient-to-l from-border to-transparent" />
)}
<span className={cn("flex-shrink", className)}>{props.children}</span>
{["right", "both"].includes(side) && (
<div className="h-px w-full flex-1 bg-gradient-to-r from-current" />
<div className="h-px w-full flex-1 bg-gradient-to-r from-border to-transparent" />
)}
</div>
)
Expand Down
9 changes: 4 additions & 5 deletions src/components/ui/accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
"use client"

import * as React from "react"
import { cn } from "@/lib/utils"
import * as AccordionPrimitive from "@radix-ui/react-accordion"
import { ChevronDownIcon } from "@radix-ui/react-icons"

import { cn } from "@/lib/utils"
import * as React from "react"

const Accordion = AccordionPrimitive.Root

Expand All @@ -28,8 +27,8 @@ const AccordionTrigger = React.forwardRef<
<AccordionPrimitive.Trigger
ref={ref}
className={cn(
"flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
className
"flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all [&[data-state=open]>svg]:rotate-180",
className,
)}
{...props}
>
Expand Down

0 comments on commit 43f482c

Please sign in to comment.