slack-ruby-block-kit 0.9.0 → 0.14.0

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/.deepsource.toml +15 -0
  3. data/.github/workflows/ci.yml +33 -0
  4. data/.rubocop.yml +22 -2
  5. data/CHANGELOG.md +98 -0
  6. data/Gemfile +13 -1
  7. data/Gemfile.lock +61 -43
  8. data/README.md +3 -1
  9. data/lib/slack/block_kit.rb +2 -2
  10. data/lib/slack/block_kit/blocks.rb +18 -0
  11. data/lib/slack/block_kit/composition/confirmation_dialog.rb +16 -0
  12. data/lib/slack/block_kit/composition/option.rb +6 -1
  13. data/lib/slack/block_kit/composition/option_group.rb +2 -2
  14. data/lib/slack/block_kit/element/button.rb +3 -11
  15. data/lib/slack/block_kit/element/channels_select.rb +3 -11
  16. data/lib/slack/block_kit/element/checkboxes.rb +53 -0
  17. data/lib/slack/block_kit/element/conversations_select.rb +3 -11
  18. data/lib/slack/block_kit/element/date_picker.rb +3 -9
  19. data/lib/slack/block_kit/element/external_select.rb +3 -12
  20. data/lib/slack/block_kit/element/multi_channels_select.rb +5 -14
  21. data/lib/slack/block_kit/element/multi_conversations_select.rb +5 -14
  22. data/lib/slack/block_kit/element/multi_external_select.rb +5 -14
  23. data/lib/slack/block_kit/element/multi_static_select.rb +18 -25
  24. data/lib/slack/block_kit/element/multi_users_select.rb +5 -14
  25. data/lib/slack/block_kit/element/overflow_menu.rb +4 -11
  26. data/lib/slack/block_kit/element/radio_buttons.rb +53 -0
  27. data/lib/slack/block_kit/element/static_select.rb +20 -25
  28. data/lib/slack/block_kit/element/timepicker.rb +49 -0
  29. data/lib/slack/block_kit/element/users_select.rb +3 -11
  30. data/lib/slack/block_kit/layout/header.rb +29 -0
  31. data/lib/slack/block_kit/layout/input.rb +196 -3
  32. data/lib/slack/block_kit/layout/section.rb +20 -3
  33. data/lib/slack/block_kit/version.rb +7 -0
  34. data/slack-ruby-block-kit.gemspec +1 -18
  35. metadata +17 -138
  36. data/.circleci/config.yml +0 -49
  37. data/.rubocop_todo.yml +0 -33
@@ -13,35 +13,26 @@ module Slack
13
13
  #
14
14
  # https://api.slack.com/reference/block-kit/block-elements#users_multi_select
15
15
  class MultiUsersSelect
16
- TYPE = 'multi_users_select'
16
+ include Composition::ConfirmationDialog::Confirmable
17
17
 
18
- attr_accessor :confirm
18
+ TYPE = 'multi_users_select'
19
19
 
20
20
  def initialize(placeholder:, action_id:, initial: nil, emoji: nil, max_selected_items: nil)
21
21
  @placeholder = Composition::PlainText.new(text: placeholder, emoji: emoji)
22
22
  @action_id = action_id
23
- @initial_user = initial
24
- @confirm = nil
23
+ @initial_users = initial
25
24
  @max_selected_items = max_selected_items
26
25
 
27
26
  yield(self) if block_given?
28
27
  end
29
28
 
30
- def confirmation_dialog
31
- @confirm = Composition::ConfirmationDialog.new
32
-
33
- yield(@confirm) if block_given?
34
-
35
- self
36
- end
37
-
38
29
  def as_json(*)
39
30
  {
40
31
  type: TYPE,
41
32
  placeholder: @placeholder.as_json,
42
33
  action_id: @action_id,
43
- initial_user: @initial_user,
44
- confirm: @confirm&.as_json,
34
+ initial_users: @initial_users,
35
+ confirm: confirm&.as_json,
45
36
  max_selected_items: @max_selected_items
46
37
  }.compact
47
38
  end
@@ -15,14 +15,15 @@ module Slack
15
15
  #
16
16
  # https://api.slack.com/reference/messaging/block-elements#overflow
17
17
  class OverflowMenu
18
+ include Composition::ConfirmationDialog::Confirmable
19
+
18
20
  TYPE = 'overflow'
19
21
 
20
- attr_accessor :options, :confirm
22
+ attr_accessor :options
21
23
 
22
24
  def initialize(action_id:)
23
25
  @action_id = action_id
24
26
  @options = []
25
- @confirm = nil
26
27
 
27
28
  yield(self) if block_given?
28
29
  end
@@ -38,20 +39,12 @@ module Slack
38
39
  self
