Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions src/__screenshot_tests__/inline-screenshot-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,15 @@ test.skip('Inline negative space', async () => {
const image = await page.screenshot();
expect(image).toMatchImageSnapshot();
});

test('Inline with growItems', async () => {
await openStoryPage({
id: 'layout-inline--grow-items',
device: 'DESKTOP',
});

const story = await screen.findByTestId('story');
const image = await story.screenshot();

expect(image).toMatchImageSnapshot();
});
15 changes: 15 additions & 0 deletions src/__screenshot_tests__/navigation-bar-screenshot-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,18 @@ test.each(['large' /* 'small' */])('MainNavigationBar inverse with %s menu in DE
await page.click(startButton);
expect(await page.screenshot()).toMatchImageSnapshot({failureThreshold: 0.00002});
});

test('MainNavigationBar large with expanded right slot', async () => {
const page = await openStoryPage({
id: 'components-navigation-bars-mainnavigationbar--default',
device: 'DESKTOP',
args: {
large: true,
expandedRightSlot: true,
},
});

const image = await page.screenshot();

expect(image).toMatchImageSnapshot();
});
19 changes: 19 additions & 0 deletions src/__stories__/inline-story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ const Row = ({
children,
padding = 0,
align,
fullWidth,
}: {
children?: React.ReactNode;
padding?: number;
align?: string;
fullWidth?: boolean;
}) => {
return children ? (
<div
Expand All @@ -26,6 +28,7 @@ const Row = ({
height: align === 'stretch' ? '100%' : 'auto',
display: 'flex',
alignItems: 'center',
width: fullWidth ? '100%' : undefined,
}}
>
<Text2 regular>{children}</Text2>
Expand Down Expand Up @@ -157,3 +160,19 @@ export const NegativeSpace: StoryComponent = () => {
};

NegativeSpace.storyName = 'Inline with negative space';

export const GrowItems: StoryComponent = () => {
return (
<div data-testid="story" style={{width: 600}}>
<Inline fullWidth space={16} alignItems="center" growItems={0}>
<Row padding={16} fullWidth>
Grow item
</Row>
<Row padding={16}>Fixed item</Row>
<Row padding={16}>Fixed item</Row>
</Inline>
</div>
);
};

GrowItems.storyName = 'Inline with growItems';
45 changes: 32 additions & 13 deletions src/__stories__/main-navigation-bar-story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import {
Avatar,
Badge,
IconShoppingCartRegular,
Inline,
MainNavigationBar,
NavigationBarAction,
NavigationBarActionGroup,
Placeholder,
SearchField,
Stack,
Text3,
useScreenSize,
Expand Down Expand Up @@ -45,6 +47,7 @@ type Args = {
topSlotBackgroundColor: string;
wide: boolean;
paddingX: PadSize | 'undefined';
expandedRightSlot: boolean;
};

export const Default: StoryComponent<Args> = ({
Expand All @@ -60,10 +63,34 @@ export const Default: StoryComponent<Args> = ({
topSlotBackgroundColor,
wide,
paddingX,
expandedRightSlot,
}) => {
const [selectedIndex, setSelectedIndex] = React.useState(0);
const {isDesktopOrBigger} = useScreenSize();

const right = expandedRightSlot ? (
<Inline fullWidth space={16} alignItems="center" growItems={0}>
<SearchField fullWidth name="search" label="Search" />

<NavigationBarAction onPress={() => {}} aria-label="Entrar">
<Avatar src={avatarImg} size={isDesktopOrBigger ? 32 : 24} initials="ML" />
{isDesktopOrBigger && 'Entrar'}
</NavigationBarAction>
</Inline>
) : (
<NavigationBarActionGroup>
<NavigationBarAction onPress={() => {}} aria-label="shopping cart with 2 items">
<Badge value={2}>
<IconShoppingCartRegular color="currentColor" />
</Badge>
</NavigationBarAction>
<NavigationBarAction onPress={() => {}} aria-label="Open profile">
<Avatar src={avatarImg} size={isDesktopOrBigger ? 32 : 24} initials="ML" />
{isDesktopOrBigger && 'María López Serrano'}
</NavigationBarAction>
</NavigationBarActionGroup>
);

return (
<MainNavigationBar
variant={variant}
Expand Down Expand Up @@ -116,19 +143,7 @@ export const Default: StoryComponent<Args> = ({
: undefined
}
selectedIndex={selectedIndex}
right={
<NavigationBarActionGroup>
<NavigationBarAction onPress={() => {}} aria-label="shopping cart with 2 items">
<Badge value={2}>
<IconShoppingCartRegular color="currentColor" />
</Badge>
</NavigationBarAction>
<NavigationBarAction onPress={() => {}} aria-label="Open profile">
<Avatar src={avatarImg} size={isDesktopOrBigger ? 32 : 24} initials="ML" />
{isDesktopOrBigger && 'María López Serrano'}
</NavigationBarAction>
</NavigationBarActionGroup>
}
right={right}
wide={wide ? (paddingX === 'undefined' ? true : {paddingX}) : false}
/>
);
Expand All @@ -149,6 +164,7 @@ Default.args = {
topSlotBackgroundColor: '',
wide: false,
paddingX: 'undefined',
expandedRightSlot: false,
};

Default.argTypes = {
Expand All @@ -171,4 +187,7 @@ Default.argTypes = {
control: {type: 'select'},
if: {arg: 'wide'},
},
expandedRightSlot: {
control: {type: 'boolean'},
},
};
9 changes: 9 additions & 0 deletions src/inline.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ export const stringSpaceWithWrap = style({
justifyContent: space,
});

export const flexLayout = style({
display: 'flex',
});

export const growItem = style({
flex: 1,
minWidth: 0,
});

globalStyle(`${marginInline} > div`, {
marginLeft: space,
marginTop: fallbackVar(verticalSpace, space),
Expand Down
44 changes: 39 additions & 5 deletions src/inline.tsx
Copy link
Copy Markdown
Contributor

@yceballost yceballost May 6, 2026

Choose a reason for hiding this comment

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

I dont feel really easy in terms of devExp to have another component called InlineItem to manage this kind of things

Is not there any other solution? maybe manage this property in the <Inline> component?

wdyt @atabel ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point, thanks! I’ve removed the public InlineItem component and moved the behavior into Inline via a growItems prop

Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,27 @@ type Props = {
fullWidth?: boolean;
dataAttributes?: DataAttributes;
wrap?: boolean;
/**
* Index or indexes of the children that should grow to fill the available space.
* Only applies when `fullWidth` is true.
*/
growItems?: number | ReadonlyArray<number>;
};

const getChildKey = (child: React.ReactNode, index: number): React.Key => {
if (!React.isValidElement(child)) {
return index;
}

return child.key !== null && child.key !== undefined ? child.key : index;
};

const shouldGrowItem = (growItems: Props['growItems'], index: number): boolean => {
if (growItems === undefined) {
return false;
}

return Array.isArray(growItems) ? growItems.includes(index) : growItems === index;
};

const Inline = ({
Expand All @@ -93,28 +114,41 @@ const Inline = ({
fullWidth,
wrap,
dataAttributes,
growItems,
}: Props): JSX.Element => {
const {platformOverrides} = useTheme();
const isStringSpace = typeof space === 'string';
const childrenArray = React.Children.toArray(children).filter((child) => !!child || child === 0);

const hasGrowItem = fullWidth && childrenArray.some((_, index) => shouldGrowItem(growItems, index));

return (
<div
className={classnames(
className,
styles.inline,
wrap ? styles.wrap : fullWidth ? styles.fullWidth : styles.noFullWidth,
isStringSpace ? (wrap ? styles.stringSpaceWithWrap : styles.stringSpace) : styles.marginInline
isStringSpace
? wrap
? styles.stringSpaceWithWrap
: styles.stringSpace
: styles.marginInline,
hasGrowItem && styles.flexLayout
)}
style={{...applyCssVars(calcInlineVars(space, verticalSpace)), alignItems}}
role={role}
aria-label={ariaLabel}
aria-labelledby={ariaLabel ? undefined : ariaLabelledBy}
{...getPrefixedDataAttributes(dataAttributes, 'Inline')}
>
{React.Children.map(children, (child) =>
!!child || child === 0 ? (
{childrenArray.map((child, index) => {
return (
<div
key={getChildKey(child, index)}
role={role === 'list' ? 'listitem' : undefined}
className={classnames(
hasGrowItem && shouldGrowItem(growItems, index) && styles.growItem
)}
style={{
// Hack to fix https://jira.tid.es/browse/WEB-1683
// In iOS the inline component sometimes cuts the last line of the content
Expand All @@ -126,8 +160,8 @@ const Inline = ({
>
{child}
</div>
) : null
)}
);
})}
</div>
);
};
Expand Down
7 changes: 7 additions & 0 deletions src/navigation-bar.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,16 @@ export const navigationBarContentRightExpanded = style([
}),
{
paddingLeft: 136,
minWidth: 0,
width: 0,
},
]);

export const navigationBarContentRightExpandedContent = style({
width: '100%',
minWidth: 0,
});

const spacerMobile = style({
'@media': {
[mq.tabletOrSmaller]: {
Expand Down
8 changes: 7 additions & 1 deletion src/navigation-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ type NavigationBarContentContainerProps = {

const NavigationBarContentContainer = React.forwardRef<HTMLDivElement, NavigationBarContentContainerProps>(
({right, children, desktopOnly, expandRightContent}, ref) => {
const shouldWrapRightContent =
expandRightContent && React.isValidElement<{fullWidth?: boolean}>(right) && right.props.fullWidth;
return (
<div
ref={ref}
Expand All @@ -129,7 +131,11 @@ const NavigationBarContentContainer = React.forwardRef<HTMLDivElement, Navigatio
: styles.navigationBarContentRight
}
>
{right}
{shouldWrapRightContent ? (
<div className={styles.navigationBarContentRightExpandedContent}>{right}</div>
) : (
right
)}
</div>
)}
</div>
Expand Down
Loading