From f2a934b4d151d8870d0261c6cef0666fe2726932 Mon Sep 17 00:00:00 2001 From: Gilad Gray Date: Thu, 9 Aug 2018 14:22:33 -0700 Subject: [PATCH 01/19] HTMLSelect: add iconProps, fix dark icon color --- .../components/html-select/_html-select.scss | 1 + .../src/components/html-select/htmlSelect.tsx | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/core/src/components/html-select/_html-select.scss b/packages/core/src/components/html-select/_html-select.scss index a1cb35b4ee..6288cf14f8 100644 --- a/packages/core/src/components/html-select/_html-select.scss +++ b/packages/core/src/components/html-select/_html-select.scss @@ -49,6 +49,7 @@ Styleguide select .#{$ns}-icon { @extend %pt-select-arrow; + @include pt-icon-colors(); } &.#{$ns}-minimal select { diff --git a/packages/core/src/components/html-select/htmlSelect.tsx b/packages/core/src/components/html-select/htmlSelect.tsx index 65f606d73d..03d26b92f2 100644 --- a/packages/core/src/components/html-select/htmlSelect.tsx +++ b/packages/core/src/components/html-select/htmlSelect.tsx @@ -9,7 +9,7 @@ import * as React from "react"; import { DISABLED, FILL, HTML_SELECT, LARGE, MINIMAL } from "../../common/classes"; import { IOptionProps } from "../../common/props"; import { IElementRefProps } from "../html/html"; -import { Icon } from "../icon/icon"; +import { Icon, IIconProps } from "../icon/icon"; export interface IHTMLSelectProps extends IElementRefProps, @@ -20,6 +20,9 @@ export interface IHTMLSelectProps /** Whether this element should fill its container. */ fill?: boolean; + /** Props to spread to the `` element. */ + iconProps?: Partial; + /** Whether to use large styles. */ large?: boolean; @@ -47,7 +50,17 @@ export interface IHTMLSelectProps /* istanbul ignore next */ export class HTMLSelect extends React.PureComponent { public render() { - const { className, disabled, elementRef, fill, large, minimal, options = [], ...htmlProps } = this.props; + const { + className, + disabled, + elementRef, + fill, + iconProps, + large, + minimal, + options = [], + ...htmlProps + } = this.props; const classes = classNames( HTML_SELECT, { @@ -70,7 +83,7 @@ export class HTMLSelect extends React.PureComponent { {optionChildren} {htmlProps.children} - + ); } From ed2255dfdd09092e139dbaacaad5b9f171ccc659 Mon Sep 17 00:00:00 2001 From: Gilad Gray Date: Thu, 9 Aug 2018 15:10:26 -0700 Subject: [PATCH 02/19] use HTMLSelect in caption massive reduction in styles --- packages/datetime/src/_datepicker.scss | 99 +++++---------------- packages/datetime/src/datePickerCaption.tsx | 99 ++++++++------------- 2 files changed, 58 insertions(+), 140 deletions(-) diff --git a/packages/datetime/src/_datepicker.scss b/packages/datetime/src/_datepicker.scss index 9dc0f26292..b94be84eba 100644 --- a/packages/datetime/src/_datepicker.scss +++ b/packages/datetime/src/_datepicker.scss @@ -152,62 +152,6 @@ $header-margin: ($header-height - $pt-input-height) / 2 !default; } } - .#{$ns}-datepicker-caption { - display: table-caption; - border-bottom: 1px solid $pt-divider-black; - padding: 0 $pt-grid-size; - text-align: center; - - select { - margin: -$datepicker-header-margin 0 $datepicker-header-margin; - border: 0; - background: none; - cursor: pointer; - height: $pt-input-height; - // increase the size of the click target, clearing the caret on the right. - padding-right: $pt-icon-size-standard; - padding-left: $pt-grid-size / 2; - line-height: $pt-input-height; - color: $pt-text-color; - font-weight: 600; - - // stylelint-disable property-no-vendor-prefix - -moz-appearance: none; - -webkit-appearance: none; - // stylelint-enable property-no-vendor-prefix - - &:focus + .#{$ns}-datepicker-caption-caret { - display: inline; - } - - &::-ms-expand { - // IE11 styling to hide the arrow - display: none; - } - } - } - - .#{$ns}-datepicker-caption-select { - display: inline-block; - position: relative; - - &:first-child { - margin-right: $pt-grid-size; - } - - &:hover .#{$ns}-datepicker-caption-caret { - fill: $pt-icon-color-hover; - } - } - - .#{$ns}-datepicker-caption-caret { - position: absolute; - top: 2px; - right: 0; - fill: $pt-icon-color; - pointer-events: none; - } - .#{$ns}-datepicker-footer { display: flex; justify-content: space-between; @@ -218,6 +162,26 @@ $header-margin: ($header-height - $pt-input-height) / 2 !default; } } +.#{$ns}-datepicker-caption { + @include pt-flex-container(row); + justify-content: space-between; + margin-bottom: $pt-grid-size / 2; + border-bottom: 1px solid $pt-divider-black; + padding: 0 $pt-button-height-small ($pt-grid-size / 2); + + // HTMLSelect overrides for a narrower appearance + select { + flex-shrink: 1; + padding-right: $pt-icon-size-standard; + padding-left: $pt-grid-size / 2; + font-weight: 600; + + + .#{$ns}-icon { + right: 2px; + } + } +} + .#{$ns}-datepicker-caption-measure { padding-left: $pt-grid-size / 2; font-weight: 600; @@ -259,29 +223,6 @@ $header-margin: ($header-height - $pt-input-height) / 2 !default; } } - .#{$ns}-datepicker-caption { - border-bottom-color: $pt-dark-divider-black; - - select { - color: $pt-dark-text-color; - } - - option { - background-color: $dark-popover-background-color; - } - - // we really need more than 4 compound selector - // to target the particular structure of this markup - // stylelint-disable-next-line - .#{$ns}-datepicker-caption-select:hover .#{$ns}-datepicker-caption-caret { - fill: $pt-dark-icon-color-hover; - } - - .#{$ns}-datepicker-caption-caret { - fill: $pt-dark-icon-color; - } - } - .#{$ns}-datepicker-footer { border-top-color: $pt-dark-divider-black; } diff --git a/packages/datetime/src/datePickerCaption.tsx b/packages/datetime/src/datePickerCaption.tsx index 8a7a309f3a..7dd85205e3 100644 --- a/packages/datetime/src/datePickerCaption.tsx +++ b/packages/datetime/src/datePickerCaption.tsx @@ -4,18 +4,21 @@ * Licensed under the terms of the LICENSE file distributed with this project. */ -import { Icon, Utils as BlueprintUtils } from "@blueprintjs/core"; +import { HTMLSelect, IOptionProps, Utils } from "@blueprintjs/core"; import * as React from "react"; import { CaptionElementProps } from "react-day-picker/types/props"; import * as Classes from "./common/classes"; -import * as Utils from "./common/utils"; +import { clone } from "./common/dateUtils"; +import { measureTextWidth } from "./common/utils"; export interface IDatePickerCaptionProps extends CaptionElementProps { maxDate: Date; minDate: Date; onMonthChange?: (month: number) => void; onYearChange?: (year: number) => void; + /** Callback invoked when the month or year ` - {monthOptionElements} - - - + ); const yearSelect = ( -
- - -
+ ); const orderedSelects = this.props.reverseMonthAndYearMenus @@ -123,8 +102,6 @@ export class DatePickerCaption extends React.PureComponent (this.containerElement = r); - private positionArrows() { // measure width of text as rendered inside our container element. const monthWidth = Utils.measureTextWidth( @@ -135,13 +112,13 @@ export class DatePickerCaption extends React.PureComponent) => { - const month = parseInt((e.target as HTMLSelectElement).value, 10); - BlueprintUtils.safeInvoke(this.props.onMonthChange, month); - }; - - private handleYearSelectChange = (e: React.FormEvent) => { - const year = parseInt((e.target as HTMLSelectElement).value, 10); - BlueprintUtils.safeInvoke(this.props.onYearChange, year); - }; + private dateChangeHandler(updater: (date: Date, value: number) => void, handler?: (value: number) => void) { + return (e: React.FormEvent) => { + const value = parseInt((e.target as HTMLSelectElement).value, 10); + const newDate = clone(this.props.date); + updater(newDate, value); + Utils.safeInvoke(this.props.onDateChange, newDate); + Utils.safeInvoke(handler, value); + }; + } } From 3162e534fd91740d561cc409517cabde9fb0e7b8 Mon Sep 17 00:00:00 2001 From: Gilad Gray Date: Thu, 9 Aug 2018 15:11:37 -0700 Subject: [PATCH 03/19] DatePickerNavbar renders prev/next Buttons use Button for another reduction in styles --- packages/datetime/src/_datepicker.scss | 43 +++++++----------- packages/datetime/src/common/classes.ts | 1 + packages/datetime/src/datePicker.tsx | 8 +++- packages/datetime/src/datePickerCaption.tsx | 10 +++-- packages/datetime/src/datePickerNavbar.tsx | 48 +++++++++++++++++++++ 5 files changed, 77 insertions(+), 33 deletions(-) create mode 100644 packages/datetime/src/datePickerNavbar.tsx diff --git a/packages/datetime/src/_datepicker.scss b/packages/datetime/src/_datepicker.scss index b94be84eba..94246e4d3d 100644 --- a/packages/datetime/src/_datepicker.scss +++ b/packages/datetime/src/_datepicker.scss @@ -51,34 +51,8 @@ $header-margin: ($header-height - $pt-input-height) / 2 !default; } } - .DayPicker-NavBar { - position: relative; - } - - .DayPicker-NavButton { - @include pt-icon-colors(); - position: absolute; - top: -$datepicker-header-margin; - cursor: pointer; - padding: $datepicker-header-margin + 1; - - &--prev { - left: -$datepicker-header-margin; - - &::before { - @include pt-icon(); - content: $pt-icon-chevron-left; - } - } - - &--next { - right: -$datepicker-header-margin; - - &::before { - @include pt-icon(); - content: $pt-icon-chevron-right; - } - } + .DayPicker-Caption { + display: table-caption; } .DayPicker-Weekdays { @@ -162,6 +136,19 @@ $header-margin: ($header-height - $pt-input-height) / 2 !default; } } +.#{$ns}-datepicker-navbar { + display: flex; + align-items: center; + position: absolute; + top: 0; + width: 100%; + height: $pt-button-height; + + > :first-child { + margin-right: auto; + } +} + .#{$ns}-datepicker-caption { @include pt-flex-container(row); justify-content: space-between; diff --git a/packages/datetime/src/common/classes.ts b/packages/datetime/src/common/classes.ts index ef7df8b5a7..e2df243100 100644 --- a/packages/datetime/src/common/classes.ts +++ b/packages/datetime/src/common/classes.ts @@ -23,6 +23,7 @@ export const DATEPICKER_DAY_SELECTED = `${DATEPICKER_DAY}--selected`; export const DATEPICKER_FOOTER = `${DATEPICKER}-footer`; export const DATEPICKER_MONTH_SELECT = `${DATEPICKER}-month-select`; export const DATEPICKER_YEAR_SELECT = `${DATEPICKER}-year-select`; +export const DATEPICKER_NAVBAR = `${DATEPICKER}-navbar`; export const DATERANGEPICKER = `${NS}-daterangepicker`; export const DATERANGEPICKER_CONTIGUOUS = `${DATERANGEPICKER}-contiguous`; diff --git a/packages/datetime/src/datePicker.tsx b/packages/datetime/src/datePicker.tsx index 92bf117828..c6fd21b736 100644 --- a/packages/datetime/src/datePicker.tsx +++ b/packages/datetime/src/datePicker.tsx @@ -7,13 +7,14 @@ import { AbstractPureComponent, Button, DISPLAYNAME_PREFIX, IProps, Utils } from "@blueprintjs/core"; import classNames from "classnames"; import * as React from "react"; -import DayPicker, { CaptionElementProps, DayModifiers, DayPickerProps } from "react-day-picker"; +import DayPicker, { CaptionElementProps, DayModifiers, DayPickerProps, NavbarElementProps } from "react-day-picker"; import * as Classes from "./common/classes"; import * as DateUtils from "./common/dateUtils"; import * as Errors from "./common/errors"; import { DatePickerCaption } from "./datePickerCaption"; import { getDefaultMaxDate, getDefaultMinDate, IDatePickerBaseProps } from "./datePickerCore"; +import { DatePickerNavbar } from "./datePickerNavbar"; export interface IDatePickerProps extends IDatePickerBaseProps, IProps { /** @@ -115,6 +116,7 @@ export class DatePicker extends AbstractPureComponent ); + private renderNavbar = (props: NavbarElementProps) => ( + + ); + private renderOptionsBar() { return (
diff --git a/packages/datetime/src/datePickerCaption.tsx b/packages/datetime/src/datePickerCaption.tsx index 7dd85205e3..56cf60aca3 100644 --- a/packages/datetime/src/datePickerCaption.tsx +++ b/packages/datetime/src/datePickerCaption.tsx @@ -18,7 +18,7 @@ export interface IDatePickerCaptionProps extends CaptionElementProps { onMonthChange?: (month: number) => void; onYearChange?: (year: number) => void; /** Callback invoked when the month or year `