From 6d0b32eb337a1315b76b340540afdb4d3d5b58f5 Mon Sep 17 00:00:00 2001 From: Cole Erikson Date: Thu, 17 Sep 2020 11:51:34 -0300 Subject: [PATCH] Refactor and redesign Date Kit --- app/pb_kits/playbook/pb_date/_date.html.erb | 41 +++-- app/pb_kits/playbook/pb_date/_date.jsx | 143 ++++++++++-------- app/pb_kits/playbook/pb_date/_date.scss | 30 ++++ app/pb_kits/playbook/pb_date/date.rb | 26 +++- .../pb_date/docs/_date_alignment.html.erb | 24 +++ .../playbook/pb_date/docs/_date_alignment.jsx | 32 ++++ .../playbook/pb_date/docs/_date_dark.html.erb | 22 +++ .../playbook/pb_date/docs/_date_dark.jsx | 36 +++++ .../pb_date/docs/_date_default.html.erb | 14 +- .../playbook/pb_date/docs/_date_default.jsx | 20 +-- .../pb_date/docs/_date_variants.html.erb | 27 ++++ .../playbook/pb_date/docs/_date_variants.jsx | 39 +++++ app/pb_kits/playbook/pb_date/docs/example.yml | 6 + app/pb_kits/playbook/pb_date/docs/index.js | 3 + spec/pb_kits/playbook/kits/date_spec.rb | 73 +++++---- 15 files changed, 404 insertions(+), 132 deletions(-) create mode 100644 app/pb_kits/playbook/pb_date/docs/_date_alignment.html.erb create mode 100644 app/pb_kits/playbook/pb_date/docs/_date_alignment.jsx create mode 100644 app/pb_kits/playbook/pb_date/docs/_date_dark.html.erb create mode 100644 app/pb_kits/playbook/pb_date/docs/_date_dark.jsx create mode 100644 app/pb_kits/playbook/pb_date/docs/_date_variants.html.erb create mode 100644 app/pb_kits/playbook/pb_date/docs/_date_variants.jsx diff --git a/app/pb_kits/playbook/pb_date/_date.html.erb b/app/pb_kits/playbook/pb_date/_date.html.erb index b9eeb04d3c..3d1bef7725 100644 --- a/app/pb_kits/playbook/pb_date/_date.html.erb +++ b/app/pb_kits/playbook/pb_date/_date.html.erb @@ -1,14 +1,37 @@ <%= content_tag(:div, id: object.id, data: object.data, - class: object.classname) do %> - <% if object.size == "lg" %> - <%= pb_rails("title", props: { text: object.lg_date, size: 3 }) %> - <% elsif object.size == "sm" %> - <%= pb_rails("icon", props: { icon: "calendar", fixed_width: true }) %> - <%= pb_rails("title", props: { tag: "span", text: object.sm_date, size: 4 }) %> - <% else %> - <%= pb_rails("title", props: { text: object.xs_date, size: 4 }) %> + class: object.classname, + aria: object.aria) do %> + + + <% if object.show_icon %> + <%= pb_rails("body", props: { + color: "light", + tag: "div", + }) do %> + <%= pb_rails("icon", props: { icon: "calendar-alt", fixed_width: true }) %> + <% end %> + <% end %> + + + <% if object.show_day_of_week %> + <%= pb_rails("title", props: { tag: "div", text: object.day_of_week, size: 4 }) %> + <%= pb_rails("body", props: { + text: "•", + color: "light", + tag: "div", + }) %> <% end %> -<% end %> + + + <%# if not current year %> + <% if object.year.to_s == DateTime.now.year.to_s %> + <%= pb_rails("title", props: { tag: "div", text: "#{object.month} #{object.day}", size: 4 }) %> + <%# if is current year %> + <% else %> + <%= pb_rails("title", props: { tag: "div", text: "#{object.month} #{object.day}, #{object.year}", size: 4 }) %> + <% end %> + +<% end %> diff --git a/app/pb_kits/playbook/pb_date/_date.jsx b/app/pb_kits/playbook/pb_date/_date.jsx index e6cdf813f1..255579e603 100644 --- a/app/pb_kits/playbook/pb_date/_date.jsx +++ b/app/pb_kits/playbook/pb_date/_date.jsx @@ -2,82 +2,93 @@ import React from 'react' import DateTime from '../pb_kit/dateTime.js' -import { Icon } from '../' +import { Body, Icon, Title } from '../' import classnames from 'classnames' import { globalProps } from '../utilities/globalProps.js' +import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props' -const defaultDateString = (value: DateTime) => { - const weekday = value.toWeekday().toUpperCase() - const month = value.toMonth().toUpperCase() - const day = value.toDay() - - return `${weekday} · ${month} ${day}` -} - -const largeDateString = (value: DateTime) => { - const month = value.toMonth().toUpperCase() - const day = value.toDay() - - return `${month} ${day}` -} - -type DateSubcomponent = { - value: DateTime, +type PbDateProps = { + alignment?: "left" | "center" | "right", + aria: Object, + className?: string, + data?: Object, + id?: string, + showDayOfWeek?: boolean, + showIcon?: boolean, + value: string | date, } -const ExtraSmallDate = ({ value, ...props }: DateSubcomponent) => ( -

