Skip to content

Commit

Permalink
Add the new task list component
Browse files Browse the repository at this point in the history
The task list component displays all the tasks a user needs to do, and
allows users to easily identify which ones are done and which they still
need to do.

Refs: alphagov/govuk-design-system/pull/1994
  • Loading branch information
peteryates committed Aug 23, 2023
1 parent cc04d76 commit 983acfc
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 0 deletions.
21 changes: 21 additions & 0 deletions app/components/govuk_component/task_list_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module GovukComponent
class TaskListComponent < GovukComponent::Base
renders_many :items, "GovukComponent::TaskListComponent::ItemComponent"

def initialize(classes: [], html_attributes: {})
super(classes: classes, html_attributes: html_attributes)
end

def call
tag.ul(**html_attributes) { safe_join(items) }
end

private

def default_attributes
{
class: 'govuk-task-list'
}
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
module GovukComponent
class TaskListComponent::ItemComponent < GovukComponent::Base
renders_one :title, "GovukComponent::TaskListComponent::TitleComponent"
renders_one :status, "GovukComponent::TaskListComponent::StatusComponent"

attr_reader :title_text, :status, :href, :hint

def initialize(title: nil, href: nil, hint: nil, status: nil, classes: [], html_attributes: {})
@title_text = title
@href = href
@hint = hint
@status = status

super(classes: classes, html_attributes: html_attributes)
end

def call
tag.li(safe_join([title_content, hint_content, status_content]), **html_attributes)
end

private

def title_content
title || with_title(text: title_text, href: href, hint: hint)
end

def status_content
case status
when String
with_status(text: status)
when Hash
with_status(**status)
else status
end
end

def hint_content
tag.div(hint, class: %w(govuk-task-list__task_hint))
end

def default_attributes
{ class: 'govuk-task-list__item' }
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module GovukComponent
class TaskListComponent::StatusComponent < GovukComponent::Base
attr_reader :text, :href, :colour

def initialize(text: nil, href: nil, colour: nil, classes: [], html_attributes: {})
@text = text
@href = href
@colour = colour

super(classes: classes, html_attributes: html_attributes)
end

def call
tag.div(**html_attributes) do
render(GovukComponent::TagComponent.new(text: text, colour: colour))
end
end

private

def default_attributes
{ class: %w(govuk-task-list__status) }
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module GovukComponent
class TaskListComponent::TitleComponent < GovukComponent::Base
attr_reader :text, :href, :hint

def initialize(text: nil, href: nil, hint: nil, classes: [], html_attributes: {})
@text = text
@href = href
@hint = hint

super(classes: classes, html_attributes: html_attributes)
end

def call
tag.div(**html_attributes) { title_content }
end

private

def title_content
return link if href.present?

text
end

def link
govuk_link_to(text, href, class: "govuk-task-list__link")
end

def hint_content
tag.div(hint, class: "govuk-task-list__task_hint")
end

def default_attributes
{ class: "govuk-task-list__task-name-and-hint" }
end
end
end
73 changes: 73 additions & 0 deletions spec/components/govuk_component/task_list_component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
require 'spec_helper'

RSpec.describe(GovukComponent::TaskListComponent, type: :component) do
let(:component_css_class) { 'govuk-task-list' }
let(:kwargs) { {} }
let(:list_item_one_kwargs) { { title: "One", status: "in progress" } }
let(:list_item_two_kwargs) { { title: "Two", status: "ok" } }

subject! do
render_inline(GovukComponent::TaskListComponent.new(**kwargs)) do |task_list|
task_list.with_item(**list_item_one_kwargs)
task_list.with_item(**list_item_two_kwargs)
end
end

it_behaves_like 'a component that accepts custom classes'
it_behaves_like 'a component that accepts custom HTML attributes'

describe "rendering items with arguments" do
specify "renders a list with the correct class and contents" do
expect(rendered_content).to have_tag("ul", with: { class: component_css_class }) do
with_tag("li", text: "One", with: { class: "govuk-task-list__item" }) do
with_tag("div", with: { class: "govuk-task-list__status" }, text: "in progress")
end

with_tag("li", text: "Two", with: { class: "govuk-task-list__item" }) do
with_tag("div", with: { class: "govuk-task-list__status" }, text: "ok")
end
end
end

context "when href is present" do
let(:href) { "/item-one" }
let(:list_item_one_kwargs) { { title: "One", status: "in progress", href: href } }

specify "a link is rendered with the correct attributes" do
expect(rendered_content).to have_tag("li") do
with_tag("a", with: { href: href, class: %w(govuk-link govuk-task-list__link) })
end
end
end

context "when a hint present" do
let(:hint_two) { "Two comes after one" }
let(:list_item_two_kwargs) { { title: "Two", status: "ok", hint: hint_two } }

specify "a hint is rendered with the correct attributes" do
expect(rendered_content).to have_tag("li") do
with_tag("div", text: hint_two, with: { class: "govuk-task-list__task_hint" })
end
end
end

context "when a status tag is present" do
let(:status_text) { "Everything's OK" }
let(:list_item_two_kwargs) { { title: "Two", status: "ok" } }

specify "a status tag is rendered with the correct attributes and text" do
expect(rendered_content).to have_tag("li") do
with_tag("div", with: { class: %w(govuk-task-list__status) }) do
with_tag("strong", with: { class: %w(govuk-tag) })
end
end
end
end
end

describe "rendering an entire task list with data" do
end

describe "rendering an entire task list with blocks" do
end
end

0 comments on commit 983acfc

Please sign in to comment.