@bigbinary/neeto-atoms 1.0.134-beta1 → 1.0.134-beta2
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/{ColorPicker-ClnRUq9y.js → ColorPicker-BvWNd8Tp.js} +2 -2
- package/dist/ColorPicker-BvWNd8Tp.js.map +1 -0
- package/dist/cjs/{ColorPicker-rhCnblTv.js → ColorPicker-Dh58otnF.js} +2 -2
- package/dist/cjs/ColorPicker-Dh58otnF.js.map +1 -0
- package/dist/cjs/components/ColorPicker.js +1 -1
- package/dist/cjs/components/index.js +1 -1
- package/dist/cjs/formik/BlockNavigation.js +7 -36
- package/dist/cjs/formik/BlockNavigation.js.map +1 -1
- package/dist/cjs/formik/Form.js +2 -2
- package/dist/cjs/formik/Form.js.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/components/ColorPicker.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/formik/BlockNavigation/BlockNavigationAlert.d.ts +3 -10
- package/dist/formik/BlockNavigation/index.d.ts +2 -2
- package/dist/formik/BlockNavigation.js +7 -36
- package/dist/formik/BlockNavigation.js.map +1 -1
- package/dist/formik/Form.js +2 -2
- package/dist/formik/Form.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/ColorPicker-ClnRUq9y.js.map +0 -1
- package/dist/cjs/ColorPicker-rhCnblTv.js.map +0 -1
|
@@ -241,7 +241,7 @@ const Target = forwardRef(
|
|
|
241
241
|
/* @__PURE__ */ jsx(
|
|
242
242
|
"span",
|
|
243
243
|
{
|
|
244
|
-
className: "block size-5 rounded-
|
|
244
|
+
className: "block size-5 rounded-[4px] border border-border",
|
|
245
245
|
style: { backgroundColor: colorValue }
|
|
246
246
|
}
|
|
247
247
|
),
|
|
@@ -434,4 +434,4 @@ const ColorPicker = forwardRef(
|
|
|
434
434
|
ColorPicker.displayName = "ColorPicker";
|
|
435
435
|
|
|
436
436
|
export { ColorPicker as C };
|
|
437
|
-
//# sourceMappingURL=ColorPicker-
|
|
437
|
+
//# sourceMappingURL=ColorPicker-BvWNd8Tp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColorPicker-BvWNd8Tp.js","sources":["../node_modules/lucide-react/dist/esm/icons/pipette.js","../src/components/ColorPicker/hooks/useEyeDropper.ts","../src/components/ColorPicker/constants.ts","../src/components/ColorPicker/hooks/useRecentlyUsedColors.ts","../src/components/ColorPicker/utils.ts","../src/components/ColorPicker/Palette.tsx","../src/components/ColorPicker/Target.tsx","../src/components/ColorPicker/ColorPicker.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.577.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m12 9-8.414 8.414A2 2 0 0 0 3 18.828v1.344a2 2 0 0 1-.586 1.414A2 2 0 0 1 3.828 21h1.344a2 2 0 0 0 1.414-.586L15 12\",\n key: \"1y3wsu\"\n }\n ],\n [\n \"path\",\n {\n d: \"m18 9 .4.4a1 1 0 1 1-3 3l-3.8-3.8a1 1 0 1 1 3-3l.4.4 3.4-3.4a1 1 0 1 1 3 3z\",\n key: \"110lr1\"\n }\n ],\n [\"path\", { d: \"m2 22 .414-.414\", key: \"jhxm08\" }]\n];\nconst Pipette = createLucideIcon(\"pipette\", __iconNode);\n\nexport { __iconNode, Pipette as default };\n//# sourceMappingURL=pipette.js.map\n","import { useCallback } from \"react\";\n\ninterface EyeDropperResult {\n sRGBHex: string;\n}\n\ndeclare global {\n interface Window {\n EyeDropper?: new () => { open: () => Promise<EyeDropperResult> };\n }\n}\n\nconst isSupported = typeof window !== \"undefined\" && \"EyeDropper\" in window;\n\nexport const useEyeDropper = () => {\n const open = useCallback(async (): Promise<string> => {\n if (!window.EyeDropper) throw new Error(\"EyeDropper API not supported\");\n\n const dropper = new window.EyeDropper();\n const result = await dropper.open();\n\n return result.sRGBHex;\n }, []);\n\n return { isSupported, open };\n};\n","export const DEFAULT_PALETTE_COLORS = [\n { hex: \"#FFFFFF\" },\n { hex: \"#D6D6D6\" },\n { hex: \"#0A0E13\" },\n { hex: \"#FECE1E\" },\n { hex: \"#F32E48\" },\n { hex: \"#02C39A\" },\n { hex: \"#2A79C4\" },\n { hex: \"#B3E5FC\" },\n { hex: \"#C3C6F9\" },\n { hex: \"#8064CE\" },\n { hex: \"#FE861E\" },\n { hex: \"#FF7DC9\" },\n { hex: \"#028090\" },\n { hex: \"#095482\" },\n];\n\nexport const RECENTLY_USED_STORAGE_KEY = \"recently-used-colors\";\n\nexport const TARGET_SIZES = {\n small: \"small\",\n medium: \"medium\",\n large: \"large\",\n} as const;\n\nexport const PICKER_HEIGHT: Record<string, string> = {\n small: \"100px\",\n medium: \"120px\",\n large: \"140px\",\n};\n","import { useSyncExternalStore } from \"react\";\n\nimport { RECENTLY_USED_STORAGE_KEY } from \"../constants\";\n\ninterface ColorValue {\n hex: string;\n rgb: string | { r: number; g: number; b: number; a?: number };\n}\n\nconst getFromStorage = (key: string, fallback: ColorValue[]): ColorValue[] => {\n try {\n const stored = localStorage.getItem(key);\n\n return stored ? JSON.parse(stored) : fallback;\n } catch {\n return fallback;\n }\n};\n\nconst setToStorage = (key: string, value: ColorValue[]) => {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // Silently fail if storage is unavailable\n }\n};\n\nconst createSyncedStore = (storageKey: string) => {\n const listeners = new Set<() => void>();\n\n const store = {\n value: getFromStorage(storageKey, []),\n getSnapshot: () => store.value,\n getServerSnapshot: () => [] as ColorValue[],\n setValue: (newValue: ColorValue[]) => {\n store.value = newValue;\n setToStorage(storageKey, newValue);\n listeners.forEach(listener => listener());\n },\n subscribe: (callback: () => void) => {\n listeners.add(callback);\n\n const storageEventHandler = (event: StorageEvent) => {\n if (event.key !== storageKey) return;\n store.value = getFromStorage(storageKey, []);\n listeners.forEach(listener => listener());\n };\n\n if (listeners.size === 1) {\n window.addEventListener(\"storage\", storageEventHandler);\n }\n\n return () => {\n listeners.delete(callback);\n if (listeners.size === 0) {\n window.removeEventListener(\"storage\", storageEventHandler);\n }\n };\n },\n };\n\n return store;\n};\n\nconst store = createSyncedStore(RECENTLY_USED_STORAGE_KEY);\n\nexport const useRecentlyUsedColors = (): [\n ColorValue[],\n (value: ColorValue[]) => void,\n] => [\n useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getServerSnapshot\n ),\n store.setValue,\n];\n","/**\n * Validates a hex color string (3, 4, 6, or 8 digits with optional #).\n */\nexport const isValidHex = (hex: string): boolean =>\n /^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(hex);\n\n/**\n * Parses a hex color string into RGBA components.\n * Returns { r: 0, g: 0, b: 0, a: 1 } for invalid inputs.\n */\nexport const hexToRgb = (\n hex: string\n): { r: number; g: number; b: number; a: number } => {\n const raw = hex.replace(/^#/, \"\");\n\n if (\n !/^([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(raw)\n ) {\n return { r: 0, g: 0, b: 0, a: 1 };\n }\n\n let r: number,\n g: number,\n b: number,\n a = 255;\n if (raw.length === 3 || raw.length === 4) {\n r = parseInt(raw[0] + raw[0], 16);\n g = parseInt(raw[1] + raw[1], 16);\n b = parseInt(raw[2] + raw[2], 16);\n if (raw.length === 4) a = parseInt(raw[3] + raw[3], 16);\n } else {\n r = parseInt(raw.slice(0, 2), 16);\n g = parseInt(raw.slice(2, 4), 16);\n b = parseInt(raw.slice(4, 6), 16);\n if (raw.length === 8) a = parseInt(raw.slice(6, 8), 16);\n }\n\n return { r, g, b, a: Math.round((a / 255) * 100) / 100 };\n};\n\n/**\n * Converts a hex color to an 8-digit hex string (#RRGGBBAA).\n */\nexport const hexToHex8 = (hex: string): string => {\n const { r, g, b, a } = hexToRgb(hex);\n const alpha = Math.round(a * 255);\n\n return `#${[r, g, b, alpha].map(channel => channel.toString(16).padStart(2, \"0\")).join(\"\")}`;\n};\n\n/**\n * Converts a color value to a normalized { hex, rgb } object.\n * Handles transparency and validity checks.\n */\nexport const getColor = (\n colorValue: string,\n showTransparencyControl: boolean\n): { hex: string; rgb: { r: number; g: number; b: number; a: number } } => {\n if (!isValidHex(colorValue)) {\n return { hex: colorValue, rgb: { r: 0, g: 0, b: 0, a: 1 } };\n }\n\n const rgb = hexToRgb(colorValue);\n\n if (rgb.a === 0) {\n return { hex: colorValue, rgb };\n }\n\n const hex = showTransparencyControl\n ? hexToHex8(colorValue)\n : `#${colorValue.replace(/^#/, \"\").slice(0, 6)}`;\n\n return { hex, rgb: hexToRgb(hex) };\n};\n","import React, { forwardRef } from \"react\";\n\nimport { cn } from \"src/shadcn/lib/utils\";\n\nimport { isValidHex } from \"./utils\";\nimport { DEFAULT_PALETTE_COLORS } from \"./constants\";\nimport type { PaletteColor } from \"./types\";\n\nexport interface PaletteProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"onChange\"\n> {\n /** Currently selected color. */\n color?: string;\n /** List of colors to render. */\n colorList?: PaletteColor[];\n /** Callback when a color swatch is clicked. */\n onChange?: (color: string) => void;\n}\n\nconst Palette = forwardRef<HTMLDivElement, PaletteProps>(\n (\n {\n color,\n colorList = DEFAULT_PALETTE_COLORS,\n onChange,\n className,\n ...otherProps\n },\n ref\n ) => (\n <div\n ref={ref}\n className={cn(\n \"flex flex-row flex-wrap items-start justify-start gap-1\",\n className\n )}\n {...otherProps}\n >\n {colorList.map(item => {\n const rgbValue =\n \"rgb\" in item && typeof item.rgb === \"string\" ? item.rgb : undefined;\n const value = item.hex ?? rgbValue ?? \"\";\n const isActive =\n !!color && !!value && color.toLowerCase() === value.toLowerCase();\n\n return (\n <button\n type=\"button\"\n key={value}\n data-testid=\"color-palette-item\"\n className={cn(\n \"size-6 rounded-[5px] border cursor-pointer overflow-hidden transition-colors\",\n isActive\n ? \"border-muted-foreground\"\n : \"border-border hover:border-muted-foreground/50\"\n )}\n onClick={() => onChange?.(value)}\n >\n <span\n className={cn(\n \"block size-full\",\n isValidHex(value)\n ? \"\"\n : \"bg-[repeating-conic-gradient(#ccc_0_25%,transparent_0_50%)] bg-[length:8px_8px]\"\n )}\n style={isValidHex(value) ? { backgroundColor: value } : undefined}\n />\n </button>\n );\n })}\n </div>\n )\n);\n\nPalette.displayName = \"ColorPicker.Palette\";\n\nexport { Palette };\n","import React, { forwardRef } from \"react\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"src/shadcn/lib/utils\";\n\nconst targetVariants = cva(\n \"inline-flex items-center justify-between rounded-md border border-input bg-background transition-colors hover:border-muted-foreground focus-visible:outline-none focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-primary/15 cursor-pointer\",\n {\n variants: {\n size: {\n small: \"h-7 p-0.5 gap-2\",\n medium: \"h-8 p-1 gap-2\",\n large: \"h-10 p-1.5 gap-3\",\n },\n },\n defaultVariants: {\n size: \"large\",\n },\n }\n);\n\nexport interface TargetProps\n extends\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"size\">,\n VariantProps<typeof targetVariants> {\n /** Show hex code text beside the color swatch. */\n showHexValue?: boolean;\n /** The original color prop value. */\n color?: string;\n /** The resolved color value to display. */\n colorValue?: string;\n}\n\nconst Target = forwardRef<HTMLButtonElement, TargetProps>(\n (\n { size = \"large\", showHexValue, color, colorValue, className, ...props },\n ref\n ) => (\n <button\n ref={ref}\n type=\"button\"\n data-testid=\"color-picker-target\"\n className={cn(targetVariants({ size }), className)}\n {...props}\n >\n {showHexValue && (\n <span className=\"text-sm font-medium text-foreground min-w-[4.5rem] ps-1\">\n {color}\n </span>\n )}\n <span className=\"inline-flex items-center gap-2\">\n <span\n className=\"block size-5 rounded-[4px] border border-border\"\n style={{ backgroundColor: colorValue }}\n />\n <ChevronDown className=\"size-4 text-muted-foreground\" />\n </span>\n </button>\n )\n);\n\nTarget.displayName = \"ColorPicker.Target\";\n\nexport { Target };\n","import { forwardRef, useState, useRef } from \"react\";\n\nimport { Pipette } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n HexColorPicker,\n HexColorInput,\n HexAlphaColorPicker,\n} from \"react-colorful\";\nimport { Button } from \"src/primitives/Button\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"src/primitives/Popover\";\nimport { cn } from \"src/shadcn/lib/utils\";\n\nimport { useEyeDropper } from \"./hooks/useEyeDropper\";\nimport { useRecentlyUsedColors } from \"./hooks/useRecentlyUsedColors\";\nimport { Palette } from \"./Palette\";\nimport { Target } from \"./Target\";\nimport { PICKER_HEIGHT } from \"./constants\";\nimport type { ColorPickerProps } from \"./types\";\nimport { getColor } from \"./utils\";\n\nconst ColorPicker = forwardRef<HTMLDivElement, ColorPickerProps>(\n (\n {\n color = \"\",\n size = \"large\",\n onChange,\n dropdownProps,\n showEyeDropper = true,\n showHexValue = false,\n showTransparencyControl = false,\n showPicker = true,\n showHexPicker = true,\n colorPalette,\n showRecentlyUsedColors = showPicker,\n className,\n },\n ref\n ) => {\n const { t } = useTranslation();\n const [colorInternal, setColorInternal] = useState(color);\n const [isColorSelected, setIsColorSelected] = useState(false);\n const [open, setOpen] = useState(false);\n const hexColorInputValue = useRef(\"\");\n const { isSupported: eyeDropperSupported, open: openEyeDropper } =\n useEyeDropper();\n const [recentlyUsedColors, setRecentlyUsedColors] = useRecentlyUsedColors();\n\n const PickerComponent = showTransparencyControl\n ? HexAlphaColorPicker\n : HexColorPicker;\n\n const colorValue = color ?? colorInternal ?? \"\";\n\n const onColorChange = (value: string) => {\n setIsColorSelected(true);\n\n if (onChange) {\n onChange(getColor(value, showTransparencyControl));\n } else {\n setColorInternal(value);\n }\n };\n\n const onColorInputChange = (hex: string) => {\n hexColorInputValue.current = hex;\n const expectedLength = showTransparencyControl ? 9 : 7;\n if (hex.length !== expectedLength) return;\n\n onColorChange(hex);\n hexColorInputValue.current = \"\";\n };\n\n const onBlur = () => {\n if (!hexColorInputValue.current) return;\n\n onColorChange(hexColorInputValue.current);\n hexColorInputValue.current = \"\";\n };\n\n const pickColor = async () => {\n try {\n const hex = await openEyeDropper();\n onColorChange(hex);\n } catch {\n // User cancelled or API unavailable\n }\n };\n\n const onOpenChange = (nextOpen: boolean) => {\n if (!nextOpen && showRecentlyUsedColors && isColorSelected) {\n const newColor = getColor(colorValue, showTransparencyControl);\n const filtered = recentlyUsedColors.filter(\n ({ hex }) => hex !== newColor.hex\n );\n const updated = [newColor, ...filtered];\n if (updated.length > 14) updated.pop();\n\n setRecentlyUsedColors(updated);\n setIsColorSelected(false);\n }\n\n setOpen(nextOpen);\n };\n\n return (\n <Popover open={open} onOpenChange={onOpenChange}>\n <PopoverTrigger asChild>\n <Target\n color={color}\n colorValue={colorValue}\n showHexValue={showHexValue}\n size={size}\n />\n </PopoverTrigger>\n <PopoverContent\n ref={ref}\n align=\"start\"\n side=\"bottom\"\n className={cn(\"w-auto p-3\", className)}\n {...dropdownProps}\n >\n <div className=\"flex flex-col gap-3 w-56\">\n {showPicker && (\n <>\n {showHexPicker && (\n <div\n data-testid=\"neeto-color-picker-section\"\n style={{\n [\"--react-colorful-height\" as string]:\n PICKER_HEIGHT[size] ?? \"140px\",\n }}\n >\n <PickerComponent\n color={colorValue}\n onChange={onColorChange}\n style={{\n width: \"100%\",\n height: PICKER_HEIGHT[size] ?? \"140px\",\n }}\n />\n </div>\n )}\n <div className=\"flex items-center justify-center gap-2\">\n {showEyeDropper && eyeDropperSupported && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={pickColor}\n aria-label={t(\n \"neetoatoms.colorPicker.pickColor\",\n \"Pick color from screen\"\n )}\n >\n <Pipette className=\"size-4\" />\n </Button>\n )}\n <div\n className=\"flex-1\"\n data-testid=\"colorpicker-editable-input\"\n >\n <HexColorInput\n prefixed\n alpha={!!showTransparencyControl}\n color={colorValue}\n data-testid=\"colorpicker-editable-input-textbox\"\n onChange={onColorInputChange}\n onBlur={onBlur}\n className=\"h-8 w-full rounded-lg border border-input bg-transparent px-2.5 text-base outline-none focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-primary/15 md:text-sm\"\n />\n </div>\n </div>\n </>\n )}\n <div\n data-testid=\"color-palette\"\n className={cn(showPicker && \"border-t border-border pt-3\")}\n >\n <Palette\n color={color}\n colorList={colorPalette}\n onChange={onColorChange}\n />\n </div>\n {showRecentlyUsedColors && recentlyUsedColors.length > 0 && (\n <div\n className=\"border-t border-border pt-3\"\n data-testid=\"color-palette-recently-used\"\n >\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n {t(\"neetoatoms.colorPicker.recentlyUsed\", \"Recently used\")}\n </p>\n <Palette\n colorList={recentlyUsedColors}\n onChange={onColorChange}\n />\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n }\n);\n\nColorPicker.displayName = \"ColorPicker\";\n\nexport { ColorPicker };\n"],"names":["store"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -243,7 +243,7 @@ const Target = React.forwardRef(
|
|
|
243
243
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
244
244
|
"span",
|
|
245
245
|
{
|
|
246
|
-
className: "block size-5 rounded-
|
|
246
|
+
className: "block size-5 rounded-[4px] border border-border",
|
|
247
247
|
style: { backgroundColor: colorValue }
|
|
248
248
|
}
|
|
249
249
|
),
|
|
@@ -436,4 +436,4 @@ const ColorPicker = React.forwardRef(
|
|
|
436
436
|
ColorPicker.displayName = "ColorPicker";
|
|
437
437
|
|
|
438
438
|
exports.ColorPicker = ColorPicker;
|
|
439
|
-
//# sourceMappingURL=ColorPicker-
|
|
439
|
+
//# sourceMappingURL=ColorPicker-Dh58otnF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColorPicker-Dh58otnF.js","sources":["../../node_modules/lucide-react/dist/esm/icons/pipette.js","../../src/components/ColorPicker/hooks/useEyeDropper.ts","../../src/components/ColorPicker/constants.ts","../../src/components/ColorPicker/hooks/useRecentlyUsedColors.ts","../../src/components/ColorPicker/utils.ts","../../src/components/ColorPicker/Palette.tsx","../../src/components/ColorPicker/Target.tsx","../../src/components/ColorPicker/ColorPicker.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.577.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m12 9-8.414 8.414A2 2 0 0 0 3 18.828v1.344a2 2 0 0 1-.586 1.414A2 2 0 0 1 3.828 21h1.344a2 2 0 0 0 1.414-.586L15 12\",\n key: \"1y3wsu\"\n }\n ],\n [\n \"path\",\n {\n d: \"m18 9 .4.4a1 1 0 1 1-3 3l-3.8-3.8a1 1 0 1 1 3-3l.4.4 3.4-3.4a1 1 0 1 1 3 3z\",\n key: \"110lr1\"\n }\n ],\n [\"path\", { d: \"m2 22 .414-.414\", key: \"jhxm08\" }]\n];\nconst Pipette = createLucideIcon(\"pipette\", __iconNode);\n\nexport { __iconNode, Pipette as default };\n//# sourceMappingURL=pipette.js.map\n","import { useCallback } from \"react\";\n\ninterface EyeDropperResult {\n sRGBHex: string;\n}\n\ndeclare global {\n interface Window {\n EyeDropper?: new () => { open: () => Promise<EyeDropperResult> };\n }\n}\n\nconst isSupported = typeof window !== \"undefined\" && \"EyeDropper\" in window;\n\nexport const useEyeDropper = () => {\n const open = useCallback(async (): Promise<string> => {\n if (!window.EyeDropper) throw new Error(\"EyeDropper API not supported\");\n\n const dropper = new window.EyeDropper();\n const result = await dropper.open();\n\n return result.sRGBHex;\n }, []);\n\n return { isSupported, open };\n};\n","export const DEFAULT_PALETTE_COLORS = [\n { hex: \"#FFFFFF\" },\n { hex: \"#D6D6D6\" },\n { hex: \"#0A0E13\" },\n { hex: \"#FECE1E\" },\n { hex: \"#F32E48\" },\n { hex: \"#02C39A\" },\n { hex: \"#2A79C4\" },\n { hex: \"#B3E5FC\" },\n { hex: \"#C3C6F9\" },\n { hex: \"#8064CE\" },\n { hex: \"#FE861E\" },\n { hex: \"#FF7DC9\" },\n { hex: \"#028090\" },\n { hex: \"#095482\" },\n];\n\nexport const RECENTLY_USED_STORAGE_KEY = \"recently-used-colors\";\n\nexport const TARGET_SIZES = {\n small: \"small\",\n medium: \"medium\",\n large: \"large\",\n} as const;\n\nexport const PICKER_HEIGHT: Record<string, string> = {\n small: \"100px\",\n medium: \"120px\",\n large: \"140px\",\n};\n","import { useSyncExternalStore } from \"react\";\n\nimport { RECENTLY_USED_STORAGE_KEY } from \"../constants\";\n\ninterface ColorValue {\n hex: string;\n rgb: string | { r: number; g: number; b: number; a?: number };\n}\n\nconst getFromStorage = (key: string, fallback: ColorValue[]): ColorValue[] => {\n try {\n const stored = localStorage.getItem(key);\n\n return stored ? JSON.parse(stored) : fallback;\n } catch {\n return fallback;\n }\n};\n\nconst setToStorage = (key: string, value: ColorValue[]) => {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // Silently fail if storage is unavailable\n }\n};\n\nconst createSyncedStore = (storageKey: string) => {\n const listeners = new Set<() => void>();\n\n const store = {\n value: getFromStorage(storageKey, []),\n getSnapshot: () => store.value,\n getServerSnapshot: () => [] as ColorValue[],\n setValue: (newValue: ColorValue[]) => {\n store.value = newValue;\n setToStorage(storageKey, newValue);\n listeners.forEach(listener => listener());\n },\n subscribe: (callback: () => void) => {\n listeners.add(callback);\n\n const storageEventHandler = (event: StorageEvent) => {\n if (event.key !== storageKey) return;\n store.value = getFromStorage(storageKey, []);\n listeners.forEach(listener => listener());\n };\n\n if (listeners.size === 1) {\n window.addEventListener(\"storage\", storageEventHandler);\n }\n\n return () => {\n listeners.delete(callback);\n if (listeners.size === 0) {\n window.removeEventListener(\"storage\", storageEventHandler);\n }\n };\n },\n };\n\n return store;\n};\n\nconst store = createSyncedStore(RECENTLY_USED_STORAGE_KEY);\n\nexport const useRecentlyUsedColors = (): [\n ColorValue[],\n (value: ColorValue[]) => void,\n] => [\n useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getServerSnapshot\n ),\n store.setValue,\n];\n","/**\n * Validates a hex color string (3, 4, 6, or 8 digits with optional #).\n */\nexport const isValidHex = (hex: string): boolean =>\n /^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(hex);\n\n/**\n * Parses a hex color string into RGBA components.\n * Returns { r: 0, g: 0, b: 0, a: 1 } for invalid inputs.\n */\nexport const hexToRgb = (\n hex: string\n): { r: number; g: number; b: number; a: number } => {\n const raw = hex.replace(/^#/, \"\");\n\n if (\n !/^([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(raw)\n ) {\n return { r: 0, g: 0, b: 0, a: 1 };\n }\n\n let r: number,\n g: number,\n b: number,\n a = 255;\n if (raw.length === 3 || raw.length === 4) {\n r = parseInt(raw[0] + raw[0], 16);\n g = parseInt(raw[1] + raw[1], 16);\n b = parseInt(raw[2] + raw[2], 16);\n if (raw.length === 4) a = parseInt(raw[3] + raw[3], 16);\n } else {\n r = parseInt(raw.slice(0, 2), 16);\n g = parseInt(raw.slice(2, 4), 16);\n b = parseInt(raw.slice(4, 6), 16);\n if (raw.length === 8) a = parseInt(raw.slice(6, 8), 16);\n }\n\n return { r, g, b, a: Math.round((a / 255) * 100) / 100 };\n};\n\n/**\n * Converts a hex color to an 8-digit hex string (#RRGGBBAA).\n */\nexport const hexToHex8 = (hex: string): string => {\n const { r, g, b, a } = hexToRgb(hex);\n const alpha = Math.round(a * 255);\n\n return `#${[r, g, b, alpha].map(channel => channel.toString(16).padStart(2, \"0\")).join(\"\")}`;\n};\n\n/**\n * Converts a color value to a normalized { hex, rgb } object.\n * Handles transparency and validity checks.\n */\nexport const getColor = (\n colorValue: string,\n showTransparencyControl: boolean\n): { hex: string; rgb: { r: number; g: number; b: number; a: number } } => {\n if (!isValidHex(colorValue)) {\n return { hex: colorValue, rgb: { r: 0, g: 0, b: 0, a: 1 } };\n }\n\n const rgb = hexToRgb(colorValue);\n\n if (rgb.a === 0) {\n return { hex: colorValue, rgb };\n }\n\n const hex = showTransparencyControl\n ? hexToHex8(colorValue)\n : `#${colorValue.replace(/^#/, \"\").slice(0, 6)}`;\n\n return { hex, rgb: hexToRgb(hex) };\n};\n","import React, { forwardRef } from \"react\";\n\nimport { cn } from \"src/shadcn/lib/utils\";\n\nimport { isValidHex } from \"./utils\";\nimport { DEFAULT_PALETTE_COLORS } from \"./constants\";\nimport type { PaletteColor } from \"./types\";\n\nexport interface PaletteProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"onChange\"\n> {\n /** Currently selected color. */\n color?: string;\n /** List of colors to render. */\n colorList?: PaletteColor[];\n /** Callback when a color swatch is clicked. */\n onChange?: (color: string) => void;\n}\n\nconst Palette = forwardRef<HTMLDivElement, PaletteProps>(\n (\n {\n color,\n colorList = DEFAULT_PALETTE_COLORS,\n onChange,\n className,\n ...otherProps\n },\n ref\n ) => (\n <div\n ref={ref}\n className={cn(\n \"flex flex-row flex-wrap items-start justify-start gap-1\",\n className\n )}\n {...otherProps}\n >\n {colorList.map(item => {\n const rgbValue =\n \"rgb\" in item && typeof item.rgb === \"string\" ? item.rgb : undefined;\n const value = item.hex ?? rgbValue ?? \"\";\n const isActive =\n !!color && !!value && color.toLowerCase() === value.toLowerCase();\n\n return (\n <button\n type=\"button\"\n key={value}\n data-testid=\"color-palette-item\"\n className={cn(\n \"size-6 rounded-[5px] border cursor-pointer overflow-hidden transition-colors\",\n isActive\n ? \"border-muted-foreground\"\n : \"border-border hover:border-muted-foreground/50\"\n )}\n onClick={() => onChange?.(value)}\n >\n <span\n className={cn(\n \"block size-full\",\n isValidHex(value)\n ? \"\"\n : \"bg-[repeating-conic-gradient(#ccc_0_25%,transparent_0_50%)] bg-[length:8px_8px]\"\n )}\n style={isValidHex(value) ? { backgroundColor: value } : undefined}\n />\n </button>\n );\n })}\n </div>\n )\n);\n\nPalette.displayName = \"ColorPicker.Palette\";\n\nexport { Palette };\n","import React, { forwardRef } from \"react\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"src/shadcn/lib/utils\";\n\nconst targetVariants = cva(\n \"inline-flex items-center justify-between rounded-md border border-input bg-background transition-colors hover:border-muted-foreground focus-visible:outline-none focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-primary/15 cursor-pointer\",\n {\n variants: {\n size: {\n small: \"h-7 p-0.5 gap-2\",\n medium: \"h-8 p-1 gap-2\",\n large: \"h-10 p-1.5 gap-3\",\n },\n },\n defaultVariants: {\n size: \"large\",\n },\n }\n);\n\nexport interface TargetProps\n extends\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"size\">,\n VariantProps<typeof targetVariants> {\n /** Show hex code text beside the color swatch. */\n showHexValue?: boolean;\n /** The original color prop value. */\n color?: string;\n /** The resolved color value to display. */\n colorValue?: string;\n}\n\nconst Target = forwardRef<HTMLButtonElement, TargetProps>(\n (\n { size = \"large\", showHexValue, color, colorValue, className, ...props },\n ref\n ) => (\n <button\n ref={ref}\n type=\"button\"\n data-testid=\"color-picker-target\"\n className={cn(targetVariants({ size }), className)}\n {...props}\n >\n {showHexValue && (\n <span className=\"text-sm font-medium text-foreground min-w-[4.5rem] ps-1\">\n {color}\n </span>\n )}\n <span className=\"inline-flex items-center gap-2\">\n <span\n className=\"block size-5 rounded-[4px] border border-border\"\n style={{ backgroundColor: colorValue }}\n />\n <ChevronDown className=\"size-4 text-muted-foreground\" />\n </span>\n </button>\n )\n);\n\nTarget.displayName = \"ColorPicker.Target\";\n\nexport { Target };\n","import { forwardRef, useState, useRef } from \"react\";\n\nimport { Pipette } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n HexColorPicker,\n HexColorInput,\n HexAlphaColorPicker,\n} from \"react-colorful\";\nimport { Button } from \"src/primitives/Button\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"src/primitives/Popover\";\nimport { cn } from \"src/shadcn/lib/utils\";\n\nimport { useEyeDropper } from \"./hooks/useEyeDropper\";\nimport { useRecentlyUsedColors } from \"./hooks/useRecentlyUsedColors\";\nimport { Palette } from \"./Palette\";\nimport { Target } from \"./Target\";\nimport { PICKER_HEIGHT } from \"./constants\";\nimport type { ColorPickerProps } from \"./types\";\nimport { getColor } from \"./utils\";\n\nconst ColorPicker = forwardRef<HTMLDivElement, ColorPickerProps>(\n (\n {\n color = \"\",\n size = \"large\",\n onChange,\n dropdownProps,\n showEyeDropper = true,\n showHexValue = false,\n showTransparencyControl = false,\n showPicker = true,\n showHexPicker = true,\n colorPalette,\n showRecentlyUsedColors = showPicker,\n className,\n },\n ref\n ) => {\n const { t } = useTranslation();\n const [colorInternal, setColorInternal] = useState(color);\n const [isColorSelected, setIsColorSelected] = useState(false);\n const [open, setOpen] = useState(false);\n const hexColorInputValue = useRef(\"\");\n const { isSupported: eyeDropperSupported, open: openEyeDropper } =\n useEyeDropper();\n const [recentlyUsedColors, setRecentlyUsedColors] = useRecentlyUsedColors();\n\n const PickerComponent = showTransparencyControl\n ? HexAlphaColorPicker\n : HexColorPicker;\n\n const colorValue = color ?? colorInternal ?? \"\";\n\n const onColorChange = (value: string) => {\n setIsColorSelected(true);\n\n if (onChange) {\n onChange(getColor(value, showTransparencyControl));\n } else {\n setColorInternal(value);\n }\n };\n\n const onColorInputChange = (hex: string) => {\n hexColorInputValue.current = hex;\n const expectedLength = showTransparencyControl ? 9 : 7;\n if (hex.length !== expectedLength) return;\n\n onColorChange(hex);\n hexColorInputValue.current = \"\";\n };\n\n const onBlur = () => {\n if (!hexColorInputValue.current) return;\n\n onColorChange(hexColorInputValue.current);\n hexColorInputValue.current = \"\";\n };\n\n const pickColor = async () => {\n try {\n const hex = await openEyeDropper();\n onColorChange(hex);\n } catch {\n // User cancelled or API unavailable\n }\n };\n\n const onOpenChange = (nextOpen: boolean) => {\n if (!nextOpen && showRecentlyUsedColors && isColorSelected) {\n const newColor = getColor(colorValue, showTransparencyControl);\n const filtered = recentlyUsedColors.filter(\n ({ hex }) => hex !== newColor.hex\n );\n const updated = [newColor, ...filtered];\n if (updated.length > 14) updated.pop();\n\n setRecentlyUsedColors(updated);\n setIsColorSelected(false);\n }\n\n setOpen(nextOpen);\n };\n\n return (\n <Popover open={open} onOpenChange={onOpenChange}>\n <PopoverTrigger asChild>\n <Target\n color={color}\n colorValue={colorValue}\n showHexValue={showHexValue}\n size={size}\n />\n </PopoverTrigger>\n <PopoverContent\n ref={ref}\n align=\"start\"\n side=\"bottom\"\n className={cn(\"w-auto p-3\", className)}\n {...dropdownProps}\n >\n <div className=\"flex flex-col gap-3 w-56\">\n {showPicker && (\n <>\n {showHexPicker && (\n <div\n data-testid=\"neeto-color-picker-section\"\n style={{\n [\"--react-colorful-height\" as string]:\n PICKER_HEIGHT[size] ?? \"140px\",\n }}\n >\n <PickerComponent\n color={colorValue}\n onChange={onColorChange}\n style={{\n width: \"100%\",\n height: PICKER_HEIGHT[size] ?? \"140px\",\n }}\n />\n </div>\n )}\n <div className=\"flex items-center justify-center gap-2\">\n {showEyeDropper && eyeDropperSupported && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={pickColor}\n aria-label={t(\n \"neetoatoms.colorPicker.pickColor\",\n \"Pick color from screen\"\n )}\n >\n <Pipette className=\"size-4\" />\n </Button>\n )}\n <div\n className=\"flex-1\"\n data-testid=\"colorpicker-editable-input\"\n >\n <HexColorInput\n prefixed\n alpha={!!showTransparencyControl}\n color={colorValue}\n data-testid=\"colorpicker-editable-input-textbox\"\n onChange={onColorInputChange}\n onBlur={onBlur}\n className=\"h-8 w-full rounded-lg border border-input bg-transparent px-2.5 text-base outline-none focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-primary/15 md:text-sm\"\n />\n </div>\n </div>\n </>\n )}\n <div\n data-testid=\"color-palette\"\n className={cn(showPicker && \"border-t border-border pt-3\")}\n >\n <Palette\n color={color}\n colorList={colorPalette}\n onChange={onColorChange}\n />\n </div>\n {showRecentlyUsedColors && recentlyUsedColors.length > 0 && (\n <div\n className=\"border-t border-border pt-3\"\n data-testid=\"color-palette-recently-used\"\n >\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n {t(\"neetoatoms.colorPicker.recentlyUsed\", \"Recently used\")}\n </p>\n <Palette\n colorList={recentlyUsedColors}\n onChange={onColorChange}\n />\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n }\n);\n\nColorPicker.displayName = \"ColorPicker\";\n\nexport { ColorPicker };\n"],"names":["createLucideIcon","useCallback","store","useSyncExternalStore","forwardRef","jsx","cn","cva","jsxs","ChevronDown","useTranslation","useState","useRef","HexAlphaColorPicker","HexColorPicker","Popover","PopoverTrigger","PopoverContent","Fragment","Button","HexColorInput"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -8,7 +8,7 @@ var Button = require('../Button-BQ4rpzsl.js');
|
|
|
8
8
|
var Badge = require('../Badge-DAm1E10J.js');
|
|
9
9
|
var Callout = require('../Callout-Bci3POCo.js');
|
|
10
10
|
var Checkbox = require('../Checkbox-83g1FDsc.js');
|
|
11
|
-
var ColorPicker = require('../ColorPicker-
|
|
11
|
+
var ColorPicker = require('../ColorPicker-Dh58otnF.js');
|
|
12
12
|
var DataTable = require('../DataTable-BXNU34g-.js');
|
|
13
13
|
var DatePicker = require('../DatePicker-Da8-hSjF.js');
|
|
14
14
|
var Dialog = require('../Dialog-ZUHGaoAE.js');
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var React = require('react');
|
|
5
4
|
var formik = require('formik');
|
|
5
|
+
var React = require('react');
|
|
6
6
|
var reactRouterDom = require('react-router-dom');
|
|
7
7
|
var Dialog = require('../Dialog-ZUHGaoAE.js');
|
|
8
8
|
var Button = require('../Button-BQ4rpzsl.js');
|
|
@@ -99,27 +99,24 @@ const useNavPrompt = ({
|
|
|
99
99
|
|
|
100
100
|
const BlockNavigationAlert = ({
|
|
101
101
|
isOpen = false,
|
|
102
|
-
isSaving = false,
|
|
103
|
-
saveAndContinue = true,
|
|
104
102
|
onClose,
|
|
105
103
|
onSubmit,
|
|
106
104
|
onDiscardChanges,
|
|
107
105
|
title = "You have unsaved changes",
|
|
108
106
|
message = "Are you sure you want to leave? All unsaved changes will be lost.",
|
|
109
107
|
cancelButtonLabel = "Discard and leave",
|
|
110
|
-
submitButtonLabel
|
|
108
|
+
submitButtonLabel = "Stay on this page"
|
|
111
109
|
}) => {
|
|
112
110
|
const submitButtonRef = React.useRef(null);
|
|
113
|
-
const primaryButtonLabel = submitButtonLabel ?? (saveAndContinue ? "Save and continue" : "Stay on this page");
|
|
114
111
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
115
112
|
Dialog.Dialog,
|
|
116
113
|
{
|
|
117
114
|
isOpen,
|
|
118
115
|
onClose: onClose ?? (() => {
|
|
119
116
|
}),
|
|
120
|
-
closeButton:
|
|
121
|
-
closeOnEsc:
|
|
122
|
-
closeOnOutsideClick:
|
|
117
|
+
closeButton: true,
|
|
118
|
+
closeOnEsc: true,
|
|
119
|
+
closeOnOutsideClick: true,
|
|
123
120
|
initialFocusRef: submitButtonRef,
|
|
124
121
|
size: "medium",
|
|
125
122
|
"data-testid": "alert-box",
|
|
@@ -138,7 +135,6 @@ const BlockNavigationAlert = ({
|
|
|
138
135
|
Button.Button,
|
|
139
136
|
{
|
|
140
137
|
"data-testid": "alert-cancel-button",
|
|
141
|
-
disabled: isSaving,
|
|
142
138
|
label: cancelButtonLabel,
|
|
143
139
|
variant: "destructive",
|
|
144
140
|
onClick: onDiscardChanges
|
|
@@ -148,8 +144,7 @@ const BlockNavigationAlert = ({
|
|
|
148
144
|
Button.Button,
|
|
149
145
|
{
|
|
150
146
|
"data-testid": "alert-submit-button",
|
|
151
|
-
label:
|
|
152
|
-
loading: isSaving,
|
|
147
|
+
label: submitButtonLabel,
|
|
153
148
|
ref: submitButtonRef,
|
|
154
149
|
onClick: onSubmit
|
|
155
150
|
}
|
|
@@ -163,10 +158,8 @@ BlockNavigationAlert.displayName = "BlockNavigationAlert";
|
|
|
163
158
|
|
|
164
159
|
const FormikBlockNavigation = ({
|
|
165
160
|
isDirty = false,
|
|
166
|
-
saveAndContinue = true,
|
|
167
161
|
...otherProps
|
|
168
162
|
}) => {
|
|
169
|
-
const [isSaving, setIsSaving] = React.useState(false);
|
|
170
163
|
const formikContext = formik.useFormikContext();
|
|
171
164
|
const shouldBlock = isDirty || Boolean(formikContext) && Boolean(formikContext.dirty);
|
|
172
165
|
const { isBlocked, continueNavigation, hidePrompt } = useNavPrompt({
|
|
@@ -177,35 +170,13 @@ const FormikBlockNavigation = ({
|
|
|
177
170
|
hidePrompt();
|
|
178
171
|
continueNavigation();
|
|
179
172
|
};
|
|
180
|
-
const handleSaveAndContinue = async () => {
|
|
181
|
-
if (!formikContext) {
|
|
182
|
-
hidePrompt();
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
setIsSaving(true);
|
|
186
|
-
try {
|
|
187
|
-
const errors = await formikContext.validateForm();
|
|
188
|
-
if (Object.keys(errors).length > 0) {
|
|
189
|
-
await formikContext.submitForm();
|
|
190
|
-
hidePrompt();
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
await formikContext.submitForm();
|
|
194
|
-
continueNavigation();
|
|
195
|
-
} catch {
|
|
196
|
-
hidePrompt();
|
|
197
|
-
} finally {
|
|
198
|
-
setIsSaving(false);
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
173
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
202
174
|
BlockNavigationAlert,
|
|
203
175
|
{
|
|
204
|
-
...{ isSaving, saveAndContinue },
|
|
205
176
|
isOpen: isBlocked,
|
|
206
177
|
onClose: hidePrompt,
|
|
207
178
|
onDiscardChanges: handleDiscardChanges,
|
|
208
|
-
onSubmit:
|
|
179
|
+
onSubmit: hidePrompt,
|
|
209
180
|
...otherProps
|
|
210
181
|
}
|
|
211
182
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlockNavigation.js","sources":["../../../src/formik/BlockNavigation/hooks/useNavPrompt.ts","../../../src/formik/BlockNavigation/BlockNavigationAlert.tsx","../../../src/formik/BlockNavigation/index.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useHistory } from \"react-router-dom\";\n\ninterface UseNavPromptOptions {\n /** Whether navigation should be blocked. */\n shouldBlock?: boolean;\n}\n\ninterface UseNavPromptReturn {\n /** Whether a navigation attempt is currently blocked. */\n isBlocked: boolean;\n /** Unblock and continue the pending navigation. */\n continueNavigation: () => void;\n /** Dismiss the prompt without navigating. */\n hidePrompt: () => void;\n}\n\nconst useNavPrompt = ({\n shouldBlock = true,\n}: UseNavPromptOptions): UseNavPromptReturn => {\n const [isBlocked, setIsBlocked] = useState(false);\n\n const history = useHistory();\n\n const unblockRef = useRef<(() => void) | undefined>(undefined);\n const navRef = useRef<{ transition: string; action: string } | null>(null);\n\n const handleNavigation = useCallback(\n (action: string, transition: string) => {\n switch (action) {\n case \"PUSH\":\n history.push(transition);\n break;\n case \"REPLACE\":\n history.replace(transition);\n break;\n case \"POP\":\n history.goBack();\n break;\n }\n },\n [history]\n );\n\n const continueNavigation = useCallback(() => {\n if (isBlocked && unblockRef.current) {\n unblockRef.current();\n setIsBlocked(false);\n if (navRef.current) {\n const { action, transition } = navRef.current;\n handleNavigation(action, transition);\n }\n }\n }, [isBlocked, handleNavigation]);\n\n const hidePrompt = useCallback(() => setIsBlocked(false), []);\n\n useEffect(() => {\n if (shouldBlock) {\n unblockRef.current = history.block(\n (transition: { pathname: string }, action: string) => {\n setIsBlocked(true);\n navRef.current = { transition: transition.pathname, action };\n\n return false;\n }\n ) as unknown as () => void;\n\n return () => {\n unblockRef.current?.();\n };\n }\n\n return undefined;\n }, [shouldBlock, history]);\n\n return { isBlocked, continueNavigation, hidePrompt };\n};\n\nexport { useNavPrompt };\nexport type { UseNavPromptOptions, UseNavPromptReturn };\n","import { useRef } from \"react\";\n\nimport { Button } from \"src/components/Button\";\nimport { Dialog } from \"src/components/Dialog\";\n\nexport interface BlockNavigationAlertProps {\n /** Whether the alert dialog is open. */\n isOpen?: boolean;\n /** Whether the form is being saved. Shows a loader on the primary button and\n * prevents the dialog from being dismissed. */\n isSaving?: boolean;\n /** Whether the primary button saves the form before resuming navigation.\n * Defaults to true; pass false for the older \"Stay on this page\" behaviour. */\n saveAndContinue?: boolean;\n /** Called when the dialog should close. */\n onClose?: () => void;\n /** Called when the user chooses to save and continue, or to stay. */\n onSubmit?: () => void;\n /** Called when the user chooses to discard and leave. */\n onDiscardChanges?: () => void;\n /** Custom title for the alert. */\n title?: string;\n /** Custom message for the alert body. */\n message?: string;\n /** Custom label for the discard/cancel button. */\n cancelButtonLabel?: string;\n /** Custom label for the primary button. Defaults to \"Save and continue\" when\n * saveAndContinue is enabled and \"Stay on this page\" otherwise. */\n submitButtonLabel?: string;\n}\n\nconst BlockNavigationAlert = ({\n isOpen = false,\n isSaving = false,\n saveAndContinue = true,\n onClose,\n onSubmit,\n onDiscardChanges,\n title = \"You have unsaved changes\",\n message = \"Are you sure you want to leave? All unsaved changes will be lost.\",\n cancelButtonLabel = \"Discard and leave\",\n submitButtonLabel,\n}: BlockNavigationAlertProps) => {\n const submitButtonRef = useRef<HTMLButtonElement>(null);\n\n const primaryButtonLabel =\n submitButtonLabel ??\n (saveAndContinue ? \"Save and continue\" : \"Stay on this page\");\n\n return (\n <Dialog\n isOpen={isOpen}\n onClose={onClose ?? (() => {})}\n closeButton={!isSaving}\n closeOnEsc={!isSaving}\n closeOnOutsideClick={!isSaving}\n initialFocusRef={submitButtonRef}\n size=\"medium\"\n data-testid=\"alert-box\"\n >\n <Dialog.Header>\n <Dialog.Title data-testid=\"alert-title\">{title}</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <p\n data-testid=\"alert-message\"\n className=\"text-sm text-muted-foreground\"\n >\n {message}\n </p>\n </Dialog.Body>\n <Dialog.Footer className=\"flex items-center justify-end gap-2\">\n <Button\n data-testid=\"alert-cancel-button\"\n disabled={isSaving}\n label={cancelButtonLabel}\n variant=\"destructive\"\n onClick={onDiscardChanges}\n />\n <Button\n data-testid=\"alert-submit-button\"\n label={primaryButtonLabel}\n loading={isSaving}\n ref={submitButtonRef}\n onClick={onSubmit}\n />\n </Dialog.Footer>\n </Dialog>\n );\n};\n\nBlockNavigationAlert.displayName = \"BlockNavigationAlert\";\n\nexport { BlockNavigationAlert };\n","import { useState } from \"react\";\n\nimport { useFormikContext } from \"formik\";\n\nimport { useNavPrompt } from \"./hooks/useNavPrompt\";\n\nimport {\n BlockNavigationAlert,\n type BlockNavigationAlertProps,\n} from \"./BlockNavigationAlert\";\n\nexport interface FormikBlockNavigationProps extends Omit<\n BlockNavigationAlertProps,\n \"isOpen\" | \"isSaving\" | \"onClose\" | \"onSubmit\" | \"onDiscardChanges\"\n> {\n /** Force the navigation block regardless of Formik dirty state. */\n isDirty?: boolean;\n}\n\nconst FormikBlockNavigation = ({\n isDirty = false,\n saveAndContinue = true,\n ...otherProps\n}: FormikBlockNavigationProps) => {\n const [isSaving, setIsSaving] = useState(false);\n\n const formikContext = useFormikContext();\n const shouldBlock =\n isDirty || (Boolean(formikContext) && Boolean(formikContext.dirty));\n\n const { isBlocked, continueNavigation, hidePrompt } = useNavPrompt({\n shouldBlock,\n });\n\n const handleDiscardChanges = () => {\n if (formikContext) formikContext.resetForm();\n hidePrompt();\n continueNavigation();\n };\n\n const handleSaveAndContinue = async () => {\n if (!formikContext) {\n hidePrompt();\n\n return;\n }\n\n setIsSaving(true);\n try {\n const errors = await formikContext.validateForm();\n if (Object.keys(errors).length > 0) {\n await formikContext.submitForm();\n hidePrompt();\n\n return;\n }\n\n await formikContext.submitForm();\n continueNavigation();\n } catch {\n hidePrompt();\n } finally {\n setIsSaving(false);\n }\n };\n\n return (\n <BlockNavigationAlert\n {...{ isSaving, saveAndContinue }}\n isOpen={isBlocked}\n onClose={hidePrompt}\n onDiscardChanges={handleDiscardChanges}\n onSubmit={saveAndContinue ? handleSaveAndContinue : hidePrompt}\n {...otherProps}\n />\n );\n};\n\nFormikBlockNavigation.displayName = \"FormikBlockNavigation\";\n\nexport { FormikBlockNavigation };\nexport type { BlockNavigationAlertProps };\n"],"names":["useState","useHistory","useRef","useCallback","useEffect","jsxs","Dialog","jsx","Button","useFormikContext"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BlockNavigation.js","sources":["../../../src/formik/BlockNavigation/hooks/useNavPrompt.ts","../../../src/formik/BlockNavigation/BlockNavigationAlert.tsx","../../../src/formik/BlockNavigation/index.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useHistory } from \"react-router-dom\";\n\ninterface UseNavPromptOptions {\n /** Whether navigation should be blocked. */\n shouldBlock?: boolean;\n}\n\ninterface UseNavPromptReturn {\n /** Whether a navigation attempt is currently blocked. */\n isBlocked: boolean;\n /** Unblock and continue the pending navigation. */\n continueNavigation: () => void;\n /** Dismiss the prompt without navigating. */\n hidePrompt: () => void;\n}\n\nconst useNavPrompt = ({\n shouldBlock = true,\n}: UseNavPromptOptions): UseNavPromptReturn => {\n const [isBlocked, setIsBlocked] = useState(false);\n\n const history = useHistory();\n\n const unblockRef = useRef<(() => void) | undefined>(undefined);\n const navRef = useRef<{ transition: string; action: string } | null>(null);\n\n const handleNavigation = useCallback(\n (action: string, transition: string) => {\n switch (action) {\n case \"PUSH\":\n history.push(transition);\n break;\n case \"REPLACE\":\n history.replace(transition);\n break;\n case \"POP\":\n history.goBack();\n break;\n }\n },\n [history]\n );\n\n const continueNavigation = useCallback(() => {\n if (isBlocked && unblockRef.current) {\n unblockRef.current();\n setIsBlocked(false);\n if (navRef.current) {\n const { action, transition } = navRef.current;\n handleNavigation(action, transition);\n }\n }\n }, [isBlocked, handleNavigation]);\n\n const hidePrompt = useCallback(() => setIsBlocked(false), []);\n\n useEffect(() => {\n if (shouldBlock) {\n unblockRef.current = history.block(\n (transition: { pathname: string }, action: string) => {\n setIsBlocked(true);\n navRef.current = { transition: transition.pathname, action };\n\n return false;\n }\n ) as unknown as () => void;\n\n return () => {\n unblockRef.current?.();\n };\n }\n\n return undefined;\n }, [shouldBlock, history]);\n\n return { isBlocked, continueNavigation, hidePrompt };\n};\n\nexport { useNavPrompt };\nexport type { UseNavPromptOptions, UseNavPromptReturn };\n","import { useRef } from \"react\";\n\nimport { Button } from \"src/components/Button\";\nimport { Dialog } from \"src/components/Dialog\";\n\nexport interface BlockNavigationAlertProps {\n /** Whether the alert dialog is open. */\n isOpen?: boolean;\n /** Called when the dialog should close. */\n onClose?: () => void;\n /** Called when the user chooses to stay. */\n onSubmit?: () => void;\n /** Called when the user chooses to discard and leave. */\n onDiscardChanges?: () => void;\n /** Custom title for the alert. */\n title?: string;\n /** Custom message for the alert body. */\n message?: string;\n /** Custom label for the discard/cancel button. */\n cancelButtonLabel?: string;\n /** Custom label for the stay/submit button. */\n submitButtonLabel?: string;\n}\n\nconst BlockNavigationAlert = ({\n isOpen = false,\n onClose,\n onSubmit,\n onDiscardChanges,\n title = \"You have unsaved changes\",\n message = \"Are you sure you want to leave? All unsaved changes will be lost.\",\n cancelButtonLabel = \"Discard and leave\",\n submitButtonLabel = \"Stay on this page\",\n}: BlockNavigationAlertProps) => {\n const submitButtonRef = useRef<HTMLButtonElement>(null);\n\n return (\n <Dialog\n isOpen={isOpen}\n onClose={onClose ?? (() => {})}\n closeButton\n closeOnEsc\n closeOnOutsideClick\n initialFocusRef={submitButtonRef}\n size=\"medium\"\n data-testid=\"alert-box\"\n >\n <Dialog.Header>\n <Dialog.Title data-testid=\"alert-title\">{title}</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <p\n data-testid=\"alert-message\"\n className=\"text-sm text-muted-foreground\"\n >\n {message}\n </p>\n </Dialog.Body>\n <Dialog.Footer className=\"flex items-center justify-end gap-2\">\n <Button\n data-testid=\"alert-cancel-button\"\n label={cancelButtonLabel}\n variant=\"destructive\"\n onClick={onDiscardChanges}\n />\n <Button\n data-testid=\"alert-submit-button\"\n label={submitButtonLabel}\n ref={submitButtonRef}\n onClick={onSubmit}\n />\n </Dialog.Footer>\n </Dialog>\n );\n};\n\nBlockNavigationAlert.displayName = \"BlockNavigationAlert\";\n\nexport { BlockNavigationAlert };\n","import { useFormikContext } from \"formik\";\n\nimport { useNavPrompt } from \"./hooks/useNavPrompt\";\n\nimport {\n BlockNavigationAlert,\n type BlockNavigationAlertProps,\n} from \"./BlockNavigationAlert\";\n\nexport interface FormikBlockNavigationProps extends Omit<\n BlockNavigationAlertProps,\n \"isOpen\" | \"onClose\" | \"onSubmit\" | \"onDiscardChanges\"\n> {\n /** Force the navigation block regardless of Formik dirty state. */\n isDirty?: boolean;\n}\n\nconst FormikBlockNavigation = ({\n isDirty = false,\n ...otherProps\n}: FormikBlockNavigationProps) => {\n const formikContext = useFormikContext();\n const shouldBlock =\n isDirty || (Boolean(formikContext) && Boolean(formikContext.dirty));\n\n const { isBlocked, continueNavigation, hidePrompt } = useNavPrompt({\n shouldBlock,\n });\n\n const handleDiscardChanges = () => {\n if (formikContext) formikContext.resetForm();\n hidePrompt();\n continueNavigation();\n };\n\n return (\n <BlockNavigationAlert\n isOpen={isBlocked}\n onClose={hidePrompt}\n onDiscardChanges={handleDiscardChanges}\n onSubmit={hidePrompt}\n {...otherProps}\n />\n );\n};\n\nFormikBlockNavigation.displayName = \"FormikBlockNavigation\";\n\nexport { FormikBlockNavigation };\nexport type { BlockNavigationAlertProps };\n"],"names":["useState","useHistory","useRef","useCallback","useEffect","jsxs","Dialog","jsx","Button","useFormikContext"],"mappings":"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"}
|
package/dist/cjs/formik/Form.js
CHANGED
|
@@ -78,11 +78,11 @@ const FormWrapper = React.forwardRef(
|
|
|
78
78
|
scrollToError(formRef, errors, status);
|
|
79
79
|
}
|
|
80
80
|
} else {
|
|
81
|
-
|
|
81
|
+
submitForm();
|
|
82
82
|
}
|
|
83
83
|
} catch (error) {
|
|
84
84
|
console.error(
|
|
85
|
-
"An unhandled error was caught
|
|
85
|
+
"An unhandled error was caught from validateForm()",
|
|
86
86
|
error
|
|
87
87
|
);
|
|
88
88
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Form.js","sources":["../../../src/formik/Form/ScrollToErrorField/utils.ts","../../../src/formik/Form/ScrollToErrorField/index.tsx","../../../src/formik/Form/FormWrapper.tsx","../../../src/formik/Form/index.tsx"],"sourcesContent":["import { is } from \"ramda\";\n\nconst transformObjectToDotNotation = (\n object: Record<string, unknown>,\n prefix = \"\"\n): string[] => {\n const result: string[] = [];\n\n Object.entries(object).forEach(([key, value]) => {\n if (!value) return;\n const nextKey = prefix ? `${prefix}.${key}` : key;\n if (is(Object, value)) {\n result.push(\n ...transformObjectToDotNotation(\n value as Record<string, unknown>,\n nextKey\n )\n );\n } else {\n result.push(nextKey);\n }\n });\n\n return result;\n};\n\nconst getErrorFieldName = (\n formikErrors: Record<string, unknown>\n): string | undefined => transformObjectToDotNotation(formikErrors)?.[0];\n\nexport const getFieldsWithServerError = (\n status: Record<string, unknown> = {}\n): string[] =>\n Object.keys(status).filter(\n fieldName => status[fieldName] != null && status[fieldName] !== \"\"\n );\n\nexport const scrollToError = (\n formRef: React.RefObject<HTMLFormElement | null>,\n errors: Record<string, unknown>,\n status: Record<string, unknown>\n): void => {\n const fieldErrorName = getErrorFieldName(errors);\n const [fieldWithServerError] = getFieldsWithServerError(status);\n\n if (!fieldErrorName && !fieldWithServerError) return;\n\n const errorFieldName = fieldErrorName || fieldWithServerError;\n const errorFormElement = formRef.current?.querySelector(\n `[name=\"${errorFieldName}\"]`\n );\n\n errorFormElement?.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n });\n};\n","import { useEffect } from \"react\";\n\nimport { useFormikContext } from \"formik\";\n\nimport { getFieldsWithServerError, scrollToError } from \"./utils\";\n\ninterface ScrollToErrorFieldProps {\n formRef: React.RefObject<HTMLFormElement | null>;\n}\n\nconst ScrollToErrorField = ({ formRef }: ScrollToErrorFieldProps) => {\n const { submitCount, isValid, errors, status } = useFormikContext();\n\n useEffect(() => {\n const fieldsWithServerError = getFieldsWithServerError(status);\n if (!formRef.current || (isValid && fieldsWithServerError.length === 0)) {\n return;\n }\n\n scrollToError(formRef, errors as Record<string, unknown>, status);\n }, [submitCount]);\n\n return null;\n};\n\nexport default ScrollToErrorField;\n","import React, { useCallback, forwardRef, useRef } from \"react\";\n\nimport { Form as FormikForm, useFormikContext } from \"formik\";\n\nimport ScrollToErrorField from \"./ScrollToErrorField\";\nimport {\n getFieldsWithServerError,\n scrollToError,\n} from \"./ScrollToErrorField/utils\";\n\ninterface FormWrapperProps {\n className?: string;\n formProps?: React.ComponentProps<\"form\">;\n children: React.ReactNode;\n scrollToErrorField: boolean;\n}\n\nconst FormWrapper = forwardRef<HTMLFormElement, FormWrapperProps>(\n ({ className, formProps, children, scrollToErrorField }, ref) => {\n const { validateForm, setErrors, setTouched, submitForm, ...formikBag } =\n useFormikContext();\n\n const { dirty: isFormDirty, isSubmitting, status } = formikBag;\n\n const formRefForScrollToErrorField = useRef<HTMLFormElement>(null);\n const formRef =\n (ref as React.RefObject<HTMLFormElement | null>) ||\n formRefForScrollToErrorField;\n\n const handleKeyDown = useCallback(\n async (event: React.KeyboardEvent<HTMLFormElement>) => {\n const target = event.target as HTMLElement & { editor?: unknown };\n const isEventFromEditorOrTextarea =\n target.tagName === \"TEXTAREA\" || target.editor;\n\n if (event.key !== \"Enter\") return;\n if (isEventFromEditorOrTextarea && !event.metaKey) return;\n\n event.preventDefault();\n\n if (event.shiftKey) return;\n if (!isFormDirty || isSubmitting) return;\n\n try {\n const errors = await validateForm();\n const fieldStatuses = getFieldsWithServerError(status);\n\n if (\n Object.keys(errors).length > 0 ||\n Object.keys(fieldStatuses).length > 0\n ) {\n setErrors(errors);\n setTouched({ ...errors, ...status });\n if (scrollToErrorField) {\n scrollToError(formRef, errors as Record<string, unknown>, status);\n }\n } else {\n await submitForm();\n }\n } catch (error) {\n console.error(\n \"An unhandled error was caught while validating or submitting the form\",\n error\n );\n }\n },\n [\n validateForm,\n setErrors,\n setTouched,\n isFormDirty,\n isSubmitting,\n submitForm,\n status,\n scrollToErrorField,\n formRef,\n ]\n );\n\n return (\n <FormikForm\n {...{ className }}\n noValidate\n ref={formRef}\n onKeyDown={handleKeyDown}\n {...formProps}\n >\n {scrollToErrorField && <ScrollToErrorField {...{ formRef }} />}\n {children}\n </FormikForm>\n );\n }\n);\n\nFormWrapper.displayName = \"FormWrapper\";\n\nexport default FormWrapper;\n","import React, { forwardRef, useRef } from \"react\";\n\nimport { Formik, FormikConfig, FormikProps, FormikValues } from \"formik\";\n\nimport FormWrapper from \"./FormWrapper\";\nimport { getFieldsWithServerError } from \"./ScrollToErrorField/utils\";\n\nexport interface FormProps<T extends FormikValues = FormikValues> {\n /** Formik configuration: initialValues, validationSchema, onSubmit, etc. */\n formikProps: FormikConfig<T>;\n /** Props forwarded to the HTML form element. */\n formProps?: React.ComponentProps<\"form\">;\n /** Auto-scroll to the first error field on submit. */\n scrollToErrorField?: boolean;\n /** Additional class name for the form wrapper. */\n className?: string;\n /** Render children directly or as a function receiving FormikProps. */\n children: React.ReactNode | ((props: FormikProps<T>) => React.ReactNode);\n}\n\nconst Form = forwardRef<HTMLFormElement, FormProps>(\n (\n { className, children, formikProps, formProps, scrollToErrorField = false },\n ref\n ) => {\n const formikRef = useRef<FormikProps<FormikValues>>(null);\n\n const handleSubmit: FormikConfig<FormikValues>[\"onSubmit\"] = (\n values,\n actions\n ) => {\n const fieldsWithServerError = getFieldsWithServerError(\n formikRef.current?.status\n );\n\n if (fieldsWithServerError.length > 0) {\n actions.setSubmitting(false);\n\n return undefined;\n }\n\n return formikProps.onSubmit(values, actions);\n };\n\n return (\n <Formik\n innerRef={formikRef as React.Ref<FormikProps<FormikValues>>}\n {...formikProps}\n onSubmit={handleSubmit}\n >\n {props => (\n <FormWrapper {...{ className, formProps, ref, scrollToErrorField }}>\n {typeof children === \"function\" ? children(props) : children}\n </FormWrapper>\n )}\n </Formik>\n );\n }\n);\n\nForm.displayName = \"Form\";\n\nexport { Form };\n"],"names":["is","useFormikContext","useEffect","forwardRef","useRef","useCallback","jsxs","FormikForm","jsx","Formik"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Form.js","sources":["../../../src/formik/Form/ScrollToErrorField/utils.ts","../../../src/formik/Form/ScrollToErrorField/index.tsx","../../../src/formik/Form/FormWrapper.tsx","../../../src/formik/Form/index.tsx"],"sourcesContent":["import { is } from \"ramda\";\n\nconst transformObjectToDotNotation = (\n object: Record<string, unknown>,\n prefix = \"\"\n): string[] => {\n const result: string[] = [];\n\n Object.entries(object).forEach(([key, value]) => {\n if (!value) return;\n const nextKey = prefix ? `${prefix}.${key}` : key;\n if (is(Object, value)) {\n result.push(\n ...transformObjectToDotNotation(\n value as Record<string, unknown>,\n nextKey\n )\n );\n } else {\n result.push(nextKey);\n }\n });\n\n return result;\n};\n\nconst getErrorFieldName = (\n formikErrors: Record<string, unknown>\n): string | undefined => transformObjectToDotNotation(formikErrors)?.[0];\n\nexport const getFieldsWithServerError = (\n status: Record<string, unknown> = {}\n): string[] =>\n Object.keys(status).filter(\n fieldName => status[fieldName] != null && status[fieldName] !== \"\"\n );\n\nexport const scrollToError = (\n formRef: React.RefObject<HTMLFormElement | null>,\n errors: Record<string, unknown>,\n status: Record<string, unknown>\n): void => {\n const fieldErrorName = getErrorFieldName(errors);\n const [fieldWithServerError] = getFieldsWithServerError(status);\n\n if (!fieldErrorName && !fieldWithServerError) return;\n\n const errorFieldName = fieldErrorName || fieldWithServerError;\n const errorFormElement = formRef.current?.querySelector(\n `[name=\"${errorFieldName}\"]`\n );\n\n errorFormElement?.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n });\n};\n","import { useEffect } from \"react\";\n\nimport { useFormikContext } from \"formik\";\n\nimport { getFieldsWithServerError, scrollToError } from \"./utils\";\n\ninterface ScrollToErrorFieldProps {\n formRef: React.RefObject<HTMLFormElement | null>;\n}\n\nconst ScrollToErrorField = ({ formRef }: ScrollToErrorFieldProps) => {\n const { submitCount, isValid, errors, status } = useFormikContext();\n\n useEffect(() => {\n const fieldsWithServerError = getFieldsWithServerError(status);\n if (!formRef.current || (isValid && fieldsWithServerError.length === 0)) {\n return;\n }\n\n scrollToError(formRef, errors as Record<string, unknown>, status);\n }, [submitCount]);\n\n return null;\n};\n\nexport default ScrollToErrorField;\n","import React, { useCallback, forwardRef, useRef } from \"react\";\n\nimport { Form as FormikForm, useFormikContext } from \"formik\";\n\nimport ScrollToErrorField from \"./ScrollToErrorField\";\nimport {\n getFieldsWithServerError,\n scrollToError,\n} from \"./ScrollToErrorField/utils\";\n\ninterface FormWrapperProps {\n className?: string;\n formProps?: React.ComponentProps<\"form\">;\n children: React.ReactNode;\n scrollToErrorField: boolean;\n}\n\nconst FormWrapper = forwardRef<HTMLFormElement, FormWrapperProps>(\n ({ className, formProps, children, scrollToErrorField }, ref) => {\n const { validateForm, setErrors, setTouched, submitForm, ...formikBag } =\n useFormikContext();\n\n const { dirty: isFormDirty, isSubmitting, status } = formikBag;\n\n const formRefForScrollToErrorField = useRef<HTMLFormElement>(null);\n const formRef =\n (ref as React.RefObject<HTMLFormElement | null>) ||\n formRefForScrollToErrorField;\n\n const handleKeyDown = useCallback(\n async (event: React.KeyboardEvent<HTMLFormElement>) => {\n const target = event.target as HTMLElement & { editor?: unknown };\n const isEventFromEditorOrTextarea =\n target.tagName === \"TEXTAREA\" || target.editor;\n\n if (event.key !== \"Enter\") return;\n if (isEventFromEditorOrTextarea && !event.metaKey) return;\n\n event.preventDefault();\n\n if (event.shiftKey) return;\n if (!isFormDirty || isSubmitting) return;\n\n try {\n const errors = await validateForm();\n const fieldStatuses = getFieldsWithServerError(status);\n\n if (\n Object.keys(errors).length > 0 ||\n Object.keys(fieldStatuses).length > 0\n ) {\n setErrors(errors);\n setTouched({ ...errors, ...status });\n if (scrollToErrorField) {\n scrollToError(formRef, errors as Record<string, unknown>, status);\n }\n } else {\n submitForm();\n }\n } catch (error) {\n console.error(\n \"An unhandled error was caught from validateForm()\",\n error\n );\n }\n },\n [\n validateForm,\n setErrors,\n setTouched,\n isFormDirty,\n isSubmitting,\n submitForm,\n status,\n scrollToErrorField,\n formRef,\n ]\n );\n\n return (\n <FormikForm\n {...{ className }}\n noValidate\n ref={formRef}\n onKeyDown={handleKeyDown}\n {...formProps}\n >\n {scrollToErrorField && <ScrollToErrorField {...{ formRef }} />}\n {children}\n </FormikForm>\n );\n }\n);\n\nFormWrapper.displayName = \"FormWrapper\";\n\nexport default FormWrapper;\n","import React, { forwardRef, useRef } from \"react\";\n\nimport { Formik, FormikConfig, FormikProps, FormikValues } from \"formik\";\n\nimport FormWrapper from \"./FormWrapper\";\nimport { getFieldsWithServerError } from \"./ScrollToErrorField/utils\";\n\nexport interface FormProps<T extends FormikValues = FormikValues> {\n /** Formik configuration: initialValues, validationSchema, onSubmit, etc. */\n formikProps: FormikConfig<T>;\n /** Props forwarded to the HTML form element. */\n formProps?: React.ComponentProps<\"form\">;\n /** Auto-scroll to the first error field on submit. */\n scrollToErrorField?: boolean;\n /** Additional class name for the form wrapper. */\n className?: string;\n /** Render children directly or as a function receiving FormikProps. */\n children: React.ReactNode | ((props: FormikProps<T>) => React.ReactNode);\n}\n\nconst Form = forwardRef<HTMLFormElement, FormProps>(\n (\n { className, children, formikProps, formProps, scrollToErrorField = false },\n ref\n ) => {\n const formikRef = useRef<FormikProps<FormikValues>>(null);\n\n const handleSubmit: FormikConfig<FormikValues>[\"onSubmit\"] = (\n values,\n actions\n ) => {\n const fieldsWithServerError = getFieldsWithServerError(\n formikRef.current?.status\n );\n\n if (fieldsWithServerError.length > 0) {\n actions.setSubmitting(false);\n\n return undefined;\n }\n\n return formikProps.onSubmit(values, actions);\n };\n\n return (\n <Formik\n innerRef={formikRef as React.Ref<FormikProps<FormikValues>>}\n {...formikProps}\n onSubmit={handleSubmit}\n >\n {props => (\n <FormWrapper {...{ className, formProps, ref, scrollToErrorField }}>\n {typeof children === \"function\" ? children(props) : children}\n </FormWrapper>\n )}\n </Formik>\n );\n }\n);\n\nForm.displayName = \"Form\";\n\nexport { Form };\n"],"names":["is","useFormikContext","useEffect","forwardRef","useRef","useCallback","jsxs","FormikForm","jsx","Formik"],"mappings":"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"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -12,7 +12,7 @@ var Badge = require('./Badge-DAm1E10J.js');
|
|
|
12
12
|
var Button = require('./Button-BQ4rpzsl.js');
|
|
13
13
|
var Callout = require('./Callout-Bci3POCo.js');
|
|
14
14
|
var Checkbox = require('./Checkbox-83g1FDsc.js');
|
|
15
|
-
var ColorPicker = require('./ColorPicker-
|
|
15
|
+
var ColorPicker = require('./ColorPicker-Dh58otnF.js');
|
|
16
16
|
var DataTable = require('./DataTable-BXNU34g-.js');
|
|
17
17
|
var DatePicker = require('./DatePicker-Da8-hSjF.js');
|
|
18
18
|
var Dialog = require('./Dialog-ZUHGaoAE.js');
|
package/dist/components/index.js
CHANGED
|
@@ -6,7 +6,7 @@ export { B as BUTTON_SIZES, a as BUTTON_VARIANTS, b as Button } from '../Button-
|
|
|
6
6
|
export { B as Badge } from '../Badge-ChmtKioK.js';
|
|
7
7
|
export { C as Callout } from '../Callout-DJGi3MQR.js';
|
|
8
8
|
export { C as Checkbox } from '../Checkbox-BalUzegZ.js';
|
|
9
|
-
export { C as ColorPicker } from '../ColorPicker-
|
|
9
|
+
export { C as ColorPicker } from '../ColorPicker-BvWNd8Tp.js';
|
|
10
10
|
export { D as DataTable, u as useColumnOrdering, a as useColumnPinning, b as useColumnVisibility, c as useTablePagination, d as useTableSelection, e as useTableSort } from '../DataTable-DKYkrFfk.js';
|
|
11
11
|
export { D as DatePicker } from '../DatePicker-B3kUEuKH.js';
|
|
12
12
|
export { D as Dialog } from '../Dialog-Yw34WDqY.js';
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
export interface BlockNavigationAlertProps {
|
|
2
2
|
/** Whether the alert dialog is open. */
|
|
3
3
|
isOpen?: boolean;
|
|
4
|
-
/** Whether the form is being saved. Shows a loader on the primary button and
|
|
5
|
-
* prevents the dialog from being dismissed. */
|
|
6
|
-
isSaving?: boolean;
|
|
7
|
-
/** Whether the primary button saves the form before resuming navigation.
|
|
8
|
-
* Defaults to true; pass false for the older "Stay on this page" behaviour. */
|
|
9
|
-
saveAndContinue?: boolean;
|
|
10
4
|
/** Called when the dialog should close. */
|
|
11
5
|
onClose?: () => void;
|
|
12
|
-
/** Called when the user chooses to
|
|
6
|
+
/** Called when the user chooses to stay. */
|
|
13
7
|
onSubmit?: () => void;
|
|
14
8
|
/** Called when the user chooses to discard and leave. */
|
|
15
9
|
onDiscardChanges?: () => void;
|
|
@@ -19,12 +13,11 @@ export interface BlockNavigationAlertProps {
|
|
|
19
13
|
message?: string;
|
|
20
14
|
/** Custom label for the discard/cancel button. */
|
|
21
15
|
cancelButtonLabel?: string;
|
|
22
|
-
/** Custom label for the
|
|
23
|
-
* saveAndContinue is enabled and "Stay on this page" otherwise. */
|
|
16
|
+
/** Custom label for the stay/submit button. */
|
|
24
17
|
submitButtonLabel?: string;
|
|
25
18
|
}
|
|
26
19
|
declare const BlockNavigationAlert: {
|
|
27
|
-
({ isOpen,
|
|
20
|
+
({ isOpen, onClose, onSubmit, onDiscardChanges, title, message, cancelButtonLabel, submitButtonLabel, }: BlockNavigationAlertProps): import("react/jsx-runtime").JSX.Element;
|
|
28
21
|
displayName: string;
|
|
29
22
|
};
|
|
30
23
|
export { BlockNavigationAlert };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { type BlockNavigationAlertProps } from "./BlockNavigationAlert";
|
|
2
|
-
export interface FormikBlockNavigationProps extends Omit<BlockNavigationAlertProps, "isOpen" | "
|
|
2
|
+
export interface FormikBlockNavigationProps extends Omit<BlockNavigationAlertProps, "isOpen" | "onClose" | "onSubmit" | "onDiscardChanges"> {
|
|
3
3
|
/** Force the navigation block regardless of Formik dirty state. */
|
|
4
4
|
isDirty?: boolean;
|
|
5
5
|
}
|
|
6
6
|
declare const FormikBlockNavigation: {
|
|
7
|
-
({ isDirty,
|
|
7
|
+
({ isDirty, ...otherProps }: FormikBlockNavigationProps): import("react/jsx-runtime").JSX.Element;
|
|
8
8
|
displayName: string;
|
|
9
9
|
};
|
|
10
10
|
export { FormikBlockNavigation };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
3
2
|
import { useFormikContext } from 'formik';
|
|
3
|
+
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
4
4
|
import { useHistory } from 'react-router-dom';
|
|
5
5
|
import { D as Dialog } from '../Dialog-Yw34WDqY.js';
|
|
6
6
|
import { b as Button } from '../Button-ZssOVkG0.js';
|
|
@@ -97,27 +97,24 @@ const useNavPrompt = ({
|
|
|
97
97
|
|
|
98
98
|
const BlockNavigationAlert = ({
|
|
99
99
|
isOpen = false,
|
|
100
|
-
isSaving = false,
|
|
101
|
-
saveAndContinue = true,
|
|
102
100
|
onClose,
|
|
103
101
|
onSubmit,
|
|
104
102
|
onDiscardChanges,
|
|
105
103
|
title = "You have unsaved changes",
|
|
106
104
|
message = "Are you sure you want to leave? All unsaved changes will be lost.",
|
|
107
105
|
cancelButtonLabel = "Discard and leave",
|
|
108
|
-
submitButtonLabel
|
|
106
|
+
submitButtonLabel = "Stay on this page"
|
|
109
107
|
}) => {
|
|
110
108
|
const submitButtonRef = useRef(null);
|
|
111
|
-
const primaryButtonLabel = submitButtonLabel ?? (saveAndContinue ? "Save and continue" : "Stay on this page");
|
|
112
109
|
return /* @__PURE__ */ jsxs(
|
|
113
110
|
Dialog,
|
|
114
111
|
{
|
|
115
112
|
isOpen,
|
|
116
113
|
onClose: onClose ?? (() => {
|
|
117
114
|
}),
|
|
118
|
-
closeButton:
|
|
119
|
-
closeOnEsc:
|
|
120
|
-
closeOnOutsideClick:
|
|
115
|
+
closeButton: true,
|
|
116
|
+
closeOnEsc: true,
|
|
117
|
+
closeOnOutsideClick: true,
|
|
121
118
|
initialFocusRef: submitButtonRef,
|
|
122
119
|
size: "medium",
|
|
123
120
|
"data-testid": "alert-box",
|
|
@@ -136,7 +133,6 @@ const BlockNavigationAlert = ({
|
|
|
136
133
|
Button,
|
|
137
134
|
{
|
|
138
135
|
"data-testid": "alert-cancel-button",
|
|
139
|
-
disabled: isSaving,
|
|
140
136
|
label: cancelButtonLabel,
|
|
141
137
|
variant: "destructive",
|
|
142
138
|
onClick: onDiscardChanges
|
|
@@ -146,8 +142,7 @@ const BlockNavigationAlert = ({
|
|
|
146
142
|
Button,
|
|
147
143
|
{
|
|
148
144
|
"data-testid": "alert-submit-button",
|
|
149
|
-
label:
|
|
150
|
-
loading: isSaving,
|
|
145
|
+
label: submitButtonLabel,
|
|
151
146
|
ref: submitButtonRef,
|
|
152
147
|
onClick: onSubmit
|
|
153
148
|
}
|
|
@@ -161,10 +156,8 @@ BlockNavigationAlert.displayName = "BlockNavigationAlert";
|
|
|
161
156
|
|
|
162
157
|
const FormikBlockNavigation = ({
|
|
163
158
|
isDirty = false,
|
|
164
|
-
saveAndContinue = true,
|
|
165
159
|
...otherProps
|
|
166
160
|
}) => {
|
|
167
|
-
const [isSaving, setIsSaving] = useState(false);
|
|
168
161
|
const formikContext = useFormikContext();
|
|
169
162
|
const shouldBlock = isDirty || Boolean(formikContext) && Boolean(formikContext.dirty);
|
|
170
163
|
const { isBlocked, continueNavigation, hidePrompt } = useNavPrompt({
|
|
@@ -175,35 +168,13 @@ const FormikBlockNavigation = ({
|
|
|
175
168
|
hidePrompt();
|
|
176
169
|
continueNavigation();
|
|
177
170
|
};
|
|
178
|
-
const handleSaveAndContinue = async () => {
|
|
179
|
-
if (!formikContext) {
|
|
180
|
-
hidePrompt();
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
setIsSaving(true);
|
|
184
|
-
try {
|
|
185
|
-
const errors = await formikContext.validateForm();
|
|
186
|
-
if (Object.keys(errors).length > 0) {
|
|
187
|
-
await formikContext.submitForm();
|
|
188
|
-
hidePrompt();
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
await formikContext.submitForm();
|
|
192
|
-
continueNavigation();
|
|
193
|
-
} catch {
|
|
194
|
-
hidePrompt();
|
|
195
|
-
} finally {
|
|
196
|
-
setIsSaving(false);
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
171
|
return /* @__PURE__ */ jsx(
|
|
200
172
|
BlockNavigationAlert,
|
|
201
173
|
{
|
|
202
|
-
...{ isSaving, saveAndContinue },
|
|
203
174
|
isOpen: isBlocked,
|
|
204
175
|
onClose: hidePrompt,
|
|
205
176
|
onDiscardChanges: handleDiscardChanges,
|
|
206
|
-
onSubmit:
|
|
177
|
+
onSubmit: hidePrompt,
|
|
207
178
|
...otherProps
|
|
208
179
|
}
|
|
209
180
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlockNavigation.js","sources":["../../src/formik/BlockNavigation/hooks/useNavPrompt.ts","../../src/formik/BlockNavigation/BlockNavigationAlert.tsx","../../src/formik/BlockNavigation/index.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useHistory } from \"react-router-dom\";\n\ninterface UseNavPromptOptions {\n /** Whether navigation should be blocked. */\n shouldBlock?: boolean;\n}\n\ninterface UseNavPromptReturn {\n /** Whether a navigation attempt is currently blocked. */\n isBlocked: boolean;\n /** Unblock and continue the pending navigation. */\n continueNavigation: () => void;\n /** Dismiss the prompt without navigating. */\n hidePrompt: () => void;\n}\n\nconst useNavPrompt = ({\n shouldBlock = true,\n}: UseNavPromptOptions): UseNavPromptReturn => {\n const [isBlocked, setIsBlocked] = useState(false);\n\n const history = useHistory();\n\n const unblockRef = useRef<(() => void) | undefined>(undefined);\n const navRef = useRef<{ transition: string; action: string } | null>(null);\n\n const handleNavigation = useCallback(\n (action: string, transition: string) => {\n switch (action) {\n case \"PUSH\":\n history.push(transition);\n break;\n case \"REPLACE\":\n history.replace(transition);\n break;\n case \"POP\":\n history.goBack();\n break;\n }\n },\n [history]\n );\n\n const continueNavigation = useCallback(() => {\n if (isBlocked && unblockRef.current) {\n unblockRef.current();\n setIsBlocked(false);\n if (navRef.current) {\n const { action, transition } = navRef.current;\n handleNavigation(action, transition);\n }\n }\n }, [isBlocked, handleNavigation]);\n\n const hidePrompt = useCallback(() => setIsBlocked(false), []);\n\n useEffect(() => {\n if (shouldBlock) {\n unblockRef.current = history.block(\n (transition: { pathname: string }, action: string) => {\n setIsBlocked(true);\n navRef.current = { transition: transition.pathname, action };\n\n return false;\n }\n ) as unknown as () => void;\n\n return () => {\n unblockRef.current?.();\n };\n }\n\n return undefined;\n }, [shouldBlock, history]);\n\n return { isBlocked, continueNavigation, hidePrompt };\n};\n\nexport { useNavPrompt };\nexport type { UseNavPromptOptions, UseNavPromptReturn };\n","import { useRef } from \"react\";\n\nimport { Button } from \"src/components/Button\";\nimport { Dialog } from \"src/components/Dialog\";\n\nexport interface BlockNavigationAlertProps {\n /** Whether the alert dialog is open. */\n isOpen?: boolean;\n /** Whether the form is being saved. Shows a loader on the primary button and\n * prevents the dialog from being dismissed. */\n isSaving?: boolean;\n /** Whether the primary button saves the form before resuming navigation.\n * Defaults to true; pass false for the older \"Stay on this page\" behaviour. */\n saveAndContinue?: boolean;\n /** Called when the dialog should close. */\n onClose?: () => void;\n /** Called when the user chooses to save and continue, or to stay. */\n onSubmit?: () => void;\n /** Called when the user chooses to discard and leave. */\n onDiscardChanges?: () => void;\n /** Custom title for the alert. */\n title?: string;\n /** Custom message for the alert body. */\n message?: string;\n /** Custom label for the discard/cancel button. */\n cancelButtonLabel?: string;\n /** Custom label for the primary button. Defaults to \"Save and continue\" when\n * saveAndContinue is enabled and \"Stay on this page\" otherwise. */\n submitButtonLabel?: string;\n}\n\nconst BlockNavigationAlert = ({\n isOpen = false,\n isSaving = false,\n saveAndContinue = true,\n onClose,\n onSubmit,\n onDiscardChanges,\n title = \"You have unsaved changes\",\n message = \"Are you sure you want to leave? All unsaved changes will be lost.\",\n cancelButtonLabel = \"Discard and leave\",\n submitButtonLabel,\n}: BlockNavigationAlertProps) => {\n const submitButtonRef = useRef<HTMLButtonElement>(null);\n\n const primaryButtonLabel =\n submitButtonLabel ??\n (saveAndContinue ? \"Save and continue\" : \"Stay on this page\");\n\n return (\n <Dialog\n isOpen={isOpen}\n onClose={onClose ?? (() => {})}\n closeButton={!isSaving}\n closeOnEsc={!isSaving}\n closeOnOutsideClick={!isSaving}\n initialFocusRef={submitButtonRef}\n size=\"medium\"\n data-testid=\"alert-box\"\n >\n <Dialog.Header>\n <Dialog.Title data-testid=\"alert-title\">{title}</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <p\n data-testid=\"alert-message\"\n className=\"text-sm text-muted-foreground\"\n >\n {message}\n </p>\n </Dialog.Body>\n <Dialog.Footer className=\"flex items-center justify-end gap-2\">\n <Button\n data-testid=\"alert-cancel-button\"\n disabled={isSaving}\n label={cancelButtonLabel}\n variant=\"destructive\"\n onClick={onDiscardChanges}\n />\n <Button\n data-testid=\"alert-submit-button\"\n label={primaryButtonLabel}\n loading={isSaving}\n ref={submitButtonRef}\n onClick={onSubmit}\n />\n </Dialog.Footer>\n </Dialog>\n );\n};\n\nBlockNavigationAlert.displayName = \"BlockNavigationAlert\";\n\nexport { BlockNavigationAlert };\n","import { useState } from \"react\";\n\nimport { useFormikContext } from \"formik\";\n\nimport { useNavPrompt } from \"./hooks/useNavPrompt\";\n\nimport {\n BlockNavigationAlert,\n type BlockNavigationAlertProps,\n} from \"./BlockNavigationAlert\";\n\nexport interface FormikBlockNavigationProps extends Omit<\n BlockNavigationAlertProps,\n \"isOpen\" | \"isSaving\" | \"onClose\" | \"onSubmit\" | \"onDiscardChanges\"\n> {\n /** Force the navigation block regardless of Formik dirty state. */\n isDirty?: boolean;\n}\n\nconst FormikBlockNavigation = ({\n isDirty = false,\n saveAndContinue = true,\n ...otherProps\n}: FormikBlockNavigationProps) => {\n const [isSaving, setIsSaving] = useState(false);\n\n const formikContext = useFormikContext();\n const shouldBlock =\n isDirty || (Boolean(formikContext) && Boolean(formikContext.dirty));\n\n const { isBlocked, continueNavigation, hidePrompt } = useNavPrompt({\n shouldBlock,\n });\n\n const handleDiscardChanges = () => {\n if (formikContext) formikContext.resetForm();\n hidePrompt();\n continueNavigation();\n };\n\n const handleSaveAndContinue = async () => {\n if (!formikContext) {\n hidePrompt();\n\n return;\n }\n\n setIsSaving(true);\n try {\n const errors = await formikContext.validateForm();\n if (Object.keys(errors).length > 0) {\n await formikContext.submitForm();\n hidePrompt();\n\n return;\n }\n\n await formikContext.submitForm();\n continueNavigation();\n } catch {\n hidePrompt();\n } finally {\n setIsSaving(false);\n }\n };\n\n return (\n <BlockNavigationAlert\n {...{ isSaving, saveAndContinue }}\n isOpen={isBlocked}\n onClose={hidePrompt}\n onDiscardChanges={handleDiscardChanges}\n onSubmit={saveAndContinue ? handleSaveAndContinue : hidePrompt}\n {...otherProps}\n />\n );\n};\n\nFormikBlockNavigation.displayName = \"FormikBlockNavigation\";\n\nexport { FormikBlockNavigation };\nexport type { BlockNavigationAlertProps };\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BlockNavigation.js","sources":["../../src/formik/BlockNavigation/hooks/useNavPrompt.ts","../../src/formik/BlockNavigation/BlockNavigationAlert.tsx","../../src/formik/BlockNavigation/index.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useHistory } from \"react-router-dom\";\n\ninterface UseNavPromptOptions {\n /** Whether navigation should be blocked. */\n shouldBlock?: boolean;\n}\n\ninterface UseNavPromptReturn {\n /** Whether a navigation attempt is currently blocked. */\n isBlocked: boolean;\n /** Unblock and continue the pending navigation. */\n continueNavigation: () => void;\n /** Dismiss the prompt without navigating. */\n hidePrompt: () => void;\n}\n\nconst useNavPrompt = ({\n shouldBlock = true,\n}: UseNavPromptOptions): UseNavPromptReturn => {\n const [isBlocked, setIsBlocked] = useState(false);\n\n const history = useHistory();\n\n const unblockRef = useRef<(() => void) | undefined>(undefined);\n const navRef = useRef<{ transition: string; action: string } | null>(null);\n\n const handleNavigation = useCallback(\n (action: string, transition: string) => {\n switch (action) {\n case \"PUSH\":\n history.push(transition);\n break;\n case \"REPLACE\":\n history.replace(transition);\n break;\n case \"POP\":\n history.goBack();\n break;\n }\n },\n [history]\n );\n\n const continueNavigation = useCallback(() => {\n if (isBlocked && unblockRef.current) {\n unblockRef.current();\n setIsBlocked(false);\n if (navRef.current) {\n const { action, transition } = navRef.current;\n handleNavigation(action, transition);\n }\n }\n }, [isBlocked, handleNavigation]);\n\n const hidePrompt = useCallback(() => setIsBlocked(false), []);\n\n useEffect(() => {\n if (shouldBlock) {\n unblockRef.current = history.block(\n (transition: { pathname: string }, action: string) => {\n setIsBlocked(true);\n navRef.current = { transition: transition.pathname, action };\n\n return false;\n }\n ) as unknown as () => void;\n\n return () => {\n unblockRef.current?.();\n };\n }\n\n return undefined;\n }, [shouldBlock, history]);\n\n return { isBlocked, continueNavigation, hidePrompt };\n};\n\nexport { useNavPrompt };\nexport type { UseNavPromptOptions, UseNavPromptReturn };\n","import { useRef } from \"react\";\n\nimport { Button } from \"src/components/Button\";\nimport { Dialog } from \"src/components/Dialog\";\n\nexport interface BlockNavigationAlertProps {\n /** Whether the alert dialog is open. */\n isOpen?: boolean;\n /** Called when the dialog should close. */\n onClose?: () => void;\n /** Called when the user chooses to stay. */\n onSubmit?: () => void;\n /** Called when the user chooses to discard and leave. */\n onDiscardChanges?: () => void;\n /** Custom title for the alert. */\n title?: string;\n /** Custom message for the alert body. */\n message?: string;\n /** Custom label for the discard/cancel button. */\n cancelButtonLabel?: string;\n /** Custom label for the stay/submit button. */\n submitButtonLabel?: string;\n}\n\nconst BlockNavigationAlert = ({\n isOpen = false,\n onClose,\n onSubmit,\n onDiscardChanges,\n title = \"You have unsaved changes\",\n message = \"Are you sure you want to leave? All unsaved changes will be lost.\",\n cancelButtonLabel = \"Discard and leave\",\n submitButtonLabel = \"Stay on this page\",\n}: BlockNavigationAlertProps) => {\n const submitButtonRef = useRef<HTMLButtonElement>(null);\n\n return (\n <Dialog\n isOpen={isOpen}\n onClose={onClose ?? (() => {})}\n closeButton\n closeOnEsc\n closeOnOutsideClick\n initialFocusRef={submitButtonRef}\n size=\"medium\"\n data-testid=\"alert-box\"\n >\n <Dialog.Header>\n <Dialog.Title data-testid=\"alert-title\">{title}</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <p\n data-testid=\"alert-message\"\n className=\"text-sm text-muted-foreground\"\n >\n {message}\n </p>\n </Dialog.Body>\n <Dialog.Footer className=\"flex items-center justify-end gap-2\">\n <Button\n data-testid=\"alert-cancel-button\"\n label={cancelButtonLabel}\n variant=\"destructive\"\n onClick={onDiscardChanges}\n />\n <Button\n data-testid=\"alert-submit-button\"\n label={submitButtonLabel}\n ref={submitButtonRef}\n onClick={onSubmit}\n />\n </Dialog.Footer>\n </Dialog>\n );\n};\n\nBlockNavigationAlert.displayName = \"BlockNavigationAlert\";\n\nexport { BlockNavigationAlert };\n","import { useFormikContext } from \"formik\";\n\nimport { useNavPrompt } from \"./hooks/useNavPrompt\";\n\nimport {\n BlockNavigationAlert,\n type BlockNavigationAlertProps,\n} from \"./BlockNavigationAlert\";\n\nexport interface FormikBlockNavigationProps extends Omit<\n BlockNavigationAlertProps,\n \"isOpen\" | \"onClose\" | \"onSubmit\" | \"onDiscardChanges\"\n> {\n /** Force the navigation block regardless of Formik dirty state. */\n isDirty?: boolean;\n}\n\nconst FormikBlockNavigation = ({\n isDirty = false,\n ...otherProps\n}: FormikBlockNavigationProps) => {\n const formikContext = useFormikContext();\n const shouldBlock =\n isDirty || (Boolean(formikContext) && Boolean(formikContext.dirty));\n\n const { isBlocked, continueNavigation, hidePrompt } = useNavPrompt({\n shouldBlock,\n });\n\n const handleDiscardChanges = () => {\n if (formikContext) formikContext.resetForm();\n hidePrompt();\n continueNavigation();\n };\n\n return (\n <BlockNavigationAlert\n isOpen={isBlocked}\n onClose={hidePrompt}\n onDiscardChanges={handleDiscardChanges}\n onSubmit={hidePrompt}\n {...otherProps}\n />\n );\n};\n\nFormikBlockNavigation.displayName = \"FormikBlockNavigation\";\n\nexport { FormikBlockNavigation };\nexport type { BlockNavigationAlertProps };\n"],"names":[],"mappings":"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"}
|
package/dist/formik/Form.js
CHANGED
|
@@ -76,11 +76,11 @@ const FormWrapper = forwardRef(
|
|
|
76
76
|
scrollToError(formRef, errors, status);
|
|
77
77
|
}
|
|
78
78
|
} else {
|
|
79
|
-
|
|
79
|
+
submitForm();
|
|
80
80
|
}
|
|
81
81
|
} catch (error) {
|
|
82
82
|
console.error(
|
|
83
|
-
"An unhandled error was caught
|
|
83
|
+
"An unhandled error was caught from validateForm()",
|
|
84
84
|
error
|
|
85
85
|
);
|
|
86
86
|
}
|
package/dist/formik/Form.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Form.js","sources":["../../src/formik/Form/ScrollToErrorField/utils.ts","../../src/formik/Form/ScrollToErrorField/index.tsx","../../src/formik/Form/FormWrapper.tsx","../../src/formik/Form/index.tsx"],"sourcesContent":["import { is } from \"ramda\";\n\nconst transformObjectToDotNotation = (\n object: Record<string, unknown>,\n prefix = \"\"\n): string[] => {\n const result: string[] = [];\n\n Object.entries(object).forEach(([key, value]) => {\n if (!value) return;\n const nextKey = prefix ? `${prefix}.${key}` : key;\n if (is(Object, value)) {\n result.push(\n ...transformObjectToDotNotation(\n value as Record<string, unknown>,\n nextKey\n )\n );\n } else {\n result.push(nextKey);\n }\n });\n\n return result;\n};\n\nconst getErrorFieldName = (\n formikErrors: Record<string, unknown>\n): string | undefined => transformObjectToDotNotation(formikErrors)?.[0];\n\nexport const getFieldsWithServerError = (\n status: Record<string, unknown> = {}\n): string[] =>\n Object.keys(status).filter(\n fieldName => status[fieldName] != null && status[fieldName] !== \"\"\n );\n\nexport const scrollToError = (\n formRef: React.RefObject<HTMLFormElement | null>,\n errors: Record<string, unknown>,\n status: Record<string, unknown>\n): void => {\n const fieldErrorName = getErrorFieldName(errors);\n const [fieldWithServerError] = getFieldsWithServerError(status);\n\n if (!fieldErrorName && !fieldWithServerError) return;\n\n const errorFieldName = fieldErrorName || fieldWithServerError;\n const errorFormElement = formRef.current?.querySelector(\n `[name=\"${errorFieldName}\"]`\n );\n\n errorFormElement?.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n });\n};\n","import { useEffect } from \"react\";\n\nimport { useFormikContext } from \"formik\";\n\nimport { getFieldsWithServerError, scrollToError } from \"./utils\";\n\ninterface ScrollToErrorFieldProps {\n formRef: React.RefObject<HTMLFormElement | null>;\n}\n\nconst ScrollToErrorField = ({ formRef }: ScrollToErrorFieldProps) => {\n const { submitCount, isValid, errors, status } = useFormikContext();\n\n useEffect(() => {\n const fieldsWithServerError = getFieldsWithServerError(status);\n if (!formRef.current || (isValid && fieldsWithServerError.length === 0)) {\n return;\n }\n\n scrollToError(formRef, errors as Record<string, unknown>, status);\n }, [submitCount]);\n\n return null;\n};\n\nexport default ScrollToErrorField;\n","import React, { useCallback, forwardRef, useRef } from \"react\";\n\nimport { Form as FormikForm, useFormikContext } from \"formik\";\n\nimport ScrollToErrorField from \"./ScrollToErrorField\";\nimport {\n getFieldsWithServerError,\n scrollToError,\n} from \"./ScrollToErrorField/utils\";\n\ninterface FormWrapperProps {\n className?: string;\n formProps?: React.ComponentProps<\"form\">;\n children: React.ReactNode;\n scrollToErrorField: boolean;\n}\n\nconst FormWrapper = forwardRef<HTMLFormElement, FormWrapperProps>(\n ({ className, formProps, children, scrollToErrorField }, ref) => {\n const { validateForm, setErrors, setTouched, submitForm, ...formikBag } =\n useFormikContext();\n\n const { dirty: isFormDirty, isSubmitting, status } = formikBag;\n\n const formRefForScrollToErrorField = useRef<HTMLFormElement>(null);\n const formRef =\n (ref as React.RefObject<HTMLFormElement | null>) ||\n formRefForScrollToErrorField;\n\n const handleKeyDown = useCallback(\n async (event: React.KeyboardEvent<HTMLFormElement>) => {\n const target = event.target as HTMLElement & { editor?: unknown };\n const isEventFromEditorOrTextarea =\n target.tagName === \"TEXTAREA\" || target.editor;\n\n if (event.key !== \"Enter\") return;\n if (isEventFromEditorOrTextarea && !event.metaKey) return;\n\n event.preventDefault();\n\n if (event.shiftKey) return;\n if (!isFormDirty || isSubmitting) return;\n\n try {\n const errors = await validateForm();\n const fieldStatuses = getFieldsWithServerError(status);\n\n if (\n Object.keys(errors).length > 0 ||\n Object.keys(fieldStatuses).length > 0\n ) {\n setErrors(errors);\n setTouched({ ...errors, ...status });\n if (scrollToErrorField) {\n scrollToError(formRef, errors as Record<string, unknown>, status);\n }\n } else {\n await submitForm();\n }\n } catch (error) {\n console.error(\n \"An unhandled error was caught while validating or submitting the form\",\n error\n );\n }\n },\n [\n validateForm,\n setErrors,\n setTouched,\n isFormDirty,\n isSubmitting,\n submitForm,\n status,\n scrollToErrorField,\n formRef,\n ]\n );\n\n return (\n <FormikForm\n {...{ className }}\n noValidate\n ref={formRef}\n onKeyDown={handleKeyDown}\n {...formProps}\n >\n {scrollToErrorField && <ScrollToErrorField {...{ formRef }} />}\n {children}\n </FormikForm>\n );\n }\n);\n\nFormWrapper.displayName = \"FormWrapper\";\n\nexport default FormWrapper;\n","import React, { forwardRef, useRef } from \"react\";\n\nimport { Formik, FormikConfig, FormikProps, FormikValues } from \"formik\";\n\nimport FormWrapper from \"./FormWrapper\";\nimport { getFieldsWithServerError } from \"./ScrollToErrorField/utils\";\n\nexport interface FormProps<T extends FormikValues = FormikValues> {\n /** Formik configuration: initialValues, validationSchema, onSubmit, etc. */\n formikProps: FormikConfig<T>;\n /** Props forwarded to the HTML form element. */\n formProps?: React.ComponentProps<\"form\">;\n /** Auto-scroll to the first error field on submit. */\n scrollToErrorField?: boolean;\n /** Additional class name for the form wrapper. */\n className?: string;\n /** Render children directly or as a function receiving FormikProps. */\n children: React.ReactNode | ((props: FormikProps<T>) => React.ReactNode);\n}\n\nconst Form = forwardRef<HTMLFormElement, FormProps>(\n (\n { className, children, formikProps, formProps, scrollToErrorField = false },\n ref\n ) => {\n const formikRef = useRef<FormikProps<FormikValues>>(null);\n\n const handleSubmit: FormikConfig<FormikValues>[\"onSubmit\"] = (\n values,\n actions\n ) => {\n const fieldsWithServerError = getFieldsWithServerError(\n formikRef.current?.status\n );\n\n if (fieldsWithServerError.length > 0) {\n actions.setSubmitting(false);\n\n return undefined;\n }\n\n return formikProps.onSubmit(values, actions);\n };\n\n return (\n <Formik\n innerRef={formikRef as React.Ref<FormikProps<FormikValues>>}\n {...formikProps}\n onSubmit={handleSubmit}\n >\n {props => (\n <FormWrapper {...{ className, formProps, ref, scrollToErrorField }}>\n {typeof children === \"function\" ? children(props) : children}\n </FormWrapper>\n )}\n </Formik>\n );\n }\n);\n\nForm.displayName = \"Form\";\n\nexport { Form };\n"],"names":["FormikForm"],"mappings":";;;;;AAEA,MAAM,4BAAA,GAA+B,CACnC,MAAA,EACA,MAAA,GAAS,EAAA,KACI;AACb,EAAA,MAAM,SAAmB,EAAC;AAE1B,EAAA,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AAC/C,IAAA,IAAI,CAAC,KAAA,EAAO;AACZ,IAAA,MAAM,UAAU,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,GAAK,GAAA;AAC9C,IAAA,IAAI,EAAA,CAAG,MAAA,EAAQ,KAAK,CAAA,EAAG;AACrB,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,GAAG,4BAAA;AAAA,UACD,KAAA;AAAA,UACA;AAAA;AACF,OACF;AAAA,IACF,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AAAA,IACrB;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,MAAA;AACT,CAAA;AAEA,MAAM,oBAAoB,CACxB,YAAA,KACuB,4BAAA,CAA6B,YAAY,IAAI,CAAC,CAAA;AAEhE,MAAM,wBAAA,GAA2B,CACtC,MAAA,GAAkC,OAElC,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAE,MAAA;AAAA,EAClB,eAAa,MAAA,CAAO,SAAS,KAAK,IAAA,IAAQ,MAAA,CAAO,SAAS,CAAA,KAAM;AAClE,CAAA;AAEK,MAAM,aAAA,GAAgB,CAC3B,OAAA,EACA,MAAA,EACA,MAAA,KACS;AACT,EAAA,MAAM,cAAA,GAAiB,kBAAkB,MAAM,CAAA;AAC/C,EAAA,MAAM,CAAC,oBAAoB,CAAA,GAAI,wBAAA,CAAyB,MAAM,CAAA;AAE9D,EAAA,IAAI,CAAC,cAAA,IAAkB,CAAC,oBAAA,EAAsB;AAE9C,EAAA,MAAM,iBAAiB,cAAA,IAAkB,oBAAA;AACzC,EAAA,MAAM,gBAAA,GAAmB,QAAQ,OAAA,EAAS,aAAA;AAAA,IACxC,UAAU,cAAc,CAAA,EAAA;AAAA,GAC1B;AAEA,EAAA,gBAAA,EAAkB,cAAA,CAAe;AAAA,IAC/B,QAAA,EAAU,QAAA;AAAA,IACV,KAAA,EAAO;AAAA,GACR,CAAA;AACH,CAAA;;AC9CA,MAAM,kBAAA,GAAqB,CAAC,EAAE,OAAA,EAAQ,KAA+B;AACnE,EAAA,MAAM,EAAE,WAAA,EAAa,OAAA,EAAS,MAAA,EAAQ,MAAA,KAAW,gBAAA,EAAiB;AAElE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,qBAAA,GAAwB,yBAAyB,MAAM,CAAA;AAC7D,IAAA,IAAI,CAAC,OAAA,CAAQ,OAAA,IAAY,OAAA,IAAW,qBAAA,CAAsB,WAAW,CAAA,EAAI;AACvE,MAAA;AAAA,IACF;AAEA,IAAA,aAAA,CAAc,OAAA,EAAS,QAAmC,MAAM,CAAA;AAAA,EAClE,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAEhB,EAAA,OAAO,IAAA;AACT,CAAA;;ACNA,MAAM,WAAA,GAAc,UAAA;AAAA,EAClB,CAAC,EAAE,SAAA,EAAW,WAAW,QAAA,EAAU,kBAAA,IAAsB,GAAA,KAAQ;AAC/D,IAAA,MAAM,EAAE,cAAc,SAAA,EAAW,UAAA,EAAY,YAAY,GAAG,SAAA,KAC1D,gBAAA,EAAiB;AAEnB,IAAA,MAAM,EAAE,KAAA,EAAO,WAAA,EAAa,YAAA,EAAc,QAAO,GAAI,SAAA;AAErD,IAAA,MAAM,4BAAA,GAA+B,OAAwB,IAAI,CAAA;AACjE,IAAA,MAAM,UACH,GAAA,IACD,4BAAA;AAEF,IAAA,MAAM,aAAA,GAAgB,WAAA;AAAA,MACpB,OAAO,KAAA,KAAgD;AACrD,QAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,QAAA,MAAM,2BAAA,GACJ,MAAA,CAAO,OAAA,KAAY,UAAA,IAAc,MAAA,CAAO,MAAA;AAE1C,QAAA,IAAI,KAAA,CAAM,QAAQ,OAAA,EAAS;AAC3B,QAAA,IAAI,2BAAA,IAA+B,CAAC,KAAA,CAAM,OAAA,EAAS;AAEnD,QAAA,KAAA,CAAM,cAAA,EAAe;AAErB,QAAA,IAAI,MAAM,QAAA,EAAU;AACpB,QAAA,IAAI,CAAC,eAAe,YAAA,EAAc;AAElC,QAAA,IAAI;AACF,UAAA,MAAM,MAAA,GAAS,MAAM,YAAA,EAAa;AAClC,UAAA,MAAM,aAAA,GAAgB,yBAAyB,MAAM,CAAA;AAErD,UAAA,IACE,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAE,MAAA,GAAS,CAAA,IAC7B,MAAA,CAAO,IAAA,CAAK,aAAa,CAAA,CAAE,MAAA,GAAS,CAAA,EACpC;AACA,YAAA,SAAA,CAAU,MAAM,CAAA;AAChB,YAAA,UAAA,CAAW,EAAE,GAAG,MAAA,EAAQ,GAAG,QAAQ,CAAA;AACnC,YAAA,IAAI,kBAAA,EAAoB;AACtB,cAAA,aAAA,CAAc,OAAA,EAAS,QAAmC,MAAM,CAAA;AAAA,YAClE;AAAA,UACF,CAAA,MAAO;AACL,YAAA,MAAM,UAAA,EAAW;AAAA,UACnB;AAAA,QACF,SAAS,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,KAAA;AAAA,YACN,uEAAA;AAAA,YACA;AAAA,WACF;AAAA,QACF;AAAA,MACF,CAAA;AAAA,MACA;AAAA,QACE,YAAA;AAAA,QACA,SAAA;AAAA,QACA,UAAA;AAAA,QACA,WAAA;AAAA,QACA,YAAA;AAAA,QACA,UAAA;AAAA,QACA,MAAA;AAAA,QACA,kBAAA;AAAA,QACA;AAAA;AACF,KACF;AAEA,IAAA,uBACE,IAAA;AAAA,MAACA,MAAA;AAAA,MAAA;AAAA,QACE,GAAG,EAAE,SAAA,EAAU;AAAA,QAChB,UAAA,EAAU,IAAA;AAAA,QACV,GAAA,EAAK,OAAA;AAAA,QACL,SAAA,EAAW,aAAA;AAAA,QACV,GAAG,SAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,kBAAA,oBAAsB,GAAA,CAAC,kBAAA,EAAA,EAAoB,GAAG,EAAE,SAAQ,EAAG,CAAA;AAAA,UAC3D;AAAA;AAAA;AAAA,KACH;AAAA,EAEJ;AACF,CAAA;AAEA,WAAA,CAAY,WAAA,GAAc,aAAA;;AC1E1B,MAAM,IAAA,GAAO,UAAA;AAAA,EACX,CACE,EAAE,SAAA,EAAW,QAAA,EAAU,aAAa,SAAA,EAAW,kBAAA,GAAqB,KAAA,EAAM,EAC1E,GAAA,KACG;AACH,IAAA,MAAM,SAAA,GAAY,OAAkC,IAAI,CAAA;AAExD,IAAA,MAAM,YAAA,GAAuD,CAC3D,MAAA,EACA,OAAA,KACG;AACH,MAAA,MAAM,qBAAA,GAAwB,wBAAA;AAAA,QAC5B,UAAU,OAAA,EAAS;AAAA,OACrB;AAEA,MAAA,IAAI,qBAAA,CAAsB,SAAS,CAAA,EAAG;AACpC,QAAA,OAAA,CAAQ,cAAc,KAAK,CAAA;AAE3B,QAAA,OAAO,MAAA;AAAA,MACT;AAEA,MAAA,OAAO,WAAA,CAAY,QAAA,CAAS,MAAA,EAAQ,OAAO,CAAA;AAAA,IAC7C,CAAA;AAEA,IAAA,uBACE,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,QAAA,EAAU,SAAA;AAAA,QACT,GAAG,WAAA;AAAA,QACJ,QAAA,EAAU,YAAA;AAAA,QAET,qCACC,GAAA,CAAC,WAAA,EAAA,EAAa,GAAG,EAAE,WAAW,SAAA,EAAW,GAAA,EAAK,kBAAA,EAAmB,EAC9D,iBAAO,QAAA,KAAa,UAAA,GAAa,QAAA,CAAS,KAAK,IAAI,QAAA,EACtD;AAAA;AAAA,KAEJ;AAAA,EAEJ;AACF;AAEA,IAAA,CAAK,WAAA,GAAc,MAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"Form.js","sources":["../../src/formik/Form/ScrollToErrorField/utils.ts","../../src/formik/Form/ScrollToErrorField/index.tsx","../../src/formik/Form/FormWrapper.tsx","../../src/formik/Form/index.tsx"],"sourcesContent":["import { is } from \"ramda\";\n\nconst transformObjectToDotNotation = (\n object: Record<string, unknown>,\n prefix = \"\"\n): string[] => {\n const result: string[] = [];\n\n Object.entries(object).forEach(([key, value]) => {\n if (!value) return;\n const nextKey = prefix ? `${prefix}.${key}` : key;\n if (is(Object, value)) {\n result.push(\n ...transformObjectToDotNotation(\n value as Record<string, unknown>,\n nextKey\n )\n );\n } else {\n result.push(nextKey);\n }\n });\n\n return result;\n};\n\nconst getErrorFieldName = (\n formikErrors: Record<string, unknown>\n): string | undefined => transformObjectToDotNotation(formikErrors)?.[0];\n\nexport const getFieldsWithServerError = (\n status: Record<string, unknown> = {}\n): string[] =>\n Object.keys(status).filter(\n fieldName => status[fieldName] != null && status[fieldName] !== \"\"\n );\n\nexport const scrollToError = (\n formRef: React.RefObject<HTMLFormElement | null>,\n errors: Record<string, unknown>,\n status: Record<string, unknown>\n): void => {\n const fieldErrorName = getErrorFieldName(errors);\n const [fieldWithServerError] = getFieldsWithServerError(status);\n\n if (!fieldErrorName && !fieldWithServerError) return;\n\n const errorFieldName = fieldErrorName || fieldWithServerError;\n const errorFormElement = formRef.current?.querySelector(\n `[name=\"${errorFieldName}\"]`\n );\n\n errorFormElement?.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n });\n};\n","import { useEffect } from \"react\";\n\nimport { useFormikContext } from \"formik\";\n\nimport { getFieldsWithServerError, scrollToError } from \"./utils\";\n\ninterface ScrollToErrorFieldProps {\n formRef: React.RefObject<HTMLFormElement | null>;\n}\n\nconst ScrollToErrorField = ({ formRef }: ScrollToErrorFieldProps) => {\n const { submitCount, isValid, errors, status } = useFormikContext();\n\n useEffect(() => {\n const fieldsWithServerError = getFieldsWithServerError(status);\n if (!formRef.current || (isValid && fieldsWithServerError.length === 0)) {\n return;\n }\n\n scrollToError(formRef, errors as Record<string, unknown>, status);\n }, [submitCount]);\n\n return null;\n};\n\nexport default ScrollToErrorField;\n","import React, { useCallback, forwardRef, useRef } from \"react\";\n\nimport { Form as FormikForm, useFormikContext } from \"formik\";\n\nimport ScrollToErrorField from \"./ScrollToErrorField\";\nimport {\n getFieldsWithServerError,\n scrollToError,\n} from \"./ScrollToErrorField/utils\";\n\ninterface FormWrapperProps {\n className?: string;\n formProps?: React.ComponentProps<\"form\">;\n children: React.ReactNode;\n scrollToErrorField: boolean;\n}\n\nconst FormWrapper = forwardRef<HTMLFormElement, FormWrapperProps>(\n ({ className, formProps, children, scrollToErrorField }, ref) => {\n const { validateForm, setErrors, setTouched, submitForm, ...formikBag } =\n useFormikContext();\n\n const { dirty: isFormDirty, isSubmitting, status } = formikBag;\n\n const formRefForScrollToErrorField = useRef<HTMLFormElement>(null);\n const formRef =\n (ref as React.RefObject<HTMLFormElement | null>) ||\n formRefForScrollToErrorField;\n\n const handleKeyDown = useCallback(\n async (event: React.KeyboardEvent<HTMLFormElement>) => {\n const target = event.target as HTMLElement & { editor?: unknown };\n const isEventFromEditorOrTextarea =\n target.tagName === \"TEXTAREA\" || target.editor;\n\n if (event.key !== \"Enter\") return;\n if (isEventFromEditorOrTextarea && !event.metaKey) return;\n\n event.preventDefault();\n\n if (event.shiftKey) return;\n if (!isFormDirty || isSubmitting) return;\n\n try {\n const errors = await validateForm();\n const fieldStatuses = getFieldsWithServerError(status);\n\n if (\n Object.keys(errors).length > 0 ||\n Object.keys(fieldStatuses).length > 0\n ) {\n setErrors(errors);\n setTouched({ ...errors, ...status });\n if (scrollToErrorField) {\n scrollToError(formRef, errors as Record<string, unknown>, status);\n }\n } else {\n submitForm();\n }\n } catch (error) {\n console.error(\n \"An unhandled error was caught from validateForm()\",\n error\n );\n }\n },\n [\n validateForm,\n setErrors,\n setTouched,\n isFormDirty,\n isSubmitting,\n submitForm,\n status,\n scrollToErrorField,\n formRef,\n ]\n );\n\n return (\n <FormikForm\n {...{ className }}\n noValidate\n ref={formRef}\n onKeyDown={handleKeyDown}\n {...formProps}\n >\n {scrollToErrorField && <ScrollToErrorField {...{ formRef }} />}\n {children}\n </FormikForm>\n );\n }\n);\n\nFormWrapper.displayName = \"FormWrapper\";\n\nexport default FormWrapper;\n","import React, { forwardRef, useRef } from \"react\";\n\nimport { Formik, FormikConfig, FormikProps, FormikValues } from \"formik\";\n\nimport FormWrapper from \"./FormWrapper\";\nimport { getFieldsWithServerError } from \"./ScrollToErrorField/utils\";\n\nexport interface FormProps<T extends FormikValues = FormikValues> {\n /** Formik configuration: initialValues, validationSchema, onSubmit, etc. */\n formikProps: FormikConfig<T>;\n /** Props forwarded to the HTML form element. */\n formProps?: React.ComponentProps<\"form\">;\n /** Auto-scroll to the first error field on submit. */\n scrollToErrorField?: boolean;\n /** Additional class name for the form wrapper. */\n className?: string;\n /** Render children directly or as a function receiving FormikProps. */\n children: React.ReactNode | ((props: FormikProps<T>) => React.ReactNode);\n}\n\nconst Form = forwardRef<HTMLFormElement, FormProps>(\n (\n { className, children, formikProps, formProps, scrollToErrorField = false },\n ref\n ) => {\n const formikRef = useRef<FormikProps<FormikValues>>(null);\n\n const handleSubmit: FormikConfig<FormikValues>[\"onSubmit\"] = (\n values,\n actions\n ) => {\n const fieldsWithServerError = getFieldsWithServerError(\n formikRef.current?.status\n );\n\n if (fieldsWithServerError.length > 0) {\n actions.setSubmitting(false);\n\n return undefined;\n }\n\n return formikProps.onSubmit(values, actions);\n };\n\n return (\n <Formik\n innerRef={formikRef as React.Ref<FormikProps<FormikValues>>}\n {...formikProps}\n onSubmit={handleSubmit}\n >\n {props => (\n <FormWrapper {...{ className, formProps, ref, scrollToErrorField }}>\n {typeof children === \"function\" ? children(props) : children}\n </FormWrapper>\n )}\n </Formik>\n );\n }\n);\n\nForm.displayName = \"Form\";\n\nexport { Form };\n"],"names":["FormikForm"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export { B as Badge } from './Badge-ChmtKioK.js';
|
|
|
11
11
|
export { b as Button } from './Button-ZssOVkG0.js';
|
|
12
12
|
export { C as Callout } from './Callout-DJGi3MQR.js';
|
|
13
13
|
export { C as Checkbox } from './Checkbox-BalUzegZ.js';
|
|
14
|
-
export { C as ColorPicker } from './ColorPicker-
|
|
14
|
+
export { C as ColorPicker } from './ColorPicker-BvWNd8Tp.js';
|
|
15
15
|
export { D as DataTable, u as useColumnOrdering, a as useColumnPinning, b as useColumnVisibility, c as useTablePagination, d as useTableSelection, e as useTableSort } from './DataTable-DKYkrFfk.js';
|
|
16
16
|
export { D as DatePicker } from './DatePicker-B3kUEuKH.js';
|
|
17
17
|
export { D as Dialog } from './Dialog-Yw34WDqY.js';
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ColorPicker-ClnRUq9y.js","sources":["../node_modules/lucide-react/dist/esm/icons/pipette.js","../src/components/ColorPicker/hooks/useEyeDropper.ts","../src/components/ColorPicker/constants.ts","../src/components/ColorPicker/hooks/useRecentlyUsedColors.ts","../src/components/ColorPicker/utils.ts","../src/components/ColorPicker/Palette.tsx","../src/components/ColorPicker/Target.tsx","../src/components/ColorPicker/ColorPicker.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.577.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m12 9-8.414 8.414A2 2 0 0 0 3 18.828v1.344a2 2 0 0 1-.586 1.414A2 2 0 0 1 3.828 21h1.344a2 2 0 0 0 1.414-.586L15 12\",\n key: \"1y3wsu\"\n }\n ],\n [\n \"path\",\n {\n d: \"m18 9 .4.4a1 1 0 1 1-3 3l-3.8-3.8a1 1 0 1 1 3-3l.4.4 3.4-3.4a1 1 0 1 1 3 3z\",\n key: \"110lr1\"\n }\n ],\n [\"path\", { d: \"m2 22 .414-.414\", key: \"jhxm08\" }]\n];\nconst Pipette = createLucideIcon(\"pipette\", __iconNode);\n\nexport { __iconNode, Pipette as default };\n//# sourceMappingURL=pipette.js.map\n","import { useCallback } from \"react\";\n\ninterface EyeDropperResult {\n sRGBHex: string;\n}\n\ndeclare global {\n interface Window {\n EyeDropper?: new () => { open: () => Promise<EyeDropperResult> };\n }\n}\n\nconst isSupported = typeof window !== \"undefined\" && \"EyeDropper\" in window;\n\nexport const useEyeDropper = () => {\n const open = useCallback(async (): Promise<string> => {\n if (!window.EyeDropper) throw new Error(\"EyeDropper API not supported\");\n\n const dropper = new window.EyeDropper();\n const result = await dropper.open();\n\n return result.sRGBHex;\n }, []);\n\n return { isSupported, open };\n};\n","export const DEFAULT_PALETTE_COLORS = [\n { hex: \"#FFFFFF\" },\n { hex: \"#D6D6D6\" },\n { hex: \"#0A0E13\" },\n { hex: \"#FECE1E\" },\n { hex: \"#F32E48\" },\n { hex: \"#02C39A\" },\n { hex: \"#2A79C4\" },\n { hex: \"#B3E5FC\" },\n { hex: \"#C3C6F9\" },\n { hex: \"#8064CE\" },\n { hex: \"#FE861E\" },\n { hex: \"#FF7DC9\" },\n { hex: \"#028090\" },\n { hex: \"#095482\" },\n];\n\nexport const RECENTLY_USED_STORAGE_KEY = \"recently-used-colors\";\n\nexport const TARGET_SIZES = {\n small: \"small\",\n medium: \"medium\",\n large: \"large\",\n} as const;\n\nexport const PICKER_HEIGHT: Record<string, string> = {\n small: \"100px\",\n medium: \"120px\",\n large: \"140px\",\n};\n","import { useSyncExternalStore } from \"react\";\n\nimport { RECENTLY_USED_STORAGE_KEY } from \"../constants\";\n\ninterface ColorValue {\n hex: string;\n rgb: string | { r: number; g: number; b: number; a?: number };\n}\n\nconst getFromStorage = (key: string, fallback: ColorValue[]): ColorValue[] => {\n try {\n const stored = localStorage.getItem(key);\n\n return stored ? JSON.parse(stored) : fallback;\n } catch {\n return fallback;\n }\n};\n\nconst setToStorage = (key: string, value: ColorValue[]) => {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // Silently fail if storage is unavailable\n }\n};\n\nconst createSyncedStore = (storageKey: string) => {\n const listeners = new Set<() => void>();\n\n const store = {\n value: getFromStorage(storageKey, []),\n getSnapshot: () => store.value,\n getServerSnapshot: () => [] as ColorValue[],\n setValue: (newValue: ColorValue[]) => {\n store.value = newValue;\n setToStorage(storageKey, newValue);\n listeners.forEach(listener => listener());\n },\n subscribe: (callback: () => void) => {\n listeners.add(callback);\n\n const storageEventHandler = (event: StorageEvent) => {\n if (event.key !== storageKey) return;\n store.value = getFromStorage(storageKey, []);\n listeners.forEach(listener => listener());\n };\n\n if (listeners.size === 1) {\n window.addEventListener(\"storage\", storageEventHandler);\n }\n\n return () => {\n listeners.delete(callback);\n if (listeners.size === 0) {\n window.removeEventListener(\"storage\", storageEventHandler);\n }\n };\n },\n };\n\n return store;\n};\n\nconst store = createSyncedStore(RECENTLY_USED_STORAGE_KEY);\n\nexport const useRecentlyUsedColors = (): [\n ColorValue[],\n (value: ColorValue[]) => void,\n] => [\n useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getServerSnapshot\n ),\n store.setValue,\n];\n","/**\n * Validates a hex color string (3, 4, 6, or 8 digits with optional #).\n */\nexport const isValidHex = (hex: string): boolean =>\n /^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(hex);\n\n/**\n * Parses a hex color string into RGBA components.\n * Returns { r: 0, g: 0, b: 0, a: 1 } for invalid inputs.\n */\nexport const hexToRgb = (\n hex: string\n): { r: number; g: number; b: number; a: number } => {\n const raw = hex.replace(/^#/, \"\");\n\n if (\n !/^([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(raw)\n ) {\n return { r: 0, g: 0, b: 0, a: 1 };\n }\n\n let r: number,\n g: number,\n b: number,\n a = 255;\n if (raw.length === 3 || raw.length === 4) {\n r = parseInt(raw[0] + raw[0], 16);\n g = parseInt(raw[1] + raw[1], 16);\n b = parseInt(raw[2] + raw[2], 16);\n if (raw.length === 4) a = parseInt(raw[3] + raw[3], 16);\n } else {\n r = parseInt(raw.slice(0, 2), 16);\n g = parseInt(raw.slice(2, 4), 16);\n b = parseInt(raw.slice(4, 6), 16);\n if (raw.length === 8) a = parseInt(raw.slice(6, 8), 16);\n }\n\n return { r, g, b, a: Math.round((a / 255) * 100) / 100 };\n};\n\n/**\n * Converts a hex color to an 8-digit hex string (#RRGGBBAA).\n */\nexport const hexToHex8 = (hex: string): string => {\n const { r, g, b, a } = hexToRgb(hex);\n const alpha = Math.round(a * 255);\n\n return `#${[r, g, b, alpha].map(channel => channel.toString(16).padStart(2, \"0\")).join(\"\")}`;\n};\n\n/**\n * Converts a color value to a normalized { hex, rgb } object.\n * Handles transparency and validity checks.\n */\nexport const getColor = (\n colorValue: string,\n showTransparencyControl: boolean\n): { hex: string; rgb: { r: number; g: number; b: number; a: number } } => {\n if (!isValidHex(colorValue)) {\n return { hex: colorValue, rgb: { r: 0, g: 0, b: 0, a: 1 } };\n }\n\n const rgb = hexToRgb(colorValue);\n\n if (rgb.a === 0) {\n return { hex: colorValue, rgb };\n }\n\n const hex = showTransparencyControl\n ? hexToHex8(colorValue)\n : `#${colorValue.replace(/^#/, \"\").slice(0, 6)}`;\n\n return { hex, rgb: hexToRgb(hex) };\n};\n","import React, { forwardRef } from \"react\";\n\nimport { cn } from \"src/shadcn/lib/utils\";\n\nimport { isValidHex } from \"./utils\";\nimport { DEFAULT_PALETTE_COLORS } from \"./constants\";\nimport type { PaletteColor } from \"./types\";\n\nexport interface PaletteProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"onChange\"\n> {\n /** Currently selected color. */\n color?: string;\n /** List of colors to render. */\n colorList?: PaletteColor[];\n /** Callback when a color swatch is clicked. */\n onChange?: (color: string) => void;\n}\n\nconst Palette = forwardRef<HTMLDivElement, PaletteProps>(\n (\n {\n color,\n colorList = DEFAULT_PALETTE_COLORS,\n onChange,\n className,\n ...otherProps\n },\n ref\n ) => (\n <div\n ref={ref}\n className={cn(\n \"flex flex-row flex-wrap items-start justify-start gap-1\",\n className\n )}\n {...otherProps}\n >\n {colorList.map(item => {\n const rgbValue =\n \"rgb\" in item && typeof item.rgb === \"string\" ? item.rgb : undefined;\n const value = item.hex ?? rgbValue ?? \"\";\n const isActive =\n !!color && !!value && color.toLowerCase() === value.toLowerCase();\n\n return (\n <button\n type=\"button\"\n key={value}\n data-testid=\"color-palette-item\"\n className={cn(\n \"size-6 rounded-[5px] border cursor-pointer overflow-hidden transition-colors\",\n isActive\n ? \"border-muted-foreground\"\n : \"border-border hover:border-muted-foreground/50\"\n )}\n onClick={() => onChange?.(value)}\n >\n <span\n className={cn(\n \"block size-full\",\n isValidHex(value)\n ? \"\"\n : \"bg-[repeating-conic-gradient(#ccc_0_25%,transparent_0_50%)] bg-[length:8px_8px]\"\n )}\n style={isValidHex(value) ? { backgroundColor: value } : undefined}\n />\n </button>\n );\n })}\n </div>\n )\n);\n\nPalette.displayName = \"ColorPicker.Palette\";\n\nexport { Palette };\n","import React, { forwardRef } from \"react\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"src/shadcn/lib/utils\";\n\nconst targetVariants = cva(\n \"inline-flex items-center justify-between rounded-md border border-input bg-background transition-colors hover:border-muted-foreground focus-visible:outline-none focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-primary/15 cursor-pointer\",\n {\n variants: {\n size: {\n small: \"h-7 p-0.5 gap-2\",\n medium: \"h-8 p-1 gap-2\",\n large: \"h-10 p-1.5 gap-3\",\n },\n },\n defaultVariants: {\n size: \"large\",\n },\n }\n);\n\nexport interface TargetProps\n extends\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"size\">,\n VariantProps<typeof targetVariants> {\n /** Show hex code text beside the color swatch. */\n showHexValue?: boolean;\n /** The original color prop value. */\n color?: string;\n /** The resolved color value to display. */\n colorValue?: string;\n}\n\nconst Target = forwardRef<HTMLButtonElement, TargetProps>(\n (\n { size = \"large\", showHexValue, color, colorValue, className, ...props },\n ref\n ) => (\n <button\n ref={ref}\n type=\"button\"\n data-testid=\"color-picker-target\"\n className={cn(targetVariants({ size }), className)}\n {...props}\n >\n {showHexValue && (\n <span className=\"text-sm font-medium text-foreground min-w-[4.5rem] ps-1\">\n {color}\n </span>\n )}\n <span className=\"inline-flex items-center gap-2\">\n <span\n className=\"block size-5 rounded-md border border-border\"\n style={{ backgroundColor: colorValue }}\n />\n <ChevronDown className=\"size-4 text-muted-foreground\" />\n </span>\n </button>\n )\n);\n\nTarget.displayName = \"ColorPicker.Target\";\n\nexport { Target };\n","import { forwardRef, useState, useRef } from \"react\";\n\nimport { Pipette } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n HexColorPicker,\n HexColorInput,\n HexAlphaColorPicker,\n} from \"react-colorful\";\nimport { Button } from \"src/primitives/Button\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"src/primitives/Popover\";\nimport { cn } from \"src/shadcn/lib/utils\";\n\nimport { useEyeDropper } from \"./hooks/useEyeDropper\";\nimport { useRecentlyUsedColors } from \"./hooks/useRecentlyUsedColors\";\nimport { Palette } from \"./Palette\";\nimport { Target } from \"./Target\";\nimport { PICKER_HEIGHT } from \"./constants\";\nimport type { ColorPickerProps } from \"./types\";\nimport { getColor } from \"./utils\";\n\nconst ColorPicker = forwardRef<HTMLDivElement, ColorPickerProps>(\n (\n {\n color = \"\",\n size = \"large\",\n onChange,\n dropdownProps,\n showEyeDropper = true,\n showHexValue = false,\n showTransparencyControl = false,\n showPicker = true,\n showHexPicker = true,\n colorPalette,\n showRecentlyUsedColors = showPicker,\n className,\n },\n ref\n ) => {\n const { t } = useTranslation();\n const [colorInternal, setColorInternal] = useState(color);\n const [isColorSelected, setIsColorSelected] = useState(false);\n const [open, setOpen] = useState(false);\n const hexColorInputValue = useRef(\"\");\n const { isSupported: eyeDropperSupported, open: openEyeDropper } =\n useEyeDropper();\n const [recentlyUsedColors, setRecentlyUsedColors] = useRecentlyUsedColors();\n\n const PickerComponent = showTransparencyControl\n ? HexAlphaColorPicker\n : HexColorPicker;\n\n const colorValue = color ?? colorInternal ?? \"\";\n\n const onColorChange = (value: string) => {\n setIsColorSelected(true);\n\n if (onChange) {\n onChange(getColor(value, showTransparencyControl));\n } else {\n setColorInternal(value);\n }\n };\n\n const onColorInputChange = (hex: string) => {\n hexColorInputValue.current = hex;\n const expectedLength = showTransparencyControl ? 9 : 7;\n if (hex.length !== expectedLength) return;\n\n onColorChange(hex);\n hexColorInputValue.current = \"\";\n };\n\n const onBlur = () => {\n if (!hexColorInputValue.current) return;\n\n onColorChange(hexColorInputValue.current);\n hexColorInputValue.current = \"\";\n };\n\n const pickColor = async () => {\n try {\n const hex = await openEyeDropper();\n onColorChange(hex);\n } catch {\n // User cancelled or API unavailable\n }\n };\n\n const onOpenChange = (nextOpen: boolean) => {\n if (!nextOpen && showRecentlyUsedColors && isColorSelected) {\n const newColor = getColor(colorValue, showTransparencyControl);\n const filtered = recentlyUsedColors.filter(\n ({ hex }) => hex !== newColor.hex\n );\n const updated = [newColor, ...filtered];\n if (updated.length > 14) updated.pop();\n\n setRecentlyUsedColors(updated);\n setIsColorSelected(false);\n }\n\n setOpen(nextOpen);\n };\n\n return (\n <Popover open={open} onOpenChange={onOpenChange}>\n <PopoverTrigger asChild>\n <Target\n color={color}\n colorValue={colorValue}\n showHexValue={showHexValue}\n size={size}\n />\n </PopoverTrigger>\n <PopoverContent\n ref={ref}\n align=\"start\"\n side=\"bottom\"\n className={cn(\"w-auto p-3\", className)}\n {...dropdownProps}\n >\n <div className=\"flex flex-col gap-3 w-56\">\n {showPicker && (\n <>\n {showHexPicker && (\n <div\n data-testid=\"neeto-color-picker-section\"\n style={{\n [\"--react-colorful-height\" as string]:\n PICKER_HEIGHT[size] ?? \"140px\",\n }}\n >\n <PickerComponent\n color={colorValue}\n onChange={onColorChange}\n style={{\n width: \"100%\",\n height: PICKER_HEIGHT[size] ?? \"140px\",\n }}\n />\n </div>\n )}\n <div className=\"flex items-center justify-center gap-2\">\n {showEyeDropper && eyeDropperSupported && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={pickColor}\n aria-label={t(\n \"neetoatoms.colorPicker.pickColor\",\n \"Pick color from screen\"\n )}\n >\n <Pipette className=\"size-4\" />\n </Button>\n )}\n <div\n className=\"flex-1\"\n data-testid=\"colorpicker-editable-input\"\n >\n <HexColorInput\n prefixed\n alpha={!!showTransparencyControl}\n color={colorValue}\n data-testid=\"colorpicker-editable-input-textbox\"\n onChange={onColorInputChange}\n onBlur={onBlur}\n className=\"h-8 w-full rounded-lg border border-input bg-transparent px-2.5 text-base outline-none focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-primary/15 md:text-sm\"\n />\n </div>\n </div>\n </>\n )}\n <div\n data-testid=\"color-palette\"\n className={cn(showPicker && \"border-t border-border pt-3\")}\n >\n <Palette\n color={color}\n colorList={colorPalette}\n onChange={onColorChange}\n />\n </div>\n {showRecentlyUsedColors && recentlyUsedColors.length > 0 && (\n <div\n className=\"border-t border-border pt-3\"\n data-testid=\"color-palette-recently-used\"\n >\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n {t(\"neetoatoms.colorPicker.recentlyUsed\", \"Recently used\")}\n </p>\n <Palette\n colorList={recentlyUsedColors}\n onChange={onColorChange}\n />\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n }\n);\n\nColorPicker.displayName = \"ColorPicker\";\n\nexport { ColorPicker };\n"],"names":["store"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ColorPicker-rhCnblTv.js","sources":["../../node_modules/lucide-react/dist/esm/icons/pipette.js","../../src/components/ColorPicker/hooks/useEyeDropper.ts","../../src/components/ColorPicker/constants.ts","../../src/components/ColorPicker/hooks/useRecentlyUsedColors.ts","../../src/components/ColorPicker/utils.ts","../../src/components/ColorPicker/Palette.tsx","../../src/components/ColorPicker/Target.tsx","../../src/components/ColorPicker/ColorPicker.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.577.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m12 9-8.414 8.414A2 2 0 0 0 3 18.828v1.344a2 2 0 0 1-.586 1.414A2 2 0 0 1 3.828 21h1.344a2 2 0 0 0 1.414-.586L15 12\",\n key: \"1y3wsu\"\n }\n ],\n [\n \"path\",\n {\n d: \"m18 9 .4.4a1 1 0 1 1-3 3l-3.8-3.8a1 1 0 1 1 3-3l.4.4 3.4-3.4a1 1 0 1 1 3 3z\",\n key: \"110lr1\"\n }\n ],\n [\"path\", { d: \"m2 22 .414-.414\", key: \"jhxm08\" }]\n];\nconst Pipette = createLucideIcon(\"pipette\", __iconNode);\n\nexport { __iconNode, Pipette as default };\n//# sourceMappingURL=pipette.js.map\n","import { useCallback } from \"react\";\n\ninterface EyeDropperResult {\n sRGBHex: string;\n}\n\ndeclare global {\n interface Window {\n EyeDropper?: new () => { open: () => Promise<EyeDropperResult> };\n }\n}\n\nconst isSupported = typeof window !== \"undefined\" && \"EyeDropper\" in window;\n\nexport const useEyeDropper = () => {\n const open = useCallback(async (): Promise<string> => {\n if (!window.EyeDropper) throw new Error(\"EyeDropper API not supported\");\n\n const dropper = new window.EyeDropper();\n const result = await dropper.open();\n\n return result.sRGBHex;\n }, []);\n\n return { isSupported, open };\n};\n","export const DEFAULT_PALETTE_COLORS = [\n { hex: \"#FFFFFF\" },\n { hex: \"#D6D6D6\" },\n { hex: \"#0A0E13\" },\n { hex: \"#FECE1E\" },\n { hex: \"#F32E48\" },\n { hex: \"#02C39A\" },\n { hex: \"#2A79C4\" },\n { hex: \"#B3E5FC\" },\n { hex: \"#C3C6F9\" },\n { hex: \"#8064CE\" },\n { hex: \"#FE861E\" },\n { hex: \"#FF7DC9\" },\n { hex: \"#028090\" },\n { hex: \"#095482\" },\n];\n\nexport const RECENTLY_USED_STORAGE_KEY = \"recently-used-colors\";\n\nexport const TARGET_SIZES = {\n small: \"small\",\n medium: \"medium\",\n large: \"large\",\n} as const;\n\nexport const PICKER_HEIGHT: Record<string, string> = {\n small: \"100px\",\n medium: \"120px\",\n large: \"140px\",\n};\n","import { useSyncExternalStore } from \"react\";\n\nimport { RECENTLY_USED_STORAGE_KEY } from \"../constants\";\n\ninterface ColorValue {\n hex: string;\n rgb: string | { r: number; g: number; b: number; a?: number };\n}\n\nconst getFromStorage = (key: string, fallback: ColorValue[]): ColorValue[] => {\n try {\n const stored = localStorage.getItem(key);\n\n return stored ? JSON.parse(stored) : fallback;\n } catch {\n return fallback;\n }\n};\n\nconst setToStorage = (key: string, value: ColorValue[]) => {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // Silently fail if storage is unavailable\n }\n};\n\nconst createSyncedStore = (storageKey: string) => {\n const listeners = new Set<() => void>();\n\n const store = {\n value: getFromStorage(storageKey, []),\n getSnapshot: () => store.value,\n getServerSnapshot: () => [] as ColorValue[],\n setValue: (newValue: ColorValue[]) => {\n store.value = newValue;\n setToStorage(storageKey, newValue);\n listeners.forEach(listener => listener());\n },\n subscribe: (callback: () => void) => {\n listeners.add(callback);\n\n const storageEventHandler = (event: StorageEvent) => {\n if (event.key !== storageKey) return;\n store.value = getFromStorage(storageKey, []);\n listeners.forEach(listener => listener());\n };\n\n if (listeners.size === 1) {\n window.addEventListener(\"storage\", storageEventHandler);\n }\n\n return () => {\n listeners.delete(callback);\n if (listeners.size === 0) {\n window.removeEventListener(\"storage\", storageEventHandler);\n }\n };\n },\n };\n\n return store;\n};\n\nconst store = createSyncedStore(RECENTLY_USED_STORAGE_KEY);\n\nexport const useRecentlyUsedColors = (): [\n ColorValue[],\n (value: ColorValue[]) => void,\n] => [\n useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getServerSnapshot\n ),\n store.setValue,\n];\n","/**\n * Validates a hex color string (3, 4, 6, or 8 digits with optional #).\n */\nexport const isValidHex = (hex: string): boolean =>\n /^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(hex);\n\n/**\n * Parses a hex color string into RGBA components.\n * Returns { r: 0, g: 0, b: 0, a: 1 } for invalid inputs.\n */\nexport const hexToRgb = (\n hex: string\n): { r: number; g: number; b: number; a: number } => {\n const raw = hex.replace(/^#/, \"\");\n\n if (\n !/^([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(raw)\n ) {\n return { r: 0, g: 0, b: 0, a: 1 };\n }\n\n let r: number,\n g: number,\n b: number,\n a = 255;\n if (raw.length === 3 || raw.length === 4) {\n r = parseInt(raw[0] + raw[0], 16);\n g = parseInt(raw[1] + raw[1], 16);\n b = parseInt(raw[2] + raw[2], 16);\n if (raw.length === 4) a = parseInt(raw[3] + raw[3], 16);\n } else {\n r = parseInt(raw.slice(0, 2), 16);\n g = parseInt(raw.slice(2, 4), 16);\n b = parseInt(raw.slice(4, 6), 16);\n if (raw.length === 8) a = parseInt(raw.slice(6, 8), 16);\n }\n\n return { r, g, b, a: Math.round((a / 255) * 100) / 100 };\n};\n\n/**\n * Converts a hex color to an 8-digit hex string (#RRGGBBAA).\n */\nexport const hexToHex8 = (hex: string): string => {\n const { r, g, b, a } = hexToRgb(hex);\n const alpha = Math.round(a * 255);\n\n return `#${[r, g, b, alpha].map(channel => channel.toString(16).padStart(2, \"0\")).join(\"\")}`;\n};\n\n/**\n * Converts a color value to a normalized { hex, rgb } object.\n * Handles transparency and validity checks.\n */\nexport const getColor = (\n colorValue: string,\n showTransparencyControl: boolean\n): { hex: string; rgb: { r: number; g: number; b: number; a: number } } => {\n if (!isValidHex(colorValue)) {\n return { hex: colorValue, rgb: { r: 0, g: 0, b: 0, a: 1 } };\n }\n\n const rgb = hexToRgb(colorValue);\n\n if (rgb.a === 0) {\n return { hex: colorValue, rgb };\n }\n\n const hex = showTransparencyControl\n ? hexToHex8(colorValue)\n : `#${colorValue.replace(/^#/, \"\").slice(0, 6)}`;\n\n return { hex, rgb: hexToRgb(hex) };\n};\n","import React, { forwardRef } from \"react\";\n\nimport { cn } from \"src/shadcn/lib/utils\";\n\nimport { isValidHex } from \"./utils\";\nimport { DEFAULT_PALETTE_COLORS } from \"./constants\";\nimport type { PaletteColor } from \"./types\";\n\nexport interface PaletteProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"onChange\"\n> {\n /** Currently selected color. */\n color?: string;\n /** List of colors to render. */\n colorList?: PaletteColor[];\n /** Callback when a color swatch is clicked. */\n onChange?: (color: string) => void;\n}\n\nconst Palette = forwardRef<HTMLDivElement, PaletteProps>(\n (\n {\n color,\n colorList = DEFAULT_PALETTE_COLORS,\n onChange,\n className,\n ...otherProps\n },\n ref\n ) => (\n <div\n ref={ref}\n className={cn(\n \"flex flex-row flex-wrap items-start justify-start gap-1\",\n className\n )}\n {...otherProps}\n >\n {colorList.map(item => {\n const rgbValue =\n \"rgb\" in item && typeof item.rgb === \"string\" ? item.rgb : undefined;\n const value = item.hex ?? rgbValue ?? \"\";\n const isActive =\n !!color && !!value && color.toLowerCase() === value.toLowerCase();\n\n return (\n <button\n type=\"button\"\n key={value}\n data-testid=\"color-palette-item\"\n className={cn(\n \"size-6 rounded-[5px] border cursor-pointer overflow-hidden transition-colors\",\n isActive\n ? \"border-muted-foreground\"\n : \"border-border hover:border-muted-foreground/50\"\n )}\n onClick={() => onChange?.(value)}\n >\n <span\n className={cn(\n \"block size-full\",\n isValidHex(value)\n ? \"\"\n : \"bg-[repeating-conic-gradient(#ccc_0_25%,transparent_0_50%)] bg-[length:8px_8px]\"\n )}\n style={isValidHex(value) ? { backgroundColor: value } : undefined}\n />\n </button>\n );\n })}\n </div>\n )\n);\n\nPalette.displayName = \"ColorPicker.Palette\";\n\nexport { Palette };\n","import React, { forwardRef } from \"react\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"src/shadcn/lib/utils\";\n\nconst targetVariants = cva(\n \"inline-flex items-center justify-between rounded-md border border-input bg-background transition-colors hover:border-muted-foreground focus-visible:outline-none focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-primary/15 cursor-pointer\",\n {\n variants: {\n size: {\n small: \"h-7 p-0.5 gap-2\",\n medium: \"h-8 p-1 gap-2\",\n large: \"h-10 p-1.5 gap-3\",\n },\n },\n defaultVariants: {\n size: \"large\",\n },\n }\n);\n\nexport interface TargetProps\n extends\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"size\">,\n VariantProps<typeof targetVariants> {\n /** Show hex code text beside the color swatch. */\n showHexValue?: boolean;\n /** The original color prop value. */\n color?: string;\n /** The resolved color value to display. */\n colorValue?: string;\n}\n\nconst Target = forwardRef<HTMLButtonElement, TargetProps>(\n (\n { size = \"large\", showHexValue, color, colorValue, className, ...props },\n ref\n ) => (\n <button\n ref={ref}\n type=\"button\"\n data-testid=\"color-picker-target\"\n className={cn(targetVariants({ size }), className)}\n {...props}\n >\n {showHexValue && (\n <span className=\"text-sm font-medium text-foreground min-w-[4.5rem] ps-1\">\n {color}\n </span>\n )}\n <span className=\"inline-flex items-center gap-2\">\n <span\n className=\"block size-5 rounded-md border border-border\"\n style={{ backgroundColor: colorValue }}\n />\n <ChevronDown className=\"size-4 text-muted-foreground\" />\n </span>\n </button>\n )\n);\n\nTarget.displayName = \"ColorPicker.Target\";\n\nexport { Target };\n","import { forwardRef, useState, useRef } from \"react\";\n\nimport { Pipette } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n HexColorPicker,\n HexColorInput,\n HexAlphaColorPicker,\n} from \"react-colorful\";\nimport { Button } from \"src/primitives/Button\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"src/primitives/Popover\";\nimport { cn } from \"src/shadcn/lib/utils\";\n\nimport { useEyeDropper } from \"./hooks/useEyeDropper\";\nimport { useRecentlyUsedColors } from \"./hooks/useRecentlyUsedColors\";\nimport { Palette } from \"./Palette\";\nimport { Target } from \"./Target\";\nimport { PICKER_HEIGHT } from \"./constants\";\nimport type { ColorPickerProps } from \"./types\";\nimport { getColor } from \"./utils\";\n\nconst ColorPicker = forwardRef<HTMLDivElement, ColorPickerProps>(\n (\n {\n color = \"\",\n size = \"large\",\n onChange,\n dropdownProps,\n showEyeDropper = true,\n showHexValue = false,\n showTransparencyControl = false,\n showPicker = true,\n showHexPicker = true,\n colorPalette,\n showRecentlyUsedColors = showPicker,\n className,\n },\n ref\n ) => {\n const { t } = useTranslation();\n const [colorInternal, setColorInternal] = useState(color);\n const [isColorSelected, setIsColorSelected] = useState(false);\n const [open, setOpen] = useState(false);\n const hexColorInputValue = useRef(\"\");\n const { isSupported: eyeDropperSupported, open: openEyeDropper } =\n useEyeDropper();\n const [recentlyUsedColors, setRecentlyUsedColors] = useRecentlyUsedColors();\n\n const PickerComponent = showTransparencyControl\n ? HexAlphaColorPicker\n : HexColorPicker;\n\n const colorValue = color ?? colorInternal ?? \"\";\n\n const onColorChange = (value: string) => {\n setIsColorSelected(true);\n\n if (onChange) {\n onChange(getColor(value, showTransparencyControl));\n } else {\n setColorInternal(value);\n }\n };\n\n const onColorInputChange = (hex: string) => {\n hexColorInputValue.current = hex;\n const expectedLength = showTransparencyControl ? 9 : 7;\n if (hex.length !== expectedLength) return;\n\n onColorChange(hex);\n hexColorInputValue.current = \"\";\n };\n\n const onBlur = () => {\n if (!hexColorInputValue.current) return;\n\n onColorChange(hexColorInputValue.current);\n hexColorInputValue.current = \"\";\n };\n\n const pickColor = async () => {\n try {\n const hex = await openEyeDropper();\n onColorChange(hex);\n } catch {\n // User cancelled or API unavailable\n }\n };\n\n const onOpenChange = (nextOpen: boolean) => {\n if (!nextOpen && showRecentlyUsedColors && isColorSelected) {\n const newColor = getColor(colorValue, showTransparencyControl);\n const filtered = recentlyUsedColors.filter(\n ({ hex }) => hex !== newColor.hex\n );\n const updated = [newColor, ...filtered];\n if (updated.length > 14) updated.pop();\n\n setRecentlyUsedColors(updated);\n setIsColorSelected(false);\n }\n\n setOpen(nextOpen);\n };\n\n return (\n <Popover open={open} onOpenChange={onOpenChange}>\n <PopoverTrigger asChild>\n <Target\n color={color}\n colorValue={colorValue}\n showHexValue={showHexValue}\n size={size}\n />\n </PopoverTrigger>\n <PopoverContent\n ref={ref}\n align=\"start\"\n side=\"bottom\"\n className={cn(\"w-auto p-3\", className)}\n {...dropdownProps}\n >\n <div className=\"flex flex-col gap-3 w-56\">\n {showPicker && (\n <>\n {showHexPicker && (\n <div\n data-testid=\"neeto-color-picker-section\"\n style={{\n [\"--react-colorful-height\" as string]:\n PICKER_HEIGHT[size] ?? \"140px\",\n }}\n >\n <PickerComponent\n color={colorValue}\n onChange={onColorChange}\n style={{\n width: \"100%\",\n height: PICKER_HEIGHT[size] ?? \"140px\",\n }}\n />\n </div>\n )}\n <div className=\"flex items-center justify-center gap-2\">\n {showEyeDropper && eyeDropperSupported && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={pickColor}\n aria-label={t(\n \"neetoatoms.colorPicker.pickColor\",\n \"Pick color from screen\"\n )}\n >\n <Pipette className=\"size-4\" />\n </Button>\n )}\n <div\n className=\"flex-1\"\n data-testid=\"colorpicker-editable-input\"\n >\n <HexColorInput\n prefixed\n alpha={!!showTransparencyControl}\n color={colorValue}\n data-testid=\"colorpicker-editable-input-textbox\"\n onChange={onColorInputChange}\n onBlur={onBlur}\n className=\"h-8 w-full rounded-lg border border-input bg-transparent px-2.5 text-base outline-none focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-primary/15 md:text-sm\"\n />\n </div>\n </div>\n </>\n )}\n <div\n data-testid=\"color-palette\"\n className={cn(showPicker && \"border-t border-border pt-3\")}\n >\n <Palette\n color={color}\n colorList={colorPalette}\n onChange={onColorChange}\n />\n </div>\n {showRecentlyUsedColors && recentlyUsedColors.length > 0 && (\n <div\n className=\"border-t border-border pt-3\"\n data-testid=\"color-palette-recently-used\"\n >\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n {t(\"neetoatoms.colorPicker.recentlyUsed\", \"Recently used\")}\n </p>\n <Palette\n colorList={recentlyUsedColors}\n onChange={onColorChange}\n />\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n }\n);\n\nColorPicker.displayName = \"ColorPicker\";\n\nexport { ColorPicker };\n"],"names":["createLucideIcon","useCallback","store","useSyncExternalStore","forwardRef","jsx","cn","cva","jsxs","ChevronDown","useTranslation","useState","useRef","HexAlphaColorPicker","HexColorPicker","Popover","PopoverTrigger","PopoverContent","Fragment","Button","HexColorInput"],"mappings":"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","x_google_ignoreList":[0]}
|