@zimyo/ui 1.1.0 → 1.1.1

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.
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { AccordionProps as AccordionProps$1, AccordionSummaryProps, AccordionDetailsProps } from '@mui/material';
3
+ import { SxProps } from '@mui/system';
4
+
5
+ interface AccordionProps extends Omit<AccordionProps$1, 'sx' | 'onChange' | 'expanded'> {
6
+ type?: 'single' | 'multiple';
7
+ collapsible?: boolean;
8
+ value?: string | string[];
9
+ defaultValue?: string | string[];
10
+ onValueChange?: (value: string | string[]) => void;
11
+ children: React.ReactNode;
12
+ sx?: SxProps;
13
+ }
14
+ interface AccordionItemProps extends Omit<AccordionProps$1, 'sx'> {
15
+ value: string;
16
+ children: React.ReactNode;
17
+ sx?: SxProps;
18
+ }
19
+ interface AccordionTriggerProps extends Omit<AccordionSummaryProps, 'sx'> {
20
+ children: React.ReactNode;
21
+ sx?: SxProps;
22
+ expandIcon?: React.ReactNode;
23
+ }
24
+ interface AccordionContentProps extends Omit<AccordionDetailsProps, 'sx'> {
25
+ children: React.ReactNode;
26
+ sx?: SxProps;
27
+ }
28
+ declare const Accordion: React.ForwardRefExoticComponent<Omit<AccordionProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
29
+ declare const AccordionItem: React.ForwardRefExoticComponent<Omit<AccordionItemProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
30
+ declare const AccordionTrigger: React.ForwardRefExoticComponent<Omit<AccordionTriggerProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
31
+ declare const AccordionContent: React.ForwardRefExoticComponent<Omit<AccordionContentProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
32
+
33
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Accordion as default };
34
+ export type { AccordionContentProps, AccordionItemProps, AccordionProps, AccordionTriggerProps };
@@ -0,0 +1,129 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import React from 'react';
3
+ import { useTheme, Accordion as Accordion$1, AccordionSummary, AccordionDetails } from '@mui/material';
4
+ import { createSvgIcon } from '@mui/material/utils';
5
+
6
+ var ExpandMoreIcon = createSvgIcon(/*#__PURE__*/jsx("path", {
7
+ d: "M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z"
8
+ }), 'ExpandMore');
9
+
10
+ const AccordionContext = React.createContext({});
11
+ // Main Accordion Container Component
12
+ const Accordion = React.forwardRef(({ type = 'single', collapsible = false, value: controlledValue, defaultValue, onValueChange, children, sx = {}, ...props }, ref) => {
13
+ const theme = useTheme();
14
+ // Internal state management
15
+ const [internalValue, setInternalValue] = React.useState(() => {
16
+ if (controlledValue !== undefined)
17
+ return controlledValue;
18
+ if (defaultValue !== undefined)
19
+ return defaultValue;
20
+ return type === 'multiple' ? [] : '';
21
+ });
22
+ const value = controlledValue !== undefined ? controlledValue : internalValue;
23
+ const handleValueChange = React.useCallback((newValue) => {
24
+ if (controlledValue === undefined) {
25
+ setInternalValue(newValue);
26
+ }
27
+ onValueChange?.(newValue);
28
+ }, [controlledValue, onValueChange]);
29
+ const contextValue = React.useMemo(() => ({
30
+ type,
31
+ collapsible,
32
+ value,
33
+ defaultValue,
34
+ onValueChange: handleValueChange,
35
+ }), [type, collapsible, value, defaultValue, handleValueChange]);
36
+ return (jsx(AccordionContext.Provider, { value: contextValue, children: jsx("div", { ref: ref, style: {
37
+ display: 'flex',
38
+ flexDirection: 'column',
39
+ gap: theme.spacing(1),
40
+ }, ...props, children: children }) }));
41
+ });
42
+ // AccordionItem Component
43
+ const AccordionItem = React.forwardRef(({ value: itemValue, children, sx = {}, ...props }, ref) => {
44
+ const theme = useTheme();
45
+ const context = React.useContext(AccordionContext);
46
+ const isExpanded = React.useMemo(() => {
47
+ if (context.type === 'multiple') {
48
+ return Array.isArray(context.value) && context.value.includes(itemValue);
49
+ }
50
+ return context.value === itemValue;
51
+ }, [context.value, context.type, itemValue]);
52
+ const handleChange = React.useCallback(() => {
53
+ if (!context.onValueChange)
54
+ return;
55
+ if (context.type === 'multiple') {
56
+ const currentValue = Array.isArray(context.value) ? context.value : [];
57
+ const newValue = isExpanded
58
+ ? currentValue.filter(v => v !== itemValue)
59
+ : [...currentValue, itemValue];
60
+ context.onValueChange(newValue);
61
+ }
62
+ else {
63
+ const newValue = isExpanded && context.collapsible ? '' : itemValue;
64
+ context.onValueChange(newValue);
65
+ }
66
+ }, [context, itemValue, isExpanded]);
67
+ return (jsx(Accordion$1, { ref: ref, expanded: isExpanded, onChange: handleChange, variant: "outlined", sx: {
68
+ borderRadius: theme.radius?.sm || theme.shape.borderRadius,
69
+ '&:before': {
70
+ display: 'none',
71
+ },
72
+ '&.Mui-expanded': {
73
+ margin: 0,
74
+ },
75
+ border: `1px solid ${theme.palette.divider}`,
76
+ ...sx,
77
+ }, ...props, children: children }));
78
+ });
79
+ // AccordionTrigger Component
80
+ const AccordionTrigger = React.forwardRef(({ children, sx = {}, expandIcon, ...props }, ref) => {
81
+ const theme = useTheme();
82
+ const defaultExpandIcon = expandIcon !== undefined ? expandIcon : jsx(ExpandMoreIcon, {});
83
+ return (jsx(AccordionSummary, { ref: ref, expandIcon: defaultExpandIcon, sx: {
84
+ borderRadius: theme.radius?.sm || theme.shape.borderRadius,
85
+ minHeight: 56,
86
+ fontWeight: 500,
87
+ '&.Mui-expanded': {
88
+ minHeight: 56,
89
+ borderBottomLeftRadius: 0,
90
+ borderBottomRightRadius: 0,
91
+ borderBottom: `1px solid ${theme.palette.divider}`,
92
+ },
93
+ '& .MuiAccordionSummary-content': {
94
+ margin: '12px 0',
95
+ '&.Mui-expanded': {
96
+ margin: '12px 0',
97
+ },
98
+ },
99
+ '& .MuiAccordionSummary-expandIconWrapper': {
100
+ transition: theme.transitions.create('transform', {
101
+ duration: theme.transitions.duration.shortest,
102
+ }),
103
+ '&.Mui-expanded': {
104
+ transform: 'rotate(180deg)',
105
+ },
106
+ },
107
+ '&:hover': {
108
+ backgroundColor: theme.palette.action.hover,
109
+ },
110
+ ...sx,
111
+ }, ...props, children: children }));
112
+ });
113
+ // AccordionContent Component
114
+ const AccordionContent = React.forwardRef(({ children, sx = {}, ...props }, ref) => {
115
+ const theme = useTheme();
116
+ return (jsx(AccordionDetails, { ref: ref, sx: {
117
+ padding: theme.spacing(2),
118
+ borderBottomLeftRadius: theme.radius?.sm || theme.shape.borderRadius,
119
+ borderBottomRightRadius: theme.radius?.sm || theme.shape.borderRadius,
120
+ ...sx,
121
+ }, ...props, children: children }));
122
+ });
123
+ // Set display names
124
+ Accordion.displayName = 'Accordion';
125
+ AccordionItem.displayName = 'AccordionItem';
126
+ AccordionTrigger.displayName = 'AccordionTrigger';
127
+ AccordionContent.displayName = 'AccordionContent';
128
+
129
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Accordion as default };
@@ -0,0 +1,137 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var React = require('react');
7
+ var material = require('@mui/material');
8
+ var utils = require('@mui/material/utils');
9
+
10
+ var ExpandMoreIcon = utils.createSvgIcon(/*#__PURE__*/jsxRuntime.jsx("path", {
11
+ d: "M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z"
12
+ }), 'ExpandMore');
13
+
14
+ const AccordionContext = React.createContext({});
15
+ // Main Accordion Container Component
16
+ const Accordion = React.forwardRef(({ type = 'single', collapsible = false, value: controlledValue, defaultValue, onValueChange, children, sx = {}, ...props }, ref) => {
17
+ const theme = material.useTheme();
18
+ // Internal state management
19
+ const [internalValue, setInternalValue] = React.useState(() => {
20
+ if (controlledValue !== undefined)
21
+ return controlledValue;
22
+ if (defaultValue !== undefined)
23
+ return defaultValue;
24
+ return type === 'multiple' ? [] : '';
25
+ });
26
+ const value = controlledValue !== undefined ? controlledValue : internalValue;
27
+ const handleValueChange = React.useCallback((newValue) => {
28
+ if (controlledValue === undefined) {
29
+ setInternalValue(newValue);
30
+ }
31
+ onValueChange?.(newValue);
32
+ }, [controlledValue, onValueChange]);
33
+ const contextValue = React.useMemo(() => ({
34
+ type,
35
+ collapsible,
36
+ value,
37
+ defaultValue,
38
+ onValueChange: handleValueChange,
39
+ }), [type, collapsible, value, defaultValue, handleValueChange]);
40
+ return (jsxRuntime.jsx(AccordionContext.Provider, { value: contextValue, children: jsxRuntime.jsx("div", { ref: ref, style: {
41
+ display: 'flex',
42
+ flexDirection: 'column',
43
+ gap: theme.spacing(1),
44
+ }, ...props, children: children }) }));
45
+ });
46
+ // AccordionItem Component
47
+ const AccordionItem = React.forwardRef(({ value: itemValue, children, sx = {}, ...props }, ref) => {
48
+ const theme = material.useTheme();
49
+ const context = React.useContext(AccordionContext);
50
+ const isExpanded = React.useMemo(() => {
51
+ if (context.type === 'multiple') {
52
+ return Array.isArray(context.value) && context.value.includes(itemValue);
53
+ }
54
+ return context.value === itemValue;
55
+ }, [context.value, context.type, itemValue]);
56
+ const handleChange = React.useCallback(() => {
57
+ if (!context.onValueChange)
58
+ return;
59
+ if (context.type === 'multiple') {
60
+ const currentValue = Array.isArray(context.value) ? context.value : [];
61
+ const newValue = isExpanded
62
+ ? currentValue.filter(v => v !== itemValue)
63
+ : [...currentValue, itemValue];
64
+ context.onValueChange(newValue);
65
+ }
66
+ else {
67
+ const newValue = isExpanded && context.collapsible ? '' : itemValue;
68
+ context.onValueChange(newValue);
69
+ }
70
+ }, [context, itemValue, isExpanded]);
71
+ return (jsxRuntime.jsx(material.Accordion, { ref: ref, expanded: isExpanded, onChange: handleChange, variant: "outlined", sx: {
72
+ borderRadius: theme.radius?.sm || theme.shape.borderRadius,
73
+ '&:before': {
74
+ display: 'none',
75
+ },
76
+ '&.Mui-expanded': {
77
+ margin: 0,
78
+ },
79
+ border: `1px solid ${theme.palette.divider}`,
80
+ ...sx,
81
+ }, ...props, children: children }));
82
+ });
83
+ // AccordionTrigger Component
84
+ const AccordionTrigger = React.forwardRef(({ children, sx = {}, expandIcon, ...props }, ref) => {
85
+ const theme = material.useTheme();
86
+ const defaultExpandIcon = expandIcon !== undefined ? expandIcon : jsxRuntime.jsx(ExpandMoreIcon, {});
87
+ return (jsxRuntime.jsx(material.AccordionSummary, { ref: ref, expandIcon: defaultExpandIcon, sx: {
88
+ borderRadius: theme.radius?.sm || theme.shape.borderRadius,
89
+ minHeight: 56,
90
+ fontWeight: 500,
91
+ '&.Mui-expanded': {
92
+ minHeight: 56,
93
+ borderBottomLeftRadius: 0,
94
+ borderBottomRightRadius: 0,
95
+ borderBottom: `1px solid ${theme.palette.divider}`,
96
+ },
97
+ '& .MuiAccordionSummary-content': {
98
+ margin: '12px 0',
99
+ '&.Mui-expanded': {
100
+ margin: '12px 0',
101
+ },
102
+ },
103
+ '& .MuiAccordionSummary-expandIconWrapper': {
104
+ transition: theme.transitions.create('transform', {
105
+ duration: theme.transitions.duration.shortest,
106
+ }),
107
+ '&.Mui-expanded': {
108
+ transform: 'rotate(180deg)',
109
+ },
110
+ },
111
+ '&:hover': {
112
+ backgroundColor: theme.palette.action.hover,
113
+ },
114
+ ...sx,
115
+ }, ...props, children: children }));
116
+ });
117
+ // AccordionContent Component
118
+ const AccordionContent = React.forwardRef(({ children, sx = {}, ...props }, ref) => {
119
+ const theme = material.useTheme();
120
+ return (jsxRuntime.jsx(material.AccordionDetails, { ref: ref, sx: {
121
+ padding: theme.spacing(2),
122
+ borderBottomLeftRadius: theme.radius?.sm || theme.shape.borderRadius,
123
+ borderBottomRightRadius: theme.radius?.sm || theme.shape.borderRadius,
124
+ ...sx,
125
+ }, ...props, children: children }));
126
+ });
127
+ // Set display names
128
+ Accordion.displayName = 'Accordion';
129
+ AccordionItem.displayName = 'AccordionItem';
130
+ AccordionTrigger.displayName = 'AccordionTrigger';
131
+ AccordionContent.displayName = 'AccordionContent';
132
+
133
+ exports.Accordion = Accordion;
134
+ exports.AccordionContent = AccordionContent;
135
+ exports.AccordionItem = AccordionItem;
136
+ exports.AccordionTrigger = AccordionTrigger;
137
+ exports.default = Accordion;
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { ButtonProps as ButtonProps$1 } from '@mui/material';
3
+ import { SxProps } from '@mui/system';
4
+
5
+ interface ButtonProps extends Omit<ButtonProps$1, 'sx'> {
6
+ loading?: boolean;
7
+ loadingText?: string;
8
+ sx?: SxProps;
9
+ loaderSize?: number;
10
+ loaderPosition?: 'start' | 'end' | 'center';
11
+ }
12
+ declare const Button: React.ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
13
+
14
+ export { Button, Button as default };
15
+ export type { ButtonProps };
@@ -0,0 +1,23 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import React from 'react';
3
+ import { useTheme, Button as Button$1, CircularProgress } from '@mui/material';
4
+
5
+ const Button = React.forwardRef(({ children, loading = false, loadingText, loaderSize = 18, loaderPosition = 'start', variant = 'contained', color = 'primary', size = 'medium', sx = {}, disabled, startIcon, endIcon, ...props }, ref) => {
6
+ const theme = useTheme();
7
+ const showStartSpinner = loading && loaderPosition === 'start';
8
+ const showEndSpinner = loading && loaderPosition === 'end';
9
+ const showCenterSpinner = loading && loaderPosition === 'center';
10
+ return (jsx(Button$1, { ref: ref, variant: variant, color: color, size: size, disabled: disabled || loading, startIcon: showStartSpinner ? (jsx(CircularProgress, { size: loaderSize, color: "inherit" })) : (startIcon), endIcon: showEndSpinner ? (jsx(CircularProgress, { size: loaderSize, color: "inherit" })) : (endIcon), sx: {
11
+ borderRadius: theme.radius.sm,
12
+ fontWeight: 500,
13
+ textTransform: 'none',
14
+ letterSpacing: '0.5px',
15
+ px: size === 'small' ? 1.5 : size === 'large' ? 3 : 2,
16
+ py: size === 'small' ? 0.5 : size === 'large' ? 1.5 : 1,
17
+ position: 'relative',
18
+ ...sx,
19
+ }, ...props, children: showCenterSpinner ? (jsx(CircularProgress, { size: loaderSize, color: "inherit" })) : loading && loadingText ? (loadingText) : (children) }));
20
+ });
21
+ Button.displayName = 'Button';
22
+
23
+ export { Button, Button as default };
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var React = require('react');
7
+ var material = require('@mui/material');
8
+
9
+ const Button = React.forwardRef(({ children, loading = false, loadingText, loaderSize = 18, loaderPosition = 'start', variant = 'contained', color = 'primary', size = 'medium', sx = {}, disabled, startIcon, endIcon, ...props }, ref) => {
10
+ const theme = material.useTheme();
11
+ const showStartSpinner = loading && loaderPosition === 'start';
12
+ const showEndSpinner = loading && loaderPosition === 'end';
13
+ const showCenterSpinner = loading && loaderPosition === 'center';
14
+ return (jsxRuntime.jsx(material.Button, { ref: ref, variant: variant, color: color, size: size, disabled: disabled || loading, startIcon: showStartSpinner ? (jsxRuntime.jsx(material.CircularProgress, { size: loaderSize, color: "inherit" })) : (startIcon), endIcon: showEndSpinner ? (jsxRuntime.jsx(material.CircularProgress, { size: loaderSize, color: "inherit" })) : (endIcon), sx: {
15
+ borderRadius: theme.radius.sm,
16
+ fontWeight: 500,
17
+ textTransform: 'none',
18
+ letterSpacing: '0.5px',
19
+ px: size === 'small' ? 1.5 : size === 'large' ? 3 : 2,
20
+ py: size === 'small' ? 0.5 : size === 'large' ? 1.5 : 1,
21
+ position: 'relative',
22
+ ...sx,
23
+ }, ...props, children: showCenterSpinner ? (jsxRuntime.jsx(material.CircularProgress, { size: loaderSize, color: "inherit" })) : loading && loadingText ? (loadingText) : (children) }));
24
+ });
25
+ Button.displayName = 'Button';
26
+
27
+ exports.Button = Button;
28
+ exports.default = Button;
@@ -0,0 +1,41 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React$1 from 'react';
3
+ import React__default from 'react';
4
+ import { CardProps } from '@mui/material';
5
+ import { SxProps } from '@mui/system';
6
+
7
+ interface CardRootProps extends CardProps {
8
+ sx?: SxProps;
9
+ variant?: 'elevated' | 'outlined' | 'bordered';
10
+ children: React__default.ReactNode;
11
+ }
12
+
13
+ declare const Card: React$1.FC<CardRootProps> & {
14
+ Header: ({ title, subtitle, action, }: {
15
+ title?: string | React.ReactNode;
16
+ subtitle?: string | React.ReactNode;
17
+ action?: React.ReactNode;
18
+ }) => react_jsx_runtime.JSX.Element;
19
+ Content: ({ children, sx }: {
20
+ children: React.ReactNode;
21
+ sx?: any;
22
+ }) => react_jsx_runtime.JSX.Element;
23
+ Body: ({ children, sx }: {
24
+ children: React.ReactNode;
25
+ sx?: any;
26
+ }) => react_jsx_runtime.JSX.Element;
27
+ Actions: ({ children, sx }: {
28
+ children: React.ReactNode;
29
+ sx?: any;
30
+ }) => react_jsx_runtime.JSX.Element;
31
+ Image: ({ src, height, alt }: {
32
+ src: string;
33
+ height?: number | string;
34
+ alt?: string;
35
+ }) => react_jsx_runtime.JSX.Element;
36
+ Skeleton: ({ lines }: {
37
+ lines?: number;
38
+ }) => react_jsx_runtime.JSX.Element;
39
+ };
40
+
41
+ export { Card as default };
@@ -0,0 +1,36 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useTheme, Card as Card$1, CardHeader as CardHeader$1, Typography, CardActions as CardActions$1, Box, Skeleton } from '@mui/material';
3
+ import MuiCardContent from '@mui/material/CardContent';
4
+ import CardMedia from '@mui/material/CardMedia';
5
+
6
+ const CardRoot = ({ children, sx = {}, elevation = 1, variant = 'elevated', ...props }) => {
7
+ const theme = useTheme();
8
+ return (jsx(Card$1, { elevation: variant === 'elevated' ? elevation : 0, variant: variant === 'outlined' ? 'outlined' : 'elevation', sx: {
9
+ borderRadius: theme.radius?.sm || 8,
10
+ border: variant === 'bordered' ? `1px solid ${theme.palette.divider}` : 'none',
11
+ overflow: 'hidden',
12
+ backgroundColor: theme.palette.background.paper,
13
+ ...sx,
14
+ }, ...props, children: children }));
15
+ };
16
+
17
+ const CardHeader = ({ title, subtitle, action, }) => (jsx(CardHeader$1, { title: typeof title === 'string' ? (jsx(Typography, { variant: "h6", fontWeight: 600, children: title })) : (title), subheader: typeof subtitle === 'string' ? (jsx(Typography, { variant: "body2", color: "text.secondary", children: subtitle })) : (subtitle), action: action }));
18
+
19
+ const CardContent = ({ children, sx }) => (jsx(MuiCardContent, { sx: sx, children: children }));
20
+
21
+ const CardActions = ({ children, sx }) => (jsx(CardActions$1, { sx: sx, children: children }));
22
+
23
+ const CardImage = ({ src, height = 160, alt = 'card image' }) => (jsx(CardMedia, { component: "img", height: height, image: src, alt: alt }));
24
+
25
+ const CardSkeleton = ({ lines = 3 }) => (jsxs(Box, { p: 2, children: [jsx(Skeleton, { variant: "rectangular", height: 140 }), [...Array(lines)].map((_, i) => (jsx(Skeleton, { variant: "text", height: 20, sx: { mt: 1 } }, i)))] }));
26
+
27
+ const Card = Object.assign(CardRoot, {
28
+ Header: CardHeader,
29
+ Content: CardContent,
30
+ Body: CardContent, // alias
31
+ Actions: CardActions,
32
+ Image: CardImage,
33
+ Skeleton: CardSkeleton,
34
+ });
35
+
36
+ export { Card as default };
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var material = require('@mui/material');
5
+ var MuiCardContent = require('@mui/material/CardContent');
6
+ var CardMedia = require('@mui/material/CardMedia');
7
+
8
+ const CardRoot = ({ children, sx = {}, elevation = 1, variant = 'elevated', ...props }) => {
9
+ const theme = material.useTheme();
10
+ return (jsxRuntime.jsx(material.Card, { elevation: variant === 'elevated' ? elevation : 0, variant: variant === 'outlined' ? 'outlined' : 'elevation', sx: {
11
+ borderRadius: theme.radius?.sm || 8,
12
+ border: variant === 'bordered' ? `1px solid ${theme.palette.divider}` : 'none',
13
+ overflow: 'hidden',
14
+ backgroundColor: theme.palette.background.paper,
15
+ ...sx,
16
+ }, ...props, children: children }));
17
+ };
18
+
19
+ const CardHeader = ({ title, subtitle, action, }) => (jsxRuntime.jsx(material.CardHeader, { title: typeof title === 'string' ? (jsxRuntime.jsx(material.Typography, { variant: "h6", fontWeight: 600, children: title })) : (title), subheader: typeof subtitle === 'string' ? (jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: subtitle })) : (subtitle), action: action }));
20
+
21
+ const CardContent = ({ children, sx }) => (jsxRuntime.jsx(MuiCardContent, { sx: sx, children: children }));
22
+
23
+ const CardActions = ({ children, sx }) => (jsxRuntime.jsx(material.CardActions, { sx: sx, children: children }));
24
+
25
+ const CardImage = ({ src, height = 160, alt = 'card image' }) => (jsxRuntime.jsx(CardMedia, { component: "img", height: height, image: src, alt: alt }));
26
+
27
+ const CardSkeleton = ({ lines = 3 }) => (jsxRuntime.jsxs(material.Box, { p: 2, children: [jsxRuntime.jsx(material.Skeleton, { variant: "rectangular", height: 140 }), [...Array(lines)].map((_, i) => (jsxRuntime.jsx(material.Skeleton, { variant: "text", height: 20, sx: { mt: 1 } }, i)))] }));
28
+
29
+ const Card = Object.assign(CardRoot, {
30
+ Header: CardHeader,
31
+ Content: CardContent,
32
+ Body: CardContent, // alias
33
+ Actions: CardActions,
34
+ Image: CardImage,
35
+ Skeleton: CardSkeleton,
36
+ });
37
+
38
+ module.exports = Card;
@@ -0,0 +1,19 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React from 'react';
3
+ import { PopoverProps as PopoverProps$1 } from '@mui/material';
4
+
5
+ interface PopoverProps extends Partial<PopoverProps$1> {
6
+ open: boolean;
7
+ onClose: () => void;
8
+ anchorEl: HTMLElement | null;
9
+ children: React.ReactNode;
10
+ width?: number | string;
11
+ maxWidth?: number | string;
12
+ minWidth?: number | string;
13
+ padding?: number;
14
+ border?: boolean;
15
+ }
16
+ declare const Popover: ({ open, onClose, anchorEl, children, width, maxWidth, minWidth, padding, border, anchorOrigin, transformOrigin, ...rest }: PopoverProps) => react_jsx_runtime.JSX.Element;
17
+
18
+ export { Popover, Popover as default };
19
+ export type { PopoverProps };
@@ -0,0 +1,22 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useTheme, Popover as Popover$1, Fade } from '@mui/material';
3
+
4
+ const Popover = ({ open, onClose, anchorEl, children, width = 240, maxWidth = '100%', minWidth = 200, padding = 2, border = true, anchorOrigin = { vertical: 'bottom', horizontal: 'left' }, transformOrigin = { vertical: 'top', horizontal: 'left' }, ...rest }) => {
5
+ const theme = useTheme();
6
+ return (jsx(Popover$1, { open: open, anchorEl: anchorEl, onClose: onClose, disableScrollLock: true, TransitionComponent: Fade, transitionDuration: 150, anchorOrigin: anchorOrigin, transformOrigin: transformOrigin, PaperProps: {
7
+ elevation: 0,
8
+ sx: {
9
+ boxShadow: 'none',
10
+ bgcolor: theme.palette.background.paper,
11
+ border: border ? `1px solid ${theme.palette.divider}` : 'none',
12
+ borderRadius: theme.radius.md,
13
+ px: theme.spacing(padding),
14
+ py: theme.spacing(padding),
15
+ width,
16
+ maxWidth,
17
+ minWidth,
18
+ },
19
+ }, ...rest, children: children }));
20
+ };
21
+
22
+ export { Popover, Popover as default };
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var material = require('@mui/material');
7
+
8
+ const Popover = ({ open, onClose, anchorEl, children, width = 240, maxWidth = '100%', minWidth = 200, padding = 2, border = true, anchorOrigin = { vertical: 'bottom', horizontal: 'left' }, transformOrigin = { vertical: 'top', horizontal: 'left' }, ...rest }) => {
9
+ const theme = material.useTheme();
10
+ return (jsxRuntime.jsx(material.Popover, { open: open, anchorEl: anchorEl, onClose: onClose, disableScrollLock: true, TransitionComponent: material.Fade, transitionDuration: 150, anchorOrigin: anchorOrigin, transformOrigin: transformOrigin, PaperProps: {
11
+ elevation: 0,
12
+ sx: {
13
+ boxShadow: 'none',
14
+ bgcolor: theme.palette.background.paper,
15
+ border: border ? `1px solid ${theme.palette.divider}` : 'none',
16
+ borderRadius: theme.radius.md,
17
+ px: theme.spacing(padding),
18
+ py: theme.spacing(padding),
19
+ width,
20
+ maxWidth,
21
+ minWidth,
22
+ },
23
+ }, ...rest, children: children }));
24
+ };
25
+
26
+ exports.Popover = Popover;
27
+ exports.default = Popover;
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import { SxProps } from '@mui/system';
3
+
4
+ interface RadioOption {
5
+ value: string;
6
+ label: string;
7
+ disabled?: boolean;
8
+ description?: string;
9
+ }
10
+ interface RadioGroupProps {
11
+ label?: string;
12
+ options: RadioOption[];
13
+ value?: string;
14
+ defaultValue?: string;
15
+ onChange?: (value: string) => void;
16
+ name?: string;
17
+ disabled?: boolean;
18
+ required?: boolean;
19
+ error?: boolean;
20
+ helperText?: string;
21
+ row?: boolean;
22
+ size?: 'small' | 'medium';
23
+ color?: 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning';
24
+ sx?: SxProps;
25
+ radioSx?: SxProps;
26
+ labelSx?: SxProps;
27
+ }
28
+ declare const RadioGroup: React.ForwardRefExoticComponent<RadioGroupProps & React.RefAttributes<HTMLDivElement>>;
29
+
30
+ export { RadioGroup, RadioGroup as default };
31
+ export type { RadioGroupProps, RadioOption };
@@ -0,0 +1,92 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import React from 'react';
3
+ import { useTheme, FormControl, FormLabel, Typography, RadioGroup as RadioGroup$1, Box, FormControlLabel, Radio, FormHelperText } from '@mui/material';
4
+
5
+ const RadioGroup = React.forwardRef(({ label, options = [], value, defaultValue, onChange, name, disabled = false, required = false, error = false, helperText, row = false, size = 'medium', color = 'primary', sx = {}, radioSx = {}, labelSx = {}, ...props }, ref) => {
6
+ const theme = useTheme();
7
+ const [internalValue, setInternalValue] = React.useState(value || defaultValue || '');
8
+ // Sync with external value prop
9
+ React.useEffect(() => {
10
+ if (value !== undefined) {
11
+ setInternalValue(value);
12
+ }
13
+ }, [value]);
14
+ const handleChange = (event) => {
15
+ const newValue = event.target.value;
16
+ if (value === undefined) {
17
+ setInternalValue(newValue);
18
+ }
19
+ onChange?.(newValue);
20
+ };
21
+ const currentValue = value !== undefined ? value : internalValue;
22
+ return (jsxs(FormControl, { ref: ref, component: "fieldset", variant: "standard", disabled: disabled, required: required, error: error, sx: {
23
+ borderRadius: '8px',
24
+ ...sx,
25
+ }, ...props, children: [label && (jsxs(FormLabel, { component: "legend", sx: {
26
+ fontWeight: 500,
27
+ fontSize: size === 'small' ? '0.875rem' : '1rem',
28
+ color: disabled
29
+ ? theme.palette.text.disabled
30
+ : error
31
+ ? theme.palette.error.main
32
+ : theme.palette.text.primary,
33
+ '&.Mui-focused': {
34
+ color: error
35
+ ? theme.palette.error.main
36
+ : `${theme.palette[color].main}`,
37
+ },
38
+ mb: 1,
39
+ ...labelSx,
40
+ }, children: [label, required && (jsx(Typography, { component: "span", sx: {
41
+ color: theme.palette.error.main,
42
+ ml: 0.5,
43
+ fontSize: 'inherit',
44
+ }, children: "*" }))] })), jsx(RadioGroup$1, { name: name, value: currentValue, onChange: handleChange, row: row, sx: {
45
+ gap: size === 'small' ? 1 : 1.5,
46
+ '& .MuiFormControlLabel-root': {
47
+ marginLeft: 0,
48
+ marginRight: row ? 2 : 0,
49
+ },
50
+ }, children: options.map((option) => (jsx(Box, { children: jsx(FormControlLabel, { value: option.value, disabled: disabled || option.disabled, control: jsx(Radio, { size: size, color: color, sx: {
51
+ '&.Mui-checked': {
52
+ color: error
53
+ ? theme.palette.error.main
54
+ : `${theme.palette[color].main}`,
55
+ },
56
+ alignSelf: option.description ? 'flex-start' : 'center',
57
+ mt: option.description ? 0.25 : 0,
58
+ ...radioSx,
59
+ } }), label: jsxs(Box, { sx: { display: 'flex', flexDirection: 'column' }, children: [jsx(Typography, { variant: size === 'small' ? 'body2' : 'body1', sx: {
60
+ fontWeight: 400,
61
+ color: disabled || option.disabled
62
+ ? theme.palette.text.disabled
63
+ : theme.palette.text.primary,
64
+ lineHeight: 1.5,
65
+ }, children: option.label }), option.description && (jsx(Typography, { variant: "caption", sx: {
66
+ color: disabled || option.disabled
67
+ ? theme.palette.text.disabled
68
+ : theme.palette.text.secondary,
69
+ mt: 0.25,
70
+ lineHeight: 1.4,
71
+ }, children: option.description }))] }), sx: {
72
+ alignItems: option.description ? 'flex-start' : 'center',
73
+ margin: 0,
74
+ display: 'flex',
75
+ '& .MuiFormControlLabel-label': {
76
+ ml: 1,
77
+ flex: 1,
78
+ },
79
+ '& .MuiButtonBase-root': {
80
+ p: size === 'small' ? 0.5 : 1,
81
+ },
82
+ } }) }, option.value))) }), helperText && (jsx(FormHelperText, { sx: {
83
+ mt: 1,
84
+ fontSize: size === 'small' ? '0.75rem' : '0.875rem',
85
+ color: error
86
+ ? theme.palette.error.main
87
+ : theme.palette.text.secondary,
88
+ }, children: helperText }))] }));
89
+ });
90
+ RadioGroup.displayName = 'RadioGroup';
91
+
92
+ export { RadioGroup, RadioGroup as default };
@@ -0,0 +1,97 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var React = require('react');
7
+ var material = require('@mui/material');
8
+
9
+ const RadioGroup = React.forwardRef(({ label, options = [], value, defaultValue, onChange, name, disabled = false, required = false, error = false, helperText, row = false, size = 'medium', color = 'primary', sx = {}, radioSx = {}, labelSx = {}, ...props }, ref) => {
10
+ const theme = material.useTheme();
11
+ const [internalValue, setInternalValue] = React.useState(value || defaultValue || '');
12
+ // Sync with external value prop
13
+ React.useEffect(() => {
14
+ if (value !== undefined) {
15
+ setInternalValue(value);
16
+ }
17
+ }, [value]);
18
+ const handleChange = (event) => {
19
+ const newValue = event.target.value;
20
+ if (value === undefined) {
21
+ setInternalValue(newValue);
22
+ }
23
+ onChange?.(newValue);
24
+ };
25
+ const currentValue = value !== undefined ? value : internalValue;
26
+ return (jsxRuntime.jsxs(material.FormControl, { ref: ref, component: "fieldset", variant: "standard", disabled: disabled, required: required, error: error, sx: {
27
+ borderRadius: '8px',
28
+ ...sx,
29
+ }, ...props, children: [label && (jsxRuntime.jsxs(material.FormLabel, { component: "legend", sx: {
30
+ fontWeight: 500,
31
+ fontSize: size === 'small' ? '0.875rem' : '1rem',
32
+ color: disabled
33
+ ? theme.palette.text.disabled
34
+ : error
35
+ ? theme.palette.error.main
36
+ : theme.palette.text.primary,
37
+ '&.Mui-focused': {
38
+ color: error
39
+ ? theme.palette.error.main
40
+ : `${theme.palette[color].main}`,
41
+ },
42
+ mb: 1,
43
+ ...labelSx,
44
+ }, children: [label, required && (jsxRuntime.jsx(material.Typography, { component: "span", sx: {
45
+ color: theme.palette.error.main,
46
+ ml: 0.5,
47
+ fontSize: 'inherit',
48
+ }, children: "*" }))] })), jsxRuntime.jsx(material.RadioGroup, { name: name, value: currentValue, onChange: handleChange, row: row, sx: {
49
+ gap: size === 'small' ? 1 : 1.5,
50
+ '& .MuiFormControlLabel-root': {
51
+ marginLeft: 0,
52
+ marginRight: row ? 2 : 0,
53
+ },
54
+ }, children: options.map((option) => (jsxRuntime.jsx(material.Box, { children: jsxRuntime.jsx(material.FormControlLabel, { value: option.value, disabled: disabled || option.disabled, control: jsxRuntime.jsx(material.Radio, { size: size, color: color, sx: {
55
+ '&.Mui-checked': {
56
+ color: error
57
+ ? theme.palette.error.main
58
+ : `${theme.palette[color].main}`,
59
+ },
60
+ alignSelf: option.description ? 'flex-start' : 'center',
61
+ mt: option.description ? 0.25 : 0,
62
+ ...radioSx,
63
+ } }), label: jsxRuntime.jsxs(material.Box, { sx: { display: 'flex', flexDirection: 'column' }, children: [jsxRuntime.jsx(material.Typography, { variant: size === 'small' ? 'body2' : 'body1', sx: {
64
+ fontWeight: 400,
65
+ color: disabled || option.disabled
66
+ ? theme.palette.text.disabled
67
+ : theme.palette.text.primary,
68
+ lineHeight: 1.5,
69
+ }, children: option.label }), option.description && (jsxRuntime.jsx(material.Typography, { variant: "caption", sx: {
70
+ color: disabled || option.disabled
71
+ ? theme.palette.text.disabled
72
+ : theme.palette.text.secondary,
73
+ mt: 0.25,
74
+ lineHeight: 1.4,
75
+ }, children: option.description }))] }), sx: {
76
+ alignItems: option.description ? 'flex-start' : 'center',
77
+ margin: 0,
78
+ display: 'flex',
79
+ '& .MuiFormControlLabel-label': {
80
+ ml: 1,
81
+ flex: 1,
82
+ },
83
+ '& .MuiButtonBase-root': {
84
+ p: size === 'small' ? 0.5 : 1,
85
+ },
86
+ } }) }, option.value))) }), helperText && (jsxRuntime.jsx(material.FormHelperText, { sx: {
87
+ mt: 1,
88
+ fontSize: size === 'small' ? '0.75rem' : '0.875rem',
89
+ color: error
90
+ ? theme.palette.error.main
91
+ : theme.palette.text.secondary,
92
+ }, children: helperText }))] }));
93
+ });
94
+ RadioGroup.displayName = 'RadioGroup';
95
+
96
+ exports.RadioGroup = RadioGroup;
97
+ exports.default = RadioGroup;
@@ -0,0 +1,30 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { TypographyProps, SxProps } from '@mui/material';
3
+
4
+ interface HeadingProps extends TypographyProps {
5
+ level?: 1 | 2 | 3 | 4 | 5 | 6;
6
+ }
7
+ declare const Heading: ({ level, ...props }: HeadingProps) => react_jsx_runtime.JSX.Element;
8
+
9
+ interface TextProps extends TypographyProps {
10
+ size?: 'sm' | 'md' | 'lg';
11
+ }
12
+ declare const Text: ({ size, ...props }: TextProps) => react_jsx_runtime.JSX.Element;
13
+
14
+ declare const Lead: (props: TypographyProps) => react_jsx_runtime.JSX.Element;
15
+
16
+ declare const Muted: (props: TypographyProps) => react_jsx_runtime.JSX.Element;
17
+
18
+ declare const Strong: (props: TypographyProps) => react_jsx_runtime.JSX.Element;
19
+
20
+ declare const Caption: (props: TypographyProps) => react_jsx_runtime.JSX.Element;
21
+
22
+ declare const Blockquote: (props: TypographyProps) => react_jsx_runtime.JSX.Element;
23
+
24
+ interface CodeProps {
25
+ children: React.ReactNode;
26
+ sx?: SxProps;
27
+ }
28
+ declare const Code: ({ children, sx }: CodeProps) => react_jsx_runtime.JSX.Element;
29
+
30
+ export { Blockquote, Caption, Code, Heading, Lead, Muted, Strong, Text };
@@ -0,0 +1,57 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { Typography, Box } from '@mui/material';
3
+
4
+ const Heading = ({ level = 1, ...props }) => {
5
+ const variant = `h${level}`;
6
+ return (jsx(Typography, { variant: variant, component: props.component || `h${level}`, fontWeight: 600, gutterBottom: true, ...props }));
7
+ };
8
+
9
+ const Text = ({ size = 'md', ...props }) => {
10
+ const variantMap = {
11
+ sm: 'body2',
12
+ md: 'body1',
13
+ lg: 'subtitle1',
14
+ };
15
+ return (jsx(Typography, { variant: variantMap[size], component: props.component || 'p', ...props }));
16
+ };
17
+
18
+ const Lead = (props) => {
19
+ return (jsx(Typography, { variant: "subtitle1", component: props.component || 'p', fontWeight: 400, color: "text.secondary", ...props }));
20
+ };
21
+
22
+ const Muted = (props) => {
23
+ return (jsx(Typography, { variant: "body2", component: props.component || 'span', color: "text.disabled", ...props }));
24
+ };
25
+
26
+ const Strong = (props) => {
27
+ return (jsx(Typography, { component: props.component || 'strong', fontWeight: 700, display: "inline", ...props }));
28
+ };
29
+
30
+ const Caption = (props) => {
31
+ return (jsx(Typography, { variant: "caption", color: "text.secondary", component: props.component || 'span', ...props }));
32
+ };
33
+
34
+ const Blockquote = (props) => {
35
+ return (jsx(Typography, { component: "blockquote", sx: {
36
+ borderLeft: '4px solid',
37
+ borderColor: 'divider',
38
+ pl: 2,
39
+ color: 'text.secondary',
40
+ fontStyle: 'italic',
41
+ }, ...props }));
42
+ };
43
+
44
+ const Code = ({ children, sx }) => {
45
+ return (jsx(Box, { component: "code", sx: {
46
+ fontFamily: 'monospace',
47
+ backgroundColor: 'grey.100',
48
+ color: 'primary.main',
49
+ px: 0.5,
50
+ py: 0.25,
51
+ borderRadius: 1,
52
+ fontSize: '0.875rem',
53
+ ...sx,
54
+ }, children: children }));
55
+ };
56
+
57
+ export { Blockquote, Caption, Code, Heading, Lead, Muted, Strong, Text };
@@ -0,0 +1,66 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var material = require('@mui/material');
5
+
6
+ const Heading = ({ level = 1, ...props }) => {
7
+ const variant = `h${level}`;
8
+ return (jsxRuntime.jsx(material.Typography, { variant: variant, component: props.component || `h${level}`, fontWeight: 600, gutterBottom: true, ...props }));
9
+ };
10
+
11
+ const Text = ({ size = 'md', ...props }) => {
12
+ const variantMap = {
13
+ sm: 'body2',
14
+ md: 'body1',
15
+ lg: 'subtitle1',
16
+ };
17
+ return (jsxRuntime.jsx(material.Typography, { variant: variantMap[size], component: props.component || 'p', ...props }));
18
+ };
19
+
20
+ const Lead = (props) => {
21
+ return (jsxRuntime.jsx(material.Typography, { variant: "subtitle1", component: props.component || 'p', fontWeight: 400, color: "text.secondary", ...props }));
22
+ };
23
+
24
+ const Muted = (props) => {
25
+ return (jsxRuntime.jsx(material.Typography, { variant: "body2", component: props.component || 'span', color: "text.disabled", ...props }));
26
+ };
27
+
28
+ const Strong = (props) => {
29
+ return (jsxRuntime.jsx(material.Typography, { component: props.component || 'strong', fontWeight: 700, display: "inline", ...props }));
30
+ };
31
+
32
+ const Caption = (props) => {
33
+ return (jsxRuntime.jsx(material.Typography, { variant: "caption", color: "text.secondary", component: props.component || 'span', ...props }));
34
+ };
35
+
36
+ const Blockquote = (props) => {
37
+ return (jsxRuntime.jsx(material.Typography, { component: "blockquote", sx: {
38
+ borderLeft: '4px solid',
39
+ borderColor: 'divider',
40
+ pl: 2,
41
+ color: 'text.secondary',
42
+ fontStyle: 'italic',
43
+ }, ...props }));
44
+ };
45
+
46
+ const Code = ({ children, sx }) => {
47
+ return (jsxRuntime.jsx(material.Box, { component: "code", sx: {
48
+ fontFamily: 'monospace',
49
+ backgroundColor: 'grey.100',
50
+ color: 'primary.main',
51
+ px: 0.5,
52
+ py: 0.25,
53
+ borderRadius: 1,
54
+ fontSize: '0.875rem',
55
+ ...sx,
56
+ }, children: children }));
57
+ };
58
+
59
+ exports.Blockquote = Blockquote;
60
+ exports.Caption = Caption;
61
+ exports.Code = Code;
62
+ exports.Heading = Heading;
63
+ exports.Lead = Lead;
64
+ exports.Muted = Muted;
65
+ exports.Strong = Strong;
66
+ exports.Text = Text;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zimyo/ui",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Scalable UI component library built on MUI Material",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -26,6 +26,31 @@
26
26
  "require": "./dist/Typography/index.js",
