design_system 0.12.0 → 0.13.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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/design_system_helper.rb +20 -2
  3. data/lib/design_system/components/grid.rb +43 -0
  4. data/lib/design_system/components/list.rb +18 -0
  5. data/lib/design_system/components/summary_list.rb +2 -0
  6. data/lib/design_system/generic/builders/elements/lead_paragraph.rb +27 -0
  7. data/lib/design_system/generic/builders/fixed_elements.rb +2 -0
  8. data/lib/design_system/generic/builders/grid.rb +44 -0
  9. data/lib/design_system/generic/builders/inset_text.rb +18 -0
  10. data/lib/design_system/generic/builders/list.rb +41 -0
  11. data/lib/design_system/generic/builders/notification.rb +26 -6
  12. data/lib/design_system/generic/builders/paragraph.rb +28 -0
  13. data/lib/design_system/generic/builders/summary_list.rb +15 -7
  14. data/lib/design_system/generic.rb +4 -0
  15. data/lib/design_system/govuk/builders/grid.rb +12 -0
  16. data/lib/design_system/govuk/builders/inset_text.rb +11 -0
  17. data/lib/design_system/govuk/builders/list.rb +11 -0
  18. data/lib/design_system/govuk/builders/paragraph.rb +11 -0
  19. data/lib/design_system/govuk/builders/summary_list.rb +4 -14
  20. data/lib/design_system/govuk/form_builder.rb +9 -6
  21. data/lib/design_system/govuk.rb +2 -0
  22. data/lib/design_system/nhsuk/builders/grid.rb +12 -0
  23. data/lib/design_system/nhsuk/builders/grid_test.rb +109 -0
  24. data/lib/design_system/nhsuk/builders/inset_text.rb +23 -0
  25. data/lib/design_system/nhsuk/builders/list.rb +11 -0
  26. data/lib/design_system/nhsuk/builders/paragraph.rb +11 -0
  27. data/lib/design_system/nhsuk/builders/summary_list.rb +1 -15
  28. data/lib/design_system/nhsuk.rb +2 -0
  29. data/lib/design_system/version.rb +1 -1
  30. metadata +17 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 682961e5ace6d1fb7a0e9efbd5f5bf9d588eb4858f7ec7013db2188771d25de8
4
- data.tar.gz: 9ea72be49b3b50294ef562c7254e94b2b29f908e4f064700106bd22231033be0
3
+ metadata.gz: b61d6a51f578ccedbe93a430fa8b94388a78b870eab9fc271088750e9c66fca3
4
+ data.tar.gz: 5dfe10f8b92f07a277716996c7d1c6378ce80f331aaaf29f474e0e3c2ee24c4f
5
5
  SHA512:
6
- metadata.gz: 4a65a069154023e6768451a889247e824a2dd6a5842d8a219ce4f76e1575b567f369395c0652ea3468bb2a428ab9d29bc95c5894755eadbc9ef2aeafd5f23fc6
7
- data.tar.gz: fefa5477b56eaf6dddd30c22697bfbb506842e008c4f8650aa33a5f93b29470a1b576636b22fd06b6c97e0bd68bc44bb225536e7c309fd064c85010db13ccd04
6
+ metadata.gz: 1a9431fa199c5e2e655029c0bb902de07ebd580668b5eb891cf6a08e9f0c2d00795498ca03f73a936db36255eec48df0cc0bee61e49c6d5ac9cfca8935c44a66
7
+ data.tar.gz: 5e6635813ca0e9d64a7854f1b276733fa00bd6c767dd652c39f79bc8f40fe3d0b2519fca32907592cd8943d6ffb9beabd0d2bd5b778092a0d68c11468dcc78e1
@@ -78,8 +78,8 @@ module DesignSystemHelper
78
78
  DesignSystem::Registry.builder(brand, 'notification', self).render_alert(message, &)
79
79
  end
80
80
 
81
- def ds_notice(message = nil, &)
82
- DesignSystem::Registry.builder(brand, 'notification', self).render_notice(message, &)
81
+ def ds_notice(message = nil, header: nil, type: :information, &)
82
+ DesignSystem::Registry.builder(brand, 'notification', self).render_notice(message, header:, type:, &)
83
83
  end
