Skip to content

Commit

Permalink
* picker: support to custom display content to trigger.
Browse files Browse the repository at this point in the history
  • Loading branch information
catouse committed Mar 21, 2024
1 parent c7e3478 commit 345b742
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 19 deletions.
12 changes: 12 additions & 0 deletions lib/picker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

用于方便用户从多个选项列表中进行选择。

## 特殊选项

### 禁用搜索

```html:example
<div id="noSearchPicker"></div>
```

```html:example
<div id="noSearchMultiPicker"></div>
```

## 远程数据

### 单选
Expand Down
15 changes: 15 additions & 0 deletions lib/picker/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,19 @@ onPageUpdate(() => {
toolbar: true,
});
console.log('> multiPicker', multiPicker);

const noSearchPicker = new Picker('#noSearchPicker', {
items,
search: false,
display: '已选择 {text}',
});
console.log('> noSearchPicker', noSearchPicker);

const noSearchMultiPicker = new Picker('#noSearchMultiPicker', {
items,
search: false,
multiple: true,
display: '已选择 {count} 项',
});
console.log('> noSearchMultiPicker', noSearchMultiPicker);
});
35 changes: 22 additions & 13 deletions lib/picker/src/component/picker-multi-select.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {classes, $, createRef, CustomContent} from '@zui/core';
import {classes, $, createRef, CustomContent, ComponentChildren} from '@zui/core';
import {formatString} from '@zui/helpers';
import '@zui/css-icons/src/icons/caret.css';
import '@zui/css-icons/src/icons/close.css';
import {PickTrigger, EVENT_PICK} from '@zui/pick/src/components';
Expand Down Expand Up @@ -64,22 +65,30 @@ export class PickerMultiSelect extends PickTrigger<PickerState, PickerSelectProp
}

protected _renderTrigger(props: PickerSelectProps) {
const {state: {selections = [], open}, search, placeholder, children} = this.props;
const {state: {selections = [], open, value}, search, placeholder, display, valueList, children} = this.props;
const showSearch = open && search;
const caret = <span key="caret" class="caret"></span>;
if (!showSearch && !selections.length) {
return [
<span key="selections" className="picker-select-placeholder">{placeholder}</span>,
caret,
];
}
return [
<div key="selections" className="picker-multi-selections">
let view: ComponentChildren;
const noSelections = !showSearch && !selections.length;
if (display && (noSelections || placeholder === undefined)) {
if (typeof display === 'function') {
view = display.call(this, valueList, selections);
} else if (typeof display === 'string') {
view = formatString(display, {value, values: valueList, count: valueList.length});
}
view = <div key="selections" className="picker-multi-selections">{view}</div>;
} else if (noSelections) {
view = <span key="selections" className="picker-select-placeholder">{placeholder}</span>;

} else {
view = (<div key="selections" className="picker-multi-selections">
{selections.map(this._renderSelection)}
{showSearch ? this._renderSearch(props) : null}
</div>,
</div>);
}
return [
view,
children,
caret,
<span key="caret" class="caret"></span>,
];
}

Expand Down
17 changes: 13 additions & 4 deletions lib/picker/src/component/picker-single-select.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {ComponentChildren, createRef} from 'preact';
import {CustomContent, classes} from '@zui/core';
import {PickTrigger} from '@zui/pick/src/components';
import {formatString} from '@zui/helpers';
import {PickerSearch} from './picker-search';
import {PickerSelectProps, PickerState} from '../types';
import '@zui/css-icons/src/icons/caret.css';
Expand Down Expand Up @@ -65,18 +66,27 @@ export class PickerSingleSelect extends PickTrigger<PickerState, PickerSelectPro
}

protected _renderTrigger(props: PickerSelectProps) {
const {children, state: {selections = [], open}, placeholder, search, disabled, readonly, clearable} = props;
const {children, state: {selections = [], value, open}, placeholder, search, disabled, readonly, clearable, display} = props;

const [selection] = selections;
const showSearch = open && search;
let view: ComponentChildren;
if (showSearch) {
view = this._renderSearch(props);
} else if (selection) {
} else if (selection || (placeholder === undefined && display)) {
const {text} = selection;
if (typeof display === 'function') {
view = display.call(this, value, selection);
} else if (typeof display === 'string') {
view = formatString(display, selection);
} else {
view = (
<CustomContent content={text} />
);
}
view = (
<span key="main" className="picker-single-selection" title={typeof text === 'string' ? text : undefined}>
<CustomContent content={text} />
{view}
</span>
);
} else {
Expand All @@ -86,7 +96,6 @@ export class PickerSingleSelect extends PickTrigger<PickerState, PickerSelectPro
<button key="deselect" type="button" className="btn picker-deselect-btn size-sm square ghost" disabled={disabled} readonly={readonly} onClick={this._handleDeselectClick}><span className="close"></span></button>
) : null;
const caret = showSearch ? null : <span key="caret" className="caret"></span>;

return [
view,
children,
Expand Down
1 change: 1 addition & 0 deletions lib/picker/src/component/picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ export class Picker<S extends PickerState = PickerState, O extends PickerOptions
hotkeys: props.hotkeys,
placeholder: props.placeholder,
search: props.search,
display: props.display,
searchHint: props.searchHint,
clearable: !!this.valueList.length && !props.required,
valueList: this.valueList,
Expand Down
4 changes: 3 additions & 1 deletion lib/picker/src/types/picker-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import type {PickOptions} from '@zui/pick';
import type {MenuOptions} from '@zui/menu';
import type {ToolbarSetting} from '@zui/toolbar';
import type {TreeOptions} from '@zui/tree';
import type {HotkeysSettings} from '@zui/core';
import type {CustomContentType, HotkeysSettings} from '@zui/core';
import type {PickerState} from './picker-state';
import type {PickerItemBasic} from './picker-item-options';

export interface PickerOptions<S extends PickerState = PickerState> extends PickOptions<S> {
multiple?: boolean | number;
Expand All @@ -21,6 +22,7 @@ export interface PickerOptions<S extends PickerState = PickerState> extends Pick
cache?: boolean;
searchDelay?: number;
searchEmptyHint?: string;
display?: string | ((values: string | string[], selections: PickerItemBasic | PickerItemBasic[]) => CustomContentType);
search?: boolean | number;
searchHint?: string;
hotkeys?: HotkeysSettings;
Expand Down
4 changes: 3 additions & 1 deletion lib/picker/src/types/picker-select-props.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {PickTriggerProps} from '@zui/pick';
import type {PickerState} from './picker-state';
import type {HotkeysSettings} from '@zui/core/src/helpers';
import type {HotkeysSettings, CustomContentType} from '@zui/core';
import type {PickerItemBasic} from './picker-item-options';

export interface PickerSelectProps<S extends PickerState = PickerState> extends PickTriggerProps<S> {
placeholder?: string;
Expand All @@ -12,6 +13,7 @@ export interface PickerSelectProps<S extends PickerState = PickerState> extends
valueList: string[];
emptyValue: string;
hotkeys?: HotkeysSettings;
display?: string | ((values: string | string[], selections: PickerItemBasic | PickerItemBasic[]) => CustomContentType);

onSelect: (values: string | string[]) => void;
onDeselect: (values: string | string[]) => void;
Expand Down

0 comments on commit 345b742

Please sign in to comment.