design_system 0.13.2 → 0.15.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.
- checksums.yaml +4 -4
- data/README.md +36 -3
- data/app/assets/stylesheets/design_system/_hljs.scss +131 -0
- data/app/assets/stylesheets/design_system/govuk.scss +43 -0
- data/app/assets/stylesheets/design_system/nhsuk.scss +55 -0
- data/app/components/design_system/base_component.rb +21 -0
- data/app/components/design_system/generic/action_link_component.rb +17 -0
- data/app/components/design_system/generic/alert_component.rb +25 -0
- data/app/components/design_system/generic/breadcrumbs_component.rb +18 -0
- data/app/components/design_system/generic/button_component.rb +51 -0
- data/app/components/design_system/generic/callout_component.html.erb +8 -0
- data/app/components/design_system/generic/callout_component.rb +15 -0
- data/app/components/design_system/generic/details_component.html.erb +4 -0
- data/app/components/design_system/generic/details_component.rb +13 -0
- data/app/components/design_system/generic/grid_component.html.erb +5 -0
- data/app/components/design_system/generic/grid_component.rb +31 -0
- data/app/components/design_system/generic/heading_component.rb +41 -0
- data/app/components/design_system/generic/inset_text_component.html.erb +1 -0
- data/app/components/design_system/generic/inset_text_component.rb +24 -0
- data/app/components/design_system/generic/link_component.rb +51 -0
- data/app/components/design_system/generic/list_component.html.erb +7 -0
- data/app/components/design_system/generic/list_component.rb +26 -0
- data/app/components/design_system/generic/notification_component.html.erb +15 -0
- data/app/components/design_system/generic/notification_component.rb +39 -0
- data/app/components/design_system/generic/panel_component.html.erb +4 -0
- data/app/components/design_system/generic/panel_component.rb +18 -0
- data/app/components/design_system/generic/paragraph_component.rb +46 -0
- data/app/components/design_system/generic/start_button_component.html.erb +4 -0
- data/app/components/design_system/generic/start_button_component.rb +17 -0
- data/app/components/design_system/generic/summary_card_component.html.erb +15 -0
- data/app/components/design_system/generic/summary_card_component.rb +40 -0
- data/app/components/design_system/generic/summary_list_component.html.erb +21 -0
- data/app/components/design_system/generic/summary_list_component.rb +59 -0
- data/app/components/design_system/generic/tab_component.html.erb +21 -0
- data/app/components/design_system/generic/tab_component.rb +14 -0
- data/app/components/design_system/generic/table_component.rb +46 -0
- data/app/components/design_system/govuk/action_link_component.html.erb +1 -0
- data/app/components/design_system/govuk/action_link_component.rb +8 -0
- data/app/components/design_system/govuk/alert_component.rb +6 -0
- data/app/components/design_system/govuk/breadcrumbs_component.html.erb +11 -0
- data/app/components/design_system/govuk/breadcrumbs_component.rb +7 -0
- data/app/components/design_system/govuk/button_component.rb +6 -0
- data/app/components/design_system/govuk/callout_component.html.erb +6 -0
- data/app/components/design_system/govuk/callout_component.rb +6 -0
- data/app/components/design_system/govuk/details_component.rb +6 -0
- data/app/components/design_system/govuk/grid_component.rb +6 -0
- data/app/components/design_system/govuk/heading_component.rb +6 -0
- data/app/components/design_system/govuk/inset_text_component.rb +6 -0
- data/app/components/design_system/govuk/link_component.rb +17 -0
- data/app/components/design_system/govuk/list_component.rb +6 -0
- data/app/components/design_system/govuk/notification_component.rb +6 -0
- data/app/components/design_system/govuk/panel_component.rb +10 -0
- data/app/components/design_system/govuk/paragraph_component.rb +6 -0
- data/app/components/design_system/govuk/start_button_component.rb +6 -0
- data/app/components/design_system/govuk/summary_card_component.html.erb +15 -0
- data/app/components/design_system/govuk/summary_card_component.rb +13 -0
- data/app/components/design_system/govuk/summary_list_component.rb +6 -0
- data/app/components/design_system/govuk/tab_component.rb +6 -0
- data/app/components/design_system/govuk/table_component.html.erb +30 -0
- data/app/components/design_system/govuk/table_component.rb +6 -0
- data/app/components/design_system/nhsuk/action_link_component.html.erb +7 -0
- data/app/components/design_system/nhsuk/action_link_component.rb +7 -0
- data/app/components/design_system/nhsuk/alert_component.rb +6 -0
- data/app/components/design_system/nhsuk/breadcrumbs_component.html.erb +16 -0
- data/app/components/design_system/nhsuk/breadcrumbs_component.rb +7 -0
- data/app/components/design_system/nhsuk/button_component.rb +6 -0
- data/app/components/design_system/nhsuk/callout_component.rb +6 -0
- data/app/components/design_system/nhsuk/details_component.rb +6 -0
- data/app/components/design_system/nhsuk/grid_component.rb +6 -0
- data/app/components/design_system/nhsuk/heading_component.rb +6 -0
- data/app/components/design_system/nhsuk/inset_text_component.html.erb +4 -0
- data/app/components/design_system/nhsuk/inset_text_component.rb +6 -0
- data/app/components/design_system/nhsuk/link_component.rb +17 -0
- data/app/components/design_system/nhsuk/list_component.rb +6 -0
- data/app/components/design_system/nhsuk/notification_component.rb +6 -0
- data/app/components/design_system/nhsuk/panel_component.rb +6 -0
- data/app/components/design_system/nhsuk/paragraph_component.rb +6 -0
- data/app/components/design_system/nhsuk/start_button_component.rb +6 -0
- data/app/components/design_system/nhsuk/summary_card_component.rb +6 -0
- data/app/components/design_system/nhsuk/summary_list_component.rb +19 -0
- data/app/components/design_system/nhsuk/tab_component.rb +6 -0
- data/app/components/design_system/nhsuk/table_component.html.erb +43 -0
- data/app/components/design_system/nhsuk/table_component.rb +6 -0
- data/app/controllers/concerns/design_system/branded.rb +6 -0
- data/app/helpers/design_system_helper.rb +65 -27
- data/app/javascript/design_system/controllers/clipboard_controller.js +41 -0
- data/app/javascript/design_system/controllers/code_highlight_controller.js +9 -0
- data/app/javascript/design_system/controllers/hello_world_controller.js +6 -0
- data/app/javascript/design_system/index.js +4 -0
- data/app/views/layouts/govuk/application.html.erb +20 -7
- data/app/views/layouts/nhsuk/application.html.erb +10 -7
- data/lib/design_system/brand_derivable.rb +9 -0
- data/lib/design_system/engine.rb +1 -0
- data/lib/design_system/generic/builders/base.rb +1 -1
- data/lib/design_system/generic/builders/code.rb +23 -0
- data/lib/design_system/generic/builders/elements/breadcrumbs.rb +4 -24
- data/lib/design_system/generic/builders/elements/headings.rb +3 -2
- data/lib/design_system/generic/builders/pagination_renderer.rb +5 -4
- data/lib/design_system/generic.rb +1 -14
- data/lib/design_system/govuk/builders/code.rb +11 -0
- data/lib/design_system/govuk/builders/fixed_elements.rb +0 -1
- data/lib/design_system/govuk.rb +1 -12
- data/lib/design_system/nhsuk/builders/code.rb +11 -0
- data/lib/design_system/nhsuk/builders/fixed_elements.rb +0 -1
- data/lib/design_system/nhsuk.rb +1 -12
- data/lib/design_system/registry.rb +19 -1
- data/lib/design_system/version.rb +1 -1
- data/public/design_system/static/design_system-0.15.0/design_system.js +53150 -0
- metadata +101 -50
- data/lib/design_system/generic/builders/action_link.rb +0 -17
- data/lib/design_system/generic/builders/button.rb +0 -33
- data/lib/design_system/generic/builders/callout.rb +0 -28
- data/lib/design_system/generic/builders/concerns/brand_derivable.rb +0 -14
- data/lib/design_system/generic/builders/details.rb +0 -30
- data/lib/design_system/generic/builders/grid.rb +0 -44
- data/lib/design_system/generic/builders/heading.rb +0 -38
- data/lib/design_system/generic/builders/inset_text.rb +0 -18
- data/lib/design_system/generic/builders/link.rb +0 -44
- data/lib/design_system/generic/builders/list.rb +0 -41
- data/lib/design_system/generic/builders/notification.rb +0 -68
- data/lib/design_system/generic/builders/panel.rb +0 -18
- data/lib/design_system/generic/builders/paragraph.rb +0 -28
- data/lib/design_system/generic/builders/summary_list.rb +0 -89
- data/lib/design_system/generic/builders/tab.rb +0 -14
- data/lib/design_system/generic/builders/table.rb +0 -73
- data/lib/design_system/govuk/builders/action_link.rb +0 -17
- data/lib/design_system/govuk/builders/button.rb +0 -55
- data/lib/design_system/govuk/builders/callout.rb +0 -26
- data/lib/design_system/govuk/builders/details.rb +0 -10
- data/lib/design_system/govuk/builders/elements/breadcrumbs.rb +0 -33
- data/lib/design_system/govuk/builders/grid.rb +0 -12
- data/lib/design_system/govuk/builders/heading.rb +0 -11
- data/lib/design_system/govuk/builders/inset_text.rb +0 -11
- data/lib/design_system/govuk/builders/link.rb +0 -21
- data/lib/design_system/govuk/builders/list.rb +0 -11
- data/lib/design_system/govuk/builders/notification.rb +0 -11
- data/lib/design_system/govuk/builders/panel.rb +0 -18
- data/lib/design_system/govuk/builders/paragraph.rb +0 -11
- data/lib/design_system/govuk/builders/summary_list.rb +0 -32
- data/lib/design_system/govuk/builders/tab.rb +0 -54
- data/lib/design_system/govuk/builders/table.rb +0 -77
- data/lib/design_system/nhsuk/builders/action_link.rb +0 -30
- data/lib/design_system/nhsuk/builders/button.rb +0 -11
- data/lib/design_system/nhsuk/builders/callout.rb +0 -11
- data/lib/design_system/nhsuk/builders/details.rb +0 -10
- data/lib/design_system/nhsuk/builders/elements/breadcrumbs.rb +0 -43
- data/lib/design_system/nhsuk/builders/grid.rb +0 -12
- data/lib/design_system/nhsuk/builders/heading.rb +0 -11
- data/lib/design_system/nhsuk/builders/inset_text.rb +0 -23
- data/lib/design_system/nhsuk/builders/link.rb +0 -21
- data/lib/design_system/nhsuk/builders/list.rb +0 -11
- data/lib/design_system/nhsuk/builders/notification.rb +0 -11
- data/lib/design_system/nhsuk/builders/panel.rb +0 -11
- data/lib/design_system/nhsuk/builders/paragraph.rb +0 -11
- data/lib/design_system/nhsuk/builders/summary_list.rb +0 -18
- data/lib/design_system/nhsuk/builders/tab.rb +0 -11
- data/lib/design_system/nhsuk/builders/table.rb +0 -68
- data/public/design_system/static/design_system-0.13.2/design_system.js +0 -1309
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module DesignSystem
|
|
2
|
+
module Generic
|
|
3
|
+
# Plain, bullet, or numbered list rendered by ds_list.
|
|
4
|
+
class ListComponent < DesignSystem::BaseComponent
|
|
5
|
+
def initialize(list:, type: :default, **options)
|
|
6
|
+
super()
|
|
7
|
+
@list = list
|
|
8
|
+
@type = type.to_sym
|
|
9
|
+
@options = options
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attr_reader :list, :type, :options
|
|
13
|
+
|
|
14
|
+
def tag_name
|
|
15
|
+
type == :number ? :ol : :ul
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def list_options
|
|
19
|
+
classes = ["#{brand}-list"]
|
|
20
|
+
classes << "#{brand}-list--bullet" if type == :bullet
|
|
21
|
+
classes << "#{brand}-list--number" if type == :number
|
|
22
|
+
css_class_options_merge(options, classes)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<% success = type == :success %>
|
|
2
|
+
<div class="<%= brand %>-notification-banner<%= " #{brand}-notification-banner--success" if success %>"
|
|
3
|
+
role="<%= success ? 'alert' : 'region' %>"
|
|
4
|
+
aria-labelledby="<%= brand %>-notification-banner-title"
|
|
5
|
+
data-module="<%= brand %>-notification-banner">
|
|
6
|
+
<div class="<%= brand %>-notification-banner__header">
|
|
7
|
+
<h2 class="<%= brand %>-notification-banner__title" id="<%= brand %>-notification-banner-title"><%= success ? 'Success' : 'Important' %></h2>
|
|
8
|
+
</div>
|
|
9
|
+
<div class="<%= brand %>-notification-banner__content">
|
|
10
|
+
<% if heading_text.present? %>
|
|
11
|
+
<%= content_tag(heading_tag, heading_text, class: "#{brand}-notification-banner__heading") %>
|
|
12
|
+
<% end %>
|
|
13
|
+
<%= body %>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module DesignSystem
|
|
2
|
+
module Generic
|
|
3
|
+
# Notification banner rendered by ds_notice. Shows an "Important"/"Success"
|
|
4
|
+
# header followed by a content area with an optional heading and the
|
|
5
|
+
# message (or block) body.
|
|
6
|
+
class NotificationComponent < DesignSystem::BaseComponent
|
|
7
|
+
TYPES = %i[information success].freeze
|
|
8
|
+
HEADING_TAGS = %i[h3 p].freeze
|
|
9
|
+
|
|
10
|
+
def initialize(message: nil, type: :information, content_heading: {})
|
|
11
|
+
super()
|
|
12
|
+
@message = message
|
|
13
|
+
@type = type
|
|
14
|
+
@content_heading = content_heading || {}
|
|
15
|
+
|
|
16
|
+
return if TYPES.include?(type)
|
|
17
|
+
|
|
18
|
+
raise ArgumentError, "Invalid notification type: #{type}. Must be one of: #{TYPES.join(', ')}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
attr_reader :message, :type, :content_heading
|
|
22
|
+
|
|
23
|
+
def heading_tag
|
|
24
|
+
tag = content_heading.fetch(:tag, :h3)
|
|
25
|
+
raise ArgumentError, "Invalid content_heading tag: #{tag}." unless HEADING_TAGS.include?(tag)
|
|
26
|
+
|
|
27
|
+
tag
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def heading_text
|
|
31
|
+
content_heading[:text]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def body
|
|
35
|
+
content.presence || message
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module DesignSystem
|
|
2
|
+
module Generic
|
|
3
|
+
# Confirmation/transaction panel rendered by ds_panel.
|
|
4
|
+
class PanelComponent < DesignSystem::BaseComponent
|
|
5
|
+
def initialize(title:, body:)
|
|
6
|
+
super()
|
|
7
|
+
@title = title
|
|
8
|
+
@body = body
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_reader :title, :body
|
|
12
|
+
|
|
13
|
+
def panel_classes
|
|
14
|
+
["#{brand}-panel"]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module DesignSystem
|
|
2
|
+
module Generic
|
|
3
|
+
# Body paragraph with typography styling, rendered by ds_paragraph.
|
|
4
|
+
# Content can be passed as the `text` argument or as a block. An optional
|
|
5
|
+
# `size` selects a smaller body style.
|
|
6
|
+
class ParagraphComponent < DesignSystem::BaseComponent
|
|
7
|
+
FONT_SIZES = %i[s].freeze
|
|
8
|
+
|
|
9
|
+
def initialize(text: nil, size: nil, **options)
|
|
10
|
+
super()
|
|
11
|
+
@text = text
|
|
12
|
+
@size = size
|
|
13
|
+
@options = options
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_reader :text, :size, :options
|
|
17
|
+
|
|
18
|
+
# Renders nothing when neither block content nor text is supplied,
|
|
19
|
+
# matching the previous builder behaviour.
|
|
20
|
+
def render?
|
|
21
|
+
body.present?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def call
|
|
25
|
+
content_tag(:p, body, **paragraph_options)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def body
|
|
31
|
+
content.presence || text
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def paragraph_options
|
|
35
|
+
{ class: classes }.merge(options)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def classes
|
|
39
|
+
return "#{brand}-body" if size.nil?
|
|
40
|
+
raise ArgumentError, "Invalid size: #{size}" unless size.in?(FONT_SIZES)
|
|
41
|
+
|
|
42
|
+
"#{brand}-body-#{size}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<%= content_tag(:a, href: href, class: "#{brand}-button #{brand}-button--start",
|
|
2
|
+
role: 'button', draggable: 'false', **options) do %>
|
|
3
|
+
<span class="<%= brand %>-button-text"><%= text %></span><svg class="<%= brand %>-button__start-icon" xmlns="http://www.w3.org/2000/svg" width="17.5" height="19" viewBox="0 0 33 40" aria-hidden="true" focusable="false"><path fill="currentColor" d="M0 0h13l20 20-20 20H0l20-20z"></path></svg>
|
|
4
|
+
<% end %>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module DesignSystem
|
|
2
|
+
module Generic
|
|
3
|
+
# The "start a service" CTA. GOV.UK defined the pattern and NHS adopted it
|
|
4
|
+
# unchanged — both brands ship identical markup with only the brand-derived
|
|
5
|
+
# CSS prefix differing, so the implementation lives here.
|
|
6
|
+
class StartButtonComponent < DesignSystem::BaseComponent
|
|
7
|
+
def initialize(text, href, options = {})
|
|
8
|
+
super()
|
|
9
|
+
@text = text
|
|
10
|
+
@href = href
|
|
11
|
+
@options = options.merge('data-module': "#{brand}-button")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_reader :text, :href, :options
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<div class="<%= brand %>-card">
|
|
2
|
+
<div class="<%= brand %>-card__heading-container">
|
|
3
|
+
<%= ds_heading(title, class: "#{brand}-card__heading #{brand}-heading-m") %>
|
|
4
|
+
<% if actions.any? %>
|
|
5
|
+
<ul class="<%= brand %>-card__actions">
|
|
6
|
+
<% actions.each do |action| %>
|
|
7
|
+
<li class="<%= brand %>-card__action"><%= render_action(action) %></li>
|
|
8
|
+
<% end %>
|
|
9
|
+
</ul>
|
|
10
|
+
<% end %>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="<%= brand %>-card__content">
|
|
13
|
+
<%= content %>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module DesignSystem
|
|
2
|
+
module Generic
|
|
3
|
+
# Card that groups a titled summary list (or any content) with optional
|
|
4
|
+
# actions, rendered by ds_summary_card. The GOV.UK brand renders a
|
|
5
|
+
# summary-card variant via its own subclass and template.
|
|
6
|
+
#
|
|
7
|
+
# Each action is a hash of { text:, href:, hidden_text: }, where
|
|
8
|
+
# hidden_text is appended in a visually hidden span to give the link an
|
|
9
|
+
# accessible, unambiguous name (e.g. " (Karen Francis)").
|
|
10
|
+
class SummaryCardComponent < DesignSystem::BaseComponent
|
|
11
|
+
include DesignSystemHelper
|
|
12
|
+
|
|
13
|
+
def initialize(title:, actions: [])
|
|
14
|
+
super()
|
|
15
|
+
@title = title
|
|
16
|
+
@actions = Array(actions)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
attr_reader :title, :actions
|
|
20
|
+
|
|
21
|
+
def render_action(action)
|
|
22
|
+
link_to(action[:href] || '#', class: "#{brand}-link") do
|
|
23
|
+
safe_join([action[:text], render_hidden_text(action[:hidden_text])])
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def render_hidden_text(hidden_text)
|
|
30
|
+
return '' if hidden_text.blank?
|
|
31
|
+
|
|
32
|
+
content_tag(:span, hidden_text, class: visually_hidden_class)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def visually_hidden_class
|
|
36
|
+
"#{brand}-u-visually-hidden"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<dl class="<%= brand %>-summary-list">
|
|
2
|
+
<% summary_list.rows.each do |row| %>
|
|
3
|
+
<div class="<%= brand %>-summary-list__row<%= " #{brand}-summary-list__row--no-actions" if row[:actions].blank? %>">
|
|
4
|
+
<dt class="<%= brand %>-summary-list__key"><%= row[:key][:content] %></dt>
|
|
5
|
+
<dd class="<%= brand %>-summary-list__value"><%= value_content(row) %></dd>
|
|
6
|
+
<% if row[:actions].present? %>
|
|
7
|
+
<dd class="<%= brand %>-summary-list__actions">
|
|
8
|
+
<% if row[:actions].length == 1 %>
|
|
9
|
+
<%= render_action(row[:actions].first) %>
|
|
10
|
+
<% else %>
|
|
11
|
+
<ul class="<%= brand %>-summary-list__actions-list">
|
|
12
|
+
<% row[:actions].each do |action| %>
|
|
13
|
+
<li class="<%= brand %>-summary-list__actions-list-item"><%= render_action(action) %></li>
|
|
14
|
+
<% end %>
|
|
15
|
+
</ul>
|
|
16
|
+
<% end %>
|
|
17
|
+
</dd>
|
|
18
|
+
<% end %>
|
|
19
|
+
</div>
|
|
20
|
+
<% end %>
|
|
21
|
+
</dl>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module DesignSystem
|
|
2
|
+
module Generic
|
|
3
|
+
# Summary list (dl) rendered by ds_summary_list. Each row has a key, one
|
|
4
|
+
# or more values, and optional actions. Brands override paragraph class
|
|
5
|
+
# and hidden text via subclasses.
|
|
6
|
+
class SummaryListComponent < DesignSystem::BaseComponent
|
|
7
|
+
def initialize(summary_list:)
|
|
8
|
+
super()
|
|
9
|
+
@summary_list = summary_list
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attr_reader :summary_list
|
|
13
|
+
|
|
14
|
+
def value_content(row)
|
|
15
|
+
if row[:values].blank?
|
|
16
|
+
''
|
|
17
|
+
elsif row[:values].length == 1
|
|
18
|
+
wrap_value(row[:values].first)
|
|
19
|
+
else
|
|
20
|
+
safe_join(row[:values].map { |value| wrap_value(value, paragraph: true) })
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def render_action(action)
|
|
25
|
+
options = action[:options].dup
|
|
26
|
+
path = options.delete(:path) || '#'
|
|
27
|
+
hidden_text = options.delete(:hidden_text)
|
|
28
|
+
|
|
29
|
+
link_to(path, { class: "#{brand}-link" }.merge(options)) do
|
|
30
|
+
safe_join([action[:content], render_hidden_text(hidden_text)])
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def wrap_value(value, paragraph: false)
|
|
35
|
+
content = if value[:options]&.dig(:path)
|
|
36
|
+
link_to(value[:content], value[:options][:path] || '#', class: "#{brand}-link")
|
|
37
|
+
else
|
|
38
|
+
value[:content]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
return content unless paragraph
|
|
42
|
+
|
|
43
|
+
content_tag(:p, content, class: value_paragraph_class)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def value_paragraph_class
|
|
49
|
+
"#{brand}-body"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def render_hidden_text(hidden_text)
|
|
53
|
+
return '' if hidden_text.blank?
|
|
54
|
+
|
|
55
|
+
content_tag(:span, hidden_text, class: "#{brand}-visually-hidden")
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<div class="<%= brand %>-tabs" data-module="<%= brand %>-tabs">
|
|
2
|
+
<% if tab.title %>
|
|
3
|
+
<h2 class="<%= brand %>-tabs__title"><%= tab.title %></h2>
|
|
4
|
+
<% end %>
|
|
5
|
+
|
|
6
|
+
<% if tab.tabs.present? %>
|
|
7
|
+
<ul class="<%= brand %>-tabs__list">
|
|
8
|
+
<% tab.tabs.each do |name, _content, id, selected| %>
|
|
9
|
+
<li class="<%= brand %>-tabs__list-item<%= " #{brand}-tabs__list-item--selected" if selected %>">
|
|
10
|
+
<a class="<%= brand %>-tabs__tab" href="#<%= id %>"><%= name %></a>
|
|
11
|
+
</li>
|
|
12
|
+
<% end %>
|
|
13
|
+
</ul>
|
|
14
|
+
|
|
15
|
+
<% tab.tabs.each do |_name, content, id, selected| %>
|
|
16
|
+
<div class="<%= brand %>-tabs__panel<%= " #{brand}-tabs__panel--hidden" unless selected %>" id="<%= id %>">
|
|
17
|
+
<%= content %>
|
|
18
|
+
</div>
|
|
19
|
+
<% end %>
|
|
20
|
+
<% end %>
|
|
21
|
+
</div>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module DesignSystem
|
|
2
|
+
module Generic
|
|
3
|
+
# Tabs rendered by ds_tab: a list of tab links followed by their panels,
|
|
4
|
+
# with the selected panel visible. Brand subclasses inherit unchanged.
|
|
5
|
+
class TabComponent < DesignSystem::BaseComponent
|
|
6
|
+
def initialize(tab:)
|
|
7
|
+
super()
|
|
8
|
+
@tab = tab
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_reader :tab
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module DesignSystem
|
|
2
|
+
module Generic
|
|
3
|
+
# Table rendered by ds_table. Wraps a caption, header row and body rows
|
|
4
|
+
# built via the Table data object. Brands override markup via their own
|
|
5
|
+
# templates; cell helpers live here for reuse.
|
|
6
|
+
class TableComponent < DesignSystem::BaseComponent
|
|
7
|
+
def initialize(table:, **options)
|
|
8
|
+
super()
|
|
9
|
+
@table = table
|
|
10
|
+
@options = options
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
attr_reader :table, :options
|
|
14
|
+
|
|
15
|
+
def cell_content(cell)
|
|
16
|
+
if cell[:content].is_a?(Numeric)
|
|
17
|
+
cell[:content].to_s
|
|
18
|
+
elsif cell[:content].is_a?(Proc)
|
|
19
|
+
capture(&cell[:content])
|
|
20
|
+
else
|
|
21
|
+
cell[:content]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def cell_numeric?(cell)
|
|
26
|
+
cell[:options][:type] == 'numeric'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def html_cell_options(cell, **extra)
|
|
30
|
+
cell[:options].except(:type).merge(extra)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def header_classes(cell)
|
|
34
|
+
classes = "#{brand}-table__header"
|
|
35
|
+
classes += " #{brand}-table__header--numeric" if cell_numeric?(cell)
|
|
36
|
+
classes
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def data_cell_classes(cell)
|
|
40
|
+
classes = "#{brand}-table__cell"
|
|
41
|
+
classes += " #{brand}-table__cell--numeric" if cell_numeric?(cell)
|
|
42
|
+
classes
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= link_to name, options, html_options.merge(class: "#{brand}-button") %>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<nav class="<%= brand %>-breadcrumbs" aria-label="Breadcrumb">
|
|
2
|
+
<ol class="<%= brand %>-breadcrumbs__list">
|
|
3
|
+
<% breadcrumbs.each do |breadcrumb| %>
|
|
4
|
+
<li class="<%= brand %>-breadcrumbs__list-item">
|
|
5
|
+
<%= link_to breadcrumb[:label], breadcrumb[:path],
|
|
6
|
+
class: "#{brand}-breadcrumbs__link",
|
|
7
|
+
'aria-current': current_page_aria(breadcrumb) %>
|
|
8
|
+
</li>
|
|
9
|
+
<% end %>
|
|
10
|
+
</ol>
|
|
11
|
+
</nav>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<div class="<%= brand %>-warning-text">
|
|
2
|
+
<span class="<%= brand %>-warning-text__icon" aria-hidden="true">!</span>
|
|
3
|
+
<strong class="<%= brand %>-warning-text__text">
|
|
4
|
+
<span class="<%= brand %>-visually-hidden">Warning</span><%= label %> <%= body %>
|
|
5
|
+
</strong>
|
|
6
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module DesignSystem
|
|
2
|
+
module Govuk
|
|
3
|
+
# GOV.UK link: maps button :type values to govuk-button style classes.
|
|
4
|
+
class LinkComponent < DesignSystem::Generic::LinkComponent
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def button_type_class_hash
|
|
8
|
+
{
|
|
9
|
+
button: "#{brand}-button",
|
|
10
|
+
secondary_button: "#{brand}-button #{brand}-button--secondary",
|
|
11
|
+
warning_button: "#{brand}-button #{brand}-button--warning",
|
|
12
|
+
reverse_button: "#{brand}-button #{brand}-button--inverse"
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<div class="<%= brand %>-summary-card">
|
|
2
|
+
<div class="<%= brand %>-summary-card__title-wrapper">
|
|
3
|
+
<%= ds_heading(title, class: "#{brand}-summary-card__title") %>
|
|
4
|
+
<% if actions.any? %>
|
|
5
|
+
<ul class="<%= brand %>-summary-card__actions">
|
|
6
|
+
<% actions.each do |action| %>
|
|
7
|
+
<li class="<%= brand %>-summary-card__action"><%= render_action(action) %></li>
|
|
8
|
+
<% end %>
|
|
9
|
+
</ul>
|
|
10
|
+
<% end %>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="<%= brand %>-summary-card__content">
|
|
13
|
+
<%= content %>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module DesignSystem
|
|
2
|
+
module Govuk
|
|
3
|
+
# GOV.UK summary card: uses the summary-card block names and the
|
|
4
|
+
# govuk-visually-hidden class for action suffixes.
|
|
5
|
+
class SummaryCardComponent < DesignSystem::Generic::SummaryCardComponent
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def visually_hidden_class
|
|
9
|
+
"#{brand}-visually-hidden"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<%= content_tag(:div, **options) do %>
|
|
2
|
+
<table class="<%= brand %>-table">
|
|
3
|
+
<% if table.caption %>
|
|
4
|
+
<caption class="<%= brand %>-table__caption <%= brand %>-table__caption--m"><%= table.caption %></caption>
|
|
5
|
+
<% end %>
|
|
6
|
+
<thead class="<%= brand %>-table__head" role="rowgroup">
|
|
7
|
+
<tr class="<%= brand %>-table__row" role="row">
|
|
8
|
+
<% table.columns.each do |column| %>
|
|
9
|
+
<%= content_tag(:th, cell_content(column),
|
|
10
|
+
**html_cell_options(column, scope: 'col', class: header_classes(column))) %>
|
|
11
|
+
<% end %>
|
|
12
|
+
</tr>
|
|
13
|
+
</thead>
|
|
14
|
+
<tbody class="<%= brand %>-table__body">
|
|
15
|
+
<% table.rows.each do |row| %>
|
|
16
|
+
<tr class="<%= brand %>-table__row" role="row">
|
|
17
|
+
<% row.each_with_index do |cell, index| %>
|
|
18
|
+
<% if index.zero? %>
|
|
19
|
+
<%= content_tag(:th, cell_content(cell),
|
|
20
|
+
**html_cell_options(cell, scope: 'row', class: header_classes(cell))) %>
|
|
21
|
+
<% else %>
|
|
22
|
+
<%= content_tag(:td, cell_content(cell),
|
|
23
|
+
**html_cell_options(cell, class: data_cell_classes(cell))) %>
|
|
24
|
+
<% end %>
|
|
25
|
+
<% end %>
|
|
26
|
+
</tr>
|
|
27
|
+
<% end %>
|
|
28
|
+
</tbody>
|
|
29
|
+
</table>
|
|
30
|
+
<% end %>
|