84
84
 
85
85
  def ds_heading(text, level: 2, **options)
@@ -118,4 +118,22 @@ module DesignSystemHelper
118
118
  def ds_action_link(name = nil, options = nil, html_options = nil)
119
119
  DesignSystem::Registry.builder(brand, 'action_link', self).render_action_link(name, options, html_options)
120
120
  end
121
+
122
+ def ds_grid(options = {}, &)
123
+ raise ArgumentError unless block_given?
124
+
125
+ DesignSystem::Registry.builder(brand, 'grid', self).render_grid(options, &)
126
+ end
127
+
128
+ def ds_paragraph(text = nil, size: nil, **options, &block)
129
+ DesignSystem::Registry.builder(brand, 'paragraph', self).render_paragraph(text, size:, **options, &block)
130
+ end
131
+
132
+ def ds_list(type: :default, **options, &block)
133
+ DesignSystem::Registry.builder(brand, 'list', self).render_list(type:, **options, &block)
134
+ end
135
+
136
+ def ds_inset_text(text = nil, ...)
137
+ DesignSystem::Registry.builder(brand, 'inset_text', self).render_inset_text(text, ...)
138
+ end
121
139
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Components
5
+ # This class provides a grid component.
6
+ class Grid
7
+ attr_accessor :columns
8
+
9
+ WIDTHS = {
10
+ full: { class: 'full', fraction: Rational(1, 1) },
11
+ half: { class: 'one-half', fraction: Rational(1, 2) },
12
+ one_half: { class: 'one-half', fraction: Rational(1, 2) },
13
+ two_thirds: { class: 'two-thirds', fraction: Rational(2, 3) },
14
+ one_third: { class: 'one-third', fraction: Rational(1, 3) },
15
+ three_quarters: { class: 'three-quarters', fraction: Rational(3, 4) },
16
+ quarter: { class: 'one-quarter', fraction: Rational(1, 4) },
17
+ one_quarter: { class: 'one-quarter', fraction: Rational(1, 4) }
18
+ }.freeze
19
+
20
+ def initialize
21
+ @columns = []
22
+ end
23
+
24
+ def add_column(width, options = {}, &block)
25
+ @columns << { width:, options:, block: }
26
+ end
27
+
28
+ def validate_total_width!
29
+ total = columns.sum { |col| width_to_fraction(col[:width]) }
30
+ raise ArgumentError, 'Total grid width exceeds 100%' if total > 1
31
+ end
32
+
33
+ private
34
+
35
+ def width_to_fraction(width)
36
+ config = WIDTHS[width]
37
+ raise ArgumentError, "Unknown grid width: #{width}" unless config
38
+
39
+ config[:fraction]
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Components
5
+ # Simple list component used by the generic list builder.
6
+ class List
7
+ attr_reader :items
8
+
9
+ def initialize
10
+ @items = []
11
+ end
12
+
13
+ def add_item(content = nil, &block)
14
+ @items << (block_given? ? block : content)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module DesignSystem
4
4
  module Components
5
+ # This class provides a summary list component.
5
6
  class SummaryList
6
7
  attr_accessor :rows
7
8
 
@@ -23,6 +24,7 @@ module DesignSystem
23
24
  end
24
25
  end
25
26
 
27
+ # This class provides a builder for a summary list row.
26
28
  class SummaryListRowBuilder
27
29
  attr_reader :row
28
30
 
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Generic
5
+ module Builders
6
+ module Elements
7
+ # This mixin module is used to provide lead paragraphs.
8
+ module LeadParagraph
9
+ def lead_paragraph(text = nil, &)
10
+ raise ArgumentError, 'Lead paragraph can only be used once per page' if @lead_paragraph
11
+
12
+ @lead_paragraph = block_given? ? capture(&) : text
13
+ end
14
+
15
+ private
16
+
17
+ def render_lead_paragraph
18
+ # Lead paragraph is a large body paragraph that should be used at the page top and once per page.
19
+ return unless @lead_paragraph
20
+
21
+ content_tag('p', @lead_paragraph, class: "#{brand}-body-l")
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -9,6 +9,7 @@ module DesignSystem
9
9
  include Elements::Breadcrumbs
