@beyondcorp/beyond-ui 1.2.65 → 1.2.69

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.
@@ -2,12 +2,18 @@ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { useState } from 'react';
3
3
  import { Skeleton } from '../Skeleton/Skeleton.js';
4
4
  import { Spinner } from '../Spinner/Spinner.js';
5
+ import { useIntersectionObserver } from '../../hooks/useIntersectionObserver.js';
5
6
 
6
7
  const DEFAULT_PLACEHOLDER = "https://res.cloudinary.com/dmpposta9/image/upload/v1759505259/beyond/beyond%20ui/beyond-ui-logo-part-with-bg_1_wydfry.png";
7
8
  const Image = ({ src, alt, className = "", fallbackSrc = DEFAULT_PLACEHOLDER, skeletonClassName = "w-full h-full", ...imgProps }) => {
8
9
  const [loaded, setLoaded] = useState(false);
9
10
  const [error, setError] = useState(false);
10
- return (jsxs("div", { className: `relative ${className}`, children: [!loaded && !error && (jsxs("div", { className: `absolute inset-0 flex items-center justify-center ${skeletonClassName}`, children: [jsx(Skeleton, { className: "w-full h-full absolute inset-0" }), jsx(Spinner, { className: "relative z-10 w-8 h-8 text-primary-500" })] })), jsx("img", { src: error ? fallbackSrc : src, alt: alt, loading: "lazy", style: loaded ? {} : { display: "none" }, onLoad: () => setLoaded(true), onError: () => setError(true), draggable: imgProps.draggable ?? false, ...imgProps, className: `absolute inset-0 w-full h-full object-cover transition-transform duration-300 ${loaded ? "" : "hidden"}` })] }));
11
+ const [containerRef, inView] = useIntersectionObserver({ threshold: 0.1, freezeOnceVisible: true });
12
+ // Only load image if inView (or fallback if IntersectionObserver unsupported)
13
+ const shouldLoad = inView;
14
+ return (jsxs("div", { ref: containerRef, className: `relative ${className}`, children: [!loaded && !error && (jsxs("div", { className: `absolute inset-0 flex items-center justify-center ${skeletonClassName}`, children: [jsx(Skeleton, { className: "w-full h-full absolute inset-0" }), jsx(Spinner, { className: "relative z-10 w-8 h-8 text-primary-500" })] })), shouldLoad && (jsx("img", { src: error ? fallbackSrc : src, alt: alt,
15
+ // loading="lazy"
16
+ style: loaded ? {} : { display: "none" }, onLoad: () => setLoaded(true), onError: () => setError(true), draggable: imgProps.draggable ?? false, ...imgProps, className: `absolute inset-0 w-full h-full object-cover transition-transform duration-300 ${loaded ? "" : "hidden"}` }))] }));
11
17
  };
12
18
 
13
19
  export { Image };
