playbook_ui 7.3.0.pre.alpha2 → 7.3.0.pre.alpha3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (326) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -2
  3. data/app/controllers/playbook/application_controller.rb +0 -2
  4. data/app/pb_kits/playbook/_playbook.scss +1 -0
  5. data/app/pb_kits/playbook/data/menu.yml +4 -3
  6. data/app/pb_kits/playbook/index.js +5 -1
  7. data/app/pb_kits/playbook/pb_avatar/_avatar.jsx +5 -1
  8. data/app/pb_kits/playbook/pb_badge/_badge.jsx +4 -2
  9. data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.html.erb +1 -12
  10. data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.jsx +1 -1
  11. data/app/pb_kits/playbook/pb_bar_graph/bar_graph.rb +3 -2
  12. data/app/pb_kits/playbook/pb_body/body.rb +1 -1
  13. data/app/pb_kits/playbook/pb_button/_button.jsx +5 -1
  14. data/app/pb_kits/playbook/pb_button/_button_mixins.scss +1 -0
  15. data/app/pb_kits/playbook/pb_button_toolbar/_button_toolbar.jsx +7 -3
  16. data/app/pb_kits/playbook/pb_button_toolbar/_button_toolbar.scss +82 -90
  17. data/app/pb_kits/playbook/pb_button_toolbar/_button_toolbar_dark.scss +57 -0
  18. data/app/pb_kits/playbook/pb_button_toolbar/_button_toolbar_mixins.scss +27 -0
  19. data/app/pb_kits/playbook/pb_button_toolbar/button_toolbar.rb +4 -2
  20. data/app/pb_kits/playbook/pb_button_toolbar/docs/_button_toolbar_default.html.erb +17 -7
  21. data/app/pb_kits/playbook/pb_button_toolbar/docs/_button_toolbar_default.jsx +32 -9
  22. data/app/pb_kits/playbook/pb_button_toolbar/docs/_button_toolbar_secondary.html.erb +18 -7
  23. data/app/pb_kits/playbook/pb_button_toolbar/docs/_button_toolbar_secondary.jsx +37 -9
  24. data/app/pb_kits/playbook/pb_button_toolbar/docs/example.yml +3 -7
  25. data/app/pb_kits/playbook/pb_button_toolbar/docs/index.js +0 -2
  26. data/app/pb_kits/playbook/pb_caption/_caption.html.erb +7 -5
  27. data/app/pb_kits/playbook/pb_caption/_caption.jsx +2 -2
  28. data/app/pb_kits/playbook/pb_caption/docs/_caption_block.html.erb +11 -0
  29. data/app/pb_kits/playbook/pb_caption/docs/_caption_block.jsx +28 -0
  30. data/app/pb_kits/playbook/pb_caption/docs/example.yml +2 -0
  31. data/app/pb_kits/playbook/pb_caption/docs/index.js +1 -0
  32. data/app/pb_kits/playbook/pb_checkbox/_checkbox.jsx +5 -2
  33. data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +3 -1
  34. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_options.html.erb +10 -0
  35. data/app/pb_kits/playbook/pb_checkbox/docs/example.yml +1 -0
  36. data/app/pb_kits/playbook/pb_circle_chart/_circle_chart.jsx +1 -1
  37. data/app/pb_kits/playbook/pb_circle_icon_button/_circle_icon_button.jsx +5 -1
  38. data/app/pb_kits/playbook/pb_contact/_contact.jsx +5 -1
  39. data/app/pb_kits/playbook/pb_currency/_currency.jsx +5 -1
  40. data/app/pb_kits/playbook/pb_dashboard_value/_dashboard_value.jsx +5 -1
  41. data/app/pb_kits/playbook/pb_date_picker/_date_picker.html.erb +1 -2
  42. data/app/pb_kits/playbook/pb_date_picker/_date_picker.jsx +3 -5
  43. data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +3 -2
  44. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.js +37 -31
  45. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_default_date.html.erb +1 -2
  46. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_default_date.jsx +1 -2
  47. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_default_date.md +1 -0
  48. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_format.html.erb +4 -0
  49. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_format.jsx +4 -0
  50. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_input.html.erb +9 -9
  51. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_input.jsx +8 -8
  52. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_input.md +3 -1
  53. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_on_change.jsx +34 -0
  54. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_on_change.md +3 -0
  55. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_range.html.erb +1 -0
  56. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_range.jsx +1 -0
  57. data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +1 -4
  58. data/app/pb_kits/playbook/pb_date_picker/docs/index.js +1 -2
  59. data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.html.erb +8 -14
  60. data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.jsx +122 -39
  61. data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.scss +33 -2
  62. data/app/pb_kits/playbook/pb_date_range_inline/date_range_inline.rb +44 -9
  63. data/app/pb_kits/playbook/pb_date_range_inline/docs/_date_range_inline_default.html.erb +14 -1
  64. data/app/pb_kits/playbook/pb_date_range_inline/docs/_date_range_inline_default.jsx +45 -1
  65. data/app/pb_kits/playbook/pb_date_range_stacked/_date_range_stacked.jsx +5 -1
  66. data/app/pb_kits/playbook/pb_date_stacked/_date_stacked.jsx +2 -2
  67. data/app/pb_kits/playbook/pb_date_year_stacked/_date_year_stacked.jsx +5 -1
  68. data/app/pb_kits/playbook/pb_distribution_bar/_distribution_bar.html.erb +1 -8
  69. data/app/pb_kits/playbook/pb_distribution_bar/distribution_bar.rb +7 -0
  70. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.html.erb +3 -2
  71. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.jsx +31 -17
  72. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.scss +10 -0
  73. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_close.html.erb +21 -0
  74. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_close.jsx +38 -0
  75. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_default.html.erb +2 -1
  76. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_default.jsx +1 -2
  77. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_multi_line.html.erb +1 -1
  78. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_multi_line.jsx +1 -1
  79. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_multi_line_dark.html.erb +1 -1
  80. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_multi_line_dark.jsx +1 -1
  81. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/example.yml +2 -0
  82. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/index.js +1 -0
  83. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.rb +7 -1
  84. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/index.js +18 -0
  85. data/app/pb_kits/playbook/pb_flex/_flex.jsx +2 -2
  86. data/app/pb_kits/playbook/pb_flex/_flex_item.jsx +1 -1
  87. data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +10 -2
  88. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -1
  89. data/app/pb_kits/playbook/pb_form/docs/_form_simple_form.html.erb +3 -3
  90. data/app/pb_kits/playbook/pb_form/docs/_form_simple_form_validate.html.erb +3 -3
  91. data/app/pb_kits/playbook/pb_form/form_builder/checkbox_field.rb +7 -2
  92. data/app/pb_kits/playbook/pb_form/form_builder/date_picker_field.rb +1 -0
  93. data/app/pb_kits/playbook/pb_form_pill/_form_pill.jsx +3 -2
  94. data/app/pb_kits/playbook/pb_gauge/_gauge.jsx +2 -2
  95. data/app/pb_kits/playbook/pb_highlight/_highlight.jsx +1 -1
  96. data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.jsx +2 -2
  97. data/app/pb_kits/playbook/pb_icon/_icon.jsx +2 -2
  98. data/app/pb_kits/playbook/pb_icon_value/_icon_value.jsx +5 -1
  99. data/app/pb_kits/playbook/pb_image/_image.jsx +5 -1
  100. data/app/pb_kits/playbook/pb_label_pill/_label_pill.jsx +5 -1
  101. data/app/pb_kits/playbook/pb_layout/_layout.jsx +4 -4
  102. data/app/pb_kits/playbook/pb_line_graph/_line_graph.html.erb +1 -13
  103. data/app/pb_kits/playbook/pb_line_graph/_line_graph.jsx +1 -1
  104. data/app/pb_kits/playbook/pb_line_graph/line_graph.rb +3 -2
  105. data/app/pb_kits/playbook/pb_list/_list.jsx +3 -2
  106. data/app/pb_kits/playbook/pb_list/_list_item.jsx +3 -2
  107. data/app/pb_kits/playbook/pb_logistic/_logistic.jsx +5 -1
  108. data/app/pb_kits/playbook/pb_message/_message.jsx +5 -1
  109. data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.jsx +5 -2
  110. data/app/pb_kits/playbook/pb_nav/_item.html.erb +3 -0
  111. data/app/pb_kits/playbook/pb_nav/_item.jsx +14 -1
  112. data/app/pb_kits/playbook/pb_nav/_nav.jsx +5 -2
  113. data/app/pb_kits/playbook/pb_nav/_vertical_nav.scss +22 -3
  114. data/app/pb_kits/playbook/pb_nav/docs/_borderless_nav.html.erb +6 -0
  115. data/app/pb_kits/playbook/pb_nav/docs/_borderless_nav.jsx +29 -0
  116. data/app/pb_kits/playbook/pb_nav/docs/_with_img_nav.html.erb +7 -0
  117. data/app/pb_kits/playbook/pb_nav/docs/_with_img_nav.jsx +42 -0
  118. data/app/pb_kits/playbook/pb_nav/docs/_with_img_nav.md +1 -0
  119. data/app/pb_kits/playbook/pb_nav/docs/example.yml +5 -0
  120. data/app/pb_kits/playbook/pb_nav/docs/index.js +2 -0
  121. data/app/pb_kits/playbook/pb_nav/item.rb +1 -0
  122. data/app/pb_kits/playbook/pb_nav/nav.rb +6 -1
  123. data/app/pb_kits/playbook/pb_person/_person.jsx +5 -1
  124. data/app/pb_kits/playbook/pb_person_contact/_person_contact.jsx +12 -7
  125. data/app/pb_kits/playbook/pb_person_contact/docs/_person_contact_with_wrong_numbers.jsx +1 -0
  126. data/app/pb_kits/playbook/pb_pill/_pill.scss +1 -0
  127. data/app/pb_kits/playbook/pb_popover/_popover.jsx +5 -1
  128. data/app/pb_kits/playbook/pb_popover/_popover.scss +6 -4
  129. data/app/pb_kits/playbook/pb_popover/index.js +3 -1
  130. data/app/pb_kits/playbook/pb_progress_simple/_progress_simple.jsx +4 -4
  131. data/app/pb_kits/playbook/pb_progress_step/_progress_step.jsx +4 -1
  132. data/app/pb_kits/playbook/pb_progress_step/_progress_step.scss +168 -33
  133. data/app/pb_kits/playbook/pb_progress_step/_progress_step_item.html.erb +3 -1
  134. data/app/pb_kits/playbook/pb_progress_step/_progress_step_item.jsx +10 -8
  135. data/app/pb_kits/playbook/pb_progress_step/docs/_description.md +1 -1
  136. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_default.html.erb +14 -16
  137. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_default.jsx +6 -3
  138. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_tracker.html.erb +17 -1
  139. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_tracker.jsx +17 -1
  140. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_vertical.jsx +10 -3
  141. data/app/pb_kits/playbook/pb_progress_step/progress_step.rb +11 -1
  142. data/app/pb_kits/playbook/pb_progress_step/progress_step_item.rb +1 -1
  143. data/app/pb_kits/playbook/pb_radio/_radio.html.erb +1 -1
  144. data/app/pb_kits/playbook/pb_radio/docs/_radio_options.html.erb +9 -0
  145. data/app/pb_kits/playbook/pb_radio/docs/example.yml +1 -0
  146. data/app/pb_kits/playbook/pb_radio/radio.rb +2 -4
  147. data/app/pb_kits/playbook/pb_section_separator/_section_separator.jsx +1 -3
  148. data/app/pb_kits/playbook/pb_section_separator/_section_separator.scss +26 -47
  149. data/app/pb_kits/playbook/pb_section_separator/_section_separator_mixin.scss +32 -0
  150. data/app/pb_kits/playbook/pb_section_separator/docs/_section_separator_line.jsx +6 -2
  151. data/app/pb_kits/playbook/pb_section_separator/docs/_section_separator_text.jsx +2 -1
  152. data/app/pb_kits/playbook/pb_section_separator/docs/_section_separator_text_background.jsx +2 -1
  153. data/app/pb_kits/playbook/pb_section_separator/docs/_section_separator_vertical.jsx +9 -3
  154. data/app/pb_kits/playbook/pb_section_separator/section_separator.rb +1 -1
  155. data/app/pb_kits/playbook/pb_select/_select.scss +1 -1
  156. data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.html.erb +4 -4
  157. data/app/pb_kits/playbook/pb_selectable_card/docs/_selectable_card_options.html.erb +16 -0
  158. data/app/pb_kits/playbook/pb_selectable_card/docs/example.yml +3 -2
  159. data/app/pb_kits/playbook/pb_selectable_card/selectable_card.rb +16 -9
  160. data/app/pb_kits/playbook/pb_selectable_card_icon/_selectable_card_icon.html.erb +3 -2
  161. data/app/pb_kits/playbook/pb_selectable_card_icon/docs/_selectable_card_icon_options.html.erb +16 -0
  162. data/app/pb_kits/playbook/pb_selectable_card_icon/docs/example.yml +4 -3
  163. data/app/pb_kits/playbook/pb_selectable_card_icon/selectable_card_icon.rb +3 -0
  164. data/app/pb_kits/playbook/pb_selectable_icon/_selectable_icon.html.erb +3 -3
  165. data/app/pb_kits/playbook/pb_selectable_icon/docs/_selectable_icon_options.html.erb +15 -0
  166. data/app/pb_kits/playbook/pb_selectable_icon/docs/example.yml +3 -2
  167. data/app/pb_kits/playbook/pb_selectable_icon/selectable_icon.rb +10 -0
  168. data/app/pb_kits/playbook/pb_stat_change/_stat_change.jsx +2 -2
  169. data/app/pb_kits/playbook/pb_stat_value/_stat_value.jsx +3 -3
  170. data/app/pb_kits/playbook/pb_stat_value/docs/_stat_value_default.jsx +6 -1
  171. data/app/pb_kits/playbook/pb_table/_table.jsx +2 -2
  172. data/app/pb_kits/playbook/pb_table/docs/_table_action_middle.html.erb +34 -0
  173. data/app/pb_kits/playbook/pb_table/docs/_table_action_middle.jsx +68 -0
  174. data/app/pb_kits/playbook/pb_table/docs/_table_action_middle.md +2 -0
  175. data/app/pb_kits/playbook/pb_table/docs/_table_icon_buttons.html.erb +61 -0
  176. data/app/pb_kits/playbook/pb_table/docs/_table_icon_buttons.jsx +89 -0
  177. data/app/pb_kits/playbook/pb_table/docs/_table_icon_buttons.md +1 -0
  178. data/app/pb_kits/playbook/pb_table/docs/_table_one_action.html.erb +34 -0
  179. data/app/pb_kits/playbook/pb_table/docs/_table_one_action.jsx +68 -0
  180. data/app/pb_kits/playbook/pb_table/docs/_table_one_action.md +2 -0
  181. data/app/pb_kits/playbook/pb_table/docs/_table_two_actions.html.erb +43 -0
  182. data/app/pb_kits/playbook/pb_table/docs/_table_two_actions.jsx +80 -0
  183. data/app/pb_kits/playbook/pb_table/docs/_table_two_actions.md +1 -0
  184. data/app/pb_kits/playbook/pb_table/docs/_table_two_plus_actions.html.erb +34 -0
  185. data/app/pb_kits/playbook/pb_table/docs/_table_two_plus_actions.jsx +63 -0
  186. data/app/pb_kits/playbook/pb_table/docs/_table_two_plus_actions.md +1 -0
  187. data/app/pb_kits/playbook/pb_table/docs/example.yml +12 -0
  188. data/app/pb_kits/playbook/pb_table/docs/index.js +6 -0
  189. data/app/pb_kits/playbook/pb_text_input/_text_input.jsx +1 -1
  190. data/app/pb_kits/playbook/pb_textarea/_textarea.jsx +1 -1
  191. data/app/pb_kits/playbook/pb_time/_time.html.erb +17 -20
  192. data/app/pb_kits/playbook/pb_time/_time.jsx +42 -29
  193. data/app/pb_kits/playbook/pb_time/_time.scss +4 -24
  194. data/app/pb_kits/playbook/pb_time/docs/_time_align.jsx +4 -1
  195. data/app/pb_kits/playbook/pb_time/docs/_time_default.html.erb +11 -11
  196. data/app/pb_kits/playbook/pb_time/docs/_time_default.jsx +13 -1
  197. data/app/pb_kits/playbook/pb_time/docs/_time_sizes.jsx +4 -1
  198. data/app/pb_kits/playbook/pb_time/docs/_time_timestamp.jsx +3 -1
  199. data/app/pb_kits/playbook/pb_time/docs/_time_timezone.html.erb +2 -1
  200. data/app/pb_kits/playbook/pb_time/docs/_time_timezone.jsx +7 -2
  201. data/app/pb_kits/playbook/pb_time_range_inline/_time_range_inline.jsx +1 -1
  202. data/app/pb_kits/playbook/pb_time_range_inline/_time_range_inline.scss +5 -5
  203. data/app/pb_kits/playbook/pb_time_stacked/_time_stacked.jsx +3 -3
  204. data/app/pb_kits/playbook/pb_timestamp/_timestamp.jsx +1 -1
  205. data/app/pb_kits/playbook/pb_title/_title.jsx +5 -1
  206. data/app/pb_kits/playbook/pb_title_count/_title_count.jsx +5 -1
  207. data/app/pb_kits/playbook/pb_title_detail/_title_detail.jsx +5 -5
  208. data/app/pb_kits/playbook/pb_toggle/_toggle.jsx +3 -3
  209. data/app/pb_kits/playbook/pb_toggle/_toggle.scss +41 -43
  210. data/app/pb_kits/playbook/pb_toggle/docs/_toggle_options.html.erb +10 -0
  211. data/app/pb_kits/playbook/pb_toggle/docs/example.yml +1 -2
  212. data/app/pb_kits/playbook/pb_toggle/docs/index.js +0 -1
  213. data/app/pb_kits/playbook/pb_toggle/toggle.rb +5 -2
  214. data/app/pb_kits/playbook/pb_typeahead/_typeahead.html.erb +24 -20
  215. data/app/pb_kits/playbook/pb_typeahead/_typeahead.jsx +19 -1
  216. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.jsx +8 -1
  217. data/app/pb_kits/playbook/pb_typeahead/components/Option.jsx +21 -13
  218. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_default.html.erb +4 -3
  219. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_context_dark.html.erb +1 -1
  220. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills.html.erb +25 -0
  221. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills.jsx +0 -3
  222. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills.md +8 -0
  223. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async.html.erb +30 -0
  224. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async.md +11 -0
  225. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async_users.html.erb +25 -0
  226. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async_users.jsx +0 -3
  227. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async_users.md +1 -0
  228. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +3 -0
  229. data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +24 -1
  230. data/app/pb_kits/playbook/pb_user_badge/_user_badge.jsx +5 -2
  231. data/app/pb_kits/playbook/props.rb +1 -1
  232. data/app/pb_kits/playbook/props/base.rb +6 -4
  233. data/app/pb_kits/playbook/react_rails_kits.js +6 -0
  234. data/app/pb_kits/playbook/tokens/_colors.scss +22 -23
  235. data/app/pb_kits/playbook/tokens/_typography.scss +4 -4
  236. data/app/pb_kits/playbook/tokens/index.scss +11 -0
  237. data/app/pb_kits/playbook/vendor.js +8 -0
  238. data/lib/playbook/engine.rb +1 -0
  239. data/lib/playbook/version.rb +1 -1
  240. metadata +47 -88
  241. data/app/controllers/playbook/guides_controller.rb +0 -11
  242. data/app/controllers/playbook/pages_controller.rb +0 -99
  243. data/app/controllers/playbook/samples_controller.rb +0 -40
  244. data/app/pb_kits/playbook/packs/application.js +0 -55
  245. data/app/pb_kits/playbook/packs/examples.js +0 -182
  246. data/app/pb_kits/playbook/packs/main.scss +0 -12
  247. data/app/pb_kits/playbook/packs/samples.js +0 -21
  248. data/app/pb_kits/playbook/packs/site_styles/_samples.scss +0 -72
  249. data/app/pb_kits/playbook/packs/site_styles/_scaffold.scss +0 -43
  250. data/app/pb_kits/playbook/packs/site_styles/_site-style.scss +0 -146
  251. data/app/pb_kits/playbook/packs/site_styles/docs/_all.scss +0 -10
  252. data/app/pb_kits/playbook/packs/site_styles/docs/_bg_light_doc_example.scss +0 -7
  253. data/app/pb_kits/playbook/packs/site_styles/docs/_code_snippet.scss +0 -531
  254. data/app/pb_kits/playbook/packs/site_styles/docs/_color_utilities.scss +0 -92
  255. data/app/pb_kits/playbook/packs/site_styles/docs/_flex_examples.scss +0 -15
  256. data/app/pb_kits/playbook/packs/site_styles/docs/_kit_doc.scss +0 -148
  257. data/app/pb_kits/playbook/packs/site_styles/docs/_kits_examples.scss +0 -15
  258. data/app/pb_kits/playbook/packs/site_styles/docs/_markdown.scss +0 -88
  259. data/app/pb_kits/playbook/packs/site_styles/docs/_spacing_tokens.scss +0 -72
  260. data/app/pb_kits/playbook/pb_button_toolbar/docs/_button_toolbar_vertical.html.erb +0 -11
  261. data/app/pb_kits/playbook/pb_button_toolbar/docs/_button_toolbar_vertical.jsx +0 -29
  262. data/app/pb_kits/playbook/pb_button_toolbar/docs/_button_toolbar_vertical_secondary.html.erb +0 -11
  263. data/app/pb_kits/playbook/pb_button_toolbar/docs/_button_toolbar_vertical_secondary.jsx +0 -34
  264. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_allow_input.html.erb +0 -4
  265. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_allow_input.jsx +0 -13
  266. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_allow_input.md +0 -1
  267. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_dark.html.erb +0 -4
  268. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_dark.jsx +0 -13
  269. data/app/pb_kits/playbook/pb_toggle/docs/_toggle_size.html.erb +0 -11
  270. data/app/pb_kits/playbook/pb_toggle/docs/_toggle_size.jsx +0 -44
  271. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async_summary.jsx +0 -45
  272. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_summary.jsx +0 -27
  273. data/app/views/layouts/playbook/_mobile_hamburger.html.erb +0 -2
  274. data/app/views/layouts/playbook/_nav.html.erb +0 -37
  275. data/app/views/layouts/playbook/_sidebar.html.erb +0 -51
  276. data/app/views/layouts/playbook/application.html.erb +0 -26
  277. data/app/views/layouts/playbook/fullscreen.html.slim +0 -10
  278. data/app/views/layouts/playbook/grid.html.slim +0 -10
  279. data/app/views/layouts/playbook/samples.html.erb +0 -19
  280. data/app/views/playbook/guides/create_kit.html.slim +0 -16
  281. data/app/views/playbook/guides/create_kit/_file_naming.html.md +0 -2
  282. data/app/views/playbook/guides/create_kit/_generator.html.md +0 -6
  283. data/app/views/playbook/guides/create_kit/_kit_examples.html.md +0 -2
  284. data/app/views/playbook/guides/create_kit/_kit_rails.html.md +0 -2
  285. data/app/views/playbook/guides/create_kit/_kit_react.html.md +0 -2
  286. data/app/views/playbook/guides/create_kit/_layout.html.md +0 -2
  287. data/app/views/playbook/guides/create_kit/_view_objects.html.md +0 -2
  288. data/app/views/playbook/guides/create_kit/_writing_sass.md +0 -10
  289. data/app/views/playbook/guides/use_nitro.html.slim +0 -6
  290. data/app/views/playbook/guides/use_nitro/_local.html.md +0 -2
  291. data/app/views/playbook/guides/use_nitro/_nitro_components.html.md +0 -2
  292. data/app/views/playbook/guides/use_nitro/_versions.html.md +0 -2
  293. data/app/views/playbook/pages/fullscreen.html.slim +0 -10
  294. data/app/views/playbook/pages/grid.html.slim +0 -2
  295. data/app/views/playbook/pages/home.html.slim +0 -4
  296. data/app/views/playbook/pages/kit_category_show.html.erb +0 -14
  297. data/app/views/playbook/pages/kit_show.html.erb +0 -33
  298. data/app/views/playbook/pages/kits.html.erb +0 -12
  299. data/app/views/playbook/pages/principals/_getting_started.html.md +0 -30
  300. data/app/views/playbook/pages/principles.html.slim +0 -3
  301. data/app/views/playbook/pages/tokens.html.slim +0 -15
  302. data/app/views/playbook/pages/tokens/_pb_doc_spacing.html.slim +0 -61
  303. data/app/views/playbook/pages/utilities.html.slim +0 -116
  304. data/app/views/playbook/pages/utilities/_pb_doc_color.html.slim +0 -15
  305. data/app/views/playbook/samples/collection_detail/index.html.erb +0 -169
  306. data/app/views/playbook/samples/collection_detail/index.jsx +0 -372
  307. data/app/views/playbook/samples/dashboards/index.html.erb +0 -81
  308. data/app/views/playbook/samples/dashboards/index.jsx +0 -130
  309. data/app/views/playbook/samples/filter_table/index.html.erb +0 -348
  310. data/app/views/playbook/samples/filter_table/index.jsx +0 -433
  311. data/app/views/playbook/samples/registration/index.html.erb +0 -316
  312. data/app/views/playbook/samples/registration/index.jsx +0 -476
  313. data/app/views/playbook/samples/sample_show.html.erb +0 -36
  314. data/lib/generators/kit/USAGE +0 -5
  315. data/lib/generators/kit/kit_generator.rb +0 -95
  316. data/lib/generators/kit/templates/kit_example_rails.erb.tt +0 -1
  317. data/lib/generators/kit/templates/kit_example_react.erb.tt +0 -10
  318. data/lib/generators/kit/templates/kit_example_yml.erb.tt +0 -9
  319. data/lib/generators/kit/templates/kit_html.erb.tt +0 -7
  320. data/lib/generators/kit/templates/kit_js.erb.tt +0 -1
  321. data/lib/generators/kit/templates/kit_jsx.erb.tt +0 -68
  322. data/lib/generators/kit/templates/kit_ruby.erb.tt +0 -11
  323. data/lib/generators/kit/templates/kit_ruby_spec.erb.tt +0 -11
  324. data/lib/generators/kit/templates/kit_scss.erb +0 -3
  325. data/lib/tasks/pb_release.rake +0 -77
  326. data/lib/tasks/playbook_tasks.rake +0 -26
