@moderneinc/neo-styled-components 4.1.2-next.c7153c → 4.1.2-next.f98de9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DataGridColumnsPanel/DataGridColumnsPanel.d.ts +1 -1
- package/dist/IconButton/IconButton.d.ts +23 -13
- package/dist/Toolbar/Toolbar.d.ts +1 -1
- package/dist/index.d.ts +24 -16
- package/dist/index.esm.js +70 -83
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +73 -86
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -28,6 +28,6 @@ export interface NeoDataGridColumnsPanelProps extends GridColumnsPanelProps {
|
|
|
28
28
|
showSearch?: boolean;
|
|
29
29
|
}
|
|
30
30
|
export declare const NeoDataGridColumnsPanel: {
|
|
31
|
-
({ showSearch, ...props }: NeoDataGridColumnsPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
({ showSearch, sx: _sx, theme: _theme, ...props }: NeoDataGridColumnsPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
32
32
|
displayName: string;
|
|
33
33
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ButtonBaseProps } from '@mui/material/ButtonBase';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
2
3
|
type IconButtonSize = 'small' | 'medium';
|
|
3
|
-
type IconButtonVariant = '
|
|
4
|
-
export interface NeoIconButtonProps extends Omit<
|
|
4
|
+
type IconButtonVariant = 'primary' | 'secondary' | 'destructive' | 'tertiary' | 'nav';
|
|
5
|
+
export interface NeoIconButtonProps extends Omit<ButtonBaseProps, 'children' | 'size'> {
|
|
5
6
|
/**
|
|
6
7
|
* The size of the icon button
|
|
7
8
|
* @default "medium"
|
|
@@ -10,10 +11,10 @@ export interface NeoIconButtonProps extends Omit<IconButtonProps, 'color' | 'siz
|
|
|
10
11
|
*/
|
|
11
12
|
size?: IconButtonSize;
|
|
12
13
|
/**
|
|
13
|
-
* The visual variant of the icon button
|
|
14
|
-
* - `
|
|
14
|
+
* The visual variant of the icon button.
|
|
15
|
+
* - `primary`, `secondary`, `destructive`, `tertiary`: Uses NeoButton's hierarchy styling
|
|
15
16
|
* - `nav`: White background with border, used in global navigation
|
|
16
|
-
* @default "
|
|
17
|
+
* @default "tertiary"
|
|
17
18
|
*/
|
|
18
19
|
variant?: IconButtonVariant;
|
|
19
20
|
/**
|
|
@@ -22,25 +23,34 @@ export interface NeoIconButtonProps extends Omit<IconButtonProps, 'color' | 'siz
|
|
|
22
23
|
* @default false
|
|
23
24
|
*/
|
|
24
25
|
active?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Show loading spinner instead of icon.
|
|
28
|
+
* Only applies to hierarchy variants (not `nav`).
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
loading?: boolean;
|
|
32
|
+
children?: ReactNode;
|
|
25
33
|
}
|
|
26
34
|
/**
|
|
27
|
-
* NeoIconButton - Icon-only button component
|
|
35
|
+
* NeoIconButton - Icon-only button component
|
|
28
36
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
37
|
+
* For hierarchy variants (primary/secondary/destructive/tertiary), wraps NeoButton with
|
|
38
|
+
* icon-only sizing. For the `nav` variant, uses a standalone MUI IconButton with custom styling.
|
|
31
39
|
*
|
|
32
|
-
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=
|
|
40
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4086-7590
|
|
33
41
|
*
|
|
34
42
|
* Figma Props Mapping:
|
|
43
|
+
* - Hierarchy (Primary|Secondary|Destructive|Tertiary) → variant prop
|
|
35
44
|
* - Size (Small|Medium) → size prop
|
|
45
|
+
* - Show text = false → always (this is the icon-only variant of NeoButton)
|
|
36
46
|
* - State=Disabled → disabled prop
|
|
47
|
+
* - State=Loading → loading prop
|
|
37
48
|
* - State=Hover → CSS :hover
|
|
38
|
-
* - State=
|
|
49
|
+
* - State=Pressed → CSS :active
|
|
39
50
|
* - State=Focus → CSS :focus-visible
|
|
40
|
-
* - State=Loading → not yet implemented
|
|
41
51
|
*/
|
|
42
52
|
export declare const NeoIconButton: {
|
|
43
|
-
({ size, variant, active, ...props }: NeoIconButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
53
|
+
({ size, variant, active, loading, children, ...props }: NeoIconButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
44
54
|
displayName: string;
|
|
45
55
|
};
|
|
46
56
|
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React$1 from 'react';
|
|
3
3
|
import React__default, { ReactNode, ElementType, HTMLAttributes, ComponentType, ComponentPropsWithoutRef } from 'react';
|
|
4
|
-
import { GridDensity, GridFilterPanel } from '@mui/x-data-grid';
|
|
4
|
+
import { GridDensity, GridFilterPanel, ToolbarProps } from '@mui/x-data-grid';
|
|
5
5
|
import Chip, { ChipProps } from '@mui/material/Chip';
|
|
6
6
|
import { AlertProps } from '@mui/material/Alert';
|
|
7
7
|
import { LinkProps } from '@mui/material/Link';
|
|
@@ -11,14 +11,13 @@ import * as _mui_material_ToggleButton from '@mui/material/ToggleButton';
|
|
|
11
11
|
import { ToggleButtonProps } from '@mui/material/ToggleButton';
|
|
12
12
|
import { ToggleButtonGroupProps } from '@mui/material/ToggleButtonGroup';
|
|
13
13
|
import { CheckboxProps } from '@mui/material/Checkbox';
|
|
14
|
-
import { GridDensity as GridDensity$1, DataGridProProps, GridSlots,
|
|
14
|
+
import { GridDensity as GridDensity$1, DataGridProProps, GridSlots, GridColumnsPanelProps } from '@mui/x-data-grid-pro';
|
|
15
15
|
import * as _mui_material_styles from '@mui/material/styles';
|
|
16
16
|
import { SxProps, Theme, Breakpoint } from '@mui/material/styles';
|
|
17
17
|
import { DividerProps } from '@mui/material/Divider';
|
|
18
18
|
import { PaperProps } from '@mui/material/Paper';
|
|
19
19
|
import { BadgeProps } from '@mui/material/Badge';
|
|
20
20
|
import { AvatarProps } from '@mui/material/Avatar';
|
|
21
|
-
import { IconButtonProps } from '@mui/material/IconButton';
|
|
22
21
|
import { InputBaseProps } from '@mui/material/InputBase';
|
|
23
22
|
import { MenuProps } from '@mui/material/Menu';
|
|
24
23
|
import { MenuItemProps } from '@mui/material/MenuItem';
|
|
@@ -1421,8 +1420,8 @@ declare const NeoGeneralAvatar: {
|
|
|
1421
1420
|
};
|
|
1422
1421
|
|
|
1423
1422
|
type IconButtonSize = 'small' | 'medium';
|
|
1424
|
-
type IconButtonVariant = '
|
|
1425
|
-
interface NeoIconButtonProps extends Omit<
|
|
1423
|
+
type IconButtonVariant = 'primary' | 'secondary' | 'destructive' | 'tertiary' | 'nav';
|
|
1424
|
+
interface NeoIconButtonProps extends Omit<ButtonBaseProps, 'children' | 'size'> {
|
|
1426
1425
|
/**
|
|
1427
1426
|
* The size of the icon button
|
|
1428
1427
|
* @default "medium"
|
|
@@ -1431,10 +1430,10 @@ interface NeoIconButtonProps extends Omit<IconButtonProps, 'color' | 'size'> {
|
|
|
1431
1430
|
*/
|
|
1432
1431
|
size?: IconButtonSize;
|
|
1433
1432
|
/**
|
|
1434
|
-
* The visual variant of the icon button
|
|
1435
|
-
* - `
|
|
1433
|
+
* The visual variant of the icon button.
|
|
1434
|
+
* - `primary`, `secondary`, `destructive`, `tertiary`: Uses NeoButton's hierarchy styling
|
|
1436
1435
|
* - `nav`: White background with border, used in global navigation
|
|
1437
|
-
* @default "
|
|
1436
|
+
* @default "tertiary"
|
|
1438
1437
|
*/
|
|
1439
1438
|
variant?: IconButtonVariant;
|
|
1440
1439
|
/**
|
|
@@ -1443,25 +1442,34 @@ interface NeoIconButtonProps extends Omit<IconButtonProps, 'color' | 'size'> {
|
|
|
1443
1442
|
* @default false
|
|
1444
1443
|
*/
|
|
1445
1444
|
active?: boolean;
|
|
1445
|
+
/**
|
|
1446
|
+
* Show loading spinner instead of icon.
|
|
1447
|
+
* Only applies to hierarchy variants (not `nav`).
|
|
1448
|
+
* @default false
|
|
1449
|
+
*/
|
|
1450
|
+
loading?: boolean;
|
|
1451
|
+
children?: ReactNode;
|
|
1446
1452
|
}
|
|
1447
1453
|
/**
|
|
1448
|
-
* NeoIconButton - Icon-only button component
|
|
1454
|
+
* NeoIconButton - Icon-only button component
|
|
1449
1455
|
*
|
|
1450
|
-
*
|
|
1451
|
-
*
|
|
1456
|
+
* For hierarchy variants (primary/secondary/destructive/tertiary), wraps NeoButton with
|
|
1457
|
+
* icon-only sizing. For the `nav` variant, uses a standalone MUI IconButton with custom styling.
|
|
1452
1458
|
*
|
|
1453
|
-
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=
|
|
1459
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4086-7590
|
|
1454
1460
|
*
|
|
1455
1461
|
* Figma Props Mapping:
|
|
1462
|
+
* - Hierarchy (Primary|Secondary|Destructive|Tertiary) → variant prop
|
|
1456
1463
|
* - Size (Small|Medium) → size prop
|
|
1464
|
+
* - Show text = false → always (this is the icon-only variant of NeoButton)
|
|
1457
1465
|
* - State=Disabled → disabled prop
|
|
1466
|
+
* - State=Loading → loading prop
|
|
1458
1467
|
* - State=Hover → CSS :hover
|
|
1459
|
-
* - State=
|
|
1468
|
+
* - State=Pressed → CSS :active
|
|
1460
1469
|
* - State=Focus → CSS :focus-visible
|
|
1461
|
-
* - State=Loading → not yet implemented
|
|
1462
1470
|
*/
|
|
1463
1471
|
declare const NeoIconButton: {
|
|
1464
|
-
({ size, variant, active, ...props }: NeoIconButtonProps): react_jsx_runtime.JSX.Element;
|
|
1472
|
+
({ size, variant, active, loading, children, ...props }: NeoIconButtonProps): react_jsx_runtime.JSX.Element;
|
|
1465
1473
|
displayName: string;
|
|
1466
1474
|
};
|
|
1467
1475
|
|
|
@@ -2771,7 +2779,7 @@ interface NeoDataGridColumnsPanelProps extends GridColumnsPanelProps {
|
|
|
2771
2779
|
showSearch?: boolean;
|
|
2772
2780
|
}
|
|
2773
2781
|
declare const NeoDataGridColumnsPanel: {
|
|
2774
|
-
({ showSearch, ...props }: NeoDataGridColumnsPanelProps): react_jsx_runtime.JSX.Element;
|
|
2782
|
+
({ showSearch, sx: _sx, theme: _theme, ...props }: NeoDataGridColumnsPanelProps): react_jsx_runtime.JSX.Element;
|
|
2775
2783
|
displayName: string;
|
|
2776
2784
|
};
|
|
2777
2785
|
|
package/dist/index.esm.js
CHANGED
|
@@ -16,7 +16,8 @@ import MuiToggleButton, { toggleButtonClasses } from '@mui/material/ToggleButton
|
|
|
16
16
|
import MuiToggleButtonGroup, { toggleButtonGroupClasses } from '@mui/material/ToggleButtonGroup';
|
|
17
17
|
import MuiCard from '@mui/material/Card';
|
|
18
18
|
import Checkbox, { checkboxClasses } from '@mui/material/Checkbox';
|
|
19
|
-
import { useGridApiContext, useGridSelector, gridColumnDefinitionsSelector, gridColumnVisibilityModelSelector,
|
|
19
|
+
import { useGridApiContext, useGridSelector, gridColumnDefinitionsSelector, gridColumnVisibilityModelSelector, GridFilterPanel, gridClasses, ColumnsPanelTrigger, ToolbarButton, gridFilterModelSelector, FilterPanelTrigger, gridPaginationModelSelector, gridRowCountSelector, gridRowSelectionCountSelector, QuickFilter, QuickFilterControl, QuickFilterClear, Toolbar } from '@mui/x-data-grid';
|
|
20
|
+
import { useGridApiRef, DataGridPro } from '@mui/x-data-grid-pro';
|
|
20
21
|
import Button, { buttonClasses } from '@mui/material/Button';
|
|
21
22
|
import Divider from '@mui/material/Divider';
|
|
22
23
|
import InputAdornment, { inputAdornmentClasses } from '@mui/material/InputAdornment';
|
|
@@ -25,7 +26,6 @@ import TextField from '@mui/material/TextField';
|
|
|
25
26
|
import { formLabelClasses } from '@mui/material/FormLabel';
|
|
26
27
|
import InputLabel, { inputLabelClasses } from '@mui/material/InputLabel';
|
|
27
28
|
import MuiSelect, { selectClasses } from '@mui/material/Select';
|
|
28
|
-
import { GridFilterPanel, gridClasses, useGridApiContext as useGridApiContext$1, useGridSelector as useGridSelector$1, gridPaginationModelSelector, gridRowCountSelector, gridRowSelectionCountSelector, QuickFilter, QuickFilterControl, QuickFilterClear } from '@mui/x-data-grid';
|
|
29
29
|
import MenuItem, { menuItemClasses } from '@mui/material/MenuItem';
|
|
30
30
|
import Tooltip, { tooltipClasses } from '@mui/material/Tooltip';
|
|
31
31
|
import { dayCalendarClasses } from '@mui/x-date-pickers/DateCalendar';
|
|
@@ -1084,7 +1084,7 @@ const LinkText = styled('span')(({ bannerType = 'outlined' }) => ({
|
|
|
1084
1084
|
textDecoration: 'underline',
|
|
1085
1085
|
},
|
|
1086
1086
|
}));
|
|
1087
|
-
const StyledIconButton
|
|
1087
|
+
const StyledIconButton = styled(IconButton)(({ closeIconColor }) => ({
|
|
1088
1088
|
padding: 0,
|
|
1089
1089
|
color: closeIconColor,
|
|
1090
1090
|
'&:hover': {
|
|
@@ -1101,7 +1101,7 @@ const NeoBanner = ({ intent = 'info', type = 'outlined', message, messagePositio
|
|
|
1101
1101
|
return null;
|
|
1102
1102
|
}
|
|
1103
1103
|
const closeIconColor = type === 'filled' ? semanticColors.surfaces.white : intentColors$1[intent].default;
|
|
1104
|
-
return (jsx(StyledAlert$1, { ...props, intent: intent, bannerType: type, messagePosition: messagePosition, icon: messagePosition === 'left' ? icon || false : false, action: showClose ? (jsx(StyledIconButton
|
|
1104
|
+
return (jsx(StyledAlert$1, { ...props, intent: intent, bannerType: type, messagePosition: messagePosition, icon: messagePosition === 'left' ? icon || false : false, action: showClose ? (jsx(StyledIconButton, { size: "small", onClick: handleClose, closeIconColor: closeIconColor, children: jsx(X, { size: 24 }) })) : undefined, children: messagePosition === 'center' ? (jsxs(Fragment, { children: [icon, jsx("span", { children: message }), linkText && (jsx(LinkText, { bannerType: type, onClick: onLinkClick, children: linkText }))] })) : (jsxs(Fragment, { children: [jsx("span", { children: message }), linkText && (jsx(LinkText, { bannerType: type, onClick: onLinkClick, children: linkText }))] })) }));
|
|
1105
1105
|
};
|
|
1106
1106
|
NeoBanner.displayName = 'NeoBanner';
|
|
1107
1107
|
|
|
@@ -1171,7 +1171,7 @@ function NeoBreadcrumbs({ children, className }) {
|
|
|
1171
1171
|
}
|
|
1172
1172
|
|
|
1173
1173
|
// Props that should not be forwarded to ButtonBase (Button-specific props that ButtonBase doesn't support)
|
|
1174
|
-
const buttonOnlyProps
|
|
1174
|
+
const buttonOnlyProps = [
|
|
1175
1175
|
'variant',
|
|
1176
1176
|
'size',
|
|
1177
1177
|
'loading',
|
|
@@ -1181,7 +1181,7 @@ const buttonOnlyProps$1 = [
|
|
|
1181
1181
|
'disableElevation',
|
|
1182
1182
|
];
|
|
1183
1183
|
const StyledButtonBase$1 = styled(ButtonBase, {
|
|
1184
|
-
shouldForwardProp: prop => !buttonOnlyProps
|
|
1184
|
+
shouldForwardProp: prop => !buttonOnlyProps.includes(prop),
|
|
1185
1185
|
})(({ theme, variant = 'primary', size = 'medium', loading = false }) => {
|
|
1186
1186
|
// Size configurations using theme.spacing()
|
|
1187
1187
|
const sizeConfig = {
|
|
@@ -2008,6 +2008,13 @@ const NeoCodeSnippet = ({ variant = 'outlined', size = 'small', endIcon, childre
|
|
|
2008
2008
|
};
|
|
2009
2009
|
NeoCodeSnippet.displayName = 'NeoCodeSnippet';
|
|
2010
2010
|
|
|
2011
|
+
// PanelWrapper was removed from @mui/x-data-grid-pro public API in v8.28.2
|
|
2012
|
+
const PanelWrapper = styled('div')({
|
|
2013
|
+
display: 'flex',
|
|
2014
|
+
flexDirection: 'column',
|
|
2015
|
+
flex: 1,
|
|
2016
|
+
'&:focus': { outline: 0 },
|
|
2017
|
+
});
|
|
2011
2018
|
const PanelContent = styled(Box)(({ theme }) => ({
|
|
2012
2019
|
display: 'flex',
|
|
2013
2020
|
flexDirection: 'column',
|
|
@@ -2114,7 +2121,10 @@ const ResetButton = styled(Button)(({ theme }) => ({
|
|
|
2114
2121
|
color: colors.grey['400'],
|
|
2115
2122
|
},
|
|
2116
2123
|
}));
|
|
2117
|
-
const NeoDataGridColumnsPanel = ({ showSearch = false,
|
|
2124
|
+
const NeoDataGridColumnsPanel = ({ showSearch = false,
|
|
2125
|
+
// Strip MUI-specific props to avoid dual-module Theme type conflict between
|
|
2126
|
+
// @mui/x-data-grid-pro (CJS) and @mui/x-data-grid (ESM) declarations
|
|
2127
|
+
sx: _sx, theme: _theme, ...props }) => {
|
|
2118
2128
|
const apiRef = useGridApiContext();
|
|
2119
2129
|
const columns = useGridSelector(apiRef, gridColumnDefinitionsSelector);
|
|
2120
2130
|
const columnVisibilityModel = useGridSelector(apiRef, gridColumnVisibilityModelSelector);
|
|
@@ -2149,7 +2159,7 @@ const NeoDataGridColumnsPanel = ({ showSearch = false, ...props }) => {
|
|
|
2149
2159
|
};
|
|
2150
2160
|
// Check if current state differs from initial/default state
|
|
2151
2161
|
const hasChanges = Object.keys(columnVisibilityModel).length > 0;
|
|
2152
|
-
return (jsx(
|
|
2162
|
+
return (jsx(PanelWrapper, { ...props, children: jsxs(PanelContent, { sx: { width: 320 }, children: [showSearch && (jsx(StyledSearchField, { placeholder: "Search", variant: "standard", value: searchText, onChange: e => setSearchText(e.target.value), slotProps: {
|
|
2153
2163
|
input: {
|
|
2154
2164
|
startAdornment: (jsx(InputAdornment, { position: "start", children: jsx(Search, {}) })),
|
|
2155
2165
|
disableUnderline: true,
|
|
@@ -2710,17 +2720,17 @@ function NeoDataGrid({ autoHeight = false, toolbar, slots, sx, density = 'standa
|
|
|
2710
2720
|
// Fix for MUI X 8.15.0+ scroll shadow issue - backgroundColor must be on main, not root
|
|
2711
2721
|
// See: https://github.com/mui/mui-x/issues/20107
|
|
2712
2722
|
// This must be set to prevent scroll shadow artifacts
|
|
2713
|
-
[`& .${gridClasses
|
|
2723
|
+
[`& .${gridClasses.main}`]: {
|
|
2714
2724
|
backgroundColor: semanticColors.surfaces.white,
|
|
2715
2725
|
},
|
|
2716
2726
|
// White background for empty/loading overlays
|
|
2717
|
-
[`& .${gridClasses
|
|
2727
|
+
[`& .${gridClasses.overlay}`]: {
|
|
2718
2728
|
backgroundColor: semanticColors.surfaces.white,
|
|
2719
2729
|
},
|
|
2720
2730
|
...getDataGridHeaderStyles(),
|
|
2721
2731
|
border: `1px solid ${semanticColors.border.secondary}`,
|
|
2722
2732
|
// Style row selection checkboxes to match header (16px, proper spacing)
|
|
2723
|
-
[`& .${gridClasses
|
|
2733
|
+
[`& .${gridClasses.cellCheckbox}`]: {
|
|
2724
2734
|
[`& .${checkboxClasses.root}`]: {
|
|
2725
2735
|
padding: `${spacing.spacing_1}px`,
|
|
2726
2736
|
[`& .${svgIconClasses.root}`]: {
|
|
@@ -2730,7 +2740,7 @@ function NeoDataGrid({ autoHeight = false, toolbar, slots, sx, density = 'standa
|
|
|
2730
2740
|
},
|
|
2731
2741
|
},
|
|
2732
2742
|
// Ensure cells are vertically centered
|
|
2733
|
-
[`& .${gridClasses
|
|
2743
|
+
[`& .${gridClasses.cell}`]: {
|
|
2734
2744
|
minHeight: density === 'compact' ? 36 : density === 'comfortable' ? 52 : 44,
|
|
2735
2745
|
paddingLeft: `${spacing.spacing_3}px`,
|
|
2736
2746
|
paddingRight: `${spacing.spacing_3}px`,
|
|
@@ -3404,20 +3414,24 @@ function subMonths(date, amount, options) {
|
|
|
3404
3414
|
return addMonths(date, -1);
|
|
3405
3415
|
}
|
|
3406
3416
|
|
|
3407
|
-
//
|
|
3408
|
-
const
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
'
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
})
|
|
3420
|
-
|
|
3417
|
+
// Cast NeoButton to a simpler type for styled() compatibility (avoids generic inference issues)
|
|
3418
|
+
const NeoButtonBase = NeoButton;
|
|
3419
|
+
// Icon-only wrapper around NeoButton for hierarchy variants
|
|
3420
|
+
const StyledIconOnlyButton = styled(NeoButtonBase)(({ size = 'medium' }) => {
|
|
3421
|
+
const dimension = size === 'small' ? 32 : spacing.spacing_5;
|
|
3422
|
+
return {
|
|
3423
|
+
'&&': {
|
|
3424
|
+
minWidth: 'unset',
|
|
3425
|
+
padding: 0,
|
|
3426
|
+
width: dimension,
|
|
3427
|
+
},
|
|
3428
|
+
};
|
|
3429
|
+
});
|
|
3430
|
+
// Nav variant - standalone styled MUI IconButton (not backed by Figma)
|
|
3431
|
+
const navOnlyProps = ['size', 'variant', 'active'];
|
|
3432
|
+
const StyledNavButton = styled(IconButton, {
|
|
3433
|
+
shouldForwardProp: prop => !navOnlyProps.includes(prop),
|
|
3434
|
+
})(({ theme, size = 'medium', active = false }) => {
|
|
3421
3435
|
const sizeConfig = {
|
|
3422
3436
|
small: {
|
|
3423
3437
|
width: 32,
|
|
@@ -3431,50 +3445,24 @@ const StyledIconButton = styled(IconButton, {
|
|
|
3431
3445
|
},
|
|
3432
3446
|
};
|
|
3433
3447
|
const sizeStyles = sizeConfig[size];
|
|
3434
|
-
|
|
3435
|
-
|
|
3448
|
+
const activeNavStyles = {
|
|
3449
|
+
backgroundColor: semanticColors.icons.pressedBackground,
|
|
3450
|
+
borderColor: 'transparent',
|
|
3451
|
+
color: semanticColors.buttons.primary.pressed,
|
|
3452
|
+
};
|
|
3453
|
+
return {
|
|
3436
3454
|
width: sizeStyles.width,
|
|
3437
3455
|
height: sizeStyles.height,
|
|
3438
3456
|
padding: sizeStyles.padding,
|
|
3439
|
-
borderRadius: borderRadius.button,
|
|
3457
|
+
borderRadius: borderRadius.button,
|
|
3440
3458
|
transition: theme.transitions.create(['background-color', 'border-color', 'color'], {
|
|
3441
3459
|
duration: theme.transitions.duration.short,
|
|
3442
3460
|
}),
|
|
3443
|
-
// Disabled state
|
|
3444
|
-
[`&.${iconButtonClasses.disabled}`]: {
|
|
3445
|
-
cursor: 'not-allowed',
|
|
3446
|
-
pointerEvents: 'auto',
|
|
3447
|
-
},
|
|
3448
|
-
// Focus visible for keyboard navigation
|
|
3449
3461
|
'&:focus-visible': {
|
|
3450
3462
|
outline: `2px solid ${semanticColors.border.focus}`,
|
|
3451
3463
|
outlineOffset: 2,
|
|
3452
3464
|
},
|
|
3453
|
-
|
|
3454
|
-
// Default variant - transparent neutral style
|
|
3455
|
-
const defaultStyles = {
|
|
3456
|
-
backgroundColor: 'transparent',
|
|
3457
|
-
color: semanticColors.icons.default,
|
|
3458
|
-
border: 'none',
|
|
3459
|
-
'&:hover': {
|
|
3460
|
-
backgroundColor: semanticColors.icons.hoverBackground,
|
|
3461
|
-
color: semanticColors.icons.hover,
|
|
3462
|
-
},
|
|
3463
|
-
'&:active': {
|
|
3464
|
-
color: semanticColors.icons.pressed,
|
|
3465
|
-
},
|
|
3466
|
-
[`&.${iconButtonClasses.disabled}`]: {
|
|
3467
|
-
backgroundColor: 'transparent',
|
|
3468
|
-
color: semanticColors.icons.disabled,
|
|
3469
|
-
},
|
|
3470
|
-
};
|
|
3471
|
-
// Nav variant - 44px pill with border, used in global navigation
|
|
3472
|
-
const activeNavStyles = {
|
|
3473
|
-
backgroundColor: semanticColors.icons.pressedBackground,
|
|
3474
|
-
borderColor: 'transparent',
|
|
3475
|
-
color: semanticColors.buttons.primary.pressed,
|
|
3476
|
-
};
|
|
3477
|
-
const navStyles = {
|
|
3465
|
+
// Nav styles
|
|
3478
3466
|
backgroundColor: semanticColors.surfaces.white,
|
|
3479
3467
|
color: semanticColors.icons.default,
|
|
3480
3468
|
border: `1px solid ${semanticColors.border.secondary}`,
|
|
@@ -3485,6 +3473,8 @@ const StyledIconButton = styled(IconButton, {
|
|
|
3485
3473
|
},
|
|
3486
3474
|
'&:active': activeNavStyles,
|
|
3487
3475
|
[`&.${iconButtonClasses.disabled}`]: {
|
|
3476
|
+
cursor: 'not-allowed',
|
|
3477
|
+
pointerEvents: 'auto',
|
|
3488
3478
|
backgroundColor: semanticColors.surfaces.white,
|
|
3489
3479
|
borderColor: semanticColors.border.secondary,
|
|
3490
3480
|
color: semanticColors.icons.disabled,
|
|
@@ -3492,33 +3482,30 @@ const StyledIconButton = styled(IconButton, {
|
|
|
3492
3482
|
},
|
|
3493
3483
|
...(active ? activeNavStyles : {}),
|
|
3494
3484
|
};
|
|
3495
|
-
const variantStyles = {
|
|
3496
|
-
default: defaultStyles,
|
|
3497
|
-
nav: navStyles,
|
|
3498
|
-
};
|
|
3499
|
-
return {
|
|
3500
|
-
...baseStyles,
|
|
3501
|
-
...variantStyles[variant],
|
|
3502
|
-
};
|
|
3503
3485
|
});
|
|
3504
3486
|
/**
|
|
3505
|
-
* NeoIconButton - Icon-only button component
|
|
3487
|
+
* NeoIconButton - Icon-only button component
|
|
3506
3488
|
*
|
|
3507
|
-
*
|
|
3508
|
-
*
|
|
3489
|
+
* For hierarchy variants (primary/secondary/destructive/tertiary), wraps NeoButton with
|
|
3490
|
+
* icon-only sizing. For the `nav` variant, uses a standalone MUI IconButton with custom styling.
|
|
3509
3491
|
*
|
|
3510
|
-
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=
|
|
3492
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4086-7590
|
|
3511
3493
|
*
|
|
3512
3494
|
* Figma Props Mapping:
|
|
3495
|
+
* - Hierarchy (Primary|Secondary|Destructive|Tertiary) → variant prop
|
|
3513
3496
|
* - Size (Small|Medium) → size prop
|
|
3497
|
+
* - Show text = false → always (this is the icon-only variant of NeoButton)
|
|
3514
3498
|
* - State=Disabled → disabled prop
|
|
3499
|
+
* - State=Loading → loading prop
|
|
3515
3500
|
* - State=Hover → CSS :hover
|
|
3516
|
-
* - State=
|
|
3501
|
+
* - State=Pressed → CSS :active
|
|
3517
3502
|
* - State=Focus → CSS :focus-visible
|
|
3518
|
-
* - State=Loading → not yet implemented
|
|
3519
3503
|
*/
|
|
3520
|
-
const NeoIconButton = ({ size = 'medium', variant = '
|
|
3521
|
-
|
|
3504
|
+
const NeoIconButton = ({ size = 'medium', variant = 'tertiary', active = false, loading, children, ...props }) => {
|
|
3505
|
+
if (variant === 'nav') {
|
|
3506
|
+
return (jsx(StyledNavButton, { size: size, active: active, disableRipple: true, ...props, children: children }));
|
|
3507
|
+
}
|
|
3508
|
+
return (jsx(StyledIconOnlyButton, { variant: variant, size: size, loading: loading, ...props, children: children }));
|
|
3522
3509
|
};
|
|
3523
3510
|
NeoIconButton.displayName = 'NeoIconButton';
|
|
3524
3511
|
|
|
@@ -4207,11 +4194,11 @@ const PaginationText = styled('p')(({ theme }) => ({
|
|
|
4207
4194
|
* />
|
|
4208
4195
|
*/
|
|
4209
4196
|
const NeoFooter = ({ variant = 'pagination', showShadow = false, loading = false, resultCount, onLoadMore, hasMore = true, paginationInfo, onPreviousPage, onNextPage, hasPreviousPage, hasNextPage, showSelected = true, children, }) => {
|
|
4210
|
-
const apiRef = useGridApiContext
|
|
4197
|
+
const apiRef = useGridApiContext();
|
|
4211
4198
|
// Use selectors to reactively subscribe to pagination state changes
|
|
4212
|
-
const paginationModel = useGridSelector
|
|
4213
|
-
const rowCount = useGridSelector
|
|
4214
|
-
const selectedCount = useGridSelector
|
|
4199
|
+
const paginationModel = useGridSelector(apiRef, gridPaginationModelSelector);
|
|
4200
|
+
const rowCount = useGridSelector(apiRef, gridRowCountSelector);
|
|
4201
|
+
const selectedCount = useGridSelector(apiRef, gridRowSelectionCountSelector);
|
|
4215
4202
|
// For pagination variant, try to derive info from DataGrid if not provided
|
|
4216
4203
|
const derivePaginationInfo = () => {
|
|
4217
4204
|
if (paginationInfo) {
|
|
@@ -4347,7 +4334,7 @@ function NeoInfiniteScrollGrid({ onLoadMore, hasNextPage = true, loadMoreAtScrol
|
|
|
4347
4334
|
}
|
|
4348
4335
|
const unsubscribe = apiRef.current?.subscribeEvent?.('scrollPositionChange', (e) => {
|
|
4349
4336
|
if (!scrollerRef.current) {
|
|
4350
|
-
const elem = document.querySelector(`.${gridClasses
|
|
4337
|
+
const elem = document.querySelector(`.${gridClasses.virtualScroller}`);
|
|
4351
4338
|
if (elem) {
|
|
4352
4339
|
scrollerRef.current = elem;
|
|
4353
4340
|
}
|
|
@@ -4401,7 +4388,7 @@ function NeoInfiniteScrollGrid({ onLoadMore, hasNextPage = true, loadMoreAtScrol
|
|
|
4401
4388
|
},
|
|
4402
4389
|
}, sx: {
|
|
4403
4390
|
// Add border at bottom of rows section (above footer)
|
|
4404
|
-
[`& .${gridClasses
|
|
4391
|
+
[`& .${gridClasses.virtualScrollerContent}`]: {
|
|
4405
4392
|
borderBottom: `1px solid ${semanticColors.border.primary}`,
|
|
4406
4393
|
},
|
|
4407
4394
|
...userSx,
|
|
@@ -4564,7 +4551,7 @@ const StyledFormHelperText = styled(FormHelperText, {
|
|
|
4564
4551
|
const NeoInputField = ({ size = 'medium', destructive = false, label, required = false, infoIcon, helperText, errorMessage, startIcon, endIcon, disabled, id, ...props }) => {
|
|
4565
4552
|
const inputId = id || `neo-input-${Math.random().toString(36).substring(7)}`;
|
|
4566
4553
|
const helperTextId = helperText || errorMessage ? `${inputId}-helper-text` : undefined;
|
|
4567
|
-
return (jsxs(StyledFormControl, { size: size, error: destructive, disabled: disabled, children: [label && (jsxs(StyledInputLabel, { htmlFor: inputId, size: size, infoIcon: !!infoIcon, disabled: disabled, error: destructive, children: [label, required && jsx("span", { "aria-hidden": "true", children: "*" }), infoIcon && jsx(InfoIconWrapper, { children: infoIcon })] })), jsx(StyledInputBase, { id: inputId, size: size, destructive: destructive, disabled: disabled, error: destructive, "aria-describedby": helperTextId, startAdornment: startIcon ? (jsx(InputAdornment, { position: "start", style: { paddingLeft: size === 'small' ? spacing.spacing_1_1_2 : spacing.spacing_2 }, children: startIcon })) : undefined, endAdornment: destructive ? (jsx(InputAdornment, { position: "end", style: { paddingRight: spacing.spacing_1_1_2 }, children: jsx(CircleAlert, { size: 20 }) })) : endIcon ? (jsx(InputAdornment, { position: "end", style: { paddingRight: spacing.spacing_1_1_2 }, children: endIcon })) : undefined, ...props }), (helperText || errorMessage) && (jsx(StyledFormHelperText, { id: helperTextId, error: destructive, disabled: disabled, children: destructive ? errorMessage : helperText }))] }));
|
|
4554
|
+
return (jsxs(StyledFormControl, { size: size, error: destructive, disabled: disabled, children: [label && (jsxs(StyledInputLabel, { htmlFor: inputId, size: size, infoIcon: !!infoIcon, disabled: disabled, error: destructive, shrink: true, children: [label, required && jsx("span", { "aria-hidden": "true", children: "*" }), infoIcon && jsx(InfoIconWrapper, { children: infoIcon })] })), jsx(StyledInputBase, { id: inputId, size: size, destructive: destructive, disabled: disabled, error: destructive, "aria-describedby": helperTextId, startAdornment: startIcon ? (jsx(InputAdornment, { position: "start", style: { paddingLeft: size === 'small' ? spacing.spacing_1_1_2 : spacing.spacing_2 }, children: startIcon })) : undefined, endAdornment: destructive ? (jsx(InputAdornment, { position: "end", style: { paddingRight: spacing.spacing_1_1_2 }, children: jsx(CircleAlert, { size: 20 }) })) : endIcon ? (jsx(InputAdornment, { position: "end", style: { paddingRight: spacing.spacing_1_1_2 }, children: endIcon })) : undefined, ...props }), (helperText || errorMessage) && (jsx(StyledFormHelperText, { id: helperTextId, error: destructive, disabled: disabled, children: destructive ? errorMessage : helperText }))] }));
|
|
4568
4555
|
};
|
|
4569
4556
|
NeoInputField.displayName = 'NeoInputField';
|
|
4570
4557
|
|