Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/drawer-width-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@drivenets/design-system': major
---

`DsDrawer`: Replace `columns` prop with `width`
5 changes: 5 additions & 0 deletions .changeset/responsive-value-utility.md
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what are these changesets names? it should be auto-generated by pnpm run changelog, not written manually

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@drivenets/design-system': minor
---

Add responsive prop support at 1440px breakpoint with CSS-first styling and `useResponsiveValue` hook for JS conditional rendering
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. This PR is built on top of something else? Why are all the changes in non-drawer code?
  2. This button should be removed in next. I don't think we should bother with it 🤷

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ $button-size-small: 28px;
$button-size-default: 32px;
$button-size-large: 40px;

@mixin content-size-tiny {
@include typography.body-xs-md;
height: $button-size-tiny;
border-radius: var(--spacing-4xs);
--icon-width-tiny: 13px;
}

@mixin content-size-small {
@include typography.body-xs-md;
height: $button-size-small;
}

@mixin content-size-medium {
height: $button-size-default;
}

@mixin content-size-large {
@include typography.body-md-md;
height: $button-size-large;
}

.button {
@include typography.body-sm-md;
display: flex;
Expand All @@ -31,24 +52,19 @@ $button-size-large: 40px;
}

&.tiny .content {
@include typography.body-xs-md;
height: $button-size-tiny;
border-radius: var(--spacing-4xs);
--icon-width-tiny: 13px;
@include content-size-tiny;
}

&.small .content {
@include typography.body-xs-md;
height: $button-size-small;
@include content-size-small;
}

&.medium .content {
height: $button-size-default;
@include content-size-medium;
}

&.large .content {
@include typography.body-md-md;
height: $button-size-large;
@include content-size-large;
}

