playbook_ui 8.3.0.pre.alpha1 → 9.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -18
  3. data/app/pb_kits/playbook/pb_avatar/_avatar.scss +0 -3
  4. data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +7 -0
  5. data/app/pb_kits/playbook/pb_form/docs/_description.md +2 -6
  6. data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +1 -1
  7. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -4
  8. data/app/pb_kits/playbook/pb_form/docs/example.yml +2 -4
  9. data/app/pb_kits/playbook/pb_form/form.rb +14 -20
  10. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.scss +18 -55
  11. data/app/pb_kits/playbook/pb_select/_select.scss +2 -1
  12. data/app/pb_kits/playbook/pb_text_input/_text_input.scss +3 -16
  13. data/app/pb_kits/playbook/pb_textarea/_textarea.scss +2 -8
  14. data/app/pb_kits/playbook/pb_textarea/_textarea_mixin.scss +9 -4
  15. data/app/pb_kits/playbook/pb_typeahead/_typeahead.scss +6 -18
  16. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async_users.jsx +1 -0
  17. data/app/pb_kits/playbook/tokens/_colors.scss +1 -1
  18. data/lib/playbook.rb +4 -1
  19. data/lib/playbook/forms.rb +3 -0
  20. data/lib/playbook/forms/builder.rb +31 -0
  21. data/{app/pb_kits/playbook/pb_form/form_builder → lib/playbook/forms/builder}/action_area.rb +2 -2
  22. data/lib/playbook/forms/builder/checkbox_field.rb +32 -0
  23. data/lib/playbook/forms/builder/collection_select_field.rb +19 -0
  24. data/lib/playbook/forms/builder/date_picker_field.rb +37 -0
  25. data/{app/pb_kits/playbook/pb_form/form_builder → lib/playbook/forms/builder}/form_field_builder.rb +2 -2
  26. data/lib/playbook/forms/builder/select_field.rb +19 -0
  27. data/lib/playbook/forms/builder/typeahead_field.rb +12 -0
  28. data/lib/playbook/pb_forms_helper.rb +41 -0
  29. data/lib/playbook/pb_kit_helper.rb +2 -0
  30. data/lib/playbook/props/base.rb +1 -1
  31. data/lib/playbook/version.rb +1 -1
  32. metadata +22 -33
  33. data/app/pb_kits/playbook/pb_form/docs/_form_simple_form.html.erb +0 -60
  34. data/app/pb_kits/playbook/pb_form/docs/_form_simple_form_validate.html.erb +0 -61
  35. data/app/pb_kits/playbook/pb_form/docs/_form_simple_form_validate.md +0 -1
  36. data/app/pb_kits/playbook/pb_form/form_builder.rb +0 -31
  37. data/app/pb_kits/playbook/pb_form/form_builder/checkbox_field.rb +0 -34
  38. data/app/pb_kits/playbook/pb_form/form_builder/collection_select_field.rb +0 -21
  39. data/app/pb_kits/playbook/pb_form/form_builder/date_picker_field.rb +0 -39
  40. data/app/pb_kits/playbook/pb_form/form_builder/select_field.rb +0 -21
  41. data/app/pb_kits/playbook/pb_form/form_builder/typeahead_field.rb +0 -14
  42. data/app/pb_kits/playbook/pb_form/form_with.html.erb +0 -11
  43. data/app/pb_kits/playbook/pb_form/form_with.rb +0 -41
  44. data/app/pb_kits/playbook/pb_form/simple_form.html.erb +0 -11
  45. data/app/pb_kits/playbook/pb_form/simple_form.rb +0 -67
@@ -22,14 +22,13 @@
22
22
  .pb_text_area_kit:focus {
23
23
  border-color: $primary;
24
24
  @include pb_textarea_focus_light;
25
+ @include transition_default;
25
26
  }
26
-
27
27
  textarea:hover,
28
28
  .pb_text_area_kit:hover {
29
29
  background-color: rgba($focus_input_light,$opacity_5);
30
30
  }
31
-
32
-
31
+
33
32
  &.resize_both > textarea {
34
33
  resize: both;
35
34
  overflow: auto;
@@ -56,11 +55,6 @@
56
55
  textarea:focus, .pb_text_area_kit:focus {
57
56
  border-color: $active_dark;
58
57
  background-color: rgba($white, 0.025);
59
- -webkit-box-shadow: none;
60
- }
61
- textarea:hover,
62
- .pb_text_area_kit:hover {
63
- background-color: rgba($white, 0.15);
64
58
  }
65
59
  }
66
60
 
