dsfr-view-components 0.0.1
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.
- 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,87 @@
|
|
1
|
+
class DsfrComponent::FooterComponent < DsfrComponent::Base
|
2
|
+
using HTMLAttributesUtils
|
3
|
+
|
4
|
+
renders_one :meta_html
|
5
|
+
renders_one :meta
|
6
|
+
renders_one :navigation
|
7
|
+
|
8
|
+
attr_reader :meta_items, :meta_text, :meta_items_title, :meta_licence, :copyright, :custom_container_classes
|
9
|
+
|
10
|
+
def initialize(
|
11
|
+
classes: [],
|
12
|
+
container_classes: [],
|
13
|
+
container_html_attributes: {},
|
14
|
+
copyright_text: config.default_footer_copyright_text,
|
15
|
+
copyright_url: config.default_footer_copyright_url,
|
16
|
+
html_attributes: {},
|
17
|
+
meta_items: {},
|
18
|
+
meta_items_title: "Support links",
|
19
|
+
meta_licence: nil,
|
20
|
+
meta_text: config.default_footer_component_meta_text,
|
21
|
+
meta_classes: [],
|
22
|
+
meta_html_attributes: {}
|
23
|
+
)
|
24
|
+
@meta_text = meta_text
|
25
|
+
@meta_items = build_meta_links(meta_items)
|
26
|
+
@meta_items_title = meta_items_title
|
27
|
+
@meta_licence = meta_licence
|
28
|
+
@custom_meta_classes = meta_classes
|
29
|
+
@custom_meta_html_attributes = meta_html_attributes
|
30
|
+
@copyright = build_copyright(copyright_text, copyright_url)
|
31
|
+
@custom_container_classes = container_classes
|
32
|
+
@custom_container_html_attributes = container_html_attributes
|
33
|
+
|
34
|
+
super(classes: classes, html_attributes: html_attributes)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def default_attributes
|
40
|
+
{ class: %w(govuk-footer) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def meta_content
|
44
|
+
meta_html || meta_text
|
45
|
+
end
|
46
|
+
|
47
|
+
def meta_classes
|
48
|
+
%w(govuk-footer__meta).append(@custom_meta_classes)
|
49
|
+
end
|
50
|
+
|
51
|
+
def meta_html_attributes
|
52
|
+
@custom_meta_html_attributes
|
53
|
+
end
|
54
|
+
|
55
|
+
def container_html_attributes
|
56
|
+
# FIXME: remove when we deprecate classes
|
57
|
+
#
|
58
|
+
# Once we drop classes this extra merging can be dropped along with the
|
59
|
+
# container_classes and meta_classes args
|
60
|
+
{ class: %w(govuk-width-container) }.deep_merge_html_attributes(
|
61
|
+
@custom_container_html_attributes.merge(class: custom_container_classes)
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
def build_meta_links(links)
|
66
|
+
return [] if links.blank?
|
67
|
+
|
68
|
+
case links
|
69
|
+
when Array
|
70
|
+
links.map { |link| raw(link_to(link[:text], link[:href], class: %w(govuk-footer__link), **link.fetch(:attr, {}))) }
|
71
|
+
when Hash
|
72
|
+
links.map { |text, href| raw(link_to(text, href, class: %w(govuk-footer__link))) }
|
73
|
+
else
|
74
|
+
fail(ArgumentError, 'meta links must be a hash or array of hashes') unless links.is_a?(Hash)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def default_licence
|
79
|
+
link = link_to("Open Government Licence v3.0", "https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/", class: %w(govuk-footer__link))
|
80
|
+
|
81
|
+
raw(%(All content is available under the #{link}, except where otherwise stated))
|
82
|
+
end
|
83
|
+
|
84
|
+
def build_copyright(text, url)
|
85
|
+
link_to(text, url, class: %w(govuk-footer__link govuk-footer__copyright-logo))
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<%= tag.header(role: 'banner', data: { module: 'govuk-header' }, **html_attributes) do %>
|
2
|
+
<%= tag.div(**container_html_attributes) do %>
|
3
|
+
<div class="govuk-header__logo">
|
4
|
+
<%= link_to(homepage_url, class: %w(govuk-header__link govuk-header__link--homepage)) do %>
|
5
|
+
<span class="govuk-header__logotype">
|
6
|
+
<% if custom_logo.present? %>
|
7
|
+
<%= custom_logo %>
|
8
|
+
<% else %>
|
9
|
+
<% if crown %>
|
10
|
+
<!--[if gt IE 8]><!-->
|
11
|
+
<svg aria-hidden="true" focusable="false" class="govuk-header__logotype-crown" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 132 97" height="30" width="36">
|
12
|
+
<path fill="currentColor" fill-rule="evenodd" d="M25 30.2c3.5 1.5 7.7-.2 9.1-3.7 1.5-3.6-.2-7.8-3.9-9.2-3.6-1.4-7.6.3-9.1 3.9-1.4 3.5.3 7.5 3.9 9zM9 39.5c3.6 1.5 7.8-.2 9.2-3.7 1.5-3.6-.2-7.8-3.9-9.1-3.6-1.5-7.6.2-9.1 3.8-1.4 3.5.3 7.5 3.8 9zM4.4 57.2c3.5 1.5 7.7-.2 9.1-3.8 1.5-3.6-.2-7.7-3.9-9.1-3.5-1.5-7.6.3-9.1 3.8-1.4 3.5.3 7.6 3.9 9.1zm38.3-21.4c3.5 1.5 7.7-.2 9.1-3.8 1.5-3.6-.2-7.7-3.9-9.1-3.6-1.5-7.6.3-9.1 3.8-1.3 3.6.4 7.7 3.9 9.1zm64.4-5.6c-3.6 1.5-7.8-.2-9.1-3.7-1.5-3.6.2-7.8 3.8-9.2 3.6-1.4 7.7.3 9.2 3.9 1.3 3.5-.4 7.5-3.9 9zm15.9 9.3c-3.6 1.5-7.7-.2-9.1-3.7-1.5-3.6.2-7.8 3.7-9.1 3.6-1.5 7.7.2 9.2 3.8 1.5 3.5-.3 7.5-3.8 9zm4.7 17.7c-3.6 1.5-7.8-.2-9.2-3.8-1.5-3.6.2-7.7 3.9-9.1 3.6-1.5 7.7.3 9.2 3.8 1.3 3.5-.4 7.6-3.9 9.1zM89.3 35.8c-3.6 1.5-7.8-.2-9.2-3.8-1.4-3.6.2-7.7 3.9-9.1 3.6-1.5 7.7.3 9.2 3.8 1.4 3.6-.3 7.7-3.9 9.1zM69.7 17.7l8.9 4.7V9.3l-8.9 2.8c-.2-.3-.5-.6-.9-.9L72.4 0H59.6l3.5 11.2c-.3.3-.6.5-.9.9l-8.8-2.8v13.1l8.8-4.7c.3.3.6.7.9.9l-5 15.4v.1c-.2.8-.4 1.6-.4 2.4 0 4.1 3.1 7.5 7 8.1h.2c.3 0 .7.1 1 .1.4 0 .7 0 1-.1h.2c4-.6 7.1-4.1 7.1-8.1 0-.8-.1-1.7-.4-2.4V34l-5.1-15.4c.4-.2.7-.6 1-.9zM66 92.8c16.9 0 32.8 1.1 47.1 3.2 4-16.9 8.9-26.7 14-33.5l-9.6-3.4c1 4.9 1.1 7.2 0 10.2-1.5-1.4-3-4.3-4.2-8.7L108.6 76c2.8-2 5-3.2 7.5-3.3-4.4 9.4-10 11.9-13.6 11.2-4.3-.8-6.3-4.6-5.6-7.9 1-4.7 5.7-5.9 8-.5 4.3-8.7-3-11.4-7.6-8.8 7.1-7.2 7.9-13.5 2.1-21.1-8 6.1-8.1 12.3-4.5 20.8-4.7-5.4-12.1-2.5-9.5 6.2 3.4-5.2 7.9-2 7.2 3.1-.6 4.3-6.4 7.8-13.5 7.2-10.3-.9-10.9-8-11.2-13.8 2.5-.5 7.1 1.8 11 7.3L80.2 60c-4.1 4.4-8 5.3-12.3 5.4 1.4-4.4 8-11.6 8-11.6H55.5s6.4 7.2 7.9 11.6c-4.2-.1-8-1-12.3-5.4l1.4 16.4c3.9-5.5 8.5-7.7 10.9-7.3-.3 5.8-.9 12.8-11.1 13.8-7.2.6-12.9-2.9-13.5-7.2-.7-5 3.8-8.3 7.1-3.1 2.7-8.7-4.6-11.6-9.4-6.2 3.7-8.5 3.6-14.7-4.6-20.8-5.8 7.6-5 13.9 2.2 21.1-4.7-2.6-11.9.1-7.7 8.8 2.3-5.5 7.1-4.2 8.1.5.7 3.3-1.3 7.1-5.7 7.9-3.5.7-9-1.8-13.5-11.2 2.5.1 4.7 1.3 7.5 3.3l-4.7-15.4c-1.2 4.4-2.7 7.2-4.3 8.7-1.1-3-.9-5.3 0-10.2l-9.5 3.4c5 6.9 9.9 16.7 14 33.5 14.8-2.1 30.8-3.2 47.7-3.2z"></path>
|
13
|
+
</svg>
|
14
|
+
<!--<![endif]-->
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<% if crown_fallback_image_path.present? %>
|
18
|
+
<!--[if IE 8]>
|
19
|
+
<%= image_tag(crown_fallback_image_path, **crown_fallback_image_attributes) %>
|
20
|
+
<![endif]-->
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<%= tag.span(logotype, class: "govuk-header__logotype-text") %>
|
24
|
+
<% end %>
|
25
|
+
</span>
|
26
|
+
<% if product_name.present? %>
|
27
|
+
<%= product_name %>
|
28
|
+
<% end %>
|
29
|
+
<% end %>
|
30
|
+
</div>
|
31
|
+
|
32
|
+
<% if service_name.present? || navigation_items.present? %>
|
33
|
+
<div class="govuk-header__content">
|
34
|
+
<% if service_name.present? %>
|
35
|
+
<%= link_to(service_name, service_url, class: %w(govuk-header__link govuk-header__service-name)) %>
|
36
|
+
<% end %>
|
37
|
+
|
38
|
+
<% if navigation_items.any? %>
|
39
|
+
<%= tag.nav(**navigation_html_attributes) do %>
|
40
|
+
<%= tag.button("Menu", type: "button", class: %w(govuk-header__menu-button govuk-js-header-toggle), hidden: true, aria: { controls: "navigation", label: menu_button_label }) %>
|
41
|
+
<ul id="navigation" class="govuk-header__navigation-list">
|
42
|
+
<% navigation_items.each do |item| %>
|
43
|
+
<%= item %>
|
44
|
+
<% end %>
|
45
|
+
</ul>
|
46
|
+
<% end %>
|
47
|
+
<% end %>
|
48
|
+
</div>
|
49
|
+
<% end %>
|
50
|
+
<% end %>
|
51
|
+
<% end %>
|
@@ -0,0 +1,145 @@
|
|
1
|
+
class DsfrComponent::HeaderComponent < DsfrComponent::Base
|
2
|
+
renders_many :navigation_items, "NavigationItem"
|
3
|
+
renders_one :custom_logo
|
4
|
+
renders_one :product_name, "ProductName"
|
5
|
+
|
6
|
+
attr_reader :logotype,
|
7
|
+
:crown,
|
8
|
+
:crown_fallback_image_path,
|
9
|
+
:homepage_url,
|
10
|
+
:service_name,
|
11
|
+
:service_url,
|
12
|
+
:menu_button_label,
|
13
|
+
:navigation_label,
|
14
|
+
:custom_navigation_classes,
|
15
|
+
:custom_container_classes
|
16
|
+
|
17
|
+
def initialize(classes: [],
|
18
|
+
html_attributes: {},
|
19
|
+
logotype: config.default_header_logotype,
|
20
|
+
crown: true,
|
21
|
+
crown_fallback_image_path: nil,
|
22
|
+
homepage_url: config.default_header_homepage_url,
|
23
|
+
menu_button_label: config.default_header_menu_button_label,
|
24
|
+
navigation_classes: [],
|
25
|
+
navigation_label: config.default_header_navigation_label,
|
26
|
+
service_name: config.default_header_service_name,
|
27
|
+
service_url: config.default_header_service_url,
|
28
|
+
container_classes: nil)
|
29
|
+
|
30
|
+
@logotype = logotype
|
31
|
+
@crown = crown
|
32
|
+
@crown_fallback_image_path = crown_fallback_image_path
|
33
|
+
@homepage_url = homepage_url
|
34
|
+
@service_name = service_name
|
35
|
+
@service_url = service_url
|
36
|
+
@menu_button_label = menu_button_label
|
37
|
+
@custom_navigation_classes = navigation_classes
|
38
|
+
@navigation_label = navigation_label
|
39
|
+
@custom_container_classes = container_classes
|
40
|
+
|
41
|
+
super(classes: classes, html_attributes: html_attributes)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def default_attributes
|
47
|
+
{ class: %w(govuk-header) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def navigation_html_attributes
|
51
|
+
nc = %w(govuk-header__navigation).append(custom_navigation_classes).compact
|
52
|
+
|
53
|
+
{ class: nc, aria: { label: navigation_label } }
|
54
|
+
end
|
55
|
+
|
56
|
+
def container_html_attributes
|
57
|
+
{ class: %w(govuk-header__container govuk-width-container).append(custom_container_classes).compact }
|
58
|
+
end
|
59
|
+
|
60
|
+
def crown_fallback_image_attributes
|
61
|
+
{
|
62
|
+
class: "govuk-header__logotype-crown-fallback-image",
|
63
|
+
width: "36",
|
64
|
+
height: "32",
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
class NavigationItem < DsfrComponent::Base
|
69
|
+
attr_reader :text, :href, :options, :active
|
70
|
+
|
71
|
+
def initialize(text:, href: nil, options: {}, active: nil, classes: [], html_attributes: {})
|
72
|
+
@text = text
|
73
|
+
@href = href
|
74
|
+
@options = options
|
75
|
+
@active_override = active
|
76
|
+
|
77
|
+
super(classes: classes, html_attributes: html_attributes)
|
78
|
+
end
|
79
|
+
|
80
|
+
def before_render
|
81
|
+
if active?
|
82
|
+
html_attributes[:class] << active_class
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def active_class
|
87
|
+
%w(govuk-header__navigation-item--active) if active?
|
88
|
+
end
|
89
|
+
|
90
|
+
def link?
|
91
|
+
href.present?
|
92
|
+
end
|
93
|
+
|
94
|
+
def call
|
95
|
+
tag.li(**html_attributes) do
|
96
|
+
if link?
|
97
|
+
link_to(text, href, class: "govuk-header__link", **options)
|
98
|
+
else
|
99
|
+
text
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def active?
|
107
|
+
return @active_override unless @active_override.nil?
|
108
|
+
return false if href.blank?
|
109
|
+
|
110
|
+
current_page?(href)
|
111
|
+
end
|
112
|
+
|
113
|
+
def default_attributes
|
114
|
+
{ class: %w(govuk-header__navigation-item) }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class ProductName < DsfrComponent::Base
|
119
|
+
attr_reader :name
|
120
|
+
|
121
|
+
def initialize(name: nil, html_attributes: {}, classes: [])
|
122
|
+
@name = name
|
123
|
+
|
124
|
+
super(classes: classes, html_attributes: html_attributes)
|
125
|
+
end
|
126
|
+
|
127
|
+
def render?
|
128
|
+
name.present? || content.present?
|
129
|
+
end
|
130
|
+
|
131
|
+
def call
|
132
|
+
if content.present?
|
133
|
+
tag.div(content, **html_attributes)
|
134
|
+
else
|
135
|
+
tag.span(name, **html_attributes)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def default_attributes
|
142
|
+
{ class: %w(govuk-header__product-name) }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class DsfrComponent::InsetTextComponent < DsfrComponent::Base
|
2
|
+
attr_reader :text, :id
|
3
|
+
|
4
|
+
def initialize(text: nil, id: nil, classes: [], html_attributes: {})
|
5
|
+
@text = text
|
6
|
+
@id = id
|
7
|
+
|
8
|
+
super(classes: classes, html_attributes: html_attributes)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
tag.div(id: id, **html_attributes) { inset_text_content }
|
13
|
+
end
|
14
|
+
|
15
|
+
def render?
|
16
|
+
inset_text_content.present?
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def inset_text_content
|
22
|
+
content.presence || text
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_attributes
|
26
|
+
{ class: %w(govuk-inset-text) }
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<%= tag.div(**html_attributes) do %>
|
2
|
+
<div class="govuk-notification-banner__header">
|
3
|
+
<%= content_tag(title_tag, class: "govuk-notification-banner__title", id: title_id) do %>
|
4
|
+
<%= title_content %>
|
5
|
+
<% end %>
|
6
|
+
</div>
|
7
|
+
<div class="govuk-notification-banner__content">
|
8
|
+
<% headings.each do |heading| %>
|
9
|
+
<%= heading %>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<%= content || text %>
|
13
|
+
</div>
|
14
|
+
<% end %>
|
@@ -0,0 +1,93 @@
|
|
1
|
+
class DsfrComponent::NotificationBannerComponent < DsfrComponent::Base
|
2
|
+
attr_reader :title_text, :title_id, :text, :success, :title_heading_level, :disable_auto_focus, :role
|
3
|
+
|
4
|
+
renders_one :title_html
|
5
|
+
renders_many :headings, "Heading"
|
6
|
+
|
7
|
+
def initialize(
|
8
|
+
title_text: nil,
|
9
|
+
text: nil,
|
10
|
+
role: nil,
|
11
|
+
success: config.default_notification_title_success,
|
12
|
+
title_heading_level: config.default_notification_title_heading_level,
|
13
|
+
title_id: config.default_notification_banner_title_id,
|
14
|
+
disable_auto_focus: config.default_notification_disable_auto_focus,
|
15
|
+
classes: [],
|
16
|
+
html_attributes: {}
|
17
|
+
)
|
18
|
+
@title_text = title_text
|
19
|
+
@title_id = title_id
|
20
|
+
@text = text
|
21
|
+
@success = success
|
22
|
+
@role = role || default_role
|
23
|
+
@title_heading_level = title_heading_level
|
24
|
+
@disable_auto_focus = disable_auto_focus
|
25
|
+
|
26
|
+
super(classes: classes, html_attributes: html_attributes)
|
27
|
+
end
|
28
|
+
|
29
|
+
def render?
|
30
|
+
headings.any? || text.present? || content.present?
|
31
|
+
end
|
32
|
+
|
33
|
+
class Heading < DsfrComponent::Base
|
34
|
+
attr_reader :text, :link_href, :link_text
|
35
|
+
|
36
|
+
def initialize(text: nil, link_text: nil, link_href: nil, classes: [], html_attributes: {})
|
37
|
+
@text = text
|
38
|
+
@link_text = link_text
|
39
|
+
@link_href = link_href
|
40
|
+
|
41
|
+
super(classes: classes, html_attributes: html_attributes)
|
42
|
+
end
|
43
|
+
|
44
|
+
def call
|
45
|
+
tag.div(**html_attributes) do
|
46
|
+
if text.present?
|
47
|
+
safe_join([text, link].compact, " ")
|
48
|
+
else
|
49
|
+
content
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def link
|
55
|
+
link_to(link_text, link_href, class: 'govuk-notification-banner__link') if link_text.present? && link_href.present?
|
56
|
+
end
|
57
|
+
|
58
|
+
def default_attributes
|
59
|
+
{ class: %w(govuk-notification-banner__heading) }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def default_attributes
|
66
|
+
{
|
67
|
+
class: class_names(
|
68
|
+
"govuk-notification-banner",
|
69
|
+
"govuk-notification-banner--success" => success
|
70
|
+
),
|
71
|
+
data: {
|
72
|
+
"module" => "govuk-notification-banner",
|
73
|
+
"disable-auto-focus" => disable_auto_focus
|
74
|
+
},
|
75
|
+
role: role,
|
76
|
+
aria: { labelledby: title_id },
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def title_content
|
81
|
+
title_html || title_text
|
82
|
+
end
|
83
|
+
|
84
|
+
def title_tag
|
85
|
+
fail "title_heading_level must be a number between 1 and 6" unless title_heading_level.is_a?(Integer) && title_heading_level.in?(1..6)
|
86
|
+
|
87
|
+
"h#{title_heading_level}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def default_role
|
91
|
+
success ? "alert" : "region"
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class DsfrComponent::PaginationComponent::AdjacentPage < DsfrComponent::Base
|
2
|
+
attr_reader :href, :label_text, :text, :suffix, :block_mode, :visually_hidden_text
|
3
|
+
alias_method :block_mode?, :block_mode
|
4
|
+
|
5
|
+
def initialize(href:, suffix:, text:, block_mode: true, label_text: nil, classes: [], html_attributes: {})
|
6
|
+
@href = href
|
7
|
+
@label_text = label_text
|
8
|
+
@text = text
|
9
|
+
@block_mode = block_mode
|
10
|
+
@suffix = suffix
|
11
|
+
|
12
|
+
super(html_attributes: html_attributes, classes: classes)
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
tag.div(**html_attributes) do
|
17
|
+
tag.a(href: href, class: %w(fr-link govuk-pagination__link), rel: suffix) do
|
18
|
+
safe_join([body, divider, label_content])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def default_attributes
|
26
|
+
{ class: ["govuk-pagination__#{suffix}"] }
|
27
|
+
end
|
28
|
+
|
29
|
+
def body
|
30
|
+
[arrow, title_span]
|
31
|
+
end
|
32
|
+
|
33
|
+
def title_span
|
34
|
+
tag.span(text, class: title_classes)
|
35
|
+
end
|
36
|
+
|
37
|
+
def divider
|
38
|
+
return if label_text.blank?
|
39
|
+
|
40
|
+
tag.span(":", class: %w(govuk-visually-hidden))
|
41
|
+
end
|
42
|
+
|
43
|
+
def label_content
|
44
|
+
return if label_text.blank?
|
45
|
+
|
46
|
+
tag.span(label_text, class: label_classes)
|
47
|
+
end
|
48
|
+
|
49
|
+
def title_classes
|
50
|
+
class_names(
|
51
|
+
%(govuk-pagination__link-title),
|
52
|
+
%(govuk-pagination__link-title--decorated) => label_text.blank?
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def label_classes
|
57
|
+
%w(govuk-pagination__link-label)
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
class DsfrComponent::PaginationComponent::Item < DsfrComponent::Base
|
2
|
+
attr_reader :number, :href, :visually_hidden_text, :mode
|
3
|
+
|
4
|
+
def initialize(number: nil, href: nil, current: false, ellipsis: false, from_pagy: false, visually_hidden_text: nil, classes: [], html_attributes: {})
|
5
|
+
@number = number
|
6
|
+
@href = href
|
7
|
+
@visually_hidden_text = visually_hidden_text
|
8
|
+
|
9
|
+
# We have three modes for rendering links:
|
10
|
+
#
|
11
|
+
# * link (a link to another page)
|
12
|
+
# * current (a link to the current page)
|
13
|
+
# * gap (an ellipsis symbol)
|
14
|
+
#
|
15
|
+
# Pagy sets these by object type:
|
16
|
+
# Integer = link
|
17
|
+
# String = current
|
18
|
+
# :gap = gap
|
19
|
+
#
|
20
|
+
# The original Nunjucks component has two boolean settings instead,
|
21
|
+
# ellipsis and current. When ellipsis is true all other arguments are
|
22
|
+
# ignored
|
23
|
+
@mode = from_pagy ? pagy_mode(number) : manual_mode(ellipsis, current)
|
24
|
+
|
25
|
+
super(classes: classes, html_attributes: html_attributes)
|
26
|
+
end
|
27
|
+
|
28
|
+
def call
|
29
|
+
case mode
|
30
|
+
when :link
|
31
|
+
link(current: false)
|
32
|
+
when :current
|
33
|
+
link(current: true)
|
34
|
+
when :gap
|
35
|
+
ellipsis_item
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def pagy_mode(number)
|
42
|
+
return :link if number.is_a?(Integer)
|
43
|
+
return :current if number.is_a?(String)
|
44
|
+
|
45
|
+
:gap
|
46
|
+
end
|
47
|
+
|
48
|
+
def manual_mode(ellipsis, current)
|
49
|
+
return :gap if ellipsis
|
50
|
+
return :current if current
|
51
|
+
|
52
|
+
:link
|
53
|
+
end
|
54
|
+
|
55
|
+
def link(current: false)
|
56
|
+
attributes = html_attributes.tap { |ha| ha[:class] << "govuk-pagination__item--current" if current }
|
57
|
+
|
58
|
+
tag.li(**attributes) do
|
59
|
+
tag.a(href: href, class: %w(fr-link govuk-pagination__link)) { number.to_s }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def ellipsis_item
|
64
|
+
tag.li("⋯", class: %w(govuk-pagination__item govuk-pagination__item--ellipses))
|
65
|
+
end
|
66
|
+
|
67
|
+
def default_attributes
|
68
|
+
{
|
69
|
+
class: %w(govuk-pagination__item),
|
70
|
+
aria: { label: aria_label }
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
def aria_label
|
75
|
+
visually_hidden_text || "Page #{number}"
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class DsfrComponent::PaginationComponent::NextPage < DsfrComponent::PaginationComponent::AdjacentPage
|
2
|
+
def initialize(href:, text:, label_text: nil, block_mode: true, classes: [], html_attributes: {})
|
3
|
+
super(
|
4
|
+
suffix: "next",
|
5
|
+
text: text,
|
6
|
+
href: href,
|
7
|
+
label_text: label_text,
|
8
|
+
block_mode: block_mode,
|
9
|
+
classes: classes,
|
10
|
+
html_attributes: html_attributes
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def body
|
15
|
+
return [arrow, title_span] if block_mode?
|
16
|
+
|
17
|
+
[title_span, arrow]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def arrow
|
23
|
+
tag.svg(class: "govuk-pagination__icon govuk-pagination__icon--next", xmlns: "http://www.w3.org/2000/svg", height: "13", width: "15", focusable: "false", viewBox: "0 0 15 13", aria: { hidden: "true" }) do
|
24
|
+
tag.path(d: "m8.107-0.0078125-1.4136 1.414 4.2926 4.293h-12.986v2h12.896l-4.1855 3.9766 1.377 1.4492 6.7441-6.4062-6.7246-6.7266z")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class DsfrComponent::PaginationComponent::PreviousPage < DsfrComponent::PaginationComponent::AdjacentPage
|
2
|
+
def initialize(href:, text:, label_text: nil, block_mode: true, classes: [], html_attributes: {})
|
3
|
+
super(
|
4
|
+
suffix: "prev",
|
5
|
+
text: text,
|
6
|
+
href: href,
|
7
|
+
label_text: label_text,
|
8
|
+
block_mode: block_mode,
|
9
|
+
classes: classes,
|
10
|
+
html_attributes: html_attributes
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def arrow
|
17
|
+
tag.svg(class: "govuk-pagination__icon govuk-pagination__icon--prev", xmlns: "http://www.w3.org/2000/svg", height: "13", width: "15", focusable: "false", viewBox: "0 0 15 13", aria: { hidden: "true" }) do
|
18
|
+
tag.path(d: "m6.5938-0.0078125-6.7266 6.7266 6.7441 6.4062 1.377-1.449-4.1856-3.9768h12.896v-2h-12.984l4.2931-4.293-1.414-1.414z")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|