mirror of
https://github.com/kemko/nomad.git
synced 2026-01-05 18:05:42 +03:00
Styleguide entry for tables
This commit is contained in:
159
ui/app/components/freestyle/sg-table.js
Normal file
159
ui/app/components/freestyle/sg-table.js
Normal file
@@ -0,0 +1,159 @@
|
||||
import Component from '@ember/component';
|
||||
import { computed } from '@ember/object';
|
||||
|
||||
export default Component.extend({
|
||||
searchTerm: '',
|
||||
|
||||
currentPage: 1,
|
||||
sortProperty: 'name',
|
||||
sortDescending: false,
|
||||
|
||||
shortList: [
|
||||
{
|
||||
name: 'Nomad',
|
||||
lang: 'golang',
|
||||
desc:
|
||||
'Nomad is a flexible, enterprise-grade cluster scheduler designed to easily integrate into existing workflows. Nomad can run a diverse workload of micro-service, batch, containerized and non-containerized applications.',
|
||||
link: 'https://www.nomadproject.io/',
|
||||
},
|
||||
{
|
||||
name: 'Terraform',
|
||||
lang: 'golang',
|
||||
desc:
|
||||
'Terraform is a tool for building, changing, and combining infrastructure safely and efficiently.',
|
||||
link: 'https://www.terraform.io/',
|
||||
},
|
||||
{
|
||||
name: 'Vault',
|
||||
lang: 'golang',
|
||||
desc:
|
||||
'A tool for secrets management, encryption as a service, and privileged access management',
|
||||
link: 'https://www.vaultproject.io/',
|
||||
},
|
||||
{
|
||||
name: 'Consul',
|
||||
lang: 'golang',
|
||||
desc:
|
||||
'Consul is a distributed, highly available, and data center aware solution to connect and configure applications across dynamic, distributed infrastructure.',
|
||||
link: 'https://www.consul.io/',
|
||||
},
|
||||
{
|
||||
name: 'Vagrant',
|
||||
lang: 'ruby',
|
||||
desc: 'Vagrant is a tool for building and distributing development environments.',
|
||||
link: 'https://www.vagrantup.com/',
|
||||
},
|
||||
{
|
||||
name: 'Packer',
|
||||
lang: 'golang',
|
||||
desc:
|
||||
'Packer is a tool for creating identical machine images for multiple platforms from a single source configuration.',
|
||||
link: 'https://www.packer.io/',
|
||||
},
|
||||
],
|
||||
|
||||
longList: [
|
||||
{ city: 'New York', growth: 0.048, population: '8405837', rank: '1', state: 'New York' },
|
||||
{ city: 'Los Angeles', growth: 0.048, population: '3884307', rank: '2', state: 'California' },
|
||||
{ city: 'Chicago', growth: -0.061, population: '2718782', rank: '3', state: 'Illinois' },
|
||||
{ city: 'Houston', growth: 0.11, population: '2195914', rank: '4', state: 'Texas' },
|
||||
{
|
||||
city: 'Philadelphia',
|
||||
growth: 0.026,
|
||||
population: '1553165',
|
||||
rank: '5',
|
||||
state: 'Pennsylvania',
|
||||
},
|
||||
{ city: 'Phoenix', growth: 0.14, population: '1513367', rank: '6', state: 'Arizona' },
|
||||
{ city: 'San Antonio', growth: 0.21, population: '1409019', rank: '7', state: 'Texas' },
|
||||
{ city: 'San Diego', growth: 0.105, population: '1355896', rank: '8', state: 'California' },
|
||||
{ city: 'Dallas', growth: 0.056, population: '1257676', rank: '9', state: 'Texas' },
|
||||
{ city: 'San Jose', growth: 0.105, population: '998537', rank: '10', state: 'California' },
|
||||
{ city: 'Austin', growth: 0.317, population: '885400', rank: '11', state: 'Texas' },
|
||||
{ city: 'Indianapolis', growth: 0.078, population: '843393', rank: '12', state: 'Indiana' },
|
||||
{ city: 'Jacksonville', growth: 0.143, population: '842583', rank: '13', state: 'Florida' },
|
||||
{
|
||||
city: 'San Francisco',
|
||||
growth: 0.077,
|
||||
population: '837442',
|
||||
rank: '14',
|
||||
state: 'California',
|
||||
},
|
||||
{ city: 'Columbus', growth: 0.148, population: '822553', rank: '15', state: 'Ohio' },
|
||||
{
|
||||
city: 'Charlotte',
|
||||
growth: 0.391,
|
||||
population: '792862',
|
||||
rank: '16',
|
||||
state: 'North Carolina',
|
||||
},
|
||||
{ city: 'Fort Worth', growth: 0.451, population: '792727', rank: '17', state: 'Texas' },
|
||||
{ city: 'Detroit', growth: -0.271, population: '688701', rank: '18', state: 'Michigan' },
|
||||
{ city: 'El Paso', growth: 0.194, population: '674433', rank: '19', state: 'Texas' },
|
||||
{ city: 'Memphis', growth: -0.053, population: '653450', rank: '20', state: 'Tennessee' },
|
||||
{ city: 'Seattle', growth: 0.156, population: '652405', rank: '21', state: 'Washington' },
|
||||
{ city: 'Denver', growth: 0.167, population: '649495', rank: '22', state: 'Colorado' },
|
||||
{
|
||||
city: 'Washington',
|
||||
growth: 0.13,
|
||||
population: '646449',
|
||||
rank: '23',
|
||||
state: 'District of Columbia',
|
||||
},
|
||||
{ city: 'Boston', growth: 0.094, population: '645966', rank: '24', state: 'Massachusetts' },
|
||||
{
|
||||
city: 'Nashville-Davidson',
|
||||
growth: 0.162,
|
||||
population: '634464',
|
||||
rank: '25',
|
||||
state: 'Tennessee',
|
||||
},
|
||||
{ city: 'Baltimore', growth: -0.04, population: '622104', rank: '26', state: 'Maryland' },
|
||||
{ city: 'Oklahoma City', growth: 0.202, population: '610613', rank: '27', state: 'Oklahoma' },
|
||||
{
|
||||
city: 'Louisville/Jefferson County',
|
||||
growth: 0.1,
|
||||
population: '609893',
|
||||
rank: '28',
|
||||
state: 'Kentucky',
|
||||
},
|
||||
{ city: 'Portland', growth: 0.15, population: '609456', rank: '29', state: 'Oregon' },
|
||||
{ city: 'Las Vegas', growth: 0.245, population: '603488', rank: '30', state: 'Nevada' },
|
||||
{ city: 'Milwaukee', growth: 0.003, population: '599164', rank: '31', state: 'Wisconsin' },
|
||||
{ city: 'Albuquerque', growth: 0.235, population: '556495', rank: '32', state: 'New Mexico' },
|
||||
{ city: 'Tucson', growth: 0.075, population: '526116', rank: '33', state: 'Arizona' },
|
||||
{ city: 'Fresno', growth: 0.183, population: '509924', rank: '34', state: 'California' },
|
||||
{ city: 'Sacramento', growth: 0.172, population: '479686', rank: '35', state: 'California' },
|
||||
{ city: 'Long Beach', growth: 0.015, population: '469428', rank: '36', state: 'California' },
|
||||
{ city: 'Kansas City', growth: 0.055, population: '467007', rank: '37', state: 'Missouri' },
|
||||
{ city: 'Mesa', growth: 0.135, population: '457587', rank: '38', state: 'Arizona' },
|
||||
{ city: 'Virginia Beach', growth: 0.051, population: '448479', rank: '39', state: 'Virginia' },
|
||||
{ city: 'Atlanta', growth: 0.062, population: '447841', rank: '40', state: 'Georgia' },
|
||||
{
|
||||
city: 'Colorado Springs',
|
||||
growth: 0.214,
|
||||
population: '439886',
|
||||
rank: '41',
|
||||
state: 'Colorado',
|
||||
},
|
||||
{ city: 'Omaha', growth: 0.059, population: '434353', rank: '42', state: 'Nebraska' },
|
||||
{ city: 'Raleigh', growth: 0.487, population: '431746', rank: '43', state: 'North Carolina' },
|
||||
{ city: 'Miami', growth: 0.149, population: '417650', rank: '44', state: 'Florida' },
|
||||
{ city: 'Oakland', growth: 0.013, population: '406253', rank: '45', state: 'California' },
|
||||
{ city: 'Minneapolis', growth: 0.045, population: '400070', rank: '46', state: 'Minnesota' },
|
||||
{ city: 'Tulsa', growth: 0.013, population: '398121', rank: '47', state: 'Oklahoma' },
|
||||
{ city: 'Cleveland', growth: -0.181, population: '390113', rank: '48', state: 'Ohio' },
|
||||
{ city: 'Wichita', growth: 0.097, population: '386552', rank: '49', state: 'Kansas' },
|
||||
{ city: 'Arlington', growth: 0.133, population: '379577', rank: '50', state: 'Texas' },
|
||||
],
|
||||
|
||||
filteredShortList: computed('searchTerm', 'shortList.[]', function() {
|
||||
const term = this.get('searchTerm').toLowerCase();
|
||||
return this.get('shortList').filter(product => product.name.toLowerCase().includes(term));
|
||||
}),
|
||||
|
||||
sortedShortList: computed('shortList.[]', 'sortProperty', 'sortDescending', function() {
|
||||
const sorted = this.get('shortList').sortBy(this.get('sortProperty'));
|
||||
return this.get('sortDescending') ? sorted.reverse() : sorted;
|
||||
}),
|
||||
});
|
||||
@@ -2,5 +2,15 @@ import { inject as service } from '@ember/service';
|
||||
import FreestyleController from 'ember-freestyle/controllers/freestyle';
|
||||
|
||||
export default FreestyleController.extend({
|
||||
queryParams: {
|
||||
currentPage: 'page',
|
||||
sortProperty: 'sort',
|
||||
sortDescending: 'desc',
|
||||
},
|
||||
|
||||
currentPage: 1,
|
||||
sortProperty: 'name',
|
||||
sortDescending: true,
|
||||
|
||||
emberFreestyle: service(),
|
||||
});
|
||||
|
||||
257
ui/app/templates/components/freestyle/sg-table.hbs
Normal file
257
ui/app/templates/components/freestyle/sg-table.hbs
Normal file
@@ -0,0 +1,257 @@
|
||||
{{#freestyle-usage "table-simple" title="Table"}}
|
||||
{{#list-table source=shortList as |t|}}
|
||||
{{#t.head}}
|
||||
<th>Name</th>
|
||||
<th>Language</th>
|
||||
<th>Description</th>
|
||||
{{/t.head}}
|
||||
{{#t.body key="model.name" as |row|}}
|
||||
<tr>
|
||||
<td>{{row.model.name}}</td>
|
||||
<td>{{row.model.lang}}</td>
|
||||
<td>{{row.model.desc}}</td>
|
||||
</tr>
|
||||
{{/t.body}}
|
||||
{{/list-table}}
|
||||
{{/freestyle-usage}}
|
||||
{{#freestyle-annotation}}
|
||||
<p>Tables have airy designs with a minimal amount of borders. This maximizes their utility.</p>
|
||||
{{/freestyle-annotation}}
|
||||
|
||||
{{#freestyle-usage "table-search" title="Table Search"}}
|
||||
<div class="boxed-section">
|
||||
<div class="boxed-section-head">
|
||||
Table Name
|
||||
{{search-box
|
||||
searchTerm=(mut searchTerm)
|
||||
placeholder="Search..."
|
||||
class="is-inline pull-right"
|
||||
inputClass="is-compact"}}
|
||||
</div>
|
||||
<div class="boxed-section-body {{if filteredShortList.length "is-full-bleed"}}">
|
||||
{{#if filteredShortList.length}}
|
||||
{{#list-table source=filteredShortList as |t|}}
|
||||
{{#t.head}}
|
||||
<th>Name</th>
|
||||
<th>Language</th>
|
||||
<th>Description</th>
|
||||
{{/t.head}}
|
||||
{{#t.body key="model.name" as |row|}}
|
||||
<tr>
|
||||
<td>{{row.model.name}}</td>
|
||||
<td>{{row.model.lang}}</td>
|
||||
<td>{{row.model.desc}}</td>
|
||||
</tr>
|
||||
{{/t.body}}
|
||||
{{/list-table}}
|
||||
{{else}}
|
||||
<div class="empty-message">
|
||||
<h3 class="empty-message-headline">No Matches</h3>
|
||||
<p class="empty-message-body">No products match your query.</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{/freestyle-usage}}
|
||||
{{#freestyle-annotation}}
|
||||
<p>Tables compose with boxed-section and boxed-section composes with search box.</p>
|
||||
{{/freestyle-annotation}}
|
||||
|
||||
{{#freestyle-usage "table-sortable-columns" title="Table Sortable Columns"}}
|
||||
{{#list-table
|
||||
source=sortedShortList
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending as |t|}}
|
||||
{{#t.head}}
|
||||
{{#t.sort-by prop="name"}}Name{{/t.sort-by}}
|
||||
{{#t.sort-by prop="lang" class="is-2"}}Language{{/t.sort-by}}
|
||||
<th>Description</th>
|
||||
{{/t.head}}
|
||||
{{#t.body key="model.name" as |row|}}
|
||||
<tr>
|
||||
<td>{{row.model.name}}</td>
|
||||
<td>{{row.model.lang}}</td>
|
||||
<td>{{row.model.desc}}</td>
|
||||
</tr>
|
||||
{{/t.body}}
|
||||
{{/list-table}}
|
||||
{{/freestyle-usage}}
|
||||
{{#freestyle-annotation}}
|
||||
<p>The list-table component provides a <code>sort-by</code> contextual component for building <code>link-to</code> components with the appropriate query params.</p>
|
||||
<p>This leaves the component stateless, relying on data to be passed down and sending actions back up via the router (via link-to).</p>
|
||||
{{/freestyle-annotation}}
|
||||
|
||||
{{#freestyle-usage "table-multi-row" title="Table Multi-row"}}
|
||||
{{#list-table
|
||||
source=sortedShortList
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
class="is-striped" as |t|}}
|
||||
{{#t.head}}
|
||||
{{#t.sort-by prop="name"}}Name{{/t.sort-by}}
|
||||
{{#t.sort-by prop="lang"}}Language{{/t.sort-by}}
|
||||
{{/t.head}}
|
||||
{{#t.body key="model.name" as |row|}}
|
||||
<tr>
|
||||
<td>{{row.model.name}}</td>
|
||||
<td>{{row.model.lang}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{{row.model.desc}}</td>
|
||||
</tr>
|
||||
{{/t.body}}
|
||||
{{/list-table}}
|
||||
{{/freestyle-usage}}
|
||||
{{#freestyle-annotation}}
|
||||
<p>THe list-table component attempts to be as flexible as possible. For this reason, <code>t.body</code> does not provide the typical <code>tr</code> element. It's sometimes desired to have multiple elements per record.</p>
|
||||
{{/freestyle-annotation}}
|
||||
|
||||
{{#freestyle-usage "table-pagination" title="Table Pagination"}}
|
||||
{{#list-pagination source=longList size=5 page=currentPage as |p|}}
|
||||
{{#list-table source=p.list class="with-foot" as |t|}}
|
||||
{{#t.head}}
|
||||
<th class="is-1">Rank</th>
|
||||
<th>City</th>
|
||||
<th>State</th>
|
||||
<th>Population</th>
|
||||
<th>Growth</th>
|
||||
{{/t.head}}
|
||||
{{#t.body key="model.rank" as |row|}}
|
||||
<tr>
|
||||
<td>{{row.model.rank}}</td>
|
||||
<td>{{row.model.city}}</td>
|
||||
<td>{{row.model.state}}</td>
|
||||
<td>{{row.model.population}}</td>
|
||||
<td>{{format-percentage row.model.growth total=1}}</td>
|
||||
</tr>
|
||||
{{/t.body}}
|
||||
{{/list-table}}
|
||||
<div class="table-foot">
|
||||
<nav class="pagination">
|
||||
<span class="bumper-left">U.S. City population and growth from 2000-2013</span>
|
||||
<div class="pagination-numbers">
|
||||
{{p.startsAt}}–{{p.endsAt}} of {{longList.length}}
|
||||
</div>
|
||||
{{#p.prev class="pagination-previous"}} < {{/p.prev}}
|
||||
{{#p.next class="pagination-next"}} > {{/p.next}}
|
||||
<ul class="pagination-list"></ul>
|
||||
</nav>
|
||||
</div>
|
||||
{{/list-pagination}}
|
||||
{{/freestyle-usage}}
|
||||
{{#freestyle-annotation}}
|
||||
<p>Pagination works like sorting: using <code>link-to</code>s to set a query param.</p>
|
||||
<p>Pagination, like Table, is a minimal design. Only a next and previous button are available. The current place in the set of pages is tracked by showing which slice of items is currently shown.</p>
|
||||
<p>The pagination component exposes first and last components (for jumping to the beginning and end of a list) as well as pageLinks for generating links around the current page.</p>
|
||||
{{/freestyle-annotation}}
|
||||
|
||||
{{#freestyle-usage "table-row-links" title="Table Row Links"}}
|
||||
{{#list-table source=shortList as |t|}}
|
||||
{{#t.head}}
|
||||
<th>Name</th>
|
||||
<th>Language</th>
|
||||
<th>Description</th>
|
||||
{{/t.head}}
|
||||
{{#t.body key="model.name" as |row|}}
|
||||
<tr class="is-interactive">
|
||||
<td><a href="#" class="is-primary">{{row.model.name}}</a></td>
|
||||
<td>{{row.model.lang}}</td>
|
||||
<td>{{row.model.desc}}</td>
|
||||
</tr>
|
||||
{{/t.body}}
|
||||
{{/list-table}}
|
||||
{{/freestyle-usage}}
|
||||
{{#freestyle-annotation}}
|
||||
<p>It is common for tables to act as lists of links, (e.g., clients list all allocations, each row links to the allocation detail). The helper class <code>is-interactive</code> on the <code>tr</code> makes table rows have a pointer cursor. The helper class <code>is-primary</code> on the <code>a</code> element in a table row makes the link bold and black instead of blue. This makes the link stand out less, since the entire row is a link.</p>
|
||||
<p>A few rules for using table row links:</p>
|
||||
<ol>
|
||||
<li>The <code>is-primary</code> cell should always be the first cell</li>
|
||||
<li>The <code>is-primary</code> cell should always contain a link to the destination in the form of an <code>a</code> element. This is to support opening a link in a new tab.</li>
|
||||
<li>The full row should transition to the destination on click. This is to improve the usability of a table by creating a larger click area.</li>
|
||||
</ol>
|
||||
{{/freestyle-annotation}}
|
||||
|
||||
{{#freestyle-usage "table-cell-links" title="Table Cell Links"}}
|
||||
{{#list-table source=shortList as |t|}}
|
||||
{{#t.head}}
|
||||
<th>Name</th>
|
||||
<th>Language</th>
|
||||
<th>Description</th>
|
||||
{{/t.head}}
|
||||
{{#t.body key="model.name" as |row|}}
|
||||
<tr>
|
||||
<td><a href={{row.model.link}}>{{row.model.name}}</a></td>
|
||||
<td>{{row.model.lang}}</td>
|
||||
<td>{{row.model.desc}}</td>
|
||||
</tr>
|
||||
{{/t.body}}
|
||||
{{/list-table}}
|
||||
{{/freestyle-usage}}
|
||||
{{#freestyle-annotation}}
|
||||
<p>Links in table cells are just links.</p>
|
||||
{{/freestyle-annotation}}
|
||||
|
||||
{{#freestyle-usage "table-cell-decorations" title="Table Cell Decorations"}}
|
||||
{{#list-table source=shortList as |t|}}
|
||||
{{#t.head}}
|
||||
<th>Name</th>
|
||||
<th>Language</th>
|
||||
<th>Description</th>
|
||||
{{/t.head}}
|
||||
{{#t.body key="model.name" as |row|}}
|
||||
<tr>
|
||||
<td><a href={{row.model.link}}>{{row.model.name}}</a></td>
|
||||
<td class="nowrap">
|
||||
<span class="color-swatch
|
||||
{{if (eq row.model.lang "ruby") "swatch-6"}}
|
||||
{{if (eq row.model.lang "golang") "swatch-5"}}" />
|
||||
{{row.model.lang}}
|
||||
</td>
|
||||
<td>{{row.model.desc}}</td>
|
||||
</tr>
|
||||
{{/t.body}}
|
||||
{{/list-table}}
|
||||
{{/freestyle-usage}}
|
||||
{{#freestyle-annotation}}
|
||||
<p>Small icons and accents of color make tables easier to scan.</p>
|
||||
{{/freestyle-annotation}}
|
||||
|
||||
{{#freestyle-usage "table-cell-icons" title="Table Cell Icons"}}
|
||||
{{#list-pagination source=longList size=5 page=currentPage as |p|}}
|
||||
{{#list-table source=p.list class="with-foot" as |t|}}
|
||||
{{#t.head}}
|
||||
<th class="is-narrow"></th>
|
||||
<th class="is-1">Rank</th>
|
||||
<th>City</th>
|
||||
<th>State</th>
|
||||
<th>Population</th>
|
||||
<th>Growth</th>
|
||||
{{/t.head}}
|
||||
{{#t.body key="model.rank" as |row|}}
|
||||
<tr>
|
||||
<td class="is-narrow">
|
||||
{{#if (lt row.model.growth 0)}}
|
||||
{{x-icon "warning" class="is-warning"}}
|
||||
{{/if}}
|
||||
</td>
|
||||
<td>{{row.model.rank}}</td>
|
||||
<td>{{row.model.city}}</td>
|
||||
<td>{{row.model.state}}</td>
|
||||
<td>{{row.model.population}}</td>
|
||||
<td>{{format-percentage row.model.growth total=1}}</td>
|
||||
</tr>
|
||||
{{/t.body}}
|
||||
{{/list-table}}
|
||||
<div class="table-foot">
|
||||
<nav class="pagination">
|
||||
<span class="bumper-left">U.S. City population and growth from 2000-2013. Cities with negative growth denoted.</span>
|
||||
<div class="pagination-numbers">
|
||||
{{p.startsAt}}–{{p.endsAt}} of {{longList.length}}
|
||||
</div>
|
||||
{{#p.prev class="pagination-previous"}} < {{/p.prev}}
|
||||
{{#p.next class="pagination-next"}} > {{/p.next}}
|
||||
<ul class="pagination-list"></ul>
|
||||
</nav>
|
||||
</div>
|
||||
{{/list-pagination}}
|
||||
{{/freestyle-usage}}
|
||||
@@ -71,8 +71,14 @@
|
||||
{{#section.subsection name="Search box"}}
|
||||
{{freestyle/sg-search-box}}
|
||||
{{/section.subsection}}
|
||||
|
||||
{{#section.subsection name="Table"}}
|
||||
{{freestyle/sg-table
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
currentPage=currentPage}}
|
||||
{{/section.subsection}}
|
||||
|
||||
{{#section.subsection name="Table, Configuration"}}
|
||||
{{/section.subsection}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user