Skip to content
This repository has been archived by the owner on Feb 27, 2020. It is now read-only.

Commit

Permalink
feat: add back nestedfilterablemultiselect
Browse files Browse the repository at this point in the history
  • Loading branch information
Logan McCaul committed Dec 3, 2019
1 parent dde3624 commit 2a802c1
Show file tree
Hide file tree
Showing 25 changed files with 7,309 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,5 @@
"enzyme-to-json/serializer"
]
},
"version": "2.0.0"
"version": "2.0.1"
}
29 changes: 29 additions & 0 deletions src/components/GroupLabel/GroupLabel-story.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { withInfo } from '@storybook/addon-info';
import GroupLabel from './GroupLabel';
import { Tooltip } from 'carbon-components-react';

const additionalProps = {
className: 'some-class',
};

storiesOf('GroupLabel', module)
.add(
'Default',
withInfo({
text: 'Group label.',
})(() => <GroupLabel {...additionalProps}>Label</GroupLabel>)
)
.add(
'With tooltip',
withInfo({
text: 'Form label with tooltip.',
})(() => (
<GroupLabel {...additionalProps}>
<Tooltip triggerText="Label">
This is the content of the tooltip.
</Tooltip>
</GroupLabel>
))
);
44 changes: 44 additions & 0 deletions src/components/GroupLabel/GroupLabel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import PropTypes from 'prop-types';
import React from 'react';
import classnames from 'classnames';

const categoryLabel = {
color: '#5A6872',
fontSize: '12px',
fontWeight: '600',
letterSpacing: '0.2px',
margin: '8px 16px',
};

const GroupLabel = ({ className, children, id, ...other }) => {
const classNames = classnames('bx--group-label', className);

return (
<label
htmlFor={id}
className="bx--group-label"
style={categoryLabel}
{...other}>
{children}
</label>
);
};

GroupLabel.propTypes = {
/**
* Specify the content of the form label
*/
children: PropTypes.node,

/**
* Provide a custom className to be applied to the containing <label> node
*/
className: PropTypes.string,

/**
* Provide a unique id for the given <GroupLabel>
*/
id: PropTypes.string,
};

export default GroupLabel;
1 change: 1 addition & 0 deletions src/components/GroupLabel/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default from './GroupLabel';
104 changes: 104 additions & 0 deletions src/components/ListBox/ListBox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import cx from 'classnames';
import React from 'react';
import PropTypes from 'prop-types';
import ListBoxField from './ListBoxField';
import ListBoxMenu from './ListBoxMenu';
import { ListBoxType } from './ListBoxPropTypes';
import childrenOf from '../../prop-types/childrenOf';

const handleOnKeyDown = event => {
if (event.keyCode === 27) {
event.stopPropagation();
}
};

const handleClick = event => {
event.preventDefault();
event.stopPropagation();
};

/**
* `ListBox` is a generic container component that handles creating the
* container class name in response to certain props.
*/
const ListBox = ({
ariaLabel,
children,
className: containerClassName,
disabled,
innerRef,
type,
invalid,
invalidText,
light,
isOpen,
...rest
}) => {
const className = cx({
[containerClassName]: !!containerClassName,
'bx--list-box': true,
'bx--list-box--inline': type === 'inline',
'bx--list-box--disabled': disabled,
'bx--list-box--light': light,
'bx--list-box--expanded': isOpen,
});
return (
<React.Fragment>
<div
{...rest}
role="listbox"
aria-label={ariaLabel}
className={className}
ref={innerRef}
onKeyDown={handleOnKeyDown}
onClick={handleClick}
data-invalid={invalid || undefined}
aria-invalid={invalid || undefined}>
{children}
</div>
{invalid ? (
<div className="bx--form-requirement">{invalidText}</div>
) : null}
</React.Fragment>
);
};

ListBox.propTypes = {
children: childrenOf([ListBoxField, ListBoxMenu]),

/**
* Specify a class name to be applied on the containing list box node
*/
className: PropTypes.string,

/**
* `innerRef` hook used for libraries like Downshift that require a reference
* on a container node when it is not a native element
*/
innerRef: PropTypes.func.isRequired,

/**
* Specify whether the ListBox is currently disabled
*/
disabled: PropTypes.bool.isRequired,

/**
* Specify the "type" of the ListBox. Currently supports either `default` or
* `inline` as an option.
*/
type: ListBoxType.isRequired,

/**
* Specify the "aria-label" of the ListBox.
*/
ariaLabel: PropTypes.string,
};

ListBox.defaultProps = {
innerRef: () => {},
disabled: false,
type: 'default',
ariaLabel: 'Choose an item',
};

