Skip to content

chore(GamutProvider): useLogicalProperties hook#3306

Open
dreamwasp wants to merge 13 commits intomainfrom
cass-gmt-1601
Open

chore(GamutProvider): useLogicalProperties hook#3306
dreamwasp wants to merge 13 commits intomainfrom
cass-gmt-1601

Conversation

@dreamwasp
Copy link
Copy Markdown
Contributor

@dreamwasp dreamwasp commented Apr 1, 2026

Overview

adds useLogicalProperties hook to gamut-styles + reorganizes utility folders in gamut-styles

PR Checklist

  • Related to designs:
  • Related to JIRA ticket: [gmt-1601]
  • Version plan added/updated (or not needed)
  • I have run this code to verify it works
  • This PR includes unit tests for the code change
  • This PR includes testing instructions tests for the code change
  • The alpha package of this PR is passing end-to-end tests in all relevant Codecademy repositories

Testing Instructions

  1. Navigate to the PopoverContainer story
  2. Flip the RTL tool and see the console.log flip
  3. Check out the new docs

PR Links and Envs

Repository PR Link
Monolith Monolith PR
Mono Mono PR

@nx-cloud
Copy link
Copy Markdown

nx-cloud bot commented Apr 1, 2026

View your CI Pipeline Execution ↗ for commit e0b009f


☁️ Nx Cloud last updated this comment at 2026-04-07 16:18:24 UTC

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 1, 2026

⚠️ JUnit XML file not found

The CLI was unable to find any JUnit XML files to upload.
For more help, visit our troubleshooting guide.

@codecademydev
Copy link
Copy Markdown
Collaborator

📬 Published Alpha Packages:

Package Version npm Diff
@codecademy/gamut 68.2.3-alpha.bf4dbb.0 npm diff
@codecademy/gamut-icons 9.57.3-alpha.bf4dbb.0 npm diff
@codecademy/gamut-illustrations 0.58.10-alpha.bf4dbb.0 npm diff
@codecademy/gamut-kit 0.6.593-alpha.bf4dbb.0 npm diff
@codecademy/gamut-patterns 0.10.29-alpha.bf4dbb.0 npm diff
@codecademy/gamut-styles 17.13.2-alpha.bf4dbb.0 npm diff
@codecademy/gamut-tests 5.3.4-alpha.bf4dbb.0 npm diff
@codecademy/variance 0.26.2-alpha.bf4dbb.0 npm diff
eslint-plugin-gamut 2.4.4-alpha.bf4dbb.0 npm diff

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

@dreamwasp dreamwasp marked this pull request as ready for review April 7, 2026 18:07
@dreamwasp dreamwasp requested a review from a team as a code owner April 7, 2026 18:07
@dreamwasp dreamwasp requested a review from LinKCoding April 7, 2026 18:07
Comment on lines 3 to +36
@@ -22,14 +25,16 @@ export default {

if (eslintFiles.length) {
commands.push(
`node_modules/@codecademy/eslint-config/bin/eslint-fix.js ${eslintFiles.join(
' '
)}`
`node_modules/@codecademy/eslint-config/bin/eslint-fix.js ${eslintFiles
.map(shellArg)
.join(' ')}`
);
}

// Run nx format, which will run prettier
commands.push(`nx format:write --files ${allChanges}`);
commands.push(
`nx format:write --files ${allChanges.map(shellArg).join(' ')}`
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.

i was getting an error when trying to commit files with spaces, this fixes that.

Copy link
Copy Markdown
Contributor

@LinKCoding LinKCoding left a comment

Choose a reason for hiding this comment

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

Left thoughts, not blocking
This is much cleaner now :) thanks!

import type { RefObject } from 'react';
import { useEffect, useLayoutEffect, useReducer } from 'react';

/** Resolved HTML `dir` keyword: effective writing direction after `dir`, then CSS `direction`, then document root. */
Copy link
Copy Markdown
Contributor

@LinKCoding LinKCoding Apr 7, 2026

Choose a reason for hiding this comment

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

nit: could go over the comments on this file with the robot to refactor them in JSDoc styled comments

import { useTheme } from '@emotion/react';

/**
* Whether Gamut system props emit logical CSS properties (`marginInlineStart`, etc.)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: "emit" feels a little off to me, maybe "map to"? or "resolve to"?

* Whether Gamut system props emit logical CSS properties (`marginInlineStart`, etc.)
* vs physical (`marginLeft`, etc.).
*
* `GamutProvider` always merges an explicit boolean (default `false`).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just noting that this should change later when the default is also changed

Comment on lines +81 to +83
// Log logical properties to the console TEST CODE
const logicalProperties = useLogicalProperties();
console.log('dir', isRtl, 'logicalProperties', logicalProperties);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These can be cleaned up now

});
return () => observer.disconnect();
}, [targetRef]);
const isRtl = useElementDir(targetRef) === 'rtl';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for doing this!
fwiw, I made an addition to the popover ticket that involved this clean up: https://skillsoftdev.atlassian.net/browse/GMT-1598?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

And was doing some clean-up here: #3317

but I like your type clean-up more :) will close mine

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

that is to say, I'd say assign yourself and mark as done if no one gets back to you re: inverting

## `GamutProvider` and `useLogicalProperties`

Gamut supports both physical and logical CSS properties through the `useLogicalProperties` prop on `GamutProvider`. This allows you to choose which mode your application uses. By default, `useLogicalProperties` is set to `true`, meaning Gamut will use logical CSS properties. If you want to use physical CSS properties, you have to set `useLogicalProperties` to `false`.
Gamut supports both physical and logical CSS properties through the `useLogicalProperties` prop on `GamutProvider`. By default it is `false`, so Gamut emits **physical** CSS (`margin-left`, `width`, and so on). Pass `useLogicalProperties={true}` to emit **logical** CSS (`margin-inline-start`, `inline-size`, and so on).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same nit: "emit" to "resolve to" or something like that


The hook returns `theme.useLogicalProperties` from `@emotion/react`’s `useTheme()`. `GamutProvider` merges the prop into the theme object, so this value stays aligned with system props.

Use it when you need conditional styles or layout logic that must mirror Gamut’s physical vs logical output. If you mount `ThemeProvider` without merging `useLogicalProperties` into the theme, the hook may return `undefined`; prefer `GamutProvider` or set the field on your theme explicitly.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice callout!


In custom components, read the same flag Emotion-styled Gamut components use via `useLogicalProperties()` from `@codecademy/gamut-styles`:

<Code>{`import { useLogicalProperties } from '@codecademy/gamut-styles';`}</Code>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
<Code>{`import { useLogicalProperties } from '@codecademy/gamut-styles';`}</Code>
```
import { useLogicalProperties } from '@codecademy/gamut-styles';
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since this code is a separate block, I think using ``` makes sense here


`useElementDir` resolves the effective text direction (`'rtl'` or `'ltr'`) for a DOM subtree. Import it from `@codecademy/gamut-styles`:

<Code>{`import { useElementDir } from '@codecademy/gamut-styles';`}</Code>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
<Code>{`import { useElementDir } from '@codecademy/gamut-styles';`}</Code>
```
import { useElementDir } from '@codecademy/gamut-styles';
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same comment about block code


For non-React code, the same rules apply via the imperative `elementDir(el)` export.

`PopoverContainer` uses `useElementDir(targetRef) === 'rtl'` for RTL-aware positioning and visuals.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This info seems like it should be included in PopoverContainer instead and have a link to this page on logical props.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants