line-message-builder 0.9.0 → 0.10.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/.release-please-manifest.json +1 -1
  3. data/.rubocop.yml +5 -0
  4. data/CHANGELOG.md +20 -0
  5. data/CLAUDE.md +124 -0
  6. data/README.md +24 -16
  7. data/claudekit.json +11 -0
  8. data/docs/rubrics/rdoc.md +169 -0
  9. data/lib/line/message/builder/actions/message.rb +47 -26
  10. data/lib/line/message/builder/actions/postback.rb +56 -26
  11. data/lib/line/message/builder/actions/uri.rb +139 -0
  12. data/lib/line/message/builder/actions.rb +6 -3
  13. data/lib/line/message/builder/base.rb +92 -67
  14. data/lib/line/message/builder/container.rb +55 -60
  15. data/lib/line/message/builder/context.rb +51 -72
  16. data/lib/line/message/builder/flex/actionable.rb +53 -32
  17. data/lib/line/message/builder/flex/box.rb +342 -79
  18. data/lib/line/message/builder/flex/bubble.rb +73 -46
  19. data/lib/line/message/builder/flex/builder.rb +39 -28
  20. data/lib/line/message/builder/flex/button.rb +90 -42
  21. data/lib/line/message/builder/flex/carousel.rb +48 -20
  22. data/lib/line/message/builder/flex/icon.rb +152 -0
  23. data/lib/line/message/builder/flex/image.rb +95 -33
  24. data/lib/line/message/builder/flex/partial.rb +47 -49
  25. data/lib/line/message/builder/flex/position.rb +187 -100
  26. data/lib/line/message/builder/flex/separator.rb +49 -6
  27. data/lib/line/message/builder/flex/size.rb +67 -47
  28. data/lib/line/message/builder/flex/span.rb +106 -32
  29. data/lib/line/message/builder/flex/text.rb +166 -54
  30. data/lib/line/message/builder/flex.rb +26 -23
  31. data/lib/line/message/builder/quick_reply.rb +174 -4
  32. data/lib/line/message/builder/text.rb +70 -3
  33. data/lib/line/message/builder/version.rb +1 -1
  34. data/lib/line/message/builder.rb +14 -11
  35. data/lib/line/message/rspec/matchers/have_flex_bubble.rb +1 -1
  36. data/lib/line/message/rspec/matchers/have_flex_component.rb +16 -6
  37. data/lib/line/message/rspec/matchers/have_flex_message.rb +1 -1
  38. data/lib/line/message/rspec/matchers/have_flex_separator.rb +1 -1
  39. data/lib/line/message/rspec/matchers/have_quick_reply.rb +1 -1
  40. data/lib/line/message/rspec/matchers/have_text_message.rb +1 -1
  41. data/llm.txt +276 -35
  42. data/release-please-config.json +3 -1
  43. metadata +9 -3
data/llm.txt CHANGED
@@ -2,6 +2,49 @@
2
2
 
3
3
  This document provides a comprehensive guide on using the Line Message Builder DSL to construct various types of LINE messages.
4
4
 
