panel.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. import { unit } from '@ant-design/cssinjs';
  2. import { FastColor } from '@ant-design/fast-color';
  3. const genPickerCellInnerStyle = token => {
  4. const {
  5. pickerCellCls,
  6. pickerCellInnerCls,
  7. cellHeight,
  8. borderRadiusSM,
  9. motionDurationMid,
  10. cellHoverBg,
  11. lineWidth,
  12. lineType,
  13. colorPrimary,
  14. cellActiveWithRangeBg,
  15. colorTextLightSolid,
  16. colorTextDisabled,
  17. cellBgDisabled,
  18. colorFillSecondary
  19. } = token;
  20. return {
  21. '&::before': {
  22. position: 'absolute',
  23. top: '50%',
  24. insetInlineStart: 0,
  25. insetInlineEnd: 0,
  26. zIndex: 1,
  27. height: cellHeight,
  28. transform: 'translateY(-50%)',
  29. content: '""',
  30. pointerEvents: 'none'
  31. },
  32. // >>> Default
  33. [pickerCellInnerCls]: {
  34. position: 'relative',
  35. zIndex: 2,
  36. display: 'inline-block',
  37. minWidth: cellHeight,
  38. height: cellHeight,
  39. lineHeight: unit(cellHeight),
  40. borderRadius: borderRadiusSM,
  41. transition: `background ${motionDurationMid}`
  42. },
  43. // >>> Hover
  44. [`&:hover:not(${pickerCellCls}-in-view):not(${pickerCellCls}-disabled),
  45. &:hover:not(${pickerCellCls}-selected):not(${pickerCellCls}-range-start):not(${pickerCellCls}-range-end):not(${pickerCellCls}-disabled)`]: {
  46. [pickerCellInnerCls]: {
  47. background: cellHoverBg
  48. }
  49. },
  50. // >>> Today
  51. [`&-in-view${pickerCellCls}-today ${pickerCellInnerCls}`]: {
  52. '&::before': {
  53. position: 'absolute',
  54. top: 0,
  55. insetInlineEnd: 0,
  56. bottom: 0,
  57. insetInlineStart: 0,
  58. zIndex: 1,
  59. border: `${unit(lineWidth)} ${lineType} ${colorPrimary}`,
  60. borderRadius: borderRadiusSM,
  61. content: '""'
  62. }
  63. },
  64. // >>> In Range
  65. [`&-in-view${pickerCellCls}-in-range,
  66. &-in-view${pickerCellCls}-range-start,
  67. &-in-view${pickerCellCls}-range-end`]: {
  68. position: 'relative',
  69. [`&:not(${pickerCellCls}-disabled):before`]: {
  70. background: cellActiveWithRangeBg
  71. }
  72. },
  73. // >>> Selected
  74. [`&-in-view${pickerCellCls}-selected,
  75. &-in-view${pickerCellCls}-range-start,
  76. &-in-view${pickerCellCls}-range-end`]: {
  77. [`&:not(${pickerCellCls}-disabled) ${pickerCellInnerCls}`]: {
  78. color: colorTextLightSolid,
  79. background: colorPrimary
  80. },
  81. [`&${pickerCellCls}-disabled ${pickerCellInnerCls}`]: {
  82. background: colorFillSecondary
  83. }
  84. },
  85. [`&-in-view${pickerCellCls}-range-start:not(${pickerCellCls}-disabled):before`]: {
  86. insetInlineStart: '50%'
  87. },
  88. [`&-in-view${pickerCellCls}-range-end:not(${pickerCellCls}-disabled):before`]: {
  89. insetInlineEnd: '50%'
  90. },
  91. // range start border-radius
  92. [`&-in-view${pickerCellCls}-range-start:not(${pickerCellCls}-range-end) ${pickerCellInnerCls}`]: {
  93. borderStartStartRadius: borderRadiusSM,
  94. borderEndStartRadius: borderRadiusSM,
  95. borderStartEndRadius: 0,
  96. borderEndEndRadius: 0
  97. },
  98. // range end border-radius
  99. [`&-in-view${pickerCellCls}-range-end:not(${pickerCellCls}-range-start) ${pickerCellInnerCls}`]: {
  100. borderStartStartRadius: 0,
  101. borderEndStartRadius: 0,
  102. borderStartEndRadius: borderRadiusSM,
  103. borderEndEndRadius: borderRadiusSM
  104. },
  105. // >>> Disabled
  106. '&-disabled': {
  107. color: colorTextDisabled,
  108. cursor: 'not-allowed',
  109. [pickerCellInnerCls]: {
  110. background: 'transparent'
  111. },
  112. '&::before': {
  113. background: cellBgDisabled
  114. }
  115. },
  116. [`&-disabled${pickerCellCls}-today ${pickerCellInnerCls}::before`]: {
  117. borderColor: colorTextDisabled
  118. }
  119. };
  120. };
  121. export const genPanelStyle = token => {
  122. const {
  123. componentCls,
  124. pickerCellCls,
  125. pickerCellInnerCls,
  126. pickerYearMonthCellWidth,
  127. pickerControlIconSize,
  128. cellWidth,
  129. paddingSM,
  130. paddingXS,
  131. paddingXXS,
  132. colorBgContainer,
  133. lineWidth,
  134. lineType,
  135. borderRadiusLG,
  136. colorPrimary,
  137. colorTextHeading,
  138. colorSplit,
  139. pickerControlIconBorderWidth,
  140. colorIcon,
  141. textHeight,
  142. motionDurationMid,
  143. colorIconHover,
  144. fontWeightStrong,
  145. cellHeight,
  146. pickerCellPaddingVertical,
  147. colorTextDisabled,
  148. colorText,
  149. fontSize,
  150. motionDurationSlow,
  151. withoutTimeCellHeight,
  152. pickerQuarterPanelContentHeight,
  153. borderRadiusSM,
  154. colorTextLightSolid,
  155. cellHoverBg,
  156. timeColumnHeight,
  157. timeColumnWidth,
  158. timeCellHeight,
  159. controlItemBgActive,
  160. marginXXS,
  161. pickerDatePanelPaddingHorizontal,
  162. pickerControlIconMargin
  163. } = token;
  164. const pickerPanelWidth = token.calc(cellWidth).mul(7).add(token.calc(pickerDatePanelPaddingHorizontal).mul(2)).equal();
  165. return {
  166. [componentCls]: {
  167. '&-panel': {
  168. display: 'inline-flex',
  169. flexDirection: 'column',
  170. textAlign: 'center',
  171. background: colorBgContainer,
  172. borderRadius: borderRadiusLG,
  173. outline: 'none',
  174. '&-focused': {
  175. borderColor: colorPrimary
  176. },
  177. '&-rtl': {
  178. [`${componentCls}-prev-icon,
  179. ${componentCls}-super-prev-icon`]: {
  180. transform: 'rotate(45deg)'
  181. },
  182. [`${componentCls}-next-icon,
  183. ${componentCls}-super-next-icon`]: {
  184. transform: 'rotate(-135deg)'
  185. },
  186. [`${componentCls}-time-panel`]: {
  187. [`${componentCls}-content`]: {
  188. direction: 'ltr',
  189. '> *': {
  190. direction: 'rtl'
  191. }
  192. }
  193. }
  194. }
  195. },
  196. // ========================================================
  197. // = Shared Panel =
  198. // ========================================================
  199. [`&-decade-panel,
  200. &-year-panel,
  201. &-quarter-panel,
  202. &-month-panel,
  203. &-week-panel,
  204. &-date-panel,
  205. &-time-panel`]: {
  206. display: 'flex',
  207. flexDirection: 'column',
  208. width: pickerPanelWidth
  209. },
  210. // ======================= Header =======================
  211. '&-header': {
  212. display: 'flex',
  213. padding: `0 ${unit(paddingXS)}`,
  214. color: colorTextHeading,
  215. borderBottom: `${unit(lineWidth)} ${lineType} ${colorSplit}`,
  216. '> *': {
  217. flex: 'none'
  218. },
  219. button: {
  220. padding: 0,
  221. color: colorIcon,
  222. lineHeight: unit(textHeight),
  223. background: 'transparent',
  224. border: 0,
  225. cursor: 'pointer',
  226. transition: `color ${motionDurationMid}`,
  227. fontSize: 'inherit',
  228. display: 'inline-flex',
  229. alignItems: 'center',
  230. justifyContent: 'center',
  231. '&:empty': {
  232. display: 'none'
  233. }
  234. },
  235. '> button': {
  236. minWidth: '1.6em',
  237. fontSize,
  238. '&:hover': {
  239. color: colorIconHover
  240. },
  241. '&:disabled': {
  242. opacity: 0.25,
  243. pointerEvents: 'none'
  244. }
  245. },
  246. '&-view': {
  247. flex: 'auto',
  248. fontWeight: fontWeightStrong,
  249. lineHeight: unit(textHeight),
  250. '> button': {
  251. color: 'inherit',
  252. fontWeight: 'inherit',
  253. verticalAlign: 'top',
  254. '&:not(:first-child)': {
  255. marginInlineStart: paddingXS
  256. },
  257. '&:hover': {
  258. color: colorPrimary
  259. }
  260. }
  261. }
  262. },
  263. // Arrow button
  264. [`&-prev-icon,
  265. &-next-icon,
  266. &-super-prev-icon,
  267. &-super-next-icon`]: {
  268. position: 'relative',
  269. width: pickerControlIconSize,
  270. height: pickerControlIconSize,
  271. '&::before': {
  272. position: 'absolute',
  273. top: 0,
  274. insetInlineStart: 0,
  275. width: pickerControlIconSize,
  276. height: pickerControlIconSize,
  277. border: `0 solid currentcolor`,
  278. borderBlockStartWidth: pickerControlIconBorderWidth,
  279. borderInlineStartWidth: pickerControlIconBorderWidth,
  280. content: '""'
  281. }
  282. },
  283. [`&-super-prev-icon,
  284. &-super-next-icon`]: {
  285. '&::after': {
  286. position: 'absolute',
  287. top: pickerControlIconMargin,
  288. insetInlineStart: pickerControlIconMargin,
  289. display: 'inline-block',
  290. width: pickerControlIconSize,
  291. height: pickerControlIconSize,
  292. border: '0 solid currentcolor',
  293. borderBlockStartWidth: pickerControlIconBorderWidth,
  294. borderInlineStartWidth: pickerControlIconBorderWidth,
  295. content: '""'
  296. }
  297. },
  298. '&-prev-icon, &-super-prev-icon': {
  299. transform: 'rotate(-45deg)'
  300. },
  301. '&-next-icon, &-super-next-icon': {
  302. transform: 'rotate(135deg)'
  303. },
  304. // ======================== Body ========================
  305. '&-content': {
  306. width: '100%',
  307. tableLayout: 'fixed',
  308. borderCollapse: 'collapse',
  309. 'th, td': {
  310. position: 'relative',
  311. minWidth: cellHeight,
  312. fontWeight: 'normal'
  313. },
  314. th: {
  315. height: token.calc(cellHeight).add(token.calc(pickerCellPaddingVertical).mul(2)).equal(),
  316. color: colorText,
  317. verticalAlign: 'middle'
  318. }
  319. },
  320. '&-cell': Object.assign({
  321. padding: `${unit(pickerCellPaddingVertical)} 0`,
  322. color: colorTextDisabled,
  323. cursor: 'pointer',
  324. // In view
  325. '&-in-view': {
  326. color: colorText
  327. }
  328. }, genPickerCellInnerStyle(token)),
  329. [`&-decade-panel,
  330. &-year-panel,
  331. &-quarter-panel,
  332. &-month-panel`]: {
  333. [`${componentCls}-content`]: {
  334. height: token.calc(withoutTimeCellHeight).mul(4).equal()
  335. },
  336. [pickerCellInnerCls]: {
  337. padding: `0 ${unit(paddingXS)}`
  338. }
  339. },
  340. '&-quarter-panel': {
  341. [`${componentCls}-content`]: {
  342. height: pickerQuarterPanelContentHeight
  343. }
  344. },
  345. // ========================================================
  346. // = Special =
  347. // ========================================================
  348. // ===================== Decade Panel =====================
  349. '&-decade-panel': {
  350. [pickerCellInnerCls]: {
  351. padding: `0 ${unit(token.calc(paddingXS).div(2).equal())}`
  352. },
  353. [`${componentCls}-cell::before`]: {
  354. display: 'none'
  355. }
  356. },
  357. // ============= Year & Quarter & Month Panel =============
  358. [`&-year-panel,
  359. &-quarter-panel,
  360. &-month-panel`]: {
  361. [`${componentCls}-body`]: {
  362. padding: `0 ${unit(paddingXS)}`
  363. },
  364. [pickerCellInnerCls]: {
  365. width: pickerYearMonthCellWidth
  366. }
  367. },
  368. // ====================== Date Panel ======================
  369. '&-date-panel': {
  370. [`${componentCls}-body`]: {
  371. padding: `${unit(paddingXS)} ${unit(pickerDatePanelPaddingHorizontal)}`
  372. },
  373. [`${componentCls}-content th`]: {
  374. boxSizing: 'border-box',
  375. padding: 0
  376. }
  377. },
  378. // ====================== Week Panel ======================
  379. '&-week-panel-row': {
  380. td: {
  381. '&:before': {
  382. transition: `background ${motionDurationMid}`
  383. },
  384. '&:first-child:before': {
  385. borderStartStartRadius: borderRadiusSM,
  386. borderEndStartRadius: borderRadiusSM
  387. },
  388. '&:last-child:before': {
  389. borderStartEndRadius: borderRadiusSM,
  390. borderEndEndRadius: borderRadiusSM
  391. }
  392. },
  393. '&:hover td:before': {
  394. background: cellHoverBg
  395. },
  396. '&-range-start td, &-range-end td, &-selected td, &-hover td': {
  397. // Rise priority to override hover style
  398. [`&${pickerCellCls}`]: {
  399. '&:before': {
  400. background: colorPrimary
  401. },
  402. [`&${componentCls}-cell-week`]: {
  403. color: new FastColor(colorTextLightSolid).setA(0.5).toHexString()
  404. },
  405. [pickerCellInnerCls]: {
  406. color: colorTextLightSolid
  407. }
  408. }
  409. },
  410. '&-range-hover td:before': {
  411. background: controlItemBgActive
  412. }
  413. },
  414. // >>> ShowWeek
  415. '&-week-panel, &-date-panel-show-week': {
  416. [`${componentCls}-body`]: {
  417. padding: `${unit(paddingXS)} ${unit(paddingSM)}`
  418. },
  419. [`${componentCls}-content th`]: {
  420. width: 'auto'
  421. }
  422. },
  423. // ==================== Datetime Panel ====================
  424. '&-datetime-panel': {
  425. display: 'flex',
  426. [`${componentCls}-time-panel`]: {
  427. borderInlineStart: `${unit(lineWidth)} ${lineType} ${colorSplit}`
  428. },
  429. [`${componentCls}-date-panel,
  430. ${componentCls}-time-panel`]: {
  431. transition: `opacity ${motionDurationSlow}`
  432. },
  433. // Keyboard
  434. '&-active': {
  435. [`${componentCls}-date-panel,
  436. ${componentCls}-time-panel`]: {
  437. opacity: 0.3,
  438. '&-active': {
  439. opacity: 1
  440. }
  441. }
  442. }
  443. },
  444. // ====================== Time Panel ======================
  445. '&-time-panel': {
  446. width: 'auto',
  447. minWidth: 'auto',
  448. [`${componentCls}-content`]: {
  449. display: 'flex',
  450. flex: 'auto',
  451. height: timeColumnHeight
  452. },
  453. '&-column': {
  454. flex: '1 0 auto',
  455. width: timeColumnWidth,
  456. margin: `${unit(paddingXXS)} 0`,
  457. padding: 0,
  458. overflowY: 'hidden',
  459. textAlign: 'start',
  460. listStyle: 'none',
  461. transition: `background ${motionDurationMid}`,
  462. overflowX: 'hidden',
  463. '&::-webkit-scrollbar': {
  464. width: 8,
  465. backgroundColor: 'transparent'
  466. },
  467. '&::-webkit-scrollbar-thumb': {
  468. backgroundColor: token.colorTextTertiary,
  469. borderRadius: token.borderRadiusSM
  470. },
  471. // For Firefox
  472. '&': {
  473. scrollbarWidth: 'thin',
  474. scrollbarColor: `${token.colorTextTertiary} transparent`
  475. },
  476. '&::after': {
  477. display: 'block',
  478. height: `calc(100% - ${unit(timeCellHeight)})`,
  479. content: '""'
  480. },
  481. '&:not(:first-child)': {
  482. borderInlineStart: `${unit(lineWidth)} ${lineType} ${colorSplit}`
  483. },
  484. '&-active': {
  485. background: new FastColor(controlItemBgActive).setA(0.2).toHexString()
  486. },
  487. '&:hover': {
  488. overflowY: 'auto'
  489. },
  490. '> li': {
  491. margin: 0,
  492. padding: 0,
  493. [`&${componentCls}-time-panel-cell`]: {
  494. marginInline: marginXXS,
  495. [`${componentCls}-time-panel-cell-inner`]: {
  496. display: 'block',
  497. width: token.calc(timeColumnWidth).sub(token.calc(marginXXS).mul(2)).equal(),
  498. height: timeCellHeight,
  499. margin: 0,
  500. paddingBlock: 0,
  501. paddingInlineEnd: 0,
  502. paddingInlineStart: token.calc(timeColumnWidth).sub(timeCellHeight).div(2).equal(),
  503. color: colorText,
  504. lineHeight: unit(timeCellHeight),
  505. borderRadius: borderRadiusSM,
  506. cursor: 'pointer',
  507. transition: `background ${motionDurationMid}`,
  508. '&:hover': {
  509. background: cellHoverBg
  510. }
  511. },
  512. '&-selected': {
  513. [`${componentCls}-time-panel-cell-inner`]: {
  514. background: controlItemBgActive
  515. }
  516. },
  517. '&-disabled': {
  518. [`${componentCls}-time-panel-cell-inner`]: {
  519. color: colorTextDisabled,
  520. background: 'transparent',
  521. cursor: 'not-allowed'
  522. }
  523. }
  524. }
  525. }
  526. }
  527. }
  528. }
  529. };
  530. };
  531. const genPickerPanelStyle = token => {
  532. const {
  533. componentCls,
  534. textHeight,
  535. lineWidth,
  536. paddingSM,
  537. antCls,
  538. colorPrimary,
  539. cellActiveWithRangeBg,
  540. colorPrimaryBorder,
  541. lineType,
  542. colorSplit
  543. } = token;
  544. return {
  545. [`${componentCls}-dropdown`]: {
  546. // ======================== Footer ========================
  547. [`${componentCls}-footer`]: {
  548. borderTop: `${unit(lineWidth)} ${lineType} ${colorSplit}`,
  549. '&-extra': {
  550. padding: `0 ${unit(paddingSM)}`,
  551. lineHeight: unit(token.calc(textHeight).sub(token.calc(lineWidth).mul(2)).equal()),
  552. textAlign: 'start',
  553. '&:not(:last-child)': {
  554. borderBottom: `${unit(lineWidth)} ${lineType} ${colorSplit}`
  555. }
  556. }
  557. },
  558. // ==================== Footer > Ranges ===================
  559. [`${componentCls}-panels + ${componentCls}-footer ${componentCls}-ranges`]: {
  560. justifyContent: 'space-between'
  561. },
  562. [`${componentCls}-ranges`]: {
  563. marginBlock: 0,
  564. paddingInline: unit(paddingSM),
  565. overflow: 'hidden',
  566. textAlign: 'start',
  567. listStyle: 'none',
  568. display: 'flex',
  569. justifyContent: 'center',
  570. alignItems: 'center',
  571. '> li': {
  572. lineHeight: unit(token.calc(textHeight).sub(token.calc(lineWidth).mul(2)).equal()),
  573. display: 'inline-block'
  574. },
  575. [`${componentCls}-now-btn-disabled`]: {
  576. pointerEvents: 'none',
  577. color: token.colorTextDisabled
  578. },
  579. // https://github.com/ant-design/ant-design/issues/23687
  580. [`${componentCls}-preset > ${antCls}-tag-blue`]: {
  581. color: colorPrimary,
  582. background: cellActiveWithRangeBg,
  583. borderColor: colorPrimaryBorder,
  584. cursor: 'pointer'
  585. },
  586. [`${componentCls}-ok`]: {
  587. paddingBlock: token.calc(lineWidth).mul(2).equal(),
  588. marginInlineStart: 'auto'
  589. }
  590. }
  591. }
  592. };
  593. };
  594. export default genPickerPanelStyle;