# Chat Create a custom chat feed or AI prompt interface. ## Layout Columns Use Tailwind's [grid column](https://tailwindcss.com/docs/grid-template-columns) utility classes to define horizontal columns for your layout. ```html
(nav)
(feed)
(online)
``` ## Layout Rows Use Tailwind's [grid row](https://tailwindcss.com/docs/grid-template-rows) utility classes to define vertical layout rows for your layout. ```html
(search)
(list)
(footer)

(feed)

Lorem, ipsum dolor sit amet consectetur adipisicing elit. Reprehenderit dolor ullam, qui et itaque quam distinctio dicta nostrum veritatis harum iure hic sequi aperiam, explicabo earum totam deserunt. Fugiat, temporibus.

(prompt)
``` ## Message Feed The feed simply loops through the available feed data. Each `
` tag represents a single _bubble_ element.

```html
---
let messageFeed = [
	{
		id: 0,
		host: true,
		avatar: 48,
		name: 'Jane',
		timestamp: 'Yesterday @ 2:30pm',
		message: 'Some message text.',
		color: 'variant-soft-primary',
	},
	{
		id: 1,
		host: false,
		avatar: 14,
		name: 'Michael',
		timestamp: 'Yesterday @ 2:45pm',
		message: 'Some message text.',
		color: 'variant-soft-primary',
	},
];
---

{ messageFeed.map((bubble) => { // Determine if host/guest role const role = bubble.host === true ? 'host' : 'guest'; // Render the bubble template return
{JSON.stringify({ role, ...bubble }, null, 2)}
; }) }
``` ## Message Bubbles Provide styling to each bubble element. ```html --- let messageFeed = [ { id: 0, host: true, avatar: 48, name: 'Jane', timestamp: 'Yesterday @ 2:30pm', message: 'Some message text.', color: 'preset-tonal-primary', }, { id: 1, host: false, avatar: 14, name: 'Michael', timestamp: 'Yesterday @ 2:45pm', message: 'Some message text.', color: 'preset-tonal-primary', }, ]; ---
{ messageFeed.map((bubble) => { return ( <> {bubble.host ? ( // Host Bubble

{bubble.name}

{bubble.timestamp}

{bubble.message}

) : ( // Guest Bubble

{bubble.name}

{bubble.timestamp}

{bubble.message}

)} ); }) }
``` ## Prompt Use Skeleton's [input group](/docs/tailwind/forms#groups) styles to create a custom text prompt. --- ## Scroll to Bottom Bind your scrollable feed panel element reference ([Svelte](https://svelte.dev/docs/svelte/bind) | [React](https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom)), then use [scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTo) to scroll the panel to the bottom on demand. Scroll behavior can be set via `behavior: 'smooth'`. ```ts function scrollChatBottom(behavior?: 'auto' | 'instant' | 'smooth' = 'smooth') { // `elemChat` represents our scrollable panel element elemChat.scrollTo({ top: elemChat.scrollHeight, behavior }); } ``` ## Add a Message Below we'll cover how to append the message feed with a new message from the host user. Per our above examples, we'll use the same `messageFeed` data structure. ```ts let messageFeed = [ /* ...*/ ]; ``` Then bind to the textarea for your prompt in order to capture any message typed by the user. ```tsx let elemPrompt: HTMLElement = useRef(); ``` ```ts let elemPrompt: HTMLElement; ``` ```tsx