Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fuselage): Introduce Callout actions #1415

Merged
merged 7 commits into from
Aug 1, 2024
Merged
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/sharp-paws-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/fuselage": minor
---

feat(fuselage): Introduce Callout actions
6 changes: 6 additions & 0 deletions packages/fuselage/.jest/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,9 @@ expect.extend({
});

expect.extend(toHaveNoViolations);

window.ResizeObserver = jest.fn().mockImplementation(() => ({
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn(),
}));
16 changes: 15 additions & 1 deletion packages/fuselage/src/components/Callout/Callout.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import type { ComponentStory, ComponentMeta } from '@storybook/react';
import React from 'react';

import { Callout } from '../..';
import { Button, ButtonGroup, Callout } from '../..';
import { setStoryDescription } from '../../helpers/setStoryDescription';

export default {
Expand Down Expand Up @@ -87,3 +87,17 @@ CustomIcon.args = {
title: 'This is a message with custom icon',
icon: 'hash',
};

export const WithActions: ComponentStory<typeof Callout> = (args) => (
<Callout {...args} />
);
WithActions.args = {
title: 'This is a generic title',
children: 'This is a generic description.',
actions: (
<ButtonGroup>
<Button small>Button</Button>
<Button small>Button</Button>
</ButtonGroup>
),
};
29 changes: 25 additions & 4 deletions packages/fuselage/src/components/Callout/Callout.styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,36 @@ $callout-text-color: theme('callout-text-color', colors.font(default));
}

&__wrapper {
display: flex;

overflow: hidden;
dougfabris marked this conversation as resolved.
Show resolved Hide resolved
flex-flow: column nowrap;

justify-content: space-between;

flex: 1 1 0;

margin-inline-start: lengths.margin(12);

@include typography.use-font-scale(c1);
> :nth-child(2) {
margin-block-start: lengths.margin(12);
}

&--large {
display: flex;

overflow: hidden;
flex-direction: row;
align-items: center;

> :nth-child(2) {
margin-block-start: lengths.margin(0);
}
}
}

