diff --git a/docs-site/src/pages/pattern-lab/_patterns/02-components/table/15-table-borderless.twig b/docs-site/src/pages/pattern-lab/_patterns/02-components/table/15-table-borderless.twig index acf4ed218c..79bce0fcad 100644 --- a/docs-site/src/pages/pattern-lab/_patterns/02-components/table/15-table-borderless.twig +++ b/docs-site/src/pages/pattern-lab/_patterns/02-components/table/15-table-borderless.twig @@ -6,7 +6,7 @@ cells: [ "Description", "Team", - "Vehical Form", + "Vehicle Form", ] }, side: { diff --git a/docs-site/src/pages/pattern-lab/_patterns/02-components/table/40-table-with-web-component.twig b/docs-site/src/pages/pattern-lab/_patterns/02-components/table/999-table-with-web-component.twig similarity index 65% rename from docs-site/src/pages/pattern-lab/_patterns/02-components/table/40-table-with-web-component.twig rename to docs-site/src/pages/pattern-lab/_patterns/02-components/table/999-table-with-web-component.twig index e78405382a..fcf8cc5886 100644 --- a/docs-site/src/pages/pattern-lab/_patterns/02-components/table/40-table-with-web-component.twig +++ b/docs-site/src/pages/pattern-lab/_patterns/02-components/table/999-table-with-web-component.twig @@ -1,15 +1,24 @@ -{% macro code_example(code, copy) %} - {% spaceless %} +{% macro code_example(code) %} +
+ {% grid "o-bolt-grid--center" %} + {% cell "u-bolt-width-12/12 u-bolt-width-6/12@small" %} + {{ code }} + {% endcell %} + {% endgrid %} +
+
+ {% spaceless %} {{ code | replace({ '<': '<', '>': '>', }) | trim | raw }} {% endspaceless %} +
{% endmacro %} {% import _self as table_example %} -{% set simple_demo %} +{% set table_demo %} @@ -52,7 +61,60 @@ {% endset %} -{% set advanced_demo %} +{% set table_prop_demo %} + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PtsRebAstStlBlk
Michael Jordan7010251
Toni Kukoc21151034
Steve Kerr522050
Total912732135
+
+{% endset %} + +{% set table_advanced_demo %} @@ -102,7 +164,7 @@ {% endset %} -{% set components_demo %} +{% set table_data_demo %}
@@ -147,7 +209,6 @@ @@ -175,36 +236,27 @@ {% endset %} -{% grid with { - attributes: { - class: [ - "o-bolt-grid--matrix" - ] - } -} %} - {% cell "u-bolt-width-12/12" %} - Web Component Usage - - Bolt Table is a web component that renders a semantic table with Bolt styles. To make a simple table, wrap a semantic <table> element with a <bolt-table> element. - - {{ simple_demo }} - {% include table_example.code_example(simple_demo, true) %} - {% endcell %} - {% cell "u-bolt-width-12/12" %} - Advanced Usage - - Attributes and utility classes are supported on table headers and cells. - - {{ advanced_demo }} - {% include table_example.code_example(advanced_demo, true) %} - {% endcell %} - {% cell "u-bolt-width-12/12" %} - Accepted Data - - Each table header or cell can accept any Bolt web components, HTML markup, or just plain text. - - {{ components_demo }} - {% include table_example.code_example(components_demo, true) %} - {% endcell %} -{% endgrid %} +Web Component Usage + + Bolt Table is a web component that renders a semantic table with Bolt styles. To make a simple table, wrap a semantic <table> element with a <bolt-table> element. + +{% include table_example.code_example(table_demo) %} + +Prop Usage + + Configure the table with the properties specified in the schema. + +{% include table_example.code_example(table_prop_demo) %} + +Advanced Usage + + Attributes and utility classes are supported on table headers and cells. + +{% include table_example.code_example(table_advanced_demo) %} + +Accepted Data + + Each table header or cell can accept any Bolt web components, HTML markup, or just plain text. + +{% include table_example.code_example(table_data_demo) %} diff --git a/packages/components/bolt-blockquote/__tests__/__image_snapshots__/blockquote-js-button-default-bolt-blockquote-w-o-shadow-dom-renders-1-snap.png b/packages/components/bolt-blockquote/__tests__/__image_snapshots__/blockquote-js-button-default-bolt-blockquote-w-o-shadow-dom-renders-1-snap.png index f6caf16cbb..2794ad7c90 100644 Binary files a/packages/components/bolt-blockquote/__tests__/__image_snapshots__/blockquote-js-button-default-bolt-blockquote-w-o-shadow-dom-renders-1-snap.png and b/packages/components/bolt-blockquote/__tests__/__image_snapshots__/blockquote-js-button-default-bolt-blockquote-w-o-shadow-dom-renders-1-snap.png differ diff --git a/packages/components/bolt-blockquote/__tests__/__image_snapshots__/blockquote-js-button-default-bolt-blockquote-with-shadow-dom-renders-1-snap.png b/packages/components/bolt-blockquote/__tests__/__image_snapshots__/blockquote-js-button-default-bolt-blockquote-with-shadow-dom-renders-1-snap.png index f6caf16cbb..e761307b45 100644 Binary files a/packages/components/bolt-blockquote/__tests__/__image_snapshots__/blockquote-js-button-default-bolt-blockquote-with-shadow-dom-renders-1-snap.png and b/packages/components/bolt-blockquote/__tests__/__image_snapshots__/blockquote-js-button-default-bolt-blockquote-with-shadow-dom-renders-1-snap.png differ diff --git a/packages/components/bolt-blockquote/src/blockquote.twig b/packages/components/bolt-blockquote/src/blockquote.twig index 5a198209f0..4d3c44e5af 100644 --- a/packages/components/bolt-blockquote/src/blockquote.twig +++ b/packages/components/bolt-blockquote/src/blockquote.twig @@ -54,7 +54,7 @@ {% if logo %} {% include "@bolt/logo.twig" with logo|merge({ - "lazyload": false, + "lazyload": false, slot: "logo", }) only %} diff --git a/packages/components/bolt-carousel/__tests__/__image_snapshots__/carousel-js-carousel-basic-3-slide-bolt-carousel-renders-w-outer-nav-controls-2-snap.png b/packages/components/bolt-carousel/__tests__/__image_snapshots__/carousel-js-carousel-basic-3-slide-bolt-carousel-renders-w-outer-nav-controls-2-snap.png index 7455699afc..db3ee0c1c0 100644 Binary files a/packages/components/bolt-carousel/__tests__/__image_snapshots__/carousel-js-carousel-basic-3-slide-bolt-carousel-renders-w-outer-nav-controls-2-snap.png and b/packages/components/bolt-carousel/__tests__/__image_snapshots__/carousel-js-carousel-basic-3-slide-bolt-carousel-renders-w-outer-nav-controls-2-snap.png differ diff --git a/packages/components/bolt-table/TESTING.md b/packages/components/bolt-table/TESTING.md new file mode 100644 index 0000000000..496d066741 --- /dev/null +++ b/packages/components/bolt-table/TESTING.md @@ -0,0 +1,47 @@ +# Table component testing steps + +## Table component render as expected (functionally and visually) + +The server-side pre-rendered `bolt-table` component should look almost identical to the client-side rendered version. To verify: + +1. Disable javascript and view the [table Demo page](https://boltdesignsystem.com/pattern-lab/patterns/02-components-table-05-table/02-components-table-05-table.html). +2. Then, enable javascript and watch as the table re-renders on the client-side. +3. The layout should not shift, e.g. the spacing in between each table item should be identical before and after the web component re-renders. + +# Table component functional testing steps + +Functional testing should be performed manually by the QA team across the standard compliment of browsers. In each scenario, browser-type is specified when necessary. If browser type is not specified, the test applies to both "desktop" and "mobile" browsers. + +## Feature: Table + + In order to present items in a table with rows and cells + As a UX designer, developer or content administrator + I need to ensure the "bolt-table" component renders and functions as expected + +## Scenario: format variations + +1. Given I am on the [format variations page](https://boltdesignsystem.com/pattern-lab/patterns/02-components-table-10-table-format-variations/02-components-table-10-table-format-variations.html) +2. When I view the table titled "Regular format" +3. Then I see all text is aligned to the left +4. When I view the table titled "Numeric format" +5. Then I see the side headers are aligned to the right, while text in other cells are center aligned + +## Scenario: borderless table + +1. Given I am on the [borderless demo page](https://boltdesignsystem.com/pattern-lab/patterns/02-components-table-15-table-borderless/02-components-table-15-table-borderless.html) +2. When I view the table titled "Remove the vertical border in between cells" +3. Then I see no vertical dividers in between cells (excluding side headers) + +## Scenario: first column fixed width table + +1. Given I am on the [first column fixed width demo page](https://boltdesignsystem.com/pattern-lab/patterns/02-components-table-20-table-first-column-fixed-width/02-components-table-20-table-first-column-fixed-width.html) +2. When I view the table titled "Set column widths to be flexible", where the first column _is not_ set to fixed width +3. Then I see the column widths are evenly distributed +4. When I view the table titled "Set the width of the first column to be as wide as the longest text", where the first column _is_ set to fixed width +5. Then I see the first column is as wide as the longest text in that particular column + +## Scenario: table with web components + +[table with Web Components](https://boltdesignsystem.com/pattern-lab/patterns/02-components-table-999-table-with-web-component/02-components-table-999-table-with-web-component.html) + +`// This is a purely visual test, use VRT` diff --git a/packages/components/bolt-table/__tests__/__snapshots__/table.js.snap b/packages/components/bolt-table/__tests__/__snapshots__/table.js.snap new file mode 100644 index 0000000000..52986d256e --- /dev/null +++ b/packages/components/bolt-table/__tests__/__snapshots__/table.js.snap @@ -0,0 +1,877 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` Component borderless table: false 1`] = ` + +
SR-44869 - UTF-8 OpenSpan.Updater.Git.dll
+ + + + + + + + + + + + + + + + + + + + + + +
+ + Description + + Team + + Vehicle Form +
+ Optimus Prime + + The awe-inspiring leader of the Autobot forces. Selfless and endlessly courageous, he is the complete opposite of his mortal enemy Megatron. + + Autobots + + Peterbilt Truck +
+ Bumblebee + + One of Optimus Primes most trusted lieutenants. Although he is not the strongest or most powerful of the Autobots, Bumblebee more than makes up for this with a bottomless well of luck, determination and bravery. He would gladly give his life to protect others and stop the Decepticons. + + Autobots + + VW Beetle +
+
+`; + +exports[` Component borderless table: true 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + +
+ + Description + + Team + + Vehicle Form +
+ Optimus Prime + + The awe-inspiring leader of the Autobot forces. Selfless and endlessly courageous, he is the complete opposite of his mortal enemy Megatron. + + Autobots + + Peterbilt Truck +
+ Bumblebee + + One of Optimus Primes most trusted lieutenants. Although he is not the strongest or most powerful of the Autobots, Bumblebee more than makes up for this with a bottomless well of luck, determination and bravery. He would gladly give his life to protect others and stop the Decepticons. + + Autobots + + VW Beetle +
+
+`; + +exports[` Component first column fixed width table: false 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Prop + + Description + + Type +
+ attributes + + Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus. + + + object + +
+ headers + + Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus. + + + object + +
+ rows + + Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus. + + + array + +
+ format + + Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus. + + + string + +
+
+`; + +exports[` Component first column fixed width table: true 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Prop + + Description + + Type +
+ attributes + + Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus. + + + object + +
+ headers + + Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus. + + + object + +
+ rows + + Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus. + + + array + +
+ format + + Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus. + + + string + +
+
+`; + +exports[` Component table format: numeric 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + Pts + + Reb + + Ast + + Stl + + Blk +
+ Michael Jordan + + 70 + + 10 + + 2 + + 5 + + 1 +
+ Toni Kukoc + + 21 + + 15 + + 10 + + 3 + + 4 +
+ Steve Kerr + + 5 + + 2 + + 20 + + 5 + + 0 +
+ Total + + 91 + + 27 + + 32 + + 13 + + 5 +
+
+`; + +exports[` Component table format: regular 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + Pts + + Reb + + Ast + + Stl + + Blk +
+ Michael Jordan + + 70 + + 10 + + 2 + + 5 + + 1 +
+ Toni Kukoc + + 21 + + 15 + + 10 + + 3 + + 4 +
+ Steve Kerr + + 5 + + 2 + + 20 + + 5 + + 0 +
+ Total + + 91 + + 27 + + 32 + + 13 + + 5 +
+
+`; + +exports[` Component table with rows only 1`] = ` + + + + + + + + + + + + + + + + + + + +
+ R1C1 + + R1C2 + + R1C3 +
+ R2C1 + + R2C2 + + R2C3 +
+ R3C1 + + R3C2 + + R3C3 +
+
+`; + +exports[` Component table with side headers 1`] = ` + + + + + + + + + + + + + + + + + + + + + + +
+ Row 1 + + R1C1 + + R1C2 + + R1C3 +
+ Row 2 + + R2C1 + + R2C2 + + R2C3 +
+ Row 3 + + R3C1 + + R3C2 + + R3C3 +
+
+`; + +exports[` Component table with top and side headers 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + Column 1 + + Column 2 + + Column 3 +
+ Row 1 + + R1C1 + + R1C2 + + R1C3 +
+ Row 2 + + R2C1 + + R2C2 + + R2C3 +
+ Row 3 + + R3C1 + + R3C2 + + R3C3 +
+
+`; + +exports[` Component table with top and side headers 2`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + Column 1 + + Column 2 + + Column 3 +
+ Row 1 + + R1C1 + + R1C2 + + R1C3 +
+ Row 2 + + R2C1 + + R2C2 + + R2C3 +
+ Row 3 + + R3C1 + + R3C2 + + R3C3 +
+ Footer + + FC1 + + FC2 + + FC3 +
+
+`; + +exports[` Component table with top headers 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Column 1 + + Column 2 + + Column 3 +
+ R1C1 + + R1C2 + + R1C3 +
+ R2C1 + + R2C2 + + R2C3 +
+ R3C1 + + R3C2 + + R3C3 +
+
+`; diff --git a/packages/components/bolt-table/__tests__/table.js b/packages/components/bolt-table/__tests__/table.js new file mode 100644 index 0000000000..83231e6bca --- /dev/null +++ b/packages/components/bolt-table/__tests__/table.js @@ -0,0 +1,257 @@ +/* eslint-disable camelcase */ + +import { + render, + renderString, + stop as stopTwigRenderer, +} from '@bolt/twig-renderer'; +const { readYamlFileSync } = require('@bolt/build-tools/utils/yaml'); +const { join } = require('path'); +const schema = readYamlFileSync(join(__dirname, '../table.schema.yml')); +const { format, borderless, first_col_fixed_width } = schema.properties; + +async function renderTwig(template, data) { + return await render(template, data, true); +} + +async function renderTwigString(template, data) { + return await renderString(template, data, true); +} + +const timeout = 60000; + +describe(' Component', () => { + afterAll(async () => { + await stopTwigRenderer(); + }, timeout); + + test('table with rows only', async () => { + const results = await renderTwig('@bolt-components-table/table.twig', { + rows: [ + { + cells: ['R1C1', 'R1C2', 'R1C3'], + }, + { + cells: ['R2C1', 'R2C2', 'R2C3'], + }, + { + cells: ['R3C1', 'R3C2', 'R3C3'], + }, + ], + }); + expect(results.ok).toBe(true); + expect(results.html).toMatchSnapshot(); + }); + + test('table with top headers', async () => { + const results = await renderTwig('@bolt-components-table/table.twig', { + headers: { + top: { + cells: ['Column 1', 'Column 2', 'Column 3'], + }, + }, + rows: [ + { + cells: ['R1C1', 'R1C2', 'R1C3'], + }, + { + cells: ['R2C1', 'R2C2', 'R2C3'], + }, + { + cells: ['R3C1', 'R3C2', 'R3C3'], + }, + ], + }); + expect(results.ok).toBe(true); + expect(results.html).toMatchSnapshot(); + }); + + test('table with side headers', async () => { + const results = await renderTwig('@bolt-components-table/table.twig', { + headers: { + side: { + cells: ['Row 1', 'Row 2', 'Row 3', 'Footer'], + }, + }, + rows: [ + { + cells: ['R1C1', 'R1C2', 'R1C3'], + }, + { + cells: ['R2C1', 'R2C2', 'R2C3'], + }, + { + cells: ['R3C1', 'R3C2', 'R3C3'], + }, + ], + }); + expect(results.ok).toBe(true); + expect(results.html).toMatchSnapshot(); + }); + + test('table with top and side headers', async () => { + const results = await renderTwig('@bolt-components-table/table.twig', { + headers: { + top: { + cells: ['Column 1', 'Column 2', 'Column 3'], + }, + side: { + cells: ['Row 1', 'Row 2', 'Row 3', 'Footer'], + }, + }, + rows: [ + { + cells: ['R1C1', 'R1C2', 'R1C3'], + }, + { + cells: ['R2C1', 'R2C2', 'R2C3'], + }, + { + cells: ['R3C1', 'R3C2', 'R3C3'], + }, + ], + }); + expect(results.ok).toBe(true); + expect(results.html).toMatchSnapshot(); + }); + + test('table with top and side headers', async () => { + const results = await renderTwig('@bolt-components-table/table.twig', { + headers: { + top: { + cells: ['Column 1', 'Column 2', 'Column 3'], + }, + side: { + cells: ['Row 1', 'Row 2', 'Row 3', 'Footer'], + }, + }, + rows: [ + { + cells: ['R1C1', 'R1C2', 'R1C3'], + }, + { + cells: ['R2C1', 'R2C2', 'R2C3'], + }, + { + cells: ['R3C1', 'R3C2', 'R3C3'], + }, + ], + footer: { + cells: ['FC1', 'FC2', 'FC3'], + }, + }); + expect(results.ok).toBe(true); + expect(results.html).toMatchSnapshot(); + }); + + format.enum.forEach(async option => { + test(`table format: ${option}`, async () => { + const results = await renderTwig('@bolt-components-table/table.twig', { + format: option, + headers: { + top: { + cells: ['Pts', 'Reb', 'Ast', 'Stl', 'Blk'], + }, + side: { + cells: ['Michael Jordan', 'Toni Kukoc', 'Steve Kerr', 'Total'], + }, + }, + rows: [ + { + cells: ['70', '10', '2', '5', '1'], + }, + { + cells: ['21', '15', '10', '3', '4'], + }, + { + cells: ['5', '2', '20', '5', '0'], + }, + ], + footer: { + cells: ['91', '27', '32', '13', '5'], + }, + }); + expect(results.ok).toBe(true); + expect(results.html).toMatchSnapshot(); + }); + }); + + borderless.enum.forEach(async option => { + test(`borderless table: ${option}`, async () => { + const results = await renderTwig('@bolt-components-table/table.twig', { + borderless: option, + headers: { + top: { + cells: ['Description', 'Team', 'Vehicle Form'], + }, + side: { + cells: ['Optimus Prime', 'Bumblebee'], + }, + }, + rows: [ + { + cells: [ + 'The awe-inspiring leader of the Autobot forces. Selfless and endlessly courageous, he is the complete opposite of his mortal enemy Megatron.', + 'Autobots', + 'Peterbilt Truck', + ], + }, + { + cells: [ + 'One of Optimus Primes most trusted lieutenants. Although he is not the strongest or most powerful of the Autobots, Bumblebee more than makes up for this with a bottomless well of luck, determination and bravery. He would gladly give his life to protect others and stop the Decepticons.', + 'Autobots', + 'VW Beetle', + ], + }, + ], + }); + expect(results.ok).toBe(true); + expect(results.html).toMatchSnapshot(); + }); + }); + + first_col_fixed_width.enum.forEach(async option => { + test(`first column fixed width table: ${option}`, async () => { + const results = await renderTwig('@bolt-components-table/table.twig', { + first_col_fixed_width: option, + headers: { + top: { + cells: ['Prop', 'Description', 'Type'], + }, + }, + rows: [ + { + cells: [ + 'attributes', + 'Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus.', + 'object', + ], + }, + { + cells: [ + 'headers', + 'Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus.', + 'object', + ], + }, + { + cells: [ + 'rows', + 'Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus.', + 'array', + ], + }, + { + cells: [ + 'format', + 'Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus.', + 'string', + ], + }, + ], + }); + expect(results.ok).toBe(true); + expect(results.html).toMatchSnapshot(); + }); + }); +}); diff --git a/packages/components/bolt-table/table.schema.yml b/packages/components/bolt-table/table.schema.yml index 8378304276..44177cbb53 100644 --- a/packages/components/bolt-table/table.schema.yml +++ b/packages/components/bolt-table/table.schema.yml @@ -76,7 +76,13 @@ properties: type: boolean description: Removes the vertical border in between cells. default: false + enum: + - true + - false first_col_fixed_width: type: boolean description: Sets the width of the first column to be as wide as the longest text. default: false + enum: + - true + - false