Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: autocomplete subprops and allow string values for readOnly in resolveData #625

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/core/types/Config.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Fields } from "./Fields";
import { ComponentData, RootData } from "./Data";

import { AsFieldProps, WithId, WithPuckProps } from "./Utils";
import { AsFieldProps, DotBranch, WithId, WithPuckProps } from "./Utils";
import { AppState } from "./AppState";
import { DefaultComponentProps, DefaultRootRenderProps } from "./Props";
import { Permissions } from "./API";
Expand Down Expand Up @@ -33,17 +33,17 @@ export type ComponentConfig<
resolveData?: (
data: DataShape,
params: {
changed: Partial<Record<keyof FieldProps, boolean>>;
changed: Partial<Record<DotBranch<FieldProps>, boolean>>;
lastData: DataShape | null;
}
) =>
| Promise<{
props?: Partial<FieldProps>;
readOnly?: Partial<Record<keyof FieldProps, boolean>>;
readOnly?: Partial<Record<DotBranch<FieldProps>, boolean | string>>;
}>
| {
props?: Partial<FieldProps>;
readOnly?: Partial<Record<keyof FieldProps, boolean>>;
readOnly?: Partial<Record<DotBranch<FieldProps>, boolean | string>>;
};
resolvePermissions?: (
data: DataShape,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/types/Data.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { DefaultComponentProps, DefaultRootFieldProps } from "./Props";
import { AsFieldProps, WithId } from "./Utils";
import { AsFieldProps, DotBranch, WithId } from "./Utils";

export type BaseData<
Props extends { [key: string]: any } = { [key: string]: any }
> = {
readOnly?: Partial<Record<keyof Props, boolean>>;
readOnly?: Partial<Record<DotBranch<Props>, boolean | string>>;
};

export type RootDataWithProps<
Expand Down
4 changes: 2 additions & 2 deletions packages/core/types/Fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export type CustomField<Props extends any = {}> = BaseField & {
id: string;
value: Props;
onChange: (value: Props) => void;
readOnly?: boolean;
readOnly?: boolean | string;
}) => ReactElement;
};

Expand Down Expand Up @@ -136,5 +136,5 @@ export type FieldProps<ValueType = any, F = Field<any>> = {
value: ValueType;
id?: string;
onChange: (value: ValueType, uiState?: Partial<UiState>) => void;
readOnly?: boolean;
readOnly?: boolean | string;
};
50 changes: 50 additions & 0 deletions packages/core/types/Utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,53 @@ export type UserGenerics<
UserAppState: UserAppState;
UserComponentData: UserComponentData;
};

// Helper type to increment depth (tuple length)
type IncrementDepth<D extends any[]> = [...D, any];

// Maximum depth to prevent infinite recursion
type MaxDepth = [any, any, any, any, any]; // Adjust the length to set the maximum depth

// Joins two strings with dot notation
export type DotJoin<A extends string, B extends string> = A extends ""
? B
: `${A}.${B}`;

// Recursively finds all keys of a Record
export type DeepKeys<O extends Record<string, any>> = {
[K in Extract<keyof O, string>]: O[K] extends Record<string, any>
? K | DotJoin<K, DeepKeys<O[K]>>
: K;
}[Extract<keyof O, string>];

/**
* Returns keys of an object in dot notation.
*
* ```
* type Foo: {
* a: {
* b: string;
* c: {
* d: string;
* e: string;
* }
* }
* f: string;
* }
* ```
*
* type Result = DotBranch<Foo> // "a" | "a.b" | "a.c" | "a.c.d" | "a.c.e" | "f"
*/

export type DotBranch<
O extends Record<string, any>,
P extends string = "",
D extends any[] = [],
K extends string = Extract<keyof O, string>
> = D["length"] extends MaxDepth["length"]
? DotJoin<P, K>
: K extends keyof O
? O[K] extends Record<string, any>
? DotBranch<O[K], DotJoin<P, K>, IncrementDepth<D>> | DotJoin<P, K>
: DotJoin<P, K>
: never;
Loading