line-message-builder 0.6.1 → 0.8.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.
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ module Builder
6
+ module Flex
7
+ # The `HasPartial` module provides functionality for Flex Message components
8
+ # (like {Box}, {Bubble}) to render reusable "partials". Partials are defined
9
+ # by creating classes that inherit from {Partial}.
10
+ #
11
+ # Including this module into a component class gives it the {#partial!} method.
12
+ #
13
+ # @example Defining and using a partial
14
+ # # Define a reusable partial
15
+ # class MyButtonPartial < Line::Message::Builder::Flex::Partial
16
+ # def call(label:, data:)
17
+ # # `button` method is available from the context (e.g., a Box)
18
+ # button style: :primary do |btn|
19
+ # btn.postback data, label: label
20
+ # end
21
+ # end
22
+ # end
23
+ #
24
+ # # Use the partial within a Box component
25
+ # a_box_component.instance_eval do
26
+ # # ... other box content ...
27
+ # partial! MyButtonPartial, label: "Action", data: "action=do_something"
28
+ # # ... other box content ...
29
+ # end
30
+ #
31
+ # @see Partial
32
+ module HasPartial
33
+ # Renders a given {Partial} class within the current component's context.
34
+ #
35
+ # This method temporarily makes the provided `assigns` available to the
36
+ # partial through the `context.assigns` mechanism. After the partial's
37
+ # `call` method completes, the original `context.assigns` are restored.
38
+ #
39
+ # @param partial_class [Class] The class of the partial to render. Must be a
40
+ # subclass of {Partial}.
41
+ # @param assigns [Hash] A hash of key-value pairs that will be made
42
+ # available as `assigns` within the partial's `call` method.
43
+ # @return [void]
44
+ # @raise [ArgumentError] if `partial_class` is not a subclass of {Partial}.
45
+ def partial!(partial_class, **assigns)
46
+ unless partial_class < Partial
47
+ raise ArgumentError,
48
+ "Argument must be a Line::Message::Builder::Flex::Partial class"
49
+ end
50
+
51
+ original_assigns = context.assigns
52
+ context.assigns = assigns
53
+ # `self` here is the component instance (e.g., Box, Bubble) that includes HasPartial.
54
+ # This component instance becomes the `@context` for the Partial instance.
55
+ partial_class.new(context: self).call
56
+ context.assigns = original_assigns
57
+ end
58
+ end
59
+
60
+ # The `Partial` class is an abstract base for creating reusable snippets
61
+ # of Flex Message content. To define a partial, create a new class that
62
+ # inherits from `Partial` and implements the {#call} instance method.
63
+ #
64
+ # Within the `call` method, you can use the standard Flex Message builder
65
+ # DSL methods (e.g., `text`, `box`, `button`) as if you were directly inside
66
+ # the component where the partial is being rendered. This is possible because
67
+ # the `Partial` instance delegates unknown method calls to the component
68
+ # instance that is rendering it (passed as `context` during initialization).
69
+ #
70
+ # @abstract Subclass and implement {#call} to create a concrete partial.
71
+ # @see HasPartial For how to render partials.
72
+ class Partial
73
+ # Initializes a new Partial instance.
74
+ # This is typically called by the {HasPartial#partial!} method.
75
+ #
76
+ # @param context [Object] The component instance (e.g., {Box}, {Bubble})
77
+ # within which this partial is being rendered. This context provides
78
+ # the DSL methods (like `text`, `box`) used in the partial's `call` method.
79
+ def initialize(context:)
80
+ @context = context # The component (e.g., Box, Bubble) rendering this partial
81
+ end
82
+
83
+ # This method must be implemented by subclasses to define the content of
84
+ # the partial. Inside this method, use the Flex Message builder DSL methods
85
+ # (e.g., `text "Hello"`, `button { ... }`) which will be delegated to the
86
+ # rendering context.
87
+ #
88
+ # Any arguments passed to `partial!` as `assigns` are available via
89
+ # `context.assigns` or directly if the rendering context's `method_missing`
90
+ # handles `assigns` lookup (as {Line::Message::Builder::Context} does).
91
+ #
92
+ # @param ... [Object] Arguments passed from the `partial!` call's `assigns`
93
+ # can be explicitly defined as parameters here, or accessed via `context.assigns`.
94
+ # @raise [NotImplementedError] if a subclass does not implement this method.
95
+ def call(*)
96
+ raise NotImplementedError,
97
+ "The #{self.class.name} class must implement the #call method to define its content."
98
+ end
99
+
100
+ # @!visibility private
101
+ # Part of Ruby's dynamic method dispatch. It's overridden here to declare
102
+ # that instances of `Partial` can respond to methods to which the
103
+ # wrapped `@context` object responds.
104
+ def respond_to_missing?(method_name, include_private = false)
105
+ @context.respond_to?(method_name, include_private) || super
106
+ end
107
+
108
+ # @!visibility private
109
+ # Handles calls to methods not explicitly defined on the `Partial` class
110
+ # by delegating them to the wrapped `@context` object (the rendering component).
111
+ # This allows the `call` method of a partial to use DSL methods like `text`,
112
+ # `box`, `button`, etc., as if they were defined directly in the partial.
113
+ def method_missing(method_name, ...)
114
+ if @context.respond_to?(method_name)
115
+ @context.public_send(method_name, ...)
116
+ else
117
+ super
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -4,9 +4,34 @@ module Line
4
4
  module Message
