@skybin-tech/nebula-ui 0.0.30 → 0.0.31

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.
Files changed (50) hide show
  1. package/dist/cjs/components/Form/DatePicker.cjs +8 -2
  2. package/dist/cjs/components/Form/DatePicker.cjs.map +1 -1
  3. package/dist/cjs/components/Form/DateTimePicker.cjs +202 -0
  4. package/dist/cjs/components/Form/DateTimePicker.cjs.map +1 -0
  5. package/dist/cjs/components/Form/PasswordRevealToggle.cjs +21 -0
  6. package/dist/cjs/components/Form/PasswordRevealToggle.cjs.map +1 -0
  7. package/dist/cjs/components/Form/TextBox.cjs +29 -14
  8. package/dist/cjs/components/Form/TextBox.cjs.map +1 -1
  9. package/dist/cjs/components/Form/TimePicker.cjs +111 -0
  10. package/dist/cjs/components/Form/TimePicker.cjs.map +1 -0
  11. package/dist/cjs/components/Form/context.cjs +1 -1
  12. package/dist/cjs/components/Form/context.cjs.map +1 -1
  13. package/dist/cjs/components/Form/index.cjs +7 -0
  14. package/dist/cjs/components/Input/Input.cjs +32 -4
  15. package/dist/cjs/components/Input/Input.cjs.map +1 -1
  16. package/dist/cjs/index.cjs +7 -0
  17. package/dist/components/Form/DatePicker.d.ts.map +1 -1
  18. package/dist/components/Form/DatePicker.js +9 -3
  19. package/dist/components/Form/DatePicker.js.map +1 -1
  20. package/dist/components/Form/DateTimePicker.d.ts +28 -0
  21. package/dist/components/Form/DateTimePicker.d.ts.map +1 -0
  22. package/dist/components/Form/DateTimePicker.js +202 -0
  23. package/dist/components/Form/DateTimePicker.js.map +1 -0
  24. package/dist/components/Form/PasswordRevealToggle.d.ts +7 -0
  25. package/dist/components/Form/PasswordRevealToggle.d.ts.map +1 -0
  26. package/dist/components/Form/PasswordRevealToggle.js +21 -0
  27. package/dist/components/Form/PasswordRevealToggle.js.map +1 -0
  28. package/dist/components/Form/TextBox.d.ts +5 -0
  29. package/dist/components/Form/TextBox.d.ts.map +1 -1
  30. package/dist/components/Form/TextBox.js +30 -15
  31. package/dist/components/Form/TextBox.js.map +1 -1
  32. package/dist/components/Form/TimePicker.d.ts +14 -0
  33. package/dist/components/Form/TimePicker.d.ts.map +1 -0
  34. package/dist/components/Form/TimePicker.js +111 -0
  35. package/dist/components/Form/TimePicker.js.map +1 -0
  36. package/dist/components/Form/context.d.ts +1 -1
  37. package/dist/components/Form/context.d.ts.map +1 -1
  38. package/dist/components/Form/context.js +1 -1
  39. package/dist/components/Form/context.js.map +1 -1
  40. package/dist/components/Form/index.d.ts +6 -0
  41. package/dist/components/Form/index.d.ts.map +1 -1
  42. package/dist/components/Form/index.js +4 -1
  43. package/dist/components/Input/Input.d.ts +14 -2
  44. package/dist/components/Input/Input.d.ts.map +1 -1
  45. package/dist/components/Input/Input.js +34 -6
  46. package/dist/components/Input/Input.js.map +1 -1
  47. package/dist/index.d.ts +2 -2
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +4 -1
  50. package/package.json +1 -1
@@ -72,7 +72,7 @@ function buildZodSchemaFromRules(type, rules) {
72
72
  if (rules.required) return finalizeSchema(schema.refine((val) => val === true, { message: typeof rules.required === "string" ? rules.required : "This field is required" }), rules);
73
73
  return finalizeSchema(schema.optional(), rules);
74
74
  }
