playbook_ui 12.23.0 → 12.24.0.pre.alpha.PLAY603datepickerquickpickinputpresetdropdown756

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) 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/_date.tsx +96 -42
  6. data/app/pb_kits/playbook/pb_date/date.html.erb +22 -2
  7. data/app/pb_kits/playbook/pb_date/date.rb +2 -0
  8. data/app/pb_kits/playbook/pb_date/docs/_date_unstyled.html.erb +30 -0
  9. data/app/pb_kits/playbook/pb_date/docs/_date_unstyled.jsx +47 -0
  10. data/app/pb_kits/playbook/pb_date/docs/_date_unstyled.md +1 -0
  11. data/app/pb_kits/playbook/pb_date/docs/example.yml +4 -4
  12. data/app/pb_kits/playbook/pb_date/docs/index.js +1 -0
  13. data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +26 -0
  14. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +99 -95
  15. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +3 -2
  16. data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +1 -1
  17. data/app/pb_kits/playbook/pb_date_picker/date_picker.test.js +44 -1
  18. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +34 -2
  19. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick.html.erb +8 -0
  20. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick.jsx +18 -0
  21. data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +2 -0
  22. data/app/pb_kits/playbook/pb_date_picker/docs/index.js +2 -1
  23. data/app/pb_kits/playbook/pb_date_picker/plugins/quickPick.tsx +164 -0
  24. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_calendar_input_icon.scss +3 -2
  25. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_quick_pick_styles.scss +75 -0
  26. data/app/pb_kits/playbook/pb_docs/kit_example.html.erb +6 -1
  27. data/app/pb_kits/playbook/pb_docs/kit_example.rb +13 -4
  28. data/app/pb_kits/playbook/pb_nav/_item.tsx +1 -1
  29. data/app/pb_kits/playbook/pb_nav/_subtle_mixin.scss +1 -1
  30. data/app/pb_kits/playbook/pb_time/_time.tsx +71 -35
  31. data/app/pb_kits/playbook/pb_time/docs/_time_unstyled.html.erb +37 -0
  32. data/app/pb_kits/playbook/pb_time/docs/_time_unstyled.jsx +58 -0
  33. data/app/pb_kits/playbook/pb_time/docs/_time_unstyled.md +1 -0
  34. data/app/pb_kits/playbook/pb_time/docs/example.yml +2 -0
  35. data/app/pb_kits/playbook/pb_time/docs/index.js +1 -0
  36. data/app/pb_kits/playbook/pb_time/time.html.erb +26 -7
  37. data/app/pb_kits/playbook/pb_time/time.rb +2 -0
  38. data/app/pb_kits/playbook/pb_title/_title.scss +3 -1
  39. data/app/pb_kits/playbook/pb_title/_title.tsx +3 -2
  40. data/app/pb_kits/playbook/pb_title/docs/_title_light_weight.html.erb +1 -0
  41. data/app/pb_kits/playbook/pb_title/docs/_title_light_weight.jsx +11 -6
  42. data/app/pb_kits/playbook/pb_title/docs/_title_light_weight.md +2 -2
  43. data/app/pb_kits/playbook/pb_title/title.rb +10 -3
  44. data/app/pb_kits/playbook/pb_title/title.test.js +3 -3
  45. data/app/pb_kits/playbook/tokens/_screen_sizes.scss +19 -0
  46. data/app/pb_kits/playbook/utilities/_spacing.scss +27 -1
  47. data/app/pb_kits/playbook/utilities/globalProps.ts +61 -16
  48. data/dist/playbook-rails.js +323 -0
  49. data/lib/playbook/pb_doc_helper.rb +4 -1
  50. data/lib/playbook/spacing.rb +20 -5
  51. data/lib/playbook/version.rb +2 -2
  52. data/lib/playbook.rb +1 -2
  53. metadata +23 -41
  54. data/app/pb_kits/playbook/pb_docs/kit_api.html.erb +0 -311
  55. data/app/pb_kits/playbook/pb_docs/kit_api.rb +0 -149
  56. data/lib/playbook/markdown/helper.rb +0 -132
  57. data/lib/playbook/markdown.rb +0 -3
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable no-console */
2
2
  import React from 'react'
3
+ import moment from 'moment'
3
4
  import { fireEvent, render, screen, waitFor, within } from '../utilities/test-utils'
4
5
 
5
6
  import DatePicker from './_date_picker'