5
5
  module Builder
6
6
  module Flex
7
+ # The `Position` module serves as a namespace for several mixin modules
8
+ # that provide common positioning-related properties (options) to various
9
+ # Flex Message components (like {Box}, {Text}, {Image}, {Button}).
10
+ #
11
+ # These mixins are included in component classes to add DSL methods for
12
+ # setting properties like alignment, gravity, padding, margin, and offsets,
13
+ # which correspond to attributes in the LINE Flex Message JSON structure.
14
+ #
15
+ # @see Horizontal For `align` property.
16
+ # @see Vertical For `gravity` property.
17
+ # @see Padding For `paddingAll`, `paddingTop`, etc. properties.
18
+ # @see Margin For `margin` property.
19
+ # @see Offset For `position`, `offsetTop`, etc. properties.
7
20
  module Position
8
- # The horizontal provides "align" options for flex components.
21
+ # Provides the `align` option for horizontal alignment of a component
22
+ # within its parent {Box} (if the parent box's `layout` is vertical).
23
+ # For components like {Image} or {Text}, this controls their horizontal
24
+ # alignment within the space allocated to them.
25
+ #
26
+ # @!method align(value)
27
+ # Sets or gets the horizontal alignment.
28
+ # @param value [Symbol, String, nil] Alignment keyword:
29
+ # `:start` (aligns to the start of the horizontal space),
30
+ # `:center` (aligns to the center),
31
+ # `:end` (aligns to the end).
32
+ # @return [Symbol, String, nil] The current alignment value.
9
33
  module Horizontal
34
+ # @!visibility private
10
35
  def self.included(base)
11
36
  base.option :align,
12
37
  default: nil,
@@ -16,10 +41,22 @@ module Line
16
41
  end
17
42
  end
18
43
 
19
- # The vertical provides "gatvity" options for flex components.
44
+ # Provides the `gravity` option for vertical alignment of a component
45
+ # within its parent {Box} (if the parent box's `layout` is horizontal
46
+ # or baseline). For components like {Image} or {Text}, this controls
47
+ # their vertical alignment within the space allocated to them.
48
+ #
49
+ # @!method gravity(value)
50
+ # Sets or gets the vertical alignment (gravity).
51
+ # @param value [Symbol, String, nil] Gravity keyword:
52
+ # `:top` (aligns to the top),
53
+ # `:center` (aligns to the center),
54
+ # `:bottom` (aligns to the bottom).
55
+ # @return [Symbol, String, nil] The current gravity value.
20
56
  module Vertical
57
+ # @!visibility private
21
58
  def self.included(base)
22
- base.option :gravity,
59
+ base.option :gravity, # NOTE: API key is `gravity` (lowercase `g`)
23
60
  default: nil,
