diff --git a/packages/calcite-components/src/components/alert/alert.scss b/packages/calcite-components/src/components/alert/alert.scss index 17587b14794..b726d2e0ee9 100644 --- a/packages/calcite-components/src/components/alert/alert.scss +++ b/packages/calcite-components/src/components/alert/alert.scss @@ -124,7 +124,7 @@ $border-style: 1px solid var(--calcite-color-border-3); inset-block-start: -2px; block-size: 2px; border-radius: var(--calcite-border-radius) var(--calcite-border-radius) 0 0; - &:after { + &::after { @apply absolute top-0 block; @@ -299,7 +299,7 @@ $alertDurations: } } -.container.focused .dismiss-progress:after { +.container.focused .dismiss-progress::after { animation-play-state: paused; } diff --git a/packages/calcite-components/src/components/flow-item/flow-item.stories.ts b/packages/calcite-components/src/components/flow-item/flow-item.stories.ts index 71fe853c7a7..102b3a1294f 100644 --- a/packages/calcite-components/src/components/flow-item/flow-item.stories.ts +++ b/packages/calcite-components/src/components/flow-item/flow-item.stories.ts @@ -65,15 +65,17 @@ const contentHTML = html` `; const footerHTML = html` - Naw. - Yeah! + Naw. + Yeah! `; const flowItemContent = `${headerHTML} ${contentHTML} - ${footerHTML}`; + Naw. + Yeah! + `; export const simple = (args: FlowItemStoryArgs): string => html` html` ${contentHTML} - ${footerHTML} + Naw. + Yeah! `; @@ -218,13 +221,34 @@ export const withActionBarAndContentTop_TestOnly = (): string => `; -export const footerPaddingAndContentBottom_TestOnly = (): string => +export const footerPaddingAndContentBottom = (): string => + html`
+ +
Header!
+

Slotted content!

+
Content bottom!
+
Footer!
+
+
`; + +export const footerStartEndAndContentBottom = (): string => + html`
+ +
Header!
+

Slotted content!

+
Content bottom!
+ ${footerHTML} +
+
`; + +export const footerSlotPrecedence = (): string => html`
Header!

Slotted content!

Content bottom!
Footer!
+ ${footerHTML}
`; diff --git a/packages/calcite-components/src/components/flow-item/flow-item.tsx b/packages/calcite-components/src/components/flow-item/flow-item.tsx index 2ad5c4169a6..55b0cbc0d58 100644 --- a/packages/calcite-components/src/components/flow-item/flow-item.tsx +++ b/packages/calcite-components/src/components/flow-item/flow-item.tsx @@ -50,8 +50,10 @@ import { CSS, ICONS, SLOTS } from "./resources"; * @slot header-content - A slot for adding custom content to the component's header. * @slot header-menu-actions - A slot for adding an overflow menu with `calcite-action`s inside a `calcite-dropdown`. * @slot fab - A slot for adding a `calcite-fab` (floating action button) to perform an action. - * @slot footer-actions - [Deprecated] Use the `"footer"` slot instead. A slot for adding `calcite-button`s to the component's footer. * @slot footer - A slot for adding custom content to the component's footer. + * @slot footer-actions - [Deprecated] Use the `"footer"` slot instead. A slot for adding `calcite-button`s to the component's footer. + * @slot footer-end - A slot for adding a trailing footer custom content. + * @slot footer-start - A slot for adding a leading footer custom content. */ @Component({ tag: "calcite-flow-item", @@ -390,8 +392,11 @@ export class FlowItem + + + + - diff --git a/packages/calcite-components/src/components/flow-item/resources.ts b/packages/calcite-components/src/components/flow-item/resources.ts index 2cae1fbcd32..3a560252586 100644 --- a/packages/calcite-components/src/components/flow-item/resources.ts +++ b/packages/calcite-components/src/components/flow-item/resources.ts @@ -18,4 +18,6 @@ export const SLOTS = { fab: "fab", footer: "footer", footerActions: "footer-actions", + footerEnd: "footer-end", + footerStart: "footer-start", }; diff --git a/packages/calcite-components/src/components/link/readme.md b/packages/calcite-components/src/components/link/readme.md index ebded6c52db..a74af0a8235 100644 --- a/packages/calcite-components/src/components/link/readme.md +++ b/packages/calcite-components/src/components/link/readme.md @@ -28,16 +28,16 @@ You can programmatically focus a `calcite-link` with the `setFocus()` method: ## Properties -| Property | Attribute | Description | Type | Default | -| ------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | ----------- | -| `disabled` | `disabled` | When `true`, interaction is prevented and the component is displayed with lower opacity. | `boolean` | `false` | +| Property | Attribute | Description | Type | Default | +| ------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | ----------- | +| `disabled` | `disabled` | When `true`, interaction is prevented and the component is displayed with lower opacity. | `boolean` | `false` | | `download` | `download` | Prompts the user to save the linked URL instead of navigating to it. Can be used with or without a value: Without a value, the browser will suggest a filename/extension See . | `boolean \| string` | `false` | -| `href` | `href` | Specifies the URL of the linked resource, which can be set as an absolute or relative path. | `string` | `undefined` | -| `iconEnd` | `icon-end` | Specifies an icon to display at the end of the component. | `string` | `undefined` | -| `iconFlipRtl` | `icon-flip-rtl` | Displays the `iconStart` and/or `iconEnd` as flipped when the element direction is right-to-left (`"rtl"`). | `"both" \| "end" \| "start"` | `undefined` | -| `iconStart` | `icon-start` | Specifies an icon to display at the start of the component. | `string` | `undefined` | -| `rel` | `rel` | Specifies the relationship to the linked document defined in `href`. | `string` | `undefined` | -| `target` | `target` | Specifies the frame or window to open the linked document. | `string` | `undefined` | +| `href` | `href` | Specifies the URL of the linked resource, which can be set as an absolute or relative path. | `string` | `undefined` | +| `iconEnd` | `icon-end` | Specifies an icon to display at the end of the component. | `string` | `undefined` | +| `iconFlipRtl` | `icon-flip-rtl` | Displays the `iconStart` and/or `iconEnd` as flipped when the element direction is right-to-left (`"rtl"`). | `"both" \| "end" \| "start"` | `undefined` | +| `iconStart` | `icon-start` | Specifies an icon to display at the start of the component. | `string` | `undefined` | +| `rel` | `rel` | Specifies the relationship to the linked document defined in `href`. | `string` | `undefined` | +| `target` | `target` | Specifies the frame or window to open the linked document. | `string` | `undefined` | ## Methods diff --git a/packages/calcite-components/src/components/panel/panel.scss b/packages/calcite-components/src/components/panel/panel.scss index 5fa4fb22448..d588d8d2b85 100644 --- a/packages/calcite-components/src/components/panel/panel.scss +++ b/packages/calcite-components/src/components/panel/panel.scss @@ -18,19 +18,25 @@ @import "../../assets/styles/header"; -:host([scale="s"]) .content-top, -.content-bottom { - padding: var(--calcite-spacing-sm); +:host([scale="s"]) { + .content-top, + .content-bottom { + padding: var(--calcite-spacing-sm); + } } -:host([scale="m"]) .content-top, -.content-bottom { - padding: var(--calcite-spacing-md); +:host([scale="m"]) { + .content-top, + .content-bottom { + padding: var(--calcite-spacing-md); + } } -:host([scale="l"]) .content-top, -.content-bottom { - padding: var(--calcite-spacing-xl); +:host([scale="l"]) { + .content-top, + .content-bottom { + padding: var(--calcite-spacing-xl); + } } .content-top, @@ -132,14 +138,25 @@ } .footer { - @apply bg-foreground-1 - flex - w-full - justify-evenly; + @apply flex mt-auto flex-row content-between justify-center items-center bg-foreground-1; - flex: 0 0 auto; - padding: var(--calcite-panel-footer-padding, theme("spacing.2")); border-block-start: 1px solid var(--calcite-color-border-3); + padding: var(--calcite-spacing-sm); + column-gap: 0; + row-gap: var(--calcite-spacing-md); +} + +@include slotted("footer-start", "*") { + @apply flex text-n2-wrap self-center; + + margin-inline-end: auto; + gap: var(--calcite-spacing-md); +} + +@include slotted("footer-end", "*") { + @apply flex text-n2-wrap self-center; + + gap: var(--calcite-spacing-md); } .fab-container { diff --git a/packages/calcite-components/src/components/panel/panel.stories.ts b/packages/calcite-components/src/components/panel/panel.stories.ts index e57051f846b..55aec5b6167 100644 --- a/packages/calcite-components/src/components/panel/panel.stories.ts +++ b/packages/calcite-components/src/components/panel/panel.stories.ts @@ -65,8 +65,8 @@ const contentHTML = html` `; const footerHTML = html` - Naw. - Yeah! + Naw. + Yeah! `; const panelContent = `${headerHTML} @@ -380,7 +380,7 @@ export const withNoHeaderBorderBlockEnd_TestOnly = (): string => >Slotted content!`; -export const contentTopBottomSlot = (): string => html` +export const footerAndContentTopBottomSlots = (): string => html`
Header!
@@ -399,3 +399,45 @@ export const contentTopBottomSlot = (): string => html`
`; + +export const footerStartAndEndSlots = (): string => html` + +
header-content slot
+

Slotted content!

+
Slot for a content-bottom.
+ + +
+`; + +export const footerSlotPrecedence = (): string => html` + +

Slotted content!

+
header-content slot
+
Slot for a content-bottom.
+ + ${footerHTML} +
+`; diff --git a/packages/calcite-components/src/components/panel/panel.tsx b/packages/calcite-components/src/components/panel/panel.tsx index 5c3416a2332..f23e41871bc 100644 --- a/packages/calcite-components/src/components/panel/panel.tsx +++ b/packages/calcite-components/src/components/panel/panel.tsx @@ -56,8 +56,10 @@ import { CSS, ICONS, SLOTS } from "./resources"; * @slot header-content - A slot for adding custom content to the header. * @slot header-menu-actions - A slot for adding an overflow menu with actions inside a `calcite-dropdown`. * @slot fab - A slot for adding a `calcite-fab` (floating action button) to perform an action. - * @slot footer-actions - [Deprecated] Use the `"footer"` slot instead. A slot for adding `calcite-button`s to the component's footer. - * @slot footer - A slot for adding custom content to the footer. + * @slot footer - A slot for adding custom content to the component's footer. + * @slot footer-actions - [Deprecated] Use the `footer-start` and `footer-end` slots instead. A slot for adding `calcite-button`s to the component's footer. + * @slot footer-end - A slot for adding a trailing footer custom content. + * @slot footer-start - A slot for adding a leading footer custom content. */ @Component({ tag: "calcite-panel", @@ -214,11 +216,15 @@ export class Panel @State() hasContentTop = false; - @State() hasFooterContent = false; + @State() hasFab = false; @State() hasFooterActions = false; - @State() hasFab = false; + @State() hasFooterContent = false; + + @State() hasFooterEndContent = false; + + @State() hasFooterStartContent = false; @State() defaultMessages: PanelMessages; @@ -323,16 +329,24 @@ export class Panel this.hasHeaderContent = slotChangeHasAssignedElement(event); }; - handleFooterSlotChange = (event: Event): void => { - this.hasFooterContent = slotChangeHasAssignedElement(event); + handleFabSlotChange = (event: Event): void => { + this.hasFab = slotChangeHasAssignedElement(event); }; handleFooterActionsSlotChange = (event: Event): void => { this.hasFooterActions = slotChangeHasAssignedElement(event); }; - handleFabSlotChange = (event: Event): void => { - this.hasFab = slotChangeHasAssignedElement(event); + handleFooterEndSlotChange = (event: Event): void => { + this.hasFooterEndContent = slotChangeHasAssignedElement(event); + }; + + handleFooterStartSlotChange = (event: Event): void => { + this.hasFooterStartContent = slotChangeHasAssignedElement(event); + }; + + handleFooterSlotChange = (event: Event): void => { + this.hasFooterContent = slotChangeHasAssignedElement(event); }; private contentBottomSlotChangeHandler = (event: Event): void => { @@ -561,13 +575,17 @@ export class Panel } renderFooterNode(): VNode { - const { hasFooterContent, hasFooterActions } = this; + const { hasFooterEndContent, hasFooterStartContent, hasFooterContent, hasFooterActions } = this; - const showFooter = hasFooterContent || hasFooterActions; + const showFooter = + hasFooterStartContent || hasFooterEndContent || hasFooterContent || hasFooterActions; return (