generated from DFE-Digital/govuk-rails-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The timeline component accepts an array of events which are ViewComponent slots (meaning it can be constructed manually too via `with_item(event)`) although I don't see us using that. It's intended to display a chronological list of events that happened to a thing.
- Loading branch information
1 parent
679cf5a
commit 253f591
Showing
6 changed files
with
219 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
module NpqSeparation | ||
class TimelineComponent < ViewComponent::Base | ||
renders_many :items, "ItemComponent" | ||
|
||
attr_reader :events | ||
|
||
def initialize(events) | ||
@events = events.sort_by(&:created_at) | ||
|
||
@events.each { |event| with_item(event) } | ||
end | ||
|
||
def call | ||
tag.div(class: "app-timeline") do | ||
safe_join(items) | ||
end | ||
end | ||
|
||
class ItemComponent < ViewComponent::Base | ||
attr_reader :event | ||
|
||
def initialize(event) | ||
@event = event | ||
end | ||
|
||
def call | ||
tag.div(class: "app-timeline__item") do | ||
safe_join([header, timestamp, description]) | ||
end | ||
end | ||
|
||
private | ||
|
||
def header | ||
tag.div(class: "app-timeline__header") do | ||
safe_join([title, byline], " ") | ||
end | ||
end | ||
|
||
def title | ||
tag.h2(event.title, class: "app-timeline__title") | ||
end | ||
|
||
def timestamp | ||
tag.p(class: "app-timeline__date") do | ||
tag.time(event.created_at.to_fs(:govuk_short), datetime: event.created_at.to_fs(:iso8601)) | ||
end | ||
end | ||
|
||
def description | ||
tag.div(class: "app-timeline__description") { event.description } | ||
end | ||
|
||
def byline | ||
return if event.byline.blank? | ||
|
||
tag.p("by #{event.byline}", class: "app-timeline__byline") | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// timeline | ||
// | ||
// borrowed from the MoJ frontend library, moj- replaced with app- as | ||
// we will likely customise this to suit our needs | ||
// | ||
// https://design-patterns.service.justice.gov.uk/components/timeline/ | ||
.app-timeline { | ||
margin-bottom: govuk-spacing(4); | ||
overflow: hidden; | ||
position: relative; | ||
|
||
&:before { | ||
background-color: $govuk-brand-colour; | ||
content: ""; | ||
height: 100%; | ||
left: 0; | ||
position: absolute; | ||
top: govuk-spacing(2); | ||
width: 5px; | ||
} | ||
|
||
} | ||
|
||
.app-timeline--full { | ||
margin-bottom: 0; | ||
&:before { | ||
height: calc(100% - 75px); | ||
} | ||
} | ||
|
||
.app-timeline__item { | ||
padding-bottom: govuk-spacing(6); | ||
padding-left: govuk-spacing(4); | ||
position: relative; | ||
|
||
&:before { | ||
background-color: $govuk-brand-colour; | ||
content: ""; | ||
height: 5px; | ||
left: 0; | ||
position: absolute; | ||
top: govuk-spacing(2); | ||
width: 15px; | ||
} | ||
|
||
} | ||
|
||
.app-timeline__title { | ||
@include govuk-font($size: 19, $weight: bold); | ||
display: inline; | ||
} | ||
|
||
.app-timeline__byline { | ||
@include govuk-font($size: 19); | ||
color: $govuk-secondary-text-colour; | ||
display: inline; | ||
margin: 0; | ||
} | ||
|
||
.app-timeline__date { | ||
@include govuk-font($size: 16); | ||
margin-top: govuk-spacing(1); | ||
margin-bottom: 0; | ||
} | ||
|
||
.app-timeline__description { | ||
@include govuk-font($size: 19); | ||
margin-top: govuk-spacing(4); | ||
} | ||
|
||
.app-timeline__documents { | ||
list-style: none; | ||
margin-bottom: 0; | ||
padding-left: 0; | ||
} | ||
|
||
.app-timeline__document-item { | ||
margin-bottom: govuk-spacing(1); | ||
|
||
&:last-child { | ||
margin-bottom: 0; | ||
} | ||
|
||
} | ||
|
||
.app-timeline__document-icon { | ||
float: left; | ||
margin-top: 4px; | ||
margin-right: 4px; | ||
fill: currentColor; | ||
|
||
@media screen and (forced-colors: active) { | ||
fill: linkText; | ||
} | ||
} | ||
|
||
.app-timeline__document-link { | ||
// background-image: url(#{$app-images-path}icon-document.svg); | ||
background-repeat: no-repeat; | ||
background-size: 20px 16px; | ||
background-position: 0 50%; | ||
padding-left: govuk-spacing(5); | ||
|
||
&:focus { | ||
color: govuk-colour("black"); // Focus colour on yellow should really be black. | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
require "rails_helper" | ||
|
||
RSpec.describe NpqSeparation::TimelineComponent, type: :component do | ||
let(:one_day_ago) { FactoryBot.build(:event, :with_byline, created_at: 1.day.ago) } | ||
let(:two_days_ago) { FactoryBot.build(:event, :with_byline, created_at: 2.days.ago) } | ||
let(:three_days_ago) { FactoryBot.build(:event, :with_byline, created_at: 3.days.ago) } | ||
let(:events) { [two_days_ago, one_day_ago, three_days_ago] } | ||
|
||
subject { NpqSeparation::TimelineComponent.new(events) } | ||
|
||
before { render_inline(subject) } | ||
|
||
context "when the events aren't in choronological order" do | ||
it "orders the events by created_at on initialization" do | ||
expect(subject.events).to eql(events.sort_by(&:created_at)) | ||
end | ||
end | ||
|
||
it "displays all of the events in a timeline" do | ||
expect(rendered_content).to have_css(".app-timeline__item", count: events.size) | ||
end | ||
|
||
it "shows a timestamp for each event" do | ||
events.each do |event| | ||
expect(rendered_content).to have_css("time", text: event.created_at.to_fs(:govuk_short)) | ||
expect(rendered_content).to have_css("time[datetime='#{event.created_at.to_fs(:iso8601)}']") | ||
end | ||
end | ||
|
||
it "shows the title and byline in the header" do | ||
events.each do |event| | ||
expect(rendered_content).to have_css(".app-timeline__header > .app-timeline__title", text: event.title) | ||
expect(rendered_content).to have_css(".app-timeline__header > .app-timeline__byline", text: event.byline) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
FactoryBot.define do | ||
factory :event do | ||
sequence(:title) { |n| "Event #{n}" } | ||
sequence(:description) { |n| "Event #{n} description goes here" } | ||
created_at { Time.zone.now } | ||
|
||
trait(:with_random_description) { description { Faker::Lorem.paragraph } } | ||
trait(:with_byline) { byline { Faker::Name.name } } | ||
end | ||
end |