Skip to content

Instantly share code, notes, and snippets.

@stanlrt
Last active July 16, 2024 15:29
Show Gist options
  • Save stanlrt/e355e9ffcf8311088ed70df618ec512b to your computer and use it in GitHub Desktop.
Save stanlrt/e355e9ffcf8311088ed70df618ec512b to your computer and use it in GitHub Desktop.
[data-scope="select"] {
&[data-part="root"] {
display: flex;
flex-direction: column;
gap: 8px;
}
&[data-part="label"] {
width: 100%;
text-align: center;
text-transform: uppercase;
color: var(--rq-theme--colour-fg-medium);
/* TODO migrate to SCSS and use @extend from typography.scss */
margin: 0;
font-size: 0.75rem;
font-family: var(--rq-core--typo-family-body);
line-height: var(--rq-core--typo-line-height-body);
letter-spacing: var(--rq-core--typo-letter-spacing-body);
font-weight: 700;
}
&[data-part="trigger"] {
display: flex;
align-items: center;
justify-content: center;
padding-inline-start: 16px;
gap: 4px;
height: 32px;
border-radius: 999px;
border: 1.4px solid var(--rq-theme--colour-fg-medium);
background-color: transparent;
color: var(--rq-theme--colour-fg-strong);
cursor: pointer;
/* TODO migrate to SCSS and use @extend from typography.scss */
margin: 0;
font-size: 1rem;
font-family: var(--rq-core--typo-family-body);
line-height: var(--rq-core--typo-line-height-body);
letter-spacing: var(--rq-core--typo-letter-spacing-body);
font-weight: 500;
[data-part="indicator"] {
transition: transform 0.25s ease-in-out;
&[data-state="open"] {
transform: rotate(180deg);
}
}
}
&[data-part="positioner"] {
[data-part="content"] {
background-color: var(--rq-theme--colour-bg);
border: 1.4px solid var(--rq-theme--colour-fg-medium);
border-radius: 8px;
padding: 4px;
[data-part="item"] {
display: flex;
align-items: center;
justify-content: start;
gap: 8px;
padding: 4px;
border-radius: 4px;
cursor: pointer;
[data-disabled] {
opacity: var(--rq-semantic--opacity-disabled);
cursor: not-allowed;
}
&:not([data-disabled]):hover {
background-color: var(--rq-theme--colour-fg-light);
}
[data-part="item-text"] {
color: var(--rq-theme--colour-fg-strong);
/* TODO migrate to SCSS and use @extend from typography.scss */
font-size: 1rem;
font-family: var(--rq-core--typo-family-body);
line-height: var(--rq-core--typo-line-height-body);
letter-spacing: var(--rq-core--typo-letter-spacing-body);
font-weight: 500;
}
}
}
}
}
import { Select as ArkSelect } from "@ark-ui/solid";
import { Index, Show } from "solid-js";
import { Portal } from "solid-js/web";
import { LocalThemeProvider, useLocalTheme } from "../../theme/LocalTheme.tsx";
import { Icon } from "../icon/Icon.tsx";
import "./select.css";
// type SelectProps<ItemType extends ArkSelect.CollectionItem> =
// ArkSelect.RootProps<ItemType>;
type SelectProps = {
/** The items to display in the select. */
items: {
value: string;
label: string;
disabled?: boolean;
}[];
/** The placeholder to display in the select. */
placeholder?: string;
/** The label to display in the select. */
label?: string;
/** The default value to display in the select. */
defaultValue?: string[];
} & (
| { placeholder: string; defaultValue?: never }
| { placeholder?: never; defaultValue: string[] }
);
/**
* A select component, which allows the user to select items from a list.
*
* data-scope: "select"
*
* @example
* ```tsx
* <Select items={[{ value: "react", label: "React" }, { value: "vue", label: "Vue", disabled: true }]} />
* ```
*/
export function Select(props: SelectProps) {
//TODO add other parts (clear trigger, item groups...)
return (
<ArkSelect.Root
positioning={{ sameWidth: true }}
items={props.items}
data-scope="select"
defaultValue={props.defaultValue}
>
<Show when={props.label}>
<ArkSelect.Label>{props.label}</ArkSelect.Label>
</Show>
<ArkSelect.Control>
<ArkSelect.Trigger>
<ArkSelect.ValueText placeholder={props.placeholder} />
<ArkSelect.Indicator>
<Icon
name="arrow_drop_down"
size={new CSSUnitValue(32, "px")}
/>
</ArkSelect.Indicator>
</ArkSelect.Trigger>
</ArkSelect.Control>
<Portal>
<ArkSelect.Positioner>
<ArkSelect.Content>
<Index each={props.items}>
{(item) => (
<ArkSelect.Item item={item()}>
<ArkSelect.ItemText>
{item().label}
</ArkSelect.ItemText>
<ArkSelect.ItemIndicator>
<Icon
name="check"
size={
new CSSUnitValue(20, "px")
}
/>
</ArkSelect.ItemIndicator>
</ArkSelect.Item>
)}
</Index>
</ArkSelect.Content>
</ArkSelect.Positioner>
</Portal>
<ArkSelect.HiddenSelect />
</ArkSelect.Root>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment