diff --git a/packages/beeq/src/components.d.ts b/packages/beeq/src/components.d.ts
index 204d7beb3..d1c4348dc 100644
--- a/packages/beeq/src/components.d.ts
+++ b/packages/beeq/src/components.d.ts
@@ -13,6 +13,7 @@ import { TButtonAppearance, TButtonBorderRadius, TButtonSize, TButtonType, TButt
import { TCardBorderRadius, TCardType } from "./components/card/bq-card.types";
import { TDialogBorderRadius, TDialogFooterAppearance, TDialogSize } from "./components/dialog/bq-dialog.types";
import { TDividerOrientation, TDividerStrokeLinecap, TDividerTitleAlignment } from "./components/divider/bq-divider.types";
+import { TDrawerPlacement } from "./components/drawer/bq-drawer.types";
import { FloatingUIPlacement } from "./services/interfaces";
import { TEmptyStateSize } from "./components/empty-state/bq-empty-state.types";
import { TIconWeight } from "./components/icon/bq-icon.types";
@@ -38,6 +39,7 @@ export { TButtonAppearance, TButtonBorderRadius, TButtonSize, TButtonType, TButt
export { TCardBorderRadius, TCardType } from "./components/card/bq-card.types";
export { TDialogBorderRadius, TDialogFooterAppearance, TDialogSize } from "./components/dialog/bq-dialog.types";
export { TDividerOrientation, TDividerStrokeLinecap, TDividerTitleAlignment } from "./components/divider/bq-divider.types";
+export { TDrawerPlacement } from "./components/drawer/bq-drawer.types";
export { FloatingUIPlacement } from "./services/interfaces";
export { TEmptyStateSize } from "./components/empty-state/bq-empty-state.types";
export { TIconWeight } from "./components/icon/bq-icon.types";
@@ -408,6 +410,7 @@ export namespace Components {
* If true, the drawer component will be shown
*/
"open": boolean;
+ "placement"?: TDrawerPlacement;
/**
* Method to be called to show the notification component
*/
@@ -2437,6 +2440,7 @@ declare namespace LocalJSX {
* If true, the drawer component will be shown
*/
"open"?: boolean;
+ "placement"?: TDrawerPlacement;
}
interface BqDropdown {
/**
diff --git a/packages/beeq/src/components/drawer/_storybook/bq-drawer.stories.tsx b/packages/beeq/src/components/drawer/_storybook/bq-drawer.stories.tsx
index 802ea19a1..8dff2434b 100644
--- a/packages/beeq/src/components/drawer/_storybook/bq-drawer.stories.tsx
+++ b/packages/beeq/src/components/drawer/_storybook/bq-drawer.stories.tsx
@@ -2,6 +2,7 @@ import type { Args, Meta, StoryObj } from '@storybook/web-components';
import { html } from 'lit-html';
import mdx from './bq-drawer.mdx';
+import { DRAWER_PLACEMENT } from '../bq-drawer.types';
const meta: Meta = {
title: 'Components/Drawer',
@@ -13,6 +14,7 @@ const meta: Meta = {
},
argTypes: {
open: { control: 'boolean' },
+ placement: { control: 'select', options: [...DRAWER_PLACEMENT] },
// Events
bqShow: { action: 'bqOpen' },
bqHide: { action: 'bqClose' },
@@ -21,19 +23,37 @@ const meta: Meta = {
},
args: {
open: false,
+ placement: 'left',
},
};
export default meta;
type Story = StoryObj;
-const Template = (args: Args) => html`
-
+const Template = (args: Args) => {
+ const handleOpenDrawer = async () => {
+ const dialogElem = document.querySelector('bq-drawer');
+ await dialogElem.show();
+ };
+
+ return html`
+
Open Drawer
-
Title
+
+
+
+ Title
+
Slot
@@ -41,26 +61,16 @@ const Template = (args: Args) => html`
Button
Button
-
-
-
-
-`;
+ `;
+};
export const Default: Story = {
render: Template,
args: {
- open: true,
+ open: false,
+ placement: 'left',
},
};
diff --git a/packages/beeq/src/components/drawer/bq-drawer.tsx b/packages/beeq/src/components/drawer/bq-drawer.tsx
index c8c1f194e..1f89c7975 100644
--- a/packages/beeq/src/components/drawer/bq-drawer.tsx
+++ b/packages/beeq/src/components/drawer/bq-drawer.tsx
@@ -1,6 +1,7 @@
import { Component, Element, Event, EventEmitter, h, Host, Method, Prop, State, Watch } from '@stencil/core';
import { enter, leave } from 'el-transition';
+import { TDrawerPlacement } from './bq-drawer.types';
import { hasSlotContent } from '../../shared/utils';
@Component({
@@ -13,8 +14,7 @@ export class BqDrawer {
// ====================
private drawerElem: HTMLDivElement;
- private footerElem: HTMLDivElement;
- private iconElement: HTMLSpanElement;
+ private footerElem: HTMLElement;
// Reference to host HTML element
// ===================================
@@ -34,6 +34,9 @@ export class BqDrawer {
/** If true, the drawer component will be shown */
@Prop({ reflect: true, mutable: true }) open: boolean;
+ /* Defines the position of the drawer */
+ @Prop({ reflect: true, mutable: true }) placement?: TDrawerPlacement = 'left';
+
// Prop lifecycle events
// =======================
@@ -131,10 +134,6 @@ export class BqDrawer {
this.bqAfterClose.emit();
};
- private handleIconSlotChange = () => {
- this.hasIcon = hasSlotContent(this.iconElement, 'icon');
- };
-
// render() function
// Always the last one in the class.
// ===================================
@@ -145,42 +144,45 @@ export class BqDrawer {
class={{ 'is-hidden': !this.open }}
aria-hidden={!this.open ? 'true' : 'false'}
hidden={!this.open ? 'true' : 'false'}
+ role="dialog"
>
-
(this.drawerElem = div)} part="wrapper">
-
- {/* Header */}
-
-
(this.iconElement = span)} part="icon">
-
+ {/* Backdrop */}
+
this.hide()}>
+
(this.drawerElem = div)} part="wrapper">
+
+
);
diff --git a/packages/beeq/src/components/drawer/bq-drawer.types.ts b/packages/beeq/src/components/drawer/bq-drawer.types.ts
new file mode 100644
index 000000000..541d9fc1a
--- /dev/null
+++ b/packages/beeq/src/components/drawer/bq-drawer.types.ts
@@ -0,0 +1,2 @@
+export const DRAWER_PLACEMENT = ['left', 'right'] as const;
+export type TDrawerPlacement = (typeof DRAWER_PLACEMENT)[number];
diff --git a/packages/beeq/src/components/drawer/scss/bq-drawer.scss b/packages/beeq/src/components/drawer/scss/bq-drawer.scss
index 2ad816cf4..d2460831e 100644
--- a/packages/beeq/src/components/drawer/scss/bq-drawer.scss
+++ b/packages/beeq/src/components/drawer/scss/bq-drawer.scss
@@ -13,7 +13,24 @@
}
.bq-drawer {
- @apply relative flex w-auto flex-col gap-[var(--bq-drawer--title-body-gap)] px-[var(--bq-drawer--wrapper-X-padding)] py-[var(--bq-drawer--wrapper-Y-padding)] transition-all;
+ @apply absolute z-20 flex h-screen w-80 flex-col overflow-auto bg-bg-primary px-[var(--bq-drawer--wrapper-X-padding)] py-[var(--bq-drawer--wrapper-Y-padding)] transition-all;
+
+ &.left {
+ @apply left-0 top-0;
+ }
+
+ &.right {
+ @apply right-0 top-0;
+ }
+}
+
+/* Styling for the backdrop */
+.bq-drawer-backdrop {
+ @apply fixed inset-0 z-10 bg-bg-alt opacity-50;
+}
+
+.bq-drawer-backdrop.open {
+ display: block;
}
/**
@@ -23,6 +40,22 @@
@apply h-fit rounded-s border-0 p-0;
}
+.bq-drawer__content {
+ @apply flex flex-1 flex-col gap-[var(--bq-drawer--title-body-gap)];
+}
+
+.bq-drawer__header {
+ @apply flex items-center;
+}
+
+.bq-drawer__title {
+ @apply flex flex-1 items-center justify-between font-bold leading-regular text-text-primary;
+}
+
+.bq-drawer__footer {
+ @apply flex items-start gap-xs pt-[var(--bq-drawer--footer-top-padding)];
+}
+
.bq-drawer__body {
- @apply h-auto p-[var(--bq-drawer--body-padding)];
+ @apply flex-1;
}
diff --git a/packages/beeq/src/components/drawer/scss/bq-drawer.variables.scss b/packages/beeq/src/components/drawer/scss/bq-drawer.variables.scss
index 77c6a1d8f..aeaa75dba 100644
--- a/packages/beeq/src/components/drawer/scss/bq-drawer.variables.scss
+++ b/packages/beeq/src/components/drawer/scss/bq-drawer.variables.scss
@@ -8,7 +8,8 @@
* @prop ---bq-drawer--body-padding - Drawer default padding for body slot
*/
--bq-drawer--title-body-gap: theme('spacing.l');
- --bq-drawer--wrapper-X-padding: theme('spacing.m');
- --bq-drawer--wrapper-Y-padding: theme('spacing.l');
+ --bq-drawer--wrapper-X-padding: theme('spacing.l');
+ --bq-drawer--wrapper-Y-padding: theme('spacing.m');
+ --bq-drawer--footer-top-padding: theme('spacing.m');
--bq-drawer--body-padding: theme('spacing.xs');
}