ThankView Styleguide

2.1 #Components.Accordion Accordion

This implementation is not good for accessibility and should be completely rewritten. For more details, see this article on the matter.

A basic accordian component using Details / Summary

Example
A summary!

I'm the detail content!

Markup
<details class="tv-summary">
    <summary>A summary! <div class="indicator"><i class="fa fa-plus"></i><i class="fa fa-minus"></i></div></summary>
    <p class="content">
        I'm the detail content!
    </p>
</details>
Source: resources/sass/_components/details-summary-accordion.scss, line 12

2.2 #Components.Button Button

It's important to know when something is visually presented as a button vs actually a button. If clicking the "button" takes the user to a new page, use an a with these classes applied. Otherwise, use a button. If your button only contains an icon, read this article about accessible icon-only buttons.

Most buttons in our UI begin with this base class. Use case modifiers exist for base buttons and the other variants.

Examples
Default styling
A Link That Looks Like a Button
.no-scale
Prevents the gentle scale up on hover.
A Link That Looks Like a Button
.btn--small
Reduces padding and font size to make the button smaller
A Link That Looks Like a Button
.btn--large
Increases padding and font size to make the button larger
A Link That Looks Like a Button
.btn--primary
Buttons for the primary action(s) users can take in a given view
A Link That Looks Like a Button
.btn--primary-alt
Alternate color scheme for primary actions
A Link That Looks Like a Button
.btn--secondary
Buttons for the secondary action(s) users can take in a given view
A Link That Looks Like a Button
.btn--secondary-alt
Alternate color scheme for secondary actions
A Link That Looks Like a Button
.btn--tertiary
Buttons for the tertiary action(s) users can take in a given view
A Link That Looks Like a Button
.btn--cancel
Color scheme for cancel buttons
A Link That Looks Like a Button
.btn--destructive
Color scheme for destructive actions such as deleting data
A Link That Looks Like a Button
.btn--green-97
Sets color to green-97
A Link That Looks Like a Button
.btn--orange-90
Sets color to orange-90
A Link That Looks Like a Button
.btn--unmute-video
White button with dropshadow, for display over video content
A Link That Looks Like a Button
.btn:disabled
default styles for disabled buttons
A Link That Looks Like a Button
Markup
<button type="button" class="btn [modifier class]">Click Me</button>
<button type="button" class="btn [modifier class]">
    <i class="fa fa-lightbulb btn__icon-left"></i> I have an icon!
</button>
<a href="#" class="btn [modifier class]">A Link That Looks Like a Button</a>
Source: resources/sass/_components/button.scss, line 1

2.2.1 #Components.Button.Circle Circle Button

A circle button, often used inline with the "pill shape" buttons for a closer aesthetic. Typically includes just an icon, and is fixed in size to 40px x 40px

Example
Markup
<button class="btn btn--circle">
<i class="fa fa-download" aria-hidden="true"></i>
</button>
Source: resources/sass/_components/button.scss, line 159

2.2.2 #Components.Button.Ghost Ghost Button

A variant of our button that loses the pill shape and appears to just be text. Used mostly when a button is the semantically correct element, but visually we want text.

Example
Markup
<button type="button" class="btn btn--ghost">Click Me</button>
Source: resources/sass/_components/button.scss, line 115

2.2.3 #Components.Button.Icon Icon-Only Button

A variant of our button that loses the pill shape and primarily gets its shape from an icon. Often includes a tooltip revealed on hover

Example
Markup
<button class="btn btn--icon-only hover:bg-gray-95">
<i class="fa fa-edit font-size-24px" aria-hidden="true"></i>
</button>
Source: resources/sass/_components/button.scss, line 138

2.2.4 #Components.Button.With Tooltips Button Tooltips

Buttons can support a tooltip that is revealed on hover. The tooltip should use utility classes for background colors and text colors.

Examples
Default styling
.btn__tooltip--extra-small
a very small tooltip
.btn__tooltip--small
a small tooltip
.btn__tooltip--large
a larger tooltip
.btn__tooltip--up
tooltip should appear above the button with transition effect
.btn__tooltip--down
tooltip should appear below the button with transition effect
.btn__tooltip--pin-left
tooltip is pinned to the left edge of the button and extends to the right
.btn__tooltip--pin-right
tooltip is pinned to the right edge of the button and extends to the left
Markup
<button class="btn btn--icon hover:bg-gray-95">
<i class="fa fa-edit font-size-24px" aria-hidden="true"></i>
<span class="btn__tooltip [modifier class] bg-blue-48 font-white">Edit</span>
</button>
Source: resources/sass/_components/button.scss, line 383

