maquinaweb-ui 2.20.0 → 2.22.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/container-animation.d.ts +2 -2
- package/dist/input-suggest.d.ts +2 -2
- package/dist/remote-selector.d.ts +3 -2
- package/dist/remote-selector.d.ts.map +1 -1
- package/dist/remote-selector.js +36 -12
- package/dist/remote-selector.js.map +1 -1
- package/dist/text-field.d.ts +5 -5
- package/dist/toggle-field.d.ts +7 -6
- package/dist/toggle-field.d.ts.map +1 -1
- package/dist/toggle-field.js +14 -7
- package/dist/toggle-field.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentProps, ElementType } from "react";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime4 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/container-animation/container-animation.d.ts
|
|
5
5
|
type ContainerAnimationProps<T extends ElementType = 'div'> = ComponentProps<'div'> & ComponentProps<T> & {
|
|
@@ -23,7 +23,7 @@ declare const ContainerAnimation: <T extends ElementType = "div">({
|
|
|
23
23
|
distance,
|
|
24
24
|
hideNotInView,
|
|
25
25
|
...props
|
|
26
|
-
}: ContainerAnimationProps<T>) =>
|
|
26
|
+
}: ContainerAnimationProps<T>) => react_jsx_runtime4.JSX.Element;
|
|
27
27
|
//#endregion
|
|
28
28
|
export { ContainerAnimation, type ContainerAnimationProps };
|
|
29
29
|
//# sourceMappingURL=container-animation.d.ts.map
|
package/dist/input-suggest.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FieldPath, FieldValues, UseControllerProps } from "react-hook-form";
|
|
2
2
|
import { Dispatch, SetStateAction } from "react";
|
|
3
|
-
import * as
|
|
3
|
+
import * as react_jsx_runtime3 from "react/jsx-runtime";
|
|
4
4
|
import { Mask, Options } from "use-mask-input";
|
|
5
5
|
import { PopoverProps } from "@radix-ui/react-popover";
|
|
6
6
|
|
|
@@ -64,7 +64,7 @@ declare function InputSuggest<TFieldValues extends FieldValues = FieldValues, TF
|
|
|
64
64
|
children,
|
|
65
65
|
initialParams,
|
|
66
66
|
...props
|
|
67
|
-
}: InputSuggestProps<TFieldValues, TFieldName> & PopoverProps):
|
|
67
|
+
}: InputSuggestProps<TFieldValues, TFieldName> & PopoverProps): react_jsx_runtime3.JSX.Element;
|
|
68
68
|
//#endregion
|
|
69
69
|
export { InputSuggest, type InputSuggestProps };
|
|
70
70
|
//# sourceMappingURL=input-suggest.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ControllerFieldState } from "react-hook-form";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime5 from "react/jsx-runtime";
|
|
3
3
|
import { PopoverProps } from "@radix-ui/react-popover";
|
|
4
4
|
|
|
5
5
|
//#region src/components/ui/selector.d.ts
|
|
@@ -14,6 +14,7 @@ type SelectorProps<T> = {
|
|
|
14
14
|
items: T[];
|
|
15
15
|
fieldLabel: keyof T;
|
|
16
16
|
fieldKey?: keyof T;
|
|
17
|
+
groupBy?: keyof T;
|
|
17
18
|
disabled?: boolean;
|
|
18
19
|
searchPlaceholder?: string;
|
|
19
20
|
label?: string;
|
|
@@ -46,7 +47,7 @@ declare function RemoteSelector<T>({
|
|
|
46
47
|
initialRequest,
|
|
47
48
|
forceToggle,
|
|
48
49
|
...props
|
|
49
|
-
}: RemoteSelectorProps<T>):
|
|
50
|
+
}: RemoteSelectorProps<T>): react_jsx_runtime5.JSX.Element;
|
|
50
51
|
//#endregion
|
|
51
52
|
export { RemoteSelector, type RemoteSelectorProps, type TUseData };
|
|
52
53
|
//# sourceMappingURL=remote-selector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-selector.d.ts","names":[],"sources":["../src/components/ui/selector.tsx","../src/components/remote-selector/remote-selector.tsx"],"sourcesContent":[],"mappings":";;;;;;AAmCoB,KAFR,aAEQ,CAAA,CAAA,CAAA,GAAA;OAIV,CAAA,EALA,CAKM;UACP,CAAA,EAAA,CAAA,IAAA,EALW,CAKX,GAAA,SAAA,GAAA,IAAA,EAAA,GAAA,IAAA;QACW,CAAA,EAAA,MAAA;UACD,CAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,GAAA,IAAA;
|
|
1
|
+
{"version":3,"file":"remote-selector.d.ts","names":[],"sources":["../src/components/ui/selector.tsx","../src/components/remote-selector/remote-selector.tsx"],"sourcesContent":[],"mappings":";;;;;;AAmCoB,KAFR,aAEQ,CAAA,CAAA,CAAA,GAAA;OAIV,CAAA,EALA,CAKM;UACP,CAAA,EAAA,CAAA,IAAA,EALW,CAKX,GAAA,SAAA,GAAA,IAAA,EAAA,GAAA,IAAA;QACW,CAAA,EAAA,MAAA;UACD,CAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,GAAA,IAAA;aACD,CAAA,EAAA,MAAA;OAOH,CAAA,EAXL,KAAA,CAAM,SAWD;OAKO,EAfb,CAea,EAAA;YACf,EAAA,MAfa,CAeb;UAIH,CAAA,EAAA,MAlBe,CAkBf;EAAY,OAAA,CAAA,EAAA,MAjBE,CAiBF;;;;ECnDJ,IAAA,EAAA,MAAQ;EAQR,SAAA,CAAA,EAAA,MAAA;EAAmB,QAAA,CAAA,EAAA,OAAA;YACX,CAAA,EDgCL,oBChCK;kBAAT,CAAA,EAAA,OAAA;MAC2B,CAAA,EAAA,MAAA;OAAT,CAAA,EAAA,MAAA;cAAX,CAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,IAAA,EDoCI,CCpCJ,GAAA,SAAA,GAAA,IAAA,EAAA,GAAA,IAAA,EAAA,GDqCX,OCrCW,CAAA,IAAA,CAAA,GAAA,IAAA;MAGK,CAAA,EAAA,OAAA;SAAd,CAAA,EAAA,CAAA,IAAA,EAAA,OAAA,EAAA,GAAA,IAAA;YAAL,CAAA,EAAA,OAAA;CAAI,GDsCJ,YCtCI;;;KAbI;QAKJ;;KAGI;EDgBA,OAAA,ECfD,QDec,CCfL,CDeK,CAAA;EAAA,aAAA,CAAA,ECdP,UDcO,CCdI,QDcJ,CCda,CDcb,CAAA,CAAA,CAAA,CAAA,CAAA;gBACf,CAAA,EAAA,OAAA;aACU,CAAA,EAAA,OAAA;ICbhB,IDiBM,CCjBD,aDiBO,CCjBO,CDiBP,CAAA,EAAA,OAAA,CAAA;AACP,iBChBO,cDgBP,CAAA,CAAA,CAAA,CAAA;EAAA,OAAA;EAAA,aAAA;EAAA,cAAA;EAAA,WAAA;EAAA,GAAA;AAAA,CAAA,ECVN,mBDUM,CCVc,CDUd,CAAA,CAAA,ECVgB,kBAAA,CAAA,GAAA,CAAA,ODUhB"}
|
package/dist/remote-selector.js
CHANGED
|
@@ -6,7 +6,7 @@ import "./label-BqtcCyMj.js";
|
|
|
6
6
|
import { FormItem, FormLabel, FormMessage, InputHelp } from "./input-help-C9Himejv.js";
|
|
7
7
|
import { Popover, PopoverContent, PopoverTrigger, ScrollBar } from "./scroll-area-C2WadzN5.js";
|
|
8
8
|
import { useController, useFormContext } from "react-hook-form";
|
|
9
|
-
import { createElement, useEffect, useState } from "react";
|
|
9
|
+
import { createElement, useEffect, useMemo, useState } from "react";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
import { Check, ChevronsUpDown, SearchIcon, X } from "lucide-react";
|
|
12
12
|
import { cva } from "class-variance-authority";
|
|
@@ -101,11 +101,32 @@ function CommandItem({ className,...props }) {
|
|
|
101
101
|
|
|
102
102
|
//#endregion
|
|
103
103
|
//#region src/components/ui/selector.tsx
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
const DEFAULT_GROUP_ID = "selector-default-group";
|
|
105
|
+
const UNDEFINED_GROUP_ID = "selector-undefined-group";
|
|
106
|
+
const buildGroups = (items, groupBy) => {
|
|
107
|
+
if (!groupBy) return [{
|
|
108
|
+
id: DEFAULT_GROUP_ID,
|
|
109
|
+
items
|
|
110
|
+
}];
|
|
111
|
+
return Object.values(items.reduce((acc, item) => {
|
|
112
|
+
const rawValue = item[groupBy];
|
|
113
|
+
const heading = rawValue == null ? void 0 : String(rawValue);
|
|
114
|
+
const groupId = heading ?? UNDEFINED_GROUP_ID;
|
|
115
|
+
if (!acc[groupId]) acc[groupId] = {
|
|
116
|
+
id: groupId,
|
|
117
|
+
heading,
|
|
118
|
+
items: []
|
|
119
|
+
};
|
|
120
|
+
acc[groupId].items.push(item);
|
|
121
|
+
return acc;
|
|
122
|
+
}, {}));
|
|
123
|
+
};
|
|
124
|
+
function Selector({ value, onChange, search, onSearch, items, label, placeholder, fieldLabel, fieldKey, groupBy, searchPlaceholder, name, empty = "Nenhuma opção encontrada...", disabled = false, className, required, fieldState, selectFirstIsOne, help, extra, extraOnClick, open, setOpen, withPortal = true,...props }) {
|
|
125
|
+
const itemKey = fieldKey || fieldLabel;
|
|
106
126
|
useEffect(() => {
|
|
107
127
|
if (selectFirstIsOne && items && items.length === 1 && !value) onChange?.(items[0]);
|
|
108
128
|
}, [items]);
|
|
129
|
+
const groups = useMemo(() => buildGroups(items, groupBy), [groupBy, items]);
|
|
109
130
|
return /* @__PURE__ */ jsxs(FormItem, {
|
|
110
131
|
className: cn("w-full", className),
|
|
111
132
|
id: `selector-${name}`,
|
|
@@ -179,15 +200,18 @@ function Selector({ value, onChange, search, onSearch, items, label, placeholder
|
|
|
179
200
|
className: "text-sm p-3 text-foreground/60",
|
|
180
201
|
children: empty
|
|
181
202
|
}),
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
203
|
+
groups.map((group) => /* @__PURE__ */ jsx(CommandGroup, {
|
|
204
|
+
heading: group.heading || group.id === UNDEFINED_GROUP_ID && "Outros",
|
|
205
|
+
children: group.items.map((item) => /* @__PURE__ */ jsxs(CommandItem, {
|
|
206
|
+
className: cn("transition-all p-2", value === item && "bg-accent! text-accent-foreground"),
|
|
207
|
+
onSelect: () => {
|
|
208
|
+
onChange?.(item);
|
|
209
|
+
setOpen?.(false);
|
|
210
|
+
},
|
|
211
|
+
value: String(item[itemKey]),
|
|
212
|
+
children: [item[fieldLabel], value === item && /* @__PURE__ */ jsx(Check, { className: "ml-auto h-4 w-4" })]
|
|
213
|
+
}, `item-${item[itemKey]}`))
|
|
214
|
+
}, `group-${group.id}`)),
|
|
191
215
|
extra && /* @__PURE__ */ jsx(CommandItem, {
|
|
192
216
|
className: cn("transition-all p-2 sticky bottom-0 bg-white hover:!bg-accent aria-selected:!bg-accent"),
|
|
193
217
|
onSelect: () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-selector.js","names":["Command","CommandPrimitive","Command"],"sources":["../src/components/ui/button.tsx","../src/components/ui/command.tsx","../src/components/ui/selector.tsx","../src/components/remote-selector/remote-selector.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '@/lib/utils';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive:\n 'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',\n outline:\n 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost:\n 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2 has-[>svg]:px-3',\n sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',\n lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',\n icon: 'size-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<'button'> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n data-slot=\"button\"\n {...(props as any)}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","'use client';\n\nimport * as React from 'react';\n\nimport { SearchIcon } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nfunction Command({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n className={cn(\n 'bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md',\n className\n )}\n data-slot=\"command\"\n {...props}\n />\n );\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n <div\n className=\"flex h-9 items-center gap-2 border-b px-3\"\n data-slot=\"command-input-wrapper\"\n >\n <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n <CommandPrimitive.Input\n className={cn(\n 'placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n data-slot=\"command-input\"\n {...props}\n />\n </div>\n );\n}\n\nfunction CommandList({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n className={cn(\n 'max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto',\n className\n )}\n data-slot=\"command-list\"\n {...props}\n />\n );\n}\n\nfunction CommandEmpty({\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n className=\"py-6 text-center text-sm\"\n data-slot=\"command-empty\"\n {...props}\n />\n );\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n className={cn(\n 'text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium',\n className\n )}\n data-slot=\"command-group\"\n {...props}\n />\n );\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n className={cn('bg-border -mx-1 h-px', className)}\n data-slot=\"command-separator\"\n {...props}\n />\n );\n}\n\nfunction CommandItem({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n className={cn(\n \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n data-slot=\"command-item\"\n {...props}\n />\n );\n}\n\nfunction CommandShortcut({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n className={cn(\n 'text-muted-foreground ml-auto text-xs tracking-widest',\n className\n )}\n data-slot=\"command-shortcut\"\n {...props}\n />\n );\n}\n\nexport {\n Command,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n};\n","'use client';\n\nimport { useEffect } from 'react';\n\nimport type { ControllerFieldState } from 'react-hook-form';\n\nimport type { PopoverProps } from '@radix-ui/react-popover';\nimport { ScrollArea, ScrollAreaViewport } from '@radix-ui/react-scroll-area';\n\nimport { Check, ChevronsUpDown, X } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from './button';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from './command';\nimport { FormItem, FormLabel, FormMessage } from './form';\nimport { InputHelp } from './input-help';\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\nimport { ScrollBar } from './scroll-area';\n\nexport type SelectorOption = {\n id: string | number;\n name: string;\n value?: any;\n children?: SelectorOption[];\n};\n\nexport type SelectorProps<T> = {\n value?: T;\n onChange?: (item: T | undefined | null) => void;\n search?: string;\n onSearch?: (search: string) => void;\n placeholder?: string;\n empty?: React.ReactNode;\n items: T[];\n fieldLabel: keyof T;\n fieldKey?: keyof T;\n disabled?: boolean;\n searchPlaceholder?: string;\n label?: string;\n name: string;\n className?: string;\n required?: boolean;\n fieldState?: ControllerFieldState;\n selectFirstIsOne?: boolean;\n help?: string;\n extra?: string;\n extraOnClick?: (\n onChange?: (item: T | undefined | null) => void\n ) => Promise<void> | void;\n open?: boolean;\n setOpen?: (open: boolean) => void;\n withPortal?: boolean;\n} & PopoverProps;\n\nexport function Selector<T>({\n value,\n onChange,\n search,\n onSearch,\n items,\n label,\n placeholder,\n fieldLabel,\n fieldKey,\n searchPlaceholder,\n name,\n empty = 'Nenhuma opção encontrada...',\n disabled = false,\n className,\n required,\n fieldState,\n selectFirstIsOne,\n help,\n extra,\n extraOnClick,\n open,\n setOpen,\n withPortal = true,\n ...props\n}: SelectorProps<T>) {\n const key = fieldKey || fieldLabel;\n\n useEffect(() => {\n if (selectFirstIsOne && items && items.length === 1 && !value) {\n onChange?.(items[0] as any);\n }\n }, [items]);\n\n return (\n <FormItem className={cn('w-full', className)} id={`selector-${name}`}>\n <div className=\"flex items-end gap-1.5\">\n <FormLabel htmlFor={name}>\n {label}:\n {required && (\n <span className=\"text-red-500 text-lg leading-[1px]\">*</span>\n )}\n </FormLabel>\n\n <InputHelp help={help} name={name} />\n </div>\n <Popover onOpenChange={setOpen} open={open} {...props}>\n <PopoverTrigger asChild>\n <Button\n aria-expanded={open}\n aria-label=\"Carregando opções...\"\n className={cn(\n 'mt-0! justify-between w-full h-10! hover:bg-transparent cursor-pointer',\n !value && 'text-muted-foreground',\n fieldState?.error && 'border-destructive'\n )}\n disabled={disabled}\n id={name}\n role=\"combobox\"\n variant=\"outline\"\n >\n <span className=\"truncate\">\n {value\n ? (value[fieldLabel] as string)\n : placeholder || `Selecione a ${label?.toLowerCase()}`}\n </span>\n <div className=\"flex items-center\">\n <div className=\"relative size-4\">\n {value !== undefined && (\n <div\n className=\"absolute left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onChange?.(null);\n }}\n >\n <X className=\"size-4\" />\n </div>\n )}\n </div>\n <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </div>\n </Button>\n </PopoverTrigger>\n {fieldState?.error && <FormMessage />}\n <PopoverContent className=\"w-(--radix-popover-trigger-width) max-w-2xl p-0\">\n <Command shouldFilter={false}>\n <CommandInput\n onValueChange={onSearch}\n placeholder={\n searchPlaceholder || `Pesquise por uma ${label?.toLowerCase()}`\n }\n value={search}\n />\n <CommandList>\n <ScrollArea className=\"h-fit max-h-[300px]\" id=\"scroll\">\n <ScrollAreaViewport className=\"w-full h-fit max-h-[300px] relative\">\n <CommandEmpty className=\"text-sm p-3 text-foreground/60\">\n {empty}\n </CommandEmpty>\n <CommandGroup>\n {items.map((item) => (\n <CommandItem\n className={cn(\n 'transition-all p-2',\n value === item && 'bg-accent! text-accent-foreground'\n )}\n key={`item-${item[key]}`}\n onSelect={() => {\n onChange?.(item);\n setOpen?.(false);\n }}\n value={String(item[key])}\n >\n {item[fieldLabel] as string}\n {value === item && (\n <Check className=\"ml-auto h-4 w-4\" />\n )}\n </CommandItem>\n ))}\n </CommandGroup>\n {extra && (\n <CommandItem\n className={cn(\n 'transition-all p-2 sticky bottom-0 bg-white hover:!bg-accent aria-selected:!bg-accent'\n )}\n onSelect={() => {\n extraOnClick?.(onChange);\n setOpen?.(false);\n }}\n >\n {extra}\n </CommandItem>\n )}\n </ScrollAreaViewport>\n <ScrollBar />\n </ScrollArea>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </FormItem>\n );\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\n\nimport { useController, useFormContext } from 'react-hook-form';\nimport { useDebounce } from 'use-debounce';\n\nimport { Selector, SelectorProps } from '../ui/selector';\n\nexport type TUseData<T> = (\n search?: string,\n initialParams?: any,\n disabled?: boolean\n) => {\n data: T[];\n};\n\nexport type RemoteSelectorProps<T> = {\n useData: TUseData<T>;\n initialParams?: Parameters<TUseData<T>>[1];\n initialRequest?: boolean;\n forceToggle?: boolean;\n} & Omit<SelectorProps<T>, 'items'>;\n\nexport function RemoteSelector<T>({\n useData,\n initialParams,\n initialRequest = false,\n forceToggle = false,\n ...props\n}: RemoteSelectorProps<T>) {\n type TItem = NonNullable<ReturnType<TUseData<T>>['data']>[number];\n\n const { control } = useFormContext();\n const { field, fieldState } = useController({\n control,\n name: props.name,\n });\n\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState('');\n const [searchDebounced] = useDebounce(search, 100, {\n maxWait: 200,\n });\n const { data } = useData(\n searchDebounced,\n initialParams,\n !open && !initialRequest\n );\n\n useEffect(() => {\n setOpen(forceToggle);\n }, [forceToggle]);\n\n return (\n <Selector\n {...props}\n fieldState={fieldState}\n items={data as TItem[]}\n key={`selector-${field.name}-${field.value}`}\n onChange={(value: any) => {\n field.onChange(value as TItem);\n }}\n onSearch={setSearch}\n open={open}\n search={search}\n setOpen={setOpen}\n value={field.value as TItem}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAOA,MAAM,iBAAiB,IACrB,+bACA;CACE,UAAU;EACR,SAAS;GACP,SAAS;GACT,aACE;GACF,SACE;GACF,WACE;GACF,OACE;GACF,MAAM;GACP;EACD,MAAM;GACJ,SAAS;GACT,IAAI;GACJ,IAAI;GACJ,MAAM;GACP;EACF;CACD,iBAAiB;EACf,SAAS;EACT,MAAM;EACP;CACF,CACF;AAED,SAAS,OAAO,EACd,WACA,SACA,MACA,UAAU,MACV,GAAG,SAIA;AAGH,QACE,oBAHW,UAAU,OAAO;EAI1B,WAAW,GAAG,eAAe;GAAE;GAAS;GAAM;GAAW,CAAC,CAAC;EAC3D,aAAU;EACV,GAAK;GACL;;;;;AC7CN,SAASA,UAAQ,EACf,UACA,GAAG,SAC6C;AAChD,QACE,oBAACC;EACC,WAAW,GACT,6FACA,UACD;EACD,aAAU;EACV,GAAI;GACJ;;AAIN,SAAS,aAAa,EACpB,UACA,GAAG,SACmD;AACtD,QACE,qBAAC;EACC,WAAU;EACV,aAAU;aAEV,oBAAC,cAAW,WAAU,+BAA+B,EACrD,oBAACA,QAAiB;GAChB,WAAW,GACT,4JACA,UACD;GACD,aAAU;GACV,GAAI;IACJ;GACE;;AAIV,SAAS,YAAY,EACnB,UACA,GAAG,SACkD;AACrD,QACE,oBAACA,QAAiB;EAChB,WAAW,GACT,+DACA,UACD;EACD,aAAU;EACV,GAAI;GACJ;;AAIN,SAAS,aAAa,EACpB,GAAG,SACmD;AACtD,QACE,oBAACA,QAAiB;EAChB,WAAU;EACV,aAAU;EACV,GAAI;GACJ;;AAIN,SAAS,aAAa,EACpB,UACA,GAAG,SACmD;AACtD,QACE,oBAACA,QAAiB;EAChB,WAAW,GACT,0NACA,UACD;EACD,aAAU;EACV,GAAI;GACJ;;AAiBN,SAAS,YAAY,EACnB,UACA,GAAG,SACkD;AACrD,QACE,oBAACA,QAAiB;EAChB,WAAW,GACT,uYACA,UACD;EACD,aAAU;EACV,GAAI;GACJ;;;;;ACvDN,SAAgB,SAAY,EAC1B,OACA,UACA,QACA,UACA,OACA,OACA,aACA,YACA,UACA,mBACA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"}
|
|
1
|
+
{"version":3,"file":"remote-selector.js","names":["Command","CommandPrimitive","Command"],"sources":["../src/components/ui/button.tsx","../src/components/ui/command.tsx","../src/components/ui/selector.tsx","../src/components/remote-selector/remote-selector.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '@/lib/utils';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive:\n 'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',\n outline:\n 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost:\n 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2 has-[>svg]:px-3',\n sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',\n lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',\n icon: 'size-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<'button'> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n data-slot=\"button\"\n {...(props as any)}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","'use client';\n\nimport * as React from 'react';\n\nimport { SearchIcon } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nfunction Command({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n className={cn(\n 'bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md',\n className\n )}\n data-slot=\"command\"\n {...props}\n />\n );\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n <div\n className=\"flex h-9 items-center gap-2 border-b px-3\"\n data-slot=\"command-input-wrapper\"\n >\n <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n <CommandPrimitive.Input\n className={cn(\n 'placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n data-slot=\"command-input\"\n {...props}\n />\n </div>\n );\n}\n\nfunction CommandList({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n className={cn(\n 'max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto',\n className\n )}\n data-slot=\"command-list\"\n {...props}\n />\n );\n}\n\nfunction CommandEmpty({\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n className=\"py-6 text-center text-sm\"\n data-slot=\"command-empty\"\n {...props}\n />\n );\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n className={cn(\n 'text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium',\n className\n )}\n data-slot=\"command-group\"\n {...props}\n />\n );\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n className={cn('bg-border -mx-1 h-px', className)}\n data-slot=\"command-separator\"\n {...props}\n />\n );\n}\n\nfunction CommandItem({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n className={cn(\n \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n data-slot=\"command-item\"\n {...props}\n />\n );\n}\n\nfunction CommandShortcut({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n className={cn(\n 'text-muted-foreground ml-auto text-xs tracking-widest',\n className\n )}\n data-slot=\"command-shortcut\"\n {...props}\n />\n );\n}\n\nexport {\n Command,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n};\n","'use client';\n\nimport { useEffect, useMemo } from 'react';\n\nimport type { ControllerFieldState } from 'react-hook-form';\n\nimport type { PopoverProps } from '@radix-ui/react-popover';\nimport { ScrollArea, ScrollAreaViewport } from '@radix-ui/react-scroll-area';\n\nimport { Check, ChevronsUpDown, X } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from './button';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from './command';\nimport { FormItem, FormLabel, FormMessage } from './form';\nimport { InputHelp } from './input-help';\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\nimport { ScrollBar } from './scroll-area';\n\nexport type SelectorOption = {\n id: string | number;\n name: string;\n value?: any;\n children?: SelectorOption[];\n};\n\nexport type SelectorProps<T> = {\n value?: T;\n onChange?: (item: T | undefined | null) => void;\n search?: string;\n onSearch?: (search: string) => void;\n placeholder?: string;\n empty?: React.ReactNode;\n items: T[];\n fieldLabel: keyof T;\n fieldKey?: keyof T;\n groupBy?: keyof T;\n disabled?: boolean;\n searchPlaceholder?: string;\n label?: string;\n name: string;\n className?: string;\n required?: boolean;\n fieldState?: ControllerFieldState;\n selectFirstIsOne?: boolean;\n help?: string;\n extra?: string;\n extraOnClick?: (\n onChange?: (item: T | undefined | null) => void\n ) => Promise<void> | void;\n open?: boolean;\n setOpen?: (open: boolean) => void;\n withPortal?: boolean;\n} & PopoverProps;\n\ntype SelectorGroup<T> = {\n id: string;\n heading?: string;\n items: T[];\n};\n\nconst DEFAULT_GROUP_ID = 'selector-default-group';\nconst UNDEFINED_GROUP_ID = 'selector-undefined-group';\n\nconst buildGroups = <T,>(items: T[], groupBy?: keyof T): SelectorGroup<T>[] => {\n if (!groupBy) return [{ id: DEFAULT_GROUP_ID, items }];\n\n return Object.values(\n items.reduce<Record<string, SelectorGroup<T>>>((acc, item) => {\n const rawValue = item[groupBy];\n const heading = rawValue == null ? undefined : String(rawValue);\n const groupId = heading ?? UNDEFINED_GROUP_ID;\n\n if (!acc[groupId]) {\n acc[groupId] = { id: groupId, heading, items: [] };\n }\n\n acc[groupId].items.push(item);\n return acc;\n }, {})\n );\n};\n\nexport function Selector<T>({\n value,\n onChange,\n search,\n onSearch,\n items,\n label,\n placeholder,\n fieldLabel,\n fieldKey,\n groupBy,\n searchPlaceholder,\n name,\n empty = 'Nenhuma opção encontrada...',\n disabled = false,\n className,\n required,\n fieldState,\n selectFirstIsOne,\n help,\n extra,\n extraOnClick,\n open,\n setOpen,\n withPortal = true,\n ...props\n}: SelectorProps<T>) {\n const itemKey = fieldKey || fieldLabel;\n\n useEffect(() => {\n if (selectFirstIsOne && items && items.length === 1 && !value) {\n onChange?.(items[0] as any);\n }\n }, [items]);\n\n const groups = useMemo(() => buildGroups(items, groupBy), [groupBy, items]);\n\n return (\n <FormItem className={cn('w-full', className)} id={`selector-${name}`}>\n <div className=\"flex items-end gap-1.5\">\n <FormLabel htmlFor={name}>\n {label}:\n {required && (\n <span className=\"text-red-500 text-lg leading-[1px]\">*</span>\n )}\n </FormLabel>\n\n <InputHelp help={help} name={name} />\n </div>\n <Popover onOpenChange={setOpen} open={open} {...props}>\n <PopoverTrigger asChild>\n <Button\n aria-expanded={open}\n aria-label=\"Carregando opções...\"\n className={cn(\n 'mt-0! justify-between w-full h-10! hover:bg-transparent cursor-pointer',\n !value && 'text-muted-foreground',\n fieldState?.error && 'border-destructive'\n )}\n disabled={disabled}\n id={name}\n role=\"combobox\"\n variant=\"outline\"\n >\n <span className=\"truncate\">\n {value\n ? (value[fieldLabel] as string)\n : placeholder || `Selecione a ${label?.toLowerCase()}`}\n </span>\n <div className=\"flex items-center\">\n <div className=\"relative size-4\">\n {value !== undefined && (\n <div\n className=\"absolute left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onChange?.(null);\n }}\n >\n <X className=\"size-4\" />\n </div>\n )}\n </div>\n <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </div>\n </Button>\n </PopoverTrigger>\n {fieldState?.error && <FormMessage />}\n <PopoverContent className=\"w-(--radix-popover-trigger-width) max-w-2xl p-0\">\n <Command shouldFilter={false}>\n <CommandInput\n onValueChange={onSearch}\n placeholder={\n searchPlaceholder || `Pesquise por uma ${label?.toLowerCase()}`\n }\n value={search}\n />\n <CommandList>\n <ScrollArea className=\"h-fit max-h-[300px]\" id=\"scroll\">\n <ScrollAreaViewport className=\"w-full h-fit max-h-[300px] relative\">\n <CommandEmpty className=\"text-sm p-3 text-foreground/60\">\n {empty}\n </CommandEmpty>\n {groups.map((group) => (\n <CommandGroup\n heading={\n group.heading ||\n (group.id === UNDEFINED_GROUP_ID && 'Outros')\n }\n key={`group-${group.id}`}\n >\n {group.items.map((item) => (\n <CommandItem\n className={cn(\n 'transition-all p-2',\n value === item &&\n 'bg-accent! text-accent-foreground'\n )}\n key={`item-${item[itemKey]}`}\n onSelect={() => {\n onChange?.(item);\n setOpen?.(false);\n }}\n value={String(item[itemKey])}\n >\n {item[fieldLabel] as string}\n {value === item && (\n <Check className=\"ml-auto h-4 w-4\" />\n )}\n </CommandItem>\n ))}\n </CommandGroup>\n ))}\n {extra && (\n <CommandItem\n className={cn(\n 'transition-all p-2 sticky bottom-0 bg-white hover:!bg-accent aria-selected:!bg-accent'\n )}\n onSelect={() => {\n extraOnClick?.(onChange);\n setOpen?.(false);\n }}\n >\n {extra}\n </CommandItem>\n )}\n </ScrollAreaViewport>\n <ScrollBar />\n </ScrollArea>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </FormItem>\n );\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\n\nimport { useController, useFormContext } from 'react-hook-form';\nimport { useDebounce } from 'use-debounce';\n\nimport { Selector, SelectorProps } from '../ui/selector';\n\nexport type TUseData<T> = (\n search?: string,\n initialParams?: any,\n disabled?: boolean\n) => {\n data: T[];\n};\n\nexport type RemoteSelectorProps<T> = {\n useData: TUseData<T>;\n initialParams?: Parameters<TUseData<T>>[1];\n initialRequest?: boolean;\n forceToggle?: boolean;\n} & Omit<SelectorProps<T>, 'items'>;\n\nexport function RemoteSelector<T>({\n useData,\n initialParams,\n initialRequest = false,\n forceToggle = false,\n ...props\n}: RemoteSelectorProps<T>) {\n type TItem = NonNullable<ReturnType<TUseData<T>>['data']>[number];\n\n const { control } = useFormContext();\n const { field, fieldState } = useController({\n control,\n name: props.name,\n });\n\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState('');\n const [searchDebounced] = useDebounce(search, 100, {\n maxWait: 200,\n });\n const { data } = useData(\n searchDebounced,\n initialParams,\n !open && !initialRequest\n );\n\n useEffect(() => {\n setOpen(forceToggle);\n }, [forceToggle]);\n\n return (\n <Selector\n {...props}\n fieldState={fieldState}\n items={data as TItem[]}\n key={`selector-${field.name}-${field.value}`}\n onChange={(value: any) => {\n field.onChange(value as TItem);\n }}\n onSearch={setSearch}\n open={open}\n search={search}\n setOpen={setOpen}\n value={field.value as TItem}\n />\n );\n}\n"],"mappings":"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"}
|
package/dist/text-field.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FieldPath, FieldPathValue, FieldValues, UseControllerProps } from "react-hook-form";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
3
3
|
import { Options } from "use-mask-input";
|
|
4
4
|
import { Options as Options$1 } from "nuqs";
|
|
5
5
|
|
|
@@ -55,7 +55,7 @@ declare function InputText({
|
|
|
55
55
|
name,
|
|
56
56
|
onChange,
|
|
57
57
|
...props
|
|
58
|
-
}: InputTextProps):
|
|
58
|
+
}: InputTextProps): react_jsx_runtime0.JSX.Element;
|
|
59
59
|
interface TextFieldProps<TFieldValues extends FieldValues = FieldValues, TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> extends UseControllerProps<TFieldValues, TFieldName> {
|
|
60
60
|
disabled?: boolean;
|
|
61
61
|
required?: boolean;
|
|
@@ -72,7 +72,7 @@ declare function TextField<TFieldValues extends FieldValues = FieldValues, TFiel
|
|
|
72
72
|
onChange,
|
|
73
73
|
transform,
|
|
74
74
|
...props
|
|
75
|
-
}: TextFieldProps<TFieldValues, TFieldName> & Omit<InputTextProps, 'onChange'>):
|
|
75
|
+
}: TextFieldProps<TFieldValues, TFieldName> & Omit<InputTextProps, 'onChange'>): react_jsx_runtime0.JSX.Element;
|
|
76
76
|
interface QueryTextFieldProps extends Omit<InputTextProps, 'onChange'> {
|
|
77
77
|
name: string;
|
|
78
78
|
defaultValue?: string;
|
|
@@ -84,7 +84,7 @@ declare function QueryTextField({
|
|
|
84
84
|
defaultValue,
|
|
85
85
|
options,
|
|
86
86
|
...props
|
|
87
|
-
}: QueryTextFieldProps):
|
|
87
|
+
}: QueryTextFieldProps): react_jsx_runtime0.JSX.Element;
|
|
88
88
|
interface CookieTextFieldProps extends InputTextProps {
|
|
89
89
|
name: string;
|
|
90
90
|
maxAge?: number;
|
|
@@ -93,7 +93,7 @@ declare function CookieTextField({
|
|
|
93
93
|
name,
|
|
94
94
|
maxAge,
|
|
95
95
|
...inputProps
|
|
96
|
-
}: CookieTextFieldProps):
|
|
96
|
+
}: CookieTextFieldProps): react_jsx_runtime0.JSX.Element;
|
|
97
97
|
//#endregion
|
|
98
98
|
export { CookieTextField, type CookieTextFieldProps, InputText, type InputTextProps, QueryTextField, type QueryTextFieldProps, TextField, type TextFieldProps };
|
|
99
99
|
//# sourceMappingURL=text-field.d.ts.map
|
package/dist/toggle-field.d.ts
CHANGED
|
@@ -26,18 +26,19 @@ declare function ToggleGroup({
|
|
|
26
26
|
}: ToggleGroupProps): react_jsx_runtime7.JSX.Element;
|
|
27
27
|
//#endregion
|
|
28
28
|
//#region src/components/toggle-field/ToggleField.d.ts
|
|
29
|
+
type ToggleOption = {
|
|
30
|
+
value: string;
|
|
31
|
+
label: string;
|
|
32
|
+
};
|
|
29
33
|
type ToggleFieldProps = Omit<React.ComponentProps<typeof ToggleGroup>, 'type'> & {
|
|
30
34
|
label?: string;
|
|
31
|
-
options:
|
|
32
|
-
value: string;
|
|
33
|
-
label: string;
|
|
34
|
-
}[];
|
|
35
|
+
options: ToggleOption[];
|
|
35
36
|
type?: 'single' | 'multiple';
|
|
36
37
|
variant?: 'outline' | 'default';
|
|
37
38
|
name: string;
|
|
38
|
-
defaultValue?:
|
|
39
|
+
defaultValue?: ToggleOption | ToggleOption[];
|
|
39
40
|
};
|
|
40
41
|
declare const ToggleField: React.FC<ToggleFieldProps>;
|
|
41
42
|
//#endregion
|
|
42
|
-
export { ToggleField, type ToggleFieldProps };
|
|
43
|
+
export { ToggleField, type ToggleFieldProps, type ToggleOption };
|
|
43
44
|
//# sourceMappingURL=toggle-field.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle-field.d.ts","names":[],"sources":["../src/components/toggle-field/ToggleGroup.tsx","../src/components/toggle-field/ToggleField.tsx"],"sourcesContent":[],"mappings":";;;;;;;;cAiBM,sBAwBL;;;;AA3B+D,CAAA,GA2B/D,+BAAA,CAAA,SAAA,CAAA,GAAA,SAAA,EAAA,GAAA,MAAA;KAqBI,gBAAA,GAAmB,OAAA,CAAM,cAAT,CAAA,OAA+B,IAA/B,CAAA,GACnB,IADmB,CACd,YADc,CAAA,OACM,cADN,CAAA,EAAA,MAAA,CAAA,GAAA;EAAA,UAAA,CAAA,EAEJ,UAFI;iBAA+B,CAAA,EAAA,MAAA;;iBAM3C,WAAA,CALkB;EAAA,SAAA;EAAA,OAAA;EAAA,IAAA;EAAA,QAAA;EAAA,UAAA;EAAA,eAAA;EAAA,GAAA;AAAA,CAAA,EAaxB,gBAbwB,CAAA,EAaR,kBAAA,CAAA,GAAA,CAAA,OAbQ;;;
|
|
1
|
+
{"version":3,"file":"toggle-field.d.ts","names":[],"sources":["../src/components/toggle-field/ToggleGroup.tsx","../src/components/toggle-field/ToggleField.tsx"],"sourcesContent":[],"mappings":";;;;;;;;cAiBM,sBAwBL;;;;AA3B+D,CAAA,GA2B/D,+BAAA,CAAA,SAAA,CAAA,GAAA,SAAA,EAAA,GAAA,MAAA;KAqBI,gBAAA,GAAmB,OAAA,CAAM,cAAT,CAAA,OAA+B,IAA/B,CAAA,GACnB,IADmB,CACd,YADc,CAAA,OACM,cADN,CAAA,EAAA,MAAA,CAAA,GAAA;EAAA,UAAA,CAAA,EAEJ,UAFI;iBAA+B,CAAA,EAAA,MAAA;;iBAM3C,WAAA,CALkB;EAAA,SAAA;EAAA,OAAA;EAAA,IAAA;EAAA,QAAA;EAAA,UAAA;EAAA,eAAA;EAAA,GAAA;AAAA,CAAA,EAaxB,gBAbwB,CAAA,EAaR,kBAAA,CAAA,GAAA,CAAA,OAbQ;;;KCrDf,YAAA;;;;KAEA,gBAAA,GAAmB,KAC7B,KAAA,CAAM,sBAAsB;;WAInB;EDAL,IAAA,CAAA,EAAA,QAAA,GAwBL,UAAA;EAqBI,OAAA,CAAA,EAAA,SAAgB,GAAA,SAAA;EAAA,IAAA,EAAA,MAAA;cAA+B,CAAA,ECzCnC,YDyCmC,GCzCpB,YDyCoB,EAAA;;cCtC9C,WDuCqB,ECvCR,KAAA,CAAM,EDuCE,CCvCC,gBDuCD,CAAA"}
|
package/dist/toggle-field.js
CHANGED
|
@@ -117,26 +117,33 @@ function ToggleGroupItem({ ref, className, children, variant, size, buttonProps,
|
|
|
117
117
|
//#endregion
|
|
118
118
|
//#region src/components/toggle-field/ToggleField.tsx
|
|
119
119
|
const ToggleField = ({ label, options, type = "single", variant = "outline", name, defaultValue,...props }) => {
|
|
120
|
-
const
|
|
120
|
+
const { control } = useFormContext();
|
|
121
121
|
const { field } = useController({
|
|
122
|
-
control
|
|
122
|
+
control,
|
|
123
123
|
name,
|
|
124
124
|
defaultValue
|
|
125
125
|
});
|
|
126
|
+
const isMultiple = type === "multiple";
|
|
127
|
+
const currentValue = field.value;
|
|
128
|
+
const selectedOptions = isMultiple ? Array.isArray(currentValue) ? currentValue : [] : [];
|
|
129
|
+
const selectedOption = !isMultiple && currentValue && !Array.isArray(currentValue) ? currentValue : null;
|
|
130
|
+
const toggleValue = isMultiple ? selectedOptions.map(({ value }) => value) : selectedOption?.value ?? "";
|
|
131
|
+
const handleValueChange = (next) => field.onChange(isMultiple ? options.filter(({ value }) => next.includes(value)) : options.find(({ value }) => value === next) ?? null);
|
|
132
|
+
const isSelected = (optionValue) => isMultiple ? selectedOptions.some(({ value }) => value === optionValue) : selectedOption?.value === optionValue;
|
|
126
133
|
return /* @__PURE__ */ jsxs("div", {
|
|
127
|
-
className: "flex gap-1
|
|
134
|
+
className: "flex flex-col gap-1",
|
|
128
135
|
children: [label && /* @__PURE__ */ jsx(Label, {
|
|
129
|
-
className:
|
|
136
|
+
className: "inline-flex items-center gap-0.5 leading-none",
|
|
130
137
|
children: label
|
|
131
138
|
}), /* @__PURE__ */ jsx(ToggleGroup, {
|
|
132
139
|
...props,
|
|
133
|
-
onValueChange:
|
|
140
|
+
onValueChange: handleValueChange,
|
|
134
141
|
type,
|
|
135
|
-
value:
|
|
142
|
+
value: toggleValue,
|
|
136
143
|
variant,
|
|
137
144
|
children: options.map((option) => /* @__PURE__ */ jsxs(ToggleGroupItem, {
|
|
138
145
|
value: option.value,
|
|
139
|
-
children: [(
|
|
146
|
+
children: [isSelected(option.value) && /* @__PURE__ */ jsx(Check, { className: "size-3" }), option.label]
|
|
140
147
|
}, `${name}-${option.value}`))
|
|
141
148
|
})]
|
|
142
149
|
});
|
package/dist/toggle-field.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle-field.js","names":["ToggleGroupRoot","ToggleGroupItemPrimitive","ToggleField: React.FC<ToggleFieldProps>"],"sources":["../src/components/toggle-field/ToggleGroup.tsx","../src/components/toggle-field/ToggleField.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\n\nimport { useController, useFormContext } from 'react-hook-form';\n\nimport { Root as CheckboxRoot } from '@radix-ui/react-checkbox';\nimport {\n Item as ToggleGroupItemPrimitive,\n Root as ToggleGroupRoot,\n} from '@radix-ui/react-toggle-group';\n\nimport { cn } from '@/lib/utils';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { HTMLMotionProps, Transition } from 'motion/react';\nimport * as m from 'motion/react-m';\n\nconst toggleVariants = cva(\n \"cursor-pointer inline-flex items-center justify-center gap-1 rounded-md text-sm font-medium hover:text-muted-foreground text-accent-foreground transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none focus:outline-none aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap\",\n {\n variants: {\n type: {\n single: '',\n multiple:\n 'border border-input/20 data-[state=on]:border-input data-[state=on]:bg-accent',\n },\n variant: {\n default: 'bg-transparent',\n outline: 'border border-input/15 bg-transparent shadow-xs',\n },\n size: {\n default: 'h-9 px-2 min-w-9',\n sm: 'h-8 px-1.5 min-w-8',\n lg: 'h-10 px-2.5 min-w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\ntype ToggleGroupContextProps = VariantProps<typeof toggleVariants> & {\n type?: 'single' | 'multiple';\n transition?: Transition;\n activeClassName?: string;\n globalId: string;\n};\n\nconst ToggleGroupContext = React.createContext<\n ToggleGroupContextProps | undefined\n>(undefined);\n\nconst useToggleGroup = (): ToggleGroupContextProps => {\n const context = React.useContext(ToggleGroupContext);\n if (!context) {\n throw new Error('useToggleGroup must be used within a ToggleGroup');\n }\n return context;\n};\n\ntype ToggleGroupProps = React.ComponentProps<typeof ToggleGroupRoot> &\n Omit<VariantProps<typeof toggleVariants>, 'type'> & {\n transition?: Transition;\n activeClassName?: string;\n };\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n children,\n transition = { type: 'spring', bounce: 0, stiffness: 200, damping: 25 },\n activeClassName,\n ...props\n}: ToggleGroupProps) {\n const globalId = React.useId();\n\n return (\n <ToggleGroupContext.Provider\n value={{\n variant,\n size,\n type: props.type,\n transition,\n activeClassName,\n globalId,\n }}\n >\n <ToggleGroupRoot\n className={cn('flex flex-wrap items-center gap-2 relative', className)}\n data-slot=\"toggle-group\"\n {...props}\n >\n {children}\n </ToggleGroupRoot>\n </ToggleGroupContext.Provider>\n );\n}\n\ntype ToggleGroupItemProps = React.ComponentProps<\n typeof ToggleGroupItemPrimitive\n> &\n Omit<VariantProps<typeof toggleVariants>, 'type'> & {\n children?: React.ReactNode;\n buttonProps?: HTMLMotionProps<'button'>;\n spanProps?: React.ComponentProps<'span'>;\n };\n\nfunction ToggleGroupItem({\n ref,\n className,\n children,\n variant,\n size,\n buttonProps,\n spanProps,\n ...props\n}: ToggleGroupItemProps) {\n const {\n activeClassName,\n transition,\n type,\n variant: contextVariant,\n size: contextSize,\n globalId,\n } = useToggleGroup();\n const itemRef = React.useRef<HTMLButtonElement | null>(null);\n React.useImperativeHandle(ref, () => itemRef.current as HTMLButtonElement);\n const [isActive, setIsActive] = React.useState(false);\n\n React.useEffect(() => {\n const node = itemRef.current;\n if (!node) return;\n const observer = new MutationObserver(() => {\n setIsActive(node.getAttribute('data-state') === 'on');\n });\n observer.observe(node, {\n attributes: true,\n attributeFilter: ['data-state'],\n });\n setIsActive(node.getAttribute('data-state') === 'on');\n return () => observer.disconnect();\n }, []);\n\n return (\n <ToggleGroupItemPrimitive ref={itemRef} {...props} asChild>\n <m.button\n data-slot=\"toggle-group-item\"\n initial={{ scale: 1 }}\n whileTap={{ scale: 0.9 }}\n {...buttonProps}\n className={cn('relative', buttonProps?.className)}\n layout\n >\n <span\n {...spanProps}\n className={cn(\n 'relative z-[1]',\n toggleVariants({\n variant: variant || contextVariant,\n size: size || contextSize,\n type,\n }),\n className,\n spanProps?.className\n )}\n data-state={isActive ? 'on' : 'off'}\n >\n {children}\n </span>\n\n {isActive && type === 'single' && (\n <m.span\n animate={{ opacity: isActive ? 1 : 0 }}\n className={cn(\n 'absolute inset-0 z-0 rounded-md bg-muted border border-input',\n activeClassName\n )}\n data-slot=\"active-toggle-group-item\"\n initial={{ opacity: 0 }}\n layoutId={`active-toggle-group-item-${globalId}`}\n transition={transition}\n />\n )}\n </m.button>\n </ToggleGroupItemPrimitive>\n );\n}\n\nconst ToggleGroupField: React.FC<\n ToggleGroupProps & {\n name: string;\n }\n> = ({ children, name, ...props }) => {\n const { control } = useFormContext();\n const { field } = useController({\n control,\n name,\n });\n\n return (\n <ToggleGroup onValueChange={field.onChange} value={field.value} {...props}>\n {children}\n </ToggleGroup>\n );\n};\n\nconst ToggleGroupItemField: React.FC<\n ToggleGroupItemProps & {\n name: string;\n }\n> = ({ children, name, ...props }) => {\n const { control } = useFormContext();\n const { field } = useController({\n control,\n name,\n });\n\n return (\n <CheckboxRoot checked={field.value} onCheckedChange={field.onChange}>\n <ToggleGroupItem {...props}>{children}</ToggleGroupItem>\n </CheckboxRoot>\n );\n};\n\nexport {\n ToggleGroup,\n ToggleGroupItem,\n ToggleGroupField,\n ToggleGroupItemField,\n type ToggleGroupProps,\n type ToggleGroupItemProps,\n};\n","'use client';\n\nimport { useController, useFormContext } from 'react-hook-form';\n\nimport { Label } from '@/components/ui/label';\n\nimport { Check } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport { ToggleGroup, ToggleGroupItem } from './ToggleGroup';\n\nexport type ToggleFieldProps = Omit<\n React.ComponentProps<typeof ToggleGroup>,\n 'type'\n> & {\n label?: string;\n options: { value: string; label: string }[];\n type?: 'single' | 'multiple';\n variant?: 'outline' | 'default';\n name: string;\n defaultValue?: string[];\n};\n\nconst ToggleField: React.FC<ToggleFieldProps> = ({\n label,\n options,\n type = 'single',\n variant = 'outline',\n name,\n defaultValue,\n ...props\n}) => {\n const form = useFormContext();\n const { field } = useController({\n control: form.control,\n name,\n defaultValue,\n });\n\n return (\n <div className=\"flex gap-1 flex-col\">\n {label && (\n <Label\n className={cn(\n 'inline-flex items-center flex-row gap-0.5 leading-none'\n )}\n >\n {label}\n </Label>\n )}\n\n <ToggleGroup\n {...props}\n onValueChange={field.onChange}\n type={type}\n value={field.value}\n variant={variant}\n >\n {options.map((option) => (\n <ToggleGroupItem key={`${name}-${option.value}`} value={option.value}>\n {((Array.isArray(field.value) &&\n field.value?.includes(option.value)) ||\n field.value === option.value) && <Check className=\"size-3\" />}\n {option.label}\n </ToggleGroupItem>\n ))}\n </ToggleGroup>\n </div>\n );\n};\n\nexport { ToggleField };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toggle-field.js","names":["ToggleGroupRoot","ToggleGroupItemPrimitive","ToggleField: React.FC<ToggleFieldProps>"],"sources":["../src/components/toggle-field/ToggleGroup.tsx","../src/components/toggle-field/ToggleField.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\n\nimport { useController, useFormContext } from 'react-hook-form';\n\nimport { Root as CheckboxRoot } from '@radix-ui/react-checkbox';\nimport {\n Item as ToggleGroupItemPrimitive,\n Root as ToggleGroupRoot,\n} from '@radix-ui/react-toggle-group';\n\nimport { cn } from '@/lib/utils';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { HTMLMotionProps, Transition } from 'motion/react';\nimport * as m from 'motion/react-m';\n\nconst toggleVariants = cva(\n \"cursor-pointer inline-flex items-center justify-center gap-1 rounded-md text-sm font-medium hover:text-muted-foreground text-accent-foreground transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none focus:outline-none aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap\",\n {\n variants: {\n type: {\n single: '',\n multiple:\n 'border border-input/20 data-[state=on]:border-input data-[state=on]:bg-accent',\n },\n variant: {\n default: 'bg-transparent',\n outline: 'border border-input/15 bg-transparent shadow-xs',\n },\n size: {\n default: 'h-9 px-2 min-w-9',\n sm: 'h-8 px-1.5 min-w-8',\n lg: 'h-10 px-2.5 min-w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\ntype ToggleGroupContextProps = VariantProps<typeof toggleVariants> & {\n type?: 'single' | 'multiple';\n transition?: Transition;\n activeClassName?: string;\n globalId: string;\n};\n\nconst ToggleGroupContext = React.createContext<\n ToggleGroupContextProps | undefined\n>(undefined);\n\nconst useToggleGroup = (): ToggleGroupContextProps => {\n const context = React.useContext(ToggleGroupContext);\n if (!context) {\n throw new Error('useToggleGroup must be used within a ToggleGroup');\n }\n return context;\n};\n\ntype ToggleGroupProps = React.ComponentProps<typeof ToggleGroupRoot> &\n Omit<VariantProps<typeof toggleVariants>, 'type'> & {\n transition?: Transition;\n activeClassName?: string;\n };\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n children,\n transition = { type: 'spring', bounce: 0, stiffness: 200, damping: 25 },\n activeClassName,\n ...props\n}: ToggleGroupProps) {\n const globalId = React.useId();\n\n return (\n <ToggleGroupContext.Provider\n value={{\n variant,\n size,\n type: props.type,\n transition,\n activeClassName,\n globalId,\n }}\n >\n <ToggleGroupRoot\n className={cn('flex flex-wrap items-center gap-2 relative', className)}\n data-slot=\"toggle-group\"\n {...props}\n >\n {children}\n </ToggleGroupRoot>\n </ToggleGroupContext.Provider>\n );\n}\n\ntype ToggleGroupItemProps = React.ComponentProps<\n typeof ToggleGroupItemPrimitive\n> &\n Omit<VariantProps<typeof toggleVariants>, 'type'> & {\n children?: React.ReactNode;\n buttonProps?: HTMLMotionProps<'button'>;\n spanProps?: React.ComponentProps<'span'>;\n };\n\nfunction ToggleGroupItem({\n ref,\n className,\n children,\n variant,\n size,\n buttonProps,\n spanProps,\n ...props\n}: ToggleGroupItemProps) {\n const {\n activeClassName,\n transition,\n type,\n variant: contextVariant,\n size: contextSize,\n globalId,\n } = useToggleGroup();\n const itemRef = React.useRef<HTMLButtonElement | null>(null);\n React.useImperativeHandle(ref, () => itemRef.current as HTMLButtonElement);\n const [isActive, setIsActive] = React.useState(false);\n\n React.useEffect(() => {\n const node = itemRef.current;\n if (!node) return;\n const observer = new MutationObserver(() => {\n setIsActive(node.getAttribute('data-state') === 'on');\n });\n observer.observe(node, {\n attributes: true,\n attributeFilter: ['data-state'],\n });\n setIsActive(node.getAttribute('data-state') === 'on');\n return () => observer.disconnect();\n }, []);\n\n return (\n <ToggleGroupItemPrimitive ref={itemRef} {...props} asChild>\n <m.button\n data-slot=\"toggle-group-item\"\n initial={{ scale: 1 }}\n whileTap={{ scale: 0.9 }}\n {...buttonProps}\n className={cn('relative', buttonProps?.className)}\n layout\n >\n <span\n {...spanProps}\n className={cn(\n 'relative z-[1]',\n toggleVariants({\n variant: variant || contextVariant,\n size: size || contextSize,\n type,\n }),\n className,\n spanProps?.className\n )}\n data-state={isActive ? 'on' : 'off'}\n >\n {children}\n </span>\n\n {isActive && type === 'single' && (\n <m.span\n animate={{ opacity: isActive ? 1 : 0 }}\n className={cn(\n 'absolute inset-0 z-0 rounded-md bg-muted border border-input',\n activeClassName\n )}\n data-slot=\"active-toggle-group-item\"\n initial={{ opacity: 0 }}\n layoutId={`active-toggle-group-item-${globalId}`}\n transition={transition}\n />\n )}\n </m.button>\n </ToggleGroupItemPrimitive>\n );\n}\n\nconst ToggleGroupField: React.FC<\n ToggleGroupProps & {\n name: string;\n }\n> = ({ children, name, ...props }) => {\n const { control } = useFormContext();\n const { field } = useController({\n control,\n name,\n });\n\n return (\n <ToggleGroup onValueChange={field.onChange} value={field.value} {...props}>\n {children}\n </ToggleGroup>\n );\n};\n\nconst ToggleGroupItemField: React.FC<\n ToggleGroupItemProps & {\n name: string;\n }\n> = ({ children, name, ...props }) => {\n const { control } = useFormContext();\n const { field } = useController({\n control,\n name,\n });\n\n return (\n <CheckboxRoot checked={field.value} onCheckedChange={field.onChange}>\n <ToggleGroupItem {...props}>{children}</ToggleGroupItem>\n </CheckboxRoot>\n );\n};\n\nexport {\n ToggleGroup,\n ToggleGroupItem,\n ToggleGroupField,\n ToggleGroupItemField,\n type ToggleGroupProps,\n type ToggleGroupItemProps,\n};\n","'use client';\n\nimport { useController, useFormContext } from 'react-hook-form';\n\nimport { Label } from '@/components/ui/label';\n\nimport { Check } from 'lucide-react';\n\nimport { ToggleGroup, ToggleGroupItem } from './ToggleGroup';\n\nexport type ToggleOption = { value: string; label: string };\n\nexport type ToggleFieldProps = Omit<\n React.ComponentProps<typeof ToggleGroup>,\n 'type'\n> & {\n label?: string;\n options: ToggleOption[];\n type?: 'single' | 'multiple';\n variant?: 'outline' | 'default';\n name: string;\n defaultValue?: ToggleOption | ToggleOption[];\n};\n\nconst ToggleField: React.FC<ToggleFieldProps> = ({\n label,\n options,\n type = 'single',\n variant = 'outline',\n name,\n defaultValue,\n ...props\n}) => {\n const { control } = useFormContext();\n const { field } = useController({ control, name, defaultValue });\n\n const isMultiple = type === 'multiple';\n const currentValue = field.value;\n\n const selectedOptions = isMultiple\n ? Array.isArray(currentValue)\n ? currentValue\n : []\n : [];\n const selectedOption =\n !isMultiple && currentValue && !Array.isArray(currentValue)\n ? currentValue\n : null;\n\n const toggleValue = isMultiple\n ? selectedOptions.map(({ value }: ToggleOption) => value)\n : (selectedOption?.value ?? '');\n\n const handleValueChange = (next: string | string[]) =>\n field.onChange(\n isMultiple\n ? options.filter(({ value }) => (next as string[]).includes(value))\n : (options.find(({ value }) => value === next) ?? null)\n );\n\n const isSelected = (optionValue: string) =>\n isMultiple\n ? selectedOptions.some(({ value }: ToggleOption) => value === optionValue)\n : selectedOption?.value === optionValue;\n\n return (\n <div className=\"flex flex-col gap-1\">\n {label && (\n <Label className=\"inline-flex items-center gap-0.5 leading-none\">\n {label}\n </Label>\n )}\n <ToggleGroup\n {...props}\n onValueChange={handleValueChange}\n type={type}\n value={toggleValue}\n variant={variant}\n >\n {options.map((option) => (\n <ToggleGroupItem key={`${name}-${option.value}`} value={option.value}>\n {isSelected(option.value) && <Check className=\"size-3\" />}\n {option.label}\n </ToggleGroupItem>\n ))}\n </ToggleGroup>\n </div>\n );\n};\n\nexport { ToggleField };\n"],"mappings":"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"}
|