@moderneinc/neo-styled-components 5.0.0-next.bd2a49 → 5.0.0-next.cd1d8d
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/Alert/Alert.d.ts +15 -1
- package/dist/Badge/Badge.d.ts +16 -2
- package/dist/Breadcrumbs/Breadcrumbs.d.ts +0 -10
- package/dist/CanceledIcon/CanceledIcon.d.ts +11 -0
- package/dist/Checkbox/Checkbox.d.ts +5 -4
- package/dist/DataGrid/DataGrid.d.ts +1 -1
- package/dist/DataGrid/DataGrid.styles.d.ts +3 -0
- package/dist/DataGridCell/DataGridCell.d.ts +0 -16
- package/dist/DataGridHeaderCell/DataGridHeaderCell.d.ts +0 -37
- package/dist/DatePickerListItem/DatePickerListItem.d.ts +2 -22
- package/dist/DatePickerMenu/DatePickerMenu.d.ts +2 -22
- package/dist/Dot/Dot.d.ts +11 -4
- package/dist/FilledStatusIcons/FilledStatusIcons.d.ts +41 -0
- package/dist/GeneralAvatar/GeneralAvatar.d.ts +1 -7
- package/dist/InputField/InputField.d.ts +12 -1
- package/dist/ListItemButton/ListItemButton.d.ts +12 -1
- package/dist/MenuItem/MenuItem.d.ts +31 -9
- package/dist/NavigationAvatar/NavigationAvatar.d.ts +3 -3
- package/dist/NavigationItem/NavigationItem.d.ts +21 -2
- package/dist/NeoActionsCell/NeoActionsCell.d.ts +9 -0
- package/dist/NeoAvatarCell/NeoAvatarCell.d.ts +25 -0
- package/dist/NeoIconCell/NeoIconCell.d.ts +14 -0
- package/dist/NeoLogoCell/NeoLogoCell.d.ts +24 -0
- package/dist/NeoProgressCell/NeoProgressCell.d.ts +21 -0
- package/dist/NeoStatusCell/NeoStatusCell.d.ts +30 -0
- package/dist/PageContent/PageContent.d.ts +12 -1
- package/dist/RadioButtonWithText/RadioButtonWithText.d.ts +2 -22
- package/dist/RipplingDot/RipplingDot.d.ts +12 -0
- package/dist/SelectField/SelectField.d.ts +64 -0
- package/dist/SideNav/NeoSideNavContext.d.ts +5 -0
- package/dist/SideNav/SideNav.d.ts +18 -25
- package/dist/TabPanel/TabPanel.d.ts +47 -0
- package/dist/Table/Table.d.ts +64 -0
- package/dist/Tabs/Tabs.d.ts +1 -1
- package/dist/Tag/Tag.d.ts +1 -2
- package/dist/ToggleButton/ToggleButton.d.ts +13 -18
- package/dist/ToggleButtonGroup/ToggleButtonGroup.d.ts +26 -0
- package/dist/ToggleButtonWithText/ToggleButtonWithText.d.ts +2 -22
- package/dist/Tooltip/Tooltip.d.ts +8 -5
- package/dist/TopNav/TopNav.d.ts +2 -22
- package/dist/TourModal/TourModal.d.ts +2 -22
- package/dist/TypologyControl/TypologyControl.d.ts +1 -1
- package/dist/VibratingDot/VibratingDot.d.ts +12 -0
- package/dist/index.d.ts +660 -143
- package/dist/index.esm.js +1376 -609
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1400 -604
- package/dist/index.js.map +1 -1
- package/dist/utils/colorHelpers.d.ts +6 -0
- package/package.json +5 -5
- package/dist/utils/avatarColors.d.ts +0 -7
package/dist/index.esm.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { semanticColors, spacing, typography, borderRadius, colors,
|
|
2
|
+
import { semanticColors, spacing, typography, borderRadius, shadows, colors, semanticTypography } from '@moderneinc/neo-design';
|
|
3
3
|
import Box from '@mui/material/Box';
|
|
4
4
|
import { styled, alpha } from '@mui/material/styles';
|
|
5
5
|
import Chip, { chipClasses } from '@mui/material/Chip';
|
|
6
6
|
import MuiAvatar from '@mui/material/Avatar';
|
|
7
|
-
import SvgIcon
|
|
7
|
+
import SvgIcon from '@mui/material/SvgIcon';
|
|
8
8
|
import Alert, { alertClasses } from '@mui/material/Alert';
|
|
9
9
|
import ButtonBase, { buttonBaseClasses } from '@mui/material/ButtonBase';
|
|
10
|
-
import React, { useContext, createContext, forwardRef, createElement, useState, useRef, useCallback, useMemo, useEffect } from 'react';
|
|
10
|
+
import React, { useContext, createContext, forwardRef, createElement, useState, useRef, useCallback, useMemo, useEffect, Children, isValidElement, cloneElement } from 'react';
|
|
11
11
|
import IconButton, { iconButtonClasses } from '@mui/material/IconButton';
|
|
12
12
|
import Breadcrumbs, { breadcrumbsClasses } from '@mui/material/Breadcrumbs';
|
|
13
13
|
import Link from '@mui/material/Link';
|
|
@@ -16,7 +16,7 @@ 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, GridFilterPanel, gridClasses, ColumnsPanelTrigger, ToolbarButton, gridFilterModelSelector, FilterPanelTrigger, gridPaginationModelSelector, gridRowCountSelector, gridRowSelectionCountSelector, QuickFilter, QuickFilterControl, QuickFilterClear, Toolbar } from '@mui/x-data-grid';
|
|
19
|
+
import { useGridApiContext, useGridSelector, gridColumnDefinitionsSelector, gridColumnVisibilityModelSelector, GridFilterPanel, gridClasses, ColumnsPanelTrigger, ToolbarButton, gridFilterModelSelector, FilterPanelTrigger, gridPaginationModelSelector, gridRowCountSelector, gridRowSelectionCountSelector, GridActionsCell, QuickFilter, QuickFilterControl, QuickFilterClear, Toolbar } from '@mui/x-data-grid';
|
|
20
20
|
import { useGridApiRef, DataGridPro } from '@mui/x-data-grid-pro';
|
|
21
21
|
import Button, { buttonClasses } from '@mui/material/Button';
|
|
22
22
|
import Divider from '@mui/material/Divider';
|
|
@@ -36,7 +36,6 @@ import { pickersCalendarHeaderClasses } from '@mui/x-date-pickers/PickersCalenda
|
|
|
36
36
|
import { PickersShortcuts } from '@mui/x-date-pickers/PickersShortcuts';
|
|
37
37
|
import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker';
|
|
38
38
|
import { dateRangePickerDayClasses } from '@mui/x-date-pickers-pro/DateRangePickerDay';
|
|
39
|
-
import Badge, { badgeClasses } from '@mui/material/Badge';
|
|
40
39
|
import LinearProgress, { linearProgressClasses } from '@mui/material/LinearProgress';
|
|
41
40
|
import Paper, { paperClasses } from '@mui/material/Paper';
|
|
42
41
|
import Stack from '@mui/material/Stack';
|
|
@@ -52,9 +51,16 @@ import Dialog, { dialogClasses } from '@mui/material/Dialog';
|
|
|
52
51
|
import DialogActions, { dialogActionsClasses } from '@mui/material/DialogActions';
|
|
53
52
|
import DialogContent, { dialogContentClasses } from '@mui/material/DialogContent';
|
|
54
53
|
import Fab from '@mui/material/Fab';
|
|
55
|
-
import Fade from '@mui/material/Fade';
|
|
54
|
+
import Fade$1 from '@mui/material/Fade';
|
|
56
55
|
import Radio, { radioClasses } from '@mui/material/Radio';
|
|
56
|
+
import { keyframes, Box as Box$1 } from '@mui/material';
|
|
57
57
|
import Skeleton from '@mui/material/Skeleton';
|
|
58
|
+
import MuiTable from '@mui/material/Table';
|
|
59
|
+
import TableBody from '@mui/material/TableBody';
|
|
60
|
+
import TableCell, { tableCellClasses } from '@mui/material/TableCell';
|
|
61
|
+
import TableContainer from '@mui/material/TableContainer';
|
|
62
|
+
import TableHead from '@mui/material/TableHead';
|
|
63
|
+
import TableRow from '@mui/material/TableRow';
|
|
58
64
|
import MuiTab, { tabClasses } from '@mui/material/Tab';
|
|
59
65
|
import MuiTabs, { tabsClasses } from '@mui/material/Tabs';
|
|
60
66
|
import Switch, { switchClasses } from '@mui/material/Switch';
|
|
@@ -62,8 +68,37 @@ import { useTreeItemModel } from '@mui/x-tree-view/hooks';
|
|
|
62
68
|
import { TreeItem, treeItemClasses } from '@mui/x-tree-view/TreeItem';
|
|
63
69
|
import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro';
|
|
64
70
|
|
|
65
|
-
const
|
|
66
|
-
|
|
71
|
+
const STATUS_COLOR_CLASSES = [
|
|
72
|
+
[chipClasses.colorDefault, semanticColors.status.neutral],
|
|
73
|
+
[chipClasses.colorError, semanticColors.status.error],
|
|
74
|
+
[chipClasses.colorWarning, semanticColors.status.warning],
|
|
75
|
+
[chipClasses.colorSuccess, semanticColors.status.success],
|
|
76
|
+
[chipClasses.colorInfo, semanticColors.status.info],
|
|
77
|
+
];
|
|
78
|
+
const outlinedColorOverrides = {
|
|
79
|
+
backgroundColor: 'transparent',
|
|
80
|
+
color: semanticColors.typography.bodySecondary,
|
|
81
|
+
border: `1px solid ${semanticColors.border.secondary}`,
|
|
82
|
+
[`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
|
|
83
|
+
color: semanticColors.typography.bodySecondary,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
const filledColorRules = Object.fromEntries(STATUS_COLOR_CLASSES.map(([className, palette]) => [
|
|
87
|
+
`&.${className}`,
|
|
88
|
+
{
|
|
89
|
+
backgroundColor: palette.light,
|
|
90
|
+
color: palette.dark,
|
|
91
|
+
border: `1px solid ${palette.transparent}`,
|
|
92
|
+
[`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
|
|
93
|
+
color: palette.dark,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
]));
|
|
97
|
+
const outlinedColorRules = Object.fromEntries(STATUS_COLOR_CLASSES.map(([className]) => [`&.${className}`, outlinedColorOverrides]));
|
|
98
|
+
const StyledChip$3 = styled(Chip, {
|
|
99
|
+
shouldForwardProp: prop => prop !== 'badgeSize' && prop !== 'badgeVariant',
|
|
100
|
+
})(({ theme, badgeSize, badgeVariant }) => ({
|
|
101
|
+
height: badgeSize === 'small' ? 20 : 24,
|
|
67
102
|
paddingTop: spacing.spacing_1_4,
|
|
68
103
|
paddingBottom: spacing.spacing_1_4,
|
|
69
104
|
paddingLeft: spacing.spacing_1,
|
|
@@ -91,51 +126,7 @@ const StyledChip$2 = styled(Chip)(({ theme }) => ({
|
|
|
91
126
|
width: 12,
|
|
92
127
|
height: 12,
|
|
93
128
|
},
|
|
94
|
-
|
|
95
|
-
[`&.${chipClasses.colorDefault}`]: {
|
|
96
|
-
backgroundColor: semanticColors.status.neutral.light,
|
|
97
|
-
color: semanticColors.status.neutral.dark,
|
|
98
|
-
border: `1px solid ${semanticColors.status.neutral.default}80`,
|
|
99
|
-
[`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
|
|
100
|
-
color: semanticColors.status.neutral.dark,
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
// Error state
|
|
104
|
-
[`&.${chipClasses.colorError}`]: {
|
|
105
|
-
backgroundColor: semanticColors.status.error.light,
|
|
106
|
-
color: semanticColors.status.error.dark,
|
|
107
|
-
border: `1px solid ${semanticColors.status.error.default}80`,
|
|
108
|
-
[`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
|
|
109
|
-
color: semanticColors.status.error.dark,
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
// Warning state
|
|
113
|
-
[`&.${chipClasses.colorWarning}`]: {
|
|
114
|
-
backgroundColor: semanticColors.status.warning.light,
|
|
115
|
-
color: semanticColors.status.warning.dark,
|
|
116
|
-
border: `1px solid ${semanticColors.status.warning.default}80`,
|
|
117
|
-
[`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
|
|
118
|
-
color: semanticColors.status.warning.dark,
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
// Success state
|
|
122
|
-
[`&.${chipClasses.colorSuccess}`]: {
|
|
123
|
-
backgroundColor: semanticColors.status.success.light,
|
|
124
|
-
color: semanticColors.status.success.dark,
|
|
125
|
-
border: `1px solid ${semanticColors.status.success.default}80`,
|
|
126
|
-
[`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
|
|
127
|
-
color: semanticColors.status.success.dark,
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
// Info state
|
|
131
|
-
[`&.${chipClasses.colorInfo}`]: {
|
|
132
|
-
backgroundColor: semanticColors.status.info.light,
|
|
133
|
-
color: semanticColors.status.info.dark,
|
|
134
|
-
border: `1px solid ${semanticColors.status.info.default}80`,
|
|
135
|
-
[`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
|
|
136
|
-
color: semanticColors.status.info.dark,
|
|
137
|
-
},
|
|
138
|
-
},
|
|
129
|
+
...(badgeVariant === 'outlined' ? outlinedColorRules : filledColorRules),
|
|
139
130
|
}));
|
|
140
131
|
/**
|
|
141
132
|
* NeoBadge - Status badge component based on MUI Chip
|
|
@@ -148,23 +139,26 @@ const StyledChip$2 = styled(Chip)(({ theme }) => ({
|
|
|
148
139
|
* - TrailingIcon → deleteIcon prop (pass React element)
|
|
149
140
|
* - Label → label prop
|
|
150
141
|
*/
|
|
151
|
-
const NeoBadge = (props) => {
|
|
152
|
-
return jsx(StyledChip$
|
|
142
|
+
const NeoBadge = ({ size = 'medium', variant = 'filled', ...props }) => {
|
|
143
|
+
return jsx(StyledChip$3, { ...props, badgeSize: size, badgeVariant: variant });
|
|
153
144
|
};
|
|
154
145
|
NeoBadge.displayName = 'NeoBadge';
|
|
155
146
|
|
|
147
|
+
const djb2Hash = (str) => {
|
|
148
|
+
let hash = 5381;
|
|
149
|
+
for (let i = 0; i < str.length; i++) {
|
|
150
|
+
hash = (hash * 33) ^ str.charCodeAt(i);
|
|
151
|
+
}
|
|
152
|
+
return hash >>> 0;
|
|
153
|
+
};
|
|
156
154
|
/**
|
|
157
|
-
*
|
|
158
|
-
*
|
|
155
|
+
* Deterministically derives an HSL background color from a string seed.
|
|
156
|
+
* Produces pastel colors matching the aesthetic of the status.avatar.initials
|
|
157
|
+
* semantic tokens (fixed 80% saturation, 90% lightness; only hue varies).
|
|
159
158
|
*/
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
3: { bg: colors.gold[100] },
|
|
164
|
-
4: { bg: colors.red[100] },
|
|
165
|
-
5: { bg: colors.violet[100] },
|
|
166
|
-
6: { bg: colors.tealGreen[100] },
|
|
167
|
-
7: { bg: colors.orange[100] },
|
|
159
|
+
const avatarColorFromSeed = (seed) => {
|
|
160
|
+
const hue = seed ? djb2Hash(seed) % 360 : 235;
|
|
161
|
+
return `hsl(${hue}, 80%, 90%)`;
|
|
168
162
|
};
|
|
169
163
|
|
|
170
164
|
/**
|
|
@@ -179,14 +173,13 @@ const focusRingStyles = {
|
|
|
179
173
|
};
|
|
180
174
|
|
|
181
175
|
const sizeConfig$1 = {
|
|
182
|
-
small: { width: spacing.spacing_4, height: spacing.spacing_4, fontSize: typography.fontSize.
|
|
176
|
+
small: { width: spacing.spacing_4, height: spacing.spacing_4, fontSize: typography.fontSize.sm },
|
|
183
177
|
medium: { width: spacing.spacing_5, height: spacing.spacing_5, fontSize: typography.fontSize.sm },
|
|
184
178
|
};
|
|
185
179
|
const StyledAvatar = styled(MuiAvatar, {
|
|
186
|
-
shouldForwardProp: prop => prop !== 'avatarSize' && prop !== '
|
|
187
|
-
})(({ theme, avatarSize,
|
|
180
|
+
shouldForwardProp: prop => prop !== 'avatarSize' && prop !== 'backgroundColor',
|
|
181
|
+
})(({ theme, avatarSize, backgroundColor }) => {
|
|
188
182
|
const size = sizeConfig$1[avatarSize];
|
|
189
|
-
const palette = avatarColorPalette[colorIndex];
|
|
190
183
|
return {
|
|
191
184
|
boxSizing: 'border-box',
|
|
192
185
|
width: size.width,
|
|
@@ -196,7 +189,7 @@ const StyledAvatar = styled(MuiAvatar, {
|
|
|
196
189
|
fontWeight: typography.fontWeight.regular,
|
|
197
190
|
lineHeight: 1,
|
|
198
191
|
color: semanticColors.typography.body,
|
|
199
|
-
backgroundColor
|
|
192
|
+
backgroundColor,
|
|
200
193
|
border: `1px solid ${semanticColors.border.primary}`,
|
|
201
194
|
'&:focus-visible': {
|
|
202
195
|
...focusRingStyles,
|
|
@@ -209,8 +202,9 @@ const StyledAvatar = styled(MuiAvatar, {
|
|
|
209
202
|
*
|
|
210
203
|
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=9600-185
|
|
211
204
|
*/
|
|
212
|
-
const NeoGeneralAvatar = ({ size = 'medium',
|
|
213
|
-
|
|
205
|
+
const NeoGeneralAvatar = ({ size = 'medium', alt, children, ...props }) => {
|
|
206
|
+
const backgroundColor = avatarColorFromSeed(alt);
|
|
207
|
+
return (jsx(StyledAvatar, { avatarSize: size, backgroundColor: backgroundColor, alt: alt, ...props, children: children }));
|
|
214
208
|
};
|
|
215
209
|
NeoGeneralAvatar.displayName = 'NeoGeneralAvatar';
|
|
216
210
|
|
|
@@ -267,22 +261,6 @@ const NeoDataGridCellContent = ({ children, ...props }) => {
|
|
|
267
261
|
return jsx(CellContentContainer, { ...props, children: children });
|
|
268
262
|
};
|
|
269
263
|
NeoDataGridCellContent.displayName = 'NeoDataGridCellContent';
|
|
270
|
-
/**
|
|
271
|
-
* Utility function to get DataGrid sx styles for consistent cell appearance
|
|
272
|
-
*
|
|
273
|
-
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4212-41631
|
|
274
|
-
*
|
|
275
|
-
* Apply this to DataGrid's `sx` prop to ensure cells are properly aligned and styled.
|
|
276
|
-
*
|
|
277
|
-
* @param size - Row size variant (affects row height)
|
|
278
|
-
* @returns SxProps for DataGrid
|
|
279
|
-
*
|
|
280
|
-
* @example
|
|
281
|
-
* <DataGrid
|
|
282
|
-
* rows={rows}
|
|
283
|
-
* columns={columns}
|
|
284
|
-
* />
|
|
285
|
-
*/
|
|
286
264
|
/**
|
|
287
265
|
* Row height configuration for DataGrid size variants (from Figma specs)
|
|
288
266
|
* - compact: 42px
|
|
@@ -476,7 +454,7 @@ const NeoActivityIndicatorCell = ({ event = 'commit-job', secondaryEvent, scene
|
|
|
476
454
|
NeoActivityIndicatorCell.displayName = 'NeoActivityIndicatorCell';
|
|
477
455
|
|
|
478
456
|
/**
|
|
479
|
-
* @license lucide-react v1.
|
|
457
|
+
* @license lucide-react v1.16.0 - ISC
|
|
480
458
|
*
|
|
481
459
|
* This source code is licensed under the ISC license.
|
|
482
460
|
* See the LICENSE file in the root directory of this source tree.
|
|
@@ -487,7 +465,7 @@ const mergeClasses = (...classes) => classes.filter((className, index, array) =>
|
|
|
487
465
|
}).join(" ").trim();
|
|
488
466
|
|
|
489
467
|
/**
|
|
490
|
-
* @license lucide-react v1.
|
|
468
|
+
* @license lucide-react v1.16.0 - ISC
|
|
491
469
|
*
|
|
492
470
|
* This source code is licensed under the ISC license.
|
|
493
471
|
* See the LICENSE file in the root directory of this source tree.
|
|
@@ -496,7 +474,7 @@ const mergeClasses = (...classes) => classes.filter((className, index, array) =>
|
|
|
496
474
|
const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
497
475
|
|
|
498
476
|
/**
|
|
499
|
-
* @license lucide-react v1.
|
|
477
|
+
* @license lucide-react v1.16.0 - ISC
|
|
500
478
|
*
|
|
501
479
|
* This source code is licensed under the ISC license.
|
|
502
480
|
* See the LICENSE file in the root directory of this source tree.
|
|
@@ -508,7 +486,7 @@ const toCamelCase = (string) => string.replace(
|
|
|
508
486
|
);
|
|
509
487
|
|
|
510
488
|
/**
|
|
511
|
-
* @license lucide-react v1.
|
|
489
|
+
* @license lucide-react v1.16.0 - ISC
|
|
512
490
|
*
|
|
513
491
|
* This source code is licensed under the ISC license.
|
|
514
492
|
* See the LICENSE file in the root directory of this source tree.
|
|
@@ -521,7 +499,7 @@ const toPascalCase = (string) => {
|
|
|
521
499
|
};
|
|
522
500
|
|
|
523
501
|
/**
|
|
524
|
-
* @license lucide-react v1.
|
|
502
|
+
* @license lucide-react v1.16.0 - ISC
|
|
525
503
|
*
|
|
526
504
|
* This source code is licensed under the ISC license.
|
|
527
505
|
* See the LICENSE file in the root directory of this source tree.
|
|
@@ -540,7 +518,7 @@ var defaultAttributes = {
|
|
|
540
518
|
};
|
|
541
519
|
|
|
542
520
|
/**
|
|
543
|
-
* @license lucide-react v1.
|
|
521
|
+
* @license lucide-react v1.16.0 - ISC
|
|
544
522
|
*
|
|
545
523
|
* This source code is licensed under the ISC license.
|
|
546
524
|
* See the LICENSE file in the root directory of this source tree.
|
|
@@ -590,7 +568,7 @@ const Icon = forwardRef(
|
|
|
590
568
|
);
|
|
591
569
|
|
|
592
570
|
/**
|
|
593
|
-
* @license lucide-react v1.
|
|
571
|
+
* @license lucide-react v1.16.0 - ISC
|
|
594
572
|
*
|
|
595
573
|
* This source code is licensed under the ISC license.
|
|
596
574
|
* See the LICENSE file in the root directory of this source tree.
|
|
@@ -615,42 +593,42 @@ const createLucideIcon = (iconName, iconNode) => {
|
|
|
615
593
|
};
|
|
616
594
|
|
|
617
595
|
/**
|
|
618
|
-
* @license lucide-react v1.
|
|
596
|
+
* @license lucide-react v1.16.0 - ISC
|
|
619
597
|
*
|
|
620
598
|
* This source code is licensed under the ISC license.
|
|
621
599
|
* See the LICENSE file in the root directory of this source tree.
|
|
622
600
|
*/
|
|
623
601
|
|
|
624
602
|
|
|
625
|
-
const __iconNode$
|
|
603
|
+
const __iconNode$p = [
|
|
626
604
|
["path", { d: "M12 5v14", key: "s699le" }],
|
|
627
605
|
["path", { d: "m19 12-7 7-7-7", key: "1idqje" }]
|
|
628
606
|
];
|
|
629
|
-
const ArrowDown = createLucideIcon("arrow-down", __iconNode$
|
|
607
|
+
const ArrowDown = createLucideIcon("arrow-down", __iconNode$p);
|
|
630
608
|
|
|
631
609
|
/**
|
|
632
|
-
* @license lucide-react v1.
|
|
610
|
+
* @license lucide-react v1.16.0 - ISC
|
|
633
611
|
*
|
|
634
612
|
* This source code is licensed under the ISC license.
|
|
635
613
|
* See the LICENSE file in the root directory of this source tree.
|
|
636
614
|
*/
|
|
637
615
|
|
|
638
616
|
|
|
639
|
-
const __iconNode$
|
|
617
|
+
const __iconNode$o = [
|
|
640
618
|
["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
|
|
641
619
|
["path", { d: "M12 19V5", key: "x0mq9r" }]
|
|
642
620
|
];
|
|
643
|
-
const ArrowUp = createLucideIcon("arrow-up", __iconNode$
|
|
621
|
+
const ArrowUp = createLucideIcon("arrow-up", __iconNode$o);
|
|
644
622
|
|
|
645
623
|
/**
|
|
646
|
-
* @license lucide-react v1.
|
|
624
|
+
* @license lucide-react v1.16.0 - ISC
|
|
647
625
|
*
|
|
648
626
|
* This source code is licensed under the ISC license.
|
|
649
627
|
* See the LICENSE file in the root directory of this source tree.
|
|
650
628
|
*/
|
|
651
629
|
|
|
652
630
|
|
|
653
|
-
const __iconNode$
|
|
631
|
+
const __iconNode$n = [
|
|
654
632
|
[
|
|
655
633
|
"path",
|
|
656
634
|
{
|
|
@@ -661,17 +639,17 @@ const __iconNode$i = [
|
|
|
661
639
|
["line", { x1: "12", x2: "12", y1: "16", y2: "12", key: "1y1yb1" }],
|
|
662
640
|
["line", { x1: "12", x2: "12.01", y1: "8", y2: "8", key: "110wyk" }]
|
|
663
641
|
];
|
|
664
|
-
const BadgeInfo = createLucideIcon("badge-info", __iconNode$
|
|
642
|
+
const BadgeInfo = createLucideIcon("badge-info", __iconNode$n);
|
|
665
643
|
|
|
666
644
|
/**
|
|
667
|
-
* @license lucide-react v1.
|
|
645
|
+
* @license lucide-react v1.16.0 - ISC
|
|
668
646
|
*
|
|
669
647
|
* This source code is licensed under the ISC license.
|
|
670
648
|
* See the LICENSE file in the root directory of this source tree.
|
|
671
649
|
*/
|
|
672
650
|
|
|
673
651
|
|
|
674
|
-
const __iconNode$
|
|
652
|
+
const __iconNode$m = [
|
|
675
653
|
["path", { d: "M8 2v4", key: "1cmpym" }],
|
|
676
654
|
["path", { d: "M16 2v4", key: "4m81vk" }],
|
|
677
655
|
["rect", { width: "18", height: "18", x: "3", y: "4", rx: "2", key: "1hopcy" }],
|
|
@@ -683,181 +661,252 @@ const __iconNode$h = [
|
|
|
683
661
|
["path", { d: "M12 18h.01", key: "mhygvu" }],
|
|
684
662
|
["path", { d: "M16 18h.01", key: "kzsmim" }]
|
|
685
663
|
];
|
|
686
|
-
const CalendarDays = createLucideIcon("calendar-days", __iconNode$
|
|
664
|
+
const CalendarDays = createLucideIcon("calendar-days", __iconNode$m);
|
|
687
665
|
|
|
688
666
|
/**
|
|
689
|
-
* @license lucide-react v1.
|
|
667
|
+
* @license lucide-react v1.16.0 - ISC
|
|
690
668
|
*
|
|
691
669
|
* This source code is licensed under the ISC license.
|
|
692
670
|
* See the LICENSE file in the root directory of this source tree.
|
|
693
671
|
*/
|
|
694
672
|
|
|
695
673
|
|
|
696
|
-
const __iconNode$
|
|
697
|
-
const ChevronDown = createLucideIcon("chevron-down", __iconNode$
|
|
674
|
+
const __iconNode$l = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
|
|
675
|
+
const ChevronDown = createLucideIcon("chevron-down", __iconNode$l);
|
|
698
676
|
|
|
699
677
|
/**
|
|
700
|
-
* @license lucide-react v1.
|
|
678
|
+
* @license lucide-react v1.16.0 - ISC
|
|
701
679
|
*
|
|
702
680
|
* This source code is licensed under the ISC license.
|
|
703
681
|
* See the LICENSE file in the root directory of this source tree.
|
|
704
682
|
*/
|
|
705
683
|
|
|
706
684
|
|
|
707
|
-
const __iconNode$
|
|
708
|
-
const ChevronLeft = createLucideIcon("chevron-left", __iconNode$
|
|
685
|
+
const __iconNode$k = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
|
|
686
|
+
const ChevronLeft = createLucideIcon("chevron-left", __iconNode$k);
|
|
709
687
|
|
|
710
688
|
/**
|
|
711
|
-
* @license lucide-react v1.
|
|
689
|
+
* @license lucide-react v1.16.0 - ISC
|
|
712
690
|
*
|
|
713
691
|
* This source code is licensed under the ISC license.
|
|
714
692
|
* See the LICENSE file in the root directory of this source tree.
|
|
715
693
|
*/
|
|
716
694
|
|
|
717
695
|
|
|
718
|
-
const __iconNode$
|
|
719
|
-
const ChevronRight = createLucideIcon("chevron-right", __iconNode$
|
|
696
|
+
const __iconNode$j = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
|
|
697
|
+
const ChevronRight = createLucideIcon("chevron-right", __iconNode$j);
|
|
720
698
|
|
|
721
699
|
/**
|
|
722
|
-
* @license lucide-react v1.
|
|
700
|
+
* @license lucide-react v1.16.0 - ISC
|
|
723
701
|
*
|
|
724
702
|
* This source code is licensed under the ISC license.
|
|
725
703
|
* See the LICENSE file in the root directory of this source tree.
|
|
726
704
|
*/
|
|
727
705
|
|
|
728
706
|
|
|
729
|
-
const __iconNode$
|
|
730
|
-
const ChevronUp = createLucideIcon("chevron-up", __iconNode$
|
|
707
|
+
const __iconNode$i = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
|
|
708
|
+
const ChevronUp = createLucideIcon("chevron-up", __iconNode$i);
|
|
731
709
|
|
|
732
710
|
/**
|
|
733
|
-
* @license lucide-react v1.
|
|
711
|
+
* @license lucide-react v1.16.0 - ISC
|
|
734
712
|
*
|
|
735
713
|
* This source code is licensed under the ISC license.
|
|
736
714
|
* See the LICENSE file in the root directory of this source tree.
|
|
737
715
|
*/
|
|
738
716
|
|
|
739
717
|
|
|
740
|
-
const __iconNode$
|
|
718
|
+
const __iconNode$h = [
|
|
741
719
|
["path", { d: "m7 15 5 5 5-5", key: "1hf1tw" }],
|
|
742
720
|
["path", { d: "m7 9 5-5 5 5", key: "sgt6xg" }]
|
|
743
721
|
];
|
|
744
|
-
const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$
|
|
722
|
+
const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$h);
|
|
745
723
|
|
|
746
724
|
/**
|
|
747
|
-
* @license lucide-react v1.
|
|
725
|
+
* @license lucide-react v1.16.0 - ISC
|
|
748
726
|
*
|
|
749
727
|
* This source code is licensed under the ISC license.
|
|
750
728
|
* See the LICENSE file in the root directory of this source tree.
|
|
751
729
|
*/
|
|
752
730
|
|
|
753
731
|
|
|
754
|
-
const __iconNode$
|
|
732
|
+
const __iconNode$g = [
|
|
755
733
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
756
734
|
["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
|
|
757
735
|
["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
|
|
758
736
|
];
|
|
759
|
-
const CircleAlert = createLucideIcon("circle-alert", __iconNode$
|
|
737
|
+
const CircleAlert = createLucideIcon("circle-alert", __iconNode$g);
|
|
760
738
|
|
|
761
739
|
/**
|
|
762
|
-
* @license lucide-react v1.
|
|
740
|
+
* @license lucide-react v1.16.0 - ISC
|
|
763
741
|
*
|
|
764
742
|
* This source code is licensed under the ISC license.
|
|
765
743
|
* See the LICENSE file in the root directory of this source tree.
|
|
766
744
|
*/
|
|
767
745
|
|
|
768
746
|
|
|
769
|
-
const __iconNode$
|
|
747
|
+
const __iconNode$f = [
|
|
770
748
|
["path", { d: "M21.801 10A10 10 0 1 1 17 3.335", key: "yps3ct" }],
|
|
771
749
|
["path", { d: "m9 11 3 3L22 4", key: "1pflzl" }]
|
|
772
750
|
];
|
|
773
|
-
const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$
|
|
751
|
+
const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$f);
|
|
774
752
|
|
|
775
753
|
/**
|
|
776
|
-
* @license lucide-react v1.
|
|
754
|
+
* @license lucide-react v1.16.0 - ISC
|
|
777
755
|
*
|
|
778
756
|
* This source code is licensed under the ISC license.
|
|
779
757
|
* See the LICENSE file in the root directory of this source tree.
|
|
780
758
|
*/
|
|
781
759
|
|
|
782
760
|
|
|
783
|
-
const __iconNode$
|
|
761
|
+
const __iconNode$e = [
|
|
784
762
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
785
763
|
["path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3", key: "1u773s" }],
|
|
786
764
|
["path", { d: "M12 17h.01", key: "p32p05" }]
|
|
787
765
|
];
|
|
788
|
-
const CircleQuestionMark = createLucideIcon("circle-question-mark", __iconNode$
|
|
766
|
+
const CircleQuestionMark = createLucideIcon("circle-question-mark", __iconNode$e);
|
|
789
767
|
|
|
790
768
|
/**
|
|
791
|
-
* @license lucide-react v1.
|
|
769
|
+
* @license lucide-react v1.16.0 - ISC
|
|
792
770
|
*
|
|
793
771
|
* This source code is licensed under the ISC license.
|
|
794
772
|
* See the LICENSE file in the root directory of this source tree.
|
|
795
773
|
*/
|
|
796
774
|
|
|
797
775
|
|
|
798
|
-
const __iconNode$
|
|
776
|
+
const __iconNode$d = [
|
|
799
777
|
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
|
|
800
778
|
["path", { d: "M9 3v18", key: "fh3hqa" }],
|
|
801
779
|
["path", { d: "M15 3v18", key: "14nvp0" }]
|
|
802
780
|
];
|
|
803
|
-
const Columns3 = createLucideIcon("columns-3", __iconNode$
|
|
781
|
+
const Columns3 = createLucideIcon("columns-3", __iconNode$d);
|
|
804
782
|
|
|
805
783
|
/**
|
|
806
|
-
* @license lucide-react v1.
|
|
784
|
+
* @license lucide-react v1.16.0 - ISC
|
|
807
785
|
*
|
|
808
786
|
* This source code is licensed under the ISC license.
|
|
809
787
|
* See the LICENSE file in the root directory of this source tree.
|
|
810
788
|
*/
|
|
811
789
|
|
|
812
790
|
|
|
813
|
-
const __iconNode$
|
|
791
|
+
const __iconNode$c = [
|
|
814
792
|
["path", { d: "M2 5h20", key: "1fs1ex" }],
|
|
815
793
|
["path", { d: "M6 12h12", key: "8npq4p" }],
|
|
816
794
|
["path", { d: "M9 19h6", key: "456am0" }]
|
|
817
795
|
];
|
|
818
|
-
const ListFilter = createLucideIcon("list-filter", __iconNode$
|
|
796
|
+
const ListFilter = createLucideIcon("list-filter", __iconNode$c);
|
|
819
797
|
|
|
820
798
|
/**
|
|
821
|
-
* @license lucide-react v1.
|
|
799
|
+
* @license lucide-react v1.16.0 - ISC
|
|
822
800
|
*
|
|
823
801
|
* This source code is licensed under the ISC license.
|
|
824
802
|
* See the LICENSE file in the root directory of this source tree.
|
|
825
803
|
*/
|
|
826
804
|
|
|
827
805
|
|
|
828
|
-
const __iconNode$
|
|
829
|
-
const Minus = createLucideIcon("minus", __iconNode$
|
|
806
|
+
const __iconNode$b = [["path", { d: "M5 12h14", key: "1ays0h" }]];
|
|
807
|
+
const Minus = createLucideIcon("minus", __iconNode$b);
|
|
830
808
|
|
|
831
809
|
/**
|
|
832
|
-
* @license lucide-react v1.
|
|
810
|
+
* @license lucide-react v1.16.0 - ISC
|
|
833
811
|
*
|
|
834
812
|
* This source code is licensed under the ISC license.
|
|
835
813
|
* See the LICENSE file in the root directory of this source tree.
|
|
836
814
|
*/
|
|
837
815
|
|
|
838
816
|
|
|
839
|
-
const __iconNode$
|
|
817
|
+
const __iconNode$a = [
|
|
818
|
+
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
|
|
819
|
+
["path", { d: "M9 3v18", key: "fh3hqa" }],
|
|
820
|
+
["path", { d: "m16 15-3-3 3-3", key: "14y99z" }]
|
|
821
|
+
];
|
|
822
|
+
const PanelLeftClose = createLucideIcon("panel-left-close", __iconNode$a);
|
|
823
|
+
|
|
824
|
+
/**
|
|
825
|
+
* @license lucide-react v1.16.0 - ISC
|
|
826
|
+
*
|
|
827
|
+
* This source code is licensed under the ISC license.
|
|
828
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
829
|
+
*/
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
const __iconNode$9 = [
|
|
833
|
+
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
|
|
834
|
+
["path", { d: "M9 3v18", key: "fh3hqa" }],
|
|
835
|
+
["path", { d: "m14 9 3 3-3 3", key: "8010ee" }]
|
|
836
|
+
];
|
|
837
|
+
const PanelLeftOpen = createLucideIcon("panel-left-open", __iconNode$9);
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* @license lucide-react v1.16.0 - ISC
|
|
841
|
+
*
|
|
842
|
+
* This source code is licensed under the ISC license.
|
|
843
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
844
|
+
*/
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
const __iconNode$8 = [
|
|
840
848
|
["path", { d: "M5 12h14", key: "1ays0h" }],
|
|
841
849
|
["path", { d: "M12 5v14", key: "s699le" }]
|
|
842
850
|
];
|
|
843
|
-
const Plus = createLucideIcon("plus", __iconNode$
|
|
851
|
+
const Plus = createLucideIcon("plus", __iconNode$8);
|
|
844
852
|
|
|
845
853
|
/**
|
|
846
|
-
* @license lucide-react v1.
|
|
854
|
+
* @license lucide-react v1.16.0 - ISC
|
|
847
855
|
*
|
|
848
856
|
* This source code is licensed under the ISC license.
|
|
849
857
|
* See the LICENSE file in the root directory of this source tree.
|
|
850
858
|
*/
|
|
851
859
|
|
|
852
860
|
|
|
853
|
-
const __iconNode$
|
|
861
|
+
const __iconNode$7 = [
|
|
854
862
|
["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
|
|
855
863
|
["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
|
|
856
864
|
];
|
|
857
|
-
const Search = createLucideIcon("search", __iconNode$
|
|
865
|
+
const Search = createLucideIcon("search", __iconNode$7);
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* @license lucide-react v1.16.0 - ISC
|
|
869
|
+
*
|
|
870
|
+
* This source code is licensed under the ISC license.
|
|
871
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
872
|
+
*/
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
const __iconNode$6 = [
|
|
876
|
+
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
|
|
877
|
+
["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
|
|
878
|
+
];
|
|
879
|
+
const SquareCheck = createLucideIcon("square-check", __iconNode$6);
|
|
880
|
+
|
|
881
|
+
/**
|
|
882
|
+
* @license lucide-react v1.16.0 - ISC
|
|
883
|
+
*
|
|
884
|
+
* This source code is licensed under the ISC license.
|
|
885
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
886
|
+
*/
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
const __iconNode$5 = [
|
|
890
|
+
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
|
|
891
|
+
["path", { d: "M8 12h8", key: "1wcyev" }]
|
|
892
|
+
];
|
|
893
|
+
const SquareMinus = createLucideIcon("square-minus", __iconNode$5);
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* @license lucide-react v1.16.0 - ISC
|
|
897
|
+
*
|
|
898
|
+
* This source code is licensed under the ISC license.
|
|
899
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
900
|
+
*/
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
const __iconNode$4 = [
|
|
904
|
+
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }]
|
|
905
|
+
];
|
|
906
|
+
const Square = createLucideIcon("square", __iconNode$4);
|
|
858
907
|
|
|
859
908
|
/**
|
|
860
|
-
* @license lucide-react v1.
|
|
909
|
+
* @license lucide-react v1.16.0 - ISC
|
|
861
910
|
*
|
|
862
911
|
* This source code is licensed under the ISC license.
|
|
863
912
|
* See the LICENSE file in the root directory of this source tree.
|
|
@@ -874,7 +923,7 @@ const __iconNode$3 = [
|
|
|
874
923
|
const Trash2 = createLucideIcon("trash-2", __iconNode$3);
|
|
875
924
|
|
|
876
925
|
/**
|
|
877
|
-
* @license lucide-react v1.
|
|
926
|
+
* @license lucide-react v1.16.0 - ISC
|
|
878
927
|
*
|
|
879
928
|
* This source code is licensed under the ISC license.
|
|
880
929
|
* See the LICENSE file in the root directory of this source tree.
|
|
@@ -895,7 +944,7 @@ const __iconNode$2 = [
|
|
|
895
944
|
const TriangleAlert = createLucideIcon("triangle-alert", __iconNode$2);
|
|
896
945
|
|
|
897
946
|
/**
|
|
898
|
-
* @license lucide-react v1.
|
|
947
|
+
* @license lucide-react v1.16.0 - ISC
|
|
899
948
|
*
|
|
900
949
|
* This source code is licensed under the ISC license.
|
|
901
950
|
* See the LICENSE file in the root directory of this source tree.
|
|
@@ -914,7 +963,7 @@ const __iconNode$1 = [
|
|
|
914
963
|
const WifiOff = createLucideIcon("wifi-off", __iconNode$1);
|
|
915
964
|
|
|
916
965
|
/**
|
|
917
|
-
* @license lucide-react v1.
|
|
966
|
+
* @license lucide-react v1.16.0 - ISC
|
|
918
967
|
*
|
|
919
968
|
* This source code is licensed under the ISC license.
|
|
920
969
|
* See the LICENSE file in the root directory of this source tree.
|
|
@@ -937,22 +986,29 @@ const intentColors$2 = {
|
|
|
937
986
|
};
|
|
938
987
|
// biome-ignore lint/suspicious/noExplicitAny: Type cast required to override MUI Alert variant type without global augmentation
|
|
939
988
|
const StyledAlert$2 = styled(Alert, {
|
|
940
|
-
shouldForwardProp: prop => prop !== 'intent' && prop !== 'alertType',
|
|
941
|
-
})(({ theme, intent = 'success', alertType = 'outlined' }) => {
|
|
989
|
+
shouldForwardProp: prop => prop !== 'intent' && prop !== 'alertType' && prop !== 'alertSize' && prop !== 'hasChildren',
|
|
990
|
+
})(({ theme, intent = 'success', alertType = 'outlined', alertSize = 'default', hasChildren = false, }) => {
|
|
942
991
|
const palette = intentColors$2[intent];
|
|
943
992
|
const isFilled = alertType === 'filled';
|
|
993
|
+
const isCompact = alertSize === 'compact';
|
|
944
994
|
const iconColor = isFilled ? semanticColors.typography.tooltip : palette.default;
|
|
945
|
-
const messageColor = isFilled
|
|
995
|
+
const messageColor = isFilled
|
|
996
|
+
? semanticColors.typography.tooltip
|
|
997
|
+
: semanticColors.typography.body;
|
|
946
998
|
return {
|
|
947
|
-
|
|
999
|
+
...(isCompact
|
|
1000
|
+
? { minHeight: spacing.spacing_5 }
|
|
1001
|
+
: hasChildren
|
|
1002
|
+
? { minHeight: spacing.spacing_8, height: 'auto' }
|
|
1003
|
+
: { height: spacing.spacing_8 }),
|
|
948
1004
|
width: '100%',
|
|
949
1005
|
borderRadius: borderRadius.xS,
|
|
950
|
-
alignItems: 'center',
|
|
1006
|
+
alignItems: hasChildren ? 'flex-start' : 'center',
|
|
951
1007
|
fontFamily: typography.fontFamily.body,
|
|
952
1008
|
fontSize: theme.typography.pxToRem(typography.fontSize.default),
|
|
953
1009
|
fontWeight: typography.fontWeight.semiBold,
|
|
954
1010
|
lineHeight: 1.5,
|
|
955
|
-
padding: theme.spacing(0, 2),
|
|
1011
|
+
padding: hasChildren ? theme.spacing(1.5, 2) : theme.spacing(0, 2),
|
|
956
1012
|
backgroundColor: isFilled ? palette.dark : palette.light,
|
|
957
1013
|
border: isFilled ? 'none' : `1px solid ${palette.transparent}`,
|
|
958
1014
|
color: isFilled ? semanticColors.typography.tooltip : semanticColors.typography.body,
|
|
@@ -969,7 +1025,7 @@ const StyledAlert$2 = styled(Alert, {
|
|
|
969
1025
|
flex: 1,
|
|
970
1026
|
display: 'flex',
|
|
971
1027
|
flexDirection: 'column',
|
|
972
|
-
justifyContent: 'center',
|
|
1028
|
+
justifyContent: hasChildren ? 'flex-start' : 'center',
|
|
973
1029
|
'& span:last-child': {
|
|
974
1030
|
fontSize: theme.typography.pxToRem(typography.fontSize.sm),
|
|
975
1031
|
fontWeight: typography.fontWeight.medium,
|
|
@@ -1007,9 +1063,9 @@ const iconMap = {
|
|
|
1007
1063
|
* - Show supporting text → description prop presence
|
|
1008
1064
|
* - Show Button → action prop presence
|
|
1009
1065
|
*/
|
|
1010
|
-
const NeoAlert = ({ intent = 'success', type = 'outlined', title, description, icon, action, ...props }) => {
|
|
1066
|
+
const NeoAlert = ({ intent = 'success', type = 'outlined', size = 'default', title, description, icon, action, children, ...props }) => {
|
|
1011
1067
|
const defaultIcon = iconMap[intent];
|
|
1012
|
-
return (jsxs(StyledAlert$2, { ...props, intent: intent, alertType: type, icon: icon ?? defaultIcon, action: action, children: [jsx("span", { children: title }), description && jsx("span", { children: description })] }));
|
|
1068
|
+
return (jsxs(StyledAlert$2, { ...props, intent: intent, alertType: type, alertSize: size, hasChildren: Boolean(children), icon: icon ?? defaultIcon, action: action, children: [jsx("span", { children: title }), description && jsx("span", { children: description }), children] }));
|
|
1013
1069
|
};
|
|
1014
1070
|
NeoAlert.displayName = 'NeoAlert';
|
|
1015
1071
|
|
|
@@ -1036,38 +1092,43 @@ const StyledAlert$1 = styled(Alert, {
|
|
|
1036
1092
|
};
|
|
1037
1093
|
return {
|
|
1038
1094
|
width: '100%',
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1095
|
+
// Include padding in the width so the full-width banner never overflows its
|
|
1096
|
+
// container (don't rely on a global border-box reset being present).
|
|
1097
|
+
boxSizing: 'border-box',
|
|
1098
|
+
// Square corners by default: banners are full-width and typically sit flush
|
|
1099
|
+
// against the top of the viewport, so rounded corners would break the seam.
|
|
1100
|
+
borderRadius: 0,
|
|
1101
|
+
minHeight: 32,
|
|
1102
|
+
paddingTop: spacing.spacing_1_2,
|
|
1103
|
+
paddingBottom: spacing.spacing_1_2,
|
|
1104
|
+
paddingLeft: spacing.spacing_2,
|
|
1105
|
+
paddingRight: spacing.spacing_2,
|
|
1106
|
+
gap: spacing.spacing_1,
|
|
1045
1107
|
alignItems: 'center',
|
|
1046
1108
|
justifyContent: messagePosition === 'center' ? 'center' : 'flex-start',
|
|
1047
1109
|
...(messagePosition === 'center' && { position: 'relative' }),
|
|
1048
|
-
|
|
1049
|
-
fontSize: typography.fontSize.default,
|
|
1110
|
+
fontSize: typography.fontSize.sm,
|
|
1050
1111
|
fontWeight: typography.fontWeight.medium,
|
|
1051
1112
|
lineHeight: 1.5,
|
|
1052
1113
|
...typeStyles,
|
|
1053
1114
|
[`& .${alertClasses.icon}`]: {
|
|
1054
1115
|
padding: 0,
|
|
1055
1116
|
opacity: 1,
|
|
1056
|
-
fontSize: typography.fontSize.
|
|
1117
|
+
fontSize: typography.fontSize.default,
|
|
1057
1118
|
color: 'inherit',
|
|
1058
1119
|
},
|
|
1059
1120
|
[`& .${alertClasses.message}`]: {
|
|
1060
1121
|
padding: 0,
|
|
1061
1122
|
display: 'flex',
|
|
1062
1123
|
alignItems: 'center',
|
|
1063
|
-
gap: spacing.
|
|
1124
|
+
gap: spacing.spacing_1,
|
|
1064
1125
|
...(messagePosition === 'left' && { flex: 1 }),
|
|
1065
1126
|
},
|
|
1066
1127
|
[`& .${alertClasses.action}`]: {
|
|
1067
1128
|
padding: 0,
|
|
1068
1129
|
...(messagePosition === 'center' && {
|
|
1069
1130
|
position: 'absolute',
|
|
1070
|
-
right: spacing.
|
|
1131
|
+
right: spacing.spacing_2,
|
|
1071
1132
|
}),
|
|
1072
1133
|
},
|
|
1073
1134
|
};
|
|
@@ -1085,6 +1146,8 @@ const LinkText = styled('span')(({ bannerType = 'outlined' }) => ({
|
|
|
1085
1146
|
},
|
|
1086
1147
|
}));
|
|
1087
1148
|
const StyledIconButton = styled(IconButton)(({ closeIconColor }) => ({
|
|
1149
|
+
minWidth: 24,
|
|
1150
|
+
minHeight: 24,
|
|
1088
1151
|
padding: 0,
|
|
1089
1152
|
color: closeIconColor,
|
|
1090
1153
|
'&:hover': {
|
|
@@ -1101,7 +1164,7 @@ const NeoBanner = ({ intent = 'info', type = 'outlined', message, messagePositio
|
|
|
1101
1164
|
return null;
|
|
1102
1165
|
}
|
|
1103
1166
|
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, { size: "small", onClick: handleClose, closeIconColor: closeIconColor, children: jsx(X, { size:
|
|
1167
|
+
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: 16 }) })) : 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
1168
|
};
|
|
1106
1169
|
NeoBanner.displayName = 'NeoBanner';
|
|
1107
1170
|
|
|
@@ -1121,12 +1184,12 @@ const StyledBreadcrumbLink = styled(Link, {
|
|
|
1121
1184
|
fontWeight: typography.fontWeight.medium,
|
|
1122
1185
|
lineHeight: 1,
|
|
1123
1186
|
textDecoration: 'none',
|
|
1124
|
-
color: current ? semanticColors.
|
|
1187
|
+
color: current ? semanticColors.typography.bodySecondary : semanticColors.typography.link.primary,
|
|
1125
1188
|
cursor: current ? 'default' : 'pointer',
|
|
1126
1189
|
borderRadius: borderRadius.xS,
|
|
1127
1190
|
transition: 'color 0.2s ease-in-out',
|
|
1128
1191
|
'&:hover': {
|
|
1129
|
-
color: current ? semanticColors.
|
|
1192
|
+
color: current ? semanticColors.icons.hover : semanticColors.buttons.tertiary.hover,
|
|
1130
1193
|
},
|
|
1131
1194
|
'&:focus-visible': {
|
|
1132
1195
|
outline: `2px solid ${semanticColors.border.focus}`,
|
|
@@ -1509,6 +1572,15 @@ const NeoButtonTabGroup = ({ size = 'medium', exclusive = true, ...props }) => {
|
|
|
1509
1572
|
};
|
|
1510
1573
|
NeoButtonTabGroup.displayName = 'NeoButtonTabGroup';
|
|
1511
1574
|
|
|
1575
|
+
/**
|
|
1576
|
+
* NeoCanceledIcon - Outlined circle struck through by a horizontal line.
|
|
1577
|
+
*
|
|
1578
|
+
* Marks a CANCELED state. Color comes entirely from `currentColor` (stroke plus
|
|
1579
|
+
* a 10% fill tint); set it via the `color`/`sx` prop or a parent.
|
|
1580
|
+
*/
|
|
1581
|
+
const NeoCanceledIcon = (props) => (jsx(SvgIcon, { viewBox: "0 0 24 24", fill: "none", ...props, children: jsxs("g", { stroke: "currentColor", strokeWidth: "1.35", children: [jsx("path", { fill: "currentColor", fillOpacity: "0.1", d: "M2.55 11.95c0 2.405.918 4.812 2.753 6.647a9.4 9.4 0 0 0 6.647 2.753c2.489 0 4.877-.99 6.646-2.753a9.3 9.3 0 0 0 2.039-3.044 9.4 9.4 0 0 0 .715-3.602m-18.8-.001a9.37 9.37 0 0 1 2.753-6.647A9.4 9.4 0 0 1 11.95 2.55c2.489 0 4.877.99 6.646 2.753a9.3 9.3 0 0 1 2.039 3.045 9.4 9.4 0 0 1 .715 3.603" }), jsx("path", { fill: "none", d: "M3 11.825h18" })] }) }));
|
|
1582
|
+
NeoCanceledIcon.displayName = 'NeoCanceledIcon';
|
|
1583
|
+
|
|
1512
1584
|
// ─── Shared ──────────────────────────────────────────────────────────────────
|
|
1513
1585
|
const activeShadow = `${shadows.card.x}px ${shadows.card.y}px ${shadows.card.blur}px ${shadows.card.spread}px ${shadows.card.shadow}`;
|
|
1514
1586
|
// ─── Small card styled components ────────────────────────────────────────────
|
|
@@ -1700,20 +1772,6 @@ const NeoCard = (props) => {
|
|
|
1700
1772
|
};
|
|
1701
1773
|
NeoCard.displayName = 'NeoCard';
|
|
1702
1774
|
|
|
1703
|
-
// Border radius per size (from Figma)
|
|
1704
|
-
const borderRadiusConfig = {
|
|
1705
|
-
xs: 2,
|
|
1706
|
-
small: 3,
|
|
1707
|
-
medium: 4,
|
|
1708
|
-
};
|
|
1709
|
-
// Unchecked: Rounded square outline (20x20 viewBox)
|
|
1710
|
-
const UncheckedIcon$1 = ({ size = 'medium' }) => (jsx(SvgIcon, { viewBox: "0 0 20 20", children: jsx("rect", { x: "1", y: "1", width: "18", height: "18", rx: borderRadiusConfig[size], fill: "none", stroke: "currentColor", strokeWidth: "1.5" }) }));
|
|
1711
|
-
// Checked: Filled rounded square with white checkmark
|
|
1712
|
-
// Path scaled from Untitled UI 24x24 (M20 6L9 17L4 12) to 20x20
|
|
1713
|
-
const CheckedIcon$1 = ({ size = 'medium' }) => (jsxs(SvgIcon, { viewBox: "0 0 20 20", children: [jsx("rect", { width: "20", height: "20", rx: borderRadiusConfig[size], fill: "currentColor" }), jsx("path", { d: "M15 6L8.5 13L5 9.5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" })] }));
|
|
1714
|
-
// Indeterminate: Filled rounded square with white minus
|
|
1715
|
-
// Path scaled from Untitled UI 24x24 (M5 12H19) to 20x20
|
|
1716
|
-
const IndeterminateIcon = ({ size = 'medium' }) => (jsxs(SvgIcon, { viewBox: "0 0 20 20", children: [jsx("rect", { width: "20", height: "20", rx: borderRadiusConfig[size], fill: "currentColor" }), jsx("path", { d: "M5 10H15", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", fill: "none" })] }));
|
|
1717
1775
|
const CheckboxContainer = styled('label')(({ disabled }) => ({
|
|
1718
1776
|
display: 'inline-flex',
|
|
1719
1777
|
alignItems: 'flex-start',
|
|
@@ -1746,7 +1804,7 @@ const HelperText$2 = styled('span')(({ theme, size = 'medium' }) => ({
|
|
|
1746
1804
|
lineHeight: size === 'xs' ? 1.5 : size === 'small' ? 1.4 : 1.5,
|
|
1747
1805
|
color: semanticColors.typography.bodySecondary,
|
|
1748
1806
|
}));
|
|
1749
|
-
//
|
|
1807
|
+
// xs focus-ring radius — no matching design token (box corner comes from the icon)
|
|
1750
1808
|
const FIGMA_XS_BORDER_RADIUS = 1;
|
|
1751
1809
|
const StyledCheckbox = styled(Checkbox, {
|
|
1752
1810
|
shouldForwardProp: prop => prop !== 'size',
|
|
@@ -1759,11 +1817,11 @@ const StyledCheckbox = styled(Checkbox, {
|
|
|
1759
1817
|
},
|
|
1760
1818
|
small: {
|
|
1761
1819
|
size: 16,
|
|
1762
|
-
borderRadius: borderRadius.xXS, //
|
|
1820
|
+
borderRadius: borderRadius.xXS, // focus-ring radius (small)
|
|
1763
1821
|
},
|
|
1764
1822
|
medium: {
|
|
1765
1823
|
size: 20,
|
|
1766
|
-
borderRadius: borderRadius.xS, //
|
|
1824
|
+
borderRadius: borderRadius.xS, // focus-ring radius (medium)
|
|
1767
1825
|
},
|
|
1768
1826
|
};
|
|
1769
1827
|
const config = sizeConfig[size];
|
|
@@ -1775,37 +1833,30 @@ const StyledCheckbox = styled(Checkbox, {
|
|
|
1775
1833
|
color: semanticColors.border.primary,
|
|
1776
1834
|
borderRadius: config.borderRadius,
|
|
1777
1835
|
flexShrink: 0,
|
|
1778
|
-
//
|
|
1779
|
-
|
|
1780
|
-
'
|
|
1781
|
-
backgroundColor: 'transparent',
|
|
1782
|
-
},
|
|
1836
|
+
// Suppress MUI's grey hover background
|
|
1837
|
+
'&:hover': {
|
|
1838
|
+
backgroundColor: 'transparent',
|
|
1783
1839
|
},
|
|
1784
|
-
//
|
|
1785
|
-
[
|
|
1786
|
-
|
|
1787
|
-
height: config.size,
|
|
1840
|
+
// Hover on the unchecked box — subtle blue outline affordance (enabled only)
|
|
1841
|
+
[`&:hover:not(.${checkboxClasses.checked}):not(.${checkboxClasses.indeterminate}):not(.${checkboxClasses.disabled})`]: {
|
|
1842
|
+
color: colors.digitalBlue[300],
|
|
1788
1843
|
},
|
|
1789
|
-
// Checked
|
|
1844
|
+
// Checked / Indeterminate — primary blue outline + mark
|
|
1790
1845
|
[`&.${checkboxClasses.checked}`]: {
|
|
1791
|
-
color:
|
|
1846
|
+
color: colors.digitalBlue[600],
|
|
1792
1847
|
},
|
|
1793
|
-
// Indeterminate state
|
|
1794
1848
|
[`&.${checkboxClasses.indeterminate}`]: {
|
|
1795
|
-
color:
|
|
1849
|
+
color: colors.digitalBlue[600],
|
|
1796
1850
|
},
|
|
1797
|
-
// Disabled
|
|
1851
|
+
// Disabled — enabled colors dimmed to 40%. Checked/indeterminate keep
|
|
1852
|
+
// digitalBlue[600] via the rules above; re-assert the unchecked outline
|
|
1853
|
+
// token so it beats MUI's default `.Mui-disabled` color.
|
|
1798
1854
|
[`&.${checkboxClasses.disabled}`]: {
|
|
1799
|
-
|
|
1855
|
+
opacity: 0.4,
|
|
1800
1856
|
cursor: 'not-allowed',
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
},
|
|
1805
|
-
// When indeterminate and disabled
|
|
1806
|
-
[`&.${checkboxClasses.indeterminate}`]: {
|
|
1807
|
-
color: semanticColors.border.primary,
|
|
1808
|
-
},
|
|
1857
|
+
},
|
|
1858
|
+
[`&.${checkboxClasses.disabled}:not(.${checkboxClasses.checked}):not(.${checkboxClasses.indeterminate})`]: {
|
|
1859
|
+
color: semanticColors.border.primary,
|
|
1809
1860
|
},
|
|
1810
1861
|
// Focus visible for keyboard navigation
|
|
1811
1862
|
'&.Mui-focusVisible': {
|
|
@@ -1813,11 +1864,10 @@ const StyledCheckbox = styled(Checkbox, {
|
|
|
1813
1864
|
outlineOffset: 2,
|
|
1814
1865
|
borderRadius: config.borderRadius,
|
|
1815
1866
|
},
|
|
1816
|
-
//
|
|
1867
|
+
// Size the Lucide icon (color comes from `color` → currentColor → stroke)
|
|
1817
1868
|
'& svg': {
|
|
1818
1869
|
width: config.size,
|
|
1819
1870
|
height: config.size,
|
|
1820
|
-
fill: 'currentColor',
|
|
1821
1871
|
},
|
|
1822
1872
|
};
|
|
1823
1873
|
});
|
|
@@ -1868,10 +1918,10 @@ const StyledCheckbox = styled(Checkbox, {
|
|
|
1868
1918
|
const NeoCheckbox = ({ size = 'medium', label, helperText, disabled, icon, checkedIcon, indeterminateIcon, className, ...props }) => {
|
|
1869
1919
|
// Add custom class to identify NeoCheckbox instances
|
|
1870
1920
|
const combinedClassName = className ? `neo-checkbox ${className}` : 'neo-checkbox';
|
|
1871
|
-
//
|
|
1872
|
-
const defaultIcon = icon || jsx(
|
|
1873
|
-
const defaultCheckedIcon = checkedIcon || jsx(
|
|
1874
|
-
const defaultIndeterminateIcon = indeterminateIcon || jsx(
|
|
1921
|
+
// Default icons (sized via CSS on the SVG); overridable per instance
|
|
1922
|
+
const defaultIcon = icon || jsx(Square, {});
|
|
1923
|
+
const defaultCheckedIcon = checkedIcon || jsx(SquareCheck, {});
|
|
1924
|
+
const defaultIndeterminateIcon = indeterminateIcon || jsx(SquareMinus, {});
|
|
1875
1925
|
// If no label, return just the checkbox
|
|
1876
1926
|
if (!label && !helperText) {
|
|
1877
1927
|
return (jsx(StyledCheckbox, { size: size, disabled: disabled, icon: defaultIcon, checkedIcon: defaultCheckedIcon, indeterminateIcon: defaultIndeterminateIcon, className: combinedClassName, ...props }));
|
|
@@ -2183,7 +2233,8 @@ const StyledMenuItem = styled(MenuItem)(({ theme }) => ({
|
|
|
2183
2233
|
gap: theme.spacing(2),
|
|
2184
2234
|
borderRadius: 0,
|
|
2185
2235
|
color: semanticColors.icons.default,
|
|
2186
|
-
|
|
2236
|
+
textDecoration: 'none',
|
|
2237
|
+
fontSize: theme.typography.pxToRem(typography.fontSize.default),
|
|
2187
2238
|
fontWeight: typography.fontWeight.regular,
|
|
2188
2239
|
lineHeight: `${typography.lineHeight.s}px`,
|
|
2189
2240
|
transition: theme.transitions.create(['background-color'], {
|
|
@@ -2249,7 +2300,7 @@ const Shortcut = styled('span')(({ theme }) => ({
|
|
|
2249
2300
|
/**
|
|
2250
2301
|
* NeoMenuItem - Menu item component based on MUI MenuItem
|
|
2251
2302
|
*
|
|
2252
|
-
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4159-
|
|
2303
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025-26?node-id=4159-8714
|
|
2253
2304
|
*
|
|
2254
2305
|
* @example
|
|
2255
2306
|
* ```tsx
|
|
@@ -2264,11 +2315,22 @@ const Shortcut = styled('span')(({ theme }) => ({
|
|
|
2264
2315
|
*
|
|
2265
2316
|
* // Disabled state
|
|
2266
2317
|
* <NeoMenuItem disabled>Disabled item</NeoMenuItem>
|
|
2318
|
+
*
|
|
2319
|
+
* // As an anchor — middle-click/right-click open in a new tab
|
|
2320
|
+
* <NeoMenuItem href="/api-explorer">API explorer</NeoMenuItem>
|
|
2321
|
+
*
|
|
2322
|
+
* // External link
|
|
2323
|
+
* <NeoMenuItem href="https://docs.example.com" target="_blank" rel="noopener noreferrer">
|
|
2324
|
+
* Documentation
|
|
2325
|
+
* </NeoMenuItem>
|
|
2326
|
+
*
|
|
2327
|
+
* // Client-side routing (Next.js)
|
|
2328
|
+
* <NeoMenuItem component={NextLink} href="/api-explorer">API explorer</NeoMenuItem>
|
|
2267
2329
|
* ```
|
|
2268
2330
|
*/
|
|
2269
|
-
|
|
2270
|
-
return (jsx(StyledMenuItem, { ...
|
|
2271
|
-
}
|
|
2331
|
+
function NeoMenuItem({ icon, shortcut, secondaryText, children, ...rest }) {
|
|
2332
|
+
return (jsx(StyledMenuItem, { ...rest, children: jsxs(MenuItemContent, { children: [icon && jsx(IconWrapper$1, { children: icon }), jsxs(LabelContainer$3, { children: [jsx(Label$3, { children: children }), secondaryText && jsx(SecondaryLabel, { children: secondaryText })] }), shortcut && jsx(Shortcut, { children: shortcut })] }) }));
|
|
2333
|
+
}
|
|
2272
2334
|
NeoMenuItem.displayName = 'NeoMenuItem';
|
|
2273
2335
|
|
|
2274
2336
|
/**
|
|
@@ -2544,56 +2606,24 @@ function SortedAscendingIcon() {
|
|
|
2544
2606
|
function UnsortedIcon() {
|
|
2545
2607
|
return jsx(ChevronsUpDown, { size: 16, color: semanticColors.icons.utility });
|
|
2546
2608
|
}
|
|
2547
|
-
|
|
2548
|
-
* Utility function to get DataGrid sx styles for header cells
|
|
2549
|
-
*
|
|
2550
|
-
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4212-41618
|
|
2551
|
-
*
|
|
2552
|
-
* Figma prop mappings:
|
|
2553
|
-
* - `size` → `size`: Figma "condensed" → MUI 'compact', Figma "default" → MUI 'standard', Figma "relaxed" → MUI 'comfortable'
|
|
2554
|
-
*
|
|
2555
|
-
* Design tokens used:
|
|
2556
|
-
* - Background: colors.grey[50] (#f9fafb)
|
|
2557
|
-
* - Border: semanticColors.border.primary
|
|
2558
|
-
* - Padding: 12px vertical, 24px horizontal
|
|
2559
|
-
* - Gap: 12px
|
|
2560
|
-
*
|
|
2561
|
-
*
|
|
2562
|
-
* @param size - Header row size variant (affects header cell height)
|
|
2563
|
-
* @returns SxProps for DataGrid header cells
|
|
2564
|
-
*
|
|
2565
|
-
* @example
|
|
2566
|
-
* import { getDataGridHeaderStyles, SortedDescendingIcon, SortedAscendingIcon, UnsortedIcon } from './DataGridHeaderCell'
|
|
2567
|
-
*
|
|
2568
|
-
* <DataGrid
|
|
2569
|
-
* columnHeaderHeight={38} // for compact (Figma: condensed)
|
|
2570
|
-
* sx={{
|
|
2571
|
-
* ...getDataGridHeaderStyles(),
|
|
2572
|
-
* }}
|
|
2573
|
-
* slots={{
|
|
2574
|
-
* columnSortedDescendingIcon: SortedDescendingIcon,
|
|
2575
|
-
* columnSortedAscendingIcon: SortedAscendingIcon,
|
|
2576
|
-
* columnUnsortedIcon: UnsortedIcon,
|
|
2577
|
-
* }}
|
|
2578
|
-
* rows={rows}
|
|
2579
|
-
* columns={columns}
|
|
2580
|
-
* />
|
|
2581
|
-
*/
|
|
2609
|
+
|
|
2582
2610
|
const getDataGridHeaderStyles = () => {
|
|
2583
2611
|
return {
|
|
2584
2612
|
// Header cell container styles - from Figma: bg, border, padding
|
|
2585
2613
|
// Height is set via density-specific selectors in DataGrid.tsx
|
|
2586
2614
|
[`& .${gridClasses.columnHeader}`]: {
|
|
2587
|
-
backgroundColor:
|
|
2615
|
+
backgroundColor: semanticColors.surfaces.dataGrid.header,
|
|
2588
2616
|
borderBottom: `1px solid ${semanticColors.border.primary}`,
|
|
2589
|
-
|
|
2590
|
-
|
|
2617
|
+
paddingTop: `${spacing.spacing_1_1_2}px`,
|
|
2618
|
+
paddingBottom: `${spacing.spacing_1_1_2}px`,
|
|
2619
|
+
paddingLeft: `${spacing.spacing_2}px`,
|
|
2620
|
+
paddingRight: `${spacing.spacing_2}px`,
|
|
2591
2621
|
boxSizing: 'border-box',
|
|
2592
2622
|
},
|
|
2593
2623
|
// Style the filler element to match header
|
|
2594
2624
|
// Height is set via density-specific selectors in DataGrid.tsx
|
|
2595
2625
|
[`& .${gridClasses.filler}`]: {
|
|
2596
|
-
backgroundColor:
|
|
2626
|
+
backgroundColor: semanticColors.surfaces.dataGrid.header,
|
|
2597
2627
|
borderBottom: `1px solid ${semanticColors.border.primary}`,
|
|
2598
2628
|
boxSizing: 'border-box',
|
|
2599
2629
|
},
|
|
@@ -2625,12 +2655,19 @@ const getDataGridHeaderStyles = () => {
|
|
|
2625
2655
|
},
|
|
2626
2656
|
},
|
|
2627
2657
|
},
|
|
2658
|
+
// MUI clips this container when header vertical padding leaves < 16px of content
|
|
2659
|
+
// area (e.g. compact: 38px − 24px padding = 14px). overflow:visible lets the
|
|
2660
|
+
// sort icon render at full 16px without being cropped.
|
|
2661
|
+
[`& .${gridClasses.columnHeaderTitleContainer}`]: {
|
|
2662
|
+
overflow: 'visible',
|
|
2663
|
+
lineHeight: 1,
|
|
2664
|
+
},
|
|
2628
2665
|
// Style MUI's sort icon to match Neo design (16x16)
|
|
2629
2666
|
[`& .${gridClasses.iconButtonContainer}`]: {
|
|
2630
2667
|
width: 16,
|
|
2631
2668
|
height: 16,
|
|
2632
2669
|
marginLeft: `${spacing.spacing_1_2}px`,
|
|
2633
|
-
|
|
2670
|
+
'& button': {
|
|
2634
2671
|
padding: 0,
|
|
2635
2672
|
width: 16,
|
|
2636
2673
|
height: 16,
|
|
@@ -2643,6 +2680,20 @@ const getDataGridHeaderStyles = () => {
|
|
|
2643
2680
|
},
|
|
2644
2681
|
};
|
|
2645
2682
|
};
|
|
2683
|
+
const getDataGridRowStyles = () => ({
|
|
2684
|
+
[`& .${gridClasses.row}`]: {
|
|
2685
|
+
backgroundColor: semanticColors.surfaces.dataGrid.default,
|
|
2686
|
+
},
|
|
2687
|
+
[`& .${gridClasses.row}:hover`]: {
|
|
2688
|
+
backgroundColor: semanticColors.surfaces.dataGrid.hover,
|
|
2689
|
+
},
|
|
2690
|
+
[`& .${gridClasses.row}.Mui-selected`]: {
|
|
2691
|
+
backgroundColor: semanticColors.surfaces.dataGrid.selected,
|
|
2692
|
+
},
|
|
2693
|
+
[`& .${gridClasses.row}.Mui-selected:hover`]: {
|
|
2694
|
+
backgroundColor: semanticColors.surfaces.dataGrid.selectedHover,
|
|
2695
|
+
},
|
|
2696
|
+
});
|
|
2646
2697
|
|
|
2647
2698
|
/**
|
|
2648
2699
|
* Adapter to use NeoCheckbox in DataGrid's baseCheckbox slot
|
|
@@ -2677,7 +2728,7 @@ const DataGridCheckbox = ({ slotProps, ...props }) => (jsx(NeoCheckbox, { size:
|
|
|
2677
2728
|
* - `size` → Row heights (compact: 42px, standard: 48px, comfortable: 56px) and header heights (compact: 38px, standard: 44px, comfortable: 52px)
|
|
2678
2729
|
*
|
|
2679
2730
|
* Design tokens used:
|
|
2680
|
-
* - Colors: semanticColors.border.primary, semanticColors.
|
|
2731
|
+
* - Colors: semanticColors.border.primary, semanticColors.surfaces.dataGrid.*
|
|
2681
2732
|
* - Typography: typography.fontFamily.body, typography.fontSize.sm
|
|
2682
2733
|
* - Spacing: spacing.spacing_*
|
|
2683
2734
|
*
|
|
@@ -2721,19 +2772,22 @@ function NeoDataGrid({ autoHeight = false, toolbar, slots, sx, density = 'standa
|
|
|
2721
2772
|
// See: https://github.com/mui/mui-x/issues/20107
|
|
2722
2773
|
// This must be set to prevent scroll shadow artifacts
|
|
2723
2774
|
[`& .${gridClasses.main}`]: {
|
|
2724
|
-
backgroundColor: semanticColors.surfaces.
|
|
2775
|
+
backgroundColor: semanticColors.surfaces.dataGrid.background,
|
|
2725
2776
|
},
|
|
2726
2777
|
// White background for empty/loading overlays
|
|
2727
2778
|
[`& .${gridClasses.overlay}`]: {
|
|
2728
|
-
backgroundColor: semanticColors.surfaces.
|
|
2779
|
+
backgroundColor: semanticColors.surfaces.dataGrid.background,
|
|
2729
2780
|
},
|
|
2730
2781
|
...getDataGridHeaderStyles(),
|
|
2782
|
+
...getDataGridRowStyles(),
|
|
2731
2783
|
border: `1px solid ${semanticColors.border.secondary}`,
|
|
2732
|
-
// Style row selection checkboxes to match header (16px, proper spacing)
|
|
2784
|
+
// Style row selection checkboxes to match header (16px, proper spacing).
|
|
2785
|
+
// Target `& svg` (not `.MuiSvgIcon-root`) so the rule also matches the
|
|
2786
|
+
// lucide `<svg>` icons NeoCheckbox renders, mirroring the header rule.
|
|
2733
2787
|
[`& .${gridClasses.cellCheckbox}`]: {
|
|
2734
2788
|
[`& .${checkboxClasses.root}`]: {
|
|
2735
2789
|
padding: `${spacing.spacing_1}px`,
|
|
2736
|
-
|
|
2790
|
+
'& svg': {
|
|
2737
2791
|
width: 16,
|
|
2738
2792
|
height: 16,
|
|
2739
2793
|
},
|
|
@@ -2782,7 +2836,7 @@ function NeoDataGridColumnsButton() {
|
|
|
2782
2836
|
}
|
|
2783
2837
|
NeoDataGridColumnsButton.displayName = 'NeoDataGridColumnsButton';
|
|
2784
2838
|
|
|
2785
|
-
const sizeStyles = {
|
|
2839
|
+
const sizeStyles$1 = {
|
|
2786
2840
|
small: {
|
|
2787
2841
|
height: 16,
|
|
2788
2842
|
minWidth: 16,
|
|
@@ -2848,16 +2902,18 @@ const filledColorStyles = {
|
|
|
2848
2902
|
violet: colors.violet[500],
|
|
2849
2903
|
beta: colors.digitalBlue[300],
|
|
2850
2904
|
};
|
|
2851
|
-
const StyledChip$
|
|
2905
|
+
const StyledChip$2 = styled(Chip)(({ theme, size, variant, color }) => ({
|
|
2852
2906
|
padding: 0,
|
|
2853
2907
|
boxSizing: 'border-box',
|
|
2854
2908
|
borderRadius: borderRadius.full,
|
|
2855
2909
|
fontSize: theme.typography.pxToRem(typography.fontSize.xs),
|
|
2856
2910
|
lineHeight: 1,
|
|
2857
2911
|
fontWeight: typography.fontWeight.medium,
|
|
2858
|
-
|
|
2912
|
+
overflow: 'visible',
|
|
2913
|
+
...(size && sizeStyles$1[size]),
|
|
2859
2914
|
[`& .${chipClasses.label}`]: {
|
|
2860
2915
|
padding: 0,
|
|
2916
|
+
overflow: 'visible',
|
|
2861
2917
|
},
|
|
2862
2918
|
...(variant === 'outlined' &&
|
|
2863
2919
|
color &&
|
|
@@ -2882,7 +2938,7 @@ const StyledChip$1 = styled(Chip)(({ theme, size, variant, color }) => ({
|
|
|
2882
2938
|
* - TEXT Label → label prop
|
|
2883
2939
|
*/
|
|
2884
2940
|
function NeoTag({ size = 'small', variant = 'outlined', intent = 'default', ...props }) {
|
|
2885
|
-
return jsx(StyledChip$
|
|
2941
|
+
return jsx(StyledChip$2, { size: size, variant: variant, color: intent, ...props });
|
|
2886
2942
|
}
|
|
2887
2943
|
NeoTag.displayName = 'NeoTag';
|
|
2888
2944
|
|
|
@@ -2941,7 +2997,7 @@ const LabelContainer$2 = styled('div')({
|
|
|
2941
2997
|
alignItems: 'center',
|
|
2942
2998
|
gap: `${spacing.spacing_1_2}px`,
|
|
2943
2999
|
});
|
|
2944
|
-
const LabelText = styled('p')({
|
|
3000
|
+
const LabelText$1 = styled('p')({
|
|
2945
3001
|
fontFamily: `${typography.fontFamily.body}, sans-serif`,
|
|
2946
3002
|
fontSize: typography.fontSize.sm,
|
|
2947
3003
|
fontWeight: typography.fontWeight.semiBold, // Always semiBold (600)
|
|
@@ -2970,7 +3026,7 @@ const IconWrapper = styled('div')({
|
|
|
2970
3026
|
},
|
|
2971
3027
|
});
|
|
2972
3028
|
function NeoDataGridHeaderLabel({ children, helpTooltip, className, }) {
|
|
2973
|
-
return (jsxs(LabelContainer$2, { className: className, "data-neo-header-label": true, children: [children && jsx(LabelText, { children: children }), helpTooltip && (jsx(Tooltip, { title: helpTooltip, placement: "top", children: jsx(IconWrapper, { children: jsx(CircleQuestionMark, {}) }) }))] }));
|
|
3029
|
+
return (jsxs(LabelContainer$2, { className: className, "data-neo-header-label": true, children: [children && jsx(LabelText$1, { children: children }), helpTooltip && (jsx(Tooltip, { title: helpTooltip, placement: "top", children: jsx(IconWrapper, { children: jsx(CircleQuestionMark, {}) }) }))] }));
|
|
2974
3030
|
}
|
|
2975
3031
|
|
|
2976
3032
|
/**
|
|
@@ -3508,7 +3564,8 @@ const StyledNavButton = styled(IconButton, {
|
|
|
3508
3564
|
*/
|
|
3509
3565
|
const NeoIconButton = ({ size = 'medium', variant = 'tertiary', active = false, loading, children, ...props }) => {
|
|
3510
3566
|
if (variant === 'nav') {
|
|
3511
|
-
|
|
3567
|
+
const { color, ...navProps } = props;
|
|
3568
|
+
return (jsx(StyledNavButton, { size: size, active: active, disableRipple: true, ...navProps, children: children }));
|
|
3512
3569
|
}
|
|
3513
3570
|
return (jsx(StyledIconOnlyButton, { variant: variant, size: size, loading: loading, ...props, children: children }));
|
|
3514
3571
|
};
|
|
@@ -3761,6 +3818,20 @@ const NeoDatePicker = ({ type = 'single', open, label, value, rangeValue, onChan
|
|
|
3761
3818
|
};
|
|
3762
3819
|
NeoDatePicker.displayName = 'NeoDatePicker';
|
|
3763
3820
|
|
|
3821
|
+
/**
|
|
3822
|
+
* NeoDatePickerListItem
|
|
3823
|
+
*
|
|
3824
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4176-8521
|
|
3825
|
+
*/
|
|
3826
|
+
const NeoDatePickerListItem = styled('div')({});
|
|
3827
|
+
|
|
3828
|
+
/**
|
|
3829
|
+
* NeoDatePickerMenu
|
|
3830
|
+
*
|
|
3831
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4176-8593
|
|
3832
|
+
*/
|
|
3833
|
+
const NeoDatePickerMenu = styled('div')({});
|
|
3834
|
+
|
|
3764
3835
|
const StyledDivider = styled(Divider)(({ theme }) => ({
|
|
3765
3836
|
borderColor: semanticColors.border.secondary,
|
|
3766
3837
|
marginTop: theme.spacing(1),
|
|
@@ -3801,26 +3872,34 @@ const sizeMap = {
|
|
|
3801
3872
|
medium: 10,
|
|
3802
3873
|
large: 12,
|
|
3803
3874
|
};
|
|
3804
|
-
const
|
|
3875
|
+
const StyledDot = styled('span', {
|
|
3876
|
+
shouldForwardProp: prop => prop !== 'ownerState',
|
|
3877
|
+
})(({ ownerState }) => {
|
|
3805
3878
|
const size = sizeMap[ownerState.size];
|
|
3806
|
-
const
|
|
3879
|
+
const palette = semanticColors.status[ownerState.color];
|
|
3807
3880
|
return {
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3881
|
+
display: 'inline-flex',
|
|
3882
|
+
alignItems: 'center',
|
|
3883
|
+
justifyContent: 'center',
|
|
3884
|
+
width: size,
|
|
3885
|
+
height: size,
|
|
3886
|
+
minWidth: size,
|
|
3887
|
+
borderRadius: '50%',
|
|
3888
|
+
flexShrink: 0,
|
|
3889
|
+
boxSizing: 'border-box',
|
|
3890
|
+
backgroundColor: palette.default,
|
|
3891
|
+
color: semanticColors.typography.tooltip,
|
|
3892
|
+
...(ownerState.variant === 'outline' && {
|
|
3893
|
+
border: `3px solid ${palette.light}`,
|
|
3894
|
+
}),
|
|
3895
|
+
'& > svg': {
|
|
3896
|
+
width: '70%',
|
|
3897
|
+
height: '70%',
|
|
3819
3898
|
},
|
|
3820
3899
|
};
|
|
3821
3900
|
});
|
|
3822
3901
|
/**
|
|
3823
|
-
* NeoDot - Status indicator dot
|
|
3902
|
+
* NeoDot - Status indicator dot.
|
|
3824
3903
|
*
|
|
3825
3904
|
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4163-3577
|
|
3826
3905
|
*
|
|
@@ -3829,26 +3908,8 @@ const StyledBadge = styled(Badge)(({ ownerState }) => {
|
|
|
3829
3908
|
* - outline (False|True) → variant prop (solid|outline)
|
|
3830
3909
|
* - Color is configurable via color prop (success|error|warning|info|neutral)
|
|
3831
3910
|
*/
|
|
3832
|
-
const NeoDot = ({ size = 'medium', variant = 'solid', color = 'neutral', ...props }) => {
|
|
3833
|
-
|
|
3834
|
-
const mediumColor = semanticColors.status[color].default;
|
|
3835
|
-
const lightColor = semanticColors.status[color].light;
|
|
3836
|
-
// For outline variant, use SVG for precise control
|
|
3837
|
-
const renderDot = () => {
|
|
3838
|
-
if (variant === 'outline') {
|
|
3839
|
-
// SVG approach: outer circle with light fill, inner circle with medium fill
|
|
3840
|
-
// Stroke width of ~3px creates the ring effect
|
|
3841
|
-
const strokeWidth = 3;
|
|
3842
|
-
const radius = dotSize / 2;
|
|
3843
|
-
const innerRadius = radius - strokeWidth;
|
|
3844
|
-
return (jsxs("svg", { width: dotSize, height: dotSize, viewBox: `0 0 ${dotSize} ${dotSize}`, style: {
|
|
3845
|
-
display: 'block',
|
|
3846
|
-
borderRadius: '50%',
|
|
3847
|
-
}, role: "img", "aria-label": `${color} status indicator`, children: [jsx("title", { children: `${color} status indicator` }), jsx("circle", { cx: radius, cy: radius, r: radius, fill: lightColor }), jsx("circle", { cx: radius, cy: radius, r: innerRadius, fill: mediumColor })] }));
|
|
3848
|
-
}
|
|
3849
|
-
return jsx("span", { style: { display: 'inline-block', width: 0, height: 0 } });
|
|
3850
|
-
};
|
|
3851
|
-
return (jsx(StyledBadge, { ...props, ownerState: { size, variant, color }, variant: "dot", children: renderDot() }));
|
|
3911
|
+
const NeoDot = ({ size = 'medium', variant = 'solid', color = 'neutral', children, ...props }) => {
|
|
3912
|
+
return (jsx(StyledDot, { ...props, ownerState: { size, variant, color }, role: "img", "aria-label": props['aria-label'] ?? `${color} status indicator`, children: children }));
|
|
3852
3913
|
};
|
|
3853
3914
|
NeoDot.displayName = 'NeoDot';
|
|
3854
3915
|
|
|
@@ -3930,8 +3991,57 @@ const NeoDownloadToast = ({ title, fileName, progress, showClose = true, showPau
|
|
|
3930
3991
|
};
|
|
3931
3992
|
NeoDownloadToast.displayName = 'NeoDownloadToast';
|
|
3932
3993
|
|
|
3994
|
+
const buildFilledIcon = ({ displayName, fillColor, body, knockout }) => {
|
|
3995
|
+
const Component = (props) => (jsxs(SvgIcon, { viewBox: "0 0 16 16", ...props, children: [jsx("g", { fill: fillColor, children: body }), jsx("g", { stroke: "#FFFFFF", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", fill: "none", children: knockout })] }));
|
|
3996
|
+
Component.displayName = displayName;
|
|
3997
|
+
return Component;
|
|
3998
|
+
};
|
|
3999
|
+
const CIRCLE_BODY = (jsx("path", { d: "M8.00001 14.6666C11.6819 14.6666 14.6667 11.6818 14.6667 7.99992C14.6667 4.31802 11.6819 1.33325 8.00001 1.33325C4.31811 1.33325 1.33334 4.31802 1.33334 7.99992C1.33334 11.6818 4.31811 14.6666 8.00001 14.6666Z" }));
|
|
4000
|
+
const NeoFilledSuccess = buildFilledIcon({
|
|
4001
|
+
displayName: 'NeoFilledSuccess',
|
|
4002
|
+
fillColor: '#3B8948',
|
|
4003
|
+
body: CIRCLE_BODY,
|
|
4004
|
+
knockout: jsx("path", { d: "M6 8.00008L7.33333 9.33341L10 6.66675" }),
|
|
4005
|
+
});
|
|
4006
|
+
const NeoFilledQueued = buildFilledIcon({
|
|
4007
|
+
displayName: 'NeoFilledQueued',
|
|
4008
|
+
fillColor: '#992FB9',
|
|
4009
|
+
body: CIRCLE_BODY,
|
|
4010
|
+
knockout: jsx("path", { d: "M8 4V8L10.6667 9.33333" }),
|
|
4011
|
+
});
|
|
4012
|
+
const NeoFilledInfo = buildFilledIcon({
|
|
4013
|
+
displayName: 'NeoFilledInfo',
|
|
4014
|
+
fillColor: '#2F42FF',
|
|
4015
|
+
body: CIRCLE_BODY,
|
|
4016
|
+
knockout: (jsxs(Fragment, { children: [jsx("path", { d: "M8 10.6667V8" }), jsx("path", { d: "M8 5.33325H8.00667" })] })),
|
|
4017
|
+
});
|
|
4018
|
+
const NeoFilledWarning = buildFilledIcon({
|
|
4019
|
+
displayName: 'NeoFilledWarning',
|
|
4020
|
+
fillColor: '#BD9319',
|
|
4021
|
+
body: (jsx("path", { d: "M14.4867 12L9.15335 2.66665C9.03706 2.46146 8.86842 2.29078 8.66463 2.17203C8.46084 2.05329 8.22921 1.99072 7.99335 1.99072C7.75749 1.99072 7.52585 2.05329 7.32206 2.17203C7.11828 2.29078 6.94964 2.46146 6.83335 2.66665L1.50001 12C1.38247 12.2036 1.32083 12.4346 1.32135 12.6697C1.32187 12.9047 1.38453 13.1355 1.50298 13.3385C1.62142 13.5416 1.79145 13.7097 1.99581 13.8259C2.20018 13.942 2.43162 14.0021 2.66668 14H13.3333C13.5673 13.9997 13.797 13.938 13.9995 13.8208C14.202 13.7037 14.3702 13.5354 14.487 13.3327C14.6039 13.1301 14.6654 12.9002 14.6653 12.6663C14.6653 12.4324 14.6036 12.2026 14.4867 12Z" })),
|
|
4022
|
+
knockout: (jsxs(Fragment, { children: [jsx("path", { d: "M8 6V8.66667" }), jsx("path", { d: "M8 11.3333H8.00667" })] })),
|
|
4023
|
+
});
|
|
4024
|
+
const NeoFilledError = buildFilledIcon({
|
|
4025
|
+
displayName: 'NeoFilledError',
|
|
4026
|
+
fillColor: '#CB3446',
|
|
4027
|
+
body: (jsx("path", { d: "M10.208 1.33325C10.5616 1.33333 10.9007 1.47385 11.1507 1.72392L14.276 4.84925C14.5261 5.09924 14.6666 5.43832 14.6667 5.79192V10.2079C14.6666 10.5615 14.5261 10.9006 14.276 11.1506L11.1507 14.2759C10.9007 14.526 10.5616 14.6665 10.208 14.6666H5.79201C5.43842 14.6665 5.09933 14.526 4.84934 14.2759L1.72401 11.1506C1.47394 10.9006 1.33342 10.5615 1.33334 10.2079V5.79192C1.33342 5.43832 1.47394 5.09924 1.72401 4.84925L4.84934 1.72392C5.09933 1.47385 5.43842 1.33333 5.79201 1.33325H10.208Z" })),
|
|
4028
|
+
knockout: (jsxs(Fragment, { children: [jsx("path", { d: "M8 5.33325V7.99992" }), jsx("path", { d: "M8 10.6667H8.00667" })] })),
|
|
4029
|
+
});
|
|
4030
|
+
const NeoFilledNeutral = buildFilledIcon({
|
|
4031
|
+
displayName: 'NeoFilledNeutral',
|
|
4032
|
+
fillColor: '#6B7280',
|
|
4033
|
+
body: CIRCLE_BODY,
|
|
4034
|
+
knockout: jsx("path", { d: "M5.33334 8H10.6667" }),
|
|
4035
|
+
});
|
|
4036
|
+
const NeoFilledCanceled = buildFilledIcon({
|
|
4037
|
+
displayName: 'NeoFilledCanceled',
|
|
4038
|
+
fillColor: '#7B7263',
|
|
4039
|
+
body: CIRCLE_BODY,
|
|
4040
|
+
knockout: (jsxs(Fragment, { children: [jsx("path", { d: "M10 6L6 10" }), jsx("path", { d: "M6 6L10 10" })] })),
|
|
4041
|
+
});
|
|
4042
|
+
|
|
3933
4043
|
const filterChipOnlyProps = ['selected', 'expanded', 'selectedLabel', 'count', 'onClear'];
|
|
3934
|
-
const StyledChip = styled(Chip, {
|
|
4044
|
+
const StyledChip$1 = styled(Chip, {
|
|
3935
4045
|
shouldForwardProp: prop => !filterChipOnlyProps.includes(prop),
|
|
3936
4046
|
})(({ theme, selected }) => ({
|
|
3937
4047
|
borderRadius: borderRadius.full,
|
|
@@ -4021,7 +4131,7 @@ const CountBadge = styled('span')(({ theme }) => ({
|
|
|
4021
4131
|
*/
|
|
4022
4132
|
const NeoFilterChip = ({ label, selected = false, expanded, selectedLabel, count = 0, onClear, onClick, ...props }) => {
|
|
4023
4133
|
const chipLabel = selected ? (jsxs(LabelContent, { children: [jsxs(TextStack, { children: [jsx(HeaderLabel, { children: label }), jsx(SelectedLabel, { children: selectedLabel ?? label })] }), count > 0 && jsx(CountBadge, { children: count })] })) : (label);
|
|
4024
|
-
return (jsx(StyledChip, { label: chipLabel, selected: selected, clickable: true, onClick: onClick, onDelete: selected && onClear ? onClear : undefined, deleteIcon: jsx(X, { size: 24 }), "aria-expanded": expanded, ...props }));
|
|
4134
|
+
return (jsx(StyledChip$1, { label: chipLabel, selected: selected, clickable: true, onClick: onClick, onDelete: selected && onClear ? onClear : undefined, deleteIcon: jsx(X, { size: 24 }), "aria-expanded": expanded, ...props }));
|
|
4025
4135
|
};
|
|
4026
4136
|
NeoFilterChip.displayName = 'NeoFilterChip';
|
|
4027
4137
|
|
|
@@ -4062,6 +4172,7 @@ const StyledFooter = styled(Box, {
|
|
|
4062
4172
|
shouldForwardProp: prop => prop !== 'showShadow',
|
|
4063
4173
|
})(({ theme, showShadow = false }) => ({
|
|
4064
4174
|
backgroundColor: semanticColors.surfaces.white,
|
|
4175
|
+
borderTop: `1px solid ${semanticColors.border.primary}`,
|
|
4065
4176
|
display: 'flex',
|
|
4066
4177
|
alignItems: 'center',
|
|
4067
4178
|
justifyContent: 'center',
|
|
@@ -4387,13 +4498,7 @@ function NeoInfiniteScrollGrid({ onLoadMore, hasNextPage = true, loadMoreAtScrol
|
|
|
4387
4498
|
showShadow: isScrolling,
|
|
4388
4499
|
...userSlotProps?.footer,
|
|
4389
4500
|
},
|
|
4390
|
-
}, sx:
|
|
4391
|
-
// Add border at bottom of rows section (above footer)
|
|
4392
|
-
[`& .${gridClasses.virtualScrollerContent}`]: {
|
|
4393
|
-
borderBottom: `1px solid ${semanticColors.border.primary}`,
|
|
4394
|
-
},
|
|
4395
|
-
...userSx,
|
|
4396
|
-
}, pagination: false, ...props,
|
|
4501
|
+
}, sx: userSx, pagination: false, ...props,
|
|
4397
4502
|
// Only show loading overlay when loading AND no rows exist yet
|
|
4398
4503
|
// This keeps existing rows visible while loading more data (footer shows loading spinner)
|
|
4399
4504
|
loading: props.loading && !hasRows }));
|
|
@@ -4819,87 +4924,127 @@ const NeoListItem = ({ size = 'medium', primaryText, secondaryText, badge, icon,
|
|
|
4819
4924
|
};
|
|
4820
4925
|
NeoListItem.displayName = 'NeoListItem';
|
|
4821
4926
|
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
color: semanticColors.icons.default,
|
|
4927
|
+
const StyledListItemButton = styled(ListItemButton, {
|
|
4928
|
+
shouldForwardProp: prop => prop !== 'listVariant',
|
|
4929
|
+
})(({ theme, listVariant = 'card' }) => listVariant === 'nav' ? navVariantStyles(theme) : cardVariantStyles(theme));
|
|
4930
|
+
// Nav variant — sidebar list item: no border, compact, subtle highlights.
|
|
4931
|
+
// Renders children inline; no ListItemIcon/ListItemText wrappers required.
|
|
4932
|
+
function navVariantStyles(theme) {
|
|
4933
|
+
return {
|
|
4934
|
+
display: 'flex',
|
|
4935
|
+
alignItems: 'center',
|
|
4936
|
+
gap: spacing.spacing_2,
|
|
4937
|
+
borderRadius: borderRadius.s,
|
|
4938
|
+
paddingTop: spacing.spacing_1,
|
|
4939
|
+
paddingBottom: spacing.spacing_1,
|
|
4940
|
+
paddingLeft: spacing.spacing_2,
|
|
4941
|
+
paddingRight: spacing.spacing_2,
|
|
4942
|
+
border: 'none',
|
|
4943
|
+
color: semanticColors.typography.bodySecondary,
|
|
4944
|
+
backgroundColor: 'transparent',
|
|
4945
|
+
transition: theme.transitions.create(['background-color', 'color']),
|
|
4946
|
+
[`&.${listItemButtonClasses.selected}`]: {
|
|
4947
|
+
backgroundColor: semanticColors.surfaces.activeHighlight,
|
|
4948
|
+
color: semanticColors.typography.body,
|
|
4949
|
+
'&:hover': {
|
|
4950
|
+
backgroundColor: semanticColors.surfaces.activeHighlight,
|
|
4951
|
+
},
|
|
4848
4952
|
},
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4953
|
+
[`&:not(.${listItemButtonClasses.selected}):not(.${listItemButtonClasses.disabled})`]: {
|
|
4954
|
+
'&:hover': {
|
|
4955
|
+
backgroundColor: semanticColors.surfaces.listHover,
|
|
4956
|
+
color: semanticColors.typography.body,
|
|
4957
|
+
},
|
|
4852
4958
|
},
|
|
4853
|
-
[
|
|
4854
|
-
|
|
4959
|
+
[`&.${listItemButtonClasses.focusVisible}`]: {
|
|
4960
|
+
outline: `2px solid ${semanticColors.border.focus}`,
|
|
4961
|
+
outlineOffset: -2,
|
|
4855
4962
|
},
|
|
4856
|
-
|
|
4857
|
-
// Deselected (default) state
|
|
4858
|
-
[`&:not(.${listItemButtonClasses.selected}):not(.${listItemButtonClasses.disabled})`]: {
|
|
4859
|
-
'&:hover': {
|
|
4860
|
-
backgroundColor: colors.grey[50],
|
|
4861
|
-
},
|
|
4862
|
-
[`& .${listItemIconClasses.root}`]: {
|
|
4863
|
-
color: semanticColors.icons.disabled,
|
|
4864
|
-
},
|
|
4865
|
-
[`& .${listItemTextClasses.primary}`]: {
|
|
4866
|
-
color: semanticColors.buttons.tertiary.disabled,
|
|
4867
|
-
},
|
|
4868
|
-
[`& .${listItemTextClasses.secondary}`]: {
|
|
4963
|
+
[`&.${listItemButtonClasses.disabled}`]: {
|
|
4869
4964
|
color: semanticColors.typography.button.disabled,
|
|
4965
|
+
opacity: 1,
|
|
4870
4966
|
},
|
|
4871
|
-
}
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4967
|
+
};
|
|
4968
|
+
}
|
|
4969
|
+
function cardVariantStyles(theme) {
|
|
4970
|
+
return {
|
|
4971
|
+
display: 'flex',
|
|
4972
|
+
alignItems: 'center',
|
|
4973
|
+
gap: spacing.spacing_2,
|
|
4974
|
+
borderRadius: borderRadius.m,
|
|
4975
|
+
paddingTop: spacing.spacing_1,
|
|
4976
|
+
paddingBottom: spacing.spacing_1,
|
|
4977
|
+
paddingLeft: spacing.spacing_3_4,
|
|
4978
|
+
paddingRight: spacing.spacing_3_4,
|
|
4979
|
+
border: `1px solid ${semanticColors.border.primary}`,
|
|
4877
4980
|
backgroundColor: theme.palette.common.white,
|
|
4878
|
-
[
|
|
4879
|
-
|
|
4880
|
-
}
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4981
|
+
transition: theme.transitions.create(['border', 'background-color']),
|
|
4982
|
+
// Active (selected) state
|
|
4983
|
+
[`&.${listItemButtonClasses.selected}`]: {
|
|
4984
|
+
border: `2px solid ${semanticColors.buttons.primary.default}`,
|
|
4985
|
+
backgroundColor: theme.palette.common.white,
|
|
4986
|
+
'&:hover': {
|
|
4987
|
+
backgroundColor: theme.palette.common.white,
|
|
4988
|
+
},
|
|
4989
|
+
// Icon color in selected state
|
|
4990
|
+
[`& .${listItemIconClasses.root}`]: {
|
|
4991
|
+
color: semanticColors.icons.default,
|
|
4992
|
+
},
|
|
4993
|
+
// Text colors in selected state
|
|
4994
|
+
[`& .${listItemTextClasses.primary}`]: {
|
|
4995
|
+
color: colors.grey[800],
|
|
4996
|
+
},
|
|
4997
|
+
[`& .${listItemTextClasses.secondary}`]: {
|
|
4998
|
+
color: semanticColors.typography.bodySecondary,
|
|
4999
|
+
},
|
|
4886
5000
|
},
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
5001
|
+
// Deselected (default) state
|
|
5002
|
+
[`&:not(.${listItemButtonClasses.selected}):not(.${listItemButtonClasses.disabled})`]: {
|
|
5003
|
+
'&:hover': {
|
|
5004
|
+
backgroundColor: colors.grey[50],
|
|
5005
|
+
},
|
|
5006
|
+
[`& .${listItemIconClasses.root}`]: {
|
|
5007
|
+
color: semanticColors.icons.disabled,
|
|
5008
|
+
},
|
|
5009
|
+
[`& .${listItemTextClasses.primary}`]: {
|
|
5010
|
+
color: semanticColors.buttons.tertiary.disabled,
|
|
5011
|
+
},
|
|
5012
|
+
[`& .${listItemTextClasses.secondary}`]: {
|
|
5013
|
+
color: semanticColors.typography.button.disabled,
|
|
5014
|
+
},
|
|
4894
5015
|
},
|
|
4895
|
-
|
|
4896
|
-
|
|
5016
|
+
// Focus state
|
|
5017
|
+
[`&.${listItemButtonClasses.focusVisible}`]: {
|
|
5018
|
+
outline: `2px solid ${semanticColors.buttons.primary.default}`,
|
|
5019
|
+
outlineOffset: 2,
|
|
5020
|
+
border: `2px solid ${semanticColors.buttons.primary.default}`,
|
|
5021
|
+
backgroundColor: theme.palette.common.white,
|
|
5022
|
+
[`& .${listItemIconClasses.root}`]: {
|
|
5023
|
+
color: semanticColors.icons.default,
|
|
5024
|
+
},
|
|
5025
|
+
[`& .${listItemTextClasses.primary}`]: {
|
|
5026
|
+
color: colors.grey[800],
|
|
5027
|
+
},
|
|
5028
|
+
[`& .${listItemTextClasses.secondary}`]: {
|
|
5029
|
+
color: semanticColors.typography.bodySecondary,
|
|
5030
|
+
},
|
|
4897
5031
|
},
|
|
4898
|
-
|
|
4899
|
-
|
|
5032
|
+
// Disabled state
|
|
5033
|
+
[`&.${listItemButtonClasses.disabled}`]: {
|
|
5034
|
+
backgroundColor: colors.grey[50],
|
|
5035
|
+
opacity: 1, // Override MUI default opacity
|
|
5036
|
+
[`& .${listItemIconClasses.root}`]: {
|
|
5037
|
+
color: semanticColors.icons.disabled,
|
|
5038
|
+
},
|
|
5039
|
+
[`& .${listItemTextClasses.primary}`]: {
|
|
5040
|
+
color: colors.grey[300],
|
|
5041
|
+
},
|
|
5042
|
+
[`& .${listItemTextClasses.secondary}`]: {
|
|
5043
|
+
color: colors.grey[300],
|
|
5044
|
+
},
|
|
4900
5045
|
},
|
|
4901
|
-
}
|
|
4902
|
-
}
|
|
5046
|
+
};
|
|
5047
|
+
}
|
|
4903
5048
|
/**
|
|
4904
5049
|
* NeoListItemButton - Selectable list item with icon and text
|
|
4905
5050
|
*
|
|
@@ -4943,8 +5088,8 @@ const StyledListItemButton = styled(ListItemButton)(({ theme }) => ({
|
|
|
4943
5088
|
* - colors.grey[300] (#d1d5db) - Disabled text
|
|
4944
5089
|
* - colors.grey[50] (#f9fafb) - Disabled background
|
|
4945
5090
|
*/
|
|
4946
|
-
const NeoListItemButton = ({ children, selected = false, disabled = false, ...props }) => {
|
|
4947
|
-
return (jsx(StyledListItemButton, { selected: selected, disabled: disabled, ...props, children: children }));
|
|
5091
|
+
const NeoListItemButton = ({ children, selected = false, disabled = false, variant = 'card', ...props }) => {
|
|
5092
|
+
return (jsx(StyledListItemButton, { selected: selected, disabled: disabled, listVariant: variant, ...props, children: children }));
|
|
4948
5093
|
};
|
|
4949
5094
|
NeoListItemButton.displayName = 'NeoListItemButton';
|
|
4950
5095
|
|
|
@@ -4954,7 +5099,6 @@ const StyledMenu = styled(Menu)(({ theme }) => ({
|
|
|
4954
5099
|
borderRadius: borderRadius.s,
|
|
4955
5100
|
border: `1px solid ${semanticColors.border.primary}`,
|
|
4956
5101
|
boxShadow: `${shadows.dropdown.x}px ${shadows.dropdown.y}px ${shadows.dropdown.blur}px ${shadows.dropdown.spread}px ${shadows.dropdown.shadow}`,
|
|
4957
|
-
minWidth: 200,
|
|
4958
5102
|
marginTop: theme.spacing(1),
|
|
4959
5103
|
paddingTop: theme.spacing(1),
|
|
4960
5104
|
paddingBottom: theme.spacing(1),
|
|
@@ -5181,9 +5325,8 @@ NeoModalFooter.displayName = 'NeoModalFooter';
|
|
|
5181
5325
|
const NavigationAvatarContainer = styled('div')({
|
|
5182
5326
|
display: 'flex',
|
|
5183
5327
|
boxSizing: 'border-box',
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
padding: spacing.spacing_3_4,
|
|
5328
|
+
padding: spacing.spacing_1_2,
|
|
5329
|
+
aspectRatio: '1 / 1',
|
|
5187
5330
|
justifyContent: 'center',
|
|
5188
5331
|
alignItems: 'center',
|
|
5189
5332
|
borderRadius: '50%',
|
|
@@ -5196,16 +5339,103 @@ const NavigationAvatarContainer = styled('div')({
|
|
|
5196
5339
|
/**
|
|
5197
5340
|
* NeoNavigationAvatar - Compact avatar for navigation contexts
|
|
5198
5341
|
*
|
|
5199
|
-
* Wraps NeoGeneralAvatar (size="small") in a
|
|
5200
|
-
* providing
|
|
5342
|
+
* Wraps NeoGeneralAvatar (size="small") in a 40px container,
|
|
5343
|
+
* providing an interactive area for navigation UI.
|
|
5201
5344
|
*
|
|
5202
5345
|
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=11325-102
|
|
5203
5346
|
*/
|
|
5204
|
-
const NeoNavigationAvatar = ({
|
|
5205
|
-
return (jsx(NavigationAvatarContainer, { children: jsx(NeoGeneralAvatar, { size: "small",
|
|
5347
|
+
const NeoNavigationAvatar = ({ children, ...props }) => {
|
|
5348
|
+
return (jsx(NavigationAvatarContainer, { children: jsx(NeoGeneralAvatar, { size: "small", ...props, children: children }) }));
|
|
5206
5349
|
};
|
|
5207
5350
|
NeoNavigationAvatar.displayName = 'NeoNavigationAvatar';
|
|
5208
5351
|
|
|
5352
|
+
const NeoSideNavContext = createContext({
|
|
5353
|
+
collapsed: false,
|
|
5354
|
+
});
|
|
5355
|
+
const useNeoSideNav = () => useContext(NeoSideNavContext);
|
|
5356
|
+
|
|
5357
|
+
/**
|
|
5358
|
+
* Variant color configuration
|
|
5359
|
+
*/
|
|
5360
|
+
const variantConfig = {
|
|
5361
|
+
light: {
|
|
5362
|
+
backgroundColor: semanticColors.surfaces.tooltip, // #4b5563 - medium gray
|
|
5363
|
+
color: semanticColors.typography.tooltip, // #ffffff - white
|
|
5364
|
+
},
|
|
5365
|
+
dark: {
|
|
5366
|
+
backgroundColor: colors.grey[50], // #f9fafb - very light gray
|
|
5367
|
+
color: colors.grey[800], // #1f2937 - dark gray
|
|
5368
|
+
},
|
|
5369
|
+
brand: {
|
|
5370
|
+
backgroundColor: colors.digitalBlue[800], // #131e7a - dark blue
|
|
5371
|
+
color: semanticColors.typography.tooltip, // #ffffff - white
|
|
5372
|
+
},
|
|
5373
|
+
};
|
|
5374
|
+
/**
|
|
5375
|
+
* Styled MUI Tooltip with Neo design system tokens
|
|
5376
|
+
*/
|
|
5377
|
+
const StyledTooltip$1 = styled(Tooltip, {
|
|
5378
|
+
shouldForwardProp: prop => prop !== 'variant' && prop !== 'description',
|
|
5379
|
+
})(({ variant = 'light', description }) => {
|
|
5380
|
+
const hasDescription = Boolean(description);
|
|
5381
|
+
const variantStyles = variantConfig[variant];
|
|
5382
|
+
return {
|
|
5383
|
+
// Style the tooltip content
|
|
5384
|
+
[`& .${tooltipClasses.tooltip}`]: {
|
|
5385
|
+
backgroundColor: variantStyles.backgroundColor,
|
|
5386
|
+
color: variantStyles.color,
|
|
5387
|
+
fontSize: typography.fontSize.xs,
|
|
5388
|
+
fontWeight: typography.fontWeight.medium,
|
|
5389
|
+
lineHeight: hasDescription ? 1.5 : 1,
|
|
5390
|
+
borderRadius: hasDescription ? borderRadius.s : borderRadius.xS,
|
|
5391
|
+
padding: hasDescription ? spacing.spacing_1_1_2 : `0 ${spacing.spacing_1}px`,
|
|
5392
|
+
...(hasDescription && {
|
|
5393
|
+
maxWidth: 296,
|
|
5394
|
+
}),
|
|
5395
|
+
...(!hasDescription && {
|
|
5396
|
+
height: spacing.spacing_3_1_4,
|
|
5397
|
+
display: 'flex',
|
|
5398
|
+
alignItems: 'center',
|
|
5399
|
+
justifyContent: 'center',
|
|
5400
|
+
}),
|
|
5401
|
+
boxShadow: `${shadows.neutral.medium.x}px ${shadows.neutral.medium.y}px ${shadows.neutral.medium.blur}px ${shadows.neutral.medium.spread}px ${shadows.neutral.medium.shadow}`,
|
|
5402
|
+
},
|
|
5403
|
+
// Style the arrow
|
|
5404
|
+
[`& .${tooltipClasses.arrow}`]: {
|
|
5405
|
+
color: variantStyles.backgroundColor,
|
|
5406
|
+
},
|
|
5407
|
+
};
|
|
5408
|
+
});
|
|
5409
|
+
/**
|
|
5410
|
+
* NeoTooltip - Tooltip component following Neo design system
|
|
5411
|
+
*
|
|
5412
|
+
* Provides contextual information when users hover over or focus on an element.
|
|
5413
|
+
* Supports three visual variants (light, dark, brand) and optional supporting text.
|
|
5414
|
+
*
|
|
5415
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4091-26557&t=Bo58EpFmg6ILJtmv-11
|
|
5416
|
+
*
|
|
5417
|
+
* Figma Props Mapping:
|
|
5418
|
+
* - Theme (Light mode|Dark mode|Brand color) → variant ('light'|'dark'|'brand')
|
|
5419
|
+
* - Placement → arrow (boolean) + placement (top/bottom/left/right/etc)
|
|
5420
|
+
* - Supporting text (True|False) → description (string|undefined)
|
|
5421
|
+
* - text → title (string, literal content)
|
|
5422
|
+
*
|
|
5423
|
+
* Design Tokens Used:
|
|
5424
|
+
* - Light: surfaces.tooltip (#4b5563), typography.tooltip (#ffffff)
|
|
5425
|
+
* - Dark: grey[50] (#f9fafb), grey[800] (#1f2937)
|
|
5426
|
+
* - Brand: digitalBlue[800] (#131e7a), typography.tooltip (#ffffff)
|
|
5427
|
+
* - Shadow: neutralMedium (0px 8px 15px 0px rgba(31,41,55,0.1))
|
|
5428
|
+
* - Typography: fontSize.xs (12), fontSize.caption (13), fontWeight.medium (500), fontWeight.semiBold (600)
|
|
5429
|
+
*/
|
|
5430
|
+
const NeoTooltip = ({ variant = 'light', title, description, children, arrow = false, placement, ...props }) => {
|
|
5431
|
+
// Build the title content
|
|
5432
|
+
// If description is provided, create a structured layout with title + description
|
|
5433
|
+
// Otherwise, just show the title text
|
|
5434
|
+
const titleContent = description ? (jsxs(Stack, { gap: 0.5, children: [jsx(Typography, { fontSize: typography.fontSize.caption, fontWeight: typography.fontWeight.semiBold, children: title }), jsx(Typography, { fontSize: typography.fontSize.xs, fontWeight: typography.fontWeight.medium, sx: { opacity: 0.75 }, children: description })] })) : (title);
|
|
5435
|
+
return (jsx(StyledTooltip$1, { variant: variant, description: description, title: titleContent, arrow: arrow, placement: placement, ...props, children: children }));
|
|
5436
|
+
};
|
|
5437
|
+
NeoTooltip.displayName = 'NeoTooltip';
|
|
5438
|
+
|
|
5209
5439
|
const customProps = ['selected'];
|
|
5210
5440
|
const StyledRoot = styled(ButtonBase, {
|
|
5211
5441
|
shouldForwardProp: prop => !customProps.includes(prop),
|
|
@@ -5224,41 +5454,34 @@ const StyledRoot = styled(ButtonBase, {
|
|
|
5224
5454
|
textDecoration: 'none',
|
|
5225
5455
|
'&:hover .neo-nav-icon-padding': {
|
|
5226
5456
|
backgroundColor: semanticColors.buttons.secondary.hoverBackground,
|
|
5227
|
-
borderColor:
|
|
5457
|
+
borderColor: semanticColors.buttons.secondary.pressedBackground,
|
|
5228
5458
|
},
|
|
5229
5459
|
'&:hover .neo-nav-label': {
|
|
5230
5460
|
color: semanticColors.buttons.primary.hover,
|
|
5231
5461
|
},
|
|
5462
|
+
[`& .${chipClasses.root}`]: {
|
|
5463
|
+
flexShrink: 0,
|
|
5464
|
+
},
|
|
5232
5465
|
'&:focus-visible': {
|
|
5233
|
-
|
|
5466
|
+
outline: 'none',
|
|
5234
5467
|
},
|
|
5235
5468
|
'&:focus-visible .neo-nav-icon-padding': {
|
|
5236
|
-
|
|
5237
|
-
borderColor: colors.digitalBlue[100],
|
|
5238
|
-
},
|
|
5239
|
-
'&:focus-visible .neo-nav-label': {
|
|
5240
|
-
color: semanticColors.buttons.primary.hover,
|
|
5469
|
+
...focusRingStyles,
|
|
5241
5470
|
},
|
|
5242
5471
|
...(selected && {
|
|
5243
5472
|
'& .neo-nav-icon-padding': {
|
|
5244
|
-
backgroundColor:
|
|
5473
|
+
backgroundColor: semanticColors.buttons.secondary.pressedBackground,
|
|
5245
5474
|
},
|
|
5246
5475
|
'& .neo-nav-label': {
|
|
5247
5476
|
color: semanticColors.buttons.primary.pressed,
|
|
5248
5477
|
fontWeight: typography.fontWeight.semiBold,
|
|
5249
5478
|
},
|
|
5250
5479
|
'&:hover .neo-nav-icon-padding': {
|
|
5251
|
-
backgroundColor:
|
|
5480
|
+
backgroundColor: semanticColors.buttons.secondary.pressedBackground,
|
|
5252
5481
|
},
|
|
5253
5482
|
'&:hover .neo-nav-label': {
|
|
5254
5483
|
color: semanticColors.buttons.primary.pressed,
|
|
5255
5484
|
},
|
|
5256
|
-
'&:focus-visible .neo-nav-icon-padding': {
|
|
5257
|
-
backgroundColor: colors.digitalBlue[100],
|
|
5258
|
-
},
|
|
5259
|
-
'&:focus-visible .neo-nav-label': {
|
|
5260
|
-
color: semanticColors.buttons.primary.pressed,
|
|
5261
|
-
},
|
|
5262
5485
|
}),
|
|
5263
5486
|
}));
|
|
5264
5487
|
const IconPadding = styled('span')({
|
|
@@ -5279,31 +5502,314 @@ const Label$2 = styled('span')(({ theme }) => ({
|
|
|
5279
5502
|
width: '100%',
|
|
5280
5503
|
transition: 'color 150ms',
|
|
5281
5504
|
}));
|
|
5282
|
-
const TagPill = styled('span')(({ theme }) => ({
|
|
5283
|
-
display: 'inline-flex',
|
|
5284
|
-
alignItems: 'center',
|
|
5285
|
-
justifyContent: 'center',
|
|
5286
|
-
height: 18,
|
|
5287
|
-
paddingLeft: spacing.spacing_3_4, // 6px
|
|
5288
|
-
paddingRight: spacing.spacing_3_4, // 6px
|
|
5289
|
-
borderRadius: borderRadius.full,
|
|
5290
|
-
backgroundColor: colors.digitalBlue[300], // #8D99FF
|
|
5291
|
-
color: semanticColors.typography.tooltip, // white
|
|
5292
|
-
fontFamily: typography.fontFamily.body,
|
|
5293
|
-
fontWeight: typography.fontWeight.medium,
|
|
5294
|
-
fontSize: theme.typography.pxToRem(typography.fontSize.xs), // 12px
|
|
5295
|
-
lineHeight: 1,
|
|
5296
|
-
}));
|
|
5297
5505
|
/**
|
|
5298
5506
|
* NeoNavigationItem - Vertical navigation item with icon, label, and optional tag
|
|
5299
5507
|
*
|
|
5300
5508
|
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=8455-6120
|
|
5301
5509
|
*/
|
|
5302
|
-
function NeoNavigationItem({ icon, label, selected = false, tag, children, ...props }) {
|
|
5303
|
-
|
|
5510
|
+
function NeoNavigationItem({ icon, label, selected = false, tag, tooltip, slotProps, children, ...props }) {
|
|
5511
|
+
const { collapsed } = useNeoSideNav();
|
|
5512
|
+
// When collapsed the label is hidden, so fall back to it for the tooltip and
|
|
5513
|
+
// accessible name — otherwise an icon-only button has no name (WCAG 4.1.2).
|
|
5514
|
+
const collapsedTooltip = tooltip ?? label;
|
|
5515
|
+
const item = (jsxs(StyledRoot, { selected: selected, "aria-label": collapsed && typeof label === 'string' ? label : undefined, disableRipple: true, ...props, children: [jsx(IconPadding, { className: "neo-nav-icon-padding", children: icon }), !collapsed && label && jsx(Label$2, { className: "neo-nav-label", children: label }), !collapsed && tag && (jsx(NeoTag, { size: "medium", variant: "filled", intent: "beta", label: tag, ...slotProps?.badge })), children] }));
|
|
5516
|
+
if (collapsed && collapsedTooltip) {
|
|
5517
|
+
return (jsx(NeoTooltip, { title: collapsedTooltip, placement: "right", arrow: true, children: item }));
|
|
5518
|
+
}
|
|
5519
|
+
return item;
|
|
5304
5520
|
}
|
|
5305
5521
|
NeoNavigationItem.displayName = 'NeoNavigationItem';
|
|
5306
5522
|
|
|
5523
|
+
const StyledActionsCell = styled(GridActionsCell)({
|
|
5524
|
+
gap: spacing.spacing_1,
|
|
5525
|
+
paddingLeft: spacing.spacing_1_1_2,
|
|
5526
|
+
paddingRight: spacing.spacing_1_1_2,
|
|
5527
|
+
});
|
|
5528
|
+
function NeoActionsCell(props) {
|
|
5529
|
+
return jsx(StyledActionsCell, { ...props });
|
|
5530
|
+
}
|
|
5531
|
+
|
|
5532
|
+
const StyledCell$1 = styled('div', {
|
|
5533
|
+
shouldForwardProp: prop => prop !== 'disabled',
|
|
5534
|
+
})(({ disabled }) => ({
|
|
5535
|
+
display: 'flex',
|
|
5536
|
+
alignItems: 'center',
|
|
5537
|
+
gap: spacing.spacing_1, // 8px between avatar and label
|
|
5538
|
+
width: '100%',
|
|
5539
|
+
height: '100%',
|
|
5540
|
+
paddingLeft: spacing.spacing_1_1_2, // 12px — input-horizontal
|
|
5541
|
+
paddingRight: spacing.spacing_1_1_2,
|
|
5542
|
+
paddingTop: spacing.spacing_1_2, // 4px — input-vertical
|
|
5543
|
+
paddingBottom: spacing.spacing_1_2,
|
|
5544
|
+
backgroundColor: disabled
|
|
5545
|
+
? semanticColors.surfaces.dataGrid.disabled
|
|
5546
|
+
: semanticColors.surfaces.dataGrid.default,
|
|
5547
|
+
boxSizing: 'border-box',
|
|
5548
|
+
}));
|
|
5549
|
+
const LabelText = styled('span', {
|
|
5550
|
+
shouldForwardProp: prop => prop !== 'disabled',
|
|
5551
|
+
})(({ disabled }) => ({
|
|
5552
|
+
overflow: 'hidden',
|
|
5553
|
+
textOverflow: 'ellipsis',
|
|
5554
|
+
whiteSpace: 'nowrap',
|
|
5555
|
+
fontFamily: typography.fontFamily.body,
|
|
5556
|
+
fontSize: typography.fontSize.xs,
|
|
5557
|
+
fontWeight: typography.fontWeight.regular,
|
|
5558
|
+
lineHeight: 1.5,
|
|
5559
|
+
color: disabled ? semanticColors.typography.bodySecondary : semanticColors.typography.body,
|
|
5560
|
+
}));
|
|
5561
|
+
/**
|
|
5562
|
+
* NeoAvatarCell — DataGrid cell displaying a user avatar with optional label.
|
|
5563
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=13425-1725
|
|
5564
|
+
*/
|
|
5565
|
+
const NeoAvatarCell = ({ name, src, label, disabled = false, empty = false, }) => {
|
|
5566
|
+
if (empty) {
|
|
5567
|
+
return jsx(StyledCell$1, { disabled: disabled });
|
|
5568
|
+
}
|
|
5569
|
+
return (jsxs(StyledCell$1, { disabled: disabled, children: [jsx(NeoGeneralAvatar, { size: "small", src: src, alt: name, children: !src && name ? name.charAt(0).toUpperCase() : undefined }), label && jsx(LabelText, { disabled: disabled, children: label })] }));
|
|
5570
|
+
};
|
|
5571
|
+
NeoAvatarCell.displayName = 'NeoAvatarCell';
|
|
5572
|
+
|
|
5573
|
+
const CellRoot = styled('div', {
|
|
5574
|
+
shouldForwardProp: prop => prop !== 'disabled',
|
|
5575
|
+
})(({ disabled }) => ({
|
|
5576
|
+
display: 'flex',
|
|
5577
|
+
alignItems: 'center',
|
|
5578
|
+
justifyContent: 'center',
|
|
5579
|
+
width: '100%',
|
|
5580
|
+
height: '100%',
|
|
5581
|
+
color: disabled ? semanticColors.icons.disabled : semanticColors.icons.default,
|
|
5582
|
+
}));
|
|
5583
|
+
/**
|
|
5584
|
+
* NeoIconCell — Icon cell for DataGrid. Renders an icon centered in the cell.
|
|
5585
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=13272-9345
|
|
5586
|
+
*/
|
|
5587
|
+
const NeoIconCell = ({ icon, ariaLabel, disabled = false }) => {
|
|
5588
|
+
if (!icon)
|
|
5589
|
+
return null;
|
|
5590
|
+
return (jsx(CellRoot, { disabled: disabled, "aria-label": ariaLabel, children: jsx(NeoIconWrapper, { size: 16, children: icon }) }));
|
|
5591
|
+
};
|
|
5592
|
+
NeoIconCell.displayName = 'NeoIconCell';
|
|
5593
|
+
|
|
5594
|
+
const CellWrapper = styled('div', {
|
|
5595
|
+
shouldForwardProp: prop => prop !== 'disabled',
|
|
5596
|
+
})(({ disabled }) => ({
|
|
5597
|
+
display: 'flex',
|
|
5598
|
+
alignItems: 'center',
|
|
5599
|
+
justifyContent: 'flex-start',
|
|
5600
|
+
width: '100%',
|
|
5601
|
+
height: '100%',
|
|
5602
|
+
paddingLeft: spacing.spacing_1,
|
|
5603
|
+
paddingRight: spacing.spacing_1,
|
|
5604
|
+
backgroundColor: disabled
|
|
5605
|
+
? semanticColors.surfaces.dataGrid.disabled
|
|
5606
|
+
: semanticColors.surfaces.dataGrid.default,
|
|
5607
|
+
'& img': {
|
|
5608
|
+
display: 'block',
|
|
5609
|
+
maxHeight: 32,
|
|
5610
|
+
width: 'auto',
|
|
5611
|
+
maxWidth: '100%',
|
|
5612
|
+
objectFit: 'contain',
|
|
5613
|
+
opacity: disabled ? 0.4 : 1,
|
|
5614
|
+
},
|
|
5615
|
+
}));
|
|
5616
|
+
/**
|
|
5617
|
+
* NeoLogoCell — DataGrid cell displaying a raster or SVG logo image.
|
|
5618
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=13278-9558
|
|
5619
|
+
*
|
|
5620
|
+
* Kept separate from NeoIconCell to match Neo's Icon/Logo component split:
|
|
5621
|
+
* - NeoIconCell: MUI SvgIcon components
|
|
5622
|
+
* - NeoLogoCell: raster or SVG image URLs (img tag)
|
|
5623
|
+
*/
|
|
5624
|
+
const NeoLogoCell = ({ src, alt = '', disabled = false }) => {
|
|
5625
|
+
if (!src) {
|
|
5626
|
+
return jsx(CellWrapper, { disabled: disabled });
|
|
5627
|
+
}
|
|
5628
|
+
return (jsx(CellWrapper, { disabled: disabled, children: jsx(NeoIconWrapper, { size: 32, children: jsx("img", { src: src, alt: alt }) }) }));
|
|
5629
|
+
};
|
|
5630
|
+
NeoLogoCell.displayName = 'NeoLogoCell';
|
|
5631
|
+
|
|
5632
|
+
const StyledLinearProgress = styled(LinearProgress, {
|
|
5633
|
+
shouldForwardProp: prop => prop !== 'labelPosition',
|
|
5634
|
+
})(() => ({
|
|
5635
|
+
height: 8,
|
|
5636
|
+
borderRadius: borderRadius.xS,
|
|
5637
|
+
backgroundColor: colors.grey[200],
|
|
5638
|
+
[`& .${linearProgressClasses.bar}`]: {
|
|
5639
|
+
borderRadius: borderRadius.xS,
|
|
5640
|
+
backgroundColor: colors.digitalBlue[500],
|
|
5641
|
+
},
|
|
5642
|
+
[`&.${linearProgressClasses.colorPrimary}`]: {
|
|
5643
|
+
backgroundColor: colors.grey[200],
|
|
5644
|
+
[`& .${linearProgressClasses.bar}`]: {
|
|
5645
|
+
backgroundColor: colors.digitalBlue[500],
|
|
5646
|
+
},
|
|
5647
|
+
},
|
|
5648
|
+
// Cancelled variant uses warning color
|
|
5649
|
+
'&[data-variant="cancelled"]': {
|
|
5650
|
+
[`& .${linearProgressClasses.bar}`]: {
|
|
5651
|
+
backgroundColor: semanticColors.status.warning.default,
|
|
5652
|
+
},
|
|
5653
|
+
},
|
|
5654
|
+
}));
|
|
5655
|
+
const ProgressWrapper = styled('div')(({ labelPosition }) => ({
|
|
5656
|
+
display: 'flex',
|
|
5657
|
+
width: '100%',
|
|
5658
|
+
...(labelPosition === 'right' && {
|
|
5659
|
+
flexDirection: 'row',
|
|
5660
|
+
alignItems: 'center',
|
|
5661
|
+
gap: spacing.spacing_3,
|
|
5662
|
+
}),
|
|
5663
|
+
...(labelPosition === 'top' && {
|
|
5664
|
+
flexDirection: 'column-reverse',
|
|
5665
|
+
alignItems: 'flex-end',
|
|
5666
|
+
gap: spacing.spacing_2,
|
|
5667
|
+
}),
|
|
5668
|
+
...(labelPosition === 'bottom' && {
|
|
5669
|
+
flexDirection: 'column',
|
|
5670
|
+
alignItems: 'flex-end',
|
|
5671
|
+
gap: spacing.spacing_2,
|
|
5672
|
+
}),
|
|
5673
|
+
...(labelPosition === 'none' && {
|
|
5674
|
+
flexDirection: 'row',
|
|
5675
|
+
}),
|
|
5676
|
+
}));
|
|
5677
|
+
const ProgressLabel = styled(Typography)(({ theme }) => ({
|
|
5678
|
+
fontSize: theme.typography.pxToRem(typography.fontSize.sm),
|
|
5679
|
+
fontWeight: typography.fontWeight.medium,
|
|
5680
|
+
color: colors.grey[800],
|
|
5681
|
+
lineHeight: 1.4,
|
|
5682
|
+
whiteSpace: 'nowrap',
|
|
5683
|
+
flexShrink: 0,
|
|
5684
|
+
}));
|
|
5685
|
+
const ProgressBarContainer = styled('div')(({ labelPosition }) => ({
|
|
5686
|
+
flexGrow: labelPosition === 'right' ? 1 : 0,
|
|
5687
|
+
width: labelPosition === 'right' ? 'auto' : '100%',
|
|
5688
|
+
}));
|
|
5689
|
+
/**
|
|
5690
|
+
* NeoProgressbar - Linear progress indicator based on MUI LinearProgress
|
|
5691
|
+
*
|
|
5692
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4120-36679
|
|
5693
|
+
*
|
|
5694
|
+
* Figma Props Mapping:
|
|
5695
|
+
* - progress (0%-100% | Cancelled) → value (0-100) + variant (default|cancelled)
|
|
5696
|
+
* - label (False|Right|Top|Bottom) → labelPosition (none|right|top|bottom)
|
|
5697
|
+
*
|
|
5698
|
+
* Design Decisions (from Issue #75):
|
|
5699
|
+
* - MUI Base Component: LinearProgress (provides accessibility, animations, progress tracking)
|
|
5700
|
+
* - Label Positioning: Single labelPosition prop with values 'none', 'right', 'top', 'bottom'
|
|
5701
|
+
* - Cancelled State: Separate variant prop (variant='cancelled') alongside value prop
|
|
5702
|
+
*/
|
|
5703
|
+
const NeoProgressbar = ({ value = 0, labelPosition = 'none', variant = 'default', labelText, ...props }) => {
|
|
5704
|
+
const showLabel = labelPosition !== 'none';
|
|
5705
|
+
const displayLabel = labelText || (variant === 'cancelled' ? 'Canceled' : `${Math.round(value)}%`);
|
|
5706
|
+
return (jsxs(ProgressWrapper, { labelPosition: labelPosition, children: [jsx(ProgressBarContainer, { labelPosition: labelPosition, children: jsx(StyledLinearProgress, { variant: "determinate", value: variant === 'cancelled' ? 100 : value, "data-variant": variant, labelPosition: labelPosition, ...props }) }), showLabel && jsx(ProgressLabel, { children: displayLabel })] }));
|
|
5707
|
+
};
|
|
5708
|
+
NeoProgressbar.displayName = 'NeoProgressbar';
|
|
5709
|
+
|
|
5710
|
+
const StyledCell = styled('div', {
|
|
5711
|
+
shouldForwardProp: prop => prop !== 'disabled',
|
|
5712
|
+
})(({ disabled }) => ({
|
|
5713
|
+
display: 'flex',
|
|
5714
|
+
alignItems: 'center',
|
|
5715
|
+
width: '100%',
|
|
5716
|
+
height: '100%',
|
|
5717
|
+
paddingLeft: spacing.spacing_1_1_2, // 12px input-horizontal
|
|
5718
|
+
paddingRight: spacing.spacing_1_1_2,
|
|
5719
|
+
backgroundColor: disabled
|
|
5720
|
+
? semanticColors.surfaces.dataGrid.disabled
|
|
5721
|
+
: semanticColors.surfaces.dataGrid.default,
|
|
5722
|
+
boxSizing: 'border-box',
|
|
5723
|
+
}));
|
|
5724
|
+
/**
|
|
5725
|
+
* NeoProgressCell — DataGrid cell displaying a linear progress indicator.
|
|
5726
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=13425-5378
|
|
5727
|
+
*/
|
|
5728
|
+
const NeoProgressCell = ({ value = 0, disabled = false, empty = false, }) => {
|
|
5729
|
+
const clampedValue = Math.min(100, Math.max(0, value));
|
|
5730
|
+
return (jsx(StyledCell, { disabled: disabled, children: !empty && jsx(NeoProgressbar, { value: clampedValue, labelPosition: "none" }) }));
|
|
5731
|
+
};
|
|
5732
|
+
NeoProgressCell.displayName = 'NeoProgressCell';
|
|
5733
|
+
|
|
5734
|
+
const variantColors = (variant) => ({
|
|
5735
|
+
bg: semanticColors.status[variant].light,
|
|
5736
|
+
fg: semanticColors.status[variant].dark,
|
|
5737
|
+
border: semanticColors.status[variant].transparent,
|
|
5738
|
+
});
|
|
5739
|
+
const StyledChip = styled('div', {
|
|
5740
|
+
shouldForwardProp: prop => prop !== 'disabled' && prop !== 'variant',
|
|
5741
|
+
})(({ disabled, variant }) => {
|
|
5742
|
+
const colors = variantColors(variant);
|
|
5743
|
+
return {
|
|
5744
|
+
display: 'inline-flex',
|
|
5745
|
+
alignItems: 'center',
|
|
5746
|
+
gap: spacing.spacing_3_4,
|
|
5747
|
+
paddingTop: spacing.spacing_1_2,
|
|
5748
|
+
paddingBottom: spacing.spacing_1_2,
|
|
5749
|
+
paddingLeft: spacing.spacing_1_1_2,
|
|
5750
|
+
paddingRight: spacing.spacing_1_1_2,
|
|
5751
|
+
borderRadius: borderRadius.full,
|
|
5752
|
+
border: `1px solid ${disabled ? semanticColors.border.secondary : colors.border}`,
|
|
5753
|
+
backgroundColor: disabled ? semanticColors.surfaces.dataGrid.disabled : colors.bg,
|
|
5754
|
+
color: disabled ? semanticColors.icons.disabled : colors.fg,
|
|
5755
|
+
fontFamily: typography.fontFamily.body,
|
|
5756
|
+
fontSize: typography.fontSize.xs,
|
|
5757
|
+
fontWeight: typography.fontWeight.medium,
|
|
5758
|
+
lineHeight: 1,
|
|
5759
|
+
whiteSpace: 'nowrap',
|
|
5760
|
+
overflow: 'hidden',
|
|
5761
|
+
maxWidth: '100%',
|
|
5762
|
+
'& svg': {
|
|
5763
|
+
flexShrink: 0,
|
|
5764
|
+
width: '1em',
|
|
5765
|
+
height: '1em',
|
|
5766
|
+
fontSize: typography.fontSize.xs,
|
|
5767
|
+
},
|
|
5768
|
+
};
|
|
5769
|
+
});
|
|
5770
|
+
const TooltipErrorPre = styled('pre')({
|
|
5771
|
+
margin: 0,
|
|
5772
|
+
padding: 0,
|
|
5773
|
+
fontFamily: typography.fontFamily.code,
|
|
5774
|
+
fontSize: typography.fontSize.sm,
|
|
5775
|
+
fontWeight: typography.fontWeight.regular,
|
|
5776
|
+
lineHeight: 1.5,
|
|
5777
|
+
color: semanticColors.typography.tooltip,
|
|
5778
|
+
whiteSpace: 'pre-wrap',
|
|
5779
|
+
wordBreak: 'break-all',
|
|
5780
|
+
maxHeight: 200,
|
|
5781
|
+
overflowY: 'auto',
|
|
5782
|
+
});
|
|
5783
|
+
const StyledTooltip = styled(Tooltip)({
|
|
5784
|
+
[`& .${tooltipClasses.tooltip}`]: {
|
|
5785
|
+
backgroundColor: semanticColors.surfaces.tooltip,
|
|
5786
|
+
maxWidth: 400,
|
|
5787
|
+
padding: `${spacing.spacing_1}px ${spacing.spacing_1_1_2}px`,
|
|
5788
|
+
},
|
|
5789
|
+
[`& .${tooltipClasses.arrow}`]: {
|
|
5790
|
+
color: semanticColors.surfaces.tooltip,
|
|
5791
|
+
},
|
|
5792
|
+
});
|
|
5793
|
+
/**
|
|
5794
|
+
* NeoStatusCell — DataGrid cell displaying an icon + label chip with optional error tooltip.
|
|
5795
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=13272-8705
|
|
5796
|
+
*/
|
|
5797
|
+
const NeoStatusCell = ({ icon, label, details, disabled = false, variant = 'success', empty = false, }) => {
|
|
5798
|
+
if (empty) {
|
|
5799
|
+
return (jsx(Box, { component: "span", sx: {
|
|
5800
|
+
color: semanticColors.typography.body,
|
|
5801
|
+
fontSize: typography.fontSize.sm,
|
|
5802
|
+
lineHeight: 1,
|
|
5803
|
+
}, children: '—' }));
|
|
5804
|
+
}
|
|
5805
|
+
const chip = (jsxs(StyledChip, { disabled: disabled, variant: variant, children: [icon, label] }));
|
|
5806
|
+
if (details) {
|
|
5807
|
+
return (jsx(StyledTooltip, { title: jsx(TooltipErrorPre, { children: details }), arrow: true, placement: "bottom-start", children: jsx(Box, { component: "span", sx: { display: 'inline-flex' }, children: chip }) }));
|
|
5808
|
+
}
|
|
5809
|
+
return chip;
|
|
5810
|
+
};
|
|
5811
|
+
NeoStatusCell.displayName = 'NeoStatusCell';
|
|
5812
|
+
|
|
5307
5813
|
/**
|
|
5308
5814
|
* Sticky header wrapper - sticks to top when scrolling
|
|
5309
5815
|
*/
|
|
@@ -5318,10 +5824,9 @@ const StickyHeader = styled(Box)(({ theme }) => ({
|
|
|
5318
5824
|
* Page title typography
|
|
5319
5825
|
*/
|
|
5320
5826
|
const PageTitle = styled(Typography)(() => ({
|
|
5321
|
-
|
|
5322
|
-
fontWeight: typography.fontWeight.medium,
|
|
5827
|
+
...semanticTypography.titles.pageHeader,
|
|
5323
5828
|
lineHeight: 1.4,
|
|
5324
|
-
color: colors.grey['900'],
|
|
5829
|
+
color: colors.grey['900'],
|
|
5325
5830
|
}));
|
|
5326
5831
|
/**
|
|
5327
5832
|
* Subtitle typography
|
|
@@ -5385,7 +5890,12 @@ const Subtitle = styled(Typography)(() => ({
|
|
|
5385
5890
|
* </NeoPageContent>
|
|
5386
5891
|
* ```
|
|
5387
5892
|
*/
|
|
5388
|
-
function NeoPageContent({ pageTitle, subtitle, breadcrumbs, action, sticky = false, contentMaxWidth = false, centerContent = true, disableGutters = false, isLoading = false, showBackToTop = true, children, sx, ...boxProps }) {
|
|
5893
|
+
function NeoPageContent({ pageTitle, subtitle, breadcrumbs, action, sticky = false, contentMaxWidth: contentMaxWidthProp = false, centerContent = true, disableGutters: disableGuttersProp = false, isLoading = false, showBackToTop = true, layout = 'default', children, sx, ...boxProps }) {
|
|
5894
|
+
// fullBleed forces no max-width, no gutters, and zero bottom padding
|
|
5895
|
+
// so children can fill the viewport edge-to-edge.
|
|
5896
|
+
const isFullBleed = layout === 'fullBleed';
|
|
5897
|
+
const contentMaxWidth = isFullBleed ? false : contentMaxWidthProp;
|
|
5898
|
+
const disableGutters = isFullBleed || disableGuttersProp;
|
|
5389
5899
|
const [showBackToTopButton, setShowBackToTopButton] = useState(false);
|
|
5390
5900
|
const headerRef = useRef(null);
|
|
5391
5901
|
const containerRef = useRef(null);
|
|
@@ -5415,7 +5925,7 @@ function NeoPageContent({ pageTitle, subtitle, breadcrumbs, action, sticky = fal
|
|
|
5415
5925
|
// Also try to scroll window in case component is in a different context
|
|
5416
5926
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
5417
5927
|
};
|
|
5418
|
-
const headerContent = (jsxs(Stack, { ref: headerRef, sx: { flexShrink: 0, gap: '0.5rem' }, children: [breadcrumbs && breadcrumbs.items.length > 0 && (jsx(NeoBreadcrumbs, { children: breadcrumbs.items.map((item, index) => (jsx(NeoBreadcrumbLink, { href: item.href, component: item.href && breadcrumbs.linkComponent ? breadcrumbs.linkComponent : undefined, current: index === breadcrumbs.items.length - 1, children: item.label }, item.href ?? index))) })), jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "flex-start", sx: { gap: '1rem' }, children: [jsxs(Stack, { sx: { gap: '0.5rem', flexGrow: 1 }, children: [jsx(PageTitle, { children: pageTitle }), subtitle &&
|
|
5928
|
+
const headerContent = (jsxs(Stack, { ref: headerRef, sx: { flexShrink: 0, gap: '0.5rem' }, children: [breadcrumbs && breadcrumbs.items.length > 0 && (jsx(NeoBreadcrumbs, { children: breadcrumbs.items.map((item, index) => (jsx(NeoBreadcrumbLink, { href: item.href, component: item.href && breadcrumbs.linkComponent ? breadcrumbs.linkComponent : undefined, current: index === breadcrumbs.items.length - 1, children: item.label }, item.href ?? index))) })), jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "flex-start", sx: { gap: '1rem' }, children: [jsxs(Stack, { sx: { gap: '0.5rem', flexGrow: 1 }, children: [typeof pageTitle === 'string' ? (jsx(PageTitle, { component: "h1", children: pageTitle })) : (pageTitle), subtitle &&
|
|
5419
5929
|
(typeof subtitle === 'string' ? (jsx(Subtitle, { variant: "caption", children: subtitle })) : (subtitle))] }), action] })] }));
|
|
5420
5930
|
const content = isLoading ? (jsx(Box, { sx: {
|
|
5421
5931
|
display: 'flex',
|
|
@@ -5437,7 +5947,7 @@ function NeoPageContent({ pageTitle, subtitle, breadcrumbs, action, sticky = fal
|
|
|
5437
5947
|
flexDirection: 'column',
|
|
5438
5948
|
px: disableGutters ? 0 : `${spacing.spacing_2_1_2}px`,
|
|
5439
5949
|
pt: sticky ? 0 : `${spacing.spacing_2}px`,
|
|
5440
|
-
pb: `${spacing.spacing_2_1_2}px`,
|
|
5950
|
+
pb: isFullBleed ? 0 : `${spacing.spacing_2_1_2}px`,
|
|
5441
5951
|
height: '100%',
|
|
5442
5952
|
overflow: 'auto',
|
|
5443
5953
|
}, children: [sticky ? (jsx(StickyHeader, { ref: headerRef, sx: {
|
|
@@ -5462,7 +5972,7 @@ function NeoPageContent({ pageTitle, subtitle, breadcrumbs, action, sticky = fal
|
|
|
5462
5972
|
width: '100%',
|
|
5463
5973
|
...(centerContent ? { mx: 'auto' } : { alignSelf: 'flex-start' }),
|
|
5464
5974
|
}),
|
|
5465
|
-
}, children: content })] }) }), showBackToTop && (jsx(Fade, { in: showBackToTopButton, children: jsx(Box, { sx: {
|
|
5975
|
+
}, children: content })] }) }), showBackToTop && (jsx(Fade$1, { in: showBackToTopButton, children: jsx(Box, { sx: {
|
|
5466
5976
|
position: 'fixed',
|
|
5467
5977
|
bottom: spacing.spacing_2,
|
|
5468
5978
|
right: spacing.spacing_4,
|
|
@@ -5509,99 +6019,21 @@ function NeoPaginatedGrid({ slots, pageSizeOptions, slotProps: userSlotProps, ..
|
|
|
5509
6019
|
// Explicitly enable pagination (matching moderne-ui ModerneDataGrid defaults)
|
|
5510
6020
|
// Set defaults first, then spread props to allow overrides
|
|
5511
6021
|
, {
|
|
5512
|
-
// Explicitly enable pagination (matching moderne-ui ModerneDataGrid defaults)
|
|
5513
|
-
// Set defaults first, then spread props to allow overrides
|
|
5514
|
-
pagination: true, paginationMode: "client", pageSizeOptions: pageSizeOptions ?? [25, 50, 100], autoHeight: false, ...props,
|
|
5515
|
-
// Merge slots after props to ensure footer is set
|
|
5516
|
-
slots: mergedSlots, slotProps: {
|
|
5517
|
-
basePopper: {
|
|
5518
|
-
placement: 'bottom-start',
|
|
5519
|
-
},
|
|
5520
|
-
footer: {
|
|
5521
|
-
variant: 'pagination',
|
|
5522
|
-
},
|
|
5523
|
-
...userSlotProps,
|
|
5524
|
-
} }));
|
|
5525
|
-
}
|
|
5526
|
-
NeoPaginatedGrid.displayName = 'NeoPaginatedGrid';
|
|
5527
|
-
|
|
5528
|
-
const StyledLinearProgress = styled(LinearProgress, {
|
|
5529
|
-
shouldForwardProp: prop => prop !== 'labelPosition',
|
|
5530
|
-
})(() => ({
|
|
5531
|
-
height: 8,
|
|
5532
|
-
borderRadius: borderRadius.xS,
|
|
5533
|
-
backgroundColor: colors.grey[200],
|
|
5534
|
-
[`& .${linearProgressClasses.bar}`]: {
|
|
5535
|
-
borderRadius: borderRadius.xS,
|
|
5536
|
-
backgroundColor: colors.digitalBlue[500],
|
|
5537
|
-
},
|
|
5538
|
-
[`&.${linearProgressClasses.colorPrimary}`]: {
|
|
5539
|
-
backgroundColor: colors.grey[200],
|
|
5540
|
-
[`& .${linearProgressClasses.bar}`]: {
|
|
5541
|
-
backgroundColor: colors.digitalBlue[500],
|
|
5542
|
-
},
|
|
5543
|
-
},
|
|
5544
|
-
// Cancelled variant uses warning color
|
|
5545
|
-
'&[data-variant="cancelled"]': {
|
|
5546
|
-
[`& .${linearProgressClasses.bar}`]: {
|
|
5547
|
-
backgroundColor: semanticColors.status.warning.default,
|
|
5548
|
-
},
|
|
5549
|
-
},
|
|
5550
|
-
}));
|
|
5551
|
-
const ProgressWrapper = styled('div')(({ labelPosition }) => ({
|
|
5552
|
-
display: 'flex',
|
|
5553
|
-
width: '100%',
|
|
5554
|
-
...(labelPosition === 'right' && {
|
|
5555
|
-
flexDirection: 'row',
|
|
5556
|
-
alignItems: 'center',
|
|
5557
|
-
gap: spacing.spacing_3,
|
|
5558
|
-
}),
|
|
5559
|
-
...(labelPosition === 'top' && {
|
|
5560
|
-
flexDirection: 'column-reverse',
|
|
5561
|
-
alignItems: 'flex-end',
|
|
5562
|
-
gap: spacing.spacing_2,
|
|
5563
|
-
}),
|
|
5564
|
-
...(labelPosition === 'bottom' && {
|
|
5565
|
-
flexDirection: 'column',
|
|
5566
|
-
alignItems: 'flex-end',
|
|
5567
|
-
gap: spacing.spacing_2,
|
|
5568
|
-
}),
|
|
5569
|
-
...(labelPosition === 'none' && {
|
|
5570
|
-
flexDirection: 'row',
|
|
5571
|
-
}),
|
|
5572
|
-
}));
|
|
5573
|
-
const ProgressLabel = styled(Typography)(({ theme }) => ({
|
|
5574
|
-
fontSize: theme.typography.pxToRem(typography.fontSize.sm),
|
|
5575
|
-
fontWeight: typography.fontWeight.medium,
|
|
5576
|
-
color: colors.grey[800],
|
|
5577
|
-
lineHeight: 1.4,
|
|
5578
|
-
whiteSpace: 'nowrap',
|
|
5579
|
-
flexShrink: 0,
|
|
5580
|
-
}));
|
|
5581
|
-
const ProgressBarContainer = styled('div')(({ labelPosition }) => ({
|
|
5582
|
-
flexGrow: labelPosition === 'right' ? 1 : 0,
|
|
5583
|
-
width: labelPosition === 'right' ? 'auto' : '100%',
|
|
5584
|
-
}));
|
|
5585
|
-
/**
|
|
5586
|
-
* NeoProgressbar - Linear progress indicator based on MUI LinearProgress
|
|
5587
|
-
*
|
|
5588
|
-
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4120-36679
|
|
5589
|
-
*
|
|
5590
|
-
* Figma Props Mapping:
|
|
5591
|
-
* - progress (0%-100% | Cancelled) → value (0-100) + variant (default|cancelled)
|
|
5592
|
-
* - label (False|Right|Top|Bottom) → labelPosition (none|right|top|bottom)
|
|
5593
|
-
*
|
|
5594
|
-
* Design Decisions (from Issue #75):
|
|
5595
|
-
* - MUI Base Component: LinearProgress (provides accessibility, animations, progress tracking)
|
|
5596
|
-
* - Label Positioning: Single labelPosition prop with values 'none', 'right', 'top', 'bottom'
|
|
5597
|
-
* - Cancelled State: Separate variant prop (variant='cancelled') alongside value prop
|
|
5598
|
-
*/
|
|
5599
|
-
const NeoProgressbar = ({ value = 0, labelPosition = 'none', variant = 'default', labelText, ...props }) => {
|
|
5600
|
-
const showLabel = labelPosition !== 'none';
|
|
5601
|
-
const displayLabel = labelText || (variant === 'cancelled' ? 'Canceled' : `${Math.round(value)}%`);
|
|
5602
|
-
return (jsxs(ProgressWrapper, { labelPosition: labelPosition, children: [jsx(ProgressBarContainer, { labelPosition: labelPosition, children: jsx(StyledLinearProgress, { variant: "determinate", value: variant === 'cancelled' ? 100 : value, "data-variant": variant, labelPosition: labelPosition, ...props }) }), showLabel && jsx(ProgressLabel, { children: displayLabel })] }));
|
|
5603
|
-
};
|
|
5604
|
-
NeoProgressbar.displayName = 'NeoProgressbar';
|
|
6022
|
+
// Explicitly enable pagination (matching moderne-ui ModerneDataGrid defaults)
|
|
6023
|
+
// Set defaults first, then spread props to allow overrides
|
|
6024
|
+
pagination: true, paginationMode: "client", pageSizeOptions: pageSizeOptions ?? [25, 50, 100], autoHeight: false, ...props,
|
|
6025
|
+
// Merge slots after props to ensure footer is set
|
|
6026
|
+
slots: mergedSlots, slotProps: {
|
|
6027
|
+
basePopper: {
|
|
6028
|
+
placement: 'bottom-start',
|
|
6029
|
+
},
|
|
6030
|
+
footer: {
|
|
6031
|
+
variant: 'pagination',
|
|
6032
|
+
},
|
|
6033
|
+
...userSlotProps,
|
|
6034
|
+
} }));
|
|
6035
|
+
}
|
|
6036
|
+
NeoPaginatedGrid.displayName = 'NeoPaginatedGrid';
|
|
5605
6037
|
|
|
5606
6038
|
const StyledTextField = styled(TextField)(({ theme }) => ({
|
|
5607
6039
|
[`& .${inputBaseClasses.root}`]: {
|
|
@@ -5845,6 +6277,55 @@ const NeoRadio = ({ size = 'medium', label, helperText, disabled, ...props }) =>
|
|
|
5845
6277
|
};
|
|
5846
6278
|
NeoRadio.displayName = 'NeoRadio';
|
|
5847
6279
|
|
|
6280
|
+
/**
|
|
6281
|
+
* NeoRadioButtonWithText
|
|
6282
|
+
*
|
|
6283
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=11565-7682
|
|
6284
|
+
*/
|
|
6285
|
+
const NeoRadioButtonWithText = styled('div')({});
|
|
6286
|
+
|
|
6287
|
+
// Box-breathing rhythm: appear (inhale) → hold → expand+fade (exhale) → rest.
|
|
6288
|
+
// Max scale is capped so the ring fits within a parent row's line-height.
|
|
6289
|
+
const ripple = keyframes `
|
|
6290
|
+
0% { opacity: 0; transform: scale(0.7); }
|
|
6291
|
+
20% { opacity: 0.9; transform: scale(0.7); }
|
|
6292
|
+
35% { opacity: 0.9; transform: scale(0.7); }
|
|
6293
|
+
80% { opacity: 0; transform: scale(1.7); }
|
|
6294
|
+
100% { opacity: 0; transform: scale(0.7); }
|
|
6295
|
+
`;
|
|
6296
|
+
/**
|
|
6297
|
+
* NeoRipplingDot - Animated status dot with an expanding ripple ring.
|
|
6298
|
+
*
|
|
6299
|
+
* Indicates an in-progress, indeterminate state (RUNNING / SYNCING / PROCESSING).
|
|
6300
|
+
* Color is inherited from `currentColor`; set it via the `color`/`sx` prop or a
|
|
6301
|
+
* parent. Sized to the lowercase-letter height regardless of parent fontSize.
|
|
6302
|
+
*/
|
|
6303
|
+
const NeoRipplingDot = props => (jsx(Box$1, { "aria-hidden": "true", ...props, style: {
|
|
6304
|
+
width: spacing.spacing_1,
|
|
6305
|
+
height: spacing.spacing_1,
|
|
6306
|
+
...props.style,
|
|
6307
|
+
}, sx: {
|
|
6308
|
+
position: 'relative',
|
|
6309
|
+
display: 'inline-block',
|
|
6310
|
+
borderRadius: '50%',
|
|
6311
|
+
backgroundColor: 'currentColor',
|
|
6312
|
+
verticalAlign: 'middle',
|
|
6313
|
+
flexShrink: 0,
|
|
6314
|
+
'&::before': {
|
|
6315
|
+
content: '""',
|
|
6316
|
+
position: 'absolute',
|
|
6317
|
+
inset: '-25%',
|
|
6318
|
+
borderRadius: '50%',
|
|
6319
|
+
border: '1px solid currentColor',
|
|
6320
|
+
animation: `${ripple} 5.6s ease-in-out infinite`,
|
|
6321
|
+
'@media (prefers-reduced-motion: reduce)': {
|
|
6322
|
+
display: 'none',
|
|
6323
|
+
},
|
|
6324
|
+
},
|
|
6325
|
+
...props.sx,
|
|
6326
|
+
} }));
|
|
6327
|
+
NeoRipplingDot.displayName = 'NeoRipplingDot';
|
|
6328
|
+
|
|
5848
6329
|
const StyledSearchChip = styled(InputBase)(({ theme }) => ({
|
|
5849
6330
|
borderRadius: borderRadius.full,
|
|
5850
6331
|
border: `1px solid ${semanticColors.buttons.secondary.defaultBorder}`,
|
|
@@ -5910,6 +6391,126 @@ const NeoSearchChip = ({ onClear, value, ...props }) => {
|
|
|
5910
6391
|
};
|
|
5911
6392
|
NeoSearchChip.displayName = 'NeoSearchChip';
|
|
5912
6393
|
|
|
6394
|
+
/**
|
|
6395
|
+
* NeoSelectField — composite of NeoInputField's form chrome (label,
|
|
6396
|
+
* helper text, error state) wrapped around NeoSelect. Mirrors the
|
|
6397
|
+
* MUI `<TextField select>` ergonomics with Neo design tokens, so
|
|
6398
|
+
* consumers don't have to compose the two manually.
|
|
6399
|
+
*
|
|
6400
|
+
* @example
|
|
6401
|
+
* <NeoSelectField
|
|
6402
|
+
* label="Response format"
|
|
6403
|
+
* value={format}
|
|
6404
|
+
* onChange={e => setFormat(e.target.value)}
|
|
6405
|
+
* options={[
|
|
6406
|
+
* { value: 'json', label: 'JSON' },
|
|
6407
|
+
* { value: 'plain', label: 'Plain text' },
|
|
6408
|
+
* ]}
|
|
6409
|
+
* />
|
|
6410
|
+
*/
|
|
6411
|
+
const NeoSelectField = ({ size = 'medium', destructive = false, label, required = false, infoIcon, helperText, errorMessage, options, children, disabled, id, ...selectProps }) => {
|
|
6412
|
+
const inputId = id || `neo-select-${Math.random().toString(36).substring(7)}`;
|
|
6413
|
+
const helperTextId = helperText || errorMessage ? `${inputId}-helper-text` : undefined;
|
|
6414
|
+
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(NeoSelect, { id: inputId, disabled: disabled, error: destructive, "aria-describedby": helperTextId, ...selectProps, children: children ??
|
|
6415
|
+
options?.map(opt => (jsx(NeoMenuItem, { value: opt.value, disabled: opt.disabled, children: opt.label }, String(opt.value)))) }), (helperText || errorMessage) && (jsx(StyledFormHelperText, { id: helperTextId, error: destructive, disabled: disabled, sx: { marginTop: `${spacing.spacing_3_4}px` }, children: destructive ? errorMessage : helperText }))] }));
|
|
6416
|
+
};
|
|
6417
|
+
NeoSelectField.displayName = 'NeoSelectField';
|
|
6418
|
+
|
|
6419
|
+
const EXPANDED_WIDTH = 98;
|
|
6420
|
+
const COLLAPSED_WIDTH = 56;
|
|
6421
|
+
// The fade overlay must end on the same color as the rail to blend cleanly.
|
|
6422
|
+
const RAIL_BACKGROUND = colors.grey[100];
|
|
6423
|
+
/**
|
|
6424
|
+
* NeoSideNav
|
|
6425
|
+
*
|
|
6426
|
+
* Collapsible vertical navigation rail with fixed `header`/`footer` slots and a
|
|
6427
|
+
* scrolling content area. Controlled via `collapsed` + `onCollapsedChange`;
|
|
6428
|
+
* broadcasts collapsed state to descendant `NeoNavigationItem`s through context.
|
|
6429
|
+
*
|
|
6430
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4065-3425
|
|
6431
|
+
*/
|
|
6432
|
+
const Root = styled('nav', {
|
|
6433
|
+
shouldForwardProp: prop => prop !== 'collapsed',
|
|
6434
|
+
})(({ collapsed, theme }) => ({
|
|
6435
|
+
display: 'flex',
|
|
6436
|
+
flexDirection: 'column',
|
|
6437
|
+
height: '100%',
|
|
6438
|
+
width: collapsed ? COLLAPSED_WIDTH : EXPANDED_WIDTH,
|
|
6439
|
+
minWidth: collapsed ? COLLAPSED_WIDTH : EXPANDED_WIDTH,
|
|
6440
|
+
backgroundColor: RAIL_BACKGROUND,
|
|
6441
|
+
transition: theme.transitions.create(['width', 'min-width'], {
|
|
6442
|
+
duration: theme.transitions.duration.shorter,
|
|
6443
|
+
}),
|
|
6444
|
+
overflow: 'hidden',
|
|
6445
|
+
}));
|
|
6446
|
+
const Header = styled('div')({
|
|
6447
|
+
flexShrink: 0,
|
|
6448
|
+
display: 'flex',
|
|
6449
|
+
flexDirection: 'column',
|
|
6450
|
+
alignItems: 'center',
|
|
6451
|
+
});
|
|
6452
|
+
const Scroll = styled('div')({
|
|
6453
|
+
flex: 1,
|
|
6454
|
+
minHeight: 0,
|
|
6455
|
+
overflowY: 'auto',
|
|
6456
|
+
overflowX: 'hidden',
|
|
6457
|
+
display: 'flex',
|
|
6458
|
+
flexDirection: 'column',
|
|
6459
|
+
alignItems: 'center',
|
|
6460
|
+
gap: spacing.spacing_1_2,
|
|
6461
|
+
paddingInline: spacing.spacing_1,
|
|
6462
|
+
'&::-webkit-scrollbar': { width: spacing.spacing_1_2 },
|
|
6463
|
+
'&::-webkit-scrollbar-thumb': {
|
|
6464
|
+
backgroundColor: semanticColors.border.primary,
|
|
6465
|
+
borderRadius: borderRadius.xXS,
|
|
6466
|
+
},
|
|
6467
|
+
});
|
|
6468
|
+
const FooterRegion = styled('div')({
|
|
6469
|
+
position: 'relative',
|
|
6470
|
+
flexShrink: 0,
|
|
6471
|
+
display: 'flex',
|
|
6472
|
+
flexDirection: 'column',
|
|
6473
|
+
alignItems: 'center',
|
|
6474
|
+
gap: spacing.spacing_1_2,
|
|
6475
|
+
paddingInline: spacing.spacing_1,
|
|
6476
|
+
paddingBottom: spacing.spacing_1,
|
|
6477
|
+
});
|
|
6478
|
+
// Gradient fade so scrolling items dissolve into the footer instead of butting against it.
|
|
6479
|
+
const Fade = styled('div')({
|
|
6480
|
+
position: 'absolute',
|
|
6481
|
+
top: -spacing.spacing_3,
|
|
6482
|
+
left: 0,
|
|
6483
|
+
right: 0,
|
|
6484
|
+
height: spacing.spacing_3,
|
|
6485
|
+
pointerEvents: 'none',
|
|
6486
|
+
background: `linear-gradient(to bottom, transparent, ${RAIL_BACKGROUND})`,
|
|
6487
|
+
});
|
|
6488
|
+
const Toggle = styled(ButtonBase)(({ theme }) => ({
|
|
6489
|
+
display: 'flex',
|
|
6490
|
+
alignItems: 'center',
|
|
6491
|
+
justifyContent: 'center',
|
|
6492
|
+
flexDirection: 'column',
|
|
6493
|
+
gap: spacing.spacing_1_2,
|
|
6494
|
+
width: '100%',
|
|
6495
|
+
paddingBlock: spacing.spacing_1,
|
|
6496
|
+
borderRadius: borderRadius.s,
|
|
6497
|
+
border: `1px solid ${semanticColors.border.secondary}`,
|
|
6498
|
+
color: semanticColors.typography.bodySecondary,
|
|
6499
|
+
fontFamily: typography.fontFamily.body,
|
|
6500
|
+
fontSize: theme.typography.pxToRem(11),
|
|
6501
|
+
lineHeight: 1,
|
|
6502
|
+
'&:hover': {
|
|
6503
|
+
color: semanticColors.typography.body,
|
|
6504
|
+
borderColor: semanticColors.border.primary,
|
|
6505
|
+
},
|
|
6506
|
+
}));
|
|
6507
|
+
function NeoSideNav({ collapsed, onCollapsedChange, header, footer, children, collapseLabel = 'Less', ...rest }) {
|
|
6508
|
+
const ToggleIcon = collapsed ? PanelLeftOpen : PanelLeftClose;
|
|
6509
|
+
const contextValue = useMemo(() => ({ collapsed }), [collapsed]);
|
|
6510
|
+
return (jsx(NeoSideNavContext.Provider, { value: contextValue, children: jsxs(Root, { collapsed: collapsed, ...rest, children: [header && jsx(Header, { children: header }), jsx(Scroll, { children: children }), jsxs(FooterRegion, { children: [jsx(Fade, {}), footer, jsxs(Toggle, { "data-testid": "neo-side-nav-toggle", "aria-label": collapsed ? 'Expand navigation' : 'Collapse navigation', disableRipple: true, onClick: () => onCollapsedChange(!collapsed), children: [jsx(ToggleIcon, { size: 18 }), !collapsed && jsx("span", { children: collapseLabel })] })] })] }) }));
|
|
6511
|
+
}
|
|
6512
|
+
NeoSideNav.displayName = 'NeoSideNav';
|
|
6513
|
+
|
|
5913
6514
|
const StyledSkeleton = styled(Skeleton, {
|
|
5914
6515
|
shouldForwardProp: prop => prop !== 'colorTheme' && prop !== 'position',
|
|
5915
6516
|
})(({ theme, colorTheme = 'light', position = 'start' }) => ({
|
|
@@ -5957,6 +6558,111 @@ const NeoSkeleton = ({ colorTheme = 'light', position = 'start', ...props }) =>
|
|
|
5957
6558
|
};
|
|
5958
6559
|
NeoSkeleton.displayName = 'NeoSkeleton';
|
|
5959
6560
|
|
|
6561
|
+
const sizePadding = {
|
|
6562
|
+
small: `${spacing.spacing_3_4}px ${spacing.spacing_1_1_2}px`,
|
|
6563
|
+
medium: `${spacing.spacing_1_1_2}px ${spacing.spacing_2}px`,
|
|
6564
|
+
};
|
|
6565
|
+
const sizeFontSize = {
|
|
6566
|
+
small: typography.fontSize.xs,
|
|
6567
|
+
medium: typography.fontSize.sm,
|
|
6568
|
+
};
|
|
6569
|
+
const StyledTable = styled(MuiTable, {
|
|
6570
|
+
shouldForwardProp: prop => prop !== 'tableSize',
|
|
6571
|
+
})(({ theme, tableSize = 'small' }) => ({
|
|
6572
|
+
borderCollapse: 'separate',
|
|
6573
|
+
borderSpacing: 0,
|
|
6574
|
+
[`& .${tableCellClasses.head}`]: {
|
|
6575
|
+
backgroundColor: colors.grey[50],
|
|
6576
|
+
color: semanticColors.typography.body,
|
|
6577
|
+
fontFamily: typography.fontFamily.body,
|
|
6578
|
+
fontSize: theme.typography.pxToRem(sizeFontSize[tableSize]),
|
|
6579
|
+
fontWeight: typography.fontWeight.semiBold,
|
|
6580
|
+
lineHeight: 1.4,
|
|
6581
|
+
padding: sizePadding[tableSize],
|
|
6582
|
+
borderBottom: `1px solid ${semanticColors.border.secondary}`,
|
|
6583
|
+
},
|
|
6584
|
+
[`& .${tableCellClasses.body}`]: {
|
|
6585
|
+
color: semanticColors.typography.body,
|
|
6586
|
+
fontFamily: typography.fontFamily.body,
|
|
6587
|
+
fontSize: theme.typography.pxToRem(sizeFontSize[tableSize]),
|
|
6588
|
+
fontWeight: typography.fontWeight.regular,
|
|
6589
|
+
lineHeight: 1.4,
|
|
6590
|
+
padding: sizePadding[tableSize],
|
|
6591
|
+
borderBottom: `1px solid ${semanticColors.border.secondary}`,
|
|
6592
|
+
},
|
|
6593
|
+
// Drop the trailing row's bottom border so the container border (if
|
|
6594
|
+
// any) is the visual edge.
|
|
6595
|
+
[`& tbody tr:last-of-type .${tableCellClasses.body}`]: {
|
|
6596
|
+
borderBottom: 'none',
|
|
6597
|
+
},
|
|
6598
|
+
}));
|
|
6599
|
+
const StyledContainer = styled('div', {
|
|
6600
|
+
shouldForwardProp: prop => prop !== 'tableVariant',
|
|
6601
|
+
})(({ tableVariant = 'bordered' }) => tableVariant === 'bordered'
|
|
6602
|
+
? {
|
|
6603
|
+
border: `1px solid ${semanticColors.border.secondary}`,
|
|
6604
|
+
borderRadius: borderRadius.card,
|
|
6605
|
+
overflow: 'hidden',
|
|
6606
|
+
backgroundColor: semanticColors.surfaces.white,
|
|
6607
|
+
}
|
|
6608
|
+
: { backgroundColor: 'transparent' });
|
|
6609
|
+
/**
|
|
6610
|
+
* NeoTable — lightweight read-only table for static data (schema rows,
|
|
6611
|
+
* key/value summaries, response metadata). For interactive grids with
|
|
6612
|
+
* sorting / filtering / pagination, use NeoDataGrid instead.
|
|
6613
|
+
*
|
|
6614
|
+
* @example
|
|
6615
|
+
* <NeoTable
|
|
6616
|
+
* columns={[
|
|
6617
|
+
* { key: 'name', header: 'Property' },
|
|
6618
|
+
* { key: 'type', header: 'Type', align: 'center', width: '120px' },
|
|
6619
|
+
* { key: 'description', header: 'Description' },
|
|
6620
|
+
* ]}
|
|
6621
|
+
* rows={[
|
|
6622
|
+
* { name: 'id', type: 'string', description: 'Resource identifier' },
|
|
6623
|
+
* { name: 'count', type: 'number', description: 'Item count' },
|
|
6624
|
+
* ]}
|
|
6625
|
+
* size="small"
|
|
6626
|
+
* />
|
|
6627
|
+
*/
|
|
6628
|
+
const NeoTable = ({ columns, rows, size = 'small', variant = 'bordered', ariaLabel, ...tableProps }) => (jsx(StyledContainer, { tableVariant: variant, children: jsx(TableContainer, { children: jsxs(StyledTable, { tableSize: size, "aria-label": ariaLabel, ...tableProps, children: [jsx(TableHead, { children: jsx(TableRow, { children: columns.map(col => (jsx(TableCell, { align: col.align ?? 'left', style: col.width ? { width: col.width } : undefined, children: col.header }, col.key))) }) }), jsx(TableBody, { children: rows.map((row, i) => (jsx(TableRow, { children: columns.map(col => (jsx(TableCell, { align: col.align ?? 'left', children: row[col.key] ?? '' }, col.key))) }, i))) })] }) }) }));
|
|
6629
|
+
NeoTable.displayName = 'NeoTable';
|
|
6630
|
+
|
|
6631
|
+
const StyledTabPanel = styled(Box, {
|
|
6632
|
+
shouldForwardProp: prop => prop !== 'tabPanelVariant',
|
|
6633
|
+
})(({ tabPanelVariant = 'default' }) => ({
|
|
6634
|
+
backgroundColor: semanticColors.surfaces.white,
|
|
6635
|
+
// default: 16px top padding for content-driven pages.
|
|
6636
|
+
// flush: zero padding so content sits directly against the tab bar's
|
|
6637
|
+
// bottom border (sidebars, panels, builders, canvases).
|
|
6638
|
+
padding: 0,
|
|
6639
|
+
...(tabPanelVariant === 'flush' ? {} : { paddingTop: spacing.spacing_2 }),
|
|
6640
|
+
}));
|
|
6641
|
+
/**
|
|
6642
|
+
* NeoTabPanel — completes the NeoTabs + NeoTab + NeoTabPanel set.
|
|
6643
|
+
*
|
|
6644
|
+
* Lightweight ARIA-compliant tab panel that renders children when its
|
|
6645
|
+
* `value` matches `currentValue`. No MUI Lab / TabContext dependency.
|
|
6646
|
+
*
|
|
6647
|
+
* @example
|
|
6648
|
+
* const [tab, setTab] = useState('overview')
|
|
6649
|
+
* return (
|
|
6650
|
+
* <>
|
|
6651
|
+
* <NeoTabs value={tab} onChange={(_, v) => setTab(v)}>
|
|
6652
|
+
* <NeoTab value="overview" label="Overview" />
|
|
6653
|
+
* <NeoTab value="details" label="Details" />
|
|
6654
|
+
* </NeoTabs>
|
|
6655
|
+
* <NeoTabPanel value="overview" currentValue={tab}>...</NeoTabPanel>
|
|
6656
|
+
* <NeoTabPanel value="details" currentValue={tab} variant="flush">...</NeoTabPanel>
|
|
6657
|
+
* </>
|
|
6658
|
+
* )
|
|
6659
|
+
*/
|
|
6660
|
+
const NeoTabPanel = ({ value, currentValue, variant = 'default', children, ...boxProps }) => {
|
|
6661
|
+
const selected = value === currentValue;
|
|
6662
|
+
return (jsx(StyledTabPanel, { role: "tabpanel", hidden: !selected, tabPanelVariant: variant, id: `tabpanel-${value}`, "aria-labelledby": `tab-${value}`, ...boxProps, children: selected ? children : null }));
|
|
6663
|
+
};
|
|
6664
|
+
NeoTabPanel.displayName = 'NeoTabPanel';
|
|
6665
|
+
|
|
5960
6666
|
/**
|
|
5961
6667
|
* NeoTabs - Tabs container component based on MUI Tabs
|
|
5962
6668
|
*
|
|
@@ -6336,6 +7042,102 @@ const NeoToggle = ({ size = 'medium', label, helperText, disabled, ...props }) =
|
|
|
6336
7042
|
};
|
|
6337
7043
|
NeoToggle.displayName = 'NeoToggle';
|
|
6338
7044
|
|
|
7045
|
+
const sizeStyles = {
|
|
7046
|
+
small: {
|
|
7047
|
+
height: 24,
|
|
7048
|
+
fontSize: typography.fontSize.xs,
|
|
7049
|
+
},
|
|
7050
|
+
medium: {
|
|
7051
|
+
height: 32,
|
|
7052
|
+
fontSize: typography.fontSize.sm,
|
|
7053
|
+
},
|
|
7054
|
+
};
|
|
7055
|
+
const StyledToggleButton$1 = styled(MuiToggleButton, {
|
|
7056
|
+
shouldForwardProp: prop => prop !== 'toggleSize',
|
|
7057
|
+
})(({ theme, toggleSize = 'medium' }) => ({
|
|
7058
|
+
height: sizeStyles[toggleSize].height,
|
|
7059
|
+
padding: `0 ${spacing.spacing_1_1_2}px`,
|
|
7060
|
+
fontFamily: typography.fontFamily.body,
|
|
7061
|
+
fontSize: theme.typography.pxToRem(sizeStyles[toggleSize].fontSize),
|
|
7062
|
+
fontWeight: typography.fontWeight.regular,
|
|
7063
|
+
lineHeight: 1,
|
|
7064
|
+
color: semanticColors.typography.bodySecondary,
|
|
7065
|
+
backgroundColor: 'transparent',
|
|
7066
|
+
border: 'none',
|
|
7067
|
+
textTransform: 'none',
|
|
7068
|
+
transition: theme.transitions.create(['background-color', 'color'], {
|
|
7069
|
+
duration: theme.transitions.duration.short,
|
|
7070
|
+
}),
|
|
7071
|
+
'&:hover': {
|
|
7072
|
+
backgroundColor: colors.grey[100],
|
|
7073
|
+
color: semanticColors.typography.body,
|
|
7074
|
+
},
|
|
7075
|
+
'&.Mui-selected, &.Mui-selected:hover': {
|
|
7076
|
+
backgroundColor: colors.grey[100],
|
|
7077
|
+
color: semanticColors.typography.body,
|
|
7078
|
+
fontWeight: typography.fontWeight.semiBold,
|
|
7079
|
+
},
|
|
7080
|
+
'&.Mui-focusVisible': {
|
|
7081
|
+
outline: `2px solid ${semanticColors.border.focus}`,
|
|
7082
|
+
outlineOffset: -2,
|
|
7083
|
+
},
|
|
7084
|
+
'&.Mui-disabled': {
|
|
7085
|
+
color: semanticColors.typography.button.disabled,
|
|
7086
|
+
cursor: 'default',
|
|
7087
|
+
pointerEvents: 'none',
|
|
7088
|
+
},
|
|
7089
|
+
}));
|
|
7090
|
+
/**
|
|
7091
|
+
* NeoToggleButton — a single button in a segmented control. Use inside
|
|
7092
|
+
* NeoToggleButtonGroup; the group manages selection state and forwards
|
|
7093
|
+
* size to its children. Suitable for inline toolbar mode switches
|
|
7094
|
+
* ("Table" / "Raw"). For page-level tabs, prefer NeoButtonTab.
|
|
7095
|
+
*/
|
|
7096
|
+
const NeoToggleButton = ({ children, size = 'medium', ...props }) => (jsx(StyledToggleButton$1, { toggleSize: size, ...props, children: children }));
|
|
7097
|
+
NeoToggleButton.displayName = 'NeoToggleButton';
|
|
7098
|
+
|
|
7099
|
+
const StyledToggleButtonGroup$1 = styled(MuiToggleButtonGroup)({
|
|
7100
|
+
borderRadius: borderRadius.button,
|
|
7101
|
+
border: `1px solid ${semanticColors.border.secondary}`,
|
|
7102
|
+
overflow: 'hidden',
|
|
7103
|
+
display: 'inline-flex',
|
|
7104
|
+
// Children fill the pill — first/last get the rounded corners, middles
|
|
7105
|
+
// are square. MUI applies positional classes via ToggleButtonGroup
|
|
7106
|
+
// context; we rely on borderRadius inheritance from the container.
|
|
7107
|
+
[`& .${toggleButtonClasses.root}`]: {
|
|
7108
|
+
borderRadius: 0,
|
|
7109
|
+
},
|
|
7110
|
+
});
|
|
7111
|
+
/**
|
|
7112
|
+
* NeoToggleButtonGroup — pill-shaped segmented control wrapping
|
|
7113
|
+
* MUI ToggleButtonGroup with Neo tokens. Use for inline toolbar mode
|
|
7114
|
+
* switches (e.g. "Table" / "Raw" in a panel header). For page-level
|
|
7115
|
+
* tab navigation, prefer NeoButtonTabGroup.
|
|
7116
|
+
*
|
|
7117
|
+
* @example
|
|
7118
|
+
* <NeoToggleButtonGroup value={mode} exclusive onChange={(_, v) => v && setMode(v)} size="small">
|
|
7119
|
+
* <NeoToggleButton value="table">Table</NeoToggleButton>
|
|
7120
|
+
* <NeoToggleButton value="raw">Raw</NeoToggleButton>
|
|
7121
|
+
* </NeoToggleButtonGroup>
|
|
7122
|
+
*/
|
|
7123
|
+
const NeoToggleButtonGroup = ({ size = 'medium', children, ...props }) => {
|
|
7124
|
+
// Forward size to each NeoToggleButton child so consumers don't have to
|
|
7125
|
+
// set it on every button. MUI's group already does this via context for
|
|
7126
|
+
// its own size prop, but our `size` shape doesn't pass through unchanged.
|
|
7127
|
+
const sized = Children.map(children, child => isValidElement(child) && child.type === NeoToggleButton
|
|
7128
|
+
? cloneElement(child, { size })
|
|
7129
|
+
: child);
|
|
7130
|
+
return jsx(StyledToggleButtonGroup$1, { ...props, children: sized });
|
|
7131
|
+
};
|
|
7132
|
+
NeoToggleButtonGroup.displayName = 'NeoToggleButtonGroup';
|
|
7133
|
+
|
|
7134
|
+
/**
|
|
7135
|
+
* NeoToggleButtonWithText
|
|
7136
|
+
*
|
|
7137
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=11565-10485
|
|
7138
|
+
*/
|
|
7139
|
+
const NeoToggleButtonWithText = styled('div')({});
|
|
7140
|
+
|
|
6339
7141
|
const StyledToolbar = styled(Toolbar)(({ theme }) => ({
|
|
6340
7142
|
backgroundColor: semanticColors.surfaces.white,
|
|
6341
7143
|
minHeight: 'auto',
|
|
@@ -6396,86 +7198,18 @@ const NeoToolbar = ({ children, ...props }) => {
|
|
|
6396
7198
|
NeoToolbar.displayName = 'NeoToolbar';
|
|
6397
7199
|
|
|
6398
7200
|
/**
|
|
6399
|
-
*
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
light: {
|
|
6403
|
-
backgroundColor: semanticColors.surfaces.tooltip, // #4b5563 - medium gray
|
|
6404
|
-
color: semanticColors.typography.tooltip, // #ffffff - white
|
|
6405
|
-
},
|
|
6406
|
-
dark: {
|
|
6407
|
-
backgroundColor: colors.grey[50], // #f9fafb - very light gray
|
|
6408
|
-
color: colors.grey[800], // #1f2937 - dark gray
|
|
6409
|
-
},
|
|
6410
|
-
brand: {
|
|
6411
|
-
backgroundColor: colors.digitalBlue[800], // #131e7a - dark blue
|
|
6412
|
-
color: semanticColors.typography.tooltip, // #ffffff - white
|
|
6413
|
-
},
|
|
6414
|
-
};
|
|
6415
|
-
/**
|
|
6416
|
-
* Styled MUI Tooltip with Neo design system tokens
|
|
7201
|
+
* NeoTopNav
|
|
7202
|
+
*
|
|
7203
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4618-185228
|
|
6417
7204
|
*/
|
|
6418
|
-
const
|
|
6419
|
-
|
|
6420
|
-
})(({ variant = 'light', description }) => {
|
|
6421
|
-
const hasDescription = Boolean(description);
|
|
6422
|
-
const variantStyles = variantConfig[variant];
|
|
6423
|
-
return {
|
|
6424
|
-
// Style the tooltip content
|
|
6425
|
-
[`& .${tooltipClasses.tooltip}`]: {
|
|
6426
|
-
backgroundColor: variantStyles.backgroundColor,
|
|
6427
|
-
color: variantStyles.color,
|
|
6428
|
-
fontSize: typography.fontSize.xs,
|
|
6429
|
-
fontWeight: typography.fontWeight.medium,
|
|
6430
|
-
lineHeight: hasDescription ? 1.5 : 1,
|
|
6431
|
-
borderRadius: hasDescription ? borderRadius.s : borderRadius.xS,
|
|
6432
|
-
padding: hasDescription ? spacing.spacing_1_1_2 : `0 ${spacing.spacing_1}px`,
|
|
6433
|
-
...(hasDescription && {
|
|
6434
|
-
maxWidth: 296,
|
|
6435
|
-
}),
|
|
6436
|
-
...(!hasDescription && {
|
|
6437
|
-
height: spacing.spacing_3_1_4,
|
|
6438
|
-
display: 'flex',
|
|
6439
|
-
alignItems: 'center',
|
|
6440
|
-
justifyContent: 'center',
|
|
6441
|
-
}),
|
|
6442
|
-
boxShadow: `${shadows.neutral.medium.x}px ${shadows.neutral.medium.y}px ${shadows.neutral.medium.blur}px ${shadows.neutral.medium.spread}px ${shadows.neutral.medium.shadow}`,
|
|
6443
|
-
},
|
|
6444
|
-
// Style the arrow
|
|
6445
|
-
[`& .${tooltipClasses.arrow}`]: {
|
|
6446
|
-
color: variantStyles.backgroundColor,
|
|
6447
|
-
},
|
|
6448
|
-
};
|
|
6449
|
-
});
|
|
7205
|
+
const NeoTopNav = styled('div')({});
|
|
7206
|
+
|
|
6450
7207
|
/**
|
|
6451
|
-
*
|
|
6452
|
-
*
|
|
6453
|
-
* Provides contextual information when users hover over or focus on an element.
|
|
6454
|
-
* Supports three visual variants (light, dark, brand) and optional supporting text.
|
|
6455
|
-
*
|
|
6456
|
-
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4091-26557&t=Bo58EpFmg6ILJtmv-11
|
|
6457
|
-
*
|
|
6458
|
-
* Figma Props Mapping:
|
|
6459
|
-
* - Theme (Light mode|Dark mode|Brand color) → variant ('light'|'dark'|'brand')
|
|
6460
|
-
* - Placement → arrow (boolean) + placement (top/bottom/left/right/etc)
|
|
6461
|
-
* - Supporting text (True|False) → description (string|undefined)
|
|
6462
|
-
* - text → title (string, literal content)
|
|
7208
|
+
* NeoTourModal
|
|
6463
7209
|
*
|
|
6464
|
-
*
|
|
6465
|
-
* - Light: surfaces.tooltip (#4b5563), typography.tooltip (#ffffff)
|
|
6466
|
-
* - Dark: grey[50] (#f9fafb), grey[800] (#1f2937)
|
|
6467
|
-
* - Brand: digitalBlue[800] (#131e7a), typography.tooltip (#ffffff)
|
|
6468
|
-
* - Shadow: neutralMedium (0px 8px 15px 0px rgba(31,41,55,0.1))
|
|
6469
|
-
* - Typography: fontSize.xs (12), fontWeight.medium (500), fontWeight.semiBold (600)
|
|
7210
|
+
* @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=12408-1800
|
|
6470
7211
|
*/
|
|
6471
|
-
const
|
|
6472
|
-
// Build the title content
|
|
6473
|
-
// If description is provided, create a structured layout with title + description
|
|
6474
|
-
// Otherwise, just show the title text
|
|
6475
|
-
const titleContent = description ? (jsxs(Stack, { gap: 0.25, children: [jsx(Typography, { fontWeight: typography.fontWeight.semiBold, children: title }), jsx(Typography, { fontWeight: typography.fontWeight.medium, children: description })] })) : (title);
|
|
6476
|
-
return (jsx(StyledTooltip, { variant: variant, description: description, title: titleContent, arrow: arrow, placement: placement, ...props, children: children }));
|
|
6477
|
-
};
|
|
6478
|
-
NeoTooltip.displayName = 'NeoTooltip';
|
|
7212
|
+
const NeoTourModal = styled('div')({});
|
|
6479
7213
|
|
|
6480
7214
|
/**
|
|
6481
7215
|
* Custom label component that reads extra slot data from the item model.
|
|
@@ -6673,6 +7407,39 @@ const NeoTypologyControl = ({ children, ...props }) => {
|
|
|
6673
7407
|
};
|
|
6674
7408
|
NeoTypologyControl.displayName = 'NeoTypologyControl';
|
|
6675
7409
|
|
|
7410
|
+
// Box-breathing rhythm: inhale (grow) → hold → exhale (shadow expand+fade) → rest.
|
|
7411
|
+
const vibrate = keyframes `
|
|
7412
|
+
0% { transform: scale(0.9); box-shadow: 0 0 0 0 transparent; }
|
|
7413
|
+
25% { transform: scale(1); box-shadow: 0 0 0 0 currentColor; }
|
|
7414
|
+
50% { transform: scale(1); box-shadow: 0 0 0 0 currentColor; }
|
|
7415
|
+
75% { transform: scale(0.9); box-shadow: 0 0 0 ${spacing.spacing_3_4}px transparent; }
|
|
7416
|
+
100% { transform: scale(0.9); box-shadow: 0 0 0 0 transparent; }
|
|
7417
|
+
`;
|
|
7418
|
+
/**
|
|
7419
|
+
* NeoVibratingDot - Animated status dot with a breathing pulse halo.
|
|
7420
|
+
*
|
|
7421
|
+
* Indicates a waiting/pending state (QUEUED / CREATED). Color is inherited from
|
|
7422
|
+
* `currentColor`; set it via the `color`/`sx` prop or a parent. Sized to the
|
|
7423
|
+
* lowercase-letter height regardless of parent fontSize.
|
|
7424
|
+
*/
|
|
7425
|
+
const NeoVibratingDot = props => (jsx(Box$1, { "aria-hidden": "true", ...props, style: {
|
|
7426
|
+
width: spacing.spacing_1,
|
|
7427
|
+
height: spacing.spacing_1,
|
|
7428
|
+
...props.style,
|
|
7429
|
+
}, sx: {
|
|
7430
|
+
display: 'inline-block',
|
|
7431
|
+
borderRadius: '50%',
|
|
7432
|
+
backgroundColor: 'currentColor',
|
|
7433
|
+
verticalAlign: 'middle',
|
|
7434
|
+
flexShrink: 0,
|
|
7435
|
+
animation: `${vibrate} 5.6s ease-in-out infinite`,
|
|
7436
|
+
'@media (prefers-reduced-motion: reduce)': {
|
|
7437
|
+
animation: 'none',
|
|
7438
|
+
},
|
|
7439
|
+
...props.sx,
|
|
7440
|
+
} }));
|
|
7441
|
+
NeoVibratingDot.displayName = 'NeoVibratingDot';
|
|
7442
|
+
|
|
6676
7443
|
/**
|
|
6677
7444
|
* @moderneinc/neo-styled-components
|
|
6678
7445
|
*
|
|
@@ -6681,5 +7448,5 @@ NeoTypologyControl.displayName = 'NeoTypologyControl';
|
|
|
6681
7448
|
|
|
6682
7449
|
const version = '0.0.0-development';
|
|
6683
7450
|
|
|
6684
|
-
export { ActivityScene, CIRCLE_RADIUS, NeoActivityHeader, NeoActivityIndicatorCell, NeoAlert, NeoBadge, NeoBanner, NeoBreadcrumbLink, NeoBreadcrumbs, NeoButton, NeoButtonTab, NeoButtonTabGroup, NeoCard, NeoCheckbox, NeoCheckboxWithText, NeoCodeSnippet, NeoDataGrid, NeoDataGridCellContent, NeoDataGridColumnsButton, NeoDataGridColumnsPanel, NeoDataGridFilterPanel, NeoDataGridFilterPanelAddIcon, NeoDataGridFilterPanelDeleteIcon, NeoDataGridFilterPanelRemoveAllIcon, NeoDataGridFiltersButton, NeoDataGridHeaderLabel, NeoSelect as NeoDataGridSelect, NeoDatePicker, NeoDivider, NeoDot, NeoDownloadToast, NeoSelect as NeoDropdown, NeoMenu as NeoDropdownMenu, NeoMenuItem as NeoDropdownMenuItem, NeoMenuItem as NeoDropdownOption, NeoFilterChip, NeoFooter, NeoGeneralAvatar, NeoIconButton, NeoIconWrapper, NeoInfiniteScrollGrid, NeoInputField, NeoListItem, NeoListItemButton, NeoLoadingSpinner, NeoMenu, NeoMenuItem, NeoModal, NeoModalContent, NeoModalFooter, NeoModalHeader, NeoMultiBadgesCell, NeoNavigationAvatar, NeoNavigationItem, NeoPageContent, NeoPaginatedGrid, NeoProgressbar, NeoQuickFilter, NeoRadio, NeoSearchChip, NeoSelect, NeoMenuItem as NeoSelectOption, NeoSkeleton, NeoStatusBadgeCell, NeoTab, NeoTabs, NeoTag, NeoToast, NeoToastButton, NeoToggle, NeoToolbar, NeoTooltip, NeoTreeItem, NeoTreeView, StyledToggleButton as NeoTypologyButton, NeoTypologyControl, NeoUserAvatarCell, SortedAscendingIcon, SortedDescendingIcon, UnsortedIcon, focusRingStyles, getDataGridHeaderStyles, neoRowHeights, version };
|
|
7451
|
+
export { ActivityScene, CIRCLE_RADIUS, NeoActionsCell, NeoActivityHeader, NeoActivityIndicatorCell, NeoAlert, NeoAvatarCell, NeoBadge, NeoBanner, NeoBreadcrumbLink, NeoBreadcrumbs, NeoButton, NeoButtonTab, NeoButtonTabGroup, NeoCanceledIcon, NeoCard, NeoCheckbox, NeoCheckboxWithText, NeoCodeSnippet, NeoDataGrid, NeoDataGridCellContent, NeoDataGridColumnsButton, NeoDataGridColumnsPanel, NeoDataGridFilterPanel, NeoDataGridFilterPanelAddIcon, NeoDataGridFilterPanelDeleteIcon, NeoDataGridFilterPanelRemoveAllIcon, NeoDataGridFiltersButton, NeoDataGridHeaderLabel, NeoSelect as NeoDataGridSelect, NeoDatePicker, NeoDatePickerListItem, NeoDatePickerMenu, NeoDivider, NeoDot, NeoDownloadToast, NeoSelect as NeoDropdown, NeoMenu as NeoDropdownMenu, NeoMenuItem as NeoDropdownMenuItem, NeoMenuItem as NeoDropdownOption, NeoFilledCanceled, NeoFilledError, NeoFilledInfo, NeoFilledNeutral, NeoFilledQueued, NeoFilledSuccess, NeoFilledWarning, NeoFilterChip, NeoFooter, NeoGeneralAvatar, NeoIconButton, NeoIconCell, NeoIconWrapper, NeoInfiniteScrollGrid, NeoInputField, NeoListItem, NeoListItemButton, NeoLoadingSpinner, NeoLogoCell, NeoMenu, NeoMenuItem, NeoModal, NeoModalContent, NeoModalFooter, NeoModalHeader, NeoMultiBadgesCell, NeoNavigationAvatar, NeoNavigationItem, NeoPageContent, NeoPaginatedGrid, NeoProgressCell, NeoProgressbar, NeoQuickFilter, NeoRadio, NeoRadioButtonWithText, NeoRipplingDot, NeoSearchChip, NeoSelect, NeoSelectField, NeoMenuItem as NeoSelectOption, NeoSideNav, NeoSkeleton, NeoStatusBadgeCell, NeoStatusCell, NeoTab, NeoTabPanel, NeoTable, NeoTabs, NeoTag, NeoToast, NeoToastButton, NeoToggle, NeoToggleButton, NeoToggleButtonGroup, NeoToggleButtonWithText, NeoToolbar, NeoTooltip, NeoTopNav, NeoTourModal, NeoTreeItem, NeoTreeView, StyledToggleButton as NeoTypologyButton, NeoTypologyControl, NeoUserAvatarCell, NeoVibratingDot, SortedAscendingIcon, SortedDescendingIcon, UnsortedIcon, focusRingStyles, getDataGridHeaderStyles, getDataGridRowStyles, neoRowHeights, version };
|
|
6685
7452
|
//# sourceMappingURL=index.esm.js.map
|