Skip to content

Commit 75a0dc2

Browse files
committed
feat(Layout): tiny scrollbar for sub-components
1 parent 823cae5 commit 75a0dc2

File tree

7 files changed

+95
-143
lines changed

7 files changed

+95
-143
lines changed

src/components/actions/Button/Button.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ export const DEFAULT_BUTTON_STYLES = {
131131
'': 'min $size',
132132
'left-icon & right-icon': 'min ($size * 2 - 2bw)',
133133
'single-icon': 'fixed $size',
134-
'type=link': 'initial',
135134
},
136135
height: {
137136
'': 'fixed $size',

src/components/content/Layout/Layout.stories.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -485,22 +485,14 @@ export const CompleteApplicationShell: Story = {
485485
}
486486
/>
487487

488-
<Layout.Content padding="2x" scrollbar="tiny">
488+
<Layout.Content gap="1x">
489489
{Array.from({ length: 10 }, (_, i) => (
490-
<div
491-
key={i}
492-
style={{
493-
padding: '16px',
494-
marginBottom: '16px',
495-
background: '#f5f5f5',
496-
borderRadius: '8px',
497-
}}
498-
>
490+
<Card key={i}>
499491
<Title level={5}>Card {i + 1}</Title>
500492
<Text>
501493
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
502494
</Text>
503-
</div>
495+
</Card>
504496
))}
505497
</Layout.Content>
506498

src/components/content/Layout/LayoutBlock.tsx

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,31 @@
1-
import { ForwardedRef, forwardRef, ReactNode } from 'react';
1+
import { ForwardedRef, forwardRef } from 'react';
22

3-
import {
4-
BaseProps,
5-
CONTAINER_STYLES,
6-
ContainerStyleProps,
7-
extractStyles,
8-
filterBaseProps,
9-
tasty,
10-
} from '../../../tasty';
3+
import { tasty } from '../../../tasty';
114

12-
import { LayoutContextReset } from './LayoutContext';
5+
import { CubeLayoutContentProps, LayoutContent } from './LayoutContent';
136

14-
const BlockElement = tasty({
15-
as: 'div',
7+
const BlockElement = tasty(LayoutContent, {
168
qa: 'LayoutBlock',
179
styles: {
18-
display: 'block',
19-
padding: '($content-padding, 1x)',
2010
flexShrink: 0,
11+
12+
Inner: {
13+
display: 'block',
14+
},
2115
},
2216
});
2317

24-
export interface CubeLayoutBlockProps extends BaseProps, ContainerStyleProps {
25-
children?: ReactNode;
26-
}
18+
export interface CubeLayoutBlockProps extends CubeLayoutContentProps {}
2719

2820
function LayoutBlock(
2921
props: CubeLayoutBlockProps,
3022
ref: ForwardedRef<HTMLDivElement>,
3123
) {
32-
const { children, ...otherProps } = props;
33-
const styles = extractStyles(otherProps, CONTAINER_STYLES);
24+
const { children, scrollbar = 'tiny', ...otherProps } = props;
3425

3526
return (
36-
<BlockElement
37-
{...filterBaseProps(otherProps, { eventProps: true })}
38-
ref={ref}
39-
styles={styles}
40-
>
41-
<LayoutContextReset>{children}</LayoutContextReset>
27+
<BlockElement {...otherProps} ref={ref} scrollbar={scrollbar}>
28+
{children}
4229
</BlockElement>
4330
);
4431
}

src/components/content/Layout/LayoutContent.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ const ContentElement = tasty({
3434
display: 'flex',
3535
flow: 'column',
3636
padding: '($content-padding, 1x)',
37-
overflow: 'auto',
37+
overflow: {
38+
'': 'auto',
39+
'scrollbar=none': 'clip',
40+
},
3841
placeSelf: 'stretch',
3942
scrollbar: {
4043
'': 'thin',
@@ -89,7 +92,7 @@ function LayoutContent(
8992
props: CubeLayoutContentProps,
9093
ref: ForwardedRef<HTMLDivElement>,
9194
) {
92-
const { children, scrollbar = 'thin', ...otherProps } = props;
95+
const { children, scrollbar = 'thin', styles, ...otherProps } = props;
9396
const extractedStyles = extractStyles(otherProps, CONTAINER_STYLES);
9497
const innerRef = useRef<HTMLDivElement>(null);
9598
const combinedRef = useCombinedRefs(ref);
@@ -116,12 +119,13 @@ function LayoutContent(
116119
[scrollbar, isHovered],
117120
);
118121

119-
// Apply container styles (like padding) to the Inner element
122+
// Merge incoming styles with extracted container styles for Inner element
120123
const finalStyles = useMemo(() => {
121124
return {
122-
Inner: extractedStyles,
125+
...styles,
126+
Inner: { ...(styles?.Inner as object), ...extractedStyles },
123127
};
124-
}, [extractedStyles]);
128+
}, [styles, extractedStyles]);
125129

126130
return (
127131
<ContentElement

src/components/content/Layout/LayoutFooter.tsx

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,48 @@
1-
import { ForwardedRef, forwardRef, ReactNode, useMemo } from 'react';
1+
import { ForwardedRef, forwardRef, useMemo } from 'react';
22

3-
import {
4-
BaseProps,
5-
CONTAINER_STYLES,
6-
ContainerStyleProps,
7-
extractStyles,
8-
filterBaseProps,
9-
tasty,
10-
} from '../../../tasty';
3+
import { tasty } from '../../../tasty';
114

12-
import { LayoutContextReset } from './LayoutContext';
5+
import { CubeLayoutContentProps, LayoutContent } from './LayoutContent';
136

14-
const FooterElement = tasty({
7+
const FooterElement = tasty(LayoutContent, {
158
as: 'footer',
169
qa: 'LayoutFooter',
1710
role: 'contentinfo',
1811
styles: {
19-
display: 'flex',
20-
flow: {
21-
'': 'row nowrap',
22-
inverted: 'row-reverse nowrap',
23-
},
24-
placeContent: 'center space-between',
25-
placeItems: 'center stretch',
26-
gap: '1x',
27-
padding: '($content-padding, 1x)',
2812
border: 'top',
29-
width: '100%',
3013
height: 'min 5x',
31-
boxSizing: 'border-box',
3214
flexShrink: 0,
15+
whiteSpace: 'nowrap',
16+
17+
Inner: {
18+
display: 'flex',
19+
flow: {
20+
'': 'row nowrap',
21+
inverted: 'row-reverse nowrap',
22+
},
23+
placeContent: 'center space-between',
24+
placeItems: 'center stretch',
25+
gap: '1x',
26+
},
3327
},
3428
});
3529

36-
export interface CubeLayoutFooterProps extends BaseProps, ContainerStyleProps {
30+
export interface CubeLayoutFooterProps extends CubeLayoutContentProps {
3731
/** Inverts the order of children (primary action on right) */
3832
invertOrder?: boolean;
39-
children?: ReactNode;
4033
}
4134

4235
function LayoutFooter(
4336
props: CubeLayoutFooterProps,
44-
ref: ForwardedRef<HTMLElement>,
37+
ref: ForwardedRef<HTMLDivElement>,
4538
) {
46-
const { children, invertOrder, mods, ...otherProps } = props;
47-
const styles = extractStyles(otherProps, CONTAINER_STYLES);
39+
const {
40+
children,
41+
invertOrder,
42+
scrollbar = 'tiny',
43+
mods,
44+
...otherProps
45+
} = props;
4846

4947
const finalMods = useMemo(
5048
() => ({
@@ -56,12 +54,12 @@ function LayoutFooter(
5654

5755
return (
5856
<FooterElement
57+
{...otherProps}
5958
ref={ref}
60-
{...filterBaseProps(otherProps, { eventProps: true })}
6159
mods={finalMods}
62-
styles={styles}
60+
scrollbar={scrollbar}
6361
>
64-
<LayoutContextReset>{children}</LayoutContextReset>
62+
{children}
6563
</FooterElement>
6664
);
6765
}

src/components/content/Layout/LayoutHeader.tsx

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,41 +9,33 @@ import {
99
} from 'react';
1010

1111
import { SlashIcon } from '../../../icons/SlashIcon';
12-
import {
13-
BaseProps,
14-
CONTAINER_STYLES,
15-
ContainerStyleProps,
16-
extractStyles,
17-
filterBaseProps,
18-
tasty,
19-
} from '../../../tasty';
12+
import { tasty } from '../../../tasty';
2013
import { Link } from '../../actions/Link/Link';
2114
import { Text } from '../Text';
2215
import { useAutoTooltip } from '../use-auto-tooltip';
2316

24-
import { LayoutContextReset } from './LayoutContext';
17+
import { CubeLayoutContentProps, LayoutContent } from './LayoutContent';
2518

26-
const HeaderElement = tasty({
19+
const HeaderElement = tasty(LayoutContent, {
2720
as: 'header',
2821
qa: 'LayoutHeader',
2922
styles: {
30-
display: 'grid',
31-
gridTemplate: `
32-
"breadcrumbs breadcrumbs breadcrumbs" auto
33-
"title suffix extra" 1fr
34-
"subtitle subtitle extra" auto
35-
/ max-content 1fr minmax(0, auto)
36-
`,
37-
gap: 0,
38-
padding: '($content-padding, 1x)',
3923
border: 'bottom',
40-
width: '100%',
41-
overflow: 'hidden',
42-
boxSizing: 'border-box',
43-
placeContent: 'stretch',
44-
placeItems: 'center stretch',
4524
flexShrink: 0,
4625

26+
Inner: {
27+
display: 'grid',
28+
gridTemplate: `
29+
"breadcrumbs breadcrumbs breadcrumbs" auto
30+
"title suffix extra" 1fr
31+
"subtitle subtitle extra" auto
32+
/ max-content 1fr minmax(0, auto)
33+
`,
34+
gap: 0,
35+
placeContent: 'stretch',
36+
placeItems: 'center stretch',
37+
},
38+
4739
Breadcrumbs: {
4840
gridArea: 'breadcrumbs',
4941
display: 'flex',
@@ -95,7 +87,7 @@ const HeaderElement = tasty({
9587
},
9688
});
9789

98-
export interface CubeLayoutHeaderProps extends BaseProps, ContainerStyleProps {
90+
export interface CubeLayoutHeaderProps extends CubeLayoutContentProps {
9991
/** Page/section title */
10092
title?: ReactNode;
10193
/** Title heading level (1-6) */
@@ -111,12 +103,11 @@ export interface CubeLayoutHeaderProps extends BaseProps, ContainerStyleProps {
111103
* Uses Link component which integrates with the navigation provider.
112104
*/
113105
breadcrumbs?: Array<[label: string, href: string]>;
114-
children?: ReactNode;
115106
}
116107

117108
function LayoutHeader(
118109
props: CubeLayoutHeaderProps,
119-
ref: ForwardedRef<HTMLElement>,
110+
ref: ForwardedRef<HTMLDivElement>,
120111
) {
121112
const {
122113
title,
@@ -125,13 +116,12 @@ function LayoutHeader(
125116
extra,
126117
subtitle,
127118
breadcrumbs,
119+
scrollbar = 'tiny',
128120
children,
129121
mods,
130122
...otherProps
131123
} = props;
132124

133-
const styles = extractStyles(otherProps, CONTAINER_STYLES);
134-
135125
// Use auto tooltip for title overflow detection
136126
const { labelRef, renderWithTooltip } = useAutoTooltip({
137127
tooltip: true,
@@ -178,19 +168,17 @@ function LayoutHeader(
178168

179169
return (
180170
<HeaderElement
171+
{...otherProps}
181172
ref={ref}
182-
{...filterBaseProps(otherProps, { eventProps: true })}
183173
mods={{ ...mods, level }}
184-
styles={styles}
174+
scrollbar={scrollbar}
185175
>
186-
<LayoutContextReset>
187-
{renderBreadcrumbs()}
188-
{renderWithTooltip(renderTitle, 'bottom')}
189-
{suffix && <div data-element="Suffix">{suffix}</div>}
190-
{extra && <div data-element="Extra">{extra}</div>}
191-
{subtitle && <div data-element="Subtitle">{subtitle}</div>}
192-
{children}
193-
</LayoutContextReset>
176+
{renderBreadcrumbs()}
177+
{renderWithTooltip(renderTitle, 'bottom')}
178+
{suffix && <div data-element="Suffix">{suffix}</div>}
179+
{extra && <div data-element="Extra">{extra}</div>}
180+
{subtitle && <div data-element="Subtitle">{subtitle}</div>}
181+
{children}
194182
</HeaderElement>
195183
);
196184
}

0 commit comments

Comments
 (0)