diff --git a/fakemui/fakemui/inputs/ButtonGroup.tsx b/fakemui/fakemui/inputs/ButtonGroup.tsx new file mode 100644 index 000000000..80f44f8f9 --- /dev/null +++ b/fakemui/fakemui/inputs/ButtonGroup.tsx @@ -0,0 +1,80 @@ +import React, { forwardRef, Children, cloneElement, isValidElement } from 'react' + +/** + * Props for ButtonGroup component + */ +export interface ButtonGroupProps extends React.HTMLAttributes { + children: React.ReactNode + /** Button size to apply to all children */ + size?: 'sm' | 'md' | 'lg' + /** Button variant to apply to all children */ + variant?: 'contained' | 'outlined' | 'text' + /** Color theme for buttons */ + color?: 'primary' | 'secondary' | 'error' | 'success' | 'warning' + /** Stack buttons vertically */ + vertical?: boolean + /** Disable all buttons */ + disabled?: boolean + /** Full width button group */ + fullWidth?: boolean +} + +/** + * ButtonGroup - Groups related buttons together with consistent styling + * + * @example + * ```tsx + * + * + * + * + * + * ``` + */ +export const ButtonGroup = forwardRef( + ( + { + children, + size = 'md', + variant = 'outlined', + color = 'primary', + vertical = false, + disabled = false, + fullWidth = false, + className = '', + ...props + }, + ref + ) => { + const childArray = Children.toArray(children) + + const enhancedChildren = childArray.map((child, index) => { + if (isValidElement(child)) { + const isFirst = index === 0 + const isLast = index === childArray.length - 1 + + return cloneElement(child as React.ReactElement>, { + size, + variant, + color, + disabled: disabled || (child.props as Record).disabled, + className: `btn-group__btn ${isFirst ? 'btn-group__btn--first' : ''} ${isLast ? 'btn-group__btn--last' : ''} ${!isFirst && !isLast ? 'btn-group__btn--middle' : ''}`, + }) + } + return child + }) + + return ( +
+ {enhancedChildren} +
+ ) + } +) + +ButtonGroup.displayName = 'ButtonGroup' diff --git a/fakemui/fakemui/inputs/index.js b/fakemui/fakemui/inputs/index.js index 8644d1f59..322e7ebe6 100644 --- a/fakemui/fakemui/inputs/index.js +++ b/fakemui/fakemui/inputs/index.js @@ -1,13 +1,17 @@ export { Button } from './Button' +export { ButtonGroup } from './ButtonGroup' export { IconButton } from './IconButton' export { Fab } from './Fab' export { Input } from './Input' export { Textarea } from './Textarea' export { Select } from './Select' +export { NativeSelect } from './NativeSelect' export { Checkbox } from './Checkbox' export { Radio } from './Radio' +export { RadioGroup, useRadioGroup } from './RadioGroup' export { Switch } from './Switch' export { Slider } from './Slider' +export { FormControl, useFormControl } from './FormControl' export { FormGroup } from './FormGroup' export { FormLabel } from './FormLabel' export { FormHelperText } from './FormHelperText' diff --git a/frontends/nextjs/src/components/managers/component/ComponentCatalog.tsx b/frontends/nextjs/src/components/managers/component/ComponentCatalog.tsx index af0a82a69..5004197eb 100644 --- a/frontends/nextjs/src/components/managers/component/ComponentCatalog.tsx +++ b/frontends/nextjs/src/components/managers/component/ComponentCatalog.tsx @@ -1,7 +1,8 @@ -import SearchIcon from '@mui/icons-material/Search' import { Box, Card, InputAdornment, Stack, TextField, Typography } from '@mui/material' import { useState } from 'react' +import { Search } from '@/fakemui/icons' + import { getComponentIcon } from '@/components/get-component-icon' import type { ComponentDefinition } from '@/lib/builder-types' import { componentCatalog } from '@/lib/component-catalog' @@ -47,7 +48,7 @@ export function ComponentCatalog({ onDragStart }: ComponentCatalogProps) { InputProps={{ startAdornment: ( - + ), }} diff --git a/frontends/nextjs/src/components/ui/molecules/display/Accordion.tsx b/frontends/nextjs/src/components/ui/molecules/display/Accordion.tsx index 749c7c915..4bf9c8200 100644 --- a/frontends/nextjs/src/components/ui/molecules/display/Accordion.tsx +++ b/frontends/nextjs/src/components/ui/molecules/display/Accordion.tsx @@ -1,6 +1,5 @@ 'use client' -import ExpandMoreIcon from '@mui/icons-material/ExpandMore' import { Accordion as MuiAccordion, AccordionDetails, @@ -9,6 +8,8 @@ import { } from '@mui/material' import { forwardRef, ReactNode, useState } from 'react' +import { ExpandMore } from '@/fakemui/icons' + interface AccordionProps { children: ReactNode type?: 'single' | 'multiple' diff --git a/frontends/nextjs/src/components/ui/molecules/navigation/Breadcrumb.tsx b/frontends/nextjs/src/components/ui/molecules/navigation/Breadcrumb.tsx index 69deca46d..98f6680b3 100644 --- a/frontends/nextjs/src/components/ui/molecules/navigation/Breadcrumb.tsx +++ b/frontends/nextjs/src/components/ui/molecules/navigation/Breadcrumb.tsx @@ -1,10 +1,10 @@ 'use client' -import MoreHorizIcon from '@mui/icons-material/MoreHoriz' -import NavigateNextIcon from '@mui/icons-material/NavigateNext' import { Box, Breadcrumbs as MuiBreadcrumbs, Link, Typography } from '@mui/material' import { forwardRef, ReactNode } from 'react' +import { MoreHoriz, NavigateNext } from '@/fakemui/icons' + interface BreadcrumbProps { children: ReactNode className?: string @@ -14,7 +14,7 @@ const Breadcrumb = forwardRef(({ children, ...prop return ( } + separator={} aria-label="breadcrumb" {...props} > diff --git a/frontends/nextjs/src/components/ui/molecules/navigation/NavGroup.tsx b/frontends/nextjs/src/components/ui/molecules/navigation/NavGroup.tsx index 295b919e9..5f313ccdb 100644 --- a/frontends/nextjs/src/components/ui/molecules/navigation/NavGroup.tsx +++ b/frontends/nextjs/src/components/ui/molecules/navigation/NavGroup.tsx @@ -1,7 +1,5 @@ 'use client' -import ExpandLessIcon from '@mui/icons-material/ExpandLess' -import ExpandMoreIcon from '@mui/icons-material/ExpandMore' import { Box, Collapse, @@ -14,6 +12,8 @@ import { } from '@mui/material' import { forwardRef, ReactNode, useState } from 'react' +import { ExpandLess, ExpandMore } from '@/fakemui/icons' + export interface NavGroupProps { label: string icon?: ReactNode @@ -72,9 +72,9 @@ const NavGroup = forwardRef( }} /> {open ? ( - + ) : ( - + )} diff --git a/frontends/nextjs/src/components/ui/molecules/overlay/Dialog.tsx b/frontends/nextjs/src/components/ui/molecules/overlay/Dialog.tsx index 346eb2556..e7b31c747 100644 --- a/frontends/nextjs/src/components/ui/molecules/overlay/Dialog.tsx +++ b/frontends/nextjs/src/components/ui/molecules/overlay/Dialog.tsx @@ -1,6 +1,5 @@ 'use client' -import CloseIcon from '@mui/icons-material/Close' import { Box, Dialog as MuiDialog, @@ -11,6 +10,8 @@ import { } from '@mui/material' import { forwardRef, ReactNode } from 'react' +import { Close } from '@/fakemui/icons' + import { DialogContent, type DialogContentProps } from './dialog/Body' import { DialogFooter, type DialogFooterProps } from './dialog/Footer' import { DialogHeader, type DialogHeaderProps } from './dialog/Header' diff --git a/frontends/nextjs/src/components/ui/molecules/overlay/dialog/Body.tsx b/frontends/nextjs/src/components/ui/molecules/overlay/dialog/Body.tsx index 5920c4a29..ded39448c 100644 --- a/frontends/nextjs/src/components/ui/molecules/overlay/dialog/Body.tsx +++ b/frontends/nextjs/src/components/ui/molecules/overlay/dialog/Body.tsx @@ -1,9 +1,10 @@ 'use client' -import CloseIcon from '@mui/icons-material/Close' import { DialogContent as MuiDialogContent, IconButton } from '@mui/material' import { forwardRef, ReactNode } from 'react' +import { Close } from '@/fakemui/icons' + export interface DialogBodyProps { children: ReactNode className?: string @@ -25,7 +26,7 @@ const DialogBody = forwardRef( onClick={onClose} sx={{ position: 'absolute', right: 8, top: 8, color: 'text.secondary' }} > - + )} {children}