Skip to content

Commit

Permalink
Merge pull request #271 from Adphorus/feature/support-for-customizabl…
Browse files Browse the repository at this point in the history
…e-static-range-labels

Support for customizable static range labels
  • Loading branch information
keremciu authored Jan 21, 2019
2 parents 2ffa7c8 + 5e4eb44 commit a423741
Show file tree
Hide file tree
Showing 8 changed files with 1,562 additions and 9 deletions.
1 change: 1 addition & 0 deletions . eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/node_modules/*
/lib/*
/dist/*
**/*.snap
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ Make sure your issue or feature doesn't have any related issue at [react-date-ra

3. Run `yarn` to install the dependencies.

4. Run `yarn dev` to start development server.
4. Run `yarn run dev` to start development server.

## Building

. Run `run test` and `run lint` for make sure tests passes and linter doesn't throw any error.
. Run `yarn run test` and `yarn run lint` for make sure tests passes and linter doesn't throw any error.

. Run `yarn build` compile the library and demo source.
. Run `yarn run build` compile the library and demo source.

. Push your changes and create a PR and apply code review decisions.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ showPreview(DateRange) | bool | true | visibility
dragSelectionEnabled(Calendar) | bool | true | whether dates can be selected via drag n drop
onPreviewChange(DateRange) | Object | | Callback function for preview changes
dateDisplayFormat(DateRange) | String | `MMM D, YYYY` | selected range preview formatter. Check out [date-fns's format option](https://date-fns.org/v2.0.0-alpha.7/docs/format)
renderStaticRangeLabel(`DefinedRange`)| Function | | Callback function to be triggered for the static range configurations that have `hasCustomRendering: true` on them. Instead of rendering `staticRange.label`, return value of this callback will be rendered.
staticRanges(`DefinedRange`, `DateRangePicker`) | Array | [default preDefined ranges](https://github.com/Adphorus/react-date-range/blob/master/src/defaultRanges.js) | -
inputRanges(`DefinedRange`, `DateRangePicker`) | Array | [default input ranges](https://github.com/Adphorus/react-date-range/blob/master/src/defaultRanges.js) | -

Expand Down
86 changes: 83 additions & 3 deletions demo/src/components/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,51 @@ import * as rdrLocales from '../../../src/locale';
import { format, addDays } from 'date-fns';
import Section from './Section';

function renderStaticRangeLabel(staticRange) {
return (
<CustomStaticRangeLabelContent text={'This is a custom label content: '}/>
);
}

class CustomStaticRangeLabelContent extends React.Component {
constructor(props) {
super(props);

this.state = {
currentDateString: Date(),
};

this.intervalId = setInterval(
() => {
this.setState({
currentDateString: Date(),
});
},
1000
);
}

componentWillUnmount() {
if (this.intervalId) {
clearInterval(this.intervalId);
}
}

render() {
const { currentDateString } = this.state;
const { text } = this.props;

return (
<span>
<i>{text}</i>
<span className={'random-date-string'}>
<b>{currentDateString}</b>
</span>
</span>
);
}
}

const nameMapper = {
ar: 'Arabic (Modern Standard Arabic - Al-fussha)',
bg: 'Bulgarian',
Expand Down Expand Up @@ -135,6 +180,7 @@ export default class Main extends Component {
[which]: payload,
});
}

handleRangeChange(which, payload) {
console.log(which, payload);
this.setState({
Expand Down Expand Up @@ -217,7 +263,7 @@ export default class Main extends Component {
readOnly
value={formatDateDisplay(this.state.multipleRanges.selection1.endDate, 'Continuous')}
/>
<div className={'newLine'} />
<div className={'newLine'}/>

<label className={'label'}>Selection2 Start:</label>
<input
Expand All @@ -231,7 +277,7 @@ export default class Main extends Component {
readOnly
value={formatDateDisplay(this.state.multipleRanges.selection2.endDate, 'Continuous')}
/>
<div className={'newLine'} />
<div className={'newLine'}/>

<label className={'label'}>Selection3 Start:</label>
<input
Expand Down Expand Up @@ -319,9 +365,24 @@ export default class Main extends Component {

<DefinedRange
ranges={[this.state.definedRange.selection]}
renderStaticRangeLabel={renderStaticRangeLabel}
staticRanges={[{
label: "Hoy",
hasCustomRendering: true,
range: () => ({
startDate: new Date(),
endDate: new Date(),
}),
isSelected() {
return (
true
);
},
}]}
onChange={this.handleRangeChange.bind(this, 'definedRange')}
className={'centered'}
/>
>
</DefinedRange>
</Section>
<Section title="RangePicker with disabled dates">
<div>
Expand All @@ -348,6 +409,25 @@ export default class Main extends Component {
disabledDates={[new Date(), addDays(new Date(), 3)]}
minDate={addDays(new Date(), -3)}
/>

<DefinedRange
ranges={[this.state.definedRange.selection]}
renderStaticRangeLabel={renderStaticRangeLabel}
staticRanges={[{
hasCustomRendering: true,
range: () => ({
startDate: new Date(),
endDate: new Date(),
}),
isSelected() {
return (
true
);
},
}]}
onChange={this.handleRangeChange.bind(this, 'definedRange')}
className={'centered'}
/>
</Section>
</main>
);
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
],
"contributors": [
"Burak Can <neoberg@gmail.com> (https://github.com/burakcan)",
"Mehmet Kamil Morcay <mehmetmorcay@gmail.com> (https://github.com/mkg0)"
"Mehmet Kamil Morcay <mehmetmorcay@gmail.com> (https://github.com/mkg0)",
"Engin Semih Basmacı <semih.basmaci@gmail.com> (https://github.com/mortargrind)"
],
"license": "MIT",
"repository": {
Expand Down
17 changes: 15 additions & 2 deletions src/components/DefinedRange.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class DefinedRanges extends Component {
};
this.handleRangeChange = this.handleRangeChange.bind(this);
}

handleRangeChange(range) {
const { onChange, ranges, focusedRange } = this.props;
const selectedRange = ranges[focusedRange[0]];
Expand All @@ -22,6 +23,7 @@ class DefinedRanges extends Component {
[selectedRange.key || `range${focusedRange[0] + 1}`]: { ...selectedRange, ...range },
});
}

getSelectedRange(ranges, staticRange) {
const focusedRangeIndex = ranges.findIndex(range => {
if (!range.startDate || !range.endDate || range.disabled) return false;
Expand All @@ -30,14 +32,24 @@ class DefinedRanges extends Component {
const selectedRange = ranges[focusedRangeIndex];
return { selectedRange, focusedRangeIndex };
}

render() {
const { onPreviewChange, ranges, rangeColors, className } = this.props;
const { onPreviewChange, ranges, renderStaticRangeLabel, rangeColors, className } = this.props;

return (
<div className={cx(styles.definedRangesWrapper, className)}>
{this.props.headerContent}
<div className={styles.staticRanges}>
{this.props.staticRanges.map((staticRange, i) => {
const { selectedRange, focusedRangeIndex } = this.getSelectedRange(ranges, staticRange);
let labelContent;

if (staticRange.hasCustomRendering) {
labelContent = renderStaticRangeLabel(staticRange);
} else {
labelContent = staticRange.label;
}

return (
<button
type="button"
Expand All @@ -59,7 +71,7 @@ class DefinedRanges extends Component {
this.props.onPreviewChange && this.props.onPreviewChange();
}}>
<span tabIndex={-1} className={styles.staticRangeLabel}>
{staticRange.label}
{labelContent}
</span>
</button>
);
Expand Down Expand Up @@ -106,6 +118,7 @@ DefinedRanges.propTypes = {
headerContent: PropTypes.any,
rangeColors: PropTypes.arrayOf(PropTypes.string),
className: PropTypes.string,
renderStaticRangeLabel: PropTypes.func,
};

DefinedRanges.defaultProps = {
Expand Down
135 changes: 135 additions & 0 deletions src/components/DefinedRange.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import React from 'react';
import { mount, shallow } from 'enzyme';

import DefinedRange from './DefinedRange';
import { isSameDay } from 'date-fns';

describe('DefinedRange tests', () => {
test('Should call "renderStaticRangeLabel" callback correct amount of times according to the "hasCustomRendering" option', () => {
const renderStaticRangeLabel = jest.fn();

mount(
<DefinedRange
staticRanges={[
{
label: 'Dynamic Label',
range: {},
isSelected(range) {
const definedRange = this.range();
return (
isSameDay(range.startDate, definedRange.startDate) &&
isSameDay(range.endDate, definedRange.endDate)
);
},
hasCustomRendering: true,
},
{
label: 'Static Label',
range: {},
isSelected(range) {
const definedRange = this.range();
return (
isSameDay(range.startDate, definedRange.startDate) &&
isSameDay(range.endDate, definedRange.endDate)
);
},
},
{
label: 'Hede',
range: {},
isSelected(range) {
const definedRange = this.range();
return (
isSameDay(range.startDate, definedRange.startDate) &&
isSameDay(range.endDate, definedRange.endDate)
);
},
hasCustomRendering: true,
},
]}
renderStaticRangeLabel={renderStaticRangeLabel}
/>
);

expect(renderStaticRangeLabel).toHaveBeenCalledTimes(2);
});

test('Should render dynamic static label contents correctly', () => {
const renderItalicLabelContent = () => (
<i className={'italic-label-content'}>{'Italic Content'}</i>
);
const renderBoldLabelContent = () => <b className={'bold-label-content'}>{'Bold Content'}</b>;
const renderSomethingElse = () => <img className={'random-image'} />;

const renderStaticRangeLabel = function(staticRange) {
let result;

if (staticRange.id === 'italic') {
result = renderItalicLabelContent();
} else if (staticRange.id === 'bold') {
result = renderBoldLabelContent();
} else {
result = renderSomethingElse();
}

return result;
};

const wrapper = shallow(
<DefinedRange
staticRanges={[
{
id: 'italic',
range: {},
isSelected(range) {
const definedRange = this.range();
return (
isSameDay(range.startDate, definedRange.startDate) &&
isSameDay(range.endDate, definedRange.endDate)
);
},
hasCustomRendering: true,
},
{
label: 'Static Label',
range: {},
isSelected(range) {
const definedRange = this.range();
return (
isSameDay(range.startDate, definedRange.startDate) &&
isSameDay(range.endDate, definedRange.endDate)
);
},
},
{
id: 'whatever',
range: {},
isSelected(range) {
const definedRange = this.range();
return (
isSameDay(range.startDate, definedRange.startDate) &&
isSameDay(range.endDate, definedRange.endDate)
);
},
hasCustomRendering: true,
},
{
id: 'bold',
range: {},
isSelected(range) {
const definedRange = this.range();
return (
isSameDay(range.startDate, definedRange.startDate) &&
isSameDay(range.endDate, definedRange.endDate)
);
},
hasCustomRendering: true,
},
]}
renderStaticRangeLabel={renderStaticRangeLabel}
/>
);

expect(wrapper).toMatchSnapshot();
});
});
Loading

0 comments on commit a423741

Please sign in to comment.