From 876f6f4fd22696e3041ae6e72db856c1bdd39030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Grimm?= Date: Thu, 5 Feb 2026 16:39:51 -0600 Subject: [PATCH 1/5] convert menu.less to menu.module.css Co-Authored-By: Claude Opus 4.6 --- src/menu/menu.less | 72 ------------------------------------- src/menu/menu.module.css | 76 ++++++++++++++++++++++++++++++++++++++++ src/menu/menu.tsx | 6 ++-- 3 files changed, 79 insertions(+), 75 deletions(-) delete mode 100644 src/menu/menu.less create mode 100644 src/menu/menu.module.css diff --git a/src/menu/menu.less b/src/menu/menu.less deleted file mode 100644 index 69afc76bc..000000000 --- a/src/menu/menu.less +++ /dev/null @@ -1,72 +0,0 @@ -.reactist_menulist[role='menu'] { - min-height: 44px; // minimum accessible target area - max-height: var(--popover-available-height); // defined by ariakit - overflow: auto; - display: block; - white-space: nowrap; - background: hsla(0, 100%, 100%, 0.99); - outline: none; - font-size: var(--reactist-font-size-copy); - padding: 4px 0; - min-width: 180px; - border: 1px solid var(--reactist-divider-secondary); - border-radius: 3px; - margin: -4px; // Required to add spacing between the viewport, used in conjunction with unstable_offset - z-index: var(--reactist-stacking-order-menu); - - [role='menuitem'], - .reactist_menugroup__label { - user-select: none; - outline: none; - text-align: left; - display: flex; - align-items: center; - padding: 5px 10px; - color: inherit; - border: none; - background-color: transparent; - font-family: var(--reactist-font-family); - font-size: var(--reactist-font-size-copy); - } - - .reactist_menugroup__label { - color: var(--reactist-content-secondary); - font-size: var(--reactist-font-size-copy); - } - - [role='menuitem'] { - width: 100%; - box-sizing: border-box; - &:hover, - &:focus, - &[aria-expanded='true'] { - color: var(--reactist-content-primary); - background-color: var(--reactist-bg-selected); - } - &[aria-disabled='true'], - &:disabled { - color: var(--reactist-content-secondary); - pointer-events: none; - } - } - - a[role='menuitem'] { - cursor: default; - text-decoration: none; - &:hover { - text-decoration: none; - } - } - - // sub-menus need to be shifted a bit towards the top to be aligned with its menu item - [role='menu'] { - margin-top: -5px; - } - - hr { - border: none; - height: 1px; - background-color: var(--reactist-bg-selected); - margin: 4px 0; - } -} diff --git a/src/menu/menu.module.css b/src/menu/menu.module.css new file mode 100644 index 000000000..29c8eeb52 --- /dev/null +++ b/src/menu/menu.module.css @@ -0,0 +1,76 @@ +/* minimum accessible target area */ +.menulist[role='menu'] { + min-height: 44px; + max-height: var(--popover-available-height); /* defined by ariakit */ + overflow: auto; + display: block; + white-space: nowrap; + background: hsla(0, 100%, 100%, 0.99); + outline: none; + font-size: var(--reactist-font-size-copy); + padding: 4px 0; + min-width: 180px; + border: 1px solid var(--reactist-divider-secondary); + border-radius: 3px; + margin: -4px; /* Required to add spacing between the viewport, used in conjunction with unstable_offset */ + z-index: var(--reactist-stacking-order-menu); +} + +.menulist [role='menuitem'], +.menulist .menuGroupLabel { + user-select: none; + outline: none; + text-align: left; + display: flex; + align-items: center; + padding: 5px 10px; + color: inherit; + border: none; + background-color: transparent; + font-family: var(--reactist-font-family); + font-size: var(--reactist-font-size-copy); +} + +.menulist .menuGroupLabel { + color: var(--reactist-content-secondary); + font-size: var(--reactist-font-size-copy); +} + +.menulist [role='menuitem'] { + width: 100%; + box-sizing: border-box; +} + +.menulist [role='menuitem']:hover, +.menulist [role='menuitem']:focus, +.menulist [role='menuitem'][aria-expanded='true'] { + color: var(--reactist-content-primary); + background-color: var(--reactist-bg-selected); +} + +.menulist [role='menuitem'][aria-disabled='true'], +.menulist [role='menuitem']:disabled { + color: var(--reactist-content-secondary); + pointer-events: none; +} + +.menulist a[role='menuitem'] { + cursor: default; + text-decoration: none; +} + +.menulist a[role='menuitem']:hover { + text-decoration: none; +} + +/* sub-menus need to be shifted a bit towards the top to be aligned with its menu item */ +.menulist [role='menu'] { + margin-top: -5px; +} + +.menulist hr { + border: none; + height: 1px; + background-color: var(--reactist-bg-selected); + margin: 4px 0; +} diff --git a/src/menu/menu.tsx b/src/menu/menu.tsx index ace95c8b6..6460ea8a6 100644 --- a/src/menu/menu.tsx +++ b/src/menu/menu.tsx @@ -1,4 +1,4 @@ -import './menu.less' +import styles from './menu.module.css' import * as React from 'react' @@ -172,7 +172,7 @@ const MenuList = React.forwardRef(function MenuLi gutter={8} shift={4} ref={ref} - className={classNames('reactist_menulist', exceptionallySetClassName)} + className={classNames(styles.menulist, exceptionallySetClassName)} getAnchorRect={getAnchorRect ?? undefined} modal={modal} flip={flip ?? (isSubMenu ? 'left bottom' : undefined)} @@ -380,7 +380,7 @@ const MenuGroup = React.forwardRef(function Menu className={exceptionallySetClassName} > {label ? ( -
+
{label}
) : null} From 13875e27bb4d958a7d8ba43ffd12ee7df0d21be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Grimm?= Date: Thu, 5 Feb 2026 16:40:32 -0600 Subject: [PATCH 2/5] convert story .less files to .css Co-Authored-By: Claude Opus 4.6 --- .storybook/preview.js | 2 +- stories/components/Avatar.stories.tsx | 2 +- stories/components/color.stories.tsx | 2 +- .../{avatar_story.less => avatar_story.css} | 0 .../styles/{color-story.less => color-story.css} | 0 stories/components/styles/story.css | 9 +++++++++ stories/components/styles/story.less | 15 --------------- 7 files changed, 12 insertions(+), 18 deletions(-) rename stories/components/styles/{avatar_story.less => avatar_story.css} (100%) rename stories/components/styles/{color-story.less => color-story.css} (100%) create mode 100644 stories/components/styles/story.css delete mode 100644 stories/components/styles/story.less diff --git a/.storybook/preview.js b/.storybook/preview.js index 92be3d3a3..eada7501f 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,6 +1,6 @@ import { addParameters } from '@storybook/react' import BaseDecorator from './BaseDecorator' -import '../stories/components/styles/story.less' +import '../stories/components/styles/story.css' export const decorators = [BaseDecorator] diff --git a/stories/components/Avatar.stories.tsx b/stories/components/Avatar.stories.tsx index 1c156fdb3..5c12b1307 100644 --- a/stories/components/Avatar.stories.tsx +++ b/stories/components/Avatar.stories.tsx @@ -1,4 +1,4 @@ -import './styles/avatar_story.less' +import './styles/avatar_story.css' import * as React from 'react' diff --git a/stories/components/color.stories.tsx b/stories/components/color.stories.tsx index 83db959d9..764336408 100644 --- a/stories/components/color.stories.tsx +++ b/stories/components/color.stories.tsx @@ -1,4 +1,4 @@ -import './styles/color-story.less' +import './styles/color-story.css' import * as React from 'react' diff --git a/stories/components/styles/avatar_story.less b/stories/components/styles/avatar_story.css similarity index 100% rename from stories/components/styles/avatar_story.less rename to stories/components/styles/avatar_story.css diff --git a/stories/components/styles/color-story.less b/stories/components/styles/color-story.css similarity index 100% rename from stories/components/styles/color-story.less rename to stories/components/styles/color-story.css diff --git a/stories/components/styles/story.css b/stories/components/styles/story.css new file mode 100644 index 000000000..6e08f70a8 --- /dev/null +++ b/stories/components/styles/story.css @@ -0,0 +1,9 @@ +body { + font-family: var(--reactist-font-family); +} + +.story { + margin: 0 40px 0 40px; + padding: 20px; + background-color: white; +} diff --git a/stories/components/styles/story.less b/stories/components/styles/story.less deleted file mode 100644 index 7d5f350da..000000000 --- a/stories/components/styles/story.less +++ /dev/null @@ -1,15 +0,0 @@ -body { - font-family: var(--reactist-font-family); -} - -.story { - margin: 0 40px 0 40px; - padding: 20px; - background-color: white; - - // checkered background - // @gray: whitesmoke; - // background-image: linear-gradient(45deg, @gray 25%, transparent 25%), linear-gradient(-45deg, @gray 25%, transparent 25%), linear-gradient(45deg, transparent 75%, @gray 75%), linear-gradient(-45deg, transparent 75%, @gray 75%); - // background-size: 20px 20px; - // background-position: 0 0, 0 10px, 10px -10px, -10px 0px; -} From 299c6756351ee5f1d67941ef3a61e43876bc8ac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Grimm?= Date: Thu, 5 Feb 2026 17:47:52 -0600 Subject: [PATCH 3/5] fix: sort imports in menu.tsx Co-Authored-By: Claude Haiku 4.5 --- src/menu/menu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/menu/menu.tsx b/src/menu/menu.tsx index 6460ea8a6..441ba8360 100644 --- a/src/menu/menu.tsx +++ b/src/menu/menu.tsx @@ -1,5 +1,3 @@ -import styles from './menu.module.css' - import * as React from 'react' import { @@ -13,6 +11,8 @@ import { } from '@ariakit/react' import classNames from 'classnames' +import styles from './menu.module.css' + import type { MenuButtonProps as AriakitMenuButtonProps, MenuItemProps as AriakitMenuItemProps, From 25f6bb5d189adda8cf6529f4d103dded68e60c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Grimm?= Date: Thu, 5 Feb 2026 18:10:25 -0600 Subject: [PATCH 4/5] fix: scope CSS modules rule to .module.css files only Co-Authored-By: Claude Opus 4.6 --- .storybook/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.storybook/main.js b/.storybook/main.js index 116175f20..c9535d841 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -50,6 +50,7 @@ module.exports = { ? [ { ...rule, + test: /\.module\.css$/, use: rule.use.map((useEntry) => { return useEntry.loader?.match(/\/css-loader/) ? { @@ -72,7 +73,6 @@ module.exports = { }, { ...rule, - test: /\.module\.css$/, exclude: /\.module\.css$/, }, ] From 4f606715e1e0410a912e5250eaa7cc9d4a6c2f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Grimm?= Date: Fri, 6 Feb 2026 15:15:44 -0600 Subject: [PATCH 5/5] use :global() to preserve original class names in menu.module.css Co-Authored-By: Claude Opus 4.6 --- src/menu/menu.module.css | 28 ++++++++++++++-------------- src/menu/menu.tsx | 8 ++++---- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/menu/menu.module.css b/src/menu/menu.module.css index 29c8eeb52..07abb1840 100644 --- a/src/menu/menu.module.css +++ b/src/menu/menu.module.css @@ -1,5 +1,5 @@ /* minimum accessible target area */ -.menulist[role='menu'] { +:global(.reactist_menulist)[role='menu'] { min-height: 44px; max-height: var(--popover-available-height); /* defined by ariakit */ overflow: auto; @@ -16,8 +16,8 @@ z-index: var(--reactist-stacking-order-menu); } -.menulist [role='menuitem'], -.menulist .menuGroupLabel { +:global(.reactist_menulist) [role='menuitem'], +:global(.reactist_menulist) :global(.reactist_menugroup__label) { user-select: none; outline: none; text-align: left; @@ -31,44 +31,44 @@ font-size: var(--reactist-font-size-copy); } -.menulist .menuGroupLabel { +:global(.reactist_menulist) :global(.reactist_menugroup__label) { color: var(--reactist-content-secondary); font-size: var(--reactist-font-size-copy); } -.menulist [role='menuitem'] { +:global(.reactist_menulist) [role='menuitem'] { width: 100%; box-sizing: border-box; } -.menulist [role='menuitem']:hover, -.menulist [role='menuitem']:focus, -.menulist [role='menuitem'][aria-expanded='true'] { +:global(.reactist_menulist) [role='menuitem']:hover, +:global(.reactist_menulist) [role='menuitem']:focus, +:global(.reactist_menulist) [role='menuitem'][aria-expanded='true'] { color: var(--reactist-content-primary); background-color: var(--reactist-bg-selected); } -.menulist [role='menuitem'][aria-disabled='true'], -.menulist [role='menuitem']:disabled { +:global(.reactist_menulist) [role='menuitem'][aria-disabled='true'], +:global(.reactist_menulist) [role='menuitem']:disabled { color: var(--reactist-content-secondary); pointer-events: none; } -.menulist a[role='menuitem'] { +:global(.reactist_menulist) a[role='menuitem'] { cursor: default; text-decoration: none; } -.menulist a[role='menuitem']:hover { +:global(.reactist_menulist) a[role='menuitem']:hover { text-decoration: none; } /* sub-menus need to be shifted a bit towards the top to be aligned with its menu item */ -.menulist [role='menu'] { +:global(.reactist_menulist) [role='menu'] { margin-top: -5px; } -.menulist hr { +:global(.reactist_menulist) hr { border: none; height: 1px; background-color: var(--reactist-bg-selected); diff --git a/src/menu/menu.tsx b/src/menu/menu.tsx index 441ba8360..9fca203fd 100644 --- a/src/menu/menu.tsx +++ b/src/menu/menu.tsx @@ -1,3 +1,5 @@ +import './menu.module.css' + import * as React from 'react' import { @@ -11,8 +13,6 @@ import { } from '@ariakit/react' import classNames from 'classnames' -import styles from './menu.module.css' - import type { MenuButtonProps as AriakitMenuButtonProps, MenuItemProps as AriakitMenuItemProps, @@ -172,7 +172,7 @@ const MenuList = React.forwardRef(function MenuLi gutter={8} shift={4} ref={ref} - className={classNames(styles.menulist, exceptionallySetClassName)} + className={classNames('reactist_menulist', exceptionallySetClassName)} getAnchorRect={getAnchorRect ?? undefined} modal={modal} flip={flip ?? (isSubMenu ? 'left bottom' : undefined)} @@ -380,7 +380,7 @@ const MenuGroup = React.forwardRef(function Menu className={exceptionallySetClassName} > {label ? ( -
+
{label}
) : null}