periplo-ui 3.61.1 → 3.63.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.
@@ -32,8 +32,11 @@ const InputDate = React.forwardRef(
32
32
  };
33
33
  const handleMaskedChange = (newValue) => {
34
34
  setInternalValue(newValue);
35
+ const [day, month, year] = newValue.split("/");
36
+ const externalValue = `${year}-${month}-${day}`;
37
+ console.log(externalValue);
35
38
  controlledOnChange?.({
36
- target: { value: newValue }
39
+ target: { value: externalValue }
37
40
  });
38
41
  };
39
42
  const handleClear = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"InputDate.js","sources":["../../../src/components/InputDate/InputDate.tsx"],"sourcesContent":["import { CalendarBlank } from '@phosphor-icons/react/dist/ssr/CalendarBlank'\nimport { WarningCircle } from '@phosphor-icons/react/dist/ssr/WarningCircle'\nimport { X } from '@phosphor-icons/react/dist/ssr/X'\nimport * as React from 'react'\n\nimport { type DateInputFormat } from './manualDateFormat'\nimport { MaskedInput } from './MaskedInput'\n\nimport { cn } from '@/lib/utils'\n\nexport type InputDateProps = {\n className?: string\n endContent?: React.ReactElement\n disabled?: boolean\n error?: boolean | string\n errorMessage?: string\n inputClassName?: string\n inputFormat?: DateInputFormat\n onClear?: boolean | (() => void)\n value?: string\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'type'>\n\nconst InputDate = React.forwardRef<HTMLInputElement, InputDateProps>(\n (\n {\n className,\n endContent,\n disabled,\n error,\n errorMessage,\n value: controlledValue,\n onChange: controlledOnChange,\n inputClassName,\n onClear = true,\n inputFormat,\n 'aria-invalid': ariaInvalid,\n ...props\n },\n ref,\n ) => {\n const [internalValue, setInternalValue] = React.useState(controlledValue ?? '')\n const [isHovered, setIsHovered] = React.useState(false)\n\n React.useEffect(() => {\n setInternalValue(controlledValue ?? '')\n }, [controlledValue])\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setInternalValue(event.target.value)\n controlledOnChange?.(event)\n }\n\n const handleMaskedChange = (newValue: string) => {\n setInternalValue(newValue)\n controlledOnChange?.({\n target: { value: newValue },\n } as React.ChangeEvent<HTMLInputElement>)\n }\n\n const handleClear = () => {\n handleChange({ target: { value: '' } } as React.ChangeEvent<HTMLInputElement>)\n if (typeof onClear === 'function') onClear()\n }\n\n const hasValue = Boolean(internalValue && internalValue.trim() !== '')\n const showClearIcon = Boolean(onClear && hasValue && isHovered && !disabled)\n const resolvedErrorMessage = typeof error === 'string' ? error : errorMessage\n const hasError = Boolean(error ?? resolvedErrorMessage)\n\n const renderCalendarIcon = () => <CalendarBlank size={20} />\n\n const renderErrorIcon = () => {\n if (!hasError) return null\n return (\n <div>\n <WarningCircle\n data-testid=\"exclaim-icon\"\n className={cn(\n 'text-error-500 transition-opacity duration-150',\n showClearIcon ? 'opacity-0' : 'opacity-100',\n )}\n size={18}\n />\n </div>\n )\n }\n\n const renderClearIcon = () => {\n if (disabled || !onClear) return null\n return (\n <div\n className={cn(\n 'absolute right-3 z-10 flex h-full w-10 items-center justify-end rounded-r-lg',\n endContent || error\n ? 'bg-transparent'\n : 'bg-gradient-to-l from-white from-60% via-white/80 via-80% to-transparent transition-opacity duration-150',\n showClearIcon ? 'opacity-100' : 'opacity-0',\n )}\n >\n <X\n data-testid=\"clear-button\"\n className={cn(\n 'h-4 w-4 shrink-0 cursor-pointer transition-opacity duration-150',\n showClearIcon ? 'opacity-100 hover:opacity-70' : 'opacity-0',\n )}\n onClick={handleClear}\n />\n </div>\n )\n }\n\n return (\n <div className=\"flex w-full flex-col gap-1\">\n <div className=\"flex w-full items-center\">\n <label\n data-testid=\"input-date-mask-control\"\n className={cn(\n 'relative flex h-12 w-full items-center rounded-lg border border-neutral-200 bg-white px-3 transition-colors focus-within:border-neutral-950',\n disabled && 'bg-neutral-50',\n hasError && 'border-error-400 focus-within:border-error-700',\n className,\n )}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {renderCalendarIcon()}\n <MaskedInput\n ref={ref}\n inputFormat={inputFormat}\n placeholder={inputFormat}\n aria-invalid={ariaInvalid ?? hasError}\n disabled={disabled}\n value={internalValue}\n onChange={handleMaskedChange}\n className={cn(\n 'w-full bg-transparent px-2 outline-0 transition-colors placeholder:text-neutral-300 disabled:cursor-not-allowed disabled:opacity-50',\n inputClassName,\n )}\n {...props}\n />\n {renderErrorIcon()}\n {renderClearIcon()}\n </label>\n </div>\n {resolvedErrorMessage && <span className=\"text-error-500 text-sm\">{resolvedErrorMessage}</span>}\n </div>\n )\n },\n)\n\nInputDate.displayName = 'InputDate'\n\nexport { InputDate }\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InputDate.js","sources":["../../../src/components/InputDate/InputDate.tsx"],"sourcesContent":["import { CalendarBlank } from '@phosphor-icons/react/dist/ssr/CalendarBlank'\nimport { WarningCircle } from '@phosphor-icons/react/dist/ssr/WarningCircle'\nimport { X } from '@phosphor-icons/react/dist/ssr/X'\nimport * as React from 'react'\n\nimport { type DateInputFormat } from './manualDateFormat'\nimport { MaskedInput } from './MaskedInput'\n\nimport { cn } from '@/lib/utils'\n\nexport type InputDateProps = {\n className?: string\n endContent?: React.ReactElement\n disabled?: boolean\n error?: boolean | string\n errorMessage?: string\n inputClassName?: string\n inputFormat?: DateInputFormat\n onClear?: boolean | (() => void)\n value?: string\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'type'>\n\nconst InputDate = React.forwardRef<HTMLInputElement, InputDateProps>(\n (\n {\n className,\n endContent,\n disabled,\n error,\n errorMessage,\n value: controlledValue,\n onChange: controlledOnChange,\n inputClassName,\n onClear = true,\n inputFormat,\n 'aria-invalid': ariaInvalid,\n ...props\n },\n ref,\n ) => {\n const [internalValue, setInternalValue] = React.useState(controlledValue ?? '')\n const [isHovered, setIsHovered] = React.useState(false)\n\n React.useEffect(() => {\n setInternalValue(controlledValue ?? '')\n }, [controlledValue])\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setInternalValue(event.target.value)\n controlledOnChange?.(event)\n }\n\n const handleMaskedChange = (newValue: string) => {\n setInternalValue(newValue)\n const [day, month, year] = newValue.split('/')\n const externalValue = `${year}-${month}-${day}`\n console.log(externalValue)\n\n controlledOnChange?.({\n target: { value: externalValue },\n } as React.ChangeEvent<HTMLInputElement>)\n }\n\n const handleClear = () => {\n handleChange({ target: { value: '' } } as React.ChangeEvent<HTMLInputElement>)\n if (typeof onClear === 'function') onClear()\n }\n\n const hasValue = Boolean(internalValue && internalValue.trim() !== '')\n const showClearIcon = Boolean(onClear && hasValue && isHovered && !disabled)\n const resolvedErrorMessage = typeof error === 'string' ? error : errorMessage\n const hasError = Boolean(error ?? resolvedErrorMessage)\n\n const renderCalendarIcon = () => <CalendarBlank size={20} />\n\n const renderErrorIcon = () => {\n if (!hasError) return null\n return (\n <div>\n <WarningCircle\n data-testid=\"exclaim-icon\"\n className={cn(\n 'text-error-500 transition-opacity duration-150',\n showClearIcon ? 'opacity-0' : 'opacity-100',\n )}\n size={18}\n />\n </div>\n )\n }\n\n const renderClearIcon = () => {\n if (disabled || !onClear) return null\n return (\n <div\n className={cn(\n 'absolute right-3 z-10 flex h-full w-10 items-center justify-end rounded-r-lg',\n endContent || error\n ? 'bg-transparent'\n : 'bg-gradient-to-l from-white from-60% via-white/80 via-80% to-transparent transition-opacity duration-150',\n showClearIcon ? 'opacity-100' : 'opacity-0',\n )}\n >\n <X\n data-testid=\"clear-button\"\n className={cn(\n 'h-4 w-4 shrink-0 cursor-pointer transition-opacity duration-150',\n showClearIcon ? 'opacity-100 hover:opacity-70' : 'opacity-0',\n )}\n onClick={handleClear}\n />\n </div>\n )\n }\n\n return (\n <div className=\"flex w-full flex-col gap-1\">\n <div className=\"flex w-full items-center\">\n <label\n data-testid=\"input-date-mask-control\"\n className={cn(\n 'relative flex h-12 w-full items-center rounded-lg border border-neutral-200 bg-white px-3 transition-colors focus-within:border-neutral-950',\n disabled && 'bg-neutral-50',\n hasError && 'border-error-400 focus-within:border-error-700',\n className,\n )}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {renderCalendarIcon()}\n <MaskedInput\n ref={ref}\n inputFormat={inputFormat}\n placeholder={inputFormat}\n aria-invalid={ariaInvalid ?? hasError}\n disabled={disabled}\n value={internalValue}\n onChange={handleMaskedChange}\n className={cn(\n 'w-full bg-transparent px-2 outline-0 transition-colors placeholder:text-neutral-300 disabled:cursor-not-allowed disabled:opacity-50',\n inputClassName,\n )}\n {...props}\n />\n {renderErrorIcon()}\n {renderClearIcon()}\n </label>\n </div>\n {resolvedErrorMessage && <span className=\"text-error-500 text-sm\">{resolvedErrorMessage}</span>}\n </div>\n )\n },\n)\n\nInputDate.displayName = 'InputDate'\n\nexport { InputDate }\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ export type StarRatingProps = {
3
+ value: number;
4
+ max?: number;
5
+ size?: 'sm' | 'md' | 'lg';
6
+ allowPartial?: boolean;
7
+ color?: string;
8
+ emptyColor?: string;
9
+ emptyBgColor?: string;
10
+ containerClassName?: string;
11
+ } & Omit<React.ComponentProps<'div'>, 'children'>;
12
+ export declare function StarRating({ value, max, size, allowPartial, color, emptyColor, emptyBgColor, className, containerClassName, ...props }: StarRatingProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,58 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { Star } from '@phosphor-icons/react/dist/ssr/Star';
3
+ import { cn } from '../../lib/utils.js';
4
+
5
+ function StarRating({
6
+ value,
7
+ max = 5,
8
+ size = "lg",
9
+ allowPartial = true,
10
+ color = "#FBBA00",
11
+ emptyColor = "#696963",
12
+ emptyBgColor = "#696963",
13
+ className,
14
+ containerClassName,
15
+ ...props
16
+ }) {
17
+ const safeMax = Math.max(1, Math.floor(max));
18
+ const clampedValue = Math.max(0, Math.min(value, safeMax));
19
+ return /* @__PURE__ */ jsx(
20
+ "div",
21
+ {
22
+ "data-size": size,
23
+ "data-slot": "star-rating",
24
+ className: cn(
25
+ "flex flex-col items-center gap-1.5",
26
+ "data-[size=lg]:[--star-size:calc(var(--spacing)*5)] data-[size=md]:[--star-size:calc(var(--spacing)*4)] data-[size=sm]:[--star-size:calc(var(--spacing)*3)]",
27
+ containerClassName
28
+ ),
29
+ "aria-label": `${clampedValue} out of ${safeMax} stars`,
30
+ role: "img",
31
+ ...props,
32
+ children: /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-0.5", className), children: Array.from({ length: safeMax }).map((_unused, index) => {
33
+ const starIndex = index + 1;
34
+ let filledRatio;
35
+ if (allowPartial) {
36
+ filledRatio = Math.max(0, Math.min(1, clampedValue - index));
37
+ } else {
38
+ filledRatio = clampedValue >= starIndex ? 1 : 0;
39
+ }
40
+ return /* @__PURE__ */ jsxs("span", { className: "relative inline-flex", style: { color: emptyColor }, "aria-hidden": "true", children: [
41
+ emptyBgColor ? /* @__PURE__ */ jsx("span", { className: "absolute inset-0", style: { color: emptyBgColor }, children: /* @__PURE__ */ jsx(Star, { weight: "fill", className: "size-[var(--star-size)]" }) }) : null,
42
+ /* @__PURE__ */ jsx(Star, { className: "size-[var(--star-size)]" }),
43
+ filledRatio > 0 ? /* @__PURE__ */ jsx(
44
+ "span",
45
+ {
46
+ className: "absolute inset-0 overflow-hidden",
47
+ style: { width: `${filledRatio * 100}%`, color },
48
+ children: /* @__PURE__ */ jsx(Star, { weight: "fill", className: "size-[var(--star-size)]" })
49
+ }
50
+ ) : null
51
+ ] }, index);
52
+ }) })
53
+ }
54
+ );
55
+ }
56
+
57
+ export { StarRating };
58
+ //# sourceMappingURL=StarRating.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StarRating.js","sources":["../../../src/components/StarRating/StarRating.tsx"],"sourcesContent":["import { Star } from '@phosphor-icons/react/dist/ssr/Star'\nimport * as React from 'react'\n\nimport { cn } from '../../lib/utils'\n\nexport type StarRatingProps = {\n value: number\n max?: number\n size?: 'sm' | 'md' | 'lg'\n allowPartial?: boolean\n color?: string\n emptyColor?: string\n emptyBgColor?: string\n containerClassName?: string\n} & Omit<React.ComponentProps<'div'>, 'children'>\n\nexport function StarRating({\n value,\n max = 5,\n size = 'lg',\n allowPartial = true,\n color = '#FBBA00',\n emptyColor = '#696963',\n emptyBgColor = '#696963',\n className,\n containerClassName,\n ...props\n}: StarRatingProps) {\n const safeMax = Math.max(1, Math.floor(max))\n const clampedValue = Math.max(0, Math.min(value, safeMax))\n\n return (\n <div\n data-size={size}\n data-slot=\"star-rating\"\n className={cn(\n 'flex flex-col items-center gap-1.5',\n 'data-[size=lg]:[--star-size:calc(var(--spacing)*5)] data-[size=md]:[--star-size:calc(var(--spacing)*4)] data-[size=sm]:[--star-size:calc(var(--spacing)*3)]',\n containerClassName,\n )}\n aria-label={`${clampedValue} out of ${safeMax} stars`}\n role=\"img\"\n {...props}\n >\n <div className={cn('flex items-center gap-0.5', className)}>\n {Array.from({ length: safeMax }).map((_unused, index) => {\n const starIndex = index + 1\n let filledRatio: number\n if (allowPartial) {\n filledRatio = Math.max(0, Math.min(1, clampedValue - index))\n } else {\n filledRatio = clampedValue >= starIndex ? 1 : 0\n }\n\n return (\n <span key={index} className=\"relative inline-flex\" style={{ color: emptyColor }} aria-hidden=\"true\">\n {emptyBgColor ? (\n <span className=\"absolute inset-0\" style={{ color: emptyBgColor }}>\n <Star weight=\"fill\" className=\"size-[var(--star-size)]\" />\n </span>\n ) : null}\n <Star className=\"size-[var(--star-size)]\" />\n {filledRatio > 0 ? (\n <span\n className=\"absolute inset-0 overflow-hidden\"\n style={{ width: `${filledRatio * 100}%`, color: color }}\n >\n <Star weight=\"fill\" className=\"size-[var(--star-size)]\" />\n </span>\n ) : null}\n </span>\n )\n })}\n </div>\n </div>\n )\n}\n"],"names":[],"mappings":";;;;AAgBO,SAAS,UAAA,CAAW;AAAA,EACzB,KAAA;AAAA,EACA,GAAA,GAAM,CAAA;AAAA,EACN,IAAA,GAAO,IAAA;AAAA,EACP,YAAA,GAAe,IAAA;AAAA,EACf,KAAA,GAAQ,SAAA;AAAA,EACR,UAAA,GAAa,SAAA;AAAA,EACb,YAAA,GAAe,SAAA;AAAA,EACf,SAAA;AAAA,EACA,kBAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAoB;AAClB,EAAA,MAAM,UAAU,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA;AAC3C,EAAA,MAAM,YAAA,GAAe,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,KAAA,EAAO,OAAO,CAAC,CAAA;AAEzD,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAW,IAAA;AAAA,MACX,WAAA,EAAU,aAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,oCAAA;AAAA,QACA,6JAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,YAAA,EAAY,CAAA,EAAG,YAAY,CAAA,QAAA,EAAW,OAAO,CAAA,MAAA,CAAA;AAAA,MAC7C,IAAA,EAAK,KAAA;AAAA,MACJ,GAAG,KAAA;AAAA,MAEJ,8BAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,2BAAA,EAA6B,SAAS,CAAA,EACtD,QAAA,EAAA,KAAA,CAAM,IAAA,CAAK,EAAE,QAAQ,OAAA,EAAS,EAAE,GAAA,CAAI,CAAC,SAAS,KAAA,KAAU;AACvD,QAAA,MAAM,YAAY,KAAA,GAAQ,CAAA;AAC1B,QAAA,IAAI,WAAA;AACJ,QAAA,IAAI,YAAA,EAAc;AAChB,UAAA,WAAA,GAAc,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAG,YAAA,GAAe,KAAK,CAAC,CAAA;AAAA,SAC7D,MAAO;AACL,UAAA,WAAA,GAAc,YAAA,IAAgB,YAAY,CAAA,GAAI,CAAA;AAAA;AAGhD,QAAA,uBACE,IAAA,CAAC,MAAA,EAAA,EAAiB,SAAA,EAAU,sBAAA,EAAuB,KAAA,EAAO,EAAE,KAAA,EAAO,UAAA,EAAW,EAAG,aAAA,EAAY,MAAA,EAC1F,QAAA,EAAA;AAAA,UAAA,YAAA,uBACE,MAAA,EAAA,EAAK,SAAA,EAAU,kBAAA,EAAmB,KAAA,EAAO,EAAE,KAAA,EAAO,YAAA,EAAa,EAC9D,QAAA,kBAAA,GAAA,CAAC,QAAK,MAAA,EAAO,MAAA,EAAO,SAAA,EAAU,yBAAA,EAA0B,GAC1D,CAAA,GACE,IAAA;AAAA,0BACJ,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,yBAAA,EAA0B,CAAA;AAAA,UACzC,cAAc,CAAA,mBACb,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,kCAAA;AAAA,cACV,OAAO,EAAE,KAAA,EAAO,GAAG,WAAA,GAAc,GAAG,KAAK,KAAA,EAAa;AAAA,cAEtD,QAAA,kBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,MAAA,EAAO,MAAA,EAAO,WAAU,yBAAA,EAA0B;AAAA;AAAA,WAC1D,GACE;AAAA,SAAA,EAAA,EAdK,KAeX,CAAA;AAAA,OAEH,CAAA,EACH;AAAA;AAAA,GACF;AAEJ;;;;"}
@@ -0,0 +1 @@
1
+ export * from './StarRating';
@@ -0,0 +1,2 @@
1
+ export { StarRating } from './StarRating.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/dist/index.d.ts CHANGED
@@ -31,6 +31,7 @@ export * from './components/Separator';
31
31
  export * from './components/Sheet';
32
32
  export * from './components/Sidebar';
33
33
  export * from './components/Skeleton';
34
+ export * from './components/StarRating';
34
35
  export * from './components/Table';
35
36
  export * from './components/Tabs';
36
37
  export * from './components/Textarea';
package/dist/index.js CHANGED
@@ -35,6 +35,7 @@ export { Separator } from './components/Separator/Separator.js';
35
35
  export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetRoot, SheetTitle, SheetTrigger } from './components/Sheet/Sheet.js';
36
36
  export { SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarRoot, SidebarSeparator, SidebarTrigger, useSidebar } from './components/Sidebar/Sidebar.js';
37
37
  export { Skeleton } from './components/Skeleton/Skeleton.js';
38
+ export { StarRating } from './components/StarRating/StarRating.js';
38
39
  export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from './components/Table/Table.js';
39
40
  export { Tabs, TabsContent, TabsLink, TabsList, TabsTrigger } from './components/Tabs/Tabs.js';
40
41
  export { Textarea } from './components/Textarea/Textarea.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "periplo-ui",
3
3
  "description": "IATI UI library",
4
4
  "private": false,
5
- "version": "3.61.1",
5
+ "version": "3.63.0",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "types": "dist/index.d.ts",