2.3 #Components.Dropdown Dropdown

The open / close click handling is normally handled by the JS framework. Remove the click handler included in the markup below when creating a dropdown in the application.

If a "selected state" variant is desired, you will need a means of setting a class of selected on dropdown__menu-item elements.

A custom "select" or dropdown menu. There are variants that support showing a selected state for a single item, or multiple items.

Examples
Default styling
.dropdown__menu--selectable
adds support for a "selected" state on dropdown__menu-item elements
.dropdown__menu--multi-select
adds support for multiple dropdown__menu-item elements to have a selected state
Markup: ../../tv-styleguide/markup-files/dropdown.hbs
<div class="dropdown" dropdown>
    <button type="button" class="dropdown__toggle" dropdown-toggle
        onclick="this.parentElement.classList.toggle('open')">
        Open / Close <i class="dropdown__toggle-indicator fa fa-angle-down"></i>
    </button>
    <ul class="dropdown__menu {{modifier_class}}">
        <li class="dropdown__menu-item selected">Item 1</li>
        <li class="dropdown__menu-item">Item 2</li>
        <li class="dropdown__menu-item">Item 3</li>
    </ul>
</div>
Source: resources/sass/_components/dropdown.scss, line 8

2.3.1 #Components.Dropdown.Multi Multi Menu Dropdown

The open / close click handling is normally handled by the JS framework. Remove the click handler included in the markup below when creating a dropdown in the application.

If a "selected state" variant is desired, you will need a means of setting a class of selected on dropdown__menu-item elements.

A dropdown featuring multiple menus side-by-side. In practice this is used for the filters menu, where items in the menu are also togglable.

Example
Markup: ../../tv-styleguide/markup-files/dropdown-multi.hbs
<div class="dropdown dropdown--multi-menu" dropdown>
    <button type="button" class="button dropdown__toggle" dropdown-toggle
        onclick="this.parentElement.classList.toggle('open')">
        Open / Close <i class="dropdown__toggle-indicator fa fa-angle-down"></i>
    </button>
    <div class="dropdown__menu">
        <ul class="dropdown__menu--multi-select">
            <span class="dropdown__menu-header">Side 1</span>
            <li class="dropdown__menu-item selected">
                Item 1
            </li>
            <li class="dropdown__menu-item">
                Item 2
            </li>
            <li class="dropdown__menu-item">
                Item 3
            </li>
        </ul>
        <ul class="dropdown__menu--multi-select">
            <span class="dropdown__menu-header">Side 2</span>
            <li class="dropdown__menu-item">
                Item 1
            </li>
            <li class="dropdown__menu-item selected">
                Item 2
            </li>
            <li class="dropdown__menu-item">
                Item 3
            </li>
        </ul>
    </div>
</div>
Source: resources/sass/_components/dropdown.scss, line 281

2.4 #Components.Overlays Overlays

Read the details on A11y Dialog's markup reference for an explanqtion regarding accessibility of overlay markup.

Overlays in ThankView leverage a library called A11y Dialog for most of their functionality. Opening and closing is normally handled by the framework, click handlers here are for demo purposes only (see script comments in markup).

Example
Markup: ../../tv-styleguide/markup-files/tv-overlay.hbs
<button type="button" class="btn btn--primary" onclick="openDialog('example-dialog-basic')">Open Overlay</button>

<div id="example-dialog-basic" class="tv-overlay" tv-overlay aria-labelledby="my-dialog-title" aria-hidden="true">
    <div class="tv-overlay__backdrop" data-a11y-dialog-hide></div>
    <div class="tv-overlay__content-wrapper" role="document">
        <div class="tv-overlay__header">
            <button class="btn btn--ghost btn--close" onclick="closeDialog('example-dialog-basic')"
                aria-label="Close dialog">
                <svg class="tv-icon close" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                    <path
                        d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
                    <path d="M0 0h24v24H0z" fill="none" />
                </svg>
            </button>
        </div>
        <div class="tv-overlay__content">
            <h1 class="tv-overlay__header-text" id="my-dialog-title">Some Header Text</h1>
            <p class="tv-overlay__message" ng-bind-html="message">Message content can either be hard coded into HTML, or
                dynamically bound via the framework. Multiple <code>tv-overlay__message</code> elements are allowed.</p>
        </div>
        {{!-- if you pass an array of button objects (see overlay-message.js for an exmaple) use the tv-overlay__actions
        container with the compile-buttons directive --}}
        <div class="tv-overlay__actions" compile-buttons buttons="{{buttonMarkup}}"></div>
    </div>
