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 (