Skip to content

Commit 1511f18

Browse files
authored
feat: Relayout of Picker (#500)
* chore: init * refactor: Use presets hooks * feat: preset style * chore: rm console * test: clean up * test: update cov * chore: CI update * chore: LGTM * test: fix part test * test: update snapshot * test: rewrite part of test * test: more test case
1 parent 2d43933 commit 1511f18

21 files changed

+331
-218
lines changed

.fatherrc.js

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
export default {
2-
cjs: 'babel',
3-
esm: { type: 'babel', importLibToEs: true },
4-
preCommit: {
5-
eslint: true,
6-
prettier: true,
7-
},
8-
runtimeHelpers: true,
9-
};
1+
import { defineConfig } from 'father';
2+
3+
export default defineConfig({
4+
plugins: ['@rc-component/father-plugin'],
5+
});

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515

1616
- uses: actions/setup-node@v1
1717
with:
18-
node-version: '12'
18+
node-version: '16'
1919

2020
- name: cache package-lock.json
2121
uses: actions/cache@v2

assets/index.less

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,14 @@
150150
}
151151
}
152152

153+
// Preset
154+
&-presets {
155+
margin: 0;
156+
padding: 0;
157+
list-style: none;
158+
background: #CCCCFF;
159+
}
160+
153161
&-footer,
154162
&-picker-footer {
155163
background: green;
@@ -451,4 +459,10 @@
451459
vertical-align: top;
452460
transition: margin 0.3s;
453461
}
462+
463+
&-panel-layout {
464+
display: flex;
465+
flex-wrap: nowrap;
466+
align-items: stretch;
467+
}
454468
}

docs/examples/basic.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ export default () => {
2828
value,
2929
onSelect,
3030
onChange,
31+
presets: [
32+
{
33+
label: 'Hello World!',
34+
value: moment(),
35+
},
36+
],
3137
};
3238

