@moderneinc/design-system-components 7.7.0-next.19b91c → 7.7.0-next.6ace41
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 +88 -61
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +114 -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,48 @@ 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
|
+
inset: 'anchor(top) anchor(right) anchor(bottom) anchor(left)',
|
|
799
|
+
},
|
|
800
|
+
// Without anchor positioning, the spinner takes the standard icon size at the icon's edge
|
|
801
|
+
'@supports not (anchor-name: --a)': {
|
|
802
|
+
[`&.${buttonClasses.loadingPositionStart} .${buttonClasses.loadingIndicator}`]: {
|
|
803
|
+
inset: 'auto',
|
|
804
|
+
left: paddingX,
|
|
805
|
+
width: spinnerSize,
|
|
806
|
+
height: spinnerSize,
|
|
807
|
+
},
|
|
808
|
+
[`&.${buttonClasses.loadingPositionEnd} .${buttonClasses.loadingIndicator}`]: {
|
|
809
|
+
inset: 'auto',
|
|
810
|
+
right: paddingX,
|
|
811
|
+
width: spinnerSize,
|
|
812
|
+
height: spinnerSize,
|
|
813
|
+
},
|
|
814
|
+
},
|
|
785
815
|
// Disabled state (always show cursor)
|
|
786
|
-
[`&.${
|
|
816
|
+
[`&.${buttonClasses.disabled}`]: {
|
|
787
817
|
cursor: 'not-allowed',
|
|
788
818
|
pointerEvents: 'auto',
|
|
789
819
|
},
|
|
790
820
|
// Focus visible for keyboard navigation
|
|
791
|
-
[`&.${
|
|
821
|
+
[`&.${buttonClasses.focusVisible}`]: {
|
|
792
822
|
outline: `2px solid ${semanticColors.color.border.focus}`,
|
|
793
823
|
outlineOffset: 2,
|
|
794
824
|
},
|
|
@@ -805,14 +835,10 @@ const StyledButtonBase$1 = styled(ButtonBase, {
|
|
|
805
835
|
'&:active': {
|
|
806
836
|
backgroundColor: semanticColors.button.primary.bgPressed,
|
|
807
837
|
},
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
:
|
|
811
|
-
|
|
812
|
-
backgroundColor: semanticColors.button.primary.bgDisabled,
|
|
813
|
-
color: semanticColors.button.fgDisabled,
|
|
814
|
-
},
|
|
815
|
-
}),
|
|
838
|
+
[disabled]: {
|
|
839
|
+
backgroundColor: semanticColors.button.primary.bgDisabled,
|
|
840
|
+
color: semanticColors.button.fgDisabled,
|
|
841
|
+
},
|
|
816
842
|
},
|
|
817
843
|
secondary: {
|
|
818
844
|
backgroundColor: semanticColors.button.secondary.bg,
|
|
@@ -824,15 +850,11 @@ const StyledButtonBase$1 = styled(ButtonBase, {
|
|
|
824
850
|
'&:active': {
|
|
825
851
|
backgroundColor: semanticColors.button.secondary.bgPressed,
|
|
826
852
|
},
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
:
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
borderColor: semanticColors.color.border.primary,
|
|
833
|
-
color: semanticColors.button.fgDisabled,
|
|
834
|
-
},
|
|
835
|
-
}),
|
|
853
|
+
[disabled]: {
|
|
854
|
+
backgroundColor: semanticColors.button.secondary.bgDisabled,
|
|
855
|
+
borderColor: semanticColors.color.border.primary,
|
|
856
|
+
color: semanticColors.button.fgDisabled,
|
|
857
|
+
},
|
|
836
858
|
},
|
|
837
859
|
destructive: {
|
|
838
860
|
backgroundColor: semanticColors.button.destructive.bg,
|
|
@@ -845,20 +867,15 @@ const StyledButtonBase$1 = styled(ButtonBase, {
|
|
|
845
867
|
backgroundColor: semanticColors.color.status.error.fg,
|
|
846
868
|
filter: 'brightness(0.9)',
|
|
847
869
|
},
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
:
|
|
851
|
-
|
|
852
|
-
backgroundColor: semanticColors.button.primary.bgDisabled,
|
|
853
|
-
color: semanticColors.button.fgDisabled,
|
|
854
|
-
},
|
|
855
|
-
}),
|
|
870
|
+
[disabled]: {
|
|
871
|
+
backgroundColor: semanticColors.button.primary.bgDisabled,
|
|
872
|
+
color: semanticColors.button.fgDisabled,
|
|
873
|
+
},
|
|
856
874
|
},
|
|
857
875
|
tertiary: {
|
|
858
876
|
backgroundColor: 'transparent',
|
|
859
877
|
color: semanticColors.color.text.input,
|
|
860
878
|
border: 'none',
|
|
861
|
-
padding: 0,
|
|
862
879
|
lineHeight: 1,
|
|
863
880
|
'&:hover': {
|
|
864
881
|
backgroundColor: 'transparent',
|
|
@@ -867,24 +884,26 @@ const StyledButtonBase$1 = styled(ButtonBase, {
|
|
|
867
884
|
'&:active': {
|
|
868
885
|
color: semanticColors.button.tertiary.fgPressed,
|
|
869
886
|
},
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
:
|
|
873
|
-
|
|
874
|
-
backgroundColor: 'transparent',
|
|
875
|
-
color: semanticColors.button.tertiary.fgDisabled,
|
|
876
|
-
},
|
|
877
|
-
}),
|
|
887
|
+
[disabled]: {
|
|
888
|
+
backgroundColor: 'transparent',
|
|
889
|
+
color: semanticColors.button.tertiary.fgDisabled,
|
|
890
|
+
},
|
|
878
891
|
},
|
|
879
892
|
};
|
|
893
|
+
// MUI greys a loading button as disabled; keep the label in the variant's colour
|
|
894
|
+
const { color } = variantStyles[variant];
|
|
880
895
|
return {
|
|
881
896
|
...baseStyles,
|
|
882
897
|
...variantStyles[variant],
|
|
898
|
+
[`&.${buttonClasses.loadingPositionStart}, &.${buttonClasses.loadingPositionEnd}`]: { color },
|
|
883
899
|
};
|
|
884
900
|
});
|
|
901
|
+
const IconSlot = styled('span')({
|
|
902
|
+
display: 'contents',
|
|
903
|
+
});
|
|
885
904
|
const LoadingSpinner = styled(CircularProgress, {
|
|
886
|
-
shouldForwardProp: prop => prop !== '
|
|
887
|
-
})(({
|
|
905
|
+
shouldForwardProp: prop => prop !== 'buttonVariant',
|
|
906
|
+
})(({ buttonVariant }) => {
|
|
888
907
|
// Use appropriate spinner color for each variant to ensure visibility
|
|
889
908
|
const spinnerColors = {
|
|
890
909
|
primary: semanticColors.color.surface.raised,
|
|
@@ -893,14 +912,22 @@ const LoadingSpinner = styled(CircularProgress, {
|
|
|
893
912
|
tertiary: semanticColors.button.tertiary.fg,
|
|
894
913
|
};
|
|
895
914
|
return {
|
|
896
|
-
color: spinnerColors[
|
|
915
|
+
color: spinnerColors[buttonVariant],
|
|
897
916
|
};
|
|
898
917
|
});
|
|
899
918
|
/**
|
|
900
|
-
* ModButton - Text button component based on MUI
|
|
919
|
+
* ModButton - Text button component based on MUI Button
|
|
901
920
|
*/
|
|
902
|
-
function ModButton({ variant = 'primary', size = 'medium', loading = false, children,
|
|
903
|
-
|
|
921
|
+
function ModButton({ variant = 'primary', size = 'medium', loading = false, children, startIcon, endIcon, ...rest }) {
|
|
922
|
+
const loadingPosition = startIcon ? 'start' : endIcon ? 'end' : 'center';
|
|
923
|
+
// Mirrors MUI: the spinner is named by the button, which gets an id while loading
|
|
924
|
+
const generatedId = useId();
|
|
925
|
+
const id = rest.id ?? (loading ? generatedId : undefined);
|
|
926
|
+
return (jsx(StyledButton, { buttonVariant: variant, buttonSize: size,
|
|
927
|
+
// Pinned so theme defaultProps or a ButtonGroup can't restyle it; ButtonBase had no focus ripple
|
|
928
|
+
variant: "text", size: "medium", color: "primary", disableFocusRipple: true, loading: loading, loadingPosition: loadingPosition, loadingIndicator: jsx(LoadingSpinner, { buttonVariant: variant,
|
|
929
|
+
// With an icon, the anchored indicator is the icon's size and the spinner fills it
|
|
930
|
+
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
931
|
}
|
|
905
932
|
ModButton.displayName = 'ModButton';
|
|
906
933
|
|