39
40
  end
40
41
 
41
- def confirmation_dialog
42
- @confirm = Composition::ConfirmationDialog.new
43
-
44
- yield(@confirm) if block_given?
45
-
46
- self
47
- end
48
-
49
42
  def as_json(*)
50
43
  {
51
44
  type: TYPE,
52
45
  action_id: @action_id,
53
46
  options: @options.map(&:as_json),
54
- confirm: @confirm&.as_json
47
+ confirm: confirm&.as_json
55
48
  }.compact
56
49
  end
57
50
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Element
6
+ # A radio button group that allows a user to choose one item from a list of possible options.
7
+ #
8
+ # https://api.slack.com/reference/messaging/block-elements#radio
9
+ class RadioButtons
10
+ include Composition::ConfirmationDialog::Confirmable
11
+
12
+ TYPE = 'radio_buttons'
13
+
14
+ attr_accessor :options
15
+
16
+ def initialize(action_id:)
17
+ @action_id = action_id
18
+ @options = []
19
+
20
+ yield(self) if block_given?
21
+ end
22
+
23
+ def option(value:, text:, initial: false)
24
+ option = Composition::Option.new(
25
+ value: value,
26
+ text: text,
27
+ initial: initial
28
+ )
29
+
30
+ @options << option
31
+
32
+ self
33
+ end
34
+
35
+ def as_json(*)
36
+ {
37
+ type: TYPE,
38
+ action_id: @action_id,
39
+ options: @options.map(&:as_json),
40
+ initial_option: initial_option&.as_json,
41
+ confirm: confirm&.as_json
42
+ }.compact
43
+ end
44
+
45
+ private
46
+
47
+ def initial_option
48
+ @options&.find(&:initial?)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -13,9 +13,11 @@ module Slack
13
13
  #
14
14
  # https://api.slack.com/reference/messaging/block-elements#static-select
15
15
  class StaticSelect
16
+ include Composition::ConfirmationDialog::Confirmable
17
+
16
18
  TYPE = 'static_select'
17
19
 
18
- attr_accessor :confirm, :options, :option_groups, :initial_option
20
+ attr_accessor :options, :option_groups
19
21
 
20
22
  def initialize(placeholder:, action_id:, emoji: nil)
21
23
  @placeholder = Composition::PlainText.new(text: placeholder, emoji: emoji)
@@ -24,20 +26,13 @@ module Slack
24
26
  yield(self) if block_given?
25
27
  end
26
28
 
27
- def confirmation_dialog
28
- @confirm = Composition::ConfirmationDialog.new
29
-
30
- yield(@confirm) if block_given?
31
-
32
- self
33
- end
34
-
35
- def option(value:, text:, emoji: nil)
29
+ def option(value:, text:, initial: false, emoji: nil)
36
30
  @options ||= []
37
31
  @options << Composition::Option.new(
38
32
  value: value,
39
33
  text: text,
40
- emoji: emoji
34
+ emoji: emoji,
35
+ initial: initial
41
36
  )
42
37
 
43
38
  self
@@ -54,27 +49,27 @@ module Slack
54
49
  self
55
50
  end
56
51
 
57
- def initial(value:, text:, emoji: nil)
58
- @initial_option = Composition::Option.new(
59
- value: value,
60
- text: text,
61
- emoji: emoji
62
- )
63
-
64
- self
65
- end
66
-
67
52
  def as_json(*)
68
53
  {
69
54
  type: TYPE,
70
55
  placeholder: @placeholder.as_json,
71
56
  action_id: @action_id,
72
- options: @options&.map(&:as_json),
73
- option_groups: @option_groups&.map(&:as_json),
74
- initial_option: @initial_option&.as_json,
75
- confirm: @confirm&.as_json
57
+ options: options&.map(&:as_json),
58
+ option_groups: option_groups&.map(&:as_json),
59
+ initial_option: initial_option&.as_json,
60
+ confirm: confirm&.as_json
76
61
  }.compact
77
62
  end
63
+
64
+ private
65
+
66
+ def initial_option
67
+ opts = options || option_groups&.flat_map(&:options)
68
+
69
+ return unless opts
70
+
71
+ opts.find(&:initial?)
72
+ end
78
73
  end
79
74
  end
