playbook_ui 12.23.0 → 12.24.0.pre.alpha.PLAY603datepickerquickpickinputpresetdropdown752

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 = ''