rails-active-ui 0.3.8 → 0.4.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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +195 -6
  3. data/Rakefile +1 -1
  4. data/app/components/accordion_component.rb +41 -24
  5. data/app/components/accordion_item_component.rb +40 -0
  6. data/app/components/ad_component.rb +1 -1
  7. data/app/components/api_component.rb +1 -1
  8. data/app/components/breadcrumb_component.rb +1 -1
  9. data/app/components/button_group_component.rb +36 -0
  10. data/app/components/button_to_component.rb +1 -1
  11. data/app/components/calendar_component.rb +24 -20
  12. data/app/components/card_component.rb +5 -3
  13. data/app/components/comment_component.rb +5 -3
  14. data/app/components/comment_group_component.rb +27 -0
  15. data/app/components/comment_reply_component.rb +47 -0
  16. data/app/components/comment_reply_group_component.rb +25 -0
  17. data/app/components/dimmer_component.rb +1 -1
  18. data/app/components/divider_component.rb +1 -1
  19. data/app/components/dropdown_component.rb +6 -2
  20. data/app/components/embed_component.rb +1 -1
  21. data/app/components/emoji_component.rb +1 -1
  22. data/app/components/feed_component.rb +16 -4
  23. data/app/components/feed_item_component.rb +85 -0
  24. data/app/components/field_component.rb +42 -0
  25. data/app/components/flag_component.rb +1 -1
  26. data/app/components/flyout_component.rb +3 -2
  27. data/app/components/h_stack_component.rb +1 -1
  28. data/app/components/header_component.rb +2 -2
  29. data/app/components/image_component.rb +1 -1
  30. data/app/components/input_component.rb +22 -41
  31. data/app/components/item_component.rb +3 -2
  32. data/app/components/item_group_component.rb +1 -1
  33. data/app/components/list_component.rb +2 -2
  34. data/app/components/list_content_component.rb +27 -0
  35. data/app/components/list_description_component.rb +17 -0
  36. data/app/components/list_header_component.rb +28 -0
  37. data/app/components/list_item_component.rb +37 -0
  38. data/app/components/loader_component.rb +1 -1
  39. data/app/components/menu_component.rb +1 -1
  40. data/app/components/modal_component.rb +2 -1
  41. data/app/components/nag_component.rb +1 -1
  42. data/app/components/overlay_component.rb +1 -1
  43. data/app/components/placeholder_component.rb +37 -13
  44. data/app/components/popup_component.rb +1 -1
  45. data/app/components/progress_component.rb +1 -1
  46. data/app/components/pusher_component.rb +1 -1
  47. data/app/components/rail_component.rb +1 -1
  48. data/app/components/rating_component.rb +1 -1
  49. data/app/components/reveal_component.rb +3 -2
  50. data/app/components/row_component.rb +4 -0
  51. data/app/components/search_component.rb +1 -1
  52. data/app/components/segment_group_component.rb +1 -1
  53. data/app/components/shape_component.rb +1 -1
  54. data/app/components/sidebar_component.rb +1 -1
  55. data/app/components/site_component.rb +1 -1
  56. data/app/components/slider_component.rb +1 -1
  57. data/app/components/state_component.rb +1 -1
  58. data/app/components/statistic_component.rb +3 -2
  59. data/app/components/step_component.rb +2 -2
  60. data/app/components/step_group_component.rb +1 -1
  61. data/app/components/sticky_component.rb +1 -1
  62. data/app/components/style_component.rb +1 -1
  63. data/app/components/sub_accordion_component.rb +25 -0
  64. data/app/components/sub_header_component.rb +1 -1
  65. data/app/components/sub_menu_component.rb +1 -1
  66. data/app/components/table_cell_component.rb +2 -2
  67. data/app/components/table_component.rb +2 -2
  68. data/app/components/tag_component.rb +57 -0
  69. data/app/components/tag_group_component.rb +33 -0
  70. data/app/components/text_component.rb +1 -1
  71. data/app/components/toast_component.rb +1 -1
  72. data/app/components/transition_component.rb +2 -2
  73. data/app/components/v_stack_component.rb +1 -1
  74. data/app/components/visibility_component.rb +1 -1
  75. data/app/helpers/component_helper.rb +23 -6
  76. data/app/helpers/ui/fomantic_form_builder.rb +155 -201
  77. data/app/javascript/ui/controllers/fui_calendar_controller.js +18 -8
  78. data/lib/ui/version.rb +1 -1
  79. metadata +15 -3
  80. data/app/components/checkbox_component.rb +0 -41
  81. data/app/components/label_component.rb +0 -49