</div>

<script>
    // this open function is for documentation demonstrations only
    // in the ThankView application opening is handled by the `tv-overlay` directive
    // which will respond to the 'open-overlay' event
    function openDialog(id) {
        const dialog = new A11yDialog(document.getElementById(id));
        dialog.show();
    };

    // this function is just for demonstrative purposes
    // in the application, assign ng-click="close()" to the standard close button
    function closeDialog(id) {
        const dialog = new A11yDialog(document.getElementById(id));
        dialog.hide();
    }

</script>
Source: resources/sass/_components/overlay.scss, line 8

2.4.1 #Components.Overlays.Fullscreen Fullscreen Overlays

Fullscreen overlays in ThankView are overlays that appear to be a full page, but don't actually navigate the user to a new page. An example is the edit video view from the video library. They feature a larger header with "back" navigation, and their content area can be treated as a full page.

Example
Markup: ../../tv-styleguide/markup-files/tv-overlay-fullscreen.hbs
<button type="button" class="btn btn--primary" onclick="openDialog('example-fullscreen-dialog')">Open Fullscreen
    Overlay</button>

<div id="example-fullscreen-dialog" class="tv-overlay tv-overlay--fullscreen" tv-overlay
    aria-labelledby="my-fullscreen-dialog-title" aria-hidden="true">
    <div class="tv-overlay__content-wrapper" role="document">
        <div class="tv-overlay__header">
            <button class="btn btn--ghost btn--close" onclick="closeDialog('example-fullscreen-dialog')"
                aria-label="Close dialog">
                <svg class="tv-icon close" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                    <path
                        d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
                    <path d="M0 0h24v24H0z" fill="none" />
                </svg>
            </button>
        </div>

        <div class="tv-overlay__content">
            <h1 id="my-fullscreen-dialog-title" class="tv-overlay__header-text">I'm Fullscreen!</h1>
            <p class="tv-overlay__message">Whatever content or layout you need goes here.</p>
        </div>
    </div>
</div>
Source: resources/sass/_components/overlay.scss, line 260

2.4.2 #Components.Overlays.Modal Modal Overlays

Modal overlays in ThankView are a larger variant of the standard overlay that generally feature some content and a media (decorative or otherwise) element side-by-side. They also feature a header bar with a close button, and can contain action buttons using an element with the class tv-overlay__actions. Open and close interactions work the same way as the base overlay.

Example
Markup: ../../tv-styleguide/markup-files/tv-overlay-modal.hbs
<button type="button" class="btn btn--primary" onclick="openDialog('example-modal-dialog')">Open Modal</button>

<div id="example-modal-dialog" class="tv-overlay tv-overlay--modal" tv-overlay aria-labelledby="my-dialog-title"
	aria-hidden="true">
	<div class="tv-overlay__backdrop" data-a11y-dialog-hide></div>
	<div class="tv-overlay__content-wrapper" role="document">
		<div class="tv-overlay__header">
			<button class="btn btn--ghost btn--close" onclick="closeDialog('example-modal-dialog')"
				aria-label="Close dialog">
				<svg class="tv-icon close" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
					<path
						d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
					<path d="M0 0h24v24H0z" fill="none" />
				</svg>
			</button>
		</div>
		<div class="tv-overlay__content">
			<h1 id="my-dialog-title" ng-show="header">Modal Overlay</h1>
			<p class="tv-overlay__message">This is a larger variant that typically displays some media on one half.</p>
		</div>
		<div class="tv-overlay__media width-100 bg-size-cover bg-pos-center"></div>
	</div>
</div>
Source: resources/sass/_components/overlay.scss, line 236

2.5 #Components.Selection Selection Controls

Standard set of custom UI elements for selection uses (e.g. checkboxes, radio buttons, etc.)

Source: resources/sass/_components/radio-button.scss, line 2

2.5.1 #Components.Selection.Checkbox Checkbox

If for some reason your checkbox is not directly associated with some text, you must still provide text for a screen reader. Add the tv-checkbox__text--hidden to hide text visually.

Component to create a custom checkbox visual. Makes use of the inclusive hiding method described by Sara Soueidan in this article. This could be significantly improved with SVG in place of Font Awesome icons