80
75
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Element
6
+ # An element which allows selection of a time of day.
7
+ #
8
+ # On desktop clients, this time picker will take the form of a dropdown
9
+ # list with free-text entry for precise choices. On mobile clients, the
10
+ # time picker will use native time picker UIs.
11
+ #
12
+ # https://api.slack.com/reference/block-kit/block-elements#timepicker
13
+ class Timepicker
14
+ include Composition::ConfirmationDialog::Confirmable
15
+
16
+ TYPE = 'timepicker'
17
+
18
+ def initialize(action_id:)
19
+ @placeholder, @initial_time = nil
20
+ @action_id = action_id
21
+
22
+ yield(self) if block_given?
23
+ end
24
+
25
+ def placeholder(text:, emoji: nil)
26
+ @placeholder = Composition::PlainText.new(text: text, emoji: emoji)
27
+
28
+ self
29
+ end
30
+
31
+ def initial_time(time_str)
32
+ @initial_time = time_str
33
+
34
+ self
35
+ end
36
+
37
+ def as_json(*)
38
+ {
39
+ type: TYPE,
40
+ action_id: @action_id,
41
+ placeholder: @placeholder&.as_json,
42
+ initial_time: @initial_time,
43
+ confirm: confirm&.as_json
44
+ }.compact
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -13,9 +13,9 @@ module Slack
13
13
  #
14
14
  # https://api.slack.com/reference/messaging/block-elements#users-select
15
15
  class UsersSelect
16
- TYPE = 'users_select'
16
+ include Composition::ConfirmationDialog::Confirmable
17
17
 
18
- attr_accessor :confirm
18
+ TYPE = 'users_select'
19
19
 
20
20
  def initialize(placeholder:, action_id:, initial: nil, emoji: nil)
21
21
  @placeholder = Composition::PlainText.new(text: placeholder, emoji: emoji)
@@ -25,21 +25,13 @@ module Slack
25
25
  yield(self) if block_given?
26
26
  end
27
27
 
28
- def confirmation_dialog
29
- @confirm = Composition::ConfirmationDialog.new
30
-
31
- yield(@confirm) if block_given?
32
-
33
- self
34
- end
35
-
36
28
  def as_json(*)
37
29
  {
38
30
  type: TYPE,
39
31
  placeholder: @placeholder.as_json,
40
32
  action_id: @action_id,
41
33
  initial_user: @initial_user,
42
- confirm: @confirm&.as_json
34
+ confirm: confirm&.as_json
43
35
  }.compact
44
36
  end
45
37
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ # A header is a plain-text block that displays in a larger, bold font.
7
+ # Use it to delineate between different groups of content in your app's
8
+ # surfaces.
9
+ #
10
+ # https://api.slack.com/reference/block-kit/blocks#header
11
+ class Header
12
+ TYPE = 'header'
13
+
14
+ def initialize(text:, block_id: nil, emoji: nil)
15
+ @text = Composition::PlainText.new(text: text, emoji: emoji)
16
+ @block_id = block_id
17
+ end
18
+
19
+ def as_json(*)
20
+ {
21
+ type: TYPE,
22
+ text: @text.as_json,
23
+ block_id: @block_id
24
+ }.compact
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -4,8 +4,8 @@ module Slack
4
4
  module BlockKit
5
5
  module Layout
6
6
  # A block that collects information from users - it can hold a plain-text
7
- # input element, a select menu element, a multi-select menu element, or a
8
- # datepicker.
7
+ # input element, a checkbox element, a radio button element,
8
+ # a select menu element, a multi-select menu element, or a datepicker.
9
9
  #
10
10
  # https://api.slack.com/reference/block-kit/blocks#input
11
11
  class Input
@@ -15,7 +15,7 @@ module Slack
15
15
 