10
10
  include Elements::Form
11
11
  include Elements::Headings
12
+ include Elements::LeadParagraph
12
13
 
13
14
  def render
14
15
  raise ArgumentError, 'Cannot use both backlink and breadcrumbs' if @backlink && @breadcrumbs.present?
@@ -20,6 +21,7 @@ module DesignSystem
20
21
  safe_buffer = ActiveSupport::SafeBuffer.new
21
22
 
22
23
  safe_buffer.concat(render_main_heading) if @main_heading
24
+ safe_buffer.concat(render_lead_paragraph) if @lead_paragraph
23
25
  safe_buffer.concat(render_form) if @form_object
24
26
 
25
27
  safe_buffer
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Generic
5
+ module Builders
6
+ # This class provides a generic grid builder.
7
+ class Grid < Base
8
+ include ActionView::Helpers::OutputSafetyHelper
9
+
10
+ def render_grid(options = {})
11
+ @grid = ::DesignSystem::Components::Grid.new
12
+ yield @grid
13
+ @grid.validate_total_width!
14
+
15
+ row_options = css_class_options_merge(options, ["#{brand}-grid-row"])
16
+ content_tag(:div, **row_options) do
17
+ safe_buffer = ActiveSupport::SafeBuffer.new
18
+ safe_buffer.concat(render_columns)
19
+
20
+ safe_buffer
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def render_columns
27
+ @grid.columns.each_with_object(ActiveSupport::SafeBuffer.new) do |column, buffer|
28
+ column_options = column[:options].dup
29
+ column_class = grid_class(column[:width])
30
+ column_options = css_class_options_merge(column_options, [column_class])
31
+
32
+ block = column[:block]
33
+ content = capture(&block) if block
34
+ buffer.concat(content_tag(:div, content, **column_options))
35
+ end
36
+ end
37
+
38
+ def grid_class(width)
39
+ "#{brand}-grid-column-#{::DesignSystem::Components::Grid::WIDTHS[width][:class]}"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Generic
5
+ module Builders
6
+ # This generates html for rendering inset text to help users identify and understand important content on the page.
7
+ class InsetText < Base
8
+ def render_inset_text(text = nil, **options, &)
9
+ content = block_given? ? capture(&) : text
10
+ return if content.blank?
11
+
12
+ div_options = css_class_options_merge(options, ["#{brand}-inset-text"])
13
+ content_tag(:div, content, **div_options)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Generic
5
+ module Builders
6
+ # Generic list builder.
7
+ class List < Base
8
+ # type: :bullet, :number
9
+ def render_list(type: :default, **options)
10
+ raise ArgumentError, 'block required' unless block_given?
11
+
12
+ @list = ::DesignSystem::Components::List.new
13
+ yield @list
14
+
15
+ tag_name = type.to_sym == :number ? :ol : :ul
16
+
17
+ classes = ["#{brand}-list"]
18
+ classes << "#{brand}-list--bullet" if type == :bullet
19
+ classes << "#{brand}-list--number" if type == :number
20
+
21
+ options = css_class_options_merge(options, classes)
22
+
23
+ content_tag(tag_name, **options) do
24
+ render_items
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def render_items
31
+ @list.items.each_with_object(ActiveSupport::SafeBuffer.new) do |item, buffer|
32
+ content = item.is_a?(Proc) ? capture(&item) : item
33
+ next if content.blank?
34
+
35
+ buffer.concat(content_tag(:li, content))
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -16,23 +16,28 @@ module DesignSystem
16
16
  end
17
17
  end
18
18
 
19
- def render_notice(msg = nil, &)
19
+ def render_notice(msg = nil, header: nil, type: :information, &)
20
20
  @context.instance_variable_set(:@link_context, :notification_banner)
21
21
 
