sera-components 1.4.7 → 1.6.0

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.
@@ -1,4 +1,6 @@
1
1
  import { DisplayInterface } from '.';
2
+ export declare function formatDate(locale: Intl.Locale, value: Date): string;
3
+ export declare function formatDateTime(locale: Intl.Locale, value: Date, withSeconds?: boolean): string;
2
4
  export declare const DateTimeDisplay: ({ value }: DisplayInterface<Date>) => import("react/jsx-runtime").JSX.Element;
3
5
  export declare const DateDisplay: ({ value }: DisplayInterface<Date>) => import("react/jsx-runtime").JSX.Element;
4
6
  export declare const DateTimeHideTimeDisplay: ({ value }: DisplayInterface<Date>) => import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { DisplayInterface } from '.';
2
- export declare const EnumDisplay: ({ nestedProperty, property, value, }: DisplayInterface<any>) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const EnumDisplay: ({ property, value }: DisplayInterface<any>) => import("react/jsx-runtime").JSX.Element;
@@ -1,10 +1,9 @@
1
- import { DataProperty, DataType, DB, ObjectProperty } from 'sera-db';
1
+ import { DataProperty, DataType, DB, ObjectProperty, NestedProperty } from 'sera-db';
2
2
  import { DateDisplay, DateTimeDisplay, DateTimeHideTimeDisplay } from './DateTimeDisplay';
3
3
  export { SingleForeignKeyDisplay, MultiForeignKeyDisplay } from './ForeignKeyDisplay';
4
4
  export type DisplayInterface<T> = {
5
5
  db: DB;
6
- property: DataProperty | ObjectProperty;
7
- nestedProperty?: DataProperty | ObjectProperty;
6
+ property: DataProperty | ObjectProperty | NestedProperty;
8
7
  value: T;
9
8
  };
10
9
  export declare const DataType2DisplayComponent: Partial<Record<DataType, React.ComponentType<DisplayInterface<any>>>>;
@@ -0,0 +1,72 @@
1
+ import { InputInterface } from '.';
2
+ import { DataProperty, ObjectProperty } from 'sera-db';
3
+ export interface ConfirmationLabelProps {
4
+ property: DataProperty | ObjectProperty;
5
+ }
6
+ /**
7
+ * A component that renders a confirmation label with "Confirm" prefix before the property label.
8
+ *
9
+ * This component displays a localized "Confirm" text followed by the property's multilingual label.
10
+ * Commonly used in forms where users need to confirm a value (e.g., "Confirm Password").
11
+ *
12
+ * @param props - The component props
13
+ * @param props.property - The data property or object property containing the label to display
14
+ *
15
+ * @returns A Text component showing "Confirm {property.label}" in the current locale
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * const passwordProperty = {
20
+ * name: "password",
21
+ * label: {
22
+ * lang: "en",
23
+ * lang2value: {
24
+ * en: "Password",
25
+ * vi: "Mật Khẩu"
26
+ * }
27
+ * }
28
+ * };
29
+ *
30
+ * <ConfirmationLabel property={passwordProperty} />
31
+ * // Renders: "Confirm Password" (in English)
32
+ * // Or: "Xác Nhận Mật Khẩu" (in Vietnamese)
33
+ * ```
34
+ */
35
+ export declare const ConfirmationLabel: ({ property }: ConfirmationLabelProps) => import("react/jsx-runtime").JSX.Element;
36
+ /**
37
+ * A confirmation input component that validates matching values against a target field.
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * // In a form field group with custom onChange to track validation state:
42
+ * const [passwordConfirmed, setPasswordConfirmed] = useState(false);
43
+ *
44
+ * {
45
+ * name: "Security Information",
46
+ * fields: [
47
+ * ["password"],
48
+ * [{
49
+ * prop: "password",
50
+ * args: {
51
+ * input: ConfirmationInput,
52
+ * onChange: (value) => {
53
+ * // Track validation state - onChange is called on every change
54
+ * // so you can lift the error state to the parent component
55
+ * setPasswordConfirmed(value === targetPassword);
56
+ * }
57
+ * }
58
+ * }]
59
+ * ]
60
+ * }
61
+ * ```
62
+ *
63
+ * The component:
64
+ * - Uses the `value` prop as the target value to match against
65
+ * - Maintains local state for the confirmation input value
66
+ * - Only shows "Values do not match" error after the field is touched
67
+ * - Calls `onChange` on every keystroke, allowing parent to lift validation errors
68
+ * - The parent can compare the confirmation value with the target to track validation state
69
+ * - Resets when the target value changes (e.g., when switching between records)
70
+ * - Delegates to the appropriate input component based on property constraints
71
+ */
72
+ export declare const ConfirmationInput: React.FC<InputInterface<string>>;
@@ -3,3 +3,7 @@ export declare const DateRangeInput: React.FC<InputInterface<{
3
3
  start?: Date;
4
4
  end?: Date;
5
5
  } | undefined>>;