@@ -1 +1 @@
1
- {"version":3,"file":"Image.js","sources":["../../../src/components/Image/Image.tsx"],"sourcesContent":["import React, { useState } from \"react\";\r\nimport { Skeleton } from \"../Skeleton\";\r\nimport { Spinner } from \"../Spinner\";\r\n\r\nexport interface ImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {\r\n src: string;\r\n alt: string;\r\n className?: string;\r\n fallbackSrc?: string;\r\n skeletonClassName?: string;\r\n}\r\n\r\nconst DEFAULT_PLACEHOLDER =\r\n \"https://res.cloudinary.com/dmpposta9/image/upload/v1759505259/beyond/beyond%20ui/beyond-ui-logo-part-with-bg_1_wydfry.png\";\r\nexport const Image: React.FC<ImageProps> = ({\r\n src,\r\n alt,\r\n className = \"\",\r\n fallbackSrc = DEFAULT_PLACEHOLDER,\r\n skeletonClassName = \"w-full h-full\",\r\n ...imgProps\r\n}) => {\r\n const [loaded, setLoaded] = useState(false);\r\n const [error, setError] = useState(false);\r\n\r\n return (\r\n <div className={`relative ${className}`}>\r\n {!loaded && !error && (\r\n <div className={`absolute inset-0 flex items-center justify-center ${skeletonClassName}`}>\r\n <Skeleton className=\"w-full h-full absolute inset-0\" />\r\n <Spinner className=\"relative z-10 w-8 h-8 text-primary-500\" />\r\n </div>\r\n )}\r\n <img\r\n src={error ? fallbackSrc : src}\r\n alt={alt}\r\n loading=\"lazy\"\r\n style={loaded ? {} : { display: \"none\" }}\r\n onLoad={() => setLoaded(true)}\r\n onError={() => setError(true)}\r\n draggable={imgProps.draggable ?? false}\r\n {...imgProps}\r\n className={`absolute inset-0 w-full h-full object-cover transition-transform duration-300 ${loaded ? \"\" : \"hidden\"}`}\r\n />\r\n </div>\r\n );\r\n};"],"names":["_jsxs","_jsx"],"mappings":";;;;;AAYA,MAAM,mBAAmB,GACvB,2HAA2H;AACtH,MAAM,KAAK,GAAyB,CAAC,EAC1C,GAAG,EACH,GAAG,EACH,SAAS,GAAG,EAAE,EACd,WAAW,GAAG,mBAAmB,EACjC,iBAAiB,GAAG,eAAe,EACnC,GAAG,QAAQ,EACZ,KAAI;IACH,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC3C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IAEzC,QACEA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,CAAA,SAAA,EAAY,SAAS,CAAA,CAAE,EAAA,QAAA,EAAA,CACpC,CAAC,MAAM,IAAI,CAAC,KAAK,KAChBA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,CAAA,kDAAA,EAAqD,iBAAiB,CAAA,CAAE,EAAA,QAAA,EAAA,CACtFC,GAAA,CAAC,QAAQ,EAAA,EAAC,SAAS,EAAC,gCAAgC,EAAA,CAAG,EACvDA,GAAA,CAAC,OAAO,EAAA,EAAC,SAAS,EAAC,wCAAwC,EAAA,CAAG,CAAA,EAAA,CAC1D,CACP,EACDA,GAAA,CAAA,KAAA,EAAA,EACE,GAAG,EAAE,KAAK,GAAG,WAAW,GAAG,GAAG,EAC9B,GAAG,EAAE,GAAG,EACR,OAAO,EAAC,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,EACxC,MAAM,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,EAC7B,OAAO,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,EAC7B,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,KAAK,EAAA,GAClC,QAAQ,EACZ,SAAS,EAAE,CAAA,8EAAA,EAAiF,MAAM,GAAG,EAAE,GAAG,QAAQ,CAAA,CAAE,EAAA,CACpH,CAAA,EAAA,CACE;AAEV;;;;"}
1
+ {"version":3,"file":"Image.js","sources":["../../../src/components/Image/Image.tsx"],"sourcesContent":["import React, { useState } from \"react\";\r\nimport { Skeleton } from \"../Skeleton\";\r\nimport { Spinner } from \"../Spinner\";\r\nimport { useIntersectionObserver } from \"../../hooks/useIntersectionObserver\";\r\n\r\nexport interface ImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {\r\n src: string;\r\n alt: string;\r\n className?: string;\r\n fallbackSrc?: string;\r\n skeletonClassName?: string;\r\n}\r\n\r\nconst DEFAULT_PLACEHOLDER =\r\n \"https://res.cloudinary.com/dmpposta9/image/upload/v1759505259/beyond/beyond%20ui/beyond-ui-logo-part-with-bg_1_wydfry.png\";\r\nexport const Image: React.FC<ImageProps> = ({\r\n src,\r\n alt,\r\n className = \"\",\r\n fallbackSrc = DEFAULT_PLACEHOLDER,\r\n skeletonClassName = \"w-full h-full\",\r\n ...imgProps\r\n}) => {\r\n const [loaded, setLoaded] = useState(false);\r\n const [error, setError] = useState(false);\r\n const [containerRef, inView] = useIntersectionObserver<HTMLDivElement>({ threshold: 0.1, freezeOnceVisible: true });\r\n\r\n // Only load image if inView (or fallback if IntersectionObserver unsupported)\r\n const shouldLoad = inView;\r\n\r\n return (\r\n <div ref={containerRef} className={`relative ${className}`}>\r\n {!loaded && !error && (\r\n <div className={`absolute inset-0 flex items-center justify-center ${skeletonClassName}`}>\r\n <Skeleton className=\"w-full h-full absolute inset-0\" />\r\n <Spinner className=\"relative z-10 w-8 h-8 text-primary-500\" />\r\n </div>\r\n )}\r\n {shouldLoad && (\r\n <img\r\n src={error ? fallbackSrc : src}\r\n alt={alt}\r\n // loading=\"lazy\"\r\n style={loaded ? {} : { display: \"none\" }}\r\n onLoad={() => setLoaded(true)}\r\n onError={() => setError(true)}\r\n draggable={imgProps.draggable ?? false}\r\n {...imgProps}\r\n className={`absolute inset-0 w-full h-full object-cover transition-transform duration-300 ${loaded ? \"\" : \"hidden\"}`}\r\n />\r\n )}\r\n </div>\r\n );\r\n};"],"names":["_jsxs","_jsx"],"mappings":";;;;;;AAaA,MAAM,mBAAmB,GACvB,2HAA2H;AACtH,MAAM,KAAK,GAAyB,CAAC,EAC1C,GAAG,EACH,GAAG,EACH,SAAS,GAAG,EAAE,EACd,WAAW,GAAG,mBAAmB,EACjC,iBAAiB,GAAG,eAAe,EACnC,GAAG,QAAQ,EACZ,KAAI;IACH,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC3C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;AACzC,IAAA,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG,uBAAuB,CAAiB,EAAE,SAAS,EAAE,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;;IAGnH,MAAM,UAAU,GAAG,MAAM;AAEzB,IAAA,QACEA,IAAA,CAAA,KAAA,EAAA,EAAK,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,CAAA,SAAA,EAAY,SAAS,CAAA,CAAE,EAAA,QAAA,EAAA,CACvD,CAAC,MAAM,IAAI,CAAC,KAAK,KAChBA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,CAAA,kDAAA,EAAqD,iBAAiB,CAAA,CAAE,EAAA,QAAA,EAAA,CACtFC,GAAA,CAAC,QAAQ,IAAC,SAAS,EAAC,gCAAgC,EAAA,CAAG,EACvDA,GAAA,CAAC,OAAO,EAAA,EAAC,SAAS,EAAC,wCAAwC,EAAA,CAAG,CAAA,EAAA,CAC1D,CACP,EACA,UAAU,KACTA,GAAA,CAAA,KAAA,EAAA,EACE,GAAG,EAAE,KAAK,GAAG,WAAW,GAAG,GAAG,EAC9B,GAAG,EAAE,GAAG;;AAER,gBAAA,KAAK,EAAE,MAAM,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,EACxC,MAAM,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,EAC7B,OAAO,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,EAC7B,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,KAAK,EAAA,GAClC,QAAQ,EACZ,SAAS,EAAE,CAAA,8EAAA,EAAiF,MAAM,GAAG,EAAE,GAAG,QAAQ,CAAA,CAAE,EAAA,CACpH,CACH,CAAA,EAAA,CACG;AAEV;;;;"}
@@ -8,6 +8,7 @@ export type EditModalField = {
8
8
  required?: boolean;
9
9
  autoFocus?: boolean;
10
10
  onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
11
+ inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
11
12
  } | {
12
13
  type: "textarea";
13
14
  label: string;
@@ -41,7 +41,7 @@ const EditModal = ({ open, title, description, fields, onChange, onSave, onClose
41
41
  field.type === "tel" ||
42
42
  field.type === "url" ||
43
43
  field.type === "password") {
44
- return (jsxs(React.Fragment, { children: [title, jsx(Input, { type: field.type, name: field.name, value: field.value, placeholder: field.placeholder, required: field.required, autoFocus: field.autoFocus, onChange: e => field.onChange ? field.onChange(e) : onChange(field.name, e.target.value), className: "w-full" })] }, field.name));
44
+ return (jsxs(React.Fragment, { children: [title, jsx(Input, { type: field.type, name: field.name, value: field.value, placeholder: field.placeholder, required: field.required, autoFocus: field.autoFocus, onChange: e => field.onChange ? field.onChange(e) : onChange(field.name, e.target.value), className: "w-full", ...field.inputProps })] }, field.name));
45
45
  }
46
46
  return null;
47
47
  }) }), jsxs("div", { className: "flex justify-end space-x-2 mt-8", children: [jsx(Button, { type: "button", variant: "secondary", onClick: onClose, children: closeLabel }), jsx(Button, { type: "submit", variant: "primary", disabled: saving, children: saveLabel })] })] })] }) }));