24
61
  validator: Validators::Enum.new(
25
62
  :top, :center, :bottom
@@ -27,35 +64,108 @@ module Line
27
64
  end
28
65
  end
29
66
 
30
- # The padding provides "padding" options for flex components.
67
+ # Provides padding options for components, allowing space to be defined
68
+ # around the content of a component, inside its borders.
69
+ #
70
+ # @!method padding_all(value)
71
+ # Sets or gets the padding for all sides.
72
+ # Corresponds to LINE API `paddingAll`.
73
+ # @param value [String, Symbol, nil] Padding value (e.g., `"10px"`, `"md"`, `"5%"`).
74
+ # Keywords: `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`.
75
+ # @return [String, Symbol, nil] The current padding value.
76
+ #
77
+ # @!method padding_top(value)
78
+ # Sets or gets the top padding. Corresponds to LINE API `paddingTop`.
79
+ # @param value [String, Symbol, nil] Padding value.
80
+ # @return [String, Symbol, nil] The current top padding.
81
+ #
82
+ # @!method padding_bottom(value)
83
+ # Sets or gets the bottom padding. Corresponds to LINE API `paddingBottom`.
84
+ # @param value [String, Symbol, nil] Padding value.
85
+ # @return [String, Symbol, nil] The current bottom padding.
86
+ #
87
+ # @!method padding_start(value)
88
+ # Sets or gets the start-edge padding (left in LTR, right in RTL).
89
+ # Corresponds to LINE API `paddingStart`.
90
+ # @param value [String, Symbol, nil] Padding value.
91
+ # @return [String, Symbol, nil] The current start padding.
92
+ #
93
+ # @!method padding_end(value)
94
+ # Sets or gets the end-edge padding (right in LTR, left in RTL).
95
+ # Corresponds to LINE API `paddingEnd`.
96
+ # @param value [String, Symbol, nil] Padding value.
97
+ # @return [String, Symbol, nil] The current end padding.
98
+ #
99
+ # @note In this DSL, `padding` is an alias for `padding_all`.
100
+ # The LINE API uses `paddingAll`. When using the DSL `padding(value)`,
101
+ # it sets the underlying value that will be output as `paddingAll`.
31
102
  module Padding
103
+ # @!visibility private
32
104
  def self.included(base)
33
- %i[padding padding_top padding_bottom padding_start padding_end].each do |option|
34
- base.option option,
105
+ # Individual side paddings
106
+ %i[padding padding_all padding_top padding_bottom padding_start padding_end].each do |option_name|
107
+ base.option option_name, # e.g., maps to `paddingTop` in JSON
35
108
  default: nil,
36
109
  validator: Validators::Size.new(:pixel, :keyword, :percentage)
37
110
  end
38
111
  end
39
112
  end
40
113
 
41
- # The margin provides "margin" options for flex components.
114
+ # Provides the `margin` option, allowing space to be defined around a
115
+ # component, outside its borders.
116
+ #
117
+ # @!method margin(value)
118
+ # Sets or gets the margin space around the component.
119
+ # @param value [String, Symbol, nil] Margin value (e.g., `"10px"`, `"md"`).
120
+ # Keywords: `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`.
121
+ # @return [String, Symbol, nil] The current margin value.
42
122
  module Margin
123
+ # @!visibility private
43
124
  def self.included(base)
44
125
  base.option :margin,
45
126
  default: nil,
46
- validator: Validators::Size.new(:pixel, :keyword)
127
+ validator: Validators::Size.new(:pixel, :keyword) # Percentage not allowed for margin
47
128
  end
48
129
  end
49
130
 
50
- # The offset provides "offset" options for flex components.
131
+ # Provides options for positioning components using offsets, either
132
+ # absolutely or relatively to their normal position.
133
+ #
134
+ # @!method position(value)
135
+ # Sets or gets the positioning scheme.
136
+ # @param value [Symbol, String, nil] Positioning type:
137
+ # `:relative` (default, offsets are relative to normal position),
138
+ # `:absolute` (offsets are relative to the parent component's edges).
139
+ # @return [Symbol, String, nil] The current position type.
140
+ #
141
+ # @!method offset_top(value)
142
+ # Sets or gets the top offset. Corresponds to LINE API `offsetTop`.
143
+ # @param value [String, Symbol, nil] Offset value (e.g., `"10px"`, `"md"`).
144
+ # @return [String, Symbol, nil] The current top offset.
145
+ #
146
+ # @!method offset_bottom(value)
147
+ # Sets or gets the bottom offset. Corresponds to LINE API `offsetBottom`.
148
+ # @param value [String, Symbol, nil] Offset value.
149
+ # @return [String, Symbol, nil] The current bottom offset.
150
+ #
151
+ # @!method offset_start(value)
152
+ # Sets or gets the start-edge offset. Corresponds to LINE API `offsetStart`.
153
+ # @param value [String, Symbol, nil] Offset value.
154
+ # @return [String, Symbol, nil] The current start offset.
155
+ #
156
+ # @!method offset_end(value)
157
+ # Sets or gets the end-edge offset. Corresponds to LINE API `offsetEnd`.
158
+ # @param value [String, Symbol, nil] Offset value.
159
+ # @return [String, Symbol, nil] The current end offset.
51
160
  module Offset
161
+ # @!visibility private
52
162
  def self.included(base)
53
163
  base.option :position,
54
- default: nil,
164
+ default: nil, # LINE API default is :relative if offsets are used
55
165
  validator: Validators::Enum.new(:absolute, :relative)
56
166
 
57
- %i[offset_top offset_bottom offset_start offset_end].each do |option|
58
- base.option option,
167
+ %i[offset_top offset_bottom offset_start offset_end].each do |option_name|
168
+ base.option option_name, # e.g., maps to `offsetTop` in JSON
59
169
  default: nil,
60
170
  validator: Validators::Size.new(:pixel, :keyword)
61
171
  end
@@ -4,17 +4,50 @@ module Line
4
4
  module Message
5
5
  module Builder
6
6
  module Flex
7
+ # The `Size` module acts as a namespace for several mixin modules that
8
+ # provide various size-related properties (options) to Flex Message
9
+ # components. These properties control aspects like the component's flex
10
+ # factor within a box, specific size keywords for images or text, and
11
+ # adjustment behaviors like shrink-to-fit.
12
+ #
13
+ # These mixins are included in component classes (e.g., {Box}, {Image}, {Text})
14
+ # to add DSL methods for these sizing attributes.
15
+ #
16
+ # @see Flex For `flex` property (flex grow/shrink factor).
17
+ # @see Image For image-specific `size` keywords.
18
+ # @see Shared For common `size` keywords (text, icons, spans).
19
+ # @see AdjustMode For `adjustMode` property (e.g., shrink-to-fit).
7
20
  module Size
8
- # The flex size provides "flex" options for flex components.
21
+ # Provides the `flex` option, which determines the ratio of space a
22
+ # component occupies within its parent {Box} relative to its siblings.
23
+ # A higher flex value means the component will take up more space.
24
+ # A value of 0 means the component does not flex (its size is fixed).
25
+ #
26
+ # @!method flex(value)
27
+ # Sets or gets the flex factor of the component.
28
+ # @param value [Integer, nil] The flex factor. `0` means no flex.
29
+ # Positive integers determine the ratio.
30
+ # @return [Integer, nil] The current flex factor.
9
31
  module Flex
32
+ # @!visibility private
10
33
  def self.included(base)
11
34
  base.option :flex,
12
- default: nil
35
+ default: nil # Default is 0 if not specified and parent is a Box
13
36
  end
14
37
  end
15
38
 
16
- # The image provides "size" options for flex image component.
39
+ # Provides the `size` option specifically for {Image} components.
40
+ # This allows setting the image size using keywords recognized by the
41
+ # LINE API for images, or explicit pixel/percentage values.
42
+ #
43
+ # @!method size(value)
44
+ # Sets or gets the size of the image.
45
+ # @param value [Symbol, String, nil] Image size. Can be keywords like
46
+ # `:xxs`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, `:full`,
47
+ # or a string like `"50px"`, `"25%"`.
48
+ # @return [Symbol, String, nil] The current image size.
17
49
  module Image
50
+ # @!visibility private
18
51
  def self.included(base)
19
52
  base.option :size,
20
53
  default: nil,
@@ -22,8 +55,18 @@ module Line
22
55
  end
23
56
  end
24
57
 
25
- # The shared provides "size" options for flex components which is icon, text and span.
58
+ # Provides a common `size` option for components like {Text}, {Icon},
59
+ # and {Span}. This allows setting size using standard keywords or explicit
60
+ # pixel values.
61
+ #
62
+ # @!method size(value)
63
+ # Sets or gets the size of the component (e.g., text font size).
64
+ # @param value [Symbol, String, nil] Component size. Can be keywords like
65
+ # `:xxs`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, `3xl`, `4xl`, `5xl`,
66
+ # or a string like `"16px"`.
67
+ # @return [Symbol, String, nil] The current component size.
26
68
  module Shared
69
+ # @!visibility private
27
70
  def self.included(base)
28
71
  base.option :size,
29
72
  default: nil,
@@ -31,18 +74,33 @@ module Line
31
74
  end
32
75
  end
33
76
 
34
- # The adjust mode provides "adjust mode" options for flex components.
77
+ # Provides the `adjust_mode` option, primarily for {Button} components,
78
+ # to control how they fit within available space. Currently, only
79
+ # `shrink-to-fit` is supported by LINE API via this property.
80
+ #
81
+ # @!method adjust_mode(value)
82
+ # Sets or gets the adjust mode.
83
+ # @param value [Symbol, String, nil] The adjust mode. Currently, only
84
+ # `:"shrink-to-fit"` is a valid value.
85
+ # @return [Symbol, String, nil] The current adjust mode.
35
86
  module AdjustMode
87
+ # @!visibility private
36
88
  def self.included(base)
37
89
  base.option :adjust_mode,
38
90
  default: nil,
39
91
  validator: Validators::Enum.new(
40
- :"shrink-to-fit"
92
+ :"shrink-to-fit" # LINE API uses "shrink-to-fit"
41
93
  )
42
94
  end
43
95
 
96
+ # A convenience DSL method to set the `adjust_mode` to `:"shrink-to-fit"`.
97
+ #
98
+ # @example
99
+ # button_component.shrink_to_fit!
100
+ #
101
+ # @return [Symbol] The value `:"shrink-to-fit"`.
44
102
  def shrink_to_fit!
45
- @adjust_mode = :"shrink-to-fit"
103
+ adjust_mode(:"shrink-to-fit")
46
104
  end
47
105
  end
48
106
  end
@@ -4,43 +4,121 @@ module Line
4
4
  module Message
5
5
  module Builder
6
6
  module Flex
7
- # The text is a component of the Flex message.
7
+ # Represents a "text" component in a LINE Flex Message.
8
+ #
9
+ # Text components are used to display strings of text. They offer various
10
+ # styling options, including font `size`, `weight` (via styles in a {Box}
11
+ # or {Bubble}), `color`, `align`ment, `gravity`, text `wrap`ping,
12
+ # `line_spacing`, and more. A text component can also have an
13
+ # {Actionable#action action} to make it tappable.
14
+ #
15
+ # @example Creating a text component within a box
16
+ # Line::Message::Builder.with do |root|
17
+ # root.flex alt_text: "Text Example" do |flex|
18
+ # flex.bubble do |bubble|
19
+ # bubble.body do |body_box|
20
+ # body_box.text "Hello, Flex World!",
21
+ # size: :xl,
22
+ # color: "#FF0000",
23
+ # wrap: true do |txt_action|
24
+ # txt_action.message "More info", text: "Tell me more about text"
25
+ # end
26
+ # end
27
+ # end
28
+ # end
29
+ # end
30
+ #
31
+ # @see https://developers.line.biz/en/reference/messaging-api/#text
32
+ # @see Actionable For making the text tappable.
33
+ # @see Position::Horizontal For `align` property.
34
+ # @see Position::Vertical For `gravity` property.
35
+ # @see Position::Margin For `margin` property.
36
+ # @see Position::Offset For offset properties.
37
+ # @see Size::Flex For `flex` sizing property.
38
+ # @see Size::Shared For common `size` keywords (e.g., `:xl`, `:sm`).
39
+ # @see Size::AdjustMode For `adjust_mode` property.
8
40
  class Text < Line::Message::Builder::Base
9
- include Actionable
10
- include Position::Horizontal
11
- include Position::Vertical
12
- include Position::Margin
13
- include Position::Offset
14
- include Size::Flex
15
- include Size::Shared
16
- include Size::AdjustMode
41
+ include Actionable # Enables defining an action for the text.
42
+ include Position::Horizontal # Adds `align` option.
43
+ include Position::Vertical # Adds `gravity` option.
44
+ include Position::Margin # Adds `margin` option.
45
+ include Position::Offset # Adds offset options.
46
+ include Size::Flex # Adds `flex` option for sizing within a parent box.
47
+ include Size::Shared # Adds `size` option (e.g., :sm, :md, :xl).
48
+ include Size::AdjustMode # Adds `adjust_mode` option.
17
49
 
50
+ # @!attribute [r] text
51
+ # @return [String] The actual text content to be displayed.
52
+ # This is a required attribute.
18
53
  attr_reader :text
19
54
 
55
+ # Specifies whether the text should wrap or be truncated if it exceeds
56
+ # the component's width.
57
+ # @!method wrap(value)
58
+ # @param value [Boolean] `true` to enable text wrapping, `false` (default) to disable.
59
+ # @return [Boolean] The current wrap setting.
20
60
  option :wrap, default: false
21
- option :line_spacing, default: nil
61
+
62
+ # Specifies the spacing between lines of text.
63
+ # Can be a pixel value (e.g., "10px") or a keyword.
64
+ # @!method line_spacing(value)
65
+ # @param value [String, nil] The line spacing value (e.g., `"5px"`).
66
+ # @return [String, nil] The current line spacing.
67
+ option :line_spacing, default: nil # API key: lineSpacing
68
+
69
+ # Specifies the color of the text.
70
+ # @!method color(value)
71
+ # @param value [String, nil] Hexadecimal color code (e.g., `"#RRGGBB"`, `"#RRGGBBAA"`).
72
+ # @return [String, nil] The current text color.
22
73
  option :color, default: nil
23
74
 
24
- def initialize(text, context: nil, **options, &)
25
- @text = text
75
+ # Initializes a new Flex Message Text component.
76
+ #
77
+ # @param text_content [String] The text to display. This is required.
78
+ # @param context [Object, nil] An optional context for the builder.
79
+ # @param options [Hash] A hash of options to set instance variables
80
+ # (e.g., `:wrap`, `:color`, `:size`, and options from included modules).
81
+ # @param block [Proc, nil] An optional block, typically used to define an
82
+ # {Actionable#action action} for the text.
83
+ # @raise [ArgumentError] if `text_content` is nil (though the more specific
84
+ # `RequiredError` is raised in `to_h`).
85
+ def initialize(text_content, context: nil, **options, &)
86
+ @text = text_content # The text content is mandatory.
26
87
 
27
- super(context: context, **options, &)
88
+ super(context: context, **options, &) # Sets options and evals block (for action).
28
89
  end
29
90
 
91
+ # A convenience DSL method to set the `wrap` property to `true`.
92
+ #
93
+ # @example
94
+ # text_component.text "Long text..."
95
+ # text_component.wrap! # Enables text wrapping
96
+ #
97
+ # @return [true]
30
98
  def wrap!
31
- @wrap = true
99
+ wrap(true) # Use the setter generated by `option`
32
100
  end
33
101
 
34
- def to_h # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
35
- raise RequiredError, "text is required" if text.nil?
102
+ def to_h
103
+ raise RequiredError, "text content is required for a text component" if text.nil?
104
+
105
+ return to_sdkv2 if context.sdkv2?
106
+
107
+ to_api
108
+ end
36
109
 
110
+ private
111
+
112
+ def to_api # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
37
113
  {
38
114
  type: "text",
39
115
  text: text,
40
- wrap: wrap,
41
- # Position
42
- align: align,
43
- gravity: gravity,
116
+ wrap: wrap, # From option
117
+ color: color, # From option
118
+ lineSpacing: line_spacing, # From option (maps to API key)
119
+ # Position::Horizontal & Position::Vertical
120
+ align: align, # From Position::Horizontal
121
+ gravity: gravity, # From Position::Vertical
44
122
  # Position::Margin
45
123
  margin: margin,
46
124
  # Position::Offset
@@ -51,13 +129,39 @@ module Line
51
129
  offsetEnd: offset_end,
52
130
  # Size::Flex
53
131
  flex: flex,
54
- # Size::Shared
55
- size: size,
56
- # Size::AdjustMode
57
- adjustMode: adjust_mode,
58
- lineSpacing: line_spacing,
59
- color: color,
60
- action: action&.to_h
132
+ # Size::Shared & Size::AdjustMode
133
+ size: size, # From Size::Shared
134
+ adjustMode: adjust_mode, # From Size::AdjustMode
135
+ # Actionable
136
+ action: action&.to_h # From Actionable module
137
+ }.compact
138
+ end
139
+
140
+ def to_sdkv2 # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
141
+ {
142
+ type: "text",
143
+ text: text,
144
+ wrap: wrap, # From option
145
+ color: color, # From option
146
+ line_spacing: line_spacing, # From option (maps to API key)
147
+ # Position::Horizontal & Position::Vertical
148
+ align: align, # From Position::Horizontal
149
+ gravity: gravity, # From Position::Vertical
150
+ # Position::Margin
151
+ margin: margin,
152
+ # Position::Offset
153
+ position: position,
154
+ offset_top: offset_top,
155
+ offset_bottom: offset_bottom,
156
+ offset_start: offset_start,
157
+ offset_end: offset_end,
158
+ # Size::Flex
159
+ flex: flex,
160
+ # Size::Shared & Size::AdjustMode
161
+ size: size, # From Size::Shared
162
+ adjust_mode: adjust_mode, # From Size::AdjustMode
163
+ # Actionable
164
+ action: action&.to_h # From Actionable module
61
165
  }.compact
62
166
  end
63
167
  end