playbook_ui 12.23.0 → 12.24.0.pre.alpha.PLAY603datepickerquickpickinputpresetdropdown752

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_swift.md +1 -0
  3. data/app/pb_kits/playbook/pb_avatar/docs/example.yml +2 -0
  4. data/app/pb_kits/playbook/pb_card/_card.tsx +1 -0
  5. data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +26 -0
  6. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +99 -95
  7. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +3 -2
  8. data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +1 -1
  9. data/app/pb_kits/playbook/pb_date_picker/date_picker.test.js +44 -1
  10. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +34 -2
  11. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick.html.erb +8 -0
  12. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick.jsx +18 -0
  13. data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +2 -0
  14. data/app/pb_kits/playbook/pb_date_picker/docs/index.js +2 -1
  15. data/app/pb_kits/playbook/pb_date_picker/plugins/quickPick.tsx +168 -0
  16. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_calendar_input_icon.scss +3 -2
  17. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_quick_pick_styles.scss +75 -0
  18. data/app/pb_kits/playbook/pb_docs/kit_example.html.erb +6 -1
  19. data/app/pb_kits/playbook/pb_docs/kit_example.rb +13 -4
  20. data/app/pb_kits/playbook/pb_nav/_item.tsx +1 -1
  21. data/app/pb_kits/playbook/pb_nav/_subtle_mixin.scss +1 -1
  22. data/app/pb_kits/playbook/pb_title/_title.scss +1 -0
  23. data/app/pb_kits/playbook/pb_title/docs/_title_light_weight.html.erb +1 -0
  24. data/app/pb_kits/playbook/pb_title/docs/_title_light_weight.jsx +11 -6
  25. data/app/pb_kits/playbook/pb_title/docs/_title_light_weight.md +2 -2
  26. data/app/pb_kits/playbook/tokens/_screen_sizes.scss +19 -0
  27. data/app/pb_kits/playbook/utilities/_spacing.scss +27 -1
  28. data/app/pb_kits/playbook/utilities/globalProps.ts +61 -16
  29. data/dist/playbook-rails.js +323 -0
  30. data/lib/playbook/pb_doc_helper.rb +4 -1
  31. data/lib/playbook/spacing.rb +20 -5
  32. data/lib/playbook/version.rb +2 -2
  33. data/lib/playbook.rb +1 -2
  34. metadata +17 -41
  35. data/app/pb_kits/playbook/pb_docs/kit_api.html.erb +0 -311
  36. data/app/pb_kits/playbook/pb_docs/kit_api.rb +0 -149
  37. data/lib/playbook/markdown/helper.rb +0 -132
  38. data/lib/playbook/markdown.rb +0 -3
