Skip to content

Commit

Permalink
feat(sidepanel): implement decorator prop
Browse files Browse the repository at this point in the history
  • Loading branch information
makafsal committed Nov 27, 2024
1 parent cdee198 commit b026812
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ $action-set-block-class: #{c4p-settings.$pkg-prefix}--action-set;
border-right: 1px solid $border-subtle-02;
}
&.#{$block-class}.#{$block-class}--has-slug,
&.#{$block-class}.#{$block-class}--has-ai-label {
&.#{$block-class}.#{$block-class}--has-ai-label,
&.#{$block-class}.#{$block-class}--has-decorator {
border-color: transparent;
box-shadow: inset 0 -80px 70px -65px $ai-inner-shadow,
0 4px 10px 2px $ai-drop-shadow;
Expand Down Expand Up @@ -197,14 +198,16 @@ $action-set-block-class: #{c4p-settings.$pkg-prefix}--action-set;
&.#{$block-class}:has(.#{$block-class}__action-toolbar),
&.#{$block-class}--has-action-toolbar,
&.#{$block-class}--has-slug,
&.#{$block-class}--has-ai-label {
&.#{$block-class}--has-ai-label,
&.#{$block-class}--has-decorator {
--#{$block-class}--title-padding-right: #{$spacing-10};
}

&.#{$block-class}:has(.#{$block-class}__action-toolbar),
&.#{$block-class}--has-action-toolbar {
&.#{$block-class}--has-slug,
&.#{$block-class}--has-ai-label {
&.#{$block-class}--has-ai-label,
&.#{$block-class}--has-decorator {
--#{$block-class}--title-padding-right: #{$spacing-11};
}
}
Expand Down Expand Up @@ -312,7 +315,8 @@ $action-set-block-class: #{c4p-settings.$pkg-prefix}--action-set;
}

&.#{$block-class}--has-slug .#{$block-class}--scrolls,
&.#{$block-class}--has-ai-label .#{$block-class}--scrolls {
&.#{$block-class}--has-ai-label .#{$block-class}--scrolls,
&.#{$block-class}--has-decorator .#{$block-class}--scrolls {
@include utilities.ai-popover-gradient('default', 0, 'layer');

box-shadow: inset 0 -80px 70px -65px $ai-inner-shadow,
Expand Down Expand Up @@ -367,7 +371,8 @@ $action-set-block-class: #{c4p-settings.$pkg-prefix}--action-set;
}

.#{$block-class}__slug-and-close,
.#{$block-class}__ai-label-and-close {
.#{$block-class}__ai-label-and-close,
.#{$block-class}__decorator-and-close {
position: absolute;
z-index: 10; /* must be higher than title container border bottom */
top: 0;
Expand Down Expand Up @@ -470,7 +475,8 @@ $action-set-block-class: #{c4p-settings.$pkg-prefix}--action-set;
}

