SGUI / Development
TextArea
Multiline content, configurable rows, descriptions and native form participation.
Loading examples…
Loading examples…
Examples
Loading examples…
Contains
No fixed SGUI child components.
Component documentation
SGUI / Development
Multiline content, configurable rows, descriptions and native form participation.
Loading examples…
Loading examples…
Loading examples…
No fixed SGUI child components.
Adjust the public props, then interact with the preview. Source follows the current state.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import { TextArea } from '@structured-growth/sg-ui/experimental';
import { Stack, Typography } from '@structured-growth/sg-ui/primitives';
export default function TextAreaPlaygroundExample() {
const [value, setValue] = useState("Design systems");
return (
<>
<ThemeScope density="comfortable">
<Stack gap={3}>
<TextArea label={"Course subject"} disabled={false} readOnly={false} description={"Host-supplied course information."} descriptionPlacement="above" errorPlacement="below" required={false} invalid={false} errorMessage="Please review this value." rows={3} value={value} onValueChange={setValue} placeholder="Search course subjects" name="subject" />
</Stack>
</ThemeScope>
</>
);
}
An independent scope demonstrates the inherited spacing and interaction targets.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import { TextArea } from '@structured-growth/sg-ui/experimental';
import { Stack, Typography } from '@structured-growth/sg-ui/primitives';
export default function TextAreaCompactExample() {
const [value, setValue] = useState("Design systems");
return (
<>
<ThemeScope density="compact">
<Stack gap={3}>
<TextArea label={"Course subject"} disabled={false} readOnly={false} description={"Host-supplied course information."} descriptionPlacement="above" errorPlacement="below" required={false} invalid={false} errorMessage="Please review this value." rows={3} value={value} onValueChange={setValue} placeholder="Search course subjects" name="subject" />
</Stack>
</ThemeScope>
</>
);
}
An independent scope demonstrates the inherited spacing and interaction targets.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import { TextArea } from '@structured-growth/sg-ui/experimental';
import { Stack, Typography } from '@structured-growth/sg-ui/primitives';
export default function TextAreaComfortableExample() {
const [value, setValue] = useState("Design systems");
return (
<>
<ThemeScope density="comfortable">
<Stack gap={3}>
<TextArea label={"Course subject"} disabled={false} readOnly={false} description={"Host-supplied course information."} descriptionPlacement="above" errorPlacement="below" required={false} invalid={false} errorMessage="Please review this value." rows={3} value={value} onValueChange={setValue} placeholder="Search course subjects" name="subject" />
</Stack>
</ThemeScope>
</>
);
}
Callbacks update local host state. No backend persistence is implied.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import { TextArea, Button } from '@structured-growth/sg-ui/experimental';
import { Stack, Typography } from '@structured-growth/sg-ui/primitives';
export default function TextAreaFormExample() {
const [value, setValue] = useState("Design systems");
const [submits, setSubmits] = useState(0);
return (
<>
<ThemeScope density="comfortable">
<form onSubmit={event => { event.preventDefault(); setSubmits(count => count + 1); }}>
<Stack gap={3}>
<Stack gap={3}>
<TextArea label={"Course subject"} disabled={false} readOnly={false} description={"Host-supplied course information."} descriptionPlacement="above" errorPlacement="below" required={true} invalid={false} errorMessage="Please review this value." rows={3} value={value} onValueChange={setValue} placeholder="Search course subjects" name="subject" />
</Stack>
<Button type="submit">Save locally</Button>
<Typography role="status">Submitted {submits} times. Connect persistence in your host.</Typography>
</Stack>
</form>
</ThemeScope>
</>
);
}
This field starts empty so its placeholder is visible. The icons are decorative and follow the text direction; they add no tab stops. The visible label remains the accessible name. Selection controls keep their dropdown action; fetching and search results belong to the host.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {TextArea} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
export default function TextAreacompactnoneExample() {
const [text,setText]=useState("");
return (
<>
<ThemeScope density="compact">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<TextArea label="Course subject" placeholder="Search course subjects" rows={3} value={text} onValueChange={setText}/>
</Box>
</ThemeScope>
</>
);
}
This field starts empty so its placeholder is visible. The icons are decorative and follow the text direction; they add no tab stops. The visible label remains the accessible name. Selection controls keep their dropdown action; fetching and search results belong to the host.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {TextArea} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
import {SearchIcon} from '@structured-growth/sg-ui/icons';
export default function TextAreacompactstartExample() {
const [text,setText]=useState("");
return (
<>
<ThemeScope density="compact">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<TextArea label="Course subject" placeholder="Search course subjects" startIcon={<SearchIcon size={16}/>} rows={3} value={text} onValueChange={setText}/>
</Box>
</ThemeScope>
</>
);
}
This field starts empty so its placeholder is visible. The icons are decorative and follow the text direction; they add no tab stops. The visible label remains the accessible name. Selection controls keep their dropdown action; fetching and search results belong to the host.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {TextArea} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
import {SchoolIcon} from '@structured-growth/sg-ui/icons';
export default function TextAreacompactendExample() {
const [text,setText]=useState("");
return (
<>
<ThemeScope density="compact">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<TextArea label="Course subject" placeholder="Search course subjects" endIcon={<SchoolIcon size={16}/>} rows={3} value={text} onValueChange={setText}/>
</Box>
</ThemeScope>
</>
);
}
This field starts empty so its placeholder is visible. The icons are decorative and follow the text direction; they add no tab stops. The visible label remains the accessible name. Selection controls keep their dropdown action; fetching and search results belong to the host.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {TextArea} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
import {SearchIcon,SchoolIcon} from '@structured-growth/sg-ui/icons';
export default function TextAreacompactbothExample() {
const [text,setText]=useState("");
return (
<>
<ThemeScope density="compact">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<TextArea label="Course subject" placeholder="Search course subjects" startIcon={<SearchIcon size={16}/>} endIcon={<SchoolIcon size={16}/>} rows={3} value={text} onValueChange={setText}/>
</Box>
</ThemeScope>
</>
);
}
This field starts empty so its placeholder is visible. The icons are decorative and follow the text direction; they add no tab stops. The visible label remains the accessible name. Selection controls keep their dropdown action; fetching and search results belong to the host.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {TextArea} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
export default function TextAreacomfortablenoneExample() {
const [text,setText]=useState("");
return (
<>
<ThemeScope density="comfortable">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<TextArea label="Course subject" placeholder="Search course subjects" rows={3} value={text} onValueChange={setText}/>
</Box>
</ThemeScope>
</>
);
}
This field starts empty so its placeholder is visible. The icons are decorative and follow the text direction; they add no tab stops. The visible label remains the accessible name. Selection controls keep their dropdown action; fetching and search results belong to the host.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {TextArea} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
import {SearchIcon} from '@structured-growth/sg-ui/icons';
export default function TextAreacomfortablestartExample() {
const [text,setText]=useState("");
return (
<>
<ThemeScope density="comfortable">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<TextArea label="Course subject" placeholder="Search course subjects" startIcon={<SearchIcon size={16}/>} rows={3} value={text} onValueChange={setText}/>
</Box>
</ThemeScope>
</>
);
}
This field starts empty so its placeholder is visible. The icons are decorative and follow the text direction; they add no tab stops. The visible label remains the accessible name. Selection controls keep their dropdown action; fetching and search results belong to the host.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {TextArea} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
import {SchoolIcon} from '@structured-growth/sg-ui/icons';
export default function TextAreacomfortableendExample() {
const [text,setText]=useState("");
return (
<>
<ThemeScope density="comfortable">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<TextArea label="Course subject" placeholder="Search course subjects" endIcon={<SchoolIcon size={16}/>} rows={3} value={text} onValueChange={setText}/>
</Box>
</ThemeScope>
</>
);
}
This field starts empty so its placeholder is visible. The icons are decorative and follow the text direction; they add no tab stops. The visible label remains the accessible name. Selection controls keep their dropdown action; fetching and search results belong to the host.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {TextArea} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
import {SearchIcon,SchoolIcon} from '@structured-growth/sg-ui/icons';
export default function TextAreacomfortablebothExample() {
const [text,setText]=useState("");
return (
<>
<ThemeScope density="comfortable">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<TextArea label="Course subject" placeholder="Search course subjects" startIcon={<SearchIcon size={16}/>} endIcon={<SchoolIcon size={16}/>} rows={3} value={text} onValueChange={setText}/>
</Box>
</ThemeScope>
</>
);
}
Descriptions and validation messages precede the input. The row aligns fields at their lower edge so inputs line up despite different message heights.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {TextArea} from '@structured-growth/sg-ui/experimental';
import {Box,Stack} from '@structured-growth/sg-ui/primitives';
export default function FieldMessagesExample() {
const [values,setValues]=useState(["Design systems","Design systems curriculum","DS-101"]);
return (
<>
<ThemeScope density="compact">
<Stack direction="row" wrap align="end" gap={4}>
<Box style={{inlineSize:'14rem',maxInlineSize:'100%'}}>
<TextArea label={"Display name"} description={"Shown in the course list."} descriptionPlacement="above" errorPlacement="above" value={values[0]} onValueChange={value=>setValues(current=>current.map((item,index)=>index===0?value:item))}/>
</Box>
<Box style={{inlineSize:'14rem',maxInlineSize:'100%'}}>
<TextArea label={"Internal name"} description={"Use a name people recognize when browsing courses and reports."} descriptionPlacement="above" errorPlacement="above" value={values[1]} onValueChange={value=>setValues(current=>current.map((item,index)=>index===1?value:item))}/>
</Box>
<Box style={{inlineSize:'14rem',maxInlineSize:'100%'}}>
<TextArea label={"Reference code"} description={"A code for this course."} descriptionPlacement="above" errorPlacement="above" invalid errorMessage="Use a unique reference code." value={values[2]} onValueChange={value=>setValues(current=>current.map((item,index)=>index===2?value:item))}/>
</Box>
</Stack>
</ThemeScope>
</>
);
}
Descriptions and validation messages follow the input. The row aligns fields at their upper edge.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {TextArea} from '@structured-growth/sg-ui/experimental';
import {Box,Stack} from '@structured-growth/sg-ui/primitives';
export default function FieldMessagesExample() {
const [values,setValues]=useState(["Design systems","Design systems curriculum","DS-101"]);
return (
<>
<ThemeScope density="compact">
<Stack direction="row" wrap align="start" gap={4}>
<Box style={{inlineSize:'14rem',maxInlineSize:'100%'}}>
<TextArea label={"Display name"} description={"Shown in the course list."} descriptionPlacement="below" errorPlacement="below" value={values[0]} onValueChange={value=>setValues(current=>current.map((item,index)=>index===0?value:item))}/>
</Box>
<Box style={{inlineSize:'14rem',maxInlineSize:'100%'}}>
<TextArea label={"Internal name"} description={"Use a name people recognize when browsing courses and reports."} descriptionPlacement="below" errorPlacement="below" value={values[1]} onValueChange={value=>setValues(current=>current.map((item,index)=>index===1?value:item))}/>
</Box>
<Box style={{inlineSize:'14rem',maxInlineSize:'100%'}}>
<TextArea label={"Reference code"} description={"A code for this course."} descriptionPlacement="below" errorPlacement="below" invalid errorMessage="Use a unique reference code." value={values[2]} onValueChange={value=>setValues(current=>current.map((item,index)=>index===2?value:item))}/>
</Box>
</Stack>
</ThemeScope>
</>
);
}
Descriptions and validation messages precede the input. The row aligns fields at their lower edge so inputs line up despite different message heights.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {TextArea} from '@structured-growth/sg-ui/experimental';
import {Box,Stack} from '@structured-growth/sg-ui/primitives';
export default function FieldMessagesExample() {
const [values,setValues]=useState(["Design systems","Design systems curriculum","DS-101"]);
return (
<>
<ThemeScope density="comfortable">
<Stack direction="row" wrap align="end" gap={4}>
<Box style={{inlineSize:'14rem',maxInlineSize:'100%'}}>
<TextArea label={"Display name"} description={"Shown in the course list."} descriptionPlacement="above" errorPlacement="above" value={values[0]} onValueChange={value=>setValues(current=>current.map((item,index)=>index===0?value:item))}/>
</Box>
<Box style={{inlineSize:'14rem',maxInlineSize:'100%'}}>
<TextArea label={"Internal name"} description={"Use a name people recognize when browsing courses and reports."} descriptionPlacement="above" errorPlacement="above" value={values[1]} onValueChange={value=>setValues(current=>current.map((item,index)=>index===1?value:item))}/>
</Box>
<Box style={{inlineSize:'14rem',maxInlineSize:'100%'}}>
<TextArea label={"Reference code"} description={"A code for this course."} descriptionPlacement="above" errorPlacement="above" invalid errorMessage="Use a unique reference code." value={values[2]} onValueChange={value=>setValues(current=>current.map((item,index)=>index===2?value:item))}/>
</Box>
</Stack>
</ThemeScope>
</>
);
}
Descriptions and validation messages follow the input. The row aligns fields at their upper edge.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {TextArea} from '@structured-growth/sg-ui/experimental';
import {Box,Stack} from '@structured-growth/sg-ui/primitives';
export default function FieldMessagesExample() {
const [values,setValues]=useState(["Design systems","Design systems curriculum","DS-101"]);
return (
<>
<ThemeScope density="comfortable">
<Stack direction="row" wrap align="start" gap={4}>
<Box style={{inlineSize:'14rem',maxInlineSize:'100%'}}>
<TextArea label={"Display name"} description={"Shown in the course list."} descriptionPlacement="below" errorPlacement="below" value={values[0]} onValueChange={value=>setValues(current=>current.map((item,index)=>index===0?value:item))}/>
</Box>
<Box style={{inlineSize:'14rem',maxInlineSize:'100%'}}>
<TextArea label={"Internal name"} description={"Use a name people recognize when browsing courses and reports."} descriptionPlacement="below" errorPlacement="below" value={values[1]} onValueChange={value=>setValues(current=>current.map((item,index)=>index===1?value:item))}/>
</Box>
<Box style={{inlineSize:'14rem',maxInlineSize:'100%'}}>
<TextArea label={"Reference code"} description={"A code for this course."} descriptionPlacement="below" errorPlacement="below" invalid errorMessage="Use a unique reference code." value={values[2]} onValueChange={value=>setValues(current=>current.map((item,index)=>index===2?value:item))}/>
</Box>
</Stack>
</ThemeScope>
</>
);
}