@@ -22,7 +22,7 @@
22
22
  overflow-wrap: break-word;
23
23
  resize: none;
24
24
  transition-property: box-shadow, color, background-color;
25
- transition-duration: .24s;
25
+ transition-duration: .3s;
26
26
  transition-timing-function: $bezier;
27
27
  &[type=number] {
28
28
  -moz-appearance:textfield;
@@ -40,9 +40,9 @@
40
40
  &:-webkit-autofill,
41
41
  &:-webkit-autofill:hover,
42
42
  &:-internal-autofill-selected {
43
- -webkit-text-fill-color: $text_color;
44
- -webkit-box-shadow: 0 0 0px 1000px transparent inset;
45
- transition: background-color 5000s ease-in-out 0s;
43
+ color: $text_color;
44
+ background-color: rgba($focus_input_light, $opacity_5);
45
+ transition: background-color 0.3s ease-in-out 0s;
46
46
  font-family: $font_family_base;
47
47
  }
48
48
  }
@@ -68,3 +68,8 @@
68
68
  @mixin pb_textarea_focus_dark {
69
69
  @include pb_textarea_focus($focus_input_dark);
70
70
  }
71
+
72
+ // Transitions ======================
73
+ @mixin transition_default{
74
+ transition: background-color 0.3s ease-in-out 0s, border-color 0.3s ease-in-out 0s;
75
+ }
@@ -14,13 +14,9 @@
14
14
  cursor: text;
15
15
  }
16
16
  .text_input_indicators,
17
- .pb_list_kit{
17
+ .pb_list_kit {
18
18
  cursor: pointer;
19
19
  }
20
-
21
-
22
-
23
-
24
20
  .pb_typeahead_loading_indicator {
25
21
  position: absolute;
26
22
  width: min-content;
@@ -31,15 +27,16 @@
31
27
  transition: opacity .15s ease-in-out;
32
28
  }
33
29
  }
34
-
35
30
  [class^=pb_text_input_kit] {
36
31
  .text_input_wrapper {
32
+ .text_input {
33
+ max-height: none;
34
+ }
37
35
  & > input:first-child {
38
36
  padding-right: $space_xl;
39
37
  }
40
38
  }
41
39
  }
42
-
43
40
  .pb_item_kit {
44
41
  padding: ($space_xs + 2) 0;
45
42
 
@@ -49,7 +46,6 @@
49
46
  }
50
47
  }
51
48
  }
52
-
53
49
  [class^=pb_list_kit] {
54
50
  max-height: 18em;
55
51
  overflow-y: auto;
@@ -63,17 +59,14 @@
63
59
  border-radius: $border_rad_heavier;
64
60
  transition: opacity .25s ease-in-out;
65
61
  }
66
-
67
62
  &:focus-within [class^=pb_list_kit] {
68
63
  display: block;
69
64
  opacity: 1;
70
65
  }
71
-
72
66
  &:not(:focus-within) [class^=pb_list_kit] {
73
67
  display: none;
74
68
  opacity: 0;
75
69
  }
76
-
77
70
  [class^=pb_list_kit] {
78
71
  margin-top: -$space-sm;
79
72
  li {
@@ -83,7 +76,6 @@
83
76
  &:focus-within {
84
77
  background-color: $active_light;
85
78
  }
86
-
87
79
  > button {
88
80
  background: none;
89
81
  color: $text_lt_default;
@@ -98,7 +90,6 @@
98
90
  }
99
91
  }
100
92
  }