Examples
Default styling
.tv-checkbox__text--hidden
used for checkboxes with no visual text to provide screen reader accessible text
Markup
<label for="my-checkbox" class="tv-checkbox">
    <input id="my-checkbox" type="checkbox" class="tv-checkbox__input" />
    <div class="tv-checkbox__visual">
        <i class="far fa-square"></i>
        <i class="fas fa-check-square"></i>
    </div>
    <span class="tv-checkbox__text [modifier class]">Check Me!</span>
</label>
Source: resources/sass/_components/checkbox.scss, line 1

2.5.2 #Components.Selection.Radio Button Radio Button

The name attribute should be used to group radio buttons together for the option they control for the expected accessible interactions. Must be unique per page. The label elements' for attribute must contain the id of the input element it corresponds to to ensure they are correctly associated with each other.

Component to create a custom radio button visual. Using a method outlined by Jen Simmons. Supports check to prevent old browsers from having broken radio buttons. Most frequently, button markup will be wrapped in a div used for layout purposes. The label text can also be customized with utility classes on the label element.

Example
Markup: ../../tv-styleguide/markup-files/radio-buttons.hbs
<div class="inline-block margin-r-16px">
    <input class="tv-radio-button" type="radio" id="my-radio-button" name="myButtons" value="some_value" />
    <label for="my-radio-button">Choose Me</label>
</div>
<div class="inline-block margin-r-16px">
    <input class="tv-radio-button" type="radio" id="my-radio-button-2" name="myButtons" value="some_value_2" />
    <label for="my-radio-button-2">No, Choose Me</label>
</div>
<div class="inline-block margin-r-16px">
    <input class="tv-radio-button" type="radio" id="my-radio-button-3" name="myButtons" value="some_value_3" />
    <label for="my-radio-button-3">No, I'm The Best Choice</label>
</div>
Source: resources/sass/_components/radio-button.scss, line 8

2.5.3 #Components.Selection.Toggle Switch Toggle Switch

Styles a checkbox as a toggle switch.

Example
Markup
<div class="toggle-switch">
    <input class="toggle-switch__input" id="my-toggle" type="checkbox" />
    <label class="toggle-switch__label font-size-16px" for="my-toggle">
        <div class="toggle-switch__visual"></div>
        <span>I'm A Switch</span>
    </label>
</div>
Source: resources/sass/account/toggle-switch.scss, line 1

2.6 #Components.Tables Table

Tables in the "account flow" should start with this base class to create a responsive table with horizontal overflow scrolling

Example
Markup: ../../tv-styleguide/markup-files/account-table.hbs
<div class="account-table" tv-table-list>
    <div class="account-table__container">
        <div class="table-scroll table-scroll-2">
            <div class="scroll-gradient"></div>
            <table>
                <thead>
                    <tr>
                        <th class="account-table__col">Col 1</th>
                        <th class="account-table__col">Col 2</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>Data 1</td>
                        <td>Data 2</td>
                    </tr>
                    <tr>
                        <td>Data 1</td>
                        <td>Data 2</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>
Source: resources/sass/_components/account-table.scss, line 3

2.6.1 #Components.Tables.Data Table Data Table

The most comprehensive version of the data table is used for Contacts/Recipients pages. Most versions of the table have a sticky-positioned header container so that column headers are always visible when scrolling through the rows. The name column is also absolute-positioned for readability when scrolling horizontally. Because of the sticky-positioned header JavaScript is used to sync the horizontal scroll of the header container and rows. JavaScript is also used for the actions dropdown menu in order to give it the correct positioning as its direct ancestor/parent needed to be a static-positioned element to avoid clipping from an overflow rule further up the hierarchy.

