@cryptlex/web-components 6.6.6-alpha28 → 6.6.6-alpha30
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/components/alert.d.ts +2 -1
- package/dist/components/alert.js +1 -1
- package/dist/components/alert.js.map +1 -1
- package/dist/components/checkbox.js +1 -1
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/form.js +1 -1
- package/dist/components/form.js.map +1 -1
- package/dist/components/id-search.js +1 -1
- package/dist/components/id-search.js.map +1 -1
- package/dist/components/multi-select.js +1 -1
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/numberfield.d.ts +3 -2
- package/dist/components/numberfield.js +1 -1
- package/dist/components/numberfield.js.map +1 -1
- package/dist/components/toast.js +1 -1
- package/dist/utilities/numbers.d.ts +7 -0
- package/dist/utilities/numbers.js +1 -1
- package/dist/utilities/numbers.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { VariantProps } from 'class-variance-authority';
|
|
2
|
+
import { default as React } from 'react';
|
|
2
3
|
import { CtxIcon } from './icons';
|
|
3
4
|
export declare const alertVariants: (props?: ({
|
|
4
5
|
variant?: "destructive" | "success" | "muted" | null | undefined;
|
|
5
6
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
6
|
-
export declare function Alert({ children, className, variant, icon
|
|
7
|
+
export declare function Alert({ children, className, variant, icon, ...props }: React.ComponentProps<'div'> & VariantProps<typeof alertVariants> & {
|
|
7
8
|
icon?: CtxIcon;
|
|
8
9
|
}): import("react/jsx-runtime").JSX.Element;
|
package/dist/components/alert.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsxs as
|
|
1
|
+
import{jsxs as u,jsx as s}from"react/jsx-runtime";import{cva as d}from"class-variance-authority";import{classNames as i}from"../utilities/theme.js";import{IcInfo as n,IcCheck as m,IcError as l}from"./icons.js";import"clsx";import"react";const f=d("transition-colors border border-dotted p-2 text-foreground body inline-flex items-start gap-2",{variants:{variant:{destructive:"bg-destructive-foreground/20 text-destructive border-destructive",success:"bg-success-foreground/20 text-success border-success",muted:"bg-muted-foreground/20 text-muted border-muted"}},defaultVariants:{variant:"muted"}}),p=e=>{switch(e){case"destructive":return l;case"success":return m;case"muted":case void 0:default:return n}};function h({children:e,className:o,variant:t,icon:c,...a}){const r=c??p(t);return u("div",{role:"alert",className:i(f({variant:t}),o),...a,children:[r&&s(r,{className:"size-icon mt-1"}),s("span",{className:"w-full",children:e})]})}export{h as Alert,f as alertVariants};
|
|
2
2
|
//# sourceMappingURL=alert.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alert.js","sources":["../../lib/components/alert.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { classNames } from '../utilities/theme';\nimport type { CtxIcon } from './icons';\n\nexport const alertVariants = cva(\n `transition-colors border border-dotted p-2 text-foreground body inline-flex items-start gap-2`,\n {\n variants: {\n variant: {\n destructive: 'bg-destructive-foreground/20 text-destructive border-destructive',\n success: 'bg-success-foreground/20 text-success border-success',\n muted: 'bg-muted-foreground/20 text-muted border-muted',\n },\n },\n defaultVariants: {\n variant: 'muted',\n },\n }\n);\n\nexport function Alert({\n children,\n className,\n variant,\n icon
|
|
1
|
+
{"version":3,"file":"alert.js","sources":["../../lib/components/alert.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport React from 'react';\nimport { classNames } from '../utilities/theme';\nimport type { CtxIcon } from './icons';\nimport { IcCheck, IcError, IcInfo } from './icons';\n\nexport const alertVariants = cva(\n `transition-colors border border-dotted p-2 text-foreground body inline-flex items-start gap-2`,\n {\n variants: {\n variant: {\n destructive: 'bg-destructive-foreground/20 text-destructive border-destructive',\n success: 'bg-success-foreground/20 text-success border-success',\n muted: 'bg-muted-foreground/20 text-muted border-muted',\n },\n },\n defaultVariants: {\n variant: 'muted',\n },\n }\n);\n\n// Default icons for each variant\nconst getDefaultIcon = (variant: string | null | undefined): CtxIcon | null => {\n switch (variant) {\n case 'destructive':\n return IcError;\n case 'success':\n return IcCheck;\n case 'muted':\n case undefined:\n default:\n return IcInfo;\n }\n};\nexport function Alert({\n children,\n className,\n variant,\n icon,\n ...props\n}: React.ComponentProps<'div'> &\n VariantProps<typeof alertVariants> & {\n icon?: CtxIcon;\n }) {\n // Overrides the default icon with the provided icon\n const Icon = icon ?? getDefaultIcon(variant);\n\n return (\n <div role=\"alert\" className={classNames(alertVariants({ variant }), className)} {...props}>\n {Icon && <Icon className=\"size-icon mt-1\" />}\n <span className=\"w-full\">{children}</span>\n </div>\n );\n}\n"],"names":["alertVariants","cva","getDefaultIcon","variant","IcError","IcCheck","IcInfo","Alert","children","className","icon","props","Icon","jsxs","classNames","jsx"],"mappings":"6OAMO,MAAMA,EAAgBC,EACzB,gGACA,CACI,SAAU,CACN,QAAS,CACL,YAAa,mEACb,QAAS,uDACT,MAAO,gDAAA,CACX,EAEJ,gBAAiB,CACb,QAAS,OAAA,CACb,CAER,EAGMC,EAAkBC,GAAuD,CAC3E,OAAQA,EAAA,CACJ,IAAK,cACD,OAAOC,EACX,IAAK,UACD,OAAOC,EACX,IAAK,QACL,KAAK,OACL,QACI,OAAOC,CAAA,CAEnB,EACO,SAASC,EAAM,CAClB,SAAAC,EACA,UAAAC,EACA,QAAAN,EACA,KAAAO,EACA,GAAGC,CACP,EAGO,CAEH,MAAMC,EAAOF,GAAQR,EAAeC,CAAO,EAE3C,OACIU,EAAC,MAAA,CAAI,KAAK,QAAQ,UAAWC,EAAWd,EAAc,CAAE,QAAAG,CAAA,CAAS,EAAGM,CAAS,EAAI,GAAGE,EAC/E,SAAA,CAAAC,GAAQG,EAACH,EAAA,CAAK,UAAU,gBAAA,CAAiB,EAC1CG,EAAC,OAAA,CAAK,UAAU,SAAU,SAAAP,CAAA,CAAS,CAAA,EACvC,CAER"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as e,Fragment as
|
|
1
|
+
import{jsx as e,Fragment as d}from"react/jsx-runtime";import{useId as h}from"react";import{Checkbox as p,composeRenderProps as n,CheckboxGroup as g}from"react-aria-components";import{useFieldContext as x}from"../utilities/form-context.js";import{classNames as s}from"../utilities/theme.js";import{FormField as f,labelVariants as k}from"./form.js";import{IcMinus as v,IcCheck as C}from"./icons.js";import"@tanstack/react-form";import"clsx";import"class-variance-authority";const w=g;function y({className:r,label:o,description:l,errorMessage:u,requiredIndicator:m,...t}){const b=h(),i=t.id||b;return e("div",{className:"group form-field",children:e(f,{label:o,description:l,errorMessage:u,requiredIndicator:m,htmlFor:i,children:e(p,{className:n(r,c=>s("group/checkbox cursor-pointer relative focus-ring flex items-center gap-x-2","disabled-muted",k,c)),id:i,...t,children:n(e(d,{}),(c,a)=>e(d,{children:e("div",{className:s("flex size-input shrink-0 items-center bg-elevation-2 justify-center border border-input text-current ring-offset-background","group-data-[indeterminate]/checkbox:bg-primary group-data-[selected]/checkbox:bg-primary group-data-[indeterminate]/checkbox:text-primary-foreground group-data-[selected]/checkbox:text-primary-foreground","group-data-[disabled]/checkbox:cursor-not-allowed group-data-[disabled]/checkbox:opacity-50","group-data-[invalid]/checkbox:border-destructive group-data-[invalid]/checkbox:group-data-[selected]/checkbox:bg-destructive group-data-[invalid]/checkbox:group-data-[selected]/checkbox:text-destructive-foreground","focus:outline-none focus-visible:outline-none"),children:a.isIndeterminate?e(v,{className:"size-icon"}):a.isSelected?e(C,{className:"size-icon"}):null})}))})})})}function M({...r}){const o=x({disabled:r.isDisabled});return e(y,{isSelected:o.state.value,isDisabled:o.form.state.isSubmitting||r.isDisabled,onChange:()=>o.handleChange(!o.state.value),onBlur:o.handleBlur,...r})}export{y as Checkbox,w as CheckboxGroup,M as TfCheckbox};
|
|
2
2
|
//# sourceMappingURL=checkbox.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox.js","sources":["../../lib/components/checkbox.tsx"],"sourcesContent":["import {\n Checkbox as AriaCheckbox,\n CheckboxGroup as AriaCheckboxGroup,\n composeRenderProps,\n type CheckboxProps as AriaCheckboxProps,\n} from 'react-aria-components';\n\nimport { useFieldContext } from '../utilities/form-context';\nimport { classNames } from '../utilities/theme';\nimport { FormField, labelVariants, type FormFieldProps } from './form';\nimport { IcCheck, IcMinus } from './icons';\n\nexport const CheckboxGroup = AriaCheckboxGroup;\ntype CheckboxProps = AriaCheckboxProps & FormFieldProps;\nexport function Checkbox({\n className,\n label,\n description,\n errorMessage,\n requiredIndicator,\n ...props\n}: Omit<CheckboxProps, 'children'>) {\n return (\n <div className=\"group form-field\">\n <FormField {...{ label, description, errorMessage, requiredIndicator }}>\n <AriaCheckbox\n className={composeRenderProps(className, className =>\n classNames(\n 'group/checkbox cursor-pointer relative focus-ring flex items-center gap-x-2',\n /* Disabled */\n 'disabled-muted',\n labelVariants,\n className\n )\n )}\n {...props}\n >\n {composeRenderProps(<></>, (_, renderProps) => (\n <>\n <div\n className={classNames(\n 'flex size-input shrink-0 items-center bg-elevation-2 justify-center border border-input text-current ring-offset-background',\n /* Selected */\n 'group-data-[indeterminate]/checkbox:bg-primary group-data-[selected]/checkbox:bg-primary group-data-[indeterminate]/checkbox:text-primary-foreground group-data-[selected]/checkbox:text-primary-foreground',\n /* Disabled */\n 'group-data-[disabled]/checkbox:cursor-not-allowed group-data-[disabled]/checkbox:opacity-50',\n /* Invalid */\n 'group-data-[invalid]/checkbox:border-destructive group-data-[invalid]/checkbox:group-data-[selected]/checkbox:bg-destructive group-data-[invalid]/checkbox:group-data-[selected]/checkbox:text-destructive-foreground',\n /* Resets */\n 'focus:outline-none focus-visible:outline-none'\n )}\n >\n {renderProps.isIndeterminate ? (\n <IcMinus className=\"size-icon\" />\n ) : renderProps.isSelected ? (\n <IcCheck className=\"size-icon\" />\n ) : null}\n </div>\n </>\n ))}\n </AriaCheckbox>\n </FormField>\n </div>\n );\n}\n\nexport type TfCheckboxProps = Omit<React.ComponentProps<typeof Checkbox>, 'onChange' | 'onBlur' | 'isChecked'>;\nexport function TfCheckbox({ ...props }: TfCheckboxProps) {\n const field = useFieldContext<boolean>({ disabled: props.isDisabled });\n return (\n <Checkbox\n isSelected={field.state.value}\n isDisabled={field.form.state.isSubmitting || props.isDisabled}\n onChange={() => field.handleChange(!field.state.value)}\n onBlur={field.handleBlur}\n {...props}\n />\n );\n}\n"],"names":["CheckboxGroup","AriaCheckboxGroup","Checkbox","className","label","description","errorMessage","requiredIndicator","props","jsx","FormField","AriaCheckbox","composeRenderProps","classNames","labelVariants","Fragment","_","renderProps","IcMinus","IcCheck","TfCheckbox","field","useFieldContext"],"mappings":"
|
|
1
|
+
{"version":3,"file":"checkbox.js","sources":["../../lib/components/checkbox.tsx"],"sourcesContent":["import { useId } from 'react';\nimport {\n Checkbox as AriaCheckbox,\n CheckboxGroup as AriaCheckboxGroup,\n composeRenderProps,\n type CheckboxProps as AriaCheckboxProps,\n} from 'react-aria-components';\n\nimport { useFieldContext } from '../utilities/form-context';\nimport { classNames } from '../utilities/theme';\nimport { FormField, labelVariants, type FormFieldProps } from './form';\nimport { IcCheck, IcMinus } from './icons';\n\nexport const CheckboxGroup = AriaCheckboxGroup;\ntype CheckboxProps = AriaCheckboxProps & FormFieldProps;\nexport function Checkbox({\n className,\n label,\n description,\n errorMessage,\n requiredIndicator,\n ...props\n}: Omit<CheckboxProps, 'children'>) {\n const generatedId = useId();\n const fieldId = props.id || generatedId;\n return (\n <div className=\"group form-field\">\n <FormField {...{ label, description, errorMessage, requiredIndicator, htmlFor: fieldId }}>\n <AriaCheckbox\n className={composeRenderProps(className, className =>\n classNames(\n 'group/checkbox cursor-pointer relative focus-ring flex items-center gap-x-2',\n /* Disabled */\n 'disabled-muted',\n labelVariants,\n className\n )\n )}\n id={fieldId}\n {...props}\n >\n {composeRenderProps(<></>, (_, renderProps) => (\n <>\n <div\n className={classNames(\n 'flex size-input shrink-0 items-center bg-elevation-2 justify-center border border-input text-current ring-offset-background',\n /* Selected */\n 'group-data-[indeterminate]/checkbox:bg-primary group-data-[selected]/checkbox:bg-primary group-data-[indeterminate]/checkbox:text-primary-foreground group-data-[selected]/checkbox:text-primary-foreground',\n /* Disabled */\n 'group-data-[disabled]/checkbox:cursor-not-allowed group-data-[disabled]/checkbox:opacity-50',\n /* Invalid */\n 'group-data-[invalid]/checkbox:border-destructive group-data-[invalid]/checkbox:group-data-[selected]/checkbox:bg-destructive group-data-[invalid]/checkbox:group-data-[selected]/checkbox:text-destructive-foreground',\n /* Resets */\n 'focus:outline-none focus-visible:outline-none'\n )}\n >\n {renderProps.isIndeterminate ? (\n <IcMinus className=\"size-icon\" />\n ) : renderProps.isSelected ? (\n <IcCheck className=\"size-icon\" />\n ) : null}\n </div>\n </>\n ))}\n </AriaCheckbox>\n </FormField>\n </div>\n );\n}\n\nexport type TfCheckboxProps = Omit<React.ComponentProps<typeof Checkbox>, 'onChange' | 'onBlur' | 'isChecked'>;\nexport function TfCheckbox({ ...props }: TfCheckboxProps) {\n const field = useFieldContext<boolean>({ disabled: props.isDisabled });\n return (\n <Checkbox\n isSelected={field.state.value}\n isDisabled={field.form.state.isSubmitting || props.isDisabled}\n onChange={() => field.handleChange(!field.state.value)}\n onBlur={field.handleBlur}\n {...props}\n />\n );\n}\n"],"names":["CheckboxGroup","AriaCheckboxGroup","Checkbox","className","label","description","errorMessage","requiredIndicator","props","generatedId","useId","fieldId","jsx","FormField","AriaCheckbox","composeRenderProps","classNames","labelVariants","Fragment","_","renderProps","IcMinus","IcCheck","TfCheckbox","field","useFieldContext"],"mappings":"wdAaO,MAAMA,EAAgBC,EAEtB,SAASC,EAAS,CACrB,UAAAC,EACA,MAAAC,EACA,YAAAC,EACA,aAAAC,EACA,kBAAAC,EACA,GAAGC,CACP,EAAoC,CAChC,MAAMC,EAAcC,EAAA,EACdC,EAAUH,EAAM,IAAMC,EAC5B,OACIG,EAAC,MAAA,CAAI,UAAU,mBACX,WAACC,EAAA,CAAgB,MAAAT,EAAO,YAAAC,EAAa,aAAAC,EAAc,kBAAAC,EAAmB,QAASI,EAC3E,SAAAC,EAACE,EAAA,CACG,UAAWC,EAAmBZ,EAAWA,GACrCa,EACI,8EAEA,iBACAC,EACAd,CAAA,CACJ,EAEJ,GAAIQ,EACH,GAAGH,EAEH,WAAmBI,EAAAM,EAAA,CAAA,CAAE,EAAK,CAACC,EAAGC,IAC3BR,EAAAM,EAAA,CACI,SAAAN,EAAC,MAAA,CACG,UAAWI,EACP,8HAEA,+MAEA,8FAEA,wNAEA,+CAAA,EAGH,SAAAI,EAAY,gBACTR,EAACS,EAAA,CAAQ,UAAU,WAAA,CAAY,EAC/BD,EAAY,WACZR,EAACU,EAAA,CAAQ,UAAU,YAAY,EAC/B,IAAA,CAAA,EAEZ,CACH,CAAA,CAAA,EAET,CAAA,CACJ,CAER,CAGO,SAASC,EAAW,CAAE,GAAGf,GAA0B,CACtD,MAAMgB,EAAQC,EAAyB,CAAE,SAAUjB,EAAM,WAAY,EACrE,OACII,EAACV,EAAA,CACG,WAAYsB,EAAM,MAAM,MACxB,WAAYA,EAAM,KAAK,MAAM,cAAgBhB,EAAM,WACnD,SAAU,IAAMgB,EAAM,aAAa,CAACA,EAAM,MAAM,KAAK,EACrD,OAAQA,EAAM,WACb,GAAGhB,CAAA,CAAA,CAGhB"}
|
package/dist/components/form.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{jsxs as a,Fragment as d,jsx as n}from"react/jsx-runtime";import{cva as l}from"class-variance-authority";import{Group as u,composeRenderProps as c,Label as f,Text as p,Button as g}from"react-aria-components";import{classNames as i}from"../utilities/theme.js";import{IcInfo as b,IcError as h}from"./icons.js";import"clsx";import"react";const x=l(["select-none body-sm font-medium leading-none","disabled-muted","group-data-[invalid]:text-destructive"]);function F({className:t,...e}){return n(f,{className:i(x(),t),...e})}function N({className:t,children:e,...r}){return a(p,{className:i("body-sm text-muted leading-tight",t),...r,slot:"description",children:[e,n(b,{className:"inline size-2 align-text-top ms-0.5"})]})}function v({className:t,children:e,...r}){return a("label",{role:"alert",className:i("body-sm leading-tight text-destructive duration-150 animate-in transition-transform slide-in-from-top-5 fade-in",t),...r,children:[e,n(h,{className:"inline size-2 align-text-top ms-0.5"})]})}const y=l("",{variants:{variant:{default:["relative flex w-full items-center overflow-hidden border border-input bg-elevation-2 input-dim ring-offset-background placeholder:text-muted-foreground","focus-ring","disabled-muted"],ghost:""}},defaultVariants:{variant:"default"}});function k({className:t,variant:e,...r}){return n(u,{className:c(t,o=>i(y({variant:e}),o)),...r})}function w({label:t,description:e,errorMessage:r,children:o,requiredIndicator:m,htmlFor:s}){return a(d,{children:[t&&a(F,{htmlFor:s,children:[t,m&&n("sup",{className:"text-destructive",children:"*"})]}),o,e&&n(N,{children:e}),r&&n(v,{htmlFor:s,children:r})]})}function B({className:t,...e}){return n(g,{className:c(t,r=>i("btn btn-ghost h-input px-2 -me-2",r)),...e})}function D({className:t,onSubmit:e,...r}){return n("form",{className:i(t),onSubmit:o=>{o.preventDefault(),e?.(o)},...r})}function E({className:t,...e}){return n("section",{className:i("flex flex-col gap-input border-
|
|
1
|
+
"use client";import{jsxs as a,Fragment as d,jsx as n}from"react/jsx-runtime";import{cva as l}from"class-variance-authority";import{Group as u,composeRenderProps as c,Label as f,Text as p,Button as g}from"react-aria-components";import{classNames as i}from"../utilities/theme.js";import{IcInfo as b,IcError as h}from"./icons.js";import"clsx";import"react";const x=l(["select-none body-sm font-medium leading-none","disabled-muted","group-data-[invalid]:text-destructive"]);function F({className:t,...e}){return n(f,{className:i(x(),t),...e})}function N({className:t,children:e,...r}){return a(p,{className:i("body-sm text-muted leading-tight",t),...r,slot:"description",children:[e,n(b,{className:"inline size-2 align-text-top ms-0.5"})]})}function v({className:t,children:e,...r}){return a("label",{role:"alert",className:i("body-sm leading-tight text-destructive duration-150 animate-in transition-transform slide-in-from-top-5 fade-in",t),...r,children:[e,n(h,{className:"inline size-2 align-text-top ms-0.5"})]})}const y=l("",{variants:{variant:{default:["relative flex w-full items-center overflow-hidden border border-input bg-elevation-2 input-dim ring-offset-background placeholder:text-muted-foreground","focus-ring","disabled-muted"],ghost:""}},defaultVariants:{variant:"default"}});function k({className:t,variant:e,...r}){return n(u,{className:c(t,o=>i(y({variant:e}),o)),...r})}function w({label:t,description:e,errorMessage:r,children:o,requiredIndicator:m,htmlFor:s}){return a(d,{children:[t&&a(F,{htmlFor:s,children:[t,m&&n("sup",{className:"text-destructive",children:"*"})]}),o,e&&n(N,{children:e}),r&&n(v,{htmlFor:s,children:r})]})}function B({className:t,...e}){return n(g,{className:c(t,r=>i("btn btn-ghost h-input px-2 -me-2",r)),...e})}function D({className:t,onSubmit:e,...r}){return n("form",{className:i(t),onSubmit:o=>{o.preventDefault(),e?.(o)},...r})}function E({className:t,...e}){return n("section",{className:i("flex flex-col gap-input border-b py-icon pb-input",t),...e})}function T({className:t,...e}){return n("h2",{className:i("heading-4",t),...e})}function A({className:t,...e}){return n("nav",{className:i("flex items-center justify-end h-header bg-glass-1 sticky bottom-0 z-50 py-icon px-input border-t",t),...e})}function P({className:t,...e}){return n("div",{className:"grid grid-cols-1 xl:grid-cols-2 gap-input mt-icon my-header",...e})}export{k as FieldGroup,D as Form,A as FormActionFooter,w as FormField,B as FormFieldButton,N as FormFieldDescription,v as FormFieldError,F as FormFieldLabel,P as FormLayout,E as FormSection,T as FormSectionTitle,y as fieldGroupVariants,x as labelVariants};
|
|
2
2
|
//# sourceMappingURL=form.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.js","sources":["../../lib/components/form.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n Button as AriaButton,\n ButtonProps as AriaButtonProps,\n Group as AriaGroup,\n GroupProps as AriaGroupProps,\n Label as AriaLabel,\n LabelProps as AriaLabelProps,\n Text as AriaText,\n TextProps as AriaTextProps,\n composeRenderProps,\n} from 'react-aria-components';\n\nimport { classNames } from '../utilities/theme';\nimport { IcError, IcInfo } from './icons';\n\n/**\n * Class variance authority variants for form field labels.\n * Provides styling for different states including disabled and invalid.\n */\nexport const labelVariants = cva([\n 'select-none body-sm font-medium leading-none',\n /* Disabled */\n 'disabled-muted',\n /* Invalid */\n 'group-data-[invalid]:text-destructive',\n]);\n\n/**\n * A form field label component that extends React Aria's Label component.\n * Applies consistent styling for form labels including disabled and invalid states.\n *\n * @param className - Optional additional CSS classes to apply\n * @param props - All other props from AriaLabelProps\n * @returns A styled label element\n */\nexport function FormFieldLabel({ className, ...props }: AriaLabelProps) {\n return <AriaLabel className={classNames(labelVariants(), className)} {...props} />;\n}\n\n/**\n * A form field description component that provides additional context or help text.\n * Automatically includes an info icon and uses the \"description\" slot for accessibility.\n */\nexport function FormFieldDescription({ className, children, ...props }: AriaTextProps) {\n return (\n <AriaText className={classNames('body-sm text-muted leading-tight', className)} {...props} slot=\"description\">\n {children}\n <IcInfo className=\"inline size-2 align-text-top ms-0.5\" />\n </AriaText>\n );\n}\n/**\n * A form field error component that displays validation error messages.\n *\n * @remarks\n * Currently uses a div instead of AriaFieldError to avoid overlap with Tanstack Form.\n * This approach needs further discussion and exploration.\n *\n */\nexport function FormFieldError({ className, children, ...props }: React.ComponentPropsWithRef<'label'>) {\n return (\n <label\n role=\"alert\"\n className={classNames(\n 'body-sm leading-tight text-destructive duration-150 animate-in transition-transform slide-in-from-top-5 fade-in',\n className\n )}\n {...props}\n >\n {children}\n <IcError className=\"inline size-2 align-text-top ms-0.5\" />\n </label>\n );\n}\n\n/**\n * Class variance authority variants for field groups.\n * Provides styling variants for different types of form field containers.\n */\nexport const fieldGroupVariants = cva('', {\n variants: {\n variant: {\n default: [\n 'relative flex w-full items-center overflow-hidden border border-input bg-elevation-2 input-dim ring-offset-background placeholder:text-muted-foreground',\n /* Focus Within */\n 'focus-ring',\n /* Disabled */\n 'disabled-muted',\n ],\n ghost: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\n/**\n * Props interface for FieldGroup component.\n * Extends AriaGroupProps with variant styling options.\n */\nexport interface GroupProps extends AriaGroupProps, VariantProps<typeof fieldGroupVariants> {}\n\n/**\n * A field group component that wraps form inputs with consistent styling.\n * Supports different variants for various use cases.\n */\nexport function FieldGroup({ className, variant, ...props }: GroupProps) {\n return (\n <AriaGroup\n className={composeRenderProps(className, className =>\n classNames(fieldGroupVariants({ variant }), className)\n )}\n {...props}\n />\n );\n}\n\n/**\n * Props for the FormField component.\n * Defines the structure for form field configuration.\n */\nexport type FormFieldProps = {\n /** Optional label text for the form field */\n label?: React.ReactNode;\n /** Optional description or help text */\n description?: React.ReactNode;\n /** Optional error message to display */\n errorMessage?: string;\n /** Show required indicator on field label */\n requiredIndicator?: boolean;\n /** Not defining the htmlFor on labels will lead to accessibilty warnings */\n htmlFor?: string;\n};\n\n/**\n * A wrapper component for form fields that provides consistent layout and styling.\n * Automatically renders label, children, description, and error message in the correct order.\n * @returns A complete form field with all associated elements\n */\nexport function FormField({\n label,\n description,\n errorMessage,\n children,\n requiredIndicator,\n htmlFor,\n}: FormFieldProps & {\n children: React.ReactNode;\n}) {\n return (\n <>\n {label && (\n <FormFieldLabel htmlFor={htmlFor}>\n {label}\n {requiredIndicator && <sup className=\"text-destructive\">*</sup>}\n </FormFieldLabel>\n )}\n {children}\n {description && <FormFieldDescription>{description}</FormFieldDescription>}\n {errorMessage && <FormFieldError htmlFor={htmlFor}>{errorMessage}</FormFieldError>}\n </>\n );\n}\n\n/**\n * A button component designed to be used within form fields.\n * Styled to fit nicely alongside form inputs with ghost styling.\n */\nexport function FormFieldButton({ className, ...props }: AriaButtonProps) {\n return (\n <AriaButton\n className={composeRenderProps(className, className =>\n classNames('btn btn-ghost h-input px-2 -me-2', className)\n )}\n {...props}\n />\n );\n}\n\n/**\n * A form component that prevents default form submission and handles submit events.\n * All forms in this application are controlled components, not pure HTML forms.\n */\nexport function Form({ className, onSubmit, ...props }: React.ComponentProps<'form'>) {\n return (\n <form\n className={classNames(className)}\n onSubmit={e => {\n // None of the forms in our applications are pure HTML forms.\n e.preventDefault();\n // If onSubmit is provided, call it.\n onSubmit?.(e);\n }}\n {...props}\n />\n );\n}\n\n/**\n * A section component for organizing form content into logical groups.\n * Provides consistent spacing and visual separation between form sections.\n */\nexport function FormSection({ className, ...props }: React.ComponentProps<'section'>) {\n return <section className={classNames('flex flex-col gap-input border-x p-icon', className)} {...props} />;\n}\n\n/**\n * A title component for form sections.\n */\nexport function FormSectionTitle({ className, ...props }: React.ComponentProps<'h2'>) {\n return <h2 className={classNames('heading-4', className)} {...props} />;\n}\n\nexport function FormActionFooter({ className, ...props }: React.ComponentProps<'nav'>) {\n return (\n <nav\n className={classNames(\n 'flex items-center justify-end h-header bg-glass-1 sticky bottom-0 z-50 py-icon px-input border-t',\n className\n )}\n {...props}\n />\n );\n}\n\nexport function FormLayout({ className, ...props }: React.ComponentProps<'div'>) {\n return <div className={'grid grid-cols-1 lg:grid-cols-2 gap-input mt-icon my-header'} {...props} />;\n}\n"],"names":["labelVariants","cva","FormFieldLabel","className","props","jsx","AriaLabel","classNames","FormFieldDescription","children","jsxs","AriaText","IcInfo","FormFieldError","IcError","fieldGroupVariants","FieldGroup","variant","AriaGroup","composeRenderProps","FormField","label","description","errorMessage","requiredIndicator","htmlFor","Fragment","FormFieldButton","AriaButton","Form","onSubmit","e","FormSection","FormSectionTitle","FormActionFooter","FormLayout"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"form.js","sources":["../../lib/components/form.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n Button as AriaButton,\n ButtonProps as AriaButtonProps,\n Group as AriaGroup,\n GroupProps as AriaGroupProps,\n Label as AriaLabel,\n LabelProps as AriaLabelProps,\n Text as AriaText,\n TextProps as AriaTextProps,\n composeRenderProps,\n} from 'react-aria-components';\n\nimport { classNames } from '../utilities/theme';\nimport { IcError, IcInfo } from './icons';\n\n/**\n * Class variance authority variants for form field labels.\n * Provides styling for different states including disabled and invalid.\n */\nexport const labelVariants = cva([\n 'select-none body-sm font-medium leading-none',\n /* Disabled */\n 'disabled-muted',\n /* Invalid */\n 'group-data-[invalid]:text-destructive',\n]);\n\n/**\n * A form field label component that extends React Aria's Label component.\n * Applies consistent styling for form labels including disabled and invalid states.\n *\n * @param className - Optional additional CSS classes to apply\n * @param props - All other props from AriaLabelProps\n * @returns A styled label element\n */\nexport function FormFieldLabel({ className, ...props }: AriaLabelProps) {\n return <AriaLabel className={classNames(labelVariants(), className)} {...props} />;\n}\n\n/**\n * A form field description component that provides additional context or help text.\n * Automatically includes an info icon and uses the \"description\" slot for accessibility.\n */\nexport function FormFieldDescription({ className, children, ...props }: AriaTextProps) {\n return (\n <AriaText className={classNames('body-sm text-muted leading-tight', className)} {...props} slot=\"description\">\n {children}\n <IcInfo className=\"inline size-2 align-text-top ms-0.5\" />\n </AriaText>\n );\n}\n/**\n * A form field error component that displays validation error messages.\n *\n * @remarks\n * Currently uses a div instead of AriaFieldError to avoid overlap with Tanstack Form.\n * This approach needs further discussion and exploration.\n *\n */\nexport function FormFieldError({ className, children, ...props }: React.ComponentPropsWithRef<'label'>) {\n return (\n <label\n role=\"alert\"\n className={classNames(\n 'body-sm leading-tight text-destructive duration-150 animate-in transition-transform slide-in-from-top-5 fade-in',\n className\n )}\n {...props}\n >\n {children}\n <IcError className=\"inline size-2 align-text-top ms-0.5\" />\n </label>\n );\n}\n\n/**\n * Class variance authority variants for field groups.\n * Provides styling variants for different types of form field containers.\n */\nexport const fieldGroupVariants = cva('', {\n variants: {\n variant: {\n default: [\n 'relative flex w-full items-center overflow-hidden border border-input bg-elevation-2 input-dim ring-offset-background placeholder:text-muted-foreground',\n /* Focus Within */\n 'focus-ring',\n /* Disabled */\n 'disabled-muted',\n ],\n ghost: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\n/**\n * Props interface for FieldGroup component.\n * Extends AriaGroupProps with variant styling options.\n */\nexport interface GroupProps extends AriaGroupProps, VariantProps<typeof fieldGroupVariants> {}\n\n/**\n * A field group component that wraps form inputs with consistent styling.\n * Supports different variants for various use cases.\n */\nexport function FieldGroup({ className, variant, ...props }: GroupProps) {\n return (\n <AriaGroup\n className={composeRenderProps(className, className =>\n classNames(fieldGroupVariants({ variant }), className)\n )}\n {...props}\n />\n );\n}\n\n/**\n * Props for the FormField component.\n * Defines the structure for form field configuration.\n */\nexport type FormFieldProps = {\n /** Optional label text for the form field */\n label?: React.ReactNode;\n /** Optional description or help text */\n description?: React.ReactNode;\n /** Optional error message to display */\n errorMessage?: string;\n /** Show required indicator on field label */\n requiredIndicator?: boolean;\n /** Not defining the htmlFor on labels will lead to accessibilty warnings */\n htmlFor?: string;\n};\n\n/**\n * A wrapper component for form fields that provides consistent layout and styling.\n * Automatically renders label, children, description, and error message in the correct order.\n * @returns A complete form field with all associated elements\n */\nexport function FormField({\n label,\n description,\n errorMessage,\n children,\n requiredIndicator,\n htmlFor,\n}: FormFieldProps & {\n children: React.ReactNode;\n}) {\n return (\n <>\n {label && (\n <FormFieldLabel htmlFor={htmlFor}>\n {label}\n {requiredIndicator && <sup className=\"text-destructive\">*</sup>}\n </FormFieldLabel>\n )}\n {children}\n {description && <FormFieldDescription>{description}</FormFieldDescription>}\n {errorMessage && <FormFieldError htmlFor={htmlFor}>{errorMessage}</FormFieldError>}\n </>\n );\n}\n\n/**\n * A button component designed to be used within form fields.\n * Styled to fit nicely alongside form inputs with ghost styling.\n */\nexport function FormFieldButton({ className, ...props }: AriaButtonProps) {\n return (\n <AriaButton\n className={composeRenderProps(className, className =>\n classNames('btn btn-ghost h-input px-2 -me-2', className)\n )}\n {...props}\n />\n );\n}\n\n/**\n * A form component that prevents default form submission and handles submit events.\n * All forms in this application are controlled components, not pure HTML forms.\n */\nexport function Form({ className, onSubmit, ...props }: React.ComponentProps<'form'>) {\n return (\n <form\n className={classNames(className)}\n onSubmit={e => {\n // None of the forms in our applications are pure HTML forms.\n e.preventDefault();\n // If onSubmit is provided, call it.\n onSubmit?.(e);\n }}\n {...props}\n />\n );\n}\n\n/**\n * A section component for organizing form content into logical groups.\n * Provides consistent spacing and visual separation between form sections.\n */\nexport function FormSection({ className, ...props }: React.ComponentProps<'section'>) {\n return (\n <section className={classNames('flex flex-col gap-input border-b py-icon pb-input', className)} {...props} />\n );\n}\n\n/**\n * A title component for form sections.\n */\nexport function FormSectionTitle({ className, ...props }: React.ComponentProps<'h2'>) {\n return <h2 className={classNames('heading-4', className)} {...props} />;\n}\n\nexport function FormActionFooter({ className, ...props }: React.ComponentProps<'nav'>) {\n return (\n <nav\n className={classNames(\n 'flex items-center justify-end h-header bg-glass-1 sticky bottom-0 z-50 py-icon px-input border-t',\n className\n )}\n {...props}\n />\n );\n}\n\nexport function FormLayout({ className, ...props }: React.ComponentProps<'div'>) {\n return <div className={'grid grid-cols-1 xl:grid-cols-2 gap-input mt-icon my-header'} {...props} />;\n}\n"],"names":["labelVariants","cva","FormFieldLabel","className","props","jsx","AriaLabel","classNames","FormFieldDescription","children","jsxs","AriaText","IcInfo","FormFieldError","IcError","fieldGroupVariants","FieldGroup","variant","AriaGroup","composeRenderProps","FormField","label","description","errorMessage","requiredIndicator","htmlFor","Fragment","FormFieldButton","AriaButton","Form","onSubmit","e","FormSection","FormSectionTitle","FormActionFooter","FormLayout"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as t,jsxs as
|
|
1
|
+
import{jsx as t,jsxs as f}from"react/jsx-runtime";import{useQuery as N}from"@tanstack/react-query";import{useId as x,useState as B}from"react";import{Autocomplete as T}from"react-aria-components";import{Loader as j}from"./loader.js";import{Menu as A,MenuItem as E}from"./menu.js";import{PopoverTrigger as K}from"./popover.js";import{SearchField as L}from"./searchfield.js";import{getFieldErrorMessage as p}from"../utilities/form.js";import{useFieldContext as g}from"../utilities/form-context.js";import{FormField as _}from"./form.js";import{SelectTrigger as q,SelectPopover as P}from"./select.js";import"../utilities/theme.js";import"clsx";import"./icons.js";import"./list-box.js";import"@tanstack/react-form";import"class-variance-authority";import"./button.js";function S({label:r,description:n,errorMessage:e,requiredIndicator:o,searchFn:a,isDisabled:I,onBlur:y,resource:C,onChange:V,value:d,renderLabel:v,...m}){const b=x(),s=m.id||b,[l,F]=B(""),{data:c,isError:u,isFetching:h,error:M}=N({queryKey:[C,"id",l],queryFn:()=>a(l)});return t("div",{className:"group form-field",children:t(_,{label:r,description:n,errorMessage:e,requiredIndicator:o,htmlFor:s,children:f(K,{onOpenChange:i=>{i||y?.(d)},children:[t(q,{id:s,isDisabled:I,children:v(d,c)}),t(P,{placement:"bottom start",children:f(T,{inputValue:l,onInputChange:F,children:[t(L,{className:"p-2",autoFocus:!0}),h&&t("div",{className:"p-input",children:t(j,{className:"mx-auto"})}),!h&&!u&&t(A,{...m,className:"max-h-48",items:c,renderEmptyState:()=>t("div",{className:"body-sm p-2",children:"No results found."}),children:i=>t(E,{id:i.id,children:i.name},i.id)}),u&&t("div",{className:"text-destructive p-icon body-sm",children:M.message})]})})]})})})}function O({...r}){return t(S,{selectedKeys:[r.value],onSelectionChange:n=>r.onChange(Array.from(n).filter(e=>typeof e=="string")[0]),renderLabel:(n,e)=>e?.find(o=>o.id===n)?.name??n,selectionMode:"single",...r})}function Q({...r}){return t(S,{selectedKeys:r.value,onSelectionChange:n=>r.onChange(Array.from(n).filter(e=>typeof e=="string")),selectionMode:"multiple",renderLabel:(n,e)=>n?.map(o=>e?.find(a=>a.id===o)?.name??o).join(","),...r})}function ie({isDisabled:r,...n}){const e=g({disabled:r});return t(O,{...n,isDisabled:r||e.form.state.isSubmitting,value:e.state.value,onBlur:o=>e.handleBlur(),onChange:o=>e.handleChange(o),errorMessage:p(e)})}function ae({isDisabled:r,...n}){const e=g({disabled:r});return t(Q,{...n,isDisabled:r||e.form.state.isSubmitting,value:e.state.value,onBlur:o=>e.handleBlur(),onChange:o=>e.handleChange(o),errorMessage:p(e)})}export{Q as MultipleIdSearchInput,O as SingleIdSearchInput,ae as TfMultipleIdSearchInput,ie as TfSingleIdSearchInput};
|
|
2
2
|
//# sourceMappingURL=id-search.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id-search.js","sources":["../../lib/components/id-search.tsx"],"sourcesContent":["import { useQuery } from '@tanstack/react-query';\nimport { useState } from 'react';\nimport { Autocomplete } from 'react-aria-components';\nimport { Loader } from '../components/loader';\nimport { Menu, MenuItem } from '../components/menu';\nimport { PopoverTrigger } from '../components/popover';\nimport { SearchField } from '../components/searchfield';\nimport { getFieldErrorMessage } from '../utilities/form';\nimport { useFieldContext } from '../utilities/form-context';\nimport type { CtxResourceName } from '../utilities/resources';\nimport { FormField, type FormFieldProps } from './form';\nimport { SelectPopover, SelectTrigger } from './select';\n\n/**\n * Minimal resource shape used by the ID search inputs.\n * Only `id` and `name` are required.\n *\n * @example\n * const user: BaseSearchableResource = { id: 'u_123', name: 'Nabeel Farooq' };\n */\ntype BaseSearchableResource = {\n /** Unique identifier used as the input value. */\n id: string;\n /** Human-readable label shown to users. */\n name: string;\n};\n\n/**\n * - Generic, accessible ID-search building block.\n * - Search (powered by react-query)\n * - Renders an accessible Autocomplete + Menu listbox\n * - Exposes a controlled `value`/`onChange` contract so callers (and wrappers) can manage state\n * - Clear separation of concerns: this component only handles UI search/display; callers provide `searchFn`\n *\n * @template T - resource type extending `BaseSearchableResource` (must have `id` and `name`)\n * @template V - controlled value type (e.g. `string` for single-select or `string[]` for multi-select)\n *\n * @param props - props object (see inline property JSDoc for the most important fields)\n *\n * @remarks\n * - `searchFn` should return `Promise<T[] | undefined>`. Returning `undefined` indicates no results / handled error.\n * - When the popover closes, `onBlur` (if provided) is called with the current `value`.\n * - `renderLabel` must convert `value` to a readable string for the control button.\n *\n * @example\n * <BaseIdSearchInput\n * label=\"Owner\"\n * searchFn={q => api.searchUsers(q)}\n * value={ownerId}\n * onChange={setOwnerId}\n * renderLabel={(v, data) => data?.find(d => d.id === v)?.name ?? v}\n * />\n *\n * @testing\n * - Mock `searchFn` in unit tests; assert keyboard navigation, open/close behavior, and `onBlur` call on popover close.\n */\nfunction BaseIdSearchInput<T extends BaseSearchableResource, V>({\n label,\n description,\n errorMessage,\n requiredIndicator,\n searchFn,\n isDisabled,\n onBlur,\n resource,\n onChange,\n value,\n renderLabel,\n ...props\n}: FormFieldProps & {\n resource: CtxResourceName;\n /** Function that returns matching resources for the current query. */\n searchFn: (q: string) => Promise<T[] | undefined>;\n /** Disable interactions. */\n isDisabled?: boolean;\n /** Key used to access an alternate display accessor on item (kept for compatibility). */\n accessor: keyof BaseSearchableResource;\n /** Controlled value. */\n value: V;\n /** Called when popover closes or the field blurs with the current value. */\n onBlur?: (v: V) => void;\n /** Controlled change handler. */\n onChange: (v: V) => void;\n /** Render a human-readable label for the current value using the latest data. */\n renderLabel: (v: V, data: T[] | undefined) => string;\n} & Omit<React.ComponentProps<typeof Menu>, 'items' | 'className'>) {\n const [search, _setSearch] = useState('');\n const { data, isError, isFetching, error } = useQuery({\n queryKey: [resource, 'id', search],\n queryFn: () => searchFn(search),\n });\n\n return (\n <div className=\"group form-field\">\n <FormField {...{ label, description, errorMessage, requiredIndicator }}>\n <PopoverTrigger\n onOpenChange={o => {\n if (!o) {\n // searchInputRef.current?.focus();\n onBlur?.(value);\n }\n }}\n >\n <SelectTrigger isDisabled={isDisabled}>{renderLabel(value, data)}</SelectTrigger>\n <SelectPopover placement=\"bottom start\">\n <Autocomplete inputValue={search} onInputChange={_setSearch}>\n <SearchField className={'p-2'} autoFocus />\n {isFetching && (\n <div className=\"p-input\">\n <Loader className=\"mx-auto\" />\n </div>\n )}\n {!isFetching && !isError && (\n <Menu\n {...props}\n className={'max-h-48'}\n items={data}\n renderEmptyState={() => <div className=\"body-sm p-2\">No results found.</div>}\n >\n {item => (\n <MenuItem key={item['id']} id={item['id']}>\n {item.name}\n </MenuItem>\n )}\n </Menu>\n )}\n {isError && <div className=\"text-destructive p-icon body-sm\">{error.message}</div>}\n </Autocomplete>\n </SelectPopover>\n </PopoverTrigger>\n </FormField>\n </div>\n );\n}\n\n/**\n * Single-selection ID search input.\n *\n * Thin, typed wrapper around `BaseIdSearchInput` specialized for the very common single-ID case.\n * Adapts the internal selection events into `onChange(id?: string)` and renders the selected label.\n *\n * @template T - resource type (extends BaseSearchableResource)\n *\n * @param props - Inherits `BaseIdSearchInput` props but uses `string[]` value type.\n *\n * @example\n * <SingleIdSearchInput\n * label=\"Reporter\"\n * value={reporterId}\n * onChange={setReporterId}\n * searchFn={q => api.searchUsers(q)}\n * />\n *\n */\nexport function SingleIdSearchInput<T extends BaseSearchableResource>({\n ...props\n}: Omit<\n React.ComponentProps<typeof BaseIdSearchInput<T, string>>,\n 'onSelectionChange' | 'selectionMode' | 'selectedKeys' | 'renderLabel'\n>) {\n return (\n <BaseIdSearchInput\n selectedKeys={[props.value]}\n onSelectionChange={e => props.onChange(Array.from(e).filter(v => typeof v === 'string')[0])}\n renderLabel={(v, d) => d?.find(di => di.id === v)?.name ?? v}\n selectionMode=\"single\"\n {...props}\n />\n );\n}\n\n/**\n * Multi-selection ID search input.\n *\n * Thin wrapper around `BaseIdSearchInput` for the multiple-ID (`string[]`) case.\n * Adapts internal selection events into `onChange(ids: string[])`.\n *\n * @template T - resource type (extends BaseSearchableResource)\n *\n * @param props - Inherits `BaseIdSearchInput` props but uses `string[]` value type.\n *\n * @example\n * <MultipleIdSearchInput\n * label=\"Reviewers\"\n * value={reviewerIds}\n * onChange={setReviewerIds}\n * searchFn={q => api.searchUsers(q)}\n * />\n *\n * @remarks\n * - The `renderLabel` joins selected item names with commas for compact display.\n */\nexport function MultipleIdSearchInput<T extends BaseSearchableResource>({\n ...props\n}: Omit<\n React.ComponentProps<typeof BaseIdSearchInput<T, string[]>>,\n 'renderLabel' | 'onSelectionChange' | 'selectionMode' | 'selectedKeys'\n>) {\n return (\n <BaseIdSearchInput\n selectedKeys={props.value}\n onSelectionChange={e => props.onChange(Array.from(e).filter(v => typeof v === 'string'))}\n selectionMode=\"multiple\"\n renderLabel={(v, d) => v?.map(vi => d?.find(di => di.id === vi)?.name ?? vi).join(',')}\n {...props}\n />\n );\n}\n\n/**\n * Form-integrated single-select ID input (field wrapper).\n *\n * Integrates `SingleIdSearchInput` into the form system using `useFieldContext`.\n * - wires `value`, `onChange`, and `onBlur`\n * - disables the control while the form is submitting\n * - surfaces field-level error messages\n *\n * @example\n * <TfSingleIdSearchInput name=\"ownerId\" label=\"Owner\" searchFn={q => api.searchUsers(q)} />\n \n */\nexport function TfSingleIdSearchInput({\n isDisabled,\n ...props\n}: Omit<React.ComponentProps<typeof SingleIdSearchInput>, 'value' | 'onChange' | 'onBlur'>) {\n const field = useFieldContext<string>({ disabled: isDisabled });\n return (\n <SingleIdSearchInput\n {...props}\n isDisabled={isDisabled || field.form.state.isSubmitting}\n value={field.state.value}\n onBlur={_ => field.handleBlur()}\n onChange={e => field.handleChange(e)}\n errorMessage={getFieldErrorMessage(field)}\n />\n );\n}\n\n/**\n * Form-integrated multi-select ID input (field wrapper).\n *\n * Integrates `MultipleIdSearchInput` into the form system using `useFieldContext`.\n * - wires `value`, `onChange`, and `onBlur`\n * - disables the control while the form is submitting\n * - surfaces field-level error messages\n *\n * @example\n * <TfMultipleIdSearchInput name=\"reviewerIds\" label=\"Reviewers\" searchFn={q => api.searchUsers(q)} />\n *\n */\nexport function TfMultipleIdSearchInput({\n isDisabled,\n ...props\n}: Omit<React.ComponentProps<typeof MultipleIdSearchInput>, 'value' | 'onChange'>) {\n const field = useFieldContext<string[]>({ disabled: isDisabled });\n return (\n <MultipleIdSearchInput\n {...props}\n isDisabled={isDisabled || field.form.state.isSubmitting}\n value={field.state.value}\n onBlur={_ => field.handleBlur()}\n onChange={e => field.handleChange(e)}\n errorMessage={getFieldErrorMessage(field)}\n />\n );\n}\n"],"names":["BaseIdSearchInput","label","description","errorMessage","requiredIndicator","searchFn","isDisabled","onBlur","resource","onChange","value","renderLabel","props","search","_setSearch","useState","data","isError","isFetching","error","useQuery","jsx","FormField","jsxs","PopoverTrigger","o","SelectTrigger","SelectPopover","Autocomplete","SearchField","Loader","Menu","item","MenuItem","SingleIdSearchInput","e","v","d","di","MultipleIdSearchInput","vi","TfSingleIdSearchInput","field","useFieldContext","_","getFieldErrorMessage","TfMultipleIdSearchInput"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"id-search.js","sources":["../../lib/components/id-search.tsx"],"sourcesContent":["import { useQuery } from '@tanstack/react-query';\nimport { useId, useState } from 'react';\nimport { Autocomplete } from 'react-aria-components';\nimport { Loader } from '../components/loader';\nimport { Menu, MenuItem } from '../components/menu';\nimport { PopoverTrigger } from '../components/popover';\nimport { SearchField } from '../components/searchfield';\nimport { getFieldErrorMessage } from '../utilities/form';\nimport { useFieldContext } from '../utilities/form-context';\nimport type { CtxResourceName } from '../utilities/resources';\nimport { FormField, type FormFieldProps } from './form';\nimport { SelectPopover, SelectTrigger } from './select';\n\n/**\n * Minimal resource shape used by the ID search inputs.\n * Only `id` and `name` are required.\n *\n * @example\n * const user: BaseSearchableResource = { id: 'u_123', name: 'Nabeel Farooq' };\n */\ntype BaseSearchableResource = {\n /** Unique identifier used as the input value. */\n id: string;\n /** Human-readable label shown to users. */\n name: string;\n};\n\n/**\n * - Generic, accessible ID-search building block.\n * - Search (powered by react-query)\n * - Renders an accessible Autocomplete + Menu listbox\n * - Exposes a controlled `value`/`onChange` contract so callers (and wrappers) can manage state\n * - Clear separation of concerns: this component only handles UI search/display; callers provide `searchFn`\n *\n * @template T - resource type extending `BaseSearchableResource` (must have `id` and `name`)\n * @template V - controlled value type (e.g. `string` for single-select or `string[]` for multi-select)\n *\n * @param props - props object (see inline property JSDoc for the most important fields)\n *\n * @remarks\n * - `searchFn` should return `Promise<T[] | undefined>`. Returning `undefined` indicates no results / handled error.\n * - When the popover closes, `onBlur` (if provided) is called with the current `value`.\n * - `renderLabel` must convert `value` to a readable string for the control button.\n *\n * @example\n * <BaseIdSearchInput\n * label=\"Owner\"\n * searchFn={q => api.searchUsers(q)}\n * value={ownerId}\n * onChange={setOwnerId}\n * renderLabel={(v, data) => data?.find(d => d.id === v)?.name ?? v}\n * />\n *\n * @testing\n * - Mock `searchFn` in unit tests; assert keyboard navigation, open/close behavior, and `onBlur` call on popover close.\n */\nfunction BaseIdSearchInput<T extends BaseSearchableResource, V>({\n label,\n description,\n errorMessage,\n requiredIndicator,\n searchFn,\n isDisabled,\n onBlur,\n resource,\n onChange,\n value,\n renderLabel,\n ...props\n}: FormFieldProps & {\n resource: CtxResourceName;\n /** Function that returns matching resources for the current query. */\n searchFn: (q: string) => Promise<T[] | undefined>;\n /** Disable interactions. */\n isDisabled?: boolean;\n /** Key used to access an alternate display accessor on item (kept for compatibility). */\n accessor: keyof BaseSearchableResource;\n /** Controlled value. */\n value: V;\n /** Called when popover closes or the field blurs with the current value. */\n onBlur?: (v: V) => void;\n /** Controlled change handler. */\n onChange: (v: V) => void;\n /** Render a human-readable label for the current value using the latest data. */\n renderLabel: (v: V, data: T[] | undefined) => string;\n} & Omit<React.ComponentProps<typeof Menu>, 'items' | 'className'>) {\n const generatedId = useId();\n const fieldId = props.id || generatedId;\n\n const [search, _setSearch] = useState('');\n const { data, isError, isFetching, error } = useQuery({\n queryKey: [resource, 'id', search],\n queryFn: () => searchFn(search),\n });\n\n return (\n <div className=\"group form-field\">\n <FormField {...{ label, description, errorMessage, requiredIndicator, htmlFor: fieldId }}>\n <PopoverTrigger\n onOpenChange={o => {\n if (!o) {\n // searchInputRef.current?.focus();\n onBlur?.(value);\n }\n }}\n >\n <SelectTrigger id={fieldId} isDisabled={isDisabled}>\n {renderLabel(value, data)}\n </SelectTrigger>\n <SelectPopover placement=\"bottom start\">\n <Autocomplete inputValue={search} onInputChange={_setSearch}>\n <SearchField className={'p-2'} autoFocus />\n {isFetching && (\n <div className=\"p-input\">\n <Loader className=\"mx-auto\" />\n </div>\n )}\n {!isFetching && !isError && (\n <Menu\n {...props}\n className={'max-h-48'}\n items={data}\n renderEmptyState={() => <div className=\"body-sm p-2\">No results found.</div>}\n >\n {item => (\n <MenuItem key={item['id']} id={item['id']}>\n {item.name}\n </MenuItem>\n )}\n </Menu>\n )}\n {isError && <div className=\"text-destructive p-icon body-sm\">{error.message}</div>}\n </Autocomplete>\n </SelectPopover>\n </PopoverTrigger>\n </FormField>\n </div>\n );\n}\n\n/**\n * Single-selection ID search input.\n *\n * Thin, typed wrapper around `BaseIdSearchInput` specialized for the very common single-ID case.\n * Adapts the internal selection events into `onChange(id?: string)` and renders the selected label.\n *\n * @template T - resource type (extends BaseSearchableResource)\n *\n * @param props - Inherits `BaseIdSearchInput` props but uses `string[]` value type.\n *\n * @example\n * <SingleIdSearchInput\n * label=\"Reporter\"\n * value={reporterId}\n * onChange={setReporterId}\n * searchFn={q => api.searchUsers(q)}\n * />\n *\n */\nexport function SingleIdSearchInput<T extends BaseSearchableResource>({\n ...props\n}: Omit<\n React.ComponentProps<typeof BaseIdSearchInput<T, string>>,\n 'onSelectionChange' | 'selectionMode' | 'selectedKeys' | 'renderLabel'\n>) {\n return (\n <BaseIdSearchInput\n selectedKeys={[props.value]}\n onSelectionChange={e => props.onChange(Array.from(e).filter(v => typeof v === 'string')[0])}\n renderLabel={(v, d) => d?.find(di => di.id === v)?.name ?? v}\n selectionMode=\"single\"\n {...props}\n />\n );\n}\n\n/**\n * Multi-selection ID search input.\n *\n * Thin wrapper around `BaseIdSearchInput` for the multiple-ID (`string[]`) case.\n * Adapts internal selection events into `onChange(ids: string[])`.\n *\n * @template T - resource type (extends BaseSearchableResource)\n *\n * @param props - Inherits `BaseIdSearchInput` props but uses `string[]` value type.\n *\n * @example\n * <MultipleIdSearchInput\n * label=\"Reviewers\"\n * value={reviewerIds}\n * onChange={setReviewerIds}\n * searchFn={q => api.searchUsers(q)}\n * />\n *\n * @remarks\n * - The `renderLabel` joins selected item names with commas for compact display.\n */\nexport function MultipleIdSearchInput<T extends BaseSearchableResource>({\n ...props\n}: Omit<\n React.ComponentProps<typeof BaseIdSearchInput<T, string[]>>,\n 'renderLabel' | 'onSelectionChange' | 'selectionMode' | 'selectedKeys'\n>) {\n return (\n <BaseIdSearchInput\n selectedKeys={props.value}\n onSelectionChange={e => props.onChange(Array.from(e).filter(v => typeof v === 'string'))}\n selectionMode=\"multiple\"\n renderLabel={(v, d) => v?.map(vi => d?.find(di => di.id === vi)?.name ?? vi).join(',')}\n {...props}\n />\n );\n}\n\n/**\n * Form-integrated single-select ID input (field wrapper).\n *\n * Integrates `SingleIdSearchInput` into the form system using `useFieldContext`.\n * - wires `value`, `onChange`, and `onBlur`\n * - disables the control while the form is submitting\n * - surfaces field-level error messages\n *\n * @example\n * <TfSingleIdSearchInput name=\"ownerId\" label=\"Owner\" searchFn={q => api.searchUsers(q)} />\n \n */\nexport function TfSingleIdSearchInput({\n isDisabled,\n ...props\n}: Omit<React.ComponentProps<typeof SingleIdSearchInput>, 'value' | 'onChange' | 'onBlur'>) {\n const field = useFieldContext<string>({ disabled: isDisabled });\n return (\n <SingleIdSearchInput\n {...props}\n isDisabled={isDisabled || field.form.state.isSubmitting}\n value={field.state.value}\n onBlur={_ => field.handleBlur()}\n onChange={e => field.handleChange(e)}\n errorMessage={getFieldErrorMessage(field)}\n />\n );\n}\n\n/**\n * Form-integrated multi-select ID input (field wrapper).\n *\n * Integrates `MultipleIdSearchInput` into the form system using `useFieldContext`.\n * - wires `value`, `onChange`, and `onBlur`\n * - disables the control while the form is submitting\n * - surfaces field-level error messages\n *\n * @example\n * <TfMultipleIdSearchInput name=\"reviewerIds\" label=\"Reviewers\" searchFn={q => api.searchUsers(q)} />\n *\n */\nexport function TfMultipleIdSearchInput({\n isDisabled,\n ...props\n}: Omit<React.ComponentProps<typeof MultipleIdSearchInput>, 'value' | 'onChange'>) {\n const field = useFieldContext<string[]>({ disabled: isDisabled });\n return (\n <MultipleIdSearchInput\n {...props}\n isDisabled={isDisabled || field.form.state.isSubmitting}\n value={field.state.value}\n onBlur={_ => field.handleBlur()}\n onChange={e => field.handleChange(e)}\n errorMessage={getFieldErrorMessage(field)}\n />\n );\n}\n"],"names":["BaseIdSearchInput","label","description","errorMessage","requiredIndicator","searchFn","isDisabled","onBlur","resource","onChange","value","renderLabel","props","generatedId","useId","fieldId","search","_setSearch","useState","data","isError","isFetching","error","useQuery","jsx","FormField","jsxs","PopoverTrigger","o","SelectTrigger","SelectPopover","Autocomplete","SearchField","Loader","Menu","item","MenuItem","SingleIdSearchInput","e","v","d","di","MultipleIdSearchInput","vi","TfSingleIdSearchInput","field","useFieldContext","_","getFieldErrorMessage","TfMultipleIdSearchInput"],"mappings":"2vBAwDA,SAASA,EAAuD,CAC5D,MAAAC,EACA,YAAAC,EACA,aAAAC,EACA,kBAAAC,EACA,SAAAC,EACA,WAAAC,EACA,OAAAC,EACA,SAAAC,EACA,SAAAC,EACA,MAAAC,EACA,YAAAC,EACA,GAAGC,CACP,EAgBoE,CAChE,MAAMC,EAAcC,EAAA,EACdC,EAAUH,EAAM,IAAMC,EAEtB,CAACG,EAAQC,CAAU,EAAIC,EAAS,EAAE,EAClC,CAAE,KAAAC,EAAM,QAAAC,EAAS,WAAAC,EAAY,MAAAC,CAAA,EAAUC,EAAS,CAClD,SAAU,CAACf,EAAU,KAAMQ,CAAM,EACjC,QAAS,IAAMX,EAASW,CAAM,CAAA,CACjC,EAED,OACIQ,EAAC,MAAA,CAAI,UAAU,mBACX,WAACC,EAAA,CAAgB,MAAAxB,EAAO,YAAAC,EAAa,aAAAC,EAAc,kBAAAC,EAAmB,QAASW,EAC3E,SAAAW,EAACC,EAAA,CACG,aAAcC,GAAK,CACVA,GAEDrB,IAASG,CAAK,CAEtB,EAEA,SAAA,CAAAc,EAACK,GAAc,GAAId,EAAS,WAAAT,EACvB,SAAAK,EAAYD,EAAOS,CAAI,EAC5B,EACAK,EAACM,GAAc,UAAU,eACrB,WAACC,EAAA,CAAa,WAAYf,EAAQ,cAAeC,EAC7C,SAAA,CAAAO,EAACQ,EAAA,CAAY,UAAW,MAAO,UAAS,GAAC,EACxCX,KACI,MAAA,CAAI,UAAU,UACX,SAAAG,EAACS,EAAA,CAAO,UAAU,SAAA,CAAU,CAAA,CAChC,EAEH,CAACZ,GAAc,CAACD,GACbI,EAACU,EAAA,CACI,GAAGtB,EACJ,UAAW,WACX,MAAOO,EACP,iBAAkB,IAAMK,EAAC,MAAA,CAAI,UAAU,cAAc,SAAA,oBAAiB,EAErE,SAAAW,GACGX,EAACY,EAAA,CAA0B,GAAID,EAAK,GAC/B,SAAAA,EAAK,IAAA,EADKA,EAAK,EAEpB,CAAA,CAAA,EAIXf,GAAWI,EAAC,MAAA,CAAI,UAAU,kCAAmC,WAAM,OAAA,CAAQ,CAAA,CAAA,CAChF,CAAA,CACJ,CAAA,CAAA,CAAA,EAER,CAAA,CACJ,CAER,CAqBO,SAASa,EAAsD,CAClE,GAAGzB,CACP,EAGG,CACC,OACIY,EAACxB,EAAA,CACG,aAAc,CAACY,EAAM,KAAK,EAC1B,kBAAmB0B,GAAK1B,EAAM,SAAS,MAAM,KAAK0B,CAAC,EAAE,UAAY,OAAOC,GAAM,QAAQ,EAAE,CAAC,CAAC,EAC1F,YAAa,CAACA,EAAGC,IAAMA,GAAG,KAAKC,GAAMA,EAAG,KAAOF,CAAC,GAAG,MAAQA,EAC3D,cAAc,SACb,GAAG3B,CAAA,CAAA,CAGhB,CAuBO,SAAS8B,EAAwD,CACpE,GAAG9B,CACP,EAGG,CACC,OACIY,EAACxB,EAAA,CACG,aAAcY,EAAM,MACpB,kBAAmB0B,GAAK1B,EAAM,SAAS,MAAM,KAAK0B,CAAC,EAAE,OAAOC,GAAK,OAAOA,GAAM,QAAQ,CAAC,EACvF,cAAc,WACd,YAAa,CAACA,EAAGC,IAAMD,GAAG,OAAUC,GAAG,KAAKC,GAAMA,EAAG,KAAOE,CAAE,GAAG,MAAQA,CAAE,EAAE,KAAK,GAAG,EACpF,GAAG/B,CAAA,CAAA,CAGhB,CAcO,SAASgC,GAAsB,CAClC,WAAAtC,EACA,GAAGM,CACP,EAA4F,CACxF,MAAMiC,EAAQC,EAAwB,CAAE,SAAUxC,EAAY,EAC9D,OACIkB,EAACa,EAAA,CACI,GAAGzB,EACJ,WAAYN,GAAcuC,EAAM,KAAK,MAAM,aAC3C,MAAOA,EAAM,MAAM,MACnB,OAAQE,GAAKF,EAAM,WAAA,EACnB,SAAUP,GAAKO,EAAM,aAAaP,CAAC,EACnC,aAAcU,EAAqBH,CAAK,CAAA,CAAA,CAGpD,CAcO,SAASI,GAAwB,CACpC,WAAA3C,EACA,GAAGM,CACP,EAAmF,CAC/E,MAAMiC,EAAQC,EAA0B,CAAE,SAAUxC,EAAY,EAChE,OACIkB,EAACkB,EAAA,CACI,GAAG9B,EACJ,WAAYN,GAAcuC,EAAM,KAAK,MAAM,aAC3C,MAAOA,EAAM,MAAM,MACnB,OAAQE,GAAKF,EAAM,WAAA,EACnB,SAAUP,GAAKO,EAAM,aAAaP,CAAC,EACnC,aAAcU,EAAqBH,CAAK,CAAA,CAAA,CAGpD"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as i}from"react/jsx-runtime";import{EasyMenu as
|
|
1
|
+
import{jsx as i}from"react/jsx-runtime";import{EasyMenu as d,MenuItem as p}from"./menu.js";import{getFieldErrorMessage as u}from"../utilities/form.js";import{useFieldContext as c}from"../utilities/form-context.js";import{FormField as f}from"./form.js";import"react-aria-components";import"../utilities/theme.js";import"clsx";import"./icons.js";import"react";import"./list-box.js";import"./select.js";import"./button.js";import"class-variance-authority";import"./loader.js";import"./popover.js";import"@tanstack/react-form";function g({items:o,value:e,onChange:t,label:n,errorMessage:s,description:a,requiredIndicator:m,...l}){return i("div",{className:"group form-field",children:i(f,{label:n,description:a,errorMessage:s,requiredIndicator:m,children:i(d,{isNonModal:!1,selectionMode:"multiple",selectedKeys:e,onSelectionChange:r=>{typeof r!="string"&&t(r)},items:o,label:l.triggerLabel??i("span",{className:"tabular-nums",children:e.size}),...l,children:r=>i(p,{id:r.id,isDisabled:r?.disabled,children:r.label},r.id)})})})}function I({...o}){const e=c({disabled:o.isDisabled});return i(g,{value:new Set(e.state.value),onChange:t=>e.setValue(Array.from(t)),onClose:e.handleBlur,errorMessage:u(e),...o})}export{g as MultiSelect,I as TfMultiSelect};
|
|
2
2
|
//# sourceMappingURL=multi-select.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-select.js","sources":["../../lib/components/multi-select.tsx"],"sourcesContent":["import React from 'react';\nimport { EasyMenu, MenuItem } from '../components/menu';\nimport type { SelectOption } from '../components/select-options';\nimport { getFieldErrorMessage } from '../utilities/form';\nimport { useFieldContext } from '../utilities/form-context';\nimport { FormField, type FormFieldProps } from './form';\n\ninterface MultipleSelectionProps {\n value: Set<string | number>;\n onChange: (v: Set<string | number>) => void;\n buttonLabel?: React.ReactNode;\n items: SelectOption[];\n}\n\nexport interface MultiSelectProps\n extends MultipleSelectionProps,\n FormFieldProps,\n Omit<React.ComponentProps<typeof EasyMenu>, 'label' | 'items'> {\n triggerLabel?: React.ReactNode;\n}\n\nexport function MultiSelect({\n items,\n value,\n onChange: setValue,\n label,\n errorMessage,\n description,\n requiredIndicator,\n ...props\n}: MultiSelectProps) {\n return (\n <div className=\"group form-field\">\n <FormField {...{ label, description, errorMessage, requiredIndicator }}>\n <EasyMenu\n isNonModal={false}\n selectionMode=\"multiple\"\n selectedKeys={value}\n onSelectionChange={v => {\n if (typeof v === 'string') return;\n setValue(v);\n }}\n items={items}\n label={props.triggerLabel ?? value.size}\n {...props}\n >\n {item => (\n <MenuItem id={item.id} key={item.id} isDisabled={item?.disabled}>\n {item.label}\n </MenuItem>\n )}\n </EasyMenu>\n </FormField>\n </div>\n );\n}\n\nexport interface TfMultiSelectProps extends Omit<MultiSelectProps, 'value' | 'onChange'> {}\nexport function TfMultiSelect({ ...props }: TfMultiSelectProps) {\n const field = useFieldContext<string[]>({\n disabled: props.isDisabled,\n });\n\n return (\n <MultiSelect\n value={new Set(field.state.value)}\n // @ts-expect-error\n onChange={e => field.setValue(Array.from(e))}\n onClose={field.handleBlur}\n errorMessage={getFieldErrorMessage(field)}\n {...props}\n />\n );\n}\n"],"names":["MultiSelect","items","value","setValue","label","errorMessage","description","requiredIndicator","props","jsx","FormField","EasyMenu","v","item","MenuItem","TfMultiSelect","field","useFieldContext","e","getFieldErrorMessage"],"mappings":"2gBAqBO,SAASA,EAAY,CACxB,MAAAC,EACA,MAAAC,EACA,SAAUC,EACV,MAAAC,EACA,aAAAC,EACA,YAAAC,EACA,kBAAAC,EACA,GAAGC,CACP,EAAqB,CACjB,OACIC,EAAC,MAAA,CAAI,UAAU,mBACX,SAAAA,EAACC,EAAA,CAAgB,MAAAN,EAAO,YAAAE,EAAa,aAAAD,EAAc,kBAAAE,EAC/C,SAAAE,EAACE,EAAA,CACG,WAAY,GACZ,cAAc,WACd,aAAcT,EACd,kBAAmBU,GAAK,CAChB,OAAOA,GAAM,UACjBT,EAASS,CAAC,CACd,EACA,MAAAX,EACA,MAAOO,EAAM,
|
|
1
|
+
{"version":3,"file":"multi-select.js","sources":["../../lib/components/multi-select.tsx"],"sourcesContent":["import React from 'react';\nimport { EasyMenu, MenuItem } from '../components/menu';\nimport type { SelectOption } from '../components/select-options';\nimport { getFieldErrorMessage } from '../utilities/form';\nimport { useFieldContext } from '../utilities/form-context';\nimport { FormField, type FormFieldProps } from './form';\n\ninterface MultipleSelectionProps {\n value: Set<string | number>;\n onChange: (v: Set<string | number>) => void;\n buttonLabel?: React.ReactNode;\n items: SelectOption[];\n}\n\nexport interface MultiSelectProps\n extends MultipleSelectionProps,\n FormFieldProps,\n Omit<React.ComponentProps<typeof EasyMenu>, 'label' | 'items'> {\n triggerLabel?: React.ReactNode;\n}\n\nexport function MultiSelect({\n items,\n value,\n onChange: setValue,\n label,\n errorMessage,\n description,\n requiredIndicator,\n ...props\n}: MultiSelectProps) {\n return (\n <div className=\"group form-field\">\n <FormField {...{ label, description, errorMessage, requiredIndicator }}>\n <EasyMenu\n isNonModal={false}\n selectionMode=\"multiple\"\n selectedKeys={value}\n onSelectionChange={v => {\n if (typeof v === 'string') return;\n setValue(v);\n }}\n items={items}\n label={props.triggerLabel ?? <span className=\"tabular-nums\">{value.size}</span>}\n {...props}\n >\n {item => (\n <MenuItem id={item.id} key={item.id} isDisabled={item?.disabled}>\n {item.label}\n </MenuItem>\n )}\n </EasyMenu>\n </FormField>\n </div>\n );\n}\n\nexport interface TfMultiSelectProps extends Omit<MultiSelectProps, 'value' | 'onChange'> {}\nexport function TfMultiSelect({ ...props }: TfMultiSelectProps) {\n const field = useFieldContext<string[]>({\n disabled: props.isDisabled,\n });\n\n return (\n <MultiSelect\n value={new Set(field.state.value)}\n // @ts-expect-error\n onChange={e => field.setValue(Array.from(e))}\n onClose={field.handleBlur}\n errorMessage={getFieldErrorMessage(field)}\n {...props}\n />\n );\n}\n"],"names":["MultiSelect","items","value","setValue","label","errorMessage","description","requiredIndicator","props","jsx","FormField","EasyMenu","v","item","MenuItem","TfMultiSelect","field","useFieldContext","e","getFieldErrorMessage"],"mappings":"2gBAqBO,SAASA,EAAY,CACxB,MAAAC,EACA,MAAAC,EACA,SAAUC,EACV,MAAAC,EACA,aAAAC,EACA,YAAAC,EACA,kBAAAC,EACA,GAAGC,CACP,EAAqB,CACjB,OACIC,EAAC,MAAA,CAAI,UAAU,mBACX,SAAAA,EAACC,EAAA,CAAgB,MAAAN,EAAO,YAAAE,EAAa,aAAAD,EAAc,kBAAAE,EAC/C,SAAAE,EAACE,EAAA,CACG,WAAY,GACZ,cAAc,WACd,aAAcT,EACd,kBAAmBU,GAAK,CAChB,OAAOA,GAAM,UACjBT,EAASS,CAAC,CACd,EACA,MAAAX,EACA,MAAOO,EAAM,cAAgBC,EAAC,QAAK,UAAU,eAAgB,WAAM,IAAA,CAAK,EACvE,GAAGD,EAEH,SAAAK,GACGJ,EAACK,EAAA,CAAS,GAAID,EAAK,GAAkB,WAAYA,GAAM,SAClD,SAAAA,EAAK,KAAA,EADkBA,EAAK,EAEjC,CAAA,CAAA,EAGZ,CAAA,CACJ,CAER,CAGO,SAASE,EAAc,CAAE,GAAGP,GAA6B,CAC5D,MAAMQ,EAAQC,EAA0B,CACpC,SAAUT,EAAM,UAAA,CACnB,EAED,OACIC,EAACT,EAAA,CACG,MAAO,IAAI,IAAIgB,EAAM,MAAM,KAAK,EAEhC,SAAUE,GAAKF,EAAM,SAAS,MAAM,KAAKE,CAAC,CAAC,EAC3C,QAASF,EAAM,WACf,aAAcG,EAAqBH,CAAK,EACvC,GAAGR,CAAA,CAAA,CAGhB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NumberFieldProps as AriaNumberFieldProps } from 'react-aria-components';
|
|
2
2
|
import { FormFieldProps } from './form';
|
|
3
|
-
type NumberFieldProps = AriaNumberFieldProps & FormFieldProps;
|
|
3
|
+
export type NumberFieldProps = AriaNumberFieldProps & FormFieldProps;
|
|
4
4
|
export declare function NumberField({ label, description, errorMessage, requiredIndicator, className, ...props }: NumberFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
5
5
|
export declare function TfNumberField({ isDisabled, ...props }: Omit<React.ComponentProps<typeof NumberField>, 'value' | 'id' | 'onChange' | 'onBlur'>): import("react/jsx-runtime").JSX.Element;
|
|
6
|
-
export {};
|
|
6
|
+
export declare function DaysField({ label, description, errorMessage, requiredIndicator, className, ...props }: NumberFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function TfDaysField({ isDisabled, ...props }: Omit<React.ComponentProps<typeof DaysField>, 'value' | 'id' | 'onChange' | 'onBlur'>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as r,jsxs as
|
|
1
|
+
import{jsx as r,jsxs as u}from"react/jsx-runtime";import{NumberField as F,composeRenderProps as m,Input as v}from"react-aria-components";import{Button as x}from"./button.js";import{getFieldErrorMessage as d}from"../utilities/form.js";import{useFieldContext as p}from"../utilities/form-context.js";import{classNames as s}from"../utilities/theme.js";import{FormField as f,FieldGroup as h}from"./form.js";import{IcUp as C,IcDown as w}from"./icons.js";import"class-variance-authority";import"./loader.js";import"clsx";import"react";import"@tanstack/react-form";const b=F;function N({className:t,...n}){return r(v,{className:m(t,e=>s("w-fit min-w-0 flex-1 border-r border-transparent bg-elevation-2 outline-0 placeholder:text-muted-foreground [&::-webkit-search-cancel-button]:hidden",e)),...n})}function D({className:t,...n}){return u("div",{className:s("absolute right-0 flex h-full flex-col border-l",t),...n,children:[r(c,{slot:"increment",children:r(C,{"aria-hidden":!0,className:"size-icon"})}),r("div",{className:"border-b"}),r(c,{slot:"decrement",children:r(w,{"aria-hidden":!0,className:"size-icon"})})]})}function c({className:t,...n}){return r(x,{className:m(t,e=>s("w-auto grow h-3 px-0.5 text-muted-foreground",e)),variant:"ghost",size:"none",...n})}function I({label:t,description:n,errorMessage:e,requiredIndicator:i,className:o,...l}){return r(b,{className:m(o,a=>s("group form-field",a)),...l,children:r(f,{label:t,description:n,errorMessage:e,requiredIndicator:i,children:u(h,{children:[r(N,{className:"pr-input"}),r(D,{})]})})})}function O({isDisabled:t,...n}){const e=p({disabled:t});return r(I,{isInvalid:!!d(e),isDisabled:t||e.form.state.isSubmitting,value:e.state.value,id:e.name,onChange:e.handleChange,onBlur:e.handleBlur,errorMessage:d(e),...n})}function S({label:t,description:n,errorMessage:e,requiredIndicator:i,className:o,...l}){return r(b,{className:m(o,a=>s("group form-field",a)),...l,children:r(f,{label:t,description:n,errorMessage:e,requiredIndicator:i,children:u(h,{children:[r(N,{className:"pr-input"}),r("div",{className:"absolute right-1 select-none text-muted",children:"days"})]})})})}function U({isDisabled:t,...n}){const e=p({disabled:t}),i=86400,o=e.state.value!=null?e.state.value/i:void 0,l=a=>{const g=a*i;e.handleChange(g)};return r(S,{isInvalid:!!d(e),isDisabled:t||e.form.state.isSubmitting,value:o,id:e.name,onChange:l,onBlur:e.handleBlur,errorMessage:d(e),...n})}export{S as DaysField,I as NumberField,U as TfDaysField,O as TfNumberField};
|
|
2
2
|
//# sourceMappingURL=numberfield.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numberfield.js","sources":["../../lib/components/numberfield.tsx"],"sourcesContent":["import {\n ButtonProps as AriaButtonProps,\n Input as AriaInput,\n InputProps as AriaInputProps,\n NumberField as AriaNumberField,\n NumberFieldProps as AriaNumberFieldProps,\n composeRenderProps,\n} from 'react-aria-components';\n\nimport { Button } from '../components/button';\nimport { getFieldErrorMessage } from '../utilities/form';\nimport { useFieldContext } from '../utilities/form-context';\nimport { classNames } from '../utilities/theme';\nimport { FieldGroup, FormField, type FormFieldProps } from './form';\nimport { IcDown, IcUp } from './icons';\n\nconst ANumberField = AriaNumberField;\n\nfunction NumberFieldInput({ className, ...props }: AriaInputProps) {\n return (\n <AriaInput\n className={composeRenderProps(className, className =>\n classNames(\n 'w-fit min-w-0 flex-1 border-r border-transparent bg-elevation-2
|
|
1
|
+
{"version":3,"file":"numberfield.js","sources":["../../lib/components/numberfield.tsx"],"sourcesContent":["import {\n ButtonProps as AriaButtonProps,\n Input as AriaInput,\n InputProps as AriaInputProps,\n NumberField as AriaNumberField,\n NumberFieldProps as AriaNumberFieldProps,\n composeRenderProps,\n} from 'react-aria-components';\n\nimport { Button } from '../components/button';\nimport { getFieldErrorMessage } from '../utilities/form';\nimport { useFieldContext } from '../utilities/form-context';\nimport { classNames } from '../utilities/theme';\nimport { FieldGroup, FormField, type FormFieldProps } from './form';\nimport { IcDown, IcUp } from './icons';\n\nconst ANumberField = AriaNumberField;\n\nfunction NumberFieldInput({ className, ...props }: AriaInputProps) {\n return (\n <AriaInput\n className={composeRenderProps(className, className =>\n classNames(\n 'w-fit min-w-0 flex-1 border-r border-transparent bg-elevation-2 outline-0 placeholder:text-muted-foreground [&::-webkit-search-cancel-button]:hidden',\n className\n )\n )}\n {...props}\n />\n );\n}\n\nfunction NumberFieldSteppers({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div className={classNames('absolute right-0 flex h-full flex-col border-l', className)} {...props}>\n <NumberFieldStepper slot=\"increment\">\n <IcUp aria-hidden className=\"size-icon\" />\n </NumberFieldStepper>\n <div className=\"border-b\" />\n <NumberFieldStepper slot=\"decrement\">\n <IcDown aria-hidden className=\"size-icon\" />\n </NumberFieldStepper>\n </div>\n );\n}\n\nfunction NumberFieldStepper({ className, ...props }: AriaButtonProps) {\n return (\n <Button\n className={composeRenderProps(className, className =>\n classNames('w-auto grow h-3 px-0.5 text-muted-foreground', className)\n )}\n variant={'ghost'}\n size={'none'}\n {...props}\n />\n );\n}\n\nexport type NumberFieldProps = AriaNumberFieldProps & FormFieldProps;\nexport function NumberField({\n label,\n description,\n errorMessage,\n requiredIndicator,\n className,\n ...props\n}: NumberFieldProps) {\n return (\n <ANumberField\n className={composeRenderProps(className, className => classNames('group form-field', className))}\n {...props}\n >\n <FormField {...{ label, description, errorMessage, requiredIndicator }}>\n <FieldGroup>\n <NumberFieldInput className={'pr-input'} />\n <NumberFieldSteppers />\n </FieldGroup>\n </FormField>\n </ANumberField>\n );\n}\n\nexport function TfNumberField({\n isDisabled,\n ...props\n}: Omit<React.ComponentProps<typeof NumberField>, 'value' | 'id' | 'onChange' | 'onBlur'>) {\n const field = useFieldContext<number>({ disabled: isDisabled });\n\n return (\n <NumberField\n isInvalid={!!getFieldErrorMessage(field)}\n isDisabled={isDisabled || field.form.state.isSubmitting}\n value={field.state.value}\n id={field.name}\n onChange={field.handleChange}\n onBlur={field.handleBlur}\n errorMessage={getFieldErrorMessage(field)}\n {...props}\n />\n );\n}\n\nexport function DaysField({\n label,\n description,\n errorMessage,\n requiredIndicator,\n className,\n ...props\n}: NumberFieldProps) {\n return (\n <ANumberField\n className={composeRenderProps(className, className => classNames('group form-field', className))}\n {...props}\n >\n <FormField {...{ label, description, errorMessage, requiredIndicator }}>\n <FieldGroup>\n <NumberFieldInput className={'pr-input'} />\n <div className=\"absolute right-1 select-none text-muted\">days</div>\n </FieldGroup>\n </FormField>\n </ANumberField>\n );\n}\n\nexport function TfDaysField({\n isDisabled,\n ...props\n}: Omit<React.ComponentProps<typeof DaysField>, 'value' | 'id' | 'onChange' | 'onBlur'>) {\n const field = useFieldContext<number>({ disabled: isDisabled });\n\n const SECONDS_PER_DAY = 86400; // 24 * 60 * 60\n\n // Convert seconds to days for display\n const daysValue = field.state.value != null ? field.state.value / SECONDS_PER_DAY : undefined;\n\n // Convert days to seconds when value changes\n const handleDaysChange = (days: number) => {\n const seconds = days * SECONDS_PER_DAY;\n field.handleChange(seconds);\n };\n\n return (\n <DaysField\n isInvalid={!!getFieldErrorMessage(field)}\n isDisabled={isDisabled || field.form.state.isSubmitting}\n value={daysValue}\n id={field.name}\n onChange={handleDaysChange}\n onBlur={field.handleBlur}\n errorMessage={getFieldErrorMessage(field)}\n {...props}\n />\n );\n}\n"],"names":["ANumberField","AriaNumberField","NumberFieldInput","className","props","jsx","AriaInput","composeRenderProps","classNames","NumberFieldSteppers","jsxs","NumberFieldStepper","IcUp","IcDown","Button","NumberField","label","description","errorMessage","requiredIndicator","FormField","FieldGroup","TfNumberField","isDisabled","field","useFieldContext","getFieldErrorMessage","DaysField","TfDaysField","SECONDS_PER_DAY","daysValue","handleDaysChange","days","seconds"],"mappings":"6iBAgBA,MAAMA,EAAeC,EAErB,SAASC,EAAiB,CAAE,UAAAC,EAAW,GAAGC,GAAyB,CAC/D,OACIC,EAACC,EAAA,CACG,UAAWC,EAAmBJ,EAAWA,GACrCK,EACI,uJACAL,CAAA,CACJ,EAEH,GAAGC,CAAA,CAAA,CAGhB,CAEA,SAASK,EAAoB,CAAE,UAAAN,EAAW,GAAGC,GAAsC,CAC/E,OACIM,EAAC,OAAI,UAAWF,EAAW,iDAAkDL,CAAS,EAAI,GAAGC,EACzF,SAAA,CAAAC,EAACM,EAAA,CAAmB,KAAK,YACrB,SAAAN,EAACO,GAAK,cAAW,GAAC,UAAU,WAAA,CAAY,CAAA,CAC5C,EACAP,EAAC,MAAA,CAAI,UAAU,UAAA,CAAW,EAC1BA,EAACM,EAAA,CAAmB,KAAK,YACrB,SAAAN,EAACQ,GAAO,cAAW,GAAC,UAAU,WAAA,CAAY,CAAA,CAC9C,CAAA,EACJ,CAER,CAEA,SAASF,EAAmB,CAAE,UAAAR,EAAW,GAAGC,GAA0B,CAClE,OACIC,EAACS,EAAA,CACG,UAAWP,EAAmBJ,EAAWA,GACrCK,EAAW,+CAAgDL,CAAS,CAAA,EAExE,QAAS,QACT,KAAM,OACL,GAAGC,CAAA,CAAA,CAGhB,CAGO,SAASW,EAAY,CACxB,MAAAC,EACA,YAAAC,EACA,aAAAC,EACA,kBAAAC,EACA,UAAAhB,EACA,GAAGC,CACP,EAAqB,CACjB,OACIC,EAACL,EAAA,CACG,UAAWO,EAAmBJ,EAAWA,GAAaK,EAAW,mBAAoBL,CAAS,CAAC,EAC9F,GAAGC,EAEJ,SAAAC,EAACe,EAAA,CAAgB,MAAAJ,EAAO,YAAAC,EAAa,aAAAC,EAAc,kBAAAC,EAC/C,SAAAT,EAACW,EAAA,CACG,SAAA,CAAAhB,EAACH,EAAA,CAAiB,UAAW,UAAA,CAAY,IACxCO,EAAA,CAAA,CAAoB,CAAA,CAAA,CACzB,CAAA,CACJ,CAAA,CAAA,CAGZ,CAEO,SAASa,EAAc,CAC1B,WAAAC,EACA,GAAGnB,CACP,EAA2F,CACvF,MAAMoB,EAAQC,EAAwB,CAAE,SAAUF,EAAY,EAE9D,OACIlB,EAACU,EAAA,CACG,UAAW,CAAC,CAACW,EAAqBF,CAAK,EACvC,WAAYD,GAAcC,EAAM,KAAK,MAAM,aAC3C,MAAOA,EAAM,MAAM,MACnB,GAAIA,EAAM,KACV,SAAUA,EAAM,aAChB,OAAQA,EAAM,WACd,aAAcE,EAAqBF,CAAK,EACvC,GAAGpB,CAAA,CAAA,CAGhB,CAEO,SAASuB,EAAU,CACtB,MAAAX,EACA,YAAAC,EACA,aAAAC,EACA,kBAAAC,EACA,UAAAhB,EACA,GAAGC,CACP,EAAqB,CACjB,OACIC,EAACL,EAAA,CACG,UAAWO,EAAmBJ,EAAWA,GAAaK,EAAW,mBAAoBL,CAAS,CAAC,EAC9F,GAAGC,EAEJ,SAAAC,EAACe,EAAA,CAAgB,MAAAJ,EAAO,YAAAC,EAAa,aAAAC,EAAc,kBAAAC,EAC/C,SAAAT,EAACW,EAAA,CACG,SAAA,CAAAhB,EAACH,EAAA,CAAiB,UAAW,UAAA,CAAY,EACzCG,EAAC,MAAA,CAAI,UAAU,0CAA0C,SAAA,MAAA,CAAI,CAAA,CAAA,CACjE,CAAA,CACJ,CAAA,CAAA,CAGZ,CAEO,SAASuB,EAAY,CACxB,WAAAL,EACA,GAAGnB,CACP,EAAyF,CACrF,MAAMoB,EAAQC,EAAwB,CAAE,SAAUF,EAAY,EAExDM,EAAkB,MAGlBC,EAAYN,EAAM,MAAM,OAAS,KAAOA,EAAM,MAAM,MAAQK,EAAkB,OAG9EE,EAAoBC,GAAiB,CACvC,MAAMC,EAAUD,EAAOH,EACvBL,EAAM,aAAaS,CAAO,CAC9B,EAEA,OACI5B,EAACsB,EAAA,CACG,UAAW,CAAC,CAACD,EAAqBF,CAAK,EACvC,WAAYD,GAAcC,EAAM,KAAK,MAAM,aAC3C,MAAOM,EACP,GAAIN,EAAM,KACV,SAAUO,EACV,OAAQP,EAAM,WACd,aAAcE,EAAqBF,CAAK,EACvC,GAAGpB,CAAA,CAAA,CAGhB"}
|
package/dist/components/toast.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as t,jsxs as r}from"react/jsx-runtime";import{UNSTABLE_ToastQueue as a,UNSTABLE_ToastRegion as l,UNSTABLE_Toast as m,UNSTABLE_ToastContent as d}from"react-aria-components";import{flushSync as u}from"react-dom";import{classNames as p}from"../utilities/theme.js";import{alertVariants as f}from"./alert.js";import{Button as h}from"./button.js";import{IcInfo as i,IcCheck as T,IcError as v}from"./icons.js";import"clsx";import"class-variance-authority";import"./loader.js";
|
|
1
|
+
import{jsx as t,jsxs as r}from"react/jsx-runtime";import{UNSTABLE_ToastQueue as a,UNSTABLE_ToastRegion as l,UNSTABLE_Toast as m,UNSTABLE_ToastContent as d}from"react-aria-components";import{flushSync as u}from"react-dom";import{classNames as p}from"../utilities/theme.js";import{alertVariants as f}from"./alert.js";import{Button as h}from"./button.js";import{IcInfo as i,IcCheck as T,IcError as v}from"./icons.js";import"clsx";import"class-variance-authority";import"react";import"./loader.js";const n=new a({wrapUpdate(e){"startViewTransition"in document?document.startViewTransition(()=>{u(e)}):e()}});function _(){return t(l,{queue:n,className:"fixed z-50 top-4 right-4 flex flex-col-reverse justify-end gap-2",children:({toast:e})=>t(m,{style:{viewTransitionName:e.key},toast:e,children:r(d,{className:p(f({variant:e.content.variant}),"flex flex-row items-center gap-2 w-full"),children:[t("div",{className:"shrink-0",children:N(e.content.variant)}),r("div",{className:"flex-1 min-w-0",children:[t("p",{slot:"title",children:e.content.title}),e.content.description&&t("p",{slot:"description",children:e.content.description})]}),t(h,{slot:"close",variant:"neutral",children:"Close"})]})})})}function N(e){switch(e){case"destructive":return t(v,{});case"success":return t(T,{});case"muted":return t(i,{});default:return t(i,{})}}function j({title:e,description:o,variant:s,timeout:c}){n.add({title:e,description:o,variant:s},{timeout:c??2e3})}export{_ as ToastProvider,j as toast};
|
|
2
2
|
//# sourceMappingURL=toast.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { default as z } from 'zod';
|
|
2
|
+
export declare const MAX_INT32 = 2147483647;
|
|
3
|
+
export declare const MAX_INT32_DAYS: number;
|
|
4
|
+
export declare const MIN_INT32 = -2147483648;
|
|
5
|
+
export declare const MIN_INT32_DAYS: number;
|
|
6
|
+
export declare function getNumberValidator(min: number, max: number): z.ZodNumber;
|
|
7
|
+
export declare function getDaysValidator(min: number): z.ZodNumber;
|
|
1
8
|
export declare function formatNumber(num: number | bigint): string;
|
|
2
9
|
/**
|
|
3
10
|
* @returns A formatted string for the number of bytes
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function e(r){return Intl.NumberFormat(navigator.language).format(r)}function
|
|
1
|
+
import n from"zod";const u=2147483647,i=Math.floor(u/86400),a=-2147483648,l=Math.ceil(a/86400);function m(r,e){return n.number().min(r,{error:t=>{if(t.code==="too_small")return`The number must be at least ${o(r)}.`}}).max(e,{error:t=>{if(t.code==="too_big")return`The number must be at most ${o(e)}.`}})}function c(r){return m(r,i)}function o(r){return Intl.NumberFormat(navigator.language).format(r)}function N(r){return r<1024?`${r} B`:r<1024*1024?`${(r/1024).toFixed(1)} KB`:r<1024*1024*1024?`${(r/(1024*1024)).toFixed(2)} MB`:`${(r/(1024*1024*1024)).toFixed(2)} GB`}export{u as MAX_INT32,i as MAX_INT32_DAYS,a as MIN_INT32,l as MIN_INT32_DAYS,N as formatFilesize,o as formatNumber,c as getDaysValidator,m as getNumberValidator};
|
|
2
2
|
//# sourceMappingURL=numbers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numbers.js","sources":["../../lib/utilities/numbers.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"numbers.js","sources":["../../lib/utilities/numbers.ts"],"sourcesContent":["import z from 'zod';\n\nexport const MAX_INT32 = 2147483647;\nexport const MAX_INT32_DAYS = Math.floor(MAX_INT32 / 86400);\nexport const MIN_INT32 = -2147483648;\nexport const MIN_INT32_DAYS = Math.ceil(MIN_INT32 / 86400);\n\nexport function getNumberValidator(min: number, max: number) {\n return z\n .number()\n .min(min, {\n error: issue => {\n if (issue.code === 'too_small') return `The number must be at least ${formatNumber(min)}.`;\n },\n })\n .max(max, {\n error: issue => {\n if (issue.code === 'too_big') return `The number must be at most ${formatNumber(max)}.`;\n },\n });\n}\n\nexport function getDaysValidator(min: number) {\n return getNumberValidator(min, MAX_INT32_DAYS);\n}\n\nexport function formatNumber(num: number | bigint) {\n return Intl.NumberFormat(navigator.language).format(num);\n}\n\n/**\n * @returns A formatted string for the number of bytes\n */\nexport function formatFilesize(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n } else if (bytes < 1024 * 1024) {\n return `${(bytes / 1024).toFixed(1)} KB`;\n } else if (bytes < 1024 * 1024 * 1024) {\n return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;\n } else {\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n }\n}\n"],"names":["MAX_INT32","MAX_INT32_DAYS","MIN_INT32","MIN_INT32_DAYS","getNumberValidator","min","max","z","issue","formatNumber","getDaysValidator","num","formatFilesize","bytes"],"mappings":"mBAEO,MAAMA,EAAY,WACZC,EAAiB,KAAK,MAAMD,EAAY,KAAK,EAC7CE,EAAY,YACZC,EAAiB,KAAK,KAAKD,EAAY,KAAK,EAElD,SAASE,EAAmBC,EAAaC,EAAa,CACzD,OAAOC,EACF,SACA,IAAIF,EAAK,CACN,MAAOG,GAAS,CACZ,GAAIA,EAAM,OAAS,kBAAoB,+BAA+BC,EAAaJ,CAAG,CAAC,GAC3F,CAAA,CACH,EACA,IAAIC,EAAK,CACN,MAAOE,GAAS,CACZ,GAAIA,EAAM,OAAS,gBAAkB,8BAA8BC,EAAaH,CAAG,CAAC,GACxF,CAAA,CACH,CACT,CAEO,SAASI,EAAiBL,EAAa,CAC1C,OAAOD,EAAmBC,EAAKJ,CAAc,CACjD,CAEO,SAASQ,EAAaE,EAAsB,CAC/C,OAAO,KAAK,aAAa,UAAU,QAAQ,EAAE,OAAOA,CAAG,CAC3D,CAKO,SAASC,EAAeC,EAAuB,CAClD,OAAIA,EAAQ,KACD,GAAGA,CAAK,KACRA,EAAQ,KAAO,KACf,IAAIA,EAAQ,MAAM,QAAQ,CAAC,CAAC,MAC5BA,EAAQ,KAAO,KAAO,KACtB,IAAIA,GAAS,KAAO,OAAO,QAAQ,CAAC,CAAC,MAErC,IAAIA,GAAS,KAAO,KAAO,OAAO,QAAQ,CAAC,CAAC,KAE3D"}
|