75
- if (type === "date") {
75
+ if (type === "date" || type === "datetime") {
76
76
  const schema = zod.z.coerce.date();
77
77
  if (!rules.required) return finalizeSchema(schema.optional(), rules);
78
78
  return finalizeSchema(schema, rules);
@@ -1 +1 @@
1
- {"version":3,"file":"context.cjs","names":[],"sources":["../../../../src/components/Form/context.ts"],"sourcesContent":["'use client';\r\n\r\nimport { createContext, useCallback, useRef } from \"react\";\r\nimport type { UseFormReturn, FieldValues } from \"react-hook-form\";\r\nimport { z } from \"zod\";\r\n\r\n/**\r\n * Validation rule types that can be applied to form fields\r\n */\r\nexport interface FieldValidationRules {\r\n /** Field is required */\r\n required?: boolean | string;\r\n /** Minimum length for strings */\r\n minLength?: number | { value: number; message: string };\r\n /** Maximum length for strings */\r\n maxLength?: number | { value: number; message: string };\r\n /** Minimum value for numbers */\r\n min?: number | { value: number; message: string };\r\n /** Maximum value for numbers */\r\n max?: number | { value: number; message: string };\r\n /** Regex pattern for validation */\r\n pattern?: RegExp | { value: RegExp; message: string };\r\n /** Email validation */\r\n email?: boolean | string;\r\n /** URL validation */\r\n url?: boolean | string;\r\n /** Custom validation function */\r\n validate?: (value: unknown) => boolean | string | Promise<boolean | string>;\r\n}\r\n\r\n/**\r\n * Form configuration options\r\n */\r\nexport interface FormConfig {\r\n /** Show validation errors inline */\r\n showInlineErrors?: boolean;\r\n /** Validate on blur */\r\n validateOnBlur?: boolean;\r\n /** Validate on change */\r\n validateOnChange?: boolean;\r\n /** Size of form controls */\r\n size?: \"sm\" | \"md\" | \"lg\";\r\n /** Layout direction */\r\n layout?: \"horizontal\" | \"vertical\" | \"inline\";\r\n /** Label width for horizontal layout */\r\n labelWidth?: string | number;\r\n /** Whether form is disabled */\r\n disabled?: boolean;\r\n /** Colon after label */\r\n colon?: boolean;\r\n}\r\n\r\n/**\r\n * Field registration info\r\n */\r\nexport interface FieldRegistration {\r\n name: string;\r\n type: \"string\" | \"number\" | \"boolean\" | \"date\" | \"array\";\r\n rules: FieldValidationRules;\r\n}\r\n\r\n/**\r\n * Form context value\r\n */\r\nexport interface FormContextValue<TFieldValues extends FieldValues = FieldValues>\r\n extends FormConfig {\r\n form: UseFormReturn<TFieldValues>;\r\n /** Register a field's validation rules */\r\n registerFieldValidation: (field: FieldRegistration) => void;\r\n /** Unregister a field's validation rules */\r\n unregisterFieldValidation: (name: string) => void;\r\n /** Get current validation schema */\r\n getValidationSchema: () => z.ZodObject<Record<string, z.ZodTypeAny>>;\r\n /** Trigger validation for a specific field */\r\n triggerValidation: (name: string) => Promise<boolean>;\r\n}\r\n\r\n/**\r\n * Default form configuration\r\n */\r\nexport const defaultFormConfig: FormConfig = {\r\n showInlineErrors: true,\r\n validateOnBlur: true,\r\n validateOnChange: false,\r\n size: \"md\",\r\n layout: \"vertical\",\r\n disabled: false,\r\n colon: true,\r\n};\r\n\r\n/**\r\n * Form context for sharing form state and configuration\r\n */\r\nexport const FormConfigContext = createContext<FormContextValue | null>(null);\r\n\r\n/**\r\n * Build a Zod schema from validation rules\r\n */\r\nexport function buildZodSchemaFromRules(\r\n type: FieldRegistration[\"type\"],\r\n rules: FieldValidationRules\r\n): z.ZodTypeAny {\r\n // Helper to extract value and message\r\n const getValueAndMessage = <T>(\r\n rule: T | { value: T; message: string } | undefined,\r\n defaultMessage: string\r\n ): { value: T; message: string } | null => {\r\n if (rule === undefined) return null;\r\n if (typeof rule === \"object\" && rule !== null && \"value\" in rule) {\r\n return rule as { value: T; message: string };\r\n }\r\n return { value: rule as T, message: defaultMessage };\r\n };\r\n\r\n // Build string schema\r\n if (type === \"string\") {\r\n let schema = z.string();\r\n\r\n const minLengthRule = getValueAndMessage(\r\n rules.minLength,\r\n `Minimum ${typeof rules.minLength === \"number\" ? rules.minLength : (rules.minLength as { value: number })?.value} characters required`\r\n );\r\n if (minLengthRule) {\r\n schema = schema.min(minLengthRule.value as number, minLengthRule.message);\r\n }\r\n\r\n const maxLengthRule = getValueAndMessage(\r\n rules.maxLength,\r\n `Maximum ${typeof rules.maxLength === \"number\" ? rules.maxLength : (rules.maxLength as { value: number })?.value} characters allowed`\r\n );\r\n if (maxLengthRule) {\r\n schema = schema.max(maxLengthRule.value as number, maxLengthRule.message);\r\n }\r\n\r\n if (rules.pattern !== undefined) {\r\n const patternRule = rules.pattern instanceof RegExp\r\n ? { value: rules.pattern, message: \"Invalid format\" }\r\n : rules.pattern;\r\n schema = schema.regex(patternRule.value, patternRule.message);\r\n }\r\n\r\n if (rules.email) {\r\n const message = typeof rules.email === \"string\" ? rules.email : \"Invalid email address\";\r\n schema = schema.email(message);\r\n }\r\n\r\n if (rules.url) {\r\n const message = typeof rules.url === \"string\" ? rules.url : \"Invalid URL\";\r\n schema = schema.url(message);\r\n }\r\n\r\n // Handle required - for strings, require non-empty\r\n if (rules.required) {\r\n const message = typeof rules.required === \"string\" ? rules.required : \"This field is required\";\r\n return finalizeSchema(\r\n z.preprocess(\r\n (value) => (value === undefined || value === null ? \"\" : value),\r\n schema.min(1, message)\r\n ),\r\n rules\r\n );\r\n }\r\n\r\n return finalizeSchema(schema.optional(), rules);\r\n }\r\n\r\n // Build number schema\r\n if (type === \"number\") {\r\n let schema = z.coerce.number();\r\n\r\n const minRule = getValueAndMessage(\r\n rules.min,\r\n `Minimum value is ${typeof rules.min === \"number\" ? rules.min : (rules.min as { value: number })?.value}`\r\n );\r\n if (minRule) {\r\n schema = schema.min(minRule.value as number, minRule.message);\r\n }\r\n\r\n const maxRule = getValueAndMessage(\r\n rules.max,\r\n `Maximum value is ${typeof rules.max === \"number\" ? rules.max : (rules.max as { value: number })?.value}`\r\n );\r\n if (maxRule) {\r\n schema = schema.max(maxRule.value as number, maxRule.message);\r\n }\r\n\r\n if (!rules.required) {\r\n return finalizeSchema(schema.optional(), rules);\r\n }\r\n return finalizeSchema(schema, rules);\r\n }\r\n\r\n // Build boolean schema\r\n if (type === \"boolean\") {\r\n const schema = z.boolean();\r\n if (rules.required) {\r\n return finalizeSchema(\r\n schema.refine((val) => val === true, {\r\n message: typeof rules.required === \"string\" ? rules.required : \"This field is required\",\r\n }),\r\n rules\r\n );\r\n }\r\n return finalizeSchema(schema.optional(), rules);\r\n }\r\n\r\n // Build date schema\r\n if (type === \"date\") {\r\n const schema = z.coerce.date();\r\n if (!rules.required) {\r\n return finalizeSchema(schema.optional(), rules);\r\n }\r\n return finalizeSchema(schema, rules);\r\n }\r\n\r\n // Build array schema\r\n if (type === \"array\") {\r\n let schema = z.array(z.unknown());\r\n if (rules.required) {\r\n const message = typeof rules.required === \"string\" ? rules.required : \"This field is required\";\r\n schema = schema.min(1, message);\r\n }\r\n return finalizeSchema(schema, rules);\r\n }\r\n\r\n // Default fallback\r\n return finalizeSchema(z.unknown(), rules);\r\n}\r\n\r\nfunction applyCustomValidate(\r\n schema: z.ZodTypeAny,\r\n rules: FieldValidationRules\r\n): z.ZodTypeAny {\r\n if (!rules.validate) {\r\n return schema;\r\n }\r\n\r\n const validateFn = rules.validate;\r\n\r\n return schema.superRefine(async (value, ctx) => {\r\n const result = await validateFn(value);\r\n\r\n if (result === true) {\r\n return;\r\n }\r\n\r\n ctx.addIssue({\r\n code: z.ZodIssueCode.custom,\r\n message: typeof result === \"string\" ? result : \"Invalid value\",\r\n });\r\n });\r\n}\r\n\r\nfunction finalizeSchema(\r\n schema: z.ZodTypeAny,\r\n rules: FieldValidationRules\r\n): z.ZodTypeAny {\r\n return applyCustomValidate(schema, rules);\r\n}\r\n\r\n/**\r\n * Hook to manage field validations\r\n */\r\nexport function useFieldValidationRegistry() {\r\n const fieldsRef = useRef<Map<string, FieldRegistration>>(new Map());\r\n\r\n const registerFieldValidation = useCallback((field: FieldRegistration) => {\r\n fieldsRef.current.set(field.name, field);\r\n }, []);\r\n\r\n const unregisterFieldValidation = useCallback((name: string) => {\r\n fieldsRef.current.delete(name);\r\n }, []);\r\n\r\n const getValidationSchema = useCallback(() => {\r\n const shape: Record<string, z.ZodTypeAny> = {};\r\n \r\n fieldsRef.current.forEach((field) => {\r\n shape[field.name] = buildZodSchemaFromRules(field.type, field.rules);\r\n });\r\n\r\n return z.object(shape);\r\n }, []);\r\n\r\n return {\r\n registerFieldValidation,\r\n unregisterFieldValidation,\r\n getValidationSchema,\r\n fieldsRef,\r\n };\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"context.cjs","names":[],"sources":["../../../../src/components/Form/context.ts"],"sourcesContent":["'use client';\r\n\r\nimport { createContext, useCallback, useRef } from \"react\";\r\nimport type { UseFormReturn, FieldValues } from \"react-hook-form\";\r\nimport { z } from \"zod\";\r\n\r\n/**\r\n * Validation rule types that can be applied to form fields\r\n */\r\nexport interface FieldValidationRules {\r\n /** Field is required */\r\n required?: boolean | string;\r\n /** Minimum length for strings */\r\n minLength?: number | { value: number; message: string };\r\n /** Maximum length for strings */\r\n maxLength?: number | { value: number; message: string };\r\n /** Minimum value for numbers */\r\n min?: number | { value: number; message: string };\r\n /** Maximum value for numbers */\r\n max?: number | { value: number; message: string };\r\n /** Regex pattern for validation */\r\n pattern?: RegExp | { value: RegExp; message: string };\r\n /** Email validation */\r\n email?: boolean | string;\r\n /** URL validation */\r\n url?: boolean | string;\r\n /** Custom validation function */\r\n validate?: (value: unknown) => boolean | string | Promise<boolean | string>;\r\n}\r\n\r\n/**\r\n * Form configuration options\r\n */\r\nexport interface FormConfig {\r\n /** Show validation errors inline */\r\n showInlineErrors?: boolean;\r\n /** Validate on blur */\r\n validateOnBlur?: boolean;\r\n /** Validate on change */\r\n validateOnChange?: boolean;\r\n /** Size of form controls */\r\n size?: \"sm\" | \"md\" | \"lg\";\r\n /** Layout direction */\r\n layout?: \"horizontal\" | \"vertical\" | \"inline\";\r\n /** Label width for horizontal layout */\r\n labelWidth?: string | number;\r\n /** Whether form is disabled */\r\n disabled?: boolean;\r\n /** Colon after label */\r\n colon?: boolean;\r\n}\r\n\r\n/**\r\n * Field registration info\r\n */\r\nexport interface FieldRegistration {\r\n name: string;\r\n type: \"string\" | \"number\" | \"boolean\" | \"date\" | \"datetime\" | \"array\";\r\n rules: FieldValidationRules;\r\n}\r\n\r\n/**\r\n * Form context value\r\n */\r\nexport interface FormContextValue<TFieldValues extends FieldValues = FieldValues>\r\n extends FormConfig {\r\n form: UseFormReturn<TFieldValues>;\r\n /** Register a field's validation rules */\r\n registerFieldValidation: (field: FieldRegistration) => void;\r\n /** Unregister a field's validation rules */\r\n unregisterFieldValidation: (name: string) => void;\r\n /** Get current validation schema */\r\n getValidationSchema: () => z.ZodObject<Record<string, z.ZodTypeAny>>;\r\n /** Trigger validation for a specific field */\r\n triggerValidation: (name: string) => Promise<boolean>;\r\n}\r\n\r\n/**\r\n * Default form configuration\r\n */\r\nexport const defaultFormConfig: FormConfig = {\r\n showInlineErrors: true,\r\n validateOnBlur: true,\r\n validateOnChange: false,\r\n size: \"md\",\r\n layout: \"vertical\",\r\n disabled: false,\r\n colon: true,\r\n};\r\n\r\n/**\r\n * Form context for sharing form state and configuration\r\n */\r\nexport const FormConfigContext = createContext<FormContextValue | null>(null);\r\n\r\n/**\r\n * Build a Zod schema from validation rules\r\n */\r\nexport function buildZodSchemaFromRules(\r\n type: FieldRegistration[\"type\"],\r\n rules: FieldValidationRules\r\n): z.ZodTypeAny {\r\n // Helper to extract value and message\r\n const getValueAndMessage = <T>(\r\n rule: T | { value: T; message: string } | undefined,\r\n defaultMessage: string\r\n ): { value: T; message: string } | null => {\r\n if (rule === undefined) return null;\r\n if (typeof rule === \"object\" && rule !== null && \"value\" in rule) {\r\n return rule as { value: T; message: string };\r\n }\r\n return { value: rule as T, message: defaultMessage };\r\n };\r\n\r\n // Build string schema\r\n if (type === \"string\") {\r\n let schema = z.string();\r\n\r\n const minLengthRule = getValueAndMessage(\r\n rules.minLength,\r\n `Minimum ${typeof rules.minLength === \"number\" ? rules.minLength : (rules.minLength as { value: number })?.value} characters required`\r\n );\r\n if (minLengthRule) {\r\n schema = schema.min(minLengthRule.value as number, minLengthRule.message);\r\n }\r\n\r\n const maxLengthRule = getValueAndMessage(\r\n rules.maxLength,\r\n `Maximum ${typeof rules.maxLength === \"number\" ? rules.maxLength : (rules.maxLength as { value: number })?.value} characters allowed`\r\n );\r\n if (maxLengthRule) {\r\n schema = schema.max(maxLengthRule.value as number, maxLengthRule.message);\r\n }\r\n\r\n if (rules.pattern !== undefined) {\r\n const patternRule = rules.pattern instanceof RegExp\r\n ? { value: rules.pattern, message: \"Invalid format\" }\r\n : rules.pattern;\r\n schema = schema.regex(patternRule.value, patternRule.message);\r\n }\r\n\r\n if (rules.email) {\r\n const message = typeof rules.email === \"string\" ? rules.email : \"Invalid email address\";\r\n schema = schema.email(message);\r\n }\r\n\r\n if (rules.url) {\r\n const message = typeof rules.url === \"string\" ? rules.url : \"Invalid URL\";\r\n schema = schema.url(message);\r\n }\r\n\r\n // Handle required - for strings, require non-empty\r\n if (rules.required) {\r\n const message = typeof rules.required === \"string\" ? rules.required : \"This field is required\";\r\n return finalizeSchema(\r\n z.preprocess(\r\n (value) => (value === undefined || value === null ? \"\" : value),\r\n schema.min(1, message)\r\n ),\r\n rules\r\n );\r\n }\r\n\r\n return finalizeSchema(schema.optional(), rules);\r\n }\r\n\r\n // Build number schema\r\n if (type === \"number\") {\r\n let schema = z.coerce.number();\r\n\r\n const minRule = getValueAndMessage(\r\n rules.min,\r\n `Minimum value is ${typeof rules.min === \"number\" ? rules.min : (rules.min as { value: number })?.value}`\r\n );\r\n if (minRule) {\r\n schema = schema.min(minRule.value as number, minRule.message);\r\n }\r\n\r\n const maxRule = getValueAndMessage(\r\n rules.max,\r\n `Maximum value is ${typeof rules.max === \"number\" ? rules.max : (rules.max as { value: number })?.value}`\r\n );\r\n if (maxRule) {\r\n schema = schema.max(maxRule.value as number, maxRule.message);\r\n }\r\n\r\n if (!rules.required) {\r\n return finalizeSchema(schema.optional(), rules);\r\n }\r\n return finalizeSchema(schema, rules);\r\n }\r\n\r\n // Build boolean schema\r\n if (type === \"boolean\") {\r\n const schema = z.boolean();\r\n if (rules.required) {\r\n return finalizeSchema(\r\n schema.refine((val) => val === true, {\r\n message: typeof rules.required === \"string\" ? rules.required : \"This field is required\",\r\n }),\r\n rules\r\n );\r\n }\r\n return finalizeSchema(schema.optional(), rules);\r\n }\r\n\r\n // Build date / datetime schema\r\n if (type === \"date\" || type === \"datetime\") {\r\n const schema = z.coerce.date();\r\n if (!rules.required) {\r\n return finalizeSchema(schema.optional(), rules);\r\n }\r\n return finalizeSchema(schema, rules);\r\n }\r\n\r\n // Build array schema\r\n if (type === \"array\") {\r\n let schema = z.array(z.unknown());\r\n if (rules.required) {\r\n const message = typeof rules.required === \"string\" ? rules.required : \"This field is required\";\r\n schema = schema.min(1, message);\r\n }\r\n return finalizeSchema(schema, rules);\r\n }\r\n\r\n // Default fallback\r\n return finalizeSchema(z.unknown(), rules);\r\n}\r\n\r\nfunction applyCustomValidate(\r\n schema: z.ZodTypeAny,\r\n rules: FieldValidationRules\r\n): z.ZodTypeAny {\r\n if (!rules.validate) {\r\n return schema;\r\n }\r\n\r\n const validateFn = rules.validate;\r\n\r\n return schema.superRefine(async (value, ctx) => {\r\n const result = await validateFn(value);\r\n\r\n if (result === true) {\r\n return;\r\n }\r\n\r\n ctx.addIssue({\r\n code: z.ZodIssueCode.custom,\r\n message: typeof result === \"string\" ? result : \"Invalid value\",\r\n });\r\n });\r\n}\r\n\r\nfunction finalizeSchema(\r\n schema: z.ZodTypeAny,\r\n rules: FieldValidationRules\r\n): z.ZodTypeAny {\r\n return applyCustomValidate(schema, rules);\r\n}\r\n\r\n/**\r\n * Hook to manage field validations\r\n */\r\nexport function useFieldValidationRegistry() {\r\n const fieldsRef = useRef<Map<string, FieldRegistration>>(new Map());\r\n\r\n const registerFieldValidation = useCallback((field: FieldRegistration) => {\r\n fieldsRef.current.set(field.name, field);\r\n }, []);\r\n\r\n const unregisterFieldValidation = useCallback((name: string) => {\r\n fieldsRef.current.delete(name);\r\n }, []);\r\n\r\n const getValidationSchema = useCallback(() => {\r\n const shape: Record<string, z.ZodTypeAny> = {};\r\n \r\n fieldsRef.current.forEach((field) => {\r\n shape[field.name] = buildZodSchemaFromRules(field.type, field.rules);\r\n });\r\n\r\n return z.object(shape);\r\n }, []);\r\n\r\n return {\r\n registerFieldValidation,\r\n unregisterFieldValidation,\r\n getValidationSchema,\r\n fieldsRef,\r\n };\r\n}\r\n"],"mappings":"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"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const require_context = require("./context.cjs");
4
4
  const require_Form = require("./Form.cjs");
5
5
  const require_FieldLayout = require("./FieldLayout.cjs");
6
+ const require_PasswordRevealToggle = require("./PasswordRevealToggle.cjs");
6
7
  const require_TextBox = require("./TextBox.cjs");
7
8
  const require_TextArea = require("./TextArea.cjs");
8
9
  const require_Select = require("./Select.cjs");
@@ -10,6 +11,8 @@ const require_CountryPicker = require("./CountryPicker.cjs");
10
11
  const require_CountrySelect = require("./CountrySelect.cjs");
11
12
  const require_PhoneInput = require("./PhoneInput.cjs");
12
13
  const require_DatePicker = require("./DatePicker.cjs");
14
+ const require_TimePicker = require("./TimePicker.cjs");
15
+ const require_DateTimePicker = require("./DateTimePicker.cjs");
13
16
  const require_Combobox = require("./Combobox.cjs");
14
17
  const require_Checkbox = require("./Checkbox.cjs");
15
18
  const require_Radio = require("./Radio.cjs");
@@ -20,6 +23,7 @@ exports.Combobox = require_Combobox.Combobox;
20
23
  exports.CountryPicker = require_CountryPicker.CountryPicker;
21
24
  exports.CountrySelect = require_CountrySelect.CountrySelect;
22
25
  exports.DatePicker = require_DatePicker.DatePicker;
26
+ exports.DateTimePicker = require_DateTimePicker.DateTimePicker;
23
27
  exports.FieldLayout = require_FieldLayout.FieldLayout;
24
28
  exports.Form = require_Form.Form;
25
29
  exports.FormCheckbox = require_Checkbox.Checkbox;
@@ -27,15 +31,18 @@ exports.FormCombobox = require_Combobox.Combobox;
27
31
  exports.FormConfigContext = require_context.FormConfigContext;
28
32
  exports.FormCountrySelect = require_CountrySelect.CountrySelect;
29
33
  exports.FormDatePicker = require_DatePicker.DatePicker;
34
+ exports.FormDateTimePicker = require_DateTimePicker.DateTimePicker;
30
35
  exports.FormPhoneInput = require_PhoneInput.PhoneInput;
31
36
  exports.FormSelect = require_Select.Select;
32
37
  exports.FormSwitch = require_FormSwitch.FormSwitch;
38
+ exports.PasswordRevealToggle = require_PasswordRevealToggle.PasswordRevealToggle;
33
39
  exports.PhoneInput = require_PhoneInput.PhoneInput;
34
40
  exports.RadioGroup = require_Radio.RadioGroup;
35
41
  exports.RadioItem = require_Radio.RadioItem;
36
42
  exports.Select = require_Select.Select;
37
43
  exports.TextArea = require_TextArea.TextArea;
38
44
  exports.TextBox = require_TextBox.TextBox;
45
+ exports.TimePicker = require_TimePicker.TimePicker;
39
46
  exports.buildZodSchemaFromRules = require_context.buildZodSchemaFromRules;
40
47
  exports.defaultFormConfig = require_context.defaultFormConfig;
41
48
  exports.useFieldError = require_hooks.useFieldError;
@@ -1,12 +1,40 @@
1
1
  "use client";
2
+ "use client";
3
+ const require_cn = require("../../utils/cn.cjs");
4
+ const require_PasswordRevealToggle = require("../Form/PasswordRevealToggle.cjs");
2
5
  const require_textbox = require("../../primitives/textbox.cjs");
3
6
  let react = require("react");
4
7
  let react_jsx_runtime = require("react/jsx-runtime");
5
8
  //#region src/components/Input/Input.tsx
6
- var Input = (0, react.forwardRef)((props, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_textbox.TextBoxPrimitive, {
7
- ref,
8
- ...props
9
- }));
9
+ var Input = (0, react.forwardRef)(({ type, className, passwordToggle, disabled, ...props }, ref) => {
10
+ const [passwordVisible, setPasswordVisible] = (0, react.useState)(false);
11
+ const showPasswordToggle = type === "password" && passwordToggle !== false;
12
+ const resolvedType = showPasswordToggle && passwordVisible ? "text" : type;
13
+ if (!showPasswordToggle) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_textbox.TextBoxPrimitive, {
14
+ ref,
15
+ type,
16
+ className,
17
+ disabled,
18
+ ...props
19
+ });
20
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
21
+ className: "relative w-full",
22
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_textbox.TextBoxPrimitive, {
23
+ ref,
24
+ type: resolvedType,
25
+ className: require_cn.cn("pr-10", className),
26
+ disabled,
27
+ ...props
28
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
29
+ className: "absolute right-3 top-1/2 -translate-y-1/2",
30
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_PasswordRevealToggle.PasswordRevealToggle, {
31
+ visible: passwordVisible,
32
+ onToggle: () => setPasswordVisible((visible) => !visible),
33
+ disabled
34
+ })
35
+ })]
36
+ });
37
+ });
10
38
  Input.displayName = "Input";