@@ -4,21 +4,51 @@
4
4
  #
5
5
  # Usage:
6
6
  # Placeholder { |c|
7
- # c.header_slot {
8
- # text '<div class="line"></div><div class="line"></div>'.html_safe
7
+ # c.header(image: true) {
8
+ # c.line
9
+ # c.line
9
10
  # }
10
11
  # c.paragraph {
11
- # text '<div class="line"></div><div class="line"></div>'.html_safe
12
+ # c.line :medium
13
+ # c.line :short
12
14
  # }
13
15
  # }
16
+ #
17
+ # Placeholder { |c|
18
+ # c.image :square
19
+ # }
20
+ #
21
+ # Placeholder { |c|
22
+ # c.line :full
23
+ # c.line :very_long
24
+ # c.line :long
25
+ # c.line :medium
26
+ # c.line :short
27
+ # c.line :very_short
28
+ # }
14
29
 
15
30
  class PlaceholderComponent < Component
16
31
  attribute :fluid, :boolean, default: false
17
32
  attribute :inverted, :boolean, default: false
18
33
 
19
- slot :header_slot
20
- slot :paragraph
21
- slot :image_slot
34
+ def line(length = nil)
35
+ css = class_names(length&.to_s&.tr("_", " "), "line")
36
+ @view_context.output_buffer << tag.div(class: css)
37
+ end
38
+
39
+ def header(image: false, &block)
40
+ css = class_names({ "image" => image }, "header")
41
+ @view_context.output_buffer << tag.div(class: css) { @view_context.capture(self, &block) }
42
+ end
43
+
44
+ def paragraph(&block)
45
+ @view_context.output_buffer << tag.div(class: "paragraph") { @view_context.capture(self, &block) }
46
+ end
47
+
48
+ def image(ratio = nil)
49
+ css = class_names(ratio, "image")
50
+ @view_context.output_buffer << tag.div(class: css)
51
+ end
22
52
 
23
53
  def to_s
24
54
  classes = class_names(
@@ -28,12 +58,6 @@ class PlaceholderComponent < Component
28
58
  "placeholder"
29
59
  )
30
60
 
31
- header_el = @slots[:header_slot] ? tag.div(class: "header") { @slots[:header_slot] } : nil
32
- para_el = @slots[:paragraph] ? tag.div(class: "paragraph") { @slots[:paragraph] } : nil
33
- image_el = @slots[:image_slot] ? tag.div(class: "image") { @slots[:image_slot] } : nil
34
-
35
- tag.div(class: classes) {
36
- safe_join([ header_el, para_el, image_el, @content.presence ])
37
- }
61
+ tag.div(**merge_html_options(class: classes)) { @content }
38
62
  end
39
63
  end
@@ -26,6 +26,6 @@ class PopupComponent < Component
26
26
  data[:fui_popup_variation_value] = variation if variation
27
27
  data[:fui_popup_on_value] = on if on != "hover"
28
28
 
29
- tag.span(data: data) { @content }
29
+ tag.span(**merge_html_options(data: data)) { @content }
30
30
  end
31
31
  end
@@ -41,7 +41,7 @@ class ProgressComponent < Component
41
41
  bar_el = tag.div(class: "bar", style: "width:#{percent}%") { @slots[:bar] }
42
42
  label_el = @slots[:label] ? tag.div(class: "label") { @slots[:label] } : nil
43
43
 
44
- tag.div(class: classes, data: { controller: "fui-progress", percent: percent }) {
44
+ tag.div(**merge_html_options(class: classes, data: { controller: "fui-progress", percent: percent })) {
45
45
  safe_join([ bar_el, label_el, @content.presence ])
46
46
  }
47
47
  end
@@ -13,6 +13,6 @@
13
13
 
14
14
  class PusherComponent < Component
15
15
  def to_s
16
- tag.div(class: "pusher") { @content }
16
+ tag.div(**merge_html_options(class: "pusher")) { @content }
17
17
  end
18
18
  end
@@ -26,6 +26,6 @@ class RailComponent < Component
26
26
  "rail"
27
27
  )
28
28
 
29
- tag.div(class: classes) { @content }
29
+ tag.div(**merge_html_options(class: classes)) { @content }
30
30
  end
31
31
  end
@@ -34,7 +34,7 @@ class RatingComponent < Component
34
34
 