Example
Name
Recorded On
Recorded On
Actions
John Doe Jan 1, 2020 Jan 1, 2020
Jane Doe Jan 1, 2020 Jan 1, 2020
Markup: ../../tv-styleguide/markup-files/data-table.hbs
<div class="data-table" role="table" aria-labelledby="page-title-header" aria-label="Guests Table" tabindex="0"
    tv-data-table>
    <div class="data-table__header-container" style="top:0;">
        <div class="scroller" name="guestListHeader" role="row">
            <div class="data-table__header check-col" role="columnheader">
                <label class="tv-checkbox">
                    <input class="tv-checkbox__input" type="checkbox" />
                    <div class="tv-checkbox__visual">
                        <i class="far fa-square"></i>
                        <i class="fas fa-check-square"></i>
                    </div>
                </label>
            </div>
            <div class="data-table__header name-col" role="columnheader">
                Name
                <div class="flex flex-dir-col margin-l-8px font-size-20px">
                    <i class="fa fa-caret-up"></i>
                    <i class="fa fa-caret-down"></i>
                </div>
            </div>
            <div class="data-table__header email-col" role="columnheader">
                Email / Phone
                <div class="flex flex-dir-col margin-l-8px font-size-20px">
                    <i class="fa fa-caret-up"></i>
                    <i class="fa fa-caret-down"></i>
                </div>
            </div>
            <div class="data-table__header recorded-on-col" role="columnheader">
                Recorded On
            </div>
            <div class="data-table__header recorded-on-col" role="columnheader">
                Recorded On
            </div>
            <div class="data-table__header actions-col" role="columnheader">
                Actions
            </div>
        </div>
    </div>
    <div class="data-table__data" name="guestList">
        <table>
            <tbody>
                <tr class="table-row">
                    <td class="data-table__col check-col">
                        <label class="tv-checkbox">
                            <input class="tv-checkbox__input" type="checkbox" />
                            <div class="tv-checkbox__visual">
                                <i class="far fa-square"></i>
                                <i class="fas fa-check-square"></i>
                            </div>
                        </label>
                    </td>
                    <td class="data-table__col name-col pad-r-4px">
                        John Doe
                    </td>
                    <td class="data-table__col email-col" title="johndoe@thankview.com">johndoe@thankview.com</td>
                    <td class="data-table__col recorded-on-col">Jan 1, 2020</td>
                    <td class="data-table__col recorded-on-col">Jan 1, 2020</td>
                    <td class="data-table__col dropdown actions-col" dropdown>
                        <button data-object-id="object-1" class="dropdown-toggle width-100 border-none font-gray-45"
                            dropdown-toggle onclick="positionActionsDropdown(event)">
                            <i class="fa fa-ellipsis-h font-size-24px pointer-events-none"></i>
                        </button>
                        <ul id="object-1-actions" class="dropdown__menu">
                            <li>Action 1</li>
                            <li>Action 2</li>
                            <li>Action 3</li>
                        </ul>
                    </td>
                </tr>
                <tr class="table-row">
                    <td class="data-table__col check-col">
                        <i class="fa fa-square-o font-size-20px relative top-2px" aria-hidden="true"></i>
                    </td>
                    <td class="data-table__col name-col pad-r-4px">
                        Jane Doe
                    </td>
                    <td class="data-table__col email-col" title="janedoe@thankview.com">janedoe@thankview.com</td>
                    <td class="data-table__col recorded-on-col">Jan 1, 2020</td>
                    <td class="data-table__col recorded-on-col">Jan 1, 2020</td>
                    <td class="data-table__col dropdown actions-col" dropdown>
                        <button data-object-id="object-2" class="dropdown-toggle width-100 border-none font-gray-45"
                            dropdown-toggle onclick="positionActionsDropdown(event)">
                            <i class="fa fa-ellipsis-h font-size-24px pointer-events-none"></i>
                        </button>
                        <ul id="object-2-actions" class="dropdown__menu">
                            <li>Action 1</li>
                            <li>Action 2</li>
                            <li>Action 3</li>
                        </ul>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

<script>
    // Only for demonstration in style guide. Refer to data-table component file for production code
    const headers = document.querySelector('.data-table__header-container .scroller');
    const dataTable = document.querySelector('.data-table__data');

    dataTable.addEventListener('scroll', () => {
        headers.scrollLeft = dataTable.scrollLeft;
    });

    const dropdowns = document.querySelectorAll('.data-table__col.actions-col');

    const closeDropdowns = () => {
        dropdowns.forEach((d) => {
            d.classList.remove('open');
        })
    }

    document.addEventListener('click', closeDropdowns);

    const positionActionsDropdown = ($event) => {
        $event.stopPropagation();
        closeDropdowns();
        $event.target.parentElement.classList.toggle('open');

        const objectId = $event.target.dataset.objectId;
        const parentHeight = $event.target.parentNode.offsetHeight;

        const topNew = $event.target.offsetTop + (parentHeight / 2);
        const rightNew = $event.target.parentNode.offsetWidth / 2;

        const dropdownMenu = document.getElementById(objectId + '-actions');
        dropdownMenu.style.top = topNew + 'px';
        dropdownMenu.style.right = rightNew + 'px';
    }
