@vritti/quantum-ui 0.5.7 → 0.5.8
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/CurrencyField.js +15 -3
- package/dist/CurrencyField.js.map +1 -1
- package/dist/lib/components/CurrencyField/CurrencyField.d.ts +1 -0
- package/dist/lib/components/CurrencyField/CurrencyField.d.ts.map +1 -1
- package/dist/lib/utils/zod.d.ts +1 -0
- package/dist/lib/utils/zod.d.ts.map +1 -1
- package/dist/utils/zod.js +7 -2
- package/dist/utils/zod.js.map +1 -1
- package/package.json +1 -1
package/dist/CurrencyField.js
CHANGED
|
@@ -21,12 +21,17 @@ function stepForDecimals(decimals) {
|
|
|
21
21
|
if (decimals <= 0) return "1";
|
|
22
22
|
return `0.${"0".repeat(decimals - 1)}1`;
|
|
23
23
|
}
|
|
24
|
+
function currencyOptions(currencies) {
|
|
25
|
+
if (!currencies) return CURRENCIES;
|
|
26
|
+
return currencies.map((code) => CURRENCIES.find((option) => option.value === code) ?? { value: code, label: code });
|
|
27
|
+
}
|
|
24
28
|
const CurrencyField = React__default.forwardRef(
|
|
25
29
|
({
|
|
26
30
|
name: _name,
|
|
27
31
|
value,
|
|
28
32
|
onChange,
|
|
29
33
|
currencyCode,
|
|
34
|
+
currencies,
|
|
30
35
|
defaultCurrencyCode = "USD",
|
|
31
36
|
label,
|
|
32
37
|
description,
|
|
@@ -39,8 +44,10 @@ const CurrencyField = React__default.forwardRef(
|
|
|
39
44
|
}, ref) => {
|
|
40
45
|
const fieldId = React__default.useId();
|
|
41
46
|
const hasError = !!error;
|
|
42
|
-
const isLocked = !!currencyCode;
|
|
43
|
-
const
|
|
47
|
+
const isLocked = !!currencyCode || currencies?.length === 1;
|
|
48
|
+
const options = React__default.useMemo(() => currencyOptions(currencies), [currencies]);
|
|
49
|
+
const fallbackCurrency = currencies && currencies.length > 0 && !currencies.includes(defaultCurrencyCode) ? currencies[0] : defaultCurrencyCode;
|
|
50
|
+
const initialCurrency = value?.currency ?? currencyCode ?? fallbackCurrency ?? "USD";
|
|
44
51
|
const [currency, setCurrency] = React__default.useState(initialCurrency);
|
|
45
52
|
const [amount, setAmount] = React__default.useState(value?.value ?? "");
|
|
46
53
|
React__default.useEffect(() => {
|
|
@@ -56,6 +63,11 @@ const CurrencyField = React__default.forwardRef(
|
|
|
56
63
|
setCurrency(currencyCode);
|
|
57
64
|
}
|
|
58
65
|
}, [currencyCode]);
|
|
66
|
+
React__default.useEffect(() => {
|
|
67
|
+
if (!currencyCode && currencies && currencies.length > 0 && !currencies.includes(currency)) {
|
|
68
|
+
setCurrency(currencies[0]);
|
|
69
|
+
}
|
|
70
|
+
}, [currencyCode, currencies?.join(",")]);
|
|
59
71
|
const decimals = getCurrencyExponent(currency);
|
|
60
72
|
const step = stepForDecimals(decimals);
|
|
61
73
|
const emit = React__default.useCallback(
|
|
@@ -126,7 +138,7 @@ const CurrencyField = React__default.forwardRef(
|
|
|
126
138
|
) : /* @__PURE__ */ jsx("div", { className: "flex items-center border-r border-input", children: /* @__PURE__ */ jsx(
|
|
127
139
|
Select,
|
|
128
140
|
{
|
|
129
|
-
options
|
|
141
|
+
options,
|
|
130
142
|
searchable: true,
|
|
131
143
|
placeholder: "Select currency",
|
|
132
144
|
value: currency,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CurrencyField.js","sources":["../lib/components/CurrencyField/CurrencyField.tsx"],"sourcesContent":["import { ChevronDown } from 'lucide-react';\nimport React from 'react';\nimport { Field, FieldContent, FieldDescription, FieldError, FieldLabel } from '../../../shadcn/shadcnField';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../../shadcn/shadcnTooltip';\nimport { cn } from '../../../shadcn/utils';\nimport { CURRENCIES } from '../../selects/currency/currencies';\nimport { type CurrencyValue, getCurrencyExponent } from '../../utils/currency';\nimport { Select, type SelectValue } from '../Select';\n\nexport interface CurrencyFieldProps {\n name?: string;\n\n value?: CurrencyValue;\n\n onChange?: (value: CurrencyValue) => void;\n\n currencyCode?: string;\n\n defaultCurrencyCode?: string;\n\n label?: React.ReactNode;\n\n description?: React.ReactNode;\n\n error?: React.ReactNode;\n\n disabled?: boolean;\n\n disabledTip?: string;\n\n placeholder?: string;\n\n className?: string;\n\n required?: boolean;\n}\n\n// Truncates an amount string to at most `decimals` fractional digits\nfunction truncateDecimals(amount: string, decimals: number): string {\n if (amount === '') return amount;\n if (!Number.isFinite(Number(amount))) return amount;\n const [whole, fraction] = amount.split('.');\n if (decimals === 0) return whole ?? '';\n if (fraction === undefined) return amount;\n if (fraction.length <= decimals) return amount;\n return `${whole}.${fraction.slice(0, decimals)}`;\n}\n\n// Returns the `step` attribute for an input given a currency exponent\nfunction stepForDecimals(decimals: number): string {\n if (decimals <= 0) return '1';\n return `0.${'0'.repeat(decimals - 1)}1`;\n}\n\n// Currency-aware money input combining a currency selector with an exponent-aware amount input\nexport const CurrencyField = React.forwardRef<HTMLInputElement, CurrencyFieldProps>(\n (\n {\n name: _name,\n value,\n onChange,\n currencyCode,\n defaultCurrencyCode = 'USD',\n label,\n description,\n error,\n disabled,\n disabledTip,\n placeholder,\n className,\n required,\n },\n ref,\n ) => {\n const fieldId = React.useId();\n const hasError = !!error;\n const isLocked = !!currencyCode;\n\n const initialCurrency = value?.currency ?? currencyCode ?? defaultCurrencyCode ?? 'USD';\n const [currency, setCurrency] = React.useState<string>(initialCurrency);\n const [amount, setAmount] = React.useState<string>(value?.value ?? '');\n\n // Sync with external controlled value changes\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentionally omitting internal state to avoid feedback loops\n React.useEffect(() => {\n if (value?.currency !== undefined && value.currency !== currency) {\n setCurrency(value.currency);\n }\n if (value?.value !== undefined && value.value !== amount) {\n setAmount(value.value);\n }\n }, [value?.currency, value?.value]);\n\n // If currencyCode prop changes while locked, reflect it\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentionally omitting internal state to avoid feedback loops\n React.useEffect(() => {\n if (currencyCode && currencyCode !== currency) {\n setCurrency(currencyCode);\n }\n }, [currencyCode]);\n\n const decimals = getCurrencyExponent(currency);\n const step = stepForDecimals(decimals);\n\n const emit = React.useCallback(\n (nextCurrency: string, nextAmount: string) => {\n onChange?.({ currency: nextCurrency, value: nextAmount });\n },\n [onChange],\n );\n\n const handleCurrencyChange = React.useCallback(\n (nextValue: SelectValue) => {\n if (nextValue == null) return;\n const nextCurrency = String(nextValue);\n const nextDecimals = getCurrencyExponent(nextCurrency);\n const truncated = truncateDecimals(amount, nextDecimals);\n setCurrency(nextCurrency);\n if (truncated !== amount) setAmount(truncated);\n emit(nextCurrency, truncated);\n },\n [amount, emit],\n );\n\n const handleAmountChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const raw = event.target.value;\n // Allow empty, digits, and a single decimal separator; cap fractional digits\n if (raw === '') {\n setAmount('');\n emit(currency, '');\n return;\n }\n // Strict numeric pattern -- reject anything else silently\n if (!/^\\d*\\.?\\d*$/.test(raw)) return;\n const truncated = truncateDecimals(raw, decimals);\n setAmount(truncated);\n emit(currency, truncated);\n },\n [currency, decimals, emit],\n );\n\n const handleAmountBlur = React.useCallback(() => {\n if (amount === '' || amount === '.') return;\n const parsed = Number(amount);\n if (!Number.isFinite(parsed)) return;\n const snapped = parsed.toFixed(decimals);\n if (snapped !== amount) {\n setAmount(snapped);\n emit(currency, snapped);\n }\n }, [amount, currency, decimals, emit]);\n\n const field = (\n <Field data-disabled={disabled}>\n {label && <FieldLabel htmlFor={fieldId}>{label}</FieldLabel>}\n\n <FieldContent>\n <div\n className={cn(\n 'flex h-9 w-full items-stretch rounded-md border border-input bg-transparent dark:bg-input/30 shadow-xs transition-[color,box-shadow]',\n 'focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[1px]',\n disabled && 'opacity-50 cursor-not-allowed pointer-events-none',\n hasError && 'border-destructive focus-within:ring-destructive/20 dark:focus-within:ring-destructive/40',\n className,\n )}\n >\n {isLocked ? (\n <span\n role=\"img\"\n aria-label={`Currency ${currency}`}\n className=\"flex items-center justify-center border-r border-input px-3 text-sm font-medium text-muted-foreground select-none\"\n >\n {currency}\n </span>\n ) : (\n <div className=\"flex items-center border-r border-input\">\n <Select\n options={CURRENCIES}\n searchable\n placeholder=\"Select currency\"\n value={currency}\n onChange={handleCurrencyChange}\n disabled={disabled}\n clearable={false}\n label=\"\"\n contentClassName=\"min-w-[280px] w-auto\"\n anchor={({ selectedOption, open, disabled: anchorDisabled }) => (\n <button\n type=\"button\"\n disabled={anchorDisabled}\n aria-label=\"Select currency\"\n aria-expanded={open}\n className={cn(\n 'flex h-full items-center gap-1 px-3 text-sm font-medium text-foreground outline-none',\n 'hover:bg-accent/50 focus-visible:bg-accent/50',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n )}\n >\n <span>{selectedOption ? String(selectedOption.value) : currency}</span>\n <ChevronDown\n className={cn('size-3.5 text-muted-foreground transition-transform', open && 'rotate-180')}\n />\n </button>\n )}\n />\n </div>\n )}\n\n <input\n ref={ref}\n id={fieldId}\n type=\"text\"\n inputMode=\"decimal\"\n pattern=\"^[0-9]*\\.?[0-9]*$\"\n step={step}\n value={amount}\n onChange={handleAmountChange}\n onBlur={handleAmountBlur}\n disabled={disabled}\n required={required}\n placeholder={placeholder}\n aria-invalid={hasError}\n aria-describedby={description || error ? `${fieldId}-description ${fieldId}-error` : undefined}\n className={cn(\n 'flex-1 min-w-0 bg-transparent px-3 py-1 text-sm outline-none',\n 'placeholder:text-muted-foreground',\n 'disabled:cursor-not-allowed',\n )}\n />\n </div>\n\n {description && !error && <FieldDescription id={`${fieldId}-description`}>{description}</FieldDescription>}\n {error && <FieldError id={`${fieldId}-error`}>{error}</FieldError>}\n </FieldContent>\n </Field>\n );\n\n if (!disabledTip || !disabled) {\n return field;\n }\n\n return (\n <TooltipProvider>\n <Tooltip>\n {/* Disabled inputs don't emit hover/focus events, so the trigger lives on a wrapper. */}\n <TooltipTrigger asChild>\n <span className=\"inline-flex w-full cursor-not-allowed\">{field}</span>\n </TooltipTrigger>\n <TooltipContent>{disabledTip}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n },\n);\n\nCurrencyField.displayName = 'CurrencyField';\n"],"names":["React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CurrencyField.js","sources":["../lib/components/CurrencyField/CurrencyField.tsx"],"sourcesContent":["import { ChevronDown } from 'lucide-react';\nimport React from 'react';\nimport { Field, FieldContent, FieldDescription, FieldError, FieldLabel } from '../../../shadcn/shadcnField';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../../shadcn/shadcnTooltip';\nimport { cn } from '../../../shadcn/utils';\nimport { CURRENCIES } from '../../selects/currency/currencies';\nimport { type CurrencyValue, getCurrencyExponent } from '../../utils/currency';\nimport { Select, type SelectOption, type SelectValue } from '../Select';\n\nexport interface CurrencyFieldProps {\n name?: string;\n\n value?: CurrencyValue;\n\n onChange?: (value: CurrencyValue) => void;\n\n currencyCode?: string;\n\n currencies?: string[];\n\n defaultCurrencyCode?: string;\n\n label?: React.ReactNode;\n\n description?: React.ReactNode;\n\n error?: React.ReactNode;\n\n disabled?: boolean;\n\n disabledTip?: string;\n\n placeholder?: string;\n\n className?: string;\n\n required?: boolean;\n}\n\n// Truncates an amount string to at most `decimals` fractional digits\nfunction truncateDecimals(amount: string, decimals: number): string {\n if (amount === '') return amount;\n if (!Number.isFinite(Number(amount))) return amount;\n const [whole, fraction] = amount.split('.');\n if (decimals === 0) return whole ?? '';\n if (fraction === undefined) return amount;\n if (fraction.length <= decimals) return amount;\n return `${whole}.${fraction.slice(0, decimals)}`;\n}\n\n// Returns the `step` attribute for an input given a currency exponent\nfunction stepForDecimals(decimals: number): string {\n if (decimals <= 0) return '1';\n return `0.${'0'.repeat(decimals - 1)}1`;\n}\n\n// The selectable currencies, in the caller's order; a code missing from the ISO list still appears as itself\nfunction currencyOptions(currencies?: string[]): SelectOption[] {\n if (!currencies) return CURRENCIES;\n return currencies.map((code) => CURRENCIES.find((option) => option.value === code) ?? { value: code, label: code });\n}\n\n// Currency-aware money input combining a currency selector with an exponent-aware amount input\nexport const CurrencyField = React.forwardRef<HTMLInputElement, CurrencyFieldProps>(\n (\n {\n name: _name,\n value,\n onChange,\n currencyCode,\n currencies,\n defaultCurrencyCode = 'USD',\n label,\n description,\n error,\n disabled,\n disabledTip,\n placeholder,\n className,\n required,\n },\n ref,\n ) => {\n const fieldId = React.useId();\n const hasError = !!error;\n const isLocked = !!currencyCode || currencies?.length === 1;\n const options = React.useMemo(() => currencyOptions(currencies), [currencies]);\n const fallbackCurrency =\n currencies && currencies.length > 0 && !currencies.includes(defaultCurrencyCode)\n ? currencies[0]\n : defaultCurrencyCode;\n\n const initialCurrency = value?.currency ?? currencyCode ?? fallbackCurrency ?? 'USD';\n const [currency, setCurrency] = React.useState<string>(initialCurrency);\n const [amount, setAmount] = React.useState<string>(value?.value ?? '');\n\n // Sync with external controlled value changes\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentionally omitting internal state to avoid feedback loops\n React.useEffect(() => {\n if (value?.currency !== undefined && value.currency !== currency) {\n setCurrency(value.currency);\n }\n if (value?.value !== undefined && value.value !== amount) {\n setAmount(value.value);\n }\n }, [value?.currency, value?.value]);\n\n // If currencyCode prop changes while locked, reflect it\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentionally omitting internal state to avoid feedback loops\n React.useEffect(() => {\n if (currencyCode && currencyCode !== currency) {\n setCurrency(currencyCode);\n }\n }, [currencyCode]);\n\n // A narrowed list that no longer holds the current currency moves it to the first one allowed\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentionally omitting internal state to avoid feedback loops\n React.useEffect(() => {\n if (!currencyCode && currencies && currencies.length > 0 && !currencies.includes(currency)) {\n setCurrency(currencies[0]);\n }\n }, [currencyCode, currencies?.join(',')]);\n\n const decimals = getCurrencyExponent(currency);\n const step = stepForDecimals(decimals);\n\n const emit = React.useCallback(\n (nextCurrency: string, nextAmount: string) => {\n onChange?.({ currency: nextCurrency, value: nextAmount });\n },\n [onChange],\n );\n\n const handleCurrencyChange = React.useCallback(\n (nextValue: SelectValue) => {\n if (nextValue == null) return;\n const nextCurrency = String(nextValue);\n const nextDecimals = getCurrencyExponent(nextCurrency);\n const truncated = truncateDecimals(amount, nextDecimals);\n setCurrency(nextCurrency);\n if (truncated !== amount) setAmount(truncated);\n emit(nextCurrency, truncated);\n },\n [amount, emit],\n );\n\n const handleAmountChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const raw = event.target.value;\n // Allow empty, digits, and a single decimal separator; cap fractional digits\n if (raw === '') {\n setAmount('');\n emit(currency, '');\n return;\n }\n // Strict numeric pattern -- reject anything else silently\n if (!/^\\d*\\.?\\d*$/.test(raw)) return;\n const truncated = truncateDecimals(raw, decimals);\n setAmount(truncated);\n emit(currency, truncated);\n },\n [currency, decimals, emit],\n );\n\n const handleAmountBlur = React.useCallback(() => {\n if (amount === '' || amount === '.') return;\n const parsed = Number(amount);\n if (!Number.isFinite(parsed)) return;\n const snapped = parsed.toFixed(decimals);\n if (snapped !== amount) {\n setAmount(snapped);\n emit(currency, snapped);\n }\n }, [amount, currency, decimals, emit]);\n\n const field = (\n <Field data-disabled={disabled}>\n {label && <FieldLabel htmlFor={fieldId}>{label}</FieldLabel>}\n\n <FieldContent>\n <div\n className={cn(\n 'flex h-9 w-full items-stretch rounded-md border border-input bg-transparent dark:bg-input/30 shadow-xs transition-[color,box-shadow]',\n 'focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[1px]',\n disabled && 'opacity-50 cursor-not-allowed pointer-events-none',\n hasError && 'border-destructive focus-within:ring-destructive/20 dark:focus-within:ring-destructive/40',\n className,\n )}\n >\n {isLocked ? (\n <span\n role=\"img\"\n aria-label={`Currency ${currency}`}\n className=\"flex items-center justify-center border-r border-input px-3 text-sm font-medium text-muted-foreground select-none\"\n >\n {currency}\n </span>\n ) : (\n <div className=\"flex items-center border-r border-input\">\n <Select\n options={options}\n searchable\n placeholder=\"Select currency\"\n value={currency}\n onChange={handleCurrencyChange}\n disabled={disabled}\n clearable={false}\n label=\"\"\n contentClassName=\"min-w-[280px] w-auto\"\n anchor={({ selectedOption, open, disabled: anchorDisabled }) => (\n <button\n type=\"button\"\n disabled={anchorDisabled}\n aria-label=\"Select currency\"\n aria-expanded={open}\n className={cn(\n 'flex h-full items-center gap-1 px-3 text-sm font-medium text-foreground outline-none',\n 'hover:bg-accent/50 focus-visible:bg-accent/50',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n )}\n >\n <span>{selectedOption ? String(selectedOption.value) : currency}</span>\n <ChevronDown\n className={cn('size-3.5 text-muted-foreground transition-transform', open && 'rotate-180')}\n />\n </button>\n )}\n />\n </div>\n )}\n\n <input\n ref={ref}\n id={fieldId}\n type=\"text\"\n inputMode=\"decimal\"\n pattern=\"^[0-9]*\\.?[0-9]*$\"\n step={step}\n value={amount}\n onChange={handleAmountChange}\n onBlur={handleAmountBlur}\n disabled={disabled}\n required={required}\n placeholder={placeholder}\n aria-invalid={hasError}\n aria-describedby={description || error ? `${fieldId}-description ${fieldId}-error` : undefined}\n className={cn(\n 'flex-1 min-w-0 bg-transparent px-3 py-1 text-sm outline-none',\n 'placeholder:text-muted-foreground',\n 'disabled:cursor-not-allowed',\n )}\n />\n </div>\n\n {description && !error && <FieldDescription id={`${fieldId}-description`}>{description}</FieldDescription>}\n {error && <FieldError id={`${fieldId}-error`}>{error}</FieldError>}\n </FieldContent>\n </Field>\n );\n\n if (!disabledTip || !disabled) {\n return field;\n }\n\n return (\n <TooltipProvider>\n <Tooltip>\n {/* Disabled inputs don't emit hover/focus events, so the trigger lives on a wrapper. */}\n <TooltipTrigger asChild>\n <span className=\"inline-flex w-full cursor-not-allowed\">{field}</span>\n </TooltipTrigger>\n <TooltipContent>{disabledTip}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n },\n);\n\nCurrencyField.displayName = 'CurrencyField';\n"],"names":["React"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CurrencyField.d.ts","sourceRoot":"","sources":["../../../../lib/components/CurrencyField/CurrencyField.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,sBAAsB,CAAC;AAG/E,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAE1C,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAExB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE9B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAExB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"CurrencyField.d.ts","sourceRoot":"","sources":["../../../../lib/components/CurrencyField/CurrencyField.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,sBAAsB,CAAC;AAG/E,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAE1C,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAEtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAExB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE9B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAExB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA0BD,eAAO,MAAM,aAAa,6FAqNzB,CAAC"}
|
package/dist/lib/utils/zod.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export declare function zodNumericField(options: Omit<NumericFieldOptions, 'null
|
|
|
24
24
|
}): z.ZodType<number | null, number | null>;
|
|
25
25
|
export interface CurrencyFieldOptions {
|
|
26
26
|
required?: string;
|
|
27
|
+
optional?: boolean;
|
|
27
28
|
positive?: boolean;
|
|
28
29
|
positiveMessage?: string;
|
|
29
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../../lib/utils/zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,cAAc,KAAK,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAGD,wBAAgB,eAAe,CAC7B,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GACrE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7B,wBAAgB,eAAe,CAC7B,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GAClE,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AA6D3C,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAGD,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,oBAAyB;;;
|
|
1
|
+
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../../lib/utils/zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,cAAc,KAAK,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAGD,wBAAgB,eAAe,CAC7B,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GACrE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7B,wBAAgB,eAAe,CAC7B,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GAClE,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AA6D3C,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAGD,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,oBAAyB;;;oCAelE;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAGD,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC5G,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,IAAI,CAAC;CAChB,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAmBtD,eAAO,MAAM,YAAY,QAAkC,CAAC;AAC5D,eAAO,MAAM,mBAAmB,QAAuD,CAAC;AAExF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,wBAAgB,YAAY,CAAC,OAAO,GAAE,gBAAqB,eAS1D;AAED,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAKD,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,qBAA0B,2BAcpE;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAGD,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACvG,wBAAgB,YAAY,CAC1B,OAAO,EAAE,gBAAgB,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GAC7C,CAAC,CAAC,OAAO,CAAC,IAAI,GAAG,SAAS,EAAE,IAAI,GAAG,SAAS,CAAC,CAAC"}
|
package/dist/utils/zod.js
CHANGED
|
@@ -10636,10 +10636,15 @@ function zodNumericField(options = {}) {
|
|
|
10636
10636
|
});
|
|
10637
10637
|
}
|
|
10638
10638
|
function zodCurrencyField(options = {}) {
|
|
10639
|
-
const {
|
|
10639
|
+
const {
|
|
10640
|
+
required = "Required",
|
|
10641
|
+
optional = false,
|
|
10642
|
+
positive = true,
|
|
10643
|
+
positiveMessage = "Must be greater than 0"
|
|
10644
|
+
} = options;
|
|
10640
10645
|
return union([object({ currency: string$1(), value: string$1() }), _undefined$1()]).superRefine((v, ctx) => {
|
|
10641
10646
|
if (!v?.value) {
|
|
10642
|
-
ctx.addIssue({ code: "custom", message: required });
|
|
10647
|
+
if (!optional) ctx.addIssue({ code: "custom", message: required });
|
|
10643
10648
|
} else if (positive && Number(v.value) <= 0) {
|
|
10644
10649
|
ctx.addIssue({ code: "custom", message: positiveMessage });
|
|
10645
10650
|
}
|