35
35
  name_el = name ? tag.input(type: "hidden", name: name, value: rating) : nil
36
36
 
37
- tag.div(class: classes, data: data) {
37
+ tag.div(**merge_html_options(class: classes, data: data)) {
38
38
  safe_join([ name_el, @content ])
39
39
  }
40
40
  end
@@ -32,8 +32,9 @@ class RevealComponent < Component
32
32
  visible_el = @slots[:visible] ? tag.div(class: "visible content") { @slots[:visible] } : nil
33
33
  hidden_el = @slots[:hidden] ? tag.div(class: "hidden content") { @slots[:hidden] } : nil
34
34
 
35
- tag.div(class: classes) {
36
- safe_join([ visible_el, hidden_el, @content ])
35
+ loose_content = @slots.values.any? ? nil : @content
36
+ tag.div(**merge_html_options(class: classes)) {
37
+ safe_join([ visible_el, hidden_el, loose_content ])
37
38
  }
38
39
  end
39
40
  end
@@ -17,9 +17,11 @@ class RowComponent < Component
17
17
  attribute :columns, :integer, default: nil
18
18
  attribute :centered, :boolean, default: false
19
19
  attribute :stretched, :boolean, default: false
20
+ attribute :doubling, :boolean, default: false
20
21
  attribute :equal_width, :boolean, default: false
21
22
  attribute :only, :string, default: nil
22
23
  attribute :aligned, :string, default: nil
24
+ attribute :color, :string, default: nil
23
25
 
24
26
  def to_s
25
27
  col_word = columns && columns.between?(1, 16) ? NUMBERS[columns - 1] : nil
@@ -28,8 +30,10 @@ class RowComponent < Component
28
30
  col_word && "#{col_word} column",
29
31
  only && "#{only} only",
30
32
  aligned && "#{aligned} aligned",
33
+ color,
31
34
  { "centered" => centered,
32
35
  "stretched" => stretched,
36
+ "doubling" => doubling,
33
37
  "equal width" => equal_width },
34
38
  "row"
35
39
  )
@@ -37,7 +37,7 @@ class SearchComponent < Component
37
37
  }
38
38
  results_el = tag.div(class: "results")
39
39
 
40
- tag.div(class: classes, data: data) {
40
+ tag.div(**merge_html_options(class: classes, data: data)) {
41
41
  safe_join([ input_wrapper, results_el, @content ])
42
42
  }
43
43
  end
@@ -31,6 +31,6 @@ class SegmentGroupComponent < Component
31
31
  "segments"
32
32
  )
33
33
 
34
- tag.div(class: classes) { @content }
34
+ tag.div(**merge_html_options(class: classes)) { @content }
35
35
  end
36
36
  end
@@ -20,6 +20,6 @@ class ShapeComponent < Component
20
20
  "shape"
21
21
  )
22
22
 
23
- tag.div(class: classes, data: { controller: "fui-shape" }) { @content }
23
+ tag.div(**merge_html_options(class: classes, data: { controller: "fui-shape" })) { @content }
24
24
  end
25
25
  end
@@ -28,6 +28,6 @@ class SidebarComponent < Component
28
28
  "menu"
29
29
  )
30
30
 
31
- tag.div(class: classes, data: { controller: "fui-sidebar", fui_sidebar_transition_value: transition }) { @content }
31
+ tag.div(**merge_html_options(class: classes, data: { controller: "fui-sidebar", fui_sidebar_transition_value: transition })) { @content }
32
32
  end
33
33
  end
@@ -7,6 +7,6 @@
7
7
 
8
8
  class SiteComponent < Component
9
9
  def to_s
10
- tag.div(data: { controller: "fui-site" }) { @content }
10
+ tag.div(**merge_html_options(data: { controller: "fui-site" })) { @content }
11
11
  end
12
12
  end
@@ -39,7 +39,7 @@ class SliderComponent < Component
39
39
 
40
40
  name_el = name ? tag.input(type: "hidden", name: name, value: value) : nil
41
41
 
