Skip to content

Commit

Permalink
VAGOV-TEAM-97920: Form Builder Navbar (#20149)
Browse files Browse the repository at this point in the history
* VAGOV-TEAM-97920:
- Renames form-builder theme and sets it as page-level theme.

* Allows for active tab to be set on each path.

* Updates page template and styles for navbar

* Removes unnecessary properties from base form.

* Adds id class to each navbar tab

* Adds unpkg external stylesheet to the module-defined library.

* Attaches styles at page level rather than form level.

* Adds unit test for libraries.yml.

* Updates existing test suites.

* Updates class names in test to reflect changes in template.
  • Loading branch information
ryguyk authored Jan 6, 2025
1 parent 7c97d87 commit 3653c51
Show file tree
Hide file tree
Showing 14 changed files with 332 additions and 105 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,92 @@
/* page container */
.va-gov-form-builder-page-container {
.form-builder-page-container {
font-family: var(--font-family-serif);
}

/* headings */
.form-builder-page-container h1 {
font-size: var(--vads-font-size-heading-level-1);
line-height: var(--units-6);
}

.form-builder-page-container h2 {
font-size: var(--vads-font-size-heading-level-2);
}

.form-builder-page-container h2 {
font-size: var(--vads-font-size-heading-level-2);
}

.form-builder-page-container h3 {
font-size: var(--vads-font-size-heading-level-3);
}

.form-builder-page-container h4 {
font-size: var(--vads-font-size-heading-level-4);
}

.form-builder-page-container h5 {
font-size: var(--vads-font-size-heading-level-5);
}

.form-builder-page-container h6 {
font-size: var(--vads-font-size-heading-level-6);
}

/* header */
.form-builder-header {
background-color: var(--va-blue-darkest);
color: var(--va-white);
padding-top: var(--units-1);
}

/* layout container */
.form-builder-layout-container {
margin: 0 var(--units-7);
}

/* title */
.form-builder-title {
margin-bottom: var(--units-1p5);
}

/* navbar */
.form-builder-navbar__nav {
display: flex;
}

.form-builder-navbar__tabs {
display: flex;
gap: var(--units-5);
list-style: none;
margin: 0;
}

.form-builder-navbar__tab {
min-width: 100px;
padding: var(--units-1);
position: relative;
text-align: center;
}

.form-builder-navbar__tab--active {
border-bottom: var(--units-0p5) solid var(--uswds-system-color-gold-vivid-20);
}

.form-builder-navbar__link {
color: var(--vads-color-white);
font-size: var(--font-size-lg);
font-weight: var(--font-weight-bold);
line-height: var(--vads-font-line-height-default);
text-decoration: none;
}

.form-builder-navbar__link:hover {
background: transparent;
color: var(--vads-color-white);
}

.form-builder-navbar__tab--active .form-builder-navbar__link,
.form-builder-navbar__tab--active .form-builder-navbar__link:hover {
color: var(--uswds-system-color-gold-vivid-20);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ class VaGovFormBuilderController extends ControllerBase {
*/
private $drupalFormBuilder;

/**
* The active tab in the form builder.
*
* @var 'forms'|'content'|'layout'
*/
private $activeTab;

/**
* {@inheritdoc}
*/
Expand All @@ -41,6 +48,34 @@ public static function create(ContainerInterface $container) {
return $instance;
}

/**
* Returns a render array representing the page with the passed-in form.
*
* @param string $formName
* The filename of the form to be rendered.
* @param string $nid
* The node id, passed in when the form in question edits an existing node.
*/
private function getFormPage($formName, $nid = NULL) {
// @phpstan-ignore-next-line
$form = $this->drupalFormBuilder->getForm('Drupal\va_gov_form_builder\Form\\' . $formName, $nid);

return [
'#type' => 'page',
'content' => $form,
// Add custom data.
'form_builder_page_data' => [
'active_tab' => $this->activeTab,
],
// Add styles.
'#attached' => [
'library' => [
'va_gov_form_builder/va_gov_form_builder_styles',
],
],
];
}

/**
* Entry point for the VA Form Builder. Redirects to the intro page.
*/
Expand All @@ -52,22 +87,24 @@ public function entry() {
* Intro page.
*/
public function intro() {
return $this->drupalFormBuilder->getForm('Drupal\va_gov_form_builder\Form\Intro');
$this->activeTab = 'forms';
return $this->getFormPage('Intro');
}

/**
* Start-conversion page.
*/
public function startConversion() {
return $this->drupalFormBuilder->getForm('Drupal\va_gov_form_builder\Form\StartConversion');
$this->activeTab = 'forms';
return $this->getFormPage('StartConversion');
}

/**
* Name-and-date-of-birth page.
*/
public function nameAndDob($nid) {
// @phpstan-ignore-next-line
return $this->drupalFormBuilder->getForm('Drupal\va_gov_form_builder\Form\NameAndDob', $nid);
$this->activeTab = 'content';
return $this->getFormPage('NameAndDob', $nid);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,13 @@ abstract class FormBuilderBase extends FormBase {

/**
* {@inheritdoc}
*
* After initially containing some logic, this function
* is now empty, and this entire class is a candiate
* for removal. Leaving it here for now, as it might prove
* necessary as we continue on.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['#theme'] = 'va_gov_form_builder';
$form['#title'] = $this->t('Form Builder');

// Add styles.
$form['#attached']['html_head'][] = [
[
'#tag' => 'link',
'#attributes' => [
'rel' => 'stylesheet',
'href' => 'https://unpkg.com/@department-of-veterans-affairs/css-library@0.16.0/dist/tokens/css/variables.css',
],
],
'external_stylesheet',
];
$form['#attached']['library'][] = 'va_gov_form_builder/va_gov_form_builder_styles';

return $form;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,66 @@
* @file
* VA.gov Form Builder's implementation of a single page.
*
* Nearly identical to VAgovClaro's implementation, except:
* - An outermost page container has been added.
* - The header includes additional content (navbar, eventually)
* - Breadcrumbs have been removed
* The variables available to this template are passed from the controller:
* - page
* - content: The main content of the page; the individual form
* - form_builder_page_data
* - active_tab: The active tab in the navbar
*
* For more information:
* @see docroot/themes/custom/vagovclaro/templates/page/page.html.twig
* @see /docroot/modules/custom/va_gov_form_builder/src/Controller/VaGovFormBuilderController.php
*/
#}
<div class="va-gov-form-builder-page-container">
<header class="content-header clearfix">
<div class="layout-container">
{{ page.header }}
<div class="form-builder-page-container">
<header class="form-builder-header">
<div class="form-builder-layout-container">

<div class="va-gov-form-builder-navbar">
<!-- This is a placeholder for our navigation bar -->
<div class="form-builder-title">
<h1 class="form-builder-title__page-title">Form Builder</h1>
</div>

{% set active_tab = page.form_builder_page_data.active_tab %}
<div class="form-builder-navbar">
<nav class="form-builder-navbar__nav">
<ul class="form-builder-navbar__tabs">

<li class="form-builder-navbar__tab form-builder-navbar__tab--forms
{{
active_tab == 'forms' ? 'form-builder-navbar__tab--active'
: ''
}}"
>
<a href="#" class="form-builder-navbar__link">Forms</a>
</li>

<li class="form-builder-navbar__tab form-builder-navbar__tab--content
{{
active_tab == 'content' ? 'form-builder-navbar__tab--active'
: ''
}}">
<a href="#" class="form-builder-navbar__link">Content</a>
</li>

<li class="form-builder-navbar__tab form-builder-navbar__tab--layout
{{
active_tab == 'layout' ? 'form-builder-navbar__tab--active'
: ''
}}"
>
<a href="#" class="form-builder-navbar__link">Layout</a>
</li>
</ul>
</nav>
</div>
</div>
</header>

<div class="layout-container">
{{ page.pre_content }}

<div class="form-builder-layout-container">
<main class="page-content clearfix" role="main">
<div class="visually-hidden"><a id="main-content" tabindex="-1"></a></div>
{{ page.highlighted }}
{% if page.help %}
<div class="help">
{{ page.help }}
</div>
{% endif %}

{# The form content #}
{{ page.content }}

</main>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ va_gov_form_builder_styles:
css:
theme:
css/va_gov_form_builder.css: {}
https://unpkg.com/@department-of-veterans-affairs/css-library@0.16.0/dist/tokens/css/variables.css:
{}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ function va_gov_form_builder_entity_bundle_field_info_alter(&$fields, EntityType
*/
function va_gov_form_builder_theme() {
return [
'va_gov_form_builder_page' => [
'template' => 'page--va-gov-form-builder',
'page__va_gov_form_builder' => [
'base hook' => 'page',
'path' => \Drupal::service('extension.list.module')->getPath('va_gov_form_builder') . '/templates',
],
];
Expand All @@ -39,7 +39,7 @@ function va_gov_form_builder_theme_suggestions_page(array &$variables) {

// Apply custom page template for all Form Builder routes.
if (strpos($route_name, 'va_gov_form_builder.') === 0) {
$suggestions[] = 'va_gov_form_builder_page';
$suggestions[] = 'page__va_gov_form_builder';
}

return $suggestions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ public function setUp(): void {
$this->controller = VaGovFormBuilderController::create($container);
}

/**
* Tests css is included.
*/
public function testCssIncluded() {
$page = $this->controller->intro();

$this->assertContains(
'va_gov_form_builder/va_gov_form_builder_styles',
$page['#attached']['library'],
"The library 'va_gov_form_builder/va_gov_form_builder_styles' is successfully attached."
);
}

/**
* Tests the entry method redirects correctly.
*/
Expand All @@ -55,20 +68,20 @@ public function testEntryRedirect() {
* Tests the intro method returns an Intro form.
*/
public function testIntro() {
$form = $this->controller->intro();
$page = $this->controller->intro();

$this->assertArrayHasKey('#type', $form);
$this->assertArrayHasKey('working_with_form_builder_header', $form);
$this->assertArrayHasKey('content', $page);
$this->assertArrayHasKey('working_with_form_builder_header', $page['content']);
}

/**
* Tests the startConversion method returns a StartConversion form.
*/
public function testStartConversion() {
$form = $this->controller->startConversion();
$page = $this->controller->startConversion();

$this->assertArrayHasKey('#type', $form);
$this->assertArrayHasKey('start_new_conversion_header', $form);
$this->assertArrayHasKey('content', $page);
$this->assertArrayHasKey('start_new_conversion_header', $page['content']);
}

/**
Expand All @@ -81,10 +94,10 @@ public function testNameAndDob() {
'field_chapters' => [],
]);

$form = $this->controller->nameAndDob($node->id());
$page = $this->controller->nameAndDob($node->id());

$this->assertArrayHasKey('#type', $form);
$this->assertArrayHasKey('name_and_dob_header', $form);
$this->assertArrayHasKey('content', $page);
$this->assertArrayHasKey('name_and_dob_header', $page['content']);
}

}
Loading

0 comments on commit 3653c51

Please sign in to comment.