formik-form-components 2.0.2 → 2.0.3

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 (107) hide show
  1. package/README.md +19 -1
  2. package/dist/Form/AppAutoCompleter.d.ts +11 -0
  3. package/dist/Form/AppAutoCompleter.d.ts.map +1 -0
  4. package/dist/Form/AppCheckBox.d.ts +15 -0
  5. package/dist/Form/AppCheckBox.d.ts.map +1 -0
  6. package/dist/Form/AppDateAndTimePicker.d.ts +14 -0
  7. package/dist/Form/AppDateAndTimePicker.d.ts.map +1 -0
  8. package/dist/Form/AppDatePicker.d.ts +11 -0
  9. package/dist/Form/AppDatePicker.d.ts.map +1 -0
  10. package/dist/Form/AppFormErrorMessage.d.ts +9 -0
  11. package/dist/Form/AppFormErrorMessage.d.ts.map +1 -0
  12. package/dist/Form/AppInputField.d.ts +9 -0
  13. package/dist/Form/AppInputField.d.ts.map +1 -0
  14. package/dist/Form/AppMultiSelector.d.ts +20 -0
  15. package/dist/Form/AppMultiSelector.d.ts.map +1 -0
  16. package/dist/Form/AppPhoneNoInput.d.ts +16 -0
  17. package/dist/Form/AppPhoneNoInput.d.ts.map +1 -0
  18. package/dist/Form/AppRadioGroup.d.ts +17 -0
  19. package/dist/Form/AppRadioGroup.d.ts.map +1 -0
  20. package/dist/Form/AppRating.d.ts +12 -0
  21. package/dist/Form/AppRating.d.ts.map +1 -0
  22. package/dist/Form/AppSelectInput.d.ts +15 -0
  23. package/dist/Form/AppSelectInput.d.ts.map +1 -0
  24. package/dist/Form/AppSimpleUploadFile.d.ts +14 -0
  25. package/dist/Form/AppSimpleUploadFile.d.ts.map +1 -0
  26. package/dist/Form/AppSwitch.d.ts +10 -0
  27. package/dist/Form/AppSwitch.d.ts.map +1 -0
  28. package/dist/Form/AppTagsCreator.d.ts +11 -0
  29. package/dist/Form/AppTagsCreator.d.ts.map +1 -0
  30. package/dist/Form/AppTextArea.d.ts +10 -0
  31. package/dist/Form/AppTextArea.d.ts.map +1 -0
  32. package/dist/Form/AppUploadFile.d.ts +20 -0
  33. package/dist/Form/AppUploadFile.d.ts.map +1 -0
  34. package/dist/Form/SubmitButton.d.ts +10 -0
  35. package/dist/Form/SubmitButton.d.ts.map +1 -0
  36. package/dist/Form/index.d.ts +10 -0
  37. package/dist/Form/index.d.ts.map +1 -0
  38. package/dist/assets/illustrations/BackgroundIllustration.d.ts +7 -0
  39. package/dist/assets/illustrations/BackgroundIllustration.d.ts.map +1 -0
  40. package/dist/assets/illustrations/UploadIllustration.d.ts +5 -0
  41. package/dist/assets/illustrations/UploadIllustration.d.ts.map +1 -0
  42. package/dist/assets/illustrations/index.d.ts +2 -0
  43. package/dist/assets/illustrations/index.d.ts.map +1 -0
  44. package/dist/file-thumbnail/types.d.ts +6 -0
  45. package/dist/file-thumbnail/types.d.ts.map +1 -0
  46. package/dist/file-thumbnail/utils.d.ts +26 -0
  47. package/dist/file-thumbnail/utils.d.ts.map +1 -0
  48. package/dist/index.esm.js +1 -2
  49. package/dist/index.js +1 -2
  50. package/dist/lib/index.d.ts +29 -0
  51. package/dist/lib/index.d.ts.map +1 -0
  52. package/dist/lib/optional-deps.d.ts +13 -0
  53. package/dist/lib/optional-deps.d.ts.map +1 -0
  54. package/dist/upload/Upload.d.ts +5 -0
  55. package/dist/upload/Upload.d.ts.map +1 -0
  56. package/dist/upload/errors/RejectionFiles.d.ts +8 -0
  57. package/dist/upload/errors/RejectionFiles.d.ts.map +1 -0
  58. package/dist/upload/index.d.ts +6 -0
  59. package/dist/upload/index.d.ts.map +1 -0
  60. package/dist/upload/preview/MultiFilePreview.d.ts +11 -0
  61. package/dist/upload/preview/MultiFilePreview.d.ts.map +1 -0
  62. package/dist/upload/preview/SingleFilePreview.d.ts +9 -0
  63. package/dist/upload/preview/SingleFilePreview.d.ts.map +1 -0
  64. package/dist/upload/types.d.ts +40 -0
  65. package/dist/upload/types.d.ts.map +1 -0
  66. package/package.json +22 -16
  67. package/src/App.css +38 -0
  68. package/src/App.test.tsx +9 -0
  69. package/src/App.tsx +166 -0
  70. package/src/Form/AppAutoCompleter.tsx +252 -0
  71. package/src/Form/AppCheckBox.tsx +101 -0
  72. package/src/Form/AppDateAndTimePicker.tsx +94 -0
  73. package/src/Form/AppDatePicker.tsx +69 -0
  74. package/src/Form/AppFormErrorMessage.tsx +34 -0
  75. package/src/Form/AppInputField.tsx +80 -0
  76. package/src/Form/AppMultiSelector.tsx +163 -0
  77. package/src/Form/AppPhoneNoInput.tsx +106 -0
  78. package/src/Form/AppRadioGroup.tsx +92 -0
  79. package/src/Form/AppRating.tsx +98 -0
  80. package/src/Form/AppSelectInput.tsx +249 -0
  81. package/src/Form/AppSimpleUploadFile.tsx +154 -0
  82. package/src/Form/AppSwitch.tsx +84 -0
  83. package/src/Form/AppTagsCreator.tsx +252 -0
  84. package/src/Form/AppTextArea.tsx +90 -0
  85. package/src/Form/AppUploadFile.tsx +167 -0
  86. package/src/Form/SubmitButton.tsx +122 -0
  87. package/src/Form/index.tsx +27 -0
  88. package/src/assets/illustrations/BackgroundIllustration.tsx +42 -0
  89. package/src/assets/illustrations/UploadIllustration.tsx +659 -0
  90. package/src/assets/illustrations/index.ts +1 -0
  91. package/src/file-thumbnail/types.ts +7 -0
  92. package/src/file-thumbnail/utils.ts +162 -0
  93. package/src/index.css +9 -0
  94. package/src/index.tsx +19 -0
  95. package/src/lib/index.ts +47 -0
  96. package/src/logo.svg +1 -0
  97. package/src/react-app-env.d.ts +1 -0
  98. package/src/reportWebVitals.ts +15 -0
  99. package/src/setupTests.ts +5 -0
  100. package/src/styles/PhoneInputCustom.css +238 -0
  101. package/src/styles/compiled-tailwind.css +1 -0
  102. package/src/upload/Upload.tsx +162 -0
  103. package/src/upload/errors/RejectionFiles.tsx +49 -0
  104. package/src/upload/index.ts +5 -0
  105. package/src/upload/preview/MultiFilePreview.tsx +297 -0
  106. package/src/upload/preview/SingleFilePreview.tsx +81 -0
  107. package/src/upload/types.ts +51 -0
