Skip to content

Commit

Permalink
feat(Cascader): highlight selected items, close #990
Browse files Browse the repository at this point in the history
  • Loading branch information
Javey committed Apr 12, 2024
1 parent 25bcd81 commit 4b99078
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 6 deletions.
4 changes: 4 additions & 0 deletions components/cascader/demos/filterable.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ import {Cascader} from 'kpc';
<div>
<Cascader data={this.get('data')} v-model="value" filterable />
<br /><br />
<Cascader data={this.get('data')} v-model="values" filterable multiple />
</div>
```

```ts
interface Props {
value?: string[] | null
values?: string[][] | null
}

export default class extends Component<Props> {
Expand All @@ -25,6 +28,7 @@ export default class extends Component<Props> {
static defaults() {
return {
value: [] as string[],
values: [] as string[][],
data: [
{
value: 'beijing',
Expand Down
3 changes: 2 additions & 1 deletion components/cascader/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ export class Cascader<
private filterable = useFilterable(
this.input.keywords,
this.value.setValue,
this.fields
this.fields,
this.value.values
);
private positionObj = {my: 'left top', at: 'right top', collisionDirection: ['left']};

Expand Down
4 changes: 3 additions & 1 deletion components/cascader/index.vdt
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const Options = (data, level, loaded, parentSelected) => {
});
}

const {filter, keywords: {value: keywords}, selectByFilter} = this.filterable;
const {filter, keywords: {value: keywords}, selectByFilter, isSelectedItem} = this.filterable;
<t:super class={`${k}-cascader`}>
<b:base-menu>
<DropdownMenu
Expand All @@ -94,6 +94,8 @@ const {filter, keywords: {value: keywords}, selectByFilter} = this.filterable;
return <DropdownItem v-for={items}
ev-select={selectByFilter.bind(null, $value)}
disabled={$value.disabled}
hideOnSelect={!multiple}
class={{[`${k}-selected`]: isSelectedItem($value)}}
>
{(() => {
// highlight keywords
Expand Down
3 changes: 3 additions & 0 deletions components/cascader/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,8 @@ export const makeFilterMenuStyles = cache(function makeFilterMenuStyles(k: strin
font-style: normal;
color: ${cascader.filter.highlightColor};
}
.${k}-dropdown-item.${k}-selected {
color: ${cascader.selectedColor};
}
`;
});
17 changes: 13 additions & 4 deletions components/cascader/useFilterable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import type {Cascader, CascaderData, BaseCascaderData} from './';
import {State} from '../../hooks/useState';
import type {Value} from './useValue';
import type {useFields} from './useFields';
import { isEqualArray } from '../utils';

export function useFilterable(
keywords: State<string>,
setValue: (value: Value) => void,
getField: ReturnType<typeof useFields>
getField: ReturnType<typeof useFields>,
values: State<Value[]>
) {
const instance = useInstance() as Cascader;

Expand Down Expand Up @@ -48,9 +50,16 @@ export function useFilterable(
}

function selectByFilter(data: CascaderData<any>[]) {
const value = data.map(item => getField(item, 'value'));
setValue(value);
setValue(getValue(data));
}

return {filter, selectByFilter, keywords};
function isSelectedItem(data: CascaderData<any>[]) {
return !!values.value.find((value) => isEqualArray(value, getValue(data)));
}

function getValue(data: CascaderData<any>[]) {
return data.map(item => getField(item, 'value'));
}

return {filter, selectByFilter, keywords, isSelectedItem};
}

0 comments on commit 4b99078

Please sign in to comment.