@optilogic/core 1.4.0 → 1.5.0

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.d.cts CHANGED
@@ -1021,6 +1021,20 @@ interface ModalProps {
1021
1021
  * `"w-[80vw] max-w-none"`.
1022
1022
  */
1023
1023
  contentClassName?: string;
1024
+ /**
1025
+ * Opt into mobile-friendly rendering. When `true`, the modal renders full-
1026
+ * screen (no border, no rounded corners, fills the viewport) under
1027
+ * `@media (pointer: coarse) and (hover: none)` — i.e. on touch devices
1028
+ * without hover. On desktop / hybrid input devices the named `size` is
1029
+ * preserved. Default: `false`.
1030
+ */
1031
+ responsive?: boolean;
1032
+ /**
1033
+ * Force mobile (full-screen) rendering regardless of device. Useful for
1034
+ * Storybook, manual QA, and the rare case where sheet-style rendering is
1035
+ * desired on desktop. Overrides `responsive`. Default: `false`.
1036
+ */
1037
+ forceMobile?: boolean;
1024
1038
  }
1025
1039
  /**
1026
1040
  * Modal component
@@ -1052,8 +1066,20 @@ interface ModalProps {
1052
1066
  * >
1053
1067
  * ...
1054
1068
  * </Modal>
1069
+ *
1070
+ * @example
1071
+ * // Full-screen on mobile (touch devices), `lg` width on desktop
1072
+ * <Modal
1073
+ * isOpen={open}
1074
+ * onClose={() => setOpen(false)}
1075
+ * title="New Database"
1076
+ * size="lg"
1077
+ * responsive
1078
+ * >
1079
+ * ...
1080
+ * </Modal>
1055
1081
  */
1056
- declare function Modal({ isOpen, onClose, title, children, footer, size, zIndex, className, contentClassName, }: ModalProps): react_jsx_runtime.JSX.Element | null;
1082
+ declare function Modal({ isOpen, onClose, title, children, footer, size, zIndex, className, contentClassName, responsive, forceMobile, }: ModalProps): react_jsx_runtime.JSX.Element | null;
1057
1083
  /**
1058
1084
  * ModalButton component
1059
1085
  * @deprecated Use Button component from @optilogic/core instead
package/dist/index.d.ts CHANGED
@@ -1021,6 +1021,20 @@ interface ModalProps {
1021
1021
  * `"w-[80vw] max-w-none"`.
1022
1022
  */
1023
1023
  contentClassName?: string;
1024
+ /**
1025
+ * Opt into mobile-friendly rendering. When `true`, the modal renders full-
1026
+ * screen (no border, no rounded corners, fills the viewport) under
1027
+ * `@media (pointer: coarse) and (hover: none)` — i.e. on touch devices
1028
+ * without hover. On desktop / hybrid input devices the named `size` is
1029
+ * preserved. Default: `false`.
1030
+ */
1031
+ responsive?: boolean;
1032
+ /**
1033
+ * Force mobile (full-screen) rendering regardless of device. Useful for
1034
+ * Storybook, manual QA, and the rare case where sheet-style rendering is
1035
+ * desired on desktop. Overrides `responsive`. Default: `false`.
1036
+ */
1037
+ forceMobile?: boolean;
1024
1038
  }
1025
1039
  /**
1026
1040
  * Modal component
@@ -1052,8 +1066,20 @@ interface ModalProps {
1052
1066
  * >
1053
1067
  * ...
1054
1068
  * </Modal>
1069
+ *
1070
+ * @example
1071
+ * // Full-screen on mobile (touch devices), `lg` width on desktop
1072
+ * <Modal
1073
+ * isOpen={open}
1074
+ * onClose={() => setOpen(false)}
1075
+ * title="New Database"
1076
+ * size="lg"
1077
+ * responsive
1078
+ * >
1079
+ * ...
1080
+ * </Modal>
1055
1081
  */
