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

replaced "hotscript" types with typescript types and removed hotscript dependency #9863

Open
wants to merge 1 commit into
base: next
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
3 changes: 1 addition & 2 deletions packages/ra-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,11 @@
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
"eventemitter3": "^5.0.1",
"hotscript": "^1.0.12",
"inflection": "^3.0.0",
"jsonexport": "^3.2.0",
"lodash": "~4.17.5",
"query-string": "^9.0.0",
"react-is": "^18.2.0"
},
"gitHead": "587df4c27bfcec4a756df4f95e5fc14728dfc0d7"
}
}
34 changes: 16 additions & 18 deletions packages/ra-core/src/util/useFieldValue.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import get from 'lodash/get';
import { Call, Objects } from 'hotscript';
import { useRecordContext } from '../controller';
import { useSourceContext } from '../core';

Expand All @@ -18,30 +17,29 @@ import { useSourceContext } from '../core';
* }
*/
export const useFieldValue = <
RecordType extends Record<string, any> = Record<string, any>
RecordType extends Record<string, any> = Record<string, any>
>(
params: UseFieldValueOptions<RecordType>
params: UseFieldValueOptions<RecordType>
) => {
const { defaultValue, source } = params;
const sourceContext = useSourceContext();
const record = useRecordContext<RecordType>(params);
const { defaultValue, source } = params;
const sourceContext = useSourceContext();
const record = useRecordContext<RecordType>(params);

return get(
record,
sourceContext?.getSource(source) ?? source,
defaultValue
);
return get(
record,
sourceContext?.getSource(source) ?? source,
defaultValue
);
};

export interface UseFieldValueOptions<
RecordType extends Record<string, any> = Record<string, any>
RecordType extends Record<string, any> = Record<string, any>
> {
// FIXME: Find a way to throw a type error when defaultValue is not of RecordType[Source] type
defaultValue?: any;
source: Call<Objects.AllPaths, RecordType> extends never
? AnyString
: Call<Objects.AllPaths, RecordType>;
record?: RecordType;
// FIXME: Find a way to throw a type error when defaultValue is not of RecordType[Source] type
defaultValue?: any;

source?: keyof RecordType extends never ? AnyString : keyof RecordType;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keyof is not enough to handle deep path fields and arrays. The issue suggested using FieldPath from react-hook-form

record?: RecordType;
}

type AnyString = string & {};
3 changes: 1 addition & 2 deletions packages/ra-ui-materialui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
"clsx": "^2.1.1",
"css-mediaquery": "^0.1.2",
"dompurify": "^2.4.3",
"hotscript": "^1.0.12",
"inflection": "^3.0.0",
"jsonexport": "^3.2.0",
"lodash": "~4.17.5",
Expand All @@ -78,4 +77,4 @@
"react-transition-group": "^4.4.5"
},
"gitHead": "587df4c27bfcec4a756df4f95e5fc14728dfc0d7"
}
}
173 changes: 85 additions & 88 deletions packages/ra-ui-materialui/src/field/FileField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { styled } from '@mui/material/styles';
import get from 'lodash/get';
import Typography from '@mui/material/Typography';
import { useFieldValue, useTranslate } from 'ra-core';
import { Call, Objects } from 'hotscript';

import { sanitizeFieldRestProps } from './sanitizeFieldRestProps';
import { FieldProps } from './types';
Expand All @@ -24,116 +23,114 @@ import { Link } from '@mui/material';
* </div>
*/
export const FileField = <
RecordType extends Record<string, any> = Record<string, any>
RecordType extends Record<string, any> = Record<string, any>
>(
props: FileFieldProps<RecordType>
props: FileFieldProps<RecordType>
) => {
const {
className,
emptyText,
title,
src,
target,
download,
ping,
rel,
...rest
} = props;
const sourceValue = useFieldValue(props);
const titleValue =
useFieldValue({
...props,
// @ts-ignore We ignore here because title might be a custom label or undefined instead of a field name
source: title,
})?.toString() ?? title;
const translate = useTranslate();
const {
className,
emptyText,
title,
src,
target,
download,
ping,
rel,
...rest
} = props;
const sourceValue = useFieldValue(props);
const titleValue =
useFieldValue({
...props,
// @ts-ignore We ignore here because title might be a custom label or undefined instead of a field name
source: title,
})?.toString() ?? title;
const translate = useTranslate();

if (!sourceValue) {
return emptyText ? (
<Typography
component="span"
variant="body2"
className={className}
{...sanitizeFieldRestProps(rest)}
>
{emptyText && translate(emptyText, { _: emptyText })}
</Typography>
) : (
<Root className={className} {...sanitizeFieldRestProps(rest)} />
);
}

if (Array.isArray(sourceValue)) {
return (
<StyledList className={className} {...sanitizeFieldRestProps(rest)}>
{sourceValue.map((file, index) => {
const fileTitleValue = title
? get(file, title, title)
: title;
const srcValue = src ? get(file, src, title) : title;

return (
<li key={index}>
<Link
href={srcValue}
title={fileTitleValue}
target={target}
download={download}
ping={ping}
rel={rel}
variant="body2"
onClick={e => e.stopPropagation()}
>
{fileTitleValue}
</Link>
</li>
);
})}
</StyledList>
);
}
if (!sourceValue) {
return emptyText ? (
<Typography
component="span"
variant="body2"
className={className}
{...sanitizeFieldRestProps(rest)}
>
{emptyText && translate(emptyText, { _: emptyText })}
</Typography>
) : (
<Root className={className} {...sanitizeFieldRestProps(rest)} />
);
}

if (Array.isArray(sourceValue)) {
return (
<Root className={className} {...sanitizeFieldRestProps(rest)}>
<Link
href={sourceValue?.toString()}
title={titleValue}
<StyledList className={className} {...sanitizeFieldRestProps(rest)}>
{sourceValue.map((file, index) => {
const fileTitleValue = title
? get(file, title, title)
: title;
const srcValue = src ? get(file, src, title) : title;

return (
<li key={index}>
<Link
href={srcValue}
title={fileTitleValue}
target={target}
download={download}
ping={ping}
rel={rel}
variant="body2"
>
{titleValue}
</Link>
</Root>
onClick={e => e.stopPropagation()}
>
{fileTitleValue}
</Link>
</li>
);
})}
</StyledList>
);
}

return (
<Root className={className} {...sanitizeFieldRestProps(rest)}>
<Link
href={sourceValue?.toString()}
title={titleValue}
target={target}
download={download}
ping={ping}
rel={rel}
variant="body2"
>
{titleValue}
</Link>
</Root>
);
};

export interface FileFieldProps<
RecordType extends Record<string, any> = Record<string, any>
RecordType extends Record<string, any> = Record<string, any>
> extends FieldProps<RecordType> {
src?: string;
title?: Call<Objects.AllPaths, RecordType> extends never
? AnyString
: Call<Objects.AllPaths, RecordType> | AnyString;
target?: string;
download?: boolean | string;
ping?: string;
rel?: string;
sx?: SxProps;
src?: string;
title?: keyof RecordType extends never ? AnyString : keyof RecordType | AnyString;
target?: string;
download?: boolean | string;
ping?: string;
rel?: string;
sx?: SxProps;
}
type AnyString = string & {};

const PREFIX = 'RaFileField';

const Root = styled('div', {
name: PREFIX,
overridesResolver: (props, styles) => styles.root,
name: PREFIX,
overridesResolver: (props, styles) => styles.root,
})({
display: 'inline-block',
display: 'inline-block',
});

const StyledList = styled('ul')({
display: 'inline-block',
display: 'inline-block',
});
Loading