From b2bf45db760e8fae68acebb0ec970cd02d7ab068 Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Fri, 31 Mar 2023 11:28:40 +0100 Subject: [PATCH 01/16] Initialized `AppFrame` component --- .../addon/components/hds/app-frame/index.hbs | 8 ++++++ .../addon/components/hds/app-frame/index.js | 28 +++++++++++++++++++ .../app/components/hds/app-frame/index.js | 6 ++++ .../@hashicorp/design-system-components.scss | 1 + .../app/styles/components/app-frame.scss | 12 ++++++++ 5 files changed, 55 insertions(+) create mode 100644 packages/components/addon/components/hds/app-frame/index.hbs create mode 100644 packages/components/addon/components/hds/app-frame/index.js create mode 100644 packages/components/app/components/hds/app-frame/index.js create mode 100644 packages/components/app/styles/components/app-frame.scss diff --git a/packages/components/addon/components/hds/app-frame/index.hbs b/packages/components/addon/components/hds/app-frame/index.hbs new file mode 100644 index 0000000000..6c205221ec --- /dev/null +++ b/packages/components/addon/components/hds/app-frame/index.hbs @@ -0,0 +1,8 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} +{{! ADD YOUR TEMPLATE CONTENT HERE }} +
+ {{yield}} +
\ No newline at end of file diff --git a/packages/components/addon/components/hds/app-frame/index.js b/packages/components/addon/components/hds/app-frame/index.js new file mode 100644 index 0000000000..bc3849f05c --- /dev/null +++ b/packages/components/addon/components/hds/app-frame/index.js @@ -0,0 +1,28 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Component from '@glimmer/component'; + +export default class HdsAppFrameIndexComponent extends Component { + // UNCOMMENT THIS IF YOU NEED A CONSTRUCTOR + // constructor() { + // super(...arguments); + // // ADD YOUR ASSERTIONS HERE + // } + + /** + * Get the class names to apply to the component. + * @method classNames + * @return {string} The "class" attribute to apply to the component. + */ + get classNames() { + let classes = ['hds-app-frame']; + + // add a class based on the @xxx argument + // classes.push(`hds-app-frame--[variant]-${this.xxx}`); + + return classes.join(' '); + } +} diff --git a/packages/components/app/components/hds/app-frame/index.js b/packages/components/app/components/hds/app-frame/index.js new file mode 100644 index 0000000000..dfb1259720 --- /dev/null +++ b/packages/components/app/components/hds/app-frame/index.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from '@hashicorp/design-system-components/components/hds/app-frame/index'; diff --git a/packages/components/app/styles/@hashicorp/design-system-components.scss b/packages/components/app/styles/@hashicorp/design-system-components.scss index c96267466f..fdd342040b 100644 --- a/packages/components/app/styles/@hashicorp/design-system-components.scss +++ b/packages/components/app/styles/@hashicorp/design-system-components.scss @@ -13,6 +13,7 @@ // Notice: this list can be automatically edited by the Ember blueprint, please don't remove the start/end comments // START COMPONENTS CSS FILES IMPORTS @use "../components/alert"; +@use "../components/app-frame"; @use "../components/avatar"; @use "../components/badge"; @use "../components/badge-count"; diff --git a/packages/components/app/styles/components/app-frame.scss b/packages/components/app/styles/components/app-frame.scss new file mode 100644 index 0000000000..fdd102b699 --- /dev/null +++ b/packages/components/app/styles/components/app-frame.scss @@ -0,0 +1,12 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +// +// APP-FRAME +// + +.hds-app-frame { + // add the component styles here +} From e9fa3613929b3155219960854544571740424ef5 Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Wed, 29 Mar 2023 20:23:29 +0100 Subject: [PATCH 02/16] ported `AppFrame` code from the `HcAppFrame` implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (re-organized sub-components in “parts” folder for simplicity) --- .../addon/components/hds/app-frame/index.hbs | 19 +++++-- .../addon/components/hds/app-frame/index.js | 50 ++++++++++++++----- .../components/hds/app-frame/parts/footer.hbs | 7 +++ .../components/hds/app-frame/parts/header.hbs | 7 +++ .../components/hds/app-frame/parts/main.hbs | 7 +++ .../components/hds/app-frame/parts/modals.hbs | 6 +++ .../hds/app-frame/parts/sidebar.hbs | 7 +++ .../components/hds/app-frame/parts/footer.js | 6 +++ .../components/hds/app-frame/parts/header.js | 6 +++ .../components/hds/app-frame/parts/main.js | 6 +++ .../components/hds/app-frame/parts/modals.js | 6 +++ .../components/hds/app-frame/parts/sidebar.js | 6 +++ .../app/styles/components/app-frame.scss | 50 ++++++++++++++++++- 13 files changed, 165 insertions(+), 18 deletions(-) create mode 100644 packages/components/addon/components/hds/app-frame/parts/footer.hbs create mode 100644 packages/components/addon/components/hds/app-frame/parts/header.hbs create mode 100644 packages/components/addon/components/hds/app-frame/parts/main.hbs create mode 100644 packages/components/addon/components/hds/app-frame/parts/modals.hbs create mode 100644 packages/components/addon/components/hds/app-frame/parts/sidebar.hbs create mode 100644 packages/components/app/components/hds/app-frame/parts/footer.js create mode 100644 packages/components/app/components/hds/app-frame/parts/header.js create mode 100644 packages/components/app/components/hds/app-frame/parts/main.js create mode 100644 packages/components/app/components/hds/app-frame/parts/modals.js create mode 100644 packages/components/app/components/hds/app-frame/parts/sidebar.js diff --git a/packages/components/addon/components/hds/app-frame/index.hbs b/packages/components/addon/components/hds/app-frame/index.hbs index 6c205221ec..a4340d4582 100644 --- a/packages/components/addon/components/hds/app-frame/index.hbs +++ b/packages/components/addon/components/hds/app-frame/index.hbs @@ -2,7 +2,18 @@ Copyright (c) HashiCorp, Inc. SPDX-License-Identifier: MPL-2.0 }} -{{! ADD YOUR TEMPLATE CONTENT HERE }} -
- {{yield}} -
\ No newline at end of file +
+ {{#if this.hasHeader}} + {{yield (hash Header=(component "hds/app-frame/parts/header"))}} + {{/if}} + {{#if this.hasSidebar}} + {{yield (hash Sidebar=(component "hds/app-frame/parts/sidebar"))}} + {{/if}} + {{yield (hash Main=(component "hds/app-frame/parts/main"))}} + {{#if this.hasFooter}} + {{yield (hash Footer=(component "hds/app-frame/parts/footer"))}} + {{/if}} + {{#if this.hasModals}} + {{yield (hash Modals=(component "hds/app-frame/parts/modals"))}} + {{/if}} +
diff --git a/packages/components/addon/components/hds/app-frame/index.js b/packages/components/addon/components/hds/app-frame/index.js index bc3849f05c..28db1cce53 100644 --- a/packages/components/addon/components/hds/app-frame/index.js +++ b/packages/components/addon/components/hds/app-frame/index.js @@ -6,23 +6,47 @@ import Component from '@glimmer/component'; export default class HdsAppFrameIndexComponent extends Component { - // UNCOMMENT THIS IF YOU NEED A CONSTRUCTOR - // constructor() { - // super(...arguments); - // // ADD YOUR ASSERTIONS HERE - // } + /** + * Indicates if the "header" container should be displayed + * + * @param hasHeader + * @type {boolean} + * @default true + */ + get hasHeader() { + return this.args.hasHeader ?? true; + } /** - * Get the class names to apply to the component. - * @method classNames - * @return {string} The "class" attribute to apply to the component. + * Indicates if the "sidebar" container should be displayed + * + * @param hasSidebar + * @type {boolean} + * @default true */ - get classNames() { - let classes = ['hds-app-frame']; + get hasSidebar() { + return this.args.hasSidebar ?? true; + } - // add a class based on the @xxx argument - // classes.push(`hds-app-frame--[variant]-${this.xxx}`); + /** + * Indicates if the "footer" container should be displayed + * + * @param hasFooter + * @type {boolean} + * @default true + */ + get hasFooter() { + return this.args.hasFooter ?? true; + } - return classes.join(' '); + /** + * Indicates if the "modals" container should be displayed + * + * @param hasModals + * @type {boolean} + * @default true + */ + get hasModals() { + return this.args.hasModals ?? true; } } diff --git a/packages/components/addon/components/hds/app-frame/parts/footer.hbs b/packages/components/addon/components/hds/app-frame/parts/footer.hbs new file mode 100644 index 0000000000..2931bf0efc --- /dev/null +++ b/packages/components/addon/components/hds/app-frame/parts/footer.hbs @@ -0,0 +1,7 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} +
+ {{yield}} +
diff --git a/packages/components/addon/components/hds/app-frame/parts/header.hbs b/packages/components/addon/components/hds/app-frame/parts/header.hbs new file mode 100644 index 0000000000..976942cd50 --- /dev/null +++ b/packages/components/addon/components/hds/app-frame/parts/header.hbs @@ -0,0 +1,7 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} +
+ {{yield}} +
diff --git a/packages/components/addon/components/hds/app-frame/parts/main.hbs b/packages/components/addon/components/hds/app-frame/parts/main.hbs new file mode 100644 index 0000000000..8baea3a5ea --- /dev/null +++ b/packages/components/addon/components/hds/app-frame/parts/main.hbs @@ -0,0 +1,7 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} +
+ {{yield}} +
diff --git a/packages/components/addon/components/hds/app-frame/parts/modals.hbs b/packages/components/addon/components/hds/app-frame/parts/modals.hbs new file mode 100644 index 0000000000..9ea21e0735 --- /dev/null +++ b/packages/components/addon/components/hds/app-frame/parts/modals.hbs @@ -0,0 +1,6 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} +{{! we use `:empty` in CSS so we have to avoid whitespaces }} +
{{~yield~}}
diff --git a/packages/components/addon/components/hds/app-frame/parts/sidebar.hbs b/packages/components/addon/components/hds/app-frame/parts/sidebar.hbs new file mode 100644 index 0000000000..0b48a3c61d --- /dev/null +++ b/packages/components/addon/components/hds/app-frame/parts/sidebar.hbs @@ -0,0 +1,7 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + diff --git a/packages/components/app/components/hds/app-frame/parts/footer.js b/packages/components/app/components/hds/app-frame/parts/footer.js new file mode 100644 index 0000000000..d7881b93e2 --- /dev/null +++ b/packages/components/app/components/hds/app-frame/parts/footer.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from '@hashicorp/design-system-components/components/hds/app-frame/parts/footer'; diff --git a/packages/components/app/components/hds/app-frame/parts/header.js b/packages/components/app/components/hds/app-frame/parts/header.js new file mode 100644 index 0000000000..5291e5d89e --- /dev/null +++ b/packages/components/app/components/hds/app-frame/parts/header.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from '@hashicorp/design-system-components/components/hds/app-frame/parts/header'; diff --git a/packages/components/app/components/hds/app-frame/parts/main.js b/packages/components/app/components/hds/app-frame/parts/main.js new file mode 100644 index 0000000000..3b26afeb40 --- /dev/null +++ b/packages/components/app/components/hds/app-frame/parts/main.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from '@hashicorp/design-system-components/components/hds/app-frame/parts/main'; diff --git a/packages/components/app/components/hds/app-frame/parts/modals.js b/packages/components/app/components/hds/app-frame/parts/modals.js new file mode 100644 index 0000000000..c365db4159 --- /dev/null +++ b/packages/components/app/components/hds/app-frame/parts/modals.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from '@hashicorp/design-system-components/components/hds/app-frame/parts/modals'; diff --git a/packages/components/app/components/hds/app-frame/parts/sidebar.js b/packages/components/app/components/hds/app-frame/parts/sidebar.js new file mode 100644 index 0000000000..38dcac0bd4 --- /dev/null +++ b/packages/components/app/components/hds/app-frame/parts/sidebar.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from '@hashicorp/design-system-components/components/hds/app-frame/parts/sidebar'; diff --git a/packages/components/app/styles/components/app-frame.scss b/packages/components/app/styles/components/app-frame.scss index fdd102b699..69f5163921 100644 --- a/packages/components/app/styles/components/app-frame.scss +++ b/packages/components/app/styles/components/app-frame.scss @@ -8,5 +8,53 @@ // .hds-app-frame { - // add the component styles here + display: grid; + grid-template-areas: + "header header" + "sidebar main" + "sidebar footer"; + grid-template-rows: auto 1fr auto; + grid-template-columns: auto 1fr; + min-height: 100vh; +} + + +// FRAME'S CONTAINERS + +.hds-app-frame__header { + z-index: 7; + grid-area: header; +} + +.hds-app-frame__sidebar { + z-index: 6; + grid-area: sidebar; +} + +.hds-app-frame__main { + grid-area: main; +} + +.hds-app-frame__footer { + z-index: 5; + grid-area: footer; +} + + +// MODALS "CONTAINER" + +.hds-app-frame__modals { + position: fixed; + top: 0; + left: 0; + z-index: 100; + width: 100vw; + height: 100vh; + pointer-events: none; + + // since the content is injected via DOM manipulation, there's no issues of whitespace generated by Ember + // that make this approach unreliable (in some cases), so we can safely use it to controls its display + &:empty { + display: none; + } } From 5e77d43ce8dd6a29d14e57d506d5cf850335c305 Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Wed, 29 Mar 2023 20:53:35 +0100 Subject: [PATCH 03/16] Initialized `AppFrame` showcase --- packages/components/tests/dummy/app/router.js | 3 +++ .../dummy/app/routes/layouts/app-frame.js | 8 +++++++ .../tests/dummy/app/styles/app.scss | 5 +++-- .../app/styles/showcase-pages/app-frame.scss | 6 +++++ .../tests/dummy/app/templates/index.hbs | 10 ++++++++- .../dummy/app/templates/layouts/app-frame.hbs | 17 ++++++++++++++ .../components/hds/app-frame/index-test.js | 22 +++++++++++++++++++ 7 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 packages/components/tests/dummy/app/routes/layouts/app-frame.js create mode 100644 packages/components/tests/dummy/app/styles/showcase-pages/app-frame.scss create mode 100644 packages/components/tests/dummy/app/templates/layouts/app-frame.hbs create mode 100644 packages/components/tests/integration/components/hds/app-frame/index-test.js diff --git a/packages/components/tests/dummy/app/router.js b/packages/components/tests/dummy/app/router.js index 83a98268c4..fc700683f3 100644 --- a/packages/components/tests/dummy/app/router.js +++ b/packages/components/tests/dummy/app/router.js @@ -54,6 +54,9 @@ Router.map(function () { this.route('tabs'); this.route('side-nav'); }); + this.route('layouts', function () { + this.route('app-frame'); + }); this.route('utilities', function () { this.route('disclosure'); this.route('dismiss-button'); diff --git a/packages/components/tests/dummy/app/routes/layouts/app-frame.js b/packages/components/tests/dummy/app/routes/layouts/app-frame.js new file mode 100644 index 0000000000..1296463585 --- /dev/null +++ b/packages/components/tests/dummy/app/routes/layouts/app-frame.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Route from '@ember/routing/route'; + +export default class ComponentsAppFrameRoute extends Route {} diff --git a/packages/components/tests/dummy/app/styles/app.scss b/packages/components/tests/dummy/app/styles/app.scss index 857dedee3e..a3afe6f111 100644 --- a/packages/components/tests/dummy/app/styles/app.scss +++ b/packages/components/tests/dummy/app/styles/app.scss @@ -27,13 +27,14 @@ // Notice: this list can be automatically edited by the Ember blueprint, please don't remove the start/end comments // START COMPONENT PAGES IMPORTS @import "./showcase-pages/alert"; +@import "./showcase-pages/app-frame"; @import "./showcase-pages/badge"; @import "./showcase-pages/breadcrumb"; @import "./showcase-pages/button"; @import "./showcase-pages/card"; @import "./showcase-pages/disclosure"; -@import "./showcase-pages/dropdown"; @import "./showcase-pages/dismiss-button"; +@import "./showcase-pages/dropdown"; @import "./showcase-pages/flyout"; @import "./showcase-pages/form/base-elements"; @import "./showcase-pages/form/checkbox"; @@ -47,8 +48,8 @@ @import "./showcase-pages/pagination"; @import "./showcase-pages/power-select"; @import "./showcase-pages/side-nav"; -@import "./showcase-pages/tabs"; @import "./showcase-pages/table"; +@import "./showcase-pages/tabs"; @import "./showcase-pages/tag"; @import "./showcase-pages/typography"; // END COMPONENT PAGES IMPORTS diff --git a/packages/components/tests/dummy/app/styles/showcase-pages/app-frame.scss b/packages/components/tests/dummy/app/styles/showcase-pages/app-frame.scss new file mode 100644 index 0000000000..cf4976535d --- /dev/null +++ b/packages/components/tests/dummy/app/styles/showcase-pages/app-frame.scss @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +// APP-FRAME \ No newline at end of file diff --git a/packages/components/tests/dummy/app/templates/index.hbs b/packages/components/tests/dummy/app/templates/index.hbs index ae5f4dbd97..cff5522423 100644 --- a/packages/components/tests/dummy/app/templates/index.hbs +++ b/packages/components/tests/dummy/app/templates/index.hbs @@ -185,6 +185,14 @@
+ Layouts +
    +
  1. + + AppFrame + +
  2. +
Utilities
  1. @@ -212,4 +220,4 @@
- \ No newline at end of file + diff --git a/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs b/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs new file mode 100644 index 0000000000..aa1b886f37 --- /dev/null +++ b/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs @@ -0,0 +1,17 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + +{{page-title "AppFrame Component"}} + +AppFrame + +
+ + {{! ADD YOUR CONTENT HERE }} + + {{! This below is just an example of invocation, to get started }} + This is the Hds::AppFrame component + +
\ No newline at end of file diff --git a/packages/components/tests/integration/components/hds/app-frame/index-test.js b/packages/components/tests/integration/components/hds/app-frame/index-test.js new file mode 100644 index 0000000000..a894945e70 --- /dev/null +++ b/packages/components/tests/integration/components/hds/app-frame/index-test.js @@ -0,0 +1,22 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | hds/app-frame/index', function (hooks) { + setupRenderingTest(hooks); + + test('it renders the component', async function (assert) { + await render(hbs``); + assert.dom(this.element).exists(); + }); + test('it should render with a CSS class that matches the component name', async function (assert) { + await render(hbs``); + assert.dom('#test-app-frame').hasClass('hds-app-frame'); + }); +}); From b1c6d7bc11adaf6cf41c5a111239089276860036 Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Wed, 29 Mar 2023 22:27:17 +0100 Subject: [PATCH 04/16] added basic showcase for `AppFrame` --- .../app/styles/showcase-pages/app-frame.scss | 38 +++++- .../dummy/app/templates/layouts/app-frame.hbs | 112 +++++++++++++++++- 2 files changed, 146 insertions(+), 4 deletions(-) diff --git a/packages/components/tests/dummy/app/styles/showcase-pages/app-frame.scss b/packages/components/tests/dummy/app/styles/showcase-pages/app-frame.scss index cf4976535d..f2e4e6a4e1 100644 --- a/packages/components/tests/dummy/app/styles/showcase-pages/app-frame.scss +++ b/packages/components/tests/dummy/app/styles/showcase-pages/app-frame.scss @@ -3,4 +3,40 @@ * SPDX-License-Identifier: MPL-2.0 */ -// APP-FRAME \ No newline at end of file +// APP-FRAME + +body.layouts-app-frame { + .shw-layout-app-frame-wrapper { + width: 100%; + aspect-ratio: 4 / 3; + + .hds-app-frame { + position: relative; + height: 100% !important; + min-height: 100% !important; + } + + .hds-app-frame__modals { + position: absolute; + width: 100%; + height: 100%; + } + } + + .shw-layout-app-frame-fake-overlay { + position: absolute; + z-index: 50; // same as HDS overlay + inset: 0; + background: var(--token-color-palette-neutral-700); + opacity: 0.25; + } + + .shw-layout-app-frame-fake-modal { + position: absolute; + z-index: 50; // same as HDS modal + width: 200px; + height: 160px; + margin: auto; + inset: 0; + } +} diff --git a/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs b/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs index aa1b886f37..ee95689025 100644 --- a/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs +++ b/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs @@ -9,9 +9,115 @@
- {{! ADD YOUR CONTENT HERE }} + Containers - {{! This below is just an example of invocation, to get started }} - This is the Hds::AppFrame component + + +
+ + + + + + + + + + + + + + +
+
+ +
+ + + + + + + + + + + +
+
+ +
+ + + + + + + + + + + +
+
+ +
+ + + + + + + + + + + +
+
+ +
+ + + + + + + + + + + + + + + +
+
+ +
+ + + + + + + + + + + + + + +
+
+ +
+ + +
+ +
\ No newline at end of file From 1c6f221f0dd02f37127e21a93f9d97692d55e156 Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Wed, 29 Mar 2023 23:10:48 +0100 Subject: [PATCH 05/16] added 3d visualization to `AppFrame` showcase --- .../app/controllers/layouts/app-frame.js | 17 +++++++ .../app/styles/showcase-pages/app-frame.scss | 49 +++++++++++++++++++ .../dummy/app/templates/layouts/app-frame.hbs | 34 +++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 packages/components/tests/dummy/app/controllers/layouts/app-frame.js diff --git a/packages/components/tests/dummy/app/controllers/layouts/app-frame.js b/packages/components/tests/dummy/app/controllers/layouts/app-frame.js new file mode 100644 index 0000000000..312d42795b --- /dev/null +++ b/packages/components/tests/dummy/app/controllers/layouts/app-frame.js @@ -0,0 +1,17 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Controller from '@ember/controller'; +import { action } from '@ember/object'; +import { tracked } from '@glimmer/tracking'; + +export default class AppFrameController extends Controller { + @tracked show3DVisualization = false; + + @action + toggle3DVisualization() { + this.show3DVisualization = !this.show3DVisualization; + } +} diff --git a/packages/components/tests/dummy/app/styles/showcase-pages/app-frame.scss b/packages/components/tests/dummy/app/styles/showcase-pages/app-frame.scss index f2e4e6a4e1..d9c939c78b 100644 --- a/packages/components/tests/dummy/app/styles/showcase-pages/app-frame.scss +++ b/packages/components/tests/dummy/app/styles/showcase-pages/app-frame.scss @@ -5,6 +5,15 @@ // APP-FRAME +@mixin shw-apply-transform($stack) { + $tx: 0; + $ty: ($stack - 1) * 5px; + $tz: ($stack * 20px); + transform: + rotateY(30deg) + translate3d($tx, $ty, $tz) !important; +} + body.layouts-app-frame { .shw-layout-app-frame-wrapper { width: 100%; @@ -23,6 +32,46 @@ body.layouts-app-frame { } } + .shw-layout-app-frame-wrapper--with-3d { + .hds-app-frame { + perspective: 2000px; + perspective-origin: 50% 50%; + } + + .hds-app-frame__header, + .hds-app-frame__sidebar, + .hds-app-frame__main, + .hds-app-frame__footer, + .hds-app-frame__modals { + transform-style: preserve-3d; + transition: transform 400ms ease-in-out; + } + + &.shw-is-3d { + outline: 1px dotted #ccc; + + .hds-app-frame__header { + @include shw-apply-transform(3); + } + + .hds-app-frame__sidebar { + @include shw-apply-transform(2); + } + + .hds-app-frame__main { + @include shw-apply-transform(0); + } + + .hds-app-frame__footer { + @include shw-apply-transform(1); + } + + .hds-app-frame__modals { + @include shw-apply-transform(4); + } + } + } + .shw-layout-app-frame-fake-overlay { position: absolute; z-index: 50; // same as HDS overlay diff --git a/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs b/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs index ee95689025..870c71d04a 100644 --- a/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs +++ b/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs @@ -120,4 +120,38 @@ + + + 3d Visualization + + + + + +
+ + + + + + + + + + + + + + +
+
+ +
+ + +
+ + \ No newline at end of file From 3b65e0115cb40f01ced9007f8eeea7d1d7c527b0 Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Wed, 29 Mar 2023 23:26:04 +0100 Subject: [PATCH 06/16] ported (and updated) integration tests for `Hds::AppFrame` from `HcAppFrame` --- .../components/hds/app-frame/index-test.js | 91 ++++++++++++++++++- 1 file changed, 86 insertions(+), 5 deletions(-) diff --git a/packages/components/tests/integration/components/hds/app-frame/index-test.js b/packages/components/tests/integration/components/hds/app-frame/index-test.js index a894945e70..aebe279ed8 100644 --- a/packages/components/tests/integration/components/hds/app-frame/index-test.js +++ b/packages/components/tests/integration/components/hds/app-frame/index-test.js @@ -5,18 +5,99 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; -import { render } from '@ember/test-helpers'; +import { render, pauseTest } from '@ember/test-helpers'; import { hbs } from 'ember-cli-htmlbars'; module('Integration | Component | hds/app-frame/index', function (hooks) { setupRenderingTest(hooks); - test('it renders the component', async function (assert) { - await render(hbs``); - assert.dom(this.element).exists(); - }); test('it should render with a CSS class that matches the component name', async function (assert) { await render(hbs``); assert.dom('#test-app-frame').hasClass('hds-app-frame'); }); + + // CONTENT + + test('it should yield the different content areas (and spreads attributes on them)', async function (assert) { + await render(hbs` + + + header container + + + sidebar container + + + main container + + + footer container + + + modals container + + + `); + + // await pauseTest(); + + assert.dom('#test-app-frame[data-test-app-frame]').exists(); + + assert.dom('#test-app-frame-header[data-test-app-frame-header]').exists(); + assert.dom('header.hds-app-frame__header').exists(); + assert.dom('header.hds-app-frame__header').includesText('header container'); + + assert.dom('#test-app-frame-sidebar[data-test-app-frame-sidebar]').exists(); + assert.dom('aside.hds-app-frame__sidebar').exists(); + assert + .dom('aside.hds-app-frame__sidebar') + .includesText('sidebar container'); + + assert.dom('#test-app-frame-main[data-test-app-frame-main]').exists(); + assert.dom('main.hds-app-frame__main').exists(); + assert.dom('main.hds-app-frame__main').includesText('main container'); + + assert.dom('#test-app-frame-footer[data-test-app-frame-footer]').exists(); + assert.dom('footer.hds-app-frame__footer').exists(); + assert.dom('footer.hds-app-frame__footer').includesText('footer container'); + + assert.dom('#test-app-frame-modals[data-test-app-frame-modals]').exists(); + assert.dom('div.hds-app-frame__modals').exists(); + assert.dom('div.hds-app-frame__modals').includesText('modals container'); + }); + + // OPTIONS + + test('it should hide the header when @hasHeader is false', async function (assert) { + await render(hbs` + + + + `); + assert.dom('#test-app-frame-header').doesNotExist(); + }); + test('it should hide the sidebar when @hasSidebar is false', async function (assert) { + await render(hbs` + + + + `); + assert.dom('#test-app-frame-sidebar').doesNotExist(); + }); + test('it should hide the sidebar when @hasFooter is false', async function (assert) { + await render(hbs` + + + + `); + assert.dom('#test-app-frame-sidebar').doesNotExist(); + }); + test('it should hide the modals when @hasModals is false', async function (assert) { + await render(hbs` + + + + `); + assert.dom('#test-app-frame-modals').doesNotExist(); + }); }); From fb716285176762a04b84a3624cfae432e91ccafc Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Thu, 30 Mar 2023 20:46:13 +0100 Subject: [PATCH 07/16] scaffolded Helios docs for `AppFrame` --- website/docs/components/app-frame/index.md | 17 +++++++++++++++++ .../app-frame/partials/code/component-api.md | 5 +++++ .../app-frame/partials/code/how-to-use.md | 9 +++++++++ 3 files changed, 31 insertions(+) create mode 100644 website/docs/components/app-frame/index.md create mode 100644 website/docs/components/app-frame/partials/code/component-api.md create mode 100644 website/docs/components/app-frame/partials/code/how-to-use.md diff --git a/website/docs/components/app-frame/index.md b/website/docs/components/app-frame/index.md new file mode 100644 index 0000000000..a53905e4fe --- /dev/null +++ b/website/docs/components/app-frame/index.md @@ -0,0 +1,17 @@ +--- +title: AppFrame +description: {Optional long description that appears in the cover} +caption: {Short description that appears in the cards} +status: released +links: + github: {link to the "AppFrame" component's folder in the GitHub repo} +previewImage: assets/illustrations/components/app-frame.jpg +navigation: + hidden: false + keywords: ['add', 'alternate', 'keywords', 'here'] +--- + +
+ @include "partials/code/how-to-use.md" + @include "partials/code/component-api.md" +
diff --git a/website/docs/components/app-frame/partials/code/component-api.md b/website/docs/components/app-frame/partials/code/component-api.md new file mode 100644 index 0000000000..4661623aa2 --- /dev/null +++ b/website/docs/components/app-frame/partials/code/component-api.md @@ -0,0 +1,5 @@ +## Component API + + + {look at other components for examples of how to describe the APIs using the "Doc::ComponentApi" syntax} + diff --git a/website/docs/components/app-frame/partials/code/how-to-use.md b/website/docs/components/app-frame/partials/code/how-to-use.md new file mode 100644 index 0000000000..fe792f7ffc --- /dev/null +++ b/website/docs/components/app-frame/partials/code/how-to-use.md @@ -0,0 +1,9 @@ +## How to use this component + + +{basic invocation details} + + +```handlebars +This is the Hds::AppFrame component +``` From eb0d11a92d05e6d7a69f4fce60fb741280795526 Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Thu, 30 Mar 2023 21:10:01 +0100 Subject: [PATCH 08/16] added `layouts` category to documentation --- website/app/components/doc/page/sidebar.js | 2 +- website/app/controllers/components.js | 2 +- website/app/templates/components.hbs | 2 ++ website/lib/markdown/table-of-contents.js | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/website/app/components/doc/page/sidebar.js b/website/app/components/doc/page/sidebar.js index d34e39e5bc..2a7403dcf1 100644 --- a/website/app/components/doc/page/sidebar.js +++ b/website/app/components/doc/page/sidebar.js @@ -16,7 +16,7 @@ const DEBOUNCE_MS = 250; const getTocSectionsBundle = (section) => { const ABOUT = ['about', 'getting-started']; const FOUNDATIONS = ['foundations', 'icons']; - const COMPONENTS = ['components', 'overrides', 'utilities']; + const COMPONENTS = ['components', 'overrides', 'layouts', 'utilities']; const PATTERNS = ['patterns']; // this will be removed later const TESTING = ['testing']; diff --git a/website/app/controllers/components.js b/website/app/controllers/components.js index 42b5e13a57..d1f6b5e49d 100644 --- a/website/app/controllers/components.js +++ b/website/app/controllers/components.js @@ -9,7 +9,7 @@ export default class ComponentsController extends Controller { get cards() { // we want to use a flat tree here... const tocTree = this.model.toc.flat; - const sections = ['components', 'overrides', 'utilities']; + const sections = ['components', 'overrides', 'layouts', 'utilities']; const cards = {}; sections.forEach((section) => { cards[section] = tocTree diff --git a/website/app/templates/components.hbs b/website/app/templates/components.hbs index 9fedb83f6d..9ccd4dd31c 100644 --- a/website/app/templates/components.hbs +++ b/website/app/templates/components.hbs @@ -11,6 +11,8 @@

Overrides

+

Layouts

+

Utilities

diff --git a/website/lib/markdown/table-of-contents.js b/website/lib/markdown/table-of-contents.js index f6b0d89858..5f3c485995 100644 --- a/website/lib/markdown/table-of-contents.js +++ b/website/lib/markdown/table-of-contents.js @@ -15,6 +15,7 @@ const CATEGORIES = [ 'foundations', 'components', 'overrides', + 'layouts', 'utilities', 'patterns', 'testing', From 5c329cc73d0837520cbf156dc10a04bb0b08ffdc Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Thu, 30 Mar 2023 21:10:18 +0100 Subject: [PATCH 09/16] moved `AppFrame` docs under the `layout` category --- website/docs/{components => layouts}/app-frame/index.md | 0 .../app-frame/partials/code/component-api.md | 0 .../{components => layouts}/app-frame/partials/code/how-to-use.md | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename website/docs/{components => layouts}/app-frame/index.md (100%) rename website/docs/{components => layouts}/app-frame/partials/code/component-api.md (100%) rename website/docs/{components => layouts}/app-frame/partials/code/how-to-use.md (100%) diff --git a/website/docs/components/app-frame/index.md b/website/docs/layouts/app-frame/index.md similarity index 100% rename from website/docs/components/app-frame/index.md rename to website/docs/layouts/app-frame/index.md diff --git a/website/docs/components/app-frame/partials/code/component-api.md b/website/docs/layouts/app-frame/partials/code/component-api.md similarity index 100% rename from website/docs/components/app-frame/partials/code/component-api.md rename to website/docs/layouts/app-frame/partials/code/component-api.md diff --git a/website/docs/components/app-frame/partials/code/how-to-use.md b/website/docs/layouts/app-frame/partials/code/how-to-use.md similarity index 100% rename from website/docs/components/app-frame/partials/code/how-to-use.md rename to website/docs/layouts/app-frame/partials/code/how-to-use.md From 08f3737d5fc8c03b6ded2593276705bddd09ebe1 Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Fri, 31 Mar 2023 11:19:27 +0100 Subject: [PATCH 10/16] added content to the Helios documentation for the `AppFrame` component --- website/app/styles/app.scss | 1 + .../app/styles/pages/layouts/app-frame.scss | 41 ++++++ website/docs/layouts/app-frame/index.js | 10 ++ website/docs/layouts/app-frame/index.md | 11 +- .../app-frame/partials/code/component-api.md | 50 ++++++- .../app-frame/partials/code/how-to-use.md | 125 +++++++++++++++++- .../illustrations/layouts/app-frame.jpg | Bin 0 -> 14279 bytes 7 files changed, 227 insertions(+), 11 deletions(-) create mode 100644 website/app/styles/pages/layouts/app-frame.scss create mode 100644 website/docs/layouts/app-frame/index.js create mode 100644 website/public/assets/illustrations/layouts/app-frame.jpg diff --git a/website/app/styles/app.scss b/website/app/styles/app.scss index 86ea1feb52..a188a34858 100644 --- a/website/app/styles/app.scss +++ b/website/app/styles/app.scss @@ -33,6 +33,7 @@ @import "pages/components/pagination"; @import "pages/components/radio-card"; @import "pages/components/table"; +@import "pages/layouts/app-frame"; // Third-party declarations @import "prism-dracula"; diff --git a/website/app/styles/pages/layouts/app-frame.scss b/website/app/styles/pages/layouts/app-frame.scss new file mode 100644 index 0000000000..090547917c --- /dev/null +++ b/website/app/styles/pages/layouts/app-frame.scss @@ -0,0 +1,41 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +// COMPONENTS > APP-FRAME + +#show-content-layouts-app-frame { + .doc-app-frame-mock-viewport { + width: 100%; + aspect-ratio: 16 / 9; + + .hds-app-frame { + position: relative; + height: 100% !important; + min-height: 100% !important; + } + + .hds-app-frame__modals { + position: absolute; + z-index: 10; + width: 100%; + height: 100%; + } + + .doc-app-frame-fake-overlay { + position: absolute; + inset: 0; + background: var(--token-color-palette-neutral-700); + opacity: 0.25; + } + + .doc-app-frame-fake-modal { + position: absolute; + width: 200px; + height: 160px; + margin: auto; + inset: 0; + } + } +} diff --git a/website/docs/layouts/app-frame/index.js b/website/docs/layouts/app-frame/index.js new file mode 100644 index 0000000000..810604b1da --- /dev/null +++ b/website/docs/layouts/app-frame/index.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Component from '@glimmer/component'; + +export default class Index extends Component { + yourSidebarBooleanFlag = false; +} diff --git a/website/docs/layouts/app-frame/index.md b/website/docs/layouts/app-frame/index.md index a53905e4fe..09fb55e19e 100644 --- a/website/docs/layouts/app-frame/index.md +++ b/website/docs/layouts/app-frame/index.md @@ -1,14 +1,13 @@ --- title: AppFrame -description: {Optional long description that appears in the cover} -caption: {Short description that appears in the cards} +description: A layout component used as top-level “frame“ for the application. +caption: A layout component used as top-level “frame“ for the application. status: released links: - github: {link to the "AppFrame" component's folder in the GitHub repo} -previewImage: assets/illustrations/components/app-frame.jpg + github: https://github.com/hashicorp/design-system/tree/main/packages/components/addon/components/hds/app-frame +previewImage: assets/illustrations/layouts/app-frame.jpg navigation: - hidden: false - keywords: ['add', 'alternate', 'keywords', 'here'] + keywords: ['layout', 'application', 'frame', 'header', 'sidebar', 'sidenav', 'footer', 'modal'] ---
diff --git a/website/docs/layouts/app-frame/partials/code/component-api.md b/website/docs/layouts/app-frame/partials/code/component-api.md index 4661623aa2..0a88bde2ec 100644 --- a/website/docs/layouts/app-frame/partials/code/component-api.md +++ b/website/docs/layouts/app-frame/partials/code/component-api.md @@ -1,5 +1,53 @@ ## Component API - {look at other components for examples of how to describe the APIs using the "Doc::ComponentApi" syntax} + + Controls the rendering of the `header` container + + + Controls the rendering of the `sidebar` container + + + Controls the rendering of the `footer` container + + + Controls the rendering of the `modals` container + + + This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). + + +### Contextual components + +The frame's elements acting as containers are passed into the `AppFrame` as yielded components, using the `Header`, `Sidebar`, `Main`, `Footer`, and `Modals` keys. + + + + Optional container that yields its content inside the `
` element.

This sub-component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). + + + + + + Optional container that yields its content inside the `
\ No newline at end of file diff --git a/packages/components/addon/components/hds/app-frame/parts/main.hbs b/packages/components/addon/components/hds/app-frame/parts/main.hbs index 8baea3a5ea..610c1f50e7 100644 --- a/packages/components/addon/components/hds/app-frame/parts/main.hbs +++ b/packages/components/addon/components/hds/app-frame/parts/main.hbs @@ -4,4 +4,4 @@ }}
{{yield}} -
+ \ No newline at end of file diff --git a/packages/components/addon/components/hds/app-frame/parts/modals.hbs b/packages/components/addon/components/hds/app-frame/parts/modals.hbs index 9ea21e0735..9071c352af 100644 --- a/packages/components/addon/components/hds/app-frame/parts/modals.hbs +++ b/packages/components/addon/components/hds/app-frame/parts/modals.hbs @@ -3,4 +3,4 @@ SPDX-License-Identifier: MPL-2.0 }} {{! we use `:empty` in CSS so we have to avoid whitespaces }} -
{{~yield~}}
+
{{~yield~}}
\ No newline at end of file diff --git a/packages/components/addon/components/hds/app-frame/parts/sidebar.hbs b/packages/components/addon/components/hds/app-frame/parts/sidebar.hbs index 0b48a3c61d..1b28ae1a73 100644 --- a/packages/components/addon/components/hds/app-frame/parts/sidebar.hbs +++ b/packages/components/addon/components/hds/app-frame/parts/sidebar.hbs @@ -4,4 +4,4 @@ }} + \ No newline at end of file diff --git a/packages/components/tests/dummy/app/templates/index.hbs b/packages/components/tests/dummy/app/templates/index.hbs index cff5522423..5a91ae987b 100644 --- a/packages/components/tests/dummy/app/templates/index.hbs +++ b/packages/components/tests/dummy/app/templates/index.hbs @@ -2,7 +2,6 @@ Copyright (c) HashiCorp, Inc. SPDX-License-Identifier: MPL-2.0 }} -
Foundations @@ -220,4 +219,4 @@
-
+
\ No newline at end of file diff --git a/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs b/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs index 870c71d04a..ee50292c0e 100644 --- a/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs +++ b/packages/components/tests/dummy/app/templates/layouts/app-frame.hbs @@ -130,7 +130,10 @@ -
+
diff --git a/packages/components/tests/integration/components/hds/app-frame/index-test.js b/packages/components/tests/integration/components/hds/app-frame/index-test.js index aebe279ed8..d41adcca1c 100644 --- a/packages/components/tests/integration/components/hds/app-frame/index-test.js +++ b/packages/components/tests/integration/components/hds/app-frame/index-test.js @@ -5,7 +5,7 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; -import { render, pauseTest } from '@ember/test-helpers'; +import { render } from '@ember/test-helpers'; import { hbs } from 'ember-cli-htmlbars'; module('Integration | Component | hds/app-frame/index', function (hooks) { From 1a7f0648a75f550d5a0fb4079ee52875d197cc44 Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Wed, 5 Apr 2023 12:12:38 +0100 Subject: [PATCH 13/16] Apply suggestions from code review Co-authored-by: Heather Larsen --- .../docs/layouts/app-frame/partials/code/component-api.md | 8 ++++---- .../docs/layouts/app-frame/partials/code/how-to-use.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/docs/layouts/app-frame/partials/code/component-api.md b/website/docs/layouts/app-frame/partials/code/component-api.md index 0a88bde2ec..e20ed0dc00 100644 --- a/website/docs/layouts/app-frame/partials/code/component-api.md +++ b/website/docs/layouts/app-frame/partials/code/component-api.md @@ -2,16 +2,16 @@ - Controls the rendering of the `header` container + Controls the rendering of the `header` container. - Controls the rendering of the `sidebar` container + Controls the rendering of the `sidebar` container. - Controls the rendering of the `footer` container + Controls the rendering of the `footer` container. - Controls the rendering of the `modals` container + Controls the rendering of the `modals` container. This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). diff --git a/website/docs/layouts/app-frame/partials/code/how-to-use.md b/website/docs/layouts/app-frame/partials/code/how-to-use.md index 84ee4af258..d9cf81756d 100644 --- a/website/docs/layouts/app-frame/partials/code/how-to-use.md +++ b/website/docs/layouts/app-frame/partials/code/how-to-use.md @@ -92,7 +92,7 @@ If for some reason it's not possible to use conditional logic to control the yie ### Modals container -We provide also an extra container that can be used to display content that sits on top of all the others elements of the page (typically modal elements): +We also provide an extra container that can be used to display content that sits on top of all the other elements of the page (typically modal elements): !!! Info From 92e255199a4db9bc0dbc1384f484cbd49080f219 Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Tue, 11 Apr 2023 10:22:58 +0100 Subject: [PATCH 14/16] replaced placeholder image with production illustration for cards --- .../illustrations/layouts/app-frame.jpg | Bin 14279 -> 18525 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/website/public/assets/illustrations/layouts/app-frame.jpg b/website/public/assets/illustrations/layouts/app-frame.jpg index d37ee5190c3fd2606162a360196ce47c848e2692..299fe7286a487c79a632767548094f5b258cf5a9 100644 GIT binary patch literal 18525 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

# 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 B=6(PG literal 14279 zcmeIzIZPB$7zgn0&3m)6yIL>{yMT@1bfx1^j)t({3Ur`=(t)5t$9fpd41< ztsM$@R3Mkq0ip{u;001~sX#N#0>Q+JKu7-XWirKk^CkapX5LS8Ycu4P>P&GGlNh=6 zN!m0e5C^|W00e>&ze5E7#x}Fsx+BxzJC74LPAg2 zPliREIvpJo8<&`L#(6e5CH36-jLfVH7qc(rl!uNf}>_bmORn6lI<;6<-U^b2K$$5ijH!ozdWu|JZTia zL3V1F%FVc;1^5c^Bj7B+aR?EhAvA=B&=49zLud#Mp&>MchR_fiLPKZ>4WS`4goe-% y8bU*82o0ejG=zrG5E?>5Xb26VAvA=B&=49zLud#Mp&>MchR_fi9)1l;o7@B{6WnS5 From 56ebc7219eee18fead094ae223b5c92ac124f839 Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Thu, 13 Apr 2023 15:42:31 +0100 Subject: [PATCH 15/16] small updates per code review suggestions --- packages/components/tests/acceptance/percy-test.js | 6 +++--- .../integration/components/hds/app-frame/index-test.js | 2 -- website/app/components/doc/page/sidebar.js | 2 +- website/app/controllers/components.js | 2 +- website/app/templates/components.hbs | 4 ++-- website/lib/markdown/table-of-contents.js | 2 +- 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/components/tests/acceptance/percy-test.js b/packages/components/tests/acceptance/percy-test.js index 49b9bb91e1..079e128fa7 100644 --- a/packages/components/tests/acceptance/percy-test.js +++ b/packages/components/tests/acceptance/percy-test.js @@ -119,15 +119,15 @@ module('Acceptance | Percy test', function (hooks) { await visit('/components/toast'); await percySnapshot('Toast'); - await visit('/utilities/dismiss-button'); - await percySnapshot('DismissButton'); - await visit('/layouts/app-frame'); await percySnapshot('AppFrame'); await visit('/overrides/power-select'); await percySnapshot('PowerSelect'); + await visit('/utilities/dismiss-button'); + await percySnapshot('DismissButton'); + assert.ok(true); }); }); diff --git a/packages/components/tests/integration/components/hds/app-frame/index-test.js b/packages/components/tests/integration/components/hds/app-frame/index-test.js index d41adcca1c..ec95aea8b9 100644 --- a/packages/components/tests/integration/components/hds/app-frame/index-test.js +++ b/packages/components/tests/integration/components/hds/app-frame/index-test.js @@ -39,8 +39,6 @@ module('Integration | Component | hds/app-frame/index', function (hooks) { `); - // await pauseTest(); - assert.dom('#test-app-frame[data-test-app-frame]').exists(); assert.dom('#test-app-frame-header[data-test-app-frame-header]').exists(); diff --git a/website/app/components/doc/page/sidebar.js b/website/app/components/doc/page/sidebar.js index 2a7403dcf1..ac38cb20f7 100644 --- a/website/app/components/doc/page/sidebar.js +++ b/website/app/components/doc/page/sidebar.js @@ -16,7 +16,7 @@ const DEBOUNCE_MS = 250; const getTocSectionsBundle = (section) => { const ABOUT = ['about', 'getting-started']; const FOUNDATIONS = ['foundations', 'icons']; - const COMPONENTS = ['components', 'overrides', 'layouts', 'utilities']; + const COMPONENTS = ['components', 'layouts', 'overrides', 'utilities']; const PATTERNS = ['patterns']; // this will be removed later const TESTING = ['testing']; diff --git a/website/app/controllers/components.js b/website/app/controllers/components.js index d1f6b5e49d..2ff128bc0f 100644 --- a/website/app/controllers/components.js +++ b/website/app/controllers/components.js @@ -9,7 +9,7 @@ export default class ComponentsController extends Controller { get cards() { // we want to use a flat tree here... const tocTree = this.model.toc.flat; - const sections = ['components', 'overrides', 'layouts', 'utilities']; + const sections = ['components', 'layouts', 'overrides', 'utilities']; const cards = {}; sections.forEach((section) => { cards[section] = tocTree diff --git a/website/app/templates/components.hbs b/website/app/templates/components.hbs index 9ccd4dd31c..bfc49d7503 100644 --- a/website/app/templates/components.hbs +++ b/website/app/templates/components.hbs @@ -9,10 +9,10 @@ -

Overrides

-

Layouts

+

Overrides

+

Utilities

diff --git a/website/lib/markdown/table-of-contents.js b/website/lib/markdown/table-of-contents.js index 5f3c485995..3b04c74abc 100644 --- a/website/lib/markdown/table-of-contents.js +++ b/website/lib/markdown/table-of-contents.js @@ -14,8 +14,8 @@ const CATEGORIES = [ 'updates', 'foundations', 'components', - 'overrides', 'layouts', + 'overrides', 'utilities', 'patterns', 'testing', From 050a2afa5bd539e15ff21728bb6ac27ac2b90dc6 Mon Sep 17 00:00:00 2001 From: Cristiano Rastelli Date: Thu, 13 Apr 2023 15:46:30 +0100 Subject: [PATCH 16/16] changeset --- .changeset/cyan-horses-buy.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cyan-horses-buy.md diff --git a/.changeset/cyan-horses-buy.md b/.changeset/cyan-horses-buy.md new file mode 100644 index 0000000000..008e3770a5 --- /dev/null +++ b/.changeset/cyan-horses-buy.md @@ -0,0 +1,5 @@ +--- +"@hashicorp/design-system-components": minor +--- + +Added `AppFrame` component