@@ -0,0 +1,162 @@
1
+ // components
2
+ import type { ExtendFile } from "./types";
3
+
4
+ // ----------------------------------------------------------------------
5
+
6
+ // Define more types here
7
+ const FORMAT_PDF = ["pdf"];
8
+ const FORMAT_TEXT = ["txt"];
9
+ const FORMAT_PHOTOSHOP = ["psd"];
10
+ const FORMAT_WORD = ["doc", "docx"];
11
+ const FORMAT_EXCEL = ["xls", "xlsx"];
12
+ const FORMAT_ZIP = ["zip", "rar", "iso"];
13
+ const FORMAT_ILLUSTRATOR = ["ai", "esp"];
14
+ const FORMAT_POWERPOINT = ["ppt", "pptx"];
15
+ const FORMAT_AUDIO = ["wav", "aif", "mp3", "aac"];
16
+ const FORMAT_IMG = ["jpg", "jpeg", "gif", "bmp", "png", "svg"];
17
+ const FORMAT_VIDEO = ["m4v", "avi", "mpg", "mp4", "webm"];
18
+
19
+ const iconUrl = (icon: string): string => `/assets/icons/files/${icon}.svg`;
20
+
21
+ // ----------------------------------------------------------------------
22
+
23
+ export function fileFormat(fileUrl: string | undefined): string {
24
+ let format;
25
+
26
+ switch (fileUrl?.includes(fileTypeByUrl(fileUrl))) {
27
+ case FORMAT_TEXT.includes(fileTypeByUrl(fileUrl)):
28
+ format = "txt";
29
+ break;
30
+ case FORMAT_ZIP.includes(fileTypeByUrl(fileUrl)):
31
+ format = "zip";
32
+ break;
33
+ case FORMAT_AUDIO.includes(fileTypeByUrl(fileUrl)):
34
+ format = "audio";
35
+ break;
36
+ case FORMAT_IMG.includes(fileTypeByUrl(fileUrl)):
37
+ format = "image";
38
+ break;
39
+ case FORMAT_VIDEO.includes(fileTypeByUrl(fileUrl)):
40
+ format = "video";
41
+ break;
42
+ case FORMAT_WORD.includes(fileTypeByUrl(fileUrl)):
43
+ format = "word";
44
+ break;
45
+ case FORMAT_EXCEL.includes(fileTypeByUrl(fileUrl)):
46
+ format = "excel";
47
+ break;
48
+ case FORMAT_POWERPOINT.includes(fileTypeByUrl(fileUrl)):
49
+ format = "powerpoint";
50
+ break;
51
+ case FORMAT_PDF.includes(fileTypeByUrl(fileUrl)):
52
+ format = "pdf";
53
+ break;
54
+ case FORMAT_PHOTOSHOP.includes(fileTypeByUrl(fileUrl)):
55
+ format = "photoshop";
56
+ break;
57
+ case FORMAT_ILLUSTRATOR.includes(fileTypeByUrl(fileUrl)):
58
+ format = "illustrator";
59
+ break;
60
+ default:
61
+ format = fileTypeByUrl(fileUrl);
62
+ }
63
+
64
+ return format;
65
+ }
66
+
67
+ // ----------------------------------------------------------------------
68
+
69
+ export function fileThumb(fileUrl: string): string {
70
+ let thumb;
71
+
72
+ switch (fileFormat(fileUrl)) {
73
+ case "folder":
74
+ thumb = iconUrl("ic_folder");
75
+ break;
76
+ case "txt":
77
+ thumb = iconUrl("ic_txt");
78
+ break;
79
+ case "zip":
80
+ thumb = iconUrl("ic_zip");
81
+ break;
82
+ case "audio":
83
+ thumb = iconUrl("ic_audio");
84
+ break;
85
+ case "video":
86
+ thumb = iconUrl("ic_video");
87
+ break;
88
+ case "word":
89
+ thumb = iconUrl("ic_word");
90
+ break;
91
+ case "excel":
92
+ thumb = iconUrl("ic_excel");
93
+ break;
94
+ case "powerpoint":
95
+ thumb = iconUrl("ic_power_point");
96
+ break;
97
+ case "pdf":
98
+ thumb = iconUrl("ic_pdf");
99
+ break;
100
+ case "photoshop":
101
+ thumb = iconUrl("ic_pts");
102
+ break;
103
+ case "illustrator":
104
+ thumb = iconUrl("ic_ai");
105
+ break;
106
+ case "image":
107
+ thumb = iconUrl("ic_img");
108
+ break;
109
+ default:
110
+ thumb = iconUrl("ic_file");
111
+ }
112
+ return thumb;
113
+ }
114
+
115
+ // ----------------------------------------------------------------------
116
+
117
+ export function fileTypeByUrl(fileUrl = ""): string {
118
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
119
+ return (fileUrl && fileUrl.split(".").pop()) || "";
120
+ }
121
+
122
+ // ----------------------------------------------------------------------
123
+
124
+ export function fileNameByUrl(fileUrl: string): string | undefined {
125
+ return fileUrl.split("/").pop();
126
+ }
127
+
128
+ // ----------------------------------------------------------------------
129
+
130
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
131
+ export function fileData(file: ExtendFile | string) {
132
+ // Url
133
+ if (typeof file === "string") {
134
+ return {
135
+ key: file,
136
+ preview: file,
137
+ name: fileNameByUrl(file),
138
+ type: fileTypeByUrl(file),
139
+ };
140
+ }
141
+
142
+ // File
143
+ return {
144
+ key: file?.preview,
145
+ name: file?.name,
146
+ size: file?.size,
147
+ path: file?.path,
148
+ type: file?.type,
149
+ preview: file?.preview,
150
+ lastModified: file?.lastModified,
151
+ lastModifiedDate: file?.lastModifiedDate,
152
+ };
153
+ }
154
+
155
+ // Helper function to format file size
156
+ export function formatFileSize(bytes: number): string {
157
+ if (bytes === 0) return "0 Bytes";
158
+ const k = 1024;
159
+ const sizes = ["Bytes", "KB", "MB", "GB"];
160
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
161
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
162
+ }
package/src/index.css ADDED
@@ -0,0 +1,9 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @layer base {
6
+ body {
7
+ @apply bg-gray-50 text-gray-900;
8
+ }
9
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import ReactDOM from "react-dom/client";
3
+ import "./index.css"; // Make sure this line exists
4
+ import App from "./App";
5
+ import reportWebVitals from "./reportWebVitals";
6
+
7
+ const root = ReactDOM.createRoot(
8
+ document.getElementById("root") as HTMLElement
9
+ );
10
+ root.render(
11
+ <React.StrictMode>
12
+ <App />
13
+ </React.StrictMode>
14
+ );
15
+
16
+ // If you want to start measuring performance in your app, pass a function
17
+ // to log results (for example: reportWebVitals(console.log))
18
+ // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
19
+ reportWebVitals();
@@ -0,0 +1,47 @@
1
+ 'use client';
2
+
3
+ // Import precompiled Tailwind CSS styles
4
+ import '../styles/compiled-tailwind.css';
5
+ import '../styles/PhoneInputCustom.css';
6
+
7
+ // Export Form Components
8
+ export { default as Form } from '../Form/index';
9
+ export { default as AppAutoCompleter } from '../Form/AppAutoCompleter';
10
+ export { default as AppCheckBox } from '../Form/AppCheckBox';
11
+ export { default as AppDateAndTimePicker } from '../Form/AppDateAndTimePicker';
12
+ export { default as AppDatePicker } from '../Form/AppDatePicker';
13
+ export { default as AppFormErrorMessage } from '../Form/AppFormErrorMessage';
14
+ export { default as AppInputField } from '../Form/AppInputField';
15
+ export { default as AppMultiSelector } from '../Form/AppMultiSelector';
16
+ export { default as AppPhoneNoInput } from '../Form/AppPhoneNoInput';
17
+ export { default as AppRadioGroup } from '../Form/AppRadioGroup';
18
+ export { default as AppRating } from '../Form/AppRating';
19
+ export { default as AppSelectInput } from '../Form/AppSelectInput';
20
+ export { default as AppSimpleUploadFile } from '../Form/AppSimpleUploadFile';
21
+ export { default as AppSwitch } from '../Form/AppSwitch';
22
+ export { default as AppTagsCreator } from '../Form/AppTagsCreator';
23
+ export { default as AppTextArea } from '../Form/AppTextArea';
24
+ export { default as AppUploadFile } from '../Form/AppUploadFile';
25
+ export { default as SubmitButton } from '../Form/SubmitButton';
26
+
27
+ // Export Upload Components
28
+ export {
29
+ Upload,
30
+ RejectionFiles,
31
+ MultiFilePreview,
32
+ SingleFilePreview
33
+ } from '../upload';
34
+
35
+ // Export Types
36
+ export type { UploadProps, CustomFile, FileWithPreview } from '../upload/types';
37
+ export type { FormProps } from '../Form/index';
38
+ export type { FileItem } from '../upload/preview/MultiFilePreview';
39
+ export type { ExtendFile } from '../file-thumbnail/types';
40
+
41
+ // Export Illustrations
42
+ export { UploadIllustration } from '../assets/illustrations';
43
+
44
+ // Export File Thumbnail utilities
45
+ export * from '../file-thumbnail/types';
46
+ export * from '../file-thumbnail/utils';
47
+
package/src/logo.svg ADDED
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
@@ -0,0 +1 @@
1
+ /// <reference types="react-scripts" />
@@ -0,0 +1,15 @@
1
+ import { ReportHandler } from 'web-vitals';
2
+
3
+ const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4
+ if (onPerfEntry && onPerfEntry instanceof Function) {
5
+ import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6
+ getCLS(onPerfEntry);
7
+ getFID(onPerfEntry);
8
+ getFCP(onPerfEntry);
9
+ getLCP(onPerfEntry);
10
+ getTTFB(onPerfEntry);
11
+ });
12
+ }
13
+ };
14
+
15
+ export default reportWebVitals;
@@ -0,0 +1,5 @@
1
+ // jest-dom adds custom jest matchers for asserting on DOM nodes.
2
+ // allows you to do things like:
3
+ // expect(element).toHaveTextContent(/react/i)
4
+ // learn more: https://github.com/testing-library/jest-dom
5
+ import '@testing-library/jest-dom';
@@ -0,0 +1,238 @@
1
+ .phone-input-wrapper {
2
+ max-width: 22rem;
3
+ margin-bottom: 1.5rem;
4
+ }
5
+
6
+ .phone-input-label {
7
+ display: block;
8
+ margin-bottom: 0.75rem;
9
+ font-size: 0.875rem;
10
+ font-weight: 500;
11
+ color: var(--text-primary, #111827);
12
+ transition: all 0.2s ease;
13
+ line-height: 1.4;
14
+ }
15
+
16
+ .phone-input-label.has-value {
17
+ color: var(--brand-color, #3b82f6);
18
+ }
19
+
20
+ .required-star {
21
+ color: #ef4444;
22
+ margin-left: 0.25rem;
23
+ font-size: 1rem;
24
+ font-weight: 700;
25
+ }
26
+
27
+ .phone-input-container {
28
+ position: relative;
29
+ display: flex;
30
+ align-items: stretch;
31
+ background: var(--input-bg, #ffffff);
32
+ border: 2px solid var(--border-default, #e5e7eb);
33
+ border-radius: 0.75rem;
34
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
35
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
36
+ overflow: hidden;
37
+ min-height: 3.5rem;
38
+ }
39
+
40
+ .phone-input-container.focus {
41
+ border-color: var(--brand-color, #3b82f6);
42
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1), 0 1px 3px 0 rgba(0, 0, 0, 0.1);
43
+ background: var(--input-focus-bg, #fefefe);
44
+ }
45
+
46
+ .phone-input-container.error {
47
+ border-color: #ef4444;
48
+ box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
49
+ }
50
+
51
+ .phone-input-container.error.focus {
52
+ border-color: #ef4444;
53
+ box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
54
+ }
55
+
56
+ .custom-phone-input {
57
+ display: flex;
58
+ align-items: center;
59
+ background: transparent;
60
+ border: none;
61
+ flex: 1;
62
+ font-family: inherit;
63
+ min-height: 3.5rem;
64
+ }
65
+
66
+ .custom-phone-input .PhoneInputCountry {
67
+ display: flex;
68
+ align-items: center;
69
+ background: var(--input-bg, #ffffff);
70
+ border-right: 4px solid var(--border-light, #f3f4f6);
71
+ padding: 0.875rem 1.25rem;
72
+ cursor: pointer;
73
+ transition: all 0.2s ease;
74
+ white-space: nowrap;
75
+ min-width: 5rem;
76
+ }
77
+
78
+
79
+
80
+ .custom-phone-input .PhoneInputCountry:hover {
81
+ background: var(--hover-bg, #f9fafb);
82
+ }
83
+
84
+
85
+ .custom-phone-input .PhoneInputCountrySelectArrow {
86
+ border-top-color: currentColor;
87
+ opacity: 0.6;
88
+ margin-left: 0.5rem;
89
+ transition: opacity 0.2s ease;
90
+ }
91
+
92
+ .custom-phone-input .PhoneInputCountrySelectArrow:hover {
93
+ opacity: 1;
94
+ }
95
+
96
+ .custom-phone-input .PhoneInputInput {
97
+ background: transparent;
98
+ border: none;
99
+ color: var(--text-primary, #111827);
100
+ font-size: 1rem;
101
+ font-weight: 400;
102
+ padding: 0.875rem 1.25rem;
103
+ flex: 1;
104
+ outline: none;
105
+ line-height: 1.5;
106
+ }
107
+
108
+ .custom-phone-input .PhoneInputInput::placeholder {
109
+ color: var(--text-muted, #9ca3af);
110
+ font-weight: 400;
111
+ }
112
+
113
+ .custom-phone-input .PhoneInputInput:focus {
114
+ outline: none;
115
+ box-shadow: none !important;
116
+ }
117
+
118
+ .custom-phone-input .PhoneInputCountryIcon {
119
+ width: 1.25rem;
120
+ height: 1.25rem;
121
+ margin-right: 0.5rem;
122
+ flex-shrink: 0;
123
+ }
124
+
125
+ .custom-phone-input .PhoneInputCountryIcon img {
126
+ width: 100%;
127
+ height: 100%;
128
+ object-fit: cover;
129
+ border-radius: 0.25rem;
130
+ }
131
+
132
+ /* Dropdown styles */
133
+ .custom-phone-input .PhoneInputCountryDropdown {
134
+ position: absolute;
135
+ top: 100%;
136
+ left: 0;
137
+ right: 0;
138
+ z-index: 50;
139
+ background: var(--dropdown-bg, #ffffff);
140
+ border: 1px solid var(--border-default, #e5e7eb);
141
+ border-radius: 0.75rem;
142
+ box-shadow:
143
+ 0 20px 25px -5px rgba(0, 0, 0, 0.1),
144
+ 0 10px 10px -5px rgba(0, 0, 0, 0.04);
145
+ max-height: 320px;
146
+ overflow: hidden;
147
+ margin-top: 0.5rem;
148
+ backdrop-filter: blur(10px);
149
+ }
150
+
151
+ .custom-phone-input .PhoneInputCountryOption {
152
+ display: flex;
153
+ align-items: center;
154
+ padding: 1rem 1.25rem;
155
+ font-size: 0.95rem;
156
+ color: var(--text-primary, #111827);
157
+ cursor: pointer;
158
+ transition: all 0.15s ease;
159
+ border-bottom: 1px solid var(--border-light, #f9fafb);
160
+ }
161
+
162
+ .custom-phone-input .PhoneInputCountryOption:last-child {
163
+ border-bottom: none;
164
+ }
165
+
166
+ .custom-phone-input .PhoneInputCountryOption:hover,
167
+ .custom-phone-input .PhoneInputCountryOption.PhoneInputCountryOption--selected {
168
+ background: linear-gradient(135deg, var(--brand-color, #3b82f6), #2563eb);
169
+ color: white;
170
+ transform: translateX(4px);
171
+ }
172
+
173
+ .custom-phone-input .PhoneInputCountryOption--selected .PhoneInputCountryIcon img {
174
+ filter: brightness(0) invert(1);
175
+ }
176
+
177
+ /* Error message */
178
+ .error-message {
179
+ margin-top: 0.5rem;
180
+ font-size: 0.875rem;
181
+ color: #ef4444;
182
+ display: flex;
183
+ align-items: center;
184
+ gap: 0.375rem;
185
+ animation: shake 0.5s ease-in-out;
186
+ }
187
+
188
+ @keyframes shake {
189
+ 0%, 100% { transform: translateX(0); }
190
+ 25% { transform: translateX(-4px); }
191
+ 75% { transform: translateX(4px); }
192
+ }
193
+
194
+ /* Disabled state */
195
+ .phone-input-container:disabled,
196
+ .custom-phone-input:disabled {
197
+ opacity: 0.6;
198
+ cursor: not-allowed;
199
+ background: var(--disabled-bg, #f9fafb);
200
+ }
201
+
202
+ .custom-phone-input:disabled .PhoneInputCountry,
203
+ .custom-phone-input:disabled .PhoneInputInput {
204
+ cursor: not-allowed;
205
+ }
206
+
207
+ /* Responsive */
208
+ @media (max-width: 640px) {
209
+ .phone-input-wrapper {
210
+ max-width: 100%;
211
+ }
212
+
213
+ .custom-phone-input .PhoneInputCountry {
214
+ min-width: 4.5rem;
215
+ padding-left: 1rem;
216
+ padding-right: 1rem;
217
+ }
218
+ }
219
+
220
+ /* High contrast mode support */
221
+ @media (prefers-contrast: high) {
222
+ .phone-input-container {
223
+ border-width: 3px;
224
+ }
225
+
226
+ .phone-input-container.focus {
227
+ border-color: var(--brand-color, #3b82f6);
228
+ box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.2);
229
+ }
230
+ }
231
+
232
+ /* Reduced motion */
233
+ @media (prefers-reduced-motion: reduce) {
234
+ * {
235
+ transition: none !important;
236
+ animation: none !important;
237
+ }
238
+ }