5
+ ## Project Status
6
+
7
+ **Current State:** Production-ready Ruby gem with comprehensive Flex Message support. Consult the Component Support Status below before using a property — anything not listed is not implemented, and an undeclared option raises.
8
+
9
+ ### Recent Major Updates
10
+ - **Unknown options now raise**: passing an option a component does not declare raises `ValidationError` instead of being silently dropped
11
+ - **URI action**: link a component to a web page without a webhook
12
+ - **Icon component**: icon-and-text pairs inside a baseline box
13
+ - **Text styling**: `weight`, `max_lines`, `style`, `decoration`, `scaling`
14
+ - **Box appearance**: background colour, border, corner radius and linear gradients
15
+ - **Button `color` and `scaling`**; Button no longer accepts `padding` (LINE defines none)
16
+ - **Image `background_color` and `animated`**; **Span `style`**; **Separator `margin` and `color`**
17
+
18
+ ### Component Support Status
19
+
20
+ Anything not listed as supported below is not implemented. There is no raw-hash
21
+ escape hatch — an undeclared option raises.
22
+
23
+ - **Text Messages**: supported, with Quick Reply
24
+ - **Flex Containers**: Bubble, Carousel
25
+ - **Flex Components**: Box, Text, Span, Button, Image, Icon, Separator
26
+ - **Actions**: `message`, `postback`, `uri`
27
+ - **Quick Replies**: supported (`message`, `postback`, `uri`)
28
+ - **Partials**: supported
29
+ - **RSpec Matchers**: text, flex message, bubble, box, text, button, image, icon, span, separator, quick reply
30
+
31
+ **Not supported yet**: the `video` component; `Bubble#direction` and a bubble-level
32
+ action; the Datetime Picker, Camera, Camera Roll, Location, Rich Menu Switch and
33
+ Clipboard actions.
34
+
35
+ **Deliberately not supported**: the `filler` component — LINE has deprecated it.
36
+ Use the spacing properties of each component instead.
37
+
38
+ ## Installation and Setup
39
+
40
+ ```bash
41
+ # Add to Gemfile
42
+ bundle add line-message-builder
43
+
44
+ # Or install directly
45
+ gem install line-message-builder
46
+ ```
47
+
5
48
  ## Basic Usage
6
49
 
7
50
  To start building messages, use the `Line::Message::Builder.with` method. This method accepts an optional context object and a block where you define your messages.
@@ -15,7 +58,12 @@ end
15
58
 
16
59
  # The `messages` variable will now hold an array of LINE message objects.
17
60
  # You can convert them to JSON for sending to the LINE API:
18
- # json_output = messages.to_json
61
+ json_output = messages.to_json
62
+
63
+ # For LINE Bot SDK v2 compatibility:
64
+ messages = Line::Message::Builder.with(mode: :sdkv2) do
65
+ text "Hello World!"
66
+ end
19
67
  ```
20
68
 
21
69
  ### Coding Style
@@ -54,6 +102,28 @@ Line::Message::Builder.with do |builder|
54
102
  end
55
103
  ```
56
104
 
105
+ ### Unknown Options Raise
106
+
107
+ Every component accepts only the options it declares. Passing anything else
108
+ raises `Line::Message::Builder::ValidationError`, naming the offending option and
109
+ listing the ones that component accepts:
110
+
111
+ ```ruby
112
+ text "Title", colour: "#FF0000"
113
+ # => Line::Message::Builder::ValidationError:
114
+ # Unknown option: colour for Line::Message::Builder::Flex::Text.
115
+ # Allowed options are: wrap, line_spacing, color, weight, max_lines, ...
116
+ ```
117
+
118
+ This is deliberate. A misspelled or unsupported property used to be dropped in
119
+ silence, producing a message that was missing the styling that was asked for
120
+ while every check downstream reported success. Read the error, correct the
121
+ option name against the list it prints, and rebuild.
122
+
123
+ Two consequences worth remembering:
124
+ - There is no `action:` option on any component. Declare actions inside the block.
125
+ - A `button` has no `label` option. The label belongs to its action.
126
+
57
127
  ### Context
58
128
 
59
129
  The builder can accept a context object. Methods called within the builder block will first attempt to resolve against this context object. This allows for dynamic message content based on your application's data.