22
+ raise ArgumentError,
23
+ "Invalid notification type: #{type}. Must be one of: #{notification_type_hash.keys.join(', ')}" unless notification_type_hash.key?(type)
24
+
25
+ header ||= notification_type_hash.dig(type, :header)
26
+
22
27
  content_to_display = block_given? ? capture(&) : msg
23
- content_tag(:div, class: "#{brand}-notification-banner", role: 'region',
28
+ content_tag(:div, class: notification_type_hash.dig(type, :class), role: notification_type_hash.dig(type, :role),
24
29
  'aria-labelledby': "#{brand}-notification-banner-title",
25
30
  'data-module': "#{brand}-notification-banner") do
26
- banner_tile + banner_content(content_to_display)
31
+ banner_tile(header) + banner_content(content_to_display)
27
32
  end
28
33
  end
29
34
 
30
35
  private
31
36
 
32
- def banner_tile
37
+ def banner_tile(header)
33
38
  content_tag(:div, class: "#{brand}-notification-banner__header") do
34
- content_tag(:h2, 'Important', class: "#{brand}-notification-banner__title",
35
- id: "#{brand}-notification-banner-title")
39
+ content_tag(:h2, header, class: "#{brand}-notification-banner__title",
40
+ id: "#{brand}-notification-banner-title")
36
41
  end
37
42
  end
38
43
 
@@ -42,6 +47,21 @@ module DesignSystem
42
47
  class: "#{brand}-notification-banner__heading")
43
48
  end
44
49
  end
50
+
51
+ def notification_type_hash
52
+ {
53
+ information: {
54
+ header: 'Important',
55
+ class: "#{brand}-notification-banner",
56
+ role: 'region'
57
+ },
58
+ success: {
59
+ header: 'Success',
60
+ class: "#{brand}-notification-banner #{brand}-notification-banner--success",
61
+ role: 'alert'
62
+ }
63
+ }
64
+ end
45
65
  end
46
66
  end
47
67
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Generic
5
+ module Builders
6
+ # This class provides generic methods to display paragraphs with typography styles.
7
+ class Paragraph < Base
8
+ FONT_SIZES = %i[s].freeze
9
+
10
+ def render_paragraph(text = nil, size: nil, **options, &block)
11
+ content = block_given? ? capture(&block) : text
12
+ return if content.blank?
13
+
14
+ content_tag('p', content, class: classes(size), **options)
15
+ end
16
+
17
+ private
18
+
19
+ def classes(size)
20
+ return "#{brand}-body" if size.nil?
21
+ raise ArgumentError, "Invalid size: #{size}" unless size.in?(FONT_SIZES)
22
+
23
+ "#{brand}-body-#{size}"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -3,6 +3,7 @@
3
3
  module DesignSystem
4
4
  module Generic
5
5
  module Builders
6
+ # This class provides generic summary list.
6
7
  class SummaryList < Base
7
8
  include ActionView::Helpers::OutputSafetyHelper
8
9
 
@@ -25,7 +26,10 @@ module DesignSystem
25
26
  end
26
27
 
27
28
  def render_row(row)
28
- content_tag(:div, class: "#{brand}-summary-list__row") do
29
+ row_classes = ["#{brand}-summary-list__row"]
30
+ row_classes << "#{brand}-summary-list__row--no-actions" if row[:actions].blank?
31
+
32
+ content_tag(:div, class: row_classes.join(' ')) do
29
33
  [render_key(row),
30
34
  render_value(row),
31
35
  render_actions(row)].compact.join.html_safe
@@ -37,10 +41,10 @@ module DesignSystem
37
41
  end
38
42
 
39
43
  def render_value(row)
40
- return if row[:values].nil? || row[:values].empty?
41
-
42
44
  content_tag(:dd, class: "#{brand}-summary-list__value") do
43
- if row[:values].length == 1
45
+ if row[:values].blank?
46
+ ''
47
+ elsif row[:values].length == 1
44
48
  row[:values].first[:content]
45
49
  else
46
50
  row[:values].map { |value| content_tag(:p, value[:content], class: "#{brand}-body") }.join.html_safe
@@ -49,7 +53,7 @@ module DesignSystem
49
53
  end
50
54
 
51
55
  def render_actions(row)
