@stfrigerio/sito-template 0.1.80 → 0.1.81
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/components/atoms/Modal/Modal.d.ts +4 -38
- package/dist/components/atoms/Modal/Modal.d.ts.map +1 -1
- package/dist/index.esm.js +48 -42
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +47 -41
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
- package/storybook-static/project.json +1 -1
package/dist/index.js
CHANGED
|
@@ -741,47 +741,29 @@ const EmptyState = ({ icon, title, message, action, size = 'default', }) => {
|
|
|
741
741
|
return (jsxRuntime.jsxs("div", { className: wrapperClass, children: [icon && jsxRuntime.jsx("div", { className: styles$z.icon, children: icon }), title && jsxRuntime.jsx("h3", { className: styles$z.title, children: title }), jsxRuntime.jsx("p", { className: styles$z.message, children: message }), action && jsxRuntime.jsx("div", { className: styles$z.action, children: action })] }));
|
|
742
742
|
};
|
|
743
743
|
|
|
744
|
-
var styles$y = {"backdrop":"Modal-module_backdrop__yOx-a","dialog":"Modal-module_dialog__yEXTq","dialogCompact":"Modal-module_dialogCompact__z1Wxp","dialogWide":"Modal-module_dialogWide__9PTXK","header":"Modal-module_header__NHHKd","title":"Modal-module_title__i3R0x","headerActions":"Modal-module_headerActions__g28UN","closeButton":"Modal-module_closeButton__siC-1","body":"Modal-module_body__U7jvM","bodyFlush":"Modal-module_bodyFlush__wtk3q"};
|
|
744
|
+
var styles$y = {"backdrop":"Modal-module_backdrop__yOx-a","dialog":"Modal-module_dialog__yEXTq","dialogCompact":"Modal-module_dialogCompact__z1Wxp","dialogWide":"Modal-module_dialogWide__9PTXK","header":"Modal-module_header__NHHKd","title":"Modal-module_title__i3R0x","headerActions":"Modal-module_headerActions__g28UN","closeButton":"Modal-module_closeButton__siC-1","body":"Modal-module_body__U7jvM","bodyFlush":"Modal-module_bodyFlush__wtk3q","backdropSheet":"Modal-module_backdropSheet__o9kW3","dialogSheet":"Modal-module_dialogSheet__EjpwP","grabBar":"Modal-module_grabBar__qhl9f"};
|
|
745
745
|
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
* title="Edit profile"
|
|
768
|
-
* size="wide"
|
|
769
|
-
* actions={<button onClick={save}>Save</button>}
|
|
770
|
-
* onClose={handleClose}
|
|
771
|
-
* >
|
|
772
|
-
* <ProfileForm />
|
|
773
|
-
* </Modal>
|
|
774
|
-
*
|
|
775
|
-
* @example
|
|
776
|
-
* // Flush body (no padding) for editors and full-bleed content
|
|
777
|
-
* <Modal open={isOpen} title="Document" padding={false} onClose={handleClose}>
|
|
778
|
-
* <DocEditor content={content} onSave={save} />
|
|
779
|
-
* </Modal>
|
|
780
|
-
*
|
|
781
|
-
* @param {ModalProps} props - The props for the Modal component
|
|
782
|
-
* @returns {React.ReactPortal | null} A portal rendering the modal, or null on the server
|
|
783
|
-
*/
|
|
784
|
-
const Modal = ({ open, title, onClose, children, size = 'default', actions, padding = true, }) => {
|
|
746
|
+
const MOBILE_BREAKPOINT = '(max-width: 640px)';
|
|
747
|
+
const useIsMobile = () => {
|
|
748
|
+
const [isMobile, setIsMobile] = React.useState(() => {
|
|
749
|
+
if (typeof window === 'undefined')
|
|
750
|
+
return false;
|
|
751
|
+
return window.matchMedia(MOBILE_BREAKPOINT).matches;
|
|
752
|
+
});
|
|
753
|
+
React.useEffect(() => {
|
|
754
|
+
if (typeof window === 'undefined')
|
|
755
|
+
return;
|
|
756
|
+
const mq = window.matchMedia(MOBILE_BREAKPOINT);
|
|
757
|
+
const onChange = (e) => setIsMobile(e.matches);
|
|
758
|
+
mq.addEventListener('change', onChange);
|
|
759
|
+
return () => mq.removeEventListener('change', onChange);
|
|
760
|
+
}, []);
|
|
761
|
+
return isMobile;
|
|
762
|
+
};
|
|
763
|
+
const Modal = ({ open, title, onClose, children, size = 'default', actions, padding = true, mobileVariant = 'sheet', draggable = true, }) => {
|
|
764
|
+
const isMobile = useIsMobile();
|
|
765
|
+
const dragControls = framerMotion.useDragControls();
|
|
766
|
+
const headerRef = React.useRef(null);
|
|
785
767
|
React.useEffect(() => {
|
|
786
768
|
if (!open)
|
|
787
769
|
return;
|
|
@@ -794,14 +776,38 @@ const Modal = ({ open, title, onClose, children, size = 'default', actions, padd
|
|
|
794
776
|
}, [open, onClose]);
|
|
795
777
|
if (typeof document === 'undefined')
|
|
796
778
|
return null;
|
|
779
|
+
const isSheet = mobileVariant === 'sheet' && isMobile;
|
|
780
|
+
const isDraggable = isSheet && draggable;
|
|
781
|
+
const backdropClass = [styles$y.backdrop, isSheet && styles$y.backdropSheet]
|
|
782
|
+
.filter(Boolean)
|
|
783
|
+
.join(' ');
|
|
797
784
|
const dialogClass = [
|
|
798
785
|
styles$y.dialog,
|
|
799
786
|
size === 'compact' && styles$y.dialogCompact,
|
|
800
787
|
size === 'wide' && styles$y.dialogWide,
|
|
788
|
+
isSheet && styles$y.dialogSheet,
|
|
801
789
|
]
|
|
802
790
|
.filter(Boolean)
|
|
803
791
|
.join(' ');
|
|
804
|
-
|
|
792
|
+
const enteringAnimation = isSheet
|
|
793
|
+
? { initial: { y: '100%' }, animate: { y: 0 }, exit: { y: '100%' } }
|
|
794
|
+
: {
|
|
795
|
+
initial: { opacity: 0, scale: 0.96, y: 8 },
|
|
796
|
+
animate: { opacity: 1, scale: 1, y: 0 },
|
|
797
|
+
exit: { opacity: 0, scale: 0.96, y: 8 },
|
|
798
|
+
};
|
|
799
|
+
return reactDom.createPortal(jsxRuntime.jsx(framerMotion.AnimatePresence, { children: open && (jsxRuntime.jsx(framerMotion.motion.div, { className: backdropClass, initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.15 }, onClick: onClose, "aria-hidden": "true", children: jsxRuntime.jsxs(framerMotion.motion.div, { className: dialogClass, role: "dialog", "aria-modal": "true", "aria-label": title, ...enteringAnimation, transition: isSheet
|
|
800
|
+
? { type: 'spring', stiffness: 320, damping: 32 }
|
|
801
|
+
: { duration: 0.15, ease: 'easeOut' }, onClick: (e) => e.stopPropagation(), drag: isDraggable ? 'y' : false, dragControls: isDraggable ? dragControls : undefined, dragConstraints: { top: 0 }, dragElastic: { top: 0, bottom: 0.3 }, dragListener: false, onDragEnd: (_, info) => {
|
|
802
|
+
if (info.offset.y > 80)
|
|
803
|
+
onClose();
|
|
804
|
+
}, children: [isSheet && jsxRuntime.jsx("div", { className: styles$y.grabBar }), jsxRuntime.jsxs("div", { ref: headerRef, className: styles$y.header, onPointerDown: (e) => {
|
|
805
|
+
if (!isDraggable)
|
|
806
|
+
return;
|
|
807
|
+
if (e.target.closest('button'))
|
|
808
|
+
return;
|
|
809
|
+
dragControls.start(e);
|
|
810
|
+
}, children: [jsxRuntime.jsx("span", { className: styles$y.title, children: title }), actions && jsxRuntime.jsx("div", { className: styles$y.headerActions, children: actions }), jsxRuntime.jsx("button", { className: styles$y.closeButton, onClick: onClose, "aria-label": "Close modal", type: "button", children: jsxRuntime.jsx(lucideReact.X, { size: 16 }) })] }), jsxRuntime.jsx("div", { className: padding ? styles$y.body : styles$y.bodyFlush, children: children })] }) })) }), document.body);
|
|
805
811
|
};
|
|
806
812
|
|
|
807
813
|
var styles$x = {"checkboxLabel":"Checkbox-module_checkboxLabel__4tBVg","checkbox":"Checkbox-module_checkbox__BbJul","checkboxText":"Checkbox-module_checkboxText__oJsc9"};
|