Skip to content
This repository has been archived by the owner on Oct 19, 2021. It is now read-only.

732 search #929

Closed
wants to merge 12 commits into from
Closed
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
2 changes: 1 addition & 1 deletion .storybook/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
}
],
"@babel/preset-react",
"@babel/preset-stage-1"
["@babel/preset-stage-1", { "decoratorsLegacy": true }]
]
}
2 changes: 1 addition & 1 deletion config/jest/jsTransform.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const babelOptions = {
},
},
],
'@babel/preset-stage-1',
['@babel/preset-stage-1', { decoratorsLegacy: true }],
'@babel/preset-react',
],
// Adding in here otherwise Jest complains about no plugin for class
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
"dependencies": {
"classnames": "2.2.5",
"downshift": "^1.31.14",
"flatpickr": "4.4.1",
"flatpickr": "4.5.0",
"invariant": "^2.2.3",
"lodash.debounce": "^4.0.8",
"lodash.isequal": "^4.5.0",
Expand Down Expand Up @@ -198,7 +198,7 @@
"presets": [
"./scripts/env",
"@babel/preset-react",
"@babel/preset-stage-1"
["@babel/preset-stage-1", { "decoratorsLegacy": true }]
]
},
"prettier": {
Expand Down
26 changes: 24 additions & 2 deletions src/components/DataTable/TableToolbarSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@ import Search from '../Search';
import setupGetInstanceId from './tools/instanceId';

const getInstanceId = setupGetInstanceId();
const translationKeys = {
'carbon.table.toolbar.search.label': 'Filter table',
'carbon.table.toolbar.search.placeholder': 'Search',
};

const translateWithId = id => {
return translationKeys[id];
};

const TableToolbarSearch = ({
className,
searchContainerClass,
onChange,
translateWithId: t,
id = `data-table-search-${getInstanceId()}`,
...rest
}) => {
Expand All @@ -25,8 +34,8 @@ const TableToolbarSearch = ({
{...rest}
small
id={id}
labelText="Filter table"
placeHolderText="Search"
labelText={t('carbon.table.toolbar.search.label')}
placeHolderText={t('carbon.table.toolbar.search.placeholder')}
onChange={onChange}
/>
</div>
Expand All @@ -45,12 +54,25 @@ TableToolbarSearch.propTypes = {
* Provide an optional id for the search container
*/
id: PropTypes.string,

/**
* Provide an optional className for the overal container of the Search
*/
searchContainerClasses: PropTypes.string,

/**
* Provide an optional hook that is called each time the input is updated
*/
onChange: PropTypes.func,

/**
* Provide custom text for the component for each translation id
*/
translateWithId: PropTypes.func.isRequired,
};

TableToolbarSearch.defaultProps = {
translateWithId,
};

export default TableToolbarSearch;
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,7 @@ exports[`DataTable should render 1`] = `
<TableToolbarSearch
id="custom-id"
onChange={[Function]}
translateWithId={[Function]}
>
<div
className="bx--toolbar-search-container"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ exports[`DataTable.TableToolbarSearch should render 1`] = `
className="custom-class"
id="custom-id"
onChange={[MockFunction]}
translateWithId={[Function]}
>
<div
className="bx--toolbar-search-container"
Expand Down
20 changes: 20 additions & 0 deletions src/components/DatePicker/DatePicker-story.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,26 @@ storiesOf('DatePicker', module)
</DatePicker>
)
)
.addWithInfo(
'range with calendar and min/max dates',
`
A range Date Picker consists of two input fields and a calendar, and optionally, the minDate and maxDate fields.
`,
() => (
<DatePicker
{...datePickerProps}
minDate="1/10/2020"
maxDate="1/20/2020"
datePickerType="range"
dateFormat="m/d/Y">
<DatePickerInput {...datePickerInputProps} id="date-picker-input-id" />
<DatePickerInput
{...datePickerInputProps}
id="date-picker-input-id-2"
/>
</DatePicker>
)
)
.addWithInfo(
'fully controlled',
`
Expand Down
34 changes: 34 additions & 0 deletions src/components/DatePicker/DatePicker-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,40 @@ describe('DatePicker', () => {
expect(datepicker.props().locale).toBe('en');
});
});

describe('Date picker with minDate and maxDate', () => {
console.error = jest.genMockFn(); // eslint-disable-line no-console

const wrapper = mount(
<DatePicker
onChange={() => {}}
datePickerType="range"
className="extra-class"
minDate="01/01/2018"
maxDate="01/30/2018">
<div className="test-child">
<input
type="text"
className="bx--date-picker__input"
id="input-from"
/>
</div>
<div className="test-child">
<input type="text" className="bx--date-picker__input" id="input-to" />
</div>
</DatePicker>
);

it('has the range date picker with min and max dates', () => {
const datepicker = wrapper.find('DatePicker');
expect(datepicker.props().minDate).toBe('01/01/2018');
expect(datepicker.props().maxDate).toBe('01/30/2018');
});

it('should not have "console.error" being created', () => {
expect(console.error).not.toBeCalled(); // eslint-disable-line no-console
});
});
});

describe('DatePickerSkeleton', () => {
Expand Down
18 changes: 17 additions & 1 deletion src/components/DatePicker/DatePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,16 @@ export default class DatePicker extends Component {
* The `change` event handler.
*/
onChange: PropTypes.func,

/**
* The minimum date that a user can start picking from.
*/
minDate: PropTypes.string,

/**
* The maximum date that a user can pick to.
*/
maxDate: PropTypes.string,
};

static defaultProps = {
Expand Down Expand Up @@ -217,17 +227,21 @@ export default class DatePicker extends Component {
locale,
appendTo,
onChange,
minDate,
maxDate,
} = this.props;
if (datePickerType === 'single' || datePickerType === 'range') {
const onHook = (electedDates, dateStr, instance) => {
this.updateClassNames(instance);
};
this.cal = flatpickr(this.inputField, {
this.cal = new flatpickr(this.inputField, {
appendTo,
mode: datePickerType,
allowInput: true,
dateFormat: dateFormat,
locale: l10n[locale],
minDate: minDate,
maxDate: maxDate,
plugins:
datePickerType === 'range'
? [new rangePlugin({ input: this.toInputField })]
Expand Down Expand Up @@ -370,6 +384,8 @@ export default class DatePicker extends Component {
short,
light,
datePickerType,
minDate, // eslint-disable-line
maxDate, // eslint-disable-line
dateFormat, // eslint-disable-line
onChange, // eslint-disable-line
...other
Expand Down
14 changes: 10 additions & 4 deletions src/components/OverflowMenu/OverflowMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,10 @@ export default class OverflowMenu extends Component {
}
};

handleClickOutside = () => {
this.closeMenu();
handleClickOutside = evt => {
if (!this._menuBody || !this._menuBody.contains(evt.target)) {
this.closeMenu();
}
};

closeMenu = () => {
Expand All @@ -275,8 +277,11 @@ export default class OverflowMenu extends Component {
* @private
*/
_bindMenuBody = menuBody => {
if (!menuBody && this._hFocusIn) {
this._hFocusIn = this._hFocusIn.release();
if (!menuBody) {
this._menuBody = menuBody;
if (this._hFocusIn) {
this._hFocusIn = this._hFocusIn.release();
}
}
};

Expand All @@ -287,6 +292,7 @@ export default class OverflowMenu extends Component {
*/
_handlePlace = menuBody => {
if (menuBody) {
this._menuBody = menuBody;
(
menuBody.querySelector('[data-floating-menu-primary-focus]') || menuBody
).focus();
Expand Down
7 changes: 7 additions & 0 deletions src/components/Pagination/Pagination-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@ describe('Pagination', () => {
expect(label.text()).toBe('1 of 10 pages');
});

it('should render ranges and pages for no items', () => {
const pager = mount(<Pagination pageSizes={[5, 10]} totalItems={0} />);
const labels = pager.find('.bx--pagination__text');
expect(labels.at(1).text()).toBe('0-0 of 0 items');
expect(labels.at(2).text()).toBe('1 of 1 pages');
});

it('should have two buttons for navigation', () => {
const buttons = right.find('.bx--pagination__button');
expect(buttons.length).toBe(2);
Expand Down
12 changes: 6 additions & 6 deletions src/components/Pagination/Pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ export default class Pagination extends Component {
// used for case when page # is 0 or empty. For other cases
// existing props will be used.
page >= 0 &&
page <= Math.ceil(this.props.totalItems / this.state.pageSize)
page <=
Math.max(Math.ceil(this.props.totalItems / this.state.pageSize), 1)
) {
this.setState({ page }, () => this.pageInputDebouncer(this.state.page));
}
Expand Down Expand Up @@ -138,7 +139,7 @@ export default class Pagination extends Component {
return itemText(pageSize * (page - 1) + 1, page * pageSize);
} else if (page > 0) {
return itemRangeText(
pageSize * (page - 1) + 1,
Math.min(pageSize * (page - 1) + 1, totalItems),
Math.min(page * pageSize, totalItems),
totalItems
);
Expand All @@ -159,7 +160,7 @@ export default class Pagination extends Component {
if (pagesUnknown) {
return pageText(page);
} else if (page > 0) {
return pageRangeText(page, Math.ceil(totalItems / pageSize));
return pageRangeText(page, Math.max(Math.ceil(totalItems / pageSize), 1));
}
return defaultPageText(Math.ceil(totalItems / pageSize));
};
Expand Down Expand Up @@ -192,6 +193,7 @@ export default class Pagination extends Component {

const statePage = this.state.page;
const statePageSize = this.state.pageSize;
const totalPages = Math.max(Math.ceil(totalItems / statePageSize), 1);
const classNames = classnames('bx--pagination', className);
const inputId = id || this.uniqueId;

Expand Down Expand Up @@ -240,9 +242,7 @@ export default class Pagination extends Component {
className="bx--pagination__button bx--pagination__button--forward"
onClick={this.incrementPage}
disabled={
this.props.disabled ||
statePage === Math.ceil(totalItems / statePageSize) ||
isLastPage
this.props.disabled || statePage === totalPages || isLastPage
}>
<Icon
className="bx--pagination__button-icon"
Expand Down
9 changes: 9 additions & 0 deletions src/components/PaginationV2/PaginationV2-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,15 @@ describe('Pagination', () => {
expect(label.text()).toBe('1 of 10 pages');
});

it('should render ranges and pages for no items', () => {
const pager = mount(
<PaginationV2 pageSizes={[5, 10]} totalItems={0} />
);
const labels = pager.find('.bx--pagination__text');
expect(labels.at(1).text()).toBe('\u00a0|\u00a0\u00a00-0 of 0 items');
expect(labels.at(2).text()).toBe('1 of 1 pages');
});

it('should have two buttons for navigation', () => {
const buttons = right.find('.bx--pagination__button');
expect(buttons.length).toBe(2);
Expand Down
13 changes: 6 additions & 7 deletions src/components/PaginationV2/PaginationV2.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ export default class PaginationV2 extends Component {
const page = Number(evt.target.value);
if (
page > 0 &&
page <= Math.ceil(this.props.totalItems / this.state.pageSize)
page <=
Math.max(Math.ceil(this.props.totalItems / this.state.pageSize), 1)
) {
this.setState({ page });
this.props.onChange({ page, pageSize: this.state.pageSize });
Expand Down Expand Up @@ -231,7 +232,7 @@ export default class PaginationV2 extends Component {
}
);
const inputId = id || this.uniqueId;
const totalPages = Math.ceil(totalItems / statePageSize);
const totalPages = Math.max(Math.ceil(totalItems / statePageSize), 1);
const selectItems = this.renderSelectItems(totalPages);

return (
Expand Down Expand Up @@ -260,7 +261,7 @@ export default class PaginationV2 extends Component {
statePage * statePageSize
)
: itemRangeText(
statePageSize * (statePage - 1) + 1,
Math.min(statePageSize * (statePage - 1) + 1, totalItems),
Math.min(statePage * statePageSize, totalItems),
totalItems
)}
Expand All @@ -270,7 +271,7 @@ export default class PaginationV2 extends Component {
<span className="bx--pagination__text">
{pagesUnknown
? pageText(statePage)
: pageRangeText(statePage, Math.ceil(totalItems / statePageSize))}
: pageRangeText(statePage, totalPages)}
</span>
<button
className={backButtonClasses}
Expand All @@ -297,9 +298,7 @@ export default class PaginationV2 extends Component {
className="bx--pagination__button bx--pagination__button--forward"
onClick={this.incrementPage}
disabled={
this.props.disabled ||
statePage === Math.ceil(totalItems / statePageSize) ||
isLastPage
this.props.disabled || statePage === totalPages || isLastPage
}>
<Icon
className="bx--pagination__button-icon"
Expand Down
Loading