52
- return if row[:actions].nil? || row[:actions].empty?
56
+ return if row[:actions].blank?
53
57
 
54
58
  content_tag(:dd, class: "#{brand}-summary-list__actions") do
55
59
  if row[:actions].length == 1
@@ -65,8 +69,12 @@ module DesignSystem
65
69
  end
66
70
 
67
71
  def render_action(action)
68
- link_to(action[:options][:path] || '#', class: "#{brand}-link") do
69
- safe_join([action[:content], render_hidden_text(action[:options][:hidden_text])])
72
+ options = action[:options].dup
73
+ path = options.delete(:path) || '#'
74
+ hidden_text = options.delete(:hidden_text)
75
+
76
+ link_to(path, { class: "#{brand}-link" }.merge(options)) do
77
+ safe_join([action[:content], render_hidden_text(hidden_text)])
70
78
  end
71
79
  end
72
80
 
@@ -7,10 +7,14 @@ require_relative 'generic/builders/button'
7
7
  require_relative 'generic/builders/callout'
8
8
  require_relative 'generic/builders/details'
9
9
  require_relative 'generic/builders/fixed_elements'
10
+ require_relative 'generic/builders/grid'
10
11
  require_relative 'generic/builders/heading'
12
+ require_relative 'generic/builders/inset_text'
11
13
  require_relative 'generic/builders/link'
14
+ require_relative 'generic/builders/list'
12
15
  require_relative 'generic/builders/notification'
13
16
  require_relative 'generic/builders/pagination_renderer'
14
17
  require_relative 'generic/builders/panel'
18
+ require_relative 'generic/builders/paragraph'
15
19
  require_relative 'generic/builders/tab'
16
20
  require_relative 'generic/builders/table'
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Govuk
5
+ module Builders
6
+ # GOV UK specific grid implementation
7
+ # Inherits all functionality from generic builder
8
+ class Grid < ::DesignSystem::Generic::Builders::Grid
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Govuk
5
+ module Builders
6
+ # This generates html for rendering inset text for Govuk
7
+ class InsetText < ::DesignSystem::Generic::Builders::InsetText
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Govuk
5
+ module Builders
6
+ # GOVUK specific list builder.
7
+ class List < ::DesignSystem::Generic::Builders::List
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Govuk
5
+ module Builders
6
+ # This class provides GOVUK methods to display paragraphs in page content.
7
+ class Paragraph < ::DesignSystem::Generic::Builders::Paragraph
8
+ end
9
+ end
10
+ end
11
+ end
@@ -3,25 +3,15 @@
3
3
  module DesignSystem
4
4
  module Govuk
5
5
  module Builders
6
+ # This class provides GOVUK Summary List.
6
7
  class SummaryList < ::DesignSystem::Generic::Builders::SummaryList
7
8
  private
8
9
 
9
- def render_row(row)
10
- row_classes = ['govuk-summary-list__row']
11
- row_classes << 'govuk-summary-list__row--no-actions' if row[:actions].empty?
12
-
13
- content_tag(:div, class: row_classes.join(' ')) do
14
- [render_key(row),
15
- render_value(row),
16
- render_actions(row)].compact.join.html_safe
17
- end
18
- end
19
-
20
10
  def render_value(row)
21
- return if row[:values].nil? || row[:values].empty?
22
-
23
11
  content_tag(:dd, class: 'govuk-summary-list__value') do
24
- if row[:values].length == 1
12
+ if row[:values].blank?
13
+ ''
14
+ elsif row[:values].length == 1
25
15
  wrap_value(row[:values].first)
26
16
  else
27
17
  row[:values].map { |value| wrap_value(value) }.join.html_safe
@@ -389,9 +389,9 @@ module DesignSystem
389
389
 
390
390
  def translated_label(method)
391
391
  # We need to retrieve the label translation in the same way as Tags::Label
392
- content ||= ActionView::Helpers::Tags::Translator.
393
- new(object, object_name, method, scope: 'helpers.label').
394
- translate
392
+ content ||= ActionView::Helpers::Tags::Translator
393
+ .new(object, object_name, method, scope: 'helpers.label')
394
+ .translate
395
395
  content || method.humanize