@@ -1,25 +1,29 @@
1
- <%= content_tag(:div,
1
+ <% if object.pills %>
2
+ <%= react_component('Typeahead', object.typeahead_with_pills_options) %>
3
+ <% else %>
4
+ <%= content_tag(:div,
2
5
  id: object.id,
3
6
  data: object.data,
4
7
  class: object.classname) do %>
5
- <div class="pb_typeahead_wrapper">
6
- <div class="pb_typeahead_loading_indicator" data-pb-typeahead-kit-loading-indicator>
7
- <i class="far fa-spinner fa-spin"></i>
8
+ <div class="pb_typeahead_wrapper">
9
+ <div class="pb_typeahead_loading_indicator" data-pb-typeahead-kit-loading-indicator>
10
+ <i class="far fa-spinner fa-spin"></i>
11
+ </div>
12
+ <%= pb_rails("text_input", props: {
13
+ type: "search",
14
+ label: object.label,
15
+ name: object.name,
16
+ value: object.value,
17
+ placeholder: object.placeholder
18
+ }) %>
19
+ <%= pb_rails("list", props: { ordered: false, borderless: false, xpadding: true, role: "status", aria: { live: "polite" }, data: { pb_typeahead_kit_results: true } }) do %>
20
+ <% end %>
8
21
  </div>
9
- <%= pb_rails("text_input", props: {
10
- type: "search",
11
- label: object.label,
12
- name: object.name,
13
- value: object.value,
14
- placeholder: object.placeholder
15
- }) %>
16
- <%= pb_rails("list", props: { ordered: false, borderless: false, xpadding: true, role: "status", aria: { live: "polite" }, data: { pb_typeahead_kit_results: true } }) do %>
17
- <% end %>
18
- </div>
19
22
 
20
- <template data-pb-typeahead-kit-result-option>
21
- <%= pb_rails("list/item") do %>
22
- <button type="button" data-result-option-item><%= tag(:slot, name: :content) %></button>
23
- <% end %>
24
- </template>
25
- <% end %>
23
+ <template data-pb-typeahead-kit-result-option>
24
+ <%= pb_rails("list/item") do %>
25
+ <button type="button" data-result-option-item><%= tag(:slot, name: :content) %></button>
26
+ <% end %>
27
+ </template>
28
+ <% end %>
29
+ <% end %>
@@ -3,6 +3,7 @@
3
3
  import React from 'react'
4
4
  import Select from 'react-select'
5
5
  import AsyncSelect from 'react-select/async'
6
+ import { get } from 'lodash'
6
7
 
7
8
  import Control from './components/Control'
8
9
  import IndicatorsContainer from './components/IndicatorsContainer'
@@ -12,6 +13,8 @@ import Option from './components/Option'
12
13
  import Placeholder from './components/Placeholder'
13
14
  import ValueContainer from './components/ValueContainer'
14
15
 
16
+ import { noop } from '../utilities/props'
17
+
15
18
  /**
16
19
  * @typedef {object} Props
17
20
  * @prop {boolean} async - whether Typeahead should fetch data from
@@ -22,6 +25,8 @@ import ValueContainer from './components/ValueContainer'
22
25
  type Props = {
23
26
  async?: boolean,
24
27
  label?: string,
28
+ loadOptions?: noop | string,
29
+ name?: string,
25
30
  }
26
31
 
27
32
  /**
@@ -45,14 +50,27 @@ const Typeahead = (props: Props) => {
45
50
  },
46
51
  isClearable: true,
47
52
  isSearchable: true,
53
+ name,
48
54
  ...props,
49
55
  }
50
56
 
57
+ if (typeof(props.loadOptions) === 'string') selectProps.loadOptions = get(window, props.loadOptions)
58
+
51
59
  const Tag = props.async ? AsyncSelect : Select
52
60
 
61
+ const handleOnChange = (data, { action }) => {
62
+ if (action === 'clear') {
63
+ const multiValueClearEvent = new CustomEvent('pb-typeahead-kit-result-clear')
64
+ document.dispatchEvent(multiValueClearEvent)
65
+ }
66
+ }
67
+
53
68
  return (
54
69
  <div className="pb_typeahead_kit react-select">
55
- <Tag {...selectProps} />
70
+ <Tag
71
+ onChange={handleOnChange}
72
+ {...selectProps}
73
+ />
56
74
  </div>
57
75
  )
58
76
  }
@@ -19,11 +19,18 @@ const MultiValue = (props: Props) => {
19
19
  selectProps,
20
20
  } = props
21
21
 
22
+ const { imageUrl, label } = data
23
+
24
+ const handleOnMultiValueRemove = () => {
25
+ const multiValueRemoveEvent = new CustomEvent('pb-typeahead-kit-result-option-remove', { detail: data })
26
+ document.dispatchEvent(multiValueRemoveEvent)
27
+ }
28
+
22
29
  const handleOnClick = () => {
23
30
  if (selectProps.onMultiValueClick) selectProps.onMultiValueClick(data)
31
+ handleOnMultiValueRemove()
24
32
  removeProps.onClick()
25
33
  }
26
- const { imageUrl, label } = data
27
34
 
28
35
  return (
29
36
  <components.MultiValueContainer
@@ -12,21 +12,29 @@ const Option = (props: any) => {
12
12
  imageUrl,
13
13
  label,
14
14
  } = props.data
15
+
16
+ const handleOptionClicked = () => {
17
+ const resultSelectedEvent = new CustomEvent('pb-typeahead-kit-result-option-select', { detail: props.data })
18
+ document.dispatchEvent(resultSelectedEvent)
19
+ }
20
+
15
21
  return (
16
22
  <components.Option {...props}>
17
- <Choose>
18
- <When condition={imageUrl}>
19
- <User
20
- align="left"
21
- avatarUrl={imageUrl}
22
- name={label}
23
- orientation="horizontal"
24
- />
25
- </When>
26
- <When condition={!imageUrl}>
27
- {label}
28
- </When>
29
- </Choose>
23
+ <div onClick={handleOptionClicked}>
24
+ <Choose>
25
+ <When condition={imageUrl}>
26
+ <User
27
+ align="left"
28
+ avatarUrl={imageUrl}
29
+ name={label}
30
+ orientation="horizontal"
31
+ />
32
+ </When>
33
+ <When condition={!imageUrl}>
34
+ {label}
35
+ </When>
36
+ </Choose>
37
+ </div>
30
38
  </components.Option>
31
39
  )
32
40
  }
@@ -19,13 +19,14 @@
19
19
  name: tag(:slot, name: "name"),
20
20
  orientation: "horizontal",
21
21
  align: "left",
22
- avatar_url: "placeholder"
22
+ avatar_url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEAAAAASUVORK5CYII=",
23
+ avatar: true
23
24
  }) %>
24
25
  </template>
25
26
 
26
27
  <%= javascript_tag defer: "defer" do %>
27
28
  document.addEventListener("pb-typeahead-kit-search", function(event) {
28
- if (!event.target.dataset.typeaheadExample) return;
29
+ if (!event.target.dataset || !event.target.dataset.typeaheadExample) return;
29
30
 
30
31
  fetch(`https://api.github.com/search/users?q=${encodeURIComponent(event.detail.searchingFor)}`)
31
32
  .then(response => response.json())
@@ -35,7 +36,7 @@
35
36
  event.detail.setResults((result.items || []).map((user) => {
36
37
  const wrapper = resultOptionTemplate.content.cloneNode(true)
37
38
  wrapper.querySelector('slot[name="name"]').replaceWith(user.login)
38
- wrapper.querySelector('img').setAttribute("src", user.avatar_url)
39
+ wrapper.querySelector('img').dataset.src = user.avatar_url
39
40
  return wrapper
40
41
  }))
41
42
  })
@@ -18,7 +18,7 @@
18
18
 
19
19
  <%= javascript_tag defer: "defer" do %>
20
20
  document.addEventListener("pb-typeahead-kit-search", function(event) {
21
- if (!event.target.dataset.typeaheadExample2) return;
21
+ if (!event.target.dataset || !event.target.dataset.typeaheadExample2) return;
22
22
 
23
23
  const fuzzyMatch = function(string, term) {
24
24
  const ratio = 0.5;
@@ -0,0 +1,25 @@
1
+ <%
2
+ options = [
3
+ { label: 'Windows', value: '#FFA500' },
4
+ { label: 'Siding', value: '#FF0000' },
5
+ { label: 'Doors', value: '#00FF00' },
6
+ { label: 'Roofs', value: '#0000FF' },
7
+ ]
8
+ %>
9
+
10
+ <%= pb_rails("typeahead", props: { options: options, label: "Colors", name: :foo, pills: true }) %>
11
+
12
+ <!-- This section is an example of the available JavaScript event hooks -->
13
+ <%= javascript_tag defer: "defer" do %>
14
+ document.addEventListener("pb-typeahead-kit-result-option-select", function(event) {
15
+ console.log('Option selected')
16
+ console.dir(event.detail)
17
+ })
18
+ document.addEventListener("pb-typeahead-kit-result-option-remove", function(event) {
19
+ console.log('Option removed')
20
+ console.dir(event.detail)
21
+ })
22
+ document.addEventListener("pb-typeahead-kit-result-clear", function() {
23
+ console.log('All options cleared')
24
+ })
25
+ <% end %>
@@ -10,12 +10,9 @@ const options = [
10
10
  { label: 'Roofs', value: '#0000FF' },
11
11
  ]
12
12
 
13
- import TypeaheadWithPillsSummary from './_typeahead_with_pills_summary'
14
-
15
13
  const TypeaheadWithPills = () => {
16
14
  return (
17
15
  <>
18
- <TypeaheadWithPillsSummary />
19
16
  <Typeahead
20
17
  isMulti
21
18
  label="Colors"
@@ -0,0 +1,8 @@
1
+ Typeahead kit is data-driven. The minimum default fields are `label` and `value`.
2
+
3
+ `{ label: "Foo", value: "bar" }`
4
+
5
+ #### Rails: Subscribing to JS Events
6
+ `pb-typeahead-kit-result-option-select` event to perform custom work when an option is clicked.
7
+ `pb-typeahead-kit-result-option-remove` event to perform custom work when a pill is clicked.
8
+ `pb-typeahead-kit-result-option-clear` event to perform custom work when all pills are removed upon clicking the X.
@@ -0,0 +1,30 @@
1
+ <%= pb_rails("typeahead", props: { async: true, load_options: 'asyncPillsPromiseOptions', label: "Github Users", name: :foo, pills: true, placeholder: "type the name of a Github user" }) %>
2
+
3
+ <!-- This section is an example of how to provide load_options prop for using dynamic options -->
4
+ <%= javascript_tag defer: "defer" do %>
5
+ // Simple filter function, providing a list of results in the expected data format
6
+
7
+ const filterResults = function(results) {
8
+ return results.items.map(function(result) {
9
+ return {
10
+ label: result.login,
11
+ value: result.id,
12
+ }
13
+ })
14
+ }
15
+
16
+ /* Note: Make sure you assign this to window or a namespace within window
17
+ or it will not be accessible to the kit! */
18
+
19
+ window.asyncPillsPromiseOptions = function(inputValue) {
20
+ return new Promise(function(resolve) {
21
+ if (inputValue) {
22
+ fetch(`https://api.github.com/search/users?q=${inputValue}`)
23
+ .then(function(response) { return response.json() })
24
+ .then(function(results) { resolve(filterResults(results))})
25
+ } else {
26
+ resolve([])
27
+ }
28
+ })
29
+ }
30
+ <% end %>
@@ -0,0 +1,11 @@
1
+ #### Rails: Providing the `load_options` Promise
2
+
3
+ **Additional required props: ** `async: true`, `pills: true`
4
+
5
+ The prop `load_options`, when used in conjunction with `async: true` and `pills: true`, points to a JavaScript function located within the global window namespace. This function should return a `Promise` which resolves with the list of formatted options as described in prior examples above. This function is identical to the function provided to the React version of this kit. See the code example for more details.
6
+
7
+ #### React: `loadOptions`
8
+
9
+ **Additional required props: ** `async: true`
10
+
11
+ [As outlined in the react-select Async docs](https://react-select.com/async), `loadOptions` expects to return a Promise that resolves resolves with the list of formatted options as described in prior examples above. See the code example for more details.
@@ -0,0 +1,25 @@
1
+ <%= pb_rails("typeahead", props: { async: true, load_options: 'asyncPillsPromiseOptionsUsers', label: "Github Users", name: :foo, pills: true, placeholder: "type the name of a Github user" }) %>
2
+
3
+ <%= javascript_tag defer: "defer" do %>
4
+ const filterUserResults = function(results) {
5
+ return results.items.map(function(result) {
6
+ return {
7
+ imageUrl: result.avatar_url,
8
+ label: result.login,
9
+ value: result.id,
10
+ }
11
+ })
12
+ }
13
+
14
+ window.asyncPillsPromiseOptionsUsers = function(inputValue) {
15
+ return new Promise(function(resolve) {
16
+ if (inputValue) {
17
+ fetch(`https://api.github.com/search/users?q=${inputValue}`)
18
+ .then(function(response) { return response.json() })
19
+ .then(function(results) { resolve(filterUserResults(results))})
20
+ } else {
21
+ resolve([])
22
+ }
23
+ })
24
+ }
25
+ <% end %>
@@ -8,8 +8,6 @@ import {
8
8
  User,
9
9
  } from '../..'
10
10
 
11
- import TypeaheadWithPillsAsyncSummary from './_typeahead_with_pills_async_summary'
12
-
13
11
  /**
14
12
  *
15
13
  * @const filterResults
@@ -65,7 +63,6 @@ const TypeaheadWithPillsAsyncUsers = () => {
65
63
 
66
64
  return (
67
65
  <>
68
- <TypeaheadWithPillsAsyncSummary />
69
66
  <If condition={users && users.length > 0}>
70
67
  <Caption
71
68
  marginBottom="xs"
@@ -0,0 +1 @@
1
+ If the data field `imageUrl` is present, FormPill will receive that field as a prop and display the image.
@@ -2,6 +2,9 @@ examples:
2
2
  rails:
3
3
  - typeahead_default: Default
4
4
  - typeahead_with_context_dark: With Context
5
+ - typeahead_with_pills: With Pills
6
+ - typeahead_with_pills_async: With Pills (Async Data)
7
+ - typeahead_with_pills_async_users: With Pills (Async Data w/ Users)
5
8
 
6
9
  react:
7
10
  - typeahead_default: Default
@@ -5,12 +5,19 @@ module Playbook
5
5
  class Typeahead
6
6
  include Playbook::Props
7
7
 
8
+ prop :async, type: Playbook::Props::Boolean,
9
+ default: false
8
10
  prop :label
11
+ prop :load_options
9
12
  prop :name
10
- prop :value
13
+ prop :options, type: Playbook::Props::HashArray, default: []
14
+ prop :pills, type: Playbook::Props::Boolean,
15
+ default: false
16
+
11
17
  prop :placeholder
12
18
  prop :search_term_minimum_length, default: 3
13
19
  prop :search_debounce_timeout, default: 250
20
+ prop :value
14
21
 
15
22
  partial "pb_typeahead/typeahead"
16
23
 
@@ -25,6 +32,22 @@ module Playbook
25
32
  pb_typeahead_kit_search_debounce_timeout: search_debounce_timeout
26
33
  )
27
34
  end
35
+
36
+ def typeahead_with_pills_options
37
+ base_options = {
38
+ isMulti: true,
39
+ label: label,
40
+ options: options,
41
+ placeholder: placeholder
42
+ }
43
+
44
+ base_options.merge!({
45
+ async: true,
46
+ loadOptions: load_options,
47
+ }) if async
48
+
49
+ base_options
50
+ end
28
51
  end
29
52
  end
30
53
  end
@@ -26,8 +26,11 @@ const UserBadge = (props: UserBadgeProps) => {
26
26
  const image = require(`./badges/_${badge}.svg`)
27
27
  const ariaProps = buildAriaProps(aria)
28
28
  const dataProps = buildDataProps(data)
29
- const classes = classnames(buildCss('pb_user_badge_kit', size), globalProps(props),
30
- className)
29
+ const classes = classnames(
30
+ buildCss('pb_user_badge_kit', size),
31
+ globalProps(props),
32
+ className
33
+ )
31
34
 
32
35
  return (
33
36
  <div
@@ -124,7 +124,7 @@ module Playbook
124
124
 
125
125
  def prop(name, type: Playbook::Props::String, **options)
126
126
  @props ||= {}
127
- @props[name] = type.new(**options)
127
+ @props[name] = type.new(options.merge(name: name, kit: self))
128
128
 
129
129
  define_method(name) { prop(name) }
130
130
  end
@@ -5,11 +5,13 @@ module Playbook
5
5
  class Error < StandardError; end
6
6
 
7
7
  class Base
8
- attr_reader :default, :required
8
+ attr_reader :default, :required, :name, :kit
9
9
 
10
- def initialize(default: nil, required: false)
10
+ def initialize(default: nil, required: false, name:, kit:)
11
11
  @default = default
12
12
  @required = required
13
+ @name = name
14
+ @kit = kit
13
15
  end
14
16
 
15
17
  def value(value)
@@ -17,10 +19,10 @@ module Playbook
17
19
  end
18
20
 
19
21
  def validate!(input_value)
20
- raise(Playbook::Props::Error, "#{inspect} is a required prop and needs to be provided a value") if required && input_value.nil?
22
+ raise(Playbook::Props::Error, "#{kit} prop '#{name}' of type #{inspect.class} is required and needs a value") if required && input_value.nil?
21
23
 
22
24
  validate(value(input_value)) ||
23
- raise(Playbook::Props::Error, "Invalid value (#{input_value.inspect}) for prop (#{inspect})")
25
+ raise(Playbook::Props::Error, "#{kit} has invalid value of '#{input_value.inspect}' for prop '#{name}' of type #{inspect.class}")
24
26
  end
25
27
 
26
28
  def validate(_value)