42
- tag.div(class: classes, data: data) {
42
+ tag.div(**merge_html_options(class: classes, data: data)) {
43
43
  safe_join([ name_el, @content ])
44
44
  }
45
45
  end
@@ -20,6 +20,6 @@ class StateComponent < Component
20
20
  data[:fui_state_class_active_value] = class_active if class_active
21
21
  data[:fui_state_class_inactive_value] = class_inactive if class_inactive
22
22
 
23
- tag.div(data: data) { @content }
23
+ tag.div(**merge_html_options(data: data)) { @content }
24
24
  end
25
25
  end
@@ -36,8 +36,9 @@ class StatisticComponent < Component
36
36
  value_el = @slots[:value] ? tag.div(class: "value") { @slots[:value] } : nil
37
37
  label_el = @slots[:label] ? tag.div(class: "label") { @slots[:label] } : nil
38
38
 
39
- tag.div(class: classes) {
40
- safe_join([ value_el, label_el, @content.presence ])
39
+ loose_content = @slots.values.any? ? nil : @content.presence
40
+ tag.div(**merge_html_options(class: classes)) {
41
+ safe_join([ value_el, label_el, loose_content ])
41
42
  }
42
43
  end
43
44
  end
@@ -48,9 +48,9 @@ class StepComponent < Component
48
48
  end
49
49
 
50
50
  if href
51
- tag.a(class: classes, href: href) { inner }
51
+ tag.a(**merge_html_options(class: classes, href: href)) { inner }
52
52
  else
53
- tag.div(class: classes) { inner }
53
+ tag.div(**merge_html_options(class: classes)) { inner }
54
54
  end
55
55
  end
56
56
  end
@@ -33,6 +33,6 @@ class StepGroupComponent < Component
33
33
  "steps"
34
34
  )
35
35
 
36
- tag.div(class: classes) { @content }
36
+ tag.div(**merge_html_options(class: classes)) { @content }
37
37
  end
38
38
  end
@@ -17,6 +17,6 @@ class StickyComponent < Component
17
17
  data[:fui_sticky_pushing_value] = "true" if pushing
18
18
  data[:fui_sticky_offset_value] = offset if offset > 0
19
19
 
20
- tag.div(class: "ui sticky", data: data) { @content }
20
+ tag.div(**merge_html_options(class: "ui sticky", data: data)) { @content }
21
21
  end
22
22
  end
@@ -18,6 +18,6 @@ class StyleComponent < Component
18
18
  end
19
19
 
20
20
  def to_s
21
- tag.style { @css&.html_safe }
21
+ tag.style(**merge_html_options) { @css&.html_safe }
22
22
  end
23
23
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SubAccordion — bare nested accordion wrapper.
4
+ #
5
+ # Renders <div class="accordion"> without the "ui" prefix or Stimulus
6
+ # controller, for use inside an AccordionItem's content slot.
7
+ #
8
+ # Usage:
9
+ # AccordionItem(active: true) { |i|
10
+ # i.title { "Level 1" }
11
+ # i.content {
12
+ # SubAccordion {
13
+ # AccordionItem { |i2|
14
+ # i2.title { "Level 1A" }
15
+ # i2.content { "Nested content" }
16
+ # }
17
+ # }
18
+ # }
19
+ # }
20
+
21
+ class SubAccordionComponent < Component
22
+ def to_s
23
+ tag.div(**merge_html_options(class: "accordion")) { @content }
24
+ end
25
+ end
@@ -10,6 +10,6 @@
10
10
 
11
11
  class SubHeaderComponent < Component
12
12
  def to_s
13
- tag.div(class: "sub header") { @content }
13
+ tag.div(**merge_html_options(class: "sub header")) { @content }
14
14
  end
15
15
  end
@@ -19,6 +19,6 @@ class SubMenuComponent < Component
19
19
  "menu"
20
20
  )
21
21
 
22
- tag.div(class: classes) { @content }
22
+ tag.div(**merge_html_options(class: classes)) { @content }
23
23
  end
24
24
  end
@@ -52,9 +52,9 @@ class TableCellComponent < Component
52
52
  opts[:rowspan] = rowspan if rowspan
53
53
 
54
54
  if heading
55
- tag.th(**opts) { @content }
55
+ tag.th(**merge_html_options(**opts)) { @content }
56
56
  else
57
- tag.td(**opts) { @content }
57
+ tag.td(**merge_html_options(**opts)) { @content }
58
58
  end
59
59
  end
60
60
  end
@@ -106,7 +106,7 @@ class TableComponent < Component
106
106
 
107
107
  footer_el = @slots[:footer] ? tag.tfoot { @slots[:footer] } : nil
108
108
 