@@ -0,0 +1,168 @@
1
+ import moment from 'moment'
2
+
3
+ type FpTypes = {
4
+ setDate: (arg0: any, arg1: boolean) => void,
5
+ config: { [key: string]: string },
6
+ clear: (arg0: boolean, arg1: boolean) => void,
7
+ close: () => void,
8
+ calendarContainer?: {
9
+ classList: { add: (arg0: string) => void };
10
+ prepend: (arg0: HTMLDivElement) => void;
11
+ append: (arg0: HTMLDivElement) => void;
12
+ },
13
+ loadedPlugins: string[],
14
+ };
15
+
16
+ type pluginDataType = {
17
+ ranges: { [key: string]: Date[] },
18
+ rangesNav: HTMLUListElement,
19
+ rangesButtons: [] | any,
20
+ }
21
+
22
+ const quickPickPlugin = () => {
23
+ return function (fp: FpTypes & any): any {
24
+
25
+ let activeLabel = ""
26
+
27
+ // variable that holds the ranges available
28
+ const ranges = {
29
+ 'Today': [new Date(), new Date()],
30
+ 'Yesterday': [moment().subtract(1, 'days').toDate(), moment().subtract(1, 'days').toDate()],
31
+ 'This week': [moment().startOf('week').toDate(), moment().endOf('week').toDate()],
32
+ 'This month': [moment().startOf('month').toDate(), new Date()],
33
+ 'This quarter': [moment().startOf('quarter').toDate(), new Date()],
34
+ 'This year': [moment().startOf('year').toDate(), new Date()],
35
+ 'Last week': [
36
+ moment().subtract(1, 'week').startOf('week').toDate(),
37
+ moment().subtract(1, 'week').endOf('week').toDate()
38
+ ],
39
+ 'Last month': [
40
+ moment().subtract(1, 'month').startOf('month').toDate(),
41
+ moment().subtract(1, 'month').endOf('month').toDate()
42
+ ],
43
+ 'Last quarter': [
44
+ moment().subtract(1, 'quarter').startOf('quarter').toDate(),
45
+ moment().subtract(1, 'quarter').endOf('quarter').toDate()
46
+ ],
47
+ 'Last year': [
48
+ moment().subtract(1, 'year').startOf('year').toDate(),
49
+ moment().subtract(1, 'year').endOf('year').toDate()
50
+ ]
51
+ }
52
+ //creating the ul element for the nav dropdown and giving it classnames
53
+ const rangesNav = document.createElement('ul');
54
+
55
+ // creating the pluginData object that will hold the properties of this plugin
56
+ const pluginData: pluginDataType = {
57
+ ranges: ranges,
58
+ rangesNav: rangesNav,
59
+ rangesButtons: [],
60
+ };
61
+
62
+ /**
63
+ * @param {string} label
64
+ * @returns HTML Element
65
+ */
66
+
67
+ //function for creating the range buttons in the nav
68
+ const addRangeButton = (label: string) => {
69
+
70
+ // creating new elements to mimick selectable card component
71
+ const div2 = document.createElement('div');
72
+ div2.className = "nav-item-link"
73
+ div2.innerHTML = label;
74
+
75
+ pluginData.rangesButtons[label] = div2;
76
+
77
+ // create li elements inside the dropdown
78
+ const item = document.createElement('li');
79
+ item.className = "nav-item";
80
+
81
+ // append those nav items to the li items
82
+ item.appendChild(pluginData.rangesButtons[label]);
83
+
84
+ // append the li item to the ul rangeNav prop
85
+ pluginData.rangesNav.appendChild(item);
86
+
87
+ // return the ranges buton prop
88
+ return pluginData.rangesButtons[label];
89
+ };
90
+
91
+ const selectActiveRangeButton = (selectedDates: Array<string>) => {
92
+ const current = pluginData.rangesNav.querySelector('.active');
93
+
94
+ if (current) {
95
+ current.classList.remove('active');
96
+ }
97
+ /** conditional statment to extract start and end dates from selectedDates,
98
+ * then loop through ranges prop in pluginData
99
+ * and check if chosen dates equal to a date in the ranges prop
100
+ * if they are equal, add the active class
101
+ */
102
+ if (selectedDates.length > 0 && activeLabel) {
103
+ // const selected = pluginData.rangesNav.querySelectorAll(".nav-item-link")
104
+ // selected.forEach(el => {
105
+ // if (el.innerHTML === activeLabel)
106
+ // el.classList.add('active')
107
+ // return
108
+ // })
109
+
110
+ pluginData.rangesButtons[activeLabel].classList.add('active');
111
+ }
112
+ }
113
+
114
+
115
+ return {
116
+ // onReady is a hook from flatpickr that runs when calender is in a ready state
117
+ onReady(selectedDates: Array<string>) {
118
+ // loop through the ranges and create an anchor tag for each range and add an event listener to set the date when user clicks on a date range
119
+ for (const [label, range] of Object.entries(pluginData.ranges)) {
120
+ addRangeButton(label).addEventListener('click', function () {
121
+
122
+ const start = moment(range[0]).toDate();
123
+ const end = moment(range[1]).toDate();
124
+
125
+ if (!start) {
126
+ fp.clear();
127
+ }
128
+ else {
129
+ activeLabel = label
130
+ fp.setDate([start, end], true);
131
+ fp.close();
132
+ }
133
+
134
+ });
135
+ }
136
+ // conditional to check if there is a dropdown to add it to the calendar container and get it the classes it needs
137
+ if (pluginData.rangesNav.children.length > 0) {
138
+
139
+ fp.calendarContainer.prepend(pluginData.rangesNav);
140
+ pluginData.rangesNav.classList.add('quick-pick-ul')
141
+ fp.calendarContainer.classList.add('quick-pick-drop-down');
142
+
143
+ /**
144
+ *
145
+ * @param {Array} selectedDates
146
+ */
147
+ // function to give the active button the active class
148
+ debugger
149
+ selectActiveRangeButton(selectedDates);
150
+ }
151
+
152
+ },
153
+ onValueUpdate(selectedDates: Array<string>) {
154
+ debugger
155
+ selectActiveRangeButton(selectedDates);
156
+ },
157
+
158
+ onClose(selectedDates: Array<string>) {
159
+ // set the input value to the selected dates when the dropdown is closed
160
+ if (selectedDates.length < 2 && selectedDates.length > 0) {
161
+ fp.input.placeholder = fp.formatDate(this.selectedDates[0], fp.config.dateFormat);
162
+ }
163
+ }
164
+ };
165
+ };
166
+ }
167
+
168
+ export default quickPickPlugin;
@@ -1,3 +1,4 @@
1
+ @import "../../tokens/colors";
1
2
  // Calendar Icon Styles
