diff --git a/js/react/lib/components/topic/index.ts b/js/react/lib/components/topic/index.ts new file mode 100644 index 0000000..cf409b7 --- /dev/null +++ b/js/react/lib/components/topic/index.ts @@ -0,0 +1,3 @@ +export * from "./topic.component"; +export * from "./subtopic.component"; +export * from "./topic.types"; diff --git a/js/react/lib/components/topic/subtopic.component.tsx b/js/react/lib/components/topic/subtopic.component.tsx new file mode 100644 index 0000000..428ee79 --- /dev/null +++ b/js/react/lib/components/topic/subtopic.component.tsx @@ -0,0 +1,16 @@ +import { Badge } from "../badge"; +import { Level } from "../level"; +import { TopicElement } from "./topic.types"; +import { withAs } from "@/utils/hoc"; + +export const SubTopic = withAs( + (Component, { level, state, title, ...rest }: TopicElement) => { + return ( + + + {title} + + + ); + } +); diff --git a/js/react/lib/components/topic/topic.component.tsx b/js/react/lib/components/topic/topic.component.tsx new file mode 100644 index 0000000..573cb4e --- /dev/null +++ b/js/react/lib/components/topic/topic.component.tsx @@ -0,0 +1,20 @@ +import { PropsWithChildren } from "react"; +import { ArrowDown } from "@/icons"; +import { Badge } from "../badge"; +import { Level } from "../level"; +import { TopicElement } from "./topic.types"; + +type TopicProps = PropsWithChildren & TopicElement; +export const Topic = ({ level, title, state, children }: TopicProps) => { + return ( +
+ + + {title} + + + + {children} +
+ ); +}; diff --git a/js/react/lib/components/topic/topic.types.ts b/js/react/lib/components/topic/topic.types.ts new file mode 100644 index 0000000..87d0a28 --- /dev/null +++ b/js/react/lib/components/topic/topic.types.ts @@ -0,0 +1,8 @@ +import { BadgeVariants } from "../badge/badge.const"; +import { LevelVariants } from "../level/level.const"; + +export type TopicElement = { + level: LevelVariants; + title: string; + state: BadgeVariants; +}; diff --git a/js/react/lib/index.ts b/js/react/lib/index.ts index dda37ef..564607d 100644 --- a/js/react/lib/index.ts +++ b/js/react/lib/index.ts @@ -11,4 +11,5 @@ export * from "./components/radio"; export * from "./components/badge"; export * from "./components/dropdown"; export * from "./components/calendar"; +export * from "./components/topic"; export * from "./icons"; diff --git a/js/react/showcase/App.tsx b/js/react/showcase/App.tsx index 89fe5ef..e600b74 100644 --- a/js/react/showcase/App.tsx +++ b/js/react/showcase/App.tsx @@ -14,6 +14,8 @@ import { DropdownState, Calendar, CalendarRangeDate, + Topic, + SubTopic, } from "@rustlanges/react"; import { ShowComponent } from "./ShowComponent"; import { useState } from "react"; @@ -279,6 +281,40 @@ export function App() { + + ); } diff --git a/styles/components.css b/styles/components.css index dc9ae68..fb78fe5 100644 --- a/styles/components.css +++ b/styles/components.css @@ -9,3 +9,4 @@ @import "./components/radio.css"; @import "./components/tag.css"; @import "./components/text.css"; +@import "./components/topic.css"; diff --git a/styles/components/topic.css b/styles/components/topic.css new file mode 100644 index 0000000..daaee30 --- /dev/null +++ b/styles/components/topic.css @@ -0,0 +1,35 @@ +@layer component { + .rustlanges-topic { + @apply w-full; + } + .rustlanges-topic[open] svg { + @apply -rotate-180; + } + + .rustlanges-topic__summary::-webkit-details-marker { + display: none; + } + + .rustlanges-topic__summary { + @apply grid w-full grid-cols-[auto_1fr_auto_auto] items-center gap-2 border-y border-black px-3 py-4; + + & > svg { + @apply duration-400 size-6 transition; + } + } + + .rustlanges-topic__title { + @apply text-neutral-950 dark:text-neutral-50; + } + + .rustlanges-subtopic { + @apply grid w-full grid-cols-[auto_1fr_auto] items-center gap-2 border-b px-6 py-2.5; + @apply border-b-gray dark:border-b-neutral-600; + } + + .rustlanges-subtopic__title { + @apply text-neutral-950; + @apply desktop:text-sm text-xs; + @apply dark:text-neutral-50; + } +}