@maxischmaxi/maxforms-embed 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/FileUpload.d.ts +11 -0
- package/dist/components/FileUpload.d.ts.map +1 -0
- package/dist/components/Form.d.ts +28 -0
- package/dist/components/Form.d.ts.map +1 -0
- package/dist/components/blocks/DividerBlock.d.ts +5 -0
- package/dist/components/blocks/DividerBlock.d.ts.map +1 -0
- package/dist/components/blocks/HeadingBlock.d.ts +10 -0
- package/dist/components/blocks/HeadingBlock.d.ts.map +1 -0
- package/dist/components/blocks/RowBlock.d.ts +13 -0
- package/dist/components/blocks/RowBlock.d.ts.map +1 -0
- package/dist/components/blocks/TextBlock.d.ts +10 -0
- package/dist/components/blocks/TextBlock.d.ts.map +1 -0
- package/dist/components/blocks/index.d.ts +5 -0
- package/dist/components/blocks/index.d.ts.map +1 -0
- package/dist/hooks/useMaxForm.d.ts +53 -0
- package/dist/hooks/useMaxForm.d.ts.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/lib/validation.d.ts +22 -0
- package/dist/lib/validation.d.ts.map +1 -0
- package/dist/maxforms-embed.css +1 -0
- package/dist/maxforms-embed.js +21769 -0
- package/dist/maxforms-embed.js.map +1 -0
- package/dist/maxforms-embed.umd.cjs +73 -0
- package/dist/maxforms-embed.umd.cjs.map +1 -0
- package/dist/types.d.ts +214 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FormField } from '@maxischmaxi/maxforms-api-client';
|
|
2
|
+
export interface FileUploadProps {
|
|
3
|
+
field: FormField;
|
|
4
|
+
formId: string;
|
|
5
|
+
apiKey: string;
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
value: string;
|
|
8
|
+
onChange: (value: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function FileUpload({ field, formId, apiKey, baseUrl, value, onChange, }: FileUploadProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=FileUpload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileUpload.d.ts","sourceRoot":"","sources":["../../src/components/FileUpload.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,SAAS,EACf,MAAM,kCAAkC,CAAC;AAE1C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AASD,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,MAAM,EACN,MAAM,EACN,OAAO,EACP,KAAK,EACL,QAAQ,GACT,EAAE,eAAe,2CAsQjB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { FormProps } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* MaxForms embed form component with Zod validation and React Hook Form.
|
|
5
|
+
*
|
|
6
|
+
* Supports custom rendering for all field types and layout blocks through
|
|
7
|
+
* render props. If no custom renderer is provided, default renderers are used.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* // Basic usage
|
|
12
|
+
* <Form formId="abc123" apiKey="your-api-key" />
|
|
13
|
+
*
|
|
14
|
+
* // With custom renderers
|
|
15
|
+
* <Form
|
|
16
|
+
* formId="abc123"
|
|
17
|
+
* apiKey="your-api-key"
|
|
18
|
+
* renderInput={({ field, register, error }) => (
|
|
19
|
+
* <div>
|
|
20
|
+
* <input {...register(field.name)} className="my-input" />
|
|
21
|
+
* {error && <span className="error">{error.message}</span>}
|
|
22
|
+
* </div>
|
|
23
|
+
* )}
|
|
24
|
+
* />
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function Form({ formId, apiKey, baseUrl, onSubmit, onError, className, renderInput, renderTextarea, renderSelect, renderCheckbox, renderRadio, renderEmail, renderNumber, renderDate, renderFile, renderHeading, renderTextBlock, renderDivider, renderRow, renderSubmit, renderFormError, renderFieldError, renderLoading, renderSuccess, renderFieldWrapper, }: FormProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
//# sourceMappingURL=Form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Form.d.ts","sourceRoot":"","sources":["../../src/components/Form.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAe,MAAM,OAAO,CAAC;AAUpD,OAAO,KAAK,EACV,SAAS,EAIV,MAAM,UAAU,CAAC;AAElB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,IAAI,CAAC,EACnB,MAAM,EACN,MAAM,EACN,OAAO,EACP,QAAQ,EACR,OAAO,EACP,SAAc,EAEd,WAAW,EACX,cAAc,EACd,YAAY,EACZ,cAAc,EACd,WAAW,EACX,WAAW,EACX,YAAY,EACZ,UAAU,EACV,UAAU,EAEV,aAAa,EACb,eAAe,EACf,aAAa,EACb,SAAS,EAET,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,kBAAkB,GACnB,EAAE,SAAS,wTAwRX"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DividerBlock.d.ts","sourceRoot":"","sources":["../../../src/components/blocks/DividerBlock.tsx"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,YAAY,4CAE3B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FormBlock } from '@maxischmaxi/maxforms-api-client';
|
|
2
|
+
export interface HeadingBlockProps {
|
|
3
|
+
block: FormBlock;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Renders a heading block (H1, H2, or H3).
|
|
7
|
+
* The heading level is determined by block.level (defaults to 2).
|
|
8
|
+
*/
|
|
9
|
+
export declare function HeadingBlock({ block }: HeadingBlockProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=HeadingBlock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeadingBlock.d.ts","sourceRoot":"","sources":["../../../src/components/blocks/HeadingBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,SAAS,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,iBAAiB,2CAcxD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { FormBlock } from '@maxischmaxi/maxforms-api-client';
|
|
3
|
+
export interface RowBlockProps {
|
|
4
|
+
block: FormBlock;
|
|
5
|
+
/** Function to render a child block */
|
|
6
|
+
renderChild: (child: FormBlock) => ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Renders a row block with multiple columns.
|
|
10
|
+
* The number of columns is determined by block.columns (defaults to 2).
|
|
11
|
+
*/
|
|
12
|
+
export declare function RowBlock({ block, renderChild }: RowBlockProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=RowBlock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RowBlock.d.ts","sourceRoot":"","sources":["../../../src/components/blocks/RowBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAElE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,CAAC;IACjB,uCAAuC;IACvC,WAAW,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,SAAS,CAAC;CAC9C;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,aAAa,2CAa7D"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FormBlock } from '@maxischmaxi/maxforms-api-client';
|
|
2
|
+
export interface TextBlockProps {
|
|
3
|
+
block: FormBlock;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Renders a text/paragraph block.
|
|
7
|
+
* The content can contain HTML from the rich text editor.
|
|
8
|
+
*/
|
|
9
|
+
export declare function TextBlock({ block }: TextBlockProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=TextBlock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextBlock.d.ts","sourceRoot":"","sources":["../../../src/components/blocks/TextBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,cAAc,2CAgBlD"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { HeadingBlock, type HeadingBlockProps } from './HeadingBlock';
|
|
2
|
+
export { TextBlock, type TextBlockProps } from './TextBlock';
|
|
3
|
+
export { DividerBlock } from './DividerBlock';
|
|
4
|
+
export { RowBlock, type RowBlockProps } from './RowBlock';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/blocks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { UseMaxFormOptions, UseMaxFormReturn } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* A powerful hook for building custom form UIs with MaxForms.
|
|
4
|
+
*
|
|
5
|
+
* This hook provides full access to:
|
|
6
|
+
* - React Hook Form instance for form state management
|
|
7
|
+
* - Zod validation schema built from form field definitions
|
|
8
|
+
* - Form configuration (fields, layout, settings)
|
|
9
|
+
* - Loading, submitting, and success states
|
|
10
|
+
* - Submit and reset actions
|
|
11
|
+
* - Helper functions for accessing fields and errors
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* function MyCustomForm() {
|
|
16
|
+
* const {
|
|
17
|
+
* form,
|
|
18
|
+
* fields,
|
|
19
|
+
* isLoading,
|
|
20
|
+
* isSubmitting,
|
|
21
|
+
* isSuccess,
|
|
22
|
+
* submitForm,
|
|
23
|
+
* getFieldError,
|
|
24
|
+
* settings,
|
|
25
|
+
* } = useMaxForm({
|
|
26
|
+
* formId: "abc123",
|
|
27
|
+
* apiKey: "your-api-key",
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* if (isLoading) return <Spinner />;
|
|
31
|
+
* if (isSuccess) return <p>{settings.successMessage}</p>;
|
|
32
|
+
*
|
|
33
|
+
* return (
|
|
34
|
+
* <form onSubmit={form.handleSubmit(submitForm)}>
|
|
35
|
+
* {fields.map((field) => (
|
|
36
|
+
* <div key={field.id}>
|
|
37
|
+
* <label>{field.label}</label>
|
|
38
|
+
* <input {...form.register(field.name)} />
|
|
39
|
+
* {getFieldError(field.name) && (
|
|
40
|
+
* <span>{getFieldError(field.name)}</span>
|
|
41
|
+
* )}
|
|
42
|
+
* </div>
|
|
43
|
+
* ))}
|
|
44
|
+
* <button disabled={isSubmitting}>
|
|
45
|
+
* {isSubmitting ? "Submitting..." : settings.submitButtonText}
|
|
46
|
+
* </button>
|
|
47
|
+
* </form>
|
|
48
|
+
* );
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function useMaxForm(options: UseMaxFormOptions): UseMaxFormReturn;
|
|
53
|
+
//# sourceMappingURL=useMaxForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMaxForm.d.ts","sourceRoot":"","sources":["../../src/hooks/useMaxForm.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAY,MAAM,UAAU,CAAC;AAoB9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAuMvE"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Form } from './components/Form';
|
|
2
|
+
import { FileUpload, FileUploadProps } from './components/FileUpload';
|
|
3
|
+
import { useMaxForm } from './hooks/useMaxForm';
|
|
4
|
+
export type { FormProps, FormData, FormSettingsData, FieldRenderContext, FileFieldRenderContext, RenderInputFn, RenderTextareaFn, RenderSelectFn, RenderCheckboxFn, RenderRadioFn, RenderEmailFn, RenderNumberFn, RenderDateFn, RenderFileFn, RenderHeadingFn, RenderTextBlockFn, RenderDividerFn, RenderRowFn, RenderSubmitFn, RenderFormErrorFn, RenderFieldErrorFn, RenderLoadingFn, RenderSuccessFn, RenderFieldWrapperFn, SubmitRenderProps, UseMaxFormOptions, UseMaxFormReturn, } from './types';
|
|
5
|
+
export { Form };
|
|
6
|
+
export { FileUpload, type FileUploadProps };
|
|
7
|
+
export { useMaxForm };
|
|
8
|
+
export { HeadingBlock, TextBlock, DividerBlock, RowBlock, } from './components/blocks';
|
|
9
|
+
export { buildFieldSchema, buildFormSchema, validateFormData, } from './lib/validation';
|
|
10
|
+
export interface RenderOptions {
|
|
11
|
+
formId: string;
|
|
12
|
+
/**
|
|
13
|
+
* API key for authenticating with the MaxForms API.
|
|
14
|
+
* Required for all embed requests.
|
|
15
|
+
*/
|
|
16
|
+
apiKey: string;
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
onSubmit?: (data: Record<string, string>) => void;
|
|
19
|
+
onError?: (error: Error) => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Renders a MaxForms form into a DOM element
|
|
23
|
+
* @param selector CSS selector or DOM element
|
|
24
|
+
* @param options Form configuration options
|
|
25
|
+
*/
|
|
26
|
+
export declare function render(selector: string | HTMLElement, options: RenderOptions): void;
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,cAAc,CAAC;AAGtB,YAAY,EACV,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,IAAI,EAAE,CAAC;AAChB,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,CAAC;AAG5C,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,OAAO,EACL,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAG1B,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CACpB,QAAQ,EAAE,MAAM,GAAG,WAAW,EAC9B,OAAO,EAAE,aAAa,GACrB,IAAI,CA0BN"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { FormField } from '@maxischmaxi/maxforms-api-client';
|
|
3
|
+
/**
|
|
4
|
+
* Builds a Zod v4 schema for a single field based on its type and validation rules.
|
|
5
|
+
* Uses Zod v4's `error` parameter for custom error messages.
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildFieldSchema(field: FormField): z.ZodType;
|
|
8
|
+
/**
|
|
9
|
+
* Builds a complete Zod schema for all form fields.
|
|
10
|
+
* The schema uses field.name as keys (matching form data structure).
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildFormSchema(fields: FormField[]): z.ZodObject<Record<string, z.ZodType>>;
|
|
13
|
+
/**
|
|
14
|
+
* Validates form data against a schema and returns formatted errors.
|
|
15
|
+
* Uses Zod v4's safeParse.
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateFormData(schema: z.ZodType, data: Record<string, string>): {
|
|
18
|
+
success: boolean;
|
|
19
|
+
data?: Record<string, string>;
|
|
20
|
+
errors?: Record<string, string>;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,kCAAkC,CAAC;AAE7E;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,CAAC,CAAC,OAAO,CAiC5D;AA0TD;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,EAAE,GAClB,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAQxC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,CAAC,CAAC,OAAO,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAiBA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--maxforms-primary: #4f46e5;--maxforms-primary-hover: #4338ca;--maxforms-error: #dc2626;--maxforms-error-bg: #fef2f2;--maxforms-success: #16a34a;--maxforms-success-bg: #f0fdf4;--maxforms-text: #374151;--maxforms-text-muted: #6b7280;--maxforms-text-light: #9ca3af;--maxforms-bg: #ffffff;--maxforms-bg-muted: #f9fafb;--maxforms-bg-hover: #f3f4f6;--maxforms-border: #d1d5db;--maxforms-border-hover: #9ca3af;--maxforms-radius: .5rem;--maxforms-radius-sm: .25rem;--maxforms-font-size: .875rem;--maxforms-font-size-sm: .75rem;--maxforms-spacing: 1rem;--maxforms-spacing-sm: .5rem}.maxforms-form{display:flex;flex-direction:column;gap:var(--maxforms-spacing);width:100%;font-family:system-ui,-apple-system,sans-serif;font-size:var(--maxforms-font-size);color:var(--maxforms-text)}.maxforms-loading,.maxforms-error,.maxforms-success{padding:var(--maxforms-spacing);border-radius:var(--maxforms-radius);text-align:center}.maxforms-loading{background-color:var(--maxforms-bg-muted);color:var(--maxforms-text-muted)}.maxforms-error{background-color:var(--maxforms-error-bg);color:var(--maxforms-error);border:1px solid var(--maxforms-error)}.maxforms-success{background-color:var(--maxforms-success-bg);color:var(--maxforms-success);border:1px solid var(--maxforms-success)}.maxforms-form-error{padding:var(--maxforms-spacing-sm) var(--maxforms-spacing);background-color:var(--maxforms-error-bg);color:var(--maxforms-error);border:1px solid var(--maxforms-error);border-radius:var(--maxforms-radius);margin-bottom:var(--maxforms-spacing-sm)}.maxforms-form-error p{margin:0}.maxforms-field{display:flex;flex-direction:column;gap:var(--maxforms-spacing-sm)}.maxforms-field-has-error .maxforms-input{border-color:var(--maxforms-error)}.maxforms-label{font-size:var(--maxforms-font-size);font-weight:500;color:var(--maxforms-text)}.maxforms-required{color:var(--maxforms-error);margin-left:.25rem}.maxforms-field-error{font-size:var(--maxforms-font-size-sm);color:var(--maxforms-error)}.maxforms-input{width:100%;padding:.625rem .875rem;font-size:var(--maxforms-font-size);color:var(--maxforms-text);background-color:var(--maxforms-bg);border:1px solid var(--maxforms-border);border-radius:var(--maxforms-radius);transition:border-color .2s ease,box-shadow .2s ease;box-sizing:border-box}.maxforms-input::placeholder{color:var(--maxforms-text-light)}.maxforms-input:hover{border-color:var(--maxforms-border-hover)}.maxforms-input:focus{outline:none;border-color:var(--maxforms-primary);box-shadow:0 0 0 3px #4f46e51a}.maxforms-input:disabled{background-color:var(--maxforms-bg-muted);cursor:not-allowed;opacity:.7}.maxforms-input-error{border-color:var(--maxforms-error)}.maxforms-input-error:focus{border-color:var(--maxforms-error);box-shadow:0 0 0 3px #dc26261a}.maxforms-textarea{min-height:100px;resize:vertical}.maxforms-select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236b7280' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right .75rem center;padding-right:2.5rem}.maxforms-checkbox-group,.maxforms-radio-group{display:flex;flex-direction:column;gap:var(--maxforms-spacing-sm)}.maxforms-checkbox-label,.maxforms-radio-label{display:flex;align-items:center;gap:.5rem;font-size:var(--maxforms-font-size);color:var(--maxforms-text);cursor:pointer}.maxforms-checkbox,.maxforms-radio{width:1rem;height:1rem;margin:0;cursor:pointer;accent-color:var(--maxforms-primary)}.maxforms-checkbox:disabled,.maxforms-radio:disabled{cursor:not-allowed;opacity:.7}.maxforms-submit{padding:.75rem 1.5rem;font-size:var(--maxforms-font-size);font-weight:500;color:#fff;background-color:var(--maxforms-primary);border:none;border-radius:var(--maxforms-radius);cursor:pointer;transition:background-color .2s ease;align-self:flex-start}.maxforms-submit:hover:not(:disabled){background-color:var(--maxforms-primary-hover)}.maxforms-submit:focus{outline:none;box-shadow:0 0 0 3px #4f46e54d}.maxforms-submit:disabled{opacity:.7;cursor:not-allowed}.maxforms-heading{margin:0;font-weight:600;color:var(--maxforms-text);line-height:1.3}.maxforms-h1{font-size:1.875rem}.maxforms-h2{font-size:1.5rem}.maxforms-h3{font-size:1.25rem}.maxforms-text{font-size:var(--maxforms-font-size);color:var(--maxforms-text-muted);line-height:1.6;margin:0}.maxforms-text p{margin:0 0 .5rem}.maxforms-text p:last-child{margin-bottom:0}.maxforms-text a{color:var(--maxforms-primary);text-decoration:underline}.maxforms-text a:hover{color:var(--maxforms-primary-hover)}.maxforms-divider{border:none;border-top:1px solid var(--maxforms-border);margin:var(--maxforms-spacing-sm) 0}.maxforms-row{display:grid;gap:var(--maxforms-spacing)}.maxforms-row-2{grid-template-columns:repeat(2,1fr)}.maxforms-row-3{grid-template-columns:repeat(3,1fr)}.maxforms-row-4{grid-template-columns:repeat(4,1fr)}.maxforms-row-col{min-width:0}@media(max-width:640px){.maxforms-row-2,.maxforms-row-3,.maxforms-row-4{grid-template-columns:1fr}}.maxforms-file-upload{width:100%}.maxforms-file-input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.maxforms-file-dropzone{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:2rem;border:2px dashed var(--maxforms-border);border-radius:var(--maxforms-radius);background-color:var(--maxforms-bg-muted);cursor:pointer;transition:all .2s ease}.maxforms-file-dropzone:hover{border-color:var(--maxforms-border-hover);background-color:var(--maxforms-bg-hover)}.maxforms-file-dropzone:focus{outline:2px solid var(--maxforms-primary);outline-offset:2px}.maxforms-file-dropzone-active{border-color:var(--maxforms-primary);background-color:#4f46e50d}.maxforms-file-dropzone-uploading{cursor:default;pointer-events:none}.maxforms-file-upload-icon{color:var(--maxforms-text-light);margin-bottom:.5rem}.maxforms-file-dropzone-text{font-size:var(--maxforms-font-size);font-weight:500;color:var(--maxforms-text);margin:0}.maxforms-file-dropzone-hint{font-size:var(--maxforms-font-size-sm);color:var(--maxforms-text-muted);margin:.25rem 0 0}.maxforms-file-progress{width:100%;text-align:center}.maxforms-file-progress-bar{width:100%;height:.5rem;background-color:var(--maxforms-bg-hover);border-radius:9999px;overflow:hidden;margin-bottom:.5rem}.maxforms-file-progress-fill{height:100%;background-color:var(--maxforms-primary);transition:width .3s ease}.maxforms-file-progress-text{font-size:var(--maxforms-font-size-sm);color:var(--maxforms-text-muted)}.maxforms-file-uploaded{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;border:1px solid var(--maxforms-border);border-radius:var(--maxforms-radius);background-color:var(--maxforms-bg-muted)}.maxforms-file-info{display:flex;align-items:center;gap:.75rem;min-width:0}.maxforms-file-icon{flex-shrink:0;color:var(--maxforms-text-muted)}.maxforms-file-name{font-size:var(--maxforms-font-size);font-weight:500;color:var(--maxforms-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.maxforms-file-remove{flex-shrink:0;padding:.25rem;border:none;background:none;color:var(--maxforms-text-light);cursor:pointer;border-radius:var(--maxforms-radius-sm);transition:all .2s ease}.maxforms-file-remove:hover{color:var(--maxforms-error);background-color:var(--maxforms-error-bg)}.maxforms-file-error{font-size:var(--maxforms-font-size);color:var(--maxforms-error);margin-top:.5rem}
|