@@ -10,7 +11,6 @@ import { getTimezoneText } from './plugins/timeSelect'
10
11
  jest.setSystemTime(new Date('01/01/2020'));
11
12
  const DEFAULT_DATE = new Date()
12
13
 
13
-
14
14
  describe('DatePicker Kit', () => {
15
15
  beforeEach(() => {
16
16
  jest.spyOn(console, 'error').mockImplementation(() => { });
@@ -158,4 +158,47 @@ describe('DatePicker Kit', () => {
158
158
  expect(input).toHaveValue('01/01/2020 at 12:00 PM')
159
159
  })
160
160
  })
161
+ test('shows DatePicker QuickPick dropdown and adds correct date to input', async () => {
162
+ const testId = 'datepicker-quick-pick'
163
+ render(
164
+ <DatePicker
165
+ allowInput
166
+ data={{ testid: testId }}
167
+ mode="range"
168
+ pickerId="date-picker-quick-pick"
169
+ placeholder="mm/dd/yyyy → mm/dd/yyyy"
170
+ selectionType="quickpick"
171
+ />
172
+ )
173
+
174
+ const kit = screen.getByTestId(testId)
175
+ const input = within(kit).getByPlaceholderText('mm/dd/yyyy → mm/dd/yyyy')
176
+
177
+ fireEvent(
178
+ input,
179
+ new MouseEvent('click', {
180
+ bubbles: true,
181
+ cancelable: true,
182
+ }),
183
+ )
184
+ const today = within(kit).getByText('Today')
185
+ const thisYear = within(kit).getByText('This year')
186
+ await waitFor(() => {
187
+ expect(today).toBeInTheDocument()
188
+ expect(thisYear).toBeInTheDocument()
189
+ })
190
+
191
+ fireEvent(
192
+ thisYear,
193
+ new MouseEvent('click', {
194
+ bubbles: true,
195
+ cancelable: true,
196
+ }),
197
+ )
198
+
199
+ await waitFor(() => {
200
+ expect(input).toHaveValue(moment().startOf('year').format('MM/DD/YYYY') + " → " + moment().format('MM/DD/YYYY'))
201
+ })
202
+
203
+ })
161
204
  })
@@ -3,6 +3,7 @@ import { BaseOptions } from 'flatpickr/dist/types/options'
3
3
  import monthSelectPlugin from 'flatpickr/dist/plugins/monthSelect'
4
4
  import weekSelect from "flatpickr/dist/plugins/weekSelect/weekSelect"
5
5
  import timeSelectPlugin from './plugins/timeSelect'
6
+ import quickPickPlugin from './plugins/quickPick'
6
7
 
7
8
  const getPositionElement = (element: string | Element) => {
8
9
  return (typeof element === 'string') ? document.querySelectorAll(element)[0] : element
@@ -19,8 +20,8 @@ type DatePickerConfig = {
19
20
  hideIcon?: boolean;
20
21
  inLine?: boolean,
21
22
  onChange: (dateStr: string, selectedDates: Date[]) => void,
23
+ selectionType?: "month" | "week" | "quickpick" | "",
22
24
  onClose: (dateStr: Date[] | string, selectedDates: Date[] | string) => void,
23
- selectionType?: "month" | "week" | "",
24
25
  showTimezone?: boolean,
25
26
  staticPosition: boolean,
26
27
  timeCaption?: string,
@@ -90,18 +91,23 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT
90
91
  }
91
92
 
92
93
  const setPlugins = () => {
93
- let pluginList = []
94
+ const pluginList = []
94
95
 
95
96
  // month and week selection
96
97
  if (selectionType === "month" || plugins.length > 0) {
97
98
  pluginList.push(monthSelectPlugin({ shorthand: true, dateFormat: 'F Y', altFormat: 'F Y' }))
98
99
  } else if ( selectionType === "week") {
99
100
  pluginList.push(weekSelect())
101
+
102
+ } else if (selectionType === "quickpick") {
103
+ //------- QUICKPICK VARIANT PLUGIN -------------//
104
+ pluginList.push(quickPickPlugin())
100
105
  }
101
106
 
102
107
  // time selection
103
108
  if (enableTime) pluginList.push(timeSelectPlugin({ caption: timeCaption, showTimezone: showTimezone}))
104
109
 
110
+
105
111
  return pluginList
106
112
  }
107
113
 
@@ -144,6 +150,9 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT
144
150
  },
145
151
  ] : disabledParser(),
146
152
  enableTime,
153
+ locale: {
154
+ rangeSeparator: ' → '
155
+ },
147
156
  maxDate,
