Skip to content

Commit

Permalink
Port Pagination to IComponentGenerator
Browse files Browse the repository at this point in the history
  • Loading branch information
gunndabad committed Dec 24, 2024
1 parent 4a865d0 commit 8a33816
Show file tree
Hide file tree
Showing 28 changed files with 492 additions and 694 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ In additional, its `gfa-prepend-error-summary` attribute has been renamed to `pr
The `prepend-error-summary` attribute can now be added to any element.
If this attribute is `true` and there are any form components with errors within the element then an error summary will be prepended.

### `<govuk-pagination-item>`
The `is-current` attribute is renamed to `current`.

### `asp-for` attributes
The `asp-for` attributes have been deprecated; the `for` attribute should be used instead.

Expand Down
48 changes: 24 additions & 24 deletions docs/components/pagination.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

```razor
<govuk-pagination>
<govuk-pagination-previous href="#" />
<govuk-pagination-item href="#">1</govuk-pagination-item>
<govuk-pagination-item href="#" is-current="true">2</govuk-pagination-item>
<govuk-pagination-item href="#">3</govuk-pagination-item>
<govuk-pagination-next href="#" />
<previous href="#" />
<item href="#">1</item>
<item href="#" current="true">2</item>
<item href="#">3</item>
<next href="#" />
</govuk-pagination>
```

Expand All @@ -20,8 +20,8 @@

```razor
<govuk-pagination>
<govuk-pagination-previous href="#" label-text="Applying for a provisional lorry or bus licence" />
<govuk-pagination-next href="#" label-text="Driver CPC part 1 test: theory" />
<previous href="#" label-text="Applying for a provisional lorry or bus licence" />
<next href="#" label-text="Driver CPC part 1 test: theory" />
</govuk-pagination>
```

Expand All @@ -31,15 +31,15 @@

```razor
<govuk-pagination>
<govuk-pagination-previous href="#" />
<govuk-pagination-item href="#">1</govuk-pagination-item>
<govuk-pagination-ellipsis />
<govuk-pagination-item href="#">6</govuk-pagination-item>
<govuk-pagination-item href="#" is-current="true">7</govuk-pagination-item>
<govuk-pagination-item href="#">8</govuk-pagination-item>
<govuk-pagination-ellipsis />
<govuk-pagination-item href="#">42</govuk-pagination-item>
<govuk-pagination-next href="#" />
<previous href="#" />
<item href="#">1</item>
<ellipsis />
<item href="#">6</item>
<item href="#" current="true">7</item>
<item href="#">8</item>
<ellipsis />
<item href="#">42</item>
<next href="#" />
</govuk-pagination>
```

Expand All @@ -49,11 +49,11 @@

### `<govuk-pagination>`

| Attribute | Type | Description |
| --- | --- | --- |
| `landmark-label` | `string` | The label for the navigation landmark that wraps the pagination. The default is `results`. |
| Attribute | Type | Description |
| --- | --- |--------------------------------------------------------------------------------------------------------------------------|
| `landmark-label` | `string` | The label for the navigation landmark that wraps the pagination. If not specified, 'Pagination' will be used. |

### `<govuk-pagination-previous>`
### `<previous>`

| Attribute | Type | Description |
| --- | --- | --- |
Expand All @@ -64,22 +64,22 @@
The content is the text for the link to the previous page. The default is `Previous page`.\
Must be inside a `<govuk-pagination>` element.

### `<govuk-pagination-item>`
### `<item>`

| Attribute | Type | Description |
| --- | --- | --- |
| (link attributes) | | If specified generates an `href` attribute using the specified values. See [documentation on links](../links.md) for more information. |
| `is-current` | `bool` | Whether this item is the current page the user is on. By default this is determined by comparing the current URL to this item's generated `href` attribute. |
| `current` | `bool` | Whether this item is the current page the user is on. By default this is determined by comparing the current URL to this item's generated `href` attribute. |
| `visually-hidden-text` | `string` | The visually hidden text for the pagination item. The default is `Page <pagination item text>`. |

The content is the pagination item text - usually a page number.\
Must be inside a `<govuk-pagination>` element.

### `<govuk-pagination-ellipsis>`
### `<ellipsis>`

Must be inside a `<govuk-pagination>` element.

### `<govuk-pagination-next>`
### `<next>`

| Attribute | Type | Description |
| --- | --- | --- |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
@page

<govuk-pagination>
<govuk-pagination-previous href="#" />
<govuk-pagination-item href="#">1</govuk-pagination-item>
<govuk-pagination-item href="#" is-current="true">2</govuk-pagination-item>
<govuk-pagination-item href="#">3</govuk-pagination-item>
<govuk-pagination-next href="#" />
<previous href="#" />
<item href="#">1</item>
<item href="#" is-current="true">2</item>
<item href="#">3</item>
<next href="#" />
</govuk-pagination>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@page

<govuk-pagination>
<govuk-pagination-previous href="#" label-text="Applying for a provisional lorry or bus licence" />
<govuk-pagination-next href="#" label-text="Driver CPC part 1 test: theory" />
<previous href="#" label-text="Applying for a provisional lorry or bus licence" />
<next href="#" label-text="Driver CPC part 1 test: theory" />
</govuk-pagination>
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
@page

<govuk-pagination>
<govuk-pagination-previous href="#" />
<govuk-pagination-item href="#">1</govuk-pagination-item>
<govuk-pagination-ellipsis />
<govuk-pagination-item href="#">6</govuk-pagination-item>
<govuk-pagination-item href="#" is-current="true">7</govuk-pagination-item>
<govuk-pagination-item href="#">8</govuk-pagination-item>
<govuk-pagination-ellipsis />
<govuk-pagination-item href="#">42</govuk-pagination-item>
<govuk-pagination-next href="#" />
<previous href="#" />
<item href="#">1</item>
<ellipsis />
<item href="#">6</item>
<item href="#" is-current="true">7</item>
<item href="#">8</item>
<ellipsis />
<item href="#">42</item>
<next href="#" />
</govuk-pagination>
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
using System;
using System.Diagnostics;
using System.Linq;
using Microsoft.AspNetCore.Html;

namespace GovUk.Frontend.AspNetCore.ComponentGeneration;

public partial class DefaultComponentGenerator
{
internal const string PaginationDefaultPreviousText = "Previous";
internal const string PaginationDefaultNextText = "Next";
internal const string PaginationElement = "nav";
internal const string PaginationEllipsisElement = "li";
internal const string PaginationItemElement = "li";
internal const string PaginationNextElement = "div";
internal const string PaginationPreviousElement = "div";

/// <inheritdoc/>
public virtual HtmlTagBuilder GeneratePagination(PaginationOptions options)
{
ArgumentNullException.ThrowIfNull(options);
options.Validate();

var blockLevel = options.Items?.Any() != true && (options.Next is not null || options.Previous is not null);

var arrowPrevious = new HtmlTagBuilder("svg")
.WithCssClasses("govuk-pagination__icon", "govuk-pagination__icon--prev")
.WithAttribute("xmlns", "http://www.w3.org/2000/svg", encodeValue: false)
.WithAttribute("height", "13", encodeValue: false)
.WithAttribute("width", "15", encodeValue: false)
.WithAttribute("aria-hidden", "true", encodeValue: false)
.WithAttribute("focusable", "false", encodeValue: false)
.WithAttribute("viewBox", "0 0 15 13", encodeValue: false)
.WithAppendedHtml(new HtmlTagBuilder("path")
.WithAttribute("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",
encodeValue: false));

var arrowNext = new HtmlTagBuilder("svg")
.WithCssClasses("govuk-pagination__icon", "govuk-pagination__icon--next")
.WithAttribute("xmlns", "http://www.w3.org/2000/svg", encodeValue: false)
.WithAttribute("height", "13", encodeValue: false)
.WithAttribute("width", "15", encodeValue: false)
.WithAttribute("aria-hidden", "true", encodeValue: false)
.WithAttribute("focusable", "false", encodeValue: false)
.WithAttribute("viewBox", "0 0 15 13", encodeValue: false)
.WithAppendedHtml(new HtmlTagBuilder("path")
.WithAttribute("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",
encodeValue: false));

HtmlTagBuilder ArrowLink(IPaginationOptionsLink link, string type, string fallbackText)
{
var arrowType = type == "prev" ? arrowPrevious : arrowNext;

return new HtmlTagBuilder("div")
.WithCssClass($"govuk-pagination__{type}")
.WithAttributes(link.ContainerAttributes)
.WithAppendedHtml(new HtmlTagBuilder("a")
.WithCssClasses("govuk-link", "govuk-pagination__link")
.WithAttribute("href", link.Href!)
.WithAttribute("rel", type, encodeValue: false)
.WithAttributes(link.Attributes)
.When(blockLevel || type == "prev", b => b.WithAppendedHtml(arrowType))
.WithAppendedHtml(new HtmlTagBuilder("span")
.WithCssClass("govuk-pagination__link-title")
.When(blockLevel && link.LabelText.NormalizeEmptyString() is null,
b => b.WithCssClass("govuk-pagination__link-title--decorated"))
.WithAppendedHtml(() =>
{
var content = GetEncodedTextOrHtml(link.Text, link.Html);

if (content is null)
{
var builder = new HtmlContentBuilder();
builder.Append(fallbackText);
builder.AppendHtml(new HtmlTagBuilder("span")
.WithCssClass("govuk-visually-hidden")
.WithAppendedText(" page"));
return builder;
}
else
{
return content;
}
}))
.When(
link.LabelText.NormalizeEmptyString() is not null && blockLevel,
b => b
.WithAppendedHtml(new HtmlTagBuilder("span")
.WithCssClass("govuk-visually-hidden")
.WithAppendedText(":"))
.WithAppendedHtml(new HtmlTagBuilder("span")
.WithCssClass("govuk-pagination__link-label")
.WithAppendedHtml(link.LabelText!)))
.When(
!blockLevel && type == "next",
b => b.WithAppendedHtml(arrowType)));
}

HtmlTagBuilder PageItem(PaginationOptionsItem item) =>
new HtmlTagBuilder("li")
.WithCssClass("govuk-pagination__item")
.When(item.Current == true, b => b.WithCssClass("govuk-pagination__item--current"))
.When(item.Ellipsis == true, b => b.WithCssClass("govuk-pagination__item--ellipses"))
.WithAppendedHtml(
item.Ellipsis == true
? new HtmlString("&ctdot;")
: new HtmlTagBuilder("a")
.WithCssClasses("govuk-link", "govuk-pagination__link")
.WithAttribute("href", item.Href!)
.WithAttribute("aria-label",
item.VisuallyHiddenText ?? new HtmlString($"Page {item.Number}"))
.When(item.Current == true,
b => b.WithAttribute("aria-current", "page", encodeValue: false))
.WithAttributes(item.Attributes)
.WithAppendedHtml(item.Number!));

return new HtmlTagBuilder("nav")
.WithCssClass("govuk-pagination")
.When(blockLevel, b => b.WithCssClass("govuk-pagination--block"))
.WithCssClasses(ExplodeClasses(options.Classes?.ToHtmlString()))
.WithAttribute("role", "navigation", encodeValue: false)
.WithAttribute("aria-label", options.LandmarkLabel ?? new HtmlString("Pagination"))
.WithAttributes(options.Attributes)
.When(
options.Previous is not null && options.Previous.Href.NormalizeEmptyString() is not null,
b =>
{
Debugger.Break();
b.WithAppendedHtml(ArrowLink(options.Previous!, "prev", "Previous"));
})
.When(
options.Items is not null,
b => b.WithAppendedHtml(new HtmlTagBuilder("ul")
.WithCssClass("govuk-pagination__list")
.WithAppendedHtml(options.Items!.Select(PageItem))))
.When(
options.Next is not null && options.Next.Href.NormalizeEmptyString() is not null,
b =>
{
Debugger.Break();
var x = ArrowLink(options.Next!, "next", "Next");
b.WithAppendedHtml(ArrowLink(options.Next!, "next", "Next"));
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ public interface IComponentGenerator
/// <returns>An <see cref="HtmlTagBuilder"/> with the component's HTML.</returns>
HtmlTagBuilder GenerateLabel(LabelOptions options);

/// <summary>
/// Generates a pagination component.
/// </summary>
/// <returns>An <see cref="HtmlTagBuilder"/> with the component's HTML.</returns>
HtmlTagBuilder GeneratePagination(PaginationOptions options);

/// <summary>
/// Generates a phase banner component.
/// </summary>
Expand Down
Loading

0 comments on commit 8a33816

Please sign in to comment.