11
39
  //#endregion
12
40
  exports.Input = Input;
@@ -1 +1 @@
1
- {"version":3,"file":"Input.cjs","names":[],"sources":["../../../../src/components/Input/Input.tsx"],"sourcesContent":["import { forwardRef } from \"react\"\r\nimport type { ComponentPropsWithoutRef, ElementRef } from \"react\"\r\nimport { Input as InputPrimitive } from \"../../primitives/input\"\r\n\r\nexport type InputProps = ComponentPropsWithoutRef<typeof InputPrimitive>\r\n\r\nexport const Input = forwardRef<\r\n ElementRef<typeof InputPrimitive>,\r\n InputProps\r\n>((props, ref) => <InputPrimitive ref={ref} {...props} />)\r\nInput.displayName = \"Input\"\r\n"],"mappings":";;;;;AAMA,IAAa,SAAA,GAAQ,MAAA,WAAA,EAGlB,OAAO,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAA,kBAAD;CAAqB;CAAK,GAAI;AAAQ,CAAA,CAAC;AACzD,MAAM,cAAc"}
1
+ {"version":3,"file":"Input.cjs","names":[],"sources":["../../../../src/components/Input/Input.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { forwardRef, useState } from \"react\"\r\nimport type { ComponentPropsWithoutRef, ElementRef } from \"react\"\r\nimport { Input as InputPrimitive } from \"../../primitives/input\"\r\nimport { cn } from \"../../utils/cn\"\r\nimport { PasswordRevealToggle } from \"../Form/PasswordRevealToggle\"\r\n\r\nexport type InputProps = ComponentPropsWithoutRef<typeof InputPrimitive> & {\r\n /**\r\n * Show an eye toggle for password fields.\r\n * Defaults to true when `type=\"password\"`.\r\n */\r\n passwordToggle?: boolean\r\n}\r\n\r\nexport const Input = forwardRef<\r\n ElementRef<typeof InputPrimitive>,\r\n InputProps\r\n>(({ type, className, passwordToggle, disabled, ...props }, ref) => {\r\n const [passwordVisible, setPasswordVisible] = useState(false)\r\n const isPasswordType = type === \"password\"\r\n const showPasswordToggle = isPasswordType && passwordToggle !== false\r\n const resolvedType = showPasswordToggle && passwordVisible ? \"text\" : type\r\n\r\n if (!showPasswordToggle) {\r\n return (\r\n <InputPrimitive\r\n ref={ref}\r\n type={type}\r\n className={className}\r\n disabled={disabled}\r\n {...props}\r\n />\r\n )\r\n }\r\n\r\n return (\r\n <div className=\"relative w-full\">\r\n <InputPrimitive\r\n ref={ref}\r\n type={resolvedType}\r\n className={cn(\"pr-10\", className)}\r\n disabled={disabled}\r\n {...props}\r\n />\r\n <div className=\"absolute right-3 top-1/2 -translate-y-1/2\">\r\n <PasswordRevealToggle\r\n visible={passwordVisible}\r\n onToggle={() => setPasswordVisible((visible) => !visible)}\r\n disabled={disabled}\r\n />\r\n </div>\r\n </div>\r\n )\r\n})\r\nInput.displayName = \"Input\"\r\n"],"mappings":";;;;;;;;AAgBA,IAAa,SAAA,GAAQ,MAAA,WAAA,EAGlB,EAAE,MAAM,WAAW,gBAAgB,UAAU,GAAG,SAAS,QAAQ;CAClE,MAAM,CAAC,iBAAiB,uBAAA,GAAsB,MAAA,SAAA,CAAS,KAAK;CAE5D,MAAM,qBADiB,SAAS,cACa,mBAAmB;CAChE,MAAM,eAAe,sBAAsB,kBAAkB,SAAS;CAEtE,IAAI,CAAC,oBACH,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAA,kBAAD;EACO;EACC;EACK;EACD;EACV,GAAI;CACL,CAAA;CAIL,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAA,kBAAD;GACO;GACL,MAAM;GACN,WAAW,WAAA,GAAG,SAAS,SAAS;GACtB;GACV,GAAI;EACL,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;GAAK,WAAU;GACb,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,6BAAA,sBAAD;IACE,SAAS;IACT,gBAAgB,oBAAoB,YAAY,CAAC,OAAO;IAC9C;GACX,CAAA;EACE,CAAA,CACF;;AAET,CAAC;AACD,MAAM,cAAc"}
@@ -4,6 +4,7 @@ const require_cn = require("./utils/cn.cjs");
4
4
  const require_Button = require("./components/Button/Button.cjs");
