-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #26 from aviemet/unset
Adds special [] syntax to unsetCompact
- Loading branch information
Showing
25 changed files
with
496 additions
and
321 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
20.14.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,18 @@ | ||
export { default as useInertiaForm, type UseInertiaFormProps, type NestedObject } from './useInertiaForm' | ||
export { default as useInertiaInput, type UseInertiaInputProps } from './useInertiaInput' | ||
export { default as useDynamicInputs } from './useDynamicInputs' | ||
export { | ||
Form, | ||
useForm, | ||
type HTTPVerb, | ||
type UseFormProps, | ||
type FormProps, | ||
} from './Form' | ||
export { default as NestedFields, type NestedFieldsProps } from './NestedFields' | ||
export { default as DynamicInputs, type DynamicInputsProps } from './Inputs/DynamicInputs' | ||
export { Input, Submit } from './Inputs' | ||
export { | ||
Input, | ||
Submit, | ||
NestedFields, | ||
useDynamicInputs, | ||
type NestedFieldsProps, | ||
DynamicInputs, | ||
type DynamicInputsProps, | ||
} from './Inputs' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from 'react' | ||
|
||
/** | ||
* Creates context with simplified type notations | ||
* Wraps useContext hook in an error check to enforce context context | ||
*/ | ||
export const createContext = <CT extends unknown | null>() => { | ||
const context = React.createContext<CT | undefined>(null) | ||
|
||
const useContext = <T extends CT = CT>() => { | ||
const c = React.useContext<T>( | ||
(context as unknown) as React.Context<T>, | ||
) | ||
if(c === null) { | ||
throw new Error('useContext must be inside a Provider with a value') | ||
} | ||
return c | ||
} | ||
|
||
return [useContext, context.Provider] as const | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { isPlainObject } from 'lodash' | ||
|
||
/** | ||
* Replaces undefined or null values with empty values, | ||
* either empty strings, empty arrays, or empty objects | ||
* Allows using values from the server which may contain | ||
* undefined or null values in a React controlled input | ||
*/ | ||
export const fillEmptyValues = <TForm>(data: TForm) => { | ||
const clone = structuredClone(data ?? {} as TForm) | ||
|
||
for(const key in clone) { | ||
if(isPlainObject(clone[key])) { | ||
// @ts-ignore | ||
clone[key] = fillEmptyValues(clone[key]) | ||
} else if(Array.isArray(clone[key])) { | ||
// @ts-ignore | ||
clone[key] = clone[key].map(el => fillEmptyValues(el)) | ||
} else if(clone[key] === undefined || clone[key] === null) { | ||
// @ts-ignore | ||
clone[key] = '' | ||
} | ||
} | ||
|
||
return clone | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
export { createContext } from './createContext' | ||
export { fillEmptyValues } from './fillEmptyValues' | ||
export { isUnset } from './isUnset' | ||
export { renameObjectWithAttributes } from './renameObjectWithAttributes' | ||
export { unsetCompact } from './unsetCompact' | ||
|
||
/** | ||
* Removes appended string (default of '_attributes') from dot notation | ||
*/ | ||
export const stripAttributes = (str: string, attribute = '_attributes') => | ||
str.replace(new RegExp(`${attribute}\\.`), '.') | ||
|
||
/** | ||
* Ensures passed value is an array | ||
*/ | ||
export const coerceArray = <T = unknown>(arg: T | T[]) => Array.isArray(arg) ? arg : [arg] | ||
|
||
// Added recursion limit to path types to prevent the error: | ||
// "Type instantiation is excessively deep and possibly infinite" | ||
type Increment<A extends any[]> = [0, ...A]; | ||
|
||
type PathImpl<T, K extends keyof T, A extends any[] = []> = | ||
A['length'] extends 5 ? never : | ||
K extends string | ||
? T[K] extends Record<string, any> | ||
? T[K] extends ArrayLike<any> | ||
? K | `${K}.${PathImpl<T[K], Exclude<keyof T[K], keyof any[]>, Increment<A>>}` | ||
: K | `${K}.${PathImpl<T[K], keyof T[K], Increment<A>>}` | ||
: K | ||
: never; | ||
|
||
export type Path<T> = PathImpl<T, keyof T> | Extract<keyof T, string>; | ||
|
||
export type PathValue<T, P extends Path<Required<T>>> = | ||
P extends `${infer K}.${infer Rest}` | ||
? K extends keyof Required<T> | ||
? Rest extends Path<Required<T>[K]> | ||
? PathValue<Required<T>[K], Rest> | ||
: never | ||
: never | ||
: P extends keyof Required<T> | ||
? Required<T>[P] | ||
: never; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { isEmpty } from 'lodash' | ||
|
||
/** | ||
* Returns whether a value should be considered empty in the context of a form input | ||
*/ | ||
export const isUnset = (v: any) => { | ||
if(typeof v === 'string') { | ||
return v === '' | ||
} | ||
|
||
if(typeof v === 'number') { | ||
return v === 0 ? false : !Boolean(v) | ||
} | ||
|
||
return isEmpty(v) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { isPlainObject } from 'lodash' | ||
import { NestedObject } from '../useInertiaForm' | ||
|
||
/** | ||
* Append string (default of '_attributes') to keys of nested records | ||
*/ | ||
export const renameObjectWithAttributes = <T>(data: T, str = '_attributes') => { | ||
const clone = structuredClone(data) | ||
|
||
// Start at one level deep | ||
Object.values(clone).forEach(value => { | ||
if(isPlainObject(value)){ | ||
recursiveAppendString(value, str) | ||
} | ||
}) | ||
return clone | ||
} | ||
|
||
const recursiveAppendString = (data: NestedObject, str) => { | ||
Object.entries(data).forEach(([key, value]) => { | ||
if(isPlainObject(value)) { | ||
renameKey(data, key, `${key}${str}`) | ||
// @ts-ignore - Can't figure out how to type arbitrarily deep nested objects | ||
recursiveAppendString(value, str) | ||
} else if(Array.isArray(value)) { | ||
renameKey(data, key, `${key}${str}`) | ||
} | ||
}) | ||
} | ||
|
||
const renameKey = (obj, oldKey, newKey) => { | ||
if(oldKey !== newKey) { | ||
obj[newKey] = obj[oldKey] | ||
delete obj[oldKey] | ||
} | ||
} |
Oops, something went wrong.