148
157
  minDate,
149
158
  mode,
@@ -171,10 +180,33 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT
171
180
  static: staticPosition,
172
181
  })
173
182
 
183
+
174
184
  // ===========================================================
175
185
  // Additional JS Functionality |
176
186
  // ===========================================================
177
187
 
188
+ // opens flatpickr instance when calander icon is clicked so we can have a hover state on icon
189
+ // window.addEventListener("DOMContentLoaded", (event) => {
190
+ // event.preventDefault();
191
+ // function attachIconClickHandler() {
192
+ // const variantArr = document.querySelectorAll(`#cal-icon-${pickerId}`)
193
+ // if (!variantArr) {
194
+ // setTimeout(attachIconClickHandler, 100);
195
+ // return;
196
+ // }
197
+
198
+ // const instance = document.querySelector<HTMLElement & { [x: string]: any }>(`#${pickerId}`)._flatpickr
199
+ // variantArr.forEach((icon) => {
200
+ // icon.addEventListener("click", function(event) {
201
+ // event.preventDefault();
202
+ // instance.open()
203
+ // });
204
+ // })
205
+ // }
206
+
207
+ // attachIconClickHandler();
208
+ // });
209
+
178
210
  // Assign dynamically sourced flatpickr instance to variable
179
211
  const picker = document.querySelector<HTMLElement & { [x: string]: any }>(`#${pickerId}`)._flatpickr
180
212
  picker.innerContainer.parentElement.id = `cal-${pickerId}`
@@ -0,0 +1,8 @@
1
+ <%= pb_rails("date_picker", props: {
2
+ allow_input: true,
3
+ mode: "range",
4
+ picker_id: "date-picker-quick-pick",
5
+ placeholder: "mm/dd/yyyy → mm/dd/yyyy",
6
+ selection_type: "quickpick"
7
+ }) %>
8
+
@@ -0,0 +1,18 @@
1
+ import React from 'react'
2
+
3
+ import DatePicker from '../_date_picker'
4
+
5
+ const DatePickerQuickPick = (props) => (
6
+ <div>
7
+ <DatePicker
8
+ allowInput
9
+ mode="range"
10
+ pickerId="date-picker-quick-pick"
11
+ placeholder="mm/dd/yyyy → mm/dd/yyyy"
12
+ selectionType="quickpick"
13
+ {...props}
14
+ />
15
+ </div>
16
+ )
17
+
18
+ export default DatePickerQuickPick
@@ -8,6 +8,7 @@ examples:
8
8
  - date_picker_input: Input Field
9
9
  - date_picker_label: Label
10
10
  - date_picker_range: Range
11
+ - date_picker_quick_pick: Range (Quick Pick)
11
12
  - date_picker_format: Format
12
13
  - date_picker_disabled: Disabled Dates
13
14
  - date_picker_min_max: Min Max
@@ -33,6 +34,7 @@ examples:
33
34
  - date_picker_on_change: onChange
34
35
  - date_picker_on_close: onClose
35
36
  - date_picker_range: Range
37
+ - date_picker_quick_pick: Range (Quick Pick)
36
38
  - date_picker_format: Format
37
39
  - date_picker_disabled: Disabled Dates
38
40
  - date_picker_min_max: Min Max
@@ -19,4 +19,5 @@ export { default as DatePickerWeek } from './_date_picker_week.jsx'
19
19
  export { default as DatePickerPositions } from './_date_picker_positions.jsx'
20
20
  export { default as DatePickerPositionsElement } from './_date_picker_positions_element.jsx'
21
21
  export { default as DatePickerAllowInput } from './_date_picker_allow_input'
