Skip to content

feat: add button group, command, kbd, select, search, and skeleton#248

Merged
kylengn merged 6 commits intomainfrom
feat/components
Dec 19, 2025
Merged

feat: add button group, command, kbd, select, search, and skeleton#248
kylengn merged 6 commits intomainfrom
feat/components

Conversation

@kylengn
Copy link
Contributor

@kylengn kylengn commented Dec 18, 2025

Summary by CodeRabbit

  • New Features
    • Added custom scrollbar styling with dark mode support.
    • Introduced Button Group component with flexible orientation and size variants.
    • Added Command Palette UI for search and command execution.
    • Introduced Keyboard Key (Kbd) component for keyboard shortcut visualization.
    • Added Search component with inline and modal search variants.
    • Introduced Select dropdown component with icon and grouping support.
    • Added Skeleton loading component for UI placeholders.

✏️ Tip: You can customize this high-level summary in your review settings.

@kylengn kylengn self-assigned this Dec 18, 2025
Copilot AI review requested due to automatic review settings December 18, 2025 12:21
@vercel
Copy link

vercel bot commented Dec 18, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
react-ui Ready Ready Preview, Comment Dec 19, 2025 4:12am

@coderabbitai
Copy link

coderabbitai bot commented Dec 18, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Introduces six new UI components (ButtonGroup, Command, Kbd, Search, Select, Skeleton) to the React UI library with comprehensive Storybook stories, custom scrollbar CSS styling, and updates the public component exports. Adds cmdk as a dependency.

Changes

Cohort / File(s) Summary
CSS and Package Configuration
libs/react/ui/index.css, libs/react/ui/package.json
Adds .scrollbar and .scrollbar-hidden CSS classes with themed scrollbar styling; adds cmdk ^1.1.1 dependency.
ButtonGroup Component
libs/react/ui/src/components/button-group/button-group.tsx, libs/react/ui/src/components/button-group/button-group.stories.tsx, libs/react/ui/src/components/button-group/index.ts
Introduces ButtonGroup wrapper with orientation variants (horizontal/vertical), ButtonGroupSeparator, and ButtonGroupText; includes comprehensive Storybook examples showcasing usage patterns.
Command Component
libs/react/ui/src/components/command/command.tsx, libs/react/ui/src/components/command/command.stories.tsx, libs/react/ui/src/components/command/index.ts
Builds command palette UI on cmdk primitives; exports Command, CommandTrigger, CommandInput (with optional clear button), CommandList, CommandGroup, CommandItem, CommandDialog, and related wrapper components; includes Default and Combobox story patterns.
Kbd Component
libs/react/ui/src/components/kbd/kbd.tsx, libs/react/ui/src/components/kbd/kbd.stories.tsx, libs/react/ui/src/components/kbd/index.ts
Introduces Kbd keyboard key component and KbdGroup container with styled keyboard shortcut visuals; demonstrates standalone keys, key combinations, and menu-integrated variants in Storybook.
Search Component
libs/react/ui/src/components/search/search.tsx, libs/react/ui/src/components/search/search.stories.tsx, libs/react/ui/src/components/search/index.ts
Implements comprehensive search UI system with Search context for open state management, SearchTrigger with keyboard shortcuts, SearchInline for inline input, SearchOverlay/SearchContent for modal, plus SearchList, SearchItem, SearchGroup, SearchFooter; supports both controlled and uncontrolled usage with Escape-to-clear behavior and meta/ctrl\+K shortcut support.
Select Component
libs/react/ui/src/components/select/select.tsx, libs/react/ui/src/components/select/select.stories.tsx, libs/react/ui/src/components/select/index.ts
Wraps Radix UI Select primitives with custom styling via cva; exports Select, SelectTrigger (with variant/size control), SelectContent (with Portal and scroll buttons), SelectItem (icon support), SelectGroup, SelectLabel, SelectSeparator; demonstrates grouped options, icon-enabled items, and size/variant toggles in Storybook.
Skeleton Component
libs/react/ui/src/components/skeleton/skeleton.tsx, libs/react/ui/src/components/skeleton/skeleton.stories.tsx, libs/react/ui/src/components/skeleton/index.ts
Adds lightweight Skeleton loading placeholder component with pulse animation and neutral background; includes stories for card, list, and showcase loading patterns.
Code Block Enhancement
libs/react/ui/src/components/code-block/code-block-footer.tsx
Integrates useResolvedTheme hook to conditionally apply theme-aware colors to ShipfoxLoader icon during running state.
Public API Exports
libs/react/ui/src/components/index.ts
Adds re-exports for button-group, command, kbd, search, select, and skeleton to the public components index.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

  • Files affected: 28 files across 6 new component modules plus utilities and public API updates
  • Logic density: Each component has distinct styling logic (cva variants) and composition patterns, but implementations follow consistent conventions
  • Repetition: Barrel exports and Storybook stories follow predictable patterns, reducing per-file review overhead
  • Key areas requiring attention:
    • search.tsx — most complex with context management, controlled/uncontrolled state handling, keyboard shortcut logic, and transition animations
    • command.tsx — comprehensive wrapper around cmdk primitives with multiple sub-components; verify prop forwarding and interaction patterns
    • select.tsx — integration with Radix UI primitives and scroll button implementation
    • code-block-footer.tsx — verify useResolvedTheme hook usage aligns with theme resolution strategy

