chore: Button Refactor - BED-6463 - #3030
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR replaces the legacy button implementation with Base UI-backed ChangesShared button migration
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
…se, remove bad focus styling, update Button again
There was a problem hiding this comment.
Actionable comments posted: 12
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/javascript/doodle-ui/src/tailwind/plugin.ts (1)
519-526: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winCommenting out
--tw-ring-colorleaves--tw-ring-shadowresolving to Tailwind's default ring color.
--tw-ring-shadowon line 525 still interpolatesvar(--tw-ring-color), which Tailwind's base layer defaults to its blue (rgb(59 130 246 / 0.5)). So.focus-ringnow paints a correct-coloredoutlineplus a blue box-shadow ring underneath it. If the box-shadow ring is no longer wanted, remove the ring variables/box-shadow entirely rather than only the color.🎨 Option: keep only the outline-based ring
'.focus-ring': { outline: 'var(--focus-ring-width) solid var(--focus-ring)', 'outline-offset': 'var(--focus-ring-offset-width)', - '--tw-ring-offset-width': 'var(--focus-ring-offset-width)', - '--tw-ring-offset-color': 'var(--focus-ring-offset)', - // TODO causes issues with Text - // '--tw-ring-color': 'var(--focus-ring)', - '--tw-ring-offset-shadow': '0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)', - '--tw-ring-shadow': - '0 0 0 calc(var(--focus-ring-width) + var(--tw-ring-offset-width)) var(--tw-ring-color)', - 'box-shadow': 'var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 `#0000`)', },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/javascript/doodle-ui/src/tailwind/plugin.ts` around lines 519 - 526, Update the focus-ring styles around the commented-out --tw-ring-color and --tw-ring-shadow declarations so the component no longer renders Tailwind’s default blue box-shadow ring; remove the ring-related variables and box-shadow when keeping the outline-only behavior, while preserving the correctly colored outline.
🧹 Nitpick comments (8)
packages/javascript/doodle-ui/src/components/Button/Button.stories.tsx (2)
135-146: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDrop the commented-out
variantargType block.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/javascript/doodle-ui/src/components/Button/Button.stories.tsx` around lines 135 - 146, Remove the commented-out variant entry from the argTypes configuration, leaving the active fontColor configuration unchanged.
204-218: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
aria-labelvalues don't match the rendered icons.Line 210 labels a star icon as "Gear Icon", and line 216 labels a filter icon the same way. Since these stories are the reference for
IconButtonaccessibility usage, the labels should describe the actual action/icon.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/javascript/doodle-ui/src/components/Button/Button.stories.tsx` around lines 204 - 218, The aria-label values on the secondary and disabled IconButtonComponent examples do not match their rendered icons. Update the labels in the Button stories so the secondary star button describes the star icon and the disabled AppIcon.FilterOutline button describes the filter icon, while leaving the primary example unchanged.packages/javascript/doodle-ui/src/components/Calendar/Calendar.tsx (1)
20-20: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valuePrefer the package entrypoint over the deep path.
TextButtonVariantsis re-exported from../Button; importing from../Button/Buttonbypasses the module boundary the index file establishes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/javascript/doodle-ui/src/components/Calendar/Calendar.tsx` at line 20, Update the TextButtonVariants import in Calendar.tsx to use the ../Button package entrypoint instead of the deep ../Button/Button path, preserving the existing symbol usage.packages/javascript/doodle-ui/src/components/Button/index.ts (1)
16-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAlso export the new prop types.
TextButtonProps/IconButtonProps(andIconButtonVariants) aren't re-exported, so wrapper components inbh-shared-uimust deep-import from./Buttonto type their props.♻️ Proposed export
-export { Button, ButtonVariants, IconButton, TextButton, TextButtonVariants, type ButtonProps } from './Button'; +export { + Button, + ButtonVariants, + IconButton, + IconButtonVariants, + TextButton, + TextButtonVariants, + type ButtonProps, + type IconButtonProps, + type TextButtonProps, +} from './Button';🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/javascript/doodle-ui/src/components/Button/index.ts` at line 16, Update the barrel export in the Button component index to re-export TextButtonProps, IconButtonProps, and IconButtonVariants alongside the existing Button symbols, allowing consumers to import these prop types without deep-importing the implementation module.packages/javascript/doodle-ui/src/components/Button/Button.tsx (2)
69-72: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
fontColoronButtonVariantsis now dead surface.Its own TODO says the only consumer was
variant="text", which this PR removed, andTextButtonownsfontColorgoing forward. Consider dropping it fromButtonVariants/ButtonPropsso the publicButtonAPI doesn't expose a no-op prop.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/javascript/doodle-ui/src/components/Button/Button.tsx` around lines 69 - 72, Remove the obsolete fontColor variant from ButtonVariants and ButtonProps, including its primary text-primary mapping, since Button no longer consumes it. Keep fontColor owned by TextButton and ensure the public Button API no longer exposes this no-op prop.
202-206: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDuplicated sizing/shape classes.
IconButtonVariantsalready emitsrounded-full border-0 p-2andsize-fit/shrink-0; repeating them inline (plushas-[svg]:p-2) just adds twMerge work and two places to keep in sync. Fold the extra classes into thecvabase.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/javascript/doodle-ui/src/components/Button/Button.tsx` around lines 202 - 206, Update the cva base used by IconButtonVariants to include the shared sizing and shape classes currently duplicated in the Button className, including the SVG padding behavior; then remove those duplicates from the inline class list while preserving unrelated classes and variant handling.packages/javascript/doodle-ui/src/tailwind/plugin.ts (1)
129-130: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDangling
// TODO remove.The marker is only added in the light
:rootblock; the same--tertiary-btn-borderin.dark(line 373) is unannotated, so the cleanup will be easy to miss. Want me to open a tracking issue?🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/javascript/doodle-ui/src/tailwind/plugin.ts` around lines 129 - 130, Remove the dangling TODO comment above --tertiary-btn-border in the light :root block; leave the variable and the corresponding dark-mode definition unchanged.packages/javascript/bh-shared-ui/src/components/LabelWithCopy.tsx (1)
19-19: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse
IconButtonfor this icon-only control.This renders only a copy icon;
packages/javascript/bh-shared-ui/src/components/Icon.tsxusesIconButtonfor the samearia-label+ icon pattern. Using it here keeps icon-only sizing and focus behavior consistent.Proposed change
-import { TextButton, Tooltip } from 'doodle-ui'; +import { IconButton, Tooltip } from 'doodle-ui'; - <TextButton + <IconButton onClick={handleCopy} aria-label='Copy to clipboard' className={cn('text-inherit text-sm', { invisible: !(!hoverOnly || hoverActive) })}> <FontAwesomeIcon icon={faCopy} /> - </TextButton> + </IconButton>Also applies to: 52-57
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/javascript/bh-shared-ui/src/components/LabelWithCopy.tsx` at line 19, Update the icon-only copy control in LabelWithCopy to use IconButton instead of TextButton, following the aria-label and icon usage established in Icon.tsx. Preserve the existing copy action and accessible label while adopting IconButton’s consistent sizing and focus behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@package.json`:
- Around line 57-59: Move the `@base-ui/react` dependency from the root
package.json dependencies into packages/javascript/doodle-ui/package.json,
preserving its current version range. Ensure the doodle-ui package directly
declares the runtime dependency required by its `@base-ui/react/button` import.
In
`@packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestFilterDialog.tsx`:
- Around line 97-102: Update the IconButton in
packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestFilterDialog.tsx
lines 97-102 to use the accessible name “Open file ingest filters”. In
packages/javascript/bh-shared-ui/src/components/FileIngest/FileIngest.test.tsx
line 98 and
packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestTable.test.tsx
line 243, replace data-testid queries with role-based button queries matching
that accessible name.
In
`@packages/javascript/bh-shared-ui/src/components/HelpTexts/CodeController/CodeController.tsx`:
- Line 128: Replace the div wrapper in the CodeController markup with a phrasing
element, preserving its existing className and contents, so it remains valid
inside the Typography component='pre' container.
In
`@packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/CypherSearch.tsx`:
- Around line 339-340: Update the class names in the CypherSearch editor styling
to use descendant selectors for nested CodeMirror elements: change the
cm-content and cm-tooltip selectors in the affected class list to the underscore
descendant forms, preserving all other classes and behavior.
In
`@packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/SavedQueries/CommonSearches.tsx`:
- Around line 182-188: Update the TextButton rendering in CommonSearches to
expose the saved-queries state with aria-expanded bound to showCommonQueries and
aria-controls referencing the controlled panel’s existing id. Ensure the panel
has a matching stable id while preserving the current toggle behavior.
In
`@packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Filters/DateField.tsx`:
- Around line 60-68: Add an accessible aria-label to the icon-only TextButton in
the date field clear-control handler, identifying that it clears the selected
date. Preserve the existing disabled state, visibility styling, and
form.setValue/form.clearErrors behavior.
In
`@packages/javascript/bh-shared-ui/src/views/PrivilegeZones/History/FilterDialog/FilterDialog.tsx`:
- Around line 126-130: Update the confirm TextButton in FilterDialog so it no
longer triggers native form submission after handleConfirm; use a non-submit
button type while preserving the existing click handler and confirmation
behavior.
In
`@packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/TagForm/GlyphSelectDialog.tsx`:
- Around line 158-162: Update the IconButton in GlyphSelectDialog to use an
accessible name that describes clearing the selection, replacing the
glyph-focused aria-label; remove or correct the invalid aria-describedby value
so it references an actual element ID only if needed.
In `@packages/javascript/doodle-ui/src/components/Button/Button.stories.tsx`:
- Around line 36-42: Update the Button story controls to expose only currently
supported values: remove `text` from the `options` array and remove `default`
from `fontColor.options`, leaving `primary` as the sole font color option. Clean
up the associated stale TODO/commented configuration in the story.
In `@packages/javascript/doodle-ui/src/components/Button/Button.tsx`:
- Around line 21-28: The shared buttonBaseClasses currently applies
hover:underline to filled variants; remove that utility from the shared base and
add it to TextButtonBaseClasses so only text-style buttons underline on hover.
Preserve transparent, primary, secondary, and IconButton hover behavior without
introducing per-variant resets.
In `@packages/javascript/doodle-ui/src/components/Calendar/Calendar.tsx`:
- Line 58: Invoke the TextButtonVariants cva factory before passing its result
to cn/clsx in the Calendar configuration, updating nav_button, day, and the
caption SelectTrigger className. Preserve the existing text-button variant
styling by using the factory with the text variant rather than passing
TextButtonVariants itself.
In `@packages/javascript/doodle-ui/src/components/Carousel/Carousel.tsx`:
- Around line 211-220: Update CarouselPrev and CarouselNext in
packages/javascript/doodle-ui/src/components/Carousel/Carousel.tsx at lines
211-220 and 257-266: type both forwardRef props as React.ComponentProps<typeof
TextButton> instead of Button props, and remove size='small' from both
TextButton usages.
---
Outside diff comments:
In `@packages/javascript/doodle-ui/src/tailwind/plugin.ts`:
- Around line 519-526: Update the focus-ring styles around the commented-out
--tw-ring-color and --tw-ring-shadow declarations so the component no longer
renders Tailwind’s default blue box-shadow ring; remove the ring-related
variables and box-shadow when keeping the outline-only behavior, while
preserving the correctly colored outline.
---
Nitpick comments:
In `@packages/javascript/bh-shared-ui/src/components/LabelWithCopy.tsx`:
- Line 19: Update the icon-only copy control in LabelWithCopy to use IconButton
instead of TextButton, following the aria-label and icon usage established in
Icon.tsx. Preserve the existing copy action and accessible label while adopting
IconButton’s consistent sizing and focus behavior.
In `@packages/javascript/doodle-ui/src/components/Button/Button.stories.tsx`:
- Around line 135-146: Remove the commented-out variant entry from the argTypes
configuration, leaving the active fontColor configuration unchanged.
- Around line 204-218: The aria-label values on the secondary and disabled
IconButtonComponent examples do not match their rendered icons. Update the
labels in the Button stories so the secondary star button describes the star
icon and the disabled AppIcon.FilterOutline button describes the filter icon,
while leaving the primary example unchanged.
In `@packages/javascript/doodle-ui/src/components/Button/Button.tsx`:
- Around line 69-72: Remove the obsolete fontColor variant from ButtonVariants
and ButtonProps, including its primary text-primary mapping, since Button no
longer consumes it. Keep fontColor owned by TextButton and ensure the public
Button API no longer exposes this no-op prop.
- Around line 202-206: Update the cva base used by IconButtonVariants to include
the shared sizing and shape classes currently duplicated in the Button
className, including the SVG padding behavior; then remove those duplicates from
the inline class list while preserving unrelated classes and variant handling.
In `@packages/javascript/doodle-ui/src/components/Button/index.ts`:
- Line 16: Update the barrel export in the Button component index to re-export
TextButtonProps, IconButtonProps, and IconButtonVariants alongside the existing
Button symbols, allowing consumers to import these prop types without
deep-importing the implementation module.
In `@packages/javascript/doodle-ui/src/components/Calendar/Calendar.tsx`:
- Line 20: Update the TextButtonVariants import in Calendar.tsx to use the
../Button package entrypoint instead of the deep ../Button/Button path,
preserving the existing symbol usage.
In `@packages/javascript/doodle-ui/src/tailwind/plugin.ts`:
- Around line 129-130: Remove the dangling TODO comment above
--tertiary-btn-border in the light :root block; leave the variable and the
corresponding dark-mode definition unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 7d5dcd0d-4779-4f0b-9dda-ddb07c5c24af
⛔ Files ignored due to path filters (10)
.yarn/cache/@babel-runtime-npm-7.29.7-423e8cd4b6-9883b49517.zipis excluded by!**/.yarn/**,!**/*.zip.yarn/cache/@base-ui-react-npm-1.6.0-b96a743958-7fed3b731e.zipis excluded by!**/.yarn/**,!**/*.zip.yarn/cache/@base-ui-utils-npm-0.3.1-7fda044f8e-48fe7f0b1a.zipis excluded by!**/.yarn/**,!**/*.zip.yarn/cache/@floating-ui-core-npm-1.8.0-7cb6ad2d03-762cd5677f.zipis excluded by!**/.yarn/**,!**/*.zip.yarn/cache/@floating-ui-dom-npm-1.8.0-a6d2aa48a8-2e7d75fb70.zipis excluded by!**/.yarn/**,!**/*.zip.yarn/cache/@floating-ui-react-dom-npm-2.1.9-751127e598-d775609760.zipis excluded by!**/.yarn/**,!**/*.zip.yarn/cache/@floating-ui-utils-npm-0.2.12-72e5a495e8-ec4e176fb2.zipis excluded by!**/.yarn/**,!**/*.zip.yarn/cache/reselect-npm-5.2.0-4fd7475b1f-e53d37a35f.zipis excluded by!**/.yarn/**,!**/*.zip.yarn/cache/use-sync-external-store-npm-1.6.0-2db2af616d-b40ad2847b.zipis excluded by!**/.yarn/**,!**/*.zipyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (60)
cmd/ui/src/views/EarlyAccessFeatures/EarlyAccessFeatures.tsxpackage.jsonpackages/javascript/bh-shared-ui/src/components/AnalyzeNowConfiguration/AnalyzeNowConfirmDialog.tsxpackages/javascript/bh-shared-ui/src/components/CitrixRDPConfiguration/CitrixRDPConfirmDialog.tsxpackages/javascript/bh-shared-ui/src/components/ColumnHeaders/ColumnHeaders.tsxpackages/javascript/bh-shared-ui/src/components/DropdownSelector/DropdownSelector.tsxpackages/javascript/bh-shared-ui/src/components/DropdownSelector/DropdownTriggerContents.tsxpackages/javascript/bh-shared-ui/src/components/DropdownSelector/constants.tspackages/javascript/bh-shared-ui/src/components/EntityInfo/EntityInfoHeader.tsxpackages/javascript/bh-shared-ui/src/components/ExploreTable/TableControls.tsxpackages/javascript/bh-shared-ui/src/components/FileIngest/FileIngest.test.tsxpackages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestFilterDialog.tsxpackages/javascript/bh-shared-ui/src/components/GroupManagementContent/GroupManagementContent.tsxpackages/javascript/bh-shared-ui/src/components/HelpTexts/CodeController/CodeController.tsxpackages/javascript/bh-shared-ui/src/components/Icon.tsxpackages/javascript/bh-shared-ui/src/components/LabelWithCopy.tsxpackages/javascript/bh-shared-ui/src/components/LoginForm/LoginForm.tsxpackages/javascript/bh-shared-ui/src/components/LoginViaSSOForm/LoginViaSSOForm.tsxpackages/javascript/bh-shared-ui/src/components/Navigation/MainNav.tsxpackages/javascript/bh-shared-ui/src/components/SSOProviderTable/SSOProviderTable.tsxpackages/javascript/bh-shared-ui/src/components/SimpleEnvironmentSelector/SimpleEnvironmentSelector.tsxpackages/javascript/bh-shared-ui/src/components/UserTokenManagementDialog/UserTokenManagementDialog.tsxpackages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/CypherSearch.tsxpackages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/EdgeFilter/EdgeFilteringDialog.tsxpackages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/SavedQueries/CommonSearches.tsxpackages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/SavedQueries/ConfirmDeleteQueryDialog.tsxpackages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/SavedQueries/ConfirmUpdateQueryDialog.tsxpackages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/SavedQueries/ImportQueryDialog.tsxpackages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/SavedQueries/QuerySearchFilter.tsxpackages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/SavedQueries/SaveQueryDialog.tsxpackages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/SavedQueries/TagToZoneLabel.tsxpackages/javascript/bh-shared-ui/src/views/OpenGraphManagement/ActiveExtensionsCard.tsxpackages/javascript/bh-shared-ui/src/views/OpenGraphManagement/DeleteExtensionButton.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/Details.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/ObjectsAccordion.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/RulesAccordion.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/SearchBar.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Filters/DateField.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Filters/TagIdField.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/History/FilterDialog/ActionField.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/History/FilterDialog/FilterDialog.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/History/FilterDialog/MadeByField.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/History/NoteCell.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/DeleteRuleButton/DeleteRuleButton.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/ObjectSelect.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/SeedSelection.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/SeedSelectionPreview.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/TagForm/GlyphSelectDialog.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/TagForm/TagForm.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/ZoneIcon.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/fragments.tsxpackages/javascript/doodle-ui/src/components/Button/Button.stories.tsxpackages/javascript/doodle-ui/src/components/Button/Button.tsxpackages/javascript/doodle-ui/src/components/Button/index.tspackages/javascript/doodle-ui/src/components/Calendar/Calendar.tsxpackages/javascript/doodle-ui/src/components/Card/Card.tsxpackages/javascript/doodle-ui/src/components/Carousel/Carousel.tsxpackages/javascript/doodle-ui/src/components/DatePicker/DatePicker.tsxpackages/javascript/doodle-ui/src/tailwind/plugin.tspackages/javascript/doodle-ui/src/tailwind/preset.ts
| "dependencies": { | ||
| "@base-ui/react": "^1.6.0" | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Does doodle-ui declare the dep itself?
fd -t f 'package.json' packages/javascript/doodle-ui --max-depth 2 --exec cat
# 2) Where is it imported from?
rg -n --type=ts --type=tsx '`@base-ui`' packages cmd || rg -n '`@base-ui`' -g '*.ts*' .
# 3) Registry check for both candidate names
for p in "`@base-ui/react`" "`@base-ui-components/react`"; do
echo "== $p =="
curl -s "https://registry.npmjs.org/$(printf %s "$p" | sed 's|/|%2F|')" | jq -r '.name? // "NOT FOUND", ("latest: " + (.["dist-tags"].latest // "n/a"))'
doneRepository: SpecterOps/BloodHound
Length of output: 5516
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== root package.json =="
cat -n package.json | sed -n '1,220p'
echo
echo "== workspace package manifests =="
fd -t f 'package.json' packages | sort
echo
echo "== base-ui imports and declarations =="
rg -n '`@base-ui/react`|`@base-ui-components/react`' package.json packages -g 'package.json' -g '*.ts' -g '*.tsx'Repository: SpecterOps/BloodHound
Length of output: 3435
Move @base-ui/react into packages/javascript/doodle-ui/package.json. The workspace package imports @base-ui/react/button, but the dependency is only listed at the repo root, so consumers of doodle-ui won’t get a declared runtime dependency.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@package.json` around lines 57 - 59, Move the `@base-ui/react` dependency from
the root package.json dependencies into
packages/javascript/doodle-ui/package.json, preserving its current version
range. Ensure the doodle-ui package directly declares the runtime dependency
required by its `@base-ui/react/button` import.
| <IconButton | ||
| aria-label='Open file ingest' | ||
| variant='secondary' | ||
| data-testid='file_ingest_log-open_filter_dialog'> | ||
| <AppIcon.FilterOutline size={22} /> | ||
| </Button> | ||
| </IconButton> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- FileIngestFilterDialog.tsx (around trigger) ---'
sed -n '80,115p' packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestFilterDialog.tsx
echo
echo '--- FileIngest.test.tsx (around queried button) ---'
sed -n '70,120p' packages/javascript/bh-shared-ui/src/components/FileIngest/FileIngest.test.tsx
echo
echo '--- Search for related accessible names and test ids ---'
rg -n "file_ingest_log-open_filter_dialog|Open file ingest|Open file ingest filters|getByRole\\(|getByTestId\\(" packages/javascript/bh-shared-ui/src/components/FileIngestTable packages/javascript/bh-shared-ui/src/components/FileIngestRepository: SpecterOps/BloodHound
Length of output: 7117
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'FILE1\n'
nl -ba packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestFilterDialog.tsx | sed -n '90,110p'
printf '\nFILE2\n'
nl -ba packages/javascript/bh-shared-ui/src/components/FileIngest/FileIngest.test.tsx | sed -n '90,110p'
printf '\nMATCHES\n'
rg -n "file_ingest_log-open_filter_dialog|Open file ingest|Open file ingest filters|getByRole\\(|getByTestId\\(" packages/javascript/bh-shared-ui/src/components/FileIngestTable packages/javascript/bh-shared-ui/src/components/FileIngestRepository: SpecterOps/BloodHound
Length of output: 205
Give the filter trigger a clearer accessible name and assert it by role.
packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestFilterDialog.tsx#L97-L102:aria-label='Open file ingest'should be action-specific, e.g.Open file ingest filters.packages/javascript/bh-shared-ui/src/components/FileIngest/FileIngest.test.tsx#L98-L98andpackages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestTable.test.tsx#L243-L243: query the button by role + accessible name instead ofdata-testid.
📍 Affects 2 files
packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestFilterDialog.tsx#L97-L102(this comment)packages/javascript/bh-shared-ui/src/components/FileIngest/FileIngest.test.tsx#L98-L98
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestFilterDialog.tsx`
around lines 97 - 102, Update the IconButton in
packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestFilterDialog.tsx
lines 97-102 to use the accessible name “Open file ingest filters”. In
packages/javascript/bh-shared-ui/src/components/FileIngest/FileIngest.test.tsx
line 98 and
packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestTable.test.tsx
line 243, replace data-testid queries with role-based button queries matching
that accessible name.
There was a problem hiding this comment.
This is worth addressing
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- trigger implementation ---'
sed -n '90,106p' packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestFilterDialog.tsx
echo
echo '--- trigger references in tests ---'
rg -n -C 4 \
"file_ingest_log-open_filter_dialog|getByRole\(\s*['\"]button['\"]|Open file ingest filters" \
packages/javascript/bh-shared-ui/src/components/FileIngest/FileIngest.test.tsx \
packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestTable.test.tsxLength of output: 8145
@specter-flq, the accessible name is already correct. The remaining valid change is to update the two tests to use the button role and the accessible name.
- Update
FileIngest.test.tsxto locate the filter trigger by role and name. - Update
FileIngestTable.test.tsxto locate the same trigger by role and name.
- 📌 Create a pull request with these changes
You are interacting with an AI system.
| <TextButton | ||
| onClick={onToggleCommonQueries} | ||
| className='flex justify-start items-center w-full pl-0' | ||
| data-testid='common-queries-toggle' | ||
| variant={'text'}> | ||
| <FontAwesomeIcon className='px-2 mr-2' icon={showCommonQueries ? faChevronDown : faChevronUp} /> | ||
| data-testid='common-queries-toggle'> | ||
| <FontAwesomeIcon className='px-2' icon={showCommonQueries ? faChevronDown : faChevronUp} /> | ||
| <span className='my-4 font-semibold text-lg'>Saved Queries</span> | ||
| </Button> | ||
| </TextButton> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Expose the saved-queries toggle state to assistive technology.
Add aria-expanded={showCommonQueries} and aria-controls referencing the controlled panel’s id; the chevron alone does not communicate the current state to screen-reader users.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/SavedQueries/CommonSearches.tsx`
around lines 182 - 188, Update the TextButton rendering in CommonSearches to
expose the saved-queries state with aria-expanded bound to showCommonQueries and
aria-controls referencing the controlled panel’s existing id. Ensure the panel
has a matching stable id while preserving the current toggle behavior.
There was a problem hiding this comment.
not really knowledgeable in a11y but maybe worth while looking into this one
There was a problem hiding this comment.
@specter-flq, this is worthwhile as a small accessibility improvement.
The current code already adds aria-expanded={showCommonQueries}. That lets screen readers announce whether Saved Queries is expanded or collapsed.
The remaining aria-controls and matching panel id are low-risk additions. They explicitly associate the toggle with its controlled content. This does not change behavior or layout.
I recommend keeping this as a minor fix in this PR.
You are interacting with an AI system.
| const buttonBaseClasses = [ | ||
| 'inline-flex items-center justify-center whitespace-nowrap rounded-3xl transition-colors', | ||
| 'hover:underline', | ||
| 'focus:outline-none focus-visible:focus-ring', | ||
| 'active:no-underline', | ||
| 'disabled:text-[#616161] dark:disabled:text-[#A6A6A6] disabled:pointer-events-none disabled:opacity-50', | ||
| 'has-[svg]:gap-2 [&>svg]:shrink-0', | ||
| ]; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
hover:underline in the shared base now applies to filled Button variants.
transparent explicitly resets it with hover:no-underline, but primary/secondary (and IconButton, which reuses these base classes) don't, so filled buttons will underline their label on hover. If underline is only intended for text-style buttons, move it out of the base into TextButtonBaseClasses.
🎨 Proposed adjustment
const buttonBaseClasses = [
'inline-flex items-center justify-center whitespace-nowrap rounded-3xl transition-colors',
- 'hover:underline',
'focus:outline-none focus-visible:focus-ring',
'active:no-underline', const TextButtonBaseClasses = cn(
...buttonBaseClasses,
+ 'hover:underline',
'px-1 py-2 has-[svg]:px-1',📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const buttonBaseClasses = [ | |
| 'inline-flex items-center justify-center whitespace-nowrap rounded-3xl transition-colors', | |
| 'hover:underline', | |
| 'focus:outline-none focus-visible:focus-ring', | |
| 'active:no-underline', | |
| 'disabled:text-[#616161] dark:disabled:text-[#A6A6A6] disabled:pointer-events-none disabled:opacity-50', | |
| 'has-[svg]:gap-2 [&>svg]:shrink-0', | |
| ]; | |
| const buttonBaseClasses = [ | |
| 'inline-flex items-center justify-center whitespace-nowrap rounded-3xl transition-colors', | |
| 'focus:outline-none focus-visible:focus-ring', | |
| 'active:no-underline', | |
| 'disabled:text-[`#616161`] dark:disabled:text-[`#A6A6A6`] disabled:pointer-events-none disabled:opacity-50', | |
| 'has-[svg]:gap-2 [&>svg]:shrink-0', | |
| ]; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/javascript/doodle-ui/src/components/Button/Button.tsx` around lines
21 - 28, The shared buttonBaseClasses currently applies hover:underline to
filled variants; remove that utility from the shared base and add it to
TextButtonBaseClasses so only text-style buttons underline on hover. Preserve
transparent, primary, secondary, and IconButton hover behavior without
introducing per-variant resets.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/javascript/bh-shared-ui/src/components/DropdownSelector/DropdownTriggerContents.tsx (1)
50-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRemove the render-time debug log.
console.log(open)runs on every render and will pollute production browser consoles.Proposed fix
- console.log(open);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/javascript/bh-shared-ui/src/components/DropdownSelector/DropdownTriggerContents.tsx` at line 50, Remove the console.log(open) debug statement from the DropdownTriggerContents render path, leaving the surrounding component behavior unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In
`@packages/javascript/bh-shared-ui/src/components/DropdownSelector/DropdownTriggerContents.tsx`:
- Line 50: Remove the console.log(open) debug statement from the
DropdownTriggerContents render path, leaving the surrounding component behavior
unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 5c1b5cb5-7661-4524-a6fa-44dcc362c602
📒 Files selected for processing (2)
packages/javascript/bh-shared-ui/src/components/DropdownSelector/DropdownTriggerContents.tsxpackages/javascript/bh-shared-ui/src/components/DropdownSelector/constants.ts
93207eb to
7d31fd0
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/javascript/doodle-ui/src/components/Carousel/Carousel.tsx`:
- Around line 212-220: Add accessible labels to both carousel controls: update
the previous-slide TextButton near Carousel controls at
packages/javascript/doodle-ui/src/components/Carousel/Carousel.tsx lines 212-220
with aria-label “Previous slide”, and the next-slide TextButton at lines 259-267
with aria-label “Next slide”.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 06794829-585c-46f8-a3af-f2326f782995
📒 Files selected for processing (9)
packages/javascript/bh-shared-ui/src/components/DropdownSelector/DropdownTriggerContents.tsxpackages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestFilterDialog.tsxpackages/javascript/bh-shared-ui/src/components/HelpTexts/CodeController/CodeController.tsxpackages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/CypherSearch.tsxpackages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/SavedQueries/CommonSearches.tsxpackages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/TagForm/GlyphSelectDialog.tsxpackages/javascript/doodle-ui/src/components/Button/Button.stories.tsxpackages/javascript/doodle-ui/src/components/Calendar/Calendar.tsxpackages/javascript/doodle-ui/src/components/Carousel/Carousel.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
- packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/SavedQueries/CommonSearches.tsx
- packages/javascript/doodle-ui/src/components/Calendar/Calendar.tsx
- packages/javascript/bh-shared-ui/src/components/FileIngestTable/FileIngestFilterDialog.tsx
- packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/TagForm/GlyphSelectDialog.tsx
9278f72 to
88dff3c
Compare
| </Button> | ||
| </Tooltip> | ||
| <TextButton | ||
| className={cn(optionStyles)} |
There was a problem hiding this comment.
We don't need the cn utility here.
| tip='Collapse All' | ||
| onClick={handleCollapseAll} | ||
| className='box-border text-contrast px-4' | ||
| className='box-border text-contrast px-4 mx-2' |
| <Button | ||
| className='pr-0' | ||
| <TextButton | ||
| className='pr-2' |
There was a problem hiding this comment.
nit: this can be removed as it gets px-1 from the component.
9482aa6 to
6139db3
Compare
6139db3 to
d552371
Compare
|
|
||
| <DialogActions> | ||
| <Button variant={'text'} className='p-2' onClick={closeDialog}> | ||
| <TextButton className='pr-2' onClick={closeDialog}> |
There was a problem hiding this comment.
nit: can remove pr-2 as it gets padding from the component.
| className={cn('text-contrast', iconClasses)} | ||
| data-testid='tier_zero_icon' | ||
| /> | ||
| <AppIcon.TierZero {...iconProps} size={16} className={cn(iconClasses)} data-testid='tier_zero_icon' /> |
There was a problem hiding this comment.
No need for the cn utility here.
There was a problem hiding this comment.
Love that we are getting rid of MUI here. I didn't see the change on bhe, was that on purpose ? if not maybe we should consider removing the makeStyles in the same file over there to keep it consistent.
| <div data-testid='explore_search-container' className='h-full min-h-0 w-[600px] flex gap-4 flex-col rounded'> | ||
| <div | ||
| className='h-10 w-full flex gap-1 rounded-lg shadow-outer-1 pointer-events-auto bg-[#f4f4f4] dark:bg-[#222222]' | ||
| className='h-10 w-full flex gap-1 items-center rounded-lg shadow-outer-1 pointer-events-auto bg-[#f4f4f4] dark:bg-[#222222]' |
There was a problem hiding this comment.
Not sure if you maybe were waiting on this for later, but should we consider replacing with respective color tokens or similar to those hardcoded values?
| it('displays a Filters button', async () => { | ||
| await act(async () => render(<FileIngest />)); | ||
| const filterButton = screen.getByRole('button', { name: /app-icon-filter-outline/i }); | ||
| const filterButton = screen.getByTestId('file_ingest_log-open_filter_dialog'); |
There was a problem hiding this comment.
We should consider getting by role over testId I think thats the preferred priority of the library. Also the rabbit makes a comment about it below.
| className={cn( | ||
| 'grow min-h-0 bg-[#f4f4f4] dark:bg-[#222222] shadow-outer-1 p-2 py-0 rounded-lg mb-4' | ||
| )}> | ||
| <div className={cn('grow min-h-0 bg-[#f4f4f4] dark:bg-[#222222] shadow-outer-1 py-0 rounded-lg mb-4')}> |
There was a problem hiding this comment.
I saw a comment from Michael S about the tokens, guess this would apply here as well, but calling it out just in case as these are more common colors that maybe we do have
| import { Accordion, AccordionContent, AccordionItem, IconButton, Skeleton, TextButton, Tooltip } from 'doodle-ui'; | ||
| import { AssetGroupTagMemberListItem } from 'js-client-library'; | ||
| import { useState } from 'react'; | ||
| import { optionStyles } from '../../..'; |
There was a problem hiding this comment.
Wonder if this path not having specific file names will give us issues ( want to say possible circular dependency ones). Maybe we should consider having it explicitly say the file just in case.
| import { AssetGroupTagSelector, CustomRulesKey, DefaultRulesKey, DisabledRulesKey, RulesKey } from 'js-client-library'; | ||
| import { useEffect, useRef, useState } from 'react'; | ||
| import { FixedSizeList } from 'react-window'; | ||
| import { optionStyles } from '../../..'; |
There was a problem hiding this comment.
Wonder if this path not having specific file names will give us issues ( want to say possible circular dependency ones). Maybe we should consider having it explicitly say the file just in case.
| export interface ButtonProps | ||
| extends React.ButtonHTMLAttributes<HTMLButtonElement>, | ||
| VariantProps<typeof ButtonVariants> { | ||
| asChild?: boolean; |
There was a problem hiding this comment.
Curious as to why we dropped this prop
| <div className='flex justify-between items-center min-h-10'> | ||
| <span>Sample Results</span> | ||
| <Button | ||
| asChild | ||
| variant='text' | ||
| disabled={!exploreUrl} | ||
| className={cn('font-normal', { | ||
| hidden: !showViewInExploreButton, | ||
| })}> | ||
| <a href={exploreUrl} target='_blank' rel='noreferrer'> | ||
| {exploreUrl && ( | ||
| <a | ||
| href={exploreUrl} | ||
| target='_blank' | ||
| rel='noopener noreferrer' | ||
| className={cn( | ||
| TextButtonVariants({ fontColor: 'primary' }), | ||
| 'text-sm', | ||
| ruleType !== SeedTypeCypher && 'hidden' | ||
| )}> | ||
| View in Explore | ||
| </a> | ||
| </Button> | ||
| )} | ||
| </div> |
There was a problem hiding this comment.
Curious on this change, from what I have seen there are benefits from the button asChild pattern with a nested link tag. Not saying the change is bad, but want to learn more about the reasoning behind it. Ties to the comment on removing the asChild from the the Button component


Description
Button refactor!!!
Updated Button base with BaseUI, updated tests, replaces Icon and Text Buttons with new TextButton and IconButton. Updated color scheme. Left tons of notes for future tickets.
Motivation and Context
Resolves BED-6463
Figma links:
https://www.figma.com/design/pqlfSCxXVB5MjX5Gq50rW8/Alpha-%F0%9F%90%95?node-id=9-12&p=f&m=dev
https://www.figma.com/design/pqlfSCxXVB5MjX5Gq50rW8/Alpha-%F0%9F%90%95?node-id=431-1937&m=dev
Why is this change required? What problem does it solve?
Updated styling for Button,
split text variant and icon variant
replaced old text and icon buttons to use the new version
removed bad focus styling
and other no broken glass areas
How Has This Been Tested?
Please describe in detail how you tested your changes.
Include details of your testing environment, and the tests you ran to
see how your change affects other areas of the code, etc.
Manually with screen reader and keyboard navigation, visually, test suite passes
Screenshots (optional):
Updated styling:


OLD:
NEW:
OLD:




NEW:
OLD:


NEW:
OLD:


NEW:
OLD:


NEW:


OLD:


NEW:
OLD:


NEW:


STORYBOOK:

Types of changes
Checklist:
Summary by CodeRabbit
New Features
Bug Fixes
Tests