diff --git a/scripts/make-dist.mjs b/scripts/make-dist.mjs index b5a5ea2..9bc60b7 100644 --- a/scripts/make-dist.mjs +++ b/scripts/make-dist.mjs @@ -7,22 +7,38 @@ if (!fs.existsSync(distDir)) fs.mkdirSync(distDir, { recursive: true }); const indexJs = `/* Auto-generated by scripts/make-dist.mjs */ export { default as Button } from "../src/components/Button.astro"; -export { default as Form } from "../src/components/Form.astro"; -export { default as Field } from "../src/components/Field.astro"; -export { default as MultiSelect } from "../src/components/MultiSelect.astro"; -export { default as ThemeSwitcher } from "../src/components/ThemeSwitcher.astro"; export { default as ColorSwitcher } from "../src/components/ColorSwitcher.astro"; +export { default as DatePicker } from "../src/components/DatePicker.astro"; +export { default as DateTimePicker } from "../src/components/DateTimePicker.astro"; +export { default as Dropdown } from "../src/components/Dropdown.astro"; +export { default as Field } from "../src/components/Field.astro"; +export { default as FieldRow } from "../src/components/FieldRow.astro"; +export { default as FileUploader } from "../src/components/FileUploader.astro"; +export { default as Form } from "../src/components/Form.astro"; +export { default as MultiSelect } from "../src/components/MultiSelect.astro"; +export { default as OtpField } from "../src/components/OtpField.astro"; +export { default as PasswordField } from "../src/components/PasswordField.astro"; +export { default as ThemeSwitcher } from "../src/components/ThemeSwitcher.astro"; +export { default as TimePicker } from "../src/components/TimePicker.astro"; export { cn } from "../src/utils/cn.js"; `; const indexDts = `/* Auto-generated types (lightweight) */ /// export const Button: any; -export const Form: any; -export const Field: any; -export const MultiSelect: any; -export const ThemeSwitcher: any; export const ColorSwitcher: any; +export const DatePicker: any; +export const DateTimePicker: any; +export const Dropdown: any; +export const Field: any; +export const FieldRow: any; +export const FileUploader: any; +export const Form: any; +export const MultiSelect: any; +export const OtpField: any; +export const PasswordField: any; +export const ThemeSwitcher: any; +export const TimePicker: any; export function cn(...classes: Array): string; `; diff --git a/src/components/DatePicker.astro b/src/components/DatePicker.astro new file mode 100644 index 0000000..9385c41 --- /dev/null +++ b/src/components/DatePicker.astro @@ -0,0 +1,568 @@ +--- +// DatePicker.astro - Updated with year dropdown and auto validation +export interface Props { + label?: string; + description?: string; + name: string; + value?: string; + placeholder?: string; + required?: boolean; + disabled?: boolean; + min?: string; + max?: string; + format?: "yyyy-mm-dd" | "dd/mm/yyyy" | "mm/dd/yyyy"; + firstDayOfWeek?: 0 | 1; + class?: string; +} + +const { + label = "Select Date", + description, + name, + value = "", + placeholder = "Select date", + required = false, + disabled = false, + min, + max, + format = "yyyy-mm-dd", + firstDayOfWeek = 1, + class: className = "", +} = Astro.props; + +const fieldId = `field-${name.replace(/[[\]]/g, "-")}`; +--- + +
+ + + { + description && ( +

+ {description} +

+ ) + } + +
+ + +
+ + +
+ + +
+ + +
+ + diff --git a/src/components/DateTimePicker.astro b/src/components/DateTimePicker.astro new file mode 100644 index 0000000..fb84281 --- /dev/null +++ b/src/components/DateTimePicker.astro @@ -0,0 +1,856 @@ +--- +// DateTimePicker.astro - Smart tab switching and auto validation +export interface Props { + label?: string; + description?: string; + name: string; + value?: string; + placeholder?: string; + required?: boolean; + disabled?: boolean; + dateFormat?: "yyyy-mm-dd" | "dd/mm/yyyy" | "mm/dd/yyyy"; + timeFormat?: 12 | 24; + timeStep?: number; + minDate?: string; + maxDate?: string; + class?: string; +} + +const { + label = "Select Date & Time", + description, + name, + value = "", + placeholder = "Select date and time", + required = false, + disabled = false, + dateFormat = "yyyy-mm-dd", + timeFormat = 12, + timeStep = 15, + minDate, + maxDate, + class: className = "", +} = Astro.props; + +const fieldId = `field-${name.replace(/[[\]]/g, "-")}`; + +let initialDate = ""; +let initialTime = ""; +if (value) { + const datetime = new Date(value); + if (!isNaN(datetime.getTime())) { + initialDate = datetime.toISOString().split("T")[0]; + initialTime = datetime.toTimeString().slice(0, 5); + } +} +--- + +
+ + + { + description && ( +

+ {description} +

+ ) + } + +
+ + +
+ + +
+ + +
+ + +
+ + diff --git a/src/components/FileUploader.astro b/src/components/FileUploader.astro new file mode 100644 index 0000000..af23d8d --- /dev/null +++ b/src/components/FileUploader.astro @@ -0,0 +1,862 @@ +--- +// FileUploader.astro - Fixed infinite recursion issue +export interface Props { + label?: string; + description?: string; + multiple?: boolean; + maxFileSize?: number; + acceptedTypes?: string[]; + maxFiles?: number; + required?: boolean; + name: string; + autoUpload?: boolean; + uploadFunction?: string; + returnUrls?: boolean; + validationFunction?: string; + class?: string; +} + +const { + label = "Upload Files", + description = "Select or drag and drop your files", + multiple = true, + maxFileSize = 10, + acceptedTypes = ["image/jpeg", "image/png", "image/gif", "image/webp"], + maxFiles = 5, + required = false, + name, + autoUpload = false, + uploadFunction = null, + returnUrls = false, + validationFunction = null, + class: className = "", +} = Astro.props; + +const fieldId = `field-${name.replace(/[[\]]/g, "-")}`; +--- + + +
+ + + { + description && ( +

+ {description} +

+ ) + } + + +
+ + { + returnUrls ? ( + + ) : ( + + ) + } + + +
+
+ + + + + +

