From f6452098b8814b972b96588019899651b32adeb4 Mon Sep 17 00:00:00 2001 From: Sam McKoy Date: Thu, 23 Nov 2023 16:12:30 +1300 Subject: [PATCH 1/2] feat: time gutter position features --- src/Calendar.js | 6 ++++++ src/TimeGrid.js | 36 +++++++++++++++++++++++------------- src/TimeGridHeader.js | 24 ++++++++++++++++++------ src/sass/time-column.scss | 15 ++++++++++++--- src/sass/time-grid.scss | 1 + stories/Calendar.stories.js | 16 ++++++++++++++++ 6 files changed, 76 insertions(+), 22 deletions(-) diff --git a/src/Calendar.js b/src/Calendar.js index ec3a7344f..1862157cb 100644 --- a/src/Calendar.js +++ b/src/Calendar.js @@ -689,6 +689,11 @@ class Calendar extends React.Component { */ timeGutterFormat: dateFormat, + /** + * The position the time gutter gets rendered (left, right, both) + */ + timeGutterPosition: PropTypes.oneOf(['left', 'right', 'both']), + /** * Toolbar header format for the Month view, e.g "2015 April" * @@ -1158,4 +1163,5 @@ export default uncontrollable(Calendar, { view: 'onView', date: 'onNavigate', selected: 'onSelectEvent', + timeGutterPosition: 'left', }) diff --git a/src/TimeGrid.js b/src/TimeGrid.js index 4ae83354b..b52906bc3 100644 --- a/src/TimeGrid.js +++ b/src/TimeGrid.js @@ -200,6 +200,7 @@ export default class TimeGrid extends Component { showMultiDayTimes, longPressThreshold, resizable, + timeGutterPosition, } = this.props width = width || this.state.gutterWidth @@ -238,6 +239,22 @@ export default class TimeGrid extends Component { allDayEvents.sort((a, b) => sortEvents(a, b, accessors, localizer)) + const timeGutter = ( + + ) + return (
{this.props.popup && this.renderOverlay()}
- + {timeGutterPosition !== 'right' && timeGutter} + {this.renderEvents( range, rangeEvents, rangeBackgroundEvents, getNow() )} + + {timeGutterPosition !== 'left' && timeGutter}
) @@ -475,4 +484,5 @@ TimeGrid.propTypes = { TimeGrid.defaultProps = { step: 30, timeslots: 2, + timeGutterPosition: 'left', } diff --git a/src/TimeGridHeader.js b/src/TimeGridHeader.js index ac76f73eb..a8216b166 100644 --- a/src/TimeGridHeader.js +++ b/src/TimeGridHeader.js @@ -128,6 +128,7 @@ class TimeGridHeader extends React.Component { resourceHeader: ResourceHeaderComponent = ResourceHeader, }, resizable, + timeGutterPosition, } = this.props let style = {} @@ -143,12 +144,14 @@ class TimeGridHeader extends React.Component { ref={scrollRef} className={clsx('rbc-time-header', isOverflowing && 'rbc-overflowing')} > -
- {TimeGutterHeader && } -
+ {timeGutterPosition !== 'right' && ( +
+ {TimeGutterHeader && } +
+ )} {resources.map(([id, resource], idx) => (
@@ -197,6 +200,15 @@ class TimeGridHeader extends React.Component { />
))} + + {timeGutterPosition !== 'left' && ( +
+ {TimeGutterHeader && } +
+ )} ) } diff --git a/src/sass/time-column.scss b/src/sass/time-column.scss index 7b172f59a..da8c440ec 100644 --- a/src/sass/time-column.scss +++ b/src/sass/time-column.scss @@ -84,11 +84,20 @@ .rbc-time-gutter, .rbc-time-header-gutter { position: sticky; - left: 0; background-color: white; - border-right: 1px solid $cell-border; z-index: 10; - margin-right: -1px; + border-left: 1px solid $cell-border; + margin-left: -1px; + } + + .rbc-time-header-gutter-left { + @extend .rbc-time-header-gutter; + left: 0; + } + + .rbc-time-header-gutter-right { + @extend .rbc-time-header-gutter; + right: 0; } .rbc-time-header { diff --git a/src/sass/time-grid.scss b/src/sass/time-grid.scss index ebb171b5f..6760aeefd 100644 --- a/src/sass/time-grid.scss +++ b/src/sass/time-grid.scss @@ -90,6 +90,7 @@ min-width: 0; flex-direction: column; border-left: 1px solid $cell-border; + border-right: 1px solid $cell-border; .rbc-rtl & { border-left-width: 0; diff --git a/stories/Calendar.stories.js b/stories/Calendar.stories.js index 9f9ddbc22..4be0a2d24 100644 --- a/stories/Calendar.stories.js +++ b/stories/Calendar.stories.js @@ -62,6 +62,22 @@ CustomTimeGutterWrapper.args = { }, } +export const TimeGutterPosition = Template.bind({}) +TimeGutterPosition.storyName = 'TimeGutter position - right' +TimeGutterPosition.args = { + timeGutterPosition: 'right', + events: demoEvents, + onSelectEvent: action('event selected'), + defaultDate: new Date(2015, 3, 1), + defaultView: Views.WEEK, + views: [Views.WEEK, Views.DAY], +} +TimeGutterPosition.argTypes = { + timeGutterPosition: { + control: { type: 'select', options: ['left', 'right', 'both'] }, + }, +} + export const CustomDateCellWrapper = Template.bind({}) CustomDateCellWrapper.storyName = 'add custom dateCellWrapper' CustomDateCellWrapper.args = { From 0b6209a83020ab3d6f237a42d25ba412c5f7cd47 Mon Sep 17 00:00:00 2001 From: Sam McKoy Date: Wed, 29 Nov 2023 10:02:39 +1300 Subject: [PATCH 2/2] fix: add storybook for props.timeGutterPosition --- stories/props/timeGutterPosition.mdx | 11 +++++ stories/props/timeGutterPosition.stories.js | 45 +++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 stories/props/timeGutterPosition.mdx create mode 100644 stories/props/timeGutterPosition.stories.js diff --git a/stories/props/timeGutterPosition.mdx b/stories/props/timeGutterPosition.mdx new file mode 100644 index 000000000..e527b9109 --- /dev/null +++ b/stories/props/timeGutterPosition.mdx @@ -0,0 +1,11 @@ +import { Canvas, Story } from '@storybook/addon-docs' +import LinkTo from '@storybook/addon-links/react' + +# timeGutterPosition + +- type: `string` (left, right, both) +- default: `left` + +The position the time gutter should be in the day/week views. + + diff --git a/stories/props/timeGutterPosition.stories.js b/stories/props/timeGutterPosition.stories.js new file mode 100644 index 000000000..1e0b2d955 --- /dev/null +++ b/stories/props/timeGutterPosition.stories.js @@ -0,0 +1,45 @@ +import React from 'react' +import demoEvents from '../resources/events' +import mdx from './timeGutterPosition.mdx' +import moment from 'moment' +import { Calendar, Views, momentLocalizer } from '../../src' + +const mLocalizer = momentLocalizer(moment) + +export default { + title: 'props', + component: Calendar, + argTypes: { + localizer: { control: { type: null } }, + events: { control: { type: null } }, + defaultDate: { control: { type: null } }, + timeGutterPosition: 'string', + }, + parameters: { + docs: { + page: mdx, + }, + }, +} + +const Template = (args) => ( +
+ +
+) + +export const TimeGutterPosition = Template.bind({}) +TimeGutterPosition.storyName = 'timeGutterPosition' +TimeGutterPosition.args = { + defaultDate: new Date(2015, 3, 13), + defaultView: Views.WEEK, + timeGutterPosition: 'both', + events: demoEvents, + localizer: mLocalizer, +} + +TimeGutterPosition.argTypes = { + timeGutterPosition: { + control: { type: 'select', options: ['left', 'right', 'both'] }, + }, +}