From 71107fd1da1269034de103dc28940cfe80371110 Mon Sep 17 00:00:00 2001 From: Brian Ferry Date: Thu, 11 Apr 2024 02:06:08 -0400 Subject: [PATCH] feat(card)!: remove BaseCard (#2586) * fix(card): moving styles and code from baseclass * chore: changset * feat(card): removing basecard class, styles * fix(card): remove unused basecard import * Update .changeset/sharp-spiders-float.md Co-authored-by: Benny Powers * docs: make changeset major * fix(card): make slot controller private * feat(card): title slot, header actions --------- Co-authored-by: Benny Powers Co-authored-by: Benny Powers --- .changeset/clever-yaks-thank.md | 4 + .changeset/sharp-spiders-float.md | 5 + elements/pf-card/BaseCard.css | 36 --- elements/pf-card/BaseCard.ts | 51 ----- .../demo/header-images-and-actions.html | 31 +++ elements/pf-card/demo/modifiers.html | 107 +++++++++ elements/pf-card/demo/pf-card.html | 9 +- elements/pf-card/demo/settings.html | 94 -------- .../title-inline-with-images-and-actions.html | 22 ++ elements/pf-card/docs/pf-card.md | 84 ++++++- elements/pf-card/pf-card.css | 215 ++++++++++++++---- elements/pf-card/pf-card.ts | 48 +++- 12 files changed, 460 insertions(+), 246 deletions(-) create mode 100644 .changeset/clever-yaks-thank.md create mode 100644 .changeset/sharp-spiders-float.md delete mode 100644 elements/pf-card/BaseCard.css delete mode 100644 elements/pf-card/BaseCard.ts create mode 100644 elements/pf-card/demo/header-images-and-actions.html create mode 100644 elements/pf-card/demo/modifiers.html delete mode 100644 elements/pf-card/demo/settings.html create mode 100644 elements/pf-card/demo/title-inline-with-images-and-actions.html diff --git a/.changeset/clever-yaks-thank.md b/.changeset/clever-yaks-thank.md new file mode 100644 index 0000000000..b10af4b792 --- /dev/null +++ b/.changeset/clever-yaks-thank.md @@ -0,0 +1,4 @@ +--- +"@patternfly/elements": minor +--- +``: added `title` slot, for when the title is not inline with any slotted header actions diff --git a/.changeset/sharp-spiders-float.md b/.changeset/sharp-spiders-float.md new file mode 100644 index 0000000000..373def2e63 --- /dev/null +++ b/.changeset/sharp-spiders-float.md @@ -0,0 +1,5 @@ +--- +"@patternfly/elements": major +--- + +``: Removes `BaseCard` base class. If your project extends `BaseCard`, we recommend extending `LitElement` instead and re-implementing card's properties. Alternately, extend from `PfCard`. diff --git a/elements/pf-card/BaseCard.css b/elements/pf-card/BaseCard.css deleted file mode 100644 index 2e51a2a5e4..0000000000 --- a/elements/pf-card/BaseCard.css +++ /dev/null @@ -1,36 +0,0 @@ -:host { - display: flex; - flex-direction: column; -} - -article { - position: relative; - height: 100%; - display: flex; - flex-direction: column; -} - -[part=header] { - display: flex; - flex-direction: row; - align-items: center; -} - -[part=body] ::slotted(:not([slot]):first-of-type) { - margin-block-start: 0 !important; -} - -[part=body] ::slotted(:not([slot]):last-of-type) { - margin-block-end: 0 !important; -} - -[part=footer] { - display: flex; - gap: 0.5em; - inset-block-end: 0; -} - -.empty { - display: none; -} - diff --git a/elements/pf-card/BaseCard.ts b/elements/pf-card/BaseCard.ts deleted file mode 100644 index 690c928d19..0000000000 --- a/elements/pf-card/BaseCard.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { LitElement, html } from 'lit'; -import { SlotController } from '@patternfly/pfe-core/controllers/slot-controller.js'; - -import { classMap } from 'lit/directives/class-map.js'; - -import style from './BaseCard.css'; - -/** - * This element creates a header, body, and footer region in which to place - * content or other components. - * - * @summary Gives a preview of information in a small layout - * - * @slot header - * If this slot is used, we expect a heading level tag (h1, h2, h3, h4, h5, h6). - * An icon, svg, or use of the icon component are also valid in this region. - * @slot - Any content that is not designated for the header or footer slot, will go to this slot. - * @slot footer - * Use this slot for anything that you want to be stuck to the base of the card. - * - * @csspart header - The container for *header* content - * @csspart body - The container for *body* content - * @csspart footer - The container for *footer* content - */ -export abstract class BaseCard extends LitElement { - static readonly styles = [style]; - - protected slots = new SlotController(this, 'header', null, 'footer'); - - render() { - return html` -
- -
- -
-
- -
-
- `; - } -} diff --git a/elements/pf-card/demo/header-images-and-actions.html b/elements/pf-card/demo/header-images-and-actions.html new file mode 100644 index 0000000000..03cd21ee88 --- /dev/null +++ b/elements/pf-card/demo/header-images-and-actions.html @@ -0,0 +1,31 @@ + + + + + + + + + Action + Link + Disabled Action + Disabled Link +
+ Separated Action + Separated Link +
+
+

Title

+ Body + Footer +
+ + diff --git a/elements/pf-card/demo/modifiers.html b/elements/pf-card/demo/modifiers.html new file mode 100644 index 0000000000..d25fab3f30 --- /dev/null +++ b/elements/pf-card/demo/modifiers.html @@ -0,0 +1,107 @@ +
+
+ + + + + + + + + + + + + + + + + +
+ +
+ +

Lightest card

+

This is the lightest pf-card and a link, and a visited link with border.

+ Try + Buy +
+
+
+ + + + diff --git a/elements/pf-card/demo/pf-card.html b/elements/pf-card/demo/pf-card.html index 300c4e9a5e..3f5df03b08 100644 --- a/elements/pf-card/demo/pf-card.html +++ b/elements/pf-card/demo/pf-card.html @@ -1,18 +1,15 @@ -

Lightest card

-

This is the lightest pf-card and a link, and a visited link with border.

- Try - Buy +

Header

+ Body + Footer
diff --git a/elements/pf-card/demo/settings.html b/elements/pf-card/demo/settings.html deleted file mode 100644 index a242b24405..0000000000 --- a/elements/pf-card/demo/settings.html +++ /dev/null @@ -1,94 +0,0 @@ -
-
- - - - - - - - - - - - - - - -
- -
- -

Lightest card

-

This is the lightest pf-card and a link, and a visited link with border.

- Try - Buy -
-
-
- - - - diff --git a/elements/pf-card/demo/title-inline-with-images-and-actions.html b/elements/pf-card/demo/title-inline-with-images-and-actions.html new file mode 100644 index 0000000000..4157935d7e --- /dev/null +++ b/elements/pf-card/demo/title-inline-with-images-and-actions.html @@ -0,0 +1,22 @@ + +

This is a really really really really really really really really really really long header

+ + + + Action + Link + Disabled Action + Disabled Link +
+ Separated Action + Separated Link +
+
+ Body + Footer +
+ + diff --git a/elements/pf-card/docs/pf-card.md b/elements/pf-card/docs/pf-card.md index 7410a941ea..e8101deb2b 100644 --- a/elements/pf-card/docs/pf-card.md +++ b/elements/pf-card/docs/pf-card.md @@ -13,7 +13,9 @@ {% band header="Usage" %} - ### Compact card + ### Basic cards + + ### Modifiers {% htmlexample %}

Header

@@ -22,20 +24,20 @@
{% endhtmlexample %} - ### Rounded card + ### Large card {% htmlexample %} - -

Header

-

This is the rounded card

+ +

Large card

+

This is the large card

Link in the footer
{% endhtmlexample %} - ### Large card + ### Rounded card {% htmlexample %} - -

Large card

-

This is the large card

+ +

Header

+

This is the rounded card

Link in the footer
{% endhtmlexample %} @@ -57,6 +59,65 @@ Link in the footer
{% endhtmlexample %} + + ### Header images and actions + You can include header images and actions in the `header` slot, along with a + title in the `title` slot. The following example includes an SVG image, and + also includes a kebab dropdown. + + {% htmlexample %} + + + + + + + + + Action + Link + Disabled Action + Disabled Link +
+ Separated Action + Separated Link +
+
+

Title

+ Body + Footer +
+ {% endhtmlexample %} + + ### Title inline with images and actions + Slotting the `

` into the `header` slot, instead of the `title` slot will + style it inline with any images or actions. + + {% htmlexample %} + +

This is a really really really really really really really really really really long header

+ + + + Action + Link + Disabled Action + Disabled Link +
+ Separated Action + Separated Link +
+
+ Body + Footer +
+ {% endhtmlexample %} + {% endband %} {% renderSlots %} @@ -79,3 +140,8 @@ {% renderCssCustomProperties %}{% endrenderCssCustomProperties %} {% renderCssParts %}{% endrenderCssParts %} + + diff --git a/elements/pf-card/pf-card.css b/elements/pf-card/pf-card.css index 507b5eabc9..93f47a4ade 100644 --- a/elements/pf-card/pf-card.css +++ b/elements/pf-card/pf-card.css @@ -1,73 +1,202 @@ :host { - background-color: var(--pf-c-card--BackgroundColor, var(--pf-global--BackgroundColor--100, #ffffff)); - box-shadow: var(--pf-c-card--BoxShadow, var(--pf-global--BoxShadow--sm, 0 0.0625rem 0.125rem 0 rgba(3, 3, 3, 0.12), 0 0 0.125rem 0 rgba(3, 3, 3, 0.06))); + --pf-c-card--BackgroundColor: var(--pf-global--BackgroundColor--100, #fff); + --pf-c-card--BoxShadow: var(--pf-global--BoxShadow--sm, 0 0.0625rem 0.125rem 0 rgba(3, 3, 3, 0.12), 0 0 0.125rem 0 rgba(3, 3, 3, 0.06)); + --pf-c-card--first-child--PaddingTop: var(--pf-global--spacer--lg, 1.5rem); + --pf-c-card--child--PaddingRight: var(--pf-global--spacer--lg, 1.5rem); + --pf-c-card--child--PaddingBottom: var(--pf-global--spacer--lg, 1.5rem); + --pf-c-card--child--PaddingLeft: var(--pf-global--spacer--lg, 1.5rem); + --pf-c-card--c-divider--child--PaddingTop: var(--pf-global--spacer--lg, 1.5rem); + --pf-c-card__title--FontFamily: var(--pf-global--FontFamily--heading--sans-serif, "RedHatDisplay", "Overpass", overpass, helvetica, arial, sans-serif); + --pf-c-card__title--FontSize: var(--pf-global--FontSize--md, 1rem); + --pf-c-card__title--FontWeight: var(--pf-global--FontWeight--bold, 700); + --pf-c-card__title--not--last-child--PaddingBottom: var(--pf-global--spacer--md, 1rem); + --pf-c-card__body--FontSize: var(--pf-global--FontSize--md, 1rem); + --pf-c-card__footer--FontSize: var(--pf-global--FontSize--md, 1rem); + --pf-c-card__actions--PaddingLeft: var(--pf-global--spacer--md, 1rem); + --pf-c-card__actions--child--MarginLeft: var(--pf-global--spacer--sm, 0.5rem); + --pf-c-card__header-toggle--MarginTop: calc(var(--pf-global--spacer--form-element, 0.375rem) * -1); + --pf-c-card__header-toggle--MarginRight: var(--pf-global--spacer--xs, 0.25rem); + --pf-c-card__header-toggle--MarginBottom: calc(var(--pf-global--spacer--form-element, 0.375rem) * -1); + --pf-c-card__header-toggle--MarginLeft: calc(var(--pf-global--spacer--md, 1rem) * -1); + --pf-c-card__header-toggle-icon--Transition: var(--pf-global--Transition, all 250ms cubic-bezier(0.42, 0, 0.58, 1)); + --pf-c-card--m-expanded__header-toggle-icon--Rotate: 90deg; + --pf-c-card--m-hoverable--hover--BoxShadow: var(--pf-global--BoxShadow--lg, 0 0.5rem 1rem 0 rgba(3, 3, 3, 0.16), 0 0 0.375rem 0 rgba(3, 3, 3, 0.08)); + --pf-c-card--m-selectable--hover--BoxShadow: var(--pf-global--BoxShadow--lg, 0 0.5rem 1rem 0 rgba(3, 3, 3, 0.16), 0 0 0.375rem 0 rgba(3, 3, 3, 0.08)); + --pf-c-card--m-selectable--focus--BoxShadow: var(--pf-global--BoxShadow--lg, 0 0.5rem 1rem 0 rgba(3, 3, 3, 0.16), 0 0 0.375rem 0 rgba(3, 3, 3, 0.08)); + --pf-c-card--m-selectable--active--BoxShadow: var(--pf-global--BoxShadow--lg, 0 0.5rem 1rem 0 rgba(3, 3, 3, 0.16), 0 0 0.375rem 0 rgba(3, 3, 3, 0.08)); + --pf-c-card--m-selectable--m-selected--BoxShadow: var(--pf-global--BoxShadow--lg, 0 0.5rem 1rem 0 rgba(3, 3, 3, 0.16), 0 0 0.375rem 0 rgba(3, 3, 3, 0.08)); + --pf-c-card--m-selectable--m-selected--before--Height: var(--pf-global--BorderWidth--lg, 3px); + --pf-c-card--m-selectable--m-selected--before--BackgroundColor: var(--pf-global--active-color--100, #06c); + --pf-c-card--m-hoverable-raised--hover--BoxShadow: var(--pf-global--BoxShadow--md, 0 0.25rem 0.5rem 0rem rgba(3, 3, 3, 0.12), 0 0 0.25rem 0 rgba(3, 3, 3, 0.06)); + --pf-c-card--m-hoverable-raised--hover--before--BackgroundColor: var(--pf-global--active-color--400, #73bcf7); + --pf-c-card--m-selectable-raised--before--Right: 0; + --pf-c-card--m-selectable-raised--before--Bottom: 0; + --pf-c-card--m-selectable-raised--before--Left: 0; + --pf-c-card--m-flat--m-selectable-raised--before--Right: calc(-1 * var(--pf-c-card--m-flat--BorderWidth)); + --pf-c-card--m-flat--m-selectable-raised--before--Bottom: calc(-1 * var(--pf-c-card--m-flat--BorderWidth)); + --pf-c-card--m-flat--m-selectable-raised--before--Left: calc(-1 * var(--pf-c-card--m-flat--BorderWidth)); + --pf-c-card--m-selectable-raised--before--Height: var(--pf-global--BorderWidth--xl, 4px); + --pf-c-card--m-selectable-raised--before--BackgroundColor: transparent; + --pf-c-card--m-selectable-raised--before--Transition: none; + --pf-c-card--m-selectable-raised--before--ScaleY: 1; + --pf-c-card--m-selectable-raised--before--TranslateY: 0; + --pf-c-card--m-selectable-raised--hover--BoxShadow: var(--pf-global--BoxShadow--md, 0 0.25rem 0.5rem 0rem rgba(3, 3, 3, 0.12), 0 0 0.25rem 0 rgba(3, 3, 3, 0.06)); + --pf-c-card--m-selectable-raised--hover--before--BackgroundColor: var(--pf-global--active-color--400, #73bcf7); + --pf-c-card--m-selectable-raised--focus--BoxShadow: var(--pf-global--BoxShadow--md, 0 0.25rem 0.5rem 0rem rgba(3, 3, 3, 0.12), 0 0 0.25rem 0 rgba(3, 3, 3, 0.06)); + --pf-c-card--m-selectable-raised--focus--before--BackgroundColor: var(--pf-global--active-color--400, #73bcf7); + --pf-c-card--m-selectable-raised--active--BoxShadow: var(--pf-global--BoxShadow--md, 0 0.25rem 0.5rem 0rem rgba(3, 3, 3, 0.12), 0 0 0.25rem 0 rgba(3, 3, 3, 0.06)); + --pf-c-card--m-selectable-raised--active--before--BackgroundColor: var(--pf-global--active-color--400, #73bcf7); + --pf-c-card--m-selectable-raised--m-selected-raised--before--BackgroundColor: var(--pf-global--active-color--100, #06c); + --pf-c-card--m-selectable-raised--m-selected-raised--BoxShadow: var(--pf-global--BoxShadow--lg, 0 0.5rem 1rem 0 rgba(3, 3, 3, 0.16), 0 0 0.375rem 0 rgba(3, 3, 3, 0.08)); + --pf-c-card--m-selectable-raised--m-selected-raised--TranslateY--base: -0.5rem; + --pf-c-card--m-selectable-raised--m-selected-raised--TranslateY: var(--pf-c-card--m-selectable-raised--m-selected-raised--TranslateY--base); + --pf-c-card--m-flat--m-selectable-raised--m-selected-raised--TranslateY: calc(var(--pf-c-card--m-selectable-raised--m-selected-raised--TranslateY--base) + var(--pf-c-card--m-flat--BorderWidth)); + --pf-c-card--m-rounded--m-selectable-raised--m-selected-raised--TranslateY: calc(var(--pf-c-card--m-selectable-raised--m-selected-raised--TranslateY--base) + var(--pf-c-card--m-rounded--BorderRadius)); + --pf-c-card--m-selectable-raised--m-selected-raised--ZIndex: var(--pf-global--ZIndex--xs, 100); + --pf-c-card--m-selectable-raised--m-selected-raised--Transition: transform .25s linear, box-shadow .25s linear; + --pf-c-card--m-selectable-raised--m-selected-raised--before--Transition: transform .25s linear; + --pf-c-card--m-selectable-raised--m-selected-raised--before--TranslateY: calc(var(--pf-c-card--m-selectable-raised--m-selected-raised--TranslateY) * -1); + --pf-c-card--m-selectable-raised--m-selected-raised--before--ScaleY: 2; + --pf-c-card--m-non-selectable-raised--BackgroundColor: var(--pf-global--BackgroundColor--light-200, #fafafa); + --pf-c-card--m-non-selectable-raised--before--BackgroundColor: var(--pf-global--disabled-color--200, #d2d2d2); + --pf-c-card--m-non-selectable-raised--before--ScaleY: 2; + --pf-c-card--m-flat--m-non-selectable-raised--before--BorderColor: var(--pf-global--disabled-color--200, #d2d2d2); + --pf-c-card--m-compact__body--FontSize: var(--pf-global--FontSize--sm, 0.875rem); + --pf-c-card--m-compact__footer--FontSize: var(--pf-global--FontSize--sm, 0.875rem); + --pf-c-card--m-compact--first-child--PaddingTop: var(--pf-global--spacer--md, 1rem); + --pf-c-card--m-compact--child--PaddingRight: var(--pf-global--spacer--md, 1rem); + --pf-c-card--m-compact--child--PaddingBottom: var(--pf-global--spacer--md, 1rem); + --pf-c-card--m-compact--child--PaddingLeft: var(--pf-global--spacer--md, 1rem); + --pf-c-card--m-compact--c-divider--child--PaddingTop: var(--pf-global--spacer--md, 1rem); + --pf-c-card--m-compact__title--not--last-child--PaddingBottom: var(--pf-global--spacer--sm, 0.5rem); + --pf-c-card--m-display-lg__title--FontSize: var(--pf-global--FontSize--xl, 1.25rem); + --pf-c-card--m-display-lg--first-child--PaddingTop: var(--pf-global--spacer--xl, 2rem); + --pf-c-card--m-display-lg--child--PaddingRight: var(--pf-global--spacer--xl, 2rem); + --pf-c-card--m-display-lg--child--PaddingBottom: var(--pf-global--spacer--xl, 2rem); + --pf-c-card--m-display-lg--child--PaddingLeft: var(--pf-global--spacer--xl, 2rem); + --pf-c-card--m-display-lg--c-divider--child--PaddingTop: var(--pf-global--spacer--xl, 2rem); + --pf-c-card--m-display-lg__title--not--last-child--PaddingBottom: var(--pf-global--spacer--lg, 1.5rem); + --pf-c-card--m-flat--BorderWidth: var(--pf-global--BorderWidth--sm, 1px); + --pf-c-card--m-flat--BorderColor: var(--pf-global--BorderColor--100, #d2d2d2); + --pf-c-card--m-rounded--BorderRadius: var(--pf-global--BorderRadius--sm, 3px); + --pf-c-card--m-full-height--Height: 100%; + --pf-c-card--m-plain--BoxShadow: none; + --pf-c-card--m-plain--BackgroundColor: transparent; + --pf-c-card__header--m-toggle-right--toggle--MarginRight: calc(var(--pf-global--spacer--form-element, 0.375rem) * -1); + --pf-c-card__header--m-toggle-right--toggle--MarginLeft: var(--pf-global--spacer--xs, 0.25rem); + --pf-c-card__header--m-toggle-right--actions--MarginRight: 0; + --pf-c-card__input--focus--BorderWidth: var(--pf-global--BorderWidth--md, 2px); + --pf-c-card__input--focus--BorderColor: var(--pf-global--primary-color--100, #06c); + display: flex; + flex-direction: column; + background-color: var(--pf-c-card--BackgroundColor); + box-shadow: var(--pf-c-card--BoxShadow); } -:host([size="compact"]) { - --_pf-c-card__body--FontSize: var(--pf-c-card--size-compact__body--FontSize, var(--pf-global--FontSize--sm, .875rem)); - --_pf-c-card__footer--FontSize: var(--pf-c-card--size-compact__footer--FontSize, var(--pf-global--spacer--md, 1rem)); - --_pf-c-card--first-child--PaddingTop: var(--pf-c-card--size-compact--first-child--PaddingTop, var(--pf-global--spacer--lg, 1.5rem)); - --_pf-c-card--child--PaddingRight: var(--pf-c-card--size-compact--child--PaddingRight, var(--pf-global--spacer--md, 1rem)); - --_pf-c-card--child--PaddingBottom: var(--pf-c-card--size-compact--child--PaddingBottom, var(--pf-global--spacer--md, 1rem)); - --_pf-c-card--child--PaddingLeft: var(--pf-c-card--size-compact--child--PaddingLeft, var(--pf-global--spacer--md, 1rem)); - --_pf-c-card__title--not--last-child--PaddingBottom: var(--pf-c-card--size-compact__title--not--last-child--PaddingBottom, var(--pf-global--spacer--sm, .5rem)); +[hidden], +.empty { + display: none !important; } -:host([size="large"]) { - --pf-c-card__title--FontSize: var(--pf-c-card--size-large__title--FontSize, var(--pf-global--FontSize--xl, 1.25rem)); - --_pf-c-card--first-child--PaddingTop: var(--pf-c-card--size-large--first-child--PaddingTop, var(--pf-global--spacer--xl, 2rem)); - --_pf-c-card--child--PaddingRight: var(--pf-c-card--size-large--child--PaddingRight, var(--pf-global--spacer--xl, 2rem)); - --_pf-c-card--child--PaddingBottom: var(--pf-c-card--size-large--child--PaddingBottom, var(--pf-global--spacer--xl, 2rem)); - --_pf-c-card--child--PaddingLeft: var(--pf-c-card--size-large--child--PaddingLeft, var(--pf-global--spacer--xl, 2rem)); - --_pf-c-card__title--not--last-child--PaddingBottom: var(--pf-c-card--size-large__title--not--last-child--PaddingBottom, var(--pf-global--spacer--lg, 1.5rem)); +header { + padding-block-start: var(--pf-c-card--first-child--PaddingTop); + padding-block-end: var(--pf-c-card__title--not--last-child--PaddingBottom); + display: flex; + flex-flow: row wrap; + align-items: center; } -:host([flat]) { - --pf-c-card--BoxShadow: none; - border: var(--pf-c-card--m-flat--BorderWidth, var(--pf-global--BorderWidth--sm, 1px)) solid var(--pf-c-card--m-flat--BorderColor, var(--pf-global--BorderColor--100, #d2d2d2)); -} +header ::slotted(*) { + margin-block: 0 !important; -:host([plain]) { - --pf-c-card--BoxShadow: var(--pf-c-card--m-plain--BoxShadow, none); - --pf-c-card--BackgroundColor: var(--pf-c-card--m-plain--BackgroundColor, transparent); + font-family: var(--pf-c-card__title--FontFamily) !important; + font-size: var(--pf-c-card__title--FontSize) !important; + font-weight: var(--pf-c-card__title--FontWeight) !important; } -:host([rounded]) { - border-radius: var(--pf-c-card--m-rounded--BorderRadius, var(--pf-global--BorderRadius--sm, 3px)); +header ::slotted(pf-dropdown) { + margin-inline-start: auto; } -:host([full-height]) { - height: var(--pf-c-card--m-full-height--Height, 100%); - --_pf-c-card__body--FullHeight--Flex: 1 1 auto; +article { + position: relative; + height: 100%; + display: flex; + flex-direction: column; } [part="header"], [part="body"], [part="footer"] { - padding-inline-start: var(--_pf-c-card--child--PaddingLeft, var(--pf-global--spacer--lg, 1.5rem)); - padding-inline-end: var(--_pf-c-card--child--PaddingRight, var(--pf-global--spacer--lg, 1.5rem)); - padding-block-end: var(--_pf-c-card--child--PaddingBottom, var(--pf-global--spacer--lg, 1.5rem)); + padding-inline-start: var(--pf-c-card--child--PaddingLeft); + padding-inline-end: var(--pf-c-card--child--PaddingRight); + padding-block-end: var(--pf-c-card--child--PaddingBottom); +} + +#title { + display: block; + flex: 1 0 100%; + padding-block-start: var(--pf-c-card__title--not--last-child--PaddingBottom); } [part="body"] { - font-size: var(--_pf-c-card__body--FontSize, var(--pf-global--FontSize--md, 1rem)); - flex: var(--_pf-c-card__body--FullHeight--Flex, initial); + font-size: var(--pf-c-card__body--FontSize); + flex: var(--pf-c-card__body--FullHeight--Flex); } -header { - padding-block-start: var(--_pf-c-card--first-child--PaddingTop, var(--pf-global--spacer--lg, 1.5rem)); - padding-block-end: var(--_pf-c-card__title--not--last-child--PaddingBottom, var(--pf-global--spacer--md, 1rem)); +[part="body"] ::slotted(:not([slot]):first-of-type) { + margin-block-start: 0 !important; } -header ::slotted(*) { - font-family: var(--pf-c-card__title--FontFamily, var(--pf-global--FontFamily--heading--sans-serif, "RedHatDisplayUpdated", helvetica, arial, sans-serif)) !important; - font-size: var(--pf-c-card__title--FontSize, var(--pf-global--FontSize--md, 1rem)) !important; - font-weight: var(--pf-c-card__title--FontWeight, var(--pf-global--FontWeight--bold, 700)) !important; - margin-block: 0 !important; +[part="body"] ::slotted(:not([slot]):last-of-type) { + margin-block-end: 0 !important; } [part="footer"] { - font-size: var(--_pf-c-card__footer--FontSize, var(--pf-global--FontSize--md, 1rem)); margin-block-start: auto; + display: flex; + gap: 0.5em; + inset-block-end: 0; + font-size: var(--pf-c-card__footer--FontSize); +} + +:host([size="compact"]) { + --pf-c-card__body--FontSize: var(--pf-c-card--m-compact__body--FontSize); + --pf-c-card__footer--FontSize: var(--pf-c-card--m-compact__footer--FontSize); + --pf-c-card--first-child--PaddingTop: var(--pf-c-card--m-compact--first-child--PaddingTop); + --pf-c-card--child--PaddingRight: var(--pf-c-card--m-compact--child--PaddingRight); + --pf-c-card--child--PaddingBottom: var(--pf-c-card--m-compact--child--PaddingBottom); + --pf-c-card--child--PaddingLeft: var(--pf-c-card--m-compact--child--PaddingLeft); + --pf-c-card--c-divider--child--PaddingTop: var(--pf-c-card--m-compact--c-divider--child--PaddingTop); + --pf-c-card__title--not--last-child--PaddingBottom: var(--pf-c-card--m-compact__title--not--last-child--PaddingBottom); +} + +:host([size="large"]) { + --pf-c-card__title--FontSize: var(--pf-c-card--m-display-lg__title--FontSize); + --pf-c-card--first-child--PaddingTop: var(--pf-c-card--m-display-lg--first-child--PaddingTop); + --pf-c-card--child--PaddingRight: var(--pf-c-card--m-display-lg--child--PaddingRight); + --pf-c-card--child--PaddingBottom: var(--pf-c-card--m-display-lg--child--PaddingBottom); + --pf-c-card--child--PaddingLeft: var(--pf-c-card--m-display-lg--child--PaddingLeft); + --pf-c-card--c-divider--child--PaddingTop: var(--pf-c-card--m-display-lg--c-divider--child--PaddingTop); + --pf-c-card__title--not--last-child--PaddingBottom: var(--pf-c-card--m-display-lg__title--not--last-child--PaddingBottom); +} + +:host([flat]) { + --pf-c-card--BoxShadow: none; + border: var(--pf-c-card--m-flat--BorderWidth) solid var(--pf-c-card--m-flat--BorderColor); +} + +:host([plain]) { + --pf-c-card--BoxShadow: var(--pf-c-card--m-plain--BoxShadow); + --pf-c-card--BackgroundColor: var(--pf-c-card--m-plain--BackgroundColor); +} + +:host([rounded]) { + border-radius: var(--pf-c-card--m-rounded--BorderRadius); +} + +:host([full-height]) { + height: var(--pf-c-card--m-full-height--Height); + --pf-c-card__body--FullHeight--Flex: 1 1 auto; } diff --git a/elements/pf-card/pf-card.ts b/elements/pf-card/pf-card.ts index 850e5624ac..890744e900 100644 --- a/elements/pf-card/pf-card.ts +++ b/elements/pf-card/pf-card.ts @@ -1,8 +1,11 @@ +import { LitElement, html } from 'lit'; import { customElement } from 'lit/decorators/custom-element.js'; import { property } from 'lit/decorators/property.js'; +import { classMap } from 'lit/directives/class-map.js'; + +import { SlotController } from '@patternfly/pfe-core/controllers/slot-controller.js'; import style from './pf-card.css'; -import { BaseCard } from './BaseCard.js'; /** * A **card** is a square or rectangular container that can contain any kind of content. @@ -14,11 +17,17 @@ import { BaseCard } from './BaseCard.js'; * @summary Gives a preview of information in a small layout * * @slot header - * If this slot is used, we expect a heading level tag (h1, h2, h3, h4, h5, h6). - * An icon, svg, or use of the icon component are also valid in this region. - * @slot - Any content that is not designated for the header or footer slot, will go to this slot. + * When included, defines the contents of a card. Card headers can contain images as well as + * the title of a card and an actions menu represented by the right-aligned kebab. + * In most cases, your card should include a header. The only exceptions are when cards being + * used as a layout element to create a white background behind other content. + * @slot title + * Communicates the title of a card if it's not included in the header. + * If a card will be utilized as a selectable and clickable card, the title needs to be made as a linked text to trigger action and indicate interaction. + * @slot - Body. Provides details about the item. A card body can include any combination of static + * text and/or active content. * @slot footer - * Use this slot for anything that you want to be stuck to the base of the card. + * Contains external links, actions, or static text at the bottom of a card. * * @csspart header - The container for *header* content * @csspart body - The container for *body* content @@ -50,8 +59,8 @@ import { BaseCard } from './BaseCard.js'; * @cssproperty {} --pf-c-card__title--FontWeight {@default `700`} */ @customElement('pf-card') -export class PfCard extends BaseCard { - static readonly styles = [...BaseCard.styles, style]; +export class PfCard extends LitElement { + static readonly styles = [style]; /** * Optionally provide a size for the card and the card contents. @@ -75,6 +84,31 @@ export class PfCard extends BaseCard { * Optionally remove the border on the card container. */ @property({ type: Boolean, reflect: true }) plain = false; + + #slots = new SlotController(this, 'header', 'title', null, 'footer'); + + render() { + return html` +
+ +
+ +
+ +
+ `; + } } declare global {