3339
const keyDown = (e, preventDefault) => {
@@ -65,7 +71,7 @@ export default () => {
6571
defaultValue: moment('11:28:39', 'HH:mm:ss'),
6672
}}
6773
showToday
68-
disabledTime={date => {
74+
disabledTime={(date) => {
6975
if (date && date.isSame(defaultValue, 'date')) {
7076
return {
7177
disabledHours: () => [1, 3, 5, 7, 9, 11],

package.json

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"prepublishOnly": "npm run compile && np --yolo --no-publish",
3434
"lint": "eslint src/ --ext .ts,.tsx,.jsx,.js,.md",
3535
"prettier": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"",
36-
"test": "father test",
36+
"test": "rc-test",
3737
"coverage": "father test --coverage",
3838
"now-build": "npm run build"
3939
},
@@ -51,6 +51,7 @@
5151
"node": ">=8.x"
5252
},
5353
"devDependencies": {
54+
"@rc-component/father-plugin": "^1.0.0",
5455
"@testing-library/react": "^12",
5556
"@types/classnames": "^2.2.9",
5657
"@types/enzyme": "^3.10.3",
@@ -70,23 +71,17 @@
7071
"eslint-plugin-jest": "^26.8.2",
7172
"eslint-plugin-react-hooks": "^4.0.2",
7273
"eslint-plugin-unicorn": "^40.0.0",
73-
"father": "^2.13.4",
74+
"father": "^4.0.0",
7475
"glob": "^7.2.0",
7576
"less": "^3.10.3",
7677
"mockdate": "^3.0.2",
7778
"np": "^7.1.0",
7879
"prettier": "^2.0.5",
80+
"rc-test": "^7.0.9",
7981
"react": "^16.0.0",
8082
"react-dom": "^16.0.0",
81-
"react-test-renderer": "^16.0.0",
8283
"typescript": "^4.0.3"
8384
},
84-
"cnpm": {
85-
"mode": "npm"
86-
},
87-
"tnpm": {
88-
"mode": "npm"
89-
},
9085
"peerDependencies": {
9186
"react": ">=16.9.0",
9287
"react-dom": ">=16.9.0"

src/PanelContext.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ export type PanelContextProps = {
1010
operationRef?: React.MutableRefObject<ContextOperationRefProps | null>;
1111
/** Only work with time panel */
1212
hideHeader?: boolean;
13-
panelRef?: React.Ref<HTMLDivElement>;
1413
hidePrevBtn?: boolean;
1514
hideNextBtn?: boolean;
1615
onDateMouseEnter?: (date: any) => void;

src/Picker.tsx

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ import { formatValue, isEqual, parseValue } from './utils/dateUtil';
2727
import getDataOrAriaProps, { toArray } from './utils/miscUtil';
2828
import type { ContextOperationRefProps } from './PanelContext';
2929
import PanelContext from './PanelContext';
30-
import type { CustomFormat, PickerMode } from './interface';
30+
import type { CustomFormat, PickerMode, PresetDate } from './interface';
3131
import { getDefaultFormat, getInputSize, elementsContains } from './utils/uiUtil';
3232
import usePickerInput from './hooks/usePickerInput';
3333
import useTextValueMapping from './hooks/useTextValueMapping';
3434
import useValueTexts from './hooks/useValueTexts';
3535
import useHoverValue from './hooks/useHoverValue';
3636
import { legacyPropsWarning } from './utils/warnUtil';
37+
import usePresets from './hooks/usePresets';
38+
import PresetPanel from './PresetPanel';
3739

3840
export type PickerRefConfig = {
3941
focus: () => void;
@@ -56,6 +58,8 @@ export type PickerSharedProps<DateType> = {
5658
inputReadOnly?: boolean;
5759
id?: string;
5860

61+
presets?: PresetDate<DateType>[];
62+
5963
// Value
6064
format?: string | CustomFormat<DateType> | (string | CustomFormat<DateType>)[];
6165

@@ -151,6 +155,7 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
151155
use12Hours,
152156
value,
153157
defaultValue,
158+
presets,
154159
open,
155160
defaultOpen,
156161
defaultOpenValue,
@@ -183,6 +188,8 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
183188

184189
const needConfirmButton: boolean = (picker === 'date' && !!showTime) || picker === 'time';
185190

191+
const presetList = usePresets(presets);
192+
186193
// ============================ Warning ============================
187194
if (process.env.NODE_ENV !== 'production') {
188195
legacyPropsWarning(props);
@@ -393,26 +400,36 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
393400
};
394401

395402
let panelNode: React.ReactNode = (
396-
<PickerPanel<DateType>
397-
{...panelProps}
398-
generateConfig={generateConfig}
399-
className={classNames({
400-
[`${prefixCls}-panel-focused`]: !typing,
401-
})}
402-
value={selectedValue}
403-
locale={locale}
404-
tabIndex={-1}
405-
onSelect={(date) => {
406-
onSelect?.(date);
407-
setSelectedValue(date);
408-
}}
409-
direction={direction}
410-
onPanelChange={(viewDate, mode) => {
411-
const { onPanelChange } = props;
412-
onLeave(true);
413-
onPanelChange?.(viewDate, mode);
414-
}}
415-
/>
403+
<div className={`${prefixCls}-panel-layout`}>
404+
<PresetPanel
405+
prefixCls={prefixCls}
406+
presets={presetList}
407+
onClick={(nextValue) => {
408+
triggerChange(nextValue);
409+
triggerOpen(false);
410+
}}
411+
/>
412+
<PickerPanel<DateType>
413+
{...panelProps}
414+
generateConfig={generateConfig}
415+
className={classNames({
416+
[`${prefixCls}-panel-focused`]: !typing,
417+
})}
418+
value={selectedValue}
419+
locale={locale}
420+
tabIndex={-1}
421+
onSelect={(date) => {
422+
onSelect?.(date);
423+
setSelectedValue(date);
424+
}}
425+
direction={direction}
426+
onPanelChange={(viewDate, mode) => {
427+
const { onPanelChange } = props;
428+
onLeave(true);
429+
onPanelChange?.(viewDate, mode);
430+
}}
431+
/>
432+
</div>
416433
);
417434

418435
if (panelRender) {
@@ -422,6 +439,7 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
422439
const panel = (
423440
<div
424441
className={`${prefixCls}-panel-container`}
442+
ref={panelDivRef}
425443
onMouseDown={(e) => {
426444
e.preventDefault();
427445
}}
@@ -505,7 +523,6 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
505523
value={{
506524
operationRef,
507525
hideHeader: picker === 'time',
508-
panelRef: panelDivRef,
509526
onSelect: onContextSelect,
510527
open: mergedOpen,
511528
defaultOpenValue,

src/PickerPanel.tsx

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,7 @@ function PickerPanel<DateType>(props: PickerPanelProps<DateType>) {
173173
// ============================ State =============================
174174

175175
const panelContext = React.useContext(PanelContext);
176-
const {
177-
operationRef,
178-
panelRef: panelDivRef,
179-
onSelect: onContextSelect,
180-
hideRanges,
181-
defaultOpenValue,
182-
} = panelContext;
176+
const { operationRef, onSelect: onContextSelect, hideRanges, defaultOpenValue } = panelContext;
183177

184178
const { inRange, panelPosition, rangedValue, hoverRangedValue } = React.useContext(RangeContext);
185179
const panelRef = React.useRef<PanelRefProps>({});
@@ -553,7 +547,6 @@ function PickerPanel<DateType>(props: PickerPanelProps<DateType>) {
553547
onKeyDown={onInternalKeyDown}
554548
onBlur={onInternalBlur}
555549
onMouseDown={onMouseDown}
556-
ref={panelDivRef}
557550
>
558551
{panelNode}
559552
{extraFooter || rangesNode || todayNode ? (

src/PresetPanel.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import * as React from 'react';
2+
import type { PresetDate } from './interface';
3+
4+
export interface PresetPanelProps<T> {
5+
prefixCls: string;
6+
presets: PresetDate<T>[];
7+
onClick: (value: T) => void;
8+
onHover?: (value: T) => void;
9+
}
10+
11+
export default function PresetPanel<T>(props: PresetPanelProps<T>) {
12+
const { prefixCls, presets, onClick, onHover } = props;
13+
14+
if (!presets.length) {
15+
return null;
16+
}
17+
18+
return (
19+
<ul className={`${prefixCls}-presets`}>
20+
{presets.map(({ label, value }, index) => (
21+
<li
22+
key={index}
23+
onClick={() => {
24+
onClick(value);
25+
}}
26+
onMouseEnter={() => {
27+
onHover?.(value);
28+
}}
29+
onMouseLeave={() => {
30+
onHover?.(null);
31+
}}
32+
>
33+
{label}
34+
</li>
35+
))}
36+
</ul>
37+
);
38+
}

0 commit comments

Comments
 (0)