@moderneinc/design-system-components 7.7.0-next.19b91c → 7.7.0-next.7feadd
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/Button/Button.d.ts +7 -5
- package/dist/index.d.ts +4 -3
- package/dist/index.esm.js +96 -61
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +122 -87
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
package/dist/Button/Button.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import ButtonBase from '@mui/material/ButtonBase';
|
|
2
|
-
import
|
|
1
|
+
import type ButtonBase from '@mui/material/ButtonBase';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
import { type ElementType, type ReactNode } from 'react';
|
|
3
4
|
declare module '@mui/material/ButtonBase' {
|
|
4
5
|
interface ButtonBasePropsVariantOverrides {
|
|
5
6
|
primary: true;
|
|
@@ -22,7 +23,8 @@ type ModButtonOwnProps = {
|
|
|
22
23
|
*/
|
|
23
24
|
size?: ButtonSize;
|
|
24
25
|
/**
|
|
25
|
-
* Show loading spinner
|
|
26
|
+
* Show a loading spinner in place of `startIcon` (or `endIcon`), or over the label when
|
|
27
|
+
* there is no icon. The button keeps its width either way.
|
|
26
28
|
* @default false
|
|
27
29
|
*/
|
|
28
30
|
loading?: boolean;
|
|
@@ -47,9 +49,9 @@ export type ModButtonProps<C extends ElementType = typeof ButtonBase> = ModButto
|
|
|
47
49
|
component?: C;
|
|
48
50
|
};
|
|
49
51
|
/**
|
|
50
|
-
* ModButton - Text button component based on MUI
|
|
52
|
+
* ModButton - Text button component based on MUI Button
|
|
51
53
|
*/
|
|
52
|
-
export declare function ModButton<C extends ElementType = typeof ButtonBase>({ variant, size, loading, children,
|
|
54
|
+
export declare function ModButton<C extends ElementType = typeof ButtonBase>({ variant, size, loading, children, startIcon, endIcon, ...rest }: ModButtonProps<C>): import("react/jsx-runtime").JSX.Element;
|
|
53
55
|
export declare namespace ModButton {
|
|
54
56
|
var displayName: string;
|
|
55
57
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -523,7 +523,8 @@ type ModButtonOwnProps = {
|
|
|
523
523
|
*/
|
|
524
524
|
size?: ButtonSize;
|
|
525
525
|
/**
|
|
526
|
-
* Show loading spinner
|
|
526
|
+
* Show a loading spinner in place of `startIcon` (or `endIcon`), or over the label when
|
|
527
|
+
* there is no icon. The button keeps its width either way.
|
|
527
528
|
* @default false
|
|
528
529
|
*/
|
|
529
530
|
loading?: boolean;
|
|
@@ -548,9 +549,9 @@ type ModButtonProps<C extends ElementType = typeof ButtonBase> = ModButtonOwnPro
|
|
|
548
549
|
component?: C;
|
|
549
550
|
};
|
|
550
551
|
/**
|
|
551
|
-
* ModButton - Text button component based on MUI
|
|
552
|
+
* ModButton - Text button component based on MUI Button
|
|
552
553
|
*/
|
|
553
|
-
declare function ModButton<C extends ElementType = typeof ButtonBase>({ variant, size, loading, children,
|
|
554
|
+
declare function ModButton<C extends ElementType = typeof ButtonBase>({ variant, size, loading, children, startIcon, endIcon, ...rest }: ModButtonProps<C>): react_jsx_runtime.JSX.Element;
|
|
554
555
|
declare namespace ModButton {
|
|
555
556
|
var displayName: string;
|
|
556
557
|
}
|
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { semanticColors, spacing, typography, borderRadius, shadows, colors, semanticColorsDark, semanticTypography,
|
|
2
|
+
import { semanticColors, spacing, typography, borderRadius, shadows, iconSize, colors, semanticColorsDark, semanticTypography, height } from '@moderneinc/design-system-tokens';
|
|
3
3
|
import Box from '@mui/material/Box';
|
|
4
4
|
import { styled, useTheme, alpha } from '@mui/material/styles';
|
|
5
5
|
import Chip, { chipClasses } from '@mui/material/Chip';
|
|
@@ -9,9 +9,10 @@ import Alert, { alertClasses } from '@mui/material/Alert';
|
|
|
9
9
|
import ButtonBase, { buttonBaseClasses } from '@mui/material/ButtonBase';
|
|
10
10
|
import { Info, WifiOff, TriangleAlert, CircleAlert, CircleCheckBig, X, ChevronRight, Square, SquareCheck, SquareMinus, Search, ChevronDown, Plus, Trash2, ArrowUp, ArrowDown, ChevronsUpDown, Columns3, ListFilter, HelpCircle, CalendarDays, Minus, ChevronLeft, AlertCircle, ChevronUp } from 'lucide-react';
|
|
11
11
|
import IconButton, { iconButtonClasses } from '@mui/material/IconButton';
|
|
12
|
-
import
|
|
12
|
+
import { useState, useId, useRef, useCallback, useMemo, forwardRef, useEffect, createContext, useContext, useLayoutEffect, Children, isValidElement, cloneElement } from 'react';
|
|
13
13
|
import Breadcrumbs, { breadcrumbsClasses } from '@mui/material/Breadcrumbs';
|
|
14
14
|
import Link from '@mui/material/Link';
|
|
15
|
+
import Button, { buttonClasses } from '@mui/material/Button';
|
|
15
16
|
import CircularProgress from '@mui/material/CircularProgress';
|
|
16
17
|
import MuiToggleButton, { toggleButtonClasses } from '@mui/material/ToggleButton';
|
|
17
18
|
import MuiToggleButtonGroup, { toggleButtonGroupClasses } from '@mui/material/ToggleButtonGroup';
|
|
@@ -19,7 +20,6 @@ import MuiCard from '@mui/material/Card';
|
|
|
19
20
|
import Checkbox, { checkboxClasses } from '@mui/material/Checkbox';
|
|
20
21
|
import { gridClasses, useGridApiContext, useGridSelector, gridColumnDefinitionsSelector, gridColumnVisibilityModelSelector, GridFilterPanel, GridPanel, gridPanelClasses, ColumnsPanelTrigger, ToolbarButton, gridFilterModelSelector, FilterPanelTrigger, gridPaginationModelSelector, gridRowCountSelector, gridRowSelectionCountSelector, GridActionsCell, QuickFilter, QuickFilterControl, QuickFilterClear, Toolbar } from '@mui/x-data-grid';
|
|
21
22
|
import { useGridApiRef, DataGridPro } from '@mui/x-data-grid-pro';
|
|
22
|
-
import Button, { buttonClasses } from '@mui/material/Button';
|
|
23
23
|
import Divider from '@mui/material/Divider';
|
|
24
24
|
import InputAdornment, { inputAdornmentClasses } from '@mui/material/InputAdornment';
|
|
25
25
|
import InputBase, { inputBaseClasses } from '@mui/material/InputBase';
|
|
@@ -740,39 +740,34 @@ function ModBreadcrumbs({ children, className }) {
|
|
|
740
740
|
return (jsx(StyledBreadcrumbs, { separator: jsx(ChevronRight, { size: 10.67, color: semanticColors.color.icon.utility }), className: className, "aria-label": "breadcrumb", children: children }));
|
|
741
741
|
}
|
|
742
742
|
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
'size',
|
|
747
|
-
'loading',
|
|
748
|
-
'startIcon',
|
|
749
|
-
'endIcon',
|
|
750
|
-
'fullWidth',
|
|
751
|
-
'disableElevation',
|
|
752
|
-
];
|
|
753
|
-
const StyledButtonBase$1 = styled(ButtonBase, {
|
|
754
|
-
shouldForwardProp: prop => !buttonOnlyProps.includes(prop),
|
|
755
|
-
})(({ theme, variant = 'primary', size = 'medium', loading = false }) => {
|
|
743
|
+
const StyledButton = styled(Button, {
|
|
744
|
+
shouldForwardProp: prop => prop !== 'buttonVariant' && prop !== 'buttonSize',
|
|
745
|
+
})(({ theme, buttonVariant: variant, buttonSize: size }) => {
|
|
756
746
|
// Size configurations
|
|
757
747
|
const sizeConfig = {
|
|
758
748
|
small: {
|
|
759
749
|
height: 32,
|
|
760
|
-
|
|
750
|
+
paddingX: spacing.spacing_1_1_2,
|
|
761
751
|
fontSize: theme.typography.pxToRem(14),
|
|
762
752
|
},
|
|
763
753
|
medium: {
|
|
764
754
|
height: spacing.spacing_5,
|
|
765
|
-
|
|
755
|
+
paddingX: spacing.spacing_2,
|
|
766
756
|
fontSize: theme.typography.pxToRem(14),
|
|
767
757
|
},
|
|
768
758
|
};
|
|
769
759
|
const sizeStyles = sizeConfig[size];
|
|
760
|
+
const paddingX = variant === 'tertiary' ? 0 : sizeStyles.paddingX;
|
|
761
|
+
const spinnerSize = size === 'small' ? iconSize.md : iconSize.xl;
|
|
762
|
+
const disabled = `&.${buttonClasses.disabled}:not(.${buttonClasses.loading})`;
|
|
770
763
|
// Base styles shared by all variants
|
|
771
764
|
const baseStyles = {
|
|
772
765
|
height: sizeStyles.height,
|
|
773
|
-
padding:
|
|
766
|
+
padding: `0 ${paddingX}px`,
|
|
767
|
+
fontFamily: 'inherit',
|
|
774
768
|
fontSize: sizeStyles.fontSize,
|
|
775
769
|
fontWeight: typography.fontWeight.semiBold,
|
|
770
|
+
letterSpacing: 'inherit',
|
|
776
771
|
lineHeight: '1.25rem',
|
|
777
772
|
borderRadius: borderRadius.button,
|
|
778
773
|
textTransform: 'none',
|
|
@@ -782,13 +777,56 @@ const StyledButtonBase$1 = styled(ButtonBase, {
|
|
|
782
777
|
position: 'relative',
|
|
783
778
|
minWidth: 'fit-content',
|
|
784
779
|
gap: spacing.spacing_1,
|
|
780
|
+
// `gap` spaces the icons; MUI's slot margins would add to it
|
|
781
|
+
[`& .${buttonClasses.startIcon}, & .${buttonClasses.endIcon}`]: {
|
|
782
|
+
margin: 0,
|
|
783
|
+
},
|
|
784
|
+
// MUI sets font-size on the icon slot's first child; IconSlot takes it so 1em icons keep the label's size
|
|
785
|
+
[`& .${buttonClasses.startIcon} > *:nth-of-type(1), & .${buttonClasses.endIcon} > *:nth-of-type(1)`]: {
|
|
786
|
+
fontSize: 'inherit',
|
|
787
|
+
},
|
|
788
|
+
// MUI's indicator is a sibling of the icon; anchoring sizes and places it on the icon
|
|
789
|
+
[`&.${buttonClasses.loadingPositionStart} .${buttonClasses.startIcon}, &.${buttonClasses.loadingPositionEnd} .${buttonClasses.endIcon}`]: {
|
|
790
|
+
anchorName: '--mod-button-icon',
|
|
791
|
+
// MUI fades the icon out while the spinner appears at full opacity
|
|
792
|
+
transition: 'none',
|
|
793
|
+
},
|
|
794
|
+
[`&.${buttonClasses.loadingPositionStart} .${buttonClasses.loadingIndicator}, &.${buttonClasses.loadingPositionEnd} .${buttonClasses.loadingIndicator}`]: {
|
|
795
|
+
// MUI switches it to relative for fullWidth
|
|
796
|
+
position: 'absolute',
|
|
797
|
+
positionAnchor: '--mod-button-icon',
|
|
798
|
+
// Square on the icon's centre; the slot can be taller than the icon, and a non-square box wobbles
|
|
799
|
+
inset: 'auto auto auto anchor(left)',
|
|
800
|
+
alignSelf: 'anchor-center',
|
|
801
|
+
width: 'anchor-size(width)',
|
|
802
|
+
height: 'anchor-size(width)',
|
|
803
|
+
},
|
|
804
|
+
// Without anchor positioning, the spinner takes the standard icon size at the icon's edge
|
|
805
|
+
'@supports not (anchor-name: --a)': {
|
|
806
|
+
[`&.${buttonClasses.loadingPositionStart} .${buttonClasses.loadingIndicator}`]: {
|
|
807
|
+
inset: 'auto',
|
|
808
|
+
left: paddingX,
|
|
809
|
+
width: spinnerSize,
|
|
810
|
+
height: spinnerSize,
|
|
811
|
+
},
|
|
812
|
+
[`&.${buttonClasses.loadingPositionEnd} .${buttonClasses.loadingIndicator}`]: {
|
|
813
|
+
inset: 'auto',
|
|
814
|
+
right: paddingX,
|
|
815
|
+
width: spinnerSize,
|
|
816
|
+
height: spinnerSize,
|
|
817
|
+
},
|
|
818
|
+
},
|
|
819
|
+
// Hide the label at once when loading starts, so it doesn't fade out under the spinner
|
|
820
|
+
[`&.${buttonClasses.loading}`]: {
|
|
821
|
+
transitionProperty: 'background-color, border-color',
|
|
822
|
+
},
|
|
785
823
|
// Disabled state (always show cursor)
|
|
786
|
-
[`&.${
|
|
824
|
+
[`&.${buttonClasses.disabled}`]: {
|
|
787
825
|
cursor: 'not-allowed',
|
|
788
826
|
pointerEvents: 'auto',
|
|
789
827
|
},
|
|
790
828
|
// Focus visible for keyboard navigation
|
|
791
|
-
[`&.${
|
|
829
|
+
[`&.${buttonClasses.focusVisible}`]: {
|
|
792
830
|
outline: `2px solid ${semanticColors.color.border.focus}`,
|
|
793
831
|
outlineOffset: 2,
|
|
794
832
|
},
|
|
@@ -805,14 +843,10 @@ const StyledButtonBase$1 = styled(ButtonBase, {
|
|
|
805
843
|
'&:active': {
|
|
806
844
|
backgroundColor: semanticColors.button.primary.bgPressed,
|
|
807
845
|
},
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
:
|
|
811
|
-
|
|
812
|
-
backgroundColor: semanticColors.button.primary.bgDisabled,
|
|
813
|
-
color: semanticColors.button.fgDisabled,
|
|
814
|
-
},
|
|
815
|
-
}),
|
|
846
|
+
[disabled]: {
|
|
847
|
+
backgroundColor: semanticColors.button.primary.bgDisabled,
|
|
848
|
+
color: semanticColors.button.fgDisabled,
|
|
849
|
+
},
|
|
816
850
|
},
|
|
817
851
|
secondary: {
|
|
818
852
|
backgroundColor: semanticColors.button.secondary.bg,
|
|
@@ -824,15 +858,11 @@ const StyledButtonBase$1 = styled(ButtonBase, {
|
|
|
824
858
|
'&:active': {
|
|
825
859
|
backgroundColor: semanticColors.button.secondary.bgPressed,
|
|
826
860
|
},
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
:
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
borderColor: semanticColors.color.border.primary,
|
|
833
|
-
color: semanticColors.button.fgDisabled,
|
|
834
|
-
},
|
|
835
|
-
}),
|
|
861
|
+
[disabled]: {
|
|
862
|
+
backgroundColor: semanticColors.button.secondary.bgDisabled,
|
|
863
|
+
borderColor: semanticColors.color.border.primary,
|
|
864
|
+
color: semanticColors.button.fgDisabled,
|
|
865
|
+
},
|
|
836
866
|
},
|
|
837
867
|
destructive: {
|
|
838
868
|
backgroundColor: semanticColors.button.destructive.bg,
|
|
@@ -845,20 +875,15 @@ const StyledButtonBase$1 = styled(ButtonBase, {
|
|
|
845
875
|
backgroundColor: semanticColors.color.status.error.fg,
|
|
846
876
|
filter: 'brightness(0.9)',
|
|
847
877
|
},
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
:
|
|
851
|
-
|
|
852
|
-
backgroundColor: semanticColors.button.primary.bgDisabled,
|
|
853
|
-
color: semanticColors.button.fgDisabled,
|
|
854
|
-
},
|
|
855
|
-
}),
|
|
878
|
+
[disabled]: {
|
|
879
|
+
backgroundColor: semanticColors.button.primary.bgDisabled,
|
|
880
|
+
color: semanticColors.button.fgDisabled,
|
|
881
|
+
},
|
|
856
882
|
},
|
|
857
883
|
tertiary: {
|
|
858
884
|
backgroundColor: 'transparent',
|
|
859
885
|
color: semanticColors.color.text.input,
|
|
860
886
|
border: 'none',
|
|
861
|
-
padding: 0,
|
|
862
887
|
lineHeight: 1,
|
|
863
888
|
'&:hover': {
|
|
864
889
|
backgroundColor: 'transparent',
|
|
@@ -867,24 +892,26 @@ const StyledButtonBase$1 = styled(ButtonBase, {
|
|
|
867
892
|
'&:active': {
|
|
868
893
|
color: semanticColors.button.tertiary.fgPressed,
|
|
869
894
|
},
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
:
|
|
873
|
-
|
|
874
|
-
backgroundColor: 'transparent',
|
|
875
|
-
color: semanticColors.button.tertiary.fgDisabled,
|
|
876
|
-
},
|
|
877
|
-
}),
|
|
895
|
+
[disabled]: {
|
|
896
|
+
backgroundColor: 'transparent',
|
|
897
|
+
color: semanticColors.button.tertiary.fgDisabled,
|
|
898
|
+
},
|
|
878
899
|
},
|
|
879
900
|
};
|
|
901
|
+
// MUI greys a loading button as disabled; keep the label in the variant's colour
|
|
902
|
+
const { color } = variantStyles[variant];
|
|
880
903
|
return {
|
|
881
904
|
...baseStyles,
|
|
882
905
|
...variantStyles[variant],
|
|
906
|
+
[`&.${buttonClasses.loadingPositionStart}, &.${buttonClasses.loadingPositionEnd}`]: { color },
|
|
883
907
|
};
|
|
884
908
|
});
|
|
909
|
+
const IconSlot = styled('span')({
|
|
910
|
+
display: 'contents',
|
|
911
|
+
});
|
|
885
912
|
const LoadingSpinner = styled(CircularProgress, {
|
|
886
|
-
shouldForwardProp: prop => prop !== '
|
|
887
|
-
})(({
|
|
913
|
+
shouldForwardProp: prop => prop !== 'buttonVariant',
|
|
914
|
+
})(({ buttonVariant }) => {
|
|
888
915
|
// Use appropriate spinner color for each variant to ensure visibility
|
|
889
916
|
const spinnerColors = {
|
|
890
917
|
primary: semanticColors.color.surface.raised,
|
|
@@ -893,14 +920,22 @@ const LoadingSpinner = styled(CircularProgress, {
|
|
|
893
920
|
tertiary: semanticColors.button.tertiary.fg,
|
|
894
921
|
};
|
|
895
922
|
return {
|
|
896
|
-
color: spinnerColors[
|
|
923
|
+
color: spinnerColors[buttonVariant],
|
|
897
924
|
};
|
|
898
925
|
});
|
|
899
926
|
/**
|
|
900
|
-
* ModButton - Text button component based on MUI
|
|
927
|
+
* ModButton - Text button component based on MUI Button
|
|
901
928
|
*/
|
|
902
|
-
function ModButton({ variant = 'primary', size = 'medium', loading = false, children,
|
|
903
|
-
|
|
929
|
+
function ModButton({ variant = 'primary', size = 'medium', loading = false, children, startIcon, endIcon, ...rest }) {
|
|
930
|
+
const loadingPosition = startIcon ? 'start' : endIcon ? 'end' : 'center';
|
|
931
|
+
// Mirrors MUI: the spinner is named by the button, which gets an id while loading
|
|
932
|
+
const generatedId = useId();
|
|
933
|
+
const id = rest.id ?? (loading ? generatedId : undefined);
|
|
934
|
+
return (jsx(StyledButton, { buttonVariant: variant, buttonSize: size,
|
|
935
|
+
// Pinned so theme defaultProps or a ButtonGroup can't restyle it; ButtonBase had no focus ripple
|
|
936
|
+
variant: "text", size: "medium", color: "primary", disableFocusRipple: true, loading: loading, loadingPosition: loadingPosition, loadingIndicator: jsx(LoadingSpinner, { buttonVariant: variant,
|
|
937
|
+
// With an icon, the anchored indicator is the icon's size and the spinner fills it
|
|
938
|
+
size: loadingPosition === 'center' ? (size === 'small' ? iconSize.md : iconSize.xl) : '100%', "aria-labelledby": id }), startIcon: startIcon && jsx(IconSlot, { children: startIcon }), endIcon: endIcon && jsx(IconSlot, { children: endIcon }), "aria-busy": loading || undefined, ...rest, id: id, children: children }));
|
|
904
939
|
}
|
|
905
940
|
ModButton.displayName = 'ModButton';
|
|
906
941
|
|