.#{$block-class}--has-slug + .#{$block-class}__overlay,
.#{$block-class}--has-ai-label + .#{$block-class}__overlay {
.#{$block-class}--has-ai-label + .#{$block-class}__overlay,
.#{$block-class}--has-decorator + .#{$block-class}__overlay {
/* stylelint-disable-next-line carbon/theme-token-use */
background-color: $ai-overlay;
}
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ const SlideOverTemplate = ({
actions,
aiLabel,
slug,
decorator,
...args
}) => {
const [open, setOpen] = useState(false);
Expand All @@ -481,6 +482,7 @@ const SlideOverTemplate = ({
ref={testRef}
aiLabel={aiLabel && sampleAILabel}
slug={slug && sampleAILabel}
decorator={decorator && sampleAILabel}
launcherButtonRef={buttonRef}
>
{!minimalContent && <ChildrenContent />}
Expand Down
10 changes: 5 additions & 5 deletions packages/ibm-products/src/components/SidePanel/SidePanel.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,11 +363,11 @@ describe('SidePanel', () => {
);
expect(navigationAction).toBeTruthy();
});
it('should not have AI Label when it is not passed', () => {
it('should not have a decorator container when a decorator not passed', () => {
const { container } = renderSidePanel();
expect(container.querySelector('.aiLabel-container')).toBe(null);
expect(container.querySelector('.decorator-container')).toBe(null);
});
it('should have AI Label when it is passed', () => {
it('should have AI Label when it is passed to decorator', () => {
const sampleAILabel = (
<AILabel className="aiLabel-container" size="xs" align="left-start">
<AILabelContent>
Expand All @@ -388,9 +388,9 @@ describe('SidePanel', () => {
</AILabel>
);
const { container } = renderSidePanel({
aiLabel: sampleAILabel,
decorator: sampleAILabel,
});
expect(container.querySelector('.aiLabel-container')).toBeTruthy();
expect(container.querySelector('.decorator-container')).toBeTruthy();
});
it('should throw console warning if labelText passed without Title', () => {
const consoleWarnSpy = jest
Expand Down
38 changes: 28 additions & 10 deletions packages/ibm-products/src/components/SidePanel/SidePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,16 +170,22 @@ type SidePanelBaseProps = {
slideIn?: boolean;

/**
* @deprecated please use the `aiLabel` prop
* @deprecated please use the `decorator` instead
* **Experimental:** Provide a `Slug` component to be rendered inside the `SidePanel` component
*/
slug?: ReactNode;

/**
* @deprecated please use the `decorator` instead
* Optional prop that is intended for any scenario where something is being generated by AI to reinforce AI transparency, accountability, and explainability at the UI level.
*/
aiLabel?: ReactNode;

/**
* Provide a `decorator` component to be rendered inside the `SidePanel` component
*/
decorator?: ReactNode;

/**
* Sets the subtitle text
*/
Expand Down Expand Up @@ -247,6 +253,7 @@ export let SidePanel = React.forwardRef(
closeIconDescription = defaults.closeIconDescription,
condensedActions,
currentStep = defaults.currentStep,
decorator,
id = blockClass,
includeOverlay,
labelText,
Expand Down Expand Up @@ -671,6 +678,7 @@ export let SidePanel = React.forwardRef(
[`${blockClass}--left-placement`]: placement === 'left',
[`${blockClass}--slide-in`]: slideIn,
[`${blockClass}--has-ai-label`]: !!aiLabel || !!slug,
[`${blockClass}--has-decorator`]: decorator,
[`${blockClass}--condensed-actions`]: condensedActions,
[`${blockClass}--has-overlay`]: includeOverlay,
},
Expand Down Expand Up @@ -704,29 +712,39 @@ export let SidePanel = React.forwardRef(
);

const renderHeader = () => {
const aiLabelCloseSize =
const closeSize =
actions && actions.length && /l/.test(size) ? 'md' : 'sm';
let normalizedAILabel;
let normalizedDecorator;
/**
* slug is deprecated
* can remove this condition in future release
*/
if (slug && slug['type']?.displayName === 'Slug') {
normalizedAILabel = React.cloneElement(
normalizedDecorator = React.cloneElement(
slug as React.ReactElement<any>,
{
// slug size is sm unless actions and size > md
size: aiLabelCloseSize,
size: closeSize,
}
);
}

if (aiLabel && aiLabel['type']?.displayName === 'AILabel') {
normalizedAILabel = React.cloneElement(
normalizedDecorator = React.cloneElement(
aiLabel as React.ReactElement<any>,
{
// aiLabel size is sm unless actions and size > md
size: aiLabelCloseSize,
size: closeSize,
}
);
}

if (decorator && decorator['type']?.displayName === 'AILabel') {
normalizedDecorator = React.cloneElement(
decorator as React.ReactElement<any>,
{
// decorator size is sm unless actions and size > md
size: closeSize,
}
);
}
Expand All @@ -745,7 +763,7 @@ export let SidePanel = React.forwardRef(
{currentStep > 0 && (
<Button
kind="ghost"
size={aiLabelCloseSize}
size={closeSize}
disabled={false}
renderIcon={(props) => <ArrowLeft size={20} {...props} />}
iconDescription={navigationBackIconDescription}
Expand All @@ -761,9 +779,9 @@ export let SidePanel = React.forwardRef(
)}
{/* title */}
{title && title.length && renderTitle()}
{/* aiLabel and close */}
{/* decorator and close */}
<div className={`${blockClass}__ai-label-and-close`}>
{normalizedAILabel}
{normalizedDecorator}
<IconButton
className={`${blockClass}__close-button`}
label={closeIconDescription}
Expand Down

0 comments on commit b026812

Please sign in to comment.