feat: Add `framed` optional property for IconElement `ui-kit` component (#37726)

Co-authored-by: Douglas Gubert <1810309+d-gubert@users.noreply.github.com>
pull/37715/merge
gabriellsh 3 days ago committed by GitHub
parent 855fae239d
commit d3538e7045
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      .changeset/many-walls-cheat.md
  2. 40
      packages/fuselage-ui-kit/src/elements/IconElement.tsx
  3. 1
      packages/fuselage-ui-kit/src/stories/Message.stories.tsx
  4. 29
      packages/fuselage-ui-kit/src/stories/payloads/infoCard.ts
  5. 4
      packages/ui-kit/src/blocks/BlockElement.ts
  6. 8
      packages/ui-kit/src/blocks/elements/IconElement.ts
  7. 4
      packages/ui-kit/src/blocks/layout/InfoCardBlock.ts
  8. 2
      packages/ui-kit/src/index.ts

@ -0,0 +1,6 @@
---
"@rocket.chat/fuselage-ui-kit": minor
"@rocket.chat/ui-kit": minor
---
Introduces a new variation of the `Icon` element to `ui-kit` through the new `framed` optional property.

@ -1,24 +1,46 @@
import { Icon } from '@rocket.chat/fuselage';
import { Icon, FramedIcon } from '@rocket.chat/fuselage';
import type * as UiKit from '@rocket.chat/ui-kit';
import type { ReactElement } from 'react';
import type { ComponentProps, ReactElement } from 'react';
import type { BlockProps } from '../utils/BlockProps';
type IconElementProps = BlockProps<UiKit.IconElement>;
type IconElementProps = BlockProps<UiKit.FrameableIconElement>;
const getVariantColor = (variant: UiKit.IconElement['variant']): string => {
const getVariantColor = (variant: UiKit.FrameableIconElement['variant']): string => {
switch (variant) {
case 'default':
return 'default';
case 'danger':
return 'danger';
case 'secondary':
return 'secondary-info';
case 'warning':
return 'status-font-on-warning';
case 'default':
default:
return 'default';
}
};
const IconElement = ({ block }: IconElementProps): ReactElement => (
<Icon size={20} name={block.icon} color={getVariantColor(block.variant)} />
);
const getFramedIconProps = (
variant: UiKit.FrameableIconElement['variant'],
): Pick<ComponentProps<typeof FramedIcon>, 'warning' | 'danger' | 'neutral'> => {
switch (variant) {
case 'danger':
return { danger: true };
case 'warning':
return { warning: true };
case 'default':
case 'secondary':
default:
return { neutral: true };
}
};
const IconElement = ({ block }: IconElementProps): ReactElement => {
const { icon, variant, framed } = block;
if (framed) {
return <FramedIcon size={20} icon={icon} {...getFramedIconProps(variant)} />;
}
return <Icon size={20} name={icon} color={getVariantColor(variant)} />;
};
export default IconElement;

@ -117,3 +117,4 @@ export const PreviewWithExternalUrl = createStory(payloads.previewWithExternalUr
export const InfoCard = createStory(payloads.infoCard);
export const InfoCardMultiple = createStory(payloads.infoCardMultiple);
export const InfoCardMultipleIcons = createStory(payloads.infoCardMultipleIcons);

@ -32,7 +32,7 @@ export const infoCardMultiple: readonly UiKit.InfoCardBlock[] = [
{
background: 'default',
elements: [
{ type: 'icon', icon: 'phone-off', variant: 'default' },
{ type: 'icon', icon: 'phone-off', variant: 'warning' },
{ type: 'plain_text', text: 'Call ended' },
],
action: getIconButtonPayload({ icon: 'info' }),
@ -44,3 +44,30 @@ export const infoCardMultiple: readonly UiKit.InfoCardBlock[] = [
],
},
];
export const infoCardMultipleIcons: readonly UiKit.InfoCardBlock[] = [
{
type: 'info_card',
rows: [
{
background: 'default',
elements: [
{ type: 'plain_text', text: 'Framed icons' },
{ type: 'icon', icon: 'phone-off', variant: 'default', framed: true },
{ type: 'icon', icon: 'clock', variant: 'warning', framed: true },
{ type: 'icon', icon: 'phone-issue', variant: 'danger', framed: true },
],
},
{
background: 'default',
elements: [
{ type: 'plain_text', text: 'Icons' },
{ type: 'icon', icon: 'phone-off', variant: 'default' },
{ type: 'icon', icon: 'clock', variant: 'warning' },
{ type: 'icon', icon: 'phone-issue', variant: 'danger' },
{ type: 'icon', icon: 'info', variant: 'secondary' },
],
},
],
},
];

@ -5,7 +5,7 @@ import type { ConversationsSelectElement } from './elements/ConversationsSelectE
import type { DatePickerElement } from './elements/DatePickerElement';
import type { ExperimentalTabElement } from './elements/ExperimentalTabElement';
import type { IconButtonElement } from './elements/IconButtonElement';
import type { IconElement } from './elements/IconElement';
import type { FrameableIconElement } from './elements/IconElement';
import type { ImageElement } from './elements/ImageElement';
import type { LinearScaleElement } from './elements/LinearScaleElement';
import type { MultiChannelsSelectElement } from './elements/MultiChannelsSelectElement';
@ -40,5 +40,5 @@ export type BlockElement =
| CheckboxElement
| TimePickerElement
| ExperimentalTabElement
| IconElement
| FrameableIconElement
| IconButtonElement;

@ -1,7 +1,11 @@
type AvailableIcons = 'phone-off' | 'phone-issue' | 'clock' | 'arrow-forward' | 'info';
type AvailableIcons = 'phone-off' | 'phone-issue' | 'clock' | 'arrow-forward' | 'info' /* | 'phone-question-mark' */; // TODO add new icon when available in fuselage
export type IconElement = {
type: 'icon';
icon: AvailableIcons;
variant: 'default' | 'danger' | 'secondary';
variant: 'default' | 'danger' | 'secondary' | 'warning';
};
export type FrameableIconElement = IconElement & {
framed?: boolean;
};

@ -1,13 +1,13 @@
import type { LayoutBlockType } from '../LayoutBlockType';
import type { LayoutBlockish } from '../LayoutBlockish';
import type { IconButtonElement } from '../elements/IconButtonElement';
import type { IconElement } from '../elements/IconElement';
import type { FrameableIconElement } from '../elements/IconElement';
import type { Markdown } from '../text/Markdown';
import type { PlainText } from '../text/PlainText';
type InfoCardRow = {
background: 'default' | 'secondary';
elements: readonly (IconElement | PlainText | Markdown)[];
elements: readonly (FrameableIconElement | PlainText | Markdown)[];
action?: IconButtonElement;
};

@ -28,7 +28,7 @@ export { RadioButtonElement } from './blocks/elements/RadioButtonElement';
export { TimePickerElement } from './blocks/elements/TimePickerElement';
export { BlockElement } from './blocks/BlockElement';
export { ExperimentalTabElement } from './blocks/elements/ExperimentalTabElement';
export { IconElement } from './blocks/elements/IconElement';
export { IconElement, FrameableIconElement } from './blocks/elements/IconElement';
export { IconButtonElement } from './blocks/elements/IconButtonElement';
export { ActionsBlock } from './blocks/layout/ActionsBlock';

Loading…
Cancel
Save