diff --git a/client/i18n/locales/english/intro.json b/client/i18n/locales/english/intro.json index 6fa70e28ca5..f9f56646602 100644 --- a/client/i18n/locales/english/intro.json +++ b/client/i18n/locales/english/intro.json @@ -1857,7 +1857,10 @@ "scec": { "title": "107", "intro": [] }, "mtbl": { "title": "108", "intro": [] }, "vlov": { "title": "109", "intro": [] }, - "njkq": { "title": "110", "intro": [] }, + "lab-availability-table": { + "title": "Build an Availability Table", + "intro": ["For this lab, you will create an availability table."] + }, "sget": { "title": "111", "intro": [] }, "huge": { "title": "112", "intro": [] }, "agbl": { "title": "113", "intro": [] }, diff --git a/client/src/pages/learn/front-end-development/lab-availability-table/index.md b/client/src/pages/learn/front-end-development/lab-availability-table/index.md new file mode 100644 index 00000000000..e9e1bb94ee4 --- /dev/null +++ b/client/src/pages/learn/front-end-development/lab-availability-table/index.md @@ -0,0 +1,9 @@ +--- +title: Introduction to the Build an Availability Table +block: lab-availability-table +superBlock: front-end-development +--- + +## Introduction to the Build an Availability Table + +For this lab, you will create an availability table. diff --git a/curriculum/challenges/_meta/lab-availability-table/meta.json b/curriculum/challenges/_meta/lab-availability-table/meta.json new file mode 100644 index 00000000000..881ee2b500f --- /dev/null +++ b/curriculum/challenges/_meta/lab-availability-table/meta.json @@ -0,0 +1,11 @@ +{ + "name": "Build an Availability Table", + "blockType": "lab", + "isUpcomingChange": true, + "usesMultifileEditor": true, + "dashedName": "lab-availability-table", + "order": 110, + "superBlock": "front-end-development", + "challengeOrder": [{ "id": "66b36358ed4f261d64840c24", "title": "Build an Availability Table" }], + "helpCategory": "HTML-CSS" +} diff --git a/curriculum/challenges/english/25-front-end-development/lab-availability-table/66b36358ed4f261d64840c24.md b/curriculum/challenges/english/25-front-end-development/lab-availability-table/66b36358ed4f261d64840c24.md new file mode 100644 index 00000000000..4a177c3db36 --- /dev/null +++ b/curriculum/challenges/english/25-front-end-development/lab-availability-table/66b36358ed4f261d64840c24.md @@ -0,0 +1,603 @@ +--- +id: 66b36358ed4f261d64840c24 +title: Build an Availability Table +challengeType: 14 +dashedName: build-an-availability-table +demoType: onClick +--- + +# --description-- + +**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab. + +**User Stories:** + +1. You should have a table with at least three columns and five rows, headers included. +1. Cells in the first row should be table headers containing days of the week. +1. Cells in the first column should be table headers with a `class` of `time` and should contain time values as their text. +1. All data cells should have the `class` of `available-#`, where `#` is a number from `0` to `5` that specifies the number of available people at that time. +1. In your `:root` selector, you should define six CSS variables named `--color#`, where `#` is a number from `0` to `5`, and assign them each a color value. Use these variables to set the background color of the corresponding `.available-#` elements. +1. In your `:root` selector, you should define CSS variables named `--solid-border` and `--dashed-border`. Use these variables to style the bottom borders of your data cells, alternating between solid and dashed borders depending on the row. Give the rows either the class of `sharp` or `half` to style them. +1. You should have a `div` element with the `id` of `legend`. It should contain a `span` element with the text `Availability` and a `div` element with the `id` of `legend-gradient`. +1. You should give the `#legend-gradient` element a linear gradient that transitions between all the colors from `--color0` to `--color5`. Each color value should have two color stops (expressed as percentages) to make the transition between colors a hard line. + +**Note:** Be sure to link your stylesheet in your HTML to apply your CSS. + +# --hints-- + +You should have a `table` element. + +```js +assert(!!document.querySelectorAll('table').length); +``` + +You should have only one `table` element. + +```js +assert(document.querySelectorAll('table').length === 1); +``` + +Your table should have at least `5` rows. + +```js +assert.isAtLeast(document.querySelectorAll('tr')?.length, 5); +``` + +Your table should have at least `3` columns. + +```js +const rows = [...document.querySelectorAll('tr')]; +assert(!!rows.length); +rows.forEach((row) => { + assert.isAtLeast(row.children.length, 3); +}) +``` + +The first row in your table should contain at least three `th` elements. + +```js +assert.isAtLeast(document.querySelectorAll('tr:first-child>th').length, 3) +``` + +The first row in your table should not contain `td` elements. + +```js +assert(document.querySelector('tr:first-child')); +assert.lengthOf(document.querySelectorAll('tr:first-child>td'), 0) +``` + +You should have at least two rows with the class of `sharp`. + +```js +assert.isAtLeast(document.querySelectorAll('tr[class~="sharp"]').length, 2); +``` + +You should have at least two rows with the class of `half`. + +```js +assert.isAtLeast(document.querySelectorAll('tr[class~="half"]').length, 2); +``` + +`th` elements in the first column should have the `class` of `time` and the contain time values. + +```js +const firstColumnData = [...document.querySelectorAll('tr th:first-child')]; +assert(!!firstColumnData.length); +for (let cell of firstColumnData) { + if (cell.innerText.match(/\d/)?.length) { + assert(cell.classList.contains('time')); + } +} +``` + +You should have at least four `th` elements with the class of `time` that contain time values. + +```js +const timeClass = document.querySelectorAll('.time'); +assert.isAtLeast(timeClass.length, 4); +for (let cell of timeClass) { + assert(cell.innerText.match(/\d/)?.length) +} +``` + +All your `td` elements should have the `class` of `available-#`, where `#` is a number from `0` to `5`. + +```js +const cells = [...document.querySelectorAll('tr[class="sharp"]>td, tr[class="half"]>td')]; +assert(!!cells.length); +for (let cell of cells) { + const classString = [...cell.classList].join(' '); + assert.lengthOf(classString.match(/(?<=\s|^)available-[0-5](?=\s|$)/gm), 1); +} +``` + +You should have at least eight `.available-#` elements, where `#` is a number between `0` and `5`. + +```js +assert.isAtLeast(document.querySelectorAll('td[class*="available-"]').length, 8); +``` + +You should define a `--color0` variable in your root selector. + +```js +const root = new __helpers.CSSHelp(document).getStyle(':root'); +assert(!!root && root.getPropVal('--color0')); +``` + +You should define a `--color1` variable in your root selector. + +```js +const root = new __helpers.CSSHelp(document).getStyle(':root'); +assert(!!root && root.getPropVal('--color1')); +``` + +You should define a `--color2` variable in your root selector. + +```js +const root = new __helpers.CSSHelp(document).getStyle(':root'); +assert(!!root && root.getPropVal('--color2')); +``` + +You should define a `--color3` variable in your root selector. + +```js +const root = new __helpers.CSSHelp(document).getStyle(':root'); +assert(!!root && root.getPropVal('--color3')); +``` + +You should define a `--color4` variable in your root selector. + +```js +const root = new __helpers.CSSHelp(document).getStyle(':root'); +assert(!!root && root.getPropVal('--color4')); +``` + +You should define a `--color5` variable in your root selector. + +```js +const root = new __helpers.CSSHelp(document).getStyle(':root'); +assert(!!root && root.getPropVal('--color5')); +``` + +You should use `--color0` to set the background color of `.available-0` elements. + +```js +const a = new __helpers.CSSHelp(document).getStyle('.available-0'); +assert(!!a && a.backgroundColor === 'var(--color0)'); +``` + +You should use `--color1` to set the background color of `.available-1` elements. + +```js +const a = new __helpers.CSSHelp(document).getStyle('.available-1'); +assert(!!a && a.backgroundColor === 'var(--color1)'); +``` + +You should use `--color2` to set the background color of `.available-2` elements. + +```js +const a = new __helpers.CSSHelp(document).getStyle('.available-2'); +assert(!!a && a.backgroundColor === 'var(--color2)'); +``` + +You should use `--color3` to set the background color of `.available-3` elements. + +```js +const a = new __helpers.CSSHelp(document).getStyle('.available-3'); +assert(!!a && a.backgroundColor === 'var(--color3)'); +``` + +You should use `--color4` to set the background color of `.available-4` elements. + +```js +const a = new __helpers.CSSHelp(document).getStyle('.available-4'); +assert(!!a && a.backgroundColor === 'var(--color4)'); +``` + +You should use `--color5` to set the background color of `.available-5` elements. + +```js +const a = new __helpers.CSSHelp(document).getStyle('.available-5'); +assert(!!a && a.backgroundColor === 'var(--color5)'); +``` + +You should define a `--solid-border` variable in your root selector. + +```js +const root = new __helpers.CSSHelp(document).getStyle(':root'); +assert(!!root && root.getPropVal('--solid-border')); +``` + +You should define a `--dashed-border` variable in your root selector. + +```js +const root = new __helpers.CSSHelp(document).getStyle(':root'); +assert(!!root && root.getPropVal('--dashed-border')); +``` + +You should target `td` elements that are children of `.sharp` elements. + +```js +const tds = new __helpers.CSSHelp(document).getStyle('.sharp td') || new __helpers.CSSHelp(document).getStyle('.sharp>td'); +assert(tds); +``` + +You should use `--solid-border` to set the `bottom-border` of `td` elements that are children of `.sharp` elements. + +```js +const tds = new __helpers.CSSHelp(document).getStyle('.sharp td') || new __helpers.CSSHelp(document).getStyle('.sharp>td'); +assert(tds && tds.borderBottom === 'var(--solid-border)'); +``` + +You should target `td` elements that are children of `.half` elements. + +```js +const tds = new __helpers.CSSHelp(document).getStyle('.half td') || new __helpers.CSSHelp(document).getStyle('.half>td'); +assert(tds); +``` + +You should use `--dashed-border` to set the `bottom-border` of `td` elements of `.half` elements. + +```js +const tds = new __helpers.CSSHelp(document).getStyle('.half td') || new __helpers.CSSHelp(document).getStyle('.half>td'); +assert(tds && tds.borderBottom === 'var(--dashed-border)'); +``` + +You should have a `div` element with the `id` of `legend`. + +```js +assert.equal(document.querySelector('#legend')?.tagName, 'DIV'); +``` + +You should have a `span` element with the text `Availability` inside your `#legend`. + +```js +assert.equal(document.querySelector('#legend span')?.innerText, 'Availability'); +``` + +You should have a `div` element with the `id` of `legend-gradient` inside your `#legend`. + +```js +assert.equal(document.querySelector('#legend #legend-gradient')?.tagName, 'DIV'); +``` + +You should set the background image of `#legend-gradient` to a linear gradient. + +```js +const legendGradient = new __helpers.CSSHelp(document).getStyle('#legend-gradient'); +assert(!!legendGradient && legendGradient.backgroundImage.includes('linear-gradient(')) +``` + +You should use two color-stops (expressed in percentage) to make the transition from one color to the following color a hard line for your `#legend-gradient`. Remember to use your `--color#` variables. + +```js +const legendGradient = new __helpers.CSSHelp(document).getStyle('#legend-gradient'); +assert(!!legendGradient && legendGradient.backgroundImage.match(/var\(\s*--color[0-5]\s*\)\s+\d+%\s+\d+%/g).length === 6) +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Availability Table + + + + + + + +``` + +```css + +``` + +# --solutions-- + +```html + + + + + + + Availability Table + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
9 AMMondayTuesdayWednesdayThursdayFriday
10 AM
11 AM
12 PM
1 PM
2 PM
3 PM
4 PM
5 PM
+
+ Availability +
0 +
5+ +
+
+
+ + + +``` + +```css +:root { + font-size: 16px; + font-family: Arial, Helvetica, sans-serif; + --color0: hsl(0, 0%, 100%); + --color1: hsl(120, 95%, 90%); + --color2: hsl(120, 95%, 80%); + --color3: hsl(120, 95%, 65%); + --color4: hsl(120, 95%, 40%); + --color5: hsl(120, 95%, 25%); + --solid-border: 0.1rem solid black; + --dashed-border: 0.09rem dashed black; +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + background-color: hsl(150, 30%, 75%); + width: 100vw; + height: 100vh; +} + +main { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-evenly; +} + +table { + border-collapse: collapse; + table-layout: fixed; + width: 32rem; +} + +tr { + height: 1.1rem; +} + +tr :first-child { + width: 4rem; +} + +td { + border-right: var(--solid-border); + border-left: var(--solid-border); +} + +.sharp td { + border-bottom: var(--solid-border); +} + +.sharp th:not([class*="time"]) { + border-bottom: var(--solid-border); +} + +.half td { + border-bottom: var(--dashed-border); +} + +tbody :last-child td { + border: 0; +} + +.time { + text-align: right; + border: 0; + padding: 0.4rem; +} + +.available-0 { + background-color: var(--color0); +} + +.available-1 { + background-color: var(--color1); +} + +.available-2 { + background-color: var(--color2); +} + +.available-3 { + background-color: var(--color3); +} + +.available-4 { + background-color: var(--color4); +} + +.available-5 { + background-color: var(--color5); +} + +#legend { + display: flex; + flex-direction: column; + align-items: center; + width: 18rem; + height: 3.5rem; + text-align: center; +} + +#legend span { + display: inline-block; + width: 5rem; + height: 2rem; +} + +#legend-gradient { + width: 100%; + height: 60%; + border: var(--solid-border); + background-image: linear-gradient(90deg, + var(--color0) 0% 17%, + var(--color1) 17% 34%, + var(--color2) 34% 50%, + var(--color3) 50% 67%, + var(--color4) 67% 83%, + var(--color5) 83% 100%); +} + +#legend-line { + width: 60%; + height: 100%; + display: flex; +} +```