Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions packages/react-drylus/src/forms/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ const styles = {
color: ${sv.colorSecondary};
}
`,
customValue: css`
position: absolute;
top: 50%;
left: ${sv.marginExtraSmall};
transform: translateY(-50%);
z-index: 999;
`,
};

export interface SelectOption<T> extends Option<T> {
Expand Down Expand Up @@ -133,6 +140,9 @@ export interface SelectProps<T> {
/** If true, a spinner is shown in the right corner, like with error and valid */
loading?: boolean;

/** Used to render custom content within the select e.g. a Tag */
renderLabel?: (v: SelectOption<T>['label']) => T;

/** Used for style overrides */
style?: Style;

Expand All @@ -155,6 +165,7 @@ export const Select = <T extends any>({ responsive, ...rest }: SelectProps<T>) =
valid,
loading,
style,
renderLabel,
...props
} = useResponsiveProps<SelectProps<T>>(rest, responsive);

Expand Down Expand Up @@ -200,17 +211,19 @@ export const Select = <T extends any>({ responsive, ...rest }: SelectProps<T>) =
);
}
})}
{value != null && renderLabel != null ? (
<div className={styles.customValue}>
{renderLabel(options.find((o) => o.value === value)?.label ?? '')}
</div>
) : null}
<select
disabled={disabled}
className={styles.select}
value={value}
onChange={handleOnChange}
style={renderLabel && value != null ? { color: 'transparent' } : undefined}
{...props}>
{run(() => {
if (!value) {
return <option key={options.length}>{placeholder}</option>;
}
})}
{value == null ? <option key={options.length}>{placeholder}</option> : null}
{options.map((option) => (
<option key={option.value} value={option.value} disabled={option.disabled}>
{option.label}
Expand Down
22 changes: 21 additions & 1 deletion packages/styleguide/app/pages/component-kit/forms/select.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Select } from '@drawbotics/react-drylus';
import { Select, Tag, Color } from '@drawbotics/react-drylus';

import Playground from '~/components/Playground';
import { ControlledField } from '../utils';
Expand Down Expand Up @@ -27,3 +27,23 @@ __Example__
}]} />
} />
</Playground>

### Example with custom label
If you're selecting between options currently represented elsewhere in the UI with another component, you can display that component on top of the `Select` if necessary. Please note that the custom value is overlayed absolutely on top, so it's your job to make sure it doesn't overflow.
<Playground mode="jsx">
<ControlledField initialValue="BE" style={{ maxWidth: 250 }} component={
<Select
renderLabel={(label) => <Tag color={Color.BLUE}>{label}</Tag>}
placeholder="Select an option..."
options={[{
label: 'Belgium',
value: 'BE',
}, {
label: 'France',
value: 'FR',
}, {
label: 'Italy',
value: 'IT',
}]} />
} />
</Playground>