@@ -1 +1 @@
1
- {"version":3,"file":"EditModal.js","sources":["../../../src/components/ProfileManagement/EditModal.tsx"],"sourcesContent":["import * as React from \"react\";\r\nimport { Modal } from \"../Modal/Modal\";\r\nimport { Button } from \"../Button\";\r\nimport { Input } from \"../Input\";\r\nimport { Textarea } from \"../Textarea\";\r\nimport { cn } from \"../../utils/cn\";\r\n\r\nexport type EditModalField =\r\n | {\r\n type: \"text\" | \"email\" | \"tel\" | \"url\" | \"password\";\r\n label: string;\r\n name: string;\r\n value?: string;\r\n placeholder?: string;\r\n required?: boolean;\r\n autoFocus?: boolean;\r\n onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\r\n }\r\n | {\r\n type: \"textarea\";\r\n label: string;\r\n name: string;\r\n value?: string;\r\n placeholder?: string;\r\n required?: boolean;\r\n rows?: number;\r\n onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\r\n }\r\n | {\r\n type: \"select\";\r\n label: string;\r\n name: string;\r\n value?: string;\r\n options: { label: string; value: string }[];\r\n placeholder?: string;\r\n required?: boolean;\r\n onChange?: (e: React.ChangeEvent<HTMLSelectElement>) => void;\r\n }\r\n | {\r\n type: \"checkbox\";\r\n label: string;\r\n name: string;\r\n checked?: boolean;\r\n required?: boolean;\r\n onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\r\n }\r\n | {\r\n type: \"radio\";\r\n label: string;\r\n name: string;\r\n value?: string;\r\n options: { label: string; value: string }[];\r\n required?: boolean;\r\n onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\r\n }\r\n | {\r\n type: \"switch\";\r\n label: string;\r\n name: string;\r\n checked?: boolean;\r\n required?: boolean;\r\n onChange?: (checked: boolean) => void;\r\n }\r\n | {\r\n type: \"custom\";\r\n name: string;\r\n render: () => React.ReactNode;\r\n };\r\n\r\nexport interface EditModalProps {\r\n open: boolean;\r\n title?: string;\r\n description?: string;\r\n fields: EditModalField[];\r\n onChange: (name: string, value: string) => void;\r\n onSave: () => void;\r\n onClose: () => void;\r\n saving?: boolean;\r\n saveLabel?: string;\r\n closeLabel?: string;\r\n className?: string;\r\n}\r\n\r\nexport const EditModal: React.FC<EditModalProps> = ({\r\n open,\r\n title,\r\n description,\r\n fields,\r\n onChange,\r\n onSave,\r\n onClose,\r\n saving,\r\n saveLabel = \"Save Changes\",\r\n closeLabel = \"Close\",\r\n className,\r\n}) => (\r\n <Modal open={open} onOpenChange={() => onClose()}>\r\n <div className={cn(\"max-w-2xl rounded-2xl p-0 p-8 mx-auto bg-white\", className)}>\r\n {title && <h2 className=\"text-2xl font-bold mb-1 text-gray-900\">{title}</h2>}\r\n {description && <p className=\"text-gray-500 mb-6\">{description}</p>}\r\n <form\r\n className=\"space-y-6\"\r\n onSubmit={e => {\r\n e.preventDefault();\r\n onSave();\r\n }}\r\n >\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {fields.map((field, idx) => {\r\n if (field.type === \"custom\") {\r\n return <div key={field.name}>{field.render()}</div>;\r\n }\r\n // Title above every input/textarea/select/etc.\r\n const title = (\r\n <div key={field.name + \"-title\"} className=\"mb-1 font-medium text-gray-700\">\r\n {field.label}\r\n </div>\r\n );\r\n if (field.type === \"textarea\") {\r\n return (\r\n <React.Fragment key={field.name}>\r\n {title}\r\n <Textarea\r\n name={field.name}\r\n value={field.value}\r\n placeholder={field.placeholder}\r\n rows={field.rows || 3}\r\n required={field.required}\r\n onChange={e => field.onChange ? field.onChange(e) : onChange(field.name, e.target.value)}\r\n className=\"w-full\"\r\n />\r\n </React.Fragment>\r\n );\r\n }\r\n if (field.type === \"select\") {\r\n // Lazy import to avoid breaking if not present\r\n const { Select } = require(\"../Select/Select\");\r\n return (\r\n <React.Fragment key={field.name}>\r\n {title}\r\n <Select\r\n name={field.name}\r\n value={field.value}\r\n options={field.options}\r\n placeholder={field.placeholder}\r\n required={field.required}\r\n onChange={(e: React.ChangeEvent<HTMLSelectElement>) => field.onChange ? field.onChange(e) : onChange(field.name, e.target.value)}\r\n className=\"w-full\"\r\n />\r\n </React.Fragment>\r\n );\r\n }\r\n if (field.type === \"checkbox\") {\r\n const { Checkbox } = require(\"../Checkbox/Checkbox\");\r\n return (\r\n <React.Fragment key={field.name}>\r\n {title}\r\n <Checkbox\r\n name={field.name}\r\n checked={field.checked}\r\n required={field.required}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => field.onChange ? field.onChange(e) : onChange(field.name, e.target.checked ? \"true\" : \"false\")}\r\n className=\"w-5 h-5\"\r\n />\r\n </React.Fragment>\r\n );\r\n }\r\n if (field.type === \"radio\") {\r\n const { RadioGroup } = require(\"../Radio/Radio\");\r\n return (\r\n <React.Fragment key={field.name}>\r\n {title}\r\n <RadioGroup\r\n name={field.name}\r\n value={field.value}\r\n options={field.options}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => field.onChange ? field.onChange(e) : onChange(field.name, e.target.value)}\r\n />\r\n </React.Fragment>\r\n );\r\n }\r\n if (field.type === \"switch\") {\r\n const { Switch } = require(\"../Switch/Switch\");\r\n return (\r\n <React.Fragment key={field.name}>\r\n {title}\r\n <Switch\r\n name={field.name}\r\n checked={field.checked}\r\n onCheckedChange={(checked: boolean) => field.onChange ? field.onChange(checked) : onChange(field.name, checked ? \"true\" : \"false\")}\r\n />\r\n </React.Fragment>\r\n );\r\n }\r\n // Default: Input\r\n if (\r\n field.type === \"text\" ||\r\n field.type === \"email\" ||\r\n field.type === \"tel\" ||\r\n field.type === \"url\" ||\r\n field.type === \"password\"\r\n ) {\r\n return (\r\n <React.Fragment key={field.name}>\r\n {title}\r\n <Input\r\n type={field.type}\r\n name={field.name}\r\n value={field.value}\r\n placeholder={field.placeholder}\r\n required={field.required}\r\n autoFocus={field.autoFocus}\r\n onChange={e => field.onChange ? field.onChange(e) : onChange(field.name, e.target.value)}\r\n className=\"w-full\"\r\n />\r\n </React.Fragment>\r\n );\r\n }\r\n return null;\r\n })}\r\n </div>\r\n <div className=\"flex justify-end space-x-2 mt-8\">\r\n <Button type=\"button\" variant=\"secondary\" onClick={onClose}>\r\n {closeLabel}\r\n </Button>\r\n <Button type=\"submit\" variant=\"primary\" disabled={saving}>\r\n {saveLabel}\r\n </Button>\r\n </div>\r\n </form>\r\n </div>\r\n </Modal>\r\n);\r\n\r\nEditModal.displayName = \"EditModal\";"],"names":["_jsx","_jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"EditModal.js","sources":["../../../src/components/ProfileManagement/EditModal.tsx"],"sourcesContent":["import * as React from \"react\";\r\nimport { Modal } from \"../Modal/Modal\";\r\nimport { Button } from \"../Button\";\r\nimport { Input } from \"../Input\";\r\nimport { Textarea } from \"../Textarea\";\r\nimport { cn } from \"../../utils/cn\";\r\n\r\nexport type EditModalField =\r\n | {\r\n type: \"text\" | \"email\" | \"tel\" | \"url\" | \"password\";\r\n label: string;\r\n name: string;\r\n value?: string;\r\n placeholder?: string;\r\n required?: boolean;\r\n autoFocus?: boolean;\r\n onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\r\n inputProps?: React.InputHTMLAttributes<HTMLInputElement>;\r\n }\r\n | {\r\n type: \"textarea\";\r\n label: string;\r\n name: string;\r\n value?: string;\r\n placeholder?: string;\r\n required?: boolean;\r\n rows?: number;\r\n onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\r\n }\r\n | {\r\n type: \"select\";\r\n label: string;\r\n name: string;\r\n value?: string;\r\n options: { label: string; value: string }[];\r\n placeholder?: string;\r\n required?: boolean;\r\n onChange?: (e: React.ChangeEvent<HTMLSelectElement>) => void;\r\n }\r\n | {\r\n type: \"checkbox\";\r\n label: string;\r\n name: string;\r\n checked?: boolean;\r\n required?: boolean;\r\n onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\r\n }\r\n | {\r\n type: \"radio\";\r\n label: string;\r\n name: string;\r\n value?: string;\r\n options: { label: string; value: string }[];\r\n required?: boolean;\r\n onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\r\n }\r\n | {\r\n type: \"switch\";\r\n label: string;\r\n name: string;\r\n checked?: boolean;\r\n required?: boolean;\r\n onChange?: (checked: boolean) => void;\r\n }\r\n | {\r\n type: \"custom\";\r\n name: string;\r\n render: () => React.ReactNode;\r\n };\r\n\r\nexport interface EditModalProps {\r\n open: boolean;\r\n title?: string;\r\n description?: string;\r\n fields: EditModalField[];\r\n onChange: (name: string, value: string) => void;\r\n onSave: () => void;\r\n onClose: () => void;\r\n saving?: boolean;\r\n saveLabel?: string;\r\n closeLabel?: string;\r\n className?: string;\r\n}\r\n\r\nexport const EditModal: React.FC<EditModalProps> = ({\r\n open,\r\n title,\r\n description,\r\n fields,\r\n onChange,\r\n onSave,\r\n onClose,\r\n saving,\r\n saveLabel = \"Save Changes\",\r\n closeLabel = \"Close\",\r\n className,\r\n}) => (\r\n <Modal open={open} onOpenChange={() => onClose()}>\r\n <div className={cn(\"max-w-2xl rounded-2xl p-0 p-8 mx-auto bg-white\", className)}>\r\n {title && <h2 className=\"text-2xl font-bold mb-1 text-gray-900\">{title}</h2>}\r\n {description && <p className=\"text-gray-500 mb-6\">{description}</p>}\r\n <form\r\n className=\"space-y-6\"\r\n onSubmit={e => {\r\n e.preventDefault();\r\n onSave();\r\n }}\r\n >\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {fields.map((field, idx) => {\r\n if (field.type === \"custom\") {\r\n return <div key={field.name}>{field.render()}</div>;\r\n }\r\n // Title above every input/textarea/select/etc.\r\n const title = (\r\n <div key={field.name + \"-title\"} className=\"mb-1 font-medium text-gray-700\">\r\n {field.label}\r\n </div>\r\n );\r\n if (field.type === \"textarea\") {\r\n return (\r\n <React.Fragment key={field.name}>\r\n {title}\r\n <Textarea\r\n name={field.name}\r\n value={field.value}\r\n placeholder={field.placeholder}\r\n rows={field.rows || 3}\r\n required={field.required}\r\n onChange={e => field.onChange ? field.onChange(e) : onChange(field.name, e.target.value)}\r\n className=\"w-full\"\r\n />\r\n </React.Fragment>\r\n );\r\n }\r\n if (field.type === \"select\") {\r\n // Lazy import to avoid breaking if not present\r\n const { Select } = require(\"../Select/Select\");\r\n return (\r\n <React.Fragment key={field.name}>\r\n {title}\r\n <Select\r\n name={field.name}\r\n value={field.value}\r\n options={field.options}\r\n placeholder={field.placeholder}\r\n required={field.required}\r\n onChange={(e: React.ChangeEvent<HTMLSelectElement>) => field.onChange ? field.onChange(e) : onChange(field.name, e.target.value)}\r\n className=\"w-full\"\r\n />\r\n </React.Fragment>\r\n );\r\n }\r\n if (field.type === \"checkbox\") {\r\n const { Checkbox } = require(\"../Checkbox/Checkbox\");\r\n return (\r\n <React.Fragment key={field.name}>\r\n {title}\r\n <Checkbox\r\n name={field.name}\r\n checked={field.checked}\r\n required={field.required}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => field.onChange ? field.onChange(e) : onChange(field.name, e.target.checked ? \"true\" : \"false\")}\r\n className=\"w-5 h-5\"\r\n />\r\n </React.Fragment>\r\n );\r\n }\r\n if (field.type === \"radio\") {\r\n const { RadioGroup } = require(\"../Radio/Radio\");\r\n return (\r\n <React.Fragment key={field.name}>\r\n {title}\r\n <RadioGroup\r\n name={field.name}\r\n value={field.value}\r\n options={field.options}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => field.onChange ? field.onChange(e) : onChange(field.name, e.target.value)}\r\n />\r\n </React.Fragment>\r\n );\r\n }\r\n if (field.type === \"switch\") {\r\n const { Switch } = require(\"../Switch/Switch\");\r\n return (\r\n <React.Fragment key={field.name}>\r\n {title}\r\n <Switch\r\n name={field.name}\r\n checked={field.checked}\r\n onCheckedChange={(checked: boolean) => field.onChange ? field.onChange(checked) : onChange(field.name, checked ? \"true\" : \"false\")}\r\n />\r\n </React.Fragment>\r\n );\r\n }\r\n // Default: Input\r\n if (\r\n field.type === \"text\" ||\r\n field.type === \"email\" ||\r\n field.type === \"tel\" ||\r\n field.type === \"url\" ||\r\n field.type === \"password\"\r\n ) {\r\n return (\r\n <React.Fragment key={field.name}>\r\n {title}\r\n <Input\r\n type={field.type}\r\n name={field.name}\r\n value={field.value}\r\n placeholder={field.placeholder}\r\n required={field.required}\r\n autoFocus={field.autoFocus}\r\n onChange={e => field.onChange ? field.onChange(e) : onChange(field.name, e.target.value)}\r\n className=\"w-full\"\r\n {...field.inputProps}\r\n />\r\n </React.Fragment>\r\n );\r\n }\r\n return null;\r\n })}\r\n </div>\r\n <div className=\"flex justify-end space-x-2 mt-8\">\r\n <Button type=\"button\" variant=\"secondary\" onClick={onClose}>\r\n {closeLabel}\r\n </Button>\r\n <Button type=\"submit\" variant=\"primary\" disabled={saving}>\r\n {saveLabel}\r\n </Button>\r\n </div>\r\n </form>\r\n </div>\r\n </Modal>\r\n);\r\n\r\nEditModal.displayName = \"EditModal\";"],"names":["_jsx","_jsxs"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export interface IntersectionOptions extends IntersectionObserverInit {
2
+ freezeOnceVisible?: boolean;
3
+ }
4
+ /**
5
+ * useIntersectionObserver
6
+ * Returns true if the element is in the viewport.
7
+ * Usage: const [ref, inView] = useIntersectionObserver(options);
8
+ */
9
+ export declare function useIntersectionObserver<T extends HTMLElement = HTMLElement>(options?: IntersectionOptions): [React.RefObject<T>, boolean];
@@ -0,0 +1,39 @@
1
+ import { useState, useEffect } from 'react';
2
+
3
+ /**
4
+ * useIntersectionObserver
5
+ * Returns true if the element is in the viewport.
6
+ * Usage: const [ref, inView] = useIntersectionObserver(options);
7
+ */
8
+ function useIntersectionObserver(options) {
9
+ const [inView, setInView] = useState(false);
10
+ const ref = useState(() => ({ current: null }))[0];
11
+ useEffect(() => {
12
+ const node = ref.current;
13
+ if (!node || typeof window === "undefined" || !("IntersectionObserver" in window)) {
14
+ setInView(true); // Fallback: always load if no observer
15
+ return;
16
+ }
17
+ let frozen = false;
18
+ const observer = new IntersectionObserver(([entry]) => {
19
+ if (entry.isIntersecting) {
20
+ setInView(true);
21
+ if (options?.freezeOnceVisible) {
22
+ frozen = true;
23
+ observer.disconnect();
24
+ }
25
+ }
26
+ else if (!frozen) {
27
+ setInView(false);
28
+ }
29
+ }, options);
30
+ observer.observe(node);
31
+ return () => {
32
+ observer.disconnect();
33
+ };
34
+ }, [ref, options]);
35
+ return [ref, inView];
36
+ }
37
+
38
+ export { useIntersectionObserver };
39
+ //# sourceMappingURL=useIntersectionObserver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIntersectionObserver.js","sources":["../../src/hooks/useIntersectionObserver.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\r\n\r\nexport interface IntersectionOptions extends IntersectionObserverInit {\r\n freezeOnceVisible?: boolean;\r\n}\r\n\r\n/**\r\n * useIntersectionObserver\r\n * Returns true if the element is in the viewport.\r\n * Usage: const [ref, inView] = useIntersectionObserver(options);\r\n */\r\nexport function useIntersectionObserver<T extends HTMLElement = HTMLElement>(\r\n options?: IntersectionOptions\r\n): [React.RefObject<T>, boolean] {\r\n const [inView, setInView] = useState(false);\r\n const ref = useState<React.RefObject<T>>(() => ({ current: null }))[0];\r\n\r\n useEffect(() => {\r\n const node = ref.current;\r\n if (!node || typeof window === \"undefined\" || !(\"IntersectionObserver\" in window)) {\r\n setInView(true); // Fallback: always load if no observer\r\n return;\r\n }\r\n\r\n let frozen = false;\r\n const observer = new IntersectionObserver(\r\n ([entry]) => {\r\n if (entry.isIntersecting) {\r\n setInView(true);\r\n if (options?.freezeOnceVisible) {\r\n frozen = true;\r\n observer.disconnect();\r\n }\r\n } else if (!frozen) {\r\n setInView(false);\r\n }\r\n },\r\n options\r\n );\r\n\r\n observer.observe(node);\r\n\r\n return () => {\r\n observer.disconnect();\r\n };\r\n }, [ref, options]);\r\n\r\n return [ref, inView];\r\n}"],"names":[],"mappings":";;AAMA;;;;AAIG;AACG,SAAU,uBAAuB,CACrC,OAA6B,EAAA;IAE7B,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;AAC3C,IAAA,MAAM,GAAG,GAAG,QAAQ,CAAqB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtE,SAAS,CAAC,MAAK;AACb,QAAA,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO;AACxB,QAAA,IAAI,CAAC,IAAI,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,EAAE,sBAAsB,IAAI,MAAM,CAAC,EAAE;AACjF,YAAA,SAAS,CAAC,IAAI,CAAC,CAAC;YAChB;QACF;QAEA,IAAI,MAAM,GAAG,KAAK;QAClB,MAAM,QAAQ,GAAG,IAAI,oBAAoB,CACvC,CAAC,CAAC,KAAK,CAAC,KAAI;AACV,YAAA,IAAI,KAAK,CAAC,cAAc,EAAE;gBACxB,SAAS,CAAC,IAAI,CAAC;AACf,gBAAA,IAAI,OAAO,EAAE,iBAAiB,EAAE;oBAC9B,MAAM,GAAG,IAAI;oBACb,QAAQ,CAAC,UAAU,EAAE;gBACvB;YACF;iBAAO,IAAI,CAAC,MAAM,EAAE;gBAClB,SAAS,CAAC,KAAK,CAAC;YAClB;QACF,CAAC,EACD,OAAO,CACR;AAED,QAAA,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;AAEtB,QAAA,OAAO,MAAK;YACV,QAAQ,CAAC,UAAU,EAAE;AACvB,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAElB,IAAA,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC;AACtB;;;;"}
package/dist/index.d.ts CHANGED
@@ -36,6 +36,7 @@ export * from './hooks/useDebounce';
36
36
  export * from './hooks/useLocalStorage';
37
37
  export * from './hooks/useToggle';
38
38
  export * from './hooks/useBreakpoint';
39
+ export * from './hooks/useIntersectionObserver';
39
40
  export * from './utils/cn';
40
41
  export * from './theme/default';
41
42
  export * from './contexts/AuthContext';
package/dist/index.js CHANGED
@@ -64,6 +64,7 @@ export { useDebounce } from './hooks/useDebounce.js';
64
64
  export { useLocalStorage } from './hooks/useLocalStorage.js';
65
65
  export { useToggle } from './hooks/useToggle.js';
66
66
  export { useBreakpoint } from './hooks/useBreakpoint.js';
67
+ export { useIntersectionObserver } from './hooks/useIntersectionObserver.js';
67
68
  export { cn } from './utils/cn.js';
68
69
  export { defaultTheme } from './theme/default.js';
69
70
  export { AuthProvider, useAuth } from './contexts/AuthContext.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beyondcorp/beyond-ui",
3
- "version": "1.2.65",
3
+ "version": "1.2.69",
4
4
  "description": "A comprehensive React UI component library built with TypeScript, TailwindCSS, and CVA",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",