Skip to content
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
2 changes: 0 additions & 2 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
"prettier": "^2.7.1",
"semver": "7.5.2",
"semver-diff": "^3.1.1",
"temp": "^0.9.4",
"tslib": "^2.6.2"
},
"devDependencies": {
Expand All @@ -90,7 +89,6 @@
"@types/pluralize": "^0.0.29",
"@types/prettier": "^2.7.3",
"@types/semver": "^7.5.8",
"@types/temp": "^0.9.1",
"@vitest/ui": "^2.1.8",
"tsup": "^6.7.0",
"typescript": "^5.8.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import {
import inquirer from "inquirer";
import { join } from "path";
import { plural } from "pluralize";
import temp from "temp";
import { getCommandRootDir } from "./get-command-root-dir";
import { mkdtempSync } from "fs";
import { tmpdir } from "os";

export const defaultActions = ["list", "create", "edit", "show"];

Expand Down Expand Up @@ -134,9 +135,6 @@ export const createResources = async (
}
moveSync(tempDir, destinationResourcePath, moveSyncOptions);

// clear temp dir
temp.cleanupSync();

// if use Next.js, generate page files. This makes easier to use the resource
if (isNextJs) {
generateNextJsPages(
Expand Down Expand Up @@ -182,8 +180,7 @@ export const createResources = async (
};

const generateTempDir = (): string => {
temp.track();
return temp.mkdirSync("resource");
return mkdtempSync(join(tmpdir(), "resource-"));
};

/**
Expand Down
30 changes: 24 additions & 6 deletions packages/core/src/hooks/i18n/useTranslate.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { useContext, useMemo } from "react";

import { I18nContext } from "@contexts/i18n";
import type { UseTranslationProps } from "./useTranslation";

/**
* If you need to translate the texts in your own components, refine provides the `useTranslate` hook.
* It returns the translate method from `i18nProvider` under the hood.
*
* @see {@link https://refine.dev/docs/api-reference/core/hooks/translate/useTranslate} for more details.
*/
export const useTranslate = () => {
export const useTranslate = ({ ns }: UseTranslationProps = {}) => {
const { i18nProvider } = useContext(I18nContext);

const fn = useMemo(() => {
Expand All @@ -21,20 +22,37 @@ export const useTranslate = () => {

function translate(
key: string,
options?: string | any,
defaultMessage?: string,
_options?: string | any,
_defaultMessage?: string,
) {
let options = _options;
let defaultMessage = _defaultMessage;

if (typeof options === "string" && defaultMessage === undefined) {
defaultMessage = options;

if (ns) {
options = { ns };
} else {
options = undefined;
}
}

if (ns && options && typeof options !== "string") {
options = { ns, ...options };
}

return (
i18nProvider?.translate(key, options, defaultMessage) ??
defaultMessage ??
(typeof options === "string" && typeof defaultMessage === "undefined"
? options
(typeof _options === "string" && typeof _defaultMessage === "undefined"
? _options
: key)
);
}

return translate;
}, [i18nProvider]);
}, [i18nProvider, ns]);

return fn;
};
8 changes: 6 additions & 2 deletions packages/core/src/hooks/i18n/useTranslation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { useGetLocale } from "./useGetLocale";
import { useSetLocale } from "./useSetLocale";
import { useTranslate } from "./useTranslate";

export interface UseTranslationProps {
ns?: string | string[];
}

/**
* It combines `useTranslate`, `useSetLocale` and `useGetLocale` hooks for a better developer experience.
* It returns `i18nProvider` methods under the hood.
Expand All @@ -11,8 +15,8 @@ import { useTranslate } from "./useTranslate";
*
* @see {@link https://refine.dev/docs/i18n/i18n-provider/} for more details.
*/
export const useTranslation = () => {
const translate = useTranslate();
export const useTranslation = ({ ns }: UseTranslationProps = {}) => {
const translate = useTranslate({ ns });
const changeLocale = useSetLocale();
const getLocale = useGetLocale();

Expand Down
30 changes: 10 additions & 20 deletions packages/react-hook-form/src/useForm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ export const useForm = <
watch,
setValue,
getValues,
reset,
handleSubmit: handleSubmitReactHookForm,
setError,
formState: { dirtyFields },
Expand Down Expand Up @@ -253,39 +254,28 @@ export const useForm = <
});
};

// On query load, attempt a first sync after registration effects run.
// On query load, reset the form with server data natively.
// This ensures useFieldArray and other RHF internals are properly initialized.
const initialLoadRef = React.useRef(true);
useEffect(() => {
const data = query?.data?.data;
if (!data) {
queryDataRef.current = undefined;
syncedFieldsRef.current = new Set();
mountedFieldsRef.current = new Set();
initialLoadRef.current = true;
return;
}

let isActive = true;

const applyQueryValues = () => {
if (!isActive) return;

applyValuesToFields(getRegisteredFields(), data, false);
};

queryDataRef.current = data;
syncedFieldsRef.current = new Set();
mountedFieldsRef.current = getMountedFields();

// defer until after field registration effects
if (typeof queueMicrotask === "function") {
queueMicrotask(applyQueryValues);
} else {
Promise.resolve().then(applyQueryValues);
if (initialLoadRef.current) {
initialLoadRef.current = false;
syncedFieldsRef.current = new Set();
reset(data as unknown as TVariables, { keepDirtyValues: true });
}

return () => {
isActive = false;
};
}, [query?.data, setValue, getValues]);
}, [query?.data, reset, getValues]);

// Re-sync when new fields register; do not override user edits.
useEffect(() => {
Expand Down
40 changes: 25 additions & 15 deletions packages/react-router/src/use-document-title.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
import { useTranslate } from "@refinedev/core";
import { useEffect } from "react";
import { useTranslate, type UseTranslationProps } from "@refinedev/core";
import { useCallback, useEffect } from "react";

type Title = string | { i18nKey: string };

export const useDocumentTitle = (title?: Title) => {
const translate = useTranslate();
interface useDocumentTitleOptions {
ns?: UseTranslationProps["ns"];

defaultTitle?: string;
}

export const useDocumentTitle = (
title?: Title,
options?: useDocumentTitleOptions,
) => {
const translate = useTranslate({ ns: options?.ns });

const getTitle = useCallback(
(title: Title) => {
const key = typeof title === "string" ? title : title.i18nKey;

return translate(key, options?.defaultTitle);
},
[translate, options?.defaultTitle],
);

useEffect(() => {
if (!title) return;

if (typeof title === "string") {
document.title = translate(title);
} else {
document.title = translate(title.i18nKey);
}
}, [title]);
document.title = getTitle(title);
}, [title, getTitle]);

return (title: Title) => {
if (typeof title === "string") {
document.title = translate(title);
} else {
document.title = translate(title.i18nKey);
}
document.title = getTitle(title);
};
};