diff --git a/packages/ably/.npmignore b/packages/ably/.npmignore
new file mode 100644
index 0000000..3321cad
--- /dev/null
+++ b/packages/ably/.npmignore
@@ -0,0 +1,11 @@
+node_modules
+.DS_Store
+test
+jest.config.js
+**/*.spec.ts
+**/*.spec.tsx
+**/*.test.ts
+**/*.test.tsx
+tsup.config.ts
+tsconfig.test.json
+tsconfig.declarations.json
\ No newline at end of file
diff --git a/packages/ably/CHANGELOG.md b/packages/ably/CHANGELOG.md
new file mode 100644
index 0000000..4851d04
--- /dev/null
+++ b/packages/ably/CHANGELOG.md
@@ -0,0 +1,93 @@
+# @refinedev/ably
+
+## 4.1.4
+
+### Patch Changes
+
+- [#5425](https://github.com/refinedev/refine/pull/5425) [`190af9fce2`](https://github.com/refinedev/refine/commit/190af9fce292bc46b169e3e121be6bf1c2a939a5) Thanks [@aliemir](https://github.com/aliemir)! - Updated `@refinedev/core` peer dependencies to latest (`^4.46.1`)
+
+## 4.1.3
+
+### Patch Changes
+
+- [#5330](https://github.com/refinedev/refine/pull/5330) [`7c8827b43d`](https://github.com/refinedev/refine/commit/7c8827b43d9e378818be6ee23032925c97ce02d5) Thanks [@BatuhanW](https://github.com/BatuhanW)! - chore: upgrade nock library version to ^13.4.0
+
+## 4.1.2
+
+### Patch Changes
+
+- [#5022](https://github.com/refinedev/refine/pull/5022) [`80513a4e42f`](https://github.com/refinedev/refine/commit/80513a4e42f8dda39e01157643594a9e4c32001b) Thanks [@BatuhanW](https://github.com/BatuhanW)! - chore: update README.md
+
+ - fix grammar errors.
+ - make all README.md files consistent.
+ - add code example code snippets.
+
+## 4.1.1
+
+### Patch Changes
+
+- [#5022](https://github.com/refinedev/refine/pull/5022) [`80513a4e42f`](https://github.com/refinedev/refine/commit/80513a4e42f8dda39e01157643594a9e4c32001b) Thanks [@BatuhanW](https://github.com/BatuhanW)! - chore: update README.md
+
+ - fix grammar errors.
+ - make all README.md files consistent.
+ - add code example code snippets.
+
+## 4.1.0
+
+### Minor Changes
+
+- Thanks [@aliemir](https://github.com/aliemir), [@alicanerdurmaz](https://github.com/alicanerdurmaz), [@batuhanW](https://github.com/batuhanW), [@salihozdemir](https://github.com/salihozdemir), [@yildirayunlu](https://github.com/yildirayunlu), [@recepkutuk](https://github.com/recepkutuk)!
+ **Moving to the `@refinedev` scope ππ**
+
+ Moved to the `@refinedev` scope and updated our packages to use the new scope. From now on, all packages will be published under the `@refinedev` scope with their new names.
+
+ Now, we're also removing the `refine` prefix from all packages. So, the `@pankod/refine-core` package is now `@refinedev/core`, `@pankod/refine-antd` is now `@refinedev/antd`, and so on.
+
+### Patch Changes
+
+## 3.31.0
+
+### Minor Changes
+
+- [#3822](https://github.com/refinedev/refine/pull/3822) [`0baa99ba787`](https://github.com/refinedev/refine/commit/0baa99ba7874394d9d28d0a7b29c082c604258fb) Thanks [@BatuhanW](https://github.com/BatuhanW)! - - refine v4 release announcement added to "postinstall". - refine v4 is released π The new version is 100% backward compatible. You can upgrade to v4 with a single command! See the migration guide here: https://refine.dev/docs/migration-guide/3x-to-4x
+
+## 3.30.0
+
+### Minor Changes
+
+- [#3822](https://github.com/refinedev/refine/pull/3822) [`0baa99ba787`](https://github.com/refinedev/refine/commit/0baa99ba7874394d9d28d0a7b29c082c604258fb) Thanks [@BatuhanW](https://github.com/BatuhanW)! - - refine v4 release announcement added to "postinstall". - refine v4 is released π The new version is 100% backward compatible. You can upgrade to v4 with a single command! See the migration guide here: https://refine.dev/docs/migration-guide/3x-to-4x
+
+## 3.29.0
+
+### Minor Changes
+
+- Update type declaration generation with `tsc` instead of `tsup` for better navigation throughout projects source code.
+
+## 3.28.0
+
+### Minor Changes
+
+- [#2440](https://github.com/refinedev/refine/pull/2440) [`0150dcd070`](https://github.com/refinedev/refine/commit/0150dcd0700253f1c4908e7e5f2e178bb122e9af) Thanks [@aliemir](https://github.com/aliemir)! - Update type declaration generation with `tsc` instead of `tsup` for better navigation throughout projects source code.
+
+## 3.27.0
+
+### Minor Changes
+
+- All of the refine packages have dependencies on the `@pankod/refine-core` package. So far we have managed these dependencies with `peerDependencies` + `dependencies` but this causes issues like #2183. (having more than one @pankod/refine-core version in node_modules and creating different instances)
+
+ Managing as `peerDependencies` + `devDependencies` seems like the best way for now to avoid such issues.
+
+## 3.26.0
+
+### Minor Changes
+
+- [#2217](https://github.com/refinedev/refine/pull/2217) [`b4aae00f77`](https://github.com/refinedev/refine/commit/b4aae00f77a2476d847994db21298ae25e4cf6e5) Thanks [@omeraplak](https://github.com/omeraplak)! - All of the refine packages have dependencies on the `@pankod/refine-core` package. So far we have managed these dependencies with `peerDependencies` + `dependencies` but this causes issues like #2183. (having more than one @pankod/refine-core version in node_modules and creating different instances)
+
+ Managing as `peerDependencies` + `devDependencies` seems like the best way for now to avoid such issues.
+
+## 3.22.2
+
+### Patch Changes
+
+- Updated dependencies [[`2deb19babf`](https://github.com/refinedev/refine/commit/2deb19babfc6db5b00b111ec29aa5ece4c371bbc)]:
+ - @pankod/refine-core@3.23.2
diff --git a/packages/ably/LICENSE b/packages/ably/LICENSE
new file mode 100644
index 0000000..1028bea
--- /dev/null
+++ b/packages/ably/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Refine Development Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/packages/ably/README.md b/packages/ably/README.md
new file mode 100644
index 0000000..c7409d7
--- /dev/null
+++ b/packages/ably/README.md
@@ -0,0 +1,74 @@
+
refine is an open-source, headless React framework for developers building enterprise internal tools, admin panels, dashboards, B2B applications.
+
+
+
+It eliminates repetitive tasks in CRUD operations and provides industry-standard solutions for critical project components like **authentication**, **access control**, **routing**, **networking**, **state management**, and **i18n**.
+
+
+
+# Airtable integration for refine
+
+[Airtable](https://www.airtable.com/) is a cloud-based platform for creating and sharing relational databases.
+
+[refine](https://refine.dev/) is **headless by design**, offering unlimited styling and customization options. Moreover, refine ships with ready-made integrations for [Ant Design](https://ant.design/), [Material UI](https://mui.com/material-ui/getting-started/overview/), [Mantine](https://mantine.dev/), and [Chakra UI](https://chakra-ui.com/) for convenience.
+
+refine has connectors for 15+ backend services, including REST API, [GraphQL](https://graphql.org/), and popular services like [Airtable](https://www.airtable.com/), [Strapi](https://strapi.io/), [Supabase](https://supabase.com/), [Firebase](https://firebase.google.com/), and [NestJS](https://nestjs.com/).
+
+## Installation & Usage
+
+```
+npm install @refinedev/airtable
+```
+
+```tsx
+import dataProvider from "@refinedev/airtable";
+
+const App = () => {
+ return (
+
+ {/* ... */}
+
+ );
+};
+```
+
+## Documentation
+
+- For more detailed information and usage, refer to the [refine data provider documentation](https://refine.dev/docs/core/providers/data-provider).
+- [Refer to refine Airtable example](https://refine.dev/docs/examples/data-provider/airtable/).
+- [Refer to documentation for more info about refine](https://refine.dev/docs/).
+- [Step up to refine tutorials](https://refine.dev/docs/tutorial/introduction/index/).
diff --git a/packages/airtable/jest.config.js b/packages/airtable/jest.config.js
new file mode 100644
index 0000000..08c8ff4
--- /dev/null
+++ b/packages/airtable/jest.config.js
@@ -0,0 +1,7 @@
+module.exports = {
+ preset: "ts-jest",
+ rootDir: "./",
+ displayName: "airtable",
+ setupFilesAfterEnv: ["/test/jest.setup.js"],
+ testEnvironment: "jsdom",
+};
diff --git a/packages/airtable/package.json b/packages/airtable/package.json
new file mode 100644
index 0000000..a7fb0a8
--- /dev/null
+++ b/packages/airtable/package.json
@@ -0,0 +1,54 @@
+{
+ "name": "@refinedev/airtable",
+ "description": "refine Airtable data provider. refine is a React-based framework for building internal tools, rapidly. It ships with Ant Design System, an enterprise-level UI toolkit.",
+ "version": "4.4.6",
+ "license": "MIT",
+ "main": "dist/index.js",
+ "typings": "dist/index.d.ts",
+ "private": false,
+ "files": [
+ "dist",
+ "src",
+ "./refine.config.js"
+ ],
+ "engines": {
+ "node": ">=10"
+ },
+ "scripts": {
+ "start": "tsup --watch --format esm,cjs,iife --legacy-output",
+ "build": "tsup --format esm,cjs,iife --minify --legacy-output",
+ "test": "jest --passWithNoTests --runInBand",
+ "prepare": "npm run build"
+ },
+ "author": "refine",
+ "module": "dist/esm/index.js",
+ "devDependencies": {
+ "@refinedev/core": "4.46.2",
+ "@esbuild-plugins/node-resolve": "^0.1.4",
+ "@types/jest": "^29.2.4",
+ "jest": "^29.3.1",
+ "jest-environment-jsdom": "^29.3.1",
+ "nock": "^13.4.0",
+ "ts-jest": "^29.0.3",
+ "tslib": "^2.3.1",
+ "tsup": "^6.7.0"
+ },
+ "dependencies": {
+ "@qualifyze/airtable-formulator": "^1.0.1",
+ "airtable": "^0.11.1",
+ "asyncairtable": "^2.1.0",
+ "query-string": "^7.1.1"
+ },
+ "peerDependencies": {
+ "@refinedev/core": "^4.46.1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/refinedev/refine.git",
+ "directory": "packages/airtable"
+ },
+ "gitHead": "829f5a516f98c06f666d6be3e6e6099c75c07719",
+ "publishConfig": {
+ "access": "public"
+ }
+}
diff --git a/packages/airtable/refine.config.js b/packages/airtable/refine.config.js
new file mode 100644
index 0000000..f3faa14
--- /dev/null
+++ b/packages/airtable/refine.config.js
@@ -0,0 +1,80 @@
+/** @type {import('@refinedev/cli').RefineConfig} */
+
+module.exports = {
+ group: "Data Provider",
+ swizzle: {
+ items: [
+ {
+ label: "Data Provider",
+ requiredPackages: [
+ "@qualifyze/airtable-formulator@1.0.1",
+ "airtable@0.11.1",
+ "asyncairtable@2.1.0",
+ "query-string@7.1.1",
+ ],
+ files: [
+ {
+ src: "./src/index.ts",
+ dest: "./providers/airtable/index.ts",
+ },
+ {
+ src: "./src/dataProvider.ts",
+ dest: "./providers/airtable/dataProvider.ts",
+ },
+ {
+ src: "./src/utils/index.ts",
+ dest: "./providers/airtable/utils/index.ts",
+ },
+ {
+ src: "./src/utils/generateFilter.ts",
+ dest: "./providers/airtable/utils/generateFilter.ts",
+ },
+ {
+ src: "./src/utils/generateFilterFormula.ts",
+ dest: "./providers/airtable/utils/generateFilterFormula.ts",
+ },
+ {
+ src: "./src/utils/generateLogicalFilterFormula.ts",
+ dest: "./providers/airtable/utils/generateLogicalFilterFormula.ts",
+ },
+ {
+ src: "./src/utils/generateLogicalFilterFormula.ts",
+ dest: "./providers/airtable/utils/generateLogicalFilterFormula.ts",
+ },
+ {
+ src: "./src/utils/generateSort.ts",
+ dest: "./providers/airtable/utils/generateSort.ts",
+ },
+ {
+ src: "./src/utils/isContainsOperator.ts",
+ dest: "./providers/airtable/utils/isContainsOperator.ts",
+ },
+ {
+ src: "./src/utils/isSimpleOperator.ts",
+ dest: "./providers/airtable/utils/isSimpleOperator.ts",
+ },
+ ],
+ message: `
+ **\`Usage\`**
+
+ \`\`\`
+ // title: App.tsx
+ import { dataProvider } from "./providers/airtable";
+
+ const API_TOKEN = "dummy-api-token";
+ const BASE_ID = "dummy-base-id";
+
+ const App = () => {
+ return (
+
+ );
+ }
+ \`\`\`
+ `,
+ },
+ ],
+ },
+};
diff --git a/packages/airtable/src/dataProvider.ts b/packages/airtable/src/dataProvider.ts
new file mode 100644
index 0000000..d62fa3e
--- /dev/null
+++ b/packages/airtable/src/dataProvider.ts
@@ -0,0 +1,161 @@
+import { DataProvider } from "@refinedev/core";
+import Airtable from "airtable";
+import { AirtableBase } from "airtable/lib/airtable_base";
+import { generateSort, generateFilter } from "./utils";
+
+export const dataProvider = (
+ apiKey: string,
+ baseId: string,
+ airtableClient?: AirtableBase,
+): Required => {
+ const base =
+ airtableClient || new Airtable({ apiKey: apiKey }).base(baseId);
+
+ return {
+ getList: async ({ resource, pagination, sorters, filters }) => {
+ const {
+ current = 1,
+ pageSize = 10,
+ mode = "server",
+ } = pagination ?? {};
+
+ const generatedSort = generateSort(sorters) || [];
+ const queryFilters = generateFilter(filters);
+
+ const { all } = base(resource).select({
+ pageSize: 100,
+ sort: generatedSort,
+ ...(queryFilters ? { filterByFormula: queryFilters } : {}),
+ });
+
+ const data = await all();
+ const isServerPaginationEnabled = mode === "server";
+
+ return {
+ data: data
+ .slice(
+ isServerPaginationEnabled
+ ? (current - 1) * pageSize
+ : undefined,
+ isServerPaginationEnabled
+ ? current * pageSize
+ : undefined,
+ )
+ .map((p) => ({
+ id: p.id,
+ ...p.fields,
+ })) as any,
+ total: data.length,
+ };
+ },
+
+ getMany: async ({ resource, ids }) => {
+ const { all } = base(resource).select({
+ pageSize: 100,
+ });
+
+ const data = await all();
+
+ return {
+ data: data
+ .filter((p) => ids.includes(p.id))
+ .map((p) => ({
+ id: p.id,
+ ...p.fields,
+ })) as any,
+ };
+ },
+
+ create: async ({ resource, variables }) => {
+ const { id, fields } = await base(resource).create(variables);
+
+ return {
+ data: {
+ id: id,
+ ...fields,
+ } as any,
+ };
+ },
+
+ createMany: async ({ resource, variables }) => {
+ const data = await base(resource).create(variables);
+
+ return {
+ data: data.map((p) => ({
+ id: p.id,
+ ...p.fields,
+ })) as any,
+ };
+ },
+
+ update: async ({ resource, id, variables }) => {
+ const { fields } = await base(resource).update(
+ id.toString(),
+ variables,
+ );
+
+ return {
+ data: {
+ id,
+ ...fields,
+ } as any,
+ };
+ },
+
+ updateMany: async ({ resource, ids, variables }) => {
+ const requestParams = ids.map((id) => ({
+ id: id.toString(),
+ fields: { ...variables },
+ }));
+ const data = await base(resource).update(requestParams);
+
+ return {
+ data: data.map((p) => ({
+ id: p.id,
+ ...p.fields,
+ })) as any,
+ };
+ },
+
+ getOne: async ({ resource, id }) => {
+ const { fields } = await base(resource).find(id.toString());
+
+ return {
+ data: {
+ id,
+ ...fields,
+ } as any,
+ };
+ },
+
+ deleteOne: async ({ resource, id }) => {
+ const { fields } = await base(resource).destroy(id.toString());
+
+ return {
+ data: {
+ id,
+ ...fields,
+ } as any,
+ };
+ },
+
+ deleteMany: async ({ resource, ids }) => {
+ const data = await base(resource).destroy(ids.map(String));
+
+ return {
+ data: data.map((p) => ({
+ id: p.id,
+ ...p.fields,
+ })) as any,
+ };
+ },
+
+ getApiUrl: () => {
+ throw Error("Not implemented on refine-airtable data provider.");
+ },
+
+ custom: async () => {
+ throw Error("Not implemented on refine-airtable data provider.");
+ },
+ };
+};
diff --git a/packages/airtable/src/index.ts b/packages/airtable/src/index.ts
new file mode 100644
index 0000000..d1ae584
--- /dev/null
+++ b/packages/airtable/src/index.ts
@@ -0,0 +1,5 @@
+import { dataProvider } from "./dataProvider";
+
+export * from "./utils";
+export * from "./dataProvider";
+export default dataProvider;
diff --git a/packages/airtable/src/utils/generateFilter.ts b/packages/airtable/src/utils/generateFilter.ts
new file mode 100644
index 0000000..0874474
--- /dev/null
+++ b/packages/airtable/src/utils/generateFilter.ts
@@ -0,0 +1,12 @@
+import { CrudFilters } from "@refinedev/core";
+import { compile } from "@qualifyze/airtable-formulator";
+import { generateFilterFormula } from "./generateFilterFormula";
+
+export const generateFilter = (filters?: CrudFilters): string | undefined => {
+ if (filters) {
+ // Top-level array has an implicit AND as per CRUDFilter design - https://refine.dev/docs/guides-and-concepts/data-provider/handling-filters/#logicalfilters
+ return compile(["AND", ...generateFilterFormula(filters)]);
+ }
+
+ return undefined;
+};
diff --git a/packages/airtable/src/utils/generateFilterFormula.ts b/packages/airtable/src/utils/generateFilterFormula.ts
new file mode 100644
index 0000000..3d14479
--- /dev/null
+++ b/packages/airtable/src/utils/generateFilterFormula.ts
@@ -0,0 +1,17 @@
+import { CrudFilters, LogicalFilter } from "@refinedev/core";
+import { Formula } from "@qualifyze/airtable-formulator";
+import { generateLogicalFilterFormula } from "./generateLogicalFilterFormula";
+
+export const generateFilterFormula = (filters: CrudFilters): Formula[] => {
+ const compound = filters.map((filter): Formula => {
+ const { operator, value } = filter;
+
+ if (operator === "or") {
+ return ["OR", ...generateFilterFormula(value)];
+ }
+
+ return generateLogicalFilterFormula(filter as LogicalFilter);
+ });
+
+ return compound;
+};
diff --git a/packages/airtable/src/utils/generateLogicalFilterFormula.ts b/packages/airtable/src/utils/generateLogicalFilterFormula.ts
new file mode 100644
index 0000000..46822aa
--- /dev/null
+++ b/packages/airtable/src/utils/generateLogicalFilterFormula.ts
@@ -0,0 +1,50 @@
+import { LogicalFilter } from "@refinedev/core";
+import { isContainsOperator, isContainssOperator } from "./isContainsOperator";
+import { isSimpleOperator, simpleOperatorMapping } from "./isSimpleOperator";
+import { Formula } from "@qualifyze/airtable-formulator";
+
+export const generateLogicalFilterFormula = (
+ filter: LogicalFilter,
+): Formula => {
+ const { field, operator, value } = filter;
+
+ if (isSimpleOperator(operator)) {
+ return [simpleOperatorMapping[operator], { field }, value];
+ }
+
+ if (isContainssOperator(operator)) {
+ const mappedOperator = {
+ containss: "!=",
+ ncontainss: "=",
+ } as const;
+
+ return [mappedOperator[operator], ["FIND", value, { field }], 0];
+ }
+
+ if (isContainsOperator(operator)) {
+ const mappedOperator = {
+ contains: "!=",
+ ncontains: "=",
+ } as const;
+
+ const find = [
+ "FIND",
+ ["LOWER", value],
+ ["LOWER", { field }],
+ ] as Formula;
+
+ return [mappedOperator[operator], find, 0];
+ }
+
+ if (operator === "null") {
+ return ["=", { field }, ["BLANK"]];
+ }
+
+ if (operator === "nnull") {
+ return ["!=", { field }, ["BLANK"]];
+ }
+
+ throw Error(
+ `Operator ${operator} is not supported for the Airtable data provider`,
+ );
+};
diff --git a/packages/airtable/src/utils/generateSort.ts b/packages/airtable/src/utils/generateSort.ts
new file mode 100644
index 0000000..e2f318c
--- /dev/null
+++ b/packages/airtable/src/utils/generateSort.ts
@@ -0,0 +1,8 @@
+import { CrudSorting } from "@refinedev/core";
+
+export const generateSort = (sorters?: CrudSorting) => {
+ return sorters?.map((item) => ({
+ field: item.field,
+ direction: item.order,
+ }));
+};
diff --git a/packages/airtable/src/utils/index.ts b/packages/airtable/src/utils/index.ts
new file mode 100644
index 0000000..ed5cf36
--- /dev/null
+++ b/packages/airtable/src/utils/index.ts
@@ -0,0 +1,6 @@
+export * from "./isSimpleOperator";
+export * from "./isContainsOperator";
+export * from "./generateLogicalFilterFormula";
+export * from "./generateFilterFormula";
+export * from "./generateFilter";
+export * from "./generateSort";
diff --git a/packages/airtable/src/utils/isContainsOperator.ts b/packages/airtable/src/utils/isContainsOperator.ts
new file mode 100644
index 0000000..b959a8b
--- /dev/null
+++ b/packages/airtable/src/utils/isContainsOperator.ts
@@ -0,0 +1,9 @@
+export const isContainssOperator = (
+ operator: any,
+): operator is "containss" | "ncontainss" =>
+ ["containss", "ncontainss"].includes(operator);
+
+export const isContainsOperator = (
+ operator: any,
+): operator is "contains" | "ncontains" =>
+ ["contains", "ncontains"].includes(operator);
diff --git a/packages/airtable/src/utils/isSimpleOperator.ts b/packages/airtable/src/utils/isSimpleOperator.ts
new file mode 100644
index 0000000..b5a594a
--- /dev/null
+++ b/packages/airtable/src/utils/isSimpleOperator.ts
@@ -0,0 +1,14 @@
+export type SimpleOperators = "eq" | "ne" | "lt" | "lte" | "gt" | "gte";
+import { OperatorSymbol } from "@qualifyze/airtable-formulator";
+
+export const simpleOperatorMapping: Record = {
+ eq: "=",
+ ne: "!=",
+ lt: "<",
+ lte: "<=",
+ gt: ">",
+ gte: ">=",
+} as const;
+
+export const isSimpleOperator = (operator: any): operator is SimpleOperators =>
+ Object.keys(simpleOperatorMapping).includes(operator);
diff --git a/packages/airtable/test/create/index.mock.ts b/packages/airtable/test/create/index.mock.ts
new file mode 100644
index 0000000..854194d
--- /dev/null
+++ b/packages/airtable/test/create/index.mock.ts
@@ -0,0 +1,48 @@
+import nock from "nock";
+
+nock("https://api.airtable.com:443", { encodedQueryParams: true })
+ .post("/v0/appKYl1H4k9g73sBT/posts/", {
+ fields: {
+ title: "foo",
+ content: "bar",
+ status: "published",
+ category: ["recDBRJljBDFH4rIh"],
+ },
+ })
+ .query({})
+ .reply(
+ 200,
+ [
+ "1f8b0800000000000003158c3d0f82301400ffcb9bc5b4151d3aa2821227c3e4c750e8436a2a35e53118c27ff7b15eee6e02674143c4a63c16785126dbc622aff7b082d6a1b703e809c89147b6da10980f6468640edfb1f66ee8d0326c0ce12bc41fe8fb323b64d7d2bfb3437e4ae3b983270ba127ec89b3dac4470f33a3885cd9ca7d96b9124a266297a8b4921b2d85966a2d84b8c1fc0704ab8bf4a4000000",
+ ],
+ [
+ "access-control-allow-headers",
+ "authorization,content-length,content-type,user-agent,x-airtable-application-id,x-airtable-user-agent,x-api-version,x-requested-with",
+ "access-control-allow-methods",
+ "DELETE,GET,OPTIONS,PATCH,POST,PUT",
+ "access-control-allow-origin",
+ "*",
+ "content-encoding",
+ "gzip",
+ "Content-Type",
+ "application/json; charset=utf-8",
+ "Date",
+ "Thu, 24 Jun 2021 13:10:12 GMT",
+ "Server",
+ "Tengine",
+ "Set-Cookie",
+ "brw=brwhuRDEqN6Ub31j3; path=/; expires=Fri, 24 Jun 2022 13:10:12 GMT; domain=.airtable.com; samesite=none; secure",
+ "Strict-Transport-Security",
+ "max-age=31536000; includeSubDomains; preload",
+ "Vary",
+ "Accept-Encoding",
+ "X-Content-Type-Options",
+ "nosniff",
+ "X-Frame-Options",
+ "DENY",
+ "Content-Length",
+ "160",
+ "Connection",
+ "Close",
+ ],
+ );
diff --git a/packages/airtable/test/create/index.spec.ts b/packages/airtable/test/create/index.spec.ts
new file mode 100644
index 0000000..adba485
--- /dev/null
+++ b/packages/airtable/test/create/index.spec.ts
@@ -0,0 +1,26 @@
+import dataProvider from "../../src/index";
+import "./index.mock";
+
+describe("create", () => {
+ it("correct response", async () => {
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).create({
+ resource: "posts",
+ variables: {
+ title: "foo",
+ content: "bar",
+ status: "published",
+ category: ["recDBRJljBDFH4rIh"],
+ },
+ });
+
+ const { data } = response;
+
+ expect(data["title"]).toEqual("foo");
+ expect(data["status"]).toEqual("published");
+ expect(data["category"]).toEqual(["recDBRJljBDFH4rIh"]);
+ expect(data["content"]).toEqual("bar\n");
+ });
+});
diff --git a/packages/airtable/test/custom/index.spec.ts b/packages/airtable/test/custom/index.spec.ts
new file mode 100644
index 0000000..e122a82
--- /dev/null
+++ b/packages/airtable/test/custom/index.spec.ts
@@ -0,0 +1,14 @@
+import dataProvider from "../../src/index";
+
+describe("custom", () => {
+ it("correct get response", async () => {
+ try {
+ await dataProvider("keywoytODSr6xAqfg", "appKYl1H4k9g73sBT")
+ .custom!({ url: "users", method: "get" });
+ } catch (error) {
+ expect(error).toEqual(
+ Error("Not implemented on refine-airtable data provider."),
+ );
+ }
+ });
+});
diff --git a/packages/airtable/test/deleteMany/index.mock.ts b/packages/airtable/test/deleteMany/index.mock.ts
new file mode 100644
index 0000000..ffae891
--- /dev/null
+++ b/packages/airtable/test/deleteMany/index.mock.ts
@@ -0,0 +1,41 @@
+import nock from "nock";
+
+nock("https://api.airtable.com:443", { encodedQueryParams: true })
+ .delete("/v0/appKYl1H4k9g73sBT/posts")
+ .query({ "records%5B%5D": "recdgFXue7JnGD90w" })
+ .reply(
+ 200,
+ [
+ "1f8b0800000000000003ab562a4a4dce2f4a2956b28aae564a49cd492d494d51b22a292a4dd551ca04b240f229e96e11a5a9e65e79ee2e9606e54ab5b1b5002d0259eb37000000",
+ ],
+ [
+ "access-control-allow-headers",
+ "authorization,content-length,content-type,user-agent,x-airtable-application-id,x-airtable-user-agent,x-api-version,x-requested-with",
+ "access-control-allow-methods",
+ "DELETE,GET,OPTIONS,PATCH,POST,PUT",
+ "access-control-allow-origin",
+ "*",
+ "content-encoding",
+ "gzip",
+ "Content-Type",
+ "application/json; charset=utf-8",
+ "Date",
+ "Thu, 24 Jun 2021 13:17:00 GMT",
+ "Server",
+ "Tengine",
+ "Set-Cookie",
+ "brw=brwTjdQAZbqbk0xGk; path=/; expires=Fri, 24 Jun 2022 13:17:00 GMT; domain=.airtable.com; samesite=none; secure",
+ "Strict-Transport-Security",
+ "max-age=31536000; includeSubDomains; preload",
+ "Vary",
+ "Accept-Encoding",
+ "X-Content-Type-Options",
+ "nosniff",
+ "X-Frame-Options",
+ "DENY",
+ "Content-Length",
+ "71",
+ "Connection",
+ "Close",
+ ],
+ );
diff --git a/packages/airtable/test/deleteMany/index.spec.ts b/packages/airtable/test/deleteMany/index.spec.ts
new file mode 100644
index 0000000..55c016b
--- /dev/null
+++ b/packages/airtable/test/deleteMany/index.spec.ts
@@ -0,0 +1,15 @@
+import dataProvider from "../../src/index";
+import "./index.mock";
+
+describe("deleteMany", () => {
+ it("correct response", async () => {
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).deleteMany!({ resource: "posts", ids: ["recdgFXue7JnGD90w"] });
+
+ const { data } = response;
+
+ expect(data).not.toBeNull();
+ });
+});
diff --git a/packages/airtable/test/deleteOne/index.mock.ts b/packages/airtable/test/deleteOne/index.mock.ts
new file mode 100644
index 0000000..b2a4ebf
--- /dev/null
+++ b/packages/airtable/test/deleteOne/index.mock.ts
@@ -0,0 +1,41 @@
+import nock from "nock";
+
+nock("https://api.airtable.com:443", { encodedQueryParams: true })
+ .delete("/v0/appKYl1H4k9g73sBT/posts/recJEGeL2aB5rGFbC")
+ .query({})
+ .reply(
+ 200,
+ [
+ "1f8b0800000000000003ab564a49cd492d494d51b22a292a4dd551ca04b2948a5293bd5cdd537d8c129d4c8bdcdd929c956a016e8d991b29000000",
+ ],
+ [
+ "access-control-allow-headers",
+ "authorization,content-length,content-type,user-agent,x-airtable-application-id,x-airtable-user-agent,x-api-version,x-requested-with",
+ "access-control-allow-methods",
+ "DELETE,GET,OPTIONS,PATCH,POST,PUT",
+ "access-control-allow-origin",
+ "*",
+ "content-encoding",
+ "gzip",
+ "Content-Type",
+ "application/json; charset=utf-8",
+ "Date",
+ "Thu, 24 Jun 2021 13:19:14 GMT",
+ "Server",
+ "Tengine",
+ "Set-Cookie",
+ "brw=brwInLaPzl4WP7sXu; path=/; expires=Fri, 24 Jun 2022 13:19:13 GMT; domain=.airtable.com; samesite=none; secure",
+ "Strict-Transport-Security",
+ "max-age=31536000; includeSubDomains; preload",
+ "Vary",
+ "Accept-Encoding",
+ "X-Content-Type-Options",
+ "nosniff",
+ "X-Frame-Options",
+ "DENY",
+ "Content-Length",
+ "59",
+ "Connection",
+ "Close",
+ ],
+ );
diff --git a/packages/airtable/test/deleteOne/index.spec.ts b/packages/airtable/test/deleteOne/index.spec.ts
new file mode 100644
index 0000000..ccb00aa
--- /dev/null
+++ b/packages/airtable/test/deleteOne/index.spec.ts
@@ -0,0 +1,15 @@
+import dataProvider from "../../src/index";
+import "./index.mock";
+
+describe("deleteOne", () => {
+ it("correct response", async () => {
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).deleteOne({ resource: "posts", id: "recJEGeL2aB5rGFbC" });
+
+ const { data } = response;
+
+ expect(data).not.toBeNull();
+ });
+});
diff --git a/packages/airtable/test/getList/index.mock.ts b/packages/airtable/test/getList/index.mock.ts
new file mode 100644
index 0000000..a612847
--- /dev/null
+++ b/packages/airtable/test/getList/index.mock.ts
@@ -0,0 +1,150 @@
+import nock from "nock";
+import url from "url";
+
+const commonHeaders = [
+ "access-control-allow-headers",
+ "authorization,content-length,content-type,user-agent,x-airtable-application-id,x-airtable-user-agent,x-api-version,x-requested-with",
+ "access-control-allow-methods",
+ "DELETE,GET,OPTIONS,PATCH,POST,PUT",
+ "access-control-allow-origin",
+ "*",
+ "airtable-uncompressed-content-length",
+ "380",
+ "Content-Type",
+ "application/json; charset=utf-8",
+ "Date",
+ "Thu, 24 Jun 2021 12:24:32 GMT",
+ "Server",
+ "Tengine",
+ "Set-Cookie",
+ "brw=brwHislGvzT3Ws3Yf; path=/; expires=Fri, 24 Jun 2022 12:24:32 GMT; domain=.airtable.com; samesite=none; secure",
+ "Strict-Transport-Security",
+ "max-age=31536000; includeSubDomains; preload",
+ "Vary",
+ "Accept-Encoding",
+ "X-Content-Type-Options",
+ "nosniff",
+ "X-Frame-Options",
+ "DENY",
+ "Content-Length",
+ "233",
+ "Connection",
+ "Close",
+];
+
+nock("https://api.airtable.com:443", { encodedQueryParams: true })
+ .persist()
+ .get("/v0/appKYl1H4k9g73sBT/posts")
+ .query((query) => {
+ if (query.pageSize !== "100") return false;
+ if (query.filterByFormula === undefined) return false;
+
+ return true;
+ })
+ .reply(
+ 200,
+ function () {
+ const parsed = new url.URL(this.req.path, "http://example.com");
+ const query = parsed.searchParams.get("filterByFormula");
+
+ return JSON.stringify({
+ offset: 0,
+ records: [
+ {
+ fields: {
+ query,
+ },
+ },
+ ],
+ });
+ },
+ commonHeaders,
+ );
+
+nock("https://api.airtable.com:443", { encodedQueryParams: true })
+ .get("/v0/appKYl1H4k9g73sBT/posts")
+ .query({ pageSize: "100" })
+ .reply(
+ 200,
+ [
+ "1f8b0800000000000003954fc18ac23014fc157dc7a292562bdaa3c86a570f2215c5ad87da3cd7484cd634825aecb7fb82a0c74598c3639899375382c15c1b5e40f45382e01039a23fdaaea637dee517d58925346027503a4d09565889a41aa394bab6d446f25abb4e923cb3f8abcd95825cc47030ff9687c1f06bdc31f11e360d286c66cf94017fe7ad14c51eb9736965515962b38213525555cf8b5055a94a95e7bd88ccf3520577b219a4773c1147d7256081df64dda61f26be1f056114f65a8cb13529df9ba693b9d027b14bcc6c11dffedbf4d9228307cca9cf27d536f7073da8e6fb7c010000",
+ ],
+ [
+ "access-control-allow-headers",
+ "authorization,content-length,content-type,user-agent,x-airtable-application-id,x-airtable-user-agent,x-api-version,x-requested-with",
+ "access-control-allow-methods",
+ "DELETE,GET,OPTIONS,PATCH,POST,PUT",
+ "access-control-allow-origin",
+ "*",
+ "airtable-uncompressed-content-length",
+ "380",
+ "content-encoding",
+ "gzip",
+ "Content-Type",
+ "application/json; charset=utf-8",
+ "Date",
+ "Thu, 24 Jun 2021 12:24:32 GMT",
+ "Server",
+ "Tengine",
+ "Set-Cookie",
+ "brw=brwHislGvzT3Ws3Yf; path=/; expires=Fri, 24 Jun 2022 12:24:32 GMT; domain=.airtable.com; samesite=none; secure",
+ "Strict-Transport-Security",
+ "max-age=31536000; includeSubDomains; preload",
+ "Vary",
+ "Accept-Encoding",
+ "X-Content-Type-Options",
+ "nosniff",
+ "X-Frame-Options",
+ "DENY",
+ "Content-Length",
+ "233",
+ "Connection",
+ "Close",
+ ],
+ );
+
+nock("https://api.airtable.com:443", { encodedQueryParams: true })
+ .get("/v0/appKYl1H4k9g73sBT/posts")
+ .query({
+ pageSize: "100",
+ "sort%5B0%5D%5Bfield%5D": "title",
+ "sort%5B0%5D%5Bdirection%5D": "desc",
+ })
+ .reply(
+ 200,
+ [
+ "1f8b0800000000000003958f416bc2401085ff8ace31a86ca211cd518235d64391144b1b0f4976ac2beb6ebbbb426b30bfdd490bf59243857718debc6f785381c1521b6e217aab4070881a63f5b816fa53ec52f3f49c9ca1073b81b2c954605dee4ef62776c0d221a76d993b7cd7e69b6e34743c5b2fe56116cf172393ec61db03279c44621628a5ee6cb491bc0b17020d12ca53716cb6010bfc3e1bf7fd30f5fd2808a37032608cbd52f2566dfa50bcacce7cccbfd42891edd53e4e851476ffbf6ea5560e95232cb79c94a9bafe9d48759da94c79de9f917b5ea6a0f5a3cef0ae9fb6972ba8a00e5b7c010000",
+ ],
+ [
+ "access-control-allow-headers",
+ "authorization,content-length,content-type,user-agent,x-airtable-application-id,x-airtable-user-agent,x-api-version,x-requested-with",
+ "access-control-allow-methods",
+ "DELETE,GET,OPTIONS,PATCH,POST,PUT",
+ "access-control-allow-origin",
+ "*",
+ "airtable-uncompressed-content-length",
+ "380",
+ "content-encoding",
+ "gzip",
+ "Content-Type",
+ "application/json; charset=utf-8",
+ "Date",
+ "Thu, 24 Jun 2021 13:07:26 GMT",
+ "Server",
+ "Tengine",
+ "Set-Cookie",
+ "brw=brw0sykMWa9glzNWF; path=/; expires=Fri, 24 Jun 2022 13:07:25 GMT; domain=.airtable.com; samesite=none; secure",
+ "Strict-Transport-Security",
+ "max-age=31536000; includeSubDomains; preload",
+ "Vary",
+ "Accept-Encoding",
+ "X-Content-Type-Options",
+ "nosniff",
+ "X-Frame-Options",
+ "DENY",
+ "Content-Length",
+ "237",
+ "Connection",
+ "Close",
+ ],
+ );
diff --git a/packages/airtable/test/getList/index.spec.ts b/packages/airtable/test/getList/index.spec.ts
new file mode 100644
index 0000000..adf46a9
--- /dev/null
+++ b/packages/airtable/test/getList/index.spec.ts
@@ -0,0 +1,444 @@
+import { ConditionalFilter } from "@refinedev/core";
+import dataProvider from "../../src/index";
+import "./index.mock";
+
+describe("getList", () => {
+ it("correct response", async () => {
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ });
+
+ expect(response.data[0]["id"]).toBe("rec9GbXLzd6dxn4Il");
+ expect(response.data[0]["title"]).toBe("Hello World 3!");
+ expect(response.total).toBe(2);
+ });
+
+ it("correct sorting response", async () => {
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ sorters: [
+ {
+ field: "title",
+ order: "desc",
+ },
+ ],
+ });
+
+ expect(response.data[0]["id"]).toBe("recLKRioqifTrPUIz");
+ expect(response.data[0]["title"]).toBe("Hello World!");
+ expect(response.total).toBe(2);
+ });
+
+ it("correct equals filter for strings", async () => {
+ const filter = {
+ operator: "eq",
+ field: "title",
+ value: "Hello World!",
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // {field} must equal exactly string
+ expect(response.data[0]["query"]).toBe('AND({title}="Hello World!")');
+ });
+
+ it("correct equals filter for numbers", async () => {
+ const filter = {
+ operator: "eq",
+ field: "age",
+ value: 100,
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // {field} must equal exactly number
+ expect(response.data[0]["query"]).toBe("AND({age}=100)");
+ });
+
+ it("correct not equals filter for strings", async () => {
+ const filter = {
+ operator: "ne",
+ field: "title",
+ value: "Hello World!",
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // {field} must not equal exactly string
+ expect(response.data[0]["query"]).toBe('AND({title}!="Hello World!")');
+ });
+
+ it("correct not equals filter for numbers", async () => {
+ const filter = {
+ operator: "ne",
+ field: "age",
+ value: 100,
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // {field} must not equal exactly number
+ expect(response.data[0]["query"]).toBe("AND({age}!=100)");
+ });
+
+ it("correct less than filter", async () => {
+ const filter = {
+ operator: "lt",
+ field: "age",
+ value: 10,
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // {field} must be less than value (as number)
+ expect(response.data[0]["query"]).toBe("AND({age}<10)");
+ });
+
+ it("correct less than or equal filter", async () => {
+ const filter = {
+ operator: "lte",
+ field: "age",
+ value: 10,
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // {field} must be less than or equal value (as number)
+ expect(response.data[0]["query"]).toBe("AND({age}<=10)");
+ });
+
+ it("correct greater than filter", async () => {
+ const filter = {
+ operator: "gt",
+ field: "age",
+ value: 10,
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // {field} must be greater than value (as number)
+ expect(response.data[0]["query"]).toBe("AND({age}>10)");
+ });
+
+ it("correct greater than or equal filter", async () => {
+ const filter = {
+ operator: "gte",
+ field: "age",
+ value: 10,
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // {field} must be greater than or equal value (as number)
+ expect(response.data[0]["query"]).toBe("AND({age}>=10)");
+ });
+
+ it("correct contains filter", async () => {
+ const filter = {
+ operator: "containss",
+ field: "title",
+ value: "Hello",
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // must find string in {field} - FIND returns non-zero value
+ expect(response.data[0]["query"]).toBe('AND(FIND("Hello",{title})!=0)');
+ });
+
+ it("correct not contains filter", async () => {
+ const filter = {
+ operator: "ncontainss",
+ field: "title",
+ value: "Hello",
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // must not find string in {field} - FIND returns zero
+ expect(response.data[0]["query"]).toBe('AND(FIND("Hello",{title})=0)');
+ });
+
+ it("correct case-insensitive contains filter", async () => {
+ const filter = {
+ operator: "contains",
+ field: "title",
+ value: "Hello",
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // must find lower-cased string in lower-cased {field} - lower-casing both values makes it case-insensitive
+ expect(response.data[0]["query"]).toBe(
+ 'AND(FIND(LOWER("Hello"),LOWER({title}))!=0)',
+ );
+ });
+
+ it("correct case-insensitive not contains filter", async () => {
+ const filter = {
+ operator: "ncontains",
+ field: "title",
+ value: "Hello",
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // must not find lower-cased string in lower-cased {field} - lower-casing both values makes it case-insensitive
+ expect(response.data[0]["query"]).toBe(
+ 'AND(FIND(LOWER("Hello"),LOWER({title}))=0)',
+ );
+ });
+
+ it("correct truthy null filter", async () => {
+ const filter = {
+ operator: "null",
+ field: "title",
+ value: undefined,
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // {field} must be null (blank)
+ expect(response.data[0]["query"]).toBe("AND({title}=BLANK())");
+ });
+
+ it("correct falsy null filter", async () => {
+ const filter = {
+ operator: "nnull",
+ field: "title",
+ value: undefined,
+ } as const;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // {field} must not be null (blank)
+ expect(response.data[0]["query"]).toBe("AND({title}!=BLANK())");
+ });
+
+ it.each(["between", "nbetween"] as const)(
+ "fails for %s filter",
+ async (operator) => {
+ const filter = {
+ operator,
+ field: "age",
+ value: [10, 15],
+ } as const;
+
+ await expect(() => {
+ return dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+ }).rejects.toThrow(
+ `Operator ${operator} is not supported for the Airtable data provider`,
+ );
+ },
+ );
+
+ it.each(["in", "nin"] as const)("fails for %s filter", async (operator) => {
+ const filter = {
+ operator,
+ field: "posts",
+ value: ["uuid-1", "uuid-2"],
+ } as const;
+
+ await expect(() => {
+ return dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+ }).rejects.toThrow(
+ `Operator ${operator} is not supported for the Airtable data provider`,
+ );
+ });
+
+ it("correct 'or' conditional filter", async () => {
+ const filter = {
+ operator: "or",
+ value: [
+ {
+ field: "title",
+ operator: "eq",
+ value: "Silver Bullet",
+ },
+ {
+ field: "title",
+ operator: "ne",
+ value: "The Mythical Man Month",
+ },
+ ],
+ } as ConditionalFilter;
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: [filter],
+ });
+
+ expect(response.total).toBe(1);
+ // {field} must either be Silver Bullet or must not be Mythical Man Month
+ expect(response.data[0]["query"]).toBe(
+ 'AND(OR({title}="Silver Bullet",{title}!="The Mythical Man Month"))',
+ );
+ });
+
+ it("correct compound 'or' conditional filter", async () => {
+ const filters = [
+ {
+ operator: "or",
+ value: [
+ {
+ field: "title",
+ operator: "eq",
+ value: "Silver Bullet",
+ },
+ {
+ field: "title",
+ operator: "ne",
+ value: "The Mythical Man Month",
+ },
+ ],
+ },
+ {
+ operator: "or",
+ value: [
+ {
+ field: "age",
+ operator: "gt",
+ value: 15,
+ },
+ {
+ field: "age",
+ operator: "lt",
+ value: 25,
+ },
+ ],
+ },
+ ] as ConditionalFilter[];
+
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getList({
+ resource: "posts",
+ filters: filters,
+ });
+
+ expect(response.total).toBe(1);
+ expect(response.data[0]["query"]).toBe(
+ 'AND(OR({title}="Silver Bullet",{title}!="The Mythical Man Month"),OR({age}>15,{age}<25))',
+ );
+ });
+});
diff --git a/packages/airtable/test/getMany/index.mock.ts b/packages/airtable/test/getMany/index.mock.ts
new file mode 100644
index 0000000..03ae66f
--- /dev/null
+++ b/packages/airtable/test/getMany/index.mock.ts
@@ -0,0 +1,43 @@
+import nock from "nock";
+
+nock("https://api.airtable.com:443", { encodedQueryParams: true })
+ .get("/v0/appKYl1H4k9g73sBT/posts")
+ .query({ pageSize: "100" })
+ .reply(
+ 200,
+ [
+ "1f8b080000000000000395905d6b83301486ff4a974b69875a959acb526aed1c88d875747a114d5c53b2a48be9585bf4b72f6eeca3e0608373111e5e4e9ef79c8124a590b806f0e10c2806b0039302c55e54851b278d571118828a12d665ce4051c5884e5542685e2ba40e9a83fda160b4de12ac6129b8225c695a2099f18e20451e853cea4fbaf577c151be24cbc05fdfeed51ce48d4e48a23338a54fdd72dbb4ad91e98d6c27b5c6d0f4a133b9364d73039ae1b7a41f14f7d1097bf8953b21bb90ecd7ba94984d9325db4d67f38523c32dc87f7aa31aebc978db7ebcf4b46dc6336e185f0019c67bb7cf832c086362b01692e1c1f80afcdac97253cb82b60bdd9e4ed14d42c533ad5219afc2537f274976a4547fabd423f72fb5bc7903b0079a9c21020000",
+ ],
+ [
+ "access-control-allow-headers",
+ "authorization,content-length,content-type,user-agent,x-airtable-application-id,x-airtable-user-agent,x-api-version,x-requested-with",
+ "access-control-allow-methods",
+ "DELETE,GET,OPTIONS,PATCH,POST,PUT",
+ "access-control-allow-origin",
+ "*",
+ "airtable-uncompressed-content-length",
+ "545",
+ "content-encoding",
+ "gzip",
+ "Content-Type",
+ "application/json; charset=utf-8",
+ "Date",
+ "Thu, 24 Jun 2021 13:20:40 GMT",
+ "Server",
+ "Tengine",
+ "Set-Cookie",
+ "brw=brwNd7NWRhWftbS0Q; path=/; expires=Fri, 24 Jun 2022 13:20:40 GMT; domain=.airtable.com; samesite=none; secure",
+ "Strict-Transport-Security",
+ "max-age=31536000; includeSubDomains; preload",
+ "Vary",
+ "Accept-Encoding",
+ "X-Content-Type-Options",
+ "nosniff",
+ "X-Frame-Options",
+ "DENY",
+ "Content-Length",
+ "294",
+ "Connection",
+ "Close",
+ ],
+ );
diff --git a/packages/airtable/test/getMany/index.spec.ts b/packages/airtable/test/getMany/index.spec.ts
new file mode 100644
index 0000000..c7ad548
--- /dev/null
+++ b/packages/airtable/test/getMany/index.spec.ts
@@ -0,0 +1,20 @@
+import dataProvider from "../../src/index";
+import "./index.mock";
+
+describe("getMany", () => {
+ it("correct response", async () => {
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getMany!({
+ resource: "posts",
+ ids: ["recLKRioqifTrPUIz", "rec9GbXLzd6dxn4Il"],
+ });
+
+ const { data } = response;
+
+ expect(data[0]["id"]).toBe("rec9GbXLzd6dxn4Il");
+ expect(data[1]["id"]).toBe("recLKRioqifTrPUIz");
+ expect(response.data.length).toBe(2);
+ });
+});
diff --git a/packages/airtable/test/getOne/index.mock.ts b/packages/airtable/test/getOne/index.mock.ts
new file mode 100644
index 0000000..5316445
--- /dev/null
+++ b/packages/airtable/test/getOne/index.mock.ts
@@ -0,0 +1,43 @@
+import nock from "nock";
+
+nock("https://api.airtable.com:443", { encodedQueryParams: true })
+ .get("/v0/appKYl1H4k9g73sBT/posts/recLKRioqifTrPUIz")
+ .query({})
+ .reply(
+ 200,
+ [
+ "1f8b08000000000000031dcb410bc2201880e1bf52df790b958cf038c6d8aa430c23283a0cfd560e43523bd4d87fcf757edf6704a341804775d8b7c6bd4c2ffdf1d47c2183dea0d501c4082176f11dfedb802aa24e557511efce7f405c675d16edce0e4559d56bdf3ce0964134d16232355aeb1667e7ad5ec294a0c744b534cfb932c2684e3639e59252c1b8e0db1521e402d30fb10f929e9a000000",
+ ],
+ [
+ "access-control-allow-headers",
+ "authorization,content-length,content-type,user-agent,x-airtable-application-id,x-airtable-user-agent,x-api-version,x-requested-with",
+ "access-control-allow-methods",
+ "DELETE,GET,OPTIONS,PATCH,POST,PUT",
+ "access-control-allow-origin",
+ "*",
+ "airtable-uncompressed-content-length",
+ "154",
+ "content-encoding",
+ "gzip",
+ "Content-Type",
+ "application/json; charset=utf-8",
+ "Date",
+ "Thu, 24 Jun 2021 13:21:53 GMT",
+ "Server",
+ "Tengine",
+ "Set-Cookie",
+ "brw=brwQBAba4kMeu0MpF; path=/; expires=Fri, 24 Jun 2022 13:21:53 GMT; domain=.airtable.com; samesite=none; secure",
+ "Strict-Transport-Security",
+ "max-age=31536000; includeSubDomains; preload",
+ "Vary",
+ "Accept-Encoding",
+ "X-Content-Type-Options",
+ "nosniff",
+ "X-Frame-Options",
+ "DENY",
+ "Content-Length",
+ "156",
+ "Connection",
+ "Close",
+ ],
+ );
diff --git a/packages/airtable/test/getOne/index.spec.ts b/packages/airtable/test/getOne/index.spec.ts
new file mode 100644
index 0000000..e41d9e3
--- /dev/null
+++ b/packages/airtable/test/getOne/index.spec.ts
@@ -0,0 +1,17 @@
+import dataProvider from "../../src/index";
+import "./index.mock";
+
+describe("getOne", () => {
+ it("correct response", async () => {
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).getOne({ resource: "posts", id: "recLKRioqifTrPUIz" });
+
+ const { data } = response;
+
+ expect(data.title).toBe("Hello World!");
+ expect(data.status).toBe("rejected");
+ expect(data.category).toEqual(["recDBRJljBDFH4rIh"]);
+ });
+});
diff --git a/packages/airtable/test/jest.setup.js b/packages/airtable/test/jest.setup.js
new file mode 100644
index 0000000..fc7bc51
--- /dev/null
+++ b/packages/airtable/test/jest.setup.js
@@ -0,0 +1,11 @@
+const fetch = require("node-fetch");
+const nock = require("nock");
+
+global.fetch = window.fetch = fetch;
+global.Request = window.Request = fetch.Request;
+global.Response = window.Response = fetch.Response;
+
+afterAll(() => {
+ nock.cleanAll();
+ nock.restore();
+});
diff --git a/packages/airtable/test/update/index.mock.ts b/packages/airtable/test/update/index.mock.ts
new file mode 100644
index 0000000..7b3e1f0
--- /dev/null
+++ b/packages/airtable/test/update/index.mock.ts
@@ -0,0 +1,43 @@
+import nock from "nock";
+
+nock("https://api.airtable.com:443", { encodedQueryParams: true })
+ .patch("/v0/appKYl1H4k9g73sBT/posts/recLKRioqifTrPUIz", {
+ fields: { title: "Hello World!!" },
+ })
+ .query({})
+ .reply(
+ 200,
+ [
+ "1f8b08000000000000031dcb410bc2201880e1bfd2bef3162a19e1718cd8aa430c23283a0cfd560e43523bd4d87fcf757edf6704a341804775d8b7c6bd4c2ffdf1d47c2187dea0d501c4082176f11dfedb802aa24e557511efce7f405c675d95edce0e65b5ad57be79c02d8768a2c5646ab4d62dcece5b9d653025e931592dcd73ce8c305a907541b9a454302ef8664908b9c0f4030447c06c9b000000",
+ ],
+ [
+ "access-control-allow-headers",
+ "authorization,content-length,content-type,user-agent,x-airtable-application-id,x-airtable-user-agent,x-api-version,x-requested-with",
+ "access-control-allow-methods",
+ "DELETE,GET,OPTIONS,PATCH,POST,PUT",
+ "access-control-allow-origin",
+ "*",
+ "content-encoding",
+ "gzip",
+ "Content-Type",
+ "application/json; charset=utf-8",
+ "Date",
+ "Thu, 24 Jun 2021 13:24:42 GMT",
+ "Server",
+ "Tengine",
+ "Set-Cookie",
+ "brw=brwQrvJXnX0I6wkCt; path=/; expires=Fri, 24 Jun 2022 13:24:42 GMT; domain=.airtable.com; samesite=none; secure",
+ "Strict-Transport-Security",
+ "max-age=31536000; includeSubDomains; preload",
+ "Vary",
+ "Accept-Encoding",
+ "X-Content-Type-Options",
+ "nosniff",
+ "X-Frame-Options",
+ "DENY",
+ "Content-Length",
+ "157",
+ "Connection",
+ "Close",
+ ],
+ );
diff --git a/packages/airtable/test/update/index.spec.ts b/packages/airtable/test/update/index.spec.ts
new file mode 100644
index 0000000..43da1ea
--- /dev/null
+++ b/packages/airtable/test/update/index.spec.ts
@@ -0,0 +1,21 @@
+import dataProvider from "../../src/index";
+import "./index.mock";
+
+describe("update", () => {
+ it("correct response", async () => {
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).update({
+ resource: "posts",
+ id: "recLKRioqifTrPUIz",
+ variables: {
+ title: "Hello World!!",
+ },
+ });
+
+ const { data } = response;
+
+ expect(data["title"]).toBe("Hello World!!");
+ });
+});
diff --git a/packages/airtable/test/updateMany/index.mock.ts b/packages/airtable/test/updateMany/index.mock.ts
new file mode 100644
index 0000000..08ae9e1
--- /dev/null
+++ b/packages/airtable/test/updateMany/index.mock.ts
@@ -0,0 +1,46 @@
+import nock from "nock";
+
+nock("https://api.airtable.com:443", { encodedQueryParams: true })
+ .patch("/v0/appKYl1H4k9g73sBT/posts/", {
+ records: [
+ { id: "recLKRioqifTrPUIz", fields: { title: "Hello World!!!" } },
+ { id: "rec9GbXLzd6dxn4Il", fields: { title: "Hello World!!!" } },
+ ],
+ })
+ .query({})
+ .reply(
+ 200,
+ [
+ "1f8b0800000000000003ad8f416bc2401085ff8a996350d9042336471135ad872229169b1c6276d49575577757680de6b73b69412f3d7810e630bcf7bee14d05064b6db885f8ab02c1216e84d9db5ce8a358a7e6fd2339431bd6026593a9c0bac29dec6f6c87a5434e6e5938dc68f343371a7a349cbfcadd70349ef64cb285bc0d4e3889c44c514add5a6823b9e7797021d420c13c15fbc60f59187458bf13446910c4611447832e636c49c97bb997c9ea7376e67dfead7a89fcbfdce1b492c26e1f6b576ae55039c20acb693255d77f1b4d5d672a53be7f130adfcf143ce3a7fc720554f78d147e010000",
+ ],
+ [
+ "access-control-allow-headers",
+ "authorization,content-length,content-type,user-agent,x-airtable-application-id,x-airtable-user-agent,x-api-version,x-requested-with",
+ "access-control-allow-methods",
+ "DELETE,GET,OPTIONS,PATCH,POST,PUT",
+ "access-control-allow-origin",
+ "*",
+ "content-encoding",
+ "gzip",
+ "Content-Type",
+ "application/json; charset=utf-8",
+ "Date",
+ "Thu, 24 Jun 2021 13:26:53 GMT",
+ "Server",
+ "Tengine",
+ "Set-Cookie",
+ "brw=brwPAe5xxAm5wIYu2; path=/; expires=Fri, 24 Jun 2022 13:26:53 GMT; domain=.airtable.com; samesite=none; secure",
+ "Strict-Transport-Security",
+ "max-age=31536000; includeSubDomains; preload",
+ "Vary",
+ "Accept-Encoding",
+ "X-Content-Type-Options",
+ "nosniff",
+ "X-Frame-Options",
+ "DENY",
+ "Content-Length",
+ "235",
+ "Connection",
+ "Close",
+ ],
+ );
diff --git a/packages/airtable/test/updateMany/index.spec.ts b/packages/airtable/test/updateMany/index.spec.ts
new file mode 100644
index 0000000..feb4d36
--- /dev/null
+++ b/packages/airtable/test/updateMany/index.spec.ts
@@ -0,0 +1,22 @@
+import dataProvider from "../../src/index";
+import "./index.mock";
+
+describe("updateMany", () => {
+ it("correct response", async () => {
+ const response = await dataProvider(
+ "keywoytODSr6xAqfg",
+ "appKYl1H4k9g73sBT",
+ ).updateMany!({
+ resource: "posts",
+ ids: ["recLKRioqifTrPUIz", "rec9GbXLzd6dxn4Il"],
+ variables: {
+ title: "Hello World!!!",
+ },
+ });
+
+ const { data } = response;
+
+ expect(data[0]["title"]).toBe("Hello World!!!");
+ expect(data[1]["title"]).toBe("Hello World!!!");
+ });
+});
diff --git a/packages/airtable/test/utils/generateFilter.spec.ts b/packages/airtable/test/utils/generateFilter.spec.ts
new file mode 100644
index 0000000..d4c02e4
--- /dev/null
+++ b/packages/airtable/test/utils/generateFilter.spec.ts
@@ -0,0 +1,33 @@
+import { CrudFilters } from "@refinedev/core";
+import { generateFilter } from "../../src/utils";
+
+describe("generateFilter", () => {
+ it("should return undefined when no filters are provided", () => {
+ expect(generateFilter()).toBeUndefined();
+ });
+
+ it("should return a filter formula when filters are provided", () => {
+ const filters: CrudFilters = [
+ { field: "name", operator: "eq", value: "John" },
+ { field: "age", operator: "gte", value: 30 },
+ ];
+ const expected = 'AND({name}="John",{age}>=30)';
+ expect(generateFilter(filters)).toBe(expected);
+ });
+
+ it("should return a complex filter formula with nested filters", () => {
+ const filters: CrudFilters = [
+ {
+ operator: "or",
+ value: [
+ { field: "name", operator: "eq", value: "John" },
+ { field: "name", operator: "eq", value: "Jane" },
+ ],
+ },
+ { field: "age", operator: "gte", value: 30 },
+ ];
+
+ const expected = 'AND(OR({name}="John",{name}="Jane"),{age}>=30)';
+ expect(generateFilter(filters)).toBe(expected);
+ });
+});
diff --git a/packages/airtable/test/utils/generateFilterFormula.spec.ts b/packages/airtable/test/utils/generateFilterFormula.spec.ts
new file mode 100644
index 0000000..8f4dd03
--- /dev/null
+++ b/packages/airtable/test/utils/generateFilterFormula.spec.ts
@@ -0,0 +1,44 @@
+import { CrudFilters } from "@refinedev/core";
+import { generateFilterFormula } from "../../src/utils";
+
+describe("generateFilterFormula", () => {
+ it("should return an empty array when no filters are provided", () => {
+ expect(generateFilterFormula([])).toEqual([]);
+ });
+
+ it("should return a formula array when filters are provided", () => {
+ const filters: CrudFilters = [
+ { field: "name", operator: "eq", value: "John" },
+ { field: "age", operator: "gte", value: 30 },
+ ];
+ const expected = [
+ ["=", { field: "name" }, "John"],
+ [">=", { field: "age" }, 30],
+ ];
+
+ expect(generateFilterFormula(filters)).toEqual(expected);
+ });
+
+ it("should return a complex formula array with nested filters", () => {
+ const filters: CrudFilters = [
+ {
+ operator: "or",
+ value: [
+ { field: "name", operator: "eq", value: "John" },
+ { field: "name", operator: "eq", value: "Jane" },
+ ],
+ },
+ { field: "age", operator: "gte", value: 30 },
+ ];
+ const expected = [
+ [
+ "OR",
+ ["=", { field: "name" }, "John"],
+ ["=", { field: "name" }, "Jane"],
+ ],
+ [">=", { field: "age" }, 30],
+ ];
+
+ expect(generateFilterFormula(filters)).toEqual(expected);
+ });
+});
diff --git a/packages/airtable/test/utils/generateLogicalFilterFormula.spec.ts b/packages/airtable/test/utils/generateLogicalFilterFormula.spec.ts
new file mode 100644
index 0000000..0cdb265
--- /dev/null
+++ b/packages/airtable/test/utils/generateLogicalFilterFormula.spec.ts
@@ -0,0 +1,58 @@
+import { CrudFilter } from "@refinedev/core";
+
+import { generateLogicalFilterFormula } from "../../src/utils";
+import { LogicalFilter } from "@refinedev/core";
+
+describe("generateLogicalFilterFormula", () => {
+ it("should generate a formula for simple operators", () => {
+ const filter: CrudFilter = {
+ field: "age",
+ operator: "gte",
+ value: 30,
+ };
+ const expected = [">=", { field: "age" }, 30];
+
+ expect(generateLogicalFilterFormula(filter)).toEqual(expected);
+ });
+
+ it("should generate a formula for contains operators", () => {
+ const filter: CrudFilter = {
+ field: "name",
+ operator: "contains",
+ value: "John",
+ };
+ const expected = [
+ "!=",
+ ["FIND", ["LOWER", "John"], ["LOWER", { field: "name" }]],
+ 0,
+ ];
+
+ expect(generateLogicalFilterFormula(filter)).toEqual(expected);
+ });
+
+ it("should generate a formula for null operators", () => {
+ const filter = { field: "email", operator: "null" } as LogicalFilter;
+ const expected = ["=", { field: "email" }, ["BLANK"]];
+
+ expect(generateLogicalFilterFormula(filter)).toEqual(expected);
+ });
+
+ it("should generate a formula for nnull operators", () => {
+ const filter = { field: "email", operator: "nnull" } as LogicalFilter;
+ const expected = ["!=", { field: "email" }, ["BLANK"]];
+
+ expect(generateLogicalFilterFormula(filter)).toEqual(expected);
+ });
+
+ it("should throw an error for unsupported operators", () => {
+ const filter = {
+ field: "age",
+ operator: "unsupported",
+ value: 30,
+ } as unknown as LogicalFilter;
+
+ expect(() => generateLogicalFilterFormula(filter)).toThrowError(
+ "Operator unsupported is not supported for the Airtable data provider",
+ );
+ });
+});
diff --git a/packages/airtable/test/utils/generateSort.spec.ts b/packages/airtable/test/utils/generateSort.spec.ts
new file mode 100644
index 0000000..dced631
--- /dev/null
+++ b/packages/airtable/test/utils/generateSort.spec.ts
@@ -0,0 +1,22 @@
+import { CrudSorting } from "@refinedev/core";
+import { generateSort } from "../../src/utils";
+
+describe("generateSort", () => {
+ it("should return undefined if no sorters are provided", () => {
+ expect(generateSort(undefined)).toBeUndefined();
+ });
+
+ it("should generate an array of sorting objects", () => {
+ const sorters: CrudSorting = [
+ { field: "name", order: "asc" },
+ { field: "age", order: "desc" },
+ ];
+
+ const expected = [
+ { field: "name", direction: "asc" },
+ { field: "age", direction: "desc" },
+ ];
+
+ expect(generateSort(sorters)).toEqual(expected);
+ });
+});
diff --git a/packages/airtable/test/utils/isContainsOperator.spec.ts b/packages/airtable/test/utils/isContainsOperator.spec.ts
new file mode 100644
index 0000000..fc5c29b
--- /dev/null
+++ b/packages/airtable/test/utils/isContainsOperator.spec.ts
@@ -0,0 +1,31 @@
+import { isContainssOperator, isContainsOperator } from "../../src/utils";
+
+describe("Operators", () => {
+ describe("isContainssOperator", () => {
+ it("should return true if operator is containss", () => {
+ expect(isContainssOperator("containss")).toBe(true);
+ });
+
+ it("should return true if operator is ncontainss", () => {
+ expect(isContainssOperator("ncontainss")).toBe(true);
+ });
+
+ it("should return false if operator is not containss or ncontainss", () => {
+ expect(isContainssOperator("contains")).toBe(false);
+ });
+ });
+
+ describe("isContainsOperator", () => {
+ it("should return true if operator is contains", () => {
+ expect(isContainsOperator("contains")).toBe(true);
+ });
+
+ it("should return true if operator is ncontains", () => {
+ expect(isContainsOperator("ncontains")).toBe(true);
+ });
+
+ it("should return false if operator is not contains or ncontains", () => {
+ expect(isContainsOperator("containss")).toBe(false);
+ });
+ });
+});
diff --git a/packages/airtable/test/utils/isSimpleOperator.spec.ts b/packages/airtable/test/utils/isSimpleOperator.spec.ts
new file mode 100644
index 0000000..f815ca7
--- /dev/null
+++ b/packages/airtable/test/utils/isSimpleOperator.spec.ts
@@ -0,0 +1,30 @@
+import { isSimpleOperator, simpleOperatorMapping } from "../../src/utils";
+
+describe("SimpleOperators", () => {
+ describe("isSimpleOperator", () => {
+ it("should return true if operator is a simple operator", () => {
+ expect(isSimpleOperator("eq")).toBe(true);
+ expect(isSimpleOperator("ne")).toBe(true);
+ expect(isSimpleOperator("lt")).toBe(true);
+ expect(isSimpleOperator("lte")).toBe(true);
+ expect(isSimpleOperator("gt")).toBe(true);
+ expect(isSimpleOperator("gte")).toBe(true);
+ });
+
+ it("should return false if operator is not a simple operator", () => {
+ expect(isSimpleOperator("contains")).toBe(false);
+ expect(isSimpleOperator("containss")).toBe(false);
+ });
+ });
+
+ describe("simpleOperatorMapping", () => {
+ it("should map simple operators to their corresponding Airtable symbols", () => {
+ expect(simpleOperatorMapping["eq"]).toBe("=");
+ expect(simpleOperatorMapping["ne"]).toBe("!=");
+ expect(simpleOperatorMapping["lt"]).toBe("<");
+ expect(simpleOperatorMapping["lte"]).toBe("<=");
+ expect(simpleOperatorMapping["gt"]).toBe(">");
+ expect(simpleOperatorMapping["gte"]).toBe(">=");
+ });
+ });
+});
diff --git a/packages/airtable/tsconfig.declarations.json b/packages/airtable/tsconfig.declarations.json
new file mode 100644
index 0000000..53758e8
--- /dev/null
+++ b/packages/airtable/tsconfig.declarations.json
@@ -0,0 +1,21 @@
+{
+ "extends": "./tsconfig.json",
+ "exclude": [
+ "node_modules",
+ "dist",
+ "test",
+ "../test/**/*",
+ "**/*.spec.ts",
+ "**/*.test.ts",
+ "**/*.spec.tsx",
+ "**/*.test.tsx"
+ ],
+ "compilerOptions": {
+ "outDir": "dist",
+ "declarationDir": "dist",
+ "declaration": true,
+ "emitDeclarationOnly": true,
+ "noEmit": false,
+ "declarationMap": true
+ }
+}
diff --git a/packages/airtable/tsconfig.json b/packages/airtable/tsconfig.json
new file mode 100644
index 0000000..84dec47
--- /dev/null
+++ b/packages/airtable/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "include": ["src", "types", "refine.config.js"],
+ "extends": "../../tsconfig.build.json",
+ "compilerOptions": {
+ "rootDir": "./src",
+ "baseUrl": "."
+ }
+}
diff --git a/packages/airtable/tsup.config.ts b/packages/airtable/tsup.config.ts
new file mode 100644
index 0000000..12c9fbc
--- /dev/null
+++ b/packages/airtable/tsup.config.ts
@@ -0,0 +1,24 @@
+import { defineConfig } from "tsup";
+import { NodeResolvePlugin } from "@esbuild-plugins/node-resolve";
+
+export default defineConfig({
+ entry: ["src/index.ts"],
+ splitting: false,
+ sourcemap: true,
+ clean: false,
+ platform: "browser",
+ esbuildPlugins: [
+ NodeResolvePlugin({
+ extensions: [".js", "ts", "tsx", "jsx"],
+ onResolved: (resolved) => {
+ if (resolved.includes("node_modules")) {
+ return {
+ external: true,
+ };
+ }
+ return resolved;
+ },
+ }),
+ ],
+ onSuccess: "tsc --project tsconfig.declarations.json",
+});
diff --git a/packages/antd/.npmignore b/packages/antd/.npmignore
new file mode 100644
index 0000000..3321cad
--- /dev/null
+++ b/packages/antd/.npmignore
@@ -0,0 +1,11 @@
+node_modules
+.DS_Store
+test
+jest.config.js
+**/*.spec.ts
+**/*.spec.tsx
+**/*.test.ts
+**/*.test.tsx
+tsup.config.ts
+tsconfig.test.json
+tsconfig.declarations.json
\ No newline at end of file
diff --git a/packages/antd/.npmrc b/packages/antd/.npmrc
new file mode 100644
index 0000000..e9ee3cb
--- /dev/null
+++ b/packages/antd/.npmrc
@@ -0,0 +1 @@
+legacy-peer-deps=true
\ No newline at end of file
diff --git a/packages/antd/CHANGELOG.md b/packages/antd/CHANGELOG.md
new file mode 100644
index 0000000..54d0aa6
--- /dev/null
+++ b/packages/antd/CHANGELOG.md
@@ -0,0 +1,3380 @@
+# @refinedev/antd
+
+## 5.37.2
+
+### Patch Changes
+
+- [#5465](https://github.com/refinedev/refine/pull/5465) [`00e00cbd98`](https://github.com/refinedev/refine/commit/00e00cbd98c34046ab83b299ede83401ae74fec1) Thanks [@aliemir](https://github.com/aliemir)! - Fixed the type issue between `remark-gfm` and `react-markdown`. #5463
+
+## 5.37.1
+
+### Patch Changes
+
+- [#5425](https://github.com/refinedev/refine/pull/5425) [`190af9fce2`](https://github.com/refinedev/refine/commit/190af9fce292bc46b169e3e121be6bf1c2a939a5) Thanks [@aliemir](https://github.com/aliemir)! - Updated `@refinedev/core` peer dependencies to latest (`^4.46.1`)
+
+- Updated dependencies [[`190af9fce2`](https://github.com/refinedev/refine/commit/190af9fce292bc46b169e3e121be6bf1c2a939a5)]:
+ - @refinedev/ui-types@1.22.4
+
+## 5.37.0
+
+### Minor Changes
+
+- [#5307](https://github.com/refinedev/refine/pull/5307) [`f8e407f850`](https://github.com/refinedev/refine/commit/f8e407f85054bccf1e6ff45c84928bc01db7f5eb) Thanks [@jackprogramsjp](https://github.com/jackprogramsjp)! - feat: added `hideForm` props for `LoginPage` and `RegisterPage` for `AuthPage` feature.
+
+ Now with the `hideForm` props feature, you can be able to hide the forms (like email/password)
+ to only show the OAuth providers. This avoids having to make your own entire AuthPage.
+
+### Patch Changes
+
+- [#5207](https://github.com/refinedev/refine/pull/5207) [`30a2834a81`](https://github.com/refinedev/refine/commit/30a2834a819ef857506b5c932500868e458fd319) Thanks [@mjomble](https://github.com/mjomble)! - chore: updated deprecated use of antd Progress
+
+- [#5269](https://github.com/refinedev/refine/pull/5269) [`a23a0945d3`](https://github.com/refinedev/refine/commit/a23a0945d3fe003ae081fca1c47312dd6bf8c2ee) Thanks [@BatuhanW](https://github.com/BatuhanW)! - feat: add "autoComplete" field for Login pages.
+
+- [#5325](https://github.com/refinedev/refine/pull/5325) [`7ff54b2060`](https://github.com/refinedev/refine/commit/7ff54b2060b0ce942c4170f744cbdf52d0940434) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - fix: `` styling issues on mobile screens.
+
+ chore: new tests are added to ``.
+
+## 5.36.19
+
+### Patch Changes
+
+- [#5259](https://github.com/refinedev/refine/pull/5259) [`eac3df87ffb`](https://github.com/refinedev/refine/commit/eac3df87ffbf61c913a6c8ea584e1d8c61e8d82e) Thanks [@aliemir](https://github.com/aliemir)! - Updated `` component to extend the `` from `@refinedev/core` with custom elements and render appropriate element based on the state.
+
+## 5.36.18
+
+### Patch Changes
+
+- [#5199](https://github.com/refinedev/refine/pull/5199) [`2b8d658a17a`](https://github.com/refinedev/refine/commit/2b8d658a17a20ae347ba92b63487418f04ec255c) Thanks [@aliemir](https://github.com/aliemir)! - Now `useSelect`, `useRadioGroup` and `useCheckboxGroup` hooks accept 4th generic type `TOption` which allows you to change the type of options. By default `TOption` will be equal to `BaseOption` type which is `{ label: any; value: any; }`. If you want to change the type of options, you can do it like this:
+
+ ```tsx
+ import { useSelect } from "@refinedev/antd";
+ import { HttpError } from "@refinedev/core";
+
+ type MyData = {
+ id: number;
+ title: string;
+ description: string;
+ category: { id: string };
+ };
+
+ type Option = { label: MyData["title"]; value: MyData["id"] }; // equals to { label: string; value: number; }
+
+ useSelect({
+ resource: "posts",
+ });
+ ```
+
+- [#5199](https://github.com/refinedev/refine/pull/5199) [`2b8d658a17a`](https://github.com/refinedev/refine/commit/2b8d658a17a20ae347ba92b63487418f04ec255c) Thanks [@aliemir](https://github.com/aliemir)! - Updated return types of `useSelect`, `useRadioGroup` and `useCheckboxGroup` hooks to only include properties that actually being returned from the hook. Previously, the return types included all properties of the respective components, which was not correct.
+
+- [#5201](https://github.com/refinedev/refine/pull/5201) [`760cfbaaa2a`](https://github.com/refinedev/refine/commit/760cfbaaa2ac8b8c070ade1e174784358cc112b0) Thanks [@aliemir](https://github.com/aliemir)! - Handle nested server side validation errors properly in `useForm`
+
+## 5.36.17
+
+### Patch Changes
+
+- [#5199](https://github.com/refinedev/refine/pull/5199) [`2b8d658a17a`](https://github.com/refinedev/refine/commit/2b8d658a17a20ae347ba92b63487418f04ec255c) Thanks [@aliemir](https://github.com/aliemir)! - Now `useSelect`, `useRadioGroup` and `useCheckboxGroup` hooks accept 4th generic type `TOption` which allows you to change the type of options. By default `TOption` will be equal to `BaseOption` type which is `{ label: any; value: any; }`. If you want to change the type of options, you can do it like this:
+
+ ```tsx
+ import { useSelect } from "@refinedev/antd";
+ import { HttpError } from "@refinedev/core";
+
+ type MyData = {
+ id: number;
+ title: string;
+ description: string;
+ category: { id: string };
+ };
+
+ type Option = { label: MyData["title"]; value: MyData["id"] }; // equals to { label: string; value: number; }
+
+ useSelect({
+ resource: "posts",
+ });
+ ```
+
+- [#5199](https://github.com/refinedev/refine/pull/5199) [`2b8d658a17a`](https://github.com/refinedev/refine/commit/2b8d658a17a20ae347ba92b63487418f04ec255c) Thanks [@aliemir](https://github.com/aliemir)! - Updated return types of `useSelect`, `useRadioGroup` and `useCheckboxGroup` hooks to only include properties that actually being returned from the hook. Previously, the return types included all properties of the respective components, which was not correct.
+
+- [#5201](https://github.com/refinedev/refine/pull/5201) [`760cfbaaa2a`](https://github.com/refinedev/refine/commit/760cfbaaa2ac8b8c070ade1e174784358cc112b0) Thanks [@aliemir](https://github.com/aliemir)! - Handle nested server side validation errors properly in `useForm`
+
+## 5.36.16
+
+### Patch Changes
+
+- [#5189](https://github.com/refinedev/refine/pull/5189) [`34b5741289f`](https://github.com/refinedev/refine/commit/34b5741289fec9f1bf1e06b101d1c0965fc5c7e7) Thanks [@BatuhanW](https://github.com/BatuhanW)! - chore: bump @ant-design/pro-layout dependency to `v7.17.12`.
+
+ Fixes https://github.com/refinedev/refine/issues/5172
+
+## 5.36.15
+
+### Patch Changes
+
+- [#5189](https://github.com/refinedev/refine/pull/5189) [`34b5741289f`](https://github.com/refinedev/refine/commit/34b5741289fec9f1bf1e06b101d1c0965fc5c7e7) Thanks [@BatuhanW](https://github.com/BatuhanW)! - chore: bump @ant-design/pro-layout dependency to `v7.17.12`.
+
+ Fixes https://github.com/refinedev/refine/issues/5172
+
+## 5.36.14
+
+### Patch Changes
+
+- [#5134](https://github.com/refinedev/refine/pull/5134) [`e4769b23171`](https://github.com/refinedev/refine/commit/e4769b231716c63e5814718942025044e1a213c3) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - fixed: antd default `` is not collapsing.
+
+## 5.36.13
+
+### Patch Changes
+
+- [#5134](https://github.com/refinedev/refine/pull/5134) [`e4769b23171`](https://github.com/refinedev/refine/commit/e4769b231716c63e5814718942025044e1a213c3) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - fixed: antd default `` is not collapsing.
+
+## 5.36.12
+
+### Patch Changes
+
+- [#5114](https://github.com/refinedev/refine/pull/5114) [`00a9252c5de`](https://github.com/refinedev/refine/commit/00a9252c5de86aad544b0ca7d087c532c6d561fa) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - fixed: `` border-bottom removed.
+ fixed: `` glitches on first render.
+
+## 5.36.11
+
+### Patch Changes
+
+- [#5114](https://github.com/refinedev/refine/pull/5114) [`00a9252c5de`](https://github.com/refinedev/refine/commit/00a9252c5de86aad544b0ca7d087c532c6d561fa) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - fixed: `` border-bottom removed.
+ fixed: `` glitches on first render.
+
+## 5.36.10
+
+### Patch Changes
+
+- [#5098](https://github.com/refinedev/refine/pull/5098) [`672f7916af7`](https://github.com/refinedev/refine/commit/672f7916af74ed0d62eb806fde35fd7e56000b23) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - fix: `undoableNotification` does not work when using `useNotificationProvider` due to a different `notification` instance.
+
+## 5.36.9
+
+### Patch Changes
+
+- [#5098](https://github.com/refinedev/refine/pull/5098) [`672f7916af7`](https://github.com/refinedev/refine/commit/672f7916af74ed0d62eb806fde35fd7e56000b23) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - fix: `undoableNotification` does not work when using `useNotificationProvider` due to a different `notification` instance.
+
+## 5.36.8
+
+### Patch Changes
+
+- [#4945](https://github.com/refinedev/refine/pull/4945) [`b838412f0d0`](https://github.com/refinedev/refine/commit/b838412f0d0b790ba95f3c07a899a021d3cd2c84) Thanks [@MahirMahdi](https://github.com/MahirMahdi)! - fix: antd notificationProvider issue
+
+ Antd notification component could not access theme context, now it's fixed.
+
+ This release provides an alternative to exported `notificationProvider` value from type `NotificationProvider` to `() => NotificationProvider`. If you previously had customizations applied to the `notificationProvider` object, you may need to update your code like the following:
+
+ ```diff
+ - import { notificationProvider } from "@refinedev/antd";
+ + import { useNotificationProvider } from "@refinedev/antd";
+ + import { App as AntdApp } from "antd";
+
+ - const myNotificationProvider = {
+ - ...notificationProvider,
+ - open: (...args) => {
+ - // do some operation here
+ - notificationProvider.open(...args);
+ - },
+ - }
+ + const myNotificationProvider = () => {
+ + const notificationProvider = useNotificationProvider();
+ + return {
+ + ...notificationProvider,
+ + open: (...args) => {
+ + // do some operation here
+ + notificationProvider.open(...args);
+ + },
+ + }
+ + }
+ }
+
+ const App = () => {
+ return (
+ +
+
+ /* ... */
+
+ +
+ );
+ }
+ ```
+
+## 5.36.7
+
+### Patch Changes
+
+- [#4945](https://github.com/refinedev/refine/pull/4945) [`b838412f0d0`](https://github.com/refinedev/refine/commit/b838412f0d0b790ba95f3c07a899a021d3cd2c84) Thanks [@MahirMahdi](https://github.com/MahirMahdi)! - fix: antd notificationProvider issue
+
+ Antd notification component could not access theme context, now it's fixed.
+
+ This release provides an alternative to exported `notificationProvider` value from type `NotificationProvider` to `() => NotificationProvider`. If you previously had customizations applied to the `notificationProvider` object, you may need to update your code like the following:
+
+ ```diff
+ - import { notificationProvider } from "@refinedev/antd";
+ + import { useNotificationProvider } from "@refinedev/antd";
+ + import { App as AntdApp } from "antd";
+
+ - const myNotificationProvider = {
+ - ...notificationProvider,
+ - open: (...args) => {
+ - // do some operation here
+ - notificationProvider.open(...args);
+ - },
+ - }
+ + const myNotificationProvider = () => {
+ + const notificationProvider = useNotificationProvider();
+ + return {
+ + ...notificationProvider,
+ + open: (...args) => {
+ + // do some operation here
+ + notificationProvider.open(...args);
+ + },
+ + }
+ + }
+ }
+
+ const App = () => {
+ return (
+ +
+
+ /* ... */
+
+ +
+ );
+ }
+ ```
+
+## 5.36.6
+
+### Patch Changes
+
+- [#5026](https://github.com/refinedev/refine/pull/5026) [`a605e4cd318`](https://github.com/refinedev/refine/commit/a605e4cd318ed5542b46e9e11a86f2c75dbb694b) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: deprecated `` and `` components removed from `swizzle`.
+ From now on, users can swizzle `` component instead.
+
+ feat: swizzled `` component destination changed to `src/components/layout/` from `src/components/themedLayout`.
+
+## 5.36.5
+
+### Patch Changes
+
+- [#5026](https://github.com/refinedev/refine/pull/5026) [`a605e4cd318`](https://github.com/refinedev/refine/commit/a605e4cd318ed5542b46e9e11a86f2c75dbb694b) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: deprecated `` and `` components removed from `swizzle`.
+ From now on, users can swizzle `` component instead.
+
+ feat: swizzled `` component destination changed to `src/components/layout/` from `src/components/themedLayout`.
+
+## 5.36.4
+
+### Patch Changes
+
+- [#5022](https://github.com/refinedev/refine/pull/5022) [`80513a4e42f`](https://github.com/refinedev/refine/commit/80513a4e42f8dda39e01157643594a9e4c32001b) Thanks [@BatuhanW](https://github.com/BatuhanW)! - chore: update README.md
+
+ - fix grammar errors.
+ - make all README.md files consistent.
+ - add code example code snippets.
+
+## 5.36.3
+
+### Patch Changes
+
+- [#5022](https://github.com/refinedev/refine/pull/5022) [`80513a4e42f`](https://github.com/refinedev/refine/commit/80513a4e42f8dda39e01157643594a9e4c32001b) Thanks [@BatuhanW](https://github.com/BatuhanW)! - chore: update README.md
+
+ - fix grammar errors.
+ - make all README.md files consistent.
+ - add code example code snippets.
+
+## 5.36.2
+
+### Patch Changes
+
+- [#4964](https://github.com/refinedev/refine/pull/4964) [`85b1ac0db5f`](https://github.com/refinedev/refine/commit/85b1ac0db5f8e61c7a78137aed0adf4bf2871848) Thanks [@BatuhanW](https://github.com/BatuhanW)! - chore: update @refinedev/core peer dependency versions.
+
+## 5.36.1
+
+### Patch Changes
+
+- [#4964](https://github.com/refinedev/refine/pull/4964) [`85b1ac0db5f`](https://github.com/refinedev/refine/commit/85b1ac0db5f8e61c7a78137aed0adf4bf2871848) Thanks [@BatuhanW](https://github.com/BatuhanW)! - chore: update @refinedev/core peer dependency versions.
+
+## 5.36.0
+
+### Minor Changes
+
+- [#4914](https://github.com/refinedev/refine/pull/4914) [`91a4d0da9f1`](https://github.com/refinedev/refine/commit/91a4d0da9f180ae358a448c7d187cee44f8c2299) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: [`optimisticUpdateMap`](https://refine.dev/docs/api-reference/core/hooks/data/useUpdate/#optimisticupdatemap) prop added to `useForm` hook. This prop allows you to update the data in the cache.
+
+ ```tsx
+ useForm({
+ mutationMode: "optimistic",
+ optimisticUpdateMap: {
+ list: true,
+ many: true,
+ detail: (previous, values, id) => {
+ if (!previous) {
+ return null;
+ }
+
+ const data = {
+ id,
+ ...previous.data,
+ ...values,
+ foo: "bar",
+ };
+
+ return {
+ ...previous,
+ data,
+ };
+ },
+ },
+ });
+ ```
+
+### Patch Changes
+
+- [#4903](https://github.com/refinedev/refine/pull/4903) [`e327cadc011`](https://github.com/refinedev/refine/commit/e327cadc011ce8696d7149252e1ad308005b1eff) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - fix: when using [`useForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useForm/), `autoSave` parameters not passed to `@refinedev/core/useForm` hook.
+ From now on, you can use `autoSave` parameters in [`useForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useForm/) hook.
+
+ feat: add `invalidateOnUnmount` prop to [`useForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useForm/) hook.
+ feat: add `invalidateOnUnmount` and `invalidateOnClose` prop to [`useModalForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useModalForm/) and [`useDrawerForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useDrawerForm/) hooks.
+ From now on, you can use the use this props to invalidate queries upon unmount or close.
+
+## 5.35.0
+
+### Minor Changes
+
+- [#4914](https://github.com/refinedev/refine/pull/4914) [`91a4d0da9f1`](https://github.com/refinedev/refine/commit/91a4d0da9f180ae358a448c7d187cee44f8c2299) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: [`optimisticUpdateMap`](https://refine.dev/docs/api-reference/core/hooks/data/useUpdate/#optimisticupdatemap) prop added to `useForm` hook. This prop allows you to update the data in the cache.
+
+ ```tsx
+ useForm({
+ mutationMode: "optimistic",
+ optimisticUpdateMap: {
+ list: true,
+ many: true,
+ detail: (previous, values, id) => {
+ if (!previous) {
+ return null;
+ }
+
+ const data = {
+ id,
+ ...previous.data,
+ ...values,
+ foo: "bar",
+ };
+
+ return {
+ ...previous,
+ data,
+ };
+ },
+ },
+ });
+ ```
+
+### Patch Changes
+
+- [#4903](https://github.com/refinedev/refine/pull/4903) [`e327cadc011`](https://github.com/refinedev/refine/commit/e327cadc011ce8696d7149252e1ad308005b1eff) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - fix: when using [`useForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useForm/), `autoSave` parameters not passed to `@refinedev/core/useForm` hook.
+ From now on, you can use `autoSave` parameters in [`useForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useForm/) hook.
+
+ feat: add `invalidateOnUnmount` prop to [`useForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useForm/) hook.
+ feat: add `invalidateOnUnmount` and `invalidateOnClose` prop to [`useModalForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useModalForm/) and [`useDrawerForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useDrawerForm/) hooks.
+ From now on, you can use the use this props to invalidate queries upon unmount or close.
+
+## 5.34.2
+
+### Patch Changes
+
+- [#4948](https://github.com/refinedev/refine/pull/4948) [`8e5efffbb23`](https://github.com/refinedev/refine/commit/8e5efffbb231bc3163c56f8e823ccb649755a9d4) Thanks [@aliemir](https://github.com/aliemir)! - Keep the hook and component names in builds for better debugging.
+
+## 5.34.1
+
+### Patch Changes
+
+- [#4948](https://github.com/refinedev/refine/pull/4948) [`8e5efffbb23`](https://github.com/refinedev/refine/commit/8e5efffbb231bc3163c56f8e823ccb649755a9d4) Thanks [@aliemir](https://github.com/aliemir)! - Keep the hook and component names in builds for better debugging.
+
+## 5.34.0
+
+### Minor Changes
+
+- [#4775](https://github.com/refinedev/refine/pull/4775) [`3052fb22449`](https://github.com/refinedev/refine/commit/3052fb22449c5e35c607e95c060c38ca48e00c82) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - fixed: `` does not refresh content #4618.
+ From now, `` uses `useInvalidate` hook to refresh data instead of `useOne`.
+
+### Patch Changes
+
+- [#4772](https://github.com/refinedev/refine/pull/4772) [`c9cc4398e99`](https://github.com/refinedev/refine/commit/c9cc4398e9996a49f7ee9c4c5656661a66b591ad) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - fixed: antd `useModalForm` and `useDrawerForm` sends request twice when `syncWithLocation` is true
+
+- [#4778](https://github.com/refinedev/refine/pull/4778) [`82909db10b4`](https://github.com/refinedev/refine/commit/82909db10b4ac1705e1354bff0c0d95951497725) Thanks [@salihozdemir](https://github.com/salihozdemir)! - fix: fixed the `goToStep` of `useStepsForm` hook return type
+
+- Updated dependencies [[`3052fb22449`](https://github.com/refinedev/refine/commit/3052fb22449c5e35c607e95c060c38ca48e00c82)]:
+ - @refinedev/ui-types@1.22.0
+
+## 5.33.0
+
+### Minor Changes
+
+- [#4775](https://github.com/refinedev/refine/pull/4775) [`3052fb22449`](https://github.com/refinedev/refine/commit/3052fb22449c5e35c607e95c060c38ca48e00c82) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - fixed: `` does not refresh content #4618.
+ From now, `` uses `useInvalidate` hook to refresh data instead of `useOne`.
+
+### Patch Changes
+
+- [#4772](https://github.com/refinedev/refine/pull/4772) [`c9cc4398e99`](https://github.com/refinedev/refine/commit/c9cc4398e9996a49f7ee9c4c5656661a66b591ad) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - fixed: antd `useModalForm` and `useDrawerForm` sends request twice when `syncWithLocation` is true
+
+- [#4778](https://github.com/refinedev/refine/pull/4778) [`82909db10b4`](https://github.com/refinedev/refine/commit/82909db10b4ac1705e1354bff0c0d95951497725) Thanks [@salihozdemir](https://github.com/salihozdemir)! - fix: fixed the `goToStep` of `useStepsForm` hook return type
+
+- Updated dependencies [[`3052fb22449`](https://github.com/refinedev/refine/commit/3052fb22449c5e35c607e95c060c38ca48e00c82)]:
+ - @refinedev/ui-types@1.21.0
+
+## 5.32.0
+
+### Minor Changes
+
+- [#4741](https://github.com/refinedev/refine/pull/4741) [`026ccf34356`](https://github.com/refinedev/refine/commit/026ccf34356bc621183894c0ee4518a6645369d1) Thanks [@aliemir](https://github.com/aliemir)! - Added `sideEffects` to `package.json` to help bundlers tree-shake unused code.
+
+### Patch Changes
+
+- [#4741](https://github.com/refinedev/refine/pull/4741) [`026ccf34356`](https://github.com/refinedev/refine/commit/026ccf34356bc621183894c0ee4518a6645369d1) Thanks [@aliemir](https://github.com/aliemir)! - Updated `DateField` to set `dayjs` extension in component instead of a global side effect.
+
+## 5.31.0
+
+### Minor Changes
+
+- [#4741](https://github.com/refinedev/refine/pull/4741) [`026ccf34356`](https://github.com/refinedev/refine/commit/026ccf34356bc621183894c0ee4518a6645369d1) Thanks [@aliemir](https://github.com/aliemir)! - Added `sideEffects` to `package.json` to help bundlers tree-shake unused code.
+
+### Patch Changes
+
+- [#4741](https://github.com/refinedev/refine/pull/4741) [`026ccf34356`](https://github.com/refinedev/refine/commit/026ccf34356bc621183894c0ee4518a6645369d1) Thanks [@aliemir](https://github.com/aliemir)! - Updated `DateField` to set `dayjs` extension in component instead of a global side effect.
+
+## 5.30.0
+
+### Minor Changes
+
+- [#4591](https://github.com/refinedev/refine/pull/4591) [`f8891ead2bd`](https://github.com/refinedev/refine/commit/f8891ead2bdb5f6743bbe9979230aa73ef3e69be) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: `autoSave` feature for [`Edit`](https://refine.dev/docs/api-reference/antd/components/basic-views/edit/#autosaveprops).
+ [useForm](https://refine.dev/docs/api-reference/antd/hooks/form/useForm/#autosave), [useDrawerForm](https://refine.dev/docs/api-reference/antd/hooks/form/useDrawerForm/#autosave), [useModalForm](https://refine.dev/docs/api-reference/antd/hooks/form/useModalForm/#autosave), [useStepsForm](https://refine.dev/docs/api-reference/antd/hooks/form/useStepsForm/#autosave) hooks now accept `autoSave` object. `enabled` is a boolean value and `debounce` is a number value in milliseconds. `debounce` is optional and default value is `1000`.
+
+ ```
+ const { autoSaveProps } = useForm({
+ autoSave: {
+ enabled: true,
+ debounce: 2000, // not required, default is 1000
+ },
+ });
+
+ return (
+
+ // form fields
+
+ );
+ ```
+
+ feat: Add [``](https://refine.dev/docs/api-reference/antd/components/antd-auto-save-indicator/) component. It comes automatically when `autoSaveProps` is given to the `Edit` page. However, this component can be used to position it in a different place.
+
+ ```
+ import { AutoSaveIndicator } from "@refinedev/antd";
+ const { autoSaveProps } = useForm({
+ autoSave: {
+ enabled: true,
+ debounce: 2000, // not required, default is 1000
+ },
+ });
+
+ return (
+
+
+
+ );
+ ```
+
+- [#4652](https://github.com/refinedev/refine/pull/4652) [`96af6d25b7a`](https://github.com/refinedev/refine/commit/96af6d25b7a870a3c1c6fd33c30e0ca2224ed411) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: when the `dataProvider` returns rejected promise with `errors` field, `useForm` will automatically update the error state with the rejected `errors` field.
+
+ [Refer to the server-side form validation documentation for more information. β](https://refine.dev/docs/advanced-tutorials/forms/server-side-form-validation/)
+
+### Patch Changes
+
+- Updated dependencies [[`f8891ead2bd`](https://github.com/refinedev/refine/commit/f8891ead2bdb5f6743bbe9979230aa73ef3e69be)]:
+ - @refinedev/ui-types@1.20.0
+
+## 5.29.0
+
+### Minor Changes
+
+- [#4591](https://github.com/refinedev/refine/pull/4591) [`f8891ead2bd`](https://github.com/refinedev/refine/commit/f8891ead2bdb5f6743bbe9979230aa73ef3e69be) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: `autoSave` feature for [`Edit`](https://refine.dev/docs/api-reference/antd/components/basic-views/edit/#autosaveprops).
+ [useForm](https://refine.dev/docs/api-reference/antd/hooks/form/useForm/#autosave), [useDrawerForm](https://refine.dev/docs/api-reference/antd/hooks/form/useDrawerForm/#autosave), [useModalForm](https://refine.dev/docs/api-reference/antd/hooks/form/useModalForm/#autosave), [useStepsForm](https://refine.dev/docs/api-reference/antd/hooks/form/useStepsForm/#autosave) hooks now accept `autoSave` object. `enabled` is a boolean value and `debounce` is a number value in milliseconds. `debounce` is optional and default value is `1000`.
+
+ ```
+ const { autoSaveProps } = useForm({
+ autoSave: {
+ enabled: true,
+ debounce: 2000, // not required, default is 1000
+ },
+ });
+
+ return (
+
+ // form fields
+
+ );
+ ```
+
+ feat: Add [``](https://refine.dev/docs/api-reference/antd/components/antd-auto-save-indicator/) component. It comes automatically when `autoSaveProps` is given to the `Edit` page. However, this component can be used to position it in a different place.
+
+ ```
+ import { AutoSaveIndicator } from "@refinedev/antd";
+ const { autoSaveProps } = useForm({
+ autoSave: {
+ enabled: true,
+ debounce: 2000, // not required, default is 1000
+ },
+ });
+
+ return (
+
+
+
+ );
+ ```
+
+- [#4652](https://github.com/refinedev/refine/pull/4652) [`96af6d25b7a`](https://github.com/refinedev/refine/commit/96af6d25b7a870a3c1c6fd33c30e0ca2224ed411) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: when the `dataProvider` returns rejected promise with `errors` field, `useForm` will automatically update the error state with the rejected `errors` field.
+
+ [Refer to the server-side form validation documentation for more information. β](https://refine.dev/docs/advanced-tutorials/forms/server-side-form-validation/)
+
+### Patch Changes
+
+- Updated dependencies [[`f8891ead2bd`](https://github.com/refinedev/refine/commit/f8891ead2bdb5f6743bbe9979230aa73ef3e69be)]:
+ - @refinedev/ui-types@1.19.0
+
+## 5.28.0
+
+### Minor Changes
+
+- [#4502](https://github.com/refinedev/refine/pull/4502) [`c7872ca621f`](https://github.com/refinedev/refine/commit/c7872ca621fdc6c0edd7ee113520bd898901ed38) Thanks [@Mr0nline](https://github.com/Mr0nline)! - feat: ability to tweak active sider items navigation
+
+ Visiting active sider items triggers page reloads due to them being links. We can now provide activeItemDisabled prop to disable such reloads.
+
+### Patch Changes
+
+- [#4607](https://github.com/refinedev/refine/pull/4607) [`fed630dcc3e`](https://github.com/refinedev/refine/commit/fed630dcc3ef291efbfa96ed6f8e5c5448ac16a6) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - test: added tests for ``.
+
+- [#4609](https://github.com/refinedev/refine/pull/4609) [`48aaf739352`](https://github.com/refinedev/refine/commit/48aaf739352c6d8edc21cb111cc871de8f68549e) Thanks [@salihozdemir](https://github.com/salihozdemir)! - fix: `icon` and `label` alignment in `Breadcrumb` component
+
+ Fixed the issue that the `icon` and `label` to be misaligned in the `Breadcrumb` component.
+
+- Updated dependencies [[`c7872ca621f`](https://github.com/refinedev/refine/commit/c7872ca621fdc6c0edd7ee113520bd898901ed38)]:
+ - @refinedev/ui-types@1.18.0
+
+## 5.27.0
+
+### Minor Changes
+
+- [#4502](https://github.com/refinedev/refine/pull/4502) [`c7872ca621f`](https://github.com/refinedev/refine/commit/c7872ca621fdc6c0edd7ee113520bd898901ed38) Thanks [@Mr0nline](https://github.com/Mr0nline)! - feat: ability to tweak active sider items navigation
+
+ Visiting active sider items triggers page reloads due to them being links. We can now provide activeItemDisabled prop to disable such reloads.
+
+### Patch Changes
+
+- [#4607](https://github.com/refinedev/refine/pull/4607) [`fed630dcc3e`](https://github.com/refinedev/refine/commit/fed630dcc3ef291efbfa96ed6f8e5c5448ac16a6) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - test: added tests for ``.
+
+- [#4609](https://github.com/refinedev/refine/pull/4609) [`48aaf739352`](https://github.com/refinedev/refine/commit/48aaf739352c6d8edc21cb111cc871de8f68549e) Thanks [@salihozdemir](https://github.com/salihozdemir)! - fix: `icon` and `label` alignment in `Breadcrumb` component
+
+ Fixed the issue that the `icon` and `label` to be misaligned in the `Breadcrumb` component.
+
+- Updated dependencies [[`c7872ca621f`](https://github.com/refinedev/refine/commit/c7872ca621fdc6c0edd7ee113520bd898901ed38)]:
+ - @refinedev/ui-types@1.17.0
+
+## 5.26.0
+
+### Minor Changes
+
+- [#4523](https://github.com/refinedev/refine/pull/4523) [`18d446b1069`](https://github.com/refinedev/refine/commit/18d446b1069c75b5033d0ce8defcb8c32fcce5cf) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: implement following hooks have `useLoadingOvertime` hook
+
+ - [`useSelect`](https://refine.dev/docs/api-reference/antd/hooks/field/useSelect/#overtimeoptions)
+ - [`useDrawerForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useDrawerForm/#overtimeoptions)
+ - [`useForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useForm/#overtimeoptions)
+ - [`useModalForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useModalForm/#overtimeoptions)
+ - [`useStepsForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useStepsForm/#overtimeoptions)
+ - [`useSimpleList`](https://refine.dev/docs/api-reference/antd/hooks/list/useSimpleList/#overtimeoptions)
+ - [`useTable`](https://refine.dev/docs/api-reference/antd/hooks/table/useTable/#overtimeoptions)
+
+### Patch Changes
+
+- [#4527](https://github.com/refinedev/refine/pull/4527) [`ceadcd29fc9`](https://github.com/refinedev/refine/commit/ceadcd29fc9e42c875a4b0a78622e9fc14b4ce42) Thanks [@salihozdemir](https://github.com/salihozdemir)! - fix: prioritization of forgotten `identifier`
+
+ If `identifier` is provided, it will be used instead of `name`.
+
+ ```tsx
+ import { DeleteButton } from "@refinedev/antd";
+
+ ;
+ ```
+
+ fix: use translate keys with `identifier`
+
+ Previously, the translate keys were generated using resource `name`. This caused issues when you had multiple `resource` usage with the same name. Now the `translate` keys are generated using `identifier` if it's present.
+
+## 5.25.0
+
+### Minor Changes
+
+- [#4523](https://github.com/refinedev/refine/pull/4523) [`18d446b1069`](https://github.com/refinedev/refine/commit/18d446b1069c75b5033d0ce8defcb8c32fcce5cf) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: implement following hooks have `useLoadingOvertime` hook
+
+ - [`useSelect`](https://refine.dev/docs/api-reference/antd/hooks/field/useSelect/#overtimeoptions)
+ - [`useDrawerForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useDrawerForm/#overtimeoptions)
+ - [`useForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useForm/#overtimeoptions)
+ - [`useModalForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useModalForm/#overtimeoptions)
+ - [`useStepsForm`](https://refine.dev/docs/api-reference/antd/hooks/form/useStepsForm/#overtimeoptions)
+ - [`useSimpleList`](https://refine.dev/docs/api-reference/antd/hooks/list/useSimpleList/#overtimeoptions)
+ - [`useTable`](https://refine.dev/docs/api-reference/antd/hooks/table/useTable/#overtimeoptions)
+
+### Patch Changes
+
+- [#4527](https://github.com/refinedev/refine/pull/4527) [`ceadcd29fc9`](https://github.com/refinedev/refine/commit/ceadcd29fc9e42c875a4b0a78622e9fc14b4ce42) Thanks [@salihozdemir](https://github.com/salihozdemir)! - fix: prioritization of forgotten `identifier`
+
+ If `identifier` is provided, it will be used instead of `name`.
+
+ ```tsx
+ import { DeleteButton } from "@refinedev/antd";
+
+ ;
+ ```
+
+ fix: use translate keys with `identifier`
+
+ Previously, the translate keys were generated using resource `name`. This caused issues when you had multiple `resource` usage with the same name. Now the `translate` keys are generated using `identifier` if it's present.
+
+## 5.24.0
+
+### Minor Changes
+
+- [#4449](https://github.com/refinedev/refine/pull/4449) [`cc84d61bc5c`](https://github.com/refinedev/refine/commit/cc84d61bc5c8cfc8ac7da391f965471ecad6c445) Thanks [@BatuhanW](https://github.com/BatuhanW)! - feat: updated Create, List, Show, Edit, Delete, Clone buttons to respect new global `accessControlProvider` configuration.
+
+ fix: Delete button's text wasn't rendered as `reason` field of `accessControlProvider`.
+
+ Given the following `can` method:
+
+ ```ts
+ const accessControlProvider: IAccessControlContext = {
+ can: async (): Promise => {
+ return { can: false, reason: "Access Denied!" };
+ },
+ };
+ ```
+
+ If user is unauthorized, `Delete` button's text should be `Access Denied!` instead of default `Delete`.
+
+ This is the default behaviour for Create, List, Show, Edit, Delete, Clone buttons already.
+
+## 5.23.0
+
+### Minor Changes
+
+- [#4449](https://github.com/refinedev/refine/pull/4449) [`cc84d61bc5c`](https://github.com/refinedev/refine/commit/cc84d61bc5c8cfc8ac7da391f965471ecad6c445) Thanks [@BatuhanW](https://github.com/BatuhanW)! - feat: updated Create, List, Show, Edit, Delete, Clone buttons to respect new global `accessControlProvider` configuration.
+
+ fix: Delete button's text wasn't rendered as `reason` field of `accessControlProvider`.
+
+ Given the following `can` method:
+
+ ```ts
+ const accessControlProvider: IAccessControlContext = {
+ can: async (): Promise => {
+ return { can: false, reason: "Access Denied!" };
+ },
+ };
+ ```
+
+ If user is unauthorized, `Delete` button's text should be `Access Denied!` instead of default `Delete`.
+
+ This is the default behaviour for Create, List, Show, Edit, Delete, Clone buttons already.
+
+## 5.22.0
+
+### Minor Changes
+
+- [#4430](https://github.com/refinedev/refine/pull/4430) [`cf07d59587f`](https://github.com/refinedev/refine/commit/cf07d59587fae2adce97a79b40fdb60b9d9a9527) Thanks [@aliemir](https://github.com/aliemir)! - Updated the `useForm`, `useModalForm`, `useDrawerForm` and `useStepsForm` to accept `queryMeta` and `mutationMeta` properties of the `useForm` hook of `@refinedev/core`. These properties are used to pass specific meta values to the query or mutation. This is useful when you have overlapping values in your data provider's `getOne` and `update` methods. For example, you may want to change the `method` of the mutation to `PATCH` but if you pass it in the `meta` property, you'll end up changing the method of the `getOne` request as well.
+
+ `queryMeta` and `mutationMeta` has precedence over `meta`. This means that if you have the same property in `queryMeta` and `meta`, the value in `queryMeta` will be used.
+
+ **Usage**
+
+ ```tsx
+ import { useForm } from "@refinedev/core";
+
+ export const MyEditPage = () => {
+ const form = useForm({
+ // this is passed both to the mutation and the query requests
+ meta: {
+ myValue: "myValue",
+ },
+ // this is only passed to the query request
+ queryMeta: {
+ propertyOnlyWorksForQuery: "propertyOnlyWorksForQuery",
+ },
+ // this is only passed to the mutation request
+ mutationMeta: {
+ propertyOnlyWorksForMutation: "propertyOnlyWorksForMutation",
+ },
+ });
+ };
+ ```
+
+### Patch Changes
+
+- [#4429](https://github.com/refinedev/refine/pull/4429) [`63daabcb703`](https://github.com/refinedev/refine/commit/63daabcb7037860bc36dff8cc417e9426e9ec027) Thanks [@aliemir](https://github.com/aliemir)! - Fixed the issue of `formLoading` property in return values of `useStepsForm` hook which was not being toggled correctly when the form was submitted or the form data was being fetched.
+
+- [#4431](https://github.com/refinedev/refine/pull/4431) [`c29a3618cf6`](https://github.com/refinedev/refine/commit/c29a3618cf6b577c36e90ec514f3a691c87aad8f) Thanks [@aliemir](https://github.com/aliemir)! - Updated the TSDoc comments to fix the broken links in the documentation.
+
+## 5.21.0
+
+### Minor Changes
+
+- [#4430](https://github.com/refinedev/refine/pull/4430) [`cf07d59587f`](https://github.com/refinedev/refine/commit/cf07d59587fae2adce97a79b40fdb60b9d9a9527) Thanks [@aliemir](https://github.com/aliemir)! - Updated the `useForm`, `useModalForm`, `useDrawerForm` and `useStepsForm` to accept `queryMeta` and `mutationMeta` properties of the `useForm` hook of `@refinedev/core`. These properties are used to pass specific meta values to the query or mutation. This is useful when you have overlapping values in your data provider's `getOne` and `update` methods. For example, you may want to change the `method` of the mutation to `PATCH` but if you pass it in the `meta` property, you'll end up changing the method of the `getOne` request as well.
+
+ `queryMeta` and `mutationMeta` has precedence over `meta`. This means that if you have the same property in `queryMeta` and `meta`, the value in `queryMeta` will be used.
+
+ **Usage**
+
+ ```tsx
+ import { useForm } from "@refinedev/core";
+
+ export const MyEditPage = () => {
+ const form = useForm({
+ // this is passed both to the mutation and the query requests
+ meta: {
+ myValue: "myValue",
+ },
+ // this is only passed to the query request
+ queryMeta: {
+ propertyOnlyWorksForQuery: "propertyOnlyWorksForQuery",
+ },
+ // this is only passed to the mutation request
+ mutationMeta: {
+ propertyOnlyWorksForMutation: "propertyOnlyWorksForMutation",
+ },
+ });
+ };
+ ```
+
+### Patch Changes
+
+- [#4429](https://github.com/refinedev/refine/pull/4429) [`63daabcb703`](https://github.com/refinedev/refine/commit/63daabcb7037860bc36dff8cc417e9426e9ec027) Thanks [@aliemir](https://github.com/aliemir)! - Fixed the issue of `formLoading` property in return values of `useStepsForm` hook which was not being toggled correctly when the form was submitted or the form data was being fetched.
+
+- [#4431](https://github.com/refinedev/refine/pull/4431) [`c29a3618cf6`](https://github.com/refinedev/refine/commit/c29a3618cf6b577c36e90ec514f3a691c87aad8f) Thanks [@aliemir](https://github.com/aliemir)! - Updated the TSDoc comments to fix the broken links in the documentation.
+
+## 5.20.0
+
+### Minor Changes
+
+- [#4404](https://github.com/refinedev/refine/pull/4404) [`f67967e8c87`](https://github.com/refinedev/refine/commit/f67967e8c871b2252b4c1b827de3656bf153d1ee) Thanks [@salihozdemir](https://github.com/salihozdemir)! - refactor: fix name and state inconsistency in ``
+
+ `useSiderVisible` is deprecated, instead we created a new hook `useThemedLayoutContext` for it. `useThemedLayoutContext` similar to `useSiderVisible` but it returns more meaningful state names. However, `useSiderVisible` is still available for backward compatibility.
+
+ Updated `Sider` and `HamburgerMenu` components using `useThemedLayoutContext`.
+
+ ```tsx
+ import { useThemedLayoutContext } from "@refinedev/antd";
+
+ const {
+ siderCollapsed,
+ setSiderCollapsed,
+ mobileSiderOpen,
+ setMobileSiderOpen,
+ } = useThemedLayoutContext();
+ ```
+
+## 5.19.0
+
+### Minor Changes
+
+- [#4404](https://github.com/refinedev/refine/pull/4404) [`f67967e8c87`](https://github.com/refinedev/refine/commit/f67967e8c871b2252b4c1b827de3656bf153d1ee) Thanks [@salihozdemir](https://github.com/salihozdemir)! - refactor: fix name and state inconsistency in ``
+
+ `useSiderVisible` is deprecated, instead we created a new hook `useThemedLayoutContext` for it. `useThemedLayoutContext` similar to `useSiderVisible` but it returns more meaningful state names. However, `useSiderVisible` is still available for backward compatibility.
+
+ Updated `Sider` and `HamburgerMenu` components using `useThemedLayoutContext`.
+
+ ```tsx
+ import { useThemedLayoutContext } from "@refinedev/antd";
+
+ const {
+ siderCollapsed,
+ setSiderCollapsed,
+ mobileSiderOpen,
+ setMobileSiderOpen,
+ } = useThemedLayoutContext();
+ ```
+
+## 5.18.2
+
+### Patch Changes
+
+- [#4316](https://github.com/refinedev/refine/pull/4316) [`4690c627e05`](https://github.com/refinedev/refine/commit/4690c627e053a7e35eb8bcb1bfca808308bfa89d) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - fix: fixed `className` for easier selection of all buttons and titles of CRUD components
+
+## 5.18.1
+
+### Patch Changes
+
+- [#4316](https://github.com/refinedev/refine/pull/4316) [`4690c627e05`](https://github.com/refinedev/refine/commit/4690c627e053a7e35eb8bcb1bfca808308bfa89d) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - fix: fixed `className` for easier selection of all buttons and titles of CRUD components
+
+## 5.18.0
+
+### Minor Changes
+
+- [#4303](https://github.com/refinedev/refine/pull/4303) [`0c569f42b4e`](https://github.com/refinedev/refine/commit/0c569f42b4e7caec75928fd8a1ebeb337c95ff81) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: added default button props into the renderer functions `headerButtons` and `footerButtons` in CRUD components.
+ Now, customization of the header and footer buttons can be achieved without losing the default functionality.
+
+ ```tsx
+ import {
+ DeleteButton,
+ EditButton,
+ ListButton,
+ RefreshButton,
+ Show,
+ } from "@refinedev/antd";
+
+ const PostShow = () => {
+ return (
+ {
+ return (
+ <>
+ {/* custom components */}
+ {listButtonProps && (
+
+ )}
+ {editButtonProps && (
+
+ )}
+ {deleteButtonProps && (
+
+ )}
+
+ >
+ );
+ }}
+ >
+ {/* ... */}
+
+ );
+ };
+ ```
+
+- [#4306](https://github.com/refinedev/refine/pull/4306) [`e6eb4dea627`](https://github.com/refinedev/refine/commit/e6eb4dea6279983d04a9f654ac2cd74915fba075) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: `syncWithLocation.syncId` default to `true` for `useDrawerForm` and `useModalForm`.
+
+### Patch Changes
+
+- [#4312](https://github.com/refinedev/refine/pull/4312) [`9a5f79186c1`](https://github.com/refinedev/refine/commit/9a5f79186c107d52e12b8ff87558a3c3dd7807b8) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: added `className` for easier selection of all buttons and titles of CRUD components
+
+- Updated dependencies [[`0c569f42b4e`](https://github.com/refinedev/refine/commit/0c569f42b4e7caec75928fd8a1ebeb337c95ff81), [`9a5f79186c1`](https://github.com/refinedev/refine/commit/9a5f79186c107d52e12b8ff87558a3c3dd7807b8)]:
+ - @refinedev/ui-types@1.16.0
+
+## 5.17.0
+
+### Minor Changes
+
+- [#4303](https://github.com/refinedev/refine/pull/4303) [`0c569f42b4e`](https://github.com/refinedev/refine/commit/0c569f42b4e7caec75928fd8a1ebeb337c95ff81) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: added default button props into the renderer functions `headerButtons` and `footerButtons` in CRUD components.
+ Now, customization of the header and footer buttons can be achieved without losing the default functionality.
+
+ ```tsx
+ import {
+ DeleteButton,
+ EditButton,
+ ListButton,
+ RefreshButton,
+ Show,
+ } from "@refinedev/antd";
+
+ const PostShow = () => {
+ return (
+ {
+ return (
+ <>
+ {/* custom components */}
+ {listButtonProps && (
+
+ )}
+ {editButtonProps && (
+
+ )}
+ {deleteButtonProps && (
+
+ )}
+
+ >
+ );
+ }}
+ >
+ {/* ... */}
+
+ );
+ };
+ ```
+
+- [#4306](https://github.com/refinedev/refine/pull/4306) [`e6eb4dea627`](https://github.com/refinedev/refine/commit/e6eb4dea6279983d04a9f654ac2cd74915fba075) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: `syncWithLocation.syncId` default to `true` for `useDrawerForm` and `useModalForm`.
+
+### Patch Changes
+
+- [#4312](https://github.com/refinedev/refine/pull/4312) [`9a5f79186c1`](https://github.com/refinedev/refine/commit/9a5f79186c107d52e12b8ff87558a3c3dd7807b8) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: added `className` for easier selection of all buttons and titles of CRUD components
+
+- Updated dependencies [[`0c569f42b4e`](https://github.com/refinedev/refine/commit/0c569f42b4e7caec75928fd8a1ebeb337c95ff81), [`9a5f79186c1`](https://github.com/refinedev/refine/commit/9a5f79186c107d52e12b8ff87558a3c3dd7807b8)]:
+ - @refinedev/ui-types@1.15.0
+
+## 5.16.2
+
+### Patch Changes
+
+- [#4295](https://github.com/refinedev/refine/pull/4295) [`7f24a6a2b14`](https://github.com/refinedev/refine/commit/7f24a6a2b14f1e10a2483298b13cc143861fb08f) Thanks [@salihozdemir](https://github.com/salihozdemir)! - chore: bump to latest version of `@refinedev/ui-types`
+
+- Updated dependencies [[`dc62abc890f`](https://github.com/refinedev/refine/commit/dc62abc890f68be161c7035c28c0118216a9e0ec)]:
+ - @refinedev/ui-types@1.14.0
+
+## 5.16.1
+
+### Patch Changes
+
+- [#4295](https://github.com/refinedev/refine/pull/4295) [`7f24a6a2b14`](https://github.com/refinedev/refine/commit/7f24a6a2b14f1e10a2483298b13cc143861fb08f) Thanks [@salihozdemir](https://github.com/salihozdemir)! - chore: bump to latest version of `@refinedev/ui-types`
+
+## 5.16.0
+
+### Minor Changes
+
+- [#4272](https://github.com/refinedev/refine/pull/4272) [`420d2442741`](https://github.com/refinedev/refine/commit/420d2442741d211561dd48c72bcb143ee5f44e9e) Thanks [@salihozdemir](https://github.com/salihozdemir)! - feat: added the `fixed` prop to the `` to allow the sider to be fixed
+
+ The prop is optional and defaults to `false`. You can see the usage as follows:
+
+ ```tsx
+ import { Refine } from "@refinedev/core";
+ import { ThemedLayoutV2, ThemedSiderV2 } from "@refinedev/antd";
+
+ const App: React.FC = () => {
+ return (
+
+ }>
+ {/* ... */}
+
+
+ );
+ };
+ ```
+
+- [#4278](https://github.com/refinedev/refine/pull/4278) [`b14f2ad8a70`](https://github.com/refinedev/refine/commit/b14f2ad8a700d5ae157f437a8f610481d88ae09b) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: added `autoSubmitClose` prop to `useEditableTable`.
+ Now you can choose whether to close the table's row after submitting the form or not.
+
+ ```tsx
+ const editableTable = useEditableTable({
+ autoSubmitClose: false,
+ });
+ ```
+
+### Patch Changes
+
+- [#4267](https://github.com/refinedev/refine/pull/4267) [`5e128c76c16`](https://github.com/refinedev/refine/commit/5e128c76c162cb01822c283e567003a5b6ce62f8) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - fix: `onFinish` prop override on `useDrawerForm` and `useModalForm` hook
+
+ When override `onFinish` prop using the `useDrawerForm` and `useModalForm` hooks, the modal not close after submit the form.
+
+- [#4277](https://github.com/refinedev/refine/pull/4277) [`7172c1b42d2`](https://github.com/refinedev/refine/commit/7172c1b42d26ade22780527892ce26ceef15c838) Thanks [@salihozdemir](https://github.com/salihozdemir)! - fix: renamed the `` prop `isSticky` to `sticky`
+
+ To provide backwards compatibility, the old prop name is still supported, but it is deprecated and will be removed in the next major version.
+
+ Example:
+
+ ```tsx
+ import { Refine } from "@refinedev/core";
+ import { ThemedLayoutV2, ThemedHeaderV2 } from "@refinedev/antd"; // or @refinedev/chakra-ui, @refinedev/mui, @refinedev/mantine
+
+ const App: React.FC = () => {
+ return (
+
+ }
+ >
+ {/* ... */}
+
+
+ );
+ };
+ ```
+
+## 5.15.0
+
+### Minor Changes
+
+- [#4272](https://github.com/refinedev/refine/pull/4272) [`420d2442741`](https://github.com/refinedev/refine/commit/420d2442741d211561dd48c72bcb143ee5f44e9e) Thanks [@salihozdemir](https://github.com/salihozdemir)! - feat: added the `fixed` prop to the `` to allow the sider to be fixed
+
+ The prop is optional and defaults to `false`. You can see the usage as follows:
+
+ ```tsx
+ import { Refine } from "@refinedev/core";
+ import { ThemedLayoutV2, ThemedSiderV2 } from "@refinedev/antd";
+
+ const App: React.FC = () => {
+ return (
+
+ }>
+ {/* ... */}
+
+
+ );
+ };
+ ```
+
+- [#4278](https://github.com/refinedev/refine/pull/4278) [`b14f2ad8a70`](https://github.com/refinedev/refine/commit/b14f2ad8a700d5ae157f437a8f610481d88ae09b) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: added `autoSubmitClose` prop to `useEditableTable`.
+ Now you can choose whether to close the table's row after submitting the form or not.
+
+ ```tsx
+ const editableTable = useEditableTable({
+ autoSubmitClose: false,
+ });
+ ```
+
+### Patch Changes
+
+- [#4267](https://github.com/refinedev/refine/pull/4267) [`5e128c76c16`](https://github.com/refinedev/refine/commit/5e128c76c162cb01822c283e567003a5b6ce62f8) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - fix: `onFinish` prop override on `useDrawerForm` and `useModalForm` hook
+
+ When override `onFinish` prop using the `useDrawerForm` and `useModalForm` hooks, the modal not close after submit the form.
+
+- [#4277](https://github.com/refinedev/refine/pull/4277) [`7172c1b42d2`](https://github.com/refinedev/refine/commit/7172c1b42d26ade22780527892ce26ceef15c838) Thanks [@salihozdemir](https://github.com/salihozdemir)! - fix: renamed the `` prop `isSticky` to `sticky`
+
+ To provide backwards compatibility, the old prop name is still supported, but it is deprecated and will be removed in the next major version.
+
+ Example:
+
+ ```tsx
+ import { Refine } from "@refinedev/core";
+ import { ThemedLayoutV2, ThemedHeaderV2 } from "@refinedev/antd"; // or @refinedev/chakra-ui, @refinedev/mui, @refinedev/mantine
+
+ const App: React.FC = () => {
+ return (
+
+ }
+ >
+ {/* ... */}
+
+
+ );
+ };
+ ```
+
+## 5.14.0
+
+### Minor Changes
+
+- [#4272](https://github.com/refinedev/refine/pull/4272) [`420d2442741`](https://github.com/refinedev/refine/commit/420d2442741d211561dd48c72bcb143ee5f44e9e) Thanks [@salihozdemir](https://github.com/salihozdemir)! - feat: added the `fixed` prop to the `` to allow the sider to be fixed
+
+ The prop is optional and defaults to `false`. You can see the usage as follows:
+
+ ```tsx
+ import { Refine } from "@refinedev/core";
+ import { ThemedLayoutV2, ThemedSiderV2 } from "@refinedev/antd";
+
+ const App: React.FC = () => {
+ return (
+
+ }>
+ {/* ... */}
+
+
+ );
+ };
+ ```
+
+- [#4278](https://github.com/refinedev/refine/pull/4278) [`b14f2ad8a70`](https://github.com/refinedev/refine/commit/b14f2ad8a700d5ae157f437a8f610481d88ae09b) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: added `autoSubmitClose` prop to `useEditableTable`.
+ Now you can choose whether to close the table's row after submitting the form or not.
+
+ ```tsx
+ const editableTable = useEditableTable({
+ autoSubmitClose: false,
+ });
+ ```
+
+### Patch Changes
+
+- [#4267](https://github.com/refinedev/refine/pull/4267) [`5e128c76c16`](https://github.com/refinedev/refine/commit/5e128c76c162cb01822c283e567003a5b6ce62f8) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - fix: `onFinish` prop override on `useDrawerForm` and `useModalForm` hook
+
+ When override `onFinish` prop using the `useDrawerForm` and `useModalForm` hooks, the modal not close after submit the form.
+
+- [#4277](https://github.com/refinedev/refine/pull/4277) [`7172c1b42d2`](https://github.com/refinedev/refine/commit/7172c1b42d26ade22780527892ce26ceef15c838) Thanks [@salihozdemir](https://github.com/salihozdemir)! - fix: renamed the `` prop `isSticky` to `sticky`
+
+ To provide backwards compatibility, the old prop name is still supported, but it is deprecated and will be removed in the next major version.
+
+ Example:
+
+ ```tsx
+ import { Refine } from "@refinedev/core";
+ import { ThemedLayoutV2, ThemedHeaderV2 } from "@refinedev/antd"; // or @refinedev/chakra-ui, @refinedev/mui, @refinedev/mantine
+
+ const App: React.FC = () => {
+ return (
+
+ }
+ >
+ {/* ... */}
+
+
+ );
+ };
+ ```
+
+## 5.13.2
+
+### Patch Changes
+
+- [#4241](https://github.com/refinedev/refine/pull/4241) [`fbe109b5a8b`](https://github.com/refinedev/refine/commit/fbe109b5a8ba8f5d870eab2d96b7477508bceec0) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Added new generic types to the `useForm` hooks. Now you can pass the query types and the mutation types to the hook.
+
+## 5.13.1
+
+### Patch Changes
+
+- [#4241](https://github.com/refinedev/refine/pull/4241) [`fbe109b5a8b`](https://github.com/refinedev/refine/commit/fbe109b5a8ba8f5d870eab2d96b7477508bceec0) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Added new generic types to the `useForm` hooks. Now you can pass the query types and the mutation types to the hook.
+
+## 5.13.0
+
+### Minor Changes
+
+- [#4209](https://github.com/refinedev/refine/pull/4209) [`3f4b5fef76f`](https://github.com/refinedev/refine/commit/3f4b5fef76f3558fc4466f455b9f55083cf47fc2) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: add `isSticky` prop to `ThemedHeaderV2` component
+
+ ```tsx
+ import { ThemedHeaderV2, ThemedLayoutV2 } from "@refinedev/antd";
+
+ const CustomHeader = () => ;
+
+ const App = () => (
+
+ // ...
+
+
+
+ // ...
+
+ );
+ ```
+
+- [#4232](https://github.com/refinedev/refine/pull/4232) [`c99bc0ad7f7`](https://github.com/refinedev/refine/commit/c99bc0ad7f7b71cf47e45a797acdea2325e6fbc8) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: `initialSiderCollapsed` added to `RefineThemedLayoutV2Props` to control initial state of ``.
+ From now on, you can control the initial collapsed state of `` by passing the `initialSiderCollapsed` prop to ``.
+
+ ```tsx
+
+ {/* .. */}
+
+ ```
+
+### Patch Changes
+
+- Updated dependencies [[`c99bc0ad7f7`](https://github.com/refinedev/refine/commit/c99bc0ad7f7b71cf47e45a797acdea2325e6fbc8), [`3f4b5fef76f`](https://github.com/refinedev/refine/commit/3f4b5fef76f3558fc4466f455b9f55083cf47fc2)]:
+ - @refinedev/ui-types@1.12.0
+
+## 5.12.0
+
+### Minor Changes
+
+- [#4209](https://github.com/refinedev/refine/pull/4209) [`3f4b5fef76f`](https://github.com/refinedev/refine/commit/3f4b5fef76f3558fc4466f455b9f55083cf47fc2) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: add `isSticky` prop to `ThemedHeaderV2` component
+
+ ```tsx
+ import { ThemedHeaderV2, ThemedLayoutV2 } from "@refinedev/antd";
+
+ const CustomHeader = () => ;
+
+ const App = () => (
+
+ // ...
+
+
+
+ // ...
+
+ );
+ ```
+
+- [#4232](https://github.com/refinedev/refine/pull/4232) [`c99bc0ad7f7`](https://github.com/refinedev/refine/commit/c99bc0ad7f7b71cf47e45a797acdea2325e6fbc8) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: `initialSiderCollapsed` added to `RefineThemedLayoutV2Props` to control initial state of ``.
+ From now on, you can control the initial collapsed state of `` by passing the `initialSiderCollapsed` prop to ``.
+
+ ```tsx
+
+ {/* .. */}
+
+ ```
+
+### Patch Changes
+
+- Updated dependencies [[`c99bc0ad7f7`](https://github.com/refinedev/refine/commit/c99bc0ad7f7b71cf47e45a797acdea2325e6fbc8), [`3f4b5fef76f`](https://github.com/refinedev/refine/commit/3f4b5fef76f3558fc4466f455b9f55083cf47fc2)]:
+ - @refinedev/ui-types@1.11.0
+
+## 5.11.0
+
+### Minor Changes
+
+- [#4194](https://github.com/refinedev/refine/pull/4194) [`8df15fe0e4e`](https://github.com/refinedev/refine/commit/8df15fe0e4e0fb2bb81102ed1e3a12a0a9532b80) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: `sorters.mode` prop added to `useTable` and `useDataGrid` hooks. This prop handles the sorting mode of the table. It can be either `server` or `off`.
+
+ - **"off"**: `sorters` are not sent to the server. You can use the `sorters` value to sort the records on the client side.
+ - **"server"**: Sorting is done on the server side. Records will be fetched by using the `sorters` value.
+
+ feat:`filters.mode` prop added to `useTable` and `useDataGrid` hooks. This prop handles the filtering mode of the table. It can be either `server` or `off`.
+
+ - **"off"**: `filters` are not sent to the server. You can use the `filters` value to filter the records on the client side.
+ - **"server"**: Filtering is done on the server side. Records will be fetched by using the `filters` value.
+
+## 5.10.0
+
+### Minor Changes
+
+- [#4194](https://github.com/refinedev/refine/pull/4194) [`8df15fe0e4e`](https://github.com/refinedev/refine/commit/8df15fe0e4e0fb2bb81102ed1e3a12a0a9532b80) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - feat: `sorters.mode` prop added to `useTable` and `useDataGrid` hooks. This prop handles the sorting mode of the table. It can be either `server` or `off`.
+
+ - **"off"**: `sorters` are not sent to the server. You can use the `sorters` value to sort the records on the client side.
+ - **"server"**: Sorting is done on the server side. Records will be fetched by using the `sorters` value.
+
+ feat:`filters.mode` prop added to `useTable` and `useDataGrid` hooks. This prop handles the filtering mode of the table. It can be either `server` or `off`.
+
+ - **"off"**: `filters` are not sent to the server. You can use the `filters` value to filter the records on the client side.
+ - **"server"**: Filtering is done on the server side. Records will be fetched by using the `filters` value.
+
+## 5.9.0
+
+### Minor Changes
+
+- [#4193](https://github.com/refinedev/refine/pull/4193) [`3d28fccc1ca`](https://github.com/refinedev/refine/commit/3d28fccc1ca14cdf316d518935cb6c17500c62a4) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: add `ThemedLayoutV2` component and `useSiderVisible` hook
+
+ `ThemeLayout` is deprecated. Added `ThemedLayoutV2` instead. This update fixed some UI problems in the layout. Also, with the new `useSiderVisible` hook, it's easier to collapse/uncollapse the `Sider`.
+
+ See here for detailed [migration guideline](https://refine.dev/docs/api-reference/antd/components/antd-themed-layout/#migrate-themedlayout-to-themedlayoutv2).
+
+### Patch Changes
+
+- Updated dependencies [[`deec38a034a`](https://github.com/refinedev/refine/commit/deec38a034a0b5ab2d7842e428f6fc3a1b8561fa)]:
+ - @refinedev/ui-types@1.10.0
+
+## 5.8.0
+
+### Minor Changes
+
+- [#4193](https://github.com/refinedev/refine/pull/4193) [`3d28fccc1ca`](https://github.com/refinedev/refine/commit/3d28fccc1ca14cdf316d518935cb6c17500c62a4) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: add `ThemedLayoutV2` component and `useSiderVisible` hook
+
+ `ThemeLayout` is deprecated. Added `ThemedLayoutV2` instead. This update fixed some UI problems in the layout. Also, with the new `useSiderVisible` hook, it's easier to collapse/uncollapse the `Sider`.
+
+ See here for detailed [migration guideline](https://refine.dev/docs/api-reference/antd/components/antd-themed-layout/#migrate-themedlayout-to-themedlayoutv2).
+
+### Patch Changes
+
+- Updated dependencies [[`deec38a034a`](https://github.com/refinedev/refine/commit/deec38a034a0b5ab2d7842e428f6fc3a1b8561fa)]:
+ - @refinedev/ui-types@1.9.0
+
+## 5.7.0
+
+### Minor Changes
+
+- [#4193](https://github.com/refinedev/refine/pull/4193) [`3d28fccc1ca`](https://github.com/refinedev/refine/commit/3d28fccc1ca14cdf316d518935cb6c17500c62a4) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - feat: add `ThemedLayoutV2` component and `useSiderVisible` hook
+
+ `ThemeLayout` is deprecated. Added `ThemedLayoutV2` instead. This update fixed some UI problems in the layout. Also, with the new `useSiderVisible` hook, it's easier to collapse/uncollapse the `Sider`.
+
+ See here for detailed [migration guideline](https://refine.dev/docs/api-reference/antd/components/antd-themed-layout/#migrate-themedlayout-to-themedlayoutv2).
+
+### Patch Changes
+
+- Updated dependencies [[`deec38a034a`](https://github.com/refinedev/refine/commit/deec38a034a0b5ab2d7842e428f6fc3a1b8561fa)]:
+ - @refinedev/ui-types@1.8.0
+
+## 5.6.0
+
+### Minor Changes
+
+- [#4113](https://github.com/refinedev/refine/pull/4113) [`1c13602e308`](https://github.com/refinedev/refine/commit/1c13602e308ffba93099922c144966f25fb2087d) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Added missing third generic parameter to hooks which are using `useQuery` internally.
+
+ For example:
+
+ ```ts
+ import { useOne, HttpError } from "@refinedev/core";
+
+ const { data } = useOne<{ count: string }, HttpError, { count: number }>({
+ resource: "product-count",
+ queryOptions: {
+ select: (rawData) => {
+ return {
+ data: {
+ count: Number(rawData?.data?.count),
+ },
+ };
+ },
+ },
+ });
+
+ console.log(typeof data?.data.count); // number
+ ```
+
+### Patch Changes
+
+- [#4113](https://github.com/refinedev/refine/pull/4113) [`1c13602e308`](https://github.com/refinedev/refine/commit/1c13602e308ffba93099922c144966f25fb2087d) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Updated the generic type name of hooks that use `useQuery` to synchronize generic type names with `tanstack-query`.
+
+## 5.5.2
+
+### Patch Changes
+
+- [#4120](https://github.com/refinedev/refine/pull/4120) [`1f310bd7b69`](https://github.com/refinedev/refine/commit/1f310bd7b6900f534bb57db90d3fc8a6ea4364c9) Thanks [@aliemir](https://github.com/aliemir)! - Fix broken `useModalForm` and `useDrawerForm` with `create` actions.
+
+## 5.5.1
+
+### Patch Changes
+
+- [#4120](https://github.com/refinedev/refine/pull/4120) [`1f310bd7b69`](https://github.com/refinedev/refine/commit/1f310bd7b6900f534bb57db90d3fc8a6ea4364c9) Thanks [@aliemir](https://github.com/aliemir)! - Fix broken `useModalForm` and `useDrawerForm` with `create` actions.
+
+## 5.5.0
+
+### Minor Changes
+
+- [#4072](https://github.com/refinedev/refine/pull/4072) [`fad40e6237f`](https://github.com/refinedev/refine/commit/fad40e6237f06f99b1a5cad943cf34cf693a78fb) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - - `` is deprecated. use `` instead with 100% backward compatibility. - https://refine.dev/docs/api-reference/antd/components/antd-themed-layout
+
+### Patch Changes
+
+- [#4114](https://github.com/refinedev/refine/pull/4114) [`afdaed3dd83`](https://github.com/refinedev/refine/commit/afdaed3dd8357d6106ed5a4e524d82cfcceaf7ec) Thanks [@aliemir](https://github.com/aliemir)! - Updated `useModalForm` and `useDrawerForm` hook's `show` method to check if there's an `id` present or provided. If there is, it will continue to show the modal/drawer. If not, the modal/drawer will not show. (Resolves #4062)
+
+## 5.4.0
+
+### Minor Changes
+
+- [#4072](https://github.com/refinedev/refine/pull/4072) [`fad40e6237f`](https://github.com/refinedev/refine/commit/fad40e6237f06f99b1a5cad943cf34cf693a78fb) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - - `` is deprecated. use `` instead with 100% backward compatibility. - https://refine.dev/docs/api-reference/antd/components/antd-themed-layout
+
+### Patch Changes
+
+- [#4114](https://github.com/refinedev/refine/pull/4114) [`afdaed3dd83`](https://github.com/refinedev/refine/commit/afdaed3dd8357d6106ed5a4e524d82cfcceaf7ec) Thanks [@aliemir](https://github.com/aliemir)! - Updated `useModalForm` and `useDrawerForm` hook's `show` method to check if there's an `id` present or provided. If there is, it will continue to show the modal/drawer. If not, the modal/drawer will not show. (Resolves #4062)
+
+## 5.3.14
+
+### Patch Changes
+
+- [#4035](https://github.com/refinedev/refine/pull/4035) [`e0c75450f97`](https://github.com/refinedev/refine/commit/e0c75450f970878fea0ace7db63548c7ba1a1688) Thanks [@salihozdemir](https://github.com/salihozdemir)! - - Re-extending the `SuccessErrorNotification` and `LiveProps` types removed
+ - `useEditableTable`'s `successNotification` and `errorNotification` props now work according to the mutation result instead of the query result
+
+## 5.3.13
+
+### Patch Changes
+
+- [#4035](https://github.com/refinedev/refine/pull/4035) [`e0c75450f97`](https://github.com/refinedev/refine/commit/e0c75450f970878fea0ace7db63548c7ba1a1688) Thanks [@salihozdemir](https://github.com/salihozdemir)! - - Re-extending the `SuccessErrorNotification` and `LiveProps` types removed
+ - `useEditableTable`'s `successNotification` and `errorNotification` props now work according to the mutation result instead of the query result
+
+## 5.3.12
+
+### Patch Changes
+
+- [#4024](https://github.com/refinedev/refine/pull/4024) [`dc6d2311eb7`](https://github.com/refinedev/refine/commit/dc6d2311eb76a458f828fb15fe26fae1c75bc95a) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - - Added: `wrapperStyles` prop to `` component to allow for custom styles to be passed in.
+
+ - Added: `textDecoration: none` to `` component.
+
+## 5.3.11
+
+### Patch Changes
+
+- [#4024](https://github.com/refinedev/refine/pull/4024) [`dc6d2311eb7`](https://github.com/refinedev/refine/commit/dc6d2311eb76a458f828fb15fe26fae1c75bc95a) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - - Added: `wrapperStyles` prop to `` component to allow for custom styles to be passed in.
+
+ - Added: `textDecoration: none` to `` component.
+
+## 5.3.10
+
+### Patch Changes
+
+- [#3997](https://github.com/refinedev/refine/pull/3997) [`f027d8a53b8`](https://github.com/refinedev/refine/commit/f027d8a53b8475f63f3557733c81b9ef040ed0ec) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - - Fixed the unsaved changes dialog is popping up unexpectedly when the user clicks the logs out.
+
+ - The ``'s `onClick` handler was changed to use the `window.confirm` API to manage the confirmation dialog.
+
+- [#3974](https://github.com/refinedev/refine/pull/3974) [`4dcc20d6a60`](https://github.com/refinedev/refine/commit/4dcc20d6a6097bb81a094e4bcb630504b2a055d2) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Deprecated the `WelcomePage` component. It'll be used from `@refinedev/core` instead.
+
+## 5.3.9
+
+### Patch Changes
+
+- [#3997](https://github.com/refinedev/refine/pull/3997) [`f027d8a53b8`](https://github.com/refinedev/refine/commit/f027d8a53b8475f63f3557733c81b9ef040ed0ec) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - - Fixed the unsaved changes dialog is popping up unexpectedly when the user clicks the logs out.
+
+ - The ``'s `onClick` handler was changed to use the `window.confirm` API to manage the confirmation dialog.
+
+- [#3974](https://github.com/refinedev/refine/pull/3974) [`4dcc20d6a60`](https://github.com/refinedev/refine/commit/4dcc20d6a6097bb81a094e4bcb630504b2a055d2) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Deprecated the `WelcomePage` component. It'll be used from `@refinedev/core` instead.
+
+## 5.3.8
+
+### Patch Changes
+
+- [#3975](https://github.com/refinedev/refine/pull/3975) [`b1e6e32f9a1`](https://github.com/refinedev/refine/commit/b1e6e32f9a19e8f26f95d41c942f90e96ed68372) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - - Fixed the unsaved changes dialog is popping up unexpectedly when the user clicks the logs out.
+
+ - The ``'s `onClick` handler was changed to use the `window.confirm` API to manage the confirmation dialog.
+
+ - `` colors updated to match the new theme colors.
+
+- Updated dependencies [[`2798f715361`](https://github.com/refinedev/refine/commit/2798f715361c5fd407d09429d94b05b602b50397)]:
+ - @refinedev/ui-types@1.5.0
+
+## 5.3.7
+
+### Patch Changes
+
+- [#3975](https://github.com/refinedev/refine/pull/3975) [`b1e6e32f9a1`](https://github.com/refinedev/refine/commit/b1e6e32f9a19e8f26f95d41c942f90e96ed68372) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - - Fixed the unsaved changes dialog is popping up unexpectedly when the user clicks the logs out.
+
+ - The ``'s `onClick` handler was changed to use the `window.confirm` API to manage the confirmation dialog.
+
+ - `` colors updated to match the new theme colors.
+
+- Updated dependencies [[`2798f715361`](https://github.com/refinedev/refine/commit/2798f715361c5fd407d09429d94b05b602b50397)]:
+ - @refinedev/ui-types@1.4.0
+
+## 5.3.6
+
+### Patch Changes
+
+- [#3967](https://github.com/refinedev/refine/pull/3967) [`67603562695`](https://github.com/refinedev/refine/commit/67603562695707e9d0bf16908d480fddf6fce7f1) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - Fixed: `` font size was overridden by parent because `` has the default font size.
+
+## 5.3.5
+
+### Patch Changes
+
+- [#3967](https://github.com/refinedev/refine/pull/3967) [`67603562695`](https://github.com/refinedev/refine/commit/67603562695707e9d0bf16908d480fddf6fce7f1) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - Fixed: `` font size was overridden by parent because `` has the default font size.
+
+## 5.3.4
+
+### Patch Changes
+
+- [#3949](https://github.com/refinedev/refine/pull/3949) [`836b06a2f67`](https://github.com/refinedev/refine/commit/836b06a2f67ec966247c422e42e11f39e6167288) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - Fixed: font size was "14px". Updated to "20px" on ``, "14px" on ``.
+
+- [#3956](https://github.com/refinedev/refine/pull/3956) [`c54714ed9ab`](https://github.com/refinedev/refine/commit/c54714ed9abd289edef9a6bef4e85b234a6b6e55) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Fixed an issue where the `` component would throw an error if the `value` prop was set to `undefined`.
+
+## 5.3.3
+
+### Patch Changes
+
+- [#3949](https://github.com/refinedev/refine/pull/3949) [`836b06a2f67`](https://github.com/refinedev/refine/commit/836b06a2f67ec966247c422e42e11f39e6167288) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - Fixed: font size was "14px". Updated to "20px" on ``, "14px" on ``.
+
+- [#3956](https://github.com/refinedev/refine/pull/3956) [`c54714ed9ab`](https://github.com/refinedev/refine/commit/c54714ed9abd289edef9a6bef4e85b234a6b6e55) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Fixed an issue where the `` component would throw an error if the `value` prop was set to `undefined`.
+
+## 5.3.2
+
+### Patch Changes
+
+- [#3931](https://github.com/refinedev/refine/pull/3931) [`d92c8e82868`](https://github.com/refinedev/refine/commit/d92c8e82868519ea7fd37678b74c1d6207a73bcd) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Added missing `autoSubmitClose`, `autoResetForm`, and `defaultVisible` props to `useDrawerForm` hook.
+
+- [#3911](https://github.com/refinedev/refine/pull/3911) [`5f9c70ebf2f`](https://github.com/refinedev/refine/commit/5f9c70ebf2faeea21eef97286ae7391bb77abfa9) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Fixed `autoSubmitClose` and `autoResetForm` props of `useModalForm` hook to work properly.
+
+- [#3931](https://github.com/refinedev/refine/pull/3931) [`d92c8e82868`](https://github.com/refinedev/refine/commit/d92c8e82868519ea7fd37678b74c1d6207a73bcd) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Added `autoSubmitClose`, `autoResetForm`, and `defaultVisible` props to `useDrawerForm` hook.
+
+- [#3948](https://github.com/refinedev/refine/pull/3948) [`b4950503334`](https://github.com/refinedev/refine/commit/b495050333464224f34851c9c57ffab457a3f120) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Fixed the unsaved changes dialog is popping up unexpectedly when the user clicks the delete button or logs out, when the form is dirty.
+
+ - The `` already has a confirmation dialog, so the alert was removed.
+ - The ``'s `onClick` handler was changed to use the `window.confirm` API to manage the confirmation dialog.
+
+## 5.3.1
+
+### Patch Changes
+
+- [#3931](https://github.com/refinedev/refine/pull/3931) [`d92c8e82868`](https://github.com/refinedev/refine/commit/d92c8e82868519ea7fd37678b74c1d6207a73bcd) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Added missing `autoSubmitClose`, `autoResetForm`, and `defaultVisible` props to `useDrawerForm` hook.
+
+- [#3911](https://github.com/refinedev/refine/pull/3911) [`5f9c70ebf2f`](https://github.com/refinedev/refine/commit/5f9c70ebf2faeea21eef97286ae7391bb77abfa9) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Fixed `autoSubmitClose` and `autoResetForm` props of `useModalForm` hook to work properly.
+
+- [#3931](https://github.com/refinedev/refine/pull/3931) [`d92c8e82868`](https://github.com/refinedev/refine/commit/d92c8e82868519ea7fd37678b74c1d6207a73bcd) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Added `autoSubmitClose`, `autoResetForm`, and `defaultVisible` props to `useDrawerForm` hook.
+
+- [#3948](https://github.com/refinedev/refine/pull/3948) [`b4950503334`](https://github.com/refinedev/refine/commit/b495050333464224f34851c9c57ffab457a3f120) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Fixed the unsaved changes dialog is popping up unexpectedly when the user clicks the delete button or logs out, when the form is dirty.
+
+ - The `` already has a confirmation dialog, so the alert was removed.
+ - The ``'s `onClick` handler was changed to use the `window.confirm` API to manage the confirmation dialog.
+
+## 5.3.0
+
+### Minor Changes
+
+- [#3912](https://github.com/refinedev/refine/pull/3912) [`0ffe70308b2`](https://github.com/refinedev/refine/commit/0ffe70308b24d2d70695399fb0a1b7b76bcf2ccb) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - - `RefineThemes` added. It contains predefined colors for the antd components.
+
+ ```tsx
+ import { RefineThemes } from "@refinedev/antd";
+ import { Refine } from "@refinedev/core";
+ import dataProvider from "@refinedev/simple-rest";
+
+ const App = () => {
+ // ---
+
+ return (
+
+
+ {/** your app here */}
+
+
+ );
+ };
+ ```
+
+ - default title with icon added to `AuthPage`. It uses `ThemedTitle` component from `@refinedev/antd`. You can remove it by setting `title` prop to `false`.
+
+ ```tsx
+
+ ```
+
+ - `title` prop added to `AuthPage`'s `renderContent` prop to use in the custom content.
+
+ ```tsx
+ {
+ return (
+
+ {title}
+
Extra Header
+ {content}
+
Extra Footer
+
+ );
+ }}
+ />
+ ```
+
+ - ``, ``, ``, `` created to use theme colors.
+
+ - `` in `` type changed to `primary`.
+ - `` type changed to `primary`.
+
+ - `` component uses colors from the theme.
+ - `` added to `AuthPage`
+
+### Patch Changes
+
+- Updated dependencies [[`0ffe70308b2`](https://github.com/refinedev/refine/commit/0ffe70308b24d2d70695399fb0a1b7b76bcf2ccb)]:
+ - @refinedev/ui-types@1.3.0
+
+## 5.2.0
+
+### Minor Changes
+
+- [#3912](https://github.com/refinedev/refine/pull/3912) [`0ffe70308b2`](https://github.com/refinedev/refine/commit/0ffe70308b24d2d70695399fb0a1b7b76bcf2ccb) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - - `RefineThemes` added. It contains predefined colors for the antd components.
+
+ ```tsx
+ import { RefineThemes } from "@refinedev/antd";
+ import { Refine } from "@refinedev/core";
+ import dataProvider from "@refinedev/simple-rest";
+
+ const App = () => {
+ // ---
+
+ return (
+
+
+ {/** your app here */}
+
+
+ );
+ };
+ ```
+
+ - default title with icon added to `AuthPage`. It uses `ThemedTitle` component from `@refinedev/antd`. You can remove it by setting `title` prop to `false`.
+
+ ```tsx
+
+ ```
+
+ - `title` prop added to `AuthPage`'s `renderContent` prop to use in the custom content.
+
+ ```tsx
+ {
+ return (
+
+ {title}
+
Extra Header
+ {content}
+
Extra Footer
+
+ );
+ }}
+ />
+ ```
+
+ - ``, ``, ``, `` created to use theme colors.
+
+ - `` in `` type changed to `primary`.
+ - `` type changed to `primary`.
+
+ - `` component uses colors from the theme.
+ - `` added to `AuthPage`
+
+### Patch Changes
+
+- Updated dependencies [[`0ffe70308b2`](https://github.com/refinedev/refine/commit/0ffe70308b24d2d70695399fb0a1b7b76bcf2ccb)]:
+ - @refinedev/ui-types@1.2.0
+
+## 5.1.2
+
+### Patch Changes
+
+- [#3885](https://github.com/refinedev/refine/pull/3885) [`5495ab7028e`](https://github.com/refinedev/refine/commit/5495ab7028e9cbd576948f2b347e6d00ddc87728) Thanks [@omeraplak](https://github.com/omeraplak)! - fix: header text color
+
+## 5.1.1
+
+### Patch Changes
+
+- [#3885](https://github.com/refinedev/refine/pull/3885) [`5495ab7028e`](https://github.com/refinedev/refine/commit/5495ab7028e9cbd576948f2b347e6d00ddc87728) Thanks [@omeraplak](https://github.com/omeraplak)! - fix: header text color
+
+## 5.1.0
+
+### Minor Changes
+
+- Thanks [@aliemir](https://github.com/aliemir), [@alicanerdurmaz](https://github.com/alicanerdurmaz), [@batuhanW](https://github.com/batuhanW), [@salihozdemir](https://github.com/salihozdemir), [@yildirayunlu](https://github.com/yildirayunlu), [@recepkutuk](https://github.com/recepkutuk)!
+ Updated the components to match the changes in routing system of `@refinedev/core`.
+
+ ## `meta` property in components
+
+ This includes `meta` props in buttons and `Sider` component. `meta` property can be used to pass additional parameters to the navigation paths.
+
+ For a `posts` resource definition like this:
+
+ ```tsx
+
+ ```
+
+ You can pass `authorId` to the `ShowButton` component like this:
+
+ ```tsx
+
+ ```
+
+ This will navigate to `/123/posts/1` path.
+
+ ## `syncWithLocation` support in `useDrawerForm` and `useModalForm` hooks
+
+ `useDrawerForm` and `useModalForm` hooks now support `syncWithLocation` prop. This prop can be used to sync the visibility state of them with the location via query params.
+
+ You can pass a boolean or an object with `key` and `syncId` properties.
+
+ - `key` is used to define the query param key. Default value is inferred from the resource and the action. For example `posts-create` for `posts` resource and `create` action.
+
+ - `syncId` is used to include the `id` property in the query param key. Default value is `false`. This is useful for `edit` and `clone` actions.
+
+ ## Removed props
+
+ `ignoreAccessControlProvider` prop is removed from buttons.
+
+- Thanks [@aliemir](https://github.com/aliemir), [@alicanerdurmaz](https://github.com/alicanerdurmaz), [@batuhanW](https://github.com/batuhanW), [@salihozdemir](https://github.com/salihozdemir), [@yildirayunlu](https://github.com/yildirayunlu), [@recepkutuk](https://github.com/recepkutuk)!
+ Updated buttons with `resource` property. `resourceNameOrRouteName` is now deprecated but kept working until next major version.
+
+- Thanks [@aliemir](https://github.com/aliemir), [@alicanerdurmaz](https://github.com/alicanerdurmaz), [@batuhanW](https://github.com/batuhanW), [@salihozdemir](https://github.com/salihozdemir), [@yildirayunlu](https://github.com/yildirayunlu), [@recepkutuk](https://github.com/recepkutuk)!
+ All **Ant Design** components re-exported from `@refinedev/antd` have been removed. You should import them from `antd` package directly.
+
+ If the package is not installed, you should install it with your package manager:
+
+ ```bash
+ npm install antd
+ # or
+ pnpm add antd
+ # or
+ yarn add antd
+ ```
+
+ After that, you can import components from `antd` package directly like below:
+
+ ```diff
+ -import { useTable, SaveButton, Button, Form, Input, Select } from "@refinedev/antd";
+
+ +import { useTable, SaveButton } from "@refinedev/antd";
+ +import { Button, Form, Input, Select } from "antd";
+ ```
+
+
+
+ `Icons` are also removed from `@refinedev/antd`. So, you should import icons from `@ant-design/icons` package directly.
+
+ If the package is not installed, you should install it with your package manager:
+
+ ```bash
+ npm install @ant-design/icons
+ # or
+ pnpm add @ant-design/icons
+ # or
+ yarn add @ant-design/icons
+ ```
+
+ After that, you can import icons from `@ant-design/icons` package directly like below:
+
+ ```diff
+ -import { Icons } from "@refinedev/antd";
+ -const { EditOutlined } = Icons;
+
+ + import { EditOutlined } from "@ant-design/icons";
+ ```
+
+- Thanks [@aliemir](https://github.com/aliemir), [@alicanerdurmaz](https://github.com/alicanerdurmaz), [@batuhanW](https://github.com/batuhanW), [@salihozdemir](https://github.com/salihozdemir), [@yildirayunlu](https://github.com/yildirayunlu), [@recepkutuk](https://github.com/recepkutuk)!
+ Upgrade `@ant-design/icons` to `^5.0.1` for consistency.
+
+- Thanks [@aliemir](https://github.com/aliemir), [@alicanerdurmaz](https://github.com/alicanerdurmaz), [@batuhanW](https://github.com/batuhanW), [@salihozdemir](https://github.com/salihozdemir), [@yildirayunlu](https://github.com/yildirayunlu), [@recepkutuk](https://github.com/recepkutuk)!
+
+ - `useCheckboxGroup`'s `sort` prop is now deprecated. Use `sorters` prop instead.
+
+ ```diff
+ useCheckboxGroup({
+ - sort,
+ + sorters,
+ })
+ ```
+
+ - `useSelect`'s `sort` prop is now deprecated. Use `sorters` prop instead.
+
+ ```diff
+ useSelect({
+ - sort,
+ + sorters,
+ })
+ ```
+
+ - `useRadioGroup`'s `sort` prop is now deprecated. Use `sorters` prop instead.
+
+ ```diff
+ useRadioGroup({
+ - sort,
+ + sorters,
+ })
+ ```
+
+ - `useImport`'s `resourceName` prop is now deprecated. Use `resource` prop instead.
+
+ ```diff
+ useImport({
+ - resourceName,
+ + resource,
+ })
+ ```
+
+- Thanks [@aliemir](https://github.com/aliemir), [@alicanerdurmaz](https://github.com/alicanerdurmaz), [@batuhanW](https://github.com/batuhanW), [@salihozdemir](https://github.com/salihozdemir), [@yildirayunlu](https://github.com/yildirayunlu), [@recepkutuk](https://github.com/recepkutuk)!
+
+ - `` isnow deprecated.
+ - Created a `` component to welcome users.
+
+- Thanks [@aliemir](https://github.com/aliemir), [@alicanerdurmaz](https://github.com/alicanerdurmaz), [@batuhanW](https://github.com/batuhanW), [@salihozdemir](https://github.com/salihozdemir), [@yildirayunlu](https://github.com/yildirayunlu), [@recepkutuk](https://github.com/recepkutuk)!
+ Added legacy auth provider and new auth provider support to all components and hooks.
+
+- Thanks [@aliemir](https://github.com/aliemir), [@alicanerdurmaz](https://github.com/alicanerdurmaz), [@batuhanW](https://github.com/batuhanW), [@salihozdemir](https://github.com/salihozdemir), [@yildirayunlu](https://github.com/yildirayunlu), [@recepkutuk](https://github.com/recepkutuk)!
+
+ ## πͺ Migrating your project automatically with refine-codemod β¨
+
+ [`@refinedev/codemod`](https://github.com/refinedev/refine/tree/master/packages/codemod) package handles the breaking changes for your project automatically, without any manual steps. It migrates your project from `3.x.x` to `4.x.x`.
+
+ Just `cd` into root folder of your project (where `package.json` is contained) and run this command:
+
+ ```sh
+ npx @refinedev/codemod@latest refine3-to-refine4
+ ```
+
+ And it's done. Now your project uses `refine@4.x.x`.
+
+ ## π Changelog
+
+ Deprecated `useMenu` removed from `@refinedev/antd` package. Use `useMenu` from `@refinedev/core` package instead.
+
+ ```diff
+ - import { useMenu } from "@refinedev/antd";
+ + import { useMenu } from "@refinedev/core";
+ ```
+
+- Thanks [@aliemir](https://github.com/aliemir), [@alicanerdurmaz](https://github.com/alicanerdurmaz), [@batuhanW](https://github.com/batuhanW), [@salihozdemir](https://github.com/salihozdemir), [@yildirayunlu](https://github.com/yildirayunlu), [@recepkutuk](https://github.com/recepkutuk)!
+ **Moving to the `@refinedev` scope ππ**
+
+ Moved to the `@refinedev` scope and updated our packages to use the new scope. From now on, all packages will be published under the `@refinedev` scope with their new names.
+
+ Now, we're also removing the `refine` prefix from all packages. So, the `@pankod/refine-core` package is now `@refinedev/core`, `@pankod/refine-antd` is now `@refinedev/antd`, and so on.
+
+- Thanks [@aliemir](https://github.com/aliemir), [@alicanerdurmaz](https://github.com/alicanerdurmaz), [@batuhanW](https://github.com/batuhanW), [@salihozdemir](https://github.com/salihozdemir), [@yildirayunlu](https://github.com/yildirayunlu), [@recepkutuk](https://github.com/recepkutuk)!
+
+ ## `useTable` hook
+
+ `useTable` return values and properties are updated.
+
+ - `initialCurrent` and `initialPageSize` props are now deprecated. Use `pagination` prop instead.
+ - To ensure backward compatibility, `initialCurrent` and `initialPageSize` props will work as before.
+
+ ```diff
+ useTable({
+ - initialCurrent,
+ - initialPageSize,
+ + pagination: {
+ + current,
+ + pageSize,
+ + },
+ })
+ ```
+
+ - `hasPagination` prop is now deprecated. Use `pagination.mode` instead.
+ - To ensure backward compatibility, `hasPagination` prop will work as before.
+
+ ```diff
+ useTable({
+ - hasPagination,
+ + pagination: {
+ + mode: "off" | "server" | "client",
+ + },
+ })
+ ```
+
+ - `initialSorter` and `permanentSorter` props are now deprecated. Use `sorters.initial` and `sorters.permanent` instead.
+ - To ensure backward compatibility, `initialSorter` and `permanentSorter` props will work as before.
+
+ ```diff
+ useTable({
+ - initialSorter,
+ - permanentSorter,
+ + sorters: {
+ + initial,
+ + permanent,
+ + },
+ })
+ ```
+
+ - `initialFilter`, `permanentFilter`, and `defaultSetFilterBehavior` props are now deprecated. Use `filters.initial`, `filters.permanent`, and `filters.defaultBehavior` instead.
+ - To ensure backward compatibility, `initialFilter`, `permanentFilter`, and `defaultSetFilterBehavior` props will work as before.
+
+ ```diff
+ useTable({
+ - initialFilter,
+ - permanentFilter,
+ - defaultSetFilterBehavior,
+ + filters: {
+ + initial,
+ + permanent,
+ + defaultBehavior,
+ + },
+ })
+ ```
+
+ - `sorter` and `setSorter` return values are now deprecated. Use `sorters` and `setSorters` instead.
+ - To ensure backward compatibility, `sorter` and `setSorter` return values will work as before.
+
+ ```diff
+ const {
+ - sorter,
+ + sorters,
+ - setSorter,
+ + setSorters,
+ } = useTable();
+ ```
+
+ ## `useSimpleList` hook
+
+ - Now `useSimpleList` hook will not accept all of `` component properties So, you can give their props to `` component directly.
+
+ ```diff
+ import { useSimpleList } from "@refinedev/antd";
+ import { List } from "antd";
+
+ const { listProps } = useSimpleList({
+ resource: "orders",
+ pagination: {
+ pageSize: 6,
+ - simple: true,
+ },
+ });
+
+
+ ```
+
+ - `initialCurrent` and `initialPageSize` props are now deprecated. Use `pagination` prop instead.
+ - To ensure backward compatibility, `initialCurrent` and `initialPageSize` props will work as before.
+
+ - ```diff
+ useSimpleList({
+ - initialCurrent,
+ - initialPageSize,
+ + pagination: {
+ + current,
+ + pageSize,
+ + },
+ })
+ ```
+
+### Patch Changes
+
+## 4.9.0
+
+### Minor Changes
+
+- [#3822](https://github.com/refinedev/refine/pull/3822) [`0baa99ba787`](https://github.com/refinedev/refine/commit/0baa99ba7874394d9d28d0a7b29c082c604258fb) Thanks [@BatuhanW](https://github.com/BatuhanW)! - - refine v4 release announcement added to "postinstall". - refine v4 is released π The new version is 100% backward compatible. You can upgrade to v4 with a single command! See the migration guide here: https://refine.dev/docs/migration-guide/3x-to-4x
+
+### Patch Changes
+
+- Updated dependencies [[`0baa99ba787`](https://github.com/refinedev/refine/commit/0baa99ba7874394d9d28d0a7b29c082c604258fb)]:
+ - @pankod/refine-ui-types@0.16.0
+
+## 4.8.0
+
+### Minor Changes
+
+- [#3822](https://github.com/refinedev/refine/pull/3822) [`0baa99ba787`](https://github.com/refinedev/refine/commit/0baa99ba7874394d9d28d0a7b29c082c604258fb) Thanks [@BatuhanW](https://github.com/BatuhanW)! - - refine v4 release announcement added to "postinstall". - refine v4 is released π The new version is 100% backward compatible. You can upgrade to v4 with a single command! See the migration guide here: https://refine.dev/docs/migration-guide/3x-to-4x
+
+### Patch Changes
+
+- Updated dependencies [[`0baa99ba787`](https://github.com/refinedev/refine/commit/0baa99ba7874394d9d28d0a7b29c082c604258fb)]:
+ - @pankod/refine-ui-types@0.15.0
+
+## 4.7.3
+
+### Patch Changes
+
+- [#3606](https://github.com/refinedev/refine/pull/3606) [`00c9a5c471a`](https://github.com/refinedev/refine/commit/00c9a5c471a684169f800d65800d87cc8d6b6511) Thanks [@aliemir](https://github.com/aliemir)! - Fixed the issue with `disabled` state in `DeleteButton`'s still opening the popover.
+
+## 4.7.2
+
+### Patch Changes
+
+- [#3606](https://github.com/refinedev/refine/pull/3606) [`00c9a5c471a`](https://github.com/refinedev/refine/commit/00c9a5c471a684169f800d65800d87cc8d6b6511) Thanks [@aliemir](https://github.com/aliemir)! - Fixed the issue with `disabled` state in `DeleteButton`'s still opening the popover.
+
+## 4.7.1
+
+### Patch Changes
+
+- [#3399](https://github.com/refinedev/refine/pull/3399) [`22b44a857a8`](https://github.com/refinedev/refine/commit/22b44a857a8ede3473965ab6baff70fc8ae31332) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - Fix `useTable` hook error return type.
+
+## 4.7.0
+
+### Minor Changes
+
+- [#3324](https://github.com/refinedev/refine/pull/3324) [`9bfb34749bc`](https://github.com/refinedev/refine/commit/9bfb34749bc8ddaaf80ccffbd0ad6d0a4487309b) Thanks [@aliemir](https://github.com/aliemir)! - Added the ability to pass mutation options to `useMutation` hooks in mutation hooks:
+ - `useForm`
+ - `useStepsForm`
+ - `useModalForm`
+ - `useDrawerForm`
+
+## 4.6.0
+
+### Minor Changes
+
+- [#3324](https://github.com/refinedev/refine/pull/3324) [`9bfb34749bc`](https://github.com/refinedev/refine/commit/9bfb34749bc8ddaaf80ccffbd0ad6d0a4487309b) Thanks [@aliemir](https://github.com/aliemir)! - Added the ability to pass mutation options to `useMutation` hooks in mutation hooks:
+ - `useForm`
+ - `useStepsForm`
+ - `useModalForm`
+ - `useDrawerForm`
+
+## 4.5.0
+
+### Minor Changes
+
+- [#3294](https://github.com/refinedev/refine/pull/3294) [`3c9c8c07d21`](https://github.com/refinedev/refine/commit/3c9c8c07d2183595402d70a3a2bc49093778e183) Thanks [@aliemir](https://github.com/aliemir)! - Remove `getContainer: false` from `useModalForm` and `useDrawerForm` and let it fallback to the default value. Users wanting to override the default value can still do so by passing `getContainer` prop to the `Modal` and `Drawer` components.
+
+## 4.4.0
+
+### Minor Changes
+
+- [#3294](https://github.com/refinedev/refine/pull/3294) [`3c9c8c07d21`](https://github.com/refinedev/refine/commit/3c9c8c07d2183595402d70a3a2bc49093778e183) Thanks [@aliemir](https://github.com/aliemir)! - Remove `getContainer: false` from `useModalForm` and `useDrawerForm` and let it fallback to the default value. Users wanting to override the default value can still do so by passing `getContainer` prop to the `Modal` and `Drawer` components.
+
+## 4.3.0
+
+### Minor Changes
+
+- [#3285](https://github.com/refinedev/refine/pull/3285) [`cc2c1f042bf`](https://github.com/refinedev/refine/commit/cc2c1f042bf43ae20c58745cccc815c337e17ae7) Thanks [@omeraplak](https://github.com/omeraplak)! - Added exports for new [``](https://ant.design/components/app), [``](https://ant.design/components/qrcode) and [``](https://ant.design/components/watermark) components.
+
+## 4.2.0
+
+### Minor Changes
+
+- [#3285](https://github.com/refinedev/refine/pull/3285) [`cc2c1f042bf`](https://github.com/refinedev/refine/commit/cc2c1f042bf43ae20c58745cccc815c337e17ae7) Thanks [@omeraplak](https://github.com/omeraplak)! - Added exports for new [``](https://ant.design/components/app), [``](https://ant.design/components/qrcode) and [``](https://ant.design/components/watermark) components.
+
+## 4.1.5
+
+### Patch Changes
+
+- [#3273](https://github.com/refinedev/refine/pull/3273) [`a30ba43cce2`](https://github.com/refinedev/refine/commit/a30ba43cce27279deaab60c000dac0537552f7c7) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - Set the `theme="dark"` of the `Menu` component in `Sider` by default.
+
+- [`a8d3f648a28`](https://github.com/refinedev/refine/commit/a8d3f648a282329cac04c1dd4b736864d6fbf756) Thanks [@omeraplak](https://github.com/omeraplak)! - Fixed onClick event type of the `` component
+
+## 4.1.4
+
+### Patch Changes
+
+- [`a8d3f648a28`](https://github.com/refinedev/refine/commit/a8d3f648a282329cac04c1dd4b736864d6fbf756) Thanks [@omeraplak](https://github.com/omeraplak)! - Fixed onClick event type of the `` component
+- [#3273](https://github.com/refinedev/refine/pull/3273) [`a30ba43cce2`](https://github.com/refinedev/refine/commit/a30ba43cce27279deaab60c000dac0537552f7c7) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - Set the `theme="dark"` of the `Menu` component in `Sider` by default.
+
+## 4.1.3
+
+### Patch Changes
+
+- [#3273](https://github.com/refinedev/refine/pull/3273) [`a30ba43cce2`](https://github.com/refinedev/refine/commit/a30ba43cce27279deaab60c000dac0537552f7c7) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - Set the `theme="dark"` of the `Menu` component in `Sider` by default.
+
+## 4.1.2
+
+### Patch Changes
+
+- [#3269](https://github.com/refinedev/refine/pull/3269) [`8b86c0c4c45`](https://github.com/refinedev/refine/commit/8b86c0c4c4529dce9eef4d6e49958eb2c50c31f2) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - Fixed: Wrong import and usage after `swizzling` `` component.
+
+## 4.1.1
+
+### Patch Changes
+
+- [#3269](https://github.com/refinedev/refine/pull/3269) [`8b86c0c4c45`](https://github.com/refinedev/refine/commit/8b86c0c4c4529dce9eef4d6e49958eb2c50c31f2) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - Fixed: Wrong import and usage after `swizzling` `` component.
+
+## 4.1.0
+
+### Minor Changes
+
+- [#3249](https://github.com/refinedev/refine/pull/3249) [`fd2e1882e06`](https://github.com/refinedev/refine/commit/fd2e1882e060135674f53350f2fe1d22347543d7) Thanks [@rajaomariajaona](https://github.com/rajaomariajaona)! - Add ability to pass pagination values in `useTable` hook. (Resolves #3246)
+
+ - `current`
+ - `setCurrent`
+ - `pageSize`
+ - `setPageSize`
+ - `pageCount`
+
+- [#3121](https://github.com/refinedev/refine/pull/3121) [`214ea79c81c`](https://github.com/refinedev/refine/commit/214ea79c81c2f21573f999083612d30256be76a9) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - We've released Ant Design v5 support :tada:
+
+ ## Upgrade
+
+ β‘οΈ You can easily update **refine** packages with **refine** CLI [`update`](https://refine.dev/docs/packages/documentation/cli/#update) command.
+
+ ```bash
+ npm run refine update
+ ```
+
+ > [How to add refine CLI to an existing project?](https://refine.dev/docs/packages/documentation/cli/#how-to-add-to-an-existing-project)
+
+ ### πͺ Migrating your project automatically with Codemod β¨
+
+ `@pankod/refine-codemod` package handles the breaking changes for your project automatically, without any manual steps. It migrates your [`@pankod/refine-antd`](https://github.com/refinedev/refine/tree/next/packages/antd) version from 3.x.x to 4.x.x.
+
+ Just `cd` into root folder of your project (where `package.json` is contained) and run this command:
+
+ ```sh
+ npx @pankod/refine-codemod antd4-to-antd5
+ ```
+
+ And it's done. Now your project uses `@pankod/refine-antd@4.x.x`.
+
+ ## Changes
+
+ - `` component moved into `@ant-design/pro-components`. **refine** is using `` in ``, ``, ``, `` components and added as a dependency. You don't need to install `@ant-design/pro-components` package manually.
+ - `` component moved into `@ant-design/compatible`.
+ - `moment.js` is replaced with `day.js`.
+ - `less` is removed from `antd` package.
+
+ > Please refer to [Ant Design Migration Guide](https://ant.design/docs/react/migration-v5) for detailed information.
+
+ π¨ Next.js 13 Not Supported Now
+
+ Currently `ant-design/pro-components` does not compatible with Next.js 13.
+ **refine** is using `ant-design/pro-components` as a dependency for `` component.
+
+ > [Refer to a related issue on ant-design/pro-components repository](https://github.com/ant-design/pro-components/issues/6338)
+
+## 4.0.0
+
+### Major Changes
+
+- [#3121](https://github.com/refinedev/refine/pull/3121) [`214ea79c81c`](https://github.com/refinedev/refine/commit/214ea79c81c2f21573f999083612d30256be76a9) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - We've released Ant Design v5 support :tada:
+
+ ## Upgrade
+
+ β‘οΈ You can easily update **refine** packages with **refine** CLI [`update`](https://refine.dev/docs/packages/documentation/cli/#update) command.
+
+ ```bash
+ npm run refine update
+ ```
+
+ > [How to add refine CLI to an existing project?](https://refine.dev/docs/packages/documentation/cli/#how-to-add-to-an-existing-project)
+
+ ### πͺ Migrating your project automatically with Codemod β¨
+
+ `@pankod/refine-codemod` package handles the breaking changes for your project automatically, without any manual steps. It migrates your [`@pankod/refine-antd`](https://github.com/refinedev/refine/tree/next/packages/antd) version from 3.x.x to 4.x.x.
+
+ Just `cd` into root folder of your project (where `package.json` is contained) and run this command:
+
+ ```sh
+ npx @pankod/refine-codemod antd4-to-antd5
+ ```
+
+ And it's done. Now your project uses `@pankod/refine-antd@4.x.x`.
+
+ ## Changes
+
+ - `` component moved into `@ant-design/pro-components`. **refine** is using `` in ``, ``, ``, `` components and added as a dependency. You don't need to install `@ant-design/pro-components` package manually.
+ - `` component moved into `@ant-design/compatible`.
+ - `moment.js` is replaced with `day.js`.
+ - `less` is removed from `antd` package.
+
+ > Please refer to [Ant Design Migration Guide](https://ant.design/docs/react/migration-v5) for detailed information.
+
+ π¨ Next.js 13 Not Supported Now
+
+ Currently `ant-design/pro-components` does not compatible with Next.js 13.
+ **refine** is using `ant-design/pro-components` as a dependency for `` component.
+
+ > [Refer to a related issue on ant-design/pro-components repository](https://github.com/ant-design/pro-components/issues/6338)
+
+### Minor Changes
+
+- [#3249](https://github.com/refinedev/refine/pull/3249) [`fd2e1882e06`](https://github.com/refinedev/refine/commit/fd2e1882e060135674f53350f2fe1d22347543d7) Thanks [@rajaomariajaona](https://github.com/rajaomariajaona)! - Add ability to pass pagination values in `useTable` hook. (Resolves #3246)
+ - `current`
+ - `setCurrent`
+ - `pageSize`
+ - `setPageSize`
+ - `pageCount`
+
+## 3.70.4
+
+### Patch Changes
+
+- [#3252](https://github.com/refinedev/refine/pull/3252) [`cf696235d0b`](https://github.com/refinedev/refine/commit/cf696235d0bdaca8554698293e8a644131522f34) Thanks [@aliemir](https://github.com/aliemir)! - Updated `esbuild` configuration to handle `antd/lib` imports in `esm` builds. (Resolves #3187)
+
+## 3.70.3
+
+### Patch Changes
+
+- [#3252](https://github.com/refinedev/refine/pull/3252) [`cf696235d0b`](https://github.com/refinedev/refine/commit/cf696235d0bdaca8554698293e8a644131522f34) Thanks [@aliemir](https://github.com/aliemir)! - Updated `esbuild` configuration to handle `antd/lib` imports in `esm` builds. (Resolves #3187)
+
+## 3.70.2
+
+### Patch Changes
+
+- [#3220](https://github.com/refinedev/refine/pull/3220) [`b867497f469`](https://github.com/refinedev/refine/commit/b867497f4694a5fbd330106a39256dee3c56199b) Thanks [@aliemir](https://github.com/aliemir)! - Updated image links in `README.MD` with CDN
+
+- Updated dependencies [[`b867497f469`](https://github.com/refinedev/refine/commit/b867497f4694a5fbd330106a39256dee3c56199b)]:
+ - @pankod/refine-ui-types@0.14.2
+
+## 3.70.1
+
+### Patch Changes
+
+- [#3220](https://github.com/refinedev/refine/pull/3220) [`b867497f469`](https://github.com/refinedev/refine/commit/b867497f4694a5fbd330106a39256dee3c56199b) Thanks [@aliemir](https://github.com/aliemir)! - Updated image links in `README.MD` with CDN
+
+- Updated dependencies [[`b867497f469`](https://github.com/refinedev/refine/commit/b867497f4694a5fbd330106a39256dee3c56199b)]:
+ - @pankod/refine-ui-types@0.14.1
+
+## 3.70.0
+
+### Minor Changes
+
+- [#3216](https://github.com/refinedev/refine/pull/3216) [`e09eb81588e`](https://github.com/refinedev/refine/commit/e09eb81588e985e270a7b3d49f9c5b28ffcbb134) Thanks [@leapful](https://github.com/leapful)! - Support filter dropdown on number value of single Select component
+
+## 3.69.0
+
+### Minor Changes
+
+- [#3216](https://github.com/refinedev/refine/pull/3216) [`e09eb81588e`](https://github.com/refinedev/refine/commit/e09eb81588e985e270a7b3d49f9c5b28ffcbb134) Thanks [@leapful](https://github.com/leapful)! - Support filter dropdown on number value of single Select component
+
+## 3.68.0
+
+### Minor Changes
+
+- [#3195](https://github.com/refinedev/refine/pull/3195) [`2fdc5c2a88e`](https://github.com/refinedev/refine/commit/2fdc5c2a88e490c7f3b6ed5b562974787863931e) Thanks [@leapful](https://github.com/leapful)! - Support Date Picker component when using with Filter Dropdown
+
+## 3.67.0
+
+### Minor Changes
+
+- [#3195](https://github.com/refinedev/refine/pull/3195) [`2fdc5c2a88e`](https://github.com/refinedev/refine/commit/2fdc5c2a88e490c7f3b6ed5b562974787863931e) Thanks [@leapful](https://github.com/leapful)! - Support Date Picker component when using with Filter Dropdown
+
+## 3.66.0
+
+### Minor Changes
+
+- [#3159](https://github.com/refinedev/refine/pull/3159) [`af2eefb32a4`](https://github.com/refinedev/refine/commit/af2eefb32a4df157062c28125c53aa3a47f48ff8) Thanks [@aliemir](https://github.com/aliemir)! - Updated `LoginPage` and `ReadyPage` to use **refine** logos from CDN rather than bundled svg files.
+
+## 3.65.0
+
+### Minor Changes
+
+- [#3159](https://github.com/refinedev/refine/pull/3159) [`af2eefb32a4`](https://github.com/refinedev/refine/commit/af2eefb32a4df157062c28125c53aa3a47f48ff8) Thanks [@aliemir](https://github.com/aliemir)! - Updated `LoginPage` and `ReadyPage` to use **refine** logos from CDN rather than bundled svg files.
+
+## 3.64.4
+
+### Patch Changes
+
+- [#3128](https://github.com/refinedev/refine/pull/3128) [`db1000a7628`](https://github.com/refinedev/refine/commit/db1000a7628d910c965eb63cd1cff81ffcd4fd4a) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - Fixed: `crud` components import path changed to relative path due to export issues on build.
+
+## 3.64.3
+
+### Patch Changes
+
+- [#3128](https://github.com/refinedev/refine/pull/3128) [`db1000a7628`](https://github.com/refinedev/refine/commit/db1000a7628d910c965eb63cd1cff81ffcd4fd4a) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - Fixed: `crud` components import path changed to relative path due to export issues on build.
+
+## 3.64.2
+
+### Patch Changes
+
+- [#3109](https://github.com/refinedev/refine/pull/3109) [`16549ed3012`](https://github.com/refinedev/refine/commit/16549ed30128750f04ae17da12024b9734d5adae) Thanks [@aliemir](https://github.com/aliemir)! - Updated `swizzle` items and their messages to include extra information and usage examples.
+
+## 3.64.1
+
+### Patch Changes
+
+- [#3109](https://github.com/refinedev/refine/pull/3109) [`16549ed3012`](https://github.com/refinedev/refine/commit/16549ed30128750f04ae17da12024b9734d5adae) Thanks [@aliemir](https://github.com/aliemir)! - Updated `swizzle` items and their messages to include extra information and usage examples.
+
+## 3.64.0
+
+### Minor Changes
+
+- [#3062](https://github.com/refinedev/refine/pull/3062) [`6c2ed708a9a`](https://github.com/refinedev/refine/commit/6c2ed708a9a76faddb9d27a0aca9f4ada3c270af) Thanks [@aliemir](https://github.com/aliemir)! - - Updated components and their type imports to make them compatible with `swizzle` feature.
+ - Added `refine.config.js` to configure the `swizzle` feature.
+
+## 3.63.0
+
+### Minor Changes
+
+- [#3062](https://github.com/refinedev/refine/pull/3062) [`6c2ed708a9a`](https://github.com/refinedev/refine/commit/6c2ed708a9a76faddb9d27a0aca9f4ada3c270af) Thanks [@aliemir](https://github.com/aliemir)! - - Updated components and their type imports to make them compatible with `swizzle` feature.
+ - Added `refine.config.js` to configure the `swizzle` feature.
+
+## 3.62.0
+
+### Minor Changes
+
+- [#2872](https://github.com/refinedev/refine/pull/2872) [`da3fc4a702`](https://github.com/refinedev/refine/commit/da3fc4a702b3ea50f7c1a2cc484fe6364fc3ddc0) Thanks [@TDP17](https://github.com/TDP17)! - Feat: Added ability to manage breadcrumb component globally via options
+
+ > **The option set in individual CRUD components takes priority over the global option**
+
+## 3.61.0
+
+### Minor Changes
+
+- [#2872](https://github.com/refinedev/refine/pull/2872) [`da3fc4a702`](https://github.com/refinedev/refine/commit/da3fc4a702b3ea50f7c1a2cc484fe6364fc3ddc0) Thanks [@TDP17](https://github.com/TDP17)! - Feat: Added ability to manage breadcrumb component globally via options
+
+ > **The option set in individual CRUD components takes priority over the global option**
+
+## 3.60.0
+
+### Minor Changes
+
+- [#2839](https://github.com/refinedev/refine/pull/2839) [`5388a338ab`](https://github.com/refinedev/refine/commit/5388a338abb9a5e03599da0a2786bea394cbc516) Thanks [@aliemir](https://github.com/aliemir)! - **Deprecation**
+
+ `ignoreAccessControlProvider` prop on buttons is deprecated. Use `accessContro.enabled` instead.
+
+ **Features**
+
+ `accessControl.enabled` prop is added to buttons to enable/disable access control for buttons.
+ `accessControl.hideIfUnauthorized` prop is added to buttons to hide the button if access is denied.
+
+- [#2836](https://github.com/refinedev/refine/pull/2836) [`e43e9a17ae`](https://github.com/refinedev/refine/commit/e43e9a17ae0ed41e649b8026b2b04d850136dcfd) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - added locales prop to date fields
+
+### Patch Changes
+
+- [#2838](https://github.com/refinedev/refine/pull/2838) [`f7968fa16f`](https://github.com/refinedev/refine/commit/f7968fa16f9930442e1122fe5294e350252bdd5c) Thanks [@aliemir](https://github.com/aliemir)! - Fixed #2828 - Buttons were not respecting access control when navigating to a new page. Now, if button is disabled, it will not also block the navigation not just the onClick event.
+
+- Updated dependencies [[`476285e342`](https://github.com/refinedev/refine/commit/476285e3427c7e065892a281da529c038aee83d2), [`5388a338ab`](https://github.com/refinedev/refine/commit/5388a338abb9a5e03599da0a2786bea394cbc516), [`e43e9a17ae`](https://github.com/refinedev/refine/commit/e43e9a17ae0ed41e649b8026b2b04d850136dcfd)]:
+ - @pankod/refine-ui-types@0.14.0
+
+## 3.59.0
+
+### Minor Changes
+
+- [#2836](https://github.com/refinedev/refine/pull/2836) [`e43e9a17ae`](https://github.com/refinedev/refine/commit/e43e9a17ae0ed41e649b8026b2b04d850136dcfd) Thanks [@alicanerdurmaz](https://github.com/alicanerdurmaz)! - added locales prop to date fields
+
+### Patch Changes
+
+- Updated dependencies [[`e43e9a17ae`](https://github.com/refinedev/refine/commit/e43e9a17ae0ed41e649b8026b2b04d850136dcfd)]:
+ - @pankod/refine-ui-types@0.13.0
+
+## 3.58.0
+
+### Minor Changes
+
+- [#2839](https://github.com/refinedev/refine/pull/2839) [`5388a338ab`](https://github.com/refinedev/refine/commit/5388a338abb9a5e03599da0a2786bea394cbc516) Thanks [@aliemir](https://github.com/aliemir)! - **Deprecation**
+
+ `ignoreAccessControlProvider` prop on buttons is deprecated. Use `accessContro.enabled` instead.
+
+ **Features**
+
+ `accessControl.enabled` prop is added to buttons to enable/disable access control for buttons.
+ `accessControl.hideIfUnauthorized` prop is added to buttons to hide the button if access is denied.
+
+### Patch Changes
+
+- [#2838](https://github.com/refinedev/refine/pull/2838) [`f7968fa16f`](https://github.com/refinedev/refine/commit/f7968fa16f9930442e1122fe5294e350252bdd5c) Thanks [@aliemir](https://github.com/aliemir)! - Fixed #2828 - Buttons were not respecting access control when navigating to a new page. Now, if button is disabled, it will not also block the navigation not just the onClick event.
+
+- Updated dependencies [[`476285e342`](https://github.com/refinedev/refine/commit/476285e3427c7e065892a281da529c038aee83d2), [`5388a338ab`](https://github.com/refinedev/refine/commit/5388a338abb9a5e03599da0a2786bea394cbc516)]:
+ - @pankod/refine-ui-types@0.12.0
+
+## 3.57.0
+
+### Minor Changes
+
+- Only `or` was supported as a conditional filter. Now `and` and `or` can be used together and nested. π
+
+ ```
+ {
+ operator: "or",
+ value: [
+ {
+ operator: "and",
+ value: [
+ {
+ field: "name",
+ operator: "eq",
+ value: "John Doe",
+ },
+ {
+ field: "age",
+ operator: "eq",
+ value: 30,
+ },
+ ],
+ },
+ {
+ operator: "and",
+ value: [
+ {
+ field: "name",
+ operator: "eq",
+ value: "JR Doe",
+ },
+ {
+ field: "age",
+ operator: "eq",
+ value: 1,
+ },
+ ],
+ },
+ ],
+ }
+ ```
+
+### Patch Changes
+
+- Updated dependencies []:
+ - @pankod/refine-ui-types@0.11.6
+
+## 3.56.0
+
+### Minor Changes
+
+- [#2751](https://github.com/refinedev/refine/pull/2751) [`addff64c77`](https://github.com/refinedev/refine/commit/addff64c777e4c9f044a1a109cb05453e6e9f762) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - Only `or` was supported as a conditional filter. Now `and` and `or` can be used together and nested. π
+
+ ```
+ {
+ operator: "or",
+ value: [
+ {
+ operator: "and",
+ value: [
+ {
+ field: "name",
+ operator: "eq",
+ value: "John Doe",
+ },
+ {
+ field: "age",
+ operator: "eq",
+ value: 30,
+ },
+ ],
+ },
+ {
+ operator: "and",
+ value: [
+ {
+ field: "name",
+ operator: "eq",
+ value: "JR Doe",
+ },
+ {
+ field: "age",
+ operator: "eq",
+ value: 1,
+ },
+ ],
+ },
+ ],
+ }
+ ```
+
+### Patch Changes
+
+- Updated dependencies [[`19124711a7`](https://github.com/refinedev/refine/commit/19124711a7dc23c0b0e61bc845fbd294927999da)]:
+ - @pankod/refine-ui-types@0.11.5
+
+## 3.55.3
+
+### Patch Changes
+
+- Fixed `providers` property empty array state in `` component
+
+## 3.55.2
+
+### Patch Changes
+
+- Fixed `providers` property empty array state in `` component
+
+## 3.55.1
+
+### Patch Changes
+
+- [#2712](https://github.com/refinedev/refine/pull/2712) [`c434055011`](https://github.com/refinedev/refine/commit/c434055011cbdd846c9f228c23987607bb828a1b) Thanks [@omeraplak](https://github.com/omeraplak)! - Fixed `providers` property empty array state in `` component
+
+## 3.55.0
+
+### Minor Changes
+
+- Added infinite loading example to antd `useSelect()`
+ `useSelect()` `fetchSize` prop is deprecated. From now [`pagination`](https://refine.dev/docs/api-reference/core/interfaceReferences/#pagination) should be used
+
+### Patch Changes
+
+- Add AuthProps type export
+
+## 3.54.0
+
+### Minor Changes
+
+- [#2629](https://github.com/refinedev/refine/pull/2629) [`bc89228e73`](https://github.com/refinedev/refine/commit/bc89228e73dbf373cbbbd0fbf5e6e4721224a7c5) Thanks [@bungambohlah](https://github.com/bungambohlah)! - Added infinite loading example to antd `useSelect()`
+ `useSelect()` `fetchSize` prop is deprecated. From now [`pagination`](https://refine.dev/docs/api-reference/core/interfaceReferences/#pagination) should be used
+
+### Patch Changes
+
+- [#2666](https://github.com/refinedev/refine/pull/2666) [`8a562d2114`](https://github.com/refinedev/refine/commit/8a562d2114b7145707070e363981a4e31e02547a) Thanks [@omeraplak](https://github.com/omeraplak)! - Add AuthProps type export
+
+## 3.53.0
+
+### Minor Changes
+
+- - Added new component core and mantine support.
+ - Move Auth types `@pankod/refine-ui-types` to `@pankod/refine-core`
+
+## 3.52.0
+
+### Minor Changes
+
+- [#2627](https://github.com/refinedev/refine/pull/2627) [`c5fb45d61f`](https://github.com/refinedev/refine/commit/c5fb45d61fa7470a7a34762ad19d17e9f87e4421) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - - Added new component core and mantine support.
+ - Move Auth types `@pankod/refine-ui-types` to `@pankod/refine-core`
+
+## 3.51.0
+
+### Minor Changes
+
+- Deprecated `LoginPage`.
+
+ **Before**
+
+ ```tsx
+ import { LoginPage } from "@pankod/refine-antd";
+
+
+ ```
+
+ **After**
+
+ ```tsx
+ import { AuthPage } from "@pankod/refine-antd";
+
+
+ ```
+
+## 3.50.0
+
+### Minor Changes
+
+- Deprecated `LoginPage`.
+
+ **Before**
+
+ ```tsx
+ import { LoginPage } from "@pankod/refine-antd";
+
+
+ ```
+
+ **After**
+
+ ```tsx
+ import { AuthPage } from "@pankod/refine-antd";
+
+
+ ```
+
+## 3.49.0
+
+### Minor Changes
+
+- [#2580](https://github.com/refinedev/refine/pull/2580) [`e1ab7da6b3`](https://github.com/refinedev/refine/commit/e1ab7da6b335bad62b15a537a3ed63c9f113bd01) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - Deprecated `LoginPage`.
+
+ **Before**
+
+ ```tsx
+ import { LoginPage } from "@pankod/refine-antd";
+
+
+ ```
+
+ **After**
+
+ ```tsx
+ import { AuthPage } from "@pankod/refine-antd";
+
+
+ ```
+
+## 3.48.10
+
+### Patch Changes
+
+- ReadyPage examples link fixed.
+
+## 3.48.9
+
+### Patch Changes
+
+- [#2505](https://github.com/refinedev/refine/pull/2505) [`a4dbb63c88`](https://github.com/refinedev/refine/commit/a4dbb63c881a83e5146829130b1377e791b44469) Thanks [@salihozdemir](https://github.com/salihozdemir)! - ReadyPage examples link fixed.
+
+## 3.48.8
+
+### Patch Changes
+
+- Updated `disabled` attribute of buttons in CRUD components according to `isLoading` prop.
+
+- Removed redundant type inheritance
+
+- Updated dependencies []:
+ - @pankod/refine-ui-types@0.11.2
+
+## 3.48.7
+
+### Patch Changes
+
+- [#2586](https://github.com/refinedev/refine/pull/2586) [`d7c8b7642b`](https://github.com/refinedev/refine/commit/d7c8b7642b7ed41a2063798e779c3cfaa09b0e7b) Thanks [@necatiozmen](https://github.com/necatiozmen)! - Removed redundant type inheritance
+
+- Updated dependencies [[`d7c8b7642b`](https://github.com/refinedev/refine/commit/d7c8b7642b7ed41a2063798e779c3cfaa09b0e7b)]:
+ - @pankod/refine-ui-types@0.11.1
+
+## 3.48.6
+
+### Patch Changes
+
+- [#2585](https://github.com/refinedev/refine/pull/2585) [`e7ab42a73b`](https://github.com/refinedev/refine/commit/e7ab42a73b87625b2646864118ad25cbe31295ad) Thanks [@salihozdemir](https://github.com/salihozdemir)! - Updated `disabled` attribute of buttons in CRUD components according to `isLoading` prop.
+
+## 3.48.5
+
+### Patch Changes
+
+- Rename `reset-password` -> `forgot-password` on docs.
+
+## 3.48.4
+
+### Patch Changes
+
+- Rename `reset-password` -> `forgot-password` on docs.
+
+## 3.48.3
+
+### Patch Changes
+
+- [#2568](https://github.com/refinedev/refine/pull/2568) [`efe99f7843`](https://github.com/refinedev/refine/commit/efe99f78433c46433f137fd9581f33f4d75778e0) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - Rename `reset-password` -> `forgot-password` on docs.
+
+## 3.48.2
+
+### Patch Changes
+
+- Fixed `useModalForm` & `useStepsForm` return type
+
+## 3.48.1
+
+### Patch Changes
+
+- [#2552](https://github.com/refinedev/refine/pull/2552) [`52cd8d633e`](https://github.com/refinedev/refine/commit/52cd8d633e57f925bb51c875aab0406e3358ec45) Thanks [@omeraplak](https://github.com/omeraplak)! - Fixed `useModalForm` & `useStepsForm` return type
+
+## 3.48.0
+
+### Minor Changes
+
+- Add `providers` support on AuthPage register page.
+
+### Patch Changes
+
+- Updated dependencies []:
+ - @pankod/refine-ui-types@0.11.0
+
+## 3.47.0
+
+### Minor Changes
+
+- [#2551](https://github.com/refinedev/refine/pull/2551) [`a65525de6f`](https://github.com/refinedev/refine/commit/a65525de6f995babfca1058e933cdbea67d6032e) Thanks [@yildirayunlu](https://github.com/yildirayunlu)! - Add `providers` support on AuthPage register page.
+
+### Patch Changes
+
+- Updated dependencies [[`a65525de6f`](https://github.com/refinedev/refine/commit/a65525de6f995babfca1058e933cdbea67d6032e)]:
+ - @pankod/refine-ui-types@0.10.0
+
+## 3.46.4
+
+### Patch Changes
+
+- - Auth pages background color fixed.
+ - Removed unused `updatePasswordLink` prop from auth pages.
+ - Removed `onSubmit` prop from auth pages. use `formProps` instead.
+- Updated dependencies []:
+ - @pankod/refine-ui-types@0.9.2
+
+## 3.46.3
+
+### Patch Changes
+
+- [#2524](https://github.com/refinedev/refine/pull/2524) [`27bf81bebb`](https://github.com/refinedev/refine/commit/27bf81bebb217d2944e20e79a8f7618eda0e9db7) Thanks [@biskuvit](https://github.com/biskuvit)! - - Auth pages background color fixed.
+ - Removed unused `updatePasswordLink` prop from auth pages.
+ - Removed `onSubmit` prop from auth pages. use `formProps` instead.
+- Updated dependencies [[`27bf81bebb`](https://github.com/refinedev/refine/commit/27bf81bebb217d2944e20e79a8f7618eda0e9db7)]:
+ - @pankod/refine-ui-types@0.9.1
+
+## 3.46.2
+
+### Patch Changes
+
+- Fixed the spacing between `icon` and `breadcrumb label` in `Breadcrumb` component.
+
+## 3.46.1
+
+### Patch Changes
+
+- [#2534](https://github.com/refinedev/refine/pull/2534) [`a9676932cc`](https://github.com/refinedev/refine/commit/a9676932ccae00f364918f163e44e73032ffa029) Thanks [@ozkalai](https://github.com/ozkalai)! - Fixed the spacing between `icon` and `breadcrumb label` in `Breadcrumb` component.
+
+## 3.46.0
+
+### Minor Changes
+
+- Added `formProps` property support for AuthPage component
+
+ ## Usage
+
+ ```tsx
+
+ ```
+
+### Patch Changes
+
+- Updated dependencies []:
+ - @pankod/refine-ui-types@0.9.0
+
+## 3.45.0
+
+### Minor Changes
+
+- [#2516](https://github.com/refinedev/refine/pull/2516) [`ad99916d6d`](https://github.com/refinedev/refine/commit/ad99916d6dbd181b857fd7df7b9619d8cac5e3e0) Thanks [@omeraplak](https://github.com/omeraplak)! - Added `formProps` property support for AuthPage component
+
+ ## Usage
+
+ ```tsx
+
+ ```
+
+### Patch Changes
+
+- Updated dependencies [[`ad99916d6d`](https://github.com/refinedev/refine/commit/ad99916d6dbd181b857fd7df7b9619d8cac5e3e0)]:
+ - @pankod/refine-ui-types@0.8.0
+
+## 3.44.0
+
+### Minor Changes
+
+- Added `render` prop to `Sider` component. You can get `dashboard`, `logout` and `items` from `render` props to customize the `Sider` component.
+
+- Added `` for Ant Design. `` is a component that provides a login, register, forgot password and update password pages.
+
+### Patch Changes
+
+- Fixed version of react-router to `6.3.0`
+
+- Passed `collapsed` prop to `render` method in `Sider` component of `@pankod/refine-antd`.
+
+- Updated dependencies []:
+ - @pankod/refine-ui-types@0.7.0
+
+## 3.43.1
+
+### Patch Changes
+
+- [#2501](https://github.com/refinedev/refine/pull/2501) [`4095a578d4`](https://github.com/refinedev/refine/commit/4095a578d471254ee58412f130ac5a0f3a62880f) Thanks [@omeraplak](https://github.com/omeraplak)! - Fixed version of react-router to `6.3.0`
+
+## 3.43.0
+
+### Minor Changes
+
+- [#2447](https://github.com/refinedev/refine/pull/2447) [`628a37a675`](https://github.com/refinedev/refine/commit/628a37a6753a778cbec5c29b698981e0157caa42) Thanks [@biskuvit](https://github.com/biskuvit)! - Added `` for Ant Design. `` is a component that provides a login, register, forgot password and update password pages.
+
+### Patch Changes
+
+- Updated dependencies [[`628a37a675`](https://github.com/refinedev/refine/commit/628a37a6753a778cbec5c29b698981e0157caa42)]:
+ - @pankod/refine-ui-types@0.6.2
+
+## 3.42.1
+
+### Patch Changes
+
+- [#2492](https://github.com/refinedev/refine/pull/2492) [`7d5bf3023d`](https://github.com/refinedev/refine/commit/7d5bf3023d00617890ffa7f9d22b1116af15e0b9) Thanks [@ozkalai](https://github.com/ozkalai)! - Passed `collapsed` prop to `render` method in `Sider` component of `@pankod/refine-antd`.
+
+- Updated dependencies [[`7d5bf3023d`](https://github.com/refinedev/refine/commit/7d5bf3023d00617890ffa7f9d22b1116af15e0b9)]:
+ - @pankod/refine-ui-types@0.6.1
+
+## 3.42.0
+
+### Minor Changes
+
+- [#2454](https://github.com/refinedev/refine/pull/2454) [`72487a4126`](https://github.com/refinedev/refine/commit/72487a4126fb7d827dccd3bcbdee9a83aa1f56af) Thanks [@ozkalai](https://github.com/ozkalai)! - Added `render` prop to `Sider` component. You can get `dashboard`, `logout` and `items` from `render` props to customize the `Sider` component.
+
+### Patch Changes
+
+- Updated dependencies [[`72487a4126`](https://github.com/refinedev/refine/commit/72487a4126fb7d827dccd3bcbdee9a83aa1f56af)]:
+ - @pankod/refine-ui-types@0.6.0
+
+## 3.41.0
+
+### Minor Changes
+
+- Added support nested sorting
+
+## 3.40.0
+
+### Minor Changes
+
+- [#2427](https://github.com/refinedev/refine/pull/2427) [`b21908e872`](https://github.com/refinedev/refine/commit/b21908e87209c3a8825991c6ab829f7c45c19e9b) Thanks [@geoffatsource](https://github.com/geoffatsource)! - Added support nested sorting
+
+## 3.39.0
+
+### Minor Changes
+
+- Update type declaration generation with `tsc` instead of `tsup` for better navigation throughout projects source code.
+
+### Patch Changes
+
+- Updated dependencies []:
+ - @pankod/refine-ui-types@0.5.0
+
+## 3.38.0
+
+### Minor Changes
+
+- [#2440](https://github.com/refinedev/refine/pull/2440) [`0150dcd070`](https://github.com/refinedev/refine/commit/0150dcd0700253f1c4908e7e5f2e178bb122e9af) Thanks [@aliemir](https://github.com/aliemir)! - Update type declaration generation with `tsc` instead of `tsup` for better navigation throughout projects source code.
+
+### Patch Changes
+
+- Updated dependencies [[`0150dcd070`](https://github.com/refinedev/refine/commit/0150dcd0700253f1c4908e7e5f2e178bb122e9af), [`0150dcd070`](https://github.com/refinedev/refine/commit/0150dcd0700253f1c4908e7e5f2e178bb122e9af)]:
+ - @pankod/refine-ui-types@0.4.0
+
+## 3.37.11
+
+### Patch Changes
+
+- Fix: `useStepsForm`'s `submit` function can be overridden
+
+## 3.37.10
+
+### Patch Changes
+
+- Fix: `useStepsForm`'s `submit` function can be overridden
+
+## 3.37.9
+
+### Patch Changes
+
+- [#2421](https://github.com/refinedev/refine/pull/2421) [`2b1c5e01b0`](https://github.com/refinedev/refine/commit/2b1c5e01b0f65b2c7558ba79539fab411480cc06) Thanks [@omeraplak](https://github.com/omeraplak)! - Fix: `useStepsForm`'s `submit` function can be overridden
+
+## 3.37.8
+
+### Patch Changes
+
+- Fix: Wrap with [``](https://refine.dev/docs/core/components/accessControl/can-access/) component to parent sider items
+
+ ```tsx
+ {
+ // console.log({ action, resource });
+ // output: {action: "list", resource: "cms" }
+
+ return { can: true };
+ },
+ }}
+ resources={[
+ {
+ name: "CMS",
+ },
+ {
+ name: "posts",
+ parentName: "CMS",
+ list: PostList,
+ },
+ ]}
+ />
+ ```
+
+## 3.37.7
+
+### Patch Changes
+
+- [#2411](https://github.com/refinedev/refine/pull/2411) [`c61470a2e0`](https://github.com/refinedev/refine/commit/c61470a2e00df94a211395541601fd39b63e2cff) Thanks [@omeraplak](https://github.com/omeraplak)! - Fix: Wrap with [``](https://refine.dev/docs/core/components/accessControl/can-access/) component to parent sider items
+
+ ```tsx
+ {
+ // console.log({ action, resource });
+ // output: {action: "list", resource: "cms" }
+
+ return { can: true };
+ },
+ }}
+ resources={[
+ {
+ name: "CMS",
+ },
+ {
+ name: "posts",
+ parentName: "CMS",
+ list: PostList,
+ },
+ ]}
+ />
+ ```
+
+## 3.37.6
+
+### Patch Changes
+
+- Fix `useModalForm` hook reset issue after successful submit
+
+## 3.37.5
+
+### Patch Changes
+
+- [#2403](https://github.com/refinedev/refine/pull/2403) [`ef8622cba3`](https://github.com/refinedev/refine/commit/ef8622cba32acc8f5edf9e4190fbe90d99e642c6) Thanks [@omeraplak](https://github.com/omeraplak)! - Fix `useModalForm` hook reset issue after successful submit
+
+## 3.37.4
+
+### Patch Changes
+
+- Updated `` component's default footer buttons property wrapper with `` component like `
+ }
+ />
+ );
+};
diff --git a/packages/antd/src/components/pages/index.tsx b/packages/antd/src/components/pages/index.tsx
new file mode 100644
index 0000000..900f047
--- /dev/null
+++ b/packages/antd/src/components/pages/index.tsx
@@ -0,0 +1,6 @@
+export { ErrorComponent } from "./error";
+export { LoginPage } from "./login";
+export { ReadyPage } from "./ready";
+export { WelcomePage } from "./welcome";
+export { AuthPage } from "./auth";
+export type { AuthProps } from "./auth";
diff --git a/packages/antd/src/components/pages/login/index.tsx b/packages/antd/src/components/pages/login/index.tsx
new file mode 100644
index 0000000..0379eae
--- /dev/null
+++ b/packages/antd/src/components/pages/login/index.tsx
@@ -0,0 +1,172 @@
+import React from "react";
+import { LoginPageProps, useActiveAuthProvider } from "@refinedev/core";
+import {
+ Row,
+ Col,
+ Layout,
+ Card,
+ Typography,
+ Form,
+ Input,
+ Button,
+ Checkbox,
+} from "antd";
+import { useLogin, useTranslate } from "@refinedev/core";
+
+import {
+ layoutStyles,
+ containerStyles,
+ titleStyles,
+ imageContainer,
+} from "./styles";
+
+const { Text, Title } = Typography;
+export interface ILoginForm {
+ username: string;
+ password: string;
+ remember: boolean;
+}
+
+/**
+ * @deprecated LoginPage is deprecated. Use AuthPage instead. @see {@link https://refine.dev/docs/api-reference/antd/components/antd-auth-page} for more details.
+ * **refine** has a default login page form which is served on `/login` route when the `authProvider` configuration is provided.
+ *
+ * @see {@link https://refine.dev/docs/api-reference/core/components/refine-config/#loginpage} for more details.
+ */
+export const LoginPage: React.FC = () => {
+ const [form] = Form.useForm();
+ const translate = useTranslate();
+
+ const authProvider = useActiveAuthProvider();
+ const { mutate: login, isLoading } = useLogin({
+ v3LegacyAuthProviderCompatible: Boolean(authProvider?.isLegacy),
+ });
+
+ const CardTitle = (
+
+ {translate("pages.login.title", "Sign in your account")}
+
+ );
+
+ return (
+
+
+