22
- export { default as DatePickerOnClose } from './_date_picker_on_close.jsx'
22
+ export { default as DatePickerQuickPick } from './_date_picker_quick_pick'
23
+ export { default as DatePickerOnClose } from './_date_picker_on_close.jsx'
@@ -0,0 +1,164 @@
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
+ let activeLabel = ""
23
+
24
+ const quickPickPlugin = () => {
25
+ return function (fp: FpTypes & any): any {
26
+ // variable that holds the ranges available
27
+ const ranges = {
28
+ 'Today': [new Date(), new Date()],
29
+ 'Yesterday': [moment().subtract(1, 'days').toDate(), moment().subtract(1, 'days').toDate()],
30
+ 'This week': [moment().startOf('week').toDate(), moment().endOf('week').toDate()],
31
+ 'This month': [moment().startOf('month').toDate(), new Date()],
32
+ 'This quarter': [moment().startOf('quarter').toDate(), new Date()],
33
+ 'This year': [moment().startOf('year').toDate(), new Date()],
34
+ 'Last week': [
35
+ moment().subtract(1, 'week').startOf('week').toDate(),
36
+ moment().subtract(1, 'week').endOf('week').toDate()
37
+ ],
38
+ 'Last month': [
39
+ moment().subtract(1, 'month').startOf('month').toDate(),
40
+ moment().subtract(1, 'month').endOf('month').toDate()
41
+ ],
42
+ 'Last quarter': [
43
+ moment().subtract(1, 'quarter').startOf('quarter').toDate(),
44
+ moment().subtract(1, 'quarter').endOf('quarter').toDate()
45
+ ],
46
+ 'Last year': [
47
+ moment().subtract(1, 'year').startOf('year').toDate(),
48
+ moment().subtract(1, 'year').endOf('year').toDate()
49
+ ]
50
+ }
51
+ //creating the ul element for the nav dropdown and giving it classnames
52
+ const rangesNav = document.createElement('ul');
53
+
54
+ // creating the pluginData object that will hold the properties of this plugin
55
+ const pluginData: pluginDataType = {
56
+ ranges: ranges,
57
+ rangesNav: rangesNav,
58
+ rangesButtons: [],
59
+ };
60
+
61
+ /**
62
+ * @param {string} label
63
+ * @returns HTML Element
64
+ */
65
+
66
+ //function for creating the range buttons in the nav
67
+ const addRangeButton = (label: string) => {
68
+
69
+ // creating new elements to mimick selectable card component
70
+ const div2 = document.createElement('div');
71
+ div2.className = "nav-item-link"
72
+ div2.innerHTML = label;
73
+
74
+ pluginData.rangesButtons[label] = div2;
75
+
76
+ // create li elements inside the dropdown
77
+ const item = document.createElement('li');
78
+ item.className = "nav-item";
79
+
80
+ // append those nav items to the li items
81
+ item.appendChild(pluginData.rangesButtons[label]);
82
+
83
+ // append the li item to the ul rangeNav prop
84
+ pluginData.rangesNav.appendChild(item);
85
+
86
+ // return the ranges buton prop
87
+ return pluginData.rangesButtons[label];
88
+ };
89
+
90
+ const selectActiveRangeButton = (selectedDates: Array<string>) => {
91
+ const current = pluginData.rangesNav.querySelector('.active');
92
+
93
+ if (current) {
94
+ current.classList.remove('active');
95
+ }
96
+ /** conditional statment to extract start and end dates from selectedDates,
97
+ * then loop through ranges prop in pluginData
98
+ * and check if chosen dates equal to a date in the ranges prop
99
+ * if they are equal, add the active class
100
+ */
101
+ if (selectedDates.length > 0 && activeLabel) {
102
+ // const selected = pluginData.rangesNav.querySelectorAll(".nav-item-link")
103
+ // selected.forEach(el => {
104
+ // if (el.innerHTML === activeLabel)
105
+ // el.classList.add('active')
106
+ // return
107
+ // })
108
+
109
+ pluginData.rangesButtons[activeLabel].classList.add('active');
110
+ }
111
+ }
112
+
113
+
114
+ return {
115
+ // onReady is a hook from flatpickr that runs when calender is in a ready state
116
+ onReady(selectedDates: Array<string>) {
117
+ // 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
118
+ for (const [label, range] of Object.entries(pluginData.ranges)) {
119
+ addRangeButton(label).addEventListener('click', function () {
120
+
121
+ const start = moment(range[0]).toDate();
122
+ const end = moment(range[1]).toDate();
123
+
124
+ if (!start) {
125
+ fp.clear();
126
+ }
127
+ else {
128
+ activeLabel = label
129
+ fp.setDate([start, end], true);
130
+ fp.close();
131
+ }
132
+ });
133
+ }
134
+ // conditional to check if there is a dropdown to add it to the calendar container and get it the classes it needs
135
+ if (pluginData.rangesNav.children.length > 0) {
136
+
137
+ fp.calendarContainer.prepend(pluginData.rangesNav);
138
+ pluginData.rangesNav.classList.add('quick-pick-ul')
139
+ fp.calendarContainer.classList.add('quick-pick-drop-down');
140
+
141
+ /**
142
+ *
143
+ * @param {Array} selectedDates
144
+ */
145
+ // function to give the active button the active class
146
+ selectActiveRangeButton(selectedDates);
147
+ }
148
+ },
149
+ onValueUpdate(selectedDates: Array<string>) {
150
+ debugger
151
+ selectActiveRangeButton(selectedDates);
152
+ },
153
+
154
+ onClose(selectedDates: Array<string>) {
155
+ // set the input value to the selected dates when the dropdown is closed
156
+ if (selectedDates.length < 2 && selectedDates.length > 0) {
157
+ fp.input.placeholder = fp.formatDate(this.selectedDates[0], fp.config.dateFormat);
158
+ }
159
+ }
160
+ };
161
+ };
162
+ }
163
+
164
+ 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
  }