109
- tag.table(class: classes) {
109
+ tag.table(**merge_html_options(class: classes)) {
110
110
  safe_join([
111
111
  tag.thead { tag.tr { safe_join(head_cells) } },
112
112
  tag.tbody { safe_join(body_rows) },
@@ -120,7 +120,7 @@ class TableComponent < Component
120
120
  footer_el = @slots[:footer] ? tag.tfoot { @slots[:footer] } : nil
121
121
  body_el = @content.presence ? tag.tbody { @content } : nil
122
122
 
123
- tag.table(class: classes) {
123
+ tag.table(**merge_html_options(class: classes)) {
124
124
  safe_join([ header_el, body_el, footer_el ])
125
125
  }
126
126
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Tag — colored labels, tags, and badges.
4
+ #
5
+ # Renders Fomantic-UI's "label" element. Named `Tag` in the DSL to avoid
6
+ # collision with Rails' `label` form helper.
7
+ #
8
+ # Usage:
9
+ # Tag(color: :blue) { "New" }
10
+ # Tag(tag_style: true, color: :teal) { "Featured" }
11
+ # Tag(ribbon: true, color: :red) { "Sale" }
12
+ # Tag(icon: "mail", detail: "23") { "Mail" }
13
+
14
+ class TagComponent < Component
15
+ include Attachable
16
+
17
+ attribute :color, :string, default: nil
18
+ attribute :size, :string, default: nil
19
+ attribute :pointing, :string, default: nil
20
+ attribute :corner, :string, default: nil
21
+ attribute :ribbon, :boolean, default: false
22
+ attribute :circular, :boolean, default: false
23
+ attribute :floating, :boolean, default: false
24
+ attribute :tag_style, :boolean, default: false
25
+ attribute :detail, :string, default: nil
26
+ attribute :icon, :string, default: nil
27
+ attribute :image, :boolean, default: false
28
+ attribute :basic, :boolean, default: false
29
+ attribute :horizontal, :boolean, default: false
30
+ attribute :inverted, :boolean, default: false
31
+ attribute :fluid, :boolean, default: false
32
+ attribute :disabled, :boolean, default: false
33
+ attribute :empty, :boolean, default: false
34
+
35
+ def to_s
36
+ classes = class_names(
37
+ "ui",
38
+ color,
39
+ size,
40
+ pointing && "#{pointing} pointing",
41
+ corner && "#{corner} corner",
42
+ { "attached" => attached,
43
+ "ribbon" => ribbon, "circular" => circular, "floating" => floating,
44
+ "tag" => tag_style, "image" => image, "basic" => basic,
45
+ "horizontal" => horizontal, "inverted" => inverted,
46
+ "fluid" => fluid, "disabled" => disabled, "empty" => empty },
47
+ "label"
48
+ )
49
+
50
+ icon_el = icon ? tag.i(class: "#{icon} icon") : nil
51
+ detail_el = detail ? tag.div(class: "detail") { detail } : nil
52
+
53
+ tag.div(**merge_html_options(class: classes)) {
54
+ safe_join([ icon_el, @content, detail_el ])
55
+ }
56
+ end
57
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # TagGroup — a group of Tag (label) elements.
4
+ #
5
+ # Usage:
6
+ # TagGroup {
7
+ # Tag { "One" }
8
+ # Tag { "Two" }
9
+ # }
10
+ # TagGroup(size: "huge", color: "blue") {
11
+ # Tag { "Fun" }
12
+ # Tag { "Happy" }
13
+ # }
14
+
15
+ class TagGroupComponent < Component
16
+ attribute :size, :string, default: nil
17
+ attribute :color, :string, default: nil
18
+ attribute :basic, :boolean, default: false
19
+ attribute :tag_style, :boolean, default: false
20
+ attribute :circular, :boolean, default: false
21
+
22
+ def to_s
23
+ classes = class_names(
24
+ "ui",
25
+ size,
26
+ color,
27
+ { "basic" => basic, "tag" => tag_style, "circular" => circular },
28
+ "labels"
29
+ )
30
+
31
+ tag.div(**merge_html_options(class: classes)) { @content }
32
+ end
33
+ end
@@ -35,7 +35,7 @@ class TextComponent < Component
35
35
  opts[:class] = fui_classes if fui_classes
36
36
  opts[:style] = style_parts.join(";") if style_parts.any?
37
37
 
38
- tag.span(**opts) { @content }
38
+ tag.span(**merge_html_options(**opts)) { @content }
39
39
  end
40
40
 
41
41
  private
@@ -31,6 +31,6 @@ class ToastComponent < Component
31
31
  data[:fui_toast_compact_value] = "true" if compact
32
32
  data[:fui_toast_show_progress_value] = "true" if show_progress
33
33
 
34
- tag.div(data: data) { @content }
34
+ tag.div(**merge_html_options(data: data)) { @content }
35
35
  end
36
36
  end
@@ -19,7 +19,7 @@ class TransitionComponent < Component
19
19
  "transition"
20
20
  )
21
21
 
22
- tag.div(
22
+ tag.div(**merge_html_options(
23
23
  class: classes,
24
24
  style: "animation-duration:#{duration}ms",
25
25
  data: {
@@ -27,6 +27,6 @@ class TransitionComponent < Component
27
27
  fui_transition_animation_value: animation,
28
28
  fui_transition_duration_value: duration
29
29
  }
30
- ) { @content }
30
+ )) { @content }
31
31
  end
32
32
  end
@@ -15,7 +15,7 @@ class VStackComponent < Component
15
15
  opts = {}
16
16
  opts[:style] = style_parts unless style_parts.empty?
17
17
 
18
- tag.div(**opts) { @content }
18
+ tag.div(**merge_html_options(**opts)) { @content }
19
19
  end
20
20
 
21
21
  private
@@ -17,6 +17,6 @@ class VisibilityComponent < Component
17
17
  data[:fui_visibility_offset_value] = offset if offset > 0
18
18
  data[:fui_visibility_once_value] = "true" if once
19
19
 
20
- tag.div(data: data) { @content }
20
+ tag.div(**merge_html_options(data: data)) { @content }
21
21
  end
22
22
  end
@@ -41,8 +41,13 @@ module ComponentHelper
41
41
  Icon: "IconComponent",
42
42
  Image: "ImageComponent",
43
43
  Input: "InputComponent",
44
- Label: "LabelComponent",
45
- List: "ListComponent",
44
+ Tag: "TagComponent",
45
+ TagGroup: "TagGroupComponent",
46
+ List: "ListComponent",
47
+ ListItem: "ListItemComponent",
48
+ ListContent: "ListContentComponent",
49
+ ListHeader: "ListHeaderComponent",
50
+ ListDescription: "ListDescriptionComponent",
46
51
  Loader: "LoaderComponent",
47
52
  Placeholder: "PlaceholderComponent",
48
53
  Rail: "RailComponent",
@@ -53,9 +58,11 @@ module ComponentHelper
53
58
  StepGroup: "StepGroupComponent",
54
59
 
55
60
  Text: "TextComponent",
61
+ ButtonGroup: "ButtonGroupComponent",
56
62
 
57
63
  # Collections
58
64
  Breadcrumb: "BreadcrumbComponent",
65
+ Field: "FieldComponent",
59
66
  Form: "FormComponent",
60
67
  Grid: "GridComponent",
61
68
  Menu: "MenuComponent",
@@ -70,15 +77,21 @@ module ComponentHelper
70
77
  Ad: "AdComponent",
71
78
  ItemGroup: "ItemGroupComponent",
72
79
  Card: "CardComponent",
73
- Comment: "CommentComponent",
80
+ Comment: "CommentComponent",
81
+ CommentGroup: "CommentGroupComponent",
82
+ CommentReplyGroup: "CommentReplyGroupComponent",
83
+ CommentReply: "CommentReplyComponent",
74
84
  Feed: "FeedComponent",
85
+ FeedItem: "FeedItemComponent",
75
86
  Item: "ItemComponent",
76
87
  Statistic: "StatisticComponent",
77
88
 
78
89
  # Modules
79
- Accordion: "AccordionComponent",
80
- Calendar: "CalendarComponent",
81
- Checkbox: "CheckboxComponent",
90
+ Accordion: "AccordionComponent",
91
+ AccordionItem: "AccordionItemComponent",
92
+ SubAccordion: "SubAccordionComponent",
93
+ Calendar: "CalendarComponent",
94
+
82
95
  Dimmer: "DimmerComponent",
83
96
  Dropdown: "DropdownComponent",
84
97
  Embed: "EmbedComponent",
@@ -121,6 +134,10 @@ module ComponentHelper
121
134
  output_buffer << content.to_s
122
135
  end
123
136
 
137
+ def NbSpace
138
+ output_buffer << "&nbsp;".html_safe
139
+ end
140
+
124
141
  def Partial(*args, **kwargs, &block)
125
142
  output_buffer << render(*args, **kwargs, &block)
126
143
  end