@mhome/ui 0.1.3 → 0.1.6
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/index.cjs.js +2 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.esm.js +2 -2
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/date-picker.jsx +5 -5
- package/src/components/dialog.jsx +23 -55
- package/src/components/drawer.jsx +6 -1
- package/src/components/icon-button.jsx +2 -1
- package/src/components/menu.jsx +83 -10
- package/src/components/select.jsx +10 -3
- package/src/components/tabs.jsx +2 -2
- package/src/components/text-field.jsx +1 -1
- package/src/components/typography.jsx +6 -2
package/package.json
CHANGED
|
@@ -26,6 +26,8 @@ const DatePicker = React.forwardRef(
|
|
|
26
26
|
const inputRef = React.useRef(null);
|
|
27
27
|
const yearPickerRef = React.useRef(null);
|
|
28
28
|
const currentYearButtonRef = React.useRef(null);
|
|
29
|
+
const [viewMode, setViewMode] = React.useState("month"); // "month" or "year"
|
|
30
|
+
const [showYearPicker, setShowYearPicker] = React.useState(false);
|
|
29
31
|
|
|
30
32
|
React.useImperativeHandle(ref, () => inputRef.current);
|
|
31
33
|
|
|
@@ -52,7 +54,7 @@ const DatePicker = React.forwardRef(
|
|
|
52
54
|
}
|
|
53
55
|
};
|
|
54
56
|
|
|
55
|
-
const handleClickOutside = (event) => {
|
|
57
|
+
const handleClickOutside = React.useCallback((event) => {
|
|
56
58
|
if (
|
|
57
59
|
calendarRef.current &&
|
|
58
60
|
!calendarRef.current.contains(event.target) &&
|
|
@@ -65,7 +67,7 @@ const DatePicker = React.forwardRef(
|
|
|
65
67
|
onOpenChange(false);
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
|
-
};
|
|
70
|
+
}, [onOpenChange]);
|
|
69
71
|
|
|
70
72
|
React.useEffect(() => {
|
|
71
73
|
if (open) {
|
|
@@ -74,12 +76,10 @@ const DatePicker = React.forwardRef(
|
|
|
74
76
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
75
77
|
};
|
|
76
78
|
}
|
|
77
|
-
}, [open]);
|
|
79
|
+
}, [open, handleClickOutside]);
|
|
78
80
|
|
|
79
81
|
const textFieldProps = slotProps?.textField || {};
|
|
80
82
|
const displayValue = selectedDate ? selectedDate.format("YYYY-MM-DD") : "";
|
|
81
|
-
const [viewMode, setViewMode] = React.useState("month"); // "month" or "year"
|
|
82
|
-
const [showYearPicker, setShowYearPicker] = React.useState(false);
|
|
83
83
|
|
|
84
84
|
// Scroll to current year when year picker opens
|
|
85
85
|
React.useEffect(() => {
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import { createPortal } from "react-dom";
|
|
3
3
|
import { cn, spacingToPx, useIsDarkMode } from "../lib/utils";
|
|
4
4
|
import { getBackground } from "../common/adaptive-theme-provider";
|
|
5
|
-
import {
|
|
5
|
+
import { backgroundTypeState, useRecoilValue } from "../global-state";
|
|
6
6
|
|
|
7
7
|
const Dialog = ({
|
|
8
8
|
open,
|
|
@@ -330,14 +330,23 @@ const DialogContent = React.forwardRef(
|
|
|
330
330
|
);
|
|
331
331
|
DialogContent.displayName = "DialogContent";
|
|
332
332
|
|
|
333
|
+
// Context to track if DialogTitle is inside DialogHeader
|
|
334
|
+
const DialogHeaderContext = React.createContext(false);
|
|
335
|
+
|
|
333
336
|
const DialogHeader = ({ className, ...props }) => (
|
|
334
|
-
<
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
337
|
+
<DialogHeaderContext.Provider value={true}>
|
|
338
|
+
<div
|
|
339
|
+
className={cn(
|
|
340
|
+
"flex flex-col space-y-1.5 px-6 pt-6",
|
|
341
|
+
className
|
|
342
|
+
)}
|
|
343
|
+
style={{
|
|
344
|
+
textAlign: "left", // Ensure left alignment for all children
|
|
345
|
+
...props.style,
|
|
346
|
+
}}
|
|
347
|
+
{...props}
|
|
348
|
+
/>
|
|
349
|
+
</DialogHeaderContext.Provider>
|
|
341
350
|
);
|
|
342
351
|
DialogHeader.displayName = "DialogHeader";
|
|
343
352
|
|
|
@@ -354,15 +363,8 @@ DialogFooter.displayName = "DialogFooter";
|
|
|
354
363
|
|
|
355
364
|
const DialogTitle = React.forwardRef(
|
|
356
365
|
({ className, style, sx, ...props }, ref) => {
|
|
357
|
-
|
|
358
|
-
const
|
|
359
|
-
const bgColor = getBackground(backgroundType, actualMode === "dark");
|
|
360
|
-
const isGradient =
|
|
361
|
-
bgColor &&
|
|
362
|
-
typeof bgColor === "string" &&
|
|
363
|
-
(bgColor.startsWith("linear-gradient") ||
|
|
364
|
-
bgColor.startsWith("radial-gradient") ||
|
|
365
|
-
bgColor.startsWith("conic-gradient"));
|
|
366
|
+
// Check if DialogTitle is inside DialogHeader (DialogHeader already has padding)
|
|
367
|
+
const isInsideDialogHeader = React.useContext(DialogHeaderContext);
|
|
366
368
|
|
|
367
369
|
// Convert sx prop to style if provided, handling MUI spacing
|
|
368
370
|
const sxStyles = React.useMemo(() => {
|
|
@@ -444,26 +446,6 @@ const DialogTitle = React.forwardRef(
|
|
|
444
446
|
return converted;
|
|
445
447
|
}, [sx]);
|
|
446
448
|
|
|
447
|
-
// Extract padding from style to allow override
|
|
448
|
-
const {
|
|
449
|
-
padding,
|
|
450
|
-
paddingTop,
|
|
451
|
-
paddingBottom,
|
|
452
|
-
paddingLeft,
|
|
453
|
-
paddingRight,
|
|
454
|
-
backgroundColor,
|
|
455
|
-
...restStyle
|
|
456
|
-
} = style || {};
|
|
457
|
-
|
|
458
|
-
// Check if padding is explicitly set (if padding is set, individual paddings should be undefined)
|
|
459
|
-
// If no padding is set at all, use defaults
|
|
460
|
-
const hasAnyPadding =
|
|
461
|
-
padding !== undefined ||
|
|
462
|
-
paddingTop !== undefined ||
|
|
463
|
-
paddingBottom !== undefined ||
|
|
464
|
-
paddingLeft !== undefined ||
|
|
465
|
-
paddingRight !== undefined;
|
|
466
|
-
|
|
467
449
|
return (
|
|
468
450
|
<h2
|
|
469
451
|
ref={ref}
|
|
@@ -471,28 +453,14 @@ const DialogTitle = React.forwardRef(
|
|
|
471
453
|
"rounded-t-[inherit]",
|
|
472
454
|
"text-lg font-semibold leading-none tracking-tight",
|
|
473
455
|
"text-foreground",
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
// For normal use, padding is handled by DialogHeader
|
|
456
|
+
"text-left",
|
|
457
|
+
!isInsideDialogHeader && "px-6 pt-6", // Default padding only when not inside DialogHeader
|
|
477
458
|
className
|
|
478
459
|
)}
|
|
479
460
|
style={{
|
|
480
|
-
|
|
481
|
-
...(backgroundColor !== undefined
|
|
482
|
-
? backgroundColor.startsWith("linear-gradient") ||
|
|
483
|
-
backgroundColor.startsWith("radial-gradient") ||
|
|
484
|
-
backgroundColor.startsWith("conic-gradient")
|
|
485
|
-
? { background: backgroundColor }
|
|
486
|
-
: { backgroundColor }
|
|
487
|
-
: {}),
|
|
488
|
-
// Allow padding override via style prop
|
|
489
|
-
padding: padding,
|
|
490
|
-
paddingLeft: paddingLeft,
|
|
491
|
-
paddingRight: paddingRight,
|
|
492
|
-
paddingTop: paddingTop,
|
|
493
|
-
paddingBottom: paddingBottom,
|
|
461
|
+
textAlign: "left",
|
|
494
462
|
...sxStyles,
|
|
495
|
-
...
|
|
463
|
+
...style,
|
|
496
464
|
}}
|
|
497
465
|
{...props}
|
|
498
466
|
/>
|
|
@@ -17,6 +17,7 @@ const Drawer = React.forwardRef(
|
|
|
17
17
|
variant = "temporary",
|
|
18
18
|
ModalProps,
|
|
19
19
|
SlideProps,
|
|
20
|
+
BackdropProps,
|
|
20
21
|
...props
|
|
21
22
|
},
|
|
22
23
|
ref
|
|
@@ -173,9 +174,13 @@ const Drawer = React.forwardRef(
|
|
|
173
174
|
opacity: open ? 1 : 0,
|
|
174
175
|
transition: `opacity ${transitionDuration}ms cubic-bezier(0.4, 0, 0.2, 1)`,
|
|
175
176
|
pointerEvents: open ? "auto" : "none",
|
|
177
|
+
...BackdropProps?.style,
|
|
176
178
|
}}
|
|
177
179
|
onClick={handleBackdropClick}
|
|
178
180
|
aria-hidden="true"
|
|
181
|
+
{...Object.fromEntries(
|
|
182
|
+
Object.entries(BackdropProps || {}).filter(([key]) => key !== "style")
|
|
183
|
+
)}
|
|
179
184
|
/>
|
|
180
185
|
)}
|
|
181
186
|
|
|
@@ -200,7 +205,7 @@ const Drawer = React.forwardRef(
|
|
|
200
205
|
}}
|
|
201
206
|
role="presentation"
|
|
202
207
|
{...Object.fromEntries(
|
|
203
|
-
Object.entries(props).filter(([key]) => key !== "style")
|
|
208
|
+
Object.entries(props).filter(([key]) => key !== "style" && key !== "BackdropProps")
|
|
204
209
|
)}
|
|
205
210
|
>
|
|
206
211
|
{/* Paper (drawer content) */}
|
|
@@ -70,8 +70,9 @@ const IconButton = React.forwardRef(
|
|
|
70
70
|
}, [children, size]);
|
|
71
71
|
|
|
72
72
|
// Warn if no aria-label is provided (accessibility best practice)
|
|
73
|
+
// Only warn in development mode
|
|
73
74
|
React.useEffect(() => {
|
|
74
|
-
if (!ariaLabel && !props["aria-labelledby"]) {
|
|
75
|
+
if (process.env.NODE_ENV === "development" && !ariaLabel && !props["aria-labelledby"]) {
|
|
75
76
|
console.warn(
|
|
76
77
|
"IconButton: Missing aria-label or aria-labelledby. Icon-only buttons should have accessible labels."
|
|
77
78
|
);
|
package/src/components/menu.jsx
CHANGED
|
@@ -24,6 +24,56 @@ const Menu = React.forwardRef(
|
|
|
24
24
|
const positionType = disablePortal ? positionProp : "fixed";
|
|
25
25
|
const menuRef = React.useRef(null);
|
|
26
26
|
const [position, setPosition] = React.useState({ top: 0, left: 0 });
|
|
27
|
+
const previousPositionRef = React.useRef({ top: 0, left: 0 });
|
|
28
|
+
|
|
29
|
+
// Extract borderRadius to a stable value to prevent infinite loops
|
|
30
|
+
// Use a ref to track the last borderRadius value to avoid dependency issues
|
|
31
|
+
// MUST be called before any early returns (React Hooks rule)
|
|
32
|
+
const borderRadiusRef = React.useRef(PaperProps?.style?.borderRadius || "8px");
|
|
33
|
+
if (PaperProps?.style?.borderRadius !== undefined) {
|
|
34
|
+
borderRadiusRef.current = PaperProps.style.borderRadius;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Process children to add borderRadius info to MenuItems
|
|
38
|
+
// We'll do this in the render phase instead of useMemo to avoid issues
|
|
39
|
+
const processChildren = (childrenToProcess) => {
|
|
40
|
+
if (!childrenToProcess) return childrenToProcess;
|
|
41
|
+
|
|
42
|
+
const borderRadius = borderRadiusRef.current;
|
|
43
|
+
|
|
44
|
+
// Get all MenuItem children first
|
|
45
|
+
const childrenArray = React.Children.toArray(childrenToProcess).filter(
|
|
46
|
+
(c) => {
|
|
47
|
+
if (!React.isValidElement(c)) return false;
|
|
48
|
+
const type = c.type;
|
|
49
|
+
return type?.displayName === "MenuItem" ||
|
|
50
|
+
(typeof type === 'function' && type.name === 'MenuItem');
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
return React.Children.map(childrenToProcess, (child) => {
|
|
55
|
+
if (!React.isValidElement(child)) return child;
|
|
56
|
+
|
|
57
|
+
// Check if child is a MenuItem
|
|
58
|
+
const type = child.type;
|
|
59
|
+
const isMenuItem = type?.displayName === "MenuItem" ||
|
|
60
|
+
(typeof type === 'function' && type.name === 'MenuItem');
|
|
61
|
+
|
|
62
|
+
if (!isMenuItem) return child;
|
|
63
|
+
|
|
64
|
+
const childIndex = childrenArray.findIndex((c) => c === child);
|
|
65
|
+
const isFirst = childIndex === 0;
|
|
66
|
+
const isLast = childIndex === childrenArray.length - 1;
|
|
67
|
+
|
|
68
|
+
// Clone child and pass borderRadius info
|
|
69
|
+
return React.cloneElement(child, {
|
|
70
|
+
...child.props,
|
|
71
|
+
_isFirst: isFirst,
|
|
72
|
+
_isLast: isLast,
|
|
73
|
+
_menuBorderRadius: borderRadius,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
};
|
|
27
77
|
|
|
28
78
|
React.useImperativeHandle(ref, () => menuRef.current);
|
|
29
79
|
|
|
@@ -255,7 +305,7 @@ const Menu = React.forwardRef(
|
|
|
255
305
|
}
|
|
256
306
|
};
|
|
257
307
|
}
|
|
258
|
-
}, [open, anchorEl, anchorOrigin, positionType, PaperProps?.style?.minWidth]);
|
|
308
|
+
}, [open, anchorEl, anchorOrigin.vertical, anchorOrigin.horizontal, positionType, PaperProps?.style?.minWidth]);
|
|
259
309
|
|
|
260
310
|
// Recalculate position after menu is rendered (to get actual dimensions)
|
|
261
311
|
React.useLayoutEffect(() => {
|
|
@@ -338,7 +388,15 @@ const Menu = React.forwardRef(
|
|
|
338
388
|
top = Math.max(padding, viewportHeight - menuHeight - padding);
|
|
339
389
|
}
|
|
340
390
|
|
|
341
|
-
|
|
391
|
+
// Only update position if it actually changed to prevent infinite loops
|
|
392
|
+
const newPosition = { top, left };
|
|
393
|
+
if (
|
|
394
|
+
Math.abs(previousPositionRef.current.top - newPosition.top) > 0.5 ||
|
|
395
|
+
Math.abs(previousPositionRef.current.left - newPosition.left) > 0.5
|
|
396
|
+
) {
|
|
397
|
+
previousPositionRef.current = newPosition;
|
|
398
|
+
setPosition(newPosition);
|
|
399
|
+
}
|
|
342
400
|
} catch (e) {
|
|
343
401
|
// Silently fail if calculation error
|
|
344
402
|
}
|
|
@@ -354,7 +412,7 @@ const Menu = React.forwardRef(
|
|
|
354
412
|
cancelAnimationFrame(rafId);
|
|
355
413
|
}
|
|
356
414
|
};
|
|
357
|
-
}, [open, anchorEl, anchorOrigin, positionType]); // Re-run when menu opens or anchor changes
|
|
415
|
+
}, [open, anchorEl, anchorOrigin.vertical, anchorOrigin.horizontal, positionType]); // Re-run when menu opens or anchor changes
|
|
358
416
|
|
|
359
417
|
// Handle backdrop click
|
|
360
418
|
React.useEffect(() => {
|
|
@@ -420,9 +478,11 @@ const Menu = React.forwardRef(
|
|
|
420
478
|
borderRadius: PaperProps?.style?.borderRadius || "8px",
|
|
421
479
|
minWidth: PaperProps?.style?.minWidth || 180,
|
|
422
480
|
maxWidth: "calc(100vw - 32px)",
|
|
423
|
-
padding: "4px 0",
|
|
481
|
+
padding: "4px 0", // Vertical padding only, no horizontal padding so MenuItem hover extends to border
|
|
424
482
|
height: "auto",
|
|
425
|
-
overflow: "
|
|
483
|
+
overflow: "hidden", // Ensure children don't overflow rounded corners, but allow MenuItem hover to extend to edges
|
|
484
|
+
// Ensure MenuItem can extend to edges
|
|
485
|
+
boxSizing: "border-box",
|
|
426
486
|
...PaperProps?.style,
|
|
427
487
|
...props.style,
|
|
428
488
|
}}
|
|
@@ -430,7 +490,7 @@ const Menu = React.forwardRef(
|
|
|
430
490
|
Object.entries(props || {}).filter(([key]) => key !== "style")
|
|
431
491
|
)}
|
|
432
492
|
>
|
|
433
|
-
{children}
|
|
493
|
+
{processChildren(children)}
|
|
434
494
|
</div>
|
|
435
495
|
);
|
|
436
496
|
|
|
@@ -450,7 +510,7 @@ Menu.displayName = "Menu";
|
|
|
450
510
|
|
|
451
511
|
const MenuItem = React.forwardRef(
|
|
452
512
|
(
|
|
453
|
-
{ className, onClick, disabled = false, sx, style, children, ...props },
|
|
513
|
+
{ className, onClick, disabled = false, sx, style, children, _isFirst, _isLast, _menuBorderRadius, ...props },
|
|
454
514
|
ref
|
|
455
515
|
) => {
|
|
456
516
|
const [hovered, setHovered] = React.useState(false);
|
|
@@ -475,13 +535,13 @@ const MenuItem = React.forwardRef(
|
|
|
475
535
|
paddingRight: `${menuItemPadding.x}px`,
|
|
476
536
|
paddingTop: `${menuItemPadding.y}px`,
|
|
477
537
|
paddingBottom: `${menuItemPadding.y}px`,
|
|
538
|
+
margin: 0, // Ensure no margin that could cause overflow
|
|
478
539
|
cursor: disabled ? "not-allowed" : "pointer",
|
|
479
540
|
fontSize: menuItemFontSize,
|
|
480
541
|
color: disabled
|
|
481
542
|
? "#666666"
|
|
482
543
|
: "#000000", // Use fixed color for testing
|
|
483
|
-
backgroundColor:
|
|
484
|
-
hovered && !disabled ? "hsl(var(--accent))" : "transparent",
|
|
544
|
+
backgroundColor: hovered && !disabled ? "hsl(var(--accent))" : "transparent",
|
|
485
545
|
opacity: disabled
|
|
486
546
|
? 0.5
|
|
487
547
|
: sxStyles.opacity !== undefined
|
|
@@ -493,7 +553,16 @@ const MenuItem = React.forwardRef(
|
|
|
493
553
|
textAlign: "left",
|
|
494
554
|
fontWeight: "normal",
|
|
495
555
|
width: "100%",
|
|
556
|
+
maxWidth: "100%", // Ensure it doesn't exceed parent width
|
|
496
557
|
boxSizing: "border-box",
|
|
558
|
+
position: "relative",
|
|
559
|
+
// Ensure MenuItem doesn't overflow Menu boundaries
|
|
560
|
+
overflow: "hidden",
|
|
561
|
+
// Apply border radius to match Menu's borderRadius
|
|
562
|
+
borderTopLeftRadius: _isFirst ? _menuBorderRadius : 0,
|
|
563
|
+
borderTopRightRadius: _isFirst ? _menuBorderRadius : 0,
|
|
564
|
+
borderBottomLeftRadius: _isLast ? _menuBorderRadius : 0,
|
|
565
|
+
borderBottomRightRadius: _isLast ? _menuBorderRadius : 0,
|
|
497
566
|
...sxStyles,
|
|
498
567
|
...style,
|
|
499
568
|
};
|
|
@@ -533,7 +602,11 @@ const MenuItem = React.forwardRef(
|
|
|
533
602
|
"focus:outline-none focus:bg-accent focus:text-accent-foreground",
|
|
534
603
|
className
|
|
535
604
|
)}
|
|
536
|
-
style={
|
|
605
|
+
style={{
|
|
606
|
+
...mergedStyle,
|
|
607
|
+
// Use pseudo-element approach: extend hover background to edges
|
|
608
|
+
position: "relative",
|
|
609
|
+
}}
|
|
537
610
|
onClick={handleClick}
|
|
538
611
|
onMouseDown={handleMouseDown}
|
|
539
612
|
onKeyDown={handleKeyDown}
|
|
@@ -28,6 +28,8 @@ const Select = React.forwardRef(
|
|
|
28
28
|
multiple = false,
|
|
29
29
|
sx,
|
|
30
30
|
style,
|
|
31
|
+
menuStyle, // Style for the dropdown menu (the open listbox)
|
|
32
|
+
menuClassName, // ClassName for the dropdown menu
|
|
31
33
|
...props
|
|
32
34
|
},
|
|
33
35
|
ref
|
|
@@ -154,7 +156,7 @@ const Select = React.forwardRef(
|
|
|
154
156
|
paddingRight: endAdornment ? "8px" : "14px",
|
|
155
157
|
paddingTop: "6px",
|
|
156
158
|
paddingBottom: "6px",
|
|
157
|
-
// If borderRadius is provided in props.style, use it; otherwise let Tailwind
|
|
159
|
+
// If borderRadius is provided in props.style, use it; otherwise let Tailwind classes handle it
|
|
158
160
|
...(style?.borderRadius !== undefined
|
|
159
161
|
? { borderRadius: style.borderRadius }
|
|
160
162
|
: {}),
|
|
@@ -194,16 +196,21 @@ const Select = React.forwardRef(
|
|
|
194
196
|
id={`${selectId}-listbox`}
|
|
195
197
|
role="listbox"
|
|
196
198
|
aria-label={label || "Options"}
|
|
197
|
-
className=
|
|
199
|
+
className={cn(
|
|
200
|
+
"absolute z-50 w-full mt-1 shadow-lg",
|
|
201
|
+
menuClassName
|
|
202
|
+
)}
|
|
198
203
|
style={{
|
|
199
204
|
backgroundColor: "hsl(var(--card))",
|
|
200
205
|
boxShadow: isDark
|
|
201
|
-
? "0px 4px 12px rgba(0, 0, 0, 0.4)
|
|
206
|
+
? "0px 4px 12px rgba(0, 0, 0, 0.4)"
|
|
202
207
|
: "0px 4px 12px rgba(0, 0, 0, 0.15)",
|
|
203
208
|
border: isDark
|
|
204
209
|
? "1px solid rgba(255, 255, 255, 0.1)"
|
|
205
210
|
: "1px solid hsl(var(--border))",
|
|
206
211
|
borderRadius: "8px",
|
|
212
|
+
overflow: "hidden",
|
|
213
|
+
...menuStyle,
|
|
207
214
|
}}
|
|
208
215
|
>
|
|
209
216
|
{React.Children.map(children, (child) => {
|
package/src/components/tabs.jsx
CHANGED
|
@@ -218,7 +218,7 @@ const Tab = React.forwardRef(
|
|
|
218
218
|
}
|
|
219
219
|
}}
|
|
220
220
|
className={cn(
|
|
221
|
-
"cursor-pointer transition-all duration-200 text-sm border-none bg-transparent focus:outline-none
|
|
221
|
+
"cursor-pointer transition-all duration-200 text-sm border-none bg-transparent focus:outline-none",
|
|
222
222
|
defaultPaddingClass,
|
|
223
223
|
"min-w-[72px] min-h-[48px] flex-1",
|
|
224
224
|
selected ? "font-semibold" : "font-medium",
|
|
@@ -320,7 +320,7 @@ const Tab = React.forwardRef(
|
|
|
320
320
|
}
|
|
321
321
|
}}
|
|
322
322
|
className={cn(
|
|
323
|
-
"cursor-pointer transition-all duration-200 min-h-[32px] min-w-[100px] rounded-2xl text-sm border-none focus:outline-none
|
|
323
|
+
"cursor-pointer transition-all duration-200 min-h-[32px] min-w-[100px] rounded-2xl text-sm border-none focus:outline-none",
|
|
324
324
|
defaultPaddingClass,
|
|
325
325
|
defaultMarginClass,
|
|
326
326
|
selected ? "font-semibold" : "font-medium",
|
|
@@ -46,7 +46,7 @@ const typographyVariants = cva("", {
|
|
|
46
46
|
|
|
47
47
|
const Typography = React.forwardRef(
|
|
48
48
|
(
|
|
49
|
-
{ className, variant = "body1", component, style, color, ...props },
|
|
49
|
+
{ className, variant = "body1", component, style, color, noWrap, gutterBottom, ...props },
|
|
50
50
|
ref
|
|
51
51
|
) => {
|
|
52
52
|
// Map MUI color props to shadcn colors
|
|
@@ -66,7 +66,11 @@ const Typography = React.forwardRef(
|
|
|
66
66
|
typographyVariants({ variant, color: mappedColor }),
|
|
67
67
|
className
|
|
68
68
|
)}
|
|
69
|
-
style={
|
|
69
|
+
style={{
|
|
70
|
+
...(noWrap && { whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }),
|
|
71
|
+
...(gutterBottom && { marginBottom: "0.35em" }),
|
|
72
|
+
...style,
|
|
73
|
+
}}
|
|
70
74
|
{...props}
|
|
71
75
|
/>
|
|
72
76
|
);
|