Skip to content

Commit

Permalink
Add classNames API
Browse files Browse the repository at this point in the history
  • Loading branch information
nderkim authored and dcousens committed Nov 16, 2022
1 parent 5f52869 commit 5d960cc
Show file tree
Hide file tree
Showing 16 changed files with 279 additions and 279 deletions.
2 changes: 2 additions & 0 deletions docs/examples/Experimental.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ const Group = (props: GroupProps<DateOption, false>) => {
const {
Heading,
getStyles,
getClassName,
children,
label,
headingProps,
Expand All @@ -136,6 +137,7 @@ const Group = (props: GroupProps<DateOption, false>) => {
selectProps={selectProps}
theme={theme}
getStyles={getStyles}
getClassName={getClassName}
cx={cx}
{...headingProps}
>
Expand Down
18 changes: 17 additions & 1 deletion packages/react-select/src/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ import {

import { defaultComponents, SelectComponentsConfig } from './components/index';

import { defaultStyles, StylesConfig, StylesProps } from './styles';
import {
ClassNamesConfig,
defaultStyles,
StylesConfig,
StylesProps,
} from './styles';
import { defaultTheme, ThemeConfig } from './theme';

import {
Expand Down Expand Up @@ -99,6 +104,10 @@ export interface Props<
* This is useful when styling via CSS classes instead of the Styles API approach.
*/
classNamePrefix?: string | null;
/**
* Provide a className based on state for each inner component
*/
classNames: ClassNamesConfig<Option, IsMulti, Group>;
/** Close the select menu when the user selects an option */
closeMenuOnSelect: boolean;
/**
Expand Down Expand Up @@ -271,6 +280,7 @@ export const defaultProps = {
backspaceRemovesValue: true,
blurInputOnSelect: isTouchCapable(),
captureMenuScroll: !isTouchCapable(),
classNames: {},
closeMenuOnSelect: true,
closeMenuOnScroll: false,
components: {},
Expand Down Expand Up @@ -1046,6 +1056,7 @@ export default class Select<
clearValue,
cx,
getStyles,
getClassName,
getValue,
selectOption,
setValue,
Expand All @@ -1058,6 +1069,7 @@ export default class Select<
clearValue,
cx,
getStyles,
getClassName,
getValue,
hasValue,
isMulti,
Expand Down Expand Up @@ -1085,6 +1097,10 @@ export default class Select<
const custom = this.props.styles[key];
return custom ? custom(base, props as any) : base;
};
getClassName = <Key extends keyof StylesProps<Option, IsMulti, Group>>(
key: Key,
props: StylesProps<Option, IsMulti, Group>[Key]
) => this.props.classNames[key]?.(props as any);
getElementId = (
element:
| 'group'
Expand Down
30 changes: 9 additions & 21 deletions packages/react-select/src/components/Control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
CSSObjectWithLabel,
GroupBase,
} from '../types';
import { getStyleProps } from '../utils';

export interface ControlProps<
Option = unknown,
Expand Down Expand Up @@ -68,30 +69,17 @@ const Control = <
>(
props: ControlProps<Option, IsMulti, Group>
) => {
const {
children,
cx,
getStyles,
className,
isDisabled,
isFocused,
innerRef,
innerProps,
menuIsOpen,
} = props;
const { children, isDisabled, isFocused, innerRef, innerProps, menuIsOpen } =
props;
return (
<div
ref={innerRef}
css={getStyles('control', props)}
className={cx(
{
control: true,
'control--is-disabled': isDisabled,
'control--is-focused': isFocused,
'control--menu-is-open': menuIsOpen,
},
className
)}
{...getStyleProps(props, 'control', {
control: true,
'control--is-disabled': isDisabled,
'control--is-focused': isFocused,
'control--menu-is-open': menuIsOpen,
})}
{...innerProps}
>
{children}
Expand Down
17 changes: 7 additions & 10 deletions packages/react-select/src/components/Group.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/** @jsx jsx */
import { ComponentType, ReactNode } from 'react';
import { jsx } from '@emotion/react';
import { cleanCommonProps } from '../utils';
import { cleanCommonProps, getStyleProps } from '../utils';

import {
CommonProps,
CommonPropsAndClassName,
CSSObjectWithLabel,
CX,
Expand Down Expand Up @@ -62,9 +63,9 @@ const Group = <
) => {
const {
children,
className,
cx,
getStyles,
getClassName,
Heading,
headingProps,
innerProps,
Expand All @@ -73,16 +74,13 @@ const Group = <
selectProps,
} = props;
return (
<div
css={getStyles('group', props)}
className={cx({ group: true }, className)}
{...innerProps}
>
<div {...getStyleProps(props, 'group', { group: true })} {...innerProps}>
<Heading
{...headingProps}
selectProps={selectProps}
theme={theme}
getStyles={getStyles}
getClassName={getClassName}
cx={cx}
>
{label}
Expand All @@ -101,6 +99,7 @@ interface GroupHeadingPropsDefinedProps<
selectProps: Props<Option, IsMulti, Group>;
theme: Theme;
getStyles: GetStyles<Option, IsMulti, Group>;
getClassName: CommonProps<Option, IsMulti, Group>['getClassName'];
cx: CX;
}

Expand Down Expand Up @@ -137,12 +136,10 @@ export const GroupHeading = <
>(
props: GroupHeadingProps<Option, IsMulti, Group>
) => {
const { getStyles, cx, className } = props;
const { data, ...innerProps } = cleanCommonProps(props);
return (
<div
css={getStyles('groupHeading', props)}
className={cx({ 'group-heading': true }, className)}
{...getStyleProps(props, 'groupHeading', { 'group-heading': true })}
{...innerProps}
/>
);
Expand Down
8 changes: 3 additions & 5 deletions packages/react-select/src/components/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
CSSObjectWithLabel,
GroupBase,
} from '../types';
import { cleanCommonProps } from '../utils';
import { cleanCommonProps, getStyleProps } from '../utils';

export interface InputSpecificProps<
Option = unknown,
Expand Down Expand Up @@ -93,14 +93,12 @@ const Input = <
>(
props: InputProps<Option, IsMulti, Group>
) => {
const { className, cx, getStyles, value } = props;
const { cx, value } = props;
const { innerRef, isDisabled, isHidden, inputClassName, ...innerProps } =
cleanCommonProps(props);

return (
<div
className={cx({ 'input-container': true }, className)}
css={getStyles('input', props)}
{...getStyleProps(props, 'input', { 'input-container': true })}
data-value={value || ''}
>
<input
Expand Down
90 changes: 39 additions & 51 deletions packages/react-select/src/components/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
getBoundingClientObj,
getScrollParent,
getScrollTop,
getStyleProps,
normalizedHeight,
scrollTo,
} from '../utils';
Expand Down Expand Up @@ -366,12 +367,10 @@ export const MenuPlacer = <
const Menu = <Option, IsMulti extends boolean, Group extends GroupBase<Option>>(
props: MenuProps<Option, IsMulti, Group>
) => {
const { children, className, cx, getStyles, innerRef, innerProps } = props;

const { children, innerRef, innerProps } = props;
return (
<div
css={getStyles('menu', props)}
className={cx({ menu: true }, className)}
{...getStyleProps(props, 'menu', { menu: true })}
ref={innerRef}
{...innerProps}
>
Expand Down Expand Up @@ -426,18 +425,13 @@ export const MenuList = <
>(
props: MenuListProps<Option, IsMulti, Group>
) => {
const { children, className, cx, getStyles, innerProps, innerRef, isMulti } =
props;
const { children, innerProps, innerRef, isMulti } = props;
return (
<div
css={getStyles('menuList', props)}
className={cx(
{
'menu-list': true,
'menu-list--is-multi': isMulti,
},
className
)}
{...getStyleProps(props, 'menuList', {
'menu-list': true,
'menu-list--is-multi': isMulti,
})}
ref={innerRef}
{...innerProps}
>
Expand Down Expand Up @@ -485,17 +479,13 @@ export const NoOptionsMessage = <
>(
props: NoticeProps<Option, IsMulti, Group>
) => {
const { children, className, cx, getStyles, innerProps } = props;
const { children, innerProps } = props;
return (
<div
css={getStyles('noOptionsMessage', props)}
className={cx(
{
'menu-notice': true,
'menu-notice--no-options': true,
},
className
)}
{...getStyleProps(props, 'noOptionsMessage', {
'menu-notice': true,
'menu-notice--no-options': true,
})}
{...innerProps}
>
{children}
Expand All @@ -513,17 +503,13 @@ export const LoadingMessage = <
>(
props: NoticeProps<Option, IsMulti, Group>
) => {
const { children, className, cx, getStyles, innerProps } = props;
const { children, innerProps } = props;
return (
<div
css={getStyles('loadingMessage', props)}
className={cx(
{
'menu-notice': true,
'menu-notice--loading': true,
},
className
)}
{...getStyleProps(props, 'loadingMessage', {
'menu-notice': true,
'menu-notice--loading': true,
})}
{...innerProps}
>
{children}
Expand Down Expand Up @@ -578,17 +564,18 @@ export const MenuPortal = <
Option,
IsMulti extends boolean,
Group extends GroupBase<Option>
>({
appendTo,
children,
className,
controlElement,
cx,
innerProps,
menuPlacement,
menuPosition,
getStyles,
}: MenuPortalProps<Option, IsMulti, Group>) => {
>(
props: MenuPortalProps<Option, IsMulti, Group>
) => {
const {
appendTo,
children,
controlElement,
innerProps,
menuPlacement,
menuPosition,
} = props;

const menuPortalRef = useRef<HTMLDivElement | null>(null);
const cleanupRef = useRef<(() => void) | void | null>(null);

Expand Down Expand Up @@ -665,16 +652,17 @@ export const MenuPortal = <
const menuWrapper = (
<div
ref={setMenuPortalElement}
css={getStyles('menuPortal', {
offset: computedPosition.offset,
position: menuPosition,
rect: computedPosition.rect,
})}
className={cx(
{...getStyleProps(
{
'menu-portal': true,
...props,
offset: computedPosition.offset,
position: menuPosition,
rect: computedPosition.rect,
},
className
'menuPortal',
{
'menu-portal': true,
}
)}
{...innerProps}
>
Expand Down
Loading

0 comments on commit 5d960cc

Please sign in to comment.