SGUI / Development
Select
Choose stable host option IDs using an accessible popup selector.
Loading examples…
Loading examples…
Examples
Loading examples…
Component documentation
SGUI / Development
Choose stable host option IDs using an accessible popup selector.
Loading examples…
Loading examples…
Loading examples…
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 { Select } from '@structured-growth/sg-ui/experimental';
import { Stack, Typography } from '@structured-growth/sg-ui/primitives';
export default function SelectPlaygroundExample() {
const [value, setValue] = useState<string | null>("design");
return (
<>
<ThemeScope density="comfortable">
<Stack gap={3}>
<Select 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." value={value} onValueChange={setValue} options={[{"id":"design","label":"Design systems"},{"id":"engineering","label":"Engineering"},{"id":"research","label":"Research"},{"id":"archived","label":"Archived course","disabled":true}]} placeholder="Choose a subject" 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 { Select } from '@structured-growth/sg-ui/experimental';
import { Stack, Typography } from '@structured-growth/sg-ui/primitives';
export default function SelectCompactExample() {
const [value, setValue] = useState<string | null>("design");
return (
<>
<ThemeScope density="compact">
<Stack gap={3}>
<Select 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." value={value} onValueChange={setValue} options={[{"id":"design","label":"Design systems"},{"id":"engineering","label":"Engineering"},{"id":"research","label":"Research"},{"id":"archived","label":"Archived course","disabled":true}]} placeholder="Choose a subject" 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 { Select } from '@structured-growth/sg-ui/experimental';
import { Stack, Typography } from '@structured-growth/sg-ui/primitives';
export default function SelectComfortableExample() {
const [value, setValue] = useState<string | null>("design");
return (
<>
<ThemeScope density="comfortable">
<Stack gap={3}>
<Select 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." value={value} onValueChange={setValue} options={[{"id":"design","label":"Design systems"},{"id":"engineering","label":"Engineering"},{"id":"research","label":"Research"},{"id":"archived","label":"Archived course","disabled":true}]} placeholder="Choose a subject" 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 { Select, Button } from '@structured-growth/sg-ui/experimental';
import { Stack, Typography } from '@structured-growth/sg-ui/primitives';
export default function SelectFormExample() {
const [value, setValue] = useState<string | null>("design");
const [submits, setSubmits] = useState(0);
return (
<>
<ThemeScope density="comfortable">
<form onSubmit={event => { event.preventDefault(); setSubmits(count => count + 1); }}>
<Stack gap={3}>
<Stack gap={3}>
<Select 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." value={value} onValueChange={setValue} options={[{"id":"design","label":"Design systems"},{"id":"engineering","label":"Engineering"},{"id":"research","label":"Research"},{"id":"archived","label":"Archived course","disabled":true}]} placeholder="Choose a subject" 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 {Select} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
export default function SelectcompactnoneExample() {
const options=[{"id":"design","label":"Design systems"},{"id":"research","label":"User research"},{"id":"engineering","label":"Engineering"}];
const [value,setValue]=useState<string|null>(null);
return (
<>
<ThemeScope density="compact">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<Select label="Course subject" placeholder="Choose a course subject" options={options} value={value} onValueChange={setValue}/>
</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 {Select} 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 SelectcompactstartExample() {
const options=[{"id":"design","label":"Design systems"},{"id":"research","label":"User research"},{"id":"engineering","label":"Engineering"}];
const [value,setValue]=useState<string|null>(null);
return (
<>
<ThemeScope density="compact">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<Select label="Course subject" placeholder="Choose a course subject" startIcon={<SearchIcon size={16}/>} options={options} value={value} onValueChange={setValue}/>
</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 {Select} 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 SelectcompactendExample() {
const options=[{"id":"design","label":"Design systems"},{"id":"research","label":"User research"},{"id":"engineering","label":"Engineering"}];
const [value,setValue]=useState<string|null>(null);
return (
<>
<ThemeScope density="compact">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<Select label="Course subject" placeholder="Choose a course subject" endIcon={<SchoolIcon size={16}/>} options={options} value={value} onValueChange={setValue}/>
</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 {Select} 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 SelectcompactbothExample() {
const options=[{"id":"design","label":"Design systems"},{"id":"research","label":"User research"},{"id":"engineering","label":"Engineering"}];
const [value,setValue]=useState<string|null>(null);
return (
<>
<ThemeScope density="compact">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<Select label="Course subject" placeholder="Choose a course subject" startIcon={<SearchIcon size={16}/>} endIcon={<SchoolIcon size={16}/>} options={options} value={value} onValueChange={setValue}/>
</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 {Select} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
export default function SelectcomfortablenoneExample() {
const options=[{"id":"design","label":"Design systems"},{"id":"research","label":"User research"},{"id":"engineering","label":"Engineering"}];
const [value,setValue]=useState<string|null>(null);
return (
<>
<ThemeScope density="comfortable">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<Select label="Course subject" placeholder="Choose a course subject" options={options} value={value} onValueChange={setValue}/>
</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 {Select} 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 SelectcomfortablestartExample() {
const options=[{"id":"design","label":"Design systems"},{"id":"research","label":"User research"},{"id":"engineering","label":"Engineering"}];
const [value,setValue]=useState<string|null>(null);
return (
<>
<ThemeScope density="comfortable">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<Select label="Course subject" placeholder="Choose a course subject" startIcon={<SearchIcon size={16}/>} options={options} value={value} onValueChange={setValue}/>
</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 {Select} 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 SelectcomfortableendExample() {
const options=[{"id":"design","label":"Design systems"},{"id":"research","label":"User research"},{"id":"engineering","label":"Engineering"}];
const [value,setValue]=useState<string|null>(null);
return (
<>
<ThemeScope density="comfortable">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<Select label="Course subject" placeholder="Choose a course subject" endIcon={<SchoolIcon size={16}/>} options={options} value={value} onValueChange={setValue}/>
</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 {Select} 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 SelectcomfortablebothExample() {
const options=[{"id":"design","label":"Design systems"},{"id":"research","label":"User research"},{"id":"engineering","label":"Engineering"}];
const [value,setValue]=useState<string|null>(null);
return (
<>
<ThemeScope density="comfortable">
<Box style={{inlineSize:'22rem',maxInlineSize:'100%'}}>
<Select label="Course subject" placeholder="Choose a course subject" startIcon={<SearchIcon size={16}/>} endIcon={<SchoolIcon size={16}/>} options={options} value={value} onValueChange={setValue}/>
</Box>
</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 { Select } from '@structured-growth/sg-ui/experimental';
import { Stack, Typography } from '@structured-growth/sg-ui/primitives';
export default function SelectCompactExample() {
const [value, setValue] = useState<string | null>("design");
return (
<>
<ThemeScope density="compact">
<Stack gap={3}>
<Select label={"Course subject"} disabled={false} readOnly={false} description={"Host-supplied course information."} descriptionPlacement="above" errorPlacement="above" required={false} invalid={true} errorMessage="Please review this value." value={value} onValueChange={setValue} options={[{"id":"design","label":"Design systems"},{"id":"engineering","label":"Engineering"},{"id":"research","label":"Research"},{"id":"archived","label":"Archived course","disabled":true}]} placeholder="Choose a subject" 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 { Select } from '@structured-growth/sg-ui/experimental';
import { Stack, Typography } from '@structured-growth/sg-ui/primitives';
export default function SelectCompactExample() {
const [value, setValue] = useState<string | null>("design");
return (
<>
<ThemeScope density="compact">
<Stack gap={3}>
<Select label={"Course subject"} disabled={false} readOnly={false} description={"Host-supplied course information."} descriptionPlacement="below" errorPlacement="below" required={false} invalid={true} errorMessage="Please review this value." value={value} onValueChange={setValue} options={[{"id":"design","label":"Design systems"},{"id":"engineering","label":"Engineering"},{"id":"research","label":"Research"},{"id":"archived","label":"Archived course","disabled":true}]} placeholder="Choose a subject" 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 { Select } from '@structured-growth/sg-ui/experimental';
import { Stack, Typography } from '@structured-growth/sg-ui/primitives';
export default function SelectComfortableExample() {
const [value, setValue] = useState<string | null>("design");
return (
<>
<ThemeScope density="comfortable">
<Stack gap={3}>
<Select label={"Course subject"} disabled={false} readOnly={false} description={"Host-supplied course information."} descriptionPlacement="above" errorPlacement="above" required={false} invalid={true} errorMessage="Please review this value." value={value} onValueChange={setValue} options={[{"id":"design","label":"Design systems"},{"id":"engineering","label":"Engineering"},{"id":"research","label":"Research"},{"id":"archived","label":"Archived course","disabled":true}]} placeholder="Choose a subject" 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 { Select } from '@structured-growth/sg-ui/experimental';
import { Stack, Typography } from '@structured-growth/sg-ui/primitives';
export default function SelectComfortableExample() {
const [value, setValue] = useState<string | null>("design");
return (
<>
<ThemeScope density="comfortable">
<Stack gap={3}>
<Select label={"Course subject"} disabled={false} readOnly={false} description={"Host-supplied course information."} descriptionPlacement="below" errorPlacement="below" required={false} invalid={true} errorMessage="Please review this value." value={value} onValueChange={setValue} options={[{"id":"design","label":"Design systems"},{"id":"engineering","label":"Engineering"},{"id":"research","label":"Research"},{"id":"archived","label":"Archived course","disabled":true}]} placeholder="Choose a subject" name="subject" />
</Stack>
</ThemeScope>
</>
);
}