Possibly related PRs

Suggested reviewers

  • dvxam
  • noe-charmet
  • EnzalRad

Poem

🐰 Six shiny components hop into view,
ButtonGroup, Command, Kbd, Search too—
Select and Skeleton join the parade,
With stories and styles, a grand UI cascade! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.44% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding six new UI components (button group, command, kbd, select, search, and skeleton) to the component library.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@argos-ci
Copy link

argos-ci bot commented Dec 18, 2025

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) 👍 Changes approved 2 changed, 22 added Dec 19, 2025, 4:15 AM

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
libs/react/ui/index.css (1)

972-1018: LGTM! Well-structured scrollbar implementation.

The custom scrollbar styles are properly implemented with:

  • Cross-browser support using both standard properties and WebKit prefixes
  • Consistent use of design tokens for theming
  • Proper dark mode adjustments
  • Clean hidden variant for cases where scrollbars should not be visible

The implementation follows CSS best practices and integrates well with the existing design system.

Optional: Consider scrollbar width for accessibility

The 4px scrollbar width/height is quite minimal. If users report difficulty interacting with scrollbars, consider increasing to 6-8px for improved accessibility, particularly for users with motor impairments.

 .scrollbar::-webkit-scrollbar {
-  width: 4px;
-  height: 4px;
+  width: 6px;
+  height: 6px;
 }

This is purely optional and depends on your design requirements and user feedback.

libs/react/ui/src/components/kbd/kbd.tsx (1)

4-4: Consider exporting KbdProps for better developer experience.

While consumers can use ComponentProps<'kbd'> directly, exporting KbdProps would improve consistency and make it easier for developers to extend or wrap the Kbd component with proper typing.

🔎 Apply this diff to export KbdProps:
-type KbdProps = ComponentProps<'kbd'>;
+export type KbdProps = ComponentProps<'kbd'>;
libs/react/ui/src/components/search/search.stories.tsx (1)

40-61: Consider extracting InlineDemo outside the render function.

Defining InlineDemo inside the render function causes it to be recreated on every render, which can lead to state loss and remounting issues. While this may work for simple Storybook demos, extracting it to the module level (like ModalSearchDemo) would be more consistent with the pattern used elsewhere in this file.

🔎 Suggested refactor
+function InlineDemo() {
+  const [value, setValue] = useState('');
+
+  return (
+    <div className="flex flex-col gap-16 max-w-400">
+      <SearchInline
+        placeholder="Search..."
+        value={value}
+        onChange={(e) => setValue(e.target.value)}
+        onClear={() => setValue('')}
+      />
+      {value && (
+        <p className="text-sm text-foreground-neutral-muted">Searching for: "{value}"</p>
+      )}
+    </div>
+  );
+}
+
 export const Inline: Story = {
-  render: () => {
-    function InlineDemo() {
-      const [value, setValue] = useState('');
-
-      return (
-        <div className="flex flex-col gap-16 max-w-400">
-          <SearchInline
-            placeholder="Search..."
-            value={value}
-            onChange={(e) => setValue(e.target.value)}
-            onClear={() => setValue('')}
-          />
-          {value && (
-            <p className="text-sm text-foreground-neutral-muted">Searching for: "{value}"</p>
-          )}
-        </div>
-      );
-    }
-    return <InlineDemo />;
-  },
+  render: () => <InlineDemo />,
 };