+ Drop files here or +

+
+ + {multiple ? `Up to ${maxFiles}` : "Single file"} + + + Max {maxFileSize}MB + + + { + acceptedTypes + .map((type) => type.split("/")[1].toUpperCase()) + .join(", ") + } + +
+
+
+ + + + + +
+ + +
+ + +
+
+ + + +
+ + diff --git a/src/components/TimePicker.astro b/src/components/TimePicker.astro new file mode 100644 index 0000000..8a52a59 --- /dev/null +++ b/src/components/TimePicker.astro @@ -0,0 +1,465 @@ +--- +// TimePicker.astro - Auto validation on render +export interface Props { + label?: string; + description?: string; + name: string; + value?: string; + placeholder?: string; + required?: boolean; + disabled?: boolean; + format?: 12 | 24; + step?: number; + min?: string; + max?: string; + class?: string; +} + +const { + label = "Select Time", + description, + name, + value = "", + placeholder = "Select time", + required = false, + disabled = false, + format = 12, + step = 15, + min, + max, + class: className = "", +} = Astro.props; + +const fieldId = `field-${name.replace(/[[\]]/g, "-")}`; +--- + +
+ + + { + description && ( +

+ {description} +

+ ) + } + +
+ + +
+ + +
+ + +
+ + +
+ + diff --git a/src/global.d.ts b/src/global.d.ts index df4a9b5..17788c5 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -1,7 +1,8 @@ declare global { interface Window { schema: any; - submit: any + submit: any; + upload: any; } } diff --git a/src/index.ts b/src/index.ts index 3249a75..746329d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,18 @@ -export { default as Button } from "./components/Button.astro"; -export { default as Form } from "./components/Form.astro"; -export { default as Field } from "./components/Field.astro"; -export { default as MultiSelect } from "./components/MultiSelect.astro"; -export { default as ThemeSwitcher } from "./components/ThemeSwitcher.astro"; -export { default as ColorSwitcher } from "./components/ColorSwitcher.astro"; + +export { default as Button } from "../src/components/Button.astro"; +export { default as ColorSwitcher } from "../src/components/ColorSwitcher.astro"; +export { default as DatePicker } from "../src/components/DatePicker.astro"; +export { default as DateTimePicker } from "../src/components/DateTimePicker.astro"; +export { default as Dropdown } from "../src/components/Dropdown.astro"; +export { default as Field } from "../src/components/Field.astro"; +export { default as FieldRow } from "../src/components/FieldRow.astro"; +export { default as FileUploader } from "../src/components/FileUploader.astro"; +export { default as Form } from "../src/components/Form.astro"; +export { default as MultiSelect } from "../src/components/MultiSelect.astro"; +export { default as OtpField } from "../src/components/OtpField.astro"; +export { default as PasswordField } from "../src/components/PasswordField.astro"; +export { default as ThemeSwitcher } from "../src/components/ThemeSwitcher.astro"; +export { default as TimePicker } from "../src/components/TimePicker.astro"; // Utils export { cn } from "./utils/cn"; \ No newline at end of file diff --git a/src/layouts/ComponentLayout.astro b/src/layouts/ComponentLayout.astro index ff28d8d..6551739 100644 --- a/src/layouts/ComponentLayout.astro +++ b/src/layouts/ComponentLayout.astro @@ -38,6 +38,9 @@ import Base from "./Base.astro";
  • Forms 4
  • +
  • + Date Time Form +
  • OTP Form
  • diff --git a/src/pages/dateform.astro b/src/pages/dateform.astro new file mode 100644 index 0000000..05dfc86 --- /dev/null +++ b/src/pages/dateform.astro @@ -0,0 +1,81 @@ +--- +import Form from "../components/Form.astro"; +import DatePicker from "../components/DatePicker.astro"; +import ComponentLayout from "../layouts/ComponentLayout.astro"; +import TimePicker from "../components/TimePicker.astro"; +import DateTimePicker from "../components/DateTimePicker.astro"; +--- + + +
    + + + + + + +
    + + + +
    + +
    + + diff --git a/src/pages/forms2.astro b/src/pages/forms2.astro index a974e32..42f8eca 100644 --- a/src/pages/forms2.astro +++ b/src/pages/forms2.astro @@ -1,5 +1,6 @@ --- import Field from "../components/Field.astro"; +import FileUploader from "../components/FileUploader.astro"; import Form from "../components/Form.astro"; import MultiSelect from "../components/MultiSelect.astro"; import ComponentLayout from "../layouts/ComponentLayout.astro"; @@ -132,13 +133,21 @@ import ComponentLayout from "../layouts/ComponentLayout.astro"; class="wr:sm:col-span-2" /> - - + f === null || /pdf$/i.test(f.type), - "Resume must be a PDF.", - ) - .refine( - (f) => f === null || f.size <= 5 * 1024 * 1024, - "Max file size is 5MB.", - ) - .optional(); - window.schema = z .object({ firstName: z.string().min(2, "Enter at least 2 characters."), @@ -205,7 +202,7 @@ import ComponentLayout from "../layouts/ComponentLayout.astro"; .number() .positive("Enter a positive number.") .optional(), - // resume: resumeSchema, + images: z.string().min(1, "At least one image is required"), coverLetter: z .string() .max(1000, "Keep it under 1000 characters.") @@ -228,4 +225,8 @@ import ComponentLayout from "../layouts/ComponentLayout.astro"; window.submit = async (data: any, form: any) => { console.log("Application:", data); }; + + window.upload = async (file: any, index: any, allFiles: any) => { + return "/image/file-" + file.name; + }; diff --git a/src/styles/global.css b/src/styles/global.css index 58a5cde..682ee05 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -37,7 +37,7 @@ --color-card: hsl(var(--card)); --color-card-foreground: hsl(var(--card-foreground)); --color-popover: hsl(var(--popover)); - --color-popover-foreground: hsl(var(--popover-foreground)); + --color-popover-foreground: hsl(var(--popover-foreground)); --color-muted: hsl(var(--muted)); --color-muted-foreground: hsl(var(--muted-foreground)); --color-border: hsl(var(--border)); @@ -47,7 +47,7 @@ --color-background-100: var(--background-100); --color-background-200: var(--background-200); --color-background-300: var(--background-300); - --color-background-400: var(--background-400); + --color-background-400: var(--background-400); --color-background-500: var(--background-500); --color-background-600: var(--background-600); --color-background-700: var(--background-700);