Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
14d2a65
working PoC
LinKCoding Jan 13, 2026
5560977
fix build and format
LinKCoding Jan 13, 2026
06c6c6c
lint fixes
LinKCoding Jan 13, 2026
ced05b1
some more refactoring
LinKCoding Jan 14, 2026
3b6ceed
fix existing test failures
LinKCoding Jan 14, 2026
c82eaba
add test for getPropertyMode
LinKCoding Jan 14, 2026
b41b484
updated gamutprovider to include useLogicalProperties
LinKCoding Jan 14, 2026
a87a22e
fix failiing tests
LinKCoding Jan 14, 2026
fdf51c7
more test fixes
LinKCoding Jan 14, 2026
e52c44f
formatted
LinKCoding Jan 14, 2026
2b26f40
add logicalprops switcher to toolbar
LinKCoding Jan 14, 2026
c58bb38
updated shorthand in margin related CSS properties
LinKCoding Jan 16, 2026
182e36b
fix linting issue re: physical
LinKCoding Jan 16, 2026
594aeb2
update docs to show logical prop updates to margin related props
LinKCoding Jan 20, 2026
45c09ae
updated padding too
LinKCoding Jan 28, 2026
5e7b999
updated Usage Guide and clean up
LinKCoding Jan 29, 2026
7ec0399
add new file to explain logical and physical properties
LinKCoding Jan 29, 2026
0d65d1a
update docs for readibility
LinKCoding Jan 29, 2026
2322842
formatted and cleaned up
LinKCoding Jan 29, 2026
5478544
fix tests and edit MockGamutProvider to use useLogicalProperties
LinKCoding Jan 29, 2026
09696e1
Merge branch 'kl-gmt-1451-logical-props' into kl-gmt-1508v2-margin-pa…
LinKCoding Jan 29, 2026
1f6e194
temp fix for test failure
LinKCoding Jan 29, 2026
a160121
added related props and stories
LinKCoding Feb 4, 2026
da27455
add new story
LinKCoding Feb 4, 2026
977d01c
fix lint error
LinKCoding Feb 5, 2026
95ab1e9
more lint fixes
LinKCoding Feb 5, 2026
a0ce0b5
leftover lint
LinKCoding Feb 5, 2026
f168015
fix test failure
LinKCoding Feb 5, 2026
64efbdf
fix more tests
LinKCoding Feb 5, 2026
cd465e0
fix codecov coverage
LinKCoding Feb 5, 2026
a8bc778
added test coverage and removed some old comments
LinKCoding Feb 5, 2026
f900297
merged base branch
LinKCoding Feb 6, 2026
ff3171b
Merge branch 'kl-gmt-1451-logical-props' into kl-gmt-1516-gamut-layou…
LinKCoding Feb 9, 2026
afbed7b
Merge branch 'kl-gmt-1451-logical-props' into kl-gmt-1516-gamut-layou…
LinKCoding Feb 9, 2026
92998dd
Merge branch 'kl-gmt-1451-logical-props' into kl-gmt-1516-gamut-layou…
LinKCoding Feb 9, 2026
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
55 changes: 49 additions & 6 deletions packages/gamut-styles/src/variance/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,13 +323,56 @@ export const layout = {
properties: ['width', 'height'],
transform: transformSize,
},
width: { property: 'width', transform: transformSize },
minWidth: { property: 'minWidth', transform: transformSize },
maxWidth: { property: 'maxWidth', transform: transformSize },
height: { property: 'height', transform: transformSize },
minHeight: { property: 'minHeight', transform: transformSize },
maxHeight: { property: 'maxHeight', transform: transformSize },
width: {
property: {
physical: 'width',
logical: 'inlineSize',
},
resolveProperty: getPropertyMode,
transform: transformSize,
},
minWidth: {
property: {
physical: 'minWidth',
logical: 'minInlineSize',
},
resolveProperty: getPropertyMode,
transform: transformSize,
},
maxWidth: {
property: {
physical: 'maxWidth',
logical: 'maxInlineSize',
},
resolveProperty: getPropertyMode,
transform: transformSize,
},
height: {
property: {
physical: 'height',
logical: 'blockSize',
},
resolveProperty: getPropertyMode,
transform: transformSize,
},
minHeight: {
property: {
physical: 'minHeight',
logical: 'minBlockSize',
},
resolveProperty: getPropertyMode,
transform: transformSize,
},
maxHeight: {
property: {
physical: 'maxHeight',
logical: 'maxBlockSize',
},
resolveProperty: getPropertyMode,
transform: transformSize,
},
verticalAlign: { property: 'verticalAlign' },
direction: { property: 'direction' },
...selfAlignments,
...gridItems,
...flexItems,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import { ContentContainer } from '..';
const renderView = setupRtl(ContentContainer);

