Channel Topic Bar
A header bar showing the channel name and a truncating topic description.
A header bar showing the channel name and a truncating topic description. Compose it from the exported registry parts so local content and behaviour stay in the application while the visual contract stays token-driven.
newt-channel-topicimport {
ChannelTopic,
ChannelTopicDescription,
ChannelTopicDivider,
ChannelTopicIcon,
ChannelTopicName,
} from "@/registry/bases/newt/ui/channel-topic"
export default function ChannelTopicDemo() {
return (
<ChannelTopic className="w-full max-w-md">
<ChannelTopicIcon />
<ChannelTopicName>channel-name</ChannelTopicName>
<ChannelTopicDivider />
<ChannelTopicDescription>
Channel topic description goes here
</ChannelTopicDescription>
</ChannelTopic>
)
}<script setup lang="ts">
import {
ChannelTopic,
ChannelTopicDescription,
ChannelTopicDivider,
ChannelTopicIcon,
ChannelTopicName,
} from "~~/registry/bases/newt/ui/channel-topic"
</script>
<template>
<ChannelTopic class="w-full max-w-md">
<ChannelTopicIcon />
<ChannelTopicName>channel-name</ChannelTopicName>
<ChannelTopicDivider />
<ChannelTopicDescription
>Channel topic description goes here</ChannelTopicDescription
>
</ChannelTopic>
</template>Installation
pnpm dlx newtui@latest add channel-topicnpx newtui@latest add channel-topicyarn dlx newtui@latest add channel-topicbunx newtui@latest add channel-topicCopy the source into your project
import * as React from "react"
import { cn } from "@/lib/utils"
const ChannelTopic = React.forwardRef<
HTMLDivElement,
React.ComponentProps<"div">
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"flex min-w-0 items-center gap-2 border-b border-newt-border px-4 py-3 text-sm",
className
)}
{...props}
/>
))
ChannelTopic.displayName = "ChannelTopic"
const ChannelTopicIcon = React.forwardRef<
HTMLSpanElement,
React.ComponentProps<"span">
>(({ className, children = "#", ...props }, ref) => (
<span
ref={ref}
aria-hidden="true"
className={cn("shrink-0 font-bold text-newt-text-muted", className)}
{...props}
>
{children}
</span>
))
ChannelTopicIcon.displayName = "ChannelTopicIcon"
const ChannelTopicName = React.forwardRef<
HTMLSpanElement,
React.ComponentProps<"span">
>(({ className, ...props }, ref) => (
<span
ref={ref}
className={cn(
"shrink-0 whitespace-nowrap font-bold text-newt-text-primary",
className
)}
{...props}
/>
))
ChannelTopicName.displayName = "ChannelTopicName"
const ChannelTopicDivider = React.forwardRef<
HTMLSpanElement,
React.ComponentProps<"span">
>(({ className, ...props }, ref) => (
<span
ref={ref}
aria-hidden="true"
className={cn("h-[18px] w-px shrink-0 bg-newt-border", className)}
{...props}
/>
))
ChannelTopicDivider.displayName = "ChannelTopicDivider"
const ChannelTopicDescription = React.forwardRef<
HTMLSpanElement,
React.ComponentProps<"span">
>(({ className, ...props }, ref) => (
<span
ref={ref}
className={cn(
"overflow-hidden text-ellipsis whitespace-nowrap text-[13px] text-newt-text-muted",
className
)}
{...props}
/>
))
ChannelTopicDescription.displayName = "ChannelTopicDescription"
export {
ChannelTopic,
ChannelTopicIcon,
ChannelTopicName,
ChannelTopicDivider,
ChannelTopicDescription,
}<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<{ class?: HTMLAttributes["class"] }>()
</script>
<template>
<div
:class="
cn(
'flex min-w-0 items-center gap-2 border-b border-newt-border px-4 py-3 text-sm',
props.class
)
"
>
<slot />
</div>
</template><script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<{ class?: HTMLAttributes["class"] }>()
</script>
<template>
<span
aria-hidden="true"
:class="cn('shrink-0 font-bold text-newt-text-muted', props.class)"
>
<slot>#</slot>
</span>
</template><script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<{ class?: HTMLAttributes["class"] }>()
</script>
<template>
<span
:class="
cn(
'shrink-0 whitespace-nowrap font-bold text-newt-text-primary',
props.class
)
"
>
<slot />
</span>
</template><script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<{ class?: HTMLAttributes["class"] }>()
</script>
<template>
<span
aria-hidden="true"
:class="cn('h-[18px] w-px shrink-0 bg-newt-border', props.class)"
/>
</template><script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<{ class?: HTMLAttributes["class"] }>()
</script>
<template>
<span
:class="
cn(
'overflow-hidden text-ellipsis whitespace-nowrap text-[13px] text-newt-text-muted',
props.class
)
"
>
<slot />
</span>
</template>export { default as ChannelTopic } from "./ChannelTopic.vue"
export { default as ChannelTopicIcon } from "./ChannelTopicIcon.vue"
export { default as ChannelTopicName } from "./ChannelTopicName.vue"
export { default as ChannelTopicDivider } from "./ChannelTopicDivider.vue"
export { default as ChannelTopicDescription } from "./ChannelTopicDescription.vue"Update the import paths
The files import @/lib/utils and sibling components through the aliases in your components.json. Point them at wherever those live in your project.
Usage
import { ChannelTopic } from "@/components/ui/channel-topic"
export function Example() {
return <ChannelTopic />
}<script setup lang="ts">
import { ChannelTopic, ChannelTopicIcon, ChannelTopicName, ChannelTopicDivider, ChannelTopicDescription } from "@/components/ui/channel-topic"
</script>
<template>
<ChannelTopic />
</template>API reference
ChannelTopic
children / default slot?React.ReactNode / Vue slot
Content rendered inside the component.
React.ReactNode / Vue slotclassName / class?string
Additional classes merged with the component defaults.
stringThe registry exports ChannelTopic, ChannelTopicIcon, ChannelTopicName, ChannelTopicDivider, ChannelTopicDescription. Parts without a table accept the native attributes for the element they render; React uses className, while Vue uses class and fallthrough attributes.
Accessibility
Preserve the native semantics of the rendered elements and pass through ARIA attributes when the surrounding context needs a label or description. Any interactive child needs a visible focus indicator, and meaning must not rely on colour alone.
Tokens
Channel Topic Bar reads its colours, radii and motion from the --newt-* tokens installed with the library. Override a token and every component that reads it follows, including this one — see the token layer. In the plain HTML and CSS distribution the same component is newt-channel-topic.