1056
- declare function Modal({ isOpen, onClose, title, children, footer, size, zIndex, className, contentClassName, }: ModalProps): react_jsx_runtime.JSX.Element | null;
1082
+ declare function Modal({ isOpen, onClose, title, children, footer, size, zIndex, className, contentClassName, responsive, forceMobile, }: ModalProps): react_jsx_runtime.JSX.Element | null;
1057
1083
  /**
1058
1084
  * ModalButton component
1059
1085
  * @deprecated Use Button component from @optilogic/core instead
package/dist/index.js CHANGED
@@ -2092,7 +2092,9 @@ function Modal({
2092
2092
  size = "md",
2093
2093
  zIndex = 50,
2094
2094
  className,
2095
- contentClassName
2095
+ contentClassName,
2096
+ responsive = false,
2097
+ forceMobile = false
2096
2098
  }) {
2097
2099
  React20.useEffect(() => {
2098
2100
  if (!isOpen) return;
@@ -2123,10 +2125,18 @@ function Modal({
2123
2125
  "2xl": "max-w-6xl",
2124
2126
  full: "max-w-[95vw]"
2125
2127
  };
2128
+ const responsiveOuter = "[@media(pointer:coarse)and(hover:none)]:!p-0";
2129
+ const responsiveFrame = "[@media(pointer:coarse)and(hover:none)]:!w-screen [@media(pointer:coarse)and(hover:none)]:!h-[100dvh] [@media(pointer:coarse)and(hover:none)]:!max-h-[100dvh] [@media(pointer:coarse)and(hover:none)]:!max-w-none [@media(pointer:coarse)and(hover:none)]:!rounded-none [@media(pointer:coarse)and(hover:none)]:!border-0";
2130
+ const forcedOuter = "!p-0";
2131
+ const forcedFrame = "!w-screen !h-[100dvh] !max-h-[100dvh] !max-w-none !rounded-none !border-0";
2126
2132
  return /* @__PURE__ */ jsxs(
2127
2133
  "div",
2128
2134
  {
2129
- className: "fixed inset-0 flex items-center justify-center p-4",
2135
+ className: cn(
2136
+ "fixed inset-0 flex items-center justify-center p-4",
2137
+ responsive && responsiveOuter,
2138
+ forceMobile && forcedOuter
2139
+ ),
2130
2140
  style: { zIndex },
2131
2141
  onClick: onClose,
2132
2142
  children: [
@@ -2140,6 +2150,8 @@ function Modal({
2140
2150
  "flex flex-col",
2141
2151
  "max-h-[90vh]",
2142
2152
  sizeClasses[size],
2153
+ responsive && responsiveFrame,
2154
+ forceMobile && forcedFrame,
2143
2155
  contentClassName
2144
2156
  ),
2145
2157
  onClick: (e) => e.stopPropagation(),
@@ -2185,6 +2197,27 @@ function ModalButton({
2185
2197
  }
2186
2198
  );
2187
2199
  }
2200
+ var mobileSheetContentClasses = [
2201
+ "[@media(pointer:coarse)and(hover:none)]:!top-auto",
2202
+ "[@media(pointer:coarse)and(hover:none)]:!bottom-0",
2203
+ "[@media(pointer:coarse)and(hover:none)]:!left-0",
2204
+ "[@media(pointer:coarse)and(hover:none)]:!translate-x-0",
2205
+ "[@media(pointer:coarse)and(hover:none)]:!translate-y-0",
2206
+ "[@media(pointer:coarse)and(hover:none)]:!w-screen",
2207
+ "[@media(pointer:coarse)and(hover:none)]:!max-w-none",
2208
+ "[@media(pointer:coarse)and(hover:none)]:!rounded-t-xl",
2209
+ "[@media(pointer:coarse)and(hover:none)]:!rounded-b-none",
2210
+ "[@media(pointer:coarse)and(hover:none)]:!pb-[calc(1.5rem+env(safe-area-inset-bottom))]"
2211
+ ].join(" ");
2212
+ var mobileSheetFooterClasses = [
2213
+ // Stack buttons full-width with comfortable tap targets on touch devices.
2214
+ "[@media(pointer:coarse)and(hover:none)]:!flex-col",
2215
+ "[@media(pointer:coarse)and(hover:none)]:!gap-2"
2216
+ ].join(" ");
2217
+ var mobileSheetActionClasses = [
2218
+ "[@media(pointer:coarse)and(hover:none)]:!w-full",
2219
+ "[@media(pointer:coarse)and(hover:none)]:!min-h-11"
2220
+ ].join(" ");
2188
2221
  function ConfirmationModal({
2189
2222
  open,
2190
2223
  onOpenChange,
@@ -2204,18 +2237,28 @@ function ConfirmationModal({
2204
2237
  onConfirm();
2205
2238
  onOpenChange(false);
2206
2239
  };
2207
- return /* @__PURE__ */ jsx(AlertDialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [
2240
+ return /* @__PURE__ */ jsx(AlertDialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(AlertDialogContent, { className: mobileSheetContentClasses, children: [
2208
2241
  /* @__PURE__ */ jsxs(AlertDialogHeader, { children: [
2209
2242
  /* @__PURE__ */ jsx(AlertDialogTitle, { children: title }),
2210
2243
  /* @__PURE__ */ jsx(AlertDialogDescription, { children: description })
2211
2244
  ] }),
2212
- /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [
2213
- /* @__PURE__ */ jsx(AlertDialogCancel, { onClick: handleCancel, children: cancelLabel }),
2245
+ /* @__PURE__ */ jsxs(AlertDialogFooter, { className: mobileSheetFooterClasses, children: [
2246
+ /* @__PURE__ */ jsx(
2247
+ AlertDialogCancel,
2248
+ {
2249
+ onClick: handleCancel,
2250
+ className: mobileSheetActionClasses,
2251
+ children: cancelLabel
2252
+ }
2253
+ ),
2214
2254
  /* @__PURE__ */ jsx(
2215
2255
  AlertDialogAction,
2216
2256
  {
2217
2257
  onClick: handleConfirm,
2218
- className: destructive ? "bg-destructive text-destructive-foreground hover:bg-destructive/90" : void 0,
2258
+ className: [
2259
+ destructive ? "bg-destructive text-destructive-foreground hover:bg-destructive/90" : "",
2260
+ mobileSheetActionClasses
2261
+ ].filter(Boolean).join(" "),
2219
2262
  children: confirmLabel
2220
2263
  }
2221
2264
  )