describe('ContentContainer', () => {
it('has maxWidth of contentWidths.max when size is medium', () => {
// Note: Only testing one mode here since variant() caches styles after first render.
it('has maxInlineSize of contentWidths.max when size is medium', () => {
const useLogicalProperties = true;
const maxWidthProp = useLogicalProperties ? 'maxInlineSize' : 'maxWidth';

const { view } = renderView({ size: 'medium' });

expect(view.container.firstChild).toHaveStyle(
`maxWidth: ${contentWidths.max}`
`${maxWidthProp}: ${contentWidths.max}`
);
});
});
77 changes: 52 additions & 25 deletions packages/gamut/src/DataList/__tests__/DataGrid.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { setupRtl } from '@codecademy/gamut-tests';
import { MockGamutProvider, setupRtl } from '@codecademy/gamut-tests';
import { matchers } from '@emotion/jest';
import { act, fireEvent, RenderResult, screen } from '@testing-library/react';
import {
act,
fireEvent,
render,
RenderResult,
screen,
} from '@testing-library/react';

import { DataGrid, DataGridProps } from '../DataGrid';
import { ColumnConfig } from '../types';
Expand Down Expand Up @@ -583,37 +589,58 @@ describe('DataGrid', () => {
});
});

describe('wrapperWidth prop', () => {
it('applies wrapperWidth to the table container when provided', () => {
renderView({ wrapperWidth: '600px' });
describe.each([
{
useLogicalProperties: true,
widthProp: 'inlineSize',
maxWidthProp: 'maxInlineSize',
},
{
useLogicalProperties: false,
widthProp: 'width',
maxWidthProp: 'maxWidth',
},
])(
'wrapperWidth prop (useLogicalProperties: $useLogicalProperties)',
({ useLogicalProperties, widthProp, maxWidthProp }) => {
const renderWithLogicalProps = (overrides?: Partial<Props>) =>
render(
<MockGamutProvider useLogicalProperties={useLogicalProperties}>
<DataGrid {...props} {...overrides} />
</MockGamutProvider>
);

const tableContainer = screen.getByTestId('scrollable-test');
expect(tableContainer).toHaveStyle({
maxWidth: '600px',
width: '600px',
it('applies wrapperWidth to the table container when provided', () => {
renderWithLogicalProps({ wrapperWidth: '600px' });

const tableContainer = screen.getByTestId('scrollable-test');
expect(tableContainer).toHaveStyle({
[maxWidthProp]: '600px',
[widthProp]: '600px',
});
});
});

it('uses default width when wrapperWidth is not provided', () => {
renderView();
it('uses default width when wrapperWidth is not provided', () => {
renderWithLogicalProps();

const tableContainer = screen.getByTestId('scrollable-test');
expect(tableContainer).toHaveStyle({
maxWidth: '100%',
width: 'inherit',
const tableContainer = screen.getByTestId('scrollable-test');
expect(tableContainer).toHaveStyle({
[maxWidthProp]: '100%',
[widthProp]: 'inherit',
});
});
});

it('passes wrapperWidth through to the underlying List component', () => {
renderView({ wrapperWidth: '750px' });
it('passes wrapperWidth through to the underlying List component', () => {
renderWithLogicalProps({ wrapperWidth: '750px' });

const tableContainer = screen.getByTestId('scrollable-test');
expect(tableContainer).toHaveStyle({
maxWidth: '750px',
width: '750px',
const tableContainer = screen.getByTestId('scrollable-test');
expect(tableContainer).toHaveStyle({
[maxWidthProp]: '750px',
[widthProp]: '750px',
});
});
});
});
}
);

describe('Container query control', () => {
it('applies container query styles by default', () => {
Expand Down
73 changes: 53 additions & 20 deletions packages/gamut/src/List/__tests__/List.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { theme } from '@codecademy/gamut-styles';
import { setupRtl } from '@codecademy/gamut-tests';
import { MockGamutProvider, setupRtl } from '@codecademy/gamut-tests';
import { matchers } from '@emotion/jest';
import { render } from '@testing-library/react';

import { List } from '../List';
import { List, ListProps } from '../List';
import { ListCol } from '../ListCol';
import { ListRow } from '../ListRow';

Expand Down Expand Up @@ -131,28 +132,60 @@ describe('List', () => {
expect(view.queryByText('Surprise!')).toBeNull();
});

describe('wrapperWidth prop', () => {
it('applies wrapperWidth to the table container when provided', () => {
const { view } = renderView({ wrapperWidth: '500px' });

const tableContainer = view.container.querySelector(
'[data-testid="scrollable-list-el"]'
describe.each([
{
useLogicalProperties: true,
widthProp: 'inlineSize',
maxWidthProp: 'maxInlineSize',
},
{
useLogicalProperties: false,
widthProp: 'width',
maxWidthProp: 'maxWidth',
},
])(
'wrapperWidth prop (useLogicalProperties: $useLogicalProperties)',
({ useLogicalProperties, widthProp, maxWidthProp }) => {
const defaultChildren = (
<ListRow data-testid="row-el">
<ListCol>Hello</ListCol>
</ListRow>
);
expect(tableContainer).toHaveStyle({ maxWidth: '500px', width: '500px' });
});

it('uses inherit width when wrapperWidth is not provided', () => {
const { view } = renderView();
const renderWithLogicalProps = (overrides?: Partial<ListProps>) =>
render(
<MockGamutProvider useLogicalProperties={useLogicalProperties}>
<List id="list-el" {...overrides}>
{overrides?.children ?? defaultChildren}
</List>
</MockGamutProvider>
);

it('applies wrapperWidth to the table container when provided', () => {
const view = renderWithLogicalProps({ wrapperWidth: '500px' });

const tableContainer = view.container.querySelector(
'[data-testid="scrollable-list-el"]'
);
expect(tableContainer).toHaveStyle({
[maxWidthProp]: '500px',
[widthProp]: '500px',
});
});

it('uses inherit width when wrapperWidth is not provided', () => {
const view = renderWithLogicalProps();

const tableContainer = view.container.querySelector(
'[data-testid="scrollable-list-el"]'
);
expect(tableContainer).toHaveStyle({
maxWidth: '100%',
width: 'inherit',
const tableContainer = view.container.querySelector(
'[data-testid="scrollable-list-el"]'
);
expect(tableContainer).toHaveStyle({
[maxWidthProp]: '100%',
[widthProp]: 'inherit',
});
});
});
});
}
);

it('applies container query styles by default', () => {
const { view } = renderView();
Expand Down
7 changes: 3 additions & 4 deletions packages/gamut/src/Pagination/EllipsisButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,21 @@ import { wrapWithSlideAnimation } from './utils';

export type EllipsisButtonProps = PaginationButtonProps & {
'aria-label': string;
direction: 'back' | 'forward';
buttonDirection: 'back' | 'forward';
};

const ellipsisButtonContents = { ellipsis: '•••', back: '«', forward: '»' };

export const BaseEllipsisButton = forwardRef<
ButtonBaseElements,
EllipsisButtonProps
// eslint-disable-next-line react/prop-types
>(({ direction, showButton, ...props }, ref) => {
>(({ buttonDirection, showButton, ...props }, ref) => {
const [contents, setContents] = useState(ellipsisButtonContents.ellipsis);

return (
<PaginationButton
ellipsis
onMouseEnter={() => setContents(ellipsisButtonContents[direction])}
onMouseEnter={() => setContents(ellipsisButtonContents[buttonDirection])}
onMouseLeave={() => setContents(ellipsisButtonContents.ellipsis)}
{...props}
ref={ref}
Expand Down
1 change: 0 additions & 1 deletion packages/gamut/src/Pagination/PaginationButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ export type PaginationButtonProps = ComponentProps<
export const PaginationButton = forwardRef<
ButtonBaseElements,
PaginationButtonProps
// eslint-disable-next-line react/prop-types
>(
(
{
Expand Down
Loading
Loading