najm-kit 2.1.27 → 2.1.29

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.ts CHANGED
@@ -457,7 +457,7 @@ declare function DialogClose({ ...props }: React$1.ComponentProps<typeof DialogP
457
457
  declare function DialogOverlay({ className, ...props }: React$1.ComponentProps<typeof DialogPrimitive.Overlay>): react_jsx_runtime.JSX.Element;
458
458
  type DialogPadding = "none" | "sm" | "md" | "lg";
459
459
  interface DialogContentProps extends React$1.ComponentProps<typeof DialogPrimitive.Content> {
460
- /** Controls the padding of the dialog surface. `none` also collapses the header/body/footer gap. Defaults to `md` (p-6). */
460
+ /** Controls the padding of the dialog surface. `none` also collapses the header/body/footer gap. Defaults to `sm` on mobile, `md` on desktop. */
461
461
  padding?: DialogPadding;
462
462
  /** Hides the built-in top-right close (X). Use when the content provides its own close control (e.g. inside a page header). */
463
463
  hideClose?: boolean;
@@ -2285,6 +2285,13 @@ interface BaseFormInputProps {
2285
2285
  onChange?: (value: any) => void;
2286
2286
  }
2287
2287
  type FormInputSpecificProps<T> = Omit<T, "value" | "onChange" | keyof BaseFormInputProps>;
2288
+ type FormImageInputProps = FormInputSpecificProps<ImageInputProps> & {
2289
+ /**
2290
+ * Optional controlled preview value.
2291
+ * React Hook Form owns the value when omitted.
2292
+ */
2293
+ value?: ImageInputProps["value"];
2294
+ };
2288
2295
  type InputTypeMap = {
2289
2296
  text: FormInputSpecificProps<TextInputProps>;
2290
2297
  number: FormInputSpecificProps<NumberInputProps>;
@@ -2298,7 +2305,7 @@ type InputTypeMap = {
2298
2305
  checkbox: FormInputSpecificProps<CheckboxInputProps>;
2299
2306
  checkboxGroup: FormInputSpecificProps<CheckboxGroupInputProps>;
2300
2307
  file: FormInputSpecificProps<FileInputProps>;
2301
- image: FormInputSpecificProps<ImageInputProps>;
2308
+ image: FormImageInputProps;
2302
2309
  date: FormInputSpecificProps<DateInputProps>;
2303
2310
  starRating: FormInputSpecificProps<StarRatingInputProps>;
2304
2311
  colorArray: FormInputSpecificProps<ColorArrayInputProps>;
package/dist/index.mjs CHANGED
@@ -1234,11 +1234,26 @@ var Button = React.forwardRef(
1234
1234
  },
1235
1235
  [autoLoading, isDisabled, onClick]
1236
1236
  );
1237
- const content = loadingText && isLoading ? loadingText : children;
1237
+ const child = asChild ? React.Children.only(children) : null;
1238
+ const childContent = asChild && React.isValidElement(child) ? child.props.children : children;
1239
+ const content = loadingText && isLoading ? loadingText : childContent;
1238
1240
  const loaderNode = isLoading ? loader : null;
1239
1241
  const leftIconNode = renderIcon(leftIcon);
1240
1242
  const rightIconNode = renderIcon(rightIcon);
1241
1243
  const showCenteredLoader = Boolean(loaderNode && loaderPosition === "center");
1244
+ const renderedContent = showCenteredLoader ? /* @__PURE__ */ jsxs(Fragment, { children: [
1245
+ /* @__PURE__ */ jsxs("span", { className: "invisible inline-flex items-center gap-2", children: [
1246
+ leftIconNode,
1247
+ content,
1248
+ rightIconNode
1249
+ ] }),
1250
+ /* @__PURE__ */ jsx("span", { className: "absolute inset-0 inline-flex items-center justify-center", children: loaderNode })
1251
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1252
+ loaderNode && loaderPosition === "left" ? loaderNode : leftIconNode,
1253
+ content,
1254
+ loaderNode && loaderPosition === "right" ? loaderNode : rightIconNode
1255
+ ] });
1256
+ const renderedChild = asChild && React.isValidElement(child) ? React.cloneElement(child, void 0, renderedContent) : renderedContent;
1242
1257
  return /* @__PURE__ */ jsx(
1243
1258
  Comp,
1244
1259
  {
@@ -1267,18 +1282,7 @@ var Button = React.forwardRef(
1267
1282
  ),
1268
1283
  onClick: handleClick,
1269
1284
  ...props,
1270
- children: showCenteredLoader ? /* @__PURE__ */ jsxs(Fragment, { children: [
1271
- /* @__PURE__ */ jsxs("span", { className: "invisible inline-flex items-center gap-2", children: [
1272
- leftIconNode,
1273
- content,
1274
- rightIconNode
1275
- ] }),
1276
- /* @__PURE__ */ jsx("span", { className: "absolute inset-0 inline-flex items-center justify-center", children: loaderNode })
1277
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1278
- loaderNode && loaderPosition === "left" ? loaderNode : leftIconNode,
1279
- content,
1280
- loaderNode && loaderPosition === "right" ? loaderNode : rightIconNode
1281
- ] })
1285
+ children: renderedChild
1282
1286
  }
1283
1287
  );
1284
1288
  }
@@ -1913,7 +1917,29 @@ var dialogPaddingMap = {
1913
1917
  md: "p-6",
1914
1918
  lg: "p-8"
1915
1919
  };
1916
- function DialogContent({ className, children, padding = "md", hideClose = false, ...props }) {
1920
+ var MOBILE_PADDING_QUERY = "(max-width: 639.98px)";
1921
+ function getDefaultPadding() {
1922
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") return "md";
1923
+ return window.matchMedia(MOBILE_PADDING_QUERY).matches ? "sm" : "md";
1924
+ }
1925
+ function useResponsivePadding(value) {
1926
+ const [resolved, setResolved] = React.useState(() => value ?? getDefaultPadding());
1927
+ React.useEffect(() => {
1928
+ if (value) {
1929
+ setResolved(value);
1930
+ return;
1931
+ }
1932
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1933
+ const mql = window.matchMedia(MOBILE_PADDING_QUERY);
1934
+ const update = () => setResolved(mql.matches ? "sm" : "md");
1935
+ update();
1936
+ mql.addEventListener("change", update);
1937
+ return () => mql.removeEventListener("change", update);
1938
+ }, [value]);
1939
+ return resolved;
1940
+ }
1941
+ function DialogContent({ className, children, padding, hideClose = false, ...props }) {
1942
+ const resolvedPadding = useResponsivePadding(padding);
1917
1943
  const portalClassName = useNPortalScope();
1918
1944
  return /* @__PURE__ */ jsx(DialogPortal, { "data-slot": "dialog-portal", children: /* @__PURE__ */ jsxs("div", { className: portalClassName, children: [
1919
1945
  /* @__PURE__ */ jsx(DialogOverlay, {}),
@@ -1921,10 +1947,10 @@ function DialogContent({ className, children, padding = "md", hideClose = false,
1921
1947
  SheetPrimitive.Content,
1922
1948
  {
1923
1949
  "data-slot": "dialog-content",
1924
- "data-padding": padding,
1950
+ "data-padding": resolvedPadding,
1925
1951
  className: cn(
1926
- "bg-card text-card-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-sm translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg najm-border border-border shadow-lg duration-200",
1927
- dialogPaddingMap[padding],
1952
+ "bg-card text-card-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-sm translate-x-[-50%] translate-y-[-50%] gap-4 rounded-none lg:rounded-lg najm-border border-border shadow-lg duration-200",
1953
+ dialogPaddingMap[resolvedPadding],
1928
1954
  className
1929
1955
  ),
1930
1956
  ...props,
@@ -2444,12 +2470,12 @@ function parseDirectDialogSlots(children) {
2444
2470
  return { ...parsed, body };
2445
2471
  }
2446
2472
  var dialogVariants = cva(
2447
- "flex flex-col w-full max-w-[95vw] h-full max-h-screen",
2473
+ "flex flex-col w-full max-w-full h-full max-h-screen",
2448
2474
  {
2449
2475
  variants: {
2450
2476
  variant: {
2451
2477
  default: "",
2452
- window: "rounded-sm"
2478
+ window: "rounded-none lg:rounded-sm"
2453
2479
  },
2454
2480
  size: {
2455
2481
  sm: "lg:max-w-md",
@@ -2546,10 +2572,11 @@ function DialogChrome({
2546
2572
  contentRef,
2547
2573
  children
2548
2574
  }) {
2575
+ const resolvedPadding = useResponsivePadding(padding);
2549
2576
  const noTitle = !title || title.trim() === "";
2550
2577
  const noDescription = !description || description.trim() === "";
2551
2578
  const noHeader = noTitle && noDescription;
2552
- const flush = padding === "none";
2579
+ const flush = resolvedPadding === "none";
2553
2580
  return /* @__PURE__ */ jsxs(Fragment, { children: [
2554
2581
  pageHeader ? /* @__PURE__ */ jsxs(Fragment, { children: [
2555
2582
  /* @__PURE__ */ jsx(DialogTitle, { className: cn("sr-only", titleClassName), children: pageHeader.title || title || "Dialog" }),
@@ -2570,7 +2597,7 @@ function DialogChrome({
2570
2597
  {
2571
2598
  className: cn(
2572
2599
  "flex-row items-center justify-between gap-3 border-b border-border bg-secondary text-left text-secondary-foreground",
2573
- windowHeaderSpacing[padding ?? "md"],
2600
+ windowHeaderSpacing[resolvedPadding],
2574
2601
  headerClassName
2575
2602
  ),
2576
2603
  children: [
package/dist/json.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import * as React3 from 'react';
2
- import React3__default, { createContext, useContext, useMemo, useRef, useCallback } from 'react';
1
+ import * as React5 from 'react';
2
+ import React5__default, { createContext, useContext, useMemo, useRef, useCallback } from 'react';
3
3
  import CodeMirror from '@uiw/react-codemirror';
4
4
  import { json } from '@codemirror/lang-json';
5
5
  import { keymap, EditorView, Decoration, ViewPlugin } from '@codemirror/view';
@@ -201,8 +201,8 @@ var NIcon = ({
201
201
  height: size,
202
202
  ...style
203
203
  };
204
- if (React3__default.isValidElement(icon)) {
205
- return React3__default.cloneElement(icon, {
204
+ if (React5__default.isValidElement(icon)) {
205
+ return React5__default.cloneElement(icon, {
206
206
  className: cn(className, icon.props.className),
207
207
  onClick,
208
208
  ...rest
@@ -249,15 +249,15 @@ var NIcon = ({
249
249
  return null;
250
250
  };
251
251
  NIcon.displayName = "NIcon";
252
- React3.createContext(0);
253
- React3.createContext(null);
252
+ React5.createContext(0);
253
+ React5.createContext(null);
254
254
  var DEFAULT_APPEARANCE = {};
255
- React3.createContext(DEFAULT_APPEARANCE);
256
- var NajmDesignContext = React3.createContext({
255
+ React5.createContext(DEFAULT_APPEARANCE);
256
+ var NajmDesignContext = React5.createContext({
257
257
  components: {}
258
258
  });
259
259
  function useNajmDesign() {
260
- return React3.useContext(NajmDesignContext);
260
+ return React5.useContext(NajmDesignContext);
261
261
  }
262
262
  function useNajmComponentStyle(name) {
263
263
  const { components } = useNajmDesign();
@@ -427,7 +427,7 @@ function renderIcon(icon) {
427
427
  if (!icon) return null;
428
428
  return /* @__PURE__ */ jsx(NIcon, { "aria-hidden": "true", icon, className: "shrink-0" });
429
429
  }
430
- var Button = React3.forwardRef(
430
+ var Button = React5.forwardRef(
431
431
  ({
432
432
  className,
433
433
  variant,
@@ -459,11 +459,11 @@ var Button = React3.forwardRef(
459
459
  const effSize = size ?? recipe?.defaultSize;
460
460
  const recipeRadius = rounded === void 0 ? resolveRadiusValue(recipe?.radius) : void 0;
461
461
  const recipeStyle = recipeRadius ? { borderRadius: recipeRadius } : void 0;
462
- const [pending, setPending] = React3.useState(false);
462
+ const [pending, setPending] = React5.useState(false);
463
463
  const isLoading = loading || pending;
464
464
  const isDisabled = disabled || disabledWhileLoading && isLoading;
465
465
  const Comp = asChild ? Slot : "button";
466
- const handleClick = React3.useCallback(
466
+ const handleClick = React5.useCallback(
467
467
  (event) => {
468
468
  if (isDisabled) {
469
469
  event.preventDefault();
@@ -480,11 +480,26 @@ var Button = React3.forwardRef(
480
480
  },
481
481
  [autoLoading, isDisabled, onClick]
482
482
  );
483
- const content = loadingText && isLoading ? loadingText : children;
483
+ const child = asChild ? React5.Children.only(children) : null;
484
+ const childContent = asChild && React5.isValidElement(child) ? child.props.children : children;
485
+ const content = loadingText && isLoading ? loadingText : childContent;
484
486
  const loaderNode = isLoading ? loader : null;
485
487
  const leftIconNode = renderIcon(leftIcon);
486
488
  const rightIconNode = renderIcon(rightIcon);
487
489
  const showCenteredLoader = Boolean(loaderNode && loaderPosition === "center");
490
+ const renderedContent = showCenteredLoader ? /* @__PURE__ */ jsxs(Fragment, { children: [
491
+ /* @__PURE__ */ jsxs("span", { className: "invisible inline-flex items-center gap-2", children: [
492
+ leftIconNode,
493
+ content,
494
+ rightIconNode
495
+ ] }),
496
+ /* @__PURE__ */ jsx("span", { className: "absolute inset-0 inline-flex items-center justify-center", children: loaderNode })
497
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
498
+ loaderNode && loaderPosition === "left" ? loaderNode : leftIconNode,
499
+ content,
500
+ loaderNode && loaderPosition === "right" ? loaderNode : rightIconNode
501
+ ] });
502
+ const renderedChild = asChild && React5.isValidElement(child) ? React5.cloneElement(child, void 0, renderedContent) : renderedContent;
488
503
  return /* @__PURE__ */ jsx(
489
504
  Comp,
490
505
  {
@@ -513,18 +528,7 @@ var Button = React3.forwardRef(
513
528
  ),
514
529
  onClick: handleClick,
515
530
  ...props,
516
- children: showCenteredLoader ? /* @__PURE__ */ jsxs(Fragment, { children: [
517
- /* @__PURE__ */ jsxs("span", { className: "invisible inline-flex items-center gap-2", children: [
518
- leftIconNode,
519
- content,
520
- rightIconNode
521
- ] }),
522
- /* @__PURE__ */ jsx("span", { className: "absolute inset-0 inline-flex items-center justify-center", children: loaderNode })
523
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
524
- loaderNode && loaderPosition === "left" ? loaderNode : leftIconNode,
525
- content,
526
- loaderNode && loaderPosition === "right" ? loaderNode : rightIconNode
527
- ] })
531
+ children: renderedChild
528
532
  }
529
533
  );
530
534
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "najm-kit",
3
- "version": "2.1.27",
3
+ "version": "2.1.29",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Reusable React UI component package for Najm framework",