Skip to content

Commit

Permalink
feat: datepicker support leftSlot and rightSlot (#2409)
Browse files Browse the repository at this point in the history
---------
Co-authored-by: luyang <[email protected]>
Co-authored-by: pointhalo <[email protected]>
  • Loading branch information
LuyangFE authored Aug 20, 2024
1 parent 26802be commit e09dee8
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 15 deletions.
5 changes: 5 additions & 0 deletions content/input/datepicker/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,7 @@ function Demo() {
| inputReadOnly | 文本框是否 readonly | boolean | false | |
| inputStyle | 输入框样式 | object | | |
| insetLabel | 前缀标签,优先级低于 `prefix` | string\|ReactNode | | |
| leftSlot | 渲染左侧额外区域 | ReactNode | | |
| max | multiple 为 true 时,多选的数目,不传或者值为 null\|undefined 的话无限制 | number | - | |
| motion | 是否开启面板展开的动画 | boolean | true | |
| multiple | 是否可以选择多个,仅支持 type="date" | boolean | false | |
Expand All @@ -883,9 +884,13 @@ function Demo() {
| presets | 日期时间快捷方式, start 和 end 在 v2.52 版本支持函数类型 | <ApiType detail='type PresetType = { start?: BaseValueType \| (() => BaseValueType); end?: BaseValueType \| (() => BaseValueType); text?: string }; type PresetsType = Array<PresetType \| (() => PresetType)>;'>Array</ApiType> | [] | |
| preventScroll | 指示浏览器是否应滚动文档以显示新聚焦的元素,作用于组件内的 focus 方法 | boolean | | |
| presetPosition | 日期时间快捷方式面板位置, 可选值'left', 'right', 'top', 'bottom' | string | 'bottom' | **2.18.0** |
| rangeSeparator | 自定义范围类型输入框的日期分隔符 | string | '~' | **1.31.0** |
| renderDate | 自定义日期显示内容 | (dayNumber, fullDate) => ReactNode | - | **1.4.0** |
| renderFullDate | 自定义显示日期格子内容 | (dayNumber, fullDate, dayStatus) => ReactNode | - | **1.4.0** |
| rangeSeparator | 自定义范围类型输入框的日期分隔符 | string | '~' | |
| renderDate | 自定义日期显示内容 | (dayNumber, fullDate) => ReactNode | - | |
| renderFullDate | 自定义显示日期格子内容 | (dayNumber, fullDate, dayStatus) => ReactNode | - | |
| rightSlot | 渲染右侧额外区域 | ReactNode | | |
| showClear | 是否显示清除按钮 | boolean | true | |
| size | 尺寸,可选值:"small", "default", "large" | string | 'default' | |
| spacing | 浮层与 trigger 的距离 | number | 4 | |
Expand Down
14 changes: 13 additions & 1 deletion packages/semi-foundation/datePicker/datePicker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ $module-list: #{$prefix}-scrolllist;

.#{$module} {
box-sizing: border-box;
display: inline-block;
display: inline-flex;

&-container {
display: flex;
}

.#{$module-list}-body {
.#{$module-list}-item {
Expand Down Expand Up @@ -820,6 +824,14 @@ $module-list: #{$prefix}-scrolllist;
&-topSlot {
border-bottom: $width-datepicker_slot-border solid $color-datepicker_border-bg-default;
}

&-leftSlot {
border-right: $width-datepicker_slot-border solid $color-datepicker_border-bg-default;
}

&-rightSlot {
border-left: $width-datepicker_slot-border solid $color-datepicker_border-bg-default;
}

&-bottomSlot {
border-top: $width-datepicker_slot-border solid $color-datepicker_border-bg-default;
Expand Down
18 changes: 17 additions & 1 deletion packages/semi-ui/datePicker/_story/DatePickerSlot/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ export default function Demo() {
);
};

const LeftSlot = function (props) {
const { style } = props;
return (
<div>LeftSlot</div>
);
};

const RightSlot = function (props) {
const { style } = props;
return (
<Space style={{ padding: '12px 20px', ...style }}>
<div>RightSlot</div>
</Space>
);
};

const MonthBottomSlot = function (props) {
const { style } = props;
return (
Expand All @@ -60,7 +76,7 @@ export default function Demo() {
return (
<div>
<span>topSlot</span>
<DatePicker topSlot={<TopSlot />} disabledDate={disabledDate} value={date} onChange={handleDateChange} />
<DatePicker topSlot={<TopSlot />} leftSlot={<LeftSlot />} rightSlot={<RightSlot/>} disabledDate={disabledDate} value={date} onChange={handleDateChange} />
<br />
<br />
<span>bottomSlot</span>
Expand Down
40 changes: 27 additions & 13 deletions packages/semi-ui/datePicker/datePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface DatePickerProps extends DatePickerFoundationProps {
insetLabelId?: string;
prefix?: React.ReactNode;
topSlot?: React.ReactNode;
rightSlot?: React.ReactNode;
renderDate?: (dayNumber?: number, fullDate?: string) => React.ReactNode;
renderFullDate?: (dayNumber?: number, fullDate?: string, dayStatus?: DayStatusType) => React.ReactNode;
triggerRender?: (props: DatePickerProps) => React.ReactNode;
Expand All @@ -63,6 +64,7 @@ export interface DatePickerProps extends DatePickerFoundationProps {
onPresetClick?: (item: PresetType, e: React.MouseEvent<HTMLDivElement>) => void;
onClickOutSide?: () => void;
locale?: Locale['DatePicker'];
leftSlot?: React.ReactNode;
dateFnsLocale?: Locale['dateFnsLocale'];
yearAndMonthOpts?: ScrollItemProps<any>;
dropdownMargin?: PopoverProps['margin']
Expand Down Expand Up @@ -747,7 +749,7 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
};

renderPanel = (locale: Locale['DatePicker'], localeCode: string, dateFnsLocale: Locale['dateFnsLocale']) => {
const { dropdownClassName, dropdownStyle, density, topSlot, bottomSlot, presetPosition, type } = this.props;
const { dropdownClassName, dropdownStyle, density, topSlot, bottomSlot, presetPosition, type, leftSlot, rightSlot } = this.props;
const wrapCls = classnames(
cssClasses.PREFIX,
{
Expand All @@ -759,20 +761,32 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke

return (
<div ref={this.panelRef} className={wrapCls} style={dropdownStyle} x-type={type}>
{topSlot && (
<div className={`${cssClasses.PREFIX}-topSlot`} x-semi-prop="topSlot">
{topSlot}
{leftSlot && (
<div className={`${cssClasses.PREFIX}-leftSlot`} x-semi-prop="leftSlot">
{leftSlot}
</div>
)}
{/* todo: monthRange does not support presetPosition temporarily */}
{presetPosition === "top" && type !== 'monthRange' && this.renderQuickControls()}
{this.adapter.typeIsYearOrMonth()
? this.renderYearMonthPanel(locale, localeCode)
: this.renderMonthGrid(locale, localeCode, dateFnsLocale)}
{presetPosition === "bottom" && type !== 'monthRange' && this.renderQuickControls()}
{bottomSlot && (
<div className={`${cssClasses.PREFIX}-bottomSlot`} x-semi-prop="bottomSlot">
{bottomSlot}
<div>
{topSlot && (
<div className={`${cssClasses.PREFIX}-topSlot`} x-semi-prop="topSlot">
{topSlot}
</div>
)}
{/* todo: monthRange does not support presetPosition temporarily */}
{presetPosition === "top" && type !== 'monthRange' && this.renderQuickControls()}
{this.adapter.typeIsYearOrMonth()
? this.renderYearMonthPanel(locale, localeCode)
: this.renderMonthGrid(locale, localeCode, dateFnsLocale)}
{presetPosition === "bottom" && type !== 'monthRange' && this.renderQuickControls()}
{bottomSlot && (
<div className={`${cssClasses.PREFIX}-bottomSlot`} x-semi-prop="bottomSlot">
{bottomSlot}
</div>
)}
</div>
{rightSlot && (
<div className={`${cssClasses.PREFIX}-rightSlot`} x-semi-prop="rightSlot">
{rightSlot}
</div>
)}
{this.renderFooter(locale, localeCode)}
Expand Down

0 comments on commit e09dee8

Please sign in to comment.