6
+ export declare const DateTimeRangeInput: React.FC<InputInterface<{
7
+ start?: Date;
8
+ end?: Date;
9
+ } | undefined>>;
@@ -0,0 +1,4 @@
1
+ import { InputInterface } from '.';
2
+ type EnumValue = string | number;
3
+ export declare const EnumInput: React.FC<InputInterface<EnumValue | undefined>>;
4
+ export {};
@@ -3,10 +3,10 @@ import { Record } from 'sera-db';
3
3
  export declare const SingleForeignKeyInput: (<T>(_props: InputInterface<T>) => import("react/jsx-runtime").JSX.Element) & {
4
4
  displayName: string;
5
5
  };
6
- export declare const MultiForeignKeyInput: (<ID extends string | number>({ db, property, value: recordIds, onChange, }: InputInterface<ID[]>) => import("react/jsx-runtime").JSX.Element) & {
6
+ export declare const MultiForeignKeyInput: (<ID extends string | number>({ db, property, value: recordIds, onChange, freeze, }: InputInterface<ID[]>) => import("react/jsx-runtime").JSX.Element) & {
7
7
  displayName: string;
8
8
  };
9
- export declare const SearchInput: <ID extends string | number, R extends Record<ID>>({ name, data, onSelect, renderOption, isIdInteger, query, setQuery, }: {
9
+ export declare const SearchInput: <ID extends string | number, R extends Record<ID>>({ name, data, onSelect, renderOption, isIdInteger, query, setQuery, freeze, }: {
10
10
  name?: string;
11
11
  query: string;
12
12
  setQuery: (query: string) => void;
@@ -14,9 +14,11 @@ export declare const SearchInput: <ID extends string | number, R extends Record<
14
14
  data: R[];
15
15
  renderOption: (record: R) => React.ReactNode;
16
16
  isIdInteger?: boolean;
17
+ freeze?: boolean;
17
18
  }) => import("react/jsx-runtime").JSX.Element;
18
- export declare const CardList: <R>({ items, onDelete, render, }: {
19
+ export declare const CardList: <R>({ items, onDelete, render, freeze, }: {
19
20
  items: R[];
20
21
  onDelete: (value: R) => void;
21
22
  render: (value: R) => React.ReactNode;
23
+ freeze?: boolean;
22
24
  }) => import("react/jsx-runtime").JSX.Element | undefined;
@@ -9,5 +9,6 @@ export interface PhoneNumberInputProps {
9
9
  };
10
10
  }) => void;
11
11
  error?: boolean | React.ReactNode;
12
+ disabled?: boolean;
12
13
  }
13
14
  export declare const PhoneNumberInput: React.FC<PhoneNumberInputProps>;
@@ -1,28 +1,32 @@
1
- import { DataProperty, DataType, DB, ObjectProperty } from 'sera-db';
1
+ import { DataProperty, DataType, DB, ObjectProperty, NestedProperty } from 'sera-db';
2
2
  import { BooleanInput } from './BooleanInput';
3
3
  import { NumberInput } from './NumberInput';
4
4
  import { TextInput } from './TextInput';
5
5
  import { DateInput } from './DateInput';
6
+ import { EnumInput } from './EnumInput';
7
+ import { ConfirmationInput, ConfirmationLabel } from './ConfirmationInput';
6
8
  export { SingleForeignKeyInput, MultiForeignKeyInput } from './ForeignKeyInput';
7
- export { DateRangeInput } from './DateRangeInput';
9
+ export { DateRangeInput, DateTimeRangeInput } from './DateRangeInput';
8
10
  /**
9
11
  * Interface for input components in forms
10
12
  * @interface InputInterface
11
13
  * @template T - The type of the input value
12
- * @property {DataProperty | ObjectProperty} property - The property being edited
14
+ * @property {DataProperty | ObjectProperty | NestedProperty} property - The property being edited
13
15
  * @property {any} value - The current value of the input
14
16
  * @property {function} onChange - Callback function triggered when input value changes
15
17
  * @property {boolean | string} [error] - If the type is boolean it will be error, if there is a string message it should display that message
18
+ * @property {boolean} [freeze = false] - Whether the input is available for editing
16
19
  */
17
20
  export type InputInterface<T> = {
18
21
  db: DB;
19
- property: DataProperty | ObjectProperty;
22
+ property: DataProperty | ObjectProperty | NestedProperty;
20
23
  value: T;
21
24
  onChange: (value: T) => void;
22
25
  error?: boolean | string;
26
+ freeze?: boolean;
23
27
  };
24
28
  /**
25
29
  * Mapping of data types to their corresponding input components
26
30
  */
27
31
  export declare const DataType2InputComponent: Partial<Record<DataType, React.FC<InputInterface<any>>>>;
28
- export { NumberInput, BooleanInput, TextInput, DateInput };
32
+ export { NumberInput, BooleanInput, TextInput, DateInput, EnumInput, ConfirmationInput, ConfirmationLabel };
@@ -1,17 +1,26 @@
1
- import { DraftRecord, GenericRecord, MultiLingualString, Schema, SchemaType, Table } from 'sera-db';
1
+ import { PropertyNames, DraftRecord, GenericRecord, Schema, SchemaType, Table, NestedProperty } from 'sera-db';
2
+ import { InputInterface } from '../data/inputs';
2
3
  import { FormItemLayout } from './FormItem';
3
- export interface CustomField {
4
- name: string;
5
- label: MultiLingualString;
6
- description?: MultiLingualString;
4
+ interface FieldArgs<R, DR> {
5
+ label?: React.ReactNode;
6
+ input?: React.ComponentType<InputInterface<any>>;
7
+ freeze?: boolean;
8
+ visible?: (record: R | DR) => boolean;
9
+ onChange?: (value: any) => void;
7
10
  }
8
- export interface FieldGroup<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends keyof R, F extends keyof DR, ST extends SchemaType<ID, R, DR, PF, F>> {
11
+ export interface FieldGroup<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>> {
9
12
  name?: string;
10
- fields: ST["allProperties"][][];
13
+ fields: (ST["allProperties"] | {
14
+ prop: ST["allProperties"];
15
+ args?: FieldArgs<R, DR>;
16
+ } | NestedProperty | {
17
+ prop: NestedProperty;
18
+ args?: FieldArgs<R, DR>;
19
+ } | ((store: Table<ID, R, DR>, record: R | DR) => React.ReactNode))[][];
11
20
  }
12
- export interface SeraFormProps<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends keyof R, F extends keyof DR, ST extends SchemaType<ID, R, DR, PF, F>> {
21
+ export interface SeraFormProps<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>> {
13
22
  schema: Schema<ID, R, DR, PF, F, ST>;
14
- store: Table<ST["id"], ST["cls"], ST["draftCls"]>;
23
+ store: Table<ID, R, DR>;
15
24
  fieldGroups: FieldGroup<ID, R, DR, PF, F, ST>[];
16
25
  layout?: FormItemLayout;
17
26
  actions: {
@@ -58,4 +67,5 @@ export interface SeraFormProps<ID extends string | number, R extends GenericReco
58
67
  * />
59
68
  * ```
60
69
  */
61
- export declare const SeraForm: <ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends keyof R, F extends keyof DR, ST extends SchemaType<ID, R, DR, PF, F>>(props: SeraFormProps<ID, R, DR, PF, F, ST>) => import("react/jsx-runtime").JSX.Element;
70
+ export declare const SeraForm: <ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>>(props: SeraFormProps<ID, R, DR, PF, F, ST>) => import("react/jsx-runtime").JSX.Element;
71
+ export {};
@@ -1,4 +1,4 @@
1
- import { DataProperty, DraftRecord, GenericRecord, ObjectProperty, Table, validators } from 'sera-db';
1
+ import { DataProperty, DB, DraftRecord, GenericRecord, ObjectProperty, Table, NestedProperty } from 'sera-db';
2
2
  import { InputInterface } from '../data/inputs';
3
3
  export interface FormItemHorizontalLayout {
4
4
  type: "horizontal";
@@ -14,17 +14,33 @@ export type FormItemLayout = FormItemHorizontalLayout | FormItemVerticalLayout;
14
14
  export interface FormItemProps<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>> {
15
15
  store: Table<ID, R, DR>;
16
16
  record: R | DR;
17
- property: DataProperty | ObjectProperty;
17
+ property: DataProperty | ObjectProperty | NestedProperty;
18
18
  InputComponent: React.FC<InputInterface<any>> | React.ComponentType<InputInterface<any>>;
19
- validator: validators.ValueValidator;
20
19
  layout?: FormItemLayout;
20
+ freeze?: boolean;
21
+ label?: React.ReactNode;
22
+ onChange?: (value: any) => void;
23
+ visible?: (record: R | DR) => boolean;
21
24
  }
25
+ export declare const DEFAULT_LAYOUT: FormItemVerticalLayout;
22
26
  /**
23
27
  * FormItem component for creating form elements with labels, tooltips and layout options.
24
28
  *
25
29
  * Supports both horizontal and vertical layouts. In horizontal layout, the label and input are placed side by side in a grid.
26
30
  * In vertical layout, the label is positioned above the input using Mantine's Input.Wrapper.
27
31
  */
28
- export declare const FormItem: (<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>>({ store, record, property, layout, InputComponent, validator, }: FormItemProps<ID, R, DR>) => import("react/jsx-runtime").JSX.Element) & {
32
+ export declare const FormItem: (<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>>({ store, record, property, layout, InputComponent, freeze, label, onChange, visible, }: FormItemProps<ID, R, DR>) => import("react/jsx-runtime").JSX.Element) & {
29
33
  displayName: string;
30
34
  };
35
+ export declare function FormItemInner({ db, layout, property, InputComponent, freeze, value, error, label, onChange, }: {
36
+ db: DB;
37
+ layout: FormItemLayout;
38
+ property: DataProperty | ObjectProperty | NestedProperty;
39
+ InputComponent: React.FC<InputInterface<any>> | React.ComponentType<InputInterface<any>>;
40
+ freeze: boolean;
41
+ value: any;
42
+ error: string | undefined;
43
+ label?: React.ReactNode;
44
+ onChange: (value: any) => void;
45
+ }): import("react/jsx-runtime").JSX.Element;
46
+ export declare function isHorizontalLayout(layout: FormItemLayout): layout is FormItemHorizontalLayout;