&.iconButton {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import classNames from 'classnames';
import type React from 'react';
import { Children, isValidElement } from 'react';

import styles from './ds-button-new.module.scss';
import type { DsButtonProps } from './ds-button-new.types';
import type { DsButtonBaseProps } from './ds-button-new.types';
import { DsIcon } from '../../../ds-icon';

const isIconOnly = (children: React.ReactNode) => {
Expand All @@ -19,7 +20,7 @@ const isIconOnly = (children: React.ReactNode) => {
/**
* Design system Button component
*/
const DsButton: React.FC<DsButtonProps> = ({
const DsButton: React.FC<DsButtonBaseProps> = ({
buttonType,
variant = 'filled',
size = 'medium',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type React from 'react';

import type { ResponsiveValue } from '../../../../utils/responsive';

export const buttonTypes = ['primary', 'secondary', 'secondary-light', 'tertiary'] as const;
export type ButtonType = (typeof buttonTypes)[number];

Expand All @@ -9,7 +11,7 @@ export type ButtonVariant = (typeof buttonVariants)[number];
export const buttonSizes = ['large', 'medium', 'small', 'tiny'] as const;
export type ButtonSize = (typeof buttonSizes)[number];

export interface DsButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
export interface DsButtonBaseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
/**
* Type of the button
* @default 'primary'
Expand Down Expand Up @@ -39,3 +41,11 @@ export interface DsButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElem
*/
contentClassName?: string;
}

export interface DsButtonProps extends Omit<DsButtonBaseProps, 'size'> {
/**
* Size of the button. Accepts a static value or a responsive object.
* @default 'medium'
*/
size?: ResponsiveValue<ButtonSize>;
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export { default as DsButtonNew } from './ds-button-new';
import { withResponsiveProps } from '../../../../utils/responsive';
import DsButtonBase from './ds-button-new';

export const DsButtonNew = withResponsiveProps(DsButtonBase, ['size']);
export * from './ds-button-new.types';
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,7 @@ export const DsCommentsDrawer = ({

return (
<>
<DsDrawer
open={open}
onOpenChange={onOpenChange}
position="start"
columns={4}
className={className}
style={style}
>
<DsDrawer open={open} onOpenChange={onOpenChange} position="start" className={className} style={style}>
<DsDrawer.Header>
<DsDrawer.Title>{commentCount} Comments</DsDrawer.Title>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { useState } from 'react';
import { describe, expect, it, vi } from 'vitest';
import { page } from 'vitest/browser';
import DsDrawer from '../ds-drawer';

const DrawerWrapper = ({ onOpenChange, ...props }: Partial<Parameters<typeof DsDrawer>[0]>) => {
const [open, setOpen] = useState(false);

const handleOpenChange = (value: boolean) => {
setOpen(value);
onOpenChange?.(value);
};

return (
<div style={{ position: 'relative', width: 800, height: 400 }}>
<button type="button" onClick={() => handleOpenChange(true)}>
Open Drawer
</button>

<DsDrawer {...props} open={open} onOpenChange={handleOpenChange}>
{props.children ?? (
<>
<DsDrawer.Header>
<DsDrawer.Title>Test Drawer</DsDrawer.Title>
<DsDrawer.CloseTrigger />
</DsDrawer.Header>
<DsDrawer.Body>Body content</DsDrawer.Body>
</>
)}
</DsDrawer>
</div>
);
};

describe('DsDrawer', () => {
it('opens and closes via trigger', async () => {
await page.render(<DrawerWrapper />);

await page.getByRole('button', { name: /open drawer/i }).click();

const dialog = page.getByRole('dialog');
await expect.element(dialog).toHaveAttribute('data-state', 'open');

await page.getByRole('button', { name: /close/i }).click();
await expect.element(dialog).toHaveAttribute('data-state', 'closed');
});

it('calls onOpenChange when opened and closed', async () => {
const onOpenChange = vi.fn();
await page.render(<DrawerWrapper onOpenChange={onOpenChange} />);

await page.getByRole('button', { name: /open drawer/i }).click();
expect(onOpenChange).toHaveBeenCalledWith(true);

await page.getByRole('button', { name: /close/i }).click();
expect(onOpenChange).toHaveBeenCalledWith(false);
});

it('renders backdrop when backdrop prop is true', async () => {
const { baseElement } = await page.render(<DrawerWrapper backdrop />);

await page.getByRole('button', { name: /open drawer/i }).click();

const dialog = page.getByRole('dialog');
await expect.element(dialog).toHaveAttribute('data-state', 'open');

const backdrop = baseElement.querySelector('[data-part="backdrop"]');
expect(backdrop).toBeTruthy();
expect(backdrop).toHaveAttribute('data-state', 'open');
});

it('has responsive width clamped between 240px and 480px', async () => {
await page.render(<DrawerWrapper />);

await page.getByRole('button', { name: /open drawer/i }).click();

const dialog = page.getByRole('dialog');
await expect.element(dialog).toHaveAttribute('data-state', 'open');

const el = dialog.element() as HTMLElement;
const width = el.getBoundingClientRect().width;
expect(width).toBeGreaterThanOrEqual(240);
expect(width).toBeLessThanOrEqual(480);
});

it('fills remaining height', async () => {
await page.render(<DrawerWrapper />);

await page.getByRole('button', { name: /open drawer/i }).click();

const dialog = page.getByRole('dialog');
await expect.element(dialog).toHaveAttribute('data-state', 'open');

const el = dialog.element() as HTMLElement;
const container = el.closest('[data-scope="dialog"]')?.parentElement;
const containerHeight = container?.getBoundingClientRect().height ?? 0;
const drawerHeight = el.getBoundingClientRect().height;
expect(drawerHeight).toBe(containerHeight);
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
@use '../../styles/grid-variables' as grid-vars;

.backdrop {
position: absolute;
inset: 0;
Expand Down Expand Up @@ -47,14 +45,13 @@
display: block;
top: 0;
bottom: 0;
width: clamp(240px, 20vw, 480px);
background: var(--color-background);
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.22);
z-index: 1200;
pointer-events: auto;
overflow: hidden;
transition:
transform 0.2s ease,
width 0.2s ease;
transition: transform 0.2s ease;

&.position-end {
right: 0;
Expand Down Expand Up @@ -83,12 +80,6 @@
animation: 0.25s slide-out-drawer-start both;
}
}

@for $i from 1 through grid-vars.$columns {
&.cols-#{$i} {
width: var(--col-span-#{$i});
}
}
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you removing this? It should be the same as per what I'm seeing in Figma

Am I missing something?


@keyframes slide-in-drawer-end {
Expand Down
Loading
Loading