dsfr-view-components 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +214 -0
  3. data/Rakefile +22 -0
  4. data/app/components/dsfr_component/accordion_component/section_component.html.erb +11 -0
  5. data/app/components/dsfr_component/accordion_component/section_component.rb +39 -0
  6. data/app/components/dsfr_component/accordion_component.html.erb +5 -0
  7. data/app/components/dsfr_component/accordion_component.rb +33 -0
  8. data/app/components/dsfr_component/alert_component.rb +22 -0
  9. data/app/components/dsfr_component/back_link_component.rb +24 -0
  10. data/app/components/dsfr_component/base.rb +28 -0
  11. data/app/components/dsfr_component/breadcrumbs_component.html.erb +7 -0
  12. data/app/components/dsfr_component/breadcrumbs_component.rb +51 -0
  13. data/app/components/dsfr_component/cookie_banner_component/message_component.rb +62 -0
  14. data/app/components/dsfr_component/cookie_banner_component.rb +35 -0
  15. data/app/components/dsfr_component/details_component.rb +42 -0
  16. data/app/components/dsfr_component/footer_component.html.erb +49 -0
  17. data/app/components/dsfr_component/footer_component.rb +87 -0
  18. data/app/components/dsfr_component/header_component.html.erb +51 -0
  19. data/app/components/dsfr_component/header_component.rb +145 -0
  20. data/app/components/dsfr_component/inset_text_component.rb +28 -0
  21. data/app/components/dsfr_component/notification_banner_component.html.erb +14 -0
  22. data/app/components/dsfr_component/notification_banner_component.rb +93 -0
  23. data/app/components/dsfr_component/pagination_component/adjacent_page.rb +59 -0
  24. data/app/components/dsfr_component/pagination_component/item.rb +77 -0
  25. data/app/components/dsfr_component/pagination_component/next_page.rb +27 -0
  26. data/app/components/dsfr_component/pagination_component/previous_page.rb +21 -0
  27. data/app/components/dsfr_component/pagination_component.rb +129 -0
  28. data/app/components/dsfr_component/panel_component.rb +56 -0
  29. data/app/components/dsfr_component/phase_banner_component.html.erb +6 -0
  30. data/app/components/dsfr_component/phase_banner_component.rb +25 -0
  31. data/app/components/dsfr_component/section_break_component.rb +49 -0
  32. data/app/components/dsfr_component/start_button_component.rb +55 -0
  33. data/app/components/dsfr_component/summary_list_component/action_component.rb +42 -0
  34. data/app/components/dsfr_component/summary_list_component/key_component.rb +23 -0
  35. data/app/components/dsfr_component/summary_list_component/row_component.rb +57 -0
  36. data/app/components/dsfr_component/summary_list_component/value_component.rb +23 -0
  37. data/app/components/dsfr_component/summary_list_component.html.erb +5 -0
  38. data/app/components/dsfr_component/summary_list_component.rb +49 -0
  39. data/app/components/dsfr_component/tab_component.html.erb +11 -0
  40. data/app/components/dsfr_component/tab_component.rb +61 -0
  41. data/app/components/dsfr_component/table_component/body_component.html.erb +5 -0
  42. data/app/components/dsfr_component/table_component/body_component.rb +21 -0
  43. data/app/components/dsfr_component/table_component/caption_component.rb +37 -0
  44. data/app/components/dsfr_component/table_component/cell_component.rb +57 -0
  45. data/app/components/dsfr_component/table_component/head_component.html.erb +5 -0
  46. data/app/components/dsfr_component/table_component/head_component.rb +23 -0
  47. data/app/components/dsfr_component/table_component/row_component.html.erb +5 -0
  48. data/app/components/dsfr_component/table_component/row_component.rb +30 -0
  49. data/app/components/dsfr_component/table_component.html.erb +7 -0
  50. data/app/components/dsfr_component/table_component.rb +35 -0
  51. data/app/components/dsfr_component/tag_component.rb +44 -0
  52. data/app/components/dsfr_component/traits/custom_html_attributes.rb +7 -0
  53. data/app/components/dsfr_component/traits.rb +1 -0
  54. data/app/components/dsfr_component/warning_text_component.rb +37 -0
  55. data/app/components/dsfr_component.rb +1 -0
  56. data/app/helpers/dsfr_back_to_top_link_helper.rb +14 -0
  57. data/app/helpers/dsfr_components_helper.rb +33 -0
  58. data/app/helpers/dsfr_link_helper.rb +123 -0
  59. data/app/helpers/dsfr_skip_link_helper.rb +13 -0
  60. data/config/routes.rb +2 -0
  61. data/lib/dsfr/components/engine.rb +110 -0
  62. data/lib/dsfr/components/helpers/css_utilities.rb +22 -0
  63. data/lib/dsfr/components/version.rb +5 -0
  64. data/lib/dsfr/components.rb +6 -0
  65. data/lib/tasks/dsfr/components_tasks.rake +4 -0
  66. metadata +482 -0