export default ListBox;
31 changes: 31 additions & 0 deletions src/components/ListBox/ListBoxField.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import PropTypes from 'prop-types';
import ListBoxMenuIcon from './ListBoxMenuIcon';
import ListBoxSelection from './ListBoxSelection';
import childrenOf from '../../prop-types/childrenOf';

/**
* `ListBoxField` is responsible for creating the containing node for valid
* elements inside of a field. It also provides a11y-related attributes like
* `role` to make sure a user can focus the given field.
*/
const ListBoxField = ({ children, tabIndex, ...rest }) => (
<div
role="button"
className="bx--list-box__field"
tabIndex={tabIndex}
{...rest}>
{children}
</div>
);

ListBoxField.propTypes = {
children: childrenOf([ListBoxMenuIcon, ListBoxSelection, 'span', 'input']),
tabIndex: PropTypes.string,
};

ListBoxField.defaultProps = {
tabIndex: '0',
};

export default ListBoxField;
22 changes: 22 additions & 0 deletions src/components/ListBox/ListBoxMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import ListBoxMenuItem from './ListBoxMenuItem';
import childrenOfType from '../../prop-types/childrenOfType';

/**
* `ListBoxMenu` is a simple container node that isolates the `list-box__menu`
* class into a single component. It is also being used to validate given
* `children` components.
*/
const ListBoxMenu = ({ children, ...rest }) => {
return (
<div className="bx--list-box__menu" {...rest}>
{children}
</div>
);
};

ListBoxMenu.propTypes = {
children: childrenOfType(ListBoxMenuItem),
};

export default ListBoxMenu;
58 changes: 58 additions & 0 deletions src/components/ListBox/ListBoxMenuIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import cx from 'classnames';
import React from 'react';
import PropTypes from 'prop-types';
import { iconCaretDown } from 'carbon-icons';
import { Icon } from 'carbon-components-react';

export const translationIds = {
'close.menu': 'close.menu',
'open.menu': 'open.menu',
};

const defaultTranslations = {
[translationIds['close.menu']]: 'Close menu',
[translationIds['open.menu']]: 'Open menu',
};

/**
* `ListBoxMenuIcon` is used to orient the icon up or down depending on the
* state of the menu for a given `ListBox`
*/
const ListBoxMenuIcon = ({ isOpen, translateWithId: t }) => {
const className = cx({
'bx--list-box__menu-icon': true,
'bx--list-box__menu-icon--open': isOpen,
});
const description = isOpen ? t('close.menu') : t('open.menu');
return (
<div className={className}>
<Icon
icon={iconCaretDown}
description={description}
name="icon--caret--down"
alt={description}
/>
</div>
);
};

ListBoxMenuIcon.propTypes = {
/**
* Specify whether the menu is currently open, which will influence the
* direction of the menu icon
*/
isOpen: PropTypes.bool.isRequired,

/**
* i18n hook used to provide the appropriate description for the given menu
* icon. This function takes in an id defined in `translationIds` and should
* return a string message for that given message id.
*/
translateWithId: PropTypes.func.isRequired,
};

ListBoxMenuIcon.defaultProps = {
translateWithId: id => defaultTranslations[id],
};

export default ListBoxMenuIcon;
46 changes: 46 additions & 0 deletions src/components/ListBox/ListBoxMenuItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import cx from 'classnames';
import React from 'react';
import PropTypes from 'prop-types';

/**
* `ListBoxMenuItem` is a helper component for managing the container class
* name, alongside any classes for any corresponding states, for a generic list
* box menu item.
*/
const ListBoxMenuItem = ({ children, isActive, isHighlighted, ...rest }) => {
const className = cx({
'bx--list-box__menu-item': true,
'bx--list-box__menu-item--active': isActive,
'bx--list-box__menu-item--highlighted': isHighlighted,
});
return (
<div className={className} {...rest}>
{children}
</div>
);
};

ListBoxMenuItem.propTypes = {
/**
* Specify any children nodes that hsould be rendered inside of the ListBox
* Menu Item
*/
children: PropTypes.node,

/**
* Specify whether the current menu item is "active".
*/
isActive: PropTypes.bool.isRequired,

/**
* Specify whether the current menu item is "highlighed".
*/
isHighlighted: PropTypes.bool.isRequired,
};

ListBoxMenuItem.defaultProps = {
isActive: false,
isHighlighted: false,
};

export default ListBoxMenuItem;
3 changes: 3 additions & 0 deletions src/components/ListBox/ListBoxPropTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import PropTypes from 'prop-types';

export const ListBoxType = PropTypes.oneOf(['default', 'inline']);
Loading

0 comments on commit 2a802c1

Please sign in to comment.