2
3
  .cal_icon_wrapper {
3
4
  pointer-events: none;
@@ -13,8 +14,8 @@
13
14
  padding-left: $space_sm - 1;
14
15
  color: $text_lt_light;
15
16
  @media (hover: hover) {
16
- &:hover {
17
- cursor: pointer;
17
+ &:hover{
18
+ background-color: rgba($focus_input_light,$opacity_5);
18
19
  }
19
20
  }
20
21
  &.dark {
@@ -0,0 +1,75 @@
1
+ @import "../../tokens/animation-curves";
2
+ @import "../../tokens/colors";
3
+ @import "../../tokens/typography";
4
+ @import "../../tokens/titles";
5
+ @import "../../tokens/spacing";
6
+
7
+ $pb_card_border_width: 1px;
8
+ $pb_card_border_radius: $border_rad_heavier;
9
+
10
+ // used to display dropdown on the left of the calender
11
+ .quick-pick-drop-down {
12
+ width: auto;
13
+ display: grid;
14
+ }
15
+
16
+ .quick-pick-ul {
17
+ padding: $space_xs 0px;
18
+ margin: 0;
19
+ list-style: none;
20
+ }
21
+
22
+ .nav-item {
23
+ list-style: none;
24
+ border-radius: 6px;
25
+ border-bottom: 0;
26
+ margin: $space_xs $space_sm;
27
+ }
28
+
29
+ .nav-item-link {
30
+ text-decoration: none;
31
+ border-width: $pb_card_border_width;
32
+ border-style: solid;
33
+ border-color: $border_light;
34
+ border-radius: $pb_card_border_radius;
35
+ padding: $space_xs 14px;
36
+ transition-property: color, background-color;
37
+ transition-duration: 0.15s;
38
+ transition-timing-function: $bezier;
39
+ line-height: 1.4;
40
+ color: $charcoal;
41
+ font-size: $font_default;
42
+ font-weight: $regular;
43
+ &.active {
44
+ border-width: 2px;
45
+ border-color: $primary;
46
+ }
47
+ @media (hover:hover) {
48
+ &:hover {
49
+ cursor: pointer;
50
+ box-shadow: $shadow-deep;
51
+ border-color: $slate;
52
+ }
53
+ }
54
+ }
55
+
56
+ // Hide the calendar
57
+ .quick-pick-drop-down > .flatpickr-months, .quick-pick-drop-down > .flatpickr-innerContainer {
58
+ display: none;
59
+ }
60
+
61
+ @media only screen and (max-width: 767px) {
62
+ .quick-pick-ul {
63
+ padding: $space_xs $space_xs;
64
+ display: grid;
65
+ grid-template-columns: 1fr 1fr;
66
+ }
67
+
68
+ .nav-item {
69
+ margin: $space_xxs $space_xs;
70
+ }
71
+
72
+ .nav-item-link {
73
+ padding: $space_xs $space_xxs;
74
+ }
75
+ }
@@ -7,7 +7,12 @@
7
7
  <%= example %>
8
8
  <br>
9
9
  </div>
10
-
10
+
11
+ <% if (action_name == "kit_show_swift") %>
12
+ <div class="pb--kit-example-markdown pt_none <%= dark ? "dark" : "" %>">
13
+ <%= render_markdown(description) %>
14
+ </div>
15
+ <% end %>
11
16
  <% if show_code %>
12
17
  <div class="markdown pb--kit-example-markdown <%= dark ? "dark" : "" %>">
13
18
  <%= render_markdown(description) %>
@@ -5,13 +5,11 @@
5
5
  module Playbook
6
6
  module PbDocs
7
7
  class KitExample < Playbook::KitBase
8
- include Playbook::Markdown::Helper
9
-
10
8
  prop :kit, type: Playbook::Props::String, required: true
11
9
  prop :example_title, type: Playbook::Props::String, required: true
12
10
  prop :example_key, type: Playbook::Props::String, required: true
13
11
  prop :show_code, type: Playbook::Props::Boolean, default: true
14
- prop :type, type: Playbook::Props::Enum, values: %w[rails react], default: "rails"
12
+ prop :type, type: Playbook::Props::Enum, values: %w[rails react swift], default: "rails"
15
13
  prop :dark, type: Playbook::Props::Boolean, default: false
16
14
 
17
15
  def example
@@ -19,6 +17,9 @@ module Playbook
19
17
  render inline: source
20
18
  elsif type == "react"
21
19
  react_component example_key.camelize, { dark: dark }
20
+ elsif type == "swift"
21
+ ## render the markdown file
22
+ render inline: source
22
23
  end
23
24
  end
24
25
 
@@ -32,7 +33,11 @@ module Playbook
32
33
 
33
34
  def source
34
35
  @source ||= begin
35
- extension = type == "react" ? "jsx" : "html.erb"
36
+ extension = if type == "rails"
37
+ "html.erb"
38
+ else
39
+ type == "swift" ? "swift" : "jsx"
40
+ end
36
41
  stringified_code = read_kit_file("docs", "_#{example_key}.#{extension}")
37
42
  sanitize_code(stringified_code)
38
43
  end
@@ -42,6 +47,10 @@ module Playbook
42
47
  read_kit_file("", "_#{example_key}.tsx")
43
48
  end
44
49
 
50
+ def swift_source
51
+ read_kit_file("", "_#{example_key}.swift")
52
+ end
53
+
45
54
  private
46
55
 
47
56
  def sanitize_code(stringified_code)
@@ -87,7 +87,7 @@ const NavItem = (props: NavItemProps) => {
87
87
  <span className="pb_nav_list_item_text">
88
88
  {text || children}
89
89
  </span>
90
-
90
+
91
91
  {iconRight &&
92
92
  <div
93
93
  className="pb_nav_list_item_icon_section"
@@ -44,7 +44,7 @@
44
44
  &[class*=_active] [class*=_link] {
45
45
  @include pb_title_4;
46
46
  color: $primary;
47
- letter-spacing: normal;
47
+ letter-spacing: normal;
48
48
  }
49
49
  }
50
50
  }
@@ -12,6 +12,7 @@
12
12
  &[class*=_2] {
13
13
  @include pb_title_2;
14
14
  @include title_colors;
15
+ @include pb_title_bold;
15
16
  }
16
17
 
17
18
  &[class*=_3] {
@@ -1 +1,2 @@
1
1
  <%= pb_rails("title", props: { text: "Title 1", tag: "h1", size: 1, bold: false }) %>
2
+ <%= pb_rails("title", props: { text: "Title 2", tag: "h2", size: 2, bold: false }) %>
@@ -1,15 +1,20 @@
1
- import React from 'react'
1
+ import React from "react"
2
2
 
3
- import Title from '../_title'
3
+ import Title from "../_title"
4
4
 
5
5
  const TitleLightWeight = (props) => {
6
6
  return (
7
7
  <div>
8
- <Title
9
- bold={false}
8
+ <Title bold={false}
10
9
  size={1}
11
- tag="h1"
12
- text="Title 1"
10
+ tag='h1'
11
+ text='Title 1'
12
+ {...props}
13
+ />
14
+ <Title bold={false}
15
+ size={2}
16
+ tag='h2'
17
+ text='Title 2'
13
18
  {...props}
14
19
  />
15
20
  </div>
@@ -1,4 +1,4 @@
1
1
  ##### Prop
2
- Title `size 1` will use `font-weight: 700` by default, if you want a lighter font weight, use the `bold` prop set to `false`.
3
- Title `size 2` & `size 3` uses a light font weight by default and will not accept a bold font weight.
2
+ Title `size 1` & `size 2` will use `font-weight: 700` by default, if you want a lighter font weight, use the `bold` prop set to `false`.
3
+ Title `size 3` uses a light font weight by default and will not accept a bold font weight.
4
4
  Title `size 4` uses a heavy font weight by default and will not accept a lighter font weight.
@@ -38,6 +38,25 @@ $breakpoints_grid: (
38
38
  )
39
39
  );
40
40
 
41
+ $breakpoints_max_only: (
42
+ xl: (
43
+ max: $screen-xl-max
44
+ ),
45
+ lg: (
46
+ max: $screen-lg-max
47
+ ),
48
+ md: (
49
+ max: $screen-md-max
50
+ ),
51
+ sm: (
52
+ max: $screen-sm-max
53
+ ),
54
+ xs: (
55
+ max: $screen-xs-max,
56
+ )
57
+ );
58
+
59
+
41
60
  @function breakpoint($breakpoint_name) {
42
61
  @return map-get($breakpoints, $breakpoint_name);
43
62
  }
@@ -7,7 +7,10 @@ $space_classes: (
7
7
  md: $space_md,
8
8
  lg: $space_lg,
9
9
  xl: $space_xl,
10
- none: 0
10
+ none: 0,
11
+ auto: auto,
12
+ initial: initial,
13
+ inherit: inherit
11
14
  );
12
15
 
13
16
  $positions: (
@@ -41,3 +44,26 @@ $positions: (
41
44
  }
42
45
  }
43
46
  }
47
+
48
+ @each $size, $size_value in $breakpoints_max_only {
49
+ @each $position_name, $position in $positions {
50
+ @each $space_name, $space in $space_classes {
51
+ $min_size: map-get($size_value, "min");
52
+ $max_size: map-get($size_value, "max");
53
+ .#{$position_name}_#{$size}_#{$space_name} {
54
+ @if type-of($position)=="list" {
55
+ @each $coordinate in $position {
56
+ @include break_at( $max_size) {
57
+ #{$coordinate}: #{$space} !important;
58
+ }
59
+ }
60
+ }
61
+ @else {
62
+ @include break_at( $max_size) {
63
+ #{$position}: #{$space} !important;
64
+ }
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
@@ -22,7 +22,7 @@ type AlignItems = {
22
22
  type AlignSelf = {
23
23
  alignSelf?: Alignment & ("auto" | "stretch" | "baseline")
24
24
  }
25
- type AllSizes = None | Sizes
25
+ type AllSizes = None | Sizes | "auto" | "initial" | "inherit"
26
26
 
27
27
  type BorderRadius = {
28
28
  borderRadius?: "none" | "xs" | "sm" | "md" | "lg" | "xl" | "rounded",
@@ -153,22 +153,67 @@ const PROP_CATEGORIES: {[key:string]: (props: {[key: string]: any}) => string} =
153
153
  padding,
154
154
  }: Margin & Padding) => {
155
155
  let css = ''
156
- css += marginRight ? `mr_${marginRight} ` : ''
157
- css += marginLeft ? `ml_${marginLeft} ` : ''
158
- css += marginTop ? `mt_${marginTop} ` : ''
159
- css += marginBottom ? `mb_${marginBottom} ` : ''
160
- css += marginX ? `mx_${marginX} ` : ''
161
- css += marginY ? `my_${marginY} ` : ''
162
- css += margin ? `m_${margin} ` : ''
163
- css += paddingRight ? `pr_${paddingRight} ` : ''
164
- css += paddingLeft ? `pl_${paddingLeft} ` : ''
165
- css += paddingTop ? `pt_${paddingTop} ` : ''
166
- css += paddingBottom ? `pb_${paddingBottom} ` : ''
167
- css += paddingX ? `px_${paddingX} ` : ''
168
- css += paddingY ? `py_${paddingY} ` : ''
169
- css += padding ? `p_${padding} ` : ''
170
- return css
156
+ const spacingProps = {
157
+ marginRight,
158
+ marginLeft,
159
+ marginTop,
160
+ marginBottom,
161
+ marginX,
162
+ marginY,
163
+ margin,
164
+ paddingRight,
165
+ paddingLeft,
166
+ paddingTop,
167
+ paddingBottom,
168
+ paddingX,
169
+ paddingY,
170
+ padding,
171
+ };
172
+
173
+ function handleObjectValue(properties: Margin | Padding, prefix: string) {
174
+ let classResult = '';
175
+
176
+ Object.entries(properties).forEach(([key, value]) => {
177
+ classResult += `${prefix}_${key}_${value} `;
178
+ });
179
+
180
+ return classResult;
181
+ }
182
+
183
+ function getPrefix(key: string) {
184
+ const prefixes: Record<string, string> = {
185
+ marginRight: 'mr',
186
+ marginLeft: 'ml',
187
+ marginTop: 'mt',
188
+ marginBottom: 'mb',
189
+ marginX: 'mx',
190
+ marginY: 'my',
191
+ margin: 'm',
192
+ paddingRight: 'pr',
193
+ paddingLeft: 'pl',
194
+ paddingTop: 'pt',
195
+ paddingBottom: 'pb',
196
+ paddingX: 'px',
197
+ paddingY: 'py',
198
+ padding: 'p',
199
+ };
200
+
201
+ return prefixes[key];
202
+ }
203
+
204
+ Object.entries(spacingProps).forEach(([key, value]) => {
205
+ if (value) {
206
+ if (typeof value === 'object') {
207
+ css += handleObjectValue(value, getPrefix(key));
208
+ } else {
209
+ const prefix = getPrefix(key);
210
+ css += `${prefix}_${value} `;
211
+ }
212
+ }
213
+ });
214
+ return css.trim();
171
215
  },
216
+
172
217
  darkProps: ({ dark }: Dark) => dark ? 'dark' : '',
173
218
  numberSpacingProps: ({ numberSpacing }: NumberSpacing) => {
174
219
  let css = ''