From 819539f3b89dc0a77900399b12ce3d5afbcd0588 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sun, 4 Feb 2024 22:21:18 +0100 Subject: [PATCH 01/53] [code-infra] Simplify bug reproduction (#11849) Signed-off-by: Olivier Tassinari Co-authored-by: Michel Engelen <32863416+michelengelen@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/1.bug.yml | 4 +--- .github/ISSUE_TEMPLATE/3.pro-support.yml | 5 +---- .github/ISSUE_TEMPLATE/4.premium-support.yml | 5 +---- .github/ISSUE_TEMPLATE/5.priority-support.yml | 5 +---- .../x-data-grid/package.json | 5 ++++- .../x-data-grid/public/index.html | 2 +- .../x-data-grid/src/demo.tsx | 6 +++--- .../x-data-grid/src/index.tsx | 2 +- .../x-data-grid/template.json | 0 .../x-data-grid/tsconfig.json | 0 docs/data/introduction/support/support.md | 19 +++++++++++++++++++ 11 files changed, 32 insertions(+), 21 deletions(-) rename {templates => bug-reproductions}/x-data-grid/package.json (80%) rename {templates => bug-reproductions}/x-data-grid/public/index.html (80%) rename {templates => bug-reproductions}/x-data-grid/src/demo.tsx (80%) rename {templates => bug-reproductions}/x-data-grid/src/index.tsx (82%) rename {templates => bug-reproductions}/x-data-grid/template.json (100%) rename {templates => bug-reproductions}/x-data-grid/tsconfig.json (100%) diff --git a/.github/ISSUE_TEMPLATE/1.bug.yml b/.github/ISSUE_TEMPLATE/1.bug.yml index 61517d69ed6e6..24e3b54a8b5a3 100644 --- a/.github/ISSUE_TEMPLATE/1.bug.yml +++ b/.github/ISSUE_TEMPLATE/1.bug.yml @@ -26,9 +26,7 @@ body: description: | **⚠️ Issues that we can't reproduce can't be fixed.** - If you don't have one, you can use one of these options: - - [DataGrid codesandbox template](https://codesandbox.io/s/github/mui/mui-x/tree/master/templates/x-data-grid?file=/src/demo.tsx) - - Fork any of the examples in our [documentation](https://mui.com/x/introduction/) by [clicking on the codesandbox or stackblitz icon](https://mui.com/static/docs/forking-an-example.png) + Please provide a link to a live example and an unambiguous set of steps to reproduce this bug. See our [documentation](https://mui.com/x/introduction/support/#bug-reproductions) on how to build a reproduction case. value: | Link to live example: (required) diff --git a/.github/ISSUE_TEMPLATE/3.pro-support.yml b/.github/ISSUE_TEMPLATE/3.pro-support.yml index 3e20ea94fc921..c3ef5d1a3e07c 100644 --- a/.github/ISSUE_TEMPLATE/3.pro-support.yml +++ b/.github/ISSUE_TEMPLATE/3.pro-support.yml @@ -36,10 +36,7 @@ body: attributes: label: The problem in depth description: | - **If applicable, please provide a live example to explain your problem.** - If you don't have one, you can use one of these options: - - [DataGrid codesandbox template](https://codesandbox.io/s/github/mui/mui-x/tree/master/templates/x-data-grid?file=/src/demo.tsx) - - Fork any of the examples in our [documentation](https://mui.com/x/introduction/) by [clicking on the codesandbox or stackblitz icon](https://mui.com/static/docs/forking-an-example.png) + Please provide a link to a live example and an unambiguous set of steps to reproduce this bug. See our [documentation](https://mui.com/x/introduction/support/#bug-reproductions) on how to build a reproduction case. - type: textarea attributes: label: Your environment diff --git a/.github/ISSUE_TEMPLATE/4.premium-support.yml b/.github/ISSUE_TEMPLATE/4.premium-support.yml index 106fabecf04d0..fb927c7619ebc 100644 --- a/.github/ISSUE_TEMPLATE/4.premium-support.yml +++ b/.github/ISSUE_TEMPLATE/4.premium-support.yml @@ -36,10 +36,7 @@ body: attributes: label: The problem in depth description: | - **If applicable, please provide a live example to explain your problem.** - If you don't have one, you can use one of these options: - - [DataGrid codesandbox template](https://codesandbox.io/s/github/mui/mui-x/tree/master/templates/x-data-grid?file=/src/demo.tsx) - - Fork any of the examples in our [documentation](https://mui.com/x/introduction/) by [clicking on the codesandbox or stackblitz icon](https://mui.com/static/docs/forking-an-example.png) + Please provide a link to a live example and an unambiguous set of steps to reproduce this bug. See our [documentation](https://mui.com/x/introduction/support/#bug-reproductions) on how to build a reproduction case. - type: textarea attributes: label: Your environment diff --git a/.github/ISSUE_TEMPLATE/5.priority-support.yml b/.github/ISSUE_TEMPLATE/5.priority-support.yml index d7f67770bd6c5..f902b8ed2f407 100644 --- a/.github/ISSUE_TEMPLATE/5.priority-support.yml +++ b/.github/ISSUE_TEMPLATE/5.priority-support.yml @@ -26,10 +26,7 @@ body: attributes: label: The problem in depth description: | - **If you're reporting a bug, please provide a live example for your report.** - If you don't have one, you can use one of these options: - - [DataGrid codesandbox template](https://codesandbox.io/s/github/mui/mui-x/tree/master/templates/x-data-grid?file=/src/demo.tsx) - - Fork any of the examples in our [documentation](https://mui.com/x/introduction/) by [clicking on the codesandbox or stackblitz icon](https://mui.com/static/docs/forking-an-example.png) + Please provide a link to a live example and an unambiguous set of steps to reproduce this bug. See our [documentation](https://mui.com/x/introduction/support/#bug-reproductions) on how to build a reproduction case. - type: textarea attributes: label: Your environment diff --git a/templates/x-data-grid/package.json b/bug-reproductions/x-data-grid/package.json similarity index 80% rename from templates/x-data-grid/package.json rename to bug-reproductions/x-data-grid/package.json index 569a43b6fb606..8178d76e1228b 100644 --- a/templates/x-data-grid/package.json +++ b/bug-reproductions/x-data-grid/package.json @@ -19,6 +19,9 @@ }, "main": "src/index.tsx", "scripts": { - "start": "react-scripts start" + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" } } diff --git a/templates/x-data-grid/public/index.html b/bug-reproductions/x-data-grid/public/index.html similarity index 80% rename from templates/x-data-grid/public/index.html rename to bug-reproductions/x-data-grid/public/index.html index 0a7ab2d3bbbca..80363f8fecc8e 100644 --- a/templates/x-data-grid/public/index.html +++ b/bug-reproductions/x-data-grid/public/index.html @@ -5,7 +5,7 @@ diff --git a/templates/x-data-grid/src/demo.tsx b/bug-reproductions/x-data-grid/src/demo.tsx similarity index 80% rename from templates/x-data-grid/src/demo.tsx rename to bug-reproductions/x-data-grid/src/demo.tsx index 10cc6a348fe17..5417a65f93e8b 100644 --- a/templates/x-data-grid/src/demo.tsx +++ b/bug-reproductions/x-data-grid/src/demo.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; import Box from '@mui/material/Box'; -import { DataGridPro } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; +import { DataGrid } from '@mui/x-data-grid'; -export default function DataGridProDemo() { +export default function Demo() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 100000, @@ -12,7 +12,7 @@ export default function DataGridProDemo() { return ( - diff --git a/templates/x-data-grid/template.json b/bug-reproductions/x-data-grid/template.json similarity index 100% rename from templates/x-data-grid/template.json rename to bug-reproductions/x-data-grid/template.json diff --git a/templates/x-data-grid/tsconfig.json b/bug-reproductions/x-data-grid/tsconfig.json similarity index 100% rename from templates/x-data-grid/tsconfig.json rename to bug-reproductions/x-data-grid/tsconfig.json diff --git a/docs/data/introduction/support/support.md b/docs/data/introduction/support/support.md index 5c1d49e2875b5..4884e04a003b2 100644 --- a/docs/data/introduction/support/support.md +++ b/docs/data/introduction/support/support.md @@ -21,6 +21,25 @@ If you think you've found a bug, or you have a new feature idea: - Please don't group multiple topics in one issue. - Please don't comment "+1" on an issue. It spams the maintainers and doesn't help move the issue forward. Use GitHub reactions instead (👍). +### Bug reproductions + +We require bug reports to be accompanied by a **minimal reproduction**. +It significantly increases the odds of fixing the problem. +You have a few possible options to provide it: + +- You can browse the documentation, find an example close to your use case, and then open it in a live editor: + [![Forking an example](https://mui.com/static/docs-infra/forking-an-example.png)](/x/react-date-pickers/getting-started/#render-your-first-component) + + - [Data Grid](/x/react-data-grid/#mit-version-free-forever) + - [Date Pickers](/x/react-date-pickers/getting-started/#render-your-first-component) + - [Charts](/x/react-charts/getting-started/#single-charts) + - [Tree View](/x/react-tree-view/#simpletreeview) + +- You can use a starter template to build a reproduction case with: + + - A minimal Data Grid [TypeScript template](https://stackblitz.com/github/mui/mui-x/tree/next/bug-reproductions/x-data-grid?file=src/index.tsx) + - A plain React [JavaScript](https://stackblitz.com/fork/github/stackblitz/starters/tree/main/react) or [TypeScript](https://stackblitz.com/fork/github/stackblitz/starters/tree/main/react-ts) template + ## Stack Overflow We use Stack Overflow for how-to questions. Answers are crowdsourced from expert developers in the MUI X community as well as MUI X maintainers. From 2faec7d336e46145dbce911bf93d4ab8be63aea1 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Mon, 5 Feb 2024 01:15:53 +0100 Subject: [PATCH 02/53] [docs] Stable layout between light and dark mode --- docs/data/introduction/licensing/licensing.md | 4 ++-- docs/public/static/x/watermark-dark.png | Bin 37505 -> 37435 bytes docs/public/static/x/watermark-light.png | Bin 36119 -> 36017 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/data/introduction/licensing/licensing.md b/docs/data/introduction/licensing/licensing.md index 2176ffb9e7b2a..538813258a901 100644 --- a/docs/data/introduction/licensing/licensing.md +++ b/docs/data/introduction/licensing/licensing.md @@ -256,10 +256,10 @@ This error indicates that your license key is missing. You might not be allowed The component will look something like this:
- +
- +
To solve the issue, you can check the [free trial conditions](#evaluation-trial-licenses), if you are eligible no actions are required. diff --git a/docs/public/static/x/watermark-dark.png b/docs/public/static/x/watermark-dark.png index 09c5dd851364c783dc8483df46b1b94f2407dc77..2275f8c25aa68954dc830125ae17f82bc76e7ef7 100644 GIT binary patch delta 112 zcmZo%%Cvh4(*$uo2@WO(28LB_Zh{O9lbANDPM*kT1QcLs{vd$@?2>|8n9{T_Q delta 230 zcmdnJgsE{U(*$uo6%Hl_28Nq;*BAYxRDGbsHD(~ppkokPHwQ>=Q~NobJCI<$(|sZ Zi%(LjAoy*_9H2uOJYD@<);T3K0RT<@Id1>} diff --git a/docs/public/static/x/watermark-light.png b/docs/public/static/x/watermark-light.png index 49cc374b73390d5487eb0eb37b4378edbcdf21e9..53e19304d1e1f667a279fd9e54c8c8c8eebea1a8 100644 GIT binary patch literal 36017 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 z zhfgHz+F5VhRIcA?h!%458Z|A!w4F{NnTYbDRysHD9%tCuLdj04x@4+vwReZ^whdoldE3}x1kGA%e%}30}lqG`uN`TK^J1J!VW4DndhMI`VWNwvpLl9(9t|lSN(#vGb4yfBQY&^#j+QyLg4| zmw+oAM$I)hnf{h+lf|mA?r{Xu(?wlEz;wD?w_P06=by}`#kdV~@8LBCPnxwme|;H- zlo+#K4F^h)V7u!5uwTyVPI=?@W#@!Lw_M!&3YSta44-!2M^2~=85Tz?i~D6~CdEg! zSS97bhA@;faT_%W(eY^UPt#n7y9WxfR6jAw;+=mZBLF8VdXM+ni-~NRjjud z$rAr61rfJfXb2%Q4aG#%s*7PnKb`J1ZptXn5fn~>CpsK5u6WKmja-SG9|$I5A$(4t z>Z=spz2KKW-=vU(`he*~@qcXUWaqV=t5Hg2R+)sseYn@nGJCa?VEu2y4qjMEWlDT1 z1tM+U*S}r&US`lDNULJrSGGH&*({o}ak#-MP_Rrs{TmKgU`LtNk5?KwF#wPOdW-9x z`O{4(4mmLK3QhsWtwnx;-i%?`_@$R#U1+yp*m1KDuUa$11wpFa79BW}8BPRr7bB3n z@U1vnv87JS^L7d@{hBpIGVn8q;*-eJ!-YnM`&vg}jGT$!{DRyj3lBHnI5_M4eU~(W z7QbrEBVimGVg(Gp2{-RQL*7g|Anna-giT0c6K5ugx@=2{-6O`kfY;^kAPeLVZek_j zXgmXgh)S0w9XbgvhWXxKeRf7+rO3Xzf~415&s2UmKmJqpE(HJ!k&*sIX&H!4lS5)o z!L^wz+%bcjV2K?^sG2EUg$GiYR!N?|{fU9qJsA_wx!xV_&H7z4A7v9bGz`lCmREL$ z0f=R!a7*^_PdDtre7<*ZuD*KoE5$46t->lw^`ShY;J2B=EZTN?FkyCwX6A41sYL(e z(5G}Zf^dn-q(+PvbjQQ3E~Zy)vysrqQn~Oj4I}&H?-z!{4BxwZBe%kwnqaAO;FIdOWe- z;#3=p6)|W?BkWkQQ8hoWJP~B5$-Qn6rhKxGg$hTP_~)K)-P_6gr3;NVvlZ{h!T|5S z22wm4E#VCm?Jm$UqPuJluXE?a6J`;-L*mRLNk3NEjqZd!C&bX+nr`;RUhe6#B?CBR z<5Zyt+Zk%lmLT3jA>yqv{K0eWrhlR$#3HY_5sk1`UUH|klB4w%UlTld*&<0p>+o}}?wUpo452UVMfeoZz|iLBaplQz#HuNuM6 zgFVEdkz~T81dc84M@1l9t>i=&RrAp>EwMO##F~O36>};pjL8MQJAnyL??5Z_W!B>( zz#tq#EI$3xc+#Zg+Zf1$v82-rGhKq&U zF=u@)fbk2j`k=9sNJ^|#pc`;1_tX5~qt;m1t}<>R%dwS(7VDFv?Cn$_LL1(pH2qXH zLQ{@1wxoNJ@{A3qp9DeMD9Nv7pR%PThH&Xmg;yG^lPUwvD|qX+f$$pyhpW1m?Oz}m zj0cZzvcD@a-5FR#Q9j3NHLK+%zN3G0z6pc+ji8>=yn6ff4->&pd5t{Z2PzGB&v#=-u1xq)jtBOucv#I}Od)t9{&F{3wmx3nj4D4&@!_u<*KhkpyIpQFi0u zwcF)i;hgvhCvt>N%?6*naoa~_E$we`t-xl^a3)gD4#fkdMsc)0Um1pYF@4EiO^t5f zPKP%uC$aiq6XZ$!!bZ6I=YFR>{s1rabiP1aI-`6cb&^39$v&w`%((*MSL%fLT`R>p z3h2rZ_!L+=7#+_u(rExnO~jen$@QTwBHRrDFob-+y{ZMn3L+oh=4gp0F3V{~EXagp zV2>cf$U^t6BUteG=+V2w@PfCxyKhO7JJuR6rP!onsb1rrasK{`2xvEvAGpO78ef(m z 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 OmwCGSxvXIZ From bd4b7245537d364337b95e06fc21288db9f9fc74 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Mon, 5 Feb 2024 01:20:37 +0100 Subject: [PATCH 03/53] [docs] Follow blank line convention with use client --- docs/data/introduction/licensing/licensing.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/data/introduction/licensing/licensing.md b/docs/data/introduction/licensing/licensing.md index 538813258a901..bb0d60c079c89 100644 --- a/docs/data/introduction/licensing/licensing.md +++ b/docs/data/introduction/licensing/licensing.md @@ -164,7 +164,6 @@ When using Next.js App Router, you have multiple options to install the license ```tsx 'use client'; - import { LicenseInfo } from '@mui/x-license-pro'; LicenseInfo.setLicenseKey('YOUR_LICENSE_KEY'); @@ -174,7 +173,6 @@ LicenseInfo.setLicenseKey('YOUR_LICENSE_KEY'); ```tsx 'use client'; - import { LicenseInfo } from '@mui/x-license-pro'; LicenseInfo.setLicenseKey('YOUR_LICENSE_KEY'); From 3c0590056d641db1d715f472ceb52ca851d14f05 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Mon, 5 Feb 2024 03:00:35 +0100 Subject: [PATCH 04/53] [docs] Fix image size and dark mode --- docs/data/introduction/support/support.md | 9 ++++++++- .../docs-infra/forking-an-example-dark.png | Bin 0 -> 47567 bytes .../static/docs-infra/forking-an-example.png | Bin 0 -> 48222 bytes 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 docs/public/static/docs-infra/forking-an-example-dark.png create mode 100644 docs/public/static/docs-infra/forking-an-example.png diff --git a/docs/data/introduction/support/support.md b/docs/data/introduction/support/support.md index 4884e04a003b2..2763c082e4d7d 100644 --- a/docs/data/introduction/support/support.md +++ b/docs/data/introduction/support/support.md @@ -28,7 +28,14 @@ It significantly increases the odds of fixing the problem. You have a few possible options to provide it: - You can browse the documentation, find an example close to your use case, and then open it in a live editor: - [![Forking an example](https://mui.com/static/docs-infra/forking-an-example.png)](/x/react-date-pickers/getting-started/#render-your-first-component) + + + Forking an example + + + Forking an example + + - [Data Grid](/x/react-data-grid/#mit-version-free-forever) - [Date Pickers](/x/react-date-pickers/getting-started/#render-your-first-component) diff --git a/docs/public/static/docs-infra/forking-an-example-dark.png b/docs/public/static/docs-infra/forking-an-example-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..1e388c6ec760324a6dd948603ed9b27ed6c0f339 GIT binary patch literal 47567 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

)J6!1D86 zSjmF5L67)PB@WYU`A{48l{~}dz~Z3~zgRYmKKlx1*JVB(>~|>*hS>w`iR?-I-Z&iK zY5er`#iC0Pd$hPzEekCkG5GG_df#u|OZ%nlKLIqIB>Um;)1SdLh(lNuYIQ7@Bq%** z9VvrDIwCPQYbtHf@_(0g(#!eI2PN(c;t1*XgN4!XO~c;OL!Qizs8hhYb6g0 zDj(8Jn7a{^y_o%r?VjtI!<+Os{HhO+>4C&4ntNGm$baeCS@hJV2{A`vqu+qBqp%pk zAv1jZ?g3ss4FY>vW~hHjKD2%^bF@6`tS@n4o~^WrUZZs>5j3IX$IHnof=h!0w>sH0 zwjxhd#F}jpXu(Jb2v$Pikei}ZWB;eS=;W@1j%zx?qbM8<*z+L_n91OQhkQ0=j>}<> zFjElxxebK?n26~qaqP9b?rdVAnN27OMfpqkGi+>NuC}aYqZ|JM$3kJ@M0-8+&0p%j z%_#rwgYb_M;on6N5a{$Atn_W$b>g4$|7wS8`>DabSb)NEZ}boBIv zD4f}n=+yvuPaLqy9_QbjBt_pYPqC@?hcMTdVEmgB3+tXfaTP`M1*7}0;Uw-CO?M8W zIA)s^zUWpj2X&&wpZ}Ep9q58Nw&ul*Jqxe5ad}HrB=Cs%ms55#+|hhRxSlTx^DJOP zW!F&*@K+{5;rlWZNe5w26(Z#CkB}g^O&R~JYv1^5Yr(vy z-CYW?{h9H`dCOeCR-w^C8=Y6Gmc=C096~o0iupSF2i3lgDowpUAE~`NGfryMZsj7+ zaULa_<@!i?-J)l{3pNiZnI$Q!-&)Y@^~cgkLf=kL)cp87uL4~@X6+G14>&El>byVQ z-3SQB+dADlj56!#!+e--PB%z@>+S3oci+r0`k_#BR5Uf)$g6(6#(Fu{jLQ3-Oh{0B zJpy0!#xCon_y7TRk&KqH^&cD4C{8OIGIbP`AL5XV7e%VQK|K&IGU

G@YVMU3ku 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 literal 0 HcmV?d00001 diff --git a/docs/public/static/docs-infra/forking-an-example.png b/docs/public/static/docs-infra/forking-an-example.png new file mode 100644 index 0000000000000000000000000000000000000000..d1a46bb379590bac20c7ae9a7f80a82571a01aa7 GIT binary patch literal 48222 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 Date: Mon, 5 Feb 2024 09:06:15 +0100 Subject: [PATCH 05/53] [pickers] Limit the valid values of `TDate` (#11791) Co-authored-by: alexandre --- .../custom-columns/EditingWithDatePickers.tsx | 2 +- .../WrappedSingleInputDateRangePicker.tsx | 3 +- .../lifecycle/LifeCycleDateFieldEmpty.js | 2 +- .../lifecycle/LifeCycleDateFieldEmpty.tsx | 2 +- .../LifeCycleDateFieldEmpty.tsx.preview | 2 +- .../lifecycle/LifeCycleDateRangeField.js | 5 +- .../lifecycle/LifeCycleDateRangeField.tsx | 7 +-- .../LifeCycleDateRangeField.tsx.preview | 5 +- .../x/api/date-pickers/date-calendar.json | 10 +-- docs/pages/x/api/date-pickers/date-field.json | 10 +-- .../pages/x/api/date-pickers/date-picker.json | 10 +-- .../api/date-pickers/date-range-calendar.json | 10 +-- .../date-pickers/date-range-picker-day.json | 2 +- .../x/api/date-pickers/date-range-picker.json | 10 +-- .../x/api/date-pickers/date-time-field.json | 18 +++--- .../x/api/date-pickers/date-time-picker.json | 18 +++--- .../date-pickers/date-time-range-picker.json | 18 +++--- .../api/date-pickers/desktop-date-picker.json | 10 +-- .../desktop-date-range-picker.json | 10 +-- .../desktop-date-time-picker.json | 18 +++--- .../desktop-date-time-range-picker.json | 18 +++--- .../api/date-pickers/desktop-time-picker.json | 10 +-- .../x/api/date-pickers/digital-clock.json | 10 +-- .../api/date-pickers/mobile-date-picker.json | 10 +-- .../mobile-date-range-picker.json | 10 +-- .../date-pickers/mobile-date-time-picker.json | 18 +++--- .../mobile-date-time-range-picker.json | 18 +++--- .../api/date-pickers/mobile-time-picker.json | 10 +-- .../x/api/date-pickers/month-calendar.json | 10 +-- .../multi-input-date-range-field.json | 10 +-- .../multi-input-date-time-range-field.json | 18 +++--- .../multi-input-time-range-field.json | 10 +-- .../multi-section-digital-clock.json | 10 +-- .../pages/x/api/date-pickers/pickers-day.json | 2 +- .../single-input-date-range-field.json | 10 +-- .../single-input-date-time-range-field.json | 18 +++--- .../single-input-time-range-field.json | 10 +-- .../api/date-pickers/static-date-picker.json | 10 +-- .../static-date-range-picker.json | 10 +-- .../date-pickers/static-date-time-picker.json | 18 +++--- .../api/date-pickers/static-time-picker.json | 10 +-- docs/pages/x/api/date-pickers/time-clock.json | 10 +-- docs/pages/x/api/date-pickers/time-field.json | 10 +-- .../pages/x/api/date-pickers/time-picker.json | 10 +-- .../x/api/date-pickers/year-calendar.json | 10 +-- docs/scripts/generateProptypes.ts | 29 +++++++++ .../DateRangeCalendar/DateRangeCalendar.tsx | 22 +++---- .../DateRangeCalendar.types.ts | 15 ++--- .../src/DateRangeCalendar/useDragRange.ts | 12 ++-- .../src/DateRangePicker/DateRangePicker.tsx | 15 ++--- .../DateRangePicker/DateRangePicker.types.ts | 7 ++- .../DateRangePickerToolbar.tsx | 7 ++- .../src/DateRangePicker/shared.tsx | 13 ++-- .../DateRangePickerDay/DateRangePickerDay.tsx | 16 ++--- .../DateTimeRangePicker.tsx | 28 ++++----- .../DateTimeRangePicker.types.ts | 7 ++- .../DateTimeRangePickerTimeWrapper.tsx | 5 +- .../DateTimeRangePickerToolbar.tsx | 16 ++--- .../src/DateTimeRangePicker/shared.tsx | 11 ++-- .../DesktopDateRangePicker.tsx | 20 +++--- .../DesktopDateRangePicker.types.ts | 7 ++- .../DesktopDateTimeRangePicker.tsx | 30 ++++----- .../DesktopDateTimeRangePicker.types.ts | 7 ++- .../DesktopDateTimeRangePickerLayout.tsx | 3 +- .../MobileDateRangePicker.tsx | 20 +++--- .../MobileDateRangePicker.types.ts | 7 ++- .../MobileDateTimeRangePicker.tsx | 30 ++++----- .../MobileDateTimeRangePicker.types.ts | 7 ++- .../MultiInputDateRangeField.tsx | 20 +++--- .../MultiInputDateRangeField.types.ts | 20 +++--- .../MultiInputDateTimeRangeField.tsx | 28 ++++----- .../MultiInputDateTimeRangeField.types.ts | 21 ++++--- .../MultiInputTimeRangeField.tsx | 20 +++--- .../MultiInputTimeRangeField.types.ts | 22 ++++--- .../SingleInputDateRangeField.tsx | 20 +++--- .../SingleInputDateRangeField.types.ts | 22 ++++--- .../useSingleInputDateRangeField.ts | 8 ++- .../SingleInputDateTimeRangeField.tsx | 23 +++---- .../SingleInputDateTimeRangeField.types.ts | 20 +++--- .../useSingleInputDateTimeRangeField.ts | 11 +++- .../SingleInputTimeRangeField.tsx | 20 +++--- .../SingleInputTimeRangeField.types.ts | 22 ++++--- .../useSingleInputTimeRangeField.ts | 8 ++- .../StaticDateRangePicker.tsx | 20 +++--- .../StaticDateRangePicker.types.ts | 7 ++- .../dateRangeViewRenderers.tsx | 9 ++- .../internals/hooks/models/useRangePicker.ts | 21 ++++--- .../useDesktopRangePicker.tsx | 3 +- .../useDesktopRangePicker.types.ts | 20 +++--- .../hooks/useEnrichedRangePickerFieldProps.ts | 20 ++++-- .../useMobileRangePicker.tsx | 3 +- .../useMobileRangePicker.types.ts | 20 +++--- .../useMultiInputDateRangeField.ts | 17 +++-- .../useMultiInputDateTimeRangeField.ts | 16 +++-- .../useMultiInputTimeRangeField.ts | 22 +++---- .../useStaticRangePicker.tsx | 3 +- .../useStaticRangePicker.types.ts | 17 +++-- .../src/internals/models/dateRange.ts | 7 ++- .../src/internals/models/dateTimeRange.ts | 5 +- .../src/internals/models/fields.ts | 10 ++- .../src/internals/models/timeRange.ts | 5 +- .../src/internals/utils/date-range-manager.ts | 10 +-- .../src/internals/utils/date-utils.ts | 10 +-- .../utils/validation/validateDateRange.ts | 4 +- .../utils/validation/validateDateTimeRange.ts | 4 +- .../src/internals/utils/valueManagers.ts | 3 +- .../x-date-pickers-pro/src/models/range.ts | 6 +- .../src/themeAugmentation/props.d.ts | 34 +++++----- .../AdapterDateFnsBase/AdapterDateFnsBase.ts | 6 ++ .../AdapterDateFnsJalali.ts | 6 ++ .../src/AdapterDayjs/AdapterDayjs.ts | 6 ++ .../src/AdapterLuxon/AdapterLuxon.ts | 6 ++ .../src/AdapterMoment/AdapterMoment.ts | 6 ++ .../AdapterMomentHijri/AdapterMomentHijri.ts | 6 ++ .../AdapterMomentJalaali.ts | 6 ++ .../src/DateCalendar/DateCalendar.tsx | 17 ++--- .../src/DateCalendar/DateCalendar.types.ts | 12 ++-- .../src/DateCalendar/DayCalendar.tsx | 15 ++--- .../tests/validation.DateCalendar.test.tsx | 3 +- .../src/DateCalendar/useCalendarState.tsx | 16 ++--- .../src/DateCalendar/useIsDateDisabled.ts | 3 +- .../src/DateField/DateField.tsx | 15 ++--- .../src/DateField/DateField.types.ts | 22 +++---- .../src/DateField/useDateField.ts | 5 +- .../src/DatePicker/DatePicker.tsx | 15 ++--- .../src/DatePicker/DatePicker.types.ts | 7 ++- .../src/DatePicker/DatePickerToolbar.tsx | 16 ++--- .../x-date-pickers/src/DatePicker/shared.tsx | 20 +++--- .../src/DateTimeField/DateTimeField.tsx | 23 +++---- .../src/DateTimeField/DateTimeField.types.ts | 22 +++---- .../src/DateTimeField/useDateTimeField.ts | 5 +- .../src/DateTimePicker/DateTimePicker.tsx | 23 +++---- .../DateTimePicker/DateTimePicker.types.ts | 7 ++- .../DateTimePicker/DateTimePickerToolbar.tsx | 9 ++- .../src/DateTimePicker/shared.tsx | 18 +++--- .../DesktopDatePicker/DesktopDatePicker.tsx | 21 +++---- .../DesktopDatePicker.types.ts | 8 +-- .../tests/DesktopDatePicker.test.tsx | 9 --- .../DesktopDateTimePicker.tsx | 28 ++++----- .../DesktopDateTimePicker.types.ts | 8 +-- .../DesktopTimePicker/DesktopTimePicker.tsx | 21 +++---- .../DesktopTimePicker.types.ts | 8 +-- .../src/DigitalClock/DigitalClock.tsx | 16 ++--- .../src/DigitalClock/DigitalClock.types.ts | 7 ++- .../LocalizationProvider.tsx | 17 ++--- .../src/MobileDatePicker/MobileDatePicker.tsx | 16 ++--- .../MobileDatePicker.types.ts | 8 +-- .../MobileDateTimePicker.tsx | 29 +++++---- .../MobileDateTimePicker.types.ts | 8 +-- .../tests/MobileDateTimePicker.test.tsx | 9 +-- .../src/MobileTimePicker/MobileTimePicker.tsx | 16 ++--- .../MobileTimePicker.types.ts | 20 +++--- .../src/MonthCalendar/MonthCalendar.tsx | 17 ++--- .../src/MonthCalendar/MonthCalendar.types.ts | 4 +- .../MultiSectionDigitalClock.tsx | 16 ++--- .../MultiSectionDigitalClock.types.ts | 6 +- .../MultiSectionDigitalClock.utils.ts | 10 +-- .../PickersCalendarHeader.tsx | 16 ++--- .../PickersCalendarHeader.types.ts | 13 ++-- .../src/PickersDay/PickersDay.tsx | 9 +-- .../src/PickersLayout/PickersLayout.tsx | 3 +- .../src/PickersLayout/PickersLayout.types.ts | 33 +++++++--- .../src/PickersLayout/usePickerLayout.tsx | 9 ++- .../src/StaticDatePicker/StaticDatePicker.tsx | 16 ++--- .../StaticDatePicker.types.ts | 8 +-- .../StaticDateTimePicker.tsx | 29 +++++---- .../StaticDateTimePicker.types.ts | 8 +-- .../src/StaticTimePicker/StaticTimePicker.tsx | 16 ++--- .../StaticTimePicker.types.ts | 8 +-- .../x-date-pickers/src/TimeClock/Clock.tsx | 7 ++- .../src/TimeClock/ClockNumbers.tsx | 8 +-- .../src/TimeClock/TimeClock.tsx | 16 ++--- .../src/TimeClock/TimeClock.types.ts | 11 ++-- .../src/TimeField/TimeField.tsx | 15 ++--- .../src/TimeField/TimeField.types.ts | 22 +++---- .../src/TimeField/useTimeField.ts | 5 +- .../src/TimePicker/TimePicker.tsx | 15 ++--- .../src/TimePicker/TimePicker.types.ts | 7 ++- .../src/TimePicker/TimePickerToolbar.tsx | 7 ++- .../x-date-pickers/src/TimePicker/shared.tsx | 14 +++-- .../src/YearCalendar/YearCalendar.tsx | 19 +++--- .../src/YearCalendar/YearCalendar.types.ts | 4 +- .../dateTimeViewRenderers.tsx | 5 +- .../dateViewRenderers/dateViewRenderers.tsx | 10 +-- .../internals/hooks/date-helpers-hooks.tsx | 10 +-- .../internals/hooks/useClockReferenceDate.ts | 4 +- .../useDesktopPicker/useDesktopPicker.tsx | 4 +- .../useDesktopPicker.types.ts | 31 +++++++--- .../src/internals/hooks/useField/useField.ts | 4 +- .../hooks/useField/useField.types.ts | 30 ++++++--- .../hooks/useField/useField.utils.ts | 38 +++++++----- .../useField/useFieldCharacterEditing.ts | 9 ++- .../internals/hooks/useField/useFieldState.ts | 4 +- .../hooks/useMobilePicker/useMobilePicker.tsx | 4 +- .../useMobilePicker/useMobilePicker.types.ts | 31 +++++++--- .../internals/hooks/usePicker/usePicker.ts | 4 +- .../hooks/usePicker/usePicker.types.ts | 8 +-- .../hooks/usePicker/usePickerValue.ts | 9 ++- .../hooks/usePicker/usePickerValue.types.ts | 9 +-- .../hooks/usePicker/usePickerViews.ts | 10 +-- .../hooks/useStaticPicker/useStaticPicker.tsx | 4 +- .../useStaticPicker/useStaticPicker.types.ts | 20 +++--- .../src/internals/hooks/useUtils.ts | 14 +++-- .../src/internals/hooks/useValidation.ts | 10 ++- .../internals/hooks/useValueWithTimezone.ts | 10 ++- .../src/internals/hooks/useViews.tsx | 3 +- .../src/internals/models/fields.ts | 10 ++- .../models/props/basePickerProps.tsx | 5 +- .../src/internals/models/props/clock.ts | 8 +-- .../src/internals/models/validation.ts | 15 ++--- .../src/internals/utils/date-time-utils.ts | 15 +++-- .../src/internals/utils/date-utils.ts | 45 ++++++++++---- .../utils/getDefaultReferenceDate.ts | 12 ++-- .../src/internals/utils/time-utils.ts | 20 +++--- .../utils/validation/validateDate.ts | 4 +- .../utils/validation/validateDateTime.ts | 4 +- .../utils/validation/validateTime.ts | 4 +- .../src/internals/utils/valueManagers.ts | 3 +- .../src/locales/utils/pickersLocaleTextApi.ts | 20 ++++-- .../x-date-pickers/src/models/adapters.ts | 3 +- packages/x-date-pickers/src/models/fields.ts | 11 +++- packages/x-date-pickers/src/models/pickers.ts | 4 ++ .../tests/fieldKeyboardInteraction.test.tsx | 6 +- .../src/themeAugmentation/props.d.ts | 62 +++++++++---------- .../timeViewRenderers/timeViewRenderers.tsx | 8 +-- scripts/x-date-pickers-pro.exports.json | 2 + scripts/x-date-pickers.exports.json | 2 + .../describeGregorianAdapter.ts | 12 ++-- .../describeGregorianAdapter.types.ts | 8 +-- .../testCalculations.ts | 9 ++- .../describeHijriAdapter.ts | 4 +- .../describeHijriAdapter.types.ts | 4 +- .../describeJalaliAdapter.ts | 4 +- .../describeJalaliAdapter.types.ts | 4 +- test/utils/pickers/misc.ts | 6 +- 235 files changed, 1631 insertions(+), 1280 deletions(-) diff --git a/docs/data/data-grid/custom-columns/EditingWithDatePickers.tsx b/docs/data/data-grid/custom-columns/EditingWithDatePickers.tsx index 4f8f4803dd6c5..5942bbb3c31c6 100644 --- a/docs/data/data-grid/custom-columns/EditingWithDatePickers.tsx +++ b/docs/data/data-grid/custom-columns/EditingWithDatePickers.tsx @@ -70,7 +70,7 @@ function GridEditDateCell({ field, value, colDef, -}: GridRenderEditCellParams) { +}: GridRenderEditCellParams) { const apiRef = useGridApiContext(); const Component = colDef.type === 'dateTime' ? DateTimePicker : DatePicker; diff --git a/docs/data/date-pickers/custom-field/WrappedSingleInputDateRangePicker.tsx b/docs/data/date-pickers/custom-field/WrappedSingleInputDateRangePicker.tsx index 6e104e4b67779..a7f000683fc7c 100644 --- a/docs/data/date-pickers/custom-field/WrappedSingleInputDateRangePicker.tsx +++ b/docs/data/date-pickers/custom-field/WrappedSingleInputDateRangePicker.tsx @@ -8,8 +8,9 @@ import { SingleInputDateRangeFieldProps, } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; -type FieldComponent = (( +type FieldComponent = (( props: SingleInputDateRangeFieldProps & React.RefAttributes, ) => React.JSX.Element) & { fieldType?: string }; diff --git a/docs/data/date-pickers/lifecycle/LifeCycleDateFieldEmpty.js b/docs/data/date-pickers/lifecycle/LifeCycleDateFieldEmpty.js index ff6c9544090e2..3ed120732789b 100644 --- a/docs/data/date-pickers/lifecycle/LifeCycleDateFieldEmpty.js +++ b/docs/data/date-pickers/lifecycle/LifeCycleDateFieldEmpty.js @@ -12,7 +12,7 @@ export default function LifeCycleDateFieldEmpty() { return ( - setValue(newValue)} /> + Value: {value == null ? 'null' : value.format('L')} diff --git a/docs/data/date-pickers/lifecycle/LifeCycleDateFieldEmpty.tsx b/docs/data/date-pickers/lifecycle/LifeCycleDateFieldEmpty.tsx index 22fafe61283b9..6444023122b6b 100644 --- a/docs/data/date-pickers/lifecycle/LifeCycleDateFieldEmpty.tsx +++ b/docs/data/date-pickers/lifecycle/LifeCycleDateFieldEmpty.tsx @@ -12,7 +12,7 @@ export default function LifeCycleDateFieldEmpty() { return ( - setValue(newValue)} /> + Value: {value == null ? 'null' : value.format('L')} diff --git a/docs/data/date-pickers/lifecycle/LifeCycleDateFieldEmpty.tsx.preview b/docs/data/date-pickers/lifecycle/LifeCycleDateFieldEmpty.tsx.preview index 7f22674742a9f..1746e78fd888d 100644 --- a/docs/data/date-pickers/lifecycle/LifeCycleDateFieldEmpty.tsx.preview +++ b/docs/data/date-pickers/lifecycle/LifeCycleDateFieldEmpty.tsx.preview @@ -1,4 +1,4 @@ - setValue(newValue)} /> + Value: {value == null ? 'null' : value.format('L')} \ No newline at end of file diff --git a/docs/data/date-pickers/lifecycle/LifeCycleDateRangeField.js b/docs/data/date-pickers/lifecycle/LifeCycleDateRangeField.js index a77c9d6d5abf8..ff34833efbb6a 100644 --- a/docs/data/date-pickers/lifecycle/LifeCycleDateRangeField.js +++ b/docs/data/date-pickers/lifecycle/LifeCycleDateRangeField.js @@ -14,10 +14,7 @@ export default function LifeCycleDateRangeField() { - setValue(newValue)} - /> + diff --git a/docs/data/date-pickers/lifecycle/LifeCycleDateRangeField.tsx b/docs/data/date-pickers/lifecycle/LifeCycleDateRangeField.tsx index f6cae364e97b8..8bab9a5ad4607 100644 --- a/docs/data/date-pickers/lifecycle/LifeCycleDateRangeField.tsx +++ b/docs/data/date-pickers/lifecycle/LifeCycleDateRangeField.tsx @@ -9,7 +9,7 @@ import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDa import { DateRange } from '@mui/x-date-pickers-pro/models'; export default function LifeCycleDateRangeField() { - const [value, setValue] = React.useState>([ + const [value, setValue] = React.useState>([ dayjs('2022-04-17'), null, ]); @@ -18,10 +18,7 @@ export default function LifeCycleDateRangeField() { - setValue(newValue)} - /> + diff --git a/docs/data/date-pickers/lifecycle/LifeCycleDateRangeField.tsx.preview b/docs/data/date-pickers/lifecycle/LifeCycleDateRangeField.tsx.preview index 90f4a115ac5da..4cce05110e86b 100644 --- a/docs/data/date-pickers/lifecycle/LifeCycleDateRangeField.tsx.preview +++ b/docs/data/date-pickers/lifecycle/LifeCycleDateRangeField.tsx.preview @@ -1,9 +1,6 @@ - setValue(newValue)} - /> + diff --git a/docs/pages/x/api/date-pickers/date-calendar.json b/docs/pages/x/api/date-pickers/date-calendar.json index f0031bb5be3de..e7b9b342558f2 100644 --- a/docs/pages/x/api/date-pickers/date-calendar.json +++ b/docs/pages/x/api/date-pickers/date-calendar.json @@ -10,7 +10,7 @@ "returned": "string" } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableHighlightToday": { "type": { "name": "bool" }, "default": "false" }, @@ -24,8 +24,8 @@ } }, "loading": { "type": { "name": "bool" }, "default": "false" }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "monthsPerRow": { "type": { "name": "enum", "description": "3
| 4" }, "default": "3" @@ -68,7 +68,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date using the validation props, except callbacks such as `shouldDisableDate`." }, "renderLoading": { @@ -126,7 +126,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/date-field.json b/docs/pages/x/api/date-pickers/date-field.json index 46e896fb433f9..ac12fc860e072 100644 --- a/docs/pages/x/api/date-pickers/date-field.json +++ b/docs/pages/x/api/date-pickers/date-field.json @@ -9,7 +9,7 @@ }, "default": "'primary'" }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disablePast": { "type": { "name": "bool" }, "default": "false" }, @@ -36,8 +36,8 @@ }, "default": "'none'" }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "name": { "type": { "name": "string" } }, "onChange": { "type": { "name": "func" }, @@ -63,7 +63,7 @@ }, "readOnly": { "type": { "name": "bool" }, "default": "false" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used." }, "required": { "type": { "name": "bool" }, "default": "false" }, @@ -123,7 +123,7 @@ "unstableFieldRef": { "type": { "name": "union", "description": "func
| object" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "variant": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/date-picker.json b/docs/pages/x/api/date-pickers/date-picker.json index 76b6407274a7d..b4a4bd93ed6e2 100644 --- a/docs/pages/x/api/date-pickers/date-picker.json +++ b/docs/pages/x/api/date-pickers/date-picker.json @@ -14,7 +14,7 @@ "returned": "string" } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "desktopModeMediaQuery": { "type": { "name": "string" }, "default": "'@media (pointer: fine)'" @@ -35,8 +35,8 @@ "label": { "type": { "name": "node" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "monthsPerRow": { "type": { "name": "enum", "description": "3
| 4" }, "default": "3" @@ -96,7 +96,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -160,7 +160,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/date-range-calendar.json b/docs/pages/x/api/date-pickers/date-range-calendar.json index afa6e86ecdf77..bc7330a92d879 100644 --- a/docs/pages/x/api/date-pickers/date-range-calendar.json +++ b/docs/pages/x/api/date-pickers/date-range-calendar.json @@ -26,7 +26,7 @@ "type": { "name": "enum", "description": "'end'
| 'start'" }, "default": "'start'" }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "disableAutoMonthSwitching": { "type": { "name": "bool" }, "default": "false" }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableDragEditing": { "type": { "name": "bool" }, "default": "false" }, @@ -37,8 +37,8 @@ "fixedWeekNumber": { "type": { "name": "number" }, "default": "undefined" }, "focusedView": { "type": { "name": "enum", "description": "'day'" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "onChange": { "type": { "name": "func" }, "signature": { @@ -76,7 +76,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date using the validation props, except callbacks such as `shouldDisableDate`." }, "renderLoading": { @@ -118,7 +118,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "view": { "type": { "name": "enum", "description": "'day'" } }, "views": { "type": { "name": "arrayOf", "description": "Array<'day'>" } } }, diff --git a/docs/pages/x/api/date-pickers/date-range-picker-day.json b/docs/pages/x/api/date-pickers/date-range-picker-day.json index 03725816fc5ab..fc19b9e50ec6d 100644 --- a/docs/pages/x/api/date-pickers/date-range-picker-day.json +++ b/docs/pages/x/api/date-pickers/date-range-picker-day.json @@ -1,6 +1,6 @@ { "props": { - "day": { "type": { "name": "any" }, "required": true }, + "day": { "type": { "name": "object" }, "required": true }, "isEndOfHighlighting": { "type": { "name": "bool" }, "required": true }, "isEndOfPreviewing": { "type": { "name": "bool" }, "required": true }, "isFirstVisibleCell": { "type": { "name": "bool" }, "required": true }, diff --git a/docs/pages/x/api/date-pickers/date-range-picker.json b/docs/pages/x/api/date-pickers/date-range-picker.json index 09c5a61c90075..e880dfb8e391d 100644 --- a/docs/pages/x/api/date-pickers/date-range-picker.json +++ b/docs/pages/x/api/date-pickers/date-range-picker.json @@ -26,7 +26,7 @@ "type": { "name": "enum", "description": "'end'
| 'start'" }, "default": "'start'" }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "desktopModeMediaQuery": { "type": { "name": "string" }, "default": "'@media (pointer: fine)'" @@ -49,8 +49,8 @@ "label": { "type": { "name": "node" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "name": { "type": { "name": "string" } }, "onAccept": { "type": { "name": "func" }, @@ -97,7 +97,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -145,7 +145,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "viewRenderers": { "type": { "name": "shape", "description": "{ day?: func }" } } }, "name": "DateRangePicker", diff --git a/docs/pages/x/api/date-pickers/date-time-field.json b/docs/pages/x/api/date-pickers/date-time-field.json index 2ccfcbcc7dd5e..6c12c32f7960c 100644 --- a/docs/pages/x/api/date-pickers/date-time-field.json +++ b/docs/pages/x/api/date-pickers/date-time-field.json @@ -10,7 +10,7 @@ }, "default": "'primary'" }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableIgnoringDatePartForTimeValidation": { "type": { "name": "bool" }, "default": "false" }, @@ -38,12 +38,12 @@ }, "default": "'none'" }, - "maxDate": { "type": { "name": "any" } }, - "maxDateTime": { "type": { "name": "any" } }, - "maxTime": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, - "minDateTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "maxDateTime": { "type": { "name": "object" } }, + "maxTime": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, + "minDateTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "name": { "type": { "name": "string" } }, "onChange": { @@ -70,7 +70,7 @@ }, "readOnly": { "type": { "name": "bool" }, "default": "false" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used." }, "required": { "type": { "name": "bool" }, "default": "false" }, @@ -138,7 +138,7 @@ "unstableFieldRef": { "type": { "name": "union", "description": "func
| object" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "variant": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/date-time-picker.json b/docs/pages/x/api/date-pickers/date-time-picker.json index 5416d121b8774..1c10d4ccfcdee 100644 --- a/docs/pages/x/api/date-pickers/date-time-picker.json +++ b/docs/pages/x/api/date-pickers/date-time-picker.json @@ -16,7 +16,7 @@ "returned": "string" } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "desktopModeMediaQuery": { "type": { "name": "string" }, "default": "'@media (pointer: fine)'" @@ -38,12 +38,12 @@ "label": { "type": { "name": "node" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "maxDateTime": { "type": { "name": "any" } }, - "maxTime": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, - "minDateTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "maxDateTime": { "type": { "name": "object" } }, + "maxTime": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, + "minDateTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "monthsPerRow": { "type": { "name": "enum", "description": "3
| 4" }, @@ -104,7 +104,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -185,7 +185,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/date-time-range-picker.json b/docs/pages/x/api/date-pickers/date-time-range-picker.json index 55d6d1ee2f796..ce588b76b7efb 100644 --- a/docs/pages/x/api/date-pickers/date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/date-time-range-picker.json @@ -27,7 +27,7 @@ "type": { "name": "enum", "description": "'end'
| 'start'" }, "default": "'start'" }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "desktopModeMediaQuery": { "type": { "name": "string" }, "default": "'@media (pointer: fine)'" @@ -53,12 +53,12 @@ "label": { "type": { "name": "node" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "maxDateTime": { "type": { "name": "any" } }, - "maxTime": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, - "minDateTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "maxDateTime": { "type": { "name": "object" } }, + "maxTime": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, + "minDateTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "name": { "type": { "name": "string" } }, "onAccept": { @@ -116,7 +116,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -181,7 +181,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/desktop-date-picker.json b/docs/pages/x/api/date-pickers/desktop-date-picker.json index 69ab72f56f8b9..af6728769c595 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-picker.json @@ -14,7 +14,7 @@ "returned": "string" } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableHighlightToday": { "type": { "name": "bool" }, "default": "false" }, @@ -31,8 +31,8 @@ "label": { "type": { "name": "node" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "monthsPerRow": { "type": { "name": "enum", "description": "3
| 4" }, "default": "3" @@ -92,7 +92,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -156,7 +156,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/desktop-date-range-picker.json b/docs/pages/x/api/date-pickers/desktop-date-range-picker.json index f846abac5f697..6803cc3627dbf 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-range-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-range-picker.json @@ -26,7 +26,7 @@ "type": { "name": "enum", "description": "'end'
| 'start'" }, "default": "'start'" }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "disableAutoMonthSwitching": { "type": { "name": "bool" }, "default": "false" }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableDragEditing": { "type": { "name": "bool" }, "default": "false" }, @@ -45,8 +45,8 @@ "label": { "type": { "name": "node" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "name": { "type": { "name": "string" } }, "onAccept": { "type": { "name": "func" }, @@ -93,7 +93,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -141,7 +141,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "viewRenderers": { "type": { "name": "shape", "description": "{ day?: func }" } } }, "name": "DesktopDateRangePicker", diff --git a/docs/pages/x/api/date-pickers/desktop-date-time-picker.json b/docs/pages/x/api/date-pickers/desktop-date-time-picker.json index 854019a2a091b..737c15cbb3e37 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-time-picker.json @@ -16,7 +16,7 @@ "returned": "string" } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableHighlightToday": { "type": { "name": "bool" }, "default": "false" }, @@ -34,12 +34,12 @@ "label": { "type": { "name": "node" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "maxDateTime": { "type": { "name": "any" } }, - "maxTime": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, - "minDateTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "maxDateTime": { "type": { "name": "object" } }, + "maxTime": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, + "minDateTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "monthsPerRow": { "type": { "name": "enum", "description": "3
| 4" }, @@ -100,7 +100,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -181,7 +181,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json b/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json index 90357b9228f5f..b083f9ceeb1e0 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json @@ -27,7 +27,7 @@ "type": { "name": "enum", "description": "'end'
| 'start'" }, "default": "'start'" }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "disableAutoMonthSwitching": { "type": { "name": "bool" }, "default": "false" }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableDragEditing": { "type": { "name": "bool" }, "default": "false" }, @@ -49,12 +49,12 @@ "label": { "type": { "name": "node" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "maxDateTime": { "type": { "name": "any" } }, - "maxTime": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, - "minDateTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "maxDateTime": { "type": { "name": "object" } }, + "maxTime": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, + "minDateTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "name": { "type": { "name": "string" } }, "onAccept": { @@ -112,7 +112,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -177,7 +177,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/desktop-time-picker.json b/docs/pages/x/api/date-pickers/desktop-time-picker.json index 1b91794a34ccb..8273e26e92d90 100644 --- a/docs/pages/x/api/date-pickers/desktop-time-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-time-picker.json @@ -7,7 +7,7 @@ "type": { "name": "bool" }, "default": "`true` for desktop, `false` for mobile (based on the chosen wrapper and `desktopModeMediaQuery` prop)." }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableIgnoringDatePartForTimeValidation": { "type": { "name": "bool" }, "default": "false" }, @@ -21,8 +21,8 @@ "inputRef": { "type": { "name": "custom", "description": "ref" } }, "label": { "type": { "name": "node" } }, "localeText": { "type": { "name": "object" } }, - "maxTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "name": { "type": { "name": "string" } }, "onAccept": { @@ -71,7 +71,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "selectedSections": { @@ -118,7 +118,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/digital-clock.json b/docs/pages/x/api/date-pickers/digital-clock.json index 8f3d3af0be1c9..ab41bb11244ee 100644 --- a/docs/pages/x/api/date-pickers/digital-clock.json +++ b/docs/pages/x/api/date-pickers/digital-clock.json @@ -3,14 +3,14 @@ "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, "autoFocus": { "type": { "name": "bool" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableIgnoringDatePartForTimeValidation": { "type": { "name": "bool" }, "default": "false" }, "disablePast": { "type": { "name": "bool" }, "default": "false" }, "focusedView": { "type": { "name": "enum", "description": "'hours'" } }, - "maxTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "onChange": { "type": { "name": "func" }, @@ -33,7 +33,7 @@ "openTo": { "type": { "name": "enum", "description": "'hours'" } }, "readOnly": { "type": { "name": "bool" }, "default": "false" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid time using the validation props, except callbacks such as `shouldDisableTime`." }, "shouldDisableTime": { @@ -67,7 +67,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", "description": "'hours'" } }, "views": { "type": { "name": "arrayOf", "description": "Array<'hours'>" }, diff --git a/docs/pages/x/api/date-pickers/mobile-date-picker.json b/docs/pages/x/api/date-pickers/mobile-date-picker.json index d519138df7f8d..54682e73a7af4 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-picker.json @@ -14,7 +14,7 @@ "returned": "string" } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableHighlightToday": { "type": { "name": "bool" }, "default": "false" }, @@ -31,8 +31,8 @@ "label": { "type": { "name": "node" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "monthsPerRow": { "type": { "name": "enum", "description": "3
| 4" }, "default": "3" @@ -92,7 +92,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -156,7 +156,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/mobile-date-range-picker.json b/docs/pages/x/api/date-pickers/mobile-date-range-picker.json index 88e6f7786dc1b..a4e7fd4f0ee02 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-range-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-range-picker.json @@ -22,7 +22,7 @@ "type": { "name": "enum", "description": "'end'
| 'start'" }, "default": "'start'" }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "disableAutoMonthSwitching": { "type": { "name": "bool" }, "default": "false" }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableDragEditing": { "type": { "name": "bool" }, "default": "false" }, @@ -41,8 +41,8 @@ "label": { "type": { "name": "node" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "name": { "type": { "name": "string" } }, "onAccept": { "type": { "name": "func" }, @@ -89,7 +89,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -137,7 +137,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "viewRenderers": { "type": { "name": "shape", "description": "{ day?: func }" } } }, "name": "MobileDateRangePicker", diff --git a/docs/pages/x/api/date-pickers/mobile-date-time-picker.json b/docs/pages/x/api/date-pickers/mobile-date-time-picker.json index df40abdc0f886..dfc374df13ffd 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-time-picker.json @@ -16,7 +16,7 @@ "returned": "string" } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableHighlightToday": { "type": { "name": "bool" }, "default": "false" }, @@ -34,12 +34,12 @@ "label": { "type": { "name": "node" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "maxDateTime": { "type": { "name": "any" } }, - "maxTime": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, - "minDateTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "maxDateTime": { "type": { "name": "object" } }, + "maxTime": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, + "minDateTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "monthsPerRow": { "type": { "name": "enum", "description": "3
| 4" }, @@ -100,7 +100,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -172,7 +172,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json b/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json index 688f24d49b0d3..fdbfb01fa0753 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json @@ -23,7 +23,7 @@ "type": { "name": "enum", "description": "'end'
| 'start'" }, "default": "'start'" }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "disableAutoMonthSwitching": { "type": { "name": "bool" }, "default": "false" }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableDragEditing": { "type": { "name": "bool" }, "default": "false" }, @@ -45,12 +45,12 @@ "label": { "type": { "name": "node" } }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "maxDateTime": { "type": { "name": "any" } }, - "maxTime": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, - "minDateTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "maxDateTime": { "type": { "name": "object" } }, + "maxTime": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, + "minDateTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "name": { "type": { "name": "string" } }, "onAccept": { @@ -108,7 +108,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -173,7 +173,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/mobile-time-picker.json b/docs/pages/x/api/date-pickers/mobile-time-picker.json index 59748eba26059..ff478590ca5df 100644 --- a/docs/pages/x/api/date-pickers/mobile-time-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-time-picker.json @@ -7,7 +7,7 @@ "type": { "name": "bool" }, "default": "`true` for desktop, `false` for mobile (based on the chosen wrapper and `desktopModeMediaQuery` prop)." }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableIgnoringDatePartForTimeValidation": { "type": { "name": "bool" }, "default": "false" }, @@ -21,8 +21,8 @@ "inputRef": { "type": { "name": "custom", "description": "ref" } }, "label": { "type": { "name": "node" } }, "localeText": { "type": { "name": "object" } }, - "maxTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "name": { "type": { "name": "string" } }, "onAccept": { @@ -71,7 +71,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "selectedSections": { @@ -109,7 +109,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/month-calendar.json b/docs/pages/x/api/date-pickers/month-calendar.json index 55c00405e6710..2fe02db3fe453 100644 --- a/docs/pages/x/api/date-pickers/month-calendar.json +++ b/docs/pages/x/api/date-pickers/month-calendar.json @@ -1,13 +1,13 @@ { "props": { "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" } }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableHighlightToday": { "type": { "name": "bool" }, "default": "false" }, "disablePast": { "type": { "name": "bool" }, "default": "false" }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "monthsPerRow": { "type": { "name": "enum", "description": "3
| 4" }, "default": "3" @@ -18,7 +18,7 @@ }, "readOnly": { "type": { "name": "bool" } }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid month using the validation props, except callbacks such as `shouldDisableMonth`." }, "shouldDisableMonth": { @@ -44,7 +44,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } } + "value": { "type": { "name": "object" } } }, "name": "MonthCalendar", "imports": [ diff --git a/docs/pages/x/api/date-pickers/multi-input-date-range-field.json b/docs/pages/x/api/date-pickers/multi-input-date-range-field.json index 43fa71b3f73fd..ab581f1f6f69f 100644 --- a/docs/pages/x/api/date-pickers/multi-input-date-range-field.json +++ b/docs/pages/x/api/date-pickers/multi-input-date-range-field.json @@ -1,7 +1,7 @@ { "props": { "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "direction": { "type": { "name": "union", @@ -18,8 +18,8 @@ "type": { "name": "enum", "description": "'dense'
| 'spacious'" }, "default": "\"dense\"" }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "onChange": { "type": { "name": "func" }, "signature": { @@ -43,7 +43,7 @@ }, "readOnly": { "type": { "name": "bool" }, "default": "false" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used." }, "selectedSections": { @@ -90,7 +90,7 @@ } }, "useFlexGap": { "type": { "name": "bool" }, "default": "false" }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } } + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } } }, "name": "MultiInputDateRangeField", "imports": [ diff --git a/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json b/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json index 481f133235df6..3ad6a4c4bc6bc 100644 --- a/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json +++ b/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json @@ -2,7 +2,7 @@ "props": { "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "direction": { "type": { "name": "union", @@ -20,12 +20,12 @@ "type": { "name": "enum", "description": "'dense'
| 'spacious'" }, "default": "\"dense\"" }, - "maxDate": { "type": { "name": "any" } }, - "maxDateTime": { "type": { "name": "any" } }, - "maxTime": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, - "minDateTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "maxDateTime": { "type": { "name": "object" } }, + "maxTime": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, + "minDateTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "onChange": { "type": { "name": "func" }, @@ -50,7 +50,7 @@ }, "readOnly": { "type": { "name": "bool" }, "default": "false" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used." }, "selectedSections": { @@ -105,7 +105,7 @@ } }, "useFlexGap": { "type": { "name": "bool" }, "default": "false" }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } } + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } } }, "name": "MultiInputDateTimeRangeField", "imports": [ diff --git a/docs/pages/x/api/date-pickers/multi-input-time-range-field.json b/docs/pages/x/api/date-pickers/multi-input-time-range-field.json index 9ea14b1bd7785..230921861f532 100644 --- a/docs/pages/x/api/date-pickers/multi-input-time-range-field.json +++ b/docs/pages/x/api/date-pickers/multi-input-time-range-field.json @@ -2,7 +2,7 @@ "props": { "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "direction": { "type": { "name": "union", @@ -20,8 +20,8 @@ "type": { "name": "enum", "description": "'dense'
| 'spacious'" }, "default": "\"dense\"" }, - "maxTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "onChange": { "type": { "name": "func" }, @@ -46,7 +46,7 @@ }, "readOnly": { "type": { "name": "bool" }, "default": "false" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used." }, "selectedSections": { @@ -93,7 +93,7 @@ } }, "useFlexGap": { "type": { "name": "bool" }, "default": "false" }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } } + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } } }, "name": "MultiInputTimeRangeField", "imports": [ diff --git a/docs/pages/x/api/date-pickers/multi-section-digital-clock.json b/docs/pages/x/api/date-pickers/multi-section-digital-clock.json index f87b4cc0e5445..792a65ce1208b 100644 --- a/docs/pages/x/api/date-pickers/multi-section-digital-clock.json +++ b/docs/pages/x/api/date-pickers/multi-section-digital-clock.json @@ -3,7 +3,7 @@ "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, "autoFocus": { "type": { "name": "bool" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableIgnoringDatePartForTimeValidation": { "type": { "name": "bool" }, "default": "false" }, @@ -14,8 +14,8 @@ "description": "'hours'
| 'meridiem'
| 'minutes'
| 'seconds'" } }, - "maxTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "onChange": { "type": { "name": "func" }, @@ -43,7 +43,7 @@ }, "readOnly": { "type": { "name": "bool" }, "default": "false" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid time using the validation props, except callbacks such as `shouldDisableTime`." }, "shouldDisableTime": { @@ -83,7 +83,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/pickers-day.json b/docs/pages/x/api/date-pickers/pickers-day.json index 42e74730e2908..1380c63391db3 100644 --- a/docs/pages/x/api/date-pickers/pickers-day.json +++ b/docs/pages/x/api/date-pickers/pickers-day.json @@ -1,6 +1,6 @@ { "props": { - "day": { "type": { "name": "any" }, "required": true }, + "day": { "type": { "name": "object" }, "required": true }, "isFirstVisibleCell": { "type": { "name": "bool" }, "required": true }, "isLastVisibleCell": { "type": { "name": "bool" }, "required": true }, "outsideCurrentMonth": { "type": { "name": "bool" }, "required": true }, diff --git a/docs/pages/x/api/date-pickers/single-input-date-range-field.json b/docs/pages/x/api/date-pickers/single-input-date-range-field.json index bf3556552fea7..0b8a151594e24 100644 --- a/docs/pages/x/api/date-pickers/single-input-date-range-field.json +++ b/docs/pages/x/api/date-pickers/single-input-date-range-field.json @@ -9,7 +9,7 @@ }, "default": "'primary'" }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disablePast": { "type": { "name": "bool" }, "default": "false" }, @@ -36,8 +36,8 @@ }, "default": "'none'" }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "name": { "type": { "name": "string" } }, "onChange": { "type": { "name": "func" }, @@ -63,7 +63,7 @@ }, "readOnly": { "type": { "name": "bool" }, "default": "false" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used." }, "required": { "type": { "name": "bool" }, "default": "false" }, @@ -107,7 +107,7 @@ "unstableFieldRef": { "type": { "name": "union", "description": "func
| object" } }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "variant": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json b/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json index 2e611014ece1d..5ea7d709048a7 100644 --- a/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json +++ b/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json @@ -10,7 +10,7 @@ }, "default": "'primary'" }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableIgnoringDatePartForTimeValidation": { "type": { "name": "bool" }, "default": "false" }, @@ -38,12 +38,12 @@ }, "default": "'none'" }, - "maxDate": { "type": { "name": "any" } }, - "maxDateTime": { "type": { "name": "any" } }, - "maxTime": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, - "minDateTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "maxDateTime": { "type": { "name": "object" } }, + "maxTime": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, + "minDateTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "name": { "type": { "name": "string" } }, "onChange": { @@ -70,7 +70,7 @@ }, "readOnly": { "type": { "name": "bool" }, "default": "false" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used." }, "required": { "type": { "name": "bool" }, "default": "false" }, @@ -122,7 +122,7 @@ "unstableFieldRef": { "type": { "name": "union", "description": "func
| object" } }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "variant": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/single-input-time-range-field.json b/docs/pages/x/api/date-pickers/single-input-time-range-field.json index 4e6f7c5e11346..3c00fc18fb75d 100644 --- a/docs/pages/x/api/date-pickers/single-input-time-range-field.json +++ b/docs/pages/x/api/date-pickers/single-input-time-range-field.json @@ -10,7 +10,7 @@ }, "default": "'primary'" }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableIgnoringDatePartForTimeValidation": { "type": { "name": "bool" }, "default": "false" }, @@ -38,8 +38,8 @@ }, "default": "'none'" }, - "maxTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "name": { "type": { "name": "string" } }, "onChange": { @@ -66,7 +66,7 @@ }, "readOnly": { "type": { "name": "bool" }, "default": "false" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used." }, "required": { "type": { "name": "bool" }, "default": "false" }, @@ -110,7 +110,7 @@ "unstableFieldRef": { "type": { "name": "union", "description": "func
| object" } }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "variant": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/static-date-picker.json b/docs/pages/x/api/date-pickers/static-date-picker.json index 32cf7df69729f..169d9df97f5b2 100644 --- a/docs/pages/x/api/date-pickers/static-date-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-picker.json @@ -10,7 +10,7 @@ "returned": "string" } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableHighlightToday": { "type": { "name": "bool" }, "default": "false" }, @@ -23,8 +23,8 @@ "fixedWeekNumber": { "type": { "name": "number" }, "default": "undefined" }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "monthsPerRow": { "type": { "name": "enum", "description": "3
| 4" }, "default": "3" @@ -78,7 +78,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -136,7 +136,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/static-date-range-picker.json b/docs/pages/x/api/date-pickers/static-date-range-picker.json index 13df18576c7c3..7147a6a57dd4b 100644 --- a/docs/pages/x/api/date-pickers/static-date-range-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-range-picker.json @@ -22,7 +22,7 @@ "type": { "name": "enum", "description": "'end'
| 'start'" }, "default": "'start'" }, - "defaultValue": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "defaultValue": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "disableAutoMonthSwitching": { "type": { "name": "bool" }, "default": "false" }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableDragEditing": { "type": { "name": "bool" }, "default": "false" }, @@ -37,8 +37,8 @@ "fixedWeekNumber": { "type": { "name": "number" }, "default": "undefined" }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "onAccept": { "type": { "name": "func" }, "signature": { "type": "function(value: TValue) => void", "describedArgs": ["value"] } @@ -79,7 +79,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -121,7 +121,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "arrayOf", "description": "Array<any>" } }, + "value": { "type": { "name": "arrayOf", "description": "Array<object>" } }, "viewRenderers": { "type": { "name": "shape", "description": "{ day?: func }" } } }, "name": "StaticDateRangePicker", diff --git a/docs/pages/x/api/date-pickers/static-date-time-picker.json b/docs/pages/x/api/date-pickers/static-date-time-picker.json index de69515b02677..49608fc99029e 100644 --- a/docs/pages/x/api/date-pickers/static-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-time-picker.json @@ -12,7 +12,7 @@ "returned": "string" } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableHighlightToday": { "type": { "name": "bool" }, "default": "false" }, @@ -26,12 +26,12 @@ "fixedWeekNumber": { "type": { "name": "number" }, "default": "undefined" }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, - "maxDate": { "type": { "name": "any" } }, - "maxDateTime": { "type": { "name": "any" } }, - "maxTime": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, - "minDateTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "maxDateTime": { "type": { "name": "object" } }, + "maxTime": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, + "minDateTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "monthsPerRow": { "type": { "name": "enum", "description": "3
| 4" }, @@ -86,7 +86,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "renderLoading": { @@ -152,7 +152,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/static-time-picker.json b/docs/pages/x/api/date-pickers/static-time-picker.json index d0995c15ec712..5cf72df9cbf49 100644 --- a/docs/pages/x/api/date-pickers/static-time-picker.json +++ b/docs/pages/x/api/date-pickers/static-time-picker.json @@ -3,7 +3,7 @@ "ampm": { "type": { "name": "bool" }, "default": "`utils.is12HourCycleInCurrentLocale()`" }, "ampmInClock": { "type": { "name": "bool" }, "default": "true on desktop, false on mobile" }, "autoFocus": { "type": { "name": "bool" } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableIgnoringDatePartForTimeValidation": { "type": { "name": "bool" }, "default": "false" }, @@ -13,8 +13,8 @@ "default": "\"mobile\"" }, "localeText": { "type": { "name": "object" } }, - "maxTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "onAccept": { "type": { "name": "func" }, @@ -57,7 +57,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "shouldDisableTime": { @@ -89,7 +89,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/time-clock.json b/docs/pages/x/api/date-pickers/time-clock.json index 86d8ec9214f7c..f569a5c964f98 100644 --- a/docs/pages/x/api/date-pickers/time-clock.json +++ b/docs/pages/x/api/date-pickers/time-clock.json @@ -4,7 +4,7 @@ "ampmInClock": { "type": { "name": "bool" }, "default": "false" }, "autoFocus": { "type": { "name": "bool" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableIgnoringDatePartForTimeValidation": { "type": { "name": "bool" }, "default": "false" }, @@ -15,8 +15,8 @@ "description": "'hours'
| 'minutes'
| 'seconds'" } }, - "maxTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "onChange": { "type": { "name": "func" }, @@ -44,7 +44,7 @@ }, "readOnly": { "type": { "name": "bool" }, "default": "false" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid time using the validation props, except callbacks such as `shouldDisableTime`." }, "shouldDisableTime": { @@ -76,7 +76,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/time-field.json b/docs/pages/x/api/date-pickers/time-field.json index ad24b2bd2a52c..8f87d61b8c3ad 100644 --- a/docs/pages/x/api/date-pickers/time-field.json +++ b/docs/pages/x/api/date-pickers/time-field.json @@ -10,7 +10,7 @@ }, "default": "'primary'" }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableIgnoringDatePartForTimeValidation": { "type": { "name": "bool" }, "default": "false" }, @@ -38,8 +38,8 @@ }, "default": "'none'" }, - "maxTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "name": { "type": { "name": "string" } }, "onChange": { @@ -66,7 +66,7 @@ }, "readOnly": { "type": { "name": "bool" }, "default": "false" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used." }, "required": { "type": { "name": "bool" }, "default": "false" }, @@ -110,7 +110,7 @@ "unstableFieldRef": { "type": { "name": "union", "description": "func
| object" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "variant": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/time-picker.json b/docs/pages/x/api/date-pickers/time-picker.json index 071c5ad8f4c25..d3386734875f2 100644 --- a/docs/pages/x/api/date-pickers/time-picker.json +++ b/docs/pages/x/api/date-pickers/time-picker.json @@ -7,7 +7,7 @@ "type": { "name": "bool" }, "default": "`true` for desktop, `false` for mobile (based on the chosen wrapper and `desktopModeMediaQuery` prop)." }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "desktopModeMediaQuery": { "type": { "name": "string" }, "default": "'@media (pointer: fine)'" @@ -25,8 +25,8 @@ "inputRef": { "type": { "name": "custom", "description": "ref" } }, "label": { "type": { "name": "node" } }, "localeText": { "type": { "name": "object" } }, - "maxTime": { "type": { "name": "any" } }, - "minTime": { "type": { "name": "any" } }, + "maxTime": { "type": { "name": "object" } }, + "minTime": { "type": { "name": "object" } }, "minutesStep": { "type": { "name": "number" }, "default": "1" }, "name": { "type": { "name": "string" } }, "onAccept": { @@ -75,7 +75,7 @@ "default": "`@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13" }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`." }, "selectedSections": { @@ -122,7 +122,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "view": { "type": { "name": "enum", diff --git a/docs/pages/x/api/date-pickers/year-calendar.json b/docs/pages/x/api/date-pickers/year-calendar.json index 2d97dfcb66042..cd8b9dc24feb7 100644 --- a/docs/pages/x/api/date-pickers/year-calendar.json +++ b/docs/pages/x/api/date-pickers/year-calendar.json @@ -1,20 +1,20 @@ { "props": { "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "object" } }, "disabled": { "type": { "name": "bool" } }, "disableFuture": { "type": { "name": "bool" }, "default": "false" }, "disableHighlightToday": { "type": { "name": "bool" }, "default": "false" }, "disablePast": { "type": { "name": "bool" }, "default": "false" }, - "maxDate": { "type": { "name": "any" } }, - "minDate": { "type": { "name": "any" } }, + "maxDate": { "type": { "name": "object" } }, + "minDate": { "type": { "name": "object" } }, "onChange": { "type": { "name": "func" }, "signature": { "type": "function(value: TDate) => void", "describedArgs": ["value"] } }, "readOnly": { "type": { "name": "bool" } }, "referenceDate": { - "type": { "name": "any" }, + "type": { "name": "object" }, "default": "The closest valid year using the validation props, except callbacks such as `shouldDisableYear`." }, "shouldDisableYear": { @@ -40,7 +40,7 @@ "text": "timezones documentation" } }, - "value": { "type": { "name": "any" } }, + "value": { "type": { "name": "object" } }, "yearsPerRow": { "type": { "name": "enum", "description": "3
| 4" }, "default": "3" diff --git a/docs/scripts/generateProptypes.ts b/docs/scripts/generateProptypes.ts index 63620878303cb..4a4473dad12b6 100644 --- a/docs/scripts/generateProptypes.ts +++ b/docs/scripts/generateProptypes.ts @@ -7,6 +7,30 @@ import { fixBabelGeneratorIssues, fixLineEndings } from '@mui-internal/docs-util import { createXTypeScriptProjects, XTypeScriptProject } from './createXTypeScriptProjects'; async function generateProptypes(project: XTypeScriptProject, sourceFile: string) { + const isTDate = (name: string) => { + if (['x-date-pickers', 'x-date-pickers-pro'].includes(project.name)) { + const T_DATE_PROPS = [ + 'value', + 'defaultValue', + 'minDate', + 'maxDate', + 'minDateTime', + 'maxDateTime', + 'minTime', + 'maxTime', + 'referenceDate', + 'day', + 'currentMonth', + ]; + + if (T_DATE_PROPS.includes(name)) { + return true; + } + } + + return false; + }; + const components = getPropTypesFromFile({ filePath: sourceFile, project, @@ -44,8 +68,13 @@ async function generateProptypes(project: XTypeScriptProject, sourceFile: string return false; } + if (isTDate(name)) { + return false; + } + return undefined; }, + shouldUseObjectForDate: ({ name }) => isTDate(name), }); if (components.length === 0) { diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx index f0a2b77125434..bd573303ca85b 100644 --- a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx +++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx @@ -32,6 +32,7 @@ import { useControlledValueWithTimezone, useViews, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { getReleaseInfo } from '../internals/utils/releaseInfo'; import { dateRangeCalendarClasses, @@ -114,7 +115,7 @@ const DayCalendarForRange = styled(DayCalendar)(({ theme }) => ({ }, })) as typeof DayCalendar; -function useDateRangeCalendarDefaultizedProps( +function useDateRangeCalendarDefaultizedProps( props: DateRangeCalendarProps, name: string, ): DateRangeCalendarDefaultizedProps { @@ -155,7 +156,7 @@ const useUtilityClasses = (ownerState: DateRangeCalendarOwnerState) => { return composeClasses(slots, getDateRangeCalendarUtilityClass, classes); }; -type DateRangeCalendarComponent = (( +type DateRangeCalendarComponent = (( props: DateRangeCalendarProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -169,10 +170,9 @@ type DateRangeCalendarComponent = (( * * - [DateRangeCalendar API](https://mui.com/x/api/date-pickers/date-range-calendar/) */ -const DateRangeCalendar = React.forwardRef(function DateRangeCalendar( - inProps: DateRangeCalendarProps, - ref: React.Ref, -) { +const DateRangeCalendar = React.forwardRef(function DateRangeCalendar< + TDate extends PickerValidDate, +>(inProps: DateRangeCalendarProps, ref: React.Ref) { const props = useDateRangeCalendarDefaultizedProps(inProps, 'MuiDateRangeCalendar'); const shouldHavePreview = useMediaQuery(DEFAULT_DESKTOP_MODE_MEDIA_QUERY, { defaultMatches: false, @@ -683,7 +683,7 @@ DateRangeCalendar.propTypes = { * The default selected value. * Used when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * If `true`, after selecting `start` date calendar will not automatically switch to the month of `end` date. * @default false @@ -737,11 +737,11 @@ DateRangeCalendar.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Callback fired when the value changes. * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value. @@ -800,7 +800,7 @@ DateRangeCalendar.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component rendered on the "day" view when `props.loading` is true. * @returns {React.ReactNode} The node to render when loading. @@ -859,7 +859,7 @@ DateRangeCalendar.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.types.ts b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.types.ts index 3752678575acb..b79cbe3a8a570 100644 --- a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.types.ts +++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.types.ts @@ -2,7 +2,7 @@ import * as React from 'react'; import { SxProps } from '@mui/system'; import { SlotComponentProps } from '@mui/base/utils'; import { Theme } from '@mui/material/styles'; -import { TimezoneProps } from '@mui/x-date-pickers/models'; +import { PickerValidDate, TimezoneProps } from '@mui/x-date-pickers/models'; import { PickersCalendarHeader, PickersCalendarHeaderProps, @@ -28,7 +28,7 @@ import { UseRangePositionProps } from '../internals/hooks/useRangePosition'; export type DateRangePosition = 'start' | 'end'; -export interface DateRangeCalendarSlots +export interface DateRangeCalendarSlots extends PickersArrowSwitcherSlots, Omit, 'day'>, PickersCalendarHeaderSlots { @@ -46,7 +46,7 @@ export interface DateRangeCalendarSlots day?: React.ElementType>; } -export interface DateRangeCalendarSlotProps +export interface DateRangeCalendarSlotProps extends PickersArrowSwitcherSlotProps, Omit, 'day'>, PickersCalendarHeaderSlotProps { @@ -62,7 +62,7 @@ export interface DateRangeCalendarSlotProps >; } -export interface ExportedDateRangeCalendarProps +export interface ExportedDateRangeCalendarProps extends ExportedDayCalendarProps, BaseDateValidationProps, DayRangeValidationProps, @@ -105,7 +105,7 @@ export interface ExportedDateRangeCalendarProps disableDragEditing?: boolean; } -export interface DateRangeCalendarProps +export interface DateRangeCalendarProps extends ExportedDateRangeCalendarProps, UseRangePositionProps, ExportedUseViewsOptions<'day'> { @@ -155,11 +155,12 @@ export interface DateRangeCalendarProps availableRangePositions?: DateRangePosition[]; } -export interface DateRangeCalendarOwnerState extends DateRangeCalendarProps { +export interface DateRangeCalendarOwnerState + extends DateRangeCalendarProps { isDragging: boolean; } -export type DateRangeCalendarDefaultizedProps = DefaultizedProps< +export type DateRangeCalendarDefaultizedProps = DefaultizedProps< DateRangeCalendarProps, | 'views' | 'openTo' diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/useDragRange.ts b/packages/x-date-pickers-pro/src/DateRangeCalendar/useDragRange.ts index 32a85ed3aeef8..5ac9cdc668000 100644 --- a/packages/x-date-pickers-pro/src/DateRangeCalendar/useDragRange.ts +++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/useDragRange.ts @@ -1,11 +1,11 @@ import * as React from 'react'; import useEventCallback from '@mui/utils/useEventCallback'; -import { MuiPickersAdapter, PickersTimezone } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter, PickersTimezone, PickerValidDate } from '@mui/x-date-pickers/models'; import { DateRangePosition } from './DateRangeCalendar.types'; import { DateRange } from '../models'; import { isEndOfRange, isStartOfRange } from '../internals/utils/date-utils'; -interface UseDragRangeParams { +interface UseDragRangeParams { disableDragEditing?: boolean; utils: MuiPickersAdapter; setRangeDragDay: (value: TDate | null) => void; @@ -29,13 +29,13 @@ interface UseDragRangeEvents { onTouchEnd?: React.TouchEventHandler; } -interface UseDragRangeResponse extends UseDragRangeEvents { +interface UseDragRangeResponse extends UseDragRangeEvents { isDragging: boolean; rangeDragDay: TDate | null; draggingDatePosition: DateRangePosition | null; } -const resolveDateFromTarget = ( +const resolveDateFromTarget = ( target: EventTarget, utils: MuiPickersAdapter, timezone: PickersTimezone, @@ -87,7 +87,7 @@ const resolveElementFromTouch = ( return null; }; -const useDragRangeEvents = ({ +const useDragRangeEvents = ({ utils, setRangeDragDay, setIsDragging, @@ -276,7 +276,7 @@ const useDragRangeEvents = ({ }; }; -export const useDragRange = ({ +export const useDragRange = ({ disableDragEditing, utils, onDatePositionChange, diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx index d05c30cdbde64..221f24079569b 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx @@ -3,11 +3,12 @@ import PropTypes from 'prop-types'; import useMediaQuery from '@mui/material/useMediaQuery'; import { useThemeProps } from '@mui/material/styles'; import { refType } from '@mui/utils'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DesktopDateRangePicker } from '../DesktopDateRangePicker'; import { MobileDateRangePicker } from '../MobileDateRangePicker'; import { DateRangePickerProps } from './DateRangePicker.types'; -type DatePickerComponent = (( +type DatePickerComponent = (( props: DateRangePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -21,7 +22,7 @@ type DatePickerComponent = (( * * - [DateRangePicker API](https://mui.com/x/api/date-pickers/date-range-picker/) */ -const DateRangePicker = React.forwardRef(function DateRangePicker( +const DateRangePicker = React.forwardRef(function DateRangePicker( inProps: DateRangePickerProps, ref: React.Ref, ) { @@ -84,7 +85,7 @@ DateRangePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * CSS media query when `Mobile` mode will be changed to `Desktop`. * @default '@media (pointer: fine)' @@ -171,11 +172,11 @@ DateRangePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Name attribute used by the `input` element in the Field. * Ignored if the field has several inputs. @@ -251,7 +252,7 @@ DateRangePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component rendered on the "day" view when `props.loading` is true. * @returns {React.ReactNode} The node to render when loading. @@ -338,7 +339,7 @@ DateRangePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), /** * Define custom view renderers for each section. * If `null`, the section will only have field editing. diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts index 7b1bfae34e522..619d929549386 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts @@ -1,3 +1,4 @@ +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DesktopDateRangePickerProps, DesktopDateRangePickerSlots, @@ -9,15 +10,15 @@ import { MobileDateRangePickerSlotProps, } from '../MobileDateRangePicker'; -export interface DateRangePickerSlots +export interface DateRangePickerSlots extends DesktopDateRangePickerSlots, MobileDateRangePickerSlots {} -export interface DateRangePickerSlotProps +export interface DateRangePickerSlotProps extends DesktopDateRangePickerSlotProps, MobileDateRangePickerSlotProps {} -export interface DateRangePickerProps +export interface DateRangePickerProps extends DesktopDateRangePickerProps, MobileDateRangePickerProps { /** diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx index 7e83059f084b1..149bc4c9bf069 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx @@ -12,6 +12,7 @@ import { useLocaleText, ExportedBaseToolbarProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DateRange } from '../models'; import { UseRangePositionResponse } from '../internals/hooks/useRangePosition'; import { @@ -29,7 +30,7 @@ const useUtilityClasses = (ownerState: DateRangePickerToolbarProps) => { return composeClasses(slots, getDateRangePickerToolbarUtilityClass, classes); }; -export interface DateRangePickerToolbarProps +export interface DateRangePickerToolbarProps extends Omit< BaseToolbarProps, 'day'>, 'views' | 'view' | 'onViewChange' | 'onChange' | 'isLandscape' @@ -67,7 +68,7 @@ const DateRangePickerToolbarContainer = styled('div', { * - [DateRangePickerToolbar API](https://mui.com/x/api/date-pickers/date-range-picker-toolbar/) */ const DateRangePickerToolbar = React.forwardRef(function DateRangePickerToolbar< - TDate extends unknown, + TDate extends PickerValidDate, >(inProps: DateRangePickerToolbarProps, ref: React.Ref) { const utils = useUtils(); const props = useThemeProps({ props: inProps, name: 'MuiDateRangePickerToolbar' }); @@ -153,7 +154,7 @@ DateRangePickerToolbar.propTypes = { * @default "––" */ toolbarPlaceholder: PropTypes.node, - value: PropTypes.arrayOf(PropTypes.any).isRequired, + value: PropTypes.arrayOf(PropTypes.object).isRequired, } as any; export { DateRangePickerToolbar }; diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx index 652ad32094229..5a0b72b9bdd09 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx @@ -10,6 +10,7 @@ import { BasePickerInputProps, PickerViewRendererLookup, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DateRangeValidationError, DateRange } from '../models'; import { DateRangeCalendarSlots, @@ -23,7 +24,8 @@ import { } from './DateRangePickerToolbar'; import { DateRangeViewRendererProps } from '../dateRangeViewRenderers'; -export interface BaseDateRangePickerSlots extends DateRangeCalendarSlots { +export interface BaseDateRangePickerSlots + extends DateRangeCalendarSlots { /** * Custom component for the toolbar rendered above the views. * @default DateTimePickerToolbar @@ -31,11 +33,12 @@ export interface BaseDateRangePickerSlots extends DateRangeCalendarSlots< toolbar?: React.JSXElementConstructor>; } -export interface BaseDateRangePickerSlotProps extends DateRangeCalendarSlotProps { +export interface BaseDateRangePickerSlotProps + extends DateRangeCalendarSlotProps { toolbar?: ExportedDateRangePickerToolbarProps; } -export interface BaseDateRangePickerProps +export interface BaseDateRangePickerProps extends Omit< BasePickerInputProps, TDate, 'day', DateRangeValidationError>, 'view' | 'views' | 'openTo' | 'onViewChange' | 'orientation' @@ -63,12 +66,12 @@ export interface BaseDateRangePickerProps } type UseDateRangePickerDefaultizedProps< - TDate, + TDate extends PickerValidDate, Props extends BaseDateRangePickerProps, > = LocalizedComponent>>; export function useDateRangePickerDefaultizedProps< - TDate, + TDate extends PickerValidDate, Props extends BaseDateRangePickerProps, >(props: Props, name: string): UseDateRangePickerDefaultizedProps { const utils = useUtils(); diff --git a/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx b/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx index 9647c304b1628..a7609833e7466 100644 --- a/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx @@ -5,6 +5,7 @@ import { useLicenseVerifier } from '@mui/x-license-pro'; import { alpha, styled, useThemeProps } from '@mui/material/styles'; import { unstable_composeClasses as composeClasses } from '@mui/utils'; import { useUtils } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { PickersDay, PickersDayProps } from '@mui/x-date-pickers/PickersDay'; import { DateRangePickerDayClasses, @@ -15,7 +16,7 @@ import { getReleaseInfo } from '../internals/utils/releaseInfo'; const releaseInfo = getReleaseInfo(); -export interface DateRangePickerDayProps +export interface DateRangePickerDayProps extends Omit, 'classes' | 'onBlur' | 'onFocus' | 'onKeyDown'> { /** * Set to `true` if the `day` is in a highlighted date range. @@ -259,18 +260,17 @@ const DateRangePickerDayDay = styled(PickersDay, { ...(ownerState.draggable && { touchAction: 'none', }), -})) as unknown as ( +})) as unknown as ( props: PickersDayProps & { ownerState: OwnerState }, ) => React.JSX.Element; -type DateRangePickerDayComponent = ( +type DateRangePickerDayComponent = ( props: DateRangePickerDayProps & React.RefAttributes, ) => React.JSX.Element; -const DateRangePickerDayRaw = React.forwardRef(function DateRangePickerDay( - inProps: DateRangePickerDayProps, - ref: React.Ref, -) { +const DateRangePickerDayRaw = React.forwardRef(function DateRangePickerDay< + TDate extends PickerValidDate, +>(inProps: DateRangePickerDayProps, ref: React.Ref) { const props = useThemeProps({ props: inProps, name: 'MuiDateRangePickerDay' }); const { className, @@ -376,7 +376,7 @@ DateRangePickerDayRaw.propTypes = { /** * The date to show. */ - day: PropTypes.any.isRequired, + day: PropTypes.object.isRequired, /** * If `true`, renders as disabled. * @default false diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx index 63d70c656b7c9..7b55b94cca536 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx @@ -2,18 +2,18 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import useMediaQuery from '@mui/material/useMediaQuery'; import { useThemeProps } from '@mui/material/styles'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DateTimeRangePickerProps } from './DateTimeRangePicker.types'; import { DesktopDateTimeRangePicker } from '../DesktopDateTimeRangePicker'; import { MobileDateTimeRangePicker } from '../MobileDateTimeRangePicker'; -type DateTimeRangePickerComponent = (( +type DateTimeRangePickerComponent = (( props: DateTimeRangePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; -const DateTimeRangePicker = React.forwardRef(function DateTimeRangePicker( - inProps: DateTimeRangePickerProps, - ref: React.Ref, -) { +const DateTimeRangePicker = React.forwardRef(function DateTimeRangePicker< + TDate extends PickerValidDate, +>(inProps: DateTimeRangePickerProps, ref: React.Ref) { const props = useThemeProps({ props: inProps, name: 'MuiDateTimeRangePicker' }); const { desktopModeMediaQuery = '@media (pointer: fine)', ...other } = props; @@ -78,7 +78,7 @@ DateTimeRangePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * CSS media query when `Mobile` mode will be changed to `Desktop`. * @default '@media (pointer: fine)' @@ -175,29 +175,29 @@ DateTimeRangePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Maximal selectable moment of time with binding to date, to set max time in each day use `maxTime`. */ - maxDateTime: PropTypes.any, + maxDateTime: PropTypes.object, /** * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Minimal selectable moment of time with binding to date, to set min time in each day use `minTime`. */ - minDateTime: PropTypes.any, + minDateTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -290,7 +290,7 @@ DateTimeRangePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component rendered on the "day" view when `props.loading` is true. * @returns {React.ReactNode} The node to render when loading. @@ -406,7 +406,7 @@ DateTimeRangePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts index 1e755b824bda2..ef4308ee99016 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts @@ -1,3 +1,4 @@ +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DesktopDateTimeRangePickerProps, DesktopDateTimeRangePickerSlots, @@ -9,15 +10,15 @@ import { MobileDateTimeRangePickerSlotProps, } from '../MobileDateTimeRangePicker'; -export interface DateTimeRangePickerSlots +export interface DateTimeRangePickerSlots extends DesktopDateTimeRangePickerSlots, MobileDateTimeRangePickerSlots {} -export interface DateTimeRangePickerSlotProps +export interface DateTimeRangePickerSlotProps extends DesktopDateTimeRangePickerSlotProps, MobileDateTimeRangePickerSlotProps {} -export interface DateTimeRangePickerProps +export interface DateTimeRangePickerProps extends DesktopDateTimeRangePickerProps, MobileDateTimeRangePickerProps { /** diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx index 465bcc3f6e1de..9bc3597b7927e 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx @@ -7,6 +7,7 @@ import { TimeViewWithMeridiem, BaseClockProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DateTimeRangePickerView } from '../internals/models'; import { DateRange } from '../models'; import { UseRangePositionResponse } from '../internals/hooks/useRangePosition'; @@ -14,7 +15,7 @@ import { isRangeValid } from '../internals/utils/date-utils'; import { calculateRangeChange } from '../internals/utils/date-range-manager'; export type DateTimeRangePickerTimeWrapperProps< - TDate, + TDate extends PickerValidDate, TView extends DateTimeRangePickerView, TComponentProps extends Omit< BaseClockProps, @@ -43,7 +44,7 @@ export type DateTimeRangePickerTimeWrapperProps< * @ignore - internal component. */ function DateTimeRangePickerTimeWrapper< - TDate, + TDate extends PickerValidDate, TView extends DateTimeRangePickerView, TComponentProps extends Omit< BaseClockProps, diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx index 5b384ac900ab6..1af69fa551241 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx @@ -11,6 +11,7 @@ import { DateOrTimeViewWithMeridiem, WrapperVariant, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DateTimePickerToolbarProps, DateTimePickerToolbar, @@ -36,7 +37,7 @@ const useUtilityClasses = (ownerState: DateTimeRangePickerToolbarProps) => type DateTimeRangeViews = Exclude; -export interface DateTimeRangePickerToolbarProps +export interface DateTimeRangePickerToolbarProps extends BaseToolbarProps, DateTimeRangeViews>, Pick, ExportedDateTimeRangePickerToolbarProps { @@ -59,11 +60,12 @@ const DateTimeRangePickerToolbarRoot = styled('div', { flexDirection: 'column', }); -type DateTimeRangePickerStartOrEndToolbarProps = DateTimePickerToolbarProps & { - ownerState?: DateTimeRangePickerToolbarProps; -}; +type DateTimeRangePickerStartOrEndToolbarProps = + DateTimePickerToolbarProps & { + ownerState?: DateTimeRangePickerToolbarProps; + }; -type DateTimeRangePickerStartOrEndToolbarComponent = ( +type DateTimeRangePickerStartOrEndToolbarComponent = ( props: DateTimeRangePickerStartOrEndToolbarProps, ) => React.JSX.Element; @@ -91,7 +93,7 @@ const DateTimeRangePickerToolbarEnd = styled(DateTimePickerToolbar, { })) as DateTimeRangePickerStartOrEndToolbarComponent; const DateTimeRangePickerToolbar = React.forwardRef(function DateTimeRangePickerToolbar< - TDate extends unknown, + TDate extends PickerValidDate, >(inProps: DateTimeRangePickerToolbarProps, ref: React.Ref) { const props = useThemeProps({ props: inProps, name: 'MuiDateTimeRangePickerToolbar' }); const utils = useUtils(); @@ -228,7 +230,7 @@ DateTimeRangePickerToolbar.propTypes = { */ toolbarPlaceholder: PropTypes.node, toolbarVariant: PropTypes.oneOf(['desktop', 'mobile']), - value: PropTypes.arrayOf(PropTypes.any).isRequired, + value: PropTypes.arrayOf(PropTypes.object).isRequired, /** * Currently visible picker view. */ diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx index d893dbe01b40d..cba6a59a1aa25 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx @@ -17,6 +17,7 @@ import { UseViewsOptions, DateTimeValidationProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { TimeViewRendererProps } from '@mui/x-date-pickers/timeViewRenderers'; import { DigitalClockSlots, DigitalClockSlotProps } from '@mui/x-date-pickers/DigitalClock'; import { @@ -42,7 +43,7 @@ import { ExportedDateTimeRangePickerTabsProps, } from './DateTimeRangePickerTabs'; -export interface BaseDateTimeRangePickerSlots +export interface BaseDateTimeRangePickerSlots extends DateRangeCalendarSlots, DigitalClockSlots, MultiSectionDigitalClockSlots { @@ -58,7 +59,7 @@ export interface BaseDateTimeRangePickerSlots toolbar?: React.JSXElementConstructor>; } -export interface BaseDateTimeRangePickerSlotProps +export interface BaseDateTimeRangePickerSlotProps extends DateRangeCalendarSlotProps, DigitalClockSlotProps, MultiSectionDigitalClockSlotProps { @@ -72,7 +73,7 @@ export interface BaseDateTimeRangePickerSlotProps toolbar?: ExportedDateTimeRangePickerToolbarProps; } -export interface BaseDateTimeRangePickerProps +export interface BaseDateTimeRangePickerProps extends Omit< BasePickerInputProps< DateRange, @@ -119,7 +120,7 @@ export interface BaseDateTimeRangePickerProps } type UseDateTimeRangePickerDefaultizedProps< - TDate, + TDate extends PickerValidDate, Props extends BaseDateTimeRangePickerProps, > = LocalizedComponent< TDate, @@ -130,7 +131,7 @@ type UseDateTimeRangePickerDefaultizedProps< }; export function useDateTimeRangePickerDefaultizedProps< - TDate, + TDate extends PickerValidDate, Props extends BaseDateTimeRangePickerProps, >(props: Props, name: string): UseDateTimeRangePickerDefaultizedProps { const utils = useUtils(); diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx index 09532eee819d3..fd25ff438f808 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { extractValidationProps, PickerViewRendererLookup } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { resolveComponentProps } from '@mui/base/utils'; import { refType } from '@mui/utils'; import { rangeValueManager } from '../internals/utils/valueManagers'; @@ -12,7 +13,7 @@ import { useDesktopRangePicker } from '../internals/hooks/useDesktopRangePicker' import { validateDateRange } from '../internals/utils/validation/validateDateRange'; import { DateRange } from '../models'; -type DesktopDateRangePickerComponent = (( +type DesktopDateRangePickerComponent = (( props: DesktopDateRangePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -26,10 +27,9 @@ type DesktopDateRangePickerComponent = (( * * - [DesktopDateRangePicker API](https://mui.com/x/api/date-pickers/desktop-date-range-picker/) */ -const DesktopDateRangePicker = React.forwardRef(function DesktopDateRangePicker( - inProps: DesktopDateRangePickerProps, - ref: React.Ref, -) { +const DesktopDateRangePicker = React.forwardRef(function DesktopDateRangePicker< + TDate extends PickerValidDate, +>(inProps: DesktopDateRangePickerProps, ref: React.Ref) { // Props with the default values common to all date time pickers const defaultizedProps = useDateRangePickerDefaultizedProps< TDate, @@ -120,7 +120,7 @@ DesktopDateRangePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * If `true`, after selecting `start` date calendar will not automatically switch to the month of `end` date. * @default false @@ -201,11 +201,11 @@ DesktopDateRangePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Name attribute used by the `input` element in the Field. * Ignored if the field has several inputs. @@ -281,7 +281,7 @@ DesktopDateRangePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component rendered on the "day" view when `props.loading` is true. * @returns {React.ReactNode} The node to render when loading. @@ -368,7 +368,7 @@ DesktopDateRangePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), /** * Define custom view renderers for each section. * If `null`, the section will only have field editing. diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.types.ts b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.types.ts index 4f83197bad5ca..364776776e06d 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.types.ts @@ -1,4 +1,5 @@ import { MakeOptional } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseDesktopRangePickerSlots, UseDesktopRangePickerSlotProps, @@ -10,15 +11,15 @@ import { BaseDateRangePickerSlotProps, } from '../DateRangePicker/shared'; -export interface DesktopDateRangePickerSlots +export interface DesktopDateRangePickerSlots extends BaseDateRangePickerSlots, MakeOptional, 'field'> {} -export interface DesktopDateRangePickerSlotProps +export interface DesktopDateRangePickerSlotProps extends BaseDateRangePickerSlotProps, Omit, 'tabs'> {} -export interface DesktopDateRangePickerProps +export interface DesktopDateRangePickerProps extends BaseDateRangePickerProps, DesktopRangeOnlyPickerProps { /** diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx index b0c6b36d18cd2..74f358cae9dce 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx @@ -8,6 +8,7 @@ import { PickerViewRenderer, PickerViewRendererLookup, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { resolveComponentProps } from '@mui/base/utils'; import { renderDigitalClockTimeView, @@ -36,7 +37,7 @@ import { DateTimeRangePickerTimeWrapper } from '../DateTimeRangePicker/DateTimeR import { RANGE_VIEW_HEIGHT } from '../internals/constants/dimensions'; import { DesktopDateTimeRangePickerLayout } from './DesktopDateTimeRangePickerLayout'; -const rendererInterceptor = function rendererInterceptor( +const rendererInterceptor = function rendererInterceptor( inViewRenderers: PickerViewRendererLookup, DateTimeRangePickerView, any, any>, popperView: DateTimeRangePickerView, rendererProps: DefaultizedProps< @@ -88,14 +89,13 @@ const rendererInterceptor = function rendererInterceptor( ); }; -type DesktopDateRangePickerComponent = (( +type DesktopDateRangePickerComponent = (( props: DesktopDateTimeRangePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; -const DesktopDateTimeRangePicker = React.forwardRef(function DesktopDateTimeRangePicker( - inProps: DesktopDateTimeRangePickerProps, - ref: React.Ref, -) { +const DesktopDateTimeRangePicker = React.forwardRef(function DesktopDateTimeRangePicker< + TDate extends PickerValidDate, +>(inProps: DesktopDateTimeRangePickerProps, ref: React.Ref) { // Props with the default values common to all date time range pickers const defaultizedProps = useDateTimeRangePickerDefaultizedProps< TDate, @@ -225,7 +225,7 @@ DesktopDateTimeRangePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * If `true`, after selecting `start` date calendar will not automatically switch to the month of `end` date. * @default false @@ -316,29 +316,29 @@ DesktopDateTimeRangePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Maximal selectable moment of time with binding to date, to set max time in each day use `maxTime`. */ - maxDateTime: PropTypes.any, + maxDateTime: PropTypes.object, /** * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Minimal selectable moment of time with binding to date, to set min time in each day use `minTime`. */ - minDateTime: PropTypes.any, + minDateTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -431,7 +431,7 @@ DesktopDateTimeRangePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component rendered on the "day" view when `props.loading` is true. * @returns {React.ReactNode} The node to render when loading. @@ -547,7 +547,7 @@ DesktopDateTimeRangePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.types.ts b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.types.ts index 3f956449fba72..a692b4307fe44 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.types.ts @@ -1,4 +1,5 @@ import { MakeOptional } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseDesktopRangePickerSlots, UseDesktopRangePickerSlotProps, @@ -11,15 +12,15 @@ import { } from '../DateTimeRangePicker/shared'; import { DateTimeRangePickerView } from '../internals/models'; -export interface DesktopDateTimeRangePickerSlots +export interface DesktopDateTimeRangePickerSlots extends BaseDateTimeRangePickerSlots, MakeOptional, 'field'> {} -export interface DesktopDateTimeRangePickerSlotProps +export interface DesktopDateTimeRangePickerSlotProps extends BaseDateTimeRangePickerSlotProps, Omit, 'tabs' | 'toolbar'> {} -export interface DesktopDateTimeRangePickerProps +export interface DesktopDateTimeRangePickerProps extends BaseDateTimeRangePickerProps, DesktopRangeOnlyPickerProps { /** diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePickerLayout.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePickerLayout.tsx index 3bb22d7026339..37d9dc97df208 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePickerLayout.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePickerLayout.tsx @@ -8,13 +8,14 @@ import { pickersLayoutClasses, usePickerLayout, } from '@mui/x-date-pickers/PickersLayout'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DateRange } from '../models'; import { DateTimeRangePickerView } from '../internals/models/dateTimeRange'; /** * @ignore - internal component. */ -export function DesktopDateTimeRangePickerLayout( +export function DesktopDateTimeRangePickerLayout( props: PickersLayoutProps, TDate, DateTimeRangePickerView>, ) { const { toolbar, tabs, content, actionBar, shortcuts } = usePickerLayout(props); diff --git a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx index c4464ff216a80..bd01168d00536 100644 --- a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { extractValidationProps, PickerViewRendererLookup } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { resolveComponentProps } from '@mui/base/utils'; import { refType } from '@mui/utils'; import { rangeValueManager } from '../internals/utils/valueManagers'; @@ -12,7 +13,7 @@ import { useMobileRangePicker } from '../internals/hooks/useMobileRangePicker'; import { validateDateRange } from '../internals/utils/validation/validateDateRange'; import { DateRange } from '../models'; -type MobileDateRangePickerComponent = (( +type MobileDateRangePickerComponent = (( props: MobileDateRangePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -26,10 +27,9 @@ type MobileDateRangePickerComponent = (( * * - [MobileDateRangePicker API](https://mui.com/x/api/date-pickers/mobile-date-range-picker/) */ -const MobileDateRangePicker = React.forwardRef(function MobileDateRangePicker( - inProps: MobileDateRangePickerProps, - ref: React.Ref, -) { +const MobileDateRangePicker = React.forwardRef(function MobileDateRangePicker< + TDate extends PickerValidDate, +>(inProps: MobileDateRangePickerProps, ref: React.Ref) { // Props with the default values common to all date time pickers const defaultizedProps = useDateRangePickerDefaultizedProps< TDate, @@ -116,7 +116,7 @@ MobileDateRangePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * If `true`, after selecting `start` date calendar will not automatically switch to the month of `end` date. * @default false @@ -197,11 +197,11 @@ MobileDateRangePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Name attribute used by the `input` element in the Field. * Ignored if the field has several inputs. @@ -277,7 +277,7 @@ MobileDateRangePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component rendered on the "day" view when `props.loading` is true. * @returns {React.ReactNode} The node to render when loading. @@ -364,7 +364,7 @@ MobileDateRangePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), /** * Define custom view renderers for each section. * If `null`, the section will only have field editing. diff --git a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.types.ts b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.types.ts index a5e6cc05419cd..9bb677638253b 100644 --- a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.types.ts @@ -1,4 +1,5 @@ import { MakeOptional } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseMobileRangePickerSlots, UseMobileRangePickerSlotProps, @@ -10,15 +11,15 @@ import { BaseDateRangePickerSlotProps, } from '../DateRangePicker/shared'; -export interface MobileDateRangePickerSlots +export interface MobileDateRangePickerSlots extends BaseDateRangePickerSlots, MakeOptional, 'field'> {} -export interface MobileDateRangePickerSlotProps +export interface MobileDateRangePickerSlotProps extends BaseDateRangePickerSlotProps, Omit, 'tabs'> {} -export interface MobileDateRangePickerProps +export interface MobileDateRangePickerProps extends BaseDateRangePickerProps, MobileRangeOnlyPickerProps { /** diff --git a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx index 5799916f98367..3a1878ce53655 100644 --- a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx @@ -10,6 +10,7 @@ import { PickerViewRenderer, DefaultizedProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { resolveComponentProps } from '@mui/base/utils'; import { renderDigitalClockTimeView, @@ -35,7 +36,7 @@ import { MultiInputDateTimeRangeField } from '../MultiInputDateTimeRangeField'; import { DateTimeRangePickerTimeWrapper } from '../DateTimeRangePicker/DateTimeRangePickerTimeWrapper'; import { RANGE_VIEW_HEIGHT } from '../internals/constants/dimensions'; -const rendererInterceptor = function rendererInterceptor( +const rendererInterceptor = function rendererInterceptor( inViewRenderers: PickerViewRendererLookup, DateTimeRangePickerView, any, any>, popperView: DateTimeRangePickerView, rendererProps: DefaultizedProps< @@ -102,14 +103,13 @@ const rendererInterceptor = function rendererInterceptor( }); }; -type MobileDateRangePickerComponent = (( +type MobileDateRangePickerComponent = (( props: MobileDateTimeRangePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; -const MobileDateTimeRangePicker = React.forwardRef(function MobileDateTimeRangePicker( - inProps: MobileDateTimeRangePickerProps, - ref: React.Ref, -) { +const MobileDateTimeRangePicker = React.forwardRef(function MobileDateTimeRangePicker< + TDate extends PickerValidDate, +>(inProps: MobileDateTimeRangePickerProps, ref: React.Ref) { // Props with the default values common to all date time range pickers const defaultizedProps = useDateTimeRangePickerDefaultizedProps< TDate, @@ -220,7 +220,7 @@ MobileDateTimeRangePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * If `true`, after selecting `start` date calendar will not automatically switch to the month of `end` date. * @default false @@ -311,29 +311,29 @@ MobileDateTimeRangePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Maximal selectable moment of time with binding to date, to set max time in each day use `maxTime`. */ - maxDateTime: PropTypes.any, + maxDateTime: PropTypes.object, /** * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Minimal selectable moment of time with binding to date, to set min time in each day use `minTime`. */ - minDateTime: PropTypes.any, + minDateTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -426,7 +426,7 @@ MobileDateTimeRangePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component rendered on the "day" view when `props.loading` is true. * @returns {React.ReactNode} The node to render when loading. @@ -542,7 +542,7 @@ MobileDateTimeRangePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.types.ts b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.types.ts index e7d18f3c649b9..de00d8476319d 100644 --- a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.types.ts @@ -1,4 +1,5 @@ import { MakeOptional } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseMobileRangePickerSlots, UseMobileRangePickerSlotProps, @@ -11,15 +12,15 @@ import { } from '../DateTimeRangePicker/shared'; import { DateTimeRangePickerView } from '../internals/models'; -export interface MobileDateTimeRangePickerSlots +export interface MobileDateTimeRangePickerSlots extends BaseDateTimeRangePickerSlots, MakeOptional, 'field'> {} -export interface MobileDateTimeRangePickerSlotProps +export interface MobileDateTimeRangePickerSlotProps extends BaseDateTimeRangePickerSlotProps, Omit, 'tabs' | 'toolbar'> {} -export interface MobileDateTimeRangePickerProps +export interface MobileDateTimeRangePickerProps extends BaseDateTimeRangePickerProps, MobileRangeOnlyPickerProps { /** diff --git a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx index 31242ffb5927a..6cc3b8d20e970 100644 --- a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx +++ b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx @@ -16,6 +16,7 @@ import { FieldsTextFieldProps, convertFieldResponseIntoMuiTextFieldProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { MultiInputDateRangeFieldProps } from './MultiInputDateRangeField.types'; import { useMultiInputDateRangeField } from '../internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField'; import { UseDateRangeFieldProps } from '../internals/models/dateRange'; @@ -59,7 +60,7 @@ const MultiInputDateRangeFieldSeparator = styled( }, )({}); -type MultiInputDateRangeFieldComponent = (( +type MultiInputDateRangeFieldComponent = (( props: MultiInputDateRangeFieldProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -73,10 +74,9 @@ type MultiInputDateRangeFieldComponent = (( * * - [MultiInputDateRangeField API](https://mui.com/x/api/multi-input-date-range-field/) */ -const MultiInputDateRangeField = React.forwardRef(function MultiInputDateRangeField( - inProps: MultiInputDateRangeFieldProps, - ref: React.Ref, -) { +const MultiInputDateRangeField = React.forwardRef(function MultiInputDateRangeField< + TDate extends PickerValidDate, +>(inProps: MultiInputDateRangeFieldProps, ref: React.Ref) { const themeProps = useThemeProps({ props: inProps, name: 'MuiMultiInputDateRangeField', @@ -173,7 +173,7 @@ MultiInputDateRangeField.propTypes = { /** * The default value. Use when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * Defines the `flex-direction` style property. * It is applied for all screen sizes. @@ -216,11 +216,11 @@ MultiInputDateRangeField.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Callback fired when the value changes. * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value. @@ -253,7 +253,7 @@ MultiInputDateRangeField.propTypes = { * For example, on time fields it will be used to determine the date to set. * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * The currently selected sections. * This prop accept four formats: @@ -361,7 +361,7 @@ MultiInputDateRangeField.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), } as any; export { MultiInputDateRangeField }; diff --git a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.types.ts b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.types.ts index 9638f73727ac5..8b741a80e9201 100644 --- a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.types.ts +++ b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.types.ts @@ -1,4 +1,5 @@ import * as React from 'react'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { SlotComponentProps } from '@mui/base/utils'; import Typography from '@mui/material/Typography'; import Stack, { StackProps } from '@mui/material/Stack'; @@ -9,21 +10,21 @@ import { MultiInputFieldRefs } from '../internals/models/fields'; import { MultiInputRangeFieldClasses, RangePosition } from '../models'; export type UseMultiInputDateRangeFieldParams< - TDate, + TDate extends PickerValidDate, TTextFieldSlotProps extends {}, > = UseMultiInputRangeFieldParams, TTextFieldSlotProps>; -export interface UseMultiInputDateRangeFieldProps +export interface UseMultiInputDateRangeFieldProps extends Omit, 'unstableFieldRef' | 'clearable' | 'onClear'>, MultiInputFieldRefs {} -export type UseMultiInputDateRangeFieldComponentProps = Omit< - TChildProps, - keyof UseMultiInputDateRangeFieldProps -> & +export type UseMultiInputDateRangeFieldComponentProps< + TDate extends PickerValidDate, + TChildProps extends {}, +> = Omit> & UseMultiInputDateRangeFieldProps; -export interface MultiInputDateRangeFieldProps +export interface MultiInputDateRangeFieldProps extends UseMultiInputDateRangeFieldComponentProps> { autoFocus?: boolean; /** @@ -42,7 +43,8 @@ export interface MultiInputDateRangeFieldProps slotProps?: MultiInputDateRangeFieldSlotProps; } -export type MultiInputDateRangeFieldOwnerState = MultiInputDateRangeFieldProps; +export type MultiInputDateRangeFieldOwnerState = + MultiInputDateRangeFieldProps; export interface MultiInputDateRangeFieldSlots { /** @@ -64,7 +66,7 @@ export interface MultiInputDateRangeFieldSlots { separator?: React.ElementType; } -export interface MultiInputDateRangeFieldSlotProps { +export interface MultiInputDateRangeFieldSlotProps { root?: SlotComponentProps>; textField?: SlotComponentProps< typeof TextField, diff --git a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx index 3820e3f57814c..64ec39d23c327 100644 --- a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx +++ b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx @@ -16,6 +16,7 @@ import { FieldsTextFieldProps, convertFieldResponseIntoMuiTextFieldProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { MultiInputDateTimeRangeFieldProps } from './MultiInputDateTimeRangeField.types'; import { useMultiInputDateTimeRangeField } from '../internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField'; import { UseDateTimeRangeFieldProps } from '../internals/models/dateTimeRange'; @@ -57,7 +58,7 @@ const MultiInputDateTimeRangeFieldSeparator = styled( }, )({}); -type MultiInputDateTimeRangeFieldComponent = (( +type MultiInputDateTimeRangeFieldComponent = (( props: MultiInputDateTimeRangeFieldProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -71,10 +72,9 @@ type MultiInputDateTimeRangeFieldComponent = (( * * - [MultiInputDateTimeRangeField API](https://mui.com/x/api/multi-input-date-time-range-field/) */ -const MultiInputDateTimeRangeField = React.forwardRef(function MultiInputDateTimeRangeField( - inProps: MultiInputDateTimeRangeFieldProps, - ref: React.Ref, -) { +const MultiInputDateTimeRangeField = React.forwardRef(function MultiInputDateTimeRangeField< + TDate extends PickerValidDate, +>(inProps: MultiInputDateTimeRangeFieldProps, ref: React.Ref) { const themeProps = useThemeProps({ props: inProps, name: 'MuiMultiInputDateTimeRangeField', @@ -176,7 +176,7 @@ MultiInputDateTimeRangeField.propTypes = { /** * The default value. Use when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * Defines the `flex-direction` style property. * It is applied for all screen sizes. @@ -224,29 +224,29 @@ MultiInputDateTimeRangeField.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Maximal selectable moment of time with binding to date, to set max time in each day use `maxTime`. */ - maxDateTime: PropTypes.any, + maxDateTime: PropTypes.object, /** * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Minimal selectable moment of time with binding to date, to set min time in each day use `minTime`. */ - minDateTime: PropTypes.any, + minDateTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -284,7 +284,7 @@ MultiInputDateTimeRangeField.propTypes = { * For example, on time fields it will be used to determine the date to set. * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * The currently selected sections. * This prop accept four formats: @@ -400,7 +400,7 @@ MultiInputDateTimeRangeField.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), } as any; export { MultiInputDateTimeRangeField }; diff --git a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.types.ts b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.types.ts index 3189bf67c2b7c..f83594e58fb1f 100644 --- a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.types.ts +++ b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.types.ts @@ -3,6 +3,7 @@ import { SlotComponentProps } from '@mui/base/utils'; import Typography from '@mui/material/Typography'; import Stack, { StackProps } from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseDateTimeRangeFieldDefaultizedProps, UseDateTimeRangeFieldProps, @@ -12,21 +13,21 @@ import { UseMultiInputRangeFieldParams } from '../internals/hooks/useMultiInputR import { MultiInputRangeFieldClasses, RangePosition } from '../models'; export type UseMultiInputDateTimeRangeFieldParams< - TDate, + TDate extends PickerValidDate, TTextFieldSlotProps extends {}, > = UseMultiInputRangeFieldParams, TTextFieldSlotProps>; -export interface UseMultiInputDateTimeRangeFieldProps +export interface UseMultiInputDateTimeRangeFieldProps extends Omit, 'unstableFieldRef' | 'clearable' | 'onClear'>, MultiInputFieldRefs {} -export type UseMultiInputDateTimeRangeFieldComponentProps = Omit< - TChildProps, - keyof UseMultiInputDateTimeRangeFieldProps -> & +export type UseMultiInputDateTimeRangeFieldComponentProps< + TDate extends PickerValidDate, + TChildProps extends {}, +> = Omit> & UseMultiInputDateTimeRangeFieldProps; -export interface MultiInputDateTimeRangeFieldProps +export interface MultiInputDateTimeRangeFieldProps extends UseMultiInputDateTimeRangeFieldComponentProps> { autoFocus?: boolean; /** @@ -45,7 +46,7 @@ export interface MultiInputDateTimeRangeFieldProps slotProps?: MultiInputDateTimeRangeFieldSlotProps; } -export type MultiInputDateTimeRangeFieldOwnerState = +export type MultiInputDateTimeRangeFieldOwnerState = MultiInputDateTimeRangeFieldProps; export interface MultiInputDateTimeRangeFieldSlots { @@ -68,7 +69,7 @@ export interface MultiInputDateTimeRangeFieldSlots { separator?: React.ElementType; } -export interface MultiInputDateTimeRangeFieldSlotProps { +export interface MultiInputDateTimeRangeFieldSlotProps { root?: SlotComponentProps>; textField?: SlotComponentProps< typeof TextField, @@ -83,7 +84,7 @@ export interface MultiInputDateTimeRangeFieldSlotProps { } export type UseMultiInputDateTimeRangeFieldDefaultizedProps< - TDate, + TDate extends PickerValidDate, AdditionalProps extends {}, > = UseDateTimeRangeFieldDefaultizedProps & Omit; diff --git a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx index 0cc0564271325..03ad3860bce26 100644 --- a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx +++ b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx @@ -16,6 +16,7 @@ import { FieldsTextFieldProps, convertFieldResponseIntoMuiTextFieldProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { MultiInputTimeRangeFieldProps } from './MultiInputTimeRangeField.types'; import { useMultiInputTimeRangeField } from '../internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField'; import { UseTimeRangeFieldProps } from '../internals/models/timeRange'; @@ -59,7 +60,7 @@ const MultiInputTimeRangeFieldSeparator = styled( }, )({}); -type MultiInputTimeRangeFieldComponent = (( +type MultiInputTimeRangeFieldComponent = (( props: MultiInputTimeRangeFieldProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -73,10 +74,9 @@ type MultiInputTimeRangeFieldComponent = (( * * - [MultiInputTimeRangeField API](https://mui.com/x/api/multi-input-time-range-field/) */ -const MultiInputTimeRangeField = React.forwardRef(function MultiInputTimeRangeField( - inProps: MultiInputTimeRangeFieldProps, - ref: React.Ref, -) { +const MultiInputTimeRangeField = React.forwardRef(function MultiInputTimeRangeField< + TDate extends PickerValidDate, +>(inProps: MultiInputTimeRangeFieldProps, ref: React.Ref) { const themeProps = useThemeProps({ props: inProps, name: 'MuiMultiInputTimeRangeField', @@ -179,7 +179,7 @@ MultiInputTimeRangeField.propTypes = { /** * The default value. Use when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * Defines the `flex-direction` style property. * It is applied for all screen sizes. @@ -228,12 +228,12 @@ MultiInputTimeRangeField.propTypes = { * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -271,7 +271,7 @@ MultiInputTimeRangeField.propTypes = { * For example, on time fields it will be used to determine the date to set. * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * The currently selected sections. * This prop accept four formats: @@ -376,7 +376,7 @@ MultiInputTimeRangeField.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), } as any; export { MultiInputTimeRangeField }; diff --git a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.types.ts b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.types.ts index 8cd1cb9682d5e..3dde1f4009337 100644 --- a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.types.ts +++ b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.types.ts @@ -3,6 +3,7 @@ import { SlotComponentProps } from '@mui/base/utils'; import Typography from '@mui/material/Typography'; import Stack, { StackProps } from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseTimeRangeFieldDefaultizedProps, UseTimeRangeFieldProps, @@ -12,21 +13,21 @@ import { MultiInputFieldRefs } from '../internals/models/fields'; import { MultiInputRangeFieldClasses, RangePosition } from '../models'; export type UseMultiInputTimeRangeFieldParams< - TDate, + TDate extends PickerValidDate, TTextFieldSlotProps extends {}, > = UseMultiInputRangeFieldParams, TTextFieldSlotProps>; -export interface UseMultiInputTimeRangeFieldProps +export interface UseMultiInputTimeRangeFieldProps extends Omit, 'unstableFieldRef' | 'clearable' | 'onClear'>, MultiInputFieldRefs {} -export type UseMultiInputTimeRangeFieldComponentProps = Omit< - TChildProps, - keyof UseMultiInputTimeRangeFieldProps -> & +export type UseMultiInputTimeRangeFieldComponentProps< + TDate extends PickerValidDate, + TChildProps extends {}, +> = Omit> & UseMultiInputTimeRangeFieldProps; -export interface MultiInputTimeRangeFieldProps +export interface MultiInputTimeRangeFieldProps extends UseMultiInputTimeRangeFieldComponentProps> { autoFocus?: boolean; /** @@ -45,7 +46,8 @@ export interface MultiInputTimeRangeFieldProps slotProps?: MultiInputTimeRangeFieldSlotProps; } -export type MultiInputTimeRangeFieldOwnerState = MultiInputTimeRangeFieldProps; +export type MultiInputTimeRangeFieldOwnerState = + MultiInputTimeRangeFieldProps; export interface MultiInputTimeRangeFieldSlots { /** @@ -67,7 +69,7 @@ export interface MultiInputTimeRangeFieldSlots { separator?: React.ElementType; } -export interface MultiInputTimeRangeFieldSlotProps { +export interface MultiInputTimeRangeFieldSlotProps { root?: SlotComponentProps>; textField?: SlotComponentProps< typeof TextField, @@ -78,7 +80,7 @@ export interface MultiInputTimeRangeFieldSlotProps { } export type UseMultiInputTimeRangeFieldDefaultizedProps< - TDate, + TDate extends PickerValidDate, AdditionalProps extends {}, > = UseTimeRangeFieldDefaultizedProps & Omit; diff --git a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.tsx b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.tsx index 79fdcbfcb1ff8..ca3db91f8151f 100644 --- a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.tsx +++ b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.tsx @@ -5,6 +5,7 @@ import { useThemeProps } from '@mui/material/styles'; import { useSlotProps } from '@mui/base/utils'; import { useClearableField } from '@mui/x-date-pickers/hooks'; import { convertFieldResponseIntoMuiTextFieldProps } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { refType } from '@mui/utils'; import { SingleInputDateRangeFieldProps, @@ -13,7 +14,7 @@ import { import { useSingleInputDateRangeField } from './useSingleInputDateRangeField'; import { FieldType } from '../internals/models'; -type DateRangeFieldComponent = (( +type DateRangeFieldComponent = (( props: SingleInputDateRangeFieldProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any; fieldType?: FieldType }; @@ -27,10 +28,9 @@ type DateRangeFieldComponent = (( * * - [SingleInputDateRangeField API](https://mui.com/x/api/single-input-date-range-field/) */ -const SingleInputDateRangeField = React.forwardRef(function SingleInputDateRangeField( - inProps: SingleInputDateRangeFieldProps, - inRef: React.Ref, -) { +const SingleInputDateRangeField = React.forwardRef(function SingleInputDateRangeField< + TDate extends PickerValidDate, +>(inProps: SingleInputDateRangeFieldProps, inRef: React.Ref) { const themeProps = useThemeProps({ props: inProps, name: 'MuiSingleInputDateRangeField', @@ -101,7 +101,7 @@ SingleInputDateRangeField.propTypes = { /** * The default value. Use when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * If `true`, the component is disabled. * @default false @@ -188,11 +188,11 @@ SingleInputDateRangeField.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Name attribute of the `input` element. */ @@ -235,7 +235,7 @@ SingleInputDateRangeField.propTypes = { * For example, on time fields it will be used to determine the date to set. * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * If `true`, the label is displayed as required and the `input` element is required. * @default false @@ -334,7 +334,7 @@ SingleInputDateRangeField.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), /** * The variant to use. * @default 'outlined' diff --git a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.types.ts b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.types.ts index 82aab457b364c..8e022305bf596 100644 --- a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.types.ts +++ b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.types.ts @@ -2,25 +2,27 @@ import * as React from 'react'; import { SlotComponentProps } from '@mui/base/utils'; import TextField from '@mui/material/TextField'; import { FieldsTextFieldProps } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseClearableFieldSlots, UseClearableFieldSlotProps } from '@mui/x-date-pickers/hooks'; import { UseDateRangeFieldDefaultizedProps, UseDateRangeFieldProps } from '../internals/models'; -export interface UseSingleInputDateRangeFieldProps extends UseDateRangeFieldProps {} +export interface UseSingleInputDateRangeFieldProps + extends UseDateRangeFieldProps {} export type UseSingleInputDateRangeFieldDefaultizedProps< - TDate, + TDate extends PickerValidDate, AdditionalProps extends {}, > = UseDateRangeFieldDefaultizedProps & Omit; -export type UseSingleInputDateRangeFieldComponentProps = Omit< - TChildProps, - keyof UseSingleInputDateRangeFieldProps -> & +export type UseSingleInputDateRangeFieldComponentProps< + TDate extends PickerValidDate, + TChildProps extends {}, +> = Omit> & UseSingleInputDateRangeFieldProps; export type SingleInputDateRangeFieldProps< - TDate, + TDate extends PickerValidDate, TChildProps extends {} = FieldsTextFieldProps, > = UseSingleInputDateRangeFieldComponentProps & { /** @@ -35,7 +37,8 @@ export type SingleInputDateRangeFieldProps< slotProps?: SingleInputDateRangeFieldSlotProps; }; -export type SingleInputDateRangeFieldOwnerState = SingleInputDateRangeFieldProps; +export type SingleInputDateRangeFieldOwnerState = + SingleInputDateRangeFieldProps; export interface SingleInputDateRangeFieldSlots extends UseClearableFieldSlots { /** @@ -46,6 +49,7 @@ export interface SingleInputDateRangeFieldSlots extends UseClearableFieldSlots { textField?: React.ElementType; } -export interface SingleInputDateRangeFieldSlotProps extends UseClearableFieldSlotProps { +export interface SingleInputDateRangeFieldSlotProps + extends UseClearableFieldSlotProps { textField?: SlotComponentProps>; } diff --git a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/useSingleInputDateRangeField.ts b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/useSingleInputDateRangeField.ts index e4fd9f760d11a..267533708dcb5 100644 --- a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/useSingleInputDateRangeField.ts +++ b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/useSingleInputDateRangeField.ts @@ -5,6 +5,7 @@ import { useField, splitFieldInternalAndForwardedProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseSingleInputDateRangeFieldComponentProps, UseSingleInputDateRangeFieldDefaultizedProps, @@ -13,7 +14,10 @@ import { import { rangeValueManager, rangeFieldValueManager } from '../internals/utils/valueManagers'; import { validateDateRange } from '../internals/utils/validation/validateDateRange'; -export const useDefaultizedDateRangeFieldProps = ( +export const useDefaultizedDateRangeFieldProps = < + TDate extends PickerValidDate, + AdditionalProps extends {}, +>( props: UseSingleInputDateRangeFieldProps, ): UseSingleInputDateRangeFieldDefaultizedProps => { const utils = useUtils(); @@ -29,7 +33,7 @@ export const useDefaultizedDateRangeFieldProps = ( +export const useSingleInputDateRangeField = ( inProps: UseSingleInputDateRangeFieldComponentProps, ) => { const props = useDefaultizedDateRangeFieldProps(inProps); diff --git a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.tsx b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.tsx index 1afa9c2ddc87d..f2635d79d128a 100644 --- a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.tsx +++ b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.tsx @@ -5,6 +5,7 @@ import { convertFieldResponseIntoMuiTextFieldProps } from '@mui/x-date-pickers/i import { useThemeProps } from '@mui/material/styles'; import { useSlotProps } from '@mui/base/utils'; import { useClearableField } from '@mui/x-date-pickers/hooks'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { refType } from '@mui/utils'; import { SingleInputDateTimeRangeFieldProps, @@ -13,7 +14,7 @@ import { import { useSingleInputDateTimeRangeField } from './useSingleInputDateTimeRangeField'; import { FieldType } from '../internals/models'; -type DateRangeFieldComponent = (( +type DateRangeFieldComponent = (( props: SingleInputDateTimeRangeFieldProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any; fieldType?: FieldType }; @@ -28,7 +29,7 @@ type DateRangeFieldComponent = (( * - [SingleInputDateTimeRangeField API](https://mui.com/x/api/single-input-date-time-range-field/) */ const SingleInputDateTimeRangeField = React.forwardRef(function SingleInputDateTimeRangeField< - TDate, + TDate extends PickerValidDate, >(inProps: SingleInputDateTimeRangeFieldProps, inRef: React.Ref) { const themeProps = useThemeProps({ props: inProps, @@ -107,7 +108,7 @@ SingleInputDateTimeRangeField.propTypes = { /** * The default value. Use when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * If `true`, the component is disabled. * @default false @@ -199,29 +200,29 @@ SingleInputDateTimeRangeField.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Maximal selectable moment of time with binding to date, to set max time in each day use `maxTime`. */ - maxDateTime: PropTypes.any, + maxDateTime: PropTypes.object, /** * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Minimal selectable moment of time with binding to date, to set min time in each day use `minTime`. */ - minDateTime: PropTypes.any, + minDateTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -269,7 +270,7 @@ SingleInputDateTimeRangeField.propTypes = { * For example, on time fields it will be used to determine the date to set. * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * If `true`, the label is displayed as required and the `input` element is required. * @default false @@ -376,7 +377,7 @@ SingleInputDateTimeRangeField.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), /** * The variant to use. * @default 'outlined' diff --git a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.types.ts b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.types.ts index 1dfb93aeeec09..9a6b6b88d7fc0 100644 --- a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.types.ts +++ b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.types.ts @@ -3,26 +3,27 @@ import { SlotComponentProps } from '@mui/base/utils'; import TextField from '@mui/material/TextField'; import { FieldsTextFieldProps } from '@mui/x-date-pickers/internals'; import { UseClearableFieldSlots, UseClearableFieldSlotProps } from '@mui/x-date-pickers/hooks'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseDateTimeRangeFieldDefaultizedProps, UseDateTimeRangeFieldProps, } from '../internals/models'; -export interface UseSingleInputDateTimeRangeFieldProps +export interface UseSingleInputDateTimeRangeFieldProps extends UseDateTimeRangeFieldProps {} export type UseSingleInputDateTimeRangeFieldDefaultizedProps< - TDate, + TDate extends PickerValidDate, AdditionalProps extends {}, > = UseDateTimeRangeFieldDefaultizedProps & AdditionalProps; -export type UseSingleInputDateTimeRangeFieldComponentProps = Omit< - TChildProps, - keyof UseSingleInputDateTimeRangeFieldProps -> & +export type UseSingleInputDateTimeRangeFieldComponentProps< + TDate extends PickerValidDate, + TChildProps extends {}, +> = Omit> & UseSingleInputDateTimeRangeFieldProps; -export interface SingleInputDateTimeRangeFieldProps +export interface SingleInputDateTimeRangeFieldProps extends UseSingleInputDateTimeRangeFieldComponentProps { /** * Overridable component slots. @@ -36,7 +37,7 @@ export interface SingleInputDateTimeRangeFieldProps slotProps?: SingleInputDateTimeRangeFieldSlotProps; } -export type SingleInputDateTimeRangeFieldOwnerState = +export type SingleInputDateTimeRangeFieldOwnerState = SingleInputDateTimeRangeFieldProps; export interface SingleInputDateTimeRangeFieldSlots extends UseClearableFieldSlots { @@ -48,7 +49,8 @@ export interface SingleInputDateTimeRangeFieldSlots extends UseClearableFieldSlo textField?: React.ElementType; } -export interface SingleInputDateTimeRangeFieldSlotProps extends UseClearableFieldSlotProps { +export interface SingleInputDateTimeRangeFieldSlotProps + extends UseClearableFieldSlotProps { textField?: SlotComponentProps< typeof TextField, {}, diff --git a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/useSingleInputDateTimeRangeField.ts b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/useSingleInputDateTimeRangeField.ts index 815b8f7ae74f0..d6afd05119409 100644 --- a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/useSingleInputDateTimeRangeField.ts +++ b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/useSingleInputDateTimeRangeField.ts @@ -5,6 +5,7 @@ import { useDefaultDates, splitFieldInternalAndForwardedProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseSingleInputDateTimeRangeFieldComponentProps, UseSingleInputDateTimeRangeFieldDefaultizedProps, @@ -13,7 +14,10 @@ import { import { rangeValueManager, rangeFieldValueManager } from '../internals/utils/valueManagers'; import { validateDateTimeRange } from '../internals/utils/validation/validateDateTimeRange'; -export const useDefaultizedTimeRangeFieldProps = ( +export const useDefaultizedTimeRangeFieldProps = < + TDate extends PickerValidDate, + AdditionalProps extends {}, +>( props: UseSingleInputDateTimeRangeFieldProps, ): UseSingleInputDateTimeRangeFieldDefaultizedProps => { const utils = useUtils(); @@ -37,7 +41,10 @@ export const useDefaultizedTimeRangeFieldProps = ( +export const useSingleInputDateTimeRangeField = < + TDate extends PickerValidDate, + TChildProps extends {}, +>( inProps: UseSingleInputDateTimeRangeFieldComponentProps, ) => { const props = useDefaultizedTimeRangeFieldProps(inProps); diff --git a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.tsx b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.tsx index 64050ad98d9a9..c719820f233f7 100644 --- a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.tsx +++ b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.tsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import MuiTextField from '@mui/material/TextField'; import { useClearableField } from '@mui/x-date-pickers/hooks'; import { convertFieldResponseIntoMuiTextFieldProps } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { useThemeProps } from '@mui/material/styles'; import { useSlotProps } from '@mui/base/utils'; import { refType } from '@mui/utils'; @@ -13,7 +14,7 @@ import { import { useSingleInputTimeRangeField } from './useSingleInputTimeRangeField'; import { FieldType } from '../internals/models'; -type DateRangeFieldComponent = (( +type DateRangeFieldComponent = (( props: SingleInputTimeRangeFieldProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any; fieldType?: FieldType }; @@ -27,10 +28,9 @@ type DateRangeFieldComponent = (( * * - [SingleInputTimeRangeField API](https://mui.com/x/api/single-input-time-range-field/) */ -const SingleInputTimeRangeField = React.forwardRef(function SingleInputTimeRangeField( - inProps: SingleInputTimeRangeFieldProps, - inRef: React.Ref, -) { +const SingleInputTimeRangeField = React.forwardRef(function SingleInputTimeRangeField< + TDate extends PickerValidDate, +>(inProps: SingleInputTimeRangeFieldProps, inRef: React.Ref) { const themeProps = useThemeProps({ props: inProps, name: 'MuiSingleInputTimeRangeField', @@ -106,7 +106,7 @@ SingleInputTimeRangeField.propTypes = { /** * The default value. Use when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * If `true`, the component is disabled. * @default false @@ -199,12 +199,12 @@ SingleInputTimeRangeField.propTypes = { * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -252,7 +252,7 @@ SingleInputTimeRangeField.propTypes = { * For example, on time fields it will be used to determine the date to set. * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * If `true`, the label is displayed as required and the `input` element is required. * @default false @@ -348,7 +348,7 @@ SingleInputTimeRangeField.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), /** * The variant to use. * @default 'outlined' diff --git a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.types.ts b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.types.ts index aee8a1558ebcc..2145337104a91 100644 --- a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.types.ts +++ b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.types.ts @@ -2,23 +2,25 @@ import * as React from 'react'; import { SlotComponentProps } from '@mui/base/utils'; import TextField from '@mui/material/TextField'; import { FieldsTextFieldProps } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseClearableFieldSlots, UseClearableFieldSlotProps } from '@mui/x-date-pickers/hooks'; import { UseTimeRangeFieldDefaultizedProps, UseTimeRangeFieldProps } from '../internals/models'; -export interface UseSingleInputTimeRangeFieldProps extends UseTimeRangeFieldProps {} +export interface UseSingleInputTimeRangeFieldProps + extends UseTimeRangeFieldProps {} export type UseSingleInputTimeRangeFieldDefaultizedProps< - TDate, + TDate extends PickerValidDate, AdditionalProps extends {}, > = UseTimeRangeFieldDefaultizedProps & AdditionalProps; -export type UseSingleInputTimeRangeFieldComponentProps = Omit< - TChildProps, - keyof UseSingleInputTimeRangeFieldProps -> & +export type UseSingleInputTimeRangeFieldComponentProps< + TDate extends PickerValidDate, + TChildProps extends {}, +> = Omit> & UseSingleInputTimeRangeFieldProps; -export interface SingleInputTimeRangeFieldProps +export interface SingleInputTimeRangeFieldProps extends UseSingleInputTimeRangeFieldComponentProps { /** * Overridable component slots. @@ -32,7 +34,8 @@ export interface SingleInputTimeRangeFieldProps slotProps?: SingleInputTimeRangeFieldSlotProps; } -export type SingleInputTimeRangeFieldOwnerState = SingleInputTimeRangeFieldProps; +export type SingleInputTimeRangeFieldOwnerState = + SingleInputTimeRangeFieldProps; export interface SingleInputTimeRangeFieldSlots extends UseClearableFieldSlots { /** @@ -43,6 +46,7 @@ export interface SingleInputTimeRangeFieldSlots extends UseClearableFieldSlots { textField?: React.ElementType; } -export interface SingleInputTimeRangeFieldSlotProps extends UseClearableFieldSlotProps { +export interface SingleInputTimeRangeFieldSlotProps + extends UseClearableFieldSlotProps { textField?: SlotComponentProps>; } diff --git a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/useSingleInputTimeRangeField.ts b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/useSingleInputTimeRangeField.ts index dc016b777afe6..92de900e89e66 100644 --- a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/useSingleInputTimeRangeField.ts +++ b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/useSingleInputTimeRangeField.ts @@ -3,6 +3,7 @@ import { useField, splitFieldInternalAndForwardedProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseSingleInputTimeRangeFieldComponentProps, UseSingleInputTimeRangeFieldDefaultizedProps, @@ -11,7 +12,10 @@ import { import { rangeValueManager, rangeFieldValueManager } from '../internals/utils/valueManagers'; import { validateTimeRange } from '../internals/utils/validation/validateTimeRange'; -export const useDefaultizedTimeRangeFieldProps = ( +export const useDefaultizedTimeRangeFieldProps = < + TDate extends PickerValidDate, + AdditionalProps extends {}, +>( props: UseSingleInputTimeRangeFieldProps, ): UseSingleInputTimeRangeFieldDefaultizedProps => { const utils = useUtils(); @@ -27,7 +31,7 @@ export const useDefaultizedTimeRangeFieldProps = ( +export const useSingleInputTimeRangeField = ( inProps: UseSingleInputTimeRangeFieldComponentProps, ) => { const props = useDefaultizedTimeRangeFieldProps(inProps); diff --git a/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx b/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx index a77cd758fdd81..58ac192fe5c84 100644 --- a/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { PickerViewRendererLookup } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { useStaticRangePicker } from '../internals/hooks/useStaticRangePicker'; import { StaticDateRangePickerProps } from './StaticDateRangePicker.types'; import { useDateRangePickerDefaultizedProps } from '../DateRangePicker/shared'; @@ -9,7 +10,7 @@ import { rangeValueManager } from '../internals/utils/valueManagers'; import { validateDateRange } from '../internals/utils/validation/validateDateRange'; import { DateRange } from '../models'; -type StaticDateRangePickerComponent = (( +type StaticDateRangePickerComponent = (( props: StaticDateRangePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -23,10 +24,9 @@ type StaticDateRangePickerComponent = (( * * - [StaticDateRangePicker API](https://mui.com/x/api/date-pickers/static-date-range-picker/) */ -const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker( - inProps: StaticDateRangePickerProps, - ref: React.Ref, -) { +const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker< + TDate extends PickerValidDate, +>(inProps: StaticDateRangePickerProps, ref: React.Ref) { const defaultizedProps = useDateRangePickerDefaultizedProps< TDate, StaticDateRangePickerProps @@ -107,7 +107,7 @@ StaticDateRangePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.arrayOf(PropTypes.any), + defaultValue: PropTypes.arrayOf(PropTypes.object), /** * If `true`, after selecting `start` date calendar will not automatically switch to the month of `end` date. * @default false @@ -167,11 +167,11 @@ StaticDateRangePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Callback fired when the value is accepted. * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value. @@ -228,7 +228,7 @@ StaticDateRangePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component rendered on the "day" view when `props.loading` is true. * @returns {React.ReactNode} The node to render when loading. @@ -287,7 +287,7 @@ StaticDateRangePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.arrayOf(PropTypes.any), + value: PropTypes.arrayOf(PropTypes.object), /** * Define custom view renderers for each section. * If `null`, the section will only have field editing. diff --git a/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.types.ts b/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.types.ts index 1f4c529a9ac1e..78406f30dc31c 100644 --- a/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.types.ts @@ -1,4 +1,5 @@ import { MakeOptional } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { StaticRangeOnlyPickerProps, UseStaticRangePickerSlots, @@ -10,15 +11,15 @@ import { BaseDateRangePickerSlotProps, } from '../DateRangePicker/shared'; -export interface StaticDateRangePickerSlots +export interface StaticDateRangePickerSlots extends BaseDateRangePickerSlots, UseStaticRangePickerSlots {} -export interface StaticDateRangePickerSlotProps +export interface StaticDateRangePickerSlotProps extends BaseDateRangePickerSlotProps, UseStaticRangePickerSlotProps {} -export interface StaticDateRangePickerProps +export interface StaticDateRangePickerProps extends BaseDateRangePickerProps, MakeOptional { /** diff --git a/packages/x-date-pickers-pro/src/dateRangeViewRenderers/dateRangeViewRenderers.tsx b/packages/x-date-pickers-pro/src/dateRangeViewRenderers/dateRangeViewRenderers.tsx index 5f557b87785ee..7253a0cd14c85 100644 --- a/packages/x-date-pickers-pro/src/dateRangeViewRenderers/dateRangeViewRenderers.tsx +++ b/packages/x-date-pickers-pro/src/dateRangeViewRenderers/dateRangeViewRenderers.tsx @@ -1,9 +1,12 @@ import * as React from 'react'; import { DateOrTimeViewWithMeridiem } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DateRangeCalendar, DateRangeCalendarProps } from '../DateRangeCalendar'; -export interface DateRangeViewRendererProps - extends Omit, 'views'> { +export interface DateRangeViewRendererProps< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends Omit, 'views'> { views: readonly TView[]; } @@ -11,7 +14,7 @@ export interface DateRangeViewRendererProps({ +export const renderDateRangeViewCalendar = ({ value, defaultValue, referenceDate, diff --git a/packages/x-date-pickers-pro/src/internals/hooks/models/useRangePicker.ts b/packages/x-date-pickers-pro/src/internals/hooks/models/useRangePicker.ts index a4239295a40e2..9c78331a02851 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/models/useRangePicker.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/models/useRangePicker.ts @@ -9,6 +9,7 @@ import { DateOrTimeViewWithMeridiem, ExportedBaseTabsProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { ExportedPickersLayoutSlots, ExportedPickersLayoutSlotProps, @@ -21,26 +22,30 @@ import { } from '../useEnrichedRangePickerFieldProps'; import { DateRange } from '../../../models'; -export interface UseRangePickerSlots - extends ExportedPickersLayoutSlots, TDate, TView>, +export interface UseRangePickerSlots< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends ExportedPickersLayoutSlots, TDate, TView>, RangePickerFieldSlots {} -export interface UseRangePickerSlotProps - extends ExportedPickersLayoutSlotProps, TDate, TView>, +export interface UseRangePickerSlotProps< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends ExportedPickersLayoutSlotProps, TDate, TView>, RangePickerFieldSlotProps { tabs?: ExportedBaseTabsProps; toolbar?: ExportedBaseToolbarProps; } -export interface RangeOnlyPickerProps +export interface RangeOnlyPickerProps extends BaseNonStaticPickerProps, - UsePickerValueNonStaticProps, + UsePickerValueNonStaticProps, RangeFieldSection>, UsePickerViewsNonStaticProps, BaseRangeNonStaticPickerProps, UseRangePositionProps {} export interface UseRangePickerProps< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TError, TExternalProps extends UsePickerViewsProps, @@ -52,7 +57,7 @@ export interface RangePickerAdditionalViewProps extends Pick {} export interface UseRangePickerParams< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseRangePickerProps< TDate, diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx b/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx index d52fe387b6e7e..b7f2c73c90729 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx @@ -15,6 +15,7 @@ import { UsePickerValueFieldResponse, ExportedBaseTabsProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DesktopRangePickerAdditionalViewProps, UseDesktopRangePickerParams, @@ -30,7 +31,7 @@ import { useRangePosition } from '../useRangePosition'; const releaseInfo = getReleaseInfo(); export const useDesktopRangePicker = < - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseDesktopRangePickerProps, >({ diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.types.ts b/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.types.ts index b2fa4f0681e0c..a98872b25d9eb 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.types.ts @@ -4,6 +4,7 @@ import { UsePickerViewsProps, DateOrTimeViewWithMeridiem, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { RangeOnlyPickerProps, RangePickerAdditionalViewProps, @@ -13,15 +14,20 @@ import { UseRangePickerSlots, } from '../models/useRangePicker'; -export interface UseDesktopRangePickerSlots - extends UseRangePickerSlots, +export interface UseDesktopRangePickerSlots< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends UseRangePickerSlots, PickersPopperSlots {} -export interface UseDesktopRangePickerSlotProps - extends UseRangePickerSlotProps, +export interface UseDesktopRangePickerSlotProps< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends UseRangePickerSlotProps, PickersPopperSlotProps {} -export interface DesktopRangeOnlyPickerProps extends RangeOnlyPickerProps { +export interface DesktopRangeOnlyPickerProps + extends RangeOnlyPickerProps { /** * If `true`, the start `input` element is focused during the first mount. */ @@ -29,7 +35,7 @@ export interface DesktopRangeOnlyPickerProps extends RangeOnlyPickerProps } export interface UseDesktopRangePickerProps< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TError, TExternalProps extends UsePickerViewsProps, @@ -55,7 +61,7 @@ export interface UseDesktopRangePickerProps< export interface DesktopRangePickerAdditionalViewProps extends RangePickerAdditionalViewProps {} export interface UseDesktopRangePickerParams< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseDesktopRangePickerProps, > extends UseRangePickerParams< diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts b/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts index b0b28d35faf27..9fb579a2e3af9 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts @@ -9,6 +9,7 @@ import { BaseSingleInputFieldProps, FieldSelectedSections, FieldRef, + PickerValidDate, } from '@mui/x-date-pickers/models'; import { UseClearableFieldSlots, UseClearableFieldSlotProps } from '@mui/x-date-pickers/hooks'; import { PickersInputLocaleText } from '@mui/x-date-pickers/locales'; @@ -54,7 +55,8 @@ export interface RangePickerFieldSlots extends UseClearableFieldSlots { textField?: React.ElementType; } -export interface RangePickerFieldSlotProps extends UseClearableFieldSlotProps { +export interface RangePickerFieldSlotProps + extends UseClearableFieldSlotProps { field?: SlotComponentProps< React.ElementType< BaseMultiInputFieldProps, TDate, RangeFieldSection, unknown> @@ -73,7 +75,7 @@ export interface RangePickerFieldSlotProps extends UseClearableFieldSlotP } export interface UseEnrichedRangePickerFieldPropsParams< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TError, FieldProps extends BaseFieldProps< @@ -105,7 +107,11 @@ export interface UseEnrichedRangePickerFieldPropsParams< onViewChange?: (view: TView) => void; } -const useMultiInputFieldSlotProps = ({ +const useMultiInputFieldSlotProps = < + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, + TError, +>({ wrapperVariant, open, actions, @@ -281,7 +287,11 @@ const useMultiInputFieldSlotProps = ({ +const useSingleInputFieldSlotProps = < + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, + TError, +>({ wrapperVariant, open, actions, @@ -398,7 +408,7 @@ const useSingleInputFieldSlotProps = ( diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.tsx b/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.tsx index 7bb0d98f26d12..7db23cf2c4a4d 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.tsx @@ -13,6 +13,7 @@ import { UsePickerValueFieldResponse, ExportedBaseTabsProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import useId from '@mui/utils/useId'; import { MobileRangePickerAdditionalViewProps, @@ -29,7 +30,7 @@ import { useRangePosition } from '../useRangePosition'; const releaseInfo = getReleaseInfo(); export const useMobileRangePicker = < - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseMobileRangePickerProps, >({ diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.types.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.types.ts index b89b4733e2e26..39235ce0b0d5a 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.types.ts @@ -4,6 +4,7 @@ import { UsePickerViewsProps, DateOrTimeViewWithMeridiem, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { RangeOnlyPickerProps, RangePickerAdditionalViewProps, @@ -13,18 +14,23 @@ import { UseRangePickerSlots, } from '../models/useRangePicker'; -export interface UseMobileRangePickerSlots - extends UseRangePickerSlots, +export interface UseMobileRangePickerSlots< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends UseRangePickerSlots, PickersModalDialogSlots {} -export interface UseMobileRangePickerSlotProps - extends UseRangePickerSlotProps, +export interface UseMobileRangePickerSlotProps< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends UseRangePickerSlotProps, PickersModalDialogSlotProps {} -export interface MobileRangeOnlyPickerProps extends RangeOnlyPickerProps {} +export interface MobileRangeOnlyPickerProps + extends RangeOnlyPickerProps {} export interface UseMobileRangePickerProps< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TError, TExternalProps extends UsePickerViewsProps, @@ -50,7 +56,7 @@ export interface UseMobileRangePickerProps< export interface MobileRangePickerAdditionalViewProps extends RangePickerAdditionalViewProps {} export interface UseMobileRangePickerParams< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseMobileRangePickerProps, > extends UseRangePickerParams< diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField.ts index 082676318eb8b..47088f346682e 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField.ts @@ -13,7 +13,7 @@ import { UseFieldResponse, useControlledValueWithTimezone, } from '@mui/x-date-pickers/internals'; -import { DateValidationError } from '@mui/x-date-pickers/models'; +import { DateValidationError, PickerValidDate } from '@mui/x-date-pickers/models'; import { useDefaultizedDateRangeFieldProps } from '../../../SingleInputDateRangeField/useSingleInputDateRangeField'; import { UseMultiInputDateRangeFieldParams } from '../../../MultiInputDateRangeField/MultiInputDateRangeField.types'; import { @@ -25,7 +25,10 @@ import type { UseMultiInputRangeFieldResponse } from './useMultiInputRangeField. import { DateRangeValidationError, DateRange } from '../../../models'; import { excludeProps } from './shared'; -export const useMultiInputDateRangeField = ({ +export const useMultiInputDateRangeField = < + TDate extends PickerValidDate, + TTextFieldSlotProps extends {}, +>({ sharedProps: inSharedProps, startTextFieldProps, unstableStartFieldRef, @@ -99,10 +102,7 @@ export const useMultiInputDateRangeField = - > = { + const startFieldProps: UseDateFieldComponentProps> = { error: !!validationError[0], ...startTextFieldProps, disabled, @@ -119,10 +119,7 @@ export const useMultiInputDateRangeField = - > = { + const endFieldProps: UseDateFieldComponentProps> = { error: !!validationError[1], ...endTextFieldProps, format, diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField.ts index 9c182c1d2523d..d398a8b5e1ab5 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField.ts @@ -16,7 +16,7 @@ import { UseFieldResponse, useControlledValueWithTimezone, } from '@mui/x-date-pickers/internals'; -import { DateTimeValidationError } from '@mui/x-date-pickers/models'; +import { DateTimeValidationError, PickerValidDate } from '@mui/x-date-pickers/models'; import type { UseMultiInputDateTimeRangeFieldDefaultizedProps, UseMultiInputDateTimeRangeFieldParams, @@ -31,7 +31,10 @@ import { rangeValueManager } from '../../utils/valueManagers'; import type { UseMultiInputRangeFieldResponse } from './useMultiInputRangeField.types'; import { excludeProps } from './shared'; -export const useDefaultizedDateTimeRangeFieldProps = ( +export const useDefaultizedDateTimeRangeFieldProps = < + TDate extends PickerValidDate, + AdditionalProps extends {}, +>( props: UseMultiInputDateTimeRangeFieldProps, ): UseMultiInputDateTimeRangeFieldDefaultizedProps => { const utils = useUtils(); @@ -55,7 +58,10 @@ export const useDefaultizedDateTimeRangeFieldProps = ({ +export const useMultiInputDateTimeRangeField = < + TDate extends PickerValidDate, + TTextFieldSlotProps extends {}, +>({ sharedProps: inSharedProps, startTextFieldProps, unstableStartFieldRef, @@ -130,7 +136,7 @@ export const useMultiInputDateTimeRangeField = + UseDateTimeFieldDefaultizedProps > = { error: !!validationError[0], ...startTextFieldProps, @@ -149,7 +155,7 @@ export const useMultiInputDateTimeRangeField = + UseDateTimeFieldDefaultizedProps > = { error: !!validationError[1], ...endTextFieldProps, diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField.ts index eab2cd035f40a..8656009ce3f2e 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField.ts @@ -14,7 +14,7 @@ import { UseFieldResponse, useControlledValueWithTimezone, } from '@mui/x-date-pickers/internals'; -import { TimeValidationError } from '@mui/x-date-pickers/models'; +import { PickerValidDate, TimeValidationError } from '@mui/x-date-pickers/models'; import { validateTimeRange, TimeRangeComponentValidationProps, @@ -29,7 +29,10 @@ import { rangeValueManager } from '../../utils/valueManagers'; import type { UseMultiInputRangeFieldResponse } from './useMultiInputRangeField.types'; import { excludeProps } from './shared'; -export const useDefaultizedTimeRangeFieldProps = ( +export const useDefaultizedTimeRangeFieldProps = < + TDate extends PickerValidDate, + AdditionalProps extends {}, +>( props: UseMultiInputTimeRangeFieldProps, ): UseMultiInputTimeRangeFieldDefaultizedProps => { const utils = useUtils(); @@ -45,7 +48,10 @@ export const useDefaultizedTimeRangeFieldProps = ({ +export const useMultiInputTimeRangeField = < + TDate extends PickerValidDate, + TTextFieldSlotProps extends {}, +>({ sharedProps: inSharedProps, startTextFieldProps, unstableStartFieldRef, @@ -118,10 +124,7 @@ export const useMultiInputTimeRangeField = - > = { + const startFieldProps: UseTimeFieldComponentProps> = { error: !!validationError[0], ...startTextFieldProps, format, @@ -137,10 +140,7 @@ export const useMultiInputTimeRangeField = - > = { + const endFieldProps: UseTimeFieldComponentProps> = { error: !!validationError[1], ...endTextFieldProps, format, diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.tsx b/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.tsx index f947943079791..75b4ec220d76b 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.tsx @@ -9,6 +9,7 @@ import { ExportedBaseToolbarProps, DateOrTimeViewWithMeridiem, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { UseStaticRangePickerParams, UseStaticRangePickerProps, @@ -28,7 +29,7 @@ const PickerStaticLayout = styled(PickersLayout)(({ theme }) => ({ * - StaticDateRangePicker */ export const useStaticRangePicker = < - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseStaticRangePickerProps, >({ diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.types.ts b/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.types.ts index 51b5459780883..2ff34eabfa9ca 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.types.ts @@ -6,6 +6,7 @@ import { StaticOnlyPickerProps, DateOrTimeViewWithMeridiem, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { ExportedPickersLayoutSlots, ExportedPickersLayoutSlotProps, @@ -14,18 +15,22 @@ import { DateRange } from '../../../models'; import { UseRangePositionProps } from '../useRangePosition'; import { RangeFieldSection } from '../../models/fields'; -export interface UseStaticRangePickerSlots - extends ExportedPickersLayoutSlots, TDate, TView> {} +export interface UseStaticRangePickerSlots< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends ExportedPickersLayoutSlots, TDate, TView> {} -export interface UseStaticRangePickerSlotProps - extends ExportedPickersLayoutSlotProps, TDate, TView> { +export interface UseStaticRangePickerSlotProps< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends ExportedPickersLayoutSlotProps, TDate, TView> { toolbar?: ExportedBaseToolbarProps; } export interface StaticRangeOnlyPickerProps extends StaticOnlyPickerProps, UseRangePositionProps {} export interface UseStaticRangePickerProps< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TError, TExternalProps extends UseStaticRangePickerProps, @@ -44,7 +49,7 @@ export interface UseStaticRangePickerProps< } export interface UseStaticRangePickerParams< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseStaticRangePickerProps, > extends Pick< diff --git a/packages/x-date-pickers-pro/src/internals/models/dateRange.ts b/packages/x-date-pickers-pro/src/internals/models/dateRange.ts index 1a31e90846619..422d777db1251 100644 --- a/packages/x-date-pickers-pro/src/internals/models/dateRange.ts +++ b/packages/x-date-pickers-pro/src/internals/models/dateRange.ts @@ -4,13 +4,14 @@ import { MakeOptional, UseFieldInternalProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import type { DateRangeValidationError, DateRange } from '../../models'; import { RangeFieldSection } from './fields'; /** * Props used to validate a day value in range pickers. */ -export interface DayRangeValidationProps { +export interface DayRangeValidationProps { /** * Disable specific date. * @@ -35,7 +36,7 @@ export interface BaseRangeProps { disabled?: boolean; } -export interface UseDateRangeFieldProps +export interface UseDateRangeFieldProps extends MakeOptional< UseFieldInternalProps, TDate, RangeFieldSection, DateRangeValidationError>, 'format' @@ -44,7 +45,7 @@ export interface UseDateRangeFieldProps BaseDateValidationProps, BaseRangeProps {} -export type UseDateRangeFieldDefaultizedProps = DefaultizedProps< +export type UseDateRangeFieldDefaultizedProps = DefaultizedProps< UseDateRangeFieldProps, keyof BaseDateValidationProps | 'format' >; diff --git a/packages/x-date-pickers-pro/src/internals/models/dateTimeRange.ts b/packages/x-date-pickers-pro/src/internals/models/dateTimeRange.ts index 25903be03bd72..3ed96dab9e6bd 100644 --- a/packages/x-date-pickers-pro/src/internals/models/dateTimeRange.ts +++ b/packages/x-date-pickers-pro/src/internals/models/dateTimeRange.ts @@ -7,11 +7,12 @@ import { DateTimeValidationProps, DateOrTimeViewWithMeridiem, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { BaseRangeProps, DayRangeValidationProps } from './dateRange'; import { DateTimeRangeValidationError, DateRange } from '../../models'; import { RangeFieldSection } from './fields'; -export interface UseDateTimeRangeFieldProps +export interface UseDateTimeRangeFieldProps extends MakeOptional< UseFieldInternalProps< DateRange, @@ -33,7 +34,7 @@ export interface UseDateTimeRangeFieldProps ampm?: boolean; } -export type UseDateTimeRangeFieldDefaultizedProps = DefaultizedProps< +export type UseDateTimeRangeFieldDefaultizedProps = DefaultizedProps< UseDateTimeRangeFieldProps, keyof BaseDateValidationProps | 'format' | 'disableIgnoringDatePartForTimeValidation' >; diff --git a/packages/x-date-pickers-pro/src/internals/models/fields.ts b/packages/x-date-pickers-pro/src/internals/models/fields.ts index 2810560c95174..893c4484c6da9 100644 --- a/packages/x-date-pickers-pro/src/internals/models/fields.ts +++ b/packages/x-date-pickers-pro/src/internals/models/fields.ts @@ -1,7 +1,7 @@ import * as React from 'react'; import { SlotComponentProps } from '@mui/base/utils'; import { BaseFieldProps, FieldsTextFieldProps } from '@mui/x-date-pickers/internals'; -import { FieldSection, FieldRef } from '@mui/x-date-pickers/models'; +import { FieldSection, FieldRef, PickerValidDate } from '@mui/x-date-pickers/models'; export interface RangeFieldSection extends FieldSection { dateName: 'start' | 'end'; @@ -40,8 +40,12 @@ export interface MultiInputFieldRefs { * Props the multi input field can receive when used inside a picker. * Only contains what the MUI component are passing to the field, not what users can pass using the `props.slotProps.field`. */ -export interface BaseMultiInputFieldProps - extends BaseFieldProps, +export interface BaseMultiInputFieldProps< + TValue, + TDate extends PickerValidDate, + TSection extends FieldSection, + TError, +> extends BaseFieldProps, MultiInputFieldRefs { slots?: { root?: React.ElementType; diff --git a/packages/x-date-pickers-pro/src/internals/models/timeRange.ts b/packages/x-date-pickers-pro/src/internals/models/timeRange.ts index fa99290d503a3..9ec9db5c39232 100644 --- a/packages/x-date-pickers-pro/src/internals/models/timeRange.ts +++ b/packages/x-date-pickers-pro/src/internals/models/timeRange.ts @@ -5,11 +5,12 @@ import { MakeOptional, UseFieldInternalProps, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { TimeRangeValidationError, DateRange } from '../../models'; import { BaseRangeProps } from './dateRange'; import { RangeFieldSection } from './fields'; -export interface UseTimeRangeFieldProps +export interface UseTimeRangeFieldProps extends MakeOptional< UseFieldInternalProps, TDate, RangeFieldSection, TimeRangeValidationError>, 'format' @@ -24,7 +25,7 @@ export interface UseTimeRangeFieldProps ampm?: boolean; } -export type UseTimeRangeFieldDefaultizedProps = DefaultizedProps< +export type UseTimeRangeFieldDefaultizedProps = DefaultizedProps< UseTimeRangeFieldProps, keyof BaseTimeValidationProps | 'format' >; diff --git a/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.ts b/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.ts index 8470c59ccb44d..bc3eb99ca75cc 100644 --- a/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.ts +++ b/packages/x-date-pickers-pro/src/internals/utils/date-range-manager.ts @@ -1,8 +1,8 @@ -import { MuiPickersAdapter } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; import { mergeDateAndTime } from '@mui/x-date-pickers/internals'; import { DateRange, RangePosition } from '../../models'; -interface CalculateRangeChangeOptions { +interface CalculateRangeChangeOptions { utils: MuiPickersAdapter; range: DateRange; newDate: TDate | null; @@ -16,12 +16,12 @@ interface CalculateRangeChangeOptions { shouldMergeDateAndTime?: boolean; } -interface CalculateRangeChangeResponse { +interface CalculateRangeChangeResponse { nextSelection: RangePosition; newRange: DateRange; } -export function calculateRangeChange({ +export function calculateRangeChange({ utils, range, newDate: selectedDate, @@ -58,7 +58,7 @@ export function calculateRangeChange({ : { nextSelection: 'start', newRange: [start, selectedDate] }; } -export function calculateRangePreview( +export function calculateRangePreview( options: CalculateRangeChangeOptions, ): DateRange { if (options.newDate == null) { diff --git a/packages/x-date-pickers-pro/src/internals/utils/date-utils.ts b/packages/x-date-pickers-pro/src/internals/utils/date-utils.ts index e69cea142837b..1d35d15cf6676 100644 --- a/packages/x-date-pickers-pro/src/internals/utils/date-utils.ts +++ b/packages/x-date-pickers-pro/src/internals/utils/date-utils.ts @@ -1,14 +1,14 @@ -import { MuiPickersAdapter } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; import { DateRange, NonEmptyDateRange } from '../../models'; -export const isRangeValid = ( +export const isRangeValid = ( utils: MuiPickersAdapter, range: DateRange | null, ): range is NonEmptyDateRange => { return Boolean(range && range[0] && range[1] && !utils.isBefore(range[1], range[0])); }; -export const isWithinRange = ( +export const isWithinRange = ( utils: MuiPickersAdapter, day: TDate, range: DateRange | null, @@ -16,7 +16,7 @@ export const isWithinRange = ( return isRangeValid(utils, range) && utils.isWithinRange(day, range); }; -export const isStartOfRange = ( +export const isStartOfRange = ( utils: MuiPickersAdapter, day: TDate, range: DateRange | null, @@ -24,7 +24,7 @@ export const isStartOfRange = ( return isRangeValid(utils, range) && utils.isSameDay(day, range[0]!); }; -export const isEndOfRange = ( +export const isEndOfRange = ( utils: MuiPickersAdapter, day: TDate, range: DateRange | null, diff --git a/packages/x-date-pickers-pro/src/internals/utils/validation/validateDateRange.ts b/packages/x-date-pickers-pro/src/internals/utils/validation/validateDateRange.ts index 6609ced6e8bfb..c0304ff0b9de8 100644 --- a/packages/x-date-pickers-pro/src/internals/utils/validation/validateDateRange.ts +++ b/packages/x-date-pickers-pro/src/internals/utils/validation/validateDateRange.ts @@ -1,4 +1,4 @@ -import { TimezoneProps } from '@mui/x-date-pickers/models'; +import { PickerValidDate, TimezoneProps } from '@mui/x-date-pickers/models'; import { Validator, validateDate, @@ -9,7 +9,7 @@ import { isRangeValid } from '../date-utils'; import { DayRangeValidationProps } from '../../models'; import { DateRangeValidationError, DateRange } from '../../../models'; -export interface DateRangeComponentValidationProps +export interface DateRangeComponentValidationProps extends DayRangeValidationProps, Required>, DefaultizedProps {} diff --git a/packages/x-date-pickers-pro/src/internals/utils/validation/validateDateTimeRange.ts b/packages/x-date-pickers-pro/src/internals/utils/validation/validateDateTimeRange.ts index ec00ad04da6d9..2eae3041a2e4a 100644 --- a/packages/x-date-pickers-pro/src/internals/utils/validation/validateDateTimeRange.ts +++ b/packages/x-date-pickers-pro/src/internals/utils/validation/validateDateTimeRange.ts @@ -1,4 +1,4 @@ -import { TimezoneProps } from '@mui/x-date-pickers/models'; +import { PickerValidDate, TimezoneProps } from '@mui/x-date-pickers/models'; import { Validator, validateDateTime, @@ -10,7 +10,7 @@ import { isRangeValid } from '../date-utils'; import { DayRangeValidationProps } from '../../models/dateRange'; import { DateTimeRangeValidationError, DateRange } from '../../../models'; -export interface DateTimeRangeComponentValidationProps +export interface DateTimeRangeComponentValidationProps extends DayRangeValidationProps, TimeValidationProps, Required>, diff --git a/packages/x-date-pickers-pro/src/internals/utils/valueManagers.ts b/packages/x-date-pickers-pro/src/internals/utils/valueManagers.ts index daddcdee38e91..82649345b5d47 100644 --- a/packages/x-date-pickers-pro/src/internals/utils/valueManagers.ts +++ b/packages/x-date-pickers-pro/src/internals/utils/valueManagers.ts @@ -8,6 +8,7 @@ import { getTodayDate, getDefaultReferenceDate, } from '@mui/x-date-pickers/internals'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { splitDateRangeSections, removeLastSeparator } from './date-fields-utils'; import type { DateRangeValidationError, @@ -20,7 +21,7 @@ import { RangeFieldSection } from '../models/fields'; export type RangePickerValueManager< TValue = [any, any], - TDate = any, + TDate extends PickerValidDate = any, TError extends | DateRangeValidationError | TimeRangeValidationError diff --git a/packages/x-date-pickers-pro/src/models/range.ts b/packages/x-date-pickers-pro/src/models/range.ts index 3fefdb333b221..92bbff21e1d17 100644 --- a/packages/x-date-pickers-pro/src/models/range.ts +++ b/packages/x-date-pickers-pro/src/models/range.ts @@ -1,5 +1,7 @@ -export type DateRange = [TDate | null, TDate | null]; +import { PickerValidDate } from '@mui/x-date-pickers/models'; -export type NonEmptyDateRange = [TDate, TDate]; +export type DateRange = [TDate | null, TDate | null]; + +export type NonEmptyDateRange = [TDate, TDate]; export type RangePosition = 'start' | 'end'; diff --git a/packages/x-date-pickers-pro/src/themeAugmentation/props.d.ts b/packages/x-date-pickers-pro/src/themeAugmentation/props.d.ts index 00e1c345620b3..c43cf07e5baa0 100644 --- a/packages/x-date-pickers-pro/src/themeAugmentation/props.d.ts +++ b/packages/x-date-pickers-pro/src/themeAugmentation/props.d.ts @@ -1,8 +1,8 @@ +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { DateRangePickerDayProps } from '../DateRangePickerDay'; import { MultiInputDateRangeFieldProps } from '../MultiInputDateRangeField/MultiInputDateRangeField.types'; import { SingleInputDateRangeFieldProps } from '../SingleInputDateRangeField/SingleInputDateRangeField.types'; import { DateRangeCalendarProps } from '../DateRangeCalendar'; - import { DateRangePickerProps, DateRangePickerToolbarProps } from '../DateRangePicker'; import { DesktopDateRangePickerProps } from '../DesktopDateRangePicker'; import { MobileDateRangePickerProps } from '../MobileDateRangePicker'; @@ -18,32 +18,32 @@ import { ExportedDateTimeRangePickerTabsProps } from '../DateTimeRangePicker/Dat import { ExportedDateTimeRangePickerToolbarProps } from '../DateTimeRangePicker/DateTimeRangePickerToolbar'; export interface PickersProComponentsPropsList { - MuiDateRangeCalendar: DateRangeCalendarProps; - MuiDateRangePickerDay: DateRangePickerDayProps; + MuiDateRangeCalendar: DateRangeCalendarProps; + MuiDateRangePickerDay: DateRangePickerDayProps; MuiDateTimeRangePickerTabs: ExportedDateTimeRangePickerTabsProps; - MuiDateRangePickerToolbar: DateRangePickerToolbarProps; + MuiDateRangePickerToolbar: DateRangePickerToolbarProps; MuiDateTimeRangePickerToolbar: ExportedDateTimeRangePickerToolbarProps; // Multi input range fields - MuiMultiInputDateRangeField: MultiInputDateRangeFieldProps; - MuiMultiInputDateTimeRangeField: MultiInputDateTimeRangeFieldProps; - MuiMultiInputTimeRangeField: MultiInputTimeRangeFieldProps; + MuiMultiInputDateRangeField: MultiInputDateRangeFieldProps; + MuiMultiInputDateTimeRangeField: MultiInputDateTimeRangeFieldProps; + MuiMultiInputTimeRangeField: MultiInputTimeRangeFieldProps; // Single input range fields - MuiSingleInputDateRangeField: SingleInputDateRangeFieldProps; - MuiSingleInputDateTimeRangeField: SingleInputDateTimeRangeFieldProps; - MuiSingleInputTimeRangeField: SingleInputTimeRangeFieldProps; + MuiSingleInputDateRangeField: SingleInputDateRangeFieldProps; + MuiSingleInputDateTimeRangeField: SingleInputDateTimeRangeFieldProps; + MuiSingleInputTimeRangeField: SingleInputTimeRangeFieldProps; // Date Range Pickers - MuiDateRangePicker: DateRangePickerProps; - MuiDesktopDateRangePicker: DesktopDateRangePickerProps; - MuiMobileDateRangePicker: MobileDateRangePickerProps; - MuiStaticDateRangePicker: StaticDateRangePickerProps; + MuiDateRangePicker: DateRangePickerProps; + MuiDesktopDateRangePicker: DesktopDateRangePickerProps; + MuiMobileDateRangePicker: MobileDateRangePickerProps; + MuiStaticDateRangePicker: StaticDateRangePickerProps; // Date Time Range Pickers - MuiDateTimeRangePicker: DateTimeRangePickerProps; - MuiDesktopDateTimeRangePicker: DesktopDateTimeRangePickerProps; - MuiMobileDateTimeRangePicker: MobileDateTimeRangePickerProps; + MuiDateTimeRangePicker: DateTimeRangePickerProps; + MuiDesktopDateTimeRangePicker: DesktopDateTimeRangePickerProps; + MuiMobileDateTimeRangePicker: MobileDateTimeRangePickerProps; } declare module '@mui/material/styles' { diff --git a/packages/x-date-pickers/src/AdapterDateFnsBase/AdapterDateFnsBase.ts b/packages/x-date-pickers/src/AdapterDateFnsBase/AdapterDateFnsBase.ts index 2207845c9cf38..a24b3a69e7d14 100644 --- a/packages/x-date-pickers/src/AdapterDateFnsBase/AdapterDateFnsBase.ts +++ b/packages/x-date-pickers/src/AdapterDateFnsBase/AdapterDateFnsBase.ts @@ -117,6 +117,12 @@ type DateFnsAdapterBaseOptions = MakeRe longFormatters: Record<'p' | 'P', (token: string, formatLong: any) => string>; }; +declare module '@mui/x-date-pickers/models' { + interface PickerValidDateLookup { + 'date-fns': Date; + } +} + /** * Based on `@date-io/date-fns` * diff --git a/packages/x-date-pickers/src/AdapterDateFnsJalali/AdapterDateFnsJalali.ts b/packages/x-date-pickers/src/AdapterDateFnsJalali/AdapterDateFnsJalali.ts index c8526d7bfeaed..7b1e651d6c5d2 100644 --- a/packages/x-date-pickers/src/AdapterDateFnsJalali/AdapterDateFnsJalali.ts +++ b/packages/x-date-pickers/src/AdapterDateFnsJalali/AdapterDateFnsJalali.ts @@ -159,6 +159,12 @@ const NUMBER_SYMBOL_MAP = { '0': '۰', }; +declare module '@mui/x-date-pickers/models' { + interface PickerValidDateLookup { + 'date-fns-jalali': Date; + } +} + /** * Based on `@date-io/date-fns-jalali` * diff --git a/packages/x-date-pickers/src/AdapterDayjs/AdapterDayjs.ts b/packages/x-date-pickers/src/AdapterDayjs/AdapterDayjs.ts index 853b72d4edf1a..667b7eb3ea642 100644 --- a/packages/x-date-pickers/src/AdapterDayjs/AdapterDayjs.ts +++ b/packages/x-date-pickers/src/AdapterDayjs/AdapterDayjs.ts @@ -111,6 +111,12 @@ const MISSING_TIMEZONE_PLUGIN = [ const withLocale = (dayjs: any, locale?: string): Constructor => !locale ? dayjs : (...args) => dayjs(...args).locale(locale); +declare module '@mui/x-date-pickers/models' { + interface PickerValidDateLookup { + dayjs: Dayjs; + } +} + /** * Based on `@date-io/dayjs` * diff --git a/packages/x-date-pickers/src/AdapterLuxon/AdapterLuxon.ts b/packages/x-date-pickers/src/AdapterLuxon/AdapterLuxon.ts index ee8f9a56ac027..295db06c32f41 100644 --- a/packages/x-date-pickers/src/AdapterLuxon/AdapterLuxon.ts +++ b/packages/x-date-pickers/src/AdapterLuxon/AdapterLuxon.ts @@ -83,6 +83,12 @@ const defaultFormats: AdapterFormats = { keyboardDateTime24h: 'D T', }; +declare module '@mui/x-date-pickers/models' { + interface PickerValidDateLookup { + luxon: DateTime; + } +} + /** * Based on `@date-io/luxon` * diff --git a/packages/x-date-pickers/src/AdapterMoment/AdapterMoment.ts b/packages/x-date-pickers/src/AdapterMoment/AdapterMoment.ts index 0a1cca168e1d1..e7b610d466b65 100644 --- a/packages/x-date-pickers/src/AdapterMoment/AdapterMoment.ts +++ b/packages/x-date-pickers/src/AdapterMoment/AdapterMoment.ts @@ -88,6 +88,12 @@ const MISSING_TIMEZONE_PLUGIN = [ 'Find more information on https://mui.com/x/react-date-pickers/timezone/#moment-and-timezone', ].join('\n'); +declare module '@mui/x-date-pickers/models' { + interface PickerValidDateLookup { + moment: Moment; + } +} + /** * Based on `@date-io/moment` * diff --git a/packages/x-date-pickers/src/AdapterMomentHijri/AdapterMomentHijri.ts b/packages/x-date-pickers/src/AdapterMomentHijri/AdapterMomentHijri.ts index f11f166c6b104..a9f102f755b20 100644 --- a/packages/x-date-pickers/src/AdapterMomentHijri/AdapterMomentHijri.ts +++ b/packages/x-date-pickers/src/AdapterMomentHijri/AdapterMomentHijri.ts @@ -86,6 +86,12 @@ const NUMBER_SYMBOL_MAP = { '0': '٠', }; +declare module '@mui/x-date-pickers/models' { + interface PickerValidDateLookup { + 'moment-hijri': Moment; + } +} + /** * Based on `@date-io/hijri` * diff --git a/packages/x-date-pickers/src/AdapterMomentJalaali/AdapterMomentJalaali.ts b/packages/x-date-pickers/src/AdapterMomentJalaali/AdapterMomentJalaali.ts index ca6cc0ed5301b..3ec4415dcb04f 100644 --- a/packages/x-date-pickers/src/AdapterMomentJalaali/AdapterMomentJalaali.ts +++ b/packages/x-date-pickers/src/AdapterMomentJalaali/AdapterMomentJalaali.ts @@ -85,6 +85,12 @@ const NUMBER_SYMBOL_MAP = { '0': '۰', }; +declare module '@mui/x-date-pickers/models' { + interface PickerValidDateLookup { + 'moment-jalaali': Moment; + } +} + /** * Based on `@date-io/jalaali` * diff --git a/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx b/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx index 11d8feecdbccc..65371086ad17a 100644 --- a/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx +++ b/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx @@ -29,6 +29,7 @@ import { BaseDateValidationProps } from '../internals/models/validation'; import { useControlledValueWithTimezone } from '../internals/hooks/useValueWithTimezone'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { VIEW_HEIGHT } from '../internals/constants/dimensions'; +import { PickerValidDate } from '../models'; const useUtilityClasses = (ownerState: DateCalendarProps) => { const { classes } = ownerState; @@ -40,7 +41,7 @@ const useUtilityClasses = (ownerState: DateCalendarProps) => { return composeClasses(slots, getDateCalendarUtilityClass, classes); }; -function useDateCalendarDefaultizedProps( +function useDateCalendarDefaultizedProps( props: DateCalendarProps, name: string, ): DateCalendarDefaultizedProps { @@ -83,7 +84,7 @@ const DateCalendarViewTransitionContainer = styled(PickersFadeTransitionGroup, { overridesResolver: (props, styles) => styles.viewTransitionContainer, })<{ ownerState: DateCalendarProps }>({}); -type DateCalendarComponent = (( +type DateCalendarComponent = (( props: DateCalendarProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -98,7 +99,7 @@ type DateCalendarComponent = (( * * - [DateCalendar API](https://mui.com/x/api/date-pickers/date-calendar/) */ -export const DateCalendar = React.forwardRef(function DateCalendar( +export const DateCalendar = React.forwardRef(function DateCalendar( inProps: DateCalendarProps, ref: React.Ref, ) { @@ -428,7 +429,7 @@ DateCalendar.propTypes = { * The default selected value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker and text field are disabled. * @default false @@ -472,11 +473,11 @@ DateCalendar.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Months rendered per row. * @default 3 @@ -536,7 +537,7 @@ DateCalendar.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component displaying when passed `loading` true. * @returns {React.ReactNode} The node to render when loading. @@ -608,7 +609,7 @@ DateCalendar.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/DateCalendar/DateCalendar.types.ts b/packages/x-date-pickers/src/DateCalendar/DateCalendar.types.ts index b02d1ffc027b4..fec30c35f9302 100644 --- a/packages/x-date-pickers/src/DateCalendar/DateCalendar.types.ts +++ b/packages/x-date-pickers/src/DateCalendar/DateCalendar.types.ts @@ -17,12 +17,12 @@ import { DayValidationProps, } from '../internals/models/validation'; import { ExportedUseViewsOptions } from '../internals/hooks/useViews'; -import { DateView, TimezoneProps } from '../models'; +import { DateView, PickerValidDate, TimezoneProps } from '../models'; import { DefaultizedProps } from '../internals/models/helpers'; import { ExportedYearCalendarProps } from '../YearCalendar/YearCalendar.types'; import { ExportedMonthCalendarProps } from '../MonthCalendar/MonthCalendar.types'; -export interface DateCalendarSlots +export interface DateCalendarSlots extends PickersCalendarHeaderSlots, DayCalendarSlots { /** @@ -33,13 +33,13 @@ export interface DateCalendarSlots calendarHeader?: React.ElementType>; } -export interface DateCalendarSlotProps +export interface DateCalendarSlotProps extends PickersCalendarHeaderSlotProps, DayCalendarSlotProps { calendarHeader?: SlotComponentProps>; } -export interface ExportedDateCalendarProps +export interface ExportedDateCalendarProps extends ExportedDayCalendarProps, ExportedMonthCalendarProps, ExportedYearCalendarProps, @@ -83,7 +83,7 @@ export interface ExportedDateCalendarProps onMonthChange?: (month: TDate) => void; } -export interface DateCalendarProps +export interface DateCalendarProps extends ExportedDateCalendarProps, ExportedUseViewsOptions { /** @@ -119,7 +119,7 @@ export interface DateCalendarProps slotProps?: DateCalendarSlotProps; } -export type DateCalendarDefaultizedProps = DefaultizedProps< +export type DateCalendarDefaultizedProps = DefaultizedProps< DateCalendarProps, | 'views' | 'openTo' diff --git a/packages/x-date-pickers/src/DateCalendar/DayCalendar.tsx b/packages/x-date-pickers/src/DateCalendar/DayCalendar.tsx index 45b1a8fe727c3..e388c1590632b 100644 --- a/packages/x-date-pickers/src/DateCalendar/DayCalendar.tsx +++ b/packages/x-date-pickers/src/DateCalendar/DayCalendar.tsx @@ -26,10 +26,10 @@ import { import { useIsDateDisabled } from './useIsDateDisabled'; import { findClosestEnabledDate, getWeekdays } from '../internals/utils/date-utils'; import { DayCalendarClasses, getDayCalendarUtilityClass } from './dayCalendarClasses'; -import { TimezoneProps } from '../models'; +import { PickerValidDate, TimezoneProps } from '../models'; import { DefaultizedProps } from '../internals/models/helpers'; -export interface DayCalendarSlots { +export interface DayCalendarSlots { /** * Custom component for day. * Check the [PickersDay](https://mui.com/x/api/date-pickers/pickers-day/) component. @@ -38,7 +38,7 @@ export interface DayCalendarSlots { day?: React.ElementType>; } -export interface DayCalendarSlotProps { +export interface DayCalendarSlotProps { day?: SlotComponentProps< typeof PickersDay, {}, @@ -46,7 +46,8 @@ export interface DayCalendarSlotProps { >; } -export interface ExportedDayCalendarProps extends ExportedPickersDayProps { +export interface ExportedDayCalendarProps + extends ExportedPickersDayProps { /** * If `true`, calls `renderLoading` instead of rendering the day calendar. * Can be used to preload information and show it in calendar. @@ -78,7 +79,7 @@ export interface ExportedDayCalendarProps extends ExportedPickersDayProps fixedWeekNumber?: number; } -export interface DayCalendarProps +export interface DayCalendarProps extends ExportedDayCalendarProps, DayValidationProps, MonthValidationProps, @@ -232,7 +233,7 @@ const PickersCalendarWeek = styled('div', { justifyContent: 'center', }); -function WrappedDay({ +function WrappedDay({ parentProps, day, focusableDay, @@ -331,7 +332,7 @@ function WrappedDay({ /** * @ignore - do not document. */ -export function DayCalendar(inProps: DayCalendarProps) { +export function DayCalendar(inProps: DayCalendarProps) { const props = useThemeProps({ props: inProps, name: 'MuiDayCalendar' }); const utils = useUtils(); diff --git a/packages/x-date-pickers/src/DateCalendar/tests/validation.DateCalendar.test.tsx b/packages/x-date-pickers/src/DateCalendar/tests/validation.DateCalendar.test.tsx index 9940b97e3d9d4..74eaafe5cfaa3 100644 --- a/packages/x-date-pickers/src/DateCalendar/tests/validation.DateCalendar.test.tsx +++ b/packages/x-date-pickers/src/DateCalendar/tests/validation.DateCalendar.test.tsx @@ -2,9 +2,10 @@ import * as React from 'react'; import { expect } from 'chai'; import { screen, fireEvent } from '@mui-internal/test-utils'; import { DateCalendar, DateCalendarProps } from '@mui/x-date-pickers/DateCalendar'; +import { PickerValidDate } from '@mui/x-date-pickers/models'; import { createPickerRenderer, adapterToUse } from 'test/utils/pickers'; -function WrappedDateCalendar( +function WrappedDateCalendar( props: Omit, 'value' | 'onChange'> & { initialValue: TDate }, ) { const { initialValue, ...other } = props; diff --git a/packages/x-date-pickers/src/DateCalendar/useCalendarState.tsx b/packages/x-date-pickers/src/DateCalendar/useCalendarState.tsx index eebe2fede5ad9..5da5597f0f0c8 100644 --- a/packages/x-date-pickers/src/DateCalendar/useCalendarState.tsx +++ b/packages/x-date-pickers/src/DateCalendar/useCalendarState.tsx @@ -3,12 +3,12 @@ import useEventCallback from '@mui/utils/useEventCallback'; import { SlideDirection } from './PickersSlideTransition'; import { useIsDateDisabled } from './useIsDateDisabled'; import { useUtils } from '../internals/hooks/useUtils'; -import { MuiPickersAdapter, PickersTimezone } from '../models'; +import { MuiPickersAdapter, PickersTimezone, PickerValidDate } from '../models'; import { DateCalendarDefaultizedProps } from './DateCalendar.types'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { SECTION_TYPE_GRANULARITY } from '../internals/utils/getDefaultReferenceDate'; -interface CalendarState { +interface CalendarState { currentMonth: TDate; focusedDay: TDate | null; isMonthSwitchingAnimating: boolean; @@ -17,12 +17,12 @@ interface CalendarState { type ReducerAction = { type: TType } & TAdditional; -interface ChangeMonthPayload { +interface ChangeMonthPayload { direction: SlideDirection; newMonth: TDate; } -interface ChangeFocusedDayPayload { +interface ChangeFocusedDayPayload { focusedDay: TDate | null; /** * The update does not trigger month switching animation. @@ -32,7 +32,7 @@ interface ChangeFocusedDayPayload { } export const createCalendarStateReducer = - ( + ( reduceAnimations: boolean, disableSwitchToMonthOnDayFocus: boolean, utils: MuiPickersAdapter, @@ -93,7 +93,7 @@ export const createCalendarStateReducer = } }; -interface UseCalendarStateParams +interface UseCalendarStateParams extends Pick< DateCalendarDefaultizedProps, | 'value' @@ -110,7 +110,9 @@ interface UseCalendarStateParams timezone: PickersTimezone; } -export const useCalendarState = (params: UseCalendarStateParams) => { +export const useCalendarState = ( + params: UseCalendarStateParams, +) => { const { value, referenceDate: referenceDateProp, diff --git a/packages/x-date-pickers/src/DateCalendar/useIsDateDisabled.ts b/packages/x-date-pickers/src/DateCalendar/useIsDateDisabled.ts index 0375516f4e953..7fbde8e847724 100644 --- a/packages/x-date-pickers/src/DateCalendar/useIsDateDisabled.ts +++ b/packages/x-date-pickers/src/DateCalendar/useIsDateDisabled.ts @@ -4,8 +4,9 @@ import { validateDate, } from '../internals/utils/validation/validateDate'; import { useLocalizationContext } from '../internals/hooks/useUtils'; +import { PickerValidDate } from '../models'; -export const useIsDateDisabled = ({ +export const useIsDateDisabled = ({ shouldDisableDate, shouldDisableMonth, shouldDisableYear, diff --git a/packages/x-date-pickers/src/DateField/DateField.tsx b/packages/x-date-pickers/src/DateField/DateField.tsx index f654d9db925b1..cf4218512439d 100644 --- a/packages/x-date-pickers/src/DateField/DateField.tsx +++ b/packages/x-date-pickers/src/DateField/DateField.tsx @@ -8,8 +8,9 @@ import { DateFieldProps, DateFieldSlotProps } from './DateField.types'; import { useDateField } from './useDateField'; import { useClearableField } from '../hooks'; import { convertFieldResponseIntoMuiTextFieldProps } from '../internals/utils/convertFieldResponseIntoMuiTextFieldProps'; +import { PickerValidDate } from '../models'; -type DateFieldComponent = (( +type DateFieldComponent = (( props: DateFieldProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -23,7 +24,7 @@ type DateFieldComponent = (( * * - [DateField API](https://mui.com/x/api/date-pickers/date-field/) */ -const DateField = React.forwardRef(function DateField( +const DateField = React.forwardRef(function DateField( inProps: DateFieldProps, inRef: React.Ref, ) { @@ -95,7 +96,7 @@ DateField.propTypes = { /** * The default value. Use when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the component is disabled. * @default false @@ -182,11 +183,11 @@ DateField.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Name attribute of the `input` element. */ @@ -229,7 +230,7 @@ DateField.propTypes = { * For example, on time fields it will be used to determine the date to set. * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * If `true`, the label is displayed as required and the `input` element is required. * @default false @@ -341,7 +342,7 @@ DateField.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The variant to use. * @default 'outlined' diff --git a/packages/x-date-pickers/src/DateField/DateField.types.ts b/packages/x-date-pickers/src/DateField/DateField.types.ts index 2b358fd2cb153..51a00deb3a8ab 100644 --- a/packages/x-date-pickers/src/DateField/DateField.types.ts +++ b/packages/x-date-pickers/src/DateField/DateField.types.ts @@ -2,7 +2,7 @@ import * as React from 'react'; import { SlotComponentProps } from '@mui/base/utils'; import TextField from '@mui/material/TextField'; import { UseClearableFieldSlots, UseClearableFieldSlotProps } from '../hooks/useClearableField'; -import { DateValidationError, FieldSection } from '../models'; +import { DateValidationError, FieldSection, PickerValidDate } from '../models'; import { UseFieldInternalProps } from '../internals/hooks/useField'; import { DefaultizedProps, MakeOptional } from '../internals/models/helpers'; import { @@ -13,7 +13,7 @@ import { } from '../internals/models/validation'; import { FieldsTextFieldProps } from '../internals/models/fields'; -export interface UseDateFieldProps +export interface UseDateFieldProps extends MakeOptional< UseFieldInternalProps, 'format' @@ -23,18 +23,17 @@ export interface UseDateFieldProps YearValidationProps, BaseDateValidationProps {} -export type UseDateFieldDefaultizedProps = DefaultizedProps< +export type UseDateFieldDefaultizedProps = DefaultizedProps< UseDateFieldProps, keyof BaseDateValidationProps | 'format' >; -export type UseDateFieldComponentProps = Omit< - TChildProps, - keyof UseDateFieldProps -> & - UseDateFieldProps; +export type UseDateFieldComponentProps< + TDate extends PickerValidDate, + TChildProps extends {}, +> = Omit> & UseDateFieldProps; -export interface DateFieldProps +export interface DateFieldProps extends UseDateFieldComponentProps { /** * Overridable component slots. @@ -48,7 +47,7 @@ export interface DateFieldProps slotProps?: DateFieldSlotProps; } -export type DateFieldOwnerState = DateFieldProps; +export type DateFieldOwnerState = DateFieldProps; export interface DateFieldSlots extends UseClearableFieldSlots { /** @@ -59,6 +58,7 @@ export interface DateFieldSlots extends UseClearableFieldSlots { textField?: React.ElementType; } -export interface DateFieldSlotProps extends UseClearableFieldSlotProps { +export interface DateFieldSlotProps + extends UseClearableFieldSlotProps { textField?: SlotComponentProps>; } diff --git a/packages/x-date-pickers/src/DateField/useDateField.ts b/packages/x-date-pickers/src/DateField/useDateField.ts index 1a7e9c4795687..2d5b495c652d2 100644 --- a/packages/x-date-pickers/src/DateField/useDateField.ts +++ b/packages/x-date-pickers/src/DateField/useDateField.ts @@ -12,8 +12,9 @@ import { validateDate } from '../internals/utils/validation/validateDate'; import { applyDefaultDate } from '../internals/utils/date-utils'; import { useUtils, useDefaultDates } from '../internals/hooks/useUtils'; import { splitFieldInternalAndForwardedProps } from '../internals/utils/fields'; +import { PickerValidDate } from '../models'; -const useDefaultizedDateField = ( +const useDefaultizedDateField = ( props: UseDateFieldProps, ): AdditionalProps & UseDateFieldDefaultizedProps => { const utils = useUtils(); @@ -29,7 +30,7 @@ const useDefaultizedDateField = ( } as any; }; -export const useDateField = ( +export const useDateField = ( inProps: UseDateFieldComponentProps, ) => { const props = useDefaultizedDateField(inProps); diff --git a/packages/x-date-pickers/src/DatePicker/DatePicker.tsx b/packages/x-date-pickers/src/DatePicker/DatePicker.tsx index 31068c055fd4d..0a6ecc56822c7 100644 --- a/packages/x-date-pickers/src/DatePicker/DatePicker.tsx +++ b/packages/x-date-pickers/src/DatePicker/DatePicker.tsx @@ -7,8 +7,9 @@ import { DesktopDatePicker } from '../DesktopDatePicker'; import { MobileDatePicker } from '../MobileDatePicker'; import { DatePickerProps } from './DatePicker.types'; import { DEFAULT_DESKTOP_MODE_MEDIA_QUERY } from '../internals/utils/utils'; +import { PickerValidDate } from '../models'; -type DatePickerComponent = (( +type DatePickerComponent = (( props: DatePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -22,7 +23,7 @@ type DatePickerComponent = (( * * - [DatePicker API](https://mui.com/x/api/date-pickers/date-picker/) */ -const DatePicker = React.forwardRef(function DatePicker( +const DatePicker = React.forwardRef(function DatePicker( inProps: DatePickerProps, ref: React.Ref, ) { @@ -69,7 +70,7 @@ DatePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * CSS media query when `Mobile` mode will be changed to `Desktop`. * @default '@media (pointer: fine)' @@ -144,11 +145,11 @@ DatePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Months rendered per row. * @default 3 @@ -240,7 +241,7 @@ DatePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component displaying when passed `loading` true. * @returns {React.ReactNode} The node to render when loading. @@ -340,7 +341,7 @@ DatePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts b/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts index 9c3c09d712cea..a287263829adc 100644 --- a/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts +++ b/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts @@ -8,16 +8,17 @@ import { MobileDatePickerSlots, MobileDatePickerSlotProps, } from '../MobileDatePicker'; +import { PickerValidDate } from '../models'; -export interface DatePickerSlots +export interface DatePickerSlots extends DesktopDatePickerSlots, MobileDatePickerSlots {} -export interface DatePickerSlotProps +export interface DatePickerSlotProps extends DesktopDatePickerSlotProps, MobileDatePickerSlotProps {} -export interface DatePickerProps +export interface DatePickerProps extends DesktopDatePickerProps, MobileDatePickerProps { /** diff --git a/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx b/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx index 6ab7b05fbc5ee..aaaaeb64d01cc 100644 --- a/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx +++ b/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx @@ -6,14 +6,15 @@ import { unstable_composeClasses as composeClasses } from '@mui/utils'; import { PickersToolbar } from '../internals/components/PickersToolbar'; import { useLocaleText, useUtils } from '../internals/hooks/useUtils'; import { BaseToolbarProps, ExportedBaseToolbarProps } from '../internals/models/props/toolbar'; -import { DateView } from '../models'; +import { DateView, PickerValidDate } from '../models'; import { DatePickerToolbarClasses, getDatePickerToolbarUtilityClass, } from './datePickerToolbarClasses'; import { resolveDateFormat } from '../internals/utils/date-utils'; -export interface DatePickerToolbarProps extends BaseToolbarProps { +export interface DatePickerToolbarProps + extends BaseToolbarProps { classes?: Partial; sx?: SxProps; } @@ -46,7 +47,7 @@ const DatePickerToolbarTitle = styled(Typography, { }), })); -type DatePickerToolbarComponent = (( +type DatePickerToolbarComponent = (( props: DatePickerToolbarProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -60,10 +61,9 @@ type DatePickerToolbarComponent = (( * * - [DatePickerToolbar API](https://mui.com/x/api/date-pickers/date-picker-toolbar/) */ -export const DatePickerToolbar = React.forwardRef(function DatePickerToolbar( - inProps: DatePickerToolbarProps, - ref: React.Ref, -) { +export const DatePickerToolbar = React.forwardRef(function DatePickerToolbar< + TDate extends PickerValidDate, +>(inProps: DatePickerToolbarProps, ref: React.Ref) { const props = useThemeProps({ props: inProps, name: 'MuiDatePickerToolbar' }); const { value, @@ -148,7 +148,7 @@ DatePickerToolbar.propTypes = { * @default "––" */ toolbarPlaceholder: PropTypes.node, - value: PropTypes.any, + value: PropTypes.object, /** * Currently visible picker view. */ diff --git a/packages/x-date-pickers/src/DatePicker/shared.tsx b/packages/x-date-pickers/src/DatePicker/shared.tsx index f770435368dc4..6618e5b31c731 100644 --- a/packages/x-date-pickers/src/DatePicker/shared.tsx +++ b/packages/x-date-pickers/src/DatePicker/shared.tsx @@ -8,7 +8,7 @@ import { } from '../DateCalendar/DateCalendar.types'; import { useDefaultDates, useUtils } from '../internals/hooks/useUtils'; import { applyDefaultViewProps } from '../internals/utils/views'; -import { DateValidationError, DateView } from '../models'; +import { DateValidationError, DateView, PickerValidDate } from '../models'; import { BasePickerInputProps } from '../internals/models/props/basePickerProps'; import { applyDefaultDate } from '../internals/utils/date-utils'; import { BaseDateValidationProps } from '../internals/models/validation'; @@ -21,7 +21,8 @@ import { import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; import { DateViewRendererProps } from '../dateViewRenderers'; -export interface BaseDatePickerSlots extends DateCalendarSlots { +export interface BaseDatePickerSlots + extends DateCalendarSlots { /** * Custom component for the toolbar rendered above the views. * @default DatePickerToolbar @@ -29,11 +30,12 @@ export interface BaseDatePickerSlots extends DateCalendarSlots { toolbar?: React.JSXElementConstructor>; } -export interface BaseDatePickerSlotProps extends DateCalendarSlotProps { +export interface BaseDatePickerSlotProps + extends DateCalendarSlotProps { toolbar?: ExportedDatePickerToolbarProps; } -export interface BaseDatePickerProps +export interface BaseDatePickerProps extends BasePickerInputProps, ExportedDateCalendarProps { /** @@ -57,17 +59,17 @@ export interface BaseDatePickerProps } type UseDatePickerDefaultizedProps< - TDate, + TDate extends PickerValidDate, Props extends BaseDatePickerProps, > = LocalizedComponent< TDate, DefaultizedProps> >; -export function useDatePickerDefaultizedProps>( - props: Props, - name: string, -): UseDatePickerDefaultizedProps { +export function useDatePickerDefaultizedProps< + TDate extends PickerValidDate, + Props extends BaseDatePickerProps, +>(props: Props, name: string): UseDatePickerDefaultizedProps { const utils = useUtils(); const defaultDates = useDefaultDates(); const themeProps = useThemeProps({ diff --git a/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx b/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx index 21a90d5d8e238..118da3db5daf4 100644 --- a/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx +++ b/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx @@ -8,8 +8,9 @@ import { DateTimeFieldProps, DateTimeFieldSlotProps } from './DateTimeField.type import { useDateTimeField } from './useDateTimeField'; import { useClearableField } from '../hooks'; import { convertFieldResponseIntoMuiTextFieldProps } from '../internals/utils/convertFieldResponseIntoMuiTextFieldProps'; +import { PickerValidDate } from '../models'; -type DateTimeFieldComponent = (( +type DateTimeFieldComponent = (( props: DateTimeFieldProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -23,7 +24,7 @@ type DateTimeFieldComponent = (( * * - [DateTimeField API](https://mui.com/x/api/date-pickers/date-time-field/) */ -const DateTimeField = React.forwardRef(function DateTimeField( +const DateTimeField = React.forwardRef(function DateTimeField( inProps: DateTimeFieldProps, inRef: React.Ref, ) { @@ -100,7 +101,7 @@ DateTimeField.propTypes = { /** * The default value. Use when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the component is disabled. * @default false @@ -192,29 +193,29 @@ DateTimeField.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Maximal selectable moment of time with binding to date, to set max time in each day use `maxTime`. */ - maxDateTime: PropTypes.any, + maxDateTime: PropTypes.object, /** * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Minimal selectable moment of time with binding to date, to set min time in each day use `minTime`. */ - minDateTime: PropTypes.any, + minDateTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -262,7 +263,7 @@ DateTimeField.propTypes = { * For example, on time fields it will be used to determine the date to set. * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * If `true`, the label is displayed as required and the `input` element is required. * @default false @@ -382,7 +383,7 @@ DateTimeField.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The variant to use. * @default 'outlined' diff --git a/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts b/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts index 98e0973d76514..984e6cf62b910 100644 --- a/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts +++ b/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts @@ -1,7 +1,7 @@ import * as React from 'react'; import { SlotComponentProps } from '@mui/base/utils'; import TextField from '@mui/material/TextField'; -import { DateTimeValidationError, FieldSection } from '../models'; +import { DateTimeValidationError, FieldSection, PickerValidDate } from '../models'; import { UseFieldInternalProps } from '../internals/hooks/useField'; import { DefaultizedProps, MakeOptional } from '../internals/models/helpers'; import { @@ -16,7 +16,7 @@ import { import { FieldsTextFieldProps } from '../internals/models/fields'; import { UseClearableFieldSlots, UseClearableFieldSlotProps } from '../hooks/useClearableField'; -export interface UseDateTimeFieldProps +export interface UseDateTimeFieldProps extends MakeOptional< UseFieldInternalProps, 'format' @@ -35,18 +35,17 @@ export interface UseDateTimeFieldProps ampm?: boolean; } -export type UseDateTimeFieldDefaultizedProps = DefaultizedProps< +export type UseDateTimeFieldDefaultizedProps = DefaultizedProps< UseDateTimeFieldProps, keyof BaseDateValidationProps | keyof BaseTimeValidationProps | 'format' >; -export type UseDateTimeFieldComponentProps = Omit< - TChildProps, - keyof UseDateTimeFieldProps -> & - UseDateTimeFieldProps; +export type UseDateTimeFieldComponentProps< + TDate extends PickerValidDate, + TChildProps extends {}, +> = Omit> & UseDateTimeFieldProps; -export interface DateTimeFieldProps +export interface DateTimeFieldProps extends UseDateTimeFieldComponentProps { /** * Overridable component slots. @@ -60,7 +59,7 @@ export interface DateTimeFieldProps slotProps?: DateTimeFieldSlotProps; } -export type DateTimeFieldOwnerState = DateTimeFieldProps; +export type DateTimeFieldOwnerState = DateTimeFieldProps; export interface DateTimeFieldSlots extends UseClearableFieldSlots { /** @@ -71,6 +70,7 @@ export interface DateTimeFieldSlots extends UseClearableFieldSlots { textField?: React.ElementType; } -export interface DateTimeFieldSlotProps extends UseClearableFieldSlotProps { +export interface DateTimeFieldSlotProps + extends UseClearableFieldSlotProps { textField?: SlotComponentProps>; } diff --git a/packages/x-date-pickers/src/DateTimeField/useDateTimeField.ts b/packages/x-date-pickers/src/DateTimeField/useDateTimeField.ts index 7e8236f12b3ab..021ea1cc3baa8 100644 --- a/packages/x-date-pickers/src/DateTimeField/useDateTimeField.ts +++ b/packages/x-date-pickers/src/DateTimeField/useDateTimeField.ts @@ -12,8 +12,9 @@ import { validateDateTime } from '../internals/utils/validation/validateDateTime import { applyDefaultDate } from '../internals/utils/date-utils'; import { useUtils, useDefaultDates } from '../internals/hooks/useUtils'; import { splitFieldInternalAndForwardedProps } from '../internals/utils/fields'; +import { PickerValidDate } from '../models'; -const useDefaultizedDateTimeField = ( +const useDefaultizedDateTimeField = ( props: UseDateTimeFieldProps, ): AdditionalProps & UseDateTimeFieldDefaultizedProps => { const utils = useUtils(); @@ -37,7 +38,7 @@ const useDefaultizedDateTimeField = ( } as any; }; -export const useDateTimeField = ( +export const useDateTimeField = ( inProps: UseDateTimeFieldComponentProps, ) => { const props = useDefaultizedDateTimeField(inProps); diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx index d00a9598a5756..f8a709895ef37 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx @@ -7,8 +7,9 @@ import { DesktopDateTimePicker } from '../DesktopDateTimePicker'; import { MobileDateTimePicker, MobileDateTimePickerProps } from '../MobileDateTimePicker'; import { DateTimePickerProps } from './DateTimePicker.types'; import { DEFAULT_DESKTOP_MODE_MEDIA_QUERY } from '../internals/utils/utils'; +import { PickerValidDate } from '../models'; -type DateTimePickerComponent = (( +type DateTimePickerComponent = (( props: DateTimePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -22,7 +23,7 @@ type DateTimePickerComponent = (( * * - [DateTimePicker API](https://mui.com/x/api/date-pickers/date-time-picker/) */ -const DateTimePicker = React.forwardRef(function DateTimePicker( +const DateTimePicker = React.forwardRef(function DateTimePicker( inProps: DateTimePickerProps, ref: React.Ref, ) { @@ -79,7 +80,7 @@ DateTimePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * CSS media query when `Mobile` mode will be changed to `Desktop`. * @default '@media (pointer: fine)' @@ -159,29 +160,29 @@ DateTimePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Maximal selectable moment of time with binding to date, to set max time in each day use `maxTime`. */ - maxDateTime: PropTypes.any, + maxDateTime: PropTypes.object, /** * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Minimal selectable moment of time with binding to date, to set min time in each day use `minTime`. */ - minDateTime: PropTypes.any, + minDateTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -278,7 +279,7 @@ DateTimePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component displaying when passed `loading` true. * @returns {React.ReactNode} The node to render when loading. @@ -407,7 +408,7 @@ DateTimePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts index 11c592b43e4fe..261c0907f258e 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts @@ -9,16 +9,17 @@ import { MobileDateTimePickerSlots, MobileDateTimePickerSlotProps, } from '../MobileDateTimePicker'; +import { PickerValidDate } from '../models'; -export interface DateTimePickerSlots +export interface DateTimePickerSlots extends DesktopDateTimePickerSlots, MobileDateTimePickerSlots {} -export interface DateTimePickerSlotProps +export interface DateTimePickerSlotProps extends DesktopDateTimePickerSlotProps, MobileDateTimePickerSlotProps {} -export interface DateTimePickerProps +export interface DateTimePickerProps extends DesktopDateTimePickerProps, Omit, 'views'> { /** diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx b/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx index d817ba20003a7..b622fa791f990 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx @@ -20,13 +20,14 @@ import { formatMeridiem } from '../internals/utils/date-utils'; import { MakeOptional } from '../internals/models/helpers'; import { pickersToolbarTextClasses } from '../internals/components/pickersToolbarTextClasses'; import { pickersToolbarClasses } from '../internals'; +import { PickerValidDate } from '../models'; export interface ExportedDateTimePickerToolbarProps extends ExportedBaseToolbarProps { ampm?: boolean; ampmInClock?: boolean; } -export interface DateTimePickerToolbarProps +export interface DateTimePickerToolbarProps extends ExportedDateTimePickerToolbarProps, MakeOptional, 'view'> { /** @@ -209,7 +210,9 @@ const DateTimePickerToolbarAmPmSelection = styled('div', { * * - [DateTimePickerToolbar API](https://mui.com/x/api/date-pickers/date-time-picker-toolbar/) */ -function DateTimePickerToolbar(inProps: DateTimePickerToolbarProps) { +function DateTimePickerToolbar( + inProps: DateTimePickerToolbarProps, +) { const props = useThemeProps({ props: inProps, name: 'MuiDateTimePickerToolbar' }); const { ampm, @@ -425,7 +428,7 @@ DateTimePickerToolbar.propTypes = { */ toolbarTitle: PropTypes.node, toolbarVariant: PropTypes.oneOf(['desktop', 'mobile']), - value: PropTypes.any, + value: PropTypes.object, /** * Currently visible picker view. */ diff --git a/packages/x-date-pickers/src/DateTimePicker/shared.tsx b/packages/x-date-pickers/src/DateTimePicker/shared.tsx index ff7ef45d18728..feb1531a67877 100644 --- a/packages/x-date-pickers/src/DateTimePicker/shared.tsx +++ b/packages/x-date-pickers/src/DateTimePicker/shared.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { useThemeProps } from '@mui/material/styles'; import { DefaultizedProps } from '../internals/models/helpers'; -import { DateTimeValidationError } from '../models'; +import { DateTimeValidationError, PickerValidDate } from '../models'; import { useDefaultDates, useUtils } from '../internals/hooks/useUtils'; import { DateCalendarSlots, @@ -34,7 +34,9 @@ import { applyDefaultViewProps } from '../internals/utils/views'; import { BaseClockProps, ExportedBaseClockProps } from '../internals/models/props/clock'; import { DateOrTimeViewWithMeridiem, TimeViewWithMeridiem } from '../internals/models'; -export interface BaseDateTimePickerSlots extends DateCalendarSlots, TimeClockSlots { +export interface BaseDateTimePickerSlots + extends DateCalendarSlots, + TimeClockSlots { /** * Tabs enabling toggling between date and time pickers. * @default DateTimePickerTabs @@ -47,7 +49,7 @@ export interface BaseDateTimePickerSlots extends DateCalendarSlots toolbar?: React.JSXElementConstructor>; } -export interface BaseDateTimePickerSlotProps +export interface BaseDateTimePickerSlotProps extends DateCalendarSlotProps, TimeClockSlotProps { /** @@ -60,8 +62,10 @@ export interface BaseDateTimePickerSlotProps toolbar?: ExportedDateTimePickerToolbarProps; } -export interface BaseDateTimePickerProps - extends BasePickerInputProps, +export interface BaseDateTimePickerProps< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends BasePickerInputProps, Omit, 'onViewChange'>, ExportedBaseClockProps, DateTimeValidationProps { @@ -97,7 +101,7 @@ export interface BaseDateTimePickerProps, > = LocalizedComponent< @@ -114,7 +118,7 @@ type UseDateTimePickerDefaultizedProps< >; export function useDateTimePickerDefaultizedProps< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, Props extends BaseDateTimePickerProps, >(props: Props, name: string): UseDateTimePickerDefaultizedProps { diff --git a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx index c338f20d131bc..dcf4c673fc86e 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx @@ -7,7 +7,7 @@ import { DesktopDatePickerProps } from './DesktopDatePicker.types'; import { useDatePickerDefaultizedProps } from '../DatePicker/shared'; import { useLocaleText, useUtils } from '../internals/hooks/useUtils'; import { validateDate } from '../internals/utils/validation/validateDate'; -import { DateView } from '../models'; +import { DateView, PickerValidDate } from '../models'; import { useDesktopPicker } from '../internals/hooks/useDesktopPicker'; import { CalendarIcon } from '../icons'; import { DateField } from '../DateField'; @@ -16,7 +16,7 @@ import { renderDateViewCalendar } from '../dateViewRenderers'; import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; import { resolveDateFormat } from '../internals/utils/date-utils'; -type DesktopDatePickerComponent = (( +type DesktopDatePickerComponent = (( props: DesktopDatePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -30,10 +30,9 @@ type DesktopDatePickerComponent = (( * * - [DesktopDatePicker API](https://mui.com/x/api/date-pickers/desktop-date-picker/) */ -const DesktopDatePicker = React.forwardRef(function DesktopDatePicker( - inProps: DesktopDatePickerProps, - ref: React.Ref, -) { +const DesktopDatePicker = React.forwardRef(function DesktopDatePicker< + TDate extends PickerValidDate, +>(inProps: DesktopDatePickerProps, ref: React.Ref) { const localeText = useLocaleText(); const utils = useUtils(); @@ -116,7 +115,7 @@ DesktopDatePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker and text field are disabled. * @default false @@ -185,11 +184,11 @@ DesktopDatePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Months rendered per row. * @default 3 @@ -281,7 +280,7 @@ DesktopDatePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component displaying when passed `loading` true. * @returns {React.ReactNode} The node to render when loading. @@ -381,7 +380,7 @@ DesktopDatePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.types.ts b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.types.ts index 8c423832fa0da..ef33cb389df47 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.types.ts +++ b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.types.ts @@ -9,17 +9,17 @@ import { BaseDatePickerSlotProps, } from '../DatePicker/shared'; import { MakeOptional } from '../internals/models/helpers'; -import { DateView } from '../models'; +import { DateView, PickerValidDate } from '../models'; -export interface DesktopDatePickerSlots +export interface DesktopDatePickerSlots extends BaseDatePickerSlots, MakeOptional, 'field' | 'openPickerIcon'> {} -export interface DesktopDatePickerSlotProps +export interface DesktopDatePickerSlotProps extends BaseDatePickerSlotProps, ExportedUseDesktopPickerSlotProps {} -export interface DesktopDatePickerProps +export interface DesktopDatePickerProps extends BaseDatePickerProps, DesktopOnlyPickerProps { /** diff --git a/packages/x-date-pickers/src/DesktopDatePicker/tests/DesktopDatePicker.test.tsx b/packages/x-date-pickers/src/DesktopDatePicker/tests/DesktopDatePicker.test.tsx index 5f89b74ea0290..7c64c8832c42a 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/tests/DesktopDatePicker.test.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/tests/DesktopDatePicker.test.tsx @@ -307,15 +307,6 @@ describe('', () => { expect(screen.getByLabelText('Next month')).not.to.have.attribute('disabled'); }); - - it('should allow to navigate to previous and next month if props.minDate == null', () => { - render(); - - openPicker({ type: 'date', variant: 'desktop' }); - - expect(screen.getByLabelText('Previous month')).not.to.have.attribute('disabled'); - expect(screen.getByLabelText('Next month')).not.to.have.attribute('disabled'); - }); }); describe('Validation', () => { diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx index 64775b786702f..dd39ba02e7794 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx @@ -20,8 +20,9 @@ import { resolveTimeViewsResponse, } from '../internals/utils/date-time-utils'; import { PickersActionBarAction } from '../PickersActionBar'; +import { PickerValidDate } from '../models'; -type DesktopDateTimePickerComponent = (( +type DesktopDateTimePickerComponent = (( props: DesktopDateTimePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -35,10 +36,9 @@ type DesktopDateTimePickerComponent = (( * * - [DesktopDateTimePicker API](https://mui.com/x/api/date-pickers/desktop-date-time-picker/) */ -const DesktopDateTimePicker = React.forwardRef(function DesktopDateTimePicker( - inProps: DesktopDateTimePickerProps, - ref: React.Ref, -) { +const DesktopDateTimePicker = React.forwardRef(function DesktopDateTimePicker< + TDate extends PickerValidDate, +>(inProps: DesktopDateTimePickerProps, ref: React.Ref) { const localeText = useLocaleText(); const utils = useUtils(); @@ -175,7 +175,7 @@ DesktopDateTimePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker and text field are disabled. * @default false @@ -249,29 +249,29 @@ DesktopDateTimePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Maximal selectable moment of time with binding to date, to set max time in each day use `maxTime`. */ - maxDateTime: PropTypes.any, + maxDateTime: PropTypes.object, /** * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Minimal selectable moment of time with binding to date, to set min time in each day use `minTime`. */ - minDateTime: PropTypes.any, + minDateTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -368,7 +368,7 @@ DesktopDateTimePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component displaying when passed `loading` true. * @returns {React.ReactNode} The node to render when loading. @@ -497,7 +497,7 @@ DesktopDateTimePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.types.ts b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.types.ts index d36ce2b031455..4848a1477317f 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.types.ts +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.types.ts @@ -9,7 +9,7 @@ import { BaseDateTimePickerSlotProps, } from '../DateTimePicker/shared'; import { MakeOptional } from '../internals/models/helpers'; -import { DateOrTimeView } from '../models'; +import { DateOrTimeView, PickerValidDate } from '../models'; import { DesktopOnlyTimePickerProps } from '../internals/models/props/clock'; import { DateOrTimeViewWithMeridiem } from '../internals/models'; import { @@ -18,7 +18,7 @@ import { } from '../MultiSectionDigitalClock'; import { DigitalClockSlots, DigitalClockSlotProps } from '../DigitalClock'; -export interface DesktopDateTimePickerSlots +export interface DesktopDateTimePickerSlots extends BaseDateTimePickerSlots, MakeOptional< UseDesktopPickerSlots, @@ -27,13 +27,13 @@ export interface DesktopDateTimePickerSlots DigitalClockSlots, MultiSectionDigitalClockSlots {} -export interface DesktopDateTimePickerSlotProps +export interface DesktopDateTimePickerSlotProps extends BaseDateTimePickerSlotProps, ExportedUseDesktopPickerSlotProps, DigitalClockSlotProps, MultiSectionDigitalClockSlotProps {} -export interface DesktopDateTimePickerProps +export interface DesktopDateTimePickerProps extends BaseDateTimePickerProps, DesktopOnlyPickerProps, DesktopOnlyTimePickerProps { diff --git a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx index de810cb47552b..659c364afb4e9 100644 --- a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx @@ -20,9 +20,9 @@ import { PickersActionBarAction } from '../PickersActionBar'; import { TimeViewWithMeridiem } from '../internals/models'; import { resolveTimeFormat } from '../internals/utils/time-utils'; import { resolveTimeViewsResponse } from '../internals/utils/date-time-utils'; -import { TimeView } from '../models/views'; +import { TimeView, PickerValidDate } from '../models'; -type DesktopTimePickerComponent = (( +type DesktopTimePickerComponent = (( props: DesktopTimePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -36,10 +36,9 @@ type DesktopTimePickerComponent = (( * * - [DesktopTimePicker API](https://mui.com/x/api/date-pickers/desktop-time-picker/) */ -const DesktopTimePicker = React.forwardRef(function DesktopTimePicker( - inProps: DesktopTimePickerProps, - ref: React.Ref, -) { +const DesktopTimePicker = React.forwardRef(function DesktopTimePicker< + TDate extends PickerValidDate, +>(inProps: DesktopTimePickerProps, ref: React.Ref) { const localeText = useLocaleText(); const utils = useUtils(); @@ -157,7 +156,7 @@ DesktopTimePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker and text field are disabled. * @default false @@ -211,12 +210,12 @@ DesktopTimePicker.propTypes = { * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -296,7 +295,7 @@ DesktopTimePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * The currently selected sections. * This prop accept four formats: @@ -384,7 +383,7 @@ DesktopTimePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.types.ts b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.types.ts index 6f3735460d58e..ec9a50c0c2c48 100644 --- a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.types.ts +++ b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.types.ts @@ -16,21 +16,21 @@ import { MultiSectionDigitalClockSlots, MultiSectionDigitalClockSlotProps, } from '../MultiSectionDigitalClock'; -import { TimeView } from '../models'; +import { PickerValidDate, TimeView } from '../models'; -export interface DesktopTimePickerSlots +export interface DesktopTimePickerSlots extends BaseTimePickerSlots, MakeOptional, 'field' | 'openPickerIcon'>, DigitalClockSlots, MultiSectionDigitalClockSlots {} -export interface DesktopTimePickerSlotProps +export interface DesktopTimePickerSlotProps extends BaseTimePickerSlotProps, ExportedUseDesktopPickerSlotProps, DigitalClockSlotProps, MultiSectionDigitalClockSlotProps {} -export interface DesktopTimePickerProps +export interface DesktopTimePickerProps extends BaseTimePickerProps, DesktopOnlyPickerProps, DesktopOnlyTimePickerProps { diff --git a/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx b/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx index 94fcdb8d9f895..e3824be369071 100644 --- a/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx +++ b/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx @@ -14,7 +14,7 @@ import { PickerViewRoot } from '../internals/components/PickerViewRoot'; import { getDigitalClockUtilityClass } from './digitalClockClasses'; import { DigitalClockProps } from './DigitalClock.types'; import { useViews } from '../internals/hooks/useViews'; -import { TimeView } from '../models'; +import { PickerValidDate, TimeView } from '../models'; import { DIGITAL_CLOCK_VIEW_HEIGHT } from '../internals/constants/dimensions'; import { useControlledValueWithTimezone } from '../internals/hooks/useValueWithTimezone'; import { singleItemValueManager } from '../internals/utils/valueManagers'; @@ -81,7 +81,7 @@ const DigitalClockItem = styled(MenuItem, { }, })); -type DigitalClockComponent = (( +type DigitalClockComponent = (( props: DigitalClockProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -95,7 +95,7 @@ type DigitalClockComponent = (( * * - [DigitalClock API](https://mui.com/x/api/date-pickers/digital-clock/) */ -export const DigitalClock = React.forwardRef(function DigitalClock( +export const DigitalClock = React.forwardRef(function DigitalClock( inProps: DigitalClockProps, ref: React.Ref, ) { @@ -352,7 +352,7 @@ DigitalClock.propTypes = { * The default selected value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker views and text field are disabled. * @default false @@ -381,12 +381,12 @@ DigitalClock.propTypes = { * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -429,7 +429,7 @@ DigitalClock.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid time using the validation props, except callbacks such as `shouldDisableTime`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Disable specific time. * @template TDate @@ -479,7 +479,7 @@ DigitalClock.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/DigitalClock/DigitalClock.types.ts b/packages/x-date-pickers/src/DigitalClock/DigitalClock.types.ts index 35b88400f1a92..7b98c84670d60 100644 --- a/packages/x-date-pickers/src/DigitalClock/DigitalClock.types.ts +++ b/packages/x-date-pickers/src/DigitalClock/DigitalClock.types.ts @@ -1,3 +1,4 @@ +import * as React from 'react'; import { SlotComponentProps } from '@mui/base/utils'; import MenuItem from '@mui/material/MenuItem'; import { DigitalClockClasses } from './digitalClockClasses'; @@ -6,9 +7,9 @@ import { DigitalClockOnlyProps, ExportedBaseClockProps, } from '../internals/models/props/clock'; -import { TimeView } from '../models'; +import { PickerValidDate, TimeView } from '../models'; -export interface ExportedDigitalClockProps +export interface ExportedDigitalClockProps extends ExportedBaseClockProps, DigitalClockOnlyProps {} @@ -24,7 +25,7 @@ export interface DigitalClockSlotProps { digitalClockItem?: SlotComponentProps>; } -export interface DigitalClockProps +export interface DigitalClockProps extends ExportedDigitalClockProps, BaseClockProps> { /** diff --git a/packages/x-date-pickers/src/LocalizationProvider/LocalizationProvider.tsx b/packages/x-date-pickers/src/LocalizationProvider/LocalizationProvider.tsx index 956bf452ccb75..e7f74202614ad 100644 --- a/packages/x-date-pickers/src/LocalizationProvider/LocalizationProvider.tsx +++ b/packages/x-date-pickers/src/LocalizationProvider/LocalizationProvider.tsx @@ -1,10 +1,10 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useThemeProps } from '@mui/material/styles'; -import { AdapterFormats, MuiPickersAdapter } from '../models'; +import { AdapterFormats, MuiPickersAdapter, PickerValidDate } from '../models'; import { PickersInputLocaleText } from '../locales'; -export interface MuiPickersAdapterContextValue { +export interface MuiPickersAdapterContextValue { defaultDates: { minDate: TDate; maxDate: TDate; @@ -14,7 +14,7 @@ export interface MuiPickersAdapterContextValue { localeText: PickersInputLocaleText | undefined; } -export type MuiPickersAdapterContextNullableValue = { +export type MuiPickersAdapterContextNullableValue = { [K in keyof MuiPickersAdapterContextValue]: MuiPickersAdapterContextValue[K] | null; }; @@ -25,7 +25,7 @@ if (process.env.NODE_ENV !== 'production') { MuiPickersAdapterContext.displayName = 'MuiPickersAdapterContext'; } -export interface LocalizationProviderProps { +export interface LocalizationProviderProps { children?: React.ReactNode; /** * Date library adapter class function. @@ -51,7 +51,7 @@ export interface LocalizationProviderProps { localeText?: PickersInputLocaleText; } -type LocalizationProviderComponent = (( +type LocalizationProviderComponent = (( props: LocalizationProviderProps, ) => React.JSX.Element) & { propTypes?: any }; @@ -67,9 +67,10 @@ type LocalizationProviderComponent = (( * * - [LocalizationProvider API](https://mui.com/x/api/date-pickers/localization-provider/) */ -export const LocalizationProvider = function LocalizationProvider( - inProps: LocalizationProviderProps, -) { +export const LocalizationProvider = function LocalizationProvider< + TDate extends PickerValidDate, + TLocale, +>(inProps: LocalizationProviderProps) { const { localeText: inLocaleText, ...otherInProps } = inProps; const { utils: parentUtils, localeText: parentLocaleText } = React.useContext( diff --git a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx index 33d54782889fa..6453a80e40a31 100644 --- a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx +++ b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx @@ -8,14 +8,14 @@ import { useDatePickerDefaultizedProps } from '../DatePicker/shared'; import { useUtils, useLocaleText } from '../internals/hooks/useUtils'; import { validateDate } from '../internals/utils/validation/validateDate'; import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; -import { DateView } from '../models'; +import { DateView, PickerValidDate } from '../models'; import { DateField } from '../DateField'; import { extractValidationProps } from '../internals/utils/validation/extractValidationProps'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { renderDateViewCalendar } from '../dateViewRenderers'; import { resolveDateFormat } from '../internals/utils/date-utils'; -type MobileDatePickerComponent = (( +type MobileDatePickerComponent = (( props: MobileDatePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -29,7 +29,7 @@ type MobileDatePickerComponent = (( * * - [MobileDatePicker API](https://mui.com/x/api/date-pickers/mobile-date-picker/) */ -const MobileDatePicker = React.forwardRef(function MobileDatePicker( +const MobileDatePicker = React.forwardRef(function MobileDatePicker( inProps: MobileDatePickerProps, ref: React.Ref, ) { @@ -113,7 +113,7 @@ MobileDatePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker and text field are disabled. * @default false @@ -182,11 +182,11 @@ MobileDatePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Months rendered per row. * @default 3 @@ -278,7 +278,7 @@ MobileDatePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component displaying when passed `loading` true. * @returns {React.ReactNode} The node to render when loading. @@ -378,7 +378,7 @@ MobileDatePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.types.ts b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.types.ts index 31fb295dbfd76..d6371b06907e5 100644 --- a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.types.ts +++ b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.types.ts @@ -9,17 +9,17 @@ import { BaseDatePickerSlotProps, } from '../DatePicker/shared'; import { MakeOptional } from '../internals/models/helpers'; -import { DateView } from '../models'; +import { DateView, PickerValidDate } from '../models'; -export interface MobileDatePickerSlots +export interface MobileDatePickerSlots extends BaseDatePickerSlots, MakeOptional, 'field'> {} -export interface MobileDatePickerSlotProps +export interface MobileDatePickerSlotProps extends BaseDatePickerSlotProps, ExportedUseMobilePickerSlotProps {} -export interface MobileDatePickerProps +export interface MobileDatePickerProps extends BaseDatePickerProps, MobileOnlyPickerProps { /** diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx index 4718f0832e3aa..3d4ec9a943da0 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx @@ -9,14 +9,14 @@ import { useDateTimePickerDefaultizedProps } from '../DateTimePicker/shared'; import { useLocaleText, useUtils } from '../internals/hooks/useUtils'; import { validateDateTime } from '../internals/utils/validation/validateDateTime'; import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; -import { DateOrTimeView } from '../models'; +import { DateOrTimeView, PickerValidDate } from '../models'; import { useMobilePicker } from '../internals/hooks/useMobilePicker'; import { extractValidationProps } from '../internals/utils/validation/extractValidationProps'; import { renderDateViewCalendar } from '../dateViewRenderers'; import { renderTimeViewClock } from '../timeViewRenderers'; import { resolveDateTimeFormat } from '../internals/utils/date-time-utils'; -type MobileDateTimePickerComponent = (( +type MobileDateTimePickerComponent = (( props: MobileDateTimePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -30,10 +30,9 @@ type MobileDateTimePickerComponent = (( * * - [MobileDateTimePicker API](https://mui.com/x/api/date-pickers/mobile-date-time-picker/) */ -const MobileDateTimePicker = React.forwardRef(function MobileDateTimePicker( - inProps: MobileDateTimePickerProps, - ref: React.Ref, -) { +const MobileDateTimePicker = React.forwardRef(function MobileDateTimePicker< + TDate extends PickerValidDate, +>(inProps: MobileDateTimePickerProps, ref: React.Ref) { const localeText = useLocaleText(); const utils = useUtils(); @@ -135,7 +134,7 @@ MobileDateTimePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker and text field are disabled. * @default false @@ -209,29 +208,29 @@ MobileDateTimePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Maximal selectable moment of time with binding to date, to set max time in each day use `maxTime`. */ - maxDateTime: PropTypes.any, + maxDateTime: PropTypes.object, /** * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Minimal selectable moment of time with binding to date, to set min time in each day use `minTime`. */ - minDateTime: PropTypes.any, + minDateTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -328,7 +327,7 @@ MobileDateTimePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component displaying when passed `loading` true. * @returns {React.ReactNode} The node to render when loading. @@ -436,7 +435,7 @@ MobileDateTimePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.types.ts b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.types.ts index 29bb903432789..d8b6a4c1d9621 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.types.ts +++ b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.types.ts @@ -9,23 +9,23 @@ import { BaseDateTimePickerSlotProps, } from '../DateTimePicker/shared'; import { MakeOptional } from '../internals/models/helpers'; -import { DateOrTimeView } from '../models'; +import { DateOrTimeView, PickerValidDate } from '../models'; import { DateOrTimeViewWithMeridiem } from '../internals/models'; export interface MobileDateTimePickerSlots< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem = DateOrTimeView, > extends BaseDateTimePickerSlots, MakeOptional, 'field'> {} export interface MobileDateTimePickerSlotProps< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem = DateOrTimeView, > extends BaseDateTimePickerSlotProps, ExportedUseMobilePickerSlotProps {} export interface MobileDateTimePickerProps< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem = DateOrTimeView, > extends BaseDateTimePickerProps, MobileOnlyPickerProps { diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/tests/MobileDateTimePicker.test.tsx b/packages/x-date-pickers/src/MobileDateTimePicker/tests/MobileDateTimePicker.test.tsx index df67f29c014c1..e796cd42c98a5 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/tests/MobileDateTimePicker.test.tsx +++ b/packages/x-date-pickers/src/MobileDateTimePicker/tests/MobileDateTimePicker.test.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import TextField from '@mui/material/TextField'; import { expect } from 'chai'; import { spy } from 'sinon'; import { fireTouchChangedEvent, screen, userEvent } from '@mui-internal/test-utils'; @@ -31,13 +30,7 @@ describe('', () => { }); it('should render toolbar and tabs by default', () => { - render( - } - />, - ); + render(); expect(screen.queryByMuiTest('picker-toolbar-title')).not.to.equal(null); expect(screen.getByRole('tab', { name: 'pick date' })).not.to.equal(null); diff --git a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx index 242983fde78c7..fc8d5747ef0ea 100644 --- a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx @@ -9,13 +9,13 @@ import { useTimePickerDefaultizedProps } from '../TimePicker/shared'; import { useLocaleText, useUtils } from '../internals/hooks/useUtils'; import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; import { validateTime } from '../internals/utils/validation/validateTime'; -import { TimeView } from '../models'; +import { PickerValidDate, TimeView } from '../models'; import { useMobilePicker } from '../internals/hooks/useMobilePicker'; import { extractValidationProps } from '../internals/utils/validation/extractValidationProps'; import { renderTimeViewClock } from '../timeViewRenderers'; import { resolveTimeFormat } from '../internals/utils/time-utils'; -type MobileTimePickerComponent = (( +type MobileTimePickerComponent = (( props: MobileTimePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -29,7 +29,7 @@ type MobileTimePickerComponent = (( * * - [MobileTimePicker API](https://mui.com/x/api/date-pickers/mobile-time-picker/) */ -const MobileTimePicker = React.forwardRef(function MobileTimePicker( +const MobileTimePicker = React.forwardRef(function MobileTimePicker( inProps: MobileTimePickerProps, ref: React.Ref, ) { @@ -120,7 +120,7 @@ MobileTimePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker and text field are disabled. * @default false @@ -174,12 +174,12 @@ MobileTimePicker.propTypes = { * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -259,7 +259,7 @@ MobileTimePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * The currently selected sections. * This prop accept four formats: @@ -326,7 +326,7 @@ MobileTimePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.types.ts b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.types.ts index 130e42e7a6b5c..152f1f2402ddf 100644 --- a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.types.ts +++ b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.types.ts @@ -9,19 +9,25 @@ import { BaseTimePickerSlotProps, } from '../TimePicker/shared'; import { MakeOptional } from '../internals/models/helpers'; -import { TimeView } from '../models'; +import { PickerValidDate, TimeView } from '../models'; import { TimeViewWithMeridiem } from '../internals/models'; -export interface MobileTimePickerSlots - extends BaseTimePickerSlots, +export interface MobileTimePickerSlots< + TDate extends PickerValidDate, + TView extends TimeViewWithMeridiem = TimeView, +> extends BaseTimePickerSlots, MakeOptional, 'field'> {} -export interface MobileTimePickerSlotProps - extends BaseTimePickerSlotProps, +export interface MobileTimePickerSlotProps< + TDate extends PickerValidDate, + TView extends TimeViewWithMeridiem = TimeView, +> extends BaseTimePickerSlotProps, ExportedUseMobilePickerSlotProps {} -export interface MobileTimePickerProps - extends BaseTimePickerProps, +export interface MobileTimePickerProps< + TDate extends PickerValidDate, + TView extends TimeViewWithMeridiem = TimeView, +> extends BaseTimePickerProps, MobileOnlyPickerProps { /** * Overridable component slots. diff --git a/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.tsx b/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.tsx index d6d5cc1dcb230..a537531d94885 100644 --- a/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.tsx +++ b/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.tsx @@ -18,6 +18,7 @@ import { singleItemValueManager } from '../internals/utils/valueManagers'; import { SECTION_TYPE_GRANULARITY } from '../internals/utils/getDefaultReferenceDate'; import { useControlledValueWithTimezone } from '../internals/hooks/useValueWithTimezone'; import { DIALOG_WIDTH } from '../internals/constants/dimensions'; +import { PickerValidDate } from '../models'; const useUtilityClasses = (ownerState: MonthCalendarProps) => { const { classes } = ownerState; @@ -29,7 +30,7 @@ const useUtilityClasses = (ownerState: MonthCalendarProps) => { return composeClasses(slots, getMonthCalendarUtilityClass, classes); }; -export function useMonthCalendarDefaultizedProps( +export function useMonthCalendarDefaultizedProps( props: MonthCalendarProps, name: string, ): DefaultizedProps< @@ -66,7 +67,7 @@ const MonthCalendarRoot = styled('div', { boxSizing: 'border-box', }); -type MonthCalendarComponent = (( +type MonthCalendarComponent = (( props: MonthCalendarProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -79,7 +80,7 @@ type MonthCalendarComponent = (( * * - [MonthCalendar API](https://mui.com/x/api/date-pickers/month-calendar/) */ -export const MonthCalendar = React.forwardRef(function MonthCalendar( +export const MonthCalendar = React.forwardRef(function MonthCalendar( inProps: MonthCalendarProps, ref: React.Ref, ) { @@ -314,7 +315,7 @@ MonthCalendar.propTypes = { * The default selected value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true` picker is disabled */ @@ -339,11 +340,11 @@ MonthCalendar.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Months rendered per row. * @default 3 @@ -365,7 +366,7 @@ MonthCalendar.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid month using the validation props, except callbacks such as `shouldDisableMonth`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Disable specific month. * @template TDate @@ -393,5 +394,5 @@ MonthCalendar.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, } as any; diff --git a/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.types.ts b/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.types.ts index c621ee167c9db..c7a8a148c6f8d 100644 --- a/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.types.ts +++ b/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.types.ts @@ -2,7 +2,7 @@ import { SxProps } from '@mui/system'; import { Theme } from '@mui/material/styles'; import { MonthCalendarClasses } from './monthCalendarClasses'; import { BaseDateValidationProps, MonthValidationProps } from '../internals/models/validation'; -import { TimezoneProps } from '../models'; +import { PickerValidDate, TimezoneProps } from '../models'; export interface ExportedMonthCalendarProps { /** @@ -11,7 +11,7 @@ export interface ExportedMonthCalendarProps { */ monthsPerRow?: 3 | 4; } -export interface MonthCalendarProps +export interface MonthCalendarProps extends ExportedMonthCalendarProps, MonthValidationProps, BaseDateValidationProps, diff --git a/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx b/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx index 0f4fbe64df7ba..3aae2c8dcb262 100644 --- a/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx +++ b/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx @@ -17,7 +17,7 @@ import { MultiSectionDigitalClockViewProps, } from './MultiSectionDigitalClock.types'; import { getHourSectionOptions, getTimeSectionOptions } from './MultiSectionDigitalClock.utils'; -import { TimeStepOptions, TimeView } from '../models'; +import { PickerValidDate, TimeStepOptions, TimeView } from '../models'; import { TimeViewWithMeridiem } from '../internals/models'; import { useControlledValueWithTimezone } from '../internals/hooks/useValueWithTimezone'; import { singleItemValueManager } from '../internals/utils/valueManagers'; @@ -44,7 +44,7 @@ const MultiSectionDigitalClockRoot = styled(PickerViewRoot, { borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, })); -type MultiSectionDigitalClockComponent = (( +type MultiSectionDigitalClockComponent = (( props: MultiSectionDigitalClockProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -59,7 +59,7 @@ type MultiSectionDigitalClockComponent = (( * - [MultiSectionDigitalClock API](https://mui.com/x/api/date-pickers/multi-section-digital-clock/) */ export const MultiSectionDigitalClock = React.forwardRef(function MultiSectionDigitalClock< - TDate extends unknown, + TDate extends PickerValidDate, >(inProps: MultiSectionDigitalClockProps, ref: React.Ref) { const utils = useUtils(); @@ -455,7 +455,7 @@ MultiSectionDigitalClock.propTypes = { * The default selected value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker views and text field are disabled. * @default false @@ -484,12 +484,12 @@ MultiSectionDigitalClock.propTypes = { * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -532,7 +532,7 @@ MultiSectionDigitalClock.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid time using the validation props, except callbacks such as `shouldDisableTime`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Disable specific time. * @template TDate @@ -586,7 +586,7 @@ MultiSectionDigitalClock.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.types.ts b/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.types.ts index 13fe496fa09fd..31f2ac1d1d73e 100644 --- a/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.types.ts +++ b/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.types.ts @@ -1,3 +1,4 @@ +import * as React from 'react'; import { SlotComponentProps } from '@mui/base/utils'; import MenuItem from '@mui/material/MenuItem'; import { MultiSectionDigitalClockClasses } from './multiSectionDigitalClockClasses'; @@ -8,6 +9,7 @@ import { } from '../internals/models/props/clock'; import { MultiSectionDigitalClockSectionProps } from './MultiSectionDigitalClockSection'; import { TimeViewWithMeridiem } from '../internals/models'; +import { PickerValidDate } from '../models'; export interface MultiSectionDigitalClockOption { isDisabled?: (value: TValue) => boolean; @@ -18,7 +20,7 @@ export interface MultiSectionDigitalClockOption { ariaLabel: string; } -export interface ExportedMultiSectionDigitalClockProps +export interface ExportedMultiSectionDigitalClockProps extends ExportedBaseClockProps, MultiSectionDigitalClockOnlyProps {} @@ -37,7 +39,7 @@ export interface MultiSectionDigitalClockSlotProps { digitalClockSectionItem?: SlotComponentProps>; } -export interface MultiSectionDigitalClockProps +export interface MultiSectionDigitalClockProps extends ExportedMultiSectionDigitalClockProps, BaseClockProps { /** diff --git a/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.utils.ts b/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.utils.ts index 660f2a7cf9dff..643fcb5e0c180 100644 --- a/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.utils.ts +++ b/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.utils.ts @@ -1,7 +1,7 @@ -import { MuiPickersAdapter } from '../models'; +import { MuiPickersAdapter, PickerValidDate } from '../models'; import { MultiSectionDigitalClockOption } from './MultiSectionDigitalClock.types'; -interface IGetHoursSectionOptions { +interface IGetHoursSectionOptions { now: TDate; value: TDate | null; utils: MuiPickersAdapter; @@ -12,7 +12,7 @@ interface IGetHoursSectionOptions { valueOrReferenceDate: TDate; } -export const getHourSectionOptions = ({ +export const getHourSectionOptions = ({ now, value, utils, @@ -66,7 +66,7 @@ export const getHourSectionOptions = ({ return result; }; -interface IGetTimeSectionOptions { +interface IGetTimeSectionOptions { value: number | null; utils: MuiPickersAdapter; isDisabled: (value: number) => boolean; @@ -76,7 +76,7 @@ interface IGetTimeSectionOptions { resolveAriaLabel: (value: string) => string; } -export const getTimeSectionOptions = ({ +export const getTimeSectionOptions = ({ value, utils, isDisabled, diff --git a/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.tsx b/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.tsx index d3367326fca6f..4edc2507e7390 100644 --- a/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.tsx +++ b/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.tsx @@ -22,6 +22,7 @@ import { PickersCalendarHeaderOwnerState, PickersCalendarHeaderProps, } from './PickersCalendarHeader.types'; +import { PickerValidDate } from '../models'; const useUtilityClasses = (ownerState: PickersCalendarHeaderOwnerState) => { const { classes } = ownerState; @@ -105,7 +106,7 @@ const PickersCalendarHeaderSwitchViewIcon = styled(ArrowDropDownIcon, { transform: 'rotate(0deg)', })); -type PickersCalendarHeaderComponent = (( +type PickersCalendarHeaderComponent = (( props: PickersCalendarHeaderProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -120,10 +121,9 @@ type PickersCalendarHeaderComponent = (( * * - [PickersCalendarHeader API](https://mui.com/x/api/date-pickers/pickers-calendar-header/) */ -const PickersCalendarHeader = React.forwardRef(function PickersCalendarHeader( - inProps: PickersCalendarHeaderProps, - ref: React.Ref, -) { +const PickersCalendarHeader = React.forwardRef(function PickersCalendarHeader< + TDate extends PickerValidDate, +>(inProps: PickersCalendarHeaderProps, ref: React.Ref) { const localeText = useLocaleText(); const utils = useUtils(); @@ -267,7 +267,7 @@ PickersCalendarHeader.propTypes = { */ classes: PropTypes.object, className: PropTypes.string, - currentMonth: PropTypes.any.isRequired, + currentMonth: PropTypes.object.isRequired, disabled: PropTypes.bool, disableFuture: PropTypes.bool, disablePast: PropTypes.bool, @@ -277,8 +277,8 @@ PickersCalendarHeader.propTypes = { */ format: PropTypes.string, labelId: PropTypes.string, - maxDate: PropTypes.any.isRequired, - minDate: PropTypes.any.isRequired, + maxDate: PropTypes.object.isRequired, + minDate: PropTypes.object.isRequired, onMonthChange: PropTypes.func.isRequired, onViewChange: PropTypes.func, reduceAnimations: PropTypes.bool.isRequired, diff --git a/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.types.ts b/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.types.ts index 506e6d4ce821f..c2270d128f8e8 100644 --- a/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.types.ts +++ b/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.types.ts @@ -1,3 +1,4 @@ +import * as React from 'react'; import { SlotComponentProps } from '@mui/base/utils'; import IconButton from '@mui/material/IconButton'; import SvgIcon from '@mui/material/SvgIcon'; @@ -8,7 +9,7 @@ import { PickersArrowSwitcherSlotProps, } from '../internals/components/PickersArrowSwitcher'; import { MonthValidationOptions } from '../internals/hooks/date-helpers-hooks'; -import { DateView } from '../models/views'; +import { PickerValidDate, DateView } from '../models'; import { SlideDirection } from '../DateCalendar/PickersSlideTransition'; import { PickersCalendarHeaderClasses } from './pickersCalendarHeaderClasses'; @@ -28,9 +29,11 @@ export interface PickersCalendarHeaderSlots extends PickersArrowSwitcherSlots { // We keep the interface to allow module augmentation export interface PickersCalendarHeaderSlotPropsOverrides {} -export type PickersCalendarHeaderOwnerState = PickersCalendarHeaderProps; +export type PickersCalendarHeaderOwnerState = + PickersCalendarHeaderProps; -export interface PickersCalendarHeaderSlotProps extends PickersArrowSwitcherSlotProps { +export interface PickersCalendarHeaderSlotProps + extends PickersArrowSwitcherSlotProps { switchViewButton?: SlotComponentProps< typeof IconButton, PickersCalendarHeaderSlotPropsOverrides, @@ -44,7 +47,7 @@ export interface PickersCalendarHeaderSlotProps extends PickersArrowSwitc >; } -export interface PickersCalendarHeaderProps +export interface PickersCalendarHeaderProps extends ExportedPickersArrowSwitcherProps, MonthValidationOptions { /** @@ -76,7 +79,7 @@ export interface PickersCalendarHeaderProps sx?: SxProps; } -export type ExportedPickersCalendarHeaderProps = Pick< +export type ExportedPickersCalendarHeaderProps = Pick< PickersCalendarHeaderProps, 'classes' | 'slots' | 'slotProps' >; diff --git a/packages/x-date-pickers/src/PickersDay/PickersDay.tsx b/packages/x-date-pickers/src/PickersDay/PickersDay.tsx index b226938bc31d7..b0ed7b3ac0eb7 100644 --- a/packages/x-date-pickers/src/PickersDay/PickersDay.tsx +++ b/packages/x-date-pickers/src/PickersDay/PickersDay.tsx @@ -18,6 +18,7 @@ import { getPickersDayUtilityClass, pickersDayClasses, } from './pickersDayClasses'; +import { PickerValidDate } from '../models'; export interface ExportedPickersDayProps { /** @@ -38,7 +39,7 @@ export interface ExportedPickersDayProps { showDaysOutsideCurrentMonth?: boolean; } -export interface PickersDayProps +export interface PickersDayProps extends ExportedPickersDayProps, Omit< ExtendMui, @@ -221,11 +222,11 @@ const PickersDayFiller = styled('div', { const noop = () => {}; -type PickersDayComponent = (( +type PickersDayComponent = (( props: PickersDayProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; -const PickersDayRaw = React.forwardRef(function PickersDay( +const PickersDayRaw = React.forwardRef(function PickersDay( inProps: PickersDayProps, forwardedRef: React.Ref, ) { @@ -373,7 +374,7 @@ PickersDayRaw.propTypes = { /** * The date to show. */ - day: PropTypes.any.isRequired, + day: PropTypes.object.isRequired, /** * If `true`, renders as disabled. * @default false diff --git a/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx b/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx index 4247d58b2f8ab..c76b350f092fb 100644 --- a/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx +++ b/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx @@ -7,6 +7,7 @@ import { PickersLayoutProps } from './PickersLayout.types'; import { pickersLayoutClasses, getPickersLayoutUtilityClass } from './pickersLayoutClasses'; import usePickerLayout from './usePickerLayout'; import { DateOrTimeViewWithMeridiem } from '../internals/models'; +import { PickerValidDate } from '../models'; const useUtilityClasses = (ownerState: PickersLayoutProps) => { const { isLandscape, classes } = ownerState; @@ -81,7 +82,7 @@ export const PickersLayoutContentWrapper = styled('div', { */ const PickersLayout = function PickersLayout< TValue, - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, >(inProps: PickersLayoutProps) { const props = useThemeProps({ props: inProps, name: 'MuiPickersLayout' }); diff --git a/packages/x-date-pickers/src/PickersLayout/PickersLayout.types.ts b/packages/x-date-pickers/src/PickersLayout/PickersLayout.types.ts index 40e699fc58dc0..27b0b042aae56 100644 --- a/packages/x-date-pickers/src/PickersLayout/PickersLayout.types.ts +++ b/packages/x-date-pickers/src/PickersLayout/PickersLayout.types.ts @@ -9,10 +9,11 @@ import { PickersLayoutClasses } from './pickersLayoutClasses'; import { DateOrTimeViewWithMeridiem, WrapperVariant } from '../internals/models/common'; import { PickersShortcutsProps } from '../PickersShortcuts'; import { ExportedPickersShortcutProps } from '../PickersShortcuts/PickersShortcuts'; +import { PickerValidDate } from '../models'; export interface ExportedPickersLayoutSlots< TValue, - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, > { /** @@ -34,8 +35,11 @@ export interface ExportedPickersLayoutSlots< >; } -interface PickersLayoutActionBarOwnerState - extends PickersLayoutProps { +interface PickersLayoutActionBarOwnerState< + TValue, + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends PickersLayoutProps { wrapperVariant: WrapperVariant; } @@ -45,7 +49,7 @@ interface PickersShortcutsOwnerState extends PickersShortcutsProps { /** @@ -72,8 +76,11 @@ export interface ExportedPickersLayoutSlotProps< layout?: Partial>; } -export interface PickersLayoutSlots - extends ExportedPickersLayoutSlots { +export interface PickersLayoutSlots< + TValue, + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends ExportedPickersLayoutSlots { /** * Tabs enabling toggling between views. */ @@ -85,8 +92,11 @@ export interface PickersLayoutSlots>; } -export interface PickersLayoutSlotProps - extends ExportedPickersLayoutSlotProps { +export interface PickersLayoutSlotProps< + TValue, + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends ExportedPickersLayoutSlotProps { /** * Props passed down to the tabs component. */ @@ -97,8 +107,11 @@ export interface PickersLayoutSlotProps - extends Omit, 'value'> { +export interface PickersLayoutProps< + TValue, + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends Omit, 'value'> { value?: TValue; className?: string; children?: React.ReactNode; diff --git a/packages/x-date-pickers/src/PickersLayout/usePickerLayout.tsx b/packages/x-date-pickers/src/PickersLayout/usePickerLayout.tsx index 8ba6c1afa4f5e..186649d43cd7d 100644 --- a/packages/x-date-pickers/src/PickersLayout/usePickerLayout.tsx +++ b/packages/x-date-pickers/src/PickersLayout/usePickerLayout.tsx @@ -7,6 +7,7 @@ import { getPickersLayoutUtilityClass } from './pickersLayoutClasses'; import { PickersShortcuts } from '../PickersShortcuts'; import { BaseToolbarProps } from '../internals/models/props/toolbar'; import { DateOrTimeViewWithMeridiem } from '../internals/models'; +import { PickerValidDate } from '../models'; function toolbarHasView( toolbarProps: BaseToolbarProps | any, @@ -31,14 +32,18 @@ const useUtilityClasses = (ownerState: PickersLayoutProps) => { interface PickersLayoutPropsWithValueRequired< TValue, - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, > extends PickersLayoutProps { value: TValue; } interface UsePickerLayoutResponse extends SubComponents {} -const usePickerLayout = ( +const usePickerLayout = < + TValue, + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +>( props: PickersLayoutProps, ): UsePickerLayoutResponse => { const { diff --git a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx index f15751cb36d15..fe7afbb4b72fc 100644 --- a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx +++ b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx @@ -5,11 +5,11 @@ import { useDatePickerDefaultizedProps } from '../DatePicker/shared'; import { renderDateViewCalendar } from '../dateViewRenderers'; import { useStaticPicker } from '../internals/hooks/useStaticPicker'; import { validateDate } from '../internals/utils/validation/validateDate'; -import { DateView } from '../models'; +import { DateView, PickerValidDate } from '../models'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; -type StaticDatePickerComponent = (( +type StaticDatePickerComponent = (( props: StaticDatePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -23,7 +23,7 @@ type StaticDatePickerComponent = (( * * - [StaticDatePicker API](https://mui.com/x/api/date-pickers/static-date-picker/) */ -const StaticDatePicker = React.forwardRef(function StaticDatePicker( +const StaticDatePicker = React.forwardRef(function StaticDatePicker( inProps: StaticDatePickerProps, ref: React.Ref, ) { @@ -91,7 +91,7 @@ StaticDatePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker and text field are disabled. * @default false @@ -141,11 +141,11 @@ StaticDatePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Months rendered per row. * @default 3 @@ -219,7 +219,7 @@ StaticDatePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component displaying when passed `loading` true. * @returns {React.ReactNode} The node to render when loading. @@ -291,7 +291,7 @@ StaticDatePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.types.ts b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.types.ts index de183ec323e96..64a84459d9b4e 100644 --- a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.types.ts +++ b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.types.ts @@ -9,17 +9,17 @@ import { UseStaticPickerSlotProps, } from '../internals/hooks/useStaticPicker'; import { MakeOptional } from '../internals/models/helpers'; -import { DateView } from '../models'; +import { DateView, PickerValidDate } from '../models'; -export interface StaticDatePickerSlots +export interface StaticDatePickerSlots extends BaseDatePickerSlots, UseStaticPickerSlots {} -export interface StaticDatePickerSlotProps +export interface StaticDatePickerSlotProps extends BaseDatePickerSlotProps, UseStaticPickerSlotProps {} -export interface StaticDatePickerProps +export interface StaticDatePickerProps extends BaseDatePickerProps, MakeOptional { /** diff --git a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx index 7e60ab686782c..e47845d169c97 100644 --- a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx +++ b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx @@ -6,11 +6,11 @@ import { renderTimeViewClock } from '../timeViewRenderers'; import { renderDateViewCalendar } from '../dateViewRenderers'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { useStaticPicker } from '../internals/hooks/useStaticPicker'; -import { DateOrTimeView } from '../models'; +import { DateOrTimeView, PickerValidDate } from '../models'; import { validateDateTime } from '../internals/utils/validation/validateDateTime'; import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; -type StaticDateTimePickerComponent = (( +type StaticDateTimePickerComponent = (( props: StaticDateTimePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -24,10 +24,9 @@ type StaticDateTimePickerComponent = (( * * - [StaticDateTimePicker API](https://mui.com/x/api/date-pickers/static-date-time-picker/) */ -const StaticDateTimePicker = React.forwardRef(function StaticDateTimePicker( - inProps: StaticDateTimePickerProps, - ref: React.Ref, -) { +const StaticDateTimePicker = React.forwardRef(function StaticDateTimePicker< + TDate extends PickerValidDate, +>(inProps: StaticDateTimePickerProps, ref: React.Ref) { const defaultizedProps = useDateTimePickerDefaultizedProps< TDate, DateOrTimeView, @@ -113,7 +112,7 @@ StaticDateTimePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker and text field are disabled. * @default false @@ -168,29 +167,29 @@ StaticDateTimePicker.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Maximal selectable moment of time with binding to date, to set max time in each day use `maxTime`. */ - maxDateTime: PropTypes.any, + maxDateTime: PropTypes.object, /** * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Minimal selectable moment of time with binding to date, to set min time in each day use `minTime`. */ - minDateTime: PropTypes.any, + minDateTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -269,7 +268,7 @@ StaticDateTimePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Component displaying when passed `loading` true. * @returns {React.ReactNode} The node to render when loading. @@ -349,7 +348,7 @@ StaticDateTimePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.types.ts b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.types.ts index ead81f65a0387..e154e31b80982 100644 --- a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.types.ts +++ b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.types.ts @@ -9,17 +9,17 @@ import { UseStaticPickerSlotProps, } from '../internals/hooks/useStaticPicker'; import { MakeOptional } from '../internals/models/helpers'; -import { DateOrTimeView } from '../models'; +import { DateOrTimeView, PickerValidDate } from '../models'; -export interface StaticDateTimePickerSlots +export interface StaticDateTimePickerSlots extends BaseDateTimePickerSlots, UseStaticPickerSlots {} -export interface StaticDateTimePickerSlotProps +export interface StaticDateTimePickerSlotProps extends BaseDateTimePickerSlotProps, UseStaticPickerSlotProps {} -export interface StaticDateTimePickerProps +export interface StaticDateTimePickerProps extends BaseDateTimePickerProps, MakeOptional { /** diff --git a/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx b/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx index a5b99754c2eaf..aaf03d7301f18 100644 --- a/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx +++ b/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import { TimeView } from '../models'; +import { PickerValidDate, TimeView } from '../models'; import { StaticTimePickerProps } from './StaticTimePicker.types'; import { useTimePickerDefaultizedProps } from '../TimePicker/shared'; import { renderTimeViewClock } from '../timeViewRenderers'; @@ -9,7 +9,7 @@ import { useStaticPicker } from '../internals/hooks/useStaticPicker'; import { validateTime } from '../internals/utils/validation/validateTime'; import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; -type StaticTimePickerComponent = (( +type StaticTimePickerComponent = (( props: StaticTimePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -23,7 +23,7 @@ type StaticTimePickerComponent = (( * * - [StaticTimePicker API](https://mui.com/x/api/date-pickers/static-time-picker/) */ -const StaticTimePicker = React.forwardRef(function StaticTimePicker( +const StaticTimePicker = React.forwardRef(function StaticTimePicker( inProps: StaticTimePickerProps, ref: React.Ref, ) { @@ -97,7 +97,7 @@ StaticTimePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker and text field are disabled. * @default false @@ -132,12 +132,12 @@ StaticTimePicker.propTypes = { * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -199,7 +199,7 @@ StaticTimePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Disable specific time. * @template TDate @@ -238,7 +238,7 @@ StaticTimePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.types.ts b/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.types.ts index b55a15bd0714a..70d04cbe841af 100644 --- a/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.types.ts +++ b/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.types.ts @@ -9,17 +9,17 @@ import { UseStaticPickerSlotProps, } from '../internals/hooks/useStaticPicker'; import { MakeOptional } from '../internals/models/helpers'; -import { TimeView } from '../models'; +import { PickerValidDate, TimeView } from '../models'; -export interface StaticTimePickerSlots +export interface StaticTimePickerSlots extends BaseTimePickerSlots, UseStaticPickerSlots {} -export interface StaticTimePickerSlotProps +export interface StaticTimePickerSlotProps extends BaseTimePickerSlotProps, UseStaticPickerSlotProps {} -export interface StaticTimePickerProps +export interface StaticTimePickerProps extends BaseTimePickerProps, MakeOptional { /** diff --git a/packages/x-date-pickers/src/TimeClock/Clock.tsx b/packages/x-date-pickers/src/TimeClock/Clock.tsx index b4080f100f6d3..8b15624405619 100644 --- a/packages/x-date-pickers/src/TimeClock/Clock.tsx +++ b/packages/x-date-pickers/src/TimeClock/Clock.tsx @@ -12,11 +12,12 @@ import { useLocaleText, useUtils } from '../internals/hooks/useUtils'; import type { PickerSelectionState } from '../internals/hooks/usePicker'; import { useMeridiemMode } from '../internals/hooks/date-helpers-hooks'; import { CLOCK_HOUR_WIDTH, getHours, getMinutes } from './shared'; -import { TimeView } from '../models'; +import { PickerValidDate, TimeView } from '../models'; import { ClockClasses, getClockUtilityClass } from './clockClasses'; import { formatMeridiem } from '../internals/utils/date-utils'; -export interface ClockProps extends ReturnType { +export interface ClockProps + extends ReturnType { ampm: boolean; ampmInClock: boolean; autoFocus?: boolean; @@ -195,7 +196,7 @@ const ClockMeridiemText = styled(Typography, { /** * @ignore - internal component. */ -export function Clock(inProps: ClockProps) { +export function Clock(inProps: ClockProps) { const props = useThemeProps({ props: inProps, name: 'MuiClock' }); const { ampm, diff --git a/packages/x-date-pickers/src/TimeClock/ClockNumbers.tsx b/packages/x-date-pickers/src/TimeClock/ClockNumbers.tsx index 19188dad42796..28c34d15caf5b 100644 --- a/packages/x-date-pickers/src/TimeClock/ClockNumbers.tsx +++ b/packages/x-date-pickers/src/TimeClock/ClockNumbers.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; import { ClockNumber } from './ClockNumber'; -import { MuiPickersAdapter } from '../models'; +import { MuiPickersAdapter, PickerValidDate } from '../models'; import type { PickerSelectionState } from '../internals/hooks/usePicker'; -interface GetHourNumbersOptions { +interface GetHourNumbersOptions { ampm: boolean; value: TDate | null; getClockNumberText: (hour: string) => string; @@ -20,7 +20,7 @@ interface GetHourNumbersOptions { /** * @ignore - internal component. */ -export const getHourNumbers = ({ +export const getHourNumbers = ({ ampm, value, getClockNumberText, @@ -79,7 +79,7 @@ export const getHourNumbers = ({ return hourNumbers; }; -export const getMinutesNumbers = ({ +export const getMinutesNumbers = ({ utils, value, isDisabled, diff --git a/packages/x-date-pickers/src/TimeClock/TimeClock.tsx b/packages/x-date-pickers/src/TimeClock/TimeClock.tsx index 93b8e6625af79..2e2e4186fe2da 100644 --- a/packages/x-date-pickers/src/TimeClock/TimeClock.tsx +++ b/packages/x-date-pickers/src/TimeClock/TimeClock.tsx @@ -9,7 +9,7 @@ import { convertValueToMeridiem, createIsAfterIgnoreDatePart } from '../internal import { useViews } from '../internals/hooks/useViews'; import type { PickerSelectionState } from '../internals/hooks/usePicker'; import { useMeridiemMode } from '../internals/hooks/date-helpers-hooks'; -import { TimeView } from '../models'; +import { PickerValidDate, TimeView } from '../models'; import { PickerViewRoot } from '../internals/components/PickerViewRoot'; import { getTimeClockUtilityClass } from './timeClockClasses'; import { Clock, ClockProps } from './Clock'; @@ -49,7 +49,7 @@ const TimeClockArrowSwitcher = styled(PickersArrowSwitcher, { top: 15, }); -type TimeClockComponent = (( +type TimeClockComponent = (( props: TimeClockProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -65,7 +65,7 @@ const TIME_CLOCK_DEFAULT_VIEWS: TimeView[] = ['hours', 'minutes']; * * - [TimeClock API](https://mui.com/x/api/date-pickers/time-clock/) */ -export const TimeClock = React.forwardRef(function TimeClock( +export const TimeClock = React.forwardRef(function TimeClock( inProps: TimeClockProps, ref: React.Ref, ) { @@ -417,7 +417,7 @@ TimeClock.propTypes = { * The default selected value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the picker views and text field are disabled. * @default false @@ -446,12 +446,12 @@ TimeClock.propTypes = { * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -494,7 +494,7 @@ TimeClock.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid time using the validation props, except callbacks such as `shouldDisableTime`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Disable specific time. * @template TDate @@ -534,7 +534,7 @@ TimeClock.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/TimeClock/TimeClock.types.ts b/packages/x-date-pickers/src/TimeClock/TimeClock.types.ts index afb3a935e5531..fda54930f817a 100644 --- a/packages/x-date-pickers/src/TimeClock/TimeClock.types.ts +++ b/packages/x-date-pickers/src/TimeClock/TimeClock.types.ts @@ -4,10 +4,11 @@ import { PickersArrowSwitcherSlotProps, } from '../internals/components/PickersArrowSwitcher'; import { BaseClockProps, ExportedBaseClockProps } from '../internals/models/props/clock'; -import { TimeView } from '../models'; +import { PickerValidDate, TimeView } from '../models'; import { TimeViewWithMeridiem } from '../internals/models'; -export interface ExportedTimeClockProps extends ExportedBaseClockProps { +export interface ExportedTimeClockProps + extends ExportedBaseClockProps { /** * Display ampm controls under the clock (instead of in the toolbar). * @default false @@ -19,8 +20,10 @@ export interface TimeClockSlots extends PickersArrowSwitcherSlots {} export interface TimeClockSlotProps extends PickersArrowSwitcherSlotProps {} -export interface TimeClockProps - extends ExportedTimeClockProps, +export interface TimeClockProps< + TDate extends PickerValidDate, + TView extends TimeViewWithMeridiem = TimeView, +> extends ExportedTimeClockProps, BaseClockProps { /** * Available views. diff --git a/packages/x-date-pickers/src/TimeField/TimeField.tsx b/packages/x-date-pickers/src/TimeField/TimeField.tsx index 495ae41d528ec..612df5b2f35a2 100644 --- a/packages/x-date-pickers/src/TimeField/TimeField.tsx +++ b/packages/x-date-pickers/src/TimeField/TimeField.tsx @@ -8,8 +8,9 @@ import { TimeFieldProps, TimeFieldSlotProps } from './TimeField.types'; import { useTimeField } from './useTimeField'; import { useClearableField } from '../hooks'; import { convertFieldResponseIntoMuiTextFieldProps } from '../internals/utils/convertFieldResponseIntoMuiTextFieldProps'; +import { PickerValidDate } from '../models'; -type TimeFieldComponent = (( +type TimeFieldComponent = (( props: TimeFieldProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -23,7 +24,7 @@ type TimeFieldComponent = (( * * - [TimeField API](https://mui.com/x/api/date-pickers/time-field/) */ -const TimeField = React.forwardRef(function TimeField( +const TimeField = React.forwardRef(function TimeField( inProps: TimeFieldProps, inRef: React.Ref, ) { @@ -100,7 +101,7 @@ TimeField.propTypes = { /** * The default value. Use when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true`, the component is disabled. * @default false @@ -193,12 +194,12 @@ TimeField.propTypes = { * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -246,7 +247,7 @@ TimeField.propTypes = { * For example, on time fields it will be used to determine the date to set. * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * If `true`, the label is displayed as required and the `input` element is required. * @default false @@ -342,7 +343,7 @@ TimeField.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The variant to use. * @default 'outlined' diff --git a/packages/x-date-pickers/src/TimeField/TimeField.types.ts b/packages/x-date-pickers/src/TimeField/TimeField.types.ts index 46c7b4659e5b2..b78ed842f6f30 100644 --- a/packages/x-date-pickers/src/TimeField/TimeField.types.ts +++ b/packages/x-date-pickers/src/TimeField/TimeField.types.ts @@ -5,10 +5,10 @@ import { UseFieldInternalProps } from '../internals/hooks/useField'; import { DefaultizedProps, MakeOptional } from '../internals/models/helpers'; import { BaseTimeValidationProps, TimeValidationProps } from '../internals/models/validation'; import { FieldsTextFieldProps } from '../internals/models/fields'; -import { FieldSection, TimeValidationError } from '../models'; +import { FieldSection, PickerValidDate, TimeValidationError } from '../models'; import { UseClearableFieldSlots, UseClearableFieldSlotProps } from '../hooks/useClearableField'; -export interface UseTimeFieldProps +export interface UseTimeFieldProps extends MakeOptional< UseFieldInternalProps, 'format' @@ -22,18 +22,17 @@ export interface UseTimeFieldProps ampm?: boolean; } -export type UseTimeFieldDefaultizedProps = DefaultizedProps< +export type UseTimeFieldDefaultizedProps = DefaultizedProps< UseTimeFieldProps, keyof BaseTimeValidationProps | 'format' >; -export type UseTimeFieldComponentProps = Omit< - TChildProps, - keyof UseTimeFieldProps -> & - UseTimeFieldProps; +export type UseTimeFieldComponentProps< + TDate extends PickerValidDate, + TChildProps extends {}, +> = Omit> & UseTimeFieldProps; -export interface TimeFieldProps +export interface TimeFieldProps extends UseTimeFieldComponentProps { /** * Overridable component slots. @@ -47,7 +46,7 @@ export interface TimeFieldProps slotProps?: TimeFieldSlotProps; } -export type TimeFieldOwnerState = TimeFieldProps; +export type TimeFieldOwnerState = TimeFieldProps; export interface TimeFieldSlots extends UseClearableFieldSlots { /** @@ -58,6 +57,7 @@ export interface TimeFieldSlots extends UseClearableFieldSlots { textField?: React.ElementType; } -export interface TimeFieldSlotProps extends UseClearableFieldSlotProps { +export interface TimeFieldSlotProps + extends UseClearableFieldSlotProps { textField?: SlotComponentProps>; } diff --git a/packages/x-date-pickers/src/TimeField/useTimeField.ts b/packages/x-date-pickers/src/TimeField/useTimeField.ts index fdaf7485cbf8a..1c6cf0089253e 100644 --- a/packages/x-date-pickers/src/TimeField/useTimeField.ts +++ b/packages/x-date-pickers/src/TimeField/useTimeField.ts @@ -11,8 +11,9 @@ import { import { validateTime } from '../internals/utils/validation/validateTime'; import { useUtils } from '../internals/hooks/useUtils'; import { splitFieldInternalAndForwardedProps } from '../internals/utils/fields'; +import { PickerValidDate } from '../models'; -const useDefaultizedTimeField = ( +const useDefaultizedTimeField = ( props: UseTimeFieldProps, ): AdditionalProps & UseTimeFieldDefaultizedProps => { const utils = useUtils(); @@ -28,7 +29,7 @@ const useDefaultizedTimeField = ( } as any; }; -export const useTimeField = ( +export const useTimeField = ( inProps: UseTimeFieldComponentProps, ) => { const props = useDefaultizedTimeField(inProps); diff --git a/packages/x-date-pickers/src/TimePicker/TimePicker.tsx b/packages/x-date-pickers/src/TimePicker/TimePicker.tsx index b78288e0e7872..0928d469cc9c8 100644 --- a/packages/x-date-pickers/src/TimePicker/TimePicker.tsx +++ b/packages/x-date-pickers/src/TimePicker/TimePicker.tsx @@ -7,8 +7,9 @@ import { DesktopTimePicker } from '../DesktopTimePicker'; import { MobileTimePicker, MobileTimePickerProps } from '../MobileTimePicker'; import { TimePickerProps } from './TimePicker.types'; import { DEFAULT_DESKTOP_MODE_MEDIA_QUERY } from '../internals/utils/utils'; +import { PickerValidDate } from '../models'; -type TimePickerComponent = (( +type TimePickerComponent = (( props: TimePickerProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; @@ -22,7 +23,7 @@ type TimePickerComponent = (( * * - [TimePicker API](https://mui.com/x/api/date-pickers/time-picker/) */ -const TimePicker = React.forwardRef(function TimePicker( +const TimePicker = React.forwardRef(function TimePicker( inProps: TimePickerProps, ref: React.Ref, ) { @@ -72,7 +73,7 @@ TimePicker.propTypes = { * The default value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * CSS media query when `Mobile` mode will be changed to `Desktop`. * @default '@media (pointer: fine)' @@ -132,12 +133,12 @@ TimePicker.propTypes = { * Maximal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - maxTime: PropTypes.any, + maxTime: PropTypes.object, /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. */ - minTime: PropTypes.any, + minTime: PropTypes.object, /** * Step over minutes. * @default 1 @@ -217,7 +218,7 @@ TimePicker.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * The currently selected sections. * This prop accept four formats: @@ -305,7 +306,7 @@ TimePicker.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * The visible view. * Used when the component view is controlled. diff --git a/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts b/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts index 3bf24d7725e1b..5561198004888 100644 --- a/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts +++ b/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts @@ -9,16 +9,17 @@ import { MobileTimePickerSlots, MobileTimePickerSlotProps, } from '../MobileTimePicker'; +import { PickerValidDate } from '../models'; -export interface TimePickerSlots +export interface TimePickerSlots extends DesktopTimePickerSlots, MobileTimePickerSlots {} -export interface TimePickerSlotProps +export interface TimePickerSlotProps extends DesktopTimePickerSlotProps, MobileTimePickerSlotProps {} -export interface TimePickerProps +export interface TimePickerProps extends DesktopTimePickerProps, Omit, 'views'> { /** diff --git a/packages/x-date-pickers/src/TimePicker/TimePickerToolbar.tsx b/packages/x-date-pickers/src/TimePicker/TimePickerToolbar.tsx index 89151a022a9e5..78614cdb22f21 100644 --- a/packages/x-date-pickers/src/TimePicker/TimePickerToolbar.tsx +++ b/packages/x-date-pickers/src/TimePicker/TimePickerToolbar.tsx @@ -16,8 +16,9 @@ import { } from './timePickerToolbarClasses'; import { TimeViewWithMeridiem } from '../internals/models'; import { formatMeridiem } from '../internals/utils/date-utils'; +import { PickerValidDate } from '../models'; -export interface TimePickerToolbarProps +export interface TimePickerToolbarProps extends BaseToolbarProps { ampm?: boolean; ampmInClock?: boolean; @@ -153,7 +154,7 @@ TimePickerToolbarAmPmSelection.propTypes = { * * - [TimePickerToolbar API](https://mui.com/x/api/date-pickers/time-picker-toolbar/) */ -function TimePickerToolbar(inProps: TimePickerToolbarProps) { +function TimePickerToolbar(inProps: TimePickerToolbarProps) { const props = useThemeProps({ props: inProps, name: 'MuiTimePickerToolbar' }); const { ampm, @@ -302,7 +303,7 @@ TimePickerToolbar.propTypes = { * @default "––" */ toolbarPlaceholder: PropTypes.node, - value: PropTypes.any, + value: PropTypes.object, /** * Currently visible picker view. */ diff --git a/packages/x-date-pickers/src/TimePicker/shared.tsx b/packages/x-date-pickers/src/TimePicker/shared.tsx index b1812f13fb69e..763948a3398ad 100644 --- a/packages/x-date-pickers/src/TimePicker/shared.tsx +++ b/packages/x-date-pickers/src/TimePicker/shared.tsx @@ -11,14 +11,14 @@ import { ExportedTimePickerToolbarProps, TimePickerToolbar, } from './TimePickerToolbar'; -import { TimeValidationError } from '../models'; +import { PickerValidDate, TimeValidationError } from '../models'; import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; import { TimeViewRendererProps } from '../timeViewRenderers'; import { applyDefaultViewProps } from '../internals/utils/views'; import { BaseClockProps, ExportedBaseClockProps } from '../internals/models/props/clock'; import { TimeViewWithMeridiem } from '../internals/models'; -export interface BaseTimePickerSlots extends TimeClockSlots { +export interface BaseTimePickerSlots extends TimeClockSlots { /** * Custom component for the toolbar rendered above the views. * @default TimePickerToolbar @@ -30,8 +30,10 @@ export interface BaseTimePickerSlotProps extends TimeClockSlotProps { toolbar?: ExportedTimePickerToolbarProps; } -export interface BaseTimePickerProps - extends BasePickerInputProps, +export interface BaseTimePickerProps< + TDate extends PickerValidDate, + TView extends TimeViewWithMeridiem, +> extends BasePickerInputProps, ExportedBaseClockProps { /** * Display ampm controls under the clock (instead of in the toolbar). @@ -64,7 +66,7 @@ export interface BaseTimePickerProps } type UseTimePickerDefaultizedProps< - TDate, + TDate extends PickerValidDate, TView extends TimeViewWithMeridiem, Props extends BaseTimePickerProps, > = LocalizedComponent< @@ -73,7 +75,7 @@ type UseTimePickerDefaultizedProps< >; export function useTimePickerDefaultizedProps< - TDate, + TDate extends PickerValidDate, TView extends TimeViewWithMeridiem, Props extends BaseTimePickerProps, >(props: Props, name: string): UseTimePickerDefaultizedProps { diff --git a/packages/x-date-pickers/src/YearCalendar/YearCalendar.tsx b/packages/x-date-pickers/src/YearCalendar/YearCalendar.tsx index d7e5ef3dfaa82..678c512bad34e 100644 --- a/packages/x-date-pickers/src/YearCalendar/YearCalendar.tsx +++ b/packages/x-date-pickers/src/YearCalendar/YearCalendar.tsx @@ -19,6 +19,7 @@ import { singleItemValueManager } from '../internals/utils/valueManagers'; import { SECTION_TYPE_GRANULARITY } from '../internals/utils/getDefaultReferenceDate'; import { useControlledValueWithTimezone } from '../internals/hooks/useValueWithTimezone'; import { DIALOG_WIDTH, MAX_CALENDAR_HEIGHT } from '../internals/constants/dimensions'; +import { PickerValidDate } from '../models'; const useUtilityClasses = (ownerState: YearCalendarProps) => { const { classes } = ownerState; @@ -30,7 +31,7 @@ const useUtilityClasses = (ownerState: YearCalendarProps) => { return composeClasses(slots, getYearCalendarUtilityClass, classes); }; -function useYearCalendarDefaultizedProps( +function useYearCalendarDefaultizedProps( props: YearCalendarProps, name: string, ): DefaultizedProps< @@ -72,7 +73,9 @@ const YearCalendarRoot = styled('div', { position: 'relative', }); -type YearCalendarComponent = ((props: YearCalendarProps) => React.JSX.Element) & { +type YearCalendarComponent = (( + props: YearCalendarProps, +) => React.JSX.Element) & { propTypes?: any; }; @@ -85,7 +88,7 @@ type YearCalendarComponent = ((props: YearCalendarProps) => React. * * - [YearCalendar API](https://mui.com/x/api/date-pickers/year-calendar/) */ -export const YearCalendar = React.forwardRef(function YearCalendar( +export const YearCalendar = React.forwardRef(function YearCalendar( inProps: YearCalendarProps, ref: React.Ref, ) { @@ -331,7 +334,7 @@ YearCalendar.propTypes = { * The default selected value. * Used when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.object, /** * If `true` picker is disabled */ @@ -356,11 +359,11 @@ YearCalendar.propTypes = { /** * Maximal selectable date. */ - maxDate: PropTypes.any, + maxDate: PropTypes.object, /** * Minimal selectable date. */ - minDate: PropTypes.any, + minDate: PropTypes.object, /** * Callback fired when the value changes. * @template TDate @@ -377,7 +380,7 @@ YearCalendar.propTypes = { * The date used to generate the new value when both `value` and `defaultValue` are empty. * @default The closest valid year using the validation props, except callbacks such as `shouldDisableYear`. */ - referenceDate: PropTypes.any, + referenceDate: PropTypes.object, /** * Disable specific year. * @template TDate @@ -405,7 +408,7 @@ YearCalendar.propTypes = { * The selected value. * Used when the component is controlled. */ - value: PropTypes.any, + value: PropTypes.object, /** * Years rendered per row. * @default 3 diff --git a/packages/x-date-pickers/src/YearCalendar/YearCalendar.types.ts b/packages/x-date-pickers/src/YearCalendar/YearCalendar.types.ts index 6b2cd9de038a9..ae45c7a04f960 100644 --- a/packages/x-date-pickers/src/YearCalendar/YearCalendar.types.ts +++ b/packages/x-date-pickers/src/YearCalendar/YearCalendar.types.ts @@ -2,7 +2,7 @@ import { SxProps } from '@mui/system'; import { Theme } from '@mui/material/styles'; import { YearCalendarClasses } from './yearCalendarClasses'; import { BaseDateValidationProps, YearValidationProps } from '../internals/models/validation'; -import { TimezoneProps } from '../models'; +import { PickerValidDate, TimezoneProps } from '../models'; export interface ExportedYearCalendarProps { /** @@ -12,7 +12,7 @@ export interface ExportedYearCalendarProps { yearsPerRow?: 3 | 4; } -export interface YearCalendarProps +export interface YearCalendarProps extends ExportedYearCalendarProps, YearValidationProps, BaseDateValidationProps, diff --git a/packages/x-date-pickers/src/dateTimeViewRenderers/dateTimeViewRenderers.tsx b/packages/x-date-pickers/src/dateTimeViewRenderers/dateTimeViewRenderers.tsx index 7e9d4340e0571..80ea74129e606 100644 --- a/packages/x-date-pickers/src/dateTimeViewRenderers/dateTimeViewRenderers.tsx +++ b/packages/x-date-pickers/src/dateTimeViewRenderers/dateTimeViewRenderers.tsx @@ -17,8 +17,9 @@ import { } from '../timeViewRenderers'; import { digitalClockClasses } from '../DigitalClock'; import { VIEW_HEIGHT } from '../internals/constants/dimensions'; +import { PickerValidDate } from '../models'; -export interface DateTimeViewRendererProps +export interface DateTimeViewRendererProps extends Omit< DateCalendarProps & MultiSectionDigitalClockProps, 'views' | 'openTo' | 'view' | 'onViewChange' | 'focusedView' | 'slots' | 'slotProps' @@ -32,7 +33,7 @@ export interface DateTimeViewRendererProps shouldRenderTimeInASingleColumn: boolean; } -export const renderDesktopDateTimeView = ({ +export const renderDesktopDateTimeView = ({ view, onViewChange, views, diff --git a/packages/x-date-pickers/src/dateViewRenderers/dateViewRenderers.tsx b/packages/x-date-pickers/src/dateViewRenderers/dateViewRenderers.tsx index a2014f4bc8cd8..fa043429c5999 100644 --- a/packages/x-date-pickers/src/dateViewRenderers/dateViewRenderers.tsx +++ b/packages/x-date-pickers/src/dateViewRenderers/dateViewRenderers.tsx @@ -1,11 +1,13 @@ import * as React from 'react'; import { DateCalendar, DateCalendarProps } from '../DateCalendar'; -import { DateView } from '../models'; +import { DateView, PickerValidDate } from '../models'; import { DateOrTimeViewWithMeridiem } from '../internals/models'; import { isDatePickerView } from '../internals/utils/date-utils'; -export interface DateViewRendererProps - extends Omit< +export interface DateViewRendererProps< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends Omit< DateCalendarProps, 'views' | 'openTo' | 'view' | 'onViewChange' | 'focusedView' > { @@ -15,7 +17,7 @@ export interface DateViewRendererProps({ +export const renderDateViewCalendar = ({ view, onViewChange, views, diff --git a/packages/x-date-pickers/src/internals/hooks/date-helpers-hooks.tsx b/packages/x-date-pickers/src/internals/hooks/date-helpers-hooks.tsx index e4f299d8ae139..7fcdcba1b2c97 100644 --- a/packages/x-date-pickers/src/internals/hooks/date-helpers-hooks.tsx +++ b/packages/x-date-pickers/src/internals/hooks/date-helpers-hooks.tsx @@ -3,9 +3,9 @@ import { useUtils } from './useUtils'; import { PickerOnChangeFn } from './useViews'; import { getMeridiem, convertToMeridiem } from '../utils/time-utils'; import { PickerSelectionState } from './usePicker'; -import { PickersTimezone } from '../../models'; +import { PickersTimezone, PickerValidDate } from '../../models'; -export interface MonthValidationOptions { +export interface MonthValidationOptions { disablePast?: boolean; disableFuture?: boolean; minDate: TDate; @@ -13,7 +13,7 @@ export interface MonthValidationOptions { timezone: PickersTimezone; } -export function useNextMonthDisabled( +export function useNextMonthDisabled( month: TDate, { disableFuture, @@ -31,7 +31,7 @@ export function useNextMonthDisabled( }, [disableFuture, maxDate, month, utils, timezone]); } -export function usePreviousMonthDisabled( +export function usePreviousMonthDisabled( month: TDate, { disablePast, @@ -50,7 +50,7 @@ export function usePreviousMonthDisabled( }, [disablePast, minDate, month, utils, timezone]); } -export function useMeridiemMode( +export function useMeridiemMode( date: TDate | null, ampm: boolean | undefined, onChange: PickerOnChangeFn, diff --git a/packages/x-date-pickers/src/internals/hooks/useClockReferenceDate.ts b/packages/x-date-pickers/src/internals/hooks/useClockReferenceDate.ts index f7f4062bad211..03afe046d50c6 100644 --- a/packages/x-date-pickers/src/internals/hooks/useClockReferenceDate.ts +++ b/packages/x-date-pickers/src/internals/hooks/useClockReferenceDate.ts @@ -1,10 +1,10 @@ import * as React from 'react'; -import { MuiPickersAdapter, PickersTimezone } from '../../models'; +import { MuiPickersAdapter, PickersTimezone, PickerValidDate } from '../../models'; import { singleItemValueManager } from '../utils/valueManagers'; import { getTodayDate } from '../utils/date-utils'; import { SECTION_TYPE_GRANULARITY } from '../utils/getDefaultReferenceDate'; -export const useClockReferenceDate = ({ +export const useClockReferenceDate = ({ value, referenceDate: referenceDateProp, utils, diff --git a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx index 7c6a84ddec528..52418e14d0ac6 100644 --- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx @@ -15,7 +15,7 @@ import { usePicker } from '../usePicker'; import { LocalizationProvider } from '../../../LocalizationProvider'; import { PickersLayout } from '../../../PickersLayout'; import { InferError } from '../useValidation'; -import { FieldSection, BaseSingleInputFieldProps } from '../../../models'; +import { FieldSection, BaseSingleInputFieldProps, PickerValidDate } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; import { UsePickerValueFieldResponse } from '../usePicker/usePickerValue.types'; @@ -26,7 +26,7 @@ import { UsePickerValueFieldResponse } from '../usePicker/usePickerValue.types'; * - DesktopTimePicker */ export const useDesktopPicker = < - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseDesktopPickerProps, >({ diff --git a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.types.ts b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.types.ts index 3c661b0c11f52..64118161d17d8 100644 --- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.types.ts @@ -10,7 +10,12 @@ import { } from '../../models/props/basePickerProps'; import { PickersPopperSlots, PickersPopperSlotProps } from '../../components/PickersPopper'; import { UsePickerParams, UsePickerProps } from '../usePicker'; -import { BaseSingleInputFieldProps, FieldSection, MuiPickersAdapter } from '../../../models'; +import { + BaseSingleInputFieldProps, + FieldSection, + MuiPickersAdapter, + PickerValidDate, +} from '../../../models'; import { ExportedPickersLayoutSlots, ExportedPickersLayoutSlotProps, @@ -24,8 +29,10 @@ import { UseClearableFieldSlotProps, } from '../../../hooks/useClearableField'; -export interface UseDesktopPickerSlots - extends Pick< +export interface UseDesktopPickerSlots< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends Pick< PickersPopperSlots, 'desktopPaper' | 'desktopTransition' | 'desktopTrapFocus' | 'popper' >, @@ -57,12 +64,16 @@ export interface UseDesktopPickerSlots - extends ExportedUseDesktopPickerSlotProps, +export interface UseDesktopPickerSlotProps< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends ExportedUseDesktopPickerSlotProps, Pick, 'toolbar'> {} -export interface ExportedUseDesktopPickerSlotProps - extends PickersPopperSlotProps, +export interface ExportedUseDesktopPickerSlotProps< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends PickersPopperSlotProps, ExportedPickersLayoutSlotProps, UseClearableFieldSlotProps { field?: SlotComponentProps< @@ -80,7 +91,7 @@ export interface ExportedUseDesktopPickerSlotProps; } -export interface DesktopOnlyPickerProps +export interface DesktopOnlyPickerProps extends BaseNonStaticPickerProps, BaseNonRangeNonStaticPickerProps, UsePickerValueNonStaticProps, @@ -92,7 +103,7 @@ export interface DesktopOnlyPickerProps } export interface UseDesktopPickerProps< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TError, TExternalProps extends UsePickerViewsProps, @@ -111,7 +122,7 @@ export interface UseDesktopPickerProps< } export interface UseDesktopPickerParams< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseDesktopPickerProps, > extends Pick< diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts index 6afb33b07eb22..740054ce131d7 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts @@ -16,11 +16,11 @@ import { adjustSectionValue, isAndroid, cleanString, getSectionOrder } from './u import { useFieldState } from './useFieldState'; import { useFieldCharacterEditing } from './useFieldCharacterEditing'; import { getActiveElement } from '../../utils/utils'; -import { FieldSection } from '../../../models'; +import { FieldSection, PickerValidDate } from '../../../models'; export const useField = < TValue, - TDate, + TDate extends PickerValidDate, TSection extends FieldSection, TForwardedProps extends UseFieldForwardedProps, TInternalProps extends UseFieldInternalProps & { minutesStep?: number }, diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts index cf0e3de7ea40c..6bfc7d3580935 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts @@ -8,13 +8,14 @@ import { FieldSectionContentType, FieldValueType, PickersTimezone, + PickerValidDate, } from '../../../models'; import type { PickerValueManager } from '../usePicker'; import { InferError, Validator } from '../useValidation'; export interface UseFieldParams< TValue, - TDate, + TDate extends PickerValidDate, TSection extends FieldSection, TForwardedProps extends UseFieldForwardedProps, TInternalProps extends UseFieldInternalProps, @@ -32,8 +33,12 @@ export interface UseFieldParams< valueType: FieldValueType; } -export interface UseFieldInternalProps - extends TimezoneProps { +export interface UseFieldInternalProps< + TValue, + TDate extends PickerValidDate, + TSection extends FieldSection, + TError, +> extends TimezoneProps { /** * The selected value. * Used when the component is controlled. @@ -183,12 +188,15 @@ export type FieldSectionWithoutPosition; -export type FieldSectionValueBoundaries = { +export type FieldSectionValueBoundaries< + TDate extends PickerValidDate, + SectionType extends FieldSectionType, +> = { minimum: number; maximum: number; } & (SectionType extends 'day' ? { longestMonth: TDate } : {}); -export type FieldSectionsValueBoundaries = { +export type FieldSectionsValueBoundaries = { [SectionType in FieldSectionType]: (params: { currentDate: TDate | null; format: string; @@ -209,7 +217,11 @@ export interface FieldChangeHandlerContext { * Object used to access and update the active date (i.e: the date containing the active section). * Mainly useful in the range fields where we need to update the date containing the active section without impacting the other one. */ -interface FieldActiveDateManager { +interface FieldActiveDateManager< + TValue, + TDate extends PickerValidDate, + TSection extends FieldSection, +> { /** * Active date from `state.value`. */ @@ -245,7 +257,11 @@ export type FieldSelectedSectionsIndexes = { shouldSelectBoundarySelectors: boolean; }; -export interface FieldValueManager { +export interface FieldValueManager< + TValue, + TDate extends PickerValidDate, + TSection extends FieldSection, +> { /** * Creates the section list from the current value. * The `prevSections` are used on the range fields to avoid losing the sections of a partially filled date when editing the other date. diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.utils.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.utils.ts index cfbea21b8f719..2f6ad0ab5b404 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.utils.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.utils.ts @@ -13,11 +13,12 @@ import { MuiPickersAdapter, FieldSectionContentType, PickersTimezone, + PickerValidDate, } from '../../../models'; import { PickersLocaleText } from '../../../locales/utils/pickersLocaleTextApi'; import { getMonthsInYear } from '../../utils/date-utils'; -export const getDateSectionConfigFromFormatToken = ( +export const getDateSectionConfigFromFormatToken = ( utils: MuiPickersAdapter, formatToken: string, ): Pick & { maxLength: number | undefined } => { @@ -62,7 +63,7 @@ const getDeltaFromKeyCode = (keyCode: Omit( +export const getDaysInWeekStr = ( utils: MuiPickersAdapter, timezone: PickersTimezone, format: string, @@ -82,7 +83,7 @@ export const getDaysInWeekStr = ( return elements.map((weekDay) => utils.formatByString(weekDay, format)); }; -export const getLetterEditingOptions = ( +export const getLetterEditingOptions = ( utils: MuiPickersAdapter, timezone: PickersTimezone, sectionType: FieldSectionType, @@ -118,7 +119,9 @@ export const FORMAT_SECONDS_NO_LEADING_ZEROS = 's'; const NON_LOCALIZED_DIGITS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; -export const getLocalizedDigits = (utils: MuiPickersAdapter) => { +export const getLocalizedDigits = ( + utils: MuiPickersAdapter, +) => { const today = utils.date(undefined); const formattedZero = utils.formatByString( utils.setSeconds(today, 0), @@ -188,7 +191,7 @@ export const cleanLeadingZeros = (valueStr: string, size: number) => { return cleanValueStr; }; -export const cleanDigitSectionValue = ( +export const cleanDigitSectionValue = ( utils: MuiPickersAdapter, value: number, sectionBoundaries: FieldSectionValueBoundaries, @@ -231,7 +234,7 @@ export const cleanDigitSectionValue = ( return applyLocalizedDigits(valueStr, localizedDigits); }; -export const adjustSectionValue = ( +export const adjustSectionValue = ( utils: MuiPickersAdapter, timezone: PickersTimezone, section: TSection, @@ -417,7 +420,7 @@ export const addPositionPropertiesToSections = ( return newSections; }; -const getSectionPlaceholder = ( +const getSectionPlaceholder = ( utils: MuiPickersAdapter, timezone: PickersTimezone, localeText: PickersLocaleText, @@ -472,7 +475,7 @@ const getSectionPlaceholder = ( } }; -export const changeSectionValueFormat = ( +export const changeSectionValueFormat = ( utils: MuiPickersAdapter, valueStr: string, currentFormat: string, @@ -487,13 +490,13 @@ export const changeSectionValueFormat = ( return utils.formatByString(utils.parse(valueStr, currentFormat)!, newFormat); }; -const isFourDigitYearFormat = ( +const isFourDigitYearFormat = ( utils: MuiPickersAdapter, timezone: PickersTimezone, format: string, ) => utils.formatByString(utils.date(undefined, timezone), format).length === 4; -export const doesSectionFormatHaveLeadingZeros = ( +export const doesSectionFormatHaveLeadingZeros = ( utils: MuiPickersAdapter, timezone: PickersTimezone, contentType: FieldSectionContentType, @@ -548,7 +551,10 @@ export const doesSectionFormatHaveLeadingZeros = ( } }; -const getEscapedPartsFromFormat = (utils: MuiPickersAdapter, format: string) => { +const getEscapedPartsFromFormat = ( + utils: MuiPickersAdapter, + format: string, +) => { const escapedParts: { start: number; end: number }[] = []; const { start: startChar, end: endChar } = utils.escapedCharacters; const regExp = new RegExp(`(\\${startChar}[^\\${endChar}]*\\${endChar})+`, 'g'); @@ -562,7 +568,7 @@ const getEscapedPartsFromFormat = (utils: MuiPickersAdapter, forma return escapedParts; }; -export const splitFormatIntoSections = ( +export const splitFormatIntoSections = ( utils: MuiPickersAdapter, timezone: PickersTimezone, localeText: PickersLocaleText, @@ -743,7 +749,7 @@ export const splitFormatIntoSections = ( * Some date libraries like `dayjs` don't support parsing from date with escaped characters. * To make sure that the parsing works, we are building a format and a date without any separator. */ -export const getDateFromDateSections = ( +export const getDateFromDateSections = ( utils: MuiPickersAdapter, sections: FieldSection[], localizedDigits: string[], @@ -800,7 +806,7 @@ export const createDateStrForInputFromSections = ( return `\u2066${dateStr}\u2069`; }; -export const getSectionsBoundaries = ( +export const getSectionsBoundaries = ( utils: MuiPickersAdapter, localizedDigits: string[], timezone: PickersTimezone, @@ -929,7 +935,7 @@ export const validateSections = ( } }; -const transferDateSectionValue = ( +const transferDateSectionValue = ( utils: MuiPickersAdapter, timezone: PickersTimezone, section: FieldSectionWithoutPosition, @@ -1004,7 +1010,7 @@ const reliableSectionModificationOrder: Record = { empty: 9, }; -export const mergeDateIntoReferenceDate = ( +export const mergeDateIntoReferenceDate = ( utils: MuiPickersAdapter, timezone: PickersTimezone, dateToTransferFrom: TDate, diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useFieldCharacterEditing.ts b/packages/x-date-pickers/src/internals/hooks/useField/useFieldCharacterEditing.ts index 13f7247bdf780..2fc78b739d0d0 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldCharacterEditing.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldCharacterEditing.ts @@ -1,6 +1,6 @@ import * as React from 'react'; import useEventCallback from '@mui/utils/useEventCallback'; -import { FieldSectionType, FieldSection, PickersTimezone } from '../../../models'; +import { FieldSectionType, FieldSection, PickersTimezone, PickerValidDate } from '../../../models'; import { useUtils } from '../useUtils'; import { FieldSectionsValueBoundaries } from './useField.types'; import { @@ -27,7 +27,7 @@ interface ApplyCharacterEditingParams { sectionIndex: number; } -interface UseFieldEditingParams { +interface UseFieldEditingParams { sections: TSection[]; updateSectionValue: (params: UpdateSectionValueParams) => void; sectionsValueBoundaries: FieldSectionsValueBoundaries; @@ -78,7 +78,10 @@ const isQueryResponseWithoutValue = ( * 1. The numeric editing when the user presses a digit * 2. The letter editing when the user presses another key */ -export const useFieldCharacterEditing = ({ +export const useFieldCharacterEditing = < + TDate extends PickerValidDate, + TSection extends FieldSection, +>({ sections, updateSectionValue, sectionsValueBoundaries, diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts b/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts index 102bac4d7f7a6..0731be627b7ed 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts @@ -20,7 +20,7 @@ import { getLocalizedDigits, } from './useField.utils'; import { InferError } from '../useValidation'; -import { FieldSection, FieldSelectedSections } from '../../../models'; +import { FieldSection, FieldSelectedSections, PickerValidDate } from '../../../models'; import { useValueWithTimezone } from '../useValueWithTimezone'; import { GetDefaultReferenceDateProps, @@ -44,7 +44,7 @@ export interface UpdateSectionValueParams { export const useFieldState = < TValue, - TDate, + TDate extends PickerValidDate, TSection extends FieldSection, TForwardedProps extends UseFieldForwardedProps, TInternalProps extends UseFieldInternalProps, diff --git a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx index a34d914b30449..f39bda9d098bb 100644 --- a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx @@ -10,7 +10,7 @@ import { useUtils } from '../useUtils'; import { LocalizationProvider } from '../../../LocalizationProvider'; import { PickersLayout } from '../../../PickersLayout'; import { InferError } from '../useValidation'; -import { FieldSection, BaseSingleInputFieldProps } from '../../../models'; +import { FieldSection, BaseSingleInputFieldProps, PickerValidDate } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; /** @@ -20,7 +20,7 @@ import { DateOrTimeViewWithMeridiem } from '../../models'; * - MobileTimePicker */ export const useMobilePicker = < - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseMobilePickerProps, >({ diff --git a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.types.ts b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.types.ts index 91c310fab3859..bbbe33d8521ef 100644 --- a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.types.ts @@ -11,7 +11,12 @@ import { PickersModalDialogSlotProps, } from '../../components/PickersModalDialog'; import { UsePickerParams, UsePickerProps } from '../usePicker'; -import { BaseSingleInputFieldProps, FieldSection, MuiPickersAdapter } from '../../../models'; +import { + BaseSingleInputFieldProps, + FieldSection, + MuiPickersAdapter, + PickerValidDate, +} from '../../../models'; import { ExportedPickersLayoutSlots, ExportedPickersLayoutSlotProps, @@ -21,8 +26,10 @@ import { UsePickerValueNonStaticProps } from '../usePicker/usePickerValue.types' import { UsePickerViewsNonStaticProps, UsePickerViewsProps } from '../usePicker/usePickerViews'; import { DateOrTimeViewWithMeridiem } from '../../models'; -export interface UseMobilePickerSlots - extends PickersModalDialogSlots, +export interface UseMobilePickerSlots< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends PickersModalDialogSlots, ExportedPickersLayoutSlots { /** * Component used to enter the date with the keyboard. @@ -36,8 +43,10 @@ export interface UseMobilePickerSlots; } -export interface ExportedUseMobilePickerSlotProps - extends PickersModalDialogSlotProps, +export interface ExportedUseMobilePickerSlotProps< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends PickersModalDialogSlotProps, ExportedPickersLayoutSlotProps { field?: SlotComponentProps< React.ElementType>, @@ -47,18 +56,20 @@ export interface ExportedUseMobilePickerSlotProps>; } -export interface UseMobilePickerSlotProps - extends ExportedUseMobilePickerSlotProps, +export interface UseMobilePickerSlotProps< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends ExportedUseMobilePickerSlotProps, Pick, 'toolbar'> {} -export interface MobileOnlyPickerProps +export interface MobileOnlyPickerProps extends BaseNonStaticPickerProps, BaseNonRangeNonStaticPickerProps, UsePickerValueNonStaticProps, UsePickerViewsNonStaticProps {} export interface UseMobilePickerProps< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TError, TExternalProps extends UsePickerViewsProps, @@ -77,7 +88,7 @@ export interface UseMobilePickerProps< } export interface UseMobilePickerParams< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseMobilePickerProps, > extends Pick< diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts index 4e60cf201427f..889aa0eb101b1 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts @@ -4,7 +4,7 @@ import { usePickerViews } from './usePickerViews'; import { usePickerLayoutProps } from './usePickerLayoutProps'; import { InferError } from '../useValidation'; import { buildWarning } from '../../utils/warning'; -import { FieldSection } from '../../../models'; +import { FieldSection, PickerValidDate } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; const warnRenderInputIsDefined = buildWarning([ @@ -15,7 +15,7 @@ const warnRenderInputIsDefined = buildWarning([ export const usePicker = < TValue, - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TSection extends FieldSection, TExternalProps extends UsePickerProps, diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.types.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.types.ts index 5b7e4aeb4ded8..0827fe08cd995 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.types.ts @@ -11,7 +11,7 @@ import { UsePickerViewsBaseProps, } from './usePickerViews'; import { UsePickerLayoutProps, UsePickerLayoutPropsResponse } from './usePickerLayoutProps'; -import { FieldSection } from '../../../models'; +import { FieldSection, PickerValidDate } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; /** @@ -19,7 +19,7 @@ import { DateOrTimeViewWithMeridiem } from '../../models'; */ export interface UsePickerBaseProps< TValue, - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TError, TExternalProps extends UsePickerViewsProps, @@ -30,7 +30,7 @@ export interface UsePickerBaseProps< export interface UsePickerProps< TValue, - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TSection extends FieldSection, TError, @@ -42,7 +42,7 @@ export interface UsePickerProps< export interface UsePickerParams< TValue, - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TSection extends FieldSection, TExternalProps extends UsePickerProps, diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts index 98863c4ebea8b..1e2c0947eef1d 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts @@ -5,7 +5,12 @@ import { useOpenState } from '../useOpenState'; import { useLocalizationContext, useUtils } from '../useUtils'; import { FieldChangeHandlerContext } from '../useField'; import { InferError, useValidation } from '../useValidation'; -import { FieldSection, FieldSelectedSections, PickerChangeHandlerContext } from '../../../models'; +import { + FieldSection, + FieldSelectedSections, + PickerChangeHandlerContext, + PickerValidDate, +} from '../../../models'; import { PickerShortcutChangeImportance, PickersShortcutsItemContext, @@ -147,7 +152,7 @@ const shouldClosePicker = ( */ export const usePickerValue = < TValue, - TDate, + TDate extends PickerValidDate, TSection extends FieldSection, TExternalProps extends UsePickerValueProps, >({ diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.types.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.types.ts index 959b45b70a337..3546b56d9f51c 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.types.ts @@ -10,6 +10,7 @@ import { MuiPickersAdapter, PickersTimezone, PickerChangeHandlerContext, + PickerValidDate, } from '../../../models'; import { GetDefaultReferenceDateProps } from '../../utils/getDefaultReferenceDate'; import { @@ -17,7 +18,7 @@ import { PickersShortcutsItemContext, } from '../../../PickersShortcuts'; -export interface PickerValueManager { +export interface PickerValueManager { /** * Determines if two values are equal. * @template TDate, TValue @@ -249,7 +250,7 @@ export interface UsePickerValueBaseProps { */ export interface UsePickerValueNonStaticProps extends Pick< - UseFieldInternalProps, + UseFieldInternalProps, 'selectedSections' | 'onSelectedSectionsChange' > { /** @@ -284,7 +285,7 @@ export interface UsePickerValueProps, > { @@ -312,7 +313,7 @@ export interface UsePickerValueActions { export type UsePickerValueFieldResponse = Required< Pick< - UseFieldInternalProps, + UseFieldInternalProps, 'value' | 'onChange' | 'selectedSections' | 'onSelectedSectionsChange' > >; diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts index d70dbe1cdeb58..58768a3877b35 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts @@ -7,7 +7,7 @@ import { useViews, UseViewsOptions } from '../useViews'; import type { UsePickerValueViewsResponse } from './usePickerValue.types'; import { isTimeView } from '../../utils/time-utils'; import { DateOrTimeViewWithMeridiem } from '../../models'; -import { TimezoneProps } from '../../../models'; +import { PickerValidDate, TimezoneProps } from '../../../models'; interface PickerViewsRendererBaseExternalProps extends Omit, 'openTo' | 'viewRenderers'> {} @@ -49,7 +49,7 @@ export type PickerViewRendererLookup< */ export interface UsePickerViewsBaseProps< TValue, - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UsePickerViewsProps, TAdditionalProps extends {}, @@ -93,7 +93,7 @@ export interface UsePickerViewsNonStaticProps { */ export interface UsePickerViewsProps< TValue, - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UsePickerViewsProps, TAdditionalProps extends {}, @@ -105,7 +105,7 @@ export interface UsePickerViewsProps< export interface UsePickerViewParams< TValue, - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UsePickerViewsProps< TValue, @@ -163,7 +163,7 @@ export interface UsePickerViewsLayoutResponse, TAdditionalProps extends {}, diff --git a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx index 7bd800892bc20..7c6f79c2914d1 100644 --- a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx @@ -6,7 +6,7 @@ import { usePicker } from '../usePicker'; import { LocalizationProvider } from '../../../LocalizationProvider'; import { PickersLayout } from '../../../PickersLayout'; import { DIALOG_WIDTH } from '../../constants/dimensions'; -import { FieldSection } from '../../../models'; +import { FieldSection, PickerValidDate } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; const PickerStaticLayout = styled(PickersLayout)(({ theme }) => ({ @@ -22,7 +22,7 @@ const PickerStaticLayout = styled(PickersLayout)(({ theme }) => ({ * - StaticTimePicker */ export const useStaticPicker = < - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseStaticPickerProps, >({ diff --git a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.types.ts b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.types.ts index 3938bfcdf7187..3ac7db4269d1c 100644 --- a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.types.ts @@ -6,14 +6,18 @@ import { import { BasePickerProps } from '../../models/props/basePickerProps'; import { UsePickerParams } from '../usePicker'; import { UsePickerViewsProps } from '../usePicker/usePickerViews'; -import { FieldSection } from '../../../models'; +import { FieldSection, PickerValidDate } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; -export interface UseStaticPickerSlots - extends ExportedPickersLayoutSlots {} +export interface UseStaticPickerSlots< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends ExportedPickersLayoutSlots {} -export interface UseStaticPickerSlotProps - extends ExportedPickersLayoutSlotProps {} +export interface UseStaticPickerSlotProps< + TDate extends PickerValidDate, + TView extends DateOrTimeViewWithMeridiem, +> extends ExportedPickersLayoutSlotProps {} export interface StaticOnlyPickerProps { /** @@ -34,7 +38,7 @@ export interface StaticOnlyPickerProps { } export interface UseStaticPickerProps< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TError, TExternalProps extends UsePickerViewsProps, @@ -44,7 +48,7 @@ export interface UseStaticPickerProps< * Overridable component slots. * @default {} */ - slots?: UseStaticPickerSlots; + slots?: UseStaticPickerSlots; /** * The props used for each component slot. * @default {} @@ -53,7 +57,7 @@ export interface UseStaticPickerProps< } export interface UseStaticPickerParams< - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseStaticPickerProps, > extends Pick< diff --git a/packages/x-date-pickers/src/internals/hooks/useUtils.ts b/packages/x-date-pickers/src/internals/hooks/useUtils.ts index 9ce0b0102bcdb..2759b1b050785 100644 --- a/packages/x-date-pickers/src/internals/hooks/useUtils.ts +++ b/packages/x-date-pickers/src/internals/hooks/useUtils.ts @@ -5,9 +5,9 @@ import { } from '../../LocalizationProvider/LocalizationProvider'; import { DEFAULT_LOCALE } from '../../locales/enUS'; import { PickersLocaleText } from '../../locales/utils/pickersLocaleTextApi'; -import { PickersTimezone } from '../../models'; +import { PickersTimezone, PickerValidDate } from '../../models'; -export const useLocalizationContext = () => { +export const useLocalizationContext = () => { const localization = React.useContext(MuiPickersAdapterContext); if (localization === null) { throw new Error( @@ -45,13 +45,15 @@ export const useLocalizationContext = () => { ); }; -export const useUtils = () => useLocalizationContext().utils; +export const useUtils = () => useLocalizationContext().utils; -export const useDefaultDates = () => useLocalizationContext().defaultDates; +export const useDefaultDates = () => + useLocalizationContext().defaultDates; -export const useLocaleText = () => useLocalizationContext().localeText; +export const useLocaleText = () => + useLocalizationContext().localeText; -export const useNow = (timezone: PickersTimezone): TDate => { +export const useNow = (timezone: PickersTimezone): TDate => { const utils = useUtils(); const now = React.useRef() as React.MutableRefObject; diff --git a/packages/x-date-pickers/src/internals/hooks/useValidation.ts b/packages/x-date-pickers/src/internals/hooks/useValidation.ts index 1742634d63b5b..406dcf61d0db8 100644 --- a/packages/x-date-pickers/src/internals/hooks/useValidation.ts +++ b/packages/x-date-pickers/src/internals/hooks/useValidation.ts @@ -1,6 +1,7 @@ import * as React from 'react'; import { useLocalizationContext } from './useUtils'; import { MuiPickersAdapterContextValue } from '../../LocalizationProvider/LocalizationProvider'; +import { PickerValidDate } from '../../models'; interface ValidationCommonProps { /** @@ -27,13 +28,18 @@ export type InferError = ? Parameters>[0] : never; -export type Validator = (params: { +export type Validator = (params: { adapter: MuiPickersAdapterContextValue; value: TValue; props: Omit; }) => TError; -export function useValidation( +export function useValidation< + TValue, + TDate extends PickerValidDate, + TError, + TValidationProps extends {}, +>( props: ValidationProps, validate: Validator, isSameError: (a: TError, b: TError | null) => boolean, diff --git a/packages/x-date-pickers/src/internals/hooks/useValueWithTimezone.ts b/packages/x-date-pickers/src/internals/hooks/useValueWithTimezone.ts index 3bac13012c37f..dd892c5d1c9da 100644 --- a/packages/x-date-pickers/src/internals/hooks/useValueWithTimezone.ts +++ b/packages/x-date-pickers/src/internals/hooks/useValueWithTimezone.ts @@ -3,14 +3,18 @@ import useEventCallback from '@mui/utils/useEventCallback'; import useControlled from '@mui/utils/useControlled'; import { useUtils } from './useUtils'; import type { PickerValueManager } from './usePicker'; -import { PickersTimezone } from '../../models'; +import { PickersTimezone, PickerValidDate } from '../../models'; /** * Hooks making sure that: * - The value returned by `onChange` always have the timezone of `props.value` or `props.defaultValue` if defined * - The value rendered is always the one from `props.timezone` if defined */ -export const useValueWithTimezone = void>({ +export const useValueWithTimezone = < + TDate extends PickerValidDate, + TValue, + TChange extends (...params: any[]) => void, +>({ timezone: timezoneProp, value: valueProp, defaultValue, @@ -60,7 +64,7 @@ export const useValueWithTimezone = void, >({ diff --git a/packages/x-date-pickers/src/internals/hooks/useViews.tsx b/packages/x-date-pickers/src/internals/hooks/useViews.tsx index 8f120dde32635..c5c25387d2bf5 100644 --- a/packages/x-date-pickers/src/internals/hooks/useViews.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useViews.tsx @@ -4,8 +4,9 @@ import { unstable_useControlled as useControlled } from '@mui/utils'; import type { PickerSelectionState } from './usePicker'; import { MakeOptional } from '../models/helpers'; import { DateOrTimeViewWithMeridiem } from '../models'; +import { PickerValidDate } from '../../models'; -export type PickerOnChangeFn = ( +export type PickerOnChangeFn = ( date: TDate | null, selectionState?: PickerSelectionState, ) => void; diff --git a/packages/x-date-pickers/src/internals/models/fields.ts b/packages/x-date-pickers/src/internals/models/fields.ts index 552dfb3bef9d3..f46af981ad9ac 100644 --- a/packages/x-date-pickers/src/internals/models/fields.ts +++ b/packages/x-date-pickers/src/internals/models/fields.ts @@ -1,10 +1,14 @@ import * as React from 'react'; import { TextFieldProps } from '@mui/material/TextField'; import type { UseFieldInternalProps } from '../hooks/useField'; -import type { FieldSection } from '../../models'; +import { FieldSection, PickerValidDate } from '../../models'; -export interface BaseFieldProps - extends Omit, 'format'> { +export interface BaseFieldProps< + TValue, + TDate extends PickerValidDate, + TSection extends FieldSection, + TError, +> extends Omit, 'format'> { className?: string; format?: string; disabled?: boolean; diff --git a/packages/x-date-pickers/src/internals/models/props/basePickerProps.tsx b/packages/x-date-pickers/src/internals/models/props/basePickerProps.tsx index ae4f8a9b8d7f9..9d0b473af2dd8 100644 --- a/packages/x-date-pickers/src/internals/models/props/basePickerProps.tsx +++ b/packages/x-date-pickers/src/internals/models/props/basePickerProps.tsx @@ -6,13 +6,14 @@ import { PickersInputComponentLocaleText } from '../../../locales/utils/pickersL import type { UsePickerViewsProps } from '../../hooks/usePicker/usePickerViews'; import { MakeOptional } from '../helpers'; import { DateOrTimeViewWithMeridiem } from '../common'; +import { PickerValidDate } from '../../../models'; /** * Props common to all pickers after applying the default props on each picker. */ export interface BasePickerProps< TValue, - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TError, TExternalProps extends UsePickerViewsProps, @@ -35,7 +36,7 @@ export interface BasePickerProps< */ export interface BasePickerInputProps< TValue, - TDate, + TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TError, > extends Omit< diff --git a/packages/x-date-pickers/src/internals/models/props/clock.ts b/packages/x-date-pickers/src/internals/models/props/clock.ts index 8c783c1ac3e67..ff5fa599f6cdb 100644 --- a/packages/x-date-pickers/src/internals/models/props/clock.ts +++ b/packages/x-date-pickers/src/internals/models/props/clock.ts @@ -1,12 +1,12 @@ import { SxProps, Theme } from '@mui/material/styles'; import { BaseTimeValidationProps, TimeValidationProps } from '../validation'; -import { TimeStepOptions, TimezoneProps } from '../../../models'; +import { PickerValidDate, TimeStepOptions, TimezoneProps } from '../../../models'; import type { ExportedDigitalClockProps } from '../../../DigitalClock/DigitalClock.types'; import type { ExportedMultiSectionDigitalClockProps } from '../../../MultiSectionDigitalClock/MultiSectionDigitalClock.types'; import type { ExportedUseViewsOptions } from '../../hooks/useViews'; import { TimeViewWithMeridiem } from '../common'; -export interface ExportedBaseClockProps +export interface ExportedBaseClockProps extends TimeValidationProps, BaseTimeValidationProps, TimezoneProps { @@ -17,7 +17,7 @@ export interface ExportedBaseClockProps ampm?: boolean; } -export interface BaseClockProps +export interface BaseClockProps extends ExportedUseViewsOptions, ExportedBaseClockProps { className?: string; @@ -52,7 +52,7 @@ export interface BaseClockProps referenceDate?: TDate; } -export interface DesktopOnlyTimePickerProps +export interface DesktopOnlyTimePickerProps extends Omit, 'timeStep'>, Omit, 'timeSteps'> { /** diff --git a/packages/x-date-pickers/src/internals/models/validation.ts b/packages/x-date-pickers/src/internals/models/validation.ts index d933b83ecb628..aee8f2a3833e9 100644 --- a/packages/x-date-pickers/src/internals/models/validation.ts +++ b/packages/x-date-pickers/src/internals/models/validation.ts @@ -1,4 +1,4 @@ -import { TimeView } from '../../models'; +import { PickerValidDate, TimeView } from '../../models'; interface FutureAndPastValidationProps { /** @@ -22,7 +22,7 @@ export interface BaseTimeValidationProps extends FutureAndPastValidationProps {} /** * Props used to validate a time value. */ -export interface TimeValidationProps { +export interface TimeValidationProps { /** * Minimal selectable time. * The date part of the object will be ignored unless `props.disableIgnoringDatePartForTimeValidation === true`. @@ -57,7 +57,8 @@ export interface TimeValidationProps { * Validation props common to all the date views. * All these props have a default value when used inside a field / picker / calendar. */ -export interface BaseDateValidationProps extends FutureAndPastValidationProps { +export interface BaseDateValidationProps + extends FutureAndPastValidationProps { /** * Maximal selectable date. */ @@ -71,7 +72,7 @@ export interface BaseDateValidationProps extends FutureAndPastValidationP /** * Props used to validate a date value (validates day + month + year). */ -export interface DayValidationProps { +export interface DayValidationProps { /** * Disable specific date. * @@ -87,7 +88,7 @@ export interface DayValidationProps { /** * Props used to validate a month value */ -export interface MonthValidationProps { +export interface MonthValidationProps { /** * Disable specific month. * @template TDate @@ -100,7 +101,7 @@ export interface MonthValidationProps { /** * Props used to validate a year value */ -export interface YearValidationProps { +export interface YearValidationProps { /** * Disable specific year. * @template TDate @@ -113,7 +114,7 @@ export interface YearValidationProps { /** * Props used to validate a date time value. */ -export interface DateTimeValidationProps { +export interface DateTimeValidationProps { /** * Minimal selectable moment of time with binding to date, to set min time in each day use `minTime`. */ diff --git a/packages/x-date-pickers/src/internals/utils/date-time-utils.ts b/packages/x-date-pickers/src/internals/utils/date-time-utils.ts index 61f4daa693c15..0be0869483c4b 100644 --- a/packages/x-date-pickers/src/internals/utils/date-time-utils.ts +++ b/packages/x-date-pickers/src/internals/utils/date-time-utils.ts @@ -2,6 +2,7 @@ import { DateOrTimeView, DateView, MuiPickersAdapter, + PickerValidDate, TimeStepOptions, TimeView, } from '../../models'; @@ -11,8 +12,8 @@ import { DateOrTimeViewWithMeridiem } from '../models'; import { DesktopOnlyTimePickerProps } from '../models/props/clock'; import { DefaultizedProps } from '../models/helpers'; -export const resolveDateTimeFormat = ( - utils: MuiPickersAdapter, +export const resolveDateTimeFormat = ( + utils: MuiPickersAdapter, { views, format, ...other }: { format?: string; views: readonly DateOrTimeView[]; ampm: boolean }, ) => { if (format) { @@ -58,13 +59,15 @@ const resolveViews = (24 * 60) / ((timeSteps.hours ?? 1) * (timeSteps.minutes ?? 5)) <= threshold; -interface DefaultizedTimeViewsProps +interface DefaultizedTimeViewsProps extends DefaultizedProps, 'ampm'> { views: readonly TView[]; } -interface DefaultizedTimeViewsResponse - extends Required< +interface DefaultizedTimeViewsResponse< + TDate extends PickerValidDate, + TView = DateOrTimeViewWithMeridiem, +> extends Required< Pick< DefaultizedTimeViewsProps, 'thresholdToRenderTimeInASingleColumn' | 'timeSteps' | 'views' @@ -74,7 +77,7 @@ interface DefaultizedTimeViewsResponse({ diff --git a/packages/x-date-pickers/src/internals/utils/date-utils.ts b/packages/x-date-pickers/src/internals/utils/date-utils.ts index ea444ec19736a..639332f7dc49e 100644 --- a/packages/x-date-pickers/src/internals/utils/date-utils.ts +++ b/packages/x-date-pickers/src/internals/utils/date-utils.ts @@ -1,8 +1,14 @@ -import { DateView, FieldValueType, MuiPickersAdapter, PickersTimezone } from '../../models'; +import { + DateView, + FieldValueType, + MuiPickersAdapter, + PickersTimezone, + PickerValidDate, +} from '../../models'; import { DateOrTimeViewWithMeridiem } from '../models'; import { areViewsEqual } from './views'; -interface FindClosestDateParams { +interface FindClosestDateParams { date: TDate; disableFuture?: boolean; disablePast?: boolean; @@ -13,7 +19,7 @@ interface FindClosestDateParams { timezone: PickersTimezone; } -export const findClosestEnabledDate = ({ +export const findClosestEnabledDate = ({ date, disableFuture, disablePast, @@ -74,12 +80,12 @@ export const findClosestEnabledDate = ({ return null; }; -export const replaceInvalidDateByNull = ( +export const replaceInvalidDateByNull = ( utils: MuiPickersAdapter, value: TDate | null, ) => (value == null || !utils.isValid(value) ? null : value); -export const applyDefaultDate = ( +export const applyDefaultDate = ( utils: MuiPickersAdapter, value: TDate | null | undefined, defaultValue: TDate, @@ -91,7 +97,11 @@ export const applyDefaultDate = ( return value; }; -export const areDatesEqual = (utils: MuiPickersAdapter, a: TDate, b: TDate) => { +export const areDatesEqual = ( + utils: MuiPickersAdapter, + a: TDate, + b: TDate, +) => { if (!utils.isValid(a) && a != null && !utils.isValid(b) && b != null) { return true; } @@ -99,7 +109,10 @@ export const areDatesEqual = (utils: MuiPickersAdapter, a: TDate, return utils.isEqual(a, b); }; -export const getMonthsInYear = (utils: MuiPickersAdapter, year: TDate) => { +export const getMonthsInYear = ( + utils: MuiPickersAdapter, + year: TDate, +) => { const firstMonth = utils.startOfYear(year); const months = [firstMonth]; @@ -111,7 +124,7 @@ export const getMonthsInYear = (utils: MuiPickersAdapter, year: TD return months; }; -export const mergeDateAndTime = ( +export const mergeDateAndTime = ( utils: MuiPickersAdapter, dateParam: TDate, timeParam: TDate, @@ -124,7 +137,7 @@ export const mergeDateAndTime = ( return mergedDate; }; -export const getTodayDate = ( +export const getTodayDate = ( utils: MuiPickersAdapter, timezone: PickersTimezone, valueType?: FieldValueType, @@ -133,7 +146,10 @@ export const getTodayDate = ( ? utils.startOfDay(utils.date(undefined, timezone)) : utils.date(undefined, timezone); -export const formatMeridiem = (utils: MuiPickersAdapter, meridiem: 'am' | 'pm') => { +export const formatMeridiem = ( + utils: MuiPickersAdapter, + meridiem: 'am' | 'pm', +) => { const date = utils.setHours(utils.date()!, meridiem === 'am' ? 2 : 14); return utils.format(date, 'meridiem'); }; @@ -142,8 +158,8 @@ const dateViews = ['year', 'month', 'day']; export const isDatePickerView = (view: DateOrTimeViewWithMeridiem): view is DateView => dateViews.includes(view); -export const resolveDateFormat = ( - utils: MuiPickersAdapter, +export const resolveDateFormat = ( + utils: MuiPickersAdapter, { format, views }: { format?: string; views: readonly DateView[] }, isInToolbar: boolean, ) => { @@ -184,7 +200,10 @@ export const resolveDateFormat = ( return formats.keyboardDate; }; -export const getWeekdays = (utils: MuiPickersAdapter, date: TDate) => { +export const getWeekdays = ( + utils: MuiPickersAdapter, + date: TDate, +) => { const start = utils.startOfWeek(date); return [0, 1, 2, 3, 4, 5, 6].map((diff) => utils.addDays(start, diff)); }; diff --git a/packages/x-date-pickers/src/internals/utils/getDefaultReferenceDate.ts b/packages/x-date-pickers/src/internals/utils/getDefaultReferenceDate.ts index c93f2fda56dae..7d31ee708ee08 100644 --- a/packages/x-date-pickers/src/internals/utils/getDefaultReferenceDate.ts +++ b/packages/x-date-pickers/src/internals/utils/getDefaultReferenceDate.ts @@ -1,8 +1,8 @@ import { createIsAfterIgnoreDatePart } from './time-utils'; import { mergeDateAndTime, getTodayDate } from './date-utils'; -import { FieldSection, MuiPickersAdapter, PickersTimezone } from '../../models'; +import { FieldSection, MuiPickersAdapter, PickersTimezone, PickerValidDate } from '../../models'; -export interface GetDefaultReferenceDateProps { +export interface GetDefaultReferenceDateProps { maxDate?: TDate; minDate?: TDate; minTime?: TDate; @@ -28,7 +28,11 @@ export const getSectionTypeGranularity = (sections: FieldSection[]) => ), ); -const roundDate = (utils: MuiPickersAdapter, granularity: number, date: TDate) => { +const roundDate = ( + utils: MuiPickersAdapter, + granularity: number, + date: TDate, +) => { if (granularity === SECTION_TYPE_GRANULARITY.year) { return utils.startOfYear(date); } @@ -54,7 +58,7 @@ const roundDate = (utils: MuiPickersAdapter, granularity: number, return roundedDate; }; -export const getDefaultReferenceDate = ({ +export const getDefaultReferenceDate = ({ props, utils, granularity, diff --git a/packages/x-date-pickers/src/internals/utils/time-utils.ts b/packages/x-date-pickers/src/internals/utils/time-utils.ts index 133ce1080c6a6..01faa1cf78626 100644 --- a/packages/x-date-pickers/src/internals/utils/time-utils.ts +++ b/packages/x-date-pickers/src/internals/utils/time-utils.ts @@ -1,4 +1,4 @@ -import { MuiPickersAdapter, TimeView } from '../../models'; +import { MuiPickersAdapter, PickerValidDate, TimeView } from '../../models'; import { DateOrTimeViewWithMeridiem, TimeViewWithMeridiem } from '../models'; import { areViewsEqual } from './views'; @@ -11,7 +11,7 @@ export const isInternalTimeView = ( export type Meridiem = 'am' | 'pm'; -export const getMeridiem = ( +export const getMeridiem = ( date: TDate | null, utils: MuiPickersAdapter, ): Meridiem | null => { @@ -33,7 +33,7 @@ export const convertValueToMeridiem = (value: number, meridiem: Meridiem | null, return value; }; -export const convertToMeridiem = ( +export const convertToMeridiem = ( time: TDate, meridiem: Meridiem, ampm: boolean, @@ -43,12 +43,18 @@ export const convertToMeridiem = ( return utils.setHours(time, newHoursAmount); }; -export const getSecondsInDay = (date: TDate, utils: MuiPickersAdapter) => { +export const getSecondsInDay = ( + date: TDate, + utils: MuiPickersAdapter, +) => { return utils.getHours(date) * 3600 + utils.getMinutes(date) * 60 + utils.getSeconds(date); }; export const createIsAfterIgnoreDatePart = - (disableIgnoringDatePartForTimeValidation: boolean, utils: MuiPickersAdapter) => + ( + disableIgnoringDatePartForTimeValidation: boolean, + utils: MuiPickersAdapter, + ) => (dateLeft: TDate, dateRight: TDate) => { if (disableIgnoringDatePartForTimeValidation) { return utils.isAfter(dateLeft, dateRight); @@ -57,8 +63,8 @@ export const createIsAfterIgnoreDatePart = return getSecondsInDay(dateLeft, utils) > getSecondsInDay(dateRight, utils); }; -export const resolveTimeFormat = ( - utils: MuiPickersAdapter, +export const resolveTimeFormat = ( + utils: MuiPickersAdapter, { format, views, ampm }: { format?: string; views: readonly TimeView[]; ampm: boolean }, ) => { if (format != null) { diff --git a/packages/x-date-pickers/src/internals/utils/validation/validateDate.ts b/packages/x-date-pickers/src/internals/utils/validation/validateDate.ts index 6cd8b41ff7c63..363b13a96f70c 100644 --- a/packages/x-date-pickers/src/internals/utils/validation/validateDate.ts +++ b/packages/x-date-pickers/src/internals/utils/validation/validateDate.ts @@ -5,11 +5,11 @@ import { MonthValidationProps, YearValidationProps, } from '../../models/validation'; -import { DateValidationError, TimezoneProps } from '../../../models'; +import { DateValidationError, PickerValidDate, TimezoneProps } from '../../../models'; import { applyDefaultDate } from '../date-utils'; import { DefaultizedProps } from '../../models/helpers'; -export interface DateComponentValidationProps +export interface DateComponentValidationProps extends DayValidationProps, MonthValidationProps, YearValidationProps, diff --git a/packages/x-date-pickers/src/internals/utils/validation/validateDateTime.ts b/packages/x-date-pickers/src/internals/utils/validation/validateDateTime.ts index 30a39602fb47b..ff14f93ac1eb4 100644 --- a/packages/x-date-pickers/src/internals/utils/validation/validateDateTime.ts +++ b/packages/x-date-pickers/src/internals/utils/validation/validateDateTime.ts @@ -1,9 +1,9 @@ import { Validator } from '../../hooks/useValidation'; import { validateDate, DateComponentValidationProps } from './validateDate'; import { validateTime, TimeComponentValidationProps } from './validateTime'; -import { DateTimeValidationError } from '../../../models'; +import { DateTimeValidationError, PickerValidDate } from '../../../models'; -export interface DateTimeComponentValidationProps +export interface DateTimeComponentValidationProps extends DateComponentValidationProps, TimeComponentValidationProps {} diff --git a/packages/x-date-pickers/src/internals/utils/validation/validateTime.ts b/packages/x-date-pickers/src/internals/utils/validation/validateTime.ts index e21efee801c33..c3d109e7ec0f9 100644 --- a/packages/x-date-pickers/src/internals/utils/validation/validateTime.ts +++ b/packages/x-date-pickers/src/internals/utils/validation/validateTime.ts @@ -1,10 +1,10 @@ import { createIsAfterIgnoreDatePart } from '../time-utils'; import { Validator } from '../../hooks/useValidation'; import { BaseTimeValidationProps, TimeValidationProps } from '../../models/validation'; -import { TimeValidationError, TimezoneProps } from '../../../models'; +import { PickerValidDate, TimeValidationError, TimezoneProps } from '../../../models'; import { DefaultizedProps } from '../../models/helpers'; -export interface TimeComponentValidationProps +export interface TimeComponentValidationProps extends Required, TimeValidationProps, DefaultizedProps {} diff --git a/packages/x-date-pickers/src/internals/utils/valueManagers.ts b/packages/x-date-pickers/src/internals/utils/valueManagers.ts index 02efbeafe40e3..e00437056044e 100644 --- a/packages/x-date-pickers/src/internals/utils/valueManagers.ts +++ b/packages/x-date-pickers/src/internals/utils/valueManagers.ts @@ -4,6 +4,7 @@ import { TimeValidationError, DateTimeValidationError, FieldSection, + PickerValidDate, } from '../../models'; import type { FieldValueManager } from '../hooks/useField'; import { areDatesEqual, getTodayDate, replaceInvalidDateByNull } from './date-utils'; @@ -15,7 +16,7 @@ import { export type SingleItemPickerValueManager< TValue = any, - TDate = any, + TDate extends PickerValidDate = any, TError extends DateValidationError | TimeValidationError | DateTimeValidationError = any, > = PickerValueManager; diff --git a/packages/x-date-pickers/src/locales/utils/pickersLocaleTextApi.ts b/packages/x-date-pickers/src/locales/utils/pickersLocaleTextApi.ts index cb738d79bb873..6e0aca44083b1 100644 --- a/packages/x-date-pickers/src/locales/utils/pickersLocaleTextApi.ts +++ b/packages/x-date-pickers/src/locales/utils/pickersLocaleTextApi.ts @@ -1,5 +1,11 @@ import { TimeViewWithMeridiem } from '../../internals/models'; -import { DateView, TimeView, MuiPickersAdapter, FieldSectionContentType } from '../../models'; +import { + DateView, + TimeView, + MuiPickersAdapter, + FieldSectionContentType, + PickerValidDate, +} from '../../models'; export interface PickersComponentSpecificLocaleText { /** @@ -24,7 +30,7 @@ export interface PickersComponentSpecificLocaleText { dateRangePickerToolbarTitle: string; } -export interface PickersComponentAgnosticLocaleText { +export interface PickersComponentAgnosticLocaleText { // Calendar navigation previousMonth: string; nextMonth: string; @@ -91,18 +97,20 @@ export interface PickersComponentAgnosticLocaleText { fieldMeridiemPlaceholder: (params: { format: string }) => string; } -export interface PickersLocaleText +export interface PickersLocaleText extends PickersComponentAgnosticLocaleText, PickersComponentSpecificLocaleText {} -export type PickersInputLocaleText = Partial>; +export type PickersInputLocaleText = Partial< + PickersLocaleText +>; /** * Translations that can be provided directly to the picker components. * It contains some generic translations like `toolbarTitle` * which will be dispatched to various translations keys in `PickersLocaleText`, depending on the pickers received them. */ -export interface PickersInputComponentLocaleText +export interface PickersInputComponentLocaleText extends Partial> { /** * Title displayed in the toolbar of this picker. @@ -114,6 +122,6 @@ export interface PickersInputComponentLocaleText export type PickersTranslationKeys = keyof PickersLocaleText; export type LocalizedComponent< - TDate, + TDate extends PickerValidDate, Props extends { localeText?: PickersInputComponentLocaleText }, > = Omit & { localeText?: PickersInputLocaleText }; diff --git a/packages/x-date-pickers/src/models/adapters.ts b/packages/x-date-pickers/src/models/adapters.ts index 199ec3bd03811..ae4cf04ddff23 100644 --- a/packages/x-date-pickers/src/models/adapters.ts +++ b/packages/x-date-pickers/src/models/adapters.ts @@ -1,5 +1,6 @@ import { FieldSectionContentType, FieldSectionType } from './fields'; import { PickersTimezone } from './timezone'; +import { PickerValidDate } from './pickers'; export interface AdapterFormats { // Token formats @@ -153,7 +154,7 @@ export type DateBuilderReturnType = ? null : TDate; -export interface MuiPickersAdapter { +export interface MuiPickersAdapter { /** * A boolean confirming that the adapter used is an MUI adapter. */ diff --git a/packages/x-date-pickers/src/models/fields.ts b/packages/x-date-pickers/src/models/fields.ts index a49895354f1ec..8f88dc742f3b9 100644 --- a/packages/x-date-pickers/src/models/fields.ts +++ b/packages/x-date-pickers/src/models/fields.ts @@ -1,5 +1,6 @@ import * as React from 'react'; import type { BaseFieldProps } from '../internals/models/fields'; +import { PickerValidDate } from './pickers'; export type FieldSectionType = | 'year' @@ -125,10 +126,14 @@ export type FieldSelectedSections = /** * Props the single input field can receive when used inside a picker. - * Only contains what the MUI component are passing to the field, not what users can pass using the `props.slotProps.field`. + * Only contains what the MUI components are passing to the field, not what users can pass using the `props.slotProps.field`. */ -export interface BaseSingleInputFieldProps - extends BaseFieldProps { +export interface BaseSingleInputFieldProps< + TValue, + TDate extends PickerValidDate, + TSection extends FieldSection, + TError, +> extends BaseFieldProps { label?: React.ReactNode; id?: string; name?: string; diff --git a/packages/x-date-pickers/src/models/pickers.ts b/packages/x-date-pickers/src/models/pickers.ts index a51d9b1bff8ac..f093acb08b6f9 100644 --- a/packages/x-date-pickers/src/models/pickers.ts +++ b/packages/x-date-pickers/src/models/pickers.ts @@ -8,3 +8,7 @@ export interface PickerChangeHandlerContext { */ shortcut?: PickersShortcutsItemContext; } + +export interface PickerValidDateLookup {} + +export type PickerValidDate = PickerValidDateLookup[keyof PickerValidDateLookup]; diff --git a/packages/x-date-pickers/src/tests/fieldKeyboardInteraction.test.tsx b/packages/x-date-pickers/src/tests/fieldKeyboardInteraction.test.tsx index 948853ed504fd..b2fdefc1e22d9 100644 --- a/packages/x-date-pickers/src/tests/fieldKeyboardInteraction.test.tsx +++ b/packages/x-date-pickers/src/tests/fieldKeyboardInteraction.test.tsx @@ -12,7 +12,7 @@ import { expectInputValue, } from 'test/utils/pickers'; import { DateTimeField } from '@mui/x-date-pickers/DateTimeField'; -import { FieldSectionType, MuiPickersAdapter } from '@mui/x-date-pickers/models'; +import { FieldSectionType, MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; import { getDateSectionConfigFromFormatToken, cleanLeadingZeros, @@ -20,7 +20,7 @@ import { const testDate = '2018-05-15T09:35:10'; -function updateDate( +function updateDate( date: TDate, adapter: MuiPickersAdapter, sectionType: FieldSectionType, @@ -182,7 +182,7 @@ adapterToTest.forEach((adapterName) => { return valueStr; }; - const testKeyPress = ({ + const testKeyPress = ({ key, format, initialValue, diff --git a/packages/x-date-pickers/src/themeAugmentation/props.d.ts b/packages/x-date-pickers/src/themeAugmentation/props.d.ts index 84feaf48aab51..066a1d694b3ec 100644 --- a/packages/x-date-pickers/src/themeAugmentation/props.d.ts +++ b/packages/x-date-pickers/src/themeAugmentation/props.d.ts @@ -17,7 +17,7 @@ import { PickerPopperProps } from '../internals/components/PickersPopper'; import { PickersToolbarProps } from '../internals/components/PickersToolbar'; import { PickersToolbarButtonProps } from '../internals/components/PickersToolbarButton'; import { ExportedPickersToolbarTextProps } from '../internals/components/PickersToolbarText'; -import { DateOrTimeView } from '../models'; +import { DateOrTimeView, PickerValidDate } from '../models'; import { DatePickerProps, DatePickerToolbarProps } from '../DatePicker'; import { DesktopDatePickerProps } from '../DesktopDatePicker'; @@ -55,25 +55,25 @@ import { import { PickersSectionListProps } from '../PickersSectionList'; export interface PickersComponentsPropsList { - MuiClock: ClockProps; + MuiClock: ClockProps; MuiClockNumber: ClockNumberProps; MuiClockPointer: ClockPointerProps; - MuiDateCalendar: DateCalendarProps; - MuiDateField: DateFieldProps; - MuiDatePickerToolbar: DatePickerToolbarProps; - MuiDateTimeField: DateTimeFieldProps; + MuiDateCalendar: DateCalendarProps; + MuiDateField: DateFieldProps; + MuiDatePickerToolbar: DatePickerToolbarProps; + MuiDateTimeField: DateTimeFieldProps; MuiDateTimePickerTabs: DateTimePickerTabsProps; - MuiDateTimePickerToolbar: DateTimePickerToolbarProps; - MuiDayCalendar: DayCalendarProps; + MuiDateTimePickerToolbar: DateTimePickerToolbarProps; + MuiDayCalendar: DayCalendarProps; MuiDayCalendarSkeleton: DayCalendarSkeletonProps; - MuiDigitalClock: ExportedDigitalClockProps; - MuiLocalizationProvider: LocalizationProviderProps; - MuiMonthCalendar: MonthCalendarProps; - MuiMultiSectionDigitalClock: MultiSectionDigitalClockProps; + MuiDigitalClock: ExportedDigitalClockProps; + MuiLocalizationProvider: LocalizationProviderProps; + MuiMonthCalendar: MonthCalendarProps; + MuiMultiSectionDigitalClock: MultiSectionDigitalClockProps; MuiMultiSectionDigitalClockSection: ExportedMultiSectionDigitalClockSectionProps; MuiPickersArrowSwitcher: ExportedPickersArrowSwitcherProps; - MuiPickersCalendarHeader: ExportedPickersCalendarHeaderProps; - MuiPickersDay: PickersDayProps; + MuiPickersCalendarHeader: ExportedPickersCalendarHeaderProps; + MuiPickersDay: PickersDayProps; MuiPickersFadeTransitionGroup: PickersFadeTransitionGroupProps; MuiPickersMonth: ExportedPickersMonthProps; MuiPickersPopper: PickerPopperProps; @@ -81,30 +81,30 @@ export interface PickersComponentsPropsList { MuiPickersToolbar: PickersToolbarProps; MuiPickersToolbarButton: PickersToolbarButtonProps; MuiPickersToolbarText: ExportedPickersToolbarTextProps; - MuiPickersLayout: PickersLayoutProps; + MuiPickersLayout: PickersLayoutProps; MuiPickersYear: ExportedPickersYearProps; - MuiTimeClock: TimeClockProps; - MuiTimeField: TimeFieldProps; - MuiTimePickerToolbar: TimePickerToolbarProps; - MuiYearCalendar: YearCalendarProps; + MuiTimeClock: TimeClockProps; + MuiTimeField: TimeFieldProps; + MuiTimePickerToolbar: TimePickerToolbarProps; + MuiYearCalendar: YearCalendarProps; // Date Pickers - MuiDatePicker: DatePickerProps; - MuiDesktopDatePicker: DesktopDatePickerProps; - MuiMobileDatePicker: MobileDatePickerProps; - MuiStaticDatePicker: StaticDatePickerProps; + MuiDatePicker: DatePickerProps; + MuiDesktopDatePicker: DesktopDatePickerProps; + MuiMobileDatePicker: MobileDatePickerProps; + MuiStaticDatePicker: StaticDatePickerProps; // Time Pickers - MuiTimePicker: TimePickerProps; - MuiDesktopTimePicker: DesktopTimePickerProps; - MuiMobileTimePicker: MobileTimePickerProps; - MuiStaticTimePicker: StaticTimePickerProps; + MuiTimePicker: TimePickerProps; + MuiDesktopTimePicker: DesktopTimePickerProps; + MuiMobileTimePicker: MobileTimePickerProps; + MuiStaticTimePicker: StaticTimePickerProps; // Date Time Pickers - MuiDateTimePicker: DateTimePickerProps; - MuiDesktopDateTimePicker: DesktopDateTimePickerProps; - MuiMobileDateTimePicker: MobileDateTimePickerProps; - MuiStaticDateTimePicker: StaticDateTimePickerProps; + MuiDateTimePicker: DateTimePickerProps; + MuiDesktopDateTimePicker: DesktopDateTimePickerProps; + MuiMobileDateTimePicker: MobileDateTimePickerProps; + MuiStaticDateTimePicker: StaticDateTimePickerProps; // V7 Picker's TextField MuiPickersTextField: PickersTextFieldProps; diff --git a/packages/x-date-pickers/src/timeViewRenderers/timeViewRenderers.tsx b/packages/x-date-pickers/src/timeViewRenderers/timeViewRenderers.tsx index 568a09abaf841..6d9d631c6d0df 100644 --- a/packages/x-date-pickers/src/timeViewRenderers/timeViewRenderers.tsx +++ b/packages/x-date-pickers/src/timeViewRenderers/timeViewRenderers.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { TimeClock, TimeClockProps } from '../TimeClock'; -import { TimeView } from '../models'; +import { PickerValidDate, TimeView } from '../models'; import { DigitalClock, DigitalClockProps } from '../DigitalClock'; import { BaseClockProps } from '../internals/models/props/clock'; import { @@ -20,7 +20,7 @@ export type TimeViewRendererProps< views: readonly TView[]; }; -export const renderTimeViewClock = ({ +export const renderTimeViewClock = ({ view, onViewChange, focusedView, @@ -82,7 +82,7 @@ export const renderTimeViewClock = ({ /> ); -export const renderDigitalClockTimeView = ({ +export const renderDigitalClockTimeView = ({ view, onViewChange, focusedView, @@ -147,7 +147,7 @@ export const renderDigitalClockTimeView = ({ /> ); -export const renderMultiSectionDigitalClockTimeView = ({ +export const renderMultiSectionDigitalClockTimeView = ({ view, onViewChange, focusedView, diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index 5343b4cafe9bf..e56672a9a27df 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -312,6 +312,8 @@ { "name": "pickersYearClasses", "kind": "Variable" }, { "name": "PickersYearClasses", "kind": "Interface" }, { "name": "PickersYearClassKey", "kind": "TypeAlias" }, + { "name": "PickerValidDate", "kind": "TypeAlias" }, + { "name": "PickerValidDateLookup", "kind": "Interface" }, { "name": "RangeFieldSection", "kind": "Interface" }, { "name": "RangePosition", "kind": "TypeAlias" }, { "name": "renderDateRangeViewCalendar", "kind": "Variable" }, diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json index e7f8314be788d..db0a05484f4f3 100644 --- a/scripts/x-date-pickers.exports.json +++ b/scripts/x-date-pickers.exports.json @@ -233,6 +233,8 @@ { "name": "pickersYearClasses", "kind": "Variable" }, { "name": "PickersYearClasses", "kind": "Interface" }, { "name": "PickersYearClassKey", "kind": "TypeAlias" }, + { "name": "PickerValidDate", "kind": "TypeAlias" }, + { "name": "PickerValidDateLookup", "kind": "Interface" }, { "name": "renderDateViewCalendar", "kind": "Variable" }, { "name": "renderDigitalClockTimeView", "kind": "Variable" }, { "name": "renderMultiSectionDigitalClockTimeView", "kind": "Variable" }, diff --git a/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.ts b/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.ts index cf87ef967b2ac..09aa0c0a3ffc3 100644 --- a/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.ts +++ b/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.ts @@ -1,5 +1,5 @@ import createDescribe from '@mui-internal/test-utils/createDescribe'; -import { MuiPickersAdapter } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; import { testCalculations } from './testCalculations'; import { testLocalization } from './testLocalization'; import { testFormat } from './testFormat'; @@ -8,7 +8,7 @@ import { DescribeGregorianAdapterTestSuiteParams, } from './describeGregorianAdapter.types'; -function innerGregorianDescribeAdapter( +function innerGregorianDescribeAdapter( Adapter: new (...args: any) => MuiPickersAdapter, params: DescribeGregorianAdapterParams, ) { @@ -42,15 +42,15 @@ function innerGregorianDescribeAdapter( }); } -type Params = [ +type Params = [ Adapter: new (...args: any) => MuiPickersAdapter, params: DescribeGregorianAdapterParams, ]; type DescribeGregorianAdapter = { - (...args: Params): void; - skip: (...args: Params) => void; - only: (...args: Params) => void; + (...args: Params): void; + skip: (...args: Params) => void; + only: (...args: Params) => void; }; export const describeGregorianAdapter = createDescribe( diff --git a/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.types.ts b/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.types.ts index 052f0a1969422..2f1c49b76d2db 100644 --- a/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.types.ts +++ b/test/utils/pickers/describeGregorianAdapter/describeGregorianAdapter.types.ts @@ -1,6 +1,6 @@ -import { MuiPickersAdapter, PickersTimezone } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter, PickersTimezone, PickerValidDate } from '@mui/x-date-pickers/models'; -export interface DescribeGregorianAdapterParams { +export interface DescribeGregorianAdapterParams { prepareAdapter?: (adapter: MuiPickersAdapter) => void; formatDateTime: string; getLocaleFromDate?: (value: TDate) => string; @@ -9,13 +9,13 @@ export interface DescribeGregorianAdapterParams { frenchLocale: TLocale; } -export interface DescribeGregorianAdapterTestSuiteParams +export interface DescribeGregorianAdapterTestSuiteParams extends Omit, 'frenchLocale'> { adapter: MuiPickersAdapter; adapterTZ: MuiPickersAdapter; adapterFr: MuiPickersAdapter; } -export type DescribeGregorianAdapterTestSuite = ( +export type DescribeGregorianAdapterTestSuite = ( params: DescribeGregorianAdapterTestSuiteParams, ) => void; diff --git a/test/utils/pickers/describeGregorianAdapter/testCalculations.ts b/test/utils/pickers/describeGregorianAdapter/testCalculations.ts index d3c4bed0632f6..e27fc0f3b458a 100644 --- a/test/utils/pickers/describeGregorianAdapter/testCalculations.ts +++ b/test/utils/pickers/describeGregorianAdapter/testCalculations.ts @@ -1,16 +1,19 @@ import { expect } from 'chai'; -import { MuiPickersAdapter, PickersTimezone } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter, PickersTimezone, PickerValidDate } from '@mui/x-date-pickers/models'; import { getDateOffset } from 'test/utils/pickers'; import { DescribeGregorianAdapterTestSuite } from './describeGregorianAdapter.types'; import { TEST_DATE_ISO_STRING, TEST_DATE_LOCALE_STRING } from './describeGregorianAdapter.utils'; /** - * To check if the date has the right offset even after changing it's date parts, + * To check if the date has the right offset even after changing its date parts, * we convert it to a different timezone that always has the same offset, * then we check that both dates have the same hour value. */ // We change to -const expectSameTimeInMonacoTZ = (adapter: MuiPickersAdapter, value: TDate) => { +const expectSameTimeInMonacoTZ = ( + adapter: MuiPickersAdapter, + value: TDate, +) => { const valueInMonacoTz = adapter.setTimezone(value, 'Europe/Monaco'); expect(adapter.getHours(value)).to.equal(adapter.getHours(valueInMonacoTz)); }; diff --git a/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.ts b/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.ts index 4592a70a605d7..ff5ecb2af047d 100644 --- a/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.ts +++ b/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.ts @@ -1,11 +1,11 @@ import createDescribe from '@mui-internal/test-utils/createDescribe'; -import { MuiPickersAdapter } from '@mui/x-date-pickers'; +import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; import { testCalculations } from './testCalculations'; import { testLocalization } from './testLocalization'; import { testFormat } from './testFormat'; import { DescribeHijriAdapterParams } from './describeHijriAdapter.types'; -function innerJalaliDescribeAdapter( +function innerJalaliDescribeAdapter( Adapter: new (...args: any) => MuiPickersAdapter, params: DescribeHijriAdapterParams, ) { diff --git a/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.types.ts b/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.types.ts index 30fb1493e7683..09c2da3616a89 100644 --- a/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.types.ts +++ b/test/utils/pickers/describeHijriAdapter/describeHijriAdapter.types.ts @@ -1,10 +1,10 @@ -import { MuiPickersAdapter } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; export interface DescribeHijriAdapterParams { before?: () => void; after?: () => void; } -export type DescribeHijriAdapterTestSuite = (params: { +export type DescribeHijriAdapterTestSuite = (params: { adapter: MuiPickersAdapter; }) => void; diff --git a/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.ts b/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.ts index a0a699b6adf87..a09f6257d4861 100644 --- a/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.ts +++ b/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.ts @@ -1,11 +1,11 @@ import createDescribe from '@mui-internal/test-utils/createDescribe'; -import { MuiPickersAdapter } from '@mui/x-date-pickers'; +import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; import { testCalculations } from './testCalculations'; import { testLocalization } from './testLocalization'; import { testFormat } from './testFormat'; import { DescribeJalaliAdapterParams } from './describeJalaliAdapter.types'; -function innerJalaliDescribeAdapter( +function innerJalaliDescribeAdapter( Adapter: new (...args: any) => MuiPickersAdapter, params: DescribeJalaliAdapterParams, ) { diff --git a/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.types.ts b/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.types.ts index be7b2904119bd..176319483313f 100644 --- a/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.types.ts +++ b/test/utils/pickers/describeJalaliAdapter/describeJalaliAdapter.types.ts @@ -1,10 +1,10 @@ -import { MuiPickersAdapter } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; export interface DescribeJalaliAdapterParams { before?: () => void; after?: () => void; } -export type DescribeJalaliAdapterTestSuite = (params: { +export type DescribeJalaliAdapterTestSuite = (params: { adapter: MuiPickersAdapter; }) => void; diff --git a/test/utils/pickers/misc.ts b/test/utils/pickers/misc.ts index 97a08af557017..14afbe8208742 100644 --- a/test/utils/pickers/misc.ts +++ b/test/utils/pickers/misc.ts @@ -1,5 +1,5 @@ import sinon from 'sinon'; -import { MuiPickersAdapter } from '@mui/x-date-pickers/models'; +import { MuiPickersAdapter, PickerValidDate } from '@mui/x-date-pickers/models'; import { PickerComponentFamily } from './describe.types'; import { OpenPickerParams } from './openPicker'; @@ -48,7 +48,7 @@ export const getExpectedOnChangeCount = ( return getChangeCountForComponentFamily(componentFamily); }; -export const getDateOffset = ( +export const getDateOffset = ( adapter: MuiPickersAdapter, date: TDate, ) => { @@ -57,7 +57,7 @@ export const getDateOffset = ( return cleanUtcHour * 60; }; -export const formatFullTimeValue = ( +export const formatFullTimeValue = ( adapter: MuiPickersAdapter, value: TDate, ) => { From 3b2d0665cdcf6ffdf1e5a7d021f0a07d8b478c7f Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskii Date: Mon, 5 Feb 2024 13:46:37 +0100 Subject: [PATCH 06/53] [DataGrid] Add support for dialogs in menu actions (#11909) --- .../column-definition/ActionsWithModalGrid.js | 92 ++++++++++++++++ .../ActionsWithModalGrid.tsx | 103 ++++++++++++++++++ .../ActionsWithModalGrid.tsx.preview | 1 + .../column-definition/column-definition.md | 102 +++++++++-------- .../src/components/cell/GridActionsCell.tsx | 14 +-- .../components/cell/GridActionsCellItem.tsx | 47 ++++++-- 6 files changed, 293 insertions(+), 66 deletions(-) create mode 100644 docs/data/data-grid/column-definition/ActionsWithModalGrid.js create mode 100644 docs/data/data-grid/column-definition/ActionsWithModalGrid.tsx create mode 100644 docs/data/data-grid/column-definition/ActionsWithModalGrid.tsx.preview diff --git a/docs/data/data-grid/column-definition/ActionsWithModalGrid.js b/docs/data/data-grid/column-definition/ActionsWithModalGrid.js new file mode 100644 index 0000000000000..7a29da11924c4 --- /dev/null +++ b/docs/data/data-grid/column-definition/ActionsWithModalGrid.js @@ -0,0 +1,92 @@ +import * as React from 'react'; +import { DataGrid, GridActionsCellItem } from '@mui/x-data-grid'; +import DeleteIcon from '@mui/icons-material/Delete'; +import { randomUserName } from '@mui/x-data-grid-generator'; +import Dialog from '@mui/material/Dialog'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogActions from '@mui/material/DialogActions'; +import Button from '@mui/material/Button'; + +const initialRows = [ + { id: 1, name: randomUserName() }, + { id: 2, name: randomUserName() }, + { id: 3, name: randomUserName() }, +]; + +function DeleteUserActionItem({ deleteUser, ...props }) { + const [open, setOpen] = React.useState(false); + + return ( + + setOpen(true)} /> + setOpen(false)} + aria-labelledby="alert-dialog-title" + aria-describedby="alert-dialog-description" + > + Delete this user? + + + This action cannot be undone. + + + + + + + + + ); +} + +export default function ActionsWithModalGrid() { + const [rows, setRows] = React.useState(initialRows); + + const deleteUser = React.useCallback( + (id) => () => { + setTimeout(() => { + setRows((prevRows) => prevRows.filter((row) => row.id !== id)); + }); + }, + [], + ); + + const columns = React.useMemo( + () => [ + { field: 'name', type: 'string' }, + { + field: 'actions', + type: 'actions', + width: 80, + getActions: (params) => [ + } + deleteUser={deleteUser(params.id)} + closeMenuOnClick={false} + />, + ], + }, + ], + [deleteUser], + ); + + return ( +
+ +
+ ); +} diff --git a/docs/data/data-grid/column-definition/ActionsWithModalGrid.tsx b/docs/data/data-grid/column-definition/ActionsWithModalGrid.tsx new file mode 100644 index 0000000000000..e32fd666d9b75 --- /dev/null +++ b/docs/data/data-grid/column-definition/ActionsWithModalGrid.tsx @@ -0,0 +1,103 @@ +import * as React from 'react'; +import { + DataGrid, + GridActionsCellItem, + GridRowId, + GridColDef, + GridActionsCellItemProps, +} from '@mui/x-data-grid'; +import DeleteIcon from '@mui/icons-material/Delete'; +import { randomUserName } from '@mui/x-data-grid-generator'; +import Dialog from '@mui/material/Dialog'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogActions from '@mui/material/DialogActions'; +import Button from '@mui/material/Button'; + +const initialRows = [ + { id: 1, name: randomUserName() }, + { id: 2, name: randomUserName() }, + { id: 3, name: randomUserName() }, +]; + +function DeleteUserActionItem({ + deleteUser, + ...props +}: GridActionsCellItemProps & { deleteUser: () => void }) { + const [open, setOpen] = React.useState(false); + + return ( + + setOpen(true)} /> + setOpen(false)} + aria-labelledby="alert-dialog-title" + aria-describedby="alert-dialog-description" + > + Delete this user? + + + This action cannot be undone. + + + + + + + + + ); +} + +type Row = (typeof initialRows)[number]; + +export default function ActionsWithModalGrid() { + const [rows, setRows] = React.useState(initialRows); + + const deleteUser = React.useCallback( + (id: GridRowId) => () => { + setTimeout(() => { + setRows((prevRows) => prevRows.filter((row) => row.id !== id)); + }); + }, + [], + ); + + const columns = React.useMemo[]>( + () => [ + { field: 'name', type: 'string' }, + { + field: 'actions', + type: 'actions', + width: 80, + getActions: (params) => [ + } + deleteUser={deleteUser(params.id)} + closeMenuOnClick={false} + />, + ], + }, + ], + [deleteUser], + ); + + return ( +
+ +
+ ); +} diff --git a/docs/data/data-grid/column-definition/ActionsWithModalGrid.tsx.preview b/docs/data/data-grid/column-definition/ActionsWithModalGrid.tsx.preview new file mode 100644 index 0000000000000..6f326f7a9cd17 --- /dev/null +++ b/docs/data/data-grid/column-definition/ActionsWithModalGrid.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/data-grid/column-definition/column-definition.md b/docs/data/data-grid/column-definition/column-definition.md index dc73721a1e571..0c1ae990eea6f 100644 --- a/docs/data/data-grid/column-definition/column-definition.md +++ b/docs/data/data-grid/column-definition/column-definition.md @@ -230,6 +230,8 @@ The following are the native column types with their required value types: | `'singleSelect'` | A value in `.valueOptions` | | `'actions'` | Not applicable | +{{"demo": "ColumnTypesGrid.js", "bg": "inline"}} + ### Converting types Default methods, such as filtering and sorting, assume that the type of the values will match the type of the column specified in `type`. @@ -249,57 +251,67 @@ If for any reason, your data type is not the correct one, you can use `valueGett To use most of the column types, you only need to define the `type` property in your column definition. However, some types require additional properties to be set to make them work correctly: -- If the column type is `'singleSelect'`, you also need to set the `valueOptions` property in the respective column definition. These values are options used for filtering and editing. +#### Single select - ```tsx - { - field: 'country', - type: 'singleSelect', - valueOptions: ['United Kingdom', 'Spain', 'Brazil'] - } - ``` - - :::warning - When using objects values for `valueOptions` you need to provide the `value` and `label` attributes for each option. - However, you can customize which attribute is used as value and label by using `getOptionValue` and `getOptionLabel`, respectively. - - ```tsx - // Without getOptionValue and getOptionLabel - { - valueOptions: [ - { value: 'BR', label: 'Brazil' }, - { value: 'FR', label: 'France' } - ] - } +If the column type is `'singleSelect'`, you also need to set the `valueOptions` property in the respective column definition. These values are options used for filtering and editing. - // With getOptionValue and getOptionLabel - { - getOptionValue: (value: any) => value.code, - getOptionLabel: (value: any) => value.name, - valueOptions: [ - { code: 'BR', name: 'Brazil' }, - { code: 'FR', name: 'France' } - ] - } - ``` +```tsx +{ + field: 'country', + type: 'singleSelect', + valueOptions: ['United Kingdom', 'Spain', 'Brazil'] +} +``` - ::: +:::warning +When using objects values for `valueOptions` you need to provide the `value` and `label` attributes for each option. +However, you can customize which attribute is used as value and label by using `getOptionValue` and `getOptionLabel`, respectively. -- If the column type is `'actions'`, you need to provide a `getActions` function that returns an array of actions available for each row (React elements). - You can add the `showInMenu` prop on the returned React elements to signal the data grid to group these actions inside a row menu. +```tsx +// Without getOptionValue and getOptionLabel +{ + valueOptions: [ + { value: 'BR', label: 'Brazil' }, + { value: 'FR', label: 'France' } + ] +} - ```tsx - { - field: 'actions', - type: 'actions', - getActions: (params: GridRowParams) => [ - , - , - ] - } - ``` +// With getOptionValue and getOptionLabel +{ + getOptionValue: (value: any) => value.code, + getOptionLabel: (value: any) => value.name, + valueOptions: [ + { code: 'BR', name: 'Brazil' }, + { code: 'FR', name: 'France' } + ] +} +``` -{{"demo": "ColumnTypesGrid.js", "bg": "inline"}} +::: + +#### Actions + +If the column type is `'actions'`, you need to provide a `getActions` function that returns an array of actions available for each row (React elements). +You can add the `showInMenu` prop on the returned React elements to signal the data grid to group these actions inside a row menu. + +```tsx +{ + field: 'actions', + type: 'actions', + getActions: (params: GridRowParams) => [ + , + , + ] +} +``` + +By default, actions shown in the menu will close the menu on click. +But in some cases, you might want to keep the menu open after clicking an action. +You can achieve this by setting the `closeMenuOnClick` prop to `false`. + +In the following example, the "Delete" action opens a confirmation dialog and therefore needs to keep the menu mounted: + +{{"demo": "ActionsWithModalGrid.js", "bg": "inline"}} ### Custom column types diff --git a/packages/grid/x-data-grid/src/components/cell/GridActionsCell.tsx b/packages/grid/x-data-grid/src/components/cell/GridActionsCell.tsx index 08083eab542e8..c3a64881b58a0 100644 --- a/packages/grid/x-data-grid/src/components/cell/GridActionsCell.tsx +++ b/packages/grid/x-data-grid/src/components/cell/GridActionsCell.tsx @@ -180,7 +180,7 @@ function GridActionsCell(props: GridActionsCellProps) { if (event.key === 'Tab') { event.preventDefault(); } - if (['Tab', 'Enter', 'Escape'].includes(event.key)) { + if (['Tab', 'Escape'].includes(event.key)) { hideMenu(); } }; @@ -223,13 +223,7 @@ function GridActionsCell(props: GridActionsCellProps) { )} {menuButtons.length > 0 && ( - + - {menuButtons.map((button, index) => React.cloneElement(button, { key: index }))} + {menuButtons.map((button, index) => + React.cloneElement(button, { key: index, closeMenu: hideMenu }), + )} )} diff --git a/packages/grid/x-data-grid/src/components/cell/GridActionsCellItem.tsx b/packages/grid/x-data-grid/src/components/cell/GridActionsCellItem.tsx index 2d3d5c5307a09..3cb8f38d93b5d 100644 --- a/packages/grid/x-data-grid/src/components/cell/GridActionsCellItem.tsx +++ b/packages/grid/x-data-grid/src/components/cell/GridActionsCellItem.tsx @@ -12,29 +12,35 @@ export type GridActionsCellItemProps = { component?: React.ElementType; } & ( | ({ showInMenu?: false; icon: React.ReactElement } & IconButtonProps) - | ({ showInMenu: true } & MenuItemProps) + | ({ + showInMenu: true; + /** + * If false, the menu will not close when this item is clicked. + * @default true + */ + closeMenuOnClick?: boolean; + closeMenu?: () => void; + } & MenuItemProps) ); -const GridActionsCellItem = React.forwardRef( +const GridActionsCellItem = React.forwardRef( (props, ref) => { - const { label, icon, showInMenu, onClick, ...other } = props; - const rootProps = useGridRootProps(); - const handleClick = (event: any) => { - if (onClick) { - onClick(event); - } - }; + if (!props.showInMenu) { + const { label, icon, showInMenu, onClick, ...other } = props; + + const handleClick = (event: React.MouseEvent) => { + onClick?.(event); + }; - if (!showInMenu) { return ( @@ -43,8 +49,25 @@ const GridActionsCellItem = React.forwardRef) => { + onClick?.(event); + if (closeMenuOnClick) { + closeMenu?.(); + } + }; + return ( - + {icon && {icon}} {label} From af046548d4534dcf690efe423e1be0d2acdb91fd Mon Sep 17 00:00:00 2001 From: Lukas Date: Mon, 5 Feb 2024 17:07:30 +0200 Subject: [PATCH 07/53] [pickers] Avoid relying on locale in Luxon `isWithinRange` method (#11936) --- .../x-date-pickers/src/AdapterLuxon/AdapterLuxon.ts | 4 ++-- .../describeGregorianAdapter/testCalculations.ts | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/x-date-pickers/src/AdapterLuxon/AdapterLuxon.ts b/packages/x-date-pickers/src/AdapterLuxon/AdapterLuxon.ts index 295db06c32f41..0118a0025be80 100644 --- a/packages/x-date-pickers/src/AdapterLuxon/AdapterLuxon.ts +++ b/packages/x-date-pickers/src/AdapterLuxon/AdapterLuxon.ts @@ -324,8 +324,8 @@ export class AdapterLuxon implements MuiPickersAdapter { public isWithinRange = (value: DateTime, [start, end]: [DateTime, DateTime]) => { return ( - value.equals(start) || - value.equals(end) || + this.isEqual(value, start) || + this.isEqual(value, end) || (this.isAfter(value, start) && this.isBefore(value, end)) ); }; diff --git a/test/utils/pickers/describeGregorianAdapter/testCalculations.ts b/test/utils/pickers/describeGregorianAdapter/testCalculations.ts index e27fc0f3b458a..a8439902d70c0 100644 --- a/test/utils/pickers/describeGregorianAdapter/testCalculations.ts +++ b/test/utils/pickers/describeGregorianAdapter/testCalculations.ts @@ -577,7 +577,7 @@ export const testCalculations: DescribeGregorianAdapterTestSuite = ({ ).to.equal(false); }); - it('should use inclusivity of range', () => { + it('should use inclusiveness of range', () => { expect( adapter.isWithinRange(adapter.date('2019-09-01T00:00:00.000Z')!, [ adapter.date('2019-09-01T00:00:00.000Z')!, @@ -606,6 +606,15 @@ export const testCalculations: DescribeGregorianAdapterTestSuite = ({ ]), ).to.equal(true); }); + + it('should be equal with values in different locales', () => { + expect( + adapter.isWithinRange(adapter.date('2022-04-17'), [ + adapterFr.date('2022-04-17'), + adapterFr.date('2022-04-19'), + ]), + ).to.equal(true); + }); }); it('Method: startOfYear', () => { From c5d5a17962b1347bee77516c741fbe24ee73917f Mon Sep 17 00:00:00 2001 From: Rom Grk Date: Mon, 5 Feb 2024 10:17:08 -0500 Subject: [PATCH 08/53] [DataGrid] Add slot typings (#11795) Co-authored-by: Andrew Cherniavskyi Co-authored-by: Bilal Shafi --- .../data-grid/components/CustomColumnMenu.tsx | 3 +- .../components/CustomLoadingOverlayGrid.tsx | 4 +- .../CustomLoadingOverlayGrid.tsx.preview | 2 +- docs/data/data-grid/components/components.md | 18 ++- .../editing/FullFeaturedCrudGrid.tsx | 3 +- .../editing/FullFeaturedCrudGrid.tsx.preview | 2 +- .../data-grid/editing/StartEditButtonGrid.tsx | 3 +- .../filtering/CustomFilterPanelPosition.tsx | 3 +- .../CustomFilterPanelPosition.tsx.preview | 2 +- .../row-updates/InfiniteLoadingGrid.tsx | 4 +- .../InfiniteLoadingGrid.tsx.preview | 2 +- .../state/RestoreStateInitialState.tsx | 3 +- .../RestoreStateInitialState.tsx.preview | 2 +- .../migration-data-grid-v6.md | 1 + .../src/DataGridPremium/DataGridPremium.tsx | 2 + .../src/DataGridPro/DataGridPro.tsx | 2 + .../GridHeaderFilterMenuContainer.tsx | 7 +- .../x-data-grid/src/DataGrid/DataGrid.tsx | 2 + .../src/components/GridPagination.tsx | 2 +- .../x-data-grid/src/components/GridRow.tsx | 2 +- .../components/base/GridFooterPlaceholder.tsx | 4 +- .../GridCellCheckboxRenderer.tsx | 4 +- .../columnSelection/GridHeaderCheckbox.tsx | 2 +- .../panel/filterPanel/GridFilterForm.tsx | 6 +- .../filterPanel/GridFilterInputBoolean.tsx | 4 +- .../GridFilterInputSingleSelect.tsx | 6 +- .../grid/x-data-grid/src/joy/joySlots.tsx | 29 ++-- .../src/models/api/gridLocaleTextApi.ts | 6 +- .../src/models/gridSlotsComponent.ts | 74 +++++------ .../src/models/gridSlotsComponentsProps.ts | 125 ++++++++++-------- .../src/tests/filtering.DataGrid.test.tsx | 5 +- scripts/x-data-grid-premium.exports.json | 8 +- scripts/x-data-grid-pro.exports.json | 8 +- scripts/x-data-grid.exports.json | 8 +- 34 files changed, 208 insertions(+), 150 deletions(-) diff --git a/docs/data/data-grid/components/CustomColumnMenu.tsx b/docs/data/data-grid/components/CustomColumnMenu.tsx index 70275eb92d007..9a0a7fa8d4f3e 100644 --- a/docs/data/data-grid/components/CustomColumnMenu.tsx +++ b/docs/data/data-grid/components/CustomColumnMenu.tsx @@ -10,6 +10,7 @@ import { GridColumnMenuSortItem, useGridApiRef, DataGridPro, + GridSlots, } from '@mui/x-data-grid-pro'; import StarOutlineIcon from '@mui/icons-material/StarOutline'; @@ -119,7 +120,7 @@ export default function CustomColumnMenu() { }, ]} slots={{ - columnMenu: CustomColumnMenuComponent, + columnMenu: CustomColumnMenuComponent as GridSlots['columnMenu'], }} slotProps={{ columnMenu: { color }, diff --git a/docs/data/data-grid/components/CustomLoadingOverlayGrid.tsx b/docs/data/data-grid/components/CustomLoadingOverlayGrid.tsx index fef9a8145a76c..c278f02c68a45 100644 --- a/docs/data/data-grid/components/CustomLoadingOverlayGrid.tsx +++ b/docs/data/data-grid/components/CustomLoadingOverlayGrid.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { DataGrid } from '@mui/x-data-grid'; +import { DataGrid, GridSlots } from '@mui/x-data-grid'; import LinearProgress from '@mui/material/LinearProgress'; import { useDemoData } from '@mui/x-data-grid-generator'; @@ -14,7 +14,7 @@ export default function CustomLoadingOverlayGrid() {
``` +If you want to ensure type safety, you can declare your component using the slot props typings: + +```tsx +import { GridSlotProps } from '@mui/x-data-grid'; + +function MyCustomColumnMenu( + props: GridSlotProps['columnMenu'] & { background: string; counter: number }, +) { + // ... +} +``` + ### Interacting with the data grid The grid exposes two hooks to help you to access the data grid data while overriding component slots. diff --git a/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx b/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx index a3f845377b155..ea0680357f04a 100644 --- a/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx +++ b/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx @@ -18,6 +18,7 @@ import { GridRowId, GridRowModel, GridRowEditStopReasons, + GridSlots, } from '@mui/x-data-grid'; import { randomCreatedDate, @@ -237,7 +238,7 @@ export default function FullFeaturedCrudGrid() { onRowEditStop={handleRowEditStop} processRowUpdate={processRowUpdate} slots={{ - toolbar: EditToolbar, + toolbar: EditToolbar as GridSlots['toolbar'], }} slotProps={{ toolbar: { setRows, setRowModesModel }, diff --git a/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx.preview b/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx.preview index b060ee3cfc323..2693093092106 100644 --- a/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx.preview +++ b/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx.preview @@ -7,7 +7,7 @@ onRowEditStop={handleRowEditStop} processRowUpdate={processRowUpdate} slots={{ - toolbar: EditToolbar, + toolbar: EditToolbar as GridSlots['toolbar'], }} slotProps={{ toolbar: { setRows, setRowModesModel }, diff --git a/docs/data/data-grid/editing/StartEditButtonGrid.tsx b/docs/data/data-grid/editing/StartEditButtonGrid.tsx index 6397547acaac8..98f848fd4e14e 100644 --- a/docs/data/data-grid/editing/StartEditButtonGrid.tsx +++ b/docs/data/data-grid/editing/StartEditButtonGrid.tsx @@ -9,6 +9,7 @@ import { GridCellModes, GridEventListener, GridCellModesModel, + GridSlots, } from '@mui/x-data-grid'; import { randomCreatedDate, @@ -147,7 +148,7 @@ export default function StartEditButtonGrid() { onCellEditStop={handleCellEditStop} onCellModesModelChange={(model) => setCellModesModel(model)} slots={{ - toolbar: EditToolbar, + toolbar: EditToolbar as GridSlots['toolbar'], }} slotProps={{ toolbar: { diff --git a/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx b/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx index 65f85ed661714..2f686357b240a 100644 --- a/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx +++ b/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { DataGrid, + GridSlots, GridToolbarContainer, GridToolbarFilterButton, } from '@mui/x-data-grid'; @@ -35,7 +36,7 @@ export default function CustomFilterPanelPosition() {
diff --git a/docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx.preview b/docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx.preview index db0cc47aa7911..d8a614229f5c7 100644 --- a/docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx.preview +++ b/docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx.preview @@ -5,6 +5,6 @@ hideFooterPagination onRowsScrollEnd={handleOnRowsScrollEnd} slots={{ - loadingOverlay: LinearProgress, + loadingOverlay: LinearProgress as GridSlots['loadingOverlay'], }} /> \ No newline at end of file diff --git a/docs/data/data-grid/state/RestoreStateInitialState.tsx b/docs/data/data-grid/state/RestoreStateInitialState.tsx index 7e576cec4eb9b..d953a4a8e5a50 100644 --- a/docs/data/data-grid/state/RestoreStateInitialState.tsx +++ b/docs/data/data-grid/state/RestoreStateInitialState.tsx @@ -5,6 +5,7 @@ import Stack from '@mui/material/Stack'; import { DataGridPro, GridInitialState, + GridSlots, GridToolbarContainer, GridToolbarDensitySelector, GridToolbarFilterButton, @@ -62,7 +63,7 @@ export default function RestoreStateInitialState() { diff --git a/docs/data/data-grid/state/RestoreStateInitialState.tsx.preview b/docs/data/data-grid/state/RestoreStateInitialState.tsx.preview index cb7e99c92deb1..a02338eabb0bb 100644 --- a/docs/data/data-grid/state/RestoreStateInitialState.tsx.preview +++ b/docs/data/data-grid/state/RestoreStateInitialState.tsx.preview @@ -2,7 +2,7 @@ diff --git a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md index 907ccdf3398a3..6e9df3de4b2f9 100644 --- a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md +++ b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md @@ -457,5 +457,6 @@ Here's the list of affected features, colDef flags and props to disable them and - The slot `row` has had these props removed: `containerWidth`, `position`. - The slot `row` has typed props now. - The slot `headerFilterCell` has had these props removed: `filterOperators`. +- All slots are now strongly typed, previously were `React.JSXElementConstructor`. diff --git a/packages/grid/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx b/packages/grid/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx index e4958093925cb..f013899888d81 100644 --- a/packages/grid/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx +++ b/packages/grid/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx @@ -23,6 +23,8 @@ import { import { useDataGridPremiumProps } from './useDataGridPremiumProps'; import { getReleaseInfo } from '../utils/releaseInfo'; +export type { GridPremiumSlotsComponent as GridSlots } from '../models'; + const releaseInfo = getReleaseInfo(); const dataGridPremiumPropValidators: PropValidator[] = [ diff --git a/packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx b/packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx index b6623f1c4d26e..e14b2b41380d8 100644 --- a/packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx +++ b/packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx @@ -16,6 +16,8 @@ import { useDataGridProProps } from './useDataGridProProps'; import { getReleaseInfo } from '../utils/releaseInfo'; import { propValidatorsDataGridPro } from '../internals/propValidation'; +export type { GridProSlotsComponent as GridSlots } from '../models'; + const releaseInfo = getReleaseInfo(); const DataGridProRaw = React.forwardRef(function DataGridPro( diff --git a/packages/grid/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx b/packages/grid/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx index 4e89cdfd4d6cd..ac8188dd7226f 100644 --- a/packages/grid/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx +++ b/packages/grid/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx @@ -53,13 +53,16 @@ function GridHeaderFilterMenuContainer(props: { return null; } + const label = apiRef.current.getLocaleText('filterPanelOperator'); + const labelString = label ? String(label) : undefined; + return ( [] = [ ...propValidatorsDataGrid, // Only validate in MIT version diff --git a/packages/grid/x-data-grid/src/components/GridPagination.tsx b/packages/grid/x-data-grid/src/components/GridPagination.tsx index 92c2717b2eae8..f7a45091220cb 100644 --- a/packages/grid/x-data-grid/src/components/GridPagination.tsx +++ b/packages/grid/x-data-grid/src/components/GridPagination.tsx @@ -26,7 +26,7 @@ const GridPaginationRoot = styled(TablePagination)(({ theme }) => ({ }, })) as typeof TablePagination; -export const GridPagination = React.forwardRef>( +export const GridPagination = React.forwardRef>( function GridPagination(props, ref) { const apiRef = useGridApiContext(); const rootProps = useGridRootProps(); diff --git a/packages/grid/x-data-grid/src/components/GridRow.tsx b/packages/grid/x-data-grid/src/components/GridRow.tsx index c66b72793ff3e..457218861b733 100644 --- a/packages/grid/x-data-grid/src/components/GridRow.tsx +++ b/packages/grid/x-data-grid/src/components/GridRow.tsx @@ -389,7 +389,7 @@ const GridRow = React.forwardRef(function GridRow( width={width} contentWidth={contentWidth} field={column.field} - align={column.align} + align={column.align ?? 'left'} /> ); } diff --git a/packages/grid/x-data-grid/src/components/base/GridFooterPlaceholder.tsx b/packages/grid/x-data-grid/src/components/base/GridFooterPlaceholder.tsx index 5974991f1bf83..d27336afc8653 100644 --- a/packages/grid/x-data-grid/src/components/base/GridFooterPlaceholder.tsx +++ b/packages/grid/x-data-grid/src/components/base/GridFooterPlaceholder.tsx @@ -8,5 +8,7 @@ export function GridFooterPlaceholder() { return null; } - return ; + return ( + + ); } diff --git a/packages/grid/x-data-grid/src/components/columnSelection/GridCellCheckboxRenderer.tsx b/packages/grid/x-data-grid/src/components/columnSelection/GridCellCheckboxRenderer.tsx index 7353974fabb98..db1ea9d1d3eb6 100644 --- a/packages/grid/x-data-grid/src/components/columnSelection/GridCellCheckboxRenderer.tsx +++ b/packages/grid/x-data-grid/src/components/columnSelection/GridCellCheckboxRenderer.tsx @@ -49,7 +49,7 @@ const GridCellCheckboxForwardRef = React.forwardRef(null); + const checkboxElement = React.useRef(null); const rippleRef = React.useRef(null); const handleRef = useForkRef(checkboxElement, ref); @@ -104,7 +104,7 @@ const GridCellCheckboxForwardRef = React.forwardRef diff --git a/packages/grid/x-data-grid/src/components/columnSelection/GridHeaderCheckbox.tsx b/packages/grid/x-data-grid/src/components/columnSelection/GridHeaderCheckbox.tsx index b62cc90fed944..215608379c39a 100644 --- a/packages/grid/x-data-grid/src/components/columnSelection/GridHeaderCheckbox.tsx +++ b/packages/grid/x-data-grid/src/components/columnSelection/GridHeaderCheckbox.tsx @@ -27,7 +27,7 @@ const useUtilityClasses = (ownerState: OwnerState) => { return composeClasses(slots, getDataGridUtilityClass, classes); }; -const GridHeaderCheckbox = React.forwardRef( +const GridHeaderCheckbox = React.forwardRef( function GridHeaderCheckbox(props, ref) { const { field, colDef, ...other } = props; const [, forceUpdate] = React.useState(false); diff --git a/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterForm.tsx b/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterForm.tsx index bc6bfdc1c3549..9ff36187ec42c 100644 --- a/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterForm.tsx +++ b/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterForm.tsx @@ -316,7 +316,7 @@ const GridFilterForm = React.forwardRef( }, [item, currentColumn]); const changeColumn = React.useCallback( - (event: SelectChangeEvent) => { + (event: SelectChangeEvent) => { const field = event.target.value as string; const column = apiRef.current.getColumn(field)!; @@ -369,7 +369,7 @@ const GridFilterForm = React.forwardRef( ); const changeOperator = React.useCallback( - (event: SelectChangeEvent) => { + (event: SelectChangeEvent) => { const operator = event.target.value as string; const newOperator = currentColumn?.filterOperators!.find((op) => op.value === operator); @@ -388,7 +388,7 @@ const GridFilterForm = React.forwardRef( ); const changeLogicOperator = React.useCallback( - (event: SelectChangeEvent) => { + (event: SelectChangeEvent) => { const logicOperator = (event.target.value as string) === GridLogicOperator.And.toString() ? GridLogicOperator.And diff --git a/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx b/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx index 32c79a69e6b76..f8dc457521aa1 100644 --- a/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx +++ b/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx @@ -85,7 +85,9 @@ function GridFilterInputBoolean(props: GridFilterInputBooleanProps) { native={isSelectNative} displayEmpty inputProps={{ ref: focusElementRef, tabIndex }} - {...others} + { + ...(others as any) /* FIXME: typing error */ + } {...baseSelectProps} > { + (event: SelectChangeEvent) => { let value = event.target.value; // NativeSelect casts the value to a string. @@ -146,7 +146,9 @@ function GridFilterInputSingleSelect(props: GridFilterInputSingleSelectProps) { placeholder: placeholder ?? apiRef.current.getLocaleText('filterPanelInputPlaceholder'), }} native={isSelectNative} - {...others} + { + ...(others as any) /* FIXME: typing error */ + } {...rootProps.slotProps?.baseSelect} > {renderSingleSelectOptions({ diff --git a/packages/grid/x-data-grid/src/joy/joySlots.tsx b/packages/grid/x-data-grid/src/joy/joySlots.tsx index 7e245b9180657..7c5819657da0f 100644 --- a/packages/grid/x-data-grid/src/joy/joySlots.tsx +++ b/packages/grid/x-data-grid/src/joy/joySlots.tsx @@ -16,7 +16,7 @@ import JoyCircularProgress from '@mui/joy/CircularProgress'; import JoyTooltip from '@mui/joy/Tooltip'; import { unstable_useForkRef as useForkRef } from '@mui/utils'; import joyIconSlots, { GridKeyboardArrowRight, GridKeyboardArrowLeft } from './icons'; -import type { GridSlotsComponent, GridSlotsComponentsProps } from '../models'; +import type { GridSlotProps, GridSlotsComponent, GridSlotsComponentsProps } from '../models'; import { useGridApiContext } from '../hooks/utils/useGridApiContext'; import { useGridRootProps } from '../hooks/utils/useGridRootProps'; import { gridFilteredTopLevelRowCountSelector, gridPaginationModelSelector } from '../hooks'; @@ -116,10 +116,10 @@ const TextField = React.forwardRef< ); }); -const Button = React.forwardRef< - HTMLButtonElement, - NonNullable ->(function Button({ startIcon, color, endIcon, size, sx, variant, ...props }, ref) { +const Button = React.forwardRef(function Button( + { startIcon, color, endIcon, size, sx, variant, ...props }, + ref, +) { return ( ->(function Switch( +const Switch = React.forwardRef(function Switch( { name, checkedIcon, @@ -204,10 +201,7 @@ const Switch = React.forwardRef< ); }); -const Select = React.forwardRef< - HTMLButtonElement, - NonNullable ->( +const Select = React.forwardRef( ( { open, @@ -314,10 +308,7 @@ const getLabelDisplayedRowsTo = ({ return pageSize === -1 ? rowCount : Math.min(rowCount, (page + 1) * pageSize); }; -const Pagination = React.forwardRef< - HTMLDivElement, - NonNullable ->((props, ref) => { +const Pagination = React.forwardRef((props, ref) => { const apiRef = useGridApiContext(); const rootProps = useGridRootProps(); const paginationModel = gridPaginationModelSelector(apiRef); @@ -443,8 +434,8 @@ const joySlots: Partial = { baseSelect: Select, baseSelectOption: Option, baseInputLabel: InputLabel, - baseFormControl: JoyFormControl, - baseTooltip: JoyTooltip, + baseFormControl: JoyFormControl as any /* FIXME: typing error */, + baseTooltip: JoyTooltip as any /* FIXME: typing error */, pagination: Pagination, loadingOverlay: LoadingOverlay, }; diff --git a/packages/grid/x-data-grid/src/models/api/gridLocaleTextApi.ts b/packages/grid/x-data-grid/src/models/api/gridLocaleTextApi.ts index c77fe2f388f9a..b25858988c0a4 100644 --- a/packages/grid/x-data-grid/src/models/api/gridLocaleTextApi.ts +++ b/packages/grid/x-data-grid/src/models/api/gridLocaleTextApi.ts @@ -41,9 +41,9 @@ export interface GridLocaleText { toolbarExportExcel: string; // Columns management text - columnsManagementSearchTitle: React.ReactNode; - columnsManagementNoColumns: React.ReactNode; - columnsManagementShowHideAllText: React.ReactNode; + columnsManagementSearchTitle: string; + columnsManagementNoColumns: string; + columnsManagementShowHideAllText: string; // Filter panel text filterPanelAddFilter: React.ReactNode; diff --git a/packages/grid/x-data-grid/src/models/gridSlotsComponent.ts b/packages/grid/x-data-grid/src/models/gridSlotsComponent.ts index 2fec34e839a47..aedf8ceb29a95 100644 --- a/packages/grid/x-data-grid/src/models/gridSlotsComponent.ts +++ b/packages/grid/x-data-grid/src/models/gridSlotsComponent.ts @@ -1,77 +1,75 @@ import * as React from 'react'; +import type { GridSlotProps } from './gridSlotsComponentsProps'; import type { GridIconSlotsComponent } from './gridIconSlotsComponent'; -import type { GridRowProps } from '../components/GridRow'; -import type { GridDetailPanelsProps } from '../components/GridDetailPanels'; -import type { GridPinnedRowsProps } from '../components/GridPinnedRows'; -import type { GridColumnHeadersProps } from '../components/GridColumnHeaders'; -// TODO: Convert all `any` to `Props & PropsOverrides` +export type { GridSlotProps } from './gridSlotsComponentsProps'; + export interface GridBaseSlots { /** * The custom Checkbox component used in the grid for both header and cells. * @default Checkbox */ - baseCheckbox: React.JSXElementConstructor; + baseCheckbox: React.JSXElementConstructor; /** * The custom Chip component used in the grid. * @default Chip */ - baseChip: React.JSXElementConstructor; + baseChip: React.JSXElementConstructor; /** * The custom InputAdornment component used in the grid. * @default InputAdornment */ - baseInputAdornment: React.JSXElementConstructor; + baseInputAdornment: React.JSXElementConstructor; /** * The custom TextField component used in the grid. * @default TextField */ - baseTextField: React.JSXElementConstructor; + baseTextField: React.JSXElementConstructor; /** * The custom FormControl component used in the grid. * @default FormControl */ - baseFormControl: React.JSXElementConstructor; + baseFormControl: React.JSXElementConstructor; /** * The custom Select component used in the grid. * @default Select */ - baseSelect: React.JSXElementConstructor; + baseSelect: React.JSXElementConstructor; /** * The custom Switch component used in the grid. * @default Switch */ - baseSwitch: React.JSXElementConstructor; + baseSwitch: React.JSXElementConstructor; /** * The custom Button component used in the grid. * @default Button */ - baseButton: React.JSXElementConstructor; + baseButton: React.JSXElementConstructor; /** * The custom IconButton component used in the grid. * @default IconButton */ - baseIconButton: React.JSXElementConstructor; + baseIconButton: React.JSXElementConstructor; /** * The custom Tooltip component used in the grid. * @default Tooltip */ - baseTooltip: React.JSXElementConstructor; + baseTooltip: React.JSXElementConstructor; /** * The custom Popper component used in the grid. * @default Popper */ - basePopper: React.JSXElementConstructor; + basePopper: React.JSXElementConstructor; /** * The custom InputLabel component used in the grid. * @default InputLabel */ - baseInputLabel: React.JSXElementConstructor; + baseInputLabel: React.JSXElementConstructor; /** * The custom SelectOption component used in the grid. * @default MenuItem */ - baseSelectOption: React.JSXElementConstructor; + baseSelectOption: React.JSXElementConstructor; } /** @@ -82,87 +80,89 @@ export interface GridSlotsComponent extends GridBaseSlots, GridIconSlotsComponen * The custom Chip component used in the grid. * @default Chip */ - baseChip: React.JSXElementConstructor; + baseChip: React.JSXElementConstructor; /** * Component rendered for each cell. * @default GridCell */ - cell: React.JSXElementConstructor; + cell: React.JSXElementConstructor; /** * Component rendered for each skeleton cell. * @default GridSkeletonCell */ - skeletonCell: React.JSXElementConstructor; + skeletonCell: React.JSXElementConstructor; /** * Filter icon component rendered in each column header. * @default GridColumnHeaderFilterIconButton */ - columnHeaderFilterIconButton: React.JSXElementConstructor; + columnHeaderFilterIconButton: React.JSXElementConstructor< + GridSlotProps['columnHeaderFilterIconButton'] + >; /** * Column menu component rendered by clicking on the 3 dots "kebab" icon in column headers. * @default GridColumnMenu */ - columnMenu: React.JSXElementConstructor; + columnMenu: React.JSXElementConstructor; /** * Component responsible for rendering the column headers. * @default DataGridColumnHeaders */ - columnHeaders: React.JSXElementConstructor; + columnHeaders: React.JSXElementConstructor; /** * Component responsible for rendering the detail panels. * @default GridDetailPanels */ - detailPanels: React.JSXElementConstructor; + detailPanels: React.JSXElementConstructor; /** * Footer component rendered at the bottom of the grid viewport. * @default GridFooter */ - footer: React.JSXElementConstructor; + footer: React.JSXElementConstructor; /** * Row count component rendered in the footer * @default GridRowCount */ - footerRowCount: React.JSXElementConstructor; + footerRowCount: React.JSXElementConstructor; /** * Toolbar component rendered inside the Header component. * @default null */ - toolbar: React.JSXElementConstructor | null; + toolbar: React.JSXElementConstructor | null; /** * Pinned rows container. * @ignore - do not document */ - pinnedRows: React.JSXElementConstructor; + pinnedRows: React.JSXElementConstructor; /** * Loading overlay component rendered when the grid is in a loading state. * @default GridLoadingOverlay */ - loadingOverlay: React.JSXElementConstructor; + loadingOverlay: React.JSXElementConstructor; /** * No results overlay component rendered when the grid has no results after filtering. * @default GridNoResultsOverlay */ - noResultsOverlay: React.JSXElementConstructor; + noResultsOverlay: React.JSXElementConstructor; /** * No rows overlay component rendered when the grid has no rows. * @default GridNoRowsOverlay */ - noRowsOverlay: React.JSXElementConstructor; + noRowsOverlay: React.JSXElementConstructor; /** * Pagination component rendered in the grid footer by default. * @default Pagination */ - pagination: React.JSXElementConstructor | null; + pagination: React.JSXElementConstructor | null; /** * Filter panel component rendered when clicking the filter button. * @default GridFilterPanel */ - filterPanel: React.JSXElementConstructor; + filterPanel: React.JSXElementConstructor; /** * GridColumns panel component rendered when clicking the columns button. * @default GridColumnsPanel */ - columnsPanel: React.JSXElementConstructor; + columnsPanel: React.JSXElementConstructor; /** * Component used inside Grid Columns panel to manage columns. * @default GridColumnsManagement @@ -172,10 +172,10 @@ export interface GridSlotsComponent extends GridBaseSlots, GridIconSlotsComponen * Panel component wrapping the filters and columns panels. * @default GridPanel */ - panel: React.JSXElementConstructor; + panel: React.JSXElementConstructor; /** * Component rendered for each row. * @default GridRow */ - row: React.JSXElementConstructor; + row: React.JSXElementConstructor; } diff --git a/packages/grid/x-data-grid/src/models/gridSlotsComponentsProps.ts b/packages/grid/x-data-grid/src/models/gridSlotsComponentsProps.ts index b22b600d1c4cc..6623ae5d4483e 100644 --- a/packages/grid/x-data-grid/src/models/gridSlotsComponentsProps.ts +++ b/packages/grid/x-data-grid/src/models/gridSlotsComponentsProps.ts @@ -1,26 +1,31 @@ import * as React from 'react'; -import { CheckboxProps } from '@mui/material/Checkbox'; -import { TextFieldProps } from '@mui/material/TextField'; -import { FormControlProps } from '@mui/material/FormControl'; -import { SelectProps } from '@mui/material/Select'; -import { SwitchProps } from '@mui/material/Switch'; -import { ButtonProps } from '@mui/material/Button'; -import { IconButtonProps } from '@mui/material/IconButton'; -import { TooltipProps } from '@mui/material/Tooltip'; +import type { CheckboxProps } from '@mui/material/Checkbox'; +import type { TextFieldProps } from '@mui/material/TextField'; +import type { FormControlProps } from '@mui/material/FormControl'; +import type { SelectProps } from '@mui/material/Select'; +import type { SwitchProps } from '@mui/material/Switch'; +import type { ButtonProps } from '@mui/material/Button'; +import type { IconButtonProps } from '@mui/material/IconButton'; +import type { InputAdornmentProps } from '@mui/material/InputAdornment'; +import type { TooltipProps } from '@mui/material/Tooltip'; import type { InputLabelProps } from '@mui/material/InputLabel'; -import { PopperProps } from '@mui/material/Popper'; -import { TablePaginationProps } from '@mui/material/TablePagination'; -import { ChipProps } from '@mui/material/Chip'; -import { GridToolbarProps } from '../components/toolbar/GridToolbar'; -import { ColumnHeaderFilterIconButtonProps } from '../components/columnHeaders/GridColumnHeaderFilterIconButton'; -import { GridColumnMenuProps } from '../components/menu/columnMenu/GridColumnMenuProps'; -import { GridColumnsPanelProps } from '../components/panel/GridColumnsPanel'; -import { GridFilterPanelProps } from '../components/panel/filterPanel/GridFilterPanel'; -import { GridFooterContainerProps } from '../components/containers/GridFooterContainer'; -import { GridOverlayProps } from '../components/containers/GridOverlay'; -import { GridPanelProps } from '../components/panel/GridPanel'; +import type { PopperProps } from '@mui/material/Popper'; +import type { TablePaginationProps } from '@mui/material/TablePagination'; +import type { ChipProps } from '@mui/material/Chip'; +import type { GridToolbarProps } from '../components/toolbar/GridToolbar'; +import type { ColumnHeaderFilterIconButtonProps } from '../components/columnHeaders/GridColumnHeaderFilterIconButton'; +import type { GridColumnMenuProps } from '../components/menu/columnMenu/GridColumnMenuProps'; +import type { GridColumnsPanelProps } from '../components/panel/GridColumnsPanel'; +import type { GridFilterPanelProps } from '../components/panel/filterPanel/GridFilterPanel'; +import type { GridFooterContainerProps } from '../components/containers/GridFooterContainer'; +import type { GridOverlayProps } from '../components/containers/GridOverlay'; +import type { GridPanelProps } from '../components/panel/GridPanel'; +import type { GridSkeletonCellProps } from '../components/cell/GridSkeletonCell'; import type { GridRowProps } from '../components/GridRow'; import type { GridCellProps } from '../components/cell/GridCell'; +import type { GridColumnHeadersProps } from '../components/GridColumnHeaders'; +import type { GridDetailPanelsProps } from '../components/GridDetailPanels'; +import type { GridPinnedRowsProps } from '../components/GridPinnedRows'; import type { GridColumnsManagementProps } from '../components/columnsManagement/GridColumnsManagement'; import type { GridRowCountProps } from '../components'; @@ -32,6 +37,7 @@ export interface BaseSelectPropsOverrides {} export interface BaseSwitchPropsOverrides {} export interface BaseButtonPropsOverrides {} export interface BaseIconButtonPropsOverrides {} +export interface BaseInputAdornmentPropsOverrides {} export interface BaseTooltipPropsOverrides {} export interface BasePopperPropsOverrides {} export interface BaseInputLabelPropsOverrides {} @@ -42,6 +48,7 @@ export interface ToolbarPropsOverrides {} export interface ColumnHeaderFilterIconButtonPropsOverrides {} export interface ColumnMenuPropsOverrides {} export interface ColumnsPanelPropsOverrides {} +export interface DetailPanelsPropsOverrides {} export interface ColumnsManagementPropsOverrides {} export interface FilterPanelPropsOverrides {} export interface FooterPropsOverrides {} @@ -51,45 +58,53 @@ export interface LoadingOverlayPropsOverrides {} export interface NoResultsOverlayPropsOverrides {} export interface NoRowsOverlayPropsOverrides {} export interface PanelPropsOverrides {} +export interface PinnedRowsPropsOverrides {} +export interface SkeletonCellPropsOverrides {} export interface RowPropsOverrides {} -type SlotProps = Partial; +export interface GridSlotProps { + baseCheckbox: CheckboxProps & BaseCheckboxPropsOverrides; + baseTextField: TextFieldProps & BaseTextFieldPropsOverrides; + baseFormControl: FormControlProps & BaseFormControlPropsOverrides; + baseSelect: SelectProps & BaseSelectPropsOverrides; + baseSwitch: SwitchProps & BaseSwitchPropsOverrides; + baseButton: ButtonProps & BaseButtonPropsOverrides; + baseIconButton: IconButtonProps & BaseIconButtonPropsOverrides; + basePopper: PopperProps & BasePopperPropsOverrides; + baseTooltip: TooltipProps & BaseTooltipPropsOverrides; + baseInputLabel: InputLabelProps & BaseInputLabelPropsOverrides; + baseInputAdornment: InputAdornmentProps & BaseInputAdornmentPropsOverrides; + baseSelectOption: { + native: boolean; + value: any; + children?: React.ReactNode; + } & BaseSelectOptionPropsOverrides; + baseChip: ChipProps & BaseChipPropsOverrides; + cell: GridCellProps & CellPropsOverrides; + columnHeaders: GridColumnHeadersProps; + columnHeaderFilterIconButton: ColumnHeaderFilterIconButtonProps & + ColumnHeaderFilterIconButtonPropsOverrides; + columnMenu: GridColumnMenuProps & ColumnMenuPropsOverrides; + columnsPanel: GridColumnsPanelProps & ColumnsPanelPropsOverrides; + columnsManagement: GridColumnsManagementProps & ColumnsManagementPropsOverrides; + detailPanels: GridDetailPanelsProps & DetailPanelsPropsOverrides; + filterPanel: GridFilterPanelProps & FilterPanelPropsOverrides; + footer: GridFooterContainerProps & FooterPropsOverrides; + footerRowCount: GridRowCountProps & FooterRowCountOverrides; + loadingOverlay: GridOverlayProps & LoadingOverlayPropsOverrides; + noResultsOverlay: GridOverlayProps & NoResultsOverlayPropsOverrides; + noRowsOverlay: GridOverlayProps & NoRowsOverlayPropsOverrides; + pagination: Partial & PaginationPropsOverrides; + panel: GridPanelProps & PanelPropsOverrides; + pinnedRows: GridPinnedRowsProps & PinnedRowsPropsOverrides; + row: GridRowProps & RowPropsOverrides; + skeletonCell: GridSkeletonCellProps & SkeletonCellPropsOverrides; + toolbar: GridToolbarProps & ToolbarPropsOverrides; +} /** * Overridable components props dynamically passed to the component at rendering. */ -export interface GridSlotsComponentsProps { - baseCheckbox?: SlotProps; - baseTextField?: SlotProps; - baseFormControl?: SlotProps; - baseSelect?: SlotProps; - baseSwitch?: SlotProps; - baseButton?: SlotProps; - baseIconButton?: SlotProps; - basePopper?: SlotProps; - baseTooltip?: SlotProps; - baseInputLabel?: SlotProps; - baseSelectOption?: SlotProps< - { native: boolean; value: any; children?: React.ReactNode }, - BaseSelectOptionPropsOverrides - >; - baseChip?: SlotProps; - cell?: SlotProps; - columnHeaderFilterIconButton?: SlotProps< - ColumnHeaderFilterIconButtonProps, - ColumnHeaderFilterIconButtonPropsOverrides - >; - columnMenu?: SlotProps; - columnsPanel?: SlotProps; - columnsManagement?: SlotProps; - filterPanel?: SlotProps; - footer?: SlotProps; - footerRowCount?: SlotProps; - loadingOverlay?: SlotProps; - noResultsOverlay?: SlotProps; - noRowsOverlay?: SlotProps; - pagination?: SlotProps; - panel?: SlotProps; - row?: SlotProps; - toolbar?: SlotProps; -} +export type GridSlotsComponentsProps = Partial<{ + [K in keyof GridSlotProps]: Partial; +}>; diff --git a/packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx index c69bb7331eca5..1c0e44a39cbf9 100644 --- a/packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx @@ -8,6 +8,7 @@ import { GridColDef, GridFilterItem, GridPreferencePanelsValue, + GridSlots, GridToolbar, GridFilterOperator, } from '@mui/x-data-grid'; @@ -1305,7 +1306,7 @@ describe(' - Filter', () => { type: 'number', }, ]} - slots={{ toolbar: GridToolbarFilterButton }} + slots={{ toolbar: GridToolbarFilterButton as GridSlots['toolbar'] }} />, ); @@ -1369,7 +1370,7 @@ describe(' - Filter', () => { ] as GridFilterOperator[], }, ]} - slots={{ toolbar: GridToolbarFilterButton }} + slots={{ toolbar: GridToolbarFilterButton as GridSlots['toolbar'] }} /> , ); diff --git a/scripts/x-data-grid-premium.exports.json b/scripts/x-data-grid-premium.exports.json index 287b954cc35ce..7093d6eac2ad7 100644 --- a/scripts/x-data-grid-premium.exports.json +++ b/scripts/x-data-grid-premium.exports.json @@ -4,6 +4,7 @@ { "name": "BaseChipPropsOverrides", "kind": "Interface" }, { "name": "BaseFormControlPropsOverrides", "kind": "Interface" }, { "name": "BaseIconButtonPropsOverrides", "kind": "Interface" }, + { "name": "BaseInputAdornmentPropsOverrides", "kind": "Interface" }, { "name": "BaseInputLabelPropsOverrides", "kind": "Interface" }, { "name": "BasePopperPropsOverrides", "kind": "Interface" }, { "name": "BaseSelectOptionPropsOverrides", "kind": "Interface" }, @@ -28,6 +29,7 @@ { "name": "DataGridPro", "kind": "Function" }, { "name": "DEFAULT_GRID_AUTOSIZE_OPTIONS", "kind": "Variable" }, { "name": "DEFAULT_GRID_COL_TYPE_KEY", "kind": "Variable" }, + { "name": "DetailPanelsPropsOverrides", "kind": "Interface" }, { "name": "ElementSize", "kind": "Interface" }, { "name": "EMPTY_PINNED_COLUMN_FIELDS", "kind": "Variable" }, { "name": "EMPTY_RENDER_CONTEXT", "kind": "Variable" }, @@ -529,8 +531,10 @@ { "name": "GridSkeletonCell", "kind": "Function" }, { "name": "GridSkeletonCellProps", "kind": "Interface" }, { "name": "GridSkeletonRowNode", "kind": "Interface" }, + { "name": "GridSlotProps", "kind": "Interface" }, + { "name": "GridSlots", "kind": "Interface" }, { "name": "GridSlotsComponent", "kind": "Interface" }, - { "name": "GridSlotsComponentsProps", "kind": "Interface" }, + { "name": "GridSlotsComponentsProps", "kind": "TypeAlias" }, { "name": "GridSortApi", "kind": "Interface" }, { "name": "GridSortCellParams", "kind": "Interface" }, { "name": "GridSortColumnLookup", "kind": "TypeAlias" }, @@ -610,6 +614,7 @@ { "name": "OutputSelector", "kind": "Interface" }, { "name": "PaginationPropsOverrides", "kind": "Interface" }, { "name": "PanelPropsOverrides", "kind": "Interface" }, + { "name": "PinnedRowsPropsOverrides", "kind": "Interface" }, { "name": "renderActionsCell", "kind": "Variable" }, { "name": "renderBooleanCell", "kind": "Variable" }, { "name": "renderEditBooleanCell", "kind": "Variable" }, @@ -621,6 +626,7 @@ { "name": "selectedGridRowsSelector", "kind": "Variable" }, { "name": "selectedIdsLookupSelector", "kind": "Variable" }, { "name": "setupExcelExportWebWorker", "kind": "Function" }, + { "name": "SkeletonCellPropsOverrides", "kind": "Interface" }, { "name": "ToolbarPropsOverrides", "kind": "Interface" }, { "name": "unstable_resetCleanupTracking", "kind": "Variable" }, { "name": "useFirstRender", "kind": "Variable" }, diff --git a/scripts/x-data-grid-pro.exports.json b/scripts/x-data-grid-pro.exports.json index 6e1bffb88d86e..7a9543c73818f 100644 --- a/scripts/x-data-grid-pro.exports.json +++ b/scripts/x-data-grid-pro.exports.json @@ -4,6 +4,7 @@ { "name": "BaseChipPropsOverrides", "kind": "Interface" }, { "name": "BaseFormControlPropsOverrides", "kind": "Interface" }, { "name": "BaseIconButtonPropsOverrides", "kind": "Interface" }, + { "name": "BaseInputAdornmentPropsOverrides", "kind": "Interface" }, { "name": "BaseInputLabelPropsOverrides", "kind": "Interface" }, { "name": "BasePopperPropsOverrides", "kind": "Interface" }, { "name": "BaseSelectOptionPropsOverrides", "kind": "Interface" }, @@ -27,6 +28,7 @@ { "name": "DataGridProProps", "kind": "Interface" }, { "name": "DEFAULT_GRID_AUTOSIZE_OPTIONS", "kind": "Variable" }, { "name": "DEFAULT_GRID_COL_TYPE_KEY", "kind": "Variable" }, + { "name": "DetailPanelsPropsOverrides", "kind": "Interface" }, { "name": "ElementSize", "kind": "Interface" }, { "name": "EMPTY_PINNED_COLUMN_FIELDS", "kind": "Variable" }, { "name": "EMPTY_RENDER_CONTEXT", "kind": "Variable" }, @@ -483,8 +485,10 @@ { "name": "GridSkeletonCell", "kind": "Function" }, { "name": "GridSkeletonCellProps", "kind": "Interface" }, { "name": "GridSkeletonRowNode", "kind": "Interface" }, + { "name": "GridSlotProps", "kind": "Interface" }, + { "name": "GridSlots", "kind": "Interface" }, { "name": "GridSlotsComponent", "kind": "Interface" }, - { "name": "GridSlotsComponentsProps", "kind": "Interface" }, + { "name": "GridSlotsComponentsProps", "kind": "TypeAlias" }, { "name": "GridSortApi", "kind": "Interface" }, { "name": "GridSortCellParams", "kind": "Interface" }, { "name": "GridSortColumnLookup", "kind": "TypeAlias" }, @@ -562,6 +566,7 @@ { "name": "OutputSelector", "kind": "Interface" }, { "name": "PaginationPropsOverrides", "kind": "Interface" }, { "name": "PanelPropsOverrides", "kind": "Interface" }, + { "name": "PinnedRowsPropsOverrides", "kind": "Interface" }, { "name": "renderActionsCell", "kind": "Variable" }, { "name": "renderBooleanCell", "kind": "Variable" }, { "name": "renderEditBooleanCell", "kind": "Variable" }, @@ -572,6 +577,7 @@ { "name": "selectedGridRowsCountSelector", "kind": "Variable" }, { "name": "selectedGridRowsSelector", "kind": "Variable" }, { "name": "selectedIdsLookupSelector", "kind": "Variable" }, + { "name": "SkeletonCellPropsOverrides", "kind": "Interface" }, { "name": "ToolbarPropsOverrides", "kind": "Interface" }, { "name": "unstable_resetCleanupTracking", "kind": "Variable" }, { "name": "useFirstRender", "kind": "Variable" }, diff --git a/scripts/x-data-grid.exports.json b/scripts/x-data-grid.exports.json index a14da1163acf4..f55ecfd6630cc 100644 --- a/scripts/x-data-grid.exports.json +++ b/scripts/x-data-grid.exports.json @@ -4,6 +4,7 @@ { "name": "BaseChipPropsOverrides", "kind": "Interface" }, { "name": "BaseFormControlPropsOverrides", "kind": "Interface" }, { "name": "BaseIconButtonPropsOverrides", "kind": "Interface" }, + { "name": "BaseInputAdornmentPropsOverrides", "kind": "Interface" }, { "name": "BaseInputLabelPropsOverrides", "kind": "Interface" }, { "name": "BasePopperPropsOverrides", "kind": "Interface" }, { "name": "BaseSelectOptionPropsOverrides", "kind": "Interface" }, @@ -24,6 +25,7 @@ { "name": "DataGrid", "kind": "Variable" }, { "name": "DataGridProps", "kind": "TypeAlias" }, { "name": "DEFAULT_GRID_COL_TYPE_KEY", "kind": "Variable" }, + { "name": "DetailPanelsPropsOverrides", "kind": "Interface" }, { "name": "ElementSize", "kind": "Interface" }, { "name": "EMPTY_PINNED_COLUMN_FIELDS", "kind": "Variable" }, { "name": "EMPTY_RENDER_CONTEXT", "kind": "Variable" }, @@ -438,8 +440,10 @@ { "name": "GridSkeletonCell", "kind": "Function" }, { "name": "GridSkeletonCellProps", "kind": "Interface" }, { "name": "GridSkeletonRowNode", "kind": "Interface" }, + { "name": "GridSlotProps", "kind": "Interface" }, + { "name": "GridSlots", "kind": "Interface" }, { "name": "GridSlotsComponent", "kind": "Interface" }, - { "name": "GridSlotsComponentsProps", "kind": "Interface" }, + { "name": "GridSlotsComponentsProps", "kind": "TypeAlias" }, { "name": "GridSortApi", "kind": "Interface" }, { "name": "GridSortCellParams", "kind": "Interface" }, { "name": "GridSortColumnLookup", "kind": "TypeAlias" }, @@ -515,6 +519,7 @@ { "name": "OutputSelector", "kind": "Interface" }, { "name": "PaginationPropsOverrides", "kind": "Interface" }, { "name": "PanelPropsOverrides", "kind": "Interface" }, + { "name": "PinnedRowsPropsOverrides", "kind": "Interface" }, { "name": "renderActionsCell", "kind": "Variable" }, { "name": "renderBooleanCell", "kind": "Variable" }, { "name": "renderEditBooleanCell", "kind": "Variable" }, @@ -525,6 +530,7 @@ { "name": "selectedGridRowsCountSelector", "kind": "Variable" }, { "name": "selectedGridRowsSelector", "kind": "Variable" }, { "name": "selectedIdsLookupSelector", "kind": "Variable" }, + { "name": "SkeletonCellPropsOverrides", "kind": "Interface" }, { "name": "ToolbarPropsOverrides", "kind": "Interface" }, { "name": "unstable_resetCleanupTracking", "kind": "Variable" }, { "name": "useFirstRender", "kind": "Variable" }, From cc20ad95b43e7b8a8cf29418fac12f151744bf18 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskii Date: Mon, 5 Feb 2024 16:58:56 +0100 Subject: [PATCH 09/53] [core] Add `docs:serve` script (#11935) --- docs/package.json | 9 +++++---- package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/package.json b/docs/package.json index baa9269d03f51..f64c94dbc67da 100644 --- a/docs/package.json +++ b/docs/package.json @@ -5,13 +5,13 @@ "author": "MUI Team", "license": "MIT", "scripts": { - "build": "rimraf docs/export && cross-env NODE_ENV=production next build --profile && yarn build-sw", + "build": "rimraf ./export && cross-env NODE_ENV=production next build --profile && yarn build-sw", "build:clean": "rimraf .next && yarn build", "build-sw": "node ./scripts/buildServiceWorker.js", "dev": "next dev --port 3001", "deploy": "git push -f upstream next:docs-next", "icons": "rimraf public/static/icons/* && node ./scripts/buildIcons.js", - "start": "next start", + "serve": "serve ./export -l 3010", "create-playground": "cpy --cwd=scripts playground.template.tsx ../../pages/playground --rename=index.tsx", "typescript": "tsc -p tsconfig.json", "typescript:transpile": "cross-env BABEL_ENV=development babel-node --extensions \".tsx,.ts,.js\" scripts/formattedTSDemos", @@ -52,8 +52,8 @@ "core-js": "^2.6.12", "cross-env": "^7.0.3", "date-fns": "^2.30.0", - "date-fns-v3": "https://registry.npmjs.org/date-fns/-/date-fns-3.2.0.tgz", "date-fns-jalali": "^2.21.3-1", + "date-fns-v3": "https://registry.npmjs.org/date-fns/-/date-fns-3.2.0.tgz", "dayjs": "^1.11.10", "doctrine": "^3.0.0", "exceljs": "^4.4.0", @@ -98,6 +98,7 @@ "@types/stylis": "^4.2.5", "@types/webpack-bundle-analyzer": "^4.6.3", "cpy-cli": "^5.0.0", - "gm": "^1.25.0" + "gm": "^1.25.0", + "serve": "^14.2.1" } } diff --git a/package.json b/package.json index b572a46f3217c..0db7e3d0dabcb 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "scripts": { "start": "yarn && yarn docs:dev", "docs:dev": "yarn workspace docs dev", - "docs:start": "yarn workspace docs start", + "docs:serve": "yarn workspace docs serve", "docs:create-playground": "yarn workspace docs create-playground", "docs:api": "NODE_OPTIONS=--max-old-space-size=4096 yarn docs:api:build && yarn docs:api:buildX", "docs:api:build": "cross-env BABEL_ENV=development babel-node -i \"/node_modules/(?!@mui)/\" -x .ts,.tsx,.js ./scripts/buildApiDocs/index.ts", From 094abbc2ece29e41f50935783af25b4e7ab1838a Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Tue, 6 Feb 2024 00:19:54 +0100 Subject: [PATCH 10/53] [core] Normalize issue template --- bug-reproductions/x-data-grid/public/index.html | 9 ++++++--- test/e2e/template.html | 4 ++-- test/regressions/template.html | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/bug-reproductions/x-data-grid/public/index.html b/bug-reproductions/x-data-grid/public/index.html index 80363f8fecc8e..9befde78ff8b2 100644 --- a/bug-reproductions/x-data-grid/public/index.html +++ b/bug-reproductions/x-data-grid/public/index.html @@ -1,12 +1,15 @@ - + - DataGridProDemo demo — MUI X + DataGrid — MUI X + + + diff --git a/test/e2e/template.html b/test/e2e/template.html index 081f21ed377a0..7d84cc7643adb 100644 --- a/test/e2e/template.html +++ b/test/e2e/template.html @@ -1,9 +1,9 @@ - + Playwright end-to-end test - +