UNPKG

10.2 kBJavaScriptView Raw
1'use client';
2
3import * as React from 'react';
4import { isFragment } from 'react-is';
5import PropTypes from 'prop-types';
6import clsx from 'clsx';
7import composeClasses from '@mui/utils/composeClasses';
8import getValidReactChildren from '@mui/utils/getValidReactChildren';
9import { styled } from "../zero-styled/index.js";
10import memoTheme from "../utils/memoTheme.js";
11import { useDefaultProps } from "../DefaultPropsProvider/index.js";
12import capitalize from "../utils/capitalize.js";
13import toggleButtonGroupClasses, { getToggleButtonGroupUtilityClass } from "./toggleButtonGroupClasses.js";
14import ToggleButtonGroupContext from "./ToggleButtonGroupContext.js";
15import ToggleButtonGroupButtonContext from "./ToggleButtonGroupButtonContext.js";
16import toggleButtonClasses from "../ToggleButton/toggleButtonClasses.js";
17import { jsx as _jsx } from "react/jsx-runtime";
18const useUtilityClasses = ownerState => {
19 const {
20 classes,
21 orientation,
22 fullWidth,
23 disabled
24 } = ownerState;
25 const slots = {
26 root: ['root', orientation, fullWidth && 'fullWidth'],
27 grouped: ['grouped', `grouped${capitalize(orientation)}`, disabled && 'disabled'],
28 firstButton: ['firstButton'],
29 lastButton: ['lastButton'],
30 middleButton: ['middleButton']
31 };
32 return composeClasses(slots, getToggleButtonGroupUtilityClass, classes);
33};
34const ToggleButtonGroupRoot = styled('div', {
35 name: 'MuiToggleButtonGroup',
36 slot: 'Root',
37 overridesResolver: (props, styles) => {
38 const {
39 ownerState
40 } = props;
41 return [{
42 [`& .${toggleButtonGroupClasses.grouped}`]: styles.grouped
43 }, {
44 [`& .${toggleButtonGroupClasses.grouped}`]: styles[`grouped${capitalize(ownerState.orientation)}`]
45 }, {
46 [`& .${toggleButtonGroupClasses.firstButton}`]: styles.firstButton
47 }, {
48 [`& .${toggleButtonGroupClasses.lastButton}`]: styles.lastButton
49 }, {
50 [`& .${toggleButtonGroupClasses.middleButton}`]: styles.middleButton
51 }, styles.root, ownerState.orientation === 'vertical' && styles.vertical, ownerState.fullWidth && styles.fullWidth];
52 }
53})(memoTheme(({
54 theme
55}) => ({
56 display: 'inline-flex',
57 borderRadius: (theme.vars || theme).shape.borderRadius,
58 variants: [{
59 props: {
60 orientation: 'vertical'
61 },
62 style: {
63 flexDirection: 'column',
64 [`& .${toggleButtonGroupClasses.grouped}`]: {
65 [`&.${toggleButtonGroupClasses.selected} + .${toggleButtonGroupClasses.grouped}.${toggleButtonGroupClasses.selected}`]: {
66 borderTop: 0,
67 marginTop: 0
68 }
69 },
70 [`& .${toggleButtonGroupClasses.firstButton},& .${toggleButtonGroupClasses.middleButton}`]: {
71 borderBottomLeftRadius: 0,
72 borderBottomRightRadius: 0
73 },
74 [`& .${toggleButtonGroupClasses.lastButton},& .${toggleButtonGroupClasses.middleButton}`]: {
75 marginTop: -1,
76 borderTop: '1px solid transparent',
77 borderTopLeftRadius: 0,
78 borderTopRightRadius: 0
79 },
80 [`& .${toggleButtonGroupClasses.lastButton}.${toggleButtonClasses.disabled},& .${toggleButtonGroupClasses.middleButton}.${toggleButtonClasses.disabled}`]: {
81 borderTop: '1px solid transparent'
82 }
83 }
84 }, {
85 props: {
86 fullWidth: true
87 },
88 style: {
89 width: '100%'
90 }
91 }, {
92 props: {
93 orientation: 'horizontal'
94 },
95 style: {
96 [`& .${toggleButtonGroupClasses.grouped}`]: {
97 [`&.${toggleButtonGroupClasses.selected} + .${toggleButtonGroupClasses.grouped}.${toggleButtonGroupClasses.selected}`]: {
98 borderLeft: 0,
99 marginLeft: 0
100 }
101 },
102 [`& .${toggleButtonGroupClasses.firstButton},& .${toggleButtonGroupClasses.middleButton}`]: {
103 borderTopRightRadius: 0,
104 borderBottomRightRadius: 0
105 },
106 [`& .${toggleButtonGroupClasses.lastButton},& .${toggleButtonGroupClasses.middleButton}`]: {
107 marginLeft: -1,
108 borderLeft: '1px solid transparent',
109 borderTopLeftRadius: 0,
110 borderBottomLeftRadius: 0
111 },
112 [`& .${toggleButtonGroupClasses.lastButton}.${toggleButtonClasses.disabled},& .${toggleButtonGroupClasses.middleButton}.${toggleButtonClasses.disabled}`]: {
113 borderLeft: '1px solid transparent'
114 }
115 }
116 }]
117})));
118const ToggleButtonGroup = /*#__PURE__*/React.forwardRef(function ToggleButtonGroup(inProps, ref) {
119 const props = useDefaultProps({
120 props: inProps,
121 name: 'MuiToggleButtonGroup'
122 });
123 const {
124 children,
125 className,
126 color = 'standard',
127 disabled = false,
128 exclusive = false,
129 fullWidth = false,
130 onChange,
131 orientation = 'horizontal',
132 size = 'medium',
133 value,
134 ...other
135 } = props;
136 const ownerState = {
137 ...props,
138 disabled,
139 fullWidth,
140 orientation,
141 size
142 };
143 const classes = useUtilityClasses(ownerState);
144 const handleChange = React.useCallback((event, buttonValue) => {
145 if (!onChange) {
146 return;
147 }
148 const index = value && value.indexOf(buttonValue);
149 let newValue;
150 if (value && index >= 0) {
151 newValue = value.slice();
152 newValue.splice(index, 1);
153 } else {
154 newValue = value ? value.concat(buttonValue) : [buttonValue];
155 }
156 onChange(event, newValue);
157 }, [onChange, value]);
158 const handleExclusiveChange = React.useCallback((event, buttonValue) => {
159 if (!onChange) {
160 return;
161 }
162 onChange(event, value === buttonValue ? null : buttonValue);
163 }, [onChange, value]);
164 const context = React.useMemo(() => ({
165 className: classes.grouped,
166 onChange: exclusive ? handleExclusiveChange : handleChange,
167 value,
168 size,
169 fullWidth,
170 color,
171 disabled
172 }), [classes.grouped, exclusive, handleExclusiveChange, handleChange, value, size, fullWidth, color, disabled]);
173 const validChildren = getValidReactChildren(children);
174 const childrenCount = validChildren.length;
175 const getButtonPositionClassName = index => {
176 const isFirstButton = index === 0;
177 const isLastButton = index === childrenCount - 1;
178 if (isFirstButton && isLastButton) {
179 return '';
180 }
181 if (isFirstButton) {
182 return classes.firstButton;
183 }
184 if (isLastButton) {
185 return classes.lastButton;
186 }
187 return classes.middleButton;
188 };
189 return /*#__PURE__*/_jsx(ToggleButtonGroupRoot, {
190 role: "group",
191 className: clsx(classes.root, className),
192 ref: ref,
193 ownerState: ownerState,
194 ...other,
195 children: /*#__PURE__*/_jsx(ToggleButtonGroupContext.Provider, {
196 value: context,
197 children: validChildren.map((child, index) => {
198 if (process.env.NODE_ENV !== 'production') {
199 if (isFragment(child)) {
200 console.error(["MUI: The ToggleButtonGroup component doesn't accept a Fragment as a child.", 'Consider providing an array instead.'].join('\n'));
201 }
202 }
203 return /*#__PURE__*/_jsx(ToggleButtonGroupButtonContext.Provider, {
204 value: getButtonPositionClassName(index),
205 children: child
206 }, index);
207 })
208 })
209 });
210});
211process.env.NODE_ENV !== "production" ? ToggleButtonGroup.propTypes /* remove-proptypes */ = {
212 // ┌────────────────────────────── Warning ──────────────────────────────┐
213 // │ These PropTypes are generated from the TypeScript type definitions. │
214 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
215 // └─────────────────────────────────────────────────────────────────────┘
216 /**
217 * The content of the component.
218 */
219 children: PropTypes.node,
220 /**
221 * Override or extend the styles applied to the component.
222 */
223 classes: PropTypes.object,
224 /**
225 * @ignore
226 */
227 className: PropTypes.string,
228 /**
229 * The color of the button when it is selected.
230 * It supports both default and custom theme colors, which can be added as shown in the
231 * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
232 * @default 'standard'
233 */
234 color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['standard', 'primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
235 /**
236 * If `true`, the component is disabled. This implies that all ToggleButton children will be disabled.
237 * @default false
238 */
239 disabled: PropTypes.bool,
240 /**
241 * If `true`, only allow one of the child ToggleButton values to be selected.
242 * @default false
243 */
244 exclusive: PropTypes.bool,
245 /**
246 * If `true`, the button group will take up the full width of its container.
247 * @default false
248 */
249 fullWidth: PropTypes.bool,
250 /**
251 * Callback fired when the value changes.
252 *
253 * @param {React.MouseEvent<HTMLElement>} event The event source of the callback.
254 * @param {any} value of the selected buttons. When `exclusive` is true
255 * this is a single value; when false an array of selected values. If no value
256 * is selected and `exclusive` is true the value is null; when false an empty array.
257 */
258 onChange: PropTypes.func,
259 /**
260 * The component orientation (layout flow direction).
261 * @default 'horizontal'
262 */
263 orientation: PropTypes.oneOf(['horizontal', 'vertical']),
264 /**
265 * The size of the component.
266 * @default 'medium'
267 */
268 size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['small', 'medium', 'large']), PropTypes.string]),
269 /**
270 * The system prop that allows defining system overrides as well as additional CSS styles.
271 */
272 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
273 /**
274 * The currently selected value within the group or an array of selected
275 * values when `exclusive` is false.
276 *
277 * The value must have reference equality with the option in order to be selected.
278 */
279 value: PropTypes.any
280} : void 0;
281export default ToggleButtonGroup;
\No newline at end of file