</script>
Source: resources/sass/_components/data-table.scss, line 33

2.6.2 #Components.Tables.With Header Table with Fixed Header

Fixed header tables have the header section "stick" to the top of the page when the table content scrolls vertically

Examples
Default styling
.account-table__header--empty
class used to hide the header when a table is empty
Markup: ../../tv-styleguide/markup-files/account-table-with-header-fixed.hbs
<div class="account-table" tv-table-list>
    <div class="account-table__header">
        <div class="search-field margin-r-4px v-align-middle">
            <form no-validate>
                <i class="fa fa-search"></i>
                <input type="text" placeholder="Search for a Result" />
                <button class="fa fa-times btn--ghost" ng-click="clearSearch($event)"></button>
            </form>
        </div>
        <div class="button-group inline-block v-align-middle width-100 md-width-auto">
            <button class="btn btn--small btn--primary">
                <i class="fa fa-plus" aria-hidden="true"></i> Action 1
            </button>
            <button class="btn btn--small btn--secondary">
                <i class="fa fa-plus" aria-hidden="true"></i> Action 2
            </button>
        </div>
    </div>
    <div class="account-table__container">
        <div class="table-scroll table-scroll-2">
            <div class="scroll-gradient"></div>
            <table>
                <thead>
                    <tr>
                        <th class="account-table__col">Col 1</th>
                        <th class="account-table__col">Col 2</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>Data 1</td>
                        <td>Data 2</td>
                    </tr>
                    <tr>
                        <td>Data 1</td>
                        <td>Data 2</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>
Source: resources/sass/_components/account-table.scss, line 18

2.6.2 #Components.Tables.With Header Table with Header

Tables can include a "header" section containing action buttons, menus or a search field. This is achieved by adding a header div before the account-table__container div

Examples
Default styling
.account-table__header--empty
class used to hide the header when a table is empty
Markup: ../../tv-styleguide/markup-files/account-table-with-header.hbs
<div class="account-table" tv-table-list>
    <div class="account-table__header">
        <div class="search-field margin-r-4px v-align-middle">
            <form no-validate>
                <i class="fa fa-search"></i>
                <input type="text" placeholder="Search for a Result" />
                <button class="fa fa-times btn--ghost" ng-click="clearSearch($event)"></button>
            </form>
        </div>
        <div class="button-group inline-block v-align-middle width-100 md-width-auto">
            <button class="btn btn--small btn--primary">
                <i class="fa fa-plus" aria-hidden="true"></i> Action 1
            </button>
            <button class="btn btn--small btn--secondary">
                <i class="fa fa-plus" aria-hidden="true"></i> Action 2
            </button>
        </div>
    </div>
    <div class="account-table__container">
        <div class="table-scroll table-scroll-2">
            <div class="scroll-gradient"></div>
            <table>
                <thead>
                    <tr>
                        <th class="account-table__col">Col 1</th>
                        <th class="account-table__col">Col 2</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>Data 1</td>
                        <td>Data 2</td>
                    </tr>
                    <tr>
                        <td>Data 1</td>
                        <td>Data 2</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>
Source: resources/sass/_components/account-table.scss, line 51

2.7 #Components.Text Fields Text Field

The associated label for a text input should primarily be styled using utility classes.

Text inputs must have an associated label. The for attribute should contain the id of the corresponding input. We cannot use placeholder text as the only label. In general we should never hide input labels, but if we must, use the sr-only utility class on the label element.

Component for basic text input.

Example
Markup
<label for="my-text-input" class="block font-size-16px font-w-7">My Text Input:</label>
<input class="tv-text-input" type="text" id="my-text-input" placeholder="Type Something Great" />
Source: resources/sass/_components/text-input.scss, line 1

2.7.1 #Components.Text Fields.Search Field Search Field

TODO: This implementation could be improved using input type="search". Doing so at the moment would likely break visual styles. We also need to document how to label the search field for screen readers.

Component to filter search via text input. Wrapper div is styled to match the basic text input field.

Example
Markup
<div class="search-field">
    <form id="search-for-thing">
        <i class="fa fa-search"></i>
        <input type="text" placeholder="Search for a Result" ng-change="updateSearch($event)" />
        <button type="button" class="fa fa-times btn--ghost" title="Clear Search" ng-click="clearSearch($event)">
        </button>
    </form>
</div>
Source: resources/sass/_components/text-input.scss, line 16