27
27
  "types": "./dist/Typography/index.d.ts"
28
28
  },
29
+ "./Card": {
30
+ "import": "./dist/Card/index.esm.js",
31
+ "require": "./dist/Card/index.js",
32
+ "types": "./dist/Card/index.d.ts"
33
+ },
34
+ "./Accordion": {
35
+ "import": "./dist/Accordion/index.esm.js",
36
+ "require": "./dist/Accordion/index.js",
37
+ "types": "./dist/Accordion/index.d.ts"
38
+ },
39
+ "./Select": {
40
+ "import": "./dist/Select/index.esm.js",
41
+ "require": "./dist/Select/index.js",
42
+ "types": "./dist/Select/index.d.ts"
43
+ },
44
+ "./TextInput": {
45
+ "import": "./dist/Input/index.esm.js",
46
+ "require": "./dist/Input/index.js",
47
+ "types": "./dist/Input/index.d.ts"
48
+ },
49
+ "./Switch": {
50
+ "import": "./dist/Switch/index.esm.js",
51
+ "require": "./dist/Switch/index.js",
52
+ "types": "./dist/Switch/index.d.ts"
53
+ },
29
54
  "./theme": {
30
55
  "import": "./dist/theme/index.esm.js",
31
56
  "require": "./dist/theme/index.js",
@@ -45,7 +70,7 @@
45
70
  "typecheck": "tsc --noEmit",
46
71
  "generate:exports": "node scripts/generate-exports.js",
47
72
  "version": "changeset version",
48
- "release": "changeset publish --access public"
73
+ "release": "changeset publish"
49
74
  },
50
75
  "peerDependencies": {
51
76
  "@emotion/react": ">=11.0.0",
@@ -88,5 +113,8 @@
88
113
  "extends": [
89
114
  "plugin:storybook/recommended"
90
115
  ]
116
+ },
117
+ "publishConfig": {
118
+ "access": "public"
91
119
  }
92
120
  }