16
16
  def initialize(
17
17
  label:,
18
- element:,
18
+ element: nil,
19
19
  block_id: nil,
20
20
  hint: nil,
21
21
  optional: nil,
@@ -28,6 +28,199 @@ module Slack
28
28
  @element = element
29
29
  end
30
30
 
31
+ def conversation_select(placeholder:, action_id:, initial: nil, emoji: nil)
32
+ @element = Element::ConversationsSelect.new(
33
+ placeholder: placeholder,
34
+ action_id: action_id,
35
+ initial: initial,
36
+ emoji: emoji
37
+ )
38
+
39
+ yield(@element) if block_given?
40
+
41
+ self
42
+ end
43
+
44
+ def multi_conversations_select(placeholder:, action_id:, initial: nil, emoji: nil, max_selected_items: nil)
45
+ @element = Element::MultiConversationsSelect.new(
46
+ placeholder: placeholder,
47
+ action_id: action_id,
48
+ initial: initial,
49
+ emoji: emoji,
50
+ max_selected_items: max_selected_items
51
+ )
52
+
53
+ yield(@element) if block_given?
54
+
55
+ self
56
+ end
57
+
58
+ def channels_select(placeholder:, action_id:, initial: nil, emoji: nil)
59
+ @element = Element::ChannelsSelect.new(
60
+ placeholder: placeholder,
61
+ action_id: action_id,
62
+ initial: initial,
63
+ emoji: emoji
64
+ )
65
+
66
+ yield(@element) if block_given?
67
+
68
+ self
69
+ end
70
+
71
+ def checkboxes(action_id:)
72
+ @element = Element::Checkboxes.new(action_id: action_id)
73
+
74
+ yield(@element) if block_given?
75
+
76
+ self
77
+ end
78
+
79
+ def datepicker(action_id:, placeholder: nil, initial: nil, emoji: nil)
80
+ @element = Element::DatePicker.new(
81
+ action_id: action_id,
82
+ placeholder: placeholder,
83
+ initial: initial,
84
+ emoji: emoji
85
+ )
86
+
87
+ yield(@element) if block_given?
88
+
89
+ self
90
+ end
91
+
92
+ def multi_channels_select(placeholder:, action_id:, initial: nil, emoji: nil, max_selected_items: nil)
93
+ @element = Element::MultiChannelsSelect.new(
94
+ placeholder: placeholder,
95
+ action_id: action_id,
96
+ initial: initial,
97
+ emoji: emoji,
98
+ max_selected_items: max_selected_items
99
+ )
100
+
101
+ yield(@element) if block_given?
102
+
103
+ self
104
+ end
105
+
106
+ def static_select(placeholder:, action_id:, emoji: nil)
107
+ @element = Element::StaticSelect.new(
108
+ placeholder: placeholder,
109
+ action_id: action_id,
110
+ emoji: emoji
111
+ )
112
+
113
+ yield(@element) if block_given?
114
+
115
+ self
116
+ end
117
+
118
+ def multi_static_select(placeholder:, action_id:, emoji: nil, max_selected_items: nil)
119
+ @element = Element::MultiStaticSelect.new(
120
+ placeholder: placeholder,
121
+ action_id: action_id,
122
+ emoji: emoji,
123
+ max_selected_items: max_selected_items
124
+ )
125
+
126
+ yield(@element) if block_given?
127
+
128
+ self
129
+ end
130
+
131
+ def external_select(placeholder:, action_id:, initial: nil, min_query_length: nil, emoji: nil)
132
+ @element = Element::ExternalSelect.new(
133
+ placeholder: placeholder,
134
+ action_id: action_id,
135
+ initial: initial,
136
+ min_query_length: min_query_length,
137
+ emoji: emoji
138
+ )
139
+
140
+ yield(@element) if block_given?
141
+
142
+ self
143
+ end
144
+
145
+ def multi_external_select(
146
+ placeholder:,
147
+ action_id:,
148
+ initial: nil,
149
+ min_query_length: nil,
150
+ emoji: nil,
151
+ max_selected_items: nil
152
+ )
153
+ @element = Element::MultiExternalSelect.new(
154
+ placeholder: placeholder,
155
+ action_id: action_id,
156
+ initial: initial,
157
+ min_query_length: min_query_length,
158
+ emoji: emoji,
159
+ max_selected_items: max_selected_items
160
+ )
161
+
162
+ yield(@element) if block_given?
163
+
164
+ self
165
+ end
166
+
167
+ def plain_text_input(
168
+ action_id:,
169
+ placeholder: nil,
170
+ emoji: nil,
171
+ initial_value: nil,
172
+ multiline: nil,
173
+ min_length: nil,
174
+ max_length: nil
175
+ )
176
+ @element = Element::PlainTextInput.new(
177
+ action_id: action_id,
178
+ placeholder: placeholder,
179
+ emoji: emoji,
180
+ initial_value: initial_value,
181
+ multiline: multiline,
182
+ min_length: min_length,
183
+ max_length: max_length
184
+ )
185
+
186
+ self
187
+ end
188
+
189
+ def radio_buttons(action_id:)
190
+ @element = Element::RadioButtons.new(action_id: action_id)
191
+
192
+ yield(@element) if block_given?
193
+
194
+ self
195
+ end
196
+
197
+ def users_select(placeholder:, action_id:, initial: nil, emoji: nil)
198
+ @element = Element::UsersSelect.new(
199
+ placeholder: placeholder,
200
+ action_id: action_id,
201
+ initial: initial,
202
+ emoji: emoji
203
+ )
204
+
205
+ yield(@element) if block_given?
206
+
207
+ self
208
+ end
209
+
210
+ def multi_users_select(placeholder:, action_id:, initial: nil, emoji: nil, max_selected_items: nil)
211
+ @element = Element::MultiUsersSelect.new(
212
+ placeholder: placeholder,
213
+ action_id: action_id,
214
+ initial: initial,
215
+ emoji: emoji,
216
+ max_selected_items: max_selected_items
217
+ )
218
+
219
+ yield(@element) if block_given?
220
+
221
+ self
222
+ end
223
+
31
224
  def as_json(*)
32
225
  {
33
226
  type: TYPE,