dsfr-view-components 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +214 -0
- data/Rakefile +22 -0
- data/app/components/dsfr_component/accordion_component/section_component.html.erb +11 -0
- data/app/components/dsfr_component/accordion_component/section_component.rb +39 -0
- data/app/components/dsfr_component/accordion_component.html.erb +5 -0
- data/app/components/dsfr_component/accordion_component.rb +33 -0
- data/app/components/dsfr_component/alert_component.rb +22 -0
- data/app/components/dsfr_component/back_link_component.rb +24 -0
- data/app/components/dsfr_component/base.rb +28 -0
- data/app/components/dsfr_component/breadcrumbs_component.html.erb +7 -0
- data/app/components/dsfr_component/breadcrumbs_component.rb +51 -0
- data/app/components/dsfr_component/cookie_banner_component/message_component.rb +62 -0
- data/app/components/dsfr_component/cookie_banner_component.rb +35 -0
- data/app/components/dsfr_component/details_component.rb +42 -0
- data/app/components/dsfr_component/footer_component.html.erb +49 -0
- data/app/components/dsfr_component/footer_component.rb +87 -0
- data/app/components/dsfr_component/header_component.html.erb +51 -0
- data/app/components/dsfr_component/header_component.rb +145 -0
- data/app/components/dsfr_component/inset_text_component.rb +28 -0
- data/app/components/dsfr_component/notification_banner_component.html.erb +14 -0
- data/app/components/dsfr_component/notification_banner_component.rb +93 -0
- data/app/components/dsfr_component/pagination_component/adjacent_page.rb +59 -0
- data/app/components/dsfr_component/pagination_component/item.rb +77 -0
- data/app/components/dsfr_component/pagination_component/next_page.rb +27 -0
- data/app/components/dsfr_component/pagination_component/previous_page.rb +21 -0
- data/app/components/dsfr_component/pagination_component.rb +129 -0
- data/app/components/dsfr_component/panel_component.rb +56 -0
- data/app/components/dsfr_component/phase_banner_component.html.erb +6 -0
- data/app/components/dsfr_component/phase_banner_component.rb +25 -0
- data/app/components/dsfr_component/section_break_component.rb +49 -0
- data/app/components/dsfr_component/start_button_component.rb +55 -0
- data/app/components/dsfr_component/summary_list_component/action_component.rb +42 -0
- data/app/components/dsfr_component/summary_list_component/key_component.rb +23 -0
- data/app/components/dsfr_component/summary_list_component/row_component.rb +57 -0
- data/app/components/dsfr_component/summary_list_component/value_component.rb +23 -0
- data/app/components/dsfr_component/summary_list_component.html.erb +5 -0
- data/app/components/dsfr_component/summary_list_component.rb +49 -0
- data/app/components/dsfr_component/tab_component.html.erb +11 -0
- data/app/components/dsfr_component/tab_component.rb +61 -0
- data/app/components/dsfr_component/table_component/body_component.html.erb +5 -0
- data/app/components/dsfr_component/table_component/body_component.rb +21 -0
- data/app/components/dsfr_component/table_component/caption_component.rb +37 -0
- data/app/components/dsfr_component/table_component/cell_component.rb +57 -0
- data/app/components/dsfr_component/table_component/head_component.html.erb +5 -0
- data/app/components/dsfr_component/table_component/head_component.rb +23 -0
- data/app/components/dsfr_component/table_component/row_component.html.erb +5 -0
- data/app/components/dsfr_component/table_component/row_component.rb +30 -0
- data/app/components/dsfr_component/table_component.html.erb +7 -0
- data/app/components/dsfr_component/table_component.rb +35 -0
- data/app/components/dsfr_component/tag_component.rb +44 -0
- data/app/components/dsfr_component/traits/custom_html_attributes.rb +7 -0
- data/app/components/dsfr_component/traits.rb +1 -0
- data/app/components/dsfr_component/warning_text_component.rb +37 -0
- data/app/components/dsfr_component.rb +1 -0
- data/app/helpers/dsfr_back_to_top_link_helper.rb +14 -0
- data/app/helpers/dsfr_components_helper.rb +33 -0
- data/app/helpers/dsfr_link_helper.rb +123 -0
- data/app/helpers/dsfr_skip_link_helper.rb +13 -0
- data/config/routes.rb +2 -0
- data/lib/dsfr/components/engine.rb +110 -0
- data/lib/dsfr/components/helpers/css_utilities.rb +22 -0
- data/lib/dsfr/components/version.rb +5 -0
- data/lib/dsfr/components.rb +6 -0
- data/lib/tasks/dsfr/components_tasks.rake +4 -0
- 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,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,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,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 @@
|
|
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,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
|