libs/react/ui/src/components/search/search.tsx (1)

147-185: Keyboard shortcut handler doesn't account for already-open state.

The shortcut handler always calls setOpen(true) but doesn't toggle the search closed. If this is intentional (only open via shortcut, close via Escape), consider adding a comment to clarify. Also, the handler could benefit from checking if the search is already open to avoid unnecessary state updates.

🔎 Optional: toggle behavior or skip if already open
     const handleKeyDown = (e: KeyboardEvent) => {
       const key = shortcutKey.toLowerCase();
       const isMetaKey = key.startsWith('meta+') || key.startsWith('cmd+') || key.startsWith('⌘');
       const isCtrlKey = key.startsWith('ctrl+');
       const targetKey = key.replace(SHORTCUT_KEY_REGEX, '');

       if (isMetaKey && e.metaKey && e.key.toLowerCase() === targetKey) {
         e.preventDefault();
-        setOpen(true);
+        setOpen(!open); // Toggle behavior, or use `setOpen(true)` if open-only is intended
       } else if (isCtrlKey && e.ctrlKey && e.key.toLowerCase() === targetKey) {
         e.preventDefault();
-        setOpen(true);
+        setOpen(!open);
       } else if (
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 399cb8a and 11adf93.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (22)
  • libs/react/ui/index.css (1 hunks)
  • libs/react/ui/package.json (1 hunks)
  • libs/react/ui/src/components/button-group/button-group.stories.tsx (1 hunks)
  • libs/react/ui/src/components/button-group/button-group.tsx (1 hunks)
  • libs/react/ui/src/components/button-group/index.ts (1 hunks)
  • libs/react/ui/src/components/code-block/code-block-footer.tsx (2 hunks)
  • libs/react/ui/src/components/command/command.stories.tsx (1 hunks)
  • libs/react/ui/src/components/command/command.tsx (1 hunks)
  • libs/react/ui/src/components/command/index.ts (1 hunks)
  • libs/react/ui/src/components/index.ts (2 hunks)
  • libs/react/ui/src/components/kbd/index.ts (1 hunks)
  • libs/react/ui/src/components/kbd/kbd.stories.tsx (1 hunks)
  • libs/react/ui/src/components/kbd/kbd.tsx (1 hunks)
  • libs/react/ui/src/components/search/index.ts (1 hunks)
  • libs/react/ui/src/components/search/search.stories.tsx (1 hunks)
  • libs/react/ui/src/components/search/search.tsx (1 hunks)
  • libs/react/ui/src/components/select/index.ts (1 hunks)
  • libs/react/ui/src/components/select/select.stories.tsx (1 hunks)
  • libs/react/ui/src/components/select/select.tsx (1 hunks)
  • libs/react/ui/src/components/skeleton/index.ts (1 hunks)
  • libs/react/ui/src/components/skeleton/skeleton.stories.tsx (1 hunks)
  • libs/react/ui/src/components/skeleton/skeleton.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*

⚙️ CodeRabbit configuration file

We handle errors at the edge of our applications in most cases. Do not recommend to add error handling around every single function. We prefer them to bubble up and be handled at upper layers.

Files:

  • libs/react/ui/src/components/kbd/index.ts
  • libs/react/ui/src/components/index.ts
  • libs/react/ui/src/components/command/index.ts
  • libs/react/ui/src/components/search/index.ts
  • libs/react/ui/src/components/button-group/index.ts
  • libs/react/ui/src/components/kbd/kbd.tsx
  • libs/react/ui/package.json
  • libs/react/ui/src/components/kbd/kbd.stories.tsx
  • libs/react/ui/src/components/skeleton/index.ts
  • libs/react/ui/src/components/skeleton/skeleton.tsx
  • libs/react/ui/src/components/skeleton/skeleton.stories.tsx
  • libs/react/ui/src/components/command/command.stories.tsx
  • libs/react/ui/src/components/code-block/code-block-footer.tsx
  • libs/react/ui/index.css
  • libs/react/ui/src/components/search/search.stories.tsx
  • libs/react/ui/src/components/button-group/button-group.tsx
  • libs/react/ui/src/components/select/select.tsx
  • libs/react/ui/src/components/command/command.tsx
  • libs/react/ui/src/components/button-group/button-group.stories.tsx
  • libs/react/ui/src/components/select/select.stories.tsx
  • libs/react/ui/src/components/select/index.ts
  • libs/react/ui/src/components/search/search.tsx
🧬 Code graph analysis (6)
libs/react/ui/src/components/kbd/kbd.stories.tsx (1)
libs/react/ui/src/components/kbd/kbd.tsx (2)
  • Kbd (6-20)
  • KbdGroup (24-32)
libs/react/ui/src/components/skeleton/skeleton.stories.tsx (1)
libs/react/ui/src/components/skeleton/skeleton.tsx (1)
  • Skeleton (6-14)
libs/react/ui/src/components/command/command.stories.tsx (3)
libs/react/ui/src/components/command/command.tsx (9)
  • Command (248-248)
  • CommandInput (251-251)
  • CommandList (252-252)
  • CommandEmpty (253-253)
  • CommandGroup (254-254)
  • CommandItem (255-255)
  • CommandSeparator (256-256)
  • CommandShortcut (257-257)
  • CommandTrigger (249-249)
libs/react/ui/src/components/icon/icon.tsx (1)
  • Icon (86-90)
libs/react/ui/src/components/popover/popover.tsx (3)
  • Popover (60-60)
  • PopoverTrigger (60-60)
  • PopoverContent (60-60)
libs/react/ui/src/components/command/command.tsx (2)
libs/react/ui/src/components/icon/icon.tsx (1)
  • Icon (86-90)
libs/react/ui/src/components/kbd/kbd.tsx (1)
  • Kbd (6-20)
libs/react/ui/src/components/select/select.stories.tsx (1)
libs/react/ui/src/components/select/select.tsx (8)
  • Select (207-207)
  • SelectTrigger (210-210)
  • SelectValue (209-209)
  • SelectContent (211-211)
  • SelectItem (213-213)
  • SelectGroup (208-208)
  • SelectLabel (212-212)
  • SelectSeparator (214-214)
libs/react/ui/src/components/search/search.tsx (2)
libs/react/ui/src/components/icon/icon.tsx (1)
  • Icon (86-90)
libs/react/ui/src/components/kbd/kbd.tsx (1)
  • Kbd (6-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Agent
  • GitHub Check: Continuous integration
🔇 Additional comments (32)
libs/react/ui/src/components/code-block/code-block-footer.tsx (1)

5-5: Theme-aware loader implementation looks good.

The integration of useResolvedTheme to conditionally style the ShipfoxLoader based on the active theme is clean and follows React best practices. The hook properly returns 'light' | 'dark', and the conditional logic in lines 37-38 correctly adapts the loader's appearance. No error handling is needed here as theme resolution is deterministic and errors would bubble up at a higher layer per your guidelines.

libs/react/ui/src/components/button-group/index.ts (1)

1-1: LGTM!

Standard barrel export pattern that enables consolidated imports for the ButtonGroup component family.

libs/react/ui/src/components/skeleton/index.ts (1)

1-1: LGTM!

Standard barrel export pattern for the Skeleton component module.

libs/react/ui/src/components/skeleton/skeleton.tsx (1)

1-14: LGTM!

Clean and minimal Skeleton component implementation with proper type safety, className merging, and prop forwarding. The use of data-slot="skeleton" provides a consistent identification pattern.

libs/react/ui/src/components/skeleton/skeleton.stories.tsx (1)

1-178: LGTM!

Comprehensive Storybook coverage demonstrating diverse Skeleton use cases including basic shapes, card loading, list loading, table loading, form loading, and avatar group loading. Well-organized and clearly labeled stories.

libs/react/ui/src/components/button-group/button-group.tsx (1)

1-111: LGTM!

Well-architected ButtonGroup component family with proper accessibility (role="group", aria-hidden), flexible composition (Slot support), and comprehensive variant management via CVA. The complex CSS selectors for child styling are appropriate for this use case, and the biome-ignore comment on Line 52 is justified as role="group" is semantically correct for button groups.

libs/react/ui/src/components/button-group/button-group.stories.tsx (1)

1-373: LGTM!

Excellent Storybook coverage with comprehensive examples demonstrating ButtonGroup usage across multiple scenarios. Good accessibility practices with consistent aria-label attributes throughout, and helpful real-world examples via SelectExample and PopoverExample components.

libs/react/ui/src/components/kbd/index.ts (1)

1-1: LGTM!

Standard barrel export pattern for the Kbd component module.

libs/react/ui/package.json (1)

41-41: Version ^1.1.1 of cmdk is current and secure.

The latest version of cmdk is 1.1.1, and there are no known vulnerabilities. The caret version constraint appropriately allows for patch-level updates while maintaining stability.

libs/react/ui/src/components/select/index.ts (1)

1-1: LGTM!

Standard barrel export pattern that aligns with the project's component organization.

libs/react/ui/src/components/command/index.ts (1)

1-1: LGTM!

Standard barrel export pattern that aligns with the project's component organization.

libs/react/ui/src/components/search/index.ts (1)

1-1: LGTM!

Standard barrel export pattern that aligns with the project's component organization.

libs/react/ui/src/components/index.ts (1)

5-29: LGTM!

All six new component exports (button-group, command, kbd, search, select, skeleton) are correctly positioned in alphabetical order and follow the established barrel export pattern.

libs/react/ui/src/components/kbd/kbd.stories.tsx (1)

1-64: LGTM!

Comprehensive Storybook coverage demonstrating the Kbd component in multiple contexts:

  • Individual keys
  • Key combinations with KbdGroup
  • Menu integration with shortcuts

The stories effectively showcase the component's versatility and usage patterns.

libs/react/ui/src/components/command/command.stories.tsx (1)

1-133: LGTM!

Both stories effectively demonstrate Command component usage:

  • Default: Full-featured command palette with search, groups, icons, and shortcuts
  • Combobox: Real-world implementation showing state management, popover integration, and selection handling

The as const assertion on icon names (lines 73-79) ensures type safety, and the combobox logic correctly handles selection state and UI updates.

libs/react/ui/src/components/kbd/kbd.tsx (2)

6-20: LGTM!

The Kbd component is well-implemented with comprehensive styling, including:

  • Proper keyboard key aesthetics
  • Theme-aware styling with dark mode support
  • Tooltip context-aware variants
  • SVG sizing handling

24-32: LGTM!

The KbdGroup component provides a clean container for grouping related keyboard keys with appropriate spacing.

libs/react/ui/src/components/select/select.stories.tsx (1)

1-162: LGTM!

Comprehensive Storybook coverage demonstrating the Select component's full API surface:

  • Basic usage with placeholder
  • Grouped options with labels and separators
  • Icon-enhanced items for visual context
  • Size variants (small, base)
  • Style variants (base, component)

The stories provide clear examples for common Select patterns and customization options.

libs/react/ui/src/components/search/search.stories.tsx (2)

141-194: LGTM!

The ModalSearchDemo component is well-structured with proper state management, keyboard shortcut configuration, and a comprehensive demonstration of the modal search flow including groups, items, and footer.


257-403: LGTM!

The AllCombinations story provides excellent documentation coverage by showcasing all variant permutations (primary/secondary, squared/rounded, base/small) for both inline and modal trigger modes in a clear grid layout.

libs/react/ui/src/components/search/search.tsx (3)

469-491: LGTM!

The SearchItem component is well-structured with proper styling for selection states, disabled states, and flexible content layout with optional icon and description support.


535-563: LGTM!

The exports are comprehensive and well-organized, exposing all necessary components, variants, types, and the context hook for external use.


397-419: The autoFocus={open} pattern used here should work reliably in practice. While autoFocus within animated components can theoretically cause timing issues, SearchInput is not a direct child of AnimatePresence—it's nested inside SearchContent's motion.div container. Since the input element itself is not animated and only appears as a result of the parent container's animation, focus management should not be disrupted. No action needed unless focus timing issues are observed in practice.

libs/react/ui/src/components/select/select.tsx (4)

7-17: LGTM!

Clean wrapper components that properly forward props and add data-slot attributes for styling hooks.


159-188: LGTM!

The SelectItem component handles icon positioning well with absolute positioning, proper spacing adjustments via conditional pl-56/pl-32 classes, and includes the item indicator for selected state.


206-220: LGTM!

Exports are comprehensive, including all components, variant definition, and type exports.


126-135: Syntax is supported in Tailwind v4.

The parentheses syntax h-(--radix-select-trigger-height) and min-w-(--radix-select-trigger-width) is official Tailwind v4 syntax for CSS variables. Confirm your project uses Tailwind v4; if using v3, convert to h-[var(--radix-select-trigger-height)] instead.

libs/react/ui/src/components/command/command.tsx (5)

126-132: Escape key handler may interfere with cmdk's built-in behavior.

The handleKeyDown with e.stopPropagation() on Escape (line 129) prevents the event from bubbling. This could interfere with cmdk's built-in keyboard handling if it relies on the event propagating. Consider whether stopping propagation is necessary here, or if simply preventing default and clearing is sufficient.


41-64: LGTM!

The CommandTrigger component is well-implemented with proper ref forwarding, placeholder/value display logic, and consistent styling via CVA variants.


187-202: Consistent implementation with SearchGroup.

The CommandGroup styling uses the same **:[[cmdk-group-heading]] pattern as SearchGroup in search.tsx, which is good for consistency across the codebase.


247-261: LGTM!

Exports are comprehensive and well-organized, including all components, variant definition, and type exports.


80-89: CustomDialog backdrop handling is already managed by CommandPrimitive.Dialog.

The custom backdrop div serves only for styling (background color and blur effect). cmdk's Dialog component wraps CommandPrimitive using Radix UI's Dialog, which includes its own overlay for handling backdrop interactions. Radix Dialog automatically provides focus trapping and closes on Escape key press, so no additional onClick handler is needed. Per the coding guidelines, behavior should bubble up through the underlying primitive rather than being duplicated at custom wrapper levels.

Adding aria-hidden="true" to the visual backdrop is reasonable for accessibility purposes.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds six new UI components to the React UI library: ButtonGroup, Command, Kbd, Select, Search, and Skeleton. The changes include adding the cmdk package as a dependency, implementing comprehensive component implementations with Storybook stories, and adding custom scrollbar styles. Additionally, the CodeBlockFooter component is updated to support theme-aware loading indicators.

Key Changes

  • Added six new components (ButtonGroup, Command, Kbd, Select, Search, Skeleton) with full TypeScript support and Storybook documentation
  • Integrated cmdk v1.1.1 library for command palette and search functionality
  • Added custom scrollbar styling with theme support to index.css
  • Updated CodeBlockFooter to use theme-aware ShipfoxLoader colors

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
pnpm-lock.yaml Added cmdk v1.1.1 dependency and removed CPU architecture constraints from Biome CLI packages
libs/react/ui/package.json Added cmdk dependency to the package
libs/react/ui/src/components/skeleton/* New Skeleton component for loading state placeholders with comprehensive story examples
libs/react/ui/src/components/select/* New Select dropdown component built on Radix UI with variants and icon support
libs/react/ui/src/components/search/* New Search component with inline and modal variants, keyboard shortcuts, and filtering
libs/react/ui/src/components/kbd/* New Kbd component for displaying keyboard shortcuts with group support
libs/react/ui/src/components/command/* New Command palette component with search, filtering, and keyboard navigation
libs/react/ui/src/components/button-group/* New ButtonGroup component for grouping related buttons with horizontal/vertical orientation
libs/react/ui/src/components/index.ts Updated to export all new components
libs/react/ui/src/components/code-block/code-block-footer.tsx Updated to use theme-aware loader colors based on resolved theme
libs/react/ui/index.css Added custom scrollbar styles with theme support and hidden scrollbar variant
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kylengn kylengn merged commit 4e13ba7 into main Dec 19, 2025
5 checks passed
@kylengn kylengn deleted the feat/components branch December 19, 2025 09:38
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.

2 participants