@@ -115,40 +185,69 @@ You can also include emojis in text messages. A `quick_reply` can be attached (s
115
185
 
116
186
  Actions define what happens when a user interacts with a button or a tappable area in a message. They are used in Flex Message components (like buttons, or even entire boxes/images) and Quick Reply buttons.
117
187
 
118
- The primary action types defined by helper methods are:
188
+ **An action is declared inside the component's block, not passed as an `action:` keyword.** No component accepts an `action:` option; writing one raises `ValidationError`.
189
+
190
+ Three action types are supported: `message`, `postback` and `uri`.
119
191
 
120
192
  ### Message Action
121
193
  Sends a text message from the user's perspective.
122
- - `label`: (String, Required for Flex Buttons, Optional for Quick Reply if `text` is short) The text displayed on the button.
123
- - `text`: (String, Required) The text message to be sent when the button is tapped.
194
+ - First argument: (String, Required) The text message to be sent when tapped.
195
+ - `label`: (String, Optional) The text displayed on the button.
124
196
 
125
197
  ```ruby
126
- # Example in a Flex Button (action is a required parameter for button)
127
- button label: "Say Hello", action: message(label: "Say Hello", text: "Hello there!")
198
+ # In a Flex component declared inside the block
199
+ button do
200
+ message "Hello there!", label: "Say Hello"
201
+ end
128
202
 
129
- # Example in a Quick Reply
130
- # For quick reply, the first argument to `message` is the text to be sent.
203
+ # In a Quick Reply — label is required here
131
204
  quick_reply do
132
- message "Yes, please!", label: "Yes" # label is optional if text is short
205
+ message "Yes, please!", label: "Yes"
133
206
  end
134
207
  ```
135
208
 
136
209
  ### Postback Action
137
- Sends a postback event to your bot's webhook. This is useful for triggering backend logic without displaying a message in the chat.
138
- - `label`: (String, Required for Flex Buttons, Optional for Quick Reply) The text displayed on the button.
139
- - `data`: (String, Required) The data string sent in the postback event to your webhook.
140
- - `display_text`: (String, Optional) Text displayed in the chat as if the user had typed it after tapping the button.
210
+ Sends a postback event to your bot's webhook. Useful for triggering backend logic without displaying a message in the chat. A postback whose event your webhook does not handle is a dead button.
211
+ - First argument: (String, Required) The data string sent in the postback event.
212
+ - `label`: (String, Optional) The text displayed on the button.
213
+ - `display_text`: (String, Optional) Text displayed in the chat as if the user had typed it.
141
214
 
142
215
  ```ruby
143
- # Example in a Flex Button
144
- button label: "Add to Cart", action: postback(label: "Add to Cart", data: "action=add_item&item_id=101", display_text: "Added to cart!")
216
+ # In a Flex component
217
+ button do
218
+ postback "action=add_item&item_id=101", label: "Add to Cart", display_text: "Added to cart!"
219
+ end
145
220
 
146
- # Example in a Quick Reply
221
+ # In a Quick Reply
147
222
  quick_reply do
148
223
  postback "action=view_profile", label: "View Profile"
149
224
  end
150
225
  ```
151
- Other action types like URI, Datetime Picker, Camera, Camera Roll, Location can also be defined by passing a hash that conforms to the LINE API's action object structure directly to the `action` parameter of a component (e.g., `action: { type: :uri, label: "Visit Website", uri: "https://example.com" }`).
226
+
227
+ ### URI Action
228
+ Opens a URI when tapped. Needs no webhook handling, so this is the action to use for linking a card to a web page.
229
+ - First argument: (String, Required) The URI to open. Schemes `http`, `https`, `line`, `tel`. Max 1000 characters.
230
+ - `label`: (String, Optional in Flex, Required in Quick Reply) The text displayed on the button.
231
+ - `alt_uri_desktop`: (String, Optional) A different URI opened on LINE for macOS and Windows. Maps to `altUri.desktop`. Has no effect in a Quick Reply.
232
+
233
+ ```ruby
234
+ # In a Flex component
235
+ button style: :primary do
236
+ uri "https://example.com/event", label: "View event"
237
+ end
238
+
239
+ # Opening a different page on desktop
240
+ button do
241
+ uri "https://example.com/mobile", label: "Open", alt_uri_desktop: "https://example.com/desktop"
242
+ end
243
+
244
+ # In a Quick Reply
245
+ quick_reply do
246
+ uri "tel:+81312345678", label: "Call us"
247
+ end
248
+ ```
249
+
250
+ The remaining LINE action types (Datetime Picker, Camera, Camera Roll, Location, Rich Menu Switch, Clipboard) are **not yet supported**. There is no raw-hash escape hatch.
152
251
 
153
252
  ## Quick Replies
154
253
 
@@ -242,7 +341,9 @@ flex alt_text: "Recipe Card" do
242
341
  end
243
342
  end
244
343
  footer do
245
- button label: "View Recipe", action: { type: :uri, label: "View Recipe", uri: "http://example.com/recipe" }
344
+ button style: :primary do
345
+ uri "https://example.com/recipe", label: "View Recipe"
346
+ end
246
347
  end
247
348
  end
248
349
  end
@@ -268,13 +369,29 @@ A `box` arranges other components.
268
369
  - Sizing:
269
370
  - `width`, `max_width`, `height`, `max_height`: (String, Optional) Pixel or percentage strings (e.g., `'100px'`, `'50%'`).
270
371
  - `flex`: (Integer, Optional) Flex factor determining how much space this box takes relative to siblings.
271
- - `action`: (Action Object, Optional) Makes the entire box tappable. See Actions section.
372
+ - Appearance:
373
+ - `background_color`: (String, Optional) Hex colour, alpha channel allowed (e.g., `'#RRGGBBAA'`).
374
+ - `border_color`: (String, Optional) Hex colour of the border.
375
+ - `border_width`: (Symbol or String, Optional) `:none`, `:light`, `:normal`, `:medium`, `:"semi-bold"`, `:bold`, or a pixel value.
376
+ - `corner_radius`: (Symbol or String, Optional) `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, or a pixel value.
377
+ - `background_angle`, `background_start_color`, `background_end_color`: (String, Optional) A linear gradient. Setting any one of them makes all three required, otherwise a `RequiredError` is raised.
378
+ - `background_center_color`, `background_center_position`: (String, Optional) An intermediate colour stop, e.g. `'#00FF00'` at `'30%'`.
379
+ - Tappable: declare an action inside the block to make the whole box tappable.
272
380
 
273
381
  ```ruby
274
- box layout: :vertical, spacing: :md, padding_all: :lg, action: message(text: "Box tapped!") do
382
+ box layout: :vertical, spacing: :md, padding_all: :lg do
383
+ message "Box tapped!", label: "Open"
275
384
  text "Item 1"
276
385
  text "Item 2"
277
386
  end
387
+
388
+ # A rounded card with a gradient background
389
+ box layout: :vertical, corner_radius: :lg, padding_all: :lg,
390
+ background_angle: "90deg",
391
+ background_start_color: "#3F51B5",
392
+ background_end_color: "#2196F3" do
393
+ text "Gradient card", color: "#FFFFFF", weight: :bold
394
+ end
278
395
  ```
279
396
 
280
397
  #### Text Component
@@ -284,21 +401,33 @@ Displays text.
284
401
  - `wrap`: (Boolean, Optional) `true` to allow text to wrap. Default `false`.
285
402
  - `line_spacing`: (String, Optional) Spacing between lines, e.g., `'4px'`, `'1.5em'`.
286
403
  - `color`: (String, Optional) Hex color code (e.g., `'#RRGGBB'`, `'#RRGGBBAA'`).
404
+ - `weight`: (Symbol, Optional) `:regular` (default) or `:bold`.
405
+ - `style`: (Symbol, Optional) `:normal` (default) or `:italic`.
406
+ - `decoration`: (Symbol, Optional) `:none` (default), `:underline` or `:"line-through"`. A decoration set here cannot be overridden by a nested span.
407
+ - `max_lines`: (Integer, Optional) Truncate after this many lines with an ellipsis. `0` (default) shows the whole text.
408
+ - `scaling`: (Boolean, Optional) `true` to follow the reader's LINE font size setting. Nested spans scale too.
287
409
  - Layout:
288
410
  - `align`: (Symbol, Optional) Horizontal alignment of the text. Valid values: `:start`, `:center`, `:end`.
289
411
  - `gravity`: (Symbol, Optional) Vertical alignment of the text within its allocated space. Valid values: `:top`, `:center`, `:bottom`.
290
412
  - `margin`: (Symbol or String, Optional) Margin around the text component. Valid keywords: `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`. Also accepts pixel values (e.g., `'10px'`).
291
413
  - Sizing:
292
- - `size`: (Symbol or String, Optional) Font size. Valid keywords: `:xxs`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, `:3xl`, `:4xl`, `:5xl`. Also accepts pixel values (e.g., `'16px'`).
293
- - `weight`: (Symbol, Optional) Font weight. Valid values: `:regular`, `:bold`.
414
+ - `size`: (Symbol or String, Optional) Font size. Accepted keywords: `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, or a pixel value (e.g., `'16px'`). Note: LINE also defines `:xxs` and `:3xl`–`:5xl`, but this gem does not accept them yet.
294
415
  - `flex`: (Integer, Optional) Flex factor.
295
416
  - `adjust_mode`: (Symbol, Optional) How text adjusts when it overflows. Valid value: `:shrink_to_fit` (reduces font size).
296
- - `action`: (Action Object, Optional) Makes the text tappable.
417
+ - Tappable: declare an action inside the block.
297
418
  - `span`: Within a Text component, you can add Span components to style parts of the text differently.
298
419
 
299
420
  ```ruby
300
421
  # Simple text component
301
- text "Special Offer!", size: :xl, weight: :bold, color: "#FF0000", align: :center, action: postback(data: "offer_details")
422
+ text "Special Offer!", size: :xl, weight: :bold, color: "#FF0000", align: :center
423
+
424
+ # Truncating a long body
425
+ text article_body, wrap: true, max_lines: 3
426
+
427
+ # Making the text tappable
428
+ text "See details" do
429
+ postback "offer_details", label: "Details"
430
+ end
302
431
 
303
432
  # Text with spans for different styling of segments
304
433
  text "Welcome to our service:" do
@@ -309,19 +438,28 @@ end
309
438
  ```
310
439
 
311
440
  #### Button Component
312
- An actionable button.
313
- - `action`: (Action Object, **Required**) Defines the action performed on tap. See Actions section.
441
+ An actionable button. **The action is declared inside the block and is required.** The button's visible text comes from the action's `label`; a button has no `label` option of its own.
314
442
  - `style`: (Symbol, Optional) Visual style of the button. Valid values: `:primary`, `:secondary`, `:link`. Default is `:link`.
443
+ - `color`: (String, Optional) Hex colour. Text colour when `style` is `:link`, background colour when `:primary` or `:secondary`.
315
444
  - `height`: (Symbol, Optional) Height of the button. Valid values: `:sm`, `:md`. Default is `:md`.
445
+ - `scaling`: (Boolean, Optional) `true` to follow the reader's LINE font size setting.
316
446
  - Layout:
317
447
  - `gravity`: (Symbol, Optional) Vertical alignment if the box containing it has extra space. Valid values: `:top`, `:center`, `:bottom`.
318
448
  - `margin`: (Symbol or String, Optional) Margin around the button. Valid keywords: `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`. Also accepts pixel values (e.g., `'10px'`).
319
449
  - Sizing:
320
450
  - `flex`: (Integer, Optional) Flex factor.
321
451
  - `adjust_mode`: (Symbol, Optional) How the button adjusts its content. Valid value: `:shrink_to_fit`.
452
+ - **No padding**: LINE defines no padding properties for a button. Pad the surrounding box instead.
322
453
 
323
454
  ```ruby
324
- button label: "Confirm", style: :primary, height: :md, action: postback(data: "confirm_order", label: "Confirm")
455
+ button style: :primary, color: "#1DB446" do
456
+ postback "action=confirm_order", label: "Confirm"
457
+ end
458
+
459
+ # Linking to a web page
460
+ button style: :link do
461
+ uri "https://example.com/event", label: "View event"
462
+ end
325
463
  ```
326
464
 
327
465
  #### Image Component
@@ -330,6 +468,8 @@ Displays an image.
330
468
  - Styling:
331
469
  - `aspect_ratio`: (String, Optional) Aspect ratio as `"width:height"`, e.g., `"1:1"`, `"16:9"`, `"4:3"`.
332
470
  - `aspect_mode`: (Symbol, Optional) How the image fits the `aspect_ratio`. Valid values: `:cover` (default, crops to fill) or `:fit` (fits within, may letterbox).
471
+ - `background_color`: (String, Optional) Hex colour shown behind the image.
472
+ - `animated`: (Boolean, Optional) `true` plays an APNG. At most 10 animated images per message; frames over 300 KB are not played.
333
473
  - Layout:
334
474
  - `align`: (Symbol, Optional) Horizontal alignment of the image. Valid values: `:start`, `:center`, `:end`.
335
475
  - `gravity`: (Symbol, Optional) Vertical alignment of the image. Valid values: `:top`, `:center`, `:bottom`.
@@ -337,10 +477,33 @@ Displays an image.
337
477
  - Sizing:
338
478
  - `size`: (Symbol or String, Optional) Size of the image. Valid keywords: `:xxs`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, `:3xl`, `:4xl`, `:5xl`, `:full`. Also accepts pixel or percentage strings (e.g. `'100px'`, `'50%'`).
339
479
  - `flex`: (Integer, Optional) Flex factor.
340
- - `action`: (Action Object, Optional) Makes the image tappable.
480
+ - Tappable: declare an action inside the block.
481
+
482
+ ```ruby
483
+ image "https://example.com/product_image.png", size: :full, aspect_ratio: "1:1", aspect_mode: :cover
484
+
485
+ # Making the image tappable
486
+ image "https://example.com/product_image.png", size: :full do
487
+ uri "https://example.com/product", label: "View product"
488
+ end
489
+ ```
490
+
491
+ #### Icon Component
492
+ An `icon` renders a small graphic that decorates the text beside it — rating stars, labelled metadata rows. **It can only be used inside a box whose `layout` is `:baseline`.** An icon takes no action and no `flex`.
493
+
494
+ - `url`: (String, Required) URL of the icon image (HTTPS).
495
+ - `size`: (Symbol or String, Optional) Icon width. Same keywords as text size. Default `:md`.
496
+ - `aspect_ratio`: (String, Optional) `"width:height"`, default `"1:1"`.
497
+ - `scaling`: (Boolean, Optional) `true` to follow the reader's LINE font size setting.
498
+ - `margin`, `position`, `offset_top`, `offset_bottom`, `offset_start`, `offset_end`: as for other components.
341
499
 
342
500
  ```ruby
343
- image "https://example.com/product_image.png", size: :full, aspect_ratio: "1:1", aspect_mode: :cover, action: message(text: "View product")
501
+ box layout: :baseline do
502
+ icon "https://example.com/star_on.png", size: :sm
503
+ icon "https://example.com/star_on.png", size: :sm
504
+ icon "https://example.com/star_off.png", size: :sm
505
+ text "3.0", size: :sm, margin: :md
506
+ end
344
507
  ```
345
508
 
346
509
  #### Span Component
@@ -349,12 +512,14 @@ Spans are used within a Text component to apply different styling to specific po
349
512
  - `text`: (String, Required) The text content of the span.
350
513
  - Styling:
351
514
  - `color`: (String, Optional) Hex color code (e.g., `'#RRGGBB'`, `'#RRGGBBAA'`).
352
- - `size`: (Symbol or String, Optional) Font size. Valid keywords: `:xxs`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, `:3xl`, `:4xl`, `:5xl`. Also accepts pixel values (e.g., `'16px'`).
515
+ - `size`: (Symbol or String, Optional) Font size. Accepted keywords: `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, or a pixel value (e.g., `'16px'`).
353
516
  - `weight`: (Symbol, Optional) Font weight. Valid values: `:regular`, `:bold`.
354
- - `decoration`: (Symbol, Optional) Text decoration. Valid values: `:none`, `:underline`, `:line-through`.
517
+ - `style`: (Symbol, Optional) `:normal` (default) or `:italic`.
518
+ - `decoration`: (Symbol, Optional) Text decoration. Valid values: `:none`, `:underline`, `:"line-through"`. Ignored when the surrounding text sets its own `decoration`.
355
519
 
356
520
  Spans also support helper methods to easily apply common styles:
357
521
  - `bold!`: Sets the weight to `:bold`.
522
+ - `italic!`: Sets the style to `:italic`.
358
523
  - `underline!`: Sets the decoration to `:underline`.
359
524
  - `line_through!`: Sets the decoration to `:line-through`.
360
525
 
@@ -381,12 +546,15 @@ end
381
546
  ```
382
547
 
383
548
  #### Separator Component
384
- A `separator` draws a horizontal line to create visual separation between components.
549
+ A `separator` draws a horizontal line to create visual separation between components. LINE defines exactly three properties for it; nothing else is accepted.
550
+
551
+ - `margin`: (Symbol or String, Optional) Space before the line. Keywords `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, or a pixel value.
552
+ - `color`: (String, Optional) Hex colour of the line.
385
553
 
386
554
  ```ruby
387
555
  box layout: :vertical do
388
556
  text "Section 1"
389
- separator
557
+ separator margin: :xl, color: "#F0F0F0"
390
558
  text "Section 2"
391
559
  end
392
560
  ```
@@ -397,6 +565,8 @@ Create space between components using:
397
565
  - `margin` property on individual components (e.g., `text "Hello", margin: :xl`).
398
566
  - An empty `box` with a defined `flex` value or `height`/`width` (e.g., `box height: "30px"`).
399
567
 
568
+ Do not reach for a `filler` component — LINE has deprecated it and this gem does not provide one.
569
+
400
570
  ### Flex Message Partials
401
571
 
402
572
  Partials allow you to define reusable segments of Flex Message layouts. This is useful for complex components that appear multiple times.
@@ -410,7 +580,9 @@ Partials allow you to define reusable segments of Flex Message layouts. This is
410
580
  # which are made available from the `assigns` hash passed to `partial!`.
411
581
  box layout: :vertical do
412
582
  text title_text, weight: :bold # 'title_text' from assigns
413
- button label: button_label, action: message(text: "Action for #{title_text}") # 'button_label' from assigns
583
+ button do # 'button_label' from assigns
584
+ message "Action for #{title_text}", label: button_label
585
+ end
414
586
  end
415
587
  end
416
588
  end
@@ -434,4 +606,73 @@ Partials allow you to define reusable segments of Flex Message layouts. This is
434
606
  ```
435
607
  Inside the partial, variables passed via `partial!` (e.g., `title_text`, `button_label`) are accessible as methods.
436
608
 
437
- This comprehensive guide should help in effectively using the Line Message Builder DSL. For very specific or advanced features, always refer to the official LINE Messaging API documentation for Flex Messages.
609
+ ## RSpec Testing Support
610
+
611
+ The gem includes comprehensive RSpec matchers for testing LINE messages:
612
+
613
+ ```ruby
614
+ # Include in spec_helper.rb or rails_helper.rb
615
+ require "line/message/rspec"
616
+
617
+ # Configure in RSpec
618
+ RSpec.configure do |config|
619
+ config.include Line::Message::RSpec::Matchers
620
+ end
621
+
622
+ # Available matchers
623
+ describe "LINE Messages" do
624
+ let(:builder) do
625
+ Line::Message::Builder.with do
626
+ text "Hello World!"
627
+ flex alt_text: "Greeting" do
628
+ bubble do
629
+ body { text "Welcome!" }
630
+ end
631
+ end
632
+ end
633
+ end
634
+
635
+ subject { builder.build }
636
+
637
+ it { is_expected.to have_line_text_message("Hello World!") }
638
+ it { is_expected.to have_line_flex_message }
639
+ it { is_expected.to have_line_flex_bubble }
640
+ it { is_expected.to have_line_flex_text("Welcome!") }
641
+ it { is_expected.to have_line_flex_separator }
642
+ it { is_expected.to have_line_flex_span }
643
+ it { is_expected.to have_line_flex_icon("https://example.com/star.png") }
644
+
645
+ # Works with webmock for API testing
646
+ it "sends correct message" do
647
+ expect(a_request(:post, "https://api.line.me/v2/bot/message/reply")
648
+ .with(body: hash_including({
649
+ messages: have_line_text_message(/Hello World!/)
650
+ }))
651
+ ).to have_been_made.once
652
+ end
653
+ end
654
+ ```
655
+
656
+ ## Development and Testing
657
+
658
+ ```bash
659
+ # Run tests
660
+ bundle exec rspec
661
+
662
+ # Run specific test
663
+ bundle exec rspec spec/line/message/builder_spec.rb
664
+
665
+ # Run linter
666
+ bundle exec rubocop
667
+
668
+ # Run both tests and linter
669
+ bundle exec rake
670
+
671
+ # Interactive console
672
+ bin/console
673
+
674
+ # Build and install locally
675
+ bundle exec rake install
676
+ ```
677
+
678
+ This comprehensive guide should help in effectively using the Line Message Builder DSL. The gem is actively maintained and production-ready for building complex LINE messaging experiences. For very specific or advanced features, always refer to the official LINE Messaging API documentation for Flex Messages.
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "release-type": "ruby",
3
+ "bump-minor-pre-major": true,
3
4
  "packages": {
4
5
  ".":{
5
6
  "component": "line-message-builder",
6
7
  "include-component-in-tag": false,
7
- "release-type": "ruby"
8
+ "release-type": "ruby",
9
+ "bump-minor-pre-major": true
8
10
  }
9
11
  }
10
12
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: line-message-builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aotokitsuruya
@@ -14,21 +14,26 @@ email:
14
14
  - contact@aotoki.me
15
15
  executables: []
16
16
  extensions: []
17
- extra_rdoc_files: []
17
+ extra_rdoc_files:
18
+ - README.md
18
19
  files:
19
20
  - ".document"
20
21
  - ".release-please-manifest.json"
21
22
  - ".rspec"
22
23
  - ".rubocop.yml"
23
24
  - CHANGELOG.md
25
+ - CLAUDE.md
24
26
  - CONVENTIONS.md
25
27
  - LICENSE.txt
26
28
  - README.md
27
29
  - Rakefile
30
+ - claudekit.json
31
+ - docs/rubrics/rdoc.md
28
32
  - lib/line/message/builder.rb
29
33
  - lib/line/message/builder/actions.rb
30
34
  - lib/line/message/builder/actions/message.rb
31
35
  - lib/line/message/builder/actions/postback.rb
36
+ - lib/line/message/builder/actions/uri.rb
32
37
  - lib/line/message/builder/base.rb
33
38
  - lib/line/message/builder/container.rb
34
39
  - lib/line/message/builder/context.rb
@@ -39,6 +44,7 @@ files:
39
44
  - lib/line/message/builder/flex/builder.rb
40
45
  - lib/line/message/builder/flex/button.rb
41
46
  - lib/line/message/builder/flex/carousel.rb
47
+ - lib/line/message/builder/flex/icon.rb
42
48
  - lib/line/message/builder/flex/image.rb
43
49
  - lib/line/message/builder/flex/partial.rb
44
50
  - lib/line/message/builder/flex/position.rb
@@ -86,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
92
  - !ruby/object:Gem::Version
87
93
  version: '0'
88
94
  requirements: []
89
- rubygems_version: 3.6.7
95
+ rubygems_version: 4.0.16
90
96
  specification_version: 4
91
97
  summary: The LINE Messaging API message builder.
92
98
  test_files: []