- {defaultDateString(value)} -

-) +const PbDate = (props: PbDateProps) => { + const { + aria = {}, + alignment = 'left', + className, + data = {}, + id, + showDayOfWeek = false, + showIcon = false, + value, + } = props -const SmallDate = ({ value, ...props }: DateSubcomponent) => ( -

- - {defaultDateString(value)} -

-) + const dateTimestamp = new DateTime({ value: value }) + const weekday = dateTimestamp.toWeekday() + const month = dateTimestamp.toMonth() + const day = dateTimestamp.toDay() + const year = dateTimestamp.toYear() + const currentYear = new Date().getFullYear().toString() -const LargeDate = ({ value, ...props }: DateSubcomponent) => ( -

- {largeDateString(value)} -

-) + const ariaProps = buildAriaProps(aria) + const dataProps = buildDataProps(data) -type PbDateProps = { - size?: "xs" | "sm" | "lg", - value?: string, - className?: string -} - -const PbDate = ({ size, value, className, ...props }: PbDateProps) => { - const date = new DateTime({ value: value }) + const classes = classnames( + buildCss('pb_date_kit', alignment), + globalProps(props), + className + ) - if (size == 'xs') - return ( - - ) - if (size == 'lg') - return ( - - ) return ( - +
+ + <If condition={showIcon}> + <Body + className="pb_icon_kit_container" + color="light" + tag="span" + > + <Icon + fixedWidth + icon="calendar-alt" + /> + </Body> + </If> + <If condition={showDayOfWeek}> + {weekday} + <Body + color="light" + tag="span" + text=" • " + /> + </If> + <span> + {month} + {' '} + {day} + </span> + <If condition={currentYear != year}> + <span> + {`, ${year}`} + </span> + </If> + +
) } diff --git a/app/pb_kits/playbook/pb_date/_date.scss b/app/pb_kits/playbook/pb_date/_date.scss index 8608cc66ef..56efa4a0b1 100644 --- a/app/pb_kits/playbook/pb_date/_date.scss +++ b/app/pb_kits/playbook/pb_date/_date.scss @@ -1,2 +1,32 @@ @import "../pb_icon/icon"; @import "../pb_title/title"; + +[class^=pb_date_kit] { + display: flex; + flex-direction: row; + align-items: center; + > div, .pb_icon_kit_container { + margin-right: 4px !important; + } + + &[class*=_center] { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + margin-right: 4px !important; + } + + &[class*=_right] { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-end; + margin-left: 4px !important; + } + &.dark { + [class^=pb_title_kit] { + color: $text_dk_default !important; + } + } +} \ No newline at end of file diff --git a/app/pb_kits/playbook/pb_date/date.rb b/app/pb_kits/playbook/pb_date/date.rb index 4e45c0b21c..561b35ede1 100644 --- a/app/pb_kits/playbook/pb_date/date.rb +++ b/app/pb_kits/playbook/pb_date/date.rb @@ -10,25 +10,37 @@ class Date partial "pb_date/date" prop :date, required: true + prop :alignment, type: Playbook::Props::Enum, + values: %w[left center right], + default: "left" + prop :show_icon, type: Playbook::Props::Boolean, + default: false + prop :show_day_of_week, type: Playbook::Props::Boolean, + default: false + # Size to be deprecated. prop :size, type: Playbook::Props::Enum, values: %w[lg sm xs], default: "sm" prop :timezone, default: "America/New_York" def classname - generate_classname("pb_date_kit") + generate_classname("pb_date_kit", alignment) end - def xs_date - "#{pb_date_time.to_day_of_week.upcase} · #{pb_date_time.to_month.upcase} #{pb_date_time.to_day}".html_safe + def day_of_week + pb_date_time.to_day_of_week end - def lg_date - "#{pb_date_time.to_month.upcase} #{pb_date_time.to_day}" + def day + pb_date_time.to_day end - def sm_date - "#{pb_date_time.to_day_of_week.upcase} · #{pb_date_time.to_month.upcase} #{pb_date_time.to_day}".html_safe + def month + pb_date_time.to_month.capitalize + end + + def year + pb_date_time.to_year end private diff --git a/app/pb_kits/playbook/pb_date/docs/_date_alignment.html.erb b/app/pb_kits/playbook/pb_date/docs/_date_alignment.html.erb new file mode 100644 index 0000000000..333bc66cfb --- /dev/null +++ b/app/pb_kits/playbook/pb_date/docs/_date_alignment.html.erb @@ -0,0 +1,24 @@ + <%= pb_rails("date", props: { + date: DateTime.now, + show_icon: true, + show_day_of_week: true + }) %> + +

+ + <%= pb_rails("date", props: { + date: DateTime.now, + show_icon: true, + show_day_of_week: true, + alignment: "center" + }) %> + +

+ + <%= pb_rails("date", props: { + date: DateTime.now, + show_icon: true, + show_day_of_week: true, + alignment: "right" + }) %> + \ No newline at end of file diff --git a/app/pb_kits/playbook/pb_date/docs/_date_alignment.jsx b/app/pb_kits/playbook/pb_date/docs/_date_alignment.jsx new file mode 100644 index 0000000000..862bc573b4 --- /dev/null +++ b/app/pb_kits/playbook/pb_date/docs/_date_alignment.jsx @@ -0,0 +1,32 @@ +import React from 'react' +import { Date as FormattedDate } from '../..' + +const DateAlignment = () => { + return ( +
+ + +
+ + + +
+ + +
+ ) +} + +export default DateAlignment diff --git a/app/pb_kits/playbook/pb_date/docs/_date_dark.html.erb b/app/pb_kits/playbook/pb_date/docs/_date_dark.html.erb new file mode 100644 index 0000000000..dea5bf5e5c --- /dev/null +++ b/app/pb_kits/playbook/pb_date/docs/_date_dark.html.erb @@ -0,0 +1,22 @@ +<%= pb_rails("date", props: { + dark: true, + date: Date.today, + show_icon: true, +}) %> + +
+ +<%= pb_rails("date", props: { + dark: true, + date: "2012-08-02T15:49:29Z", + show_icon: true, +}) %> + +
+ +<%= pb_rails("date", props: { + dark: true, + date: "2017-12-02T15:49:29Z", + show_day_of_week: true, + show_icon: true, +}) %> diff --git a/app/pb_kits/playbook/pb_date/docs/_date_dark.jsx b/app/pb_kits/playbook/pb_date/docs/_date_dark.jsx new file mode 100644 index 0000000000..d620d02333 --- /dev/null +++ b/app/pb_kits/playbook/pb_date/docs/_date_dark.jsx @@ -0,0 +1,36 @@ +import React from 'react' +import { Date as FormattedDate } from '../../' + +const DateDark = () => { + return ( +
+ + +
+ + + +
+ + +
+ ) +} + +export default DateDark + +// *Development Note* - We are reviewing this kit for a potential name change due to naming collisions when `new Date()` is used. +// To avoid this bug, please use name spacing as shown in the code examples. ie `import { Date as AliasedComponentName } from '../../' diff --git a/app/pb_kits/playbook/pb_date/docs/_date_default.html.erb b/app/pb_kits/playbook/pb_date/docs/_date_default.html.erb index 4162174fc4..0299dc5185 100644 --- a/app/pb_kits/playbook/pb_date/docs/_date_default.html.erb +++ b/app/pb_kits/playbook/pb_date/docs/_date_default.html.erb @@ -1,24 +1,16 @@ <%= pb_rails("date", props: { date: Date.today, - size: "lg" }) %>
<%= pb_rails("date", props: { - date: DateTime.now + date: "2012-08-02T15:49:29Z", }) %>
<%= pb_rails("date", props: { - date: DateTime.now, - timezone: "Asia/Tokyo" -}) %> - -
- -<%= pb_rails("date", props: { - date: Date.new(2010, 11, 12), - size: "xs" + date: "2017-12-02T15:49:29Z", + show_day_of_week: true }) %> diff --git a/app/pb_kits/playbook/pb_date/docs/_date_default.jsx b/app/pb_kits/playbook/pb_date/docs/_date_default.jsx index dda6f0dc0f..48b23bb057 100644 --- a/app/pb_kits/playbook/pb_date/docs/_date_default.jsx +++ b/app/pb_kits/playbook/pb_date/docs/_date_default.jsx @@ -1,28 +1,30 @@ import React from 'react' -import { Date } from '../../' +import { Date as FormattedDate } from '../../' const DateDefault = () => { return (
-
-
-
) } export default DateDefault + +// *Development Note* - We are reviewing this kit for a potential name change due to naming collisions when `new Date()` is used. +// To avoid this bug, please use name spacing as shown in the code examples. ie `import { Date as AliasedComponentName } from '../../' diff --git a/app/pb_kits/playbook/pb_date/docs/_date_variants.html.erb b/app/pb_kits/playbook/pb_date/docs/_date_variants.html.erb new file mode 100644 index 0000000000..1712128d18 --- /dev/null +++ b/app/pb_kits/playbook/pb_date/docs/_date_variants.html.erb @@ -0,0 +1,27 @@ +
+ <%= pb_rails("date", props: { + date: DateTime.now, + }) %> + +

+ + <%= pb_rails("date", props: { + date: DateTime.now, + show_icon: true + }) %> + +

+ + <%= pb_rails("date", props: { + date: DateTime.now, + show_day_of_week: true + }) %> + +

+ + <%= pb_rails("date", props: { + date: DateTime.now, + show_icon: true, + show_day_of_week: true + }) %> +
\ No newline at end of file diff --git a/app/pb_kits/playbook/pb_date/docs/_date_variants.jsx b/app/pb_kits/playbook/pb_date/docs/_date_variants.jsx new file mode 100644 index 0000000000..ebc6b21426 --- /dev/null +++ b/app/pb_kits/playbook/pb_date/docs/_date_variants.jsx @@ -0,0 +1,39 @@ +import React from 'react' +import { Date as FormattedDate } from '../..' + +const DateVariants = () => { + return ( +
+ + +
+
+ + + +
+
+ + + +
+
+ + +
+ ) +} + +export default DateVariants diff --git a/app/pb_kits/playbook/pb_date/docs/example.yml b/app/pb_kits/playbook/pb_date/docs/example.yml index 733e7ff3de..ce88fabf3a 100644 --- a/app/pb_kits/playbook/pb_date/docs/example.yml +++ b/app/pb_kits/playbook/pb_date/docs/example.yml @@ -2,9 +2,15 @@ examples: rails: - date_default: Default + - date_variants: Variants + - date_alignment: Alignment - date_timezone: Timezones + - date_dark: Dark react: - date_default: Default + - date_variants: Variants + - date_alignment: Alignment + - date_dark: Dark diff --git a/app/pb_kits/playbook/pb_date/docs/index.js b/app/pb_kits/playbook/pb_date/docs/index.js index 9ea88e1264..7566a5cf71 100644 --- a/app/pb_kits/playbook/pb_date/docs/index.js +++ b/app/pb_kits/playbook/pb_date/docs/index.js @@ -1 +1,4 @@ export { default as DateDefault } from './_date_default.jsx' +export { default as DateVariants } from './_date_variants.jsx' +export { default as DateAlignment } from './_date_alignment.jsx' +export { default as DateDark } from './_date_dark.jsx' diff --git a/spec/pb_kits/playbook/kits/date_spec.rb b/spec/pb_kits/playbook/kits/date_spec.rb index 657ded4031..9112827653 100644 --- a/spec/pb_kits/playbook/kits/date_spec.rb +++ b/spec/pb_kits/playbook/kits/date_spec.rb @@ -7,63 +7,73 @@ it { is_expected.to define_partial } + it { is_expected.to define_enum_prop(:alignment) + .with_values("left", "center", "right") + .with_default("left") } it { is_expected.to define_prop(:date) } - it { is_expected.to define_prop(:timezone) } + it { is_expected.to define_boolean_prop(:show_icon) + .with_default(false) } it do is_expected.to define_enum_prop(:size) - .with_default("sm") - .with_values("lg", "sm", "xs") - end + .with_default("sm") + .with_values("lg", "sm", "xs") + end + it { is_expected.to define_boolean_prop(:show_day_of_week) + .with_default(false) } + it { is_expected.to define_prop(:timezone) } - describe "#xs_date" do + describe "#day_of_week" do it "displays the date" do expect(subject.new( date: Date.new(2019, 10, 31), - size: "xs" - ).xs_date).to include "OCT 31" + ).day_of_week).to include "Thu" end end - describe "#sm_date" do - it "displays the date" do + describe "#day" do + it "displays the day" do expect(subject.new( - date: Date.new(2019, 10, 20), - size: "sm" - ).sm_date).to include "OCT 20" + date: Date.new(2020, 9, 15), + ).day).to eq("15") end end - describe "#lg_date" do - it "displays the date" do + describe "#month" do + it "displays the month" do expect(subject.new( date: Date.new(2019, 10, 19), - size: "lg" - ).lg_date).to include "OCT 19" + ).month).to eq("Oct") + end + end + + describe "#year" do + it "displays the year" do + expect(subject.new( + date: Date.new(2019, 12, 19), + ).year).to eq("2019") end end describe "#timezones" do - it "displays the date respecting EST timezone" do + it "displays the next day based on Timezone" do expect(subject.new( - date: DateTime.new(2019, 10, 19), - size: "lg", - ).lg_date).to include "OCT 18" + date: DateTime.new(2020, 12, 31, 16, 12, 12), + timezone: "Australia/Sydney" + ).day).to eq(" 1") end - it "displays the date respecting Syndey Australia TZ" do + it "displays the next month based on Timezone" do expect(subject.new( - date: DateTime.new(2019, 10, 19), - size: "lg", + date: DateTime.new(2019, 12, 31, 16, 12, 12), timezone: "Australia/Sydney" - ).lg_date).to include "OCT 19" + ).month).to eq("Jan") end - it "displays the date respecting Syndey Australia TZ with Time" do + it "displays the next year based on Timezone" do expect(subject.new( - date: DateTime.new(2019, 10, 19, 14, 4, 4), - size: "lg", + date: DateTime.new(2019, 12, 31, 16, 12, 12), timezone: "Australia/Sydney" - ).lg_date).to include "OCT 20" + ).year).to eq("2020") end end @@ -71,8 +81,11 @@ it "returns namespaced class name", :aggregate_failures do required_props = { date: Date.today } - expect(subject.new(required_props).classname).to eq "pb_date_kit" - expect(subject.new(required_props.merge(classname: "additional_class")).classname).to eq "pb_date_kit additional_class" + expect(subject.new(required_props).classname).to eq "pb_date_kit_left" + expect(subject.new(required_props.merge(alignment: "center")).classname).to eq "pb_date_kit_center" + expect(subject.new(required_props.merge(alignment: "right")).classname).to eq "pb_date_kit_right" + expect(subject.new(required_props.merge(dark: true)).classname).to eq "pb_date_kit_left dark" + expect(subject.new(required_props.merge(classname: "additional_class")).classname).to eq "pb_date_kit_left additional_class" end end end