@@ -20,6 +20,7 @@ type TimeProps = {
20
20
  size?: "md" | "sm";
21
21
  showTimezone?: boolean;
22
22
  timeZone?: string;
23
+ unstyled?: boolean;
23
24
  } & GlobalProps
24
25
 
25
26
  const Time = (props: TimeProps) => {
@@ -30,8 +31,10 @@ const Time = (props: TimeProps) => {
30
31
  showIcon,
31
32
  size,
32
33
  timeZone,
34
+ unstyled = false,
33
35
  showTimezone = true,
34
36
  } = props;
37
+
35
38
  const classes = classnames(
36
39
  buildCss("pb_time_kit", align, size),
37
40
  globalProps(props),
@@ -43,46 +46,79 @@ const Time = (props: TimeProps) => {
43
46
  return (
44
47
  <div className={classes}>
45
48
  {showIcon && (
46
- <>
47
- <Body color="light" tag="span">
48
- <Icon fixedWidth icon="clock" size={size === "md" ? "" : "sm"} />
49
- </Body>{" "}
50
- </>
51
- )}
52
-
53
- <time dateTime={date}>
54
- <span>
55
- {size === "md" ? (
56
- <>
57
- <Body
58
- className="pb_time"
59
- tag="span"
60
- text={dateTimestamp.toTimeWithMeridian()}
61
- />{" "}
62
- {showTimezone && (
63
- <Body
64
- color="light"
65
- tag="span"
66
- text={dateTimestamp.toTimezone()}
49
+ unstyled
50
+ ? (
51
+ <span>
52
+ <Icon fixedWidth
53
+ icon="clock"
67
54
  />
68
- )}
69
- </>
70
- ) : (
55
+ {" "}
56
+ </span>
57
+ )
58
+ : (
71
59
  <>
72
- <Caption
73
- color="light"
74
- tag="span"
75
- text={dateTimestamp.toTimeWithMeridian()}
76
- />{" "}
77
- {showTimezone && (
78
- <Caption
79
- color="light"
60
+ <Body color="light"
80
61
  tag="span"
81
- text={dateTimestamp.toTimezone()}
62
+ >
63
+ <Icon fixedWidth
64
+ icon="clock"
65
+ size={size === "md" ? "" : "sm"}
82
66
  />
83
- )}
67
+ {" "}
68
+ </Body>
84
69
  </>
85
- )}
70
+ )
71
+ )}
72
+
73
+ <time dateTime={date}>
74
+ <span>
75
+ {unstyled
76
+ ? (
77
+ <>
78
+ <span>
79
+ {dateTimestamp.toTimeWithMeridian()}
80
+ </span>
81
+ {" "}
82
+ {showTimezone && (
83
+ <span>
84
+ {dateTimestamp.toTimezone()}
85
+ </span>
86
+ )}
87
+ </>
88
+ )
89
+ : size === "md"
90
+ ? (
91
+ <>
92
+ <Body
93
+ className="pb_time"
94
+ tag="span"
95
+ text={dateTimestamp.toTimeWithMeridian()}
96
+ />{" "}
97
+ {showTimezone && (
98
+ <Body
99
+ color="light"
100
+ tag="span"
101
+ text={dateTimestamp.toTimezone()}
102
+ />
103
+ )}
104
+ </>
105
+ )
106
+ : (
107
+ <>
108
+ <Caption
109
+ color="light"
110
+ tag="span"
111
+ text={dateTimestamp.toTimeWithMeridian()}
112
+ />{" "}
113
+ {showTimezone && (
114
+ <Caption
115
+ color="light"
116
+ tag="span"
117
+ text={dateTimestamp.toTimezone()}
118
+ />
119
+ )}
120
+ </>
121
+ )}
86
122
  </span>
87
123
  </time>
88
124
  </div>