Card compact and expanded template

This commit is contained in:
adilallo
2026-02-11 22:02:10 -07:00
parent f60df15c2b
commit b2ed1d438c
44 changed files with 1920 additions and 48 deletions
@@ -4,7 +4,7 @@ import { memo, forwardRef } from "react";
import { useComponentId, useFormField } from "../../../hooks";
import { TextAreaView } from "./TextArea.view";
import type { TextAreaProps } from "./TextArea.types";
import { normalizeInputState, normalizeSmallMediumLargeSize, normalizeLabelVariant } from "../../../../lib/propNormalization";
import { normalizeInputState, normalizeSmallMediumLargeSize, normalizeLabelVariant, normalizeTextAreaAppearance } from "../../../../lib/propNormalization";
const TextAreaContainer = forwardRef<HTMLTextAreaElement, TextAreaProps>(
(
@@ -27,6 +27,7 @@ const TextAreaContainer = forwardRef<HTMLTextAreaElement, TextAreaProps>(
textHint = false,
formHeader = true,
showHelpIcon = false,
appearance: appearanceProp = "default",
...props
},
ref,
@@ -35,6 +36,7 @@ const TextAreaContainer = forwardRef<HTMLTextAreaElement, TextAreaProps>(
const size = normalizeSmallMediumLargeSize(sizeProp);
const labelVariant = normalizeLabelVariant(labelVariantProp);
const state = normalizeInputState(stateProp);
const appearance = normalizeTextAreaAppearance(appearanceProp);
// Generate unique ID for accessibility if not provided
const { id: textareaId, labelId } = useComponentId("textarea", id);
@@ -74,11 +76,26 @@ const TextAreaContainer = forwardRef<HTMLTextAreaElement, TextAreaProps>(
},
};
// State styles
// State styles (embedded: Figma 20736-12668 borderless, darker grey block, white text)
const getStateStyles = (): {
textarea: string;
label: string;
} => {
if (appearance === "embedded") {
if (disabled) {
return {
textarea:
"border-0 bg-[var(--color-surface-default-secondary)] text-[var(--color-content-default-primary)] cursor-not-allowed opacity-60",
label: "text-[var(--color-content-default-secondary)]",
};
}
return {
textarea:
"border-0 bg-[var(--color-surface-default-secondary)] text-[var(--color-content-default-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-border-default-tertiary)] focus:ring-inset",
label: "text-[var(--color-content-default-secondary)]",
};
}
if (disabled) {
return {
textarea:
@@ -138,8 +155,8 @@ const TextAreaContainer = forwardRef<HTMLTextAreaElement, TextAreaProps>(
: `${currentSize.label} font-inter`;
const textareaClasses = `
w-full border transition-all duration-200 ease-in-out
focus:outline-none focus:ring-0 resize-none
scrollbar-design w-full transition-all duration-200 ease-in-out resize-none
${appearance === "embedded" ? "rounded-[var(--radius-300,12px)]" : "border"}
${currentSize.textarea}
${stateStyles.textarea}
${className}
@@ -180,6 +197,7 @@ const TextAreaContainer = forwardRef<HTMLTextAreaElement, TextAreaProps>(
textHint={textHint}
formHeader={formHeader}
showHelpIcon={showHelpIcon}
appearance={appearance}
{...props}
/>
);
@@ -3,6 +3,8 @@ import type { InputStateValue } from "../../../../lib/propNormalization";
export type TextAreaSizeValue = "small" | "medium" | "large" | "Small" | "Medium" | "Large";
export type TextAreaLabelVariantValue = "default" | "horizontal" | "Default" | "Horizontal";
export type TextAreaAppearanceValue = "default" | "embedded" | "Default" | "Embedded";
export interface TextAreaProps extends Omit<
React.TextareaHTMLAttributes<HTMLTextAreaElement>,
"size" | "onChange" | "onFocus" | "onBlur"
@@ -47,6 +49,12 @@ export interface TextAreaProps extends Omit<
* @default false
*/
showHelpIcon?: boolean;
/**
* Visual appearance. "embedded" matches Create modal sections (Figma 20736-12668):
* borderless, darker grey background, white text. "default" is standard bordered input.
* @default "default"
*/
appearance?: TextAreaAppearanceValue;
}
export interface TextAreaViewProps {
@@ -73,4 +81,5 @@ export interface TextAreaViewProps {
textHint?: boolean;
formHeader?: boolean;
showHelpIcon?: boolean;
appearance?: "default" | "embedded";
}
@@ -24,6 +24,12 @@ export const TextAreaView = forwardRef<HTMLTextAreaElement, TextAreaViewProps>(
textHint = false,
formHeader = true,
showHelpIcon = false,
appearance: _appearance,
// Component-only props: do not pass to DOM
size: _size,
labelVariant: _labelVariant,
state: _state,
error: _error,
...props
},
ref,