@@ -0,0 +1,57 @@
1
+ class DsfrComponent::TableComponent::CellComponent < DsfrComponent::Base
2
+ attr_reader :text, :header, :numeric, :width
3
+
4
+ alias_method :numeric?, :numeric
5
+
6
+ WIDTHS = {
7
+ "full" => "govuk-!-width-full",
8
+ "three-quarters" => "govuk-!-width-three-quarters",
9
+ "two-thirds" => "govuk-!-width-two-thirds",
10
+ "one-half" => "govuk-!-width-one-half",
11
+ "one-third" => "govuk-!-width-one-third",
12
+ "one-quarter" => "govuk-!-width-one-quarter",
13
+ }.freeze
14
+
15
+ def initialize(header: false, text: nil, numeric: false, width: nil, classes: [], html_attributes: {})
16
+ @header = header
17
+ @text = text
18
+ @numeric = numeric
19
+ @width = width
20
+
21
+ super(classes: classes, html_attributes: html_attributes)
22
+ end
23
+
24
+ def call
25
+ content_tag(cell_element, cell_content, **html_attributes)
26
+ end
27
+
28
+ private
29
+
30
+ def width?
31
+ width.present?
32
+ end
33
+
34
+ def cell_content
35
+ content || text
36
+ end
37
+
38
+ def cell_element
39
+ header ? :th : :td
40
+ end
41
+
42
+ def default_attributes
43
+ { class: default_classes }
44
+ end
45
+
46
+ def default_classes
47
+ if header
48
+ class_names("govuk-table__header", "govuk-table__header--numeric" => numeric?, width_class => width?).split
49
+ else
50
+ class_names("govuk-table__cell", "govuk-table__cell--numeric" => numeric?, width_class => width?).split
51
+ end
52
+ end
53
+
54
+ def width_class
55
+ WIDTHS.fetch(width, nil)
56
+ end
57
+ end
@@ -0,0 +1,5 @@
1
+ <%= tag.thead(**html_attributes) do %>
2
+ <% rows.each do |row| %>
3
+ <%= row %>
4
+ <% end %>
5
+ <% end %>
@@ -0,0 +1,23 @@
1
+ class DsfrComponent::TableComponent::HeadComponent < DsfrComponent::Base
2
+ renders_many :rows, "DsfrComponent::TableComponent::RowComponent"
3
+
4
+ attr_reader :row_data
5
+
6
+ def initialize(rows: nil, classes: [], html_attributes: {})
7
+ super(classes: classes, html_attributes: html_attributes)
8
+
9
+ build_rows_from_row_data(rows)
10
+ end
11
+
12
+ private
13
+
14
+ def build_rows_from_row_data(data)
15
+ return if data.blank?
16
+
17
+ data.each { |d| row(cell_data: d, header: true) }
18
+ end
19
+
20
+ def default_attributes
21
+ { class: %w(govuk-table__head) }
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ <%= tag.tr(**html_attributes) do %>
2
+ <% cells.each do |cell| %>
3
+ <%= cell %>
4
+ <% end %>
5
+ <% end %>
@@ -0,0 +1,30 @@
1
+ class DsfrComponent::TableComponent::RowComponent < DsfrComponent::Base
2
+ renders_many :cells, "DsfrComponent::TableComponent::CellComponent"
3
+
4
+ attr_reader :header, :first_cell_is_header
5
+
6
+ def initialize(cell_data: nil, first_cell_is_header: false, header: false, classes: [], html_attributes: {})
7
+ @header = header
8
+ @first_cell_is_header = first_cell_is_header
9
+
10
+ super(classes: classes, html_attributes: html_attributes)
11
+
12
+ build_cells_from_cell_data(cell_data)
13
+ end
14
+
15
+ private
16
+
17
+ def build_cells_from_cell_data(cell_data)
18
+ return if cell_data.blank?
19
+
20
+ cell_data.map.with_index { |cd, i| cell(header: cell_is_header?(i), text: cd) }
21
+ end
22
+
23
+ def cell_is_header?(count)
24
+ header || (first_cell_is_header && count.zero?)
25
+ end
26
+
27
+ def default_attributes
28
+ { class: %w(govuk-table__row) }
29
+ end
30
+ end
@@ -0,0 +1,7 @@
1
+ <%= tag.table(**html_attributes) do %>
2
+ <%= caption %>
3
+ <%= head %>
4
+ <% bodies.each do |body| %>
5
+ <%= body %>
6
+ <% end %>
7
+ <% end %>
@@ -0,0 +1,35 @@
1
+ module DsfrComponent
2
+ class TableComponent < DsfrComponent::Base
3
+ renders_one :caption, "DsfrComponent::TableComponent::CaptionComponent"
4
+ renders_one :head, "DsfrComponent::TableComponent::HeadComponent"
5
+ renders_many :bodies, "DsfrComponent::TableComponent::BodyComponent"
6
+
7
+ attr_accessor :id, :first_cell_is_header, :caption_text
8
+
9
+ def initialize(id: nil, rows: nil, head: nil, caption: nil, first_cell_is_header: false, classes: [], html_attributes: {})
10
+ @id = id
11
+ @first_cell_is_header = first_cell_is_header
12
+ @caption_text = caption
13
+
14
+ super(classes: classes, html_attributes: html_attributes)
15
+
16
+ # when no rows are passed in it's likely we're taking the slot approach
17
+ return unless rows.presence
18
+
19
+ # if no head is passed in,use the first row for headers
20
+ build(*(head ? [head, rows] : [rows[0], rows[1..]]), caption_text)
21
+ end
22
+
23
+ private
24
+
25
+ def build(head_data, body_data, caption_text)
26
+ caption(text: caption_text)
27
+ head(rows: [head_data])
28
+ body(rows: body_data, first_cell_is_header: first_cell_is_header)
29
+ end
30
+
31
+ def default_attributes
32
+ { id: id, class: %w(govuk-table) }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,44 @@
1
+ class DsfrComponent::TagComponent < DsfrComponent::Base
2
+ attr_reader :text, :colour
3
+
4
+ COLOURS = %w(grey green turquoise blue red purple pink orange yellow).freeze
5
+
6
+ def initialize(text: nil, colour: config.default_tag_colour, classes: [], html_attributes: {})
7
+ @text = text
8
+ @colour = colour
9
+
10
+ super(classes: classes, html_attributes: html_attributes)
11
+ end
12
+
13
+ def call
14
+ tag.strong(tag_content, **html_attributes)
15
+ end
16
+
17
+ private
18
+
19
+ def tag_content
20
+ @text || content || fail(ArgumentError, "no text or content")
21
+ end
22
+
23
+ def default_attributes
24
+ {
25
+ class: ["govuk-tag", colour_class]
26
+ }
27
+ end
28
+
29
+ def colour_class
30
+ return nil if colour.blank?
31
+
32
+ fail(ArgumentError, colour_error_message) unless valid_colour?
33
+
34
+ %(govuk-tag--#{colour})
35
+ end
36
+
37
+ def valid_colour?
38
+ @colour.in?(COLOURS)
39
+ end
40
+
41
+ def colour_error_message
42
+ "invalid tag colour #{colour}, supported colours are #{COLOURS.to_sentence}"
43
+ end
44
+ end
@@ -0,0 +1,7 @@
1
+ module DsfrComponent
2
+ module Traits
3
+ module CustomHtmlAttributes
4
+ attr_reader :html_attributes
5
+ end
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ module DsfrComponent::Traits; end
@@ -0,0 +1,37 @@
1
+ class DsfrComponent::WarningTextComponent < DsfrComponent::Base
2
+ attr_reader :text, :icon, :icon_fallback_text
3
+
4
+ def initialize(text: nil, icon_fallback_text: config.default_warning_text_icon_fallback_text, icon: config.default_warning_text_icon, classes: [], html_attributes: {})
5
+ @text = text
6
+ @icon = icon
7
+ @icon_fallback_text = icon_fallback_text
8
+
9
+ super(classes: classes, html_attributes: html_attributes)
10
+ end
11
+
12
+ def call
13
+ tag.div(**html_attributes) do
14
+ safe_join([icon_element, warning_text])
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def icon_element
21
+ tag.span(icon, class: 'govuk-warning-text__icon', aria: { hidden: true })
22
+ end
23
+
24
+ def warning_text
25
+ tag.strong(class: 'govuk-warning-text__text') do
26
+ safe_join([assistive, (content || text)])
27
+ end
28
+ end
29
+
30
+ def assistive
31
+ tag.span(icon_fallback_text, class: 'govuk-warning-text__assistive')
32
+ end
33
+
34
+ def default_attributes
35
+ { class: %w(govuk-warning-text) }
36
+ end
37
+ end
@@ -0,0 +1 @@
1
+ module DsfrComponent; end
@@ -0,0 +1,14 @@
1
+ module DsfrBackToTopLinkHelper
2
+ def dsfr_back_to_top_link(target = '#top')
3
+ link_to(target, class: 'fr-link fr-link--no-visited-state') do
4
+ <<-HTML.squish.html_safe
5
+ <svg class="app-back-to-top__icon" xmlns="http://www.w3.org/2000/svg" width="13" height="17" viewBox="0 0 13 17">
6
+ <path fill="currentColor" d="M6.5 0L0 6.5 1.4 8l4-4v12.7h2V4l4.3 4L13 6.4z"></path>
7
+ </svg>
8
+ Back to top
9
+ HTML
10
+ end
11
+ end
12
+ end
13
+
14
+ ActiveSupport.on_load(:action_view) { include DsfrBackToTopLinkHelper }
@@ -0,0 +1,33 @@
1
+ module DsfrComponentsHelper
2
+ {
3
+ dsfr_accordion: 'DsfrComponent::AccordionComponent',
4
+ dsfr_back_link: 'DsfrComponent::BackLinkComponent',
5
+ dsfr_breadcrumbs: 'DsfrComponent::BreadcrumbsComponent',
6
+ dsfr_cookie_banner: 'DsfrComponent::CookieBannerComponent',
7
+ dsfr_details: 'DsfrComponent::DetailsComponent',
8
+ dsfr_footer: 'DsfrComponent::FooterComponent',
9
+ dsfr_header: 'DsfrComponent::HeaderComponent',
10
+ dsfr_inset_text: 'DsfrComponent::InsetTextComponent',
11
+ dsfr_notification_banner: 'DsfrComponent::NotificationBannerComponent',
12
+ dsfr_pagination: 'DsfrComponent::PaginationComponent',
13
+ dsfr_panel: 'DsfrComponent::PanelComponent',
14
+ dsfr_phase_banner: 'DsfrComponent::PhaseBannerComponent',
15
+ dsfr_section_break: 'DsfrComponent::SectionBreakComponent',
16
+ dsfr_start_button: 'DsfrComponent::StartButtonComponent',
17
+ dsfr_summary_list: 'DsfrComponent::SummaryListComponent',
18
+ dsfr_table: 'DsfrComponent::TableComponent',
19
+ dsfr_tabs: 'DsfrComponent::TabComponent',
20
+ dsfr_tag: 'DsfrComponent::TagComponent',
21
+ dsfr_warning_text: 'DsfrComponent::WarningTextComponent',
22
+ }.each do |name, klass|
23
+ define_method(name) do |*args, **kwargs, &block|
24
+ capture do
25
+ render(klass.constantize.new(*args, **kwargs)) do |com|
26
+ block.call(com) if block.present?
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ ActiveSupport.on_load(:action_view) { include DsfrComponentsHelper }
@@ -0,0 +1,123 @@
1
+ module DsfrLinkHelper
2
+ LINK_STYLES = {
3
+ inverse: "fr-link--inverse",
4
+ muted: "fr-link--muted",
5
+ no_underline: "fr-link--no-underline",
6
+ no_visited_state: "fr-link--no-visited-state",
7
+ text_colour: "fr-link--text-colour",
8
+ }.freeze
9
+
10
+ BUTTON_STYLES = {
11
+ disabled: "fr-btn--disabled",
12
+ secondary: "fr-btn--secondary",
13
+ warning: "fr-btn--warning",
14
+ }.freeze
15
+
16
+ def dsfr_link_classes(*styles, default_class: 'fr-link')
17
+ if (invalid_styles = (styles - LINK_STYLES.keys)) && invalid_styles.any?
18
+ fail(ArgumentError, "invalid styles #{invalid_styles.to_sentence}. Valid styles are #{LINK_STYLES.keys.to_sentence}")
19
+ end
20
+
21
+ [default_class] + LINK_STYLES.values_at(*styles).compact
22
+ end
23
+
24
+ def dsfr_button_classes(*styles, default_class: 'fr-btn')
25
+ if (invalid_styles = (styles - BUTTON_STYLES.keys)) && invalid_styles.any?
26
+ fail(ArgumentError, "invalid styles #{invalid_styles.to_sentence}. Valid styles are #{BUTTON_STYLES.keys.to_sentence}")
27
+ end
28
+
29
+ [default_class] + BUTTON_STYLES.values_at(*styles).compact
30
+ end
31
+
32
+ def dsfr_link_to(name = nil, options = nil, extra_options = {}, &block)
33
+ extra_options = options if block_given?
34
+ html_options = build_html_options(extra_options)
35
+
36
+ if block_given?
37
+ link_to(name, html_options, &block)
38
+ else
39
+ link_to(name, options, html_options)
40
+ end
41
+ end
42
+
43
+ def dsfr_mail_to(email_address, name = nil, extra_options = {}, &block)
44
+ extra_options = name if block_given?
45
+ html_options = build_html_options(extra_options)
46
+
47
+ if block_given?
48
+ mail_to(email_address, html_options, &block)
49
+ else
50
+ mail_to(email_address, name, html_options)
51
+ end
52
+ end
53
+
54
+ def dsfr_button_to(name = nil, options = nil, extra_options = {}, &block)
55
+ extra_options = options if block_given?
56
+ html_options = build_html_options(extra_options, style: :button)
57
+
58
+ if block_given?
59
+ button_to(options, html_options, &block)
60
+ else
61
+ button_to(name, options, html_options)
62
+ end
63
+ end
64
+
65
+ def dsfr_button_link_to(name = nil, options = nil, extra_options = {}, &block)
66
+ extra_options = options if block_given?
67
+ html_options = DsfrComponent::StartButtonComponent::LINK_ATTRIBUTES
68
+ .merge build_html_options(extra_options, style: :button)
69
+
70
+ if block_given?
71
+ link_to(name, html_options, &block)
72
+ else
73
+ link_to(name, options, html_options)
74
+ end
75
+ end
76
+
77
+ def dsfr_breadcrumb_link_to(name = nil, options = nil, extra_options = {}, &block)
78
+ extra_options = options if block_given?
79
+ html_options = build_html_options(extra_options, style: :breadcrumb)
80
+
81
+ if block_given?
82
+ link_to(name, html_options, &block)
83
+ else
84
+ link_to(name, options, html_options)
85
+ end
86
+ end
87
+
88
+ private
89
+
90
+ def build_html_options(provided_options, style: :link)
91
+ styles = case style
92
+ when :link then LINK_STYLES
93
+ when :button then BUTTON_STYLES
94
+ else {}
95
+ end
96
+
97
+ remaining_options = provided_options&.slice!(*styles.keys)
98
+
99
+ return {} unless (style_classes = build_style_classes(style, provided_options))
100
+
101
+ inject_class(remaining_options, class_name: style_classes)
102
+ end
103
+
104
+ def build_style_classes(style, provided_options)
105
+ keys = *provided_options&.keys
106
+
107
+ case style
108
+ when :link then dsfr_link_classes(*keys)
109
+ when :button then dsfr_button_classes(*keys)
110
+ when :breadcrumb then %w(govuk-breadcrumbs__link)
111
+ end
112
+ end
113
+
114
+ def inject_class(attributes, class_name:)
115
+ attributes ||= {}
116
+
117
+ attributes.with_indifferent_access.tap do |attrs|
118
+ attrs[:class] = Array.wrap(attrs[:class]).prepend(class_name).flatten.join(" ")
119
+ end
120
+ end
121
+ end
122
+
123
+ ActiveSupport.on_load(:action_view) { include DsfrLinkHelper }
@@ -0,0 +1,13 @@
1
+ module DsfrSkipLinkHelper
2
+ def dsfr_skip_link(text: 'Skip to main content', href: '#main-content', classes: [], **html_attributes, &block)
3
+ link_classes = Array.wrap(classes).append('govuk-skip-link')
4
+
5
+ html_attributes_with_data_module = { data: { module: "govuk-skip-link" } }.deep_merge(html_attributes)
6
+
7
+ return link_to(href, class: link_classes, **html_attributes_with_data_module, &block) if block_given?
8
+
9
+ link_to(text, href, class: link_classes, **html_attributes_with_data_module)
10
+ end
11
+ end
12
+
13
+ ActiveSupport.on_load(:action_view) { include DsfrSkipLinkHelper }
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Dsfr::Components::Engine.routes.draw do
2
+ end
@@ -0,0 +1,110 @@
1
+ require "rails/engine"
2
+ require "active_support/configurable"
3
+
4
+ module Dsfr
5
+ module Components
6
+ include ActiveSupport::Configurable
7
+
8
+ class << self
9
+ # Configure the form builder in the usual manner. All of the
10
+ # keys in {DEFAULTS} can be configured as per the example below
11
+ #
12
+ # @example
13
+ # Dsfr::Components.configure do |conf|
14
+ # conf.do_some_things = 'yes'
15
+ # end
16
+ def configure
17
+ yield(config)
18
+ end
19
+
20
+ # Resets each of the configurable values to its default
21
+ #
22
+ # @note This method is only really intended for use to clean up
23
+ # during testing
24
+ def reset!
25
+ configure do |c|
26
+ DEFAULTS.each { |k, v| c.send("#{k}=", v) }
27
+ end
28
+ end
29
+ end
30
+
31
+ # @!group Defaults
32
+ #
33
+ # Default components configuration
34
+ #
35
+ # +:default_back_link_text+ Default text for the back link, defaults to +Back+
36
+ # +:default_breadcrumbs_collapse_on_mobile+ false
37
+ # +:default_breadcrumbs_hide_in_print+ false
38
+ # +:default_cookie_banner_aria_label+ "Cookie banner"
39
+ # +:default_cookie_banner_hide_in_print+ true
40
+ # +:default_header_navigation_label+ 'Navigation menu'
41
+ # +:default_header_menu_button_label+ 'Show or hide navigation menu'
42
+ # +:default_header_logotype+ 'GOV.UK'
43
+ # +:default_header_homepage_url+ '/'
44
+ # +:default_header_service_name+ nil
45
+ # +:default_header_service_url+ '/'
46
+ # +:default_footer_meta_text+ nil
47
+ # +:default_footer_copyright_text+ '© Crown copyright'
48
+ # +:default_footer_copyright_url+ "https://www.nationalarchives.gov.uk/information-management/re-using-public-sector-information/uk-government-licensing-framework/crown-copyright/"
49
+ # +:default_pagination_landmark_label+ "results"
50
+ # +:default_pagination_next_text+ Default 'next' text for pagination. An +Array+ where the first item is visible and the second visually hidden. Defaults to ["Next", "page"]
51
+ # +:default_pagination_previous_text+ Default 'previous' text for pagination. An +Array+ where the first item is visible and the second visually hidden. Defaults to ["Previous", "page"]
52
+ # +:default_phase_banner_tag+ nil
53
+ # +:default_phase_banner_text+ nil
54
+ # +:default_section_break_visible+ false
55
+ # +:default_section_break_size+ Size of the section break, possible values: +m+, +l+ and +xl+. Defaults to nil.
56
+ # +:default_tag_colour+ the default colour for tags, possible values: +grey+, +green+, +turquoise+, +blue+, +red+, +purple+, +pink+, +orange+, +yellow+. Defaults to +nil+
57
+ # +:default_start_button_as_button+ false
58
+ # +:default_summary_list_borders+ true
59
+ # +:default_notification_banner_title_id+ "govuk-notification-banner-title"
60
+ # +:default_notification_disable_auto_focus+ nil
61
+ # +:default_notification_title_heading_level+ 2
62
+ # +:default_notification_title_success+ false
63
+ # +:default_warning_text_icon_fallback_text+ "Warning"
64
+ # +:default_warning_text_icon+ "!"
65
+ #
66
+ # +:require_summary_list_action_visually_hidden_text+ when true forces visually hidden text to be set for every action. It can still be explicitly skipped by passing in +nil+. Defaults to +false+
67
+ DEFAULTS = {
68
+ default_back_link_text: 'Back',
69
+ default_breadcrumbs_collapse_on_mobile: false,
70
+ default_breadcrumbs_hide_in_print: false,
71
+ default_cookie_banner_aria_label: "Cookie banner",
72
+ default_cookie_banner_hide_in_print: true,
73
+ default_header_navigation_label: 'Navigation menu',
74
+ default_header_menu_button_label: 'Show or hide navigation menu',
75
+ default_header_logotype: 'GOV.UK',
76
+ default_header_homepage_url: '/',
77
+ default_header_service_name: nil,
78
+ default_header_service_url: '/',
79
+ default_footer_meta_text: nil,
80
+ default_footer_copyright_text: '© Crown copyright',
81
+ default_footer_copyright_url: "https://www.nationalarchives.gov.uk/information-management/re-using-public-sector-information/uk-government-licensing-framework/crown-copyright/",
82
+ default_pagination_landmark_label: "results",
83
+ default_pagination_next_text: %w(Next page),
84
+ default_pagination_previous_text: %w(Previous page),
85
+ default_phase_banner_tag: nil,
86
+ default_phase_banner_text: nil,
87
+ default_section_break_visible: false,
88
+ default_section_break_size: nil,
89
+ default_tag_colour: nil,
90
+ default_start_button_as_button: false,
91
+ default_summary_list_borders: true,
92
+ default_notification_banner_title_id: "govuk-notification-banner-title",
93
+ default_notification_disable_auto_focus: nil,
94
+ default_notification_title_heading_level: 2,
95
+ default_notification_title_success: false,
96
+ default_warning_text_icon_fallback_text: "Warning",
97
+ default_warning_text_icon: "!",
98
+
99
+ require_summary_list_action_visually_hidden_text: false,
100
+ }.freeze
101
+
102
+ DEFAULTS.each_key { |k| config_accessor(k) { DEFAULTS[k] } }
103
+
104
+ class Engine < ::Rails::Engine
105
+ isolate_namespace Dsfr::Components
106
+ end
107
+ end
108
+ end
109
+
110
+ Dir[Dsfr::Components::Engine.root.join("app", "helpers", "*.rb")].sort.each { |f| require f }
@@ -0,0 +1,22 @@
1
+ module Dsfr
2
+ module Components
3
+ module Helpers
4
+ module CssUtilities
5
+ def combine_classes(default_classes, custom_classes)
6
+ converted_custom_classes = case custom_classes
7
+ when Array
8
+ custom_classes
9
+ when String
10
+ custom_classes.split
11
+ when NilClass
12
+ []
13
+ else
14
+ fail(ArgumentError, "custom classes must be a String, Array or NilClass")
15
+ end
16
+
17
+ default_classes.concat(converted_custom_classes).uniq
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ module Dsfr
2
+ module Components
3
+ VERSION = '0.0.1'.freeze
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ require "rails/engine"
2
+ require "view_component"
3
+ require "dsfr/components/helpers/css_utilities"
4
+ require "dsfr/components/engine"
5
+ require "html_attributes_utils"
6
+ require "pagy"
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :govuk_components do
3
+ # # Task goes here
4
+ # end