396
396
  end
397
397
 
@@ -399,9 +399,12 @@ module DesignSystem
399
399
  # This method is used to translate the label for a given value
400
400
  # Example: assign an alternative name for checkbox items
401
401
  method_and_value = "#{method}.#{value}"
402
- translation = ActionView::Helpers::Tags::Translator.
403
- new(object, object_name, method_and_value, scope: 'helpers.options').
404
- translate
402
+ translation = ActionView::Helpers::Tags::Translator
403
+ .new(object, object_name, method_and_value, scope: 'helpers.options')
404
+ .translate
405
+
406
+ return value.to_s if translation.nil?
407
+
405
408
  # If translation returns the humanized version of the value,
406
409
  # it means no translation was found, so return the original value
407
410
  # Extra condition: if value contains dots and translation is only the last part
@@ -8,9 +8,11 @@ require_relative 'govuk/builders/details'
8
8
  require_relative 'govuk/builders/fixed_elements'
9
9
  require_relative 'govuk/builders/heading'
10
10
  require_relative 'govuk/builders/link'
11
+ require_relative 'govuk/builders/list'
11
12
  require_relative 'govuk/builders/notification'
12
13
  require_relative 'govuk/builders/pagination_renderer'
13
14
  require_relative 'govuk/builders/panel'
15
+ require_relative 'govuk/builders/paragraph'
14
16
  require_relative 'govuk/builders/summary_list'
15
17
  require_relative 'govuk/builders/tab'
16
18
  require_relative 'govuk/builders/table'
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Nhsuk
5
+ module Builders
6
+ # NHS UK specific grid implementation
7
+ # Inherits all functionality from generic builder
8
+ class Grid < ::DesignSystem::Generic::Builders::Grid
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,109 @@
1
+ require 'test_helper'
2
+
3
+ module DesignSystem
4
+ module Nhsuk
5
+ module Builders
6
+ # This tests the nhsuk grid builder
7
+ class GridTest < ActionView::TestCase
8
+ include DesignSystemHelper
9
+
10
+ setup do
11
+ @brand = 'nhsuk'
12
+ @controller.stubs(:brand).returns(@brand)
13
+ end
14
+
15
+ test 'should fail if width is specified' do
16
+ assert_raises(ArgumentError) do
17
+ ds_grid do |grid|
18
+ grid.add_column do
19
+ 'Test content'
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ test 'should fail if given width is not supported' do
26
+ error = assert_raises(ArgumentError) do
27
+ ds_grid do |grid|
28
+ grid.add_column(:nonsense_width) do
29
+ 'Test content'
30
+ end
31
+ end
32
+ end
33
+ assert_equal 'Unknown grid width: nonsense_width', error.message
34
+ end
35
+
36
+ test 'should render block of content' do
37
+ @output_buffer = ds_grid do |grid|
38
+ grid.add_column(:two_thirds) do
39
+ content_tag(:p, 'Test content')
40
+ end
41
+ end
42
+
43
+ assert_select "div.#{brand}-grid-row" do
44
+ assert_select "div.#{brand}-grid-column-two-thirds" do
45
+ assert_select 'p', text: 'Test content'
46
+ end
47
+ end
48
+ end
49
+
50
+ test 'should render multiple columns' do
51
+ @output_buffer = ds_grid do |grid|
52
+ grid.add_column(:two_thirds) do
53
+ content_tag(:p, 'Two thirds content')
54
+ end
55
+ grid.add_column(:one_third) do
56
+ content_tag(:p, 'One third content')
57
+ end
58
+ end
59
+ assert_select "div.#{brand}-grid-row" do
60
+ assert_select "div.#{brand}-grid-column-two-thirds" do
61
+ assert_select 'p', text: 'Two thirds content'
62
+ end
63
+ assert_select "div.#{brand}-grid-column-one-third" do
64
+ assert_select 'p', text: 'One third content'
65
+ end
66
+ end
67
+ end
68
+
69
+ test 'should raise an error if total width exceeds 100%' do
70
+ error = assert_raises(ArgumentError) do
71
+ ds_grid do |grid|
72
+ grid.add_column(:two_thirds) do
73
+ content_tag(:p, 'Two thirds content')
74
+ end
75
+ grid.add_column(:two_thirds) do
76
+ content_tag(:p, 'Two thirds content')
77
+ end
78
+ end
79
+ end
80
+ assert_equal 'Total grid width exceeds 100%', error.message
81
+ end
82
+
83
+ test 'should render nested grid' do
84
+ @output_buffer = ds_grid do |row|
85
+ row.add_column(:two_thirds) do
86
+ content_tag(:p, 'Outer two thirds content') +
87
+ ds_grid do |inner_row|
88
+ inner_row.add_column(:two_thirds) do
89
+ content_tag(:p, 'Inner two thirds content')
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ assert_select "div.#{brand}-grid-row" do
96
+ assert_select "div.#{brand}-grid-column-two-thirds" do
97
+ assert_select 'p', text: 'Outer two thirds content'
98
+ assert_select "div.#{brand}-grid-row" do
99
+ assert_select "div.#{brand}-grid-column-two-thirds" do
100
+ assert_select 'p', text: 'Inner two thirds content'
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Nhsuk
5
+ module Builders
6
+ # This generates html for rendering inset text for Nhsuk
7
+ class InsetText < ::DesignSystem::Generic::Builders::InsetText
8
+ def render_inset_text(text = nil, **options, &)
9
+ content = block_given? ? capture(&) : text
10
+ return if content.blank?
11
+
12
+ wrapped_content = block_given? ? content : content_tag(:p, content)
13
+
14
+ div_options = css_class_options_merge(options, ["#{brand}-inset-text"])
15
+
16
+ content_tag(:div, **div_options) do
17
+ content_tag(:span, 'Information: ', class: "#{brand}-u-visually-hidden") + wrapped_content
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Nhsuk
5
+ module Builders
6
+ # Generic list builder for NHSUK.
7
+ class List < ::DesignSystem::Generic::Builders::List
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DesignSystem
4
+ module Nhsuk
5
+ module Builders
6
+ # This class provides NHSUK methods to display paragraphs in page content.
7
+ class Paragraph < ::DesignSystem::Generic::Builders::Paragraph
8
+ end
9
+ end
10
+ end
11
+ end
@@ -3,24 +3,10 @@
3
3
  module DesignSystem