&__wrapper-content {
display: flex;

overflow: hidden;
flex-flow: column nowrap;

> :nth-child(2) {
margin-block-start: lengths.margin(4);
Expand Down
21 changes: 17 additions & 4 deletions packages/fuselage/src/components/Callout/Callout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ComponentProps, ReactNode } from 'react';
import { useResizeObserver } from '@rocket.chat/fuselage-hooks';
import type { ComponentProps, ReactElement, ReactNode } from 'react';
import React from 'react';

import Box from '../Box';
Expand All @@ -9,16 +10,24 @@ type CalloutProps = Omit<ComponentProps<typeof Box>, 'type' | 'name'> & {
title?: ReactNode;
children?: ReactNode;
icon?: ComponentProps<typeof Icon>['name'];
actions?: ReactElement;
};

const WRAPPER_LIMIT_SIZE = 420;

export const Callout = ({
type,
title,
children,
icon,
className,
actions,
...props
}: CalloutProps) => {
const { ref, borderBoxSize } = useResizeObserver();
const isLarge =
borderBoxSize.inlineSize && borderBoxSize.inlineSize >= WRAPPER_LIMIT_SIZE;

const defaultIcon =
(type === 'info' && 'info-circled') ||
(type === 'success' && 'checkmark-circled') ||
Expand All @@ -28,6 +37,7 @@ export const Callout = ({

return (
<Box
ref={ref}
is='section'
className={['rcx-callout', type && `rcx-callout--${type}`, className]
.filter(Boolean)
Expand All @@ -39,9 +49,12 @@ export const Callout = ({
name={icon || defaultIcon}
size='x20'
/>
<Box rcx-callout__wrapper>
{title && <Box rcx-callout__title>{title}</Box>}
{children && <Box rcx-callout__content>{children}</Box>}
<Box rcx-callout__wrapper rcx-callout__wrapper--large={isLarge}>
<Box rcx-callout__wrapper-content>
{title && <Box rcx-callout__title>{title}</Box>}
{children && <Box rcx-callout__content>{children}</Box>}
</Box>
{actions && <Box rcx-callout__actions>{actions}</Box>}
</Box>
</Box>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ exports[`[CheckBox Rendering] renders CustomIcon without crashing 1`] = `
class="rcx-box rcx-box--full rcx-callout__wrapper"
>
<div
class="rcx-box rcx-box--full rcx-callout__title"
class="rcx-box rcx-box--full rcx-callout__wrapper-content"
>
This is a message with custom icon
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
>
This is a generic description.
<div
class="rcx-box rcx-box--full rcx-callout__title"
>
This is a message with custom icon
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
>
This is a generic description.
</div>
</div>
</div>
</section>
Expand All @@ -47,14 +51,18 @@ exports[`[CheckBox Rendering] renders Danger without crashing 1`] = `
class="rcx-box rcx-box--full rcx-callout__wrapper"
>
<div
class="rcx-box rcx-box--full rcx-callout__title"
>
This is a danger message
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
class="rcx-box rcx-box--full rcx-callout__wrapper-content"
>
This is a generic description.
<div
class="rcx-box rcx-box--full rcx-callout__title"
>
This is a danger message
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
>
This is a generic description.
</div>
</div>
</div>
</section>
Expand All @@ -78,14 +86,18 @@ exports[`[CheckBox Rendering] renders Default without crashing 1`] = `
class="rcx-box rcx-box--full rcx-callout__wrapper"
>
<div
class="rcx-box rcx-box--full rcx-callout__title"
class="rcx-box rcx-box--full rcx-callout__wrapper-content"
>
This is a generic title
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
>
This is a generic description.
<div
class="rcx-box rcx-box--full rcx-callout__title"
>
This is a generic title
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
>
This is a generic description.
</div>
</div>
</div>
</section>
Expand All @@ -109,14 +121,18 @@ exports[`[CheckBox Rendering] renders Info without crashing 1`] = `
class="rcx-box rcx-box--full rcx-callout__wrapper"
>
<div
class="rcx-box rcx-box--full rcx-callout__title"
class="rcx-box rcx-box--full rcx-callout__wrapper-content"
>
This is a info message
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
>
This is a generic description.
<div
class="rcx-box rcx-box--full rcx-callout__title"
>
This is a info message
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
>
This is a generic description.
</div>
</div>
</div>
</section>
Expand All @@ -140,14 +156,18 @@ exports[`[CheckBox Rendering] renders Success without crashing 1`] = `
class="rcx-box rcx-box--full rcx-callout__wrapper"
>
<div
class="rcx-box rcx-box--full rcx-callout__title"
>
This is a success message
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
class="rcx-box rcx-box--full rcx-callout__wrapper-content"
>
This is a generic description.
<div
class="rcx-box rcx-box--full rcx-callout__title"
>
This is a success message
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
>
This is a generic description.
</div>
</div>
</div>
</section>
Expand All @@ -171,14 +191,82 @@ exports[`[CheckBox Rendering] renders Warning without crashing 1`] = `
class="rcx-box rcx-box--full rcx-callout__wrapper"
>
<div
class="rcx-box rcx-box--full rcx-callout__title"
class="rcx-box rcx-box--full rcx-callout__wrapper-content"
>
<div
class="rcx-box rcx-box--full rcx-callout__title"
>
This is a warning message
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
>
This is a generic description.
</div>
</div>
</div>
</section>
</div>
</body>
`;

exports[`[CheckBox Rendering] renders WithActions without crashing 1`] = `
<body>
<div>
<section
class="rcx-box rcx-box--full rcx-callout"
>
<i
aria-hidden="true"
class="rcx-box rcx-box--full rcx-icon--name-info-circled rcx-icon rcx-callout__icon rcx-css-4pvxx3"
>
</i>
<div
class="rcx-box rcx-box--full rcx-callout__wrapper"
>
<div
class="rcx-box rcx-box--full rcx-callout__wrapper-content"
>
This is a warning message
<div
class="rcx-box rcx-box--full rcx-callout__title"
>
This is a generic title
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
>
This is a generic description.
</div>
</div>
<div
class="rcx-box rcx-box--full rcx-callout__content"
class="rcx-box rcx-box--full rcx-callout__actions"
>
This is a generic description.
<div
class="rcx-button-group rcx-button-group--align-start"
role="group"
>
<button
class="rcx-box rcx-box--full rcx-button--small rcx-button rcx-button-group__item"
type="button"
>
<span
class="rcx-button--content"
>
Button
</span>
</button>
<button
class="rcx-box rcx-box--full rcx-button--small rcx-button rcx-button-group__item"
type="button"
>
<span
class="rcx-button--content"
>
Button
</span>
</button>
</div>
</div>
</div>
</section>
Expand All @@ -202,9 +290,13 @@ exports[`[CheckBox Rendering] renders WithDescriptionOnly without crashing 1`] =
class="rcx-box rcx-box--full rcx-callout__wrapper"
>
<div
class="rcx-box rcx-box--full rcx-callout__content"
class="rcx-box rcx-box--full rcx-callout__wrapper-content"
>
This is a generic description.
<div
class="rcx-box rcx-box--full rcx-callout__content"
>
This is a generic description.
</div>
</div>
</div>
</section>
Expand Down
Loading