← All proposals

Chat Input

A labelled textarea with a toolbar inside the same bordered box:

Net-new componentOpen in Storybook

proposals/ChatInput/chat-input.css107 lines · View on GitHub
/* The border, background and focus ring live on the field, not the textarea,
   so the toolbar sits inside the same box. Resizing also targets the field,
   which puts the drag handle in the bottom corner, below the toolbar. */
.pds-chat-input {
	--chat-input-padding: var(--pds-spacing-xs);
}

.pds-chat-input--m {
	--chat-input-padding: var(--pds-spacing-s);
}

.pds-chat-input__field {
	background-color: var(--pds-color-surface-default);
	border: var(--pds-border-width-default) solid var(--pds-color-border-input);
	border-radius: var(--pds-border-radius-input);
	display: flex;
	flex-direction: column;
	overflow: hidden;

	&:focus-within {
		outline: var(--pds-border-width-outline) solid
			var(--pds-color-interactive-focus);
		outline-offset: 0;
	}
}

/* Files dragged over the field: a dashed focus-colored border and a tinted
   background. The optional label sits over the field, so the pointer events
   pass through it and the drag counter stays accurate. */
.pds-chat-input__field {
	position: relative;
}

.pds-chat-input__field.pds-is-drag-over {
	background-color: var(--pds-color-interactive-background-hover);
	border-color: var(--pds-color-interactive-focus);
	border-style: dashed;
}

.pds-chat-input__drop-label {
	align-items: center;
	background-color: var(--pds-color-interactive-background-hover);
	color: var(--pds-color-foreground-default);
	display: flex;
	font-size: var(--pds-typography-size-s);
	inset: 0;
	justify-content: center;
	pointer-events: none;
	position: absolute;
	z-index: 1;
}

.pds-chat-input__field.pds-is-resizable {
	resize: vertical;
}

.pds-chat-input__textarea {
	background-color: transparent;
	border: 0;
	color: var(--pds-color-foreground-default);
	flex-grow: 1;
	font-family: var(--pds-typography-ff-default);
	font-size: var(--pds-typography-size-s);
	line-height: var(--pds-typography-lh-l);
	min-height: 0;
	outline: none;
	padding: var(--chat-input-padding);
	resize: none;

	&::placeholder {
		color: var(--pds-color-input-placeholder);
	}
}

.pds-chat-input__actions {
	align-items: center;
	display: flex;
	flex-shrink: 0;
	gap: var(--pds-spacing-s);
	justify-content: space-between;
	padding: var(--pds-spacing-2xs) var(--pds-spacing-xs) var(--pds-spacing-xs);
}

.pds-chat-input__actions-start,
.pds-chat-input__actions-end {
	align-items: center;
	display: flex;
	gap: var(--pds-spacing-2xs);
}

/* Compact: one row. The controls sit beside the text instead of under it.
   Keeps the standard input radius, like every other PDS field. */
.pds-chat-input--compact .pds-chat-input__field {
	align-items: center;
	flex-direction: row;
	gap: var(--pds-spacing-xs);
	padding: var(--pds-spacing-xs);
	resize: none;
}

.pds-chat-input--compact .pds-chat-input__textarea {
	flex: 1 1 0;
	min-width: 0;
	overflow: hidden;
	padding: 0 var(--pds-spacing-2xs);
}