4
4
  module Nhsuk
5
5
  module Builders
6
+ # This class provides NHSUK Summary List.
6
7
  class SummaryList < ::DesignSystem::Generic::Builders::SummaryList
7
8
  private
8
9
 
9
- def validate_mix_actions
10
- if @summary_list.rows.any? { |row| row[:actions].empty? } &&
11
- @summary_list.rows.any? { |row| row[:actions].any? }
12
- raise ArgumentError, "A mix of rows with and without actions is not supported for #{brand} style."
13
- end
14
- end
15
-
16
- def render_rows
17
- validate_mix_actions
18
-
19
- content_tag(:dl, class: "#{brand}-summary-list") do
20
- @summary_list.rows.map { |row| render_row(row) }.join.html_safe
21
- end
22
- end
23
-
24
10
  def render_hidden_text(hidden_text)
25
11
  return '' if hidden_text.blank?
26
12
 
@@ -6,9 +6,11 @@ require_relative 'nhsuk/builders/fixed_elements'
6
6
  require_relative 'nhsuk/builders/details'
7
7
  require_relative 'nhsuk/builders/heading'
8
8
  require_relative 'nhsuk/builders/link'
9
+ require_relative 'nhsuk/builders/list'
9
10
  require_relative 'nhsuk/builders/notification'
10
11
  require_relative 'nhsuk/builders/pagination_renderer'
11
12
  require_relative 'nhsuk/builders/panel'
13
+ require_relative 'nhsuk/builders/paragraph'
12
14
  require_relative 'nhsuk/builders/summary_list'
13
15
  require_relative 'nhsuk/builders/tab'
14
16
  require_relative 'nhsuk/builders/table'
@@ -1,3 +1,3 @@
1
1
  module DesignSystem
2
- VERSION = '0.12.0'.freeze
2
+ VERSION = '0.13.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: design_system
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Filis Liu
@@ -398,6 +398,8 @@ files:
398
398
  - config/routes.rb
399
399
  - lib/design_system.rb
400
400
  - lib/design_system/all.rb
401
+ - lib/design_system/components/grid.rb
402
+ - lib/design_system/components/list.rb
401
403
  - lib/design_system/components/summary_list.rb
402
404
  - lib/design_system/components/tab.rb
403
405
  - lib/design_system/components/table.rb
@@ -413,12 +415,17 @@ files:
413
415
  - lib/design_system/generic/builders/elements/breadcrumbs.rb
414
416
  - lib/design_system/generic/builders/elements/form.rb
415
417
  - lib/design_system/generic/builders/elements/headings.rb
418
+ - lib/design_system/generic/builders/elements/lead_paragraph.rb
416
419
  - lib/design_system/generic/builders/fixed_elements.rb
420
+ - lib/design_system/generic/builders/grid.rb
417
421
  - lib/design_system/generic/builders/heading.rb
422
+ - lib/design_system/generic/builders/inset_text.rb
418
423
  - lib/design_system/generic/builders/link.rb
424
+ - lib/design_system/generic/builders/list.rb
419
425
  - lib/design_system/generic/builders/notification.rb
420
426
  - lib/design_system/generic/builders/pagination_renderer.rb
421
427
  - lib/design_system/generic/builders/panel.rb
428
+ - lib/design_system/generic/builders/paragraph.rb
422
429
  - lib/design_system/generic/builders/summary_list.rb
423
430
  - lib/design_system/generic/builders/tab.rb
424
431
  - lib/design_system/generic/builders/table.rb
@@ -431,11 +438,15 @@ files:
431
438
  - lib/design_system/govuk/builders/elements/breadcrumbs.rb
432
439
  - lib/design_system/govuk/builders/elements/headings.rb
433
440
  - lib/design_system/govuk/builders/fixed_elements.rb
441
+ - lib/design_system/govuk/builders/grid.rb
434
442
  - lib/design_system/govuk/builders/heading.rb
443
+ - lib/design_system/govuk/builders/inset_text.rb
435
444
  - lib/design_system/govuk/builders/link.rb
445
+ - lib/design_system/govuk/builders/list.rb
436
446
  - lib/design_system/govuk/builders/notification.rb
437
447
  - lib/design_system/govuk/builders/pagination_renderer.rb
438
448
  - lib/design_system/govuk/builders/panel.rb
449
+ - lib/design_system/govuk/builders/paragraph.rb
439
450
  - lib/design_system/govuk/builders/summary_list.rb
440
451
  - lib/design_system/govuk/builders/tab.rb
441
452
  - lib/design_system/govuk/builders/table.rb
@@ -450,11 +461,16 @@ files:
450
461
  - lib/design_system/nhsuk/builders/details.rb
451
462
  - lib/design_system/nhsuk/builders/elements/breadcrumbs.rb
452
463
  - lib/design_system/nhsuk/builders/fixed_elements.rb
464
+ - lib/design_system/nhsuk/builders/grid.rb
465
+ - lib/design_system/nhsuk/builders/grid_test.rb
453
466
  - lib/design_system/nhsuk/builders/heading.rb
467
+ - lib/design_system/nhsuk/builders/inset_text.rb
454
468
  - lib/design_system/nhsuk/builders/link.rb
469
+ - lib/design_system/nhsuk/builders/list.rb
455
470
  - lib/design_system/nhsuk/builders/notification.rb
456
471
  - lib/design_system/nhsuk/builders/pagination_renderer.rb
457
472
  - lib/design_system/nhsuk/builders/panel.rb
473
+ - lib/design_system/nhsuk/builders/paragraph.rb
458
474
  - lib/design_system/nhsuk/builders/summary_list.rb
459
475
  - lib/design_system/nhsuk/builders/tab.rb
460
476
  - lib/design_system/nhsuk/builders/table.rb