101
-
102
93
  &[class*=dark] {
103
94
  .pb_typeahead_wrapper .pb_typeahead_loading_indicator {
104
95
  color: $text_dk_light;
@@ -113,23 +104,21 @@
113
104
  .typeahead-kit-select__option:hover {
114
105
  background-color: $active_dark;
115
106
  }
116
- .typeahead-kit-select__indicator:hover{
107
+ .typeahead-kit-select__indicator:hover {
117
108
  color: $white;
118
109
  }
119
-
120
110
  .typeahead-kit-select__input {
121
111
  color: white;
122
112
  input:focus {
123
113
  box-shadow: none;
124
114
  }
125
115
  }
126
- .typeahead-kit-select__single-value{
116
+ .typeahead-kit-select__single-value {
127
117
  color: white;
128
118
  }
129
119
  .typeahead-kit-select__option--is-focused {
130
120
  background-color: $active_dark;
131
121
  }
132
-
133
122
  [class^=pb_list_kit] {
134
123
  background-color: $bg_dark;
135
124
  }
@@ -144,7 +133,6 @@
144
133
  }
145
134
  }
146
135
  }
147
-
148
136
  &.react-select, &.react-select .dark {
149
137
  .text_input {
150
138
  display: inherit;
@@ -90,6 +90,7 @@ const TypeaheadWithPillsAsyncUsers = (props) => {
90
90
  isMulti
91
91
  label="Github Users"
92
92
  loadOptions={promiseOptions}
93
+ noOptionsMessage={() => 'Type to Search'}
93
94
  onChange={handleOnChange}
94
95
  onMultiValueClick={handleOnMultiValueClick}
95
96
  placeholder="type the name of a Github user"
@@ -114,7 +114,7 @@ $shadow_colors: (
114
114
 
115
115
  /* Text colors ------------------------*/
116
116
  $text_lt_default: $charcoal;
117
- $text_lt_light: #919EAB;
117
+ $text_lt_light: #687887;
118
118
  $text_lt_lighter: $slate;
119
119
  $text_dk_default: $white;
120
120
  $text_dk_light: rgba($white, $opacity_6);
data/lib/playbook.rb CHANGED
@@ -6,8 +6,11 @@ require "webpacker"
6
6
  require "webpacker/react"
7
7
  require "view_component/engine"
8
8
 
9
- require "playbook/props"
10
9
  require "playbook/version"
10
+
11
+ require "playbook/props"
12
+ require "playbook/forms"
13
+ require "playbook/pb_forms_helper"
11
14
  require "playbook/pb_kit_helper"
12
15
  require "playbook/pb_doc_helper"
13
16
  require "playbook/kit_base"
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "forms/builder"
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Playbook
4
+ module Forms
5
+ class Builder < ::ActionView::Helpers::FormBuilder
6
+ require_relative "builder/action_area"
7
+ require_relative "builder/checkbox_field"
8
+ require_relative "builder/collection_select_field"
9
+ require_relative "builder/date_picker_field"
10
+ require_relative "builder/form_field_builder"
11
+ require_relative "builder/select_field"
12
+ require_relative "builder/typeahead_field"
13
+
14
+ prepend(FormFieldBuilder.new(:email_field, kit_name: "text_input"))
15
+ prepend(FormFieldBuilder.new(:number_field, kit_name: "text_input"))
16
+ prepend(FormFieldBuilder.new(:search_field, kit_name: "text_input"))
17
+ prepend(FormFieldBuilder.new(:telephone_field, kit_name: "text_input"))
18
+ prepend(FormFieldBuilder.new(:text_field, kit_name: "text_input"))
19
+ prepend(FormFieldBuilder.new(:password_field, kit_name: "text_input"))
20
+ prepend(FormFieldBuilder.new(:url_field, kit_name: "text_input"))
21
+ prepend(FormFieldBuilder.new(:text_area, kit_name: "textarea"))
22
+
23
+ def actions
24
+ context = @template.respond_to?(:view_context) ? @template.view_context : @template
25
+ context.content_tag :ol, class: "pb-form-actions" do
26
+ yield ActionArea.new(@template, submit_default_value)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playbook
4
- module PbForm
5
- module FormBuilder
4
+ module Forms
5
+ class Builder
6
6
  class ActionArea
7
7
  def initialize(view_context, submit_default_value)
8
8
  self.view_context = view_context
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Playbook
4
+ module Forms
5
+ class Builder
6
+ def check_box(name, props: {}, **options)
7
+ label_text = @template.label(@object_name, name) if props[:label] == true
8
+ options[:required] = true if props[:required]
9
+ props[:margin_bottom] = "sm"
10
+ props[:form_spacing] = true
11
+
12
+ checked_value = options[:checked_value]
13
+ unchecked_value = options[:unchecked_value]
14
+ options.delete(:checked_value)
15
+ options.delete(:unchecked_value)
16
+
17
+ input = super(name, options, checked_value, unchecked_value)
18
+
19
+ if props[:label]
20
+ @template.pb_rails("caption", props: { text: label_text, margin_bottom: "xs" }) +
21
+ @template.pb_rails("checkbox", props: props) do
22
+ input
23
+ end
24
+ else
25
+ @template.pb_rails("checkbox", props: props) do
26
+ input
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Playbook
4
+ module Forms
5
+ class Builder
6
+ def collection_select(name, collection, value_method, text_method, options = {}, html_options = {}, props: {} )
7
+ props[:label] = @template.label(@object_name, name) if props[:label] == true
8
+ options[:skip_default_ids] = false unless options.has_key?(:skip_default_ids)
9
+ options[:prompt] = props[:blank_selection] || ""
10
+ html_options[:required] = "required" if props[:required]
11
+ input = super(name, collection, value_method, text_method, options, html_options)
12
+
13
+ @template.pb_rails("select", props: props) do
14
+ input
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Playbook
4
+ module Forms
5
+ class Builder
6
+ def date_picker(name, props: {})
7
+ prefix = @object_name
8
+ html_attribute_name = "#{prefix}[#{name}]"
9
+ html_id = "#{prefix}_#{name}"
10
+
11
+ props[:label] = @template.label(@object_name, name) if props[:label] == true
12
+ props[:label] = "Date Picker" if props[:label].nil?
13
+
14
+ props[:name] = html_attribute_name
15
+ props[:picker_id] = html_id
16
+
17
+ input = text_field(
18
+ name,
19
+ autocomplete: "off",
20
+ disabled: props[:disable_input],
21
+ data: props[:input_data],
22
+ aria: props[:input_aria],
23
+ props: {
24
+ error: props[:error],
25
+ label: props[:hide_label] ? nil : props[:label],
26
+ placeholder: props[:placeholder],
27
+ required: props[:required],
28
+ }
29
+ )
30
+
31
+ @template.pb_rails("date_picker", props: props) do
32
+ input
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playbook
4
- module PbForm
5
- module FormBuilder
4
+ module Forms
5
+ class Builder
6
6
  class FormFieldBuilder < Module
7
7
  def initialize(method_name, kit_name:)
8
8
  define_method method_name do |name, props: {}, **options, &block|
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Playbook
4
+ module Forms
5
+ class Builder
6
+ def select(name, choices = nil, options = {}, html_options = {}, props: {}, &block)
7
+ props[:label] = @template.label(@object_name, name) if props[:label] == true
8
+ options[:skip_default_ids] = false unless options.has_key?(:skip_default_ids)
9
+ options[:prompt] = props[:blank_selection] || ""
10
+ html_options[:required] = "required" if props[:required]
11
+ input = super(name, choices, options, html_options, &block)
12
+
13
+ @template.pb_rails("select", props: props) do
14
+ input
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Playbook
4
+ module Forms
5
+ class Builder
6
+ def typeahead(name, _options = {}, _html_options = {}, props: {})
7
+ props[:name] = name
8
+ @template.pb_rails("typeahead", props: props)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Playbook
4
+ module PbFormsHelper
5
+ # Renders a pb form with ::Playbook::Forms::Builder, that can render
6
+ # Playbook kits in the most railsie way.
7
+ #
8
+ # I.e.:
9
+ #
10
+ # pb_form_with model: @user do |f|
11
+ # f.text_field :name
12
+ # end
13
+ #
14
+ # The form can also validate the fields, and trigger the validation automatically:
15
+ #
16
+ # I.e.:
17
+ #
18
+ # pb_form_with model: @user, validate: true do |f|
19
+ # f.text_field :name, required: true
20
+ # end
21
+ #
22
+ # @param data [Hash] hash of data attributes
23
+ # @param validate [Boolean] whether validation should be triggered or not
24
+ # @see [#form_with] for other options
25
+ def pb_form_with(data: {}, validate: false, **kwargs, &block)
26
+ data = data.merge("pb-form-validation" => validate)
27
+ classname = ["pb-form", kwargs[:class]].join(" ")
28
+ options = kwargs.merge(
29
+ class: classname,
30
+ data: data,
31
+ builder: ::Playbook::Forms::Builder
32
+ )
33
+
34
+ content_for(:pb_js, javascript_tag(<<~JS))
35
+ window.addEventListener("DOMContentLoaded", function() { PbFormValidation.start() })
36
+ JS
37
+
38
+ form_with(**options, &block)
39
+ end
40
+ end
41
+ end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Playbook
4
4
  module PbKitHelper
5
+ include ::Playbook::PbFormsHelper
6
+
5
7
  def pb_rails(kit_name, props: {}, &block)
6
8
  kit = Playbook::KitResolver.resolve(kit_name.to_s)
7
9
  render_component kit.new(props, &block), &block
@@ -20,7 +20,7 @@ module Playbook
20
20
  end
21
21
 
22
22
  def validate!(input_value)
23
- warn("#{kit} Kit: The prop '#{name}' is deprecated and will be removed in a future release!") if deprecated #TODO: add some color for pop
23
+ warn("#{kit} Kit: The prop '#{name}' is deprecated and will be removed in a future release!") if deprecated && input_value #TODO: add some color for pop
24
24
 
25
25
  raise(Playbook::Props::Error, "#{kit} prop '#{name}' of type #{inspect.class} is required and needs a value") if required && input_value.nil?
26
26