5
5
  const require_context = require("./components/Form/context.cjs");
6
6
  const require_Form = require("./components/Form/Form.cjs");
7
+ const require_PasswordRevealToggle = require("./components/Form/PasswordRevealToggle.cjs");
7
8
  const require_TextBox = require("./components/Form/TextBox.cjs");
8
9
  const require_TextArea = require("./components/Form/TextArea.cjs");
9
10
  const require_select = require("./primitives/select.cjs");
@@ -16,6 +17,8 @@ const require_CountrySelect = require("./components/Form/CountrySelect.cjs");
16
17
  const require_PhoneInput = require("./components/Form/PhoneInput.cjs");
17
18
  const require_calendar = require("./primitives/calendar.cjs");
18
19
  const require_DatePicker = require("./components/Form/DatePicker.cjs");
20
+ const require_TimePicker = require("./components/Form/TimePicker.cjs");
21
+ const require_DateTimePicker = require("./components/Form/DateTimePicker.cjs");
19
22
  const require_Combobox = require("./components/Form/Combobox.cjs");
20
23
  const require_Checkbox = require("./components/Form/Checkbox.cjs");
21
24
  const require_Radio = require("./components/Form/Radio.cjs");
@@ -102,6 +105,7 @@ exports.CommandSeparator = require_command.CommandSeparator;
102
105
  exports.CommandShortcut = require_command.CommandShortcut;
103
106
  exports.CountrySelect = require_CountrySelect.CountrySelect;
104
107
  exports.DatePicker = require_DatePicker.DatePicker;
108
+ exports.DateTimePicker = require_DateTimePicker.DateTimePicker;
105
109
  exports.Dialog = require_dialog.Dialog;
106
110
  exports.DialogClose = require_dialog.DialogClose;
107
111
  exports.DialogContent = require_dialog.DialogContent;
@@ -133,6 +137,7 @@ exports.FormCombobox = require_Combobox.Combobox;
133
137
  exports.FormConfigContext = require_context.FormConfigContext;
134
138
  exports.FormCountrySelect = require_CountrySelect.CountrySelect;
135
139
  exports.FormDatePicker = require_DatePicker.DatePicker;
140
+ exports.FormDateTimePicker = require_DateTimePicker.DateTimePicker;
136
141
  exports.FormPhoneInput = require_PhoneInput.PhoneInput;
137
142
  exports.FormSelect = require_Select.Select;
138
143
  exports.FormSwitch = require_FormSwitch.FormSwitch;
@@ -149,6 +154,7 @@ exports.PaginationItem = require_Pagination.PaginationItem;
149
154
  exports.PaginationLink = require_Pagination.PaginationLink;
150
155
  exports.PaginationNext = require_Pagination.PaginationNext;
151
156
  exports.PaginationPrevious = require_Pagination.PaginationPrevious;
157
+ exports.PasswordRevealToggle = require_PasswordRevealToggle.PasswordRevealToggle;
152
158
  exports.PhoneInput = require_PhoneInput.PhoneInput;
153
159
  exports.Popover = require_popover.Popover;
154
160
  exports.PopoverAnchor = require_popover.PopoverAnchor;
@@ -198,6 +204,7 @@ exports.TabsTrigger = require_Tabs.TabsTrigger;
198
204
  exports.TextArea = require_TextArea.TextArea;
199
205
  exports.TextBox = require_TextBox.TextBox;
200
206
  exports.Textarea = require_Textarea.Textarea;
207
+ exports.TimePicker = require_TimePicker.TimePicker;
201
208
  exports.Toast = require_toast.Toast;
202
209
  exports.ToastAction = require_toast.ToastAction;
203
210
  exports.ToastClose = require_toast.ToastClose;
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../src/components/Form/DatePicker.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAsD,KAAK,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACrI,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAQlE,QAAA,MAAM,kBAAkB;;;8EAiBtB,CAAC;AAEH,MAAM,WAAW,eAAe,CAC9B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,CAC/D,SAAQ,YAAY,CAAC,OAAO,kBAAkB,CAAC;IAC/C,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;CAC7E;AAED,wBAAgB,UAAU,CACxB,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,EAC/D,EACA,IAAI,EACJ,KAAK,EACL,UAAU,EACV,SAAgB,EAChB,KAAK,EAAE,WAAW,EAClB,IAAI,EACJ,OAAO,EACP,SAAgB,EAChB,WAA2B,EAC3B,QAAQ,EACR,SAAS,EACT,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,eAAe,EACxB,QAAQ,EACR,QAAQ,GACT,EAAE,eAAe,CAAC,YAAY,EAAE,KAAK,CAAC,+BAkGtC;yBArHe,UAAU"}
1
+ {"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../src/components/Form/DatePicker.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAsD,KAAK,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACrI,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAqBlE,QAAA,MAAM,kBAAkB;;;8EAiBtB,CAAC;AAEH,MAAM,WAAW,eAAe,CAC9B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,CAC/D,SAAQ,YAAY,CAAC,OAAO,kBAAkB,CAAC;IAC/C,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;CAC7E;AAED,wBAAgB,UAAU,CACxB,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,EAC/D,EACA,IAAI,EACJ,KAAK,EACL,UAAU,EACV,SAAgB,EAChB,KAAK,EAAE,WAAW,EAClB,IAAI,EACJ,OAAO,EACP,SAAgB,EAChB,WAA2B,EAC3B,QAAQ,EACR,SAAS,EACT,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,eAAe,EACxB,QAAQ,EACR,QAAQ,GACT,EAAE,eAAe,CAAC,YAAY,EAAE,KAAK,CAAC,+BAkGtC;yBArHe,UAAU"}
@@ -11,8 +11,14 @@ import { cva } from "class-variance-authority";
11
11
  import { jsx, jsxs } from "react/jsx-runtime";
12
12
  import { useController, useFormContext } from "react-hook-form";
13
13
  import { CalendarIcon } from "lucide-react";
14
- import { format } from "date-fns";
14
+ import { format, startOfDay } from "date-fns";
15
15
  //#region src/components/Form/DatePicker.tsx
16
+ function toStartOfDay(value) {
17
+ if (!value || value === "") return;
18
+ const date = value instanceof Date ? value : new Date(value);
19
+ if (Number.isNaN(date.getTime())) return;
20
+ return startOfDay(date);
21
+ }
16
22
  var datePickerVariants = cva("w-full justify-start text-left font-normal", {
17
23
  variants: {
18
24
  size: {
@@ -66,7 +72,7 @@ function DatePicker({ name, label, helperText, showError = true, error: customEr
66
72
  name,
67
73
  control
68
74
  });
69
- const selectedDate = field.value ? new Date(field.value) : void 0;
75
+ const selectedDate = toStartOfDay(field.value);
70
76
  const fieldError = fieldState.error?.message;
71
77
  const errorMessage = customError ?? fieldError;
72
78
  const hasError = !!errorMessage;
@@ -107,7 +113,7 @@ function DatePicker({ name, label, helperText, showError = true, error: customEr
107
113
  mode: "single",
108
114
  selected: selectedDate,
109
115
  onSelect: (date) => {
110
- field.onChange(date ?? "");
116
+ field.onChange(date ? startOfDay(date) : "");
111
117
  setOpen(false);
112
118
  }
113
119
  })
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.js","names":[],"sources":["../../../src/components/Form/DatePicker.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useContext, useEffect, useId, useState } from \"react\";\r\nimport { format } from \"date-fns\";\r\nimport { CalendarIcon } from \"lucide-react\";\r\nimport { useController, useFormContext as useRHFFormContext, type Control, type FieldPath, type FieldValues } from \"react-hook-form\";\r\nimport { cva, type VariantProps } from \"class-variance-authority\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport { Calendar } from \"../../primitives/calendar\";\r\nimport { Popover, PopoverContent, PopoverTrigger } from \"../../primitives/popover\";\r\nimport { FormConfigContext, type FieldValidationRules, type FormConfig } from \"./context\";\r\nimport { FieldLayout } from \"./FieldLayout\";\r\n\r\nconst datePickerVariants = cva(\"w-full justify-start text-left font-normal\", {\r\n variants: {\r\n size: {\r\n sm: \"h-8 text-xs\",\r\n md: \"h-10 text-sm\",\r\n lg: \"h-12 text-base\",\r\n },\r\n variant: {\r\n default: \"border-input\",\r\n error: \"border-destructive\",\r\n success: \"border-green-500\",\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n variant: \"default\",\r\n },\r\n});\r\n\r\nexport interface DatePickerProps<\r\n TFieldValues extends FieldValues = FieldValues,\r\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\r\n> extends VariantProps<typeof datePickerVariants> {\r\n name: TName;\r\n label?: string;\r\n helperText?: string;\r\n showError?: boolean;\r\n error?: string;\r\n fullWidth?: boolean;\r\n placeholder?: string;\r\n disabled?: boolean;\r\n className?: string;\r\n id?: string;\r\n control?: Control<TFieldValues>;\r\n required?: boolean | string;\r\n validate?: (value: unknown) => boolean | string | Promise<boolean | string>;\r\n}\r\n\r\nexport function DatePicker<\r\n TFieldValues extends FieldValues = FieldValues,\r\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\r\n>({\r\n name,\r\n label,\r\n helperText,\r\n showError = true,\r\n error: customError,\r\n size,\r\n variant,\r\n fullWidth = true,\r\n placeholder = \"Pick a date\",\r\n disabled,\r\n className,\r\n id: providedId,\r\n control: externalControl,\r\n required,\r\n validate,\r\n}: DatePickerProps<TFieldValues, TName>) {\r\n const generatedId = useId();\r\n const inputId = providedId ?? generatedId;\r\n const [open, setOpen] = useState(false);\r\n const formConfigContext = useContext(FormConfigContext);\r\n const formConfig: FormConfig = formConfigContext ?? {};\r\n const rhfContext = useRHFFormContext<TFieldValues>();\r\n const control = externalControl ?? rhfContext?.control;\r\n\r\n const registerFieldValidation = formConfigContext?.registerFieldValidation;\r\n const unregisterFieldValidation = formConfigContext?.unregisterFieldValidation;\r\n\r\n useEffect(() => {\r\n if (registerFieldValidation) {\r\n const rules: FieldValidationRules = {};\r\n if (required !== undefined) rules.required = required;\r\n if (validate !== undefined) rules.validate = validate;\r\n\r\n registerFieldValidation({\r\n name: name as string,\r\n type: \"date\",\r\n rules,\r\n });\r\n\r\n return () => {\r\n unregisterFieldValidation?.(name as string);\r\n };\r\n }\r\n }, [\r\n registerFieldValidation,\r\n unregisterFieldValidation,\r\n name,\r\n required,\r\n validate,\r\n ]);\r\n\r\n const { field, fieldState } = useController<TFieldValues, TName>({\r\n name,\r\n control,\r\n });\r\n\r\n const selectedDate = field.value ? new Date(field.value) : undefined;\r\n const fieldError = fieldState.error?.message;\r\n const errorMessage = customError ?? fieldError;\r\n const hasError = !!errorMessage;\r\n const effectiveSize = size ?? formConfig.size ?? \"md\";\r\n const effectiveDisabled = disabled ?? formConfig.disabled;\r\n const effectiveVariant = hasError ? \"error\" : variant;\r\n\r\n return (\r\n <FieldLayout\r\n inputId={inputId}\r\n label={label}\r\n required={!!required}\r\n helperText={helperText}\r\n errorMessage={showError ? errorMessage : undefined}\r\n showError={showError}\r\n fullWidth={fullWidth}\r\n formConfig={formConfig}\r\n >\r\n <Popover open={open} onOpenChange={setOpen}>\r\n <PopoverTrigger asChild>\r\n <Button\r\n id={inputId}\r\n type=\"button\"\r\n variant=\"outline\"\r\n disabled={effectiveDisabled}\r\n aria-invalid={hasError}\r\n aria-describedby={\r\n hasError\r\n ? `${inputId}-error`\r\n : helperText\r\n ? `${inputId}-helper`\r\n : undefined\r\n }\r\n className={cn(\r\n datePickerVariants({ size: effectiveSize, variant: effectiveVariant }),\r\n !selectedDate && \"text-muted-foreground\",\r\n className\r\n )}\r\n >\r\n <CalendarIcon className=\"mr-2 h-4 w-4\" />\r\n {selectedDate ? format(selectedDate, \"PPP\") : placeholder}\r\n </Button>\r\n </PopoverTrigger>\r\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\r\n <Calendar\r\n mode=\"single\"\r\n selected={selectedDate}\r\n onSelect={(date) => {\r\n field.onChange(date ?? \"\");\r\n setOpen(false);\r\n }}\r\n />\r\n </PopoverContent>\r\n </Popover>\r\n </FieldLayout>\r\n );\r\n}\r\n\r\nDatePicker.displayName = \"DatePicker\";\r\n"],"mappings":";;;;;;;;;;;;;;;AAcA,IAAM,qBAAqB,IAAI,8CAA8C;CAC3E,UAAU;EACR,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,SAAS;GACP,SAAS;GACT,OAAO;GACP,SAAS;EACX;CACF;CACA,iBAAiB;EACf,MAAM;EACN,SAAS;CACX;AACF,CAAC;AAqBD,SAAgB,WAGd,EACA,MACA,OACA,YACA,YAAY,MACZ,OAAO,aACP,MACA,SACA,YAAY,MACZ,cAAc,eACd,UACA,WACA,IAAI,YACJ,SAAS,iBACT,UACA,YACuC;CACvC,MAAM,cAAc,MAAM;CAC1B,MAAM,UAAU,cAAc;CAC9B,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,oBAAoB,WAAW,iBAAiB;CACtD,MAAM,aAAyB,qBAAqB,CAAC;CACrD,MAAM,aAAa,eAAgC;CACnD,MAAM,UAAU,mBAAmB,YAAY;CAE/C,MAAM,0BAA0B,mBAAmB;CACnD,MAAM,4BAA4B,mBAAmB;CAErD,gBAAgB;EACd,IAAI,yBAAyB;GAC3B,MAAM,QAA8B,CAAC;GACrC,IAAI,aAAa,KAAA,GAAW,MAAM,WAAW;GAC7C,IAAI,aAAa,KAAA,GAAW,MAAM,WAAW;GAE7C,wBAAwB;IAChB;IACN,MAAM;IACN;GACF,CAAC;GAED,aAAa;IACX,4BAA4B,IAAc;GAC5C;EACF;CACF,GAAG;EACD;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,EAAE,OAAO,eAAe,cAAmC;EAC/D;EACA;CACF,CAAC;CAED,MAAM,eAAe,MAAM,QAAQ,IAAI,KAAK,MAAM,KAAK,IAAI,KAAA;CAC3D,MAAM,aAAa,WAAW,OAAO;CACrC,MAAM,eAAe,eAAe;CACpC,MAAM,WAAW,CAAC,CAAC;CACnB,MAAM,gBAAgB,QAAQ,WAAW,QAAQ;CACjD,MAAM,oBAAoB,YAAY,WAAW;CACjD,MAAM,mBAAmB,WAAW,UAAU;CAE9C,OACE,oBAAC,aAAD;EACW;EACF;EACP,UAAU,CAAC,CAAC;EACA;EACZ,cAAc,YAAY,eAAe,KAAA;EAC9B;EACA;EACC;EAEZ,UAAA,qBAAC,SAAD;GAAe;GAAM,cAAc;GAAnC,UAAA,CACE,oBAAC,gBAAD;IAAgB,SAAA;IACd,UAAA,qBAAC,QAAD;KACE,IAAI;KACJ,MAAK;KACL,SAAQ;KACR,UAAU;KACV,gBAAc;KACd,oBACE,WACI,GAAG,QAAQ,UACX,aACE,GAAG,QAAQ,WACX,KAAA;KAER,WAAW,GACT,mBAAmB;MAAE,MAAM;MAAe,SAAS;KAAiB,CAAC,GACrE,CAAC,gBAAgB,yBACjB,SACF;KAjBF,UAAA,CAmBE,oBAAC,cAAD,EAAc,WAAU,eAAgB,CAAA,GACvC,eAAe,OAAO,cAAc,KAAK,IAAI,WACxC;;GACM,CAAA,GAChB,oBAAC,gBAAD;IAAgB,WAAU;IAAa,OAAM;IAC3C,UAAA,oBAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,WAAW,SAAS;MAClB,MAAM,SAAS,QAAQ,EAAE;MACzB,QAAQ,KAAK;KACf;IACD,CAAA;GACa,CAAA,CACT;;CACE,CAAA;AAEjB;AAEA,WAAW,cAAc"}
1
+ {"version":3,"file":"DatePicker.js","names":[],"sources":["../../../src/components/Form/DatePicker.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useContext, useEffect, useId, useState } from \"react\";\r\nimport { format, startOfDay } from \"date-fns\";\r\nimport { CalendarIcon } from \"lucide-react\";\r\nimport { useController, useFormContext as useRHFFormContext, type Control, type FieldPath, type FieldValues } from \"react-hook-form\";\r\nimport { cva, type VariantProps } from \"class-variance-authority\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport { Calendar } from \"../../primitives/calendar\";\r\nimport { Popover, PopoverContent, PopoverTrigger } from \"../../primitives/popover\";\r\nimport { FormConfigContext, type FieldValidationRules, type FormConfig } from \"./context\";\r\nimport { FieldLayout } from \"./FieldLayout\";\r\n\r\nfunction toStartOfDay(value: unknown): Date | undefined {\r\n if (!value || value === \"\") {\r\n return undefined;\r\n }\r\n\r\n const date = value instanceof Date ? value : new Date(value as string | number);\r\n if (Number.isNaN(date.getTime())) {\r\n return undefined;\r\n }\r\n\r\n return startOfDay(date);\r\n}\r\n\r\nconst datePickerVariants = cva(\"w-full justify-start text-left font-normal\", {\r\n variants: {\r\n size: {\r\n sm: \"h-8 text-xs\",\r\n md: \"h-10 text-sm\",\r\n lg: \"h-12 text-base\",\r\n },\r\n variant: {\r\n default: \"border-input\",\r\n error: \"border-destructive\",\r\n success: \"border-green-500\",\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n variant: \"default\",\r\n },\r\n});\r\n\r\nexport interface DatePickerProps<\r\n TFieldValues extends FieldValues = FieldValues,\r\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\r\n> extends VariantProps<typeof datePickerVariants> {\r\n name: TName;\r\n label?: string;\r\n helperText?: string;\r\n showError?: boolean;\r\n error?: string;\r\n fullWidth?: boolean;\r\n placeholder?: string;\r\n disabled?: boolean;\r\n className?: string;\r\n id?: string;\r\n control?: Control<TFieldValues>;\r\n required?: boolean | string;\r\n validate?: (value: unknown) => boolean | string | Promise<boolean | string>;\r\n}\r\n\r\nexport function DatePicker<\r\n TFieldValues extends FieldValues = FieldValues,\r\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\r\n>({\r\n name,\r\n label,\r\n helperText,\r\n showError = true,\r\n error: customError,\r\n size,\r\n variant,\r\n fullWidth = true,\r\n placeholder = \"Pick a date\",\r\n disabled,\r\n className,\r\n id: providedId,\r\n control: externalControl,\r\n required,\r\n validate,\r\n}: DatePickerProps<TFieldValues, TName>) {\r\n const generatedId = useId();\r\n const inputId = providedId ?? generatedId;\r\n const [open, setOpen] = useState(false);\r\n const formConfigContext = useContext(FormConfigContext);\r\n const formConfig: FormConfig = formConfigContext ?? {};\r\n const rhfContext = useRHFFormContext<TFieldValues>();\r\n const control = externalControl ?? rhfContext?.control;\r\n\r\n const registerFieldValidation = formConfigContext?.registerFieldValidation;\r\n const unregisterFieldValidation = formConfigContext?.unregisterFieldValidation;\r\n\r\n useEffect(() => {\r\n if (registerFieldValidation) {\r\n const rules: FieldValidationRules = {};\r\n if (required !== undefined) rules.required = required;\r\n if (validate !== undefined) rules.validate = validate;\r\n\r\n registerFieldValidation({\r\n name: name as string,\r\n type: \"date\",\r\n rules,\r\n });\r\n\r\n return () => {\r\n unregisterFieldValidation?.(name as string);\r\n };\r\n }\r\n }, [\r\n registerFieldValidation,\r\n unregisterFieldValidation,\r\n name,\r\n required,\r\n validate,\r\n ]);\r\n\r\n const { field, fieldState } = useController<TFieldValues, TName>({\r\n name,\r\n control,\r\n });\r\n\r\n const selectedDate = toStartOfDay(field.value);\r\n const fieldError = fieldState.error?.message;\r\n const errorMessage = customError ?? fieldError;\r\n const hasError = !!errorMessage;\r\n const effectiveSize = size ?? formConfig.size ?? \"md\";\r\n const effectiveDisabled = disabled ?? formConfig.disabled;\r\n const effectiveVariant = hasError ? \"error\" : variant;\r\n\r\n return (\r\n <FieldLayout\r\n inputId={inputId}\r\n label={label}\r\n required={!!required}\r\n helperText={helperText}\r\n errorMessage={showError ? errorMessage : undefined}\r\n showError={showError}\r\n fullWidth={fullWidth}\r\n formConfig={formConfig}\r\n >\r\n <Popover open={open} onOpenChange={setOpen}>\r\n <PopoverTrigger asChild>\r\n <Button\r\n id={inputId}\r\n type=\"button\"\r\n variant=\"outline\"\r\n disabled={effectiveDisabled}\r\n aria-invalid={hasError}\r\n aria-describedby={\r\n hasError\r\n ? `${inputId}-error`\r\n : helperText\r\n ? `${inputId}-helper`\r\n : undefined\r\n }\r\n className={cn(\r\n datePickerVariants({ size: effectiveSize, variant: effectiveVariant }),\r\n !selectedDate && \"text-muted-foreground\",\r\n className\r\n )}\r\n >\r\n <CalendarIcon className=\"mr-2 h-4 w-4\" />\r\n {selectedDate ? format(selectedDate, \"PPP\") : placeholder}\r\n </Button>\r\n </PopoverTrigger>\r\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\r\n <Calendar\r\n mode=\"single\"\r\n selected={selectedDate}\r\n onSelect={(date) => {\r\n field.onChange(date ? startOfDay(date) : \"\");\r\n setOpen(false);\r\n }}\r\n />\r\n </PopoverContent>\r\n </Popover>\r\n </FieldLayout>\r\n );\r\n}\r\n\r\nDatePicker.displayName = \"DatePicker\";\r\n"],"mappings":";;;;;;;;;;;;;;;AAcA,SAAS,aAAa,OAAkC;CACtD,IAAI,CAAC,SAAS,UAAU,IACtB;CAGF,MAAM,OAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAwB;CAC9E,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAC7B;CAGF,OAAO,WAAW,IAAI;AACxB;AAEA,IAAM,qBAAqB,IAAI,8CAA8C;CAC3E,UAAU;EACR,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,SAAS;GACP,SAAS;GACT,OAAO;GACP,SAAS;EACX;CACF;CACA,iBAAiB;EACf,MAAM;EACN,SAAS;CACX;AACF,CAAC;AAqBD,SAAgB,WAGd,EACA,MACA,OACA,YACA,YAAY,MACZ,OAAO,aACP,MACA,SACA,YAAY,MACZ,cAAc,eACd,UACA,WACA,IAAI,YACJ,SAAS,iBACT,UACA,YACuC;CACvC,MAAM,cAAc,MAAM;CAC1B,MAAM,UAAU,cAAc;CAC9B,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,oBAAoB,WAAW,iBAAiB;CACtD,MAAM,aAAyB,qBAAqB,CAAC;CACrD,MAAM,aAAa,eAAgC;CACnD,MAAM,UAAU,mBAAmB,YAAY;CAE/C,MAAM,0BAA0B,mBAAmB;CACnD,MAAM,4BAA4B,mBAAmB;CAErD,gBAAgB;EACd,IAAI,yBAAyB;GAC3B,MAAM,QAA8B,CAAC;GACrC,IAAI,aAAa,KAAA,GAAW,MAAM,WAAW;GAC7C,IAAI,aAAa,KAAA,GAAW,MAAM,WAAW;GAE7C,wBAAwB;IAChB;IACN,MAAM;IACN;GACF,CAAC;GAED,aAAa;IACX,4BAA4B,IAAc;GAC5C;EACF;CACF,GAAG;EACD;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,EAAE,OAAO,eAAe,cAAmC;EAC/D;EACA;CACF,CAAC;CAED,MAAM,eAAe,aAAa,MAAM,KAAK;CAC7C,MAAM,aAAa,WAAW,OAAO;CACrC,MAAM,eAAe,eAAe;CACpC,MAAM,WAAW,CAAC,CAAC;CACnB,MAAM,gBAAgB,QAAQ,WAAW,QAAQ;CACjD,MAAM,oBAAoB,YAAY,WAAW;CACjD,MAAM,mBAAmB,WAAW,UAAU;CAE9C,OACE,oBAAC,aAAD;EACW;EACF;EACP,UAAU,CAAC,CAAC;EACA;EACZ,cAAc,YAAY,eAAe,KAAA;EAC9B;EACA;EACC;EAEZ,UAAA,qBAAC,SAAD;GAAe;GAAM,cAAc;GAAnC,UAAA,CACE,oBAAC,gBAAD;IAAgB,SAAA;IACd,UAAA,qBAAC,QAAD;KACE,IAAI;KACJ,MAAK;KACL,SAAQ;KACR,UAAU;KACV,gBAAc;KACd,oBACE,WACI,GAAG,QAAQ,UACX,aACE,GAAG,QAAQ,WACX,KAAA;KAER,WAAW,GACT,mBAAmB;MAAE,MAAM;MAAe,SAAS;KAAiB,CAAC,GACrE,CAAC,gBAAgB,yBACjB,SACF;KAjBF,UAAA,CAmBE,oBAAC,cAAD,EAAc,WAAU,eAAgB,CAAA,GACvC,eAAe,OAAO,cAAc,KAAK,IAAI,WACxC;;GACM,CAAA,GAChB,oBAAC,gBAAD;IAAgB,WAAU;IAAa,OAAM;IAC3C,UAAA,oBAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,WAAW,SAAS;MAClB,MAAM,SAAS,OAAO,WAAW,IAAI,IAAI,EAAE;MAC3C,QAAQ,KAAK;KACf;IACD,CAAA;GACa,CAAA,CACT;;CACE,CAAA;AAEjB;AAEA,WAAW,cAAc"}
@@ -0,0 +1,28 @@
1
+ import { Control, FieldPath, FieldValues } from 'react-hook-form';
2
+ import { VariantProps } from 'class-variance-authority';
3
+ declare const dateTimePickerVariants: (props?: ({
4
+ size?: "sm" | "lg" | "md" | null | undefined;
5
+ variant?: "default" | "error" | "success" | null | undefined;
6
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
7
+ export interface DateTimePickerProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> extends VariantProps<typeof dateTimePickerVariants> {
8
+ name: TName;
9
+ label?: string;
10
+ helperText?: string;
11
+ showError?: boolean;
12
+ error?: string;
13
+ fullWidth?: boolean;
14
+ placeholder?: string;
15
+ disabled?: boolean;
16
+ className?: string;
17
+ id?: string;
18
+ control?: Control<TFieldValues>;
19
+ required?: boolean | string;
20
+ validate?: (value: unknown) => boolean | string | Promise<boolean | string>;
21
+ minuteStep?: number;
22
+ }
23
+ export declare function DateTimePicker<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ name, label, helperText, showError, error: customError, size, variant, fullWidth, placeholder, disabled, className, id: providedId, control: externalControl, required, validate, minuteStep, }: DateTimePickerProps<TFieldValues, TName>): import("react").JSX.Element;
24
+ export declare namespace DateTimePicker {
25
+ var displayName: string;
26
+ }
27
+ export {};
28
+ //# sourceMappingURL=DateTimePicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateTimePicker.d.ts","sourceRoot":"","sources":["../../../src/components/Form/DateTimePicker.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAsD,KAAK,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACrI,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAUlE,QAAA,MAAM,sBAAsB;;;8EAiB1B,CAAC;AAEH,MAAM,WAAW,mBAAmB,CAClC,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,CAC/D,SAAQ,YAAY,CAAC,OAAO,sBAAsB,CAAC;IACnD,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAkCD,wBAAgB,cAAc,CAC5B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,EAC/D,EACA,IAAI,EACJ,KAAK,EACL,UAAU,EACV,SAAgB,EAChB,KAAK,EAAE,WAAW,EAClB,IAAI,EACJ,OAAO,EACP,SAAgB,EAChB,WAA2B,EAC3B,QAAQ,EACR,SAAS,EACT,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,eAAe,EACxB,QAAQ,EACR,QAAQ,EACR,UAAc,GACf,EAAE,mBAAmB,CAAC,YAAY,EAAE,KAAK,CAAC,+BAuL1C;yBA3Me,cAAc"}
@@ -0,0 +1,202 @@
1
+ "use client";
2
+ "use client";
3
+ import { cn } from "../../utils/cn.js";
4
+ import { Button } from "../../primitives/button.js";
5
+ import { FormConfigContext } from "./context.js";
6
+ import { FieldLayout } from "./FieldLayout.js";
7
+ import { Popover, PopoverContent, PopoverTrigger } from "../../primitives/popover.js";
8
+ import { Calendar } from "../../primitives/calendar.js";
9
+ import { Separator } from "../../primitives/separator.js";
10
+ import { TimePicker } from "./TimePicker.js";
11
+ import { useContext, useEffect, useId, useState } from "react";
12
+ import { cva } from "class-variance-authority";
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
+ import { useController, useFormContext } from "react-hook-form";
15
+ import { CalendarIcon, Clock } from "lucide-react";
16
+ import { format, startOfDay } from "date-fns";
17
+ //#region src/components/Form/DateTimePicker.tsx
18
+ var dateTimePickerVariants = cva("w-full justify-start text-left font-normal", {
19
+ variants: {
20
+ size: {
21
+ sm: "h-8 text-xs",
22
+ md: "h-10 text-sm",
23
+ lg: "h-12 text-base"
24
+ },
25
+ variant: {
26
+ default: "border-input",
27
+ error: "border-destructive",
28
+ success: "border-green-500"
29
+ }
30
+ },
31
+ defaultVariants: {
32
+ size: "md",
33
+ variant: "default"
34
+ }
35
+ });
36
+ function toValidDate(value) {
37
+ if (!value || value === "") return;
38
+ const date = value instanceof Date ? value : new Date(value);
39
+ if (Number.isNaN(date.getTime())) return;
40
+ return date;
41
+ }
42
+ function hasTimePart(date) {
43
+ return date.getHours() !== 0 || date.getMinutes() !== 0 || date.getSeconds() !== 0 || date.getMilliseconds() !== 0;
44
+ }
45
+ function withPreservedTime(nextDay, previous) {
46
+ const next = new Date(nextDay);
47
+ next.setHours(previous.getHours(), previous.getMinutes(), previous.getSeconds(), previous.getMilliseconds());
48
+ return next;
49
+ }
50
+ function isSelectEventTarget(target) {
51
+ return target instanceof Element && Boolean(target.closest("[data-radix-select-content]"));
52
+ }
53
+ function DateTimePicker({ name, label, helperText, showError = true, error: customError, size, variant, fullWidth = true, placeholder = "Pick a date", disabled, className, id: providedId, control: externalControl, required, validate, minuteStep = 5 }) {
54
+ const generatedId = useId();
55
+ const inputId = providedId ?? generatedId;
56
+ const [open, setOpen] = useState(false);
57
+ const [timeOpen, setTimeOpen] = useState(false);
58
+ const [timeSet, setTimeSet] = useState(false);
59
+ const formConfigContext = useContext(FormConfigContext);
60
+ const formConfig = formConfigContext ?? {};
61
+ const rhfContext = useFormContext();
62
+ const control = externalControl ?? rhfContext?.control;
63
+ const registerFieldValidation = formConfigContext?.registerFieldValidation;
64
+ const unregisterFieldValidation = formConfigContext?.unregisterFieldValidation;
65
+ useEffect(() => {
66
+ if (registerFieldValidation) {
67
+ const rules = {};
68
+ if (required !== void 0) rules.required = required;
69
+ if (validate !== void 0) rules.validate = validate;
70
+ registerFieldValidation({
71
+ name,
72
+ type: "datetime",
73
+ rules
74
+ });
75
+ return () => {
76
+ unregisterFieldValidation?.(name);
77
+ };
78
+ }
79
+ }, [
80
+ registerFieldValidation,
81
+ unregisterFieldValidation,
82
+ name,
83
+ required,
84
+ validate
85
+ ]);
86
+ const { field, fieldState } = useController({
87
+ name,
88
+ control
89
+ });
90
+ const selectedDate = toValidDate(field.value);
91
+ useEffect(() => {
92
+ const date = toValidDate(field.value);
93
+ if (!date) {
94
+ setTimeSet(false);
95
+ return;
96
+ }
97
+ if (hasTimePart(date)) setTimeSet(true);
98
+ }, [field.value]);
99
+ const fieldError = fieldState.error?.message;
100
+ const errorMessage = customError ?? fieldError;
101
+ const hasError = !!errorMessage;
102
+ const effectiveSize = size ?? formConfig.size ?? "md";
103
+ const effectiveDisabled = disabled ?? formConfig.disabled;
104
+ const effectiveVariant = hasError ? "error" : variant;
105
+ const displayHasTime = timeSet && !!selectedDate;
106
+ const handleOpenChange = (nextOpen) => {
107
+ setOpen(nextOpen);
108
+ if (nextOpen && timeSet) {
109
+ setTimeOpen(true);
110
+ return;
111
+ }
112
+ if (!nextOpen) setTimeOpen(false);
113
+ };
114
+ return /* @__PURE__ */ jsx(FieldLayout, {
115
+ inputId,
116
+ label,
117
+ required: !!required,
118
+ helperText,
119
+ errorMessage: showError ? errorMessage : void 0,
120
+ showError,
121
+ fullWidth,
122
+ formConfig,
123
+ children: /* @__PURE__ */ jsxs(Popover, {
124
+ open,
125
+ onOpenChange: handleOpenChange,
126
+ children: [/* @__PURE__ */ jsx(PopoverTrigger, {
127
+ asChild: true,
128
+ children: /* @__PURE__ */ jsxs(Button, {
129
+ id: inputId,
130
+ type: "button",
131
+ variant: "outline",
132
+ disabled: effectiveDisabled,
133
+ "aria-invalid": hasError,
134
+ "aria-describedby": hasError ? `${inputId}-error` : helperText ? `${inputId}-helper` : void 0,
135
+ className: cn(dateTimePickerVariants({
136
+ size: effectiveSize,
137
+ variant: effectiveVariant
138
+ }), !selectedDate && "text-muted-foreground", className),
139
+ children: [/* @__PURE__ */ jsx(CalendarIcon, { className: "mr-2 h-4 w-4" }), selectedDate ? format(selectedDate, displayHasTime ? "PPP p" : "PPP") : placeholder]
140
+ })
141
+ }), /* @__PURE__ */ jsxs(PopoverContent, {
142
+ className: "w-auto p-0",
143
+ align: "start",
144
+ onPointerDownOutside: (event) => {
145
+ if (isSelectEventTarget(event.target)) event.preventDefault();
146
+ },
147
+ onFocusOutside: (event) => {
148
+ if (isSelectEventTarget(event.target)) event.preventDefault();
149
+ },
150
+ children: [
151
+ /* @__PURE__ */ jsx(Calendar, {
152
+ mode: "single",
153
+ selected: selectedDate,
154
+ onSelect: (date) => {
155
+ if (!date) {
156
+ field.onChange("");
157
+ setTimeSet(false);
158
+ return;
159
+ }
160
+ if (selectedDate && timeSet) {
161
+ field.onChange(withPreservedTime(date, selectedDate));
162
+ setOpen(false);
163
+ return;
164
+ }
165
+ field.onChange(startOfDay(date));
166
+ }
167
+ }),
168
+ /* @__PURE__ */ jsx(Separator, {}),
169
+ /* @__PURE__ */ jsxs("div", {
170
+ className: "p-3",
171
+ children: [/* @__PURE__ */ jsxs(Button, {
172
+ type: "button",
173
+ variant: "ghost",
174
+ disabled: effectiveDisabled,
175
+ className: "h-8 w-full justify-start px-2 font-normal",
176
+ onClick: () => setTimeOpen((current) => !current),
177
+ children: [/* @__PURE__ */ jsx(Clock, { className: "mr-2 h-4 w-4" }), displayHasTime && selectedDate ? format(selectedDate, "p") : "Add time"]
178
+ }), timeOpen ? /* @__PURE__ */ jsx(TimePicker, {
179
+ className: "mt-2",
180
+ value: selectedDate,
181
+ minuteStep,
182
+ disabled: effectiveDisabled,
183
+ onChange: (date) => {
184
+ field.onChange(date);
185
+ setTimeSet(true);
186
+ },
187
+ onClear: () => {
188
+ if (selectedDate) field.onChange(startOfDay(selectedDate));
189
+ setTimeSet(false);
190
+ }
191
+ }) : null]
192
+ })
193
+ ]
194
+ })]
195
+ })
196
+ });
197
+ }
198
+ DateTimePicker.displayName = "DateTimePicker";
199
+ //#endregion
200
+ export { DateTimePicker };
201
+
202
+ //# sourceMappingURL=DateTimePicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateTimePicker.js","names":[],"sources":["../../../src/components/Form/DateTimePicker.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useContext, useEffect, useId, useState } from \"react\";\r\nimport { format, startOfDay } from \"date-fns\";\r\nimport { CalendarIcon, Clock } from \"lucide-react\";\r\nimport { useController, useFormContext as useRHFFormContext, type Control, type FieldPath, type FieldValues } from \"react-hook-form\";\r\nimport { cva, type VariantProps } from \"class-variance-authority\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport { Calendar } from \"../../primitives/calendar\";\r\nimport { Popover, PopoverContent, PopoverTrigger } from \"../../primitives/popover\";\r\nimport { Separator } from \"../../primitives/separator\";\r\nimport { FormConfigContext, type FieldValidationRules, type FormConfig } from \"./context\";\r\nimport { FieldLayout } from \"./FieldLayout\";\r\nimport { TimePicker } from \"./TimePicker\";\r\n\r\nconst dateTimePickerVariants = cva(\"w-full justify-start text-left font-normal\", {\r\n variants: {\r\n size: {\r\n sm: \"h-8 text-xs\",\r\n md: \"h-10 text-sm\",\r\n lg: \"h-12 text-base\",\r\n },\r\n variant: {\r\n default: \"border-input\",\r\n error: \"border-destructive\",\r\n success: \"border-green-500\",\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n variant: \"default\",\r\n },\r\n});\r\n\r\nexport interface DateTimePickerProps<\r\n TFieldValues extends FieldValues = FieldValues,\r\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\r\n> extends VariantProps<typeof dateTimePickerVariants> {\r\n name: TName;\r\n label?: string;\r\n helperText?: string;\r\n showError?: boolean;\r\n error?: string;\r\n fullWidth?: boolean;\r\n placeholder?: string;\r\n disabled?: boolean;\r\n className?: string;\r\n id?: string;\r\n control?: Control<TFieldValues>;\r\n required?: boolean | string;\r\n validate?: (value: unknown) => boolean | string | Promise<boolean | string>;\r\n minuteStep?: number;\r\n}\r\n\r\nfunction toValidDate(value: unknown): Date | undefined {\r\n if (!value || value === \"\") {\r\n return undefined;\r\n }\r\n\r\n const date = value instanceof Date ? value : new Date(value as string | number);\r\n if (Number.isNaN(date.getTime())) {\r\n return undefined;\r\n }\r\n\r\n return date;\r\n}\r\n\r\nfunction hasTimePart(date: Date): boolean {\r\n return date.getHours() !== 0 || date.getMinutes() !== 0 || date.getSeconds() !== 0 || date.getMilliseconds() !== 0;\r\n}\r\n\r\nfunction withPreservedTime(nextDay: Date, previous: Date): Date {\r\n const next = new Date(nextDay);\r\n next.setHours(\r\n previous.getHours(),\r\n previous.getMinutes(),\r\n previous.getSeconds(),\r\n previous.getMilliseconds()\r\n );\r\n return next;\r\n}\r\n\r\nfunction isSelectEventTarget(target: EventTarget | null): boolean {\r\n return target instanceof Element && Boolean(target.closest(\"[data-radix-select-content]\"));\r\n}\r\n\r\nexport function DateTimePicker<\r\n TFieldValues extends FieldValues = FieldValues,\r\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\r\n>({\r\n name,\r\n label,\r\n helperText,\r\n showError = true,\r\n error: customError,\r\n size,\r\n variant,\r\n fullWidth = true,\r\n placeholder = \"Pick a date\",\r\n disabled,\r\n className,\r\n id: providedId,\r\n control: externalControl,\r\n required,\r\n validate,\r\n minuteStep = 5,\r\n}: DateTimePickerProps<TFieldValues, TName>) {\r\n const generatedId = useId();\r\n const inputId = providedId ?? generatedId;\r\n const [open, setOpen] = useState(false);\r\n const [timeOpen, setTimeOpen] = useState(false);\r\n const [timeSet, setTimeSet] = useState(false);\r\n const formConfigContext = useContext(FormConfigContext);\r\n const formConfig: FormConfig = formConfigContext ?? {};\r\n const rhfContext = useRHFFormContext<TFieldValues>();\r\n const control = externalControl ?? rhfContext?.control;\r\n\r\n const registerFieldValidation = formConfigContext?.registerFieldValidation;\r\n const unregisterFieldValidation = formConfigContext?.unregisterFieldValidation;\r\n\r\n useEffect(() => {\r\n if (registerFieldValidation) {\r\n const rules: FieldValidationRules = {};\r\n if (required !== undefined) rules.required = required;\r\n if (validate !== undefined) rules.validate = validate;\r\n\r\n registerFieldValidation({\r\n name: name as string,\r\n type: \"datetime\",\r\n rules,\r\n });\r\n\r\n return () => {\r\n unregisterFieldValidation?.(name as string);\r\n };\r\n }\r\n }, [\r\n registerFieldValidation,\r\n unregisterFieldValidation,\r\n name,\r\n required,\r\n validate,\r\n ]);\r\n\r\n const { field, fieldState } = useController<TFieldValues, TName>({\r\n name,\r\n control,\r\n });\r\n\r\n const selectedDate = toValidDate(field.value);\r\n\r\n useEffect(() => {\r\n const date = toValidDate(field.value);\r\n if (!date) {\r\n setTimeSet(false);\r\n return;\r\n }\r\n\r\n if (hasTimePart(date)) {\r\n setTimeSet(true);\r\n }\r\n }, [field.value]);\r\n\r\n const fieldError = fieldState.error?.message;\r\n const errorMessage = customError ?? fieldError;\r\n const hasError = !!errorMessage;\r\n const effectiveSize = size ?? formConfig.size ?? \"md\";\r\n const effectiveDisabled = disabled ?? formConfig.disabled;\r\n const effectiveVariant = hasError ? \"error\" : variant;\r\n const displayHasTime = timeSet && !!selectedDate;\r\n\r\n const handleOpenChange = (nextOpen: boolean) => {\r\n setOpen(nextOpen);\r\n if (nextOpen && timeSet) {\r\n setTimeOpen(true);\r\n return;\r\n }\r\n\r\n if (!nextOpen) {\r\n setTimeOpen(false);\r\n }\r\n };\r\n\r\n return (\r\n <FieldLayout\r\n inputId={inputId}\r\n label={label}\r\n required={!!required}\r\n helperText={helperText}\r\n errorMessage={showError ? errorMessage : undefined}\r\n showError={showError}\r\n fullWidth={fullWidth}\r\n formConfig={formConfig}\r\n >\r\n <Popover open={open} onOpenChange={handleOpenChange}>\r\n <PopoverTrigger asChild>\r\n <Button\r\n id={inputId}\r\n type=\"button\"\r\n variant=\"outline\"\r\n disabled={effectiveDisabled}\r\n aria-invalid={hasError}\r\n aria-describedby={\r\n hasError\r\n ? `${inputId}-error`\r\n : helperText\r\n ? `${inputId}-helper`\r\n : undefined\r\n }\r\n className={cn(\r\n dateTimePickerVariants({ size: effectiveSize, variant: effectiveVariant }),\r\n !selectedDate && \"text-muted-foreground\",\r\n className\r\n )}\r\n >\r\n <CalendarIcon className=\"mr-2 h-4 w-4\" />\r\n {selectedDate\r\n ? format(selectedDate, displayHasTime ? \"PPP p\" : \"PPP\")\r\n : placeholder}\r\n </Button>\r\n </PopoverTrigger>\r\n <PopoverContent\r\n className=\"w-auto p-0\"\r\n align=\"start\"\r\n onPointerDownOutside={(event) => {\r\n if (isSelectEventTarget(event.target)) {\r\n event.preventDefault();\r\n }\r\n }}\r\n onFocusOutside={(event) => {\r\n if (isSelectEventTarget(event.target)) {\r\n event.preventDefault();\r\n }\r\n }}\r\n >\r\n <Calendar\r\n mode=\"single\"\r\n selected={selectedDate}\r\n onSelect={(date) => {\r\n if (!date) {\r\n field.onChange(\"\");\r\n setTimeSet(false);\r\n return;\r\n }\r\n\r\n if (selectedDate && timeSet) {\r\n field.onChange(withPreservedTime(date, selectedDate));\r\n setOpen(false);\r\n return;\r\n }\r\n\r\n field.onChange(startOfDay(date));\r\n }}\r\n />\r\n <Separator />\r\n <div className=\"p-3\">\r\n <Button\r\n type=\"button\"\r\n variant=\"ghost\"\r\n disabled={effectiveDisabled}\r\n className=\"h-8 w-full justify-start px-2 font-normal\"\r\n onClick={() => setTimeOpen((current) => !current)}\r\n >\r\n <Clock className=\"mr-2 h-4 w-4\" />\r\n {displayHasTime && selectedDate ? format(selectedDate, \"p\") : \"Add time\"}\r\n </Button>\r\n {timeOpen ? (\r\n <TimePicker\r\n className=\"mt-2\"\r\n value={selectedDate}\r\n minuteStep={minuteStep}\r\n disabled={effectiveDisabled}\r\n onChange={(date) => {\r\n field.onChange(date);\r\n setTimeSet(true);\r\n }}\r\n onClear={() => {\r\n if (selectedDate) {\r\n field.onChange(startOfDay(selectedDate));\r\n }\r\n setTimeSet(false);\r\n }}\r\n />\r\n ) : null}\r\n </div>\r\n </PopoverContent>\r\n </Popover>\r\n </FieldLayout>\r\n );\r\n}\r\n\r\nDateTimePicker.displayName = \"DateTimePicker\";\r\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface PasswordRevealToggleProps {
2
+ visible: boolean;
3
+ onToggle: () => void;
4
+ disabled?: boolean;
5
+ }
6
+ export declare function PasswordRevealToggle({ visible, onToggle, disabled, }: PasswordRevealToggleProps): import("react").JSX.Element;
7
+ //# sourceMappingURL=PasswordRevealToggle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PasswordRevealToggle.d.ts","sourceRoot":"","sources":["../../../src/components/Form/PasswordRevealToggle.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,yBAAyB;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,oBAAoB,CAAC,EACpC,OAAO,EACP,QAAQ,EACR,QAAgB,GAChB,EAAE,yBAAyB,+BAc3B"}
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ "use client";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { Eye, EyeOff } from "lucide-react";
5
+ //#region src/components/Form/PasswordRevealToggle.tsx
6
+ function PasswordRevealToggle({ visible, onToggle, disabled = false }) {
7
+ return /* @__PURE__ */ jsx("button", {
8
+ type: "button",
9
+ onClick: onToggle,
10
+ disabled,
11
+ className: "text-muted-foreground hover:text-foreground transition-colors disabled:pointer-events-none disabled:opacity-50",
12
+ tabIndex: -1,
13
+ "aria-label": visible ? "Hide password" : "Show password",
14
+ "aria-pressed": visible,
15
+ children: visible ? /* @__PURE__ */ jsx(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Eye, { className: "h-4 w-4" })
16
+ });
17
+ }
18
+ //#endregion
19
+ export { PasswordRevealToggle };
20
+
21
+ //# sourceMappingURL=PasswordRevealToggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PasswordRevealToggle.js","names":[],"sources":["../../../src/components/Form/PasswordRevealToggle.tsx"],"sourcesContent":["\"use client\";\n\nimport { Eye, EyeOff } from \"lucide-react\";\n\nexport interface PasswordRevealToggleProps {\n\tvisible: boolean;\n\tonToggle: () => void;\n\tdisabled?: boolean;\n}\n\nexport function PasswordRevealToggle({\n\tvisible,\n\tonToggle,\n\tdisabled = false,\n}: PasswordRevealToggleProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tonClick={onToggle}\n\t\t\tdisabled={disabled}\n\t\t\tclassName=\"text-muted-foreground hover:text-foreground transition-colors disabled:pointer-events-none disabled:opacity-50\"\n\t\t\ttabIndex={-1}\n\t\t\taria-label={visible ? \"Hide password\" : \"Show password\"}\n\t\t\taria-pressed={visible}\n\t\t>\n\t\t\t{visible ? <EyeOff className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\n\t\t</button>\n\t);\n}\n"],"mappings":";;;;;AAUA,SAAgB,qBAAqB,EACpC,SACA,UACA,WAAW,SACkB;CAC7B,OACC,oBAAC,UAAD;EACC,MAAK;EACL,SAAS;EACC;EACV,WAAU;EACV,UAAU;EACV,cAAY,UAAU,kBAAkB;EACxC,gBAAc;EAEb,UAAA,UAAU,oBAAC,QAAD,EAAQ,WAAU,UAAW,CAAA,IAAI,oBAAC,KAAD,EAAK,WAAU,UAAW,CAAA;CAC/D,CAAA;AAEV"}
@@ -33,6 +33,11 @@ export interface TextBoxProps<TFieldValues extends FieldValues = FieldValues, TN
33
33
  allowClear?: boolean;
34
34
  /** Callback when clear is clicked */
35
35
  onClear?: () => void;
36
+ /**
37
+ * Show an eye toggle for password fields.
38
+ * Defaults to true when `type="password"`.
39
+ */
40
+ passwordToggle?: boolean;
36
41
  /** External control (for use outside Form